Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ repos:
- id: mixed-line-ending
- id: name-tests-test
args: ["--pytest-test-first"]
- id: requirements-txt-fixer
# - id: requirements-txt-fixer
- id: trailing-whitespace

- repo: https://github.com/pre-commit/pygrep-hooks
rev: "v1.10.0"
hooks:
- id: rst-backticks
- id: rst-directive-colons
- id: rst-inline-touching-normal
# - repo: https://github.com/pre-commit/pygrep-hooks
# rev: "v1.10.0"
# hooks:
# - id: rst-backticks
# - id: rst-directive-colons
# - id: rst-inline-touching-normal

- repo: https://github.com/pre-commit/mirrors-prettier
rev: "v4.0.0-alpha.8"
Expand All @@ -48,17 +48,17 @@ repos:
args: ["--fix", "--show-fixes"]
- id: ruff-format

- repo: https://github.com/pre-commit/mirrors-clang-format
rev: "v19.1.5"
hooks:
- id: clang-format
types_or: [c++, c, cuda]
# - repo: https://github.com/pre-commit/mirrors-clang-format
# rev: "v19.1.5"
# hooks:
# - id: clang-format
# types_or: [c++, c, cuda]

- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.13.0"
hooks:
- id: mypy
files: src|tests
files: src #|tests
args: []
additional_dependencies:
- pytest
Expand All @@ -83,10 +83,10 @@ repos:
entry: PyBind|Numpy|Cmake|CCache|Github|PyTest
exclude: .pre-commit-config.yaml

- repo: https://github.com/cheshirekow/cmake-format-precommit
rev: "v0.6.13"
hooks:
- id: cmake-format
# - repo: https://github.com/cheshirekow/cmake-format-precommit
# rev: "v0.6.13"
# hooks:
# - id: cmake-format

- repo: https://github.com/abravalheri/validate-pyproject
rev: "v0.23"
Expand Down
12 changes: 9 additions & 3 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ def lint(session: nox.Session) -> None:
Run the linter.
"""
session.install("pre-commit")
session.run("pre-commit", "run", "--all-files", "--show-diff-on-failure", *session.posargs)
session.run(
"pre-commit", "run", "--all-files", "--show-diff-on-failure", *session.posargs
)


@nox.session
Expand Down Expand Up @@ -50,7 +52,9 @@ def docs(session: nox.Session) -> None:

parser = argparse.ArgumentParser()
parser.add_argument("--serve", action="store_true", help="Serve after building")
parser.add_argument("-b", dest="builder", default="html", help="Build target (default: html)")
parser.add_argument(
"-b", dest="builder", default="html", help="Build target (default: html)"
)
args, posargs = parser.parse_known_args(session.posargs)

if args.builder != "html" and args.serve:
Expand All @@ -62,7 +66,9 @@ def docs(session: nox.Session) -> None:
session.chdir("docs")

if args.builder == "linkcheck":
session.run("sphinx-build", "-b", "linkcheck", ".", "_build/linkcheck", *posargs)
session.run(
"sphinx-build", "-b", "linkcheck", ".", "_build/linkcheck", *posargs
)
return

shared_args = (
Expand Down
4 changes: 0 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,6 @@ disallow_untyped_defs = true
disallow_incomplete_defs = true


[tool.ruff]
src = ["src"]
line-length = 200

[tool.ruff.lint]
extend-select = [
"B", # flake8-bugbear
Expand Down
64 changes: 44 additions & 20 deletions src/pscpy/adios2py/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import itertools
import logging
import os
from collections.abc import Collection
Expand All @@ -13,7 +14,7 @@
from numpy.typing import NDArray
from typing_extensions import TypeGuard

_ad = Adios()
logger = logging.getLogger(__name__)


class Variable:
Expand All @@ -25,10 +26,10 @@ def __init__(self, var: adios2.Variable, engine: adios2.Engine) -> None:
self.name = self._name()
self.shape = self._shape()
self.dtype = self._dtype()
logging.debug("variable __init__ var %s engine %s", var, engine)
logger.debug("variable __init__ var %s engine %s", var, engine)

def close(self) -> None:
logging.debug("adios2py.variable close")
logger.debug("adios2py.variable close")
self._var = None
self._engine = None

Expand All @@ -37,7 +38,9 @@ def _assert_not_closed(self) -> None:
error_message = "adios2py: variable is closed"
raise ValueError(error_message)

def _set_selection(self, start: NDArray[np.integer[Any]], count: NDArray[np.integer[Any]]) -> None:
def _set_selection(
self, start: NDArray[np.integer[Any]], count: NDArray[np.integer[Any]]
) -> None:
self._assert_not_closed()

self._var.set_selection((start[::-1], count[::-1]))
Expand All @@ -57,7 +60,9 @@ def _dtype(self) -> np.dtype[Any]:

return np.dtype(adios2.type_adios_to_numpy(self._var.type())) # type: ignore[no-any-return]

def __getitem__(self, args: SupportsInt | slice | tuple[SupportsInt | slice, ...]) -> NDArray[Any]:
def __getitem__(
self, args: SupportsInt | slice | tuple[SupportsInt | slice, ...]
) -> NDArray[Any]:
self._assert_not_closed()

if not isinstance(args, tuple):
Expand Down Expand Up @@ -99,7 +104,9 @@ def __getitem__(self, args: SupportsInt | slice | tuple[SupportsInt | slice, ...

self._set_selection(sel_start, sel_count)

arr = np.empty(arr_shape, dtype=self.dtype, order="F") # FIXME is column-major correct?
arr = np.empty(
arr_shape, dtype=self.dtype, order="F"
) # FIXME is column-major correct?
self._engine.get(self._var, arr, adios2.bindings.Mode.Sync)
return arr

Expand All @@ -110,11 +117,19 @@ def __repr__(self) -> str:
class FileState:
"""Collects the state of a `File` to reflect the fact that they are coupled."""

_ad = Adios()
_io_count = itertools.count()

def __init__(self, filename: str | os.PathLike[Any]) -> None:
self.io_name = f"io-{filename}"
self.io = _ad.declare_io(self.io_name)
self.io_name = f"io-adios2py-{next(self._io_count)}"
logger.debug("io_name = %s", self.io_name)
self.io = self._ad.declare_io(self.io_name)
self.engine = self.io.open(str(filename), adios2.bindings.Mode.Read)

def close(self) -> None:
self.engine.close()
self._ad.remove_io(self.io_name)

@staticmethod
def is_open(maybe_state: FileState | None) -> TypeGuard[FileState]:
return maybe_state is not None
Expand All @@ -126,43 +141,52 @@ class File:
_state: FileState | None

def __init__(self, filename: str | os.PathLike[Any], mode: str = "r") -> None:
logging.debug("adios2py: __init__ %s", filename)
logger.debug("File.__init__(%s, %s)", filename, mode)
assert mode == "r"
self._state = FileState(filename)
self._open_vars: dict[str, Variable] = {}

self.variable_names: Collection[str] = self._state.io.available_variables().keys()
self.attribute_names: Collection[str] = self._state.io.available_attributes().keys()
self.variable_names: Collection[str] = (
self._state.io.available_variables().keys()
)
self.attribute_names: Collection[str] = (
self._state.io.available_attributes().keys()
)

def __enter__(self) -> File:
logging.debug("adios2py: __enter__")
logger.debug("File.__enter__()")
return self

def __exit__(self, exception_type: type[BaseException] | None, exception: BaseException | None, traceback: TracebackType | None) -> None:
logging.debug("adios2py: __exit__")
def __exit__(
self,
exception_type: type[BaseException] | None,
exception: BaseException | None,
traceback: TracebackType | None,
) -> None:
logger.debug("File.__exit__()")
self.close()

def __del__(self) -> None:
logging.debug("adios2py: __del__")
logger.debug("File.__del__()")
if FileState.is_open(self._state):
self.close()

def close(self) -> None:
assert FileState.is_open(self._state)

logging.debug("adios2py: close")
logging.debug("open vars %s", self._open_vars)
logger.debug("File.close(): open vars %s", self._open_vars)
for var in self._open_vars.values():
var.close()

self._state.engine.close()
_ad.remove_io(self._state.io_name)
self._state.close()
self._state = None

def get_variable(self, variable_name: str) -> Variable:
assert FileState.is_open(self._state)

var = Variable(self._state.io.inquire_variable(variable_name), self._state.engine)
var = Variable(
self._state.io.inquire_variable(variable_name), self._state.engine
)
self._open_vars[variable_name] = var
return var

Expand Down
19 changes: 15 additions & 4 deletions src/pscpy/psc.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from .adios2py import File


def _get_array_attribute(file: File, attribute_name: str, default: ArrayLike | None) -> NDArray[np.floating[Any]]:
def _get_array_attribute(
file: File, attribute_name: str, default: ArrayLike | None
) -> NDArray[np.floating[Any]]:
if attribute_name in file.attribute_names:
return np.asarray(file.get_attribute(attribute_name))
if default is not None:
Expand All @@ -24,7 +26,12 @@
TODO: Should also know about timestep, species, whatever...
"""

def __init__(self, file: File, length: ArrayLike | None = None, corner: ArrayLike | None = None) -> None:
def __init__(
self,
file: File,
length: ArrayLike | None = None,
corner: ArrayLike | None = None,
) -> None:
assert len(file.variable_names) > 0
var = next(iter(file.variable_names))
self.gdims = np.asarray(file.get_variable(var).shape)[0:3]
Expand Down Expand Up @@ -86,7 +93,11 @@
]
for species_idx, species_name in enumerate(species_names):
for moment_idx, moment in enumerate(moments):
field_to_component["all_1st"][f"{moment}_{species_name}"] = moment_idx + 13 * species_idx
field_to_component["all_1st_cc"][f"{moment}_{species_name}"] = moment_idx + 13 * species_idx
field_to_component["all_1st"][f"{moment}_{species_name}"] = (

Check warning on line 96 in src/pscpy/psc.py

View check run for this annotation

Codecov / codecov/patch

src/pscpy/psc.py#L96

Added line #L96 was not covered by tests
moment_idx + 13 * species_idx
)
field_to_component["all_1st_cc"][f"{moment}_{species_name}"] = (

Check warning on line 99 in src/pscpy/psc.py

View check run for this annotation

Codecov / codecov/patch

src/pscpy/psc.py#L99

Added line #L99 was not covered by tests
moment_idx + 13 * species_idx
)

return field_to_component
Loading
Loading