diff --git a/.github/workflows/main_unit_tests.yml b/.github/workflows/main_unit_tests.yml index b8a1289b9..cf8ace3d5 100644 --- a/.github/workflows/main_unit_tests.yml +++ b/.github/workflows/main_unit_tests.yml @@ -20,8 +20,8 @@ jobs: sudo apt-get install libopenmpi-dev libboost1.74-dev - name: Install Python packages run: | - python -m pip install --upgrade pip - pip install -r requirements_dev.txt + python -m pip install --upgrade pip setuptools wheel + pip install -r requirements_dev.txt -c constraints.txt - name: Clone datafiles run: | mkdir -p tests/main/input && cd tests/main/input diff --git a/.gitmodules b/.gitmodules index 60de021df..3420aa1b7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,4 @@ -[submodule "external/gt4py"] - path = external/gt4py - url = https://github.com/gridtools/gt4py.git -[submodule "external/dace"] - path = external/dace - url = https://github.com/spcl/dace.git + +[submodule "NDSL"] + path = NDSL + url = git@github.com:NOAA-GFDL/NDSL.git diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 585b145db..823a57205 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -26,18 +26,6 @@ repos: fv3core/pace/fv3core/stencils/fv_subgridz.py | fv3core/tests/conftest.py )$ - - id: mypy - name: mypy-util - args: [--config-file, setup.cfg] - files: ^util - - id: mypy - name: mypy-stencils - args: [--config-file, setup.cfg] - files: stencils - exclude: | - (?x)^( - stencils/pace/stencils/testing/grid.py | - )$ - id: mypy name: mypy-driver args: [--config-file, setup.cfg] @@ -51,12 +39,12 @@ repos: args: [--config-file, setup.cfg] files: physics - id: mypy - name: mypy-dsl + name: mypy-ndsl args: [--config-file, setup.cfg] - files: dsl + files: ndsl exclude: | (?x)^( - dsl/pace/dsl/gt4py_utils.py | + ndsl/ndsl/gt4py_utils.py | )$ - repo: https://github.com/pre-commit/pre-commit-hooks rev: v2.3.0 diff --git a/NDSL b/NDSL new file mode 160000 index 000000000..44d985452 --- /dev/null +++ b/NDSL @@ -0,0 +1 @@ +Subproject commit 44d985452ef45e12ce7764aa4b8b90679af744d4 diff --git a/constraints.txt b/constraints.txt index 02b6b94f5..e9a99ab68 100644 --- a/constraints.txt +++ b/constraints.txt @@ -2,7 +2,7 @@ # This file is autogenerated by pip-compile with Python 3.8 # by the following command: # -# pip-compile --output-file=constraints.txt driver/setup.py dsl/setup.py fv3core/setup.py physics/setup.py requirements_dev.txt requirements_docs.txt requirements_lint.txt stencils/setup.py util/requirements.txt util/setup.py +# pip-compile --output-file=constraints.txt requirements_dev.txt requirements_docs.txt requirements_lint.txt # aenum==3.1.11 # via dace @@ -11,9 +11,7 @@ aiohttp==3.7.4.post0 alabaster==0.7.12 # via sphinx appdirs==1.4.4 - # via - # -r util/requirements.txt - # fv3config + # via fv3config asciitree==0.3.3 # via zarr asttokens==2.0.5 @@ -42,16 +40,14 @@ black==22.3.0 # via gt4py boltons==21.0.0 # via gt4py -bump2version==1.0.1 - # via -r util/requirements.txt cached-property==1.5.2 # via gt4py cachetools==4.2.2 # via google-auth certifi==2021.5.30 - # via requests -cffi==1.14.6 - # via google-crc32c + # via + # netcdf4 + # requests cfgv==3.3.1 # via pre-commit cftime==1.5.0 @@ -59,7 +55,6 @@ cftime==1.5.0 # -r requirements_dev.txt # netcdf4 # pace-util - # pace-util (util/setup.py) chardet==4.0.0 # via aiohttp charset-normalizer==2.0.4 @@ -76,26 +71,17 @@ cmake==3.26.4 commonmark==0.9.1 # via recommonmark coverage==5.5 - # via - # -r util/requirements.txt - # pytest-cov + # via pytest-cov cytoolz==0.12.1 # via gt4py dace==0.15 - # via - # -r requirements_dev.txt - # pace-dsl - # pace-dsl (dsl/setup.py) - # pace-util + # via ndsl dacite==1.6.0 # via # fv3config # pace-driver - # pace-driver (driver/setup.py) dask==2021.12.0 - # via - # -r requirements_dev.txt - # -r util/requirements.txt + # via -r requirements_dev.txt debugpy==1.6.3 # via ipykernel decorator==5.0.9 @@ -124,26 +110,20 @@ executing==0.8.2 f90nml==1.3.1 # via # -r requirements_dev.txt - # -r util/requirements.txt # fv3config # pace-fv3core - # pace-fv3core (fv3core/setup.py) # pace-physics - # pace-physics (physics/setup.py) # pace-util - # pace-util (util/setup.py) fasteners==0.16.3 # via zarr fastjsonschema==2.16.2 # via nbformat filelock==3.0.12 - # via - # tox - # virtualenv -flake8==3.8.4 - # via -r util/requirements.txt + # via virtualenv flask==2.1.2 # via dace +fparser==0.1.4 + # via dace frozendict==2.3.4 # via gt4py fsspec==2021.7.0 @@ -152,46 +132,22 @@ fsspec==2021.7.0 # fv3config # gcsfs # pace-util - # pace-util (util/setup.py) fv3config==0.9.0 # via -r requirements_dev.txt gcsfs==2021.7.0 - # via - # -r util/requirements.txt - # fv3config -google-api-core==2.0.0 - # via - # google-cloud-core - # google-cloud-storage + # via fv3config google-auth==2.0.1 # via # gcsfs - # google-api-core # google-auth-oauthlib - # google-cloud-core - # google-cloud-storage google-auth-oauthlib==0.4.5 # via gcsfs -google-cloud-core==2.0.0 - # via google-cloud-storage -google-cloud-storage==1.42.0 - # via -r util/requirements.txt -google-crc32c==1.1.2 - # via google-resumable-media -google-resumable-media==2.0.0 - # via google-cloud-storage -googleapis-common-protos==1.53.0 - # via google-api-core gprof2dot==2021.2.21 # via pytest-profiling gridtools-cpp==2.3.1 # via gt4py -h5netcdf==0.11.0 - # via -r util/requirements.txt -h5py==3.9.0 - # via - # -r util/requirements.txt - # h5netcdf +gt4py==1.0.1 + # via ndsl identify==2.2.13 # via pre-commit idna==3.2 @@ -245,25 +201,20 @@ matplotlib-inline==0.1.6 # via # ipykernel # ipython -mccabe==0.6.1 - # via flake8 mpi4py==3.1.4 # via # -r requirements_dev.txt # pace-driver - # pace-driver (driver/setup.py) mpmath==1.2.1 # via sympy multidict==5.1.0 # via # aiohttp # yarl -mypy==0.790 - # via -r util/requirements.txt mypy-extensions==0.4.3 - # via - # black - # mypy + # via black +nanobind==1.8.0 + # via gt4py nbclient==0.6.8 # via nbmake nbformat==5.7.0 @@ -281,7 +232,6 @@ netcdf4==1.6.4 # via # -r requirements_dev.txt # pace-driver - # pace-driver (driver/setup.py) networkx==2.6.3 # via dace ninja==1.11.1 @@ -289,42 +239,37 @@ ninja==1.11.1 nodeenv==1.6.0 # via pre-commit numcodecs==0.7.2 - # via - # -r util/requirements.txt - # zarr + # via zarr numpy==1.21.2 # via # -r requirements_dev.txt - # -r util/requirements.txt # cftime # dace # gt4py - # h5py # netcdf4 # numcodecs # pace-driver - # pace-driver (driver/setup.py) # pace-fv3core - # pace-fv3core (fv3core/setup.py) # pace-physics - # pace-physics (physics/setup.py) # pace-util - # pace-util (util/setup.py) # pandas + # scipy # xarray # zarr oauthlib==3.1.1 # via requests-oauthlib ordered-set==4.1.0 # via deepdiff +pace-util==0.9.0 + # via ndsl packaging==21.0 # via # dask # gt4py # ipykernel # pytest + # setuptools-scm # sphinx - # tox pandas==1.3.2 # via xarray parso==0.8.3 @@ -344,19 +289,13 @@ platformdirs==2.2.0 # black # virtualenv pluggy==0.13.1 - # via - # pytest - # tox + # via pytest ply==3.11 # via dace pre-commit==2.14.0 # via -r requirements_lint.txt prompt-toolkit==3.0.31 # via ipython -protobuf==3.17.3 - # via - # google-api-core - # googleapis-common-protos psutil==5.9.3 # via ipykernel ptyprocess==0.7.0 @@ -364,9 +303,7 @@ ptyprocess==0.7.0 pure-eval==0.2.2 # via stack-data py==1.10.0 - # via - # pytest - # tox + # via pytest pyasn1==0.4.8 # via # pyasn1-modules @@ -375,14 +312,8 @@ pyasn1-modules==0.2.8 # via google-auth pybind11==2.8.1 # via gt4py -pycodestyle==2.6.0 - # via flake8 -pycparser==2.20 - # via cffi pydantic==1.7.4 # via nbmake -pyflakes==2.2.0 - # via flake8 pygments==2.10.0 # via # ipython @@ -402,9 +333,7 @@ pytest==6.2.4 # pytest-regressions # pytest-subtests pytest-cov==2.12.1 - # via - # -r requirements_dev.txt - # -r util/requirements.txt + # via -r requirements_dev.txt pytest-datadir==1.3.1 # via pytest-regressions pytest-profiling==1.7.0 @@ -412,9 +341,7 @@ pytest-profiling==1.7.0 pytest-regressions==2.2.0 # via -r requirements_dev.txt pytest-subtests==0.5.0 - # via - # -r requirements_dev.txt - # -r util/requirements.txt + # via -r requirements_dev.txt python-dateutil==2.8.2 # via # jupyter-client @@ -429,7 +356,6 @@ pyyaml==5.4.1 # dask # fv3config # pace-driver - # pace-driver (driver/setup.py) # pre-commit # pytest-regressions pyzmq==24.0.1 @@ -442,24 +368,23 @@ requests==2.26.0 # via # dace # gcsfs - # google-api-core - # google-cloud-storage # requests-oauthlib # sphinx requests-oauthlib==1.3.0 # via google-auth-oauthlib rsa==4.7.2 # via google-auth +scipy==1.10.1 + # via -r requirements_dev.txt +setuptools-scm==8.0.4 + # via fparser six==1.16.0 # via # asttokens # astunparse # fasteners - # h5py - # protobuf # pytest-profiling # python-dateutil - # tox # virtualenv snowballstemmer==2.1.0 # via sphinx @@ -475,9 +400,7 @@ sphinx-argparse==0.3.1 sphinx-gallery==0.10.1 # via -r requirements_docs.txt sphinx-rtd-theme==0.5.2 - # via - # -r requirements_docs.txt - # -r util/requirements.txt + # via -r requirements_docs.txt sphinxcontrib-applehelp==1.0.2 # via sphinx sphinxcontrib-devhelp==1.0.2 @@ -501,12 +424,12 @@ toml==0.10.2 # pre-commit # pytest # pytest-cov - # tox tomli==1.2.1 - # via black + # via + # black + # setuptools-scm toolz==0.11.1 # via - # -r util/requirements.txt # cytoolz # dask # partd @@ -514,8 +437,6 @@ tornado==6.2 # via # ipykernel # jupyter-client -tox==3.24.3 - # via -r util/requirements.txt traitlets==5.5.0 # via # ipykernel @@ -525,22 +446,17 @@ traitlets==5.5.0 # matplotlib-inline # nbclient # nbformat -typed-ast==1.4.3 - # via mypy typing-extensions==4.3.0 # via # aiohttp # black # gt4py - # mypy # pace-util - # pace-util (util/setup.py) + # setuptools-scm urllib3==1.26.6 # via requests virtualenv==20.7.2 - # via - # pre-commit - # tox + # via pre-commit wcwidth==0.2.5 # via prompt-toolkit websockets==10.3 @@ -548,18 +464,13 @@ websockets==10.3 werkzeug==2.1.2 # via flask wheel==0.37.0 - # via - # -r util/requirements.txt - # astunparse + # via astunparse xarray==0.19.0 # via # -r requirements_dev.txt # pace-driver - # pace-driver (driver/setup.py) # pace-fv3core - # pace-fv3core (fv3core/setup.py) # pace-physics - # pace-physics (physics/setup.py) xxhash==2.0.2 # via gt4py yarl==1.6.3 @@ -568,7 +479,6 @@ zarr==2.9.2 # via # -r requirements_dev.txt # pace-driver - # pace-driver (driver/setup.py) zipp==3.8.0 # via # importlib-metadata diff --git a/driver/examples/stencil_signatures.py b/driver/examples/stencil_signatures.py index 75144abed..90712b94f 100644 --- a/driver/examples/stencil_signatures.py +++ b/driver/examples/stencil_signatures.py @@ -2,17 +2,17 @@ import inspect from typing import Optional, TextIO +import ndsl.dsl +import ndsl.util import yaml import pace.driver -import pace.dsl -import pace.util def has_stencils(object): for name in dir(object): try: - stencil_found = isinstance(getattr(object, name), pace.dsl.FrozenStencil) + stencil_found = isinstance(getattr(object, name), ndsl.dsl.FrozenStencil) except (AttributeError, RuntimeError): stencil_found = False if stencil_found: @@ -26,7 +26,7 @@ def report_stencils(obj, file: Optional[TextIO]): print(f"module {module.__name__}, class {obj.__class__.__name__}:", file=file) all_access_names = collections.defaultdict(list) for name, value in obj.__dict__.items(): - if isinstance(value, pace.dsl.FrozenStencil): + if isinstance(value, ndsl.dsl.FrozenStencil): print(f" stencil {name}:", file=file) for arg_name, field_info in value.stencil_object.field_info.items(): if field_info is None: diff --git a/driver/pace/driver/__init__.py b/driver/pace/driver/__init__.py index efac65543..df00d3413 100644 --- a/driver/pace/driver/__init__.py +++ b/driver/pace/driver/__init__.py @@ -1,3 +1,5 @@ +from ndsl.performance import PerformanceConfig + from .comm import ( CreatesComm, CreatesCommSelector, @@ -10,7 +12,6 @@ from .driver import Driver, DriverConfig, RestartConfig from .grid import GeneratedGridConfig, SerialboxGridConfig from .initialization import AnalyticInit, PredefinedStateInit, RestartInit -from .performance import PerformanceConfig from .registry import Registry from .state import DriverState, TendencyState diff --git a/driver/pace/driver/comm.py b/driver/pace/driver/comm.py index 36798696a..27b00a5b4 100644 --- a/driver/pace/driver/comm.py +++ b/driver/pace/driver/comm.py @@ -3,13 +3,10 @@ import os from typing import Any, ClassVar, List -import pace.driver -import pace.dsl -import pace.stencils -import pace.util -import pace.util.grid -from pace.util.caching_comm import CachingCommReader, CachingCommWriter -from pace.util.comm import Comm +from ndsl.comm.caching_comm import CachingCommReader, CachingCommWriter +from ndsl.comm.comm_abc import Comm +from ndsl.comm.mpi import MPIComm +from ndsl.comm.null_comm import NullComm from .registry import Registry @@ -86,7 +83,7 @@ class MPICommConfig(CreatesComm): """ def get_comm(self): - return pace.util.MPIComm() + return MPIComm() def cleanup(self, comm): pass @@ -113,7 +110,7 @@ class NullCommConfig(CreatesComm): fill_value: float = 0.0 def get_comm(self): - return pace.util.NullComm( + return NullComm( rank=self.rank, total_ranks=self.total_ranks, fill_value=self.fill_value ) @@ -144,7 +141,7 @@ class WriterCommConfig(CreatesComm): def get_comm(self) -> CachingCommWriter: underlying = MPICommConfig().get_comm() if underlying.Get_rank() in self.ranks: - return pace.util.CachingCommWriter(underlying) + return CachingCommWriter(underlying) else: return underlying @@ -181,7 +178,7 @@ class ReaderCommConfig(CreatesComm): def get_comm(self) -> CachingCommReader: with open(os.path.join(self.path, f"comm_{self.rank}.pkl"), "rb") as f: - return pace.util.CachingCommReader.load(f) + return CachingCommReader.load(f) def cleanup(self, comm: CachingCommWriter): pass diff --git a/driver/pace/driver/configs/comm.py b/driver/pace/driver/configs/comm.py index 5f2c8c1b4..502f19bec 100644 --- a/driver/pace/driver/configs/comm.py +++ b/driver/pace/driver/configs/comm.py @@ -4,13 +4,9 @@ from typing import Any, ClassVar, List import dacite - -import pace.driver -import pace.dsl -import pace.stencils -import pace.util -import pace.util.grid -from pace.util.caching_comm import CachingCommReader, CachingCommWriter +from ndsl.comm.caching_comm import CachingCommReader, CachingCommWriter +from ndsl.comm.mpi import MPIComm +from ndsl.comm.null_comm import NullComm class CreatesComm(abc.ABC): @@ -85,7 +81,7 @@ class MPICommConfig(CreatesComm): """ def get_comm(self): - return pace.util.MPIComm() + return MPIComm() def cleanup(self, comm): pass @@ -112,7 +108,7 @@ class NullCommConfig(CreatesComm): fill_value: float def get_comm(self): - return pace.util.NullComm( + return NullComm( rank=self.rank, total_ranks=self.total_ranks, fill_value=self.fill_value ) @@ -143,7 +139,7 @@ class WriterCommConfig(CreatesComm): def get_comm(self) -> CachingCommWriter: underlying = MPICommConfig().get_comm() if underlying.Get_rank() in self.ranks: - return pace.util.CachingCommWriter(underlying) + return CachingCommWriter(underlying) else: return underlying @@ -180,7 +176,7 @@ class ReaderCommConfig(CreatesComm): def get_comm(self) -> CachingCommReader: with open(os.path.join(self.path, f"comm_{self.rank}.pkl"), "rb") as f: - return pace.util.CachingCommReader.load(f) + return CachingCommReader.load(f) def cleanup(self, comm: CachingCommWriter): pass diff --git a/driver/pace/driver/diagnostics.py b/driver/pace/driver/diagnostics.py index 36f5960a1..6843a6e7d 100644 --- a/driver/pace/driver/diagnostics.py +++ b/driver/pace/driver/diagnostics.py @@ -4,14 +4,15 @@ from datetime import datetime, timedelta from typing import List, Optional, Union -import pace.driver -import pace.dsl -import pace.stencils -import pace.util -import pace.util.grid -from pace.dsl.dace.orchestration import dace_inhibitor +from ndsl.comm.communicator import Communicator +from ndsl.constants import RGRAV, Z_DIM, Z_INTERFACE_DIM +from ndsl.dsl.dace.orchestration import dace_inhibitor +from ndsl.filesystem import get_fs +from ndsl.grid import GridData +from ndsl.monitor import Monitor, NetCDFMonitor, ZarrMonitor +from ndsl.quantity import Quantity + from pace.fv3core.dycore_state import DycoreState -from pace.util.constants import RGRAV from .state import DriverState @@ -28,7 +29,7 @@ def store(self, time: Union[datetime, timedelta], state: DriverState): ... @abc.abstractmethod - def store_grid(self, grid_data: pace.util.grid.GridData): + def store_grid(self, grid_data: GridData): ... @abc.abstractmethod @@ -47,15 +48,13 @@ def select_data(self, state: DycoreState): if name not in state.__dict__.keys(): raise ValueError(f"Invalid state variable {name} for level select") assert len(getattr(state, name).dims) > 2 - if getattr(state, name).dims[2] != ( - pace.util.Z_DIM or pace.util.Z_INTERFACE_DIM - ): + if getattr(state, name).dims[2] != (Z_DIM or Z_INTERFACE_DIM): raise ValueError( f"z_select only works for state variables with dimension (x, y, z). \ \n {name} has dimension {getattr(state, name).dims}" ) var_name = f"{name}_z{self.level}" - output[var_name] = pace.util.Quantity( + output[var_name] = Quantity( getattr(state, name).data[:, :, self.level], dims=getattr(state, name).dims[0:2], origin=getattr(state, name).origin[0:2], @@ -100,7 +99,7 @@ def __post_init__(self): f"got {self.output_format}" ) - def diagnostics_factory(self, communicator: pace.util.Communicator) -> Diagnostics: + def diagnostics_factory(self, communicator: Communicator) -> Diagnostics: """ Create a diagnostics object. @@ -111,18 +110,18 @@ def diagnostics_factory(self, communicator: pace.util.Communicator) -> Diagnosti if self.path is None: diagnostics: Diagnostics = NullDiagnostics() else: - fs = pace.util.get_fs(self.path) + fs = get_fs(self.path) if not fs.exists(self.path): fs.makedirs(self.path, exist_ok=True) if self.output_format == "zarr": store = zarr_storage.DirectoryStore(path=self.path) - monitor: pace.util.Monitor = pace.util.ZarrMonitor( + monitor: Monitor = ZarrMonitor( store=store, partitioner=communicator.partitioner, mpi_comm=communicator.comm, ) elif self.output_format == "netcdf": - monitor = pace.util.NetCDFMonitor( + monitor = NetCDFMonitor( path=self.path, communicator=communicator, time_chunk_size=self.time_chunk_size, @@ -146,7 +145,7 @@ class MonitorDiagnostics(Diagnostics): def __init__( self, - monitor: pace.util.Monitor, + monitor: Monitor, names: List[str], derived_names: List[str], z_select: List[ZSelect], @@ -198,7 +197,7 @@ def _get_z_select_state(self, state: DycoreState): z_select_state.update(zselect.select_data(state)) return z_select_state - def store_grid(self, grid_data: pace.util.grid.GridData): + def store_grid(self, grid_data: GridData): zarr_grid = { "lat": grid_data.lat, "lon": grid_data.lon, @@ -218,16 +217,14 @@ class NullDiagnostics(Diagnostics): def store(self, time: Union[datetime, timedelta], state: DriverState): pass - def store_grid(self, grid_data: pace.util.grid.GridData): + def store_grid(self, grid_data: GridData): pass def cleanup(self): pass -def _compute_column_integral( - name: str, q_in: pace.util.Quantity, delp: pace.util.Quantity -): +def _compute_column_integral(name: str, q_in: Quantity, delp: Quantity): """ Compute column integrated mixing ratio (e.g., total liquid water path) @@ -237,12 +234,12 @@ def _compute_column_integral( delp: pressure thickness of atmospheric layer """ assert len(q_in.dims) > 2 - if q_in.dims[2] != pace.util.Z_DIM: + if q_in.dims[2] != Z_DIM: raise NotImplementedError( "this function assumes the z-dimension is the third dimension" ) k_slice = slice(q_in.origin[2], q_in.origin[2] + q_in.extent[2]) - column_integral = pace.util.Quantity( + column_integral = Quantity( RGRAV * q_in.np.sum(q_in.data[:, :, k_slice] * delp.data[:, :, k_slice], axis=2), dims=tuple(q_in.dims[:2]) + tuple(q_in.dims[3:]), diff --git a/driver/pace/driver/driver.py b/driver/pace/driver/driver.py index 24197621a..bd350a4de 100644 --- a/driver/pace/driver/driver.py +++ b/driver/pace/driver/driver.py @@ -8,35 +8,39 @@ import dace import dacite import yaml +from ndsl.comm.comm_abc import Comm +from ndsl.comm.communicator import ( + Communicator, + CubedSphereCommunicator, + TileCommunicator, +) +from ndsl.comm.partitioner import TilePartitioner +from ndsl.constants import N_HALO_DEFAULT +from ndsl.dsl.dace.dace_config import DaceConfig +from ndsl.dsl.dace.orchestration import dace_inhibitor, orchestrate +from ndsl.dsl.stencil import GridIndexing, StencilFactory +from ndsl.dsl.stencil_config import CompilationConfig, RunMode, StencilConfig +from ndsl.dsl.typing import Float +from ndsl.grid import DampingCoefficients, DriverGridData, GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from ndsl.logging import ndsl_log +from ndsl.performance import PerformanceConfig +from ndsl.performance.collector import PerformanceCollector +from ndsl.performance.timer import Timer import pace.driver -import pace.dsl import pace.physics -import pace.stencils -import pace.util -import pace.util.grid from pace import fv3core from pace.driver.safety_checks import SafetyChecker -from pace.dsl.dace.dace_config import DaceConfig -from pace.dsl.dace.orchestration import dace_inhibitor, orchestrate -from pace.dsl.stencil_config import CompilationConfig, RunMode -from pace.dsl.typing import Float # TODO: move update_atmos_state into pace.driver -from pace.stencils import update_atmos_state -from pace.util.communicator import ( - Communicator, - CubedSphereCommunicator, - TileCommunicator, -) -from pace.util.logging import pace_log +from pace.physics.update import update_atmos_state from . import diagnostics from .comm import CreatesCommSelector from .grid import GeneratedGridConfig, GridInitializerSelector from .initialization import InitializerSelector -from .performance import PerformanceConfig -from .performance.collector import PerformanceCollector from .state import DriverState @@ -88,7 +92,7 @@ class DriverConfig: defaults to every timestep """ - stencil_config: pace.dsl.StencilConfig + stencil_config: StencilConfig initialization: InitializerSelector nx_tile: int nz: int @@ -163,25 +167,21 @@ def apply_tendencies(self) -> bool: def get_grid( self, - communicator: pace.util.Communicator, - quantity_factory: Optional[pace.util.QuantityFactory] = None, - ) -> Tuple[ - pace.util.grid.DampingCoefficients, - pace.util.grid.DriverGridData, - pace.util.grid.GridData, - ]: + communicator: Communicator, + quantity_factory: Optional[QuantityFactory] = None, + ) -> Tuple[DampingCoefficients, DriverGridData, GridData]: if quantity_factory is None: - sizer = pace.util.SubtileGridSizer.from_tile_params( + sizer = SubtileGridSizer.from_tile_params( nx_tile=self.nx_tile, ny_tile=self.nx_tile, nz=self.nz, - n_halo=pace.util.N_HALO_DEFAULT, + n_halo=N_HALO_DEFAULT, extra_dim_lengths={}, layout=self.layout, tile_partitioner=communicator.partitioner.tile, tile_rank=communicator.tile.rank, ) - quantity_factory = pace.util.QuantityFactory.from_backend( + quantity_factory = QuantityFactory.from_backend( sizer, backend=self.stencil_config.compilation_config.backend ) @@ -192,36 +192,34 @@ def get_grid( def get_driver_state( self, - communicator: pace.util.Communicator, - damping_coefficients: pace.util.grid.DampingCoefficients, - driver_grid_data: pace.util.grid.DriverGridData, - grid_data: pace.util.grid.GridData, - quantity_factory: Optional[pace.util.QuantityFactory] = None, - stencil_factory: Optional[pace.dsl.StencilFactory] = None, + communicator: Communicator, + damping_coefficients: DampingCoefficients, + driver_grid_data: DriverGridData, + grid_data: GridData, + quantity_factory: Optional[QuantityFactory] = None, + stencil_factory: Optional[StencilFactory] = None, ) -> DriverState: """Load the initial state of the driver.""" if quantity_factory is None or stencil_factory is None: - sizer = pace.util.SubtileGridSizer.from_tile_params( + sizer = SubtileGridSizer.from_tile_params( nx_tile=self.nx_tile, ny_tile=self.nx_tile, nz=self.nz, - n_halo=pace.util.N_HALO_DEFAULT, + n_halo=N_HALO_DEFAULT, extra_dim_lengths={}, layout=self.layout, tile_partitioner=communicator.partitioner.tile, tile_rank=communicator.tile.rank, ) if quantity_factory is None: - quantity_factory = pace.util.QuantityFactory.from_backend( + quantity_factory = QuantityFactory.from_backend( sizer, backend=self.stencil_config.compilation_config.backend ) if stencil_factory is None: - grid_indexing = ( - pace.dsl.stencil.GridIndexing.from_sizer_and_communicator( - sizer=sizer, comm=communicator - ) + grid_indexing = GridIndexing.from_sizer_and_communicator( + sizer=sizer, comm=communicator ) - stencil_factory = pace.dsl.StencilFactory( + stencil_factory = StencilFactory( config=self.stencil_config, grid_indexing=grid_indexing ) @@ -352,7 +350,7 @@ def write_final_if_enabled( self, state: DriverState, *, - comm: pace.util.Comm, + comm: Comm, time: datetime, driver_config: DriverConfig, restart_path: str, @@ -370,7 +368,7 @@ def write_intermediate_if_enabled( state: DriverState, *, step: int, - comm: pace.util.Comm, + comm: Comm, time: Union[datetime, timedelta], driver_config: DriverConfig, restart_path: str, @@ -396,7 +394,7 @@ def __init__( config: driver configuration comm: communication object behaving like mpi4py.Comm """ - pace_log.info("initializing driver") + ndsl_log.info("initializing driver") self.config: DriverConfig = config self.time = self.config.start_time self.comm_config = config.comm_config @@ -474,13 +472,13 @@ def exit_instead_of_build(self): communicator=communicator, stencil_compare_comm=stencil_compare_comm, ) - pace_log.info("setting up grid started") + ndsl_log.info("setting up grid started") (damping_coefficients, driver_grid_data, grid_data,) = self.config.get_grid( quantity_factory=self.quantity_factory, communicator=communicator, ) - pace_log.info("setting up grid done") - pace_log.info("setting up state started") + ndsl_log.info("setting up grid done") + ndsl_log.info("setting up state started") self.state = self.config.get_driver_state( quantity_factory=self.quantity_factory, communicator=communicator, @@ -488,10 +486,10 @@ def exit_instead_of_build(self): driver_grid_data=driver_grid_data, grid_data=grid_data, ) - pace_log.info("setting up state done") + ndsl_log.info("setting up state done") self._start_time = self.config.initialization.start_time - pace_log.info("setting up dycore object started") + ndsl_log.info("setting up dycore object started") self.dycore = fv3core.DynamicalCore( comm=communicator, grid_data=self.state.grid_data, @@ -503,9 +501,9 @@ def exit_instead_of_build(self): phis=self.state.dycore_state.phis, state=self.state.dycore_state, ) - pace_log.info("setting up dycore object done") + ndsl_log.info("setting up dycore object done") - pace_log.info("setting up physics object started") + ndsl_log.info("setting up physics object started") if not config.dycore_only and not config.disable_step_physics: self.physics = pace.physics.Physics( stencil_factory=self.stencil_factory, @@ -540,12 +538,12 @@ def exit_instead_of_build(self): # Make sure those are set to None to raise any issues self.dycore_to_physics = None self.end_of_step_update = None - pace_log.info("setting up physics object done") - pace_log.info("setting up diagnostics factory started") + ndsl_log.info("setting up physics object done") + ndsl_log.info("setting up diagnostics factory started") self.diagnostics = config.diagnostics_config.diagnostics_factory( communicator=communicator ) - pace_log.info("setting up diagnostics factory done") + ndsl_log.info("setting up diagnostics factory done") log_subtile_location( partitioner=communicator.partitioner.tile, rank=communicator.rank ) @@ -553,14 +551,14 @@ def exit_instead_of_build(self): self.diagnostics.store(time=self.time, state=self.state) self._time_run = self.config.start_time - pace_log.info("setting up safety checkers started") + ndsl_log.info("setting up safety checkers started") self.safety_checker = SafetyChecker() SafetyChecker.register_variable("ua", -200, 200, compute_domain_only=True) SafetyChecker.register_variable("va", -200, 200, compute_domain_only=True) SafetyChecker.register_variable("delp", -1.0, 4000, compute_domain_only=True) SafetyChecker.register_variable("pt", 100, 380, compute_domain_only=True) - pace_log.info("setting up safety checkers done") - pace_log.info("initialization of the object done") + ndsl_log.info("setting up safety checkers done") + ndsl_log.info("initialization of the object done") def _update_driver_config_with_communicator( self, communicator: Communicator @@ -597,11 +595,11 @@ def _end_of_step_actions(self, step: int): Using a method allows those actions to be removed from the orchestration path. """ if __debug__: - pace_log.info(f"Finished stepping {step}") + ndsl_log.info(f"Finished stepping {step}") self.performance_collector.collect_performance() self.time += self.config.timestep if ((step + 1) % self.config.output_frequency) == 0: - pace_log.info(f"diagnostics for step {self.time} started") + ndsl_log.info(f"diagnostics for step {self.time} started") self.performance_collector.write_out_rank_0( self.config.stencil_config.compilation_config.backend, self.config.stencil_config.dace_config.is_dace_orchestrated(), @@ -609,13 +607,13 @@ def _end_of_step_actions(self, step: int): "Ongoing", ) self.diagnostics.store(time=self.time, state=self.state) - pace_log.info(f"diagnostics for step {self.time} finished") + ndsl_log.info(f"diagnostics for step {self.time} finished") if ( self.config.safety_check_frequency and ((step + 1) % self.config.safety_check_frequency) == 0 ): self.safety_checker.check_state(self.state.dycore_state) - pace_log.info(f"checking state for for step {step+1} finished") + ndsl_log.info(f"checking state for for step {step+1} finished") self.config.restart_config.write_intermediate_if_enabled( state=self.state, step=step, @@ -628,7 +626,7 @@ def _end_of_step_actions(self, step: int): def _critical_path_step_all( self, steps_count: int, - timer: pace.util.Timer, + timer: Timer, dt: Float, ): """Start of code path where performance is critical. @@ -663,7 +661,7 @@ def _critical_path_step_all( self._end_of_step_actions(step) def step_all(self): - pace_log.info("integrating driver forward in time") + ndsl_log.info("integrating driver forward in time") with self.performance_collector.total_timer.clock("total"): self.profiler.enable() PerformanceCollector.mark_cuda_profiler("Begin integration") @@ -688,7 +686,7 @@ def _write_performance_json_output(self): @dace_inhibitor def cleanup(self): - pace_log.info("cleaning up driver") + ndsl_log.info("cleaning up driver") self.performance_collector.write_out_rank_0( self.config.stencil_config.compilation_config.backend, self.config.stencil_config.dace_config.is_dace_orchestrated(), @@ -714,21 +712,21 @@ def cleanup(self): self.comm_config.cleanup(self.comm) -def log_subtile_location(partitioner: pace.util.TilePartitioner, rank: int): +def log_subtile_location(partitioner: TilePartitioner, rank: int): location_info = { "north": partitioner.on_tile_top(rank), "south": partitioner.on_tile_bottom(rank), "east": partitioner.on_tile_right(rank), "west": partitioner.on_tile_left(rank), } - pace_log.info(f"running on rank {rank} with subtile location {location_info}") + ndsl_log.info(f"running on rank {rank} with subtile location {location_info}") def _setup_factories( config: DriverConfig, - communicator: pace.util.Communicator, + communicator: Communicator, stencil_compare_comm, -) -> Tuple[pace.util.QuantityFactory, pace.dsl.StencilFactory]: +) -> Tuple[QuantityFactory, StencilFactory]: """ Args: config: configuration of driver @@ -742,24 +740,24 @@ def _setup_factories( stencil_factory: creates Stencils """ - sizer = pace.util.SubtileGridSizer.from_tile_params( + sizer = SubtileGridSizer.from_tile_params( nx_tile=config.nx_tile, ny_tile=config.nx_tile, nz=config.nz, - n_halo=pace.util.N_HALO_DEFAULT, + n_halo=N_HALO_DEFAULT, extra_dim_lengths={}, layout=config.layout, tile_partitioner=communicator.partitioner.tile, tile_rank=communicator.tile.rank, ) - grid_indexing = pace.dsl.stencil.GridIndexing.from_sizer_and_communicator( + grid_indexing = GridIndexing.from_sizer_and_communicator( sizer=sizer, comm=communicator ) - quantity_factory = pace.util.QuantityFactory.from_backend( + quantity_factory = QuantityFactory.from_backend( sizer, backend=config.stencil_config.compilation_config.backend ) - stencil_factory = pace.dsl.StencilFactory( + stencil_factory = StencilFactory( config=config.stencil_config, grid_indexing=grid_indexing, comm=stencil_compare_comm, diff --git a/driver/pace/driver/grid.py b/driver/pace/driver/grid.py index e1c3b0579..a93e38206 100644 --- a/driver/pace/driver/grid.py +++ b/driver/pace/driver/grid.py @@ -4,30 +4,26 @@ import f90nml import xarray as xr - -import pace.driver -import pace.dsl -import pace.physics -import pace.stencils -import pace.util -import pace.util.grid -from pace.stencils.testing import TranslateGrid -from pace.util import Communicator, QuantityFactory -from pace.util.grid import ( +from ndsl.comm.communicator import Communicator +from ndsl.comm.partitioner import get_tile_index +from ndsl.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM +from ndsl.grid import ( DampingCoefficients, DriverGridData, GridData, MetricTerms, direct_transform, ) -from pace.util.grid.helper import ( +from ndsl.grid.helper import ( AngleGridData, ContravariantGridData, HorizontalGridData, VerticalGridData, ) -from pace.util.logging import pace_log -from pace.util.namelist import Namelist +from ndsl.initialization.allocator import QuantityFactory +from ndsl.logging import ndsl_log +from ndsl.namelist import Namelist +from ndsl.stencils.testing import TranslateGrid, grid from .registry import Registry @@ -36,8 +32,8 @@ class GridInitializer(abc.ABC): @abc.abstractmethod def get_grid( self, - quantity_factory: pace.util.QuantityFactory, - communicator: pace.util.Communicator, + quantity_factory: QuantityFactory, + communicator: Communicator, ) -> Tuple[DampingCoefficients, DriverGridData, GridData]: ... @@ -162,7 +158,7 @@ def _f90_namelist(self) -> f90nml.Namelist: def _namelist(self) -> Namelist: return Namelist.from_f90nml(self._f90_namelist) - def _serializer(self, communicator: pace.util.Communicator): + def _serializer(self, communicator: Communicator): import serialbox serializer = serialbox.Serializer( @@ -174,9 +170,9 @@ def _serializer(self, communicator: pace.util.Communicator): def _get_serialized_grid( self, - communicator: pace.util.Communicator, + communicator: Communicator, backend: str, - ) -> pace.stencils.testing.grid.Grid: # type: ignore + ) -> grid.Grid: # type: ignore ser = self._serializer(communicator) grid = TranslateGrid.new_from_serialized_data( ser, communicator.rank, self._namelist.layout, backend @@ -189,10 +185,10 @@ def get_grid( communicator: Communicator, ) -> Tuple[DampingCoefficients, DriverGridData, GridData]: backend = quantity_factory.zeros( - dims=[pace.util.X_DIM, pace.util.Y_DIM], units="unknown" + dims=[X_DIM, Y_DIM], units="unknown" ).gt4py_backend - pace_log.info("Using serialized grid data") + ndsl_log.info("Using serialized grid data") grid = self._get_serialized_grid(communicator, backend) grid_data = grid.grid_data driver_grid_data = grid.driver_grid_data @@ -237,15 +233,12 @@ def get_grid( quantity_factory: QuantityFactory, communicator: Communicator, ) -> Tuple[DampingCoefficients, DriverGridData, GridData]: - - pace_log.info("Using external grid data") + ndsl_log.info("Using external grid data") # ToDo: refactor when grid_type is an enum if self.grid_type <= 3: tile_num = ( - pace.util.get_tile_index( - communicator.rank, communicator.partitioner.total_ranks - ) + get_tile_index(communicator.rank, communicator.partitioner.total_ranks) + 1 ) tile_file = self.grid_file_path + str(tile_num) + ".nc" @@ -260,7 +253,7 @@ def get_grid( subtile_slice_grid = communicator.partitioner.tile.subtile_slice( rank=communicator.rank, - global_dims=[pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM], + global_dims=[Y_INTERFACE_DIM, X_INTERFACE_DIM], global_extent=(npy, npx), overlap=True, ) diff --git a/driver/pace/driver/initialization.py b/driver/pace/driver/initialization.py index 04b08d3d7..1e6e9b87e 100644 --- a/driver/pace/driver/initialization.py +++ b/driver/pace/driver/initialization.py @@ -6,21 +6,21 @@ from typing import Callable, ClassVar, List, Type, TypeVar import f90nml +from ndsl.comm.communicator import Communicator +from ndsl.constants import X_DIM, Y_DIM +from ndsl.dsl.dace.orchestration import DaceConfig +from ndsl.dsl.stencil import StencilConfig, StencilFactory +from ndsl.dsl.stencil_config import CompilationConfig +from ndsl.grid import DampingCoefficients, DriverGridData, GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.namelist import Namelist +from ndsl.stencils.testing import TranslateGrid, grid import pace.driver -import pace.dsl import pace.fv3core.initialization.analytic_init as analytic_init import pace.physics -import pace.stencils -import pace.util -import pace.util.grid from pace import fv3core -from pace.dsl.dace.orchestration import DaceConfig -from pace.dsl.stencil import StencilFactory -from pace.dsl.stencil_config import CompilationConfig from pace.fv3core.testing import TranslateFVDynamics -from pace.stencils.testing import TranslateGrid -from pace.util.namelist import Namelist from .registry import Registry from .state import DriverState, TendencyState, _restart_driver_state @@ -35,11 +35,11 @@ def start_time(self) -> datetime: @abc.abstractmethod def get_driver_state( self, - quantity_factory: pace.util.QuantityFactory, - communicator: pace.util.Communicator, - damping_coefficients: pace.util.grid.DampingCoefficients, - driver_grid_data: pace.util.grid.DriverGridData, - grid_data: pace.util.grid.GridData, + quantity_factory: QuantityFactory, + communicator: Communicator, + damping_coefficients: DampingCoefficients, + driver_grid_data: DriverGridData, + grid_data: GridData, schemes: List[pace.physics.PHYSICS_PACKAGES], ) -> DriverState: ... @@ -73,11 +73,11 @@ def start_time(self) -> datetime: def get_driver_state( self, - quantity_factory: pace.util.QuantityFactory, - communicator: pace.util.Communicator, - damping_coefficients: pace.util.grid.DampingCoefficients, - driver_grid_data: pace.util.grid.DriverGridData, - grid_data: pace.util.grid.GridData, + quantity_factory: QuantityFactory, + communicator: Communicator, + damping_coefficients: DampingCoefficients, + driver_grid_data: DriverGridData, + grid_data: GridData, schemes: List[pace.physics.PHYSICS_PACKAGES], ) -> DriverState: return self.config.get_driver_state( @@ -107,11 +107,11 @@ class AnalyticInit(Initializer): def get_driver_state( self, - quantity_factory: pace.util.QuantityFactory, - communicator: pace.util.Communicator, - damping_coefficients: pace.util.grid.DampingCoefficients, - driver_grid_data: pace.util.grid.DriverGridData, - grid_data: pace.util.grid.GridData, + quantity_factory: QuantityFactory, + communicator: Communicator, + damping_coefficients: DampingCoefficients, + driver_grid_data: DriverGridData, + grid_data: GridData, schemes: List[pace.physics.PHYSICS_PACKAGES], ) -> DriverState: dycore_state = analytic_init.init_analytic_state( @@ -151,11 +151,11 @@ class RestartInit(Initializer): def get_driver_state( self, - quantity_factory: pace.util.QuantityFactory, - communicator: pace.util.Communicator, - damping_coefficients: pace.util.grid.DampingCoefficients, - driver_grid_data: pace.util.grid.DriverGridData, - grid_data: pace.util.grid.GridData, + quantity_factory: QuantityFactory, + communicator: Communicator, + damping_coefficients: DampingCoefficients, + driver_grid_data: DriverGridData, + grid_data: GridData, schemes: List[pace.physics.PHYSICS_PACKAGES], ) -> DriverState: state = _restart_driver_state( @@ -202,11 +202,11 @@ def start_time(self) -> datetime: def get_driver_state( self, - quantity_factory: pace.util.QuantityFactory, - communicator: pace.util.Communicator, - damping_coefficients: pace.util.grid.DampingCoefficients, - driver_grid_data: pace.util.grid.DriverGridData, - grid_data: pace.util.grid.GridData, + quantity_factory: QuantityFactory, + communicator: Communicator, + damping_coefficients: DampingCoefficients, + driver_grid_data: DriverGridData, + grid_data: GridData, schemes: List[pace.physics.PHYSICS_PACKAGES], ) -> DriverState: state = _restart_driver_state( @@ -254,16 +254,16 @@ def _namelist(self) -> Namelist: def _get_serialized_grid( self, - communicator: pace.util.Communicator, + communicator: Communicator, backend: str, - ) -> pace.stencils.testing.grid.Grid: # type: ignore + ) -> grid.Grid: # type: ignore ser = self._serializer(communicator) grid = TranslateGrid.new_from_serialized_data( ser, communicator.rank, self._namelist.layout, backend ).python_grid() return grid - def _serializer(self, communicator: pace.util.Communicator): + def _serializer(self, communicator: Communicator): import serialbox serializer = serialbox.Serializer( @@ -275,15 +275,15 @@ def _serializer(self, communicator: pace.util.Communicator): def get_driver_state( self, - quantity_factory: pace.util.QuantityFactory, - communicator: pace.util.Communicator, - damping_coefficients: pace.util.grid.DampingCoefficients, - driver_grid_data: pace.util.grid.DriverGridData, - grid_data: pace.util.grid.GridData, + quantity_factory: QuantityFactory, + communicator: Communicator, + damping_coefficients: DampingCoefficients, + driver_grid_data: DriverGridData, + grid_data: GridData, schemes: List[pace.physics.PHYSICS_PACKAGES], ) -> DriverState: backend = quantity_factory.zeros( - dims=[pace.util.X_DIM, pace.util.Y_DIM], units="unknown" + dims=[X_DIM, Y_DIM], units="unknown" ).gt4py_backend dycore_state = self._initialize_dycore_state(communicator, backend) @@ -304,7 +304,7 @@ def get_driver_state( def _initialize_dycore_state( self, - communicator: pace.util.Communicator, + communicator: Communicator, backend: str, ) -> fv3core.DycoreState: grid = self._get_serialized_grid(communicator=communicator, backend=backend) @@ -317,7 +317,7 @@ def _initialize_dycore_state( tile_nx=self._namelist.npx, tile_nz=self._namelist.npz, ) - stencil_config = pace.dsl.stencil.StencilConfig( + stencil_config = StencilConfig( compilation_config=CompilationConfig( backend=backend, communicator=communicator ), @@ -346,18 +346,18 @@ class PredefinedStateInit(Initializer): dycore_state: fv3core.DycoreState physics_state: pace.physics.PhysicsState tendency_state: TendencyState - grid_data: pace.util.grid.GridData - damping_coefficients: pace.util.grid.DampingCoefficients - driver_grid_data: pace.util.grid.DriverGridData + grid_data: GridData + damping_coefficients: DampingCoefficients + driver_grid_data: DriverGridData start_time: datetime = datetime(2016, 8, 1) def get_driver_state( self, - quantity_factory: pace.util.QuantityFactory, - communicator: pace.util.Communicator, - damping_coefficients: pace.util.grid.DampingCoefficients, - driver_grid_data: pace.util.grid.DriverGridData, - grid_data: pace.util.grid.GridData, + quantity_factory: QuantityFactory, + communicator: Communicator, + damping_coefficients: DampingCoefficients, + driver_grid_data: DriverGridData, + grid_data: GridData, schemes: List[pace.physics.PHYSICS_PACKAGES], ) -> DriverState: return DriverState( diff --git a/driver/pace/driver/performance/__init__.py b/driver/pace/driver/performance/__init__.py deleted file mode 100644 index 61602daf1..000000000 --- a/driver/pace/driver/performance/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .config import PerformanceConfig diff --git a/driver/pace/driver/performance/collector.py b/driver/pace/driver/performance/collector.py deleted file mode 100644 index cbc6c62ae..000000000 --- a/driver/pace/driver/performance/collector.py +++ /dev/null @@ -1,177 +0,0 @@ -import copy -import os.path -import subprocess -from collections.abc import Mapping -from typing import List, Protocol - -import numpy as np - -import pace.util -from pace.driver.performance.report import ( - Report, - TimeReport, - collect_keys_from_data, - gather_hit_counts, - get_experiment_info, - write_to_timestamped_json, -) -from pace.util._optional_imports import cupy as cp -from pace.util.utils import GPU_AVAILABLE - -from .report import collect_data_and_write_to_file - - -class AbstractPerformanceCollector(Protocol): - total_timer: pace.util.Timer - timestep_timer: pace.util.Timer - - def collect_performance(self): - ... - - def write_out_performance( - self, - backend: str, - is_orchestrated: bool, - dt_atmos: float, - ): - ... - - def write_out_rank_0( - self, backend: str, is_orchestrated: bool, dt_atmos: float, sim_status: str - ): - ... - - @classmethod - def start_cuda_profiler(cls): - if GPU_AVAILABLE: - cp.cuda.profiler.start() - - @classmethod - def stop_cuda_profiler(cls): - if GPU_AVAILABLE: - cp.cuda.profiler.stop() - - @classmethod - def mark_cuda_profiler(cls, message: str): - if GPU_AVAILABLE: - cp.cuda.nvtx.Mark(message) - - -class PerformanceCollector(AbstractPerformanceCollector): - def __init__(self, experiment_name: str, comm: pace.util.Comm): - self.times_per_step: List[Mapping[str, float]] = [] - self.hits_per_step: List[Mapping[str, int]] = [] - self.timestep_timer = pace.util.Timer() - self.total_timer = pace.util.Timer() - self.experiment_name = experiment_name - self.comm = comm - - def clear(self): - self.times_per_step = [] - self.hits_per_step = [] - - def collect_performance(self): - """ - Take the accumulated timings and flush them into a new entry - in times_per_step and hits_per_step. - """ - self.times_per_step.append(self.timestep_timer.times) - self.hits_per_step.append(self.timestep_timer.hits) - self.timestep_timer.reset() - - def write_out_rank_0( - self, backend: str, is_orchestrated: bool, dt_atmos: float, sim_status: str - ): - if self.comm.Get_rank() == 0: - git_hash = "None" - while {} in self.hits_per_step: - self.hits_per_step.remove({}) - keys = collect_keys_from_data(self.times_per_step) - data: List[float] = [] - timing_info = {} - for timer_name in keys: - data.clear() - for data_point in self.times_per_step: - if timer_name in data_point: - data.append(data_point[timer_name]) - timing_info[timer_name] = TimeReport( - hits=0, times=copy.deepcopy(np.array(data).tolist()) - ) - exp_info = get_experiment_info( - self.experiment_name, - len(self.hits_per_step) - 1, - backend, - git_hash, - is_orchestrated, - ) - timing_info = gather_hit_counts(self.hits_per_step, timing_info) - report = Report( - setup=exp_info, - times=timing_info, - dt_atmos=dt_atmos, - sim_status=sim_status, - ) - write_to_timestamped_json(report) - else: - pass - - def write_out_performance( - self, - backend: str, - is_orchestrated: bool, - dt_atmos: float, - ): - if self.comm.Get_rank() == 0: - try: - driver_path = os.path.dirname(__file__) - git_hash = ( - subprocess.check_output( - ["git", "-C", driver_path, "rev-parse", "HEAD"] - ) - .decode() - .rstrip() - ) - except subprocess.CalledProcessError: - git_hash = "None" - else: - git_hash = None - git_hash = self.comm.bcast(git_hash, root=0) - - self.times_per_step.append(self.total_timer.times) - self.hits_per_step.append(self.total_timer.hits) - self.comm.Barrier() - while {} in self.hits_per_step: - self.hits_per_step.remove({}) - collect_data_and_write_to_file( - len(self.hits_per_step) - 1, - backend, - is_orchestrated, - git_hash, - self.comm, - self.hits_per_step, - self.times_per_step, - self.experiment_name, - dt_atmos, - ) - - -class NullPerformanceCollector(AbstractPerformanceCollector): - def __init__(self): - self.total_timer = pace.util.NullTimer() - self.timestep_timer = pace.util.NullTimer() - - def collect_performance(self): - pass - - def write_out_performance( - self, - backend: str, - is_orchestrated: bool, - dt_atmos: float, - ): - pass - - def write_out_rank_0( - self, backend: str, is_orchestrated: bool, dt_atmos: float, sim_status: str - ): - pass diff --git a/driver/pace/driver/performance/config.py b/driver/pace/driver/performance/config.py deleted file mode 100644 index 2a2e66db4..000000000 --- a/driver/pace/driver/performance/config.py +++ /dev/null @@ -1,41 +0,0 @@ -import dataclasses - -import pace.util -from pace.util import NullProfiler, Profiler - -from .collector import ( - AbstractPerformanceCollector, - NullPerformanceCollector, - PerformanceCollector, -) - - -@dataclasses.dataclass -class PerformanceConfig: - """Performance stats collector. - - collect_performance: overall flag turning collection on/pff - collect_cProfile: use cProfile for CPU Python profiling - collect_communication: collect halo exchange details - experiment_name: to be printed in the JSON summary - json_all_rank_threshold: number of nodes above the full performance - report for all nodes won't be written (rank 0 is always written) - """ - - collect_performance: bool = False - collect_cProfile: bool = False - collect_communication: bool = False - experiment_name: str = "test" - json_all_rank_threshold: int = 1000 - - def build(self, comm: pace.util.Comm) -> AbstractPerformanceCollector: - if self.collect_performance: - return PerformanceCollector(experiment_name=self.experiment_name, comm=comm) - else: - return NullPerformanceCollector() - - def build_profiler(self): - if self.collect_cProfile: - return Profiler() - else: - return NullProfiler() diff --git a/driver/pace/driver/performance/report.py b/driver/pace/driver/performance/report.py deleted file mode 100644 index 4160df0fa..000000000 --- a/driver/pace/driver/performance/report.py +++ /dev/null @@ -1,155 +0,0 @@ -import copy -import dataclasses -import json -from datetime import datetime -from typing import Any, Dict, List, Mapping - -import numpy as np - -from pace.util.comm import Comm - - -@dataclasses.dataclass -class Experiment: - dataset: str - format_version: int - git_hash: str - timestamp: str - timesteps: int - backend: str - - -@dataclasses.dataclass -class TimeReport: - hits: int - times: list - - -@dataclasses.dataclass -class Report: - setup: Experiment - times: dict - dt_atmos: float - sim_status: str = "Finished" - SYPD: float = 0.0 - - def __post_init__(self): - self.SYPD = get_sypd(self.times, self.dt_atmos) - - -def get_experiment_info( - experiment_name: str, - time_step: int, - backend: str, - git_hash: str, - is_orchestrated: bool, -) -> Experiment: - orchestration = "orchestrated" if is_orchestrated else "python" - experiment = Experiment( - dataset=experiment_name, - format_version=3, - git_hash=git_hash, - timestamp=datetime.now().strftime("%d/%m/%Y %H:%M:%S"), - timesteps=time_step, - backend=f"{orchestration}/{backend}", - ) - return experiment - - -def collect_keys_from_data(times_per_step: List[Mapping[str, float]]) -> List[str]: - """Collects all the keys in the list of dicts and returns a sorted version""" - keys = set() - for data_point in times_per_step: - for k, _ in data_point.items(): - keys.add(k) - sorted_keys = list(keys) - sorted_keys.sort() - return sorted_keys - - -def gather_timing_data( - times_per_step: List[Mapping[str, float]], - comm, - root: int = 0, -) -> Dict[str, Any]: - """returns an updated version of the results dictionary owned - by the root node to hold data on the substeps as well as the main loop timers""" - is_root = comm.Get_rank() == root - keys = collect_keys_from_data(times_per_step) - data: List[float] = [] - timing_info = {} - for timer_name in keys: - data.clear() - for data_point in times_per_step: - if timer_name in data_point: - data.append(data_point[timer_name]) - - sendbuf = np.array(data) - recvbuf = None - if is_root: - recvbuf = np.array([data] * comm.Get_size()) - comm.Gather(sendbuf, recvbuf, root=0) - if is_root: - timing_info[timer_name] = TimeReport( - hits=0, times=copy.deepcopy(recvbuf.tolist()) - ) - return timing_info - - -def write_to_timestamped_json(experiment: Report) -> None: - now = datetime.now() - filename = now.strftime("%Y-%m-%d-%H-%M-%S") - with open(filename + ".json", "w") as outfile: - json.dump(dataclasses.asdict(experiment), outfile, sort_keys=True, indent=4) - - -def gather_hit_counts( - hits_per_step: List[Mapping[str, int]], timing_info: Dict[str, TimeReport] -) -> Dict[str, TimeReport]: - """collects the hit count across all timers called in a program execution""" - for data_point in hits_per_step: - for name, value in data_point.items(): - timing_info[name].hits += value - return timing_info - - -def get_sypd(timing_info: Dict[str, TimeReport], dt_atmos: float) -> float: - if "mainloop" in timing_info: - is_list_of_list = any( - isinstance(el, list) for el in timing_info["mainloop"].times - ) - if is_list_of_list: - mainloop = np.mean(sum(timing_info["mainloop"].times, [])) - else: - mainloop = np.mean(timing_info["mainloop"].times) - speedup = dt_atmos / mainloop - sypd = 1.0 / 365.0 * speedup - else: - sypd = -999.0 - return sypd - - -def collect_data_and_write_to_file( - time_step: int, - backend: str, - is_orchestrated: bool, - git_hash: str, - comm: Comm, - hits_per_step: List, - times_per_step: List, - experiment_name: str, - dt_atmos: float, -) -> None: - """ - collect the gathered data from all the ranks onto rank 0 and write the timing file - """ - is_root = comm.Get_rank() == 0 - timing_info = gather_timing_data(times_per_step, comm) - - if is_root: - exp_info = get_experiment_info( - experiment_name, time_step, backend, git_hash, is_orchestrated - ) - timing_info = gather_hit_counts(hits_per_step, timing_info) - report = Report(setup=exp_info, times=timing_info, dt_atmos=dt_atmos) - write_to_timestamped_json(report) diff --git a/driver/pace/driver/run.py b/driver/pace/driver/run.py index df70eb14a..62806fc55 100644 --- a/driver/pace/driver/run.py +++ b/driver/pace/driver/run.py @@ -4,8 +4,7 @@ import click import yaml - -from pace.util import AVAILABLE_LOG_LEVELS, pace_log +from ndsl.logging import AVAILABLE_LOG_LEVELS, ndsl_log from .driver import Driver, DriverConfig @@ -33,12 +32,12 @@ def command_line(config_path: str, log_rank: Optional[int], log_level: str): CONFIG_PATH is the path to a DriverConfig yaml file. """ level = AVAILABLE_LOG_LEVELS[log_level.lower()] - pace_log.setLevel(level) - pace_log.info("loading DriverConfig from yaml") + ndsl_log.setLevel(level) + ndsl_log.info("loading DriverConfig from yaml") with open(config_path, "r") as f: config = yaml.safe_load(f) driver_config = DriverConfig.from_dict(config) - pace_log.info( + ndsl_log.info( f"DriverConfig loaded: {yaml.dump(dataclasses.asdict(driver_config))}" ) main(driver_config=driver_config) diff --git a/driver/pace/driver/safety_checks.py b/driver/pace/driver/safety_checks.py index 4ae2b8fd2..6c2911ec4 100644 --- a/driver/pace/driver/safety_checks.py +++ b/driver/pace/driver/safety_checks.py @@ -1,9 +1,9 @@ from typing import ClassVar, Dict, Optional import numpy as np +from ndsl.quantity import Quantity from pace.fv3core.dycore_state import DycoreState -from pace.util.quantity import Quantity class VariableBounds: @@ -79,7 +79,6 @@ def check_state(self, state: DycoreState): except AttributeError: raise NotImplementedError("Variable is not in the state") if variable_bounds.compute_domain_only: - min_value = var.view[:].min() max_value = var.view[:].max() else: diff --git a/driver/pace/driver/state.py b/driver/pace/driver/state.py index 93c99b55b..136f1f98b 100644 --- a/driver/pace/driver/state.py +++ b/driver/pace/driver/state.py @@ -2,14 +2,19 @@ from dataclasses import fields from typing import List +import ndsl.dsl.gt4py_utils as gt_utils import xarray as xr +from ndsl.comm.communicator import Communicator +from ndsl.constants import N_HALO_DEFAULT, X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.typing import Float +from ndsl.filesystem import get_fs +from ndsl.grid import DampingCoefficients, DriverGridData, GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from ndsl.quantity import Quantity -import pace.dsl.gt4py_utils as gt_utils import pace.physics -import pace.util -import pace.util.grid from pace import fv3core -from pace.dsl.typing import Float @dataclasses.dataclass() @@ -19,33 +24,33 @@ class TendencyState: to the dynamical core model state. """ - u_dt: pace.util.Quantity = dataclasses.field( + u_dt: Quantity = dataclasses.field( metadata={ "name": "eastward_wind_tendency_due_to_physics", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s**2", "intent": "inout", } ) - v_dt: pace.util.Quantity = dataclasses.field( + v_dt: Quantity = dataclasses.field( metadata={ "name": "northward_wind_tendency_due_to_physics", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s**2", "intent": "inout", } ) - pt_dt: pace.util.Quantity = dataclasses.field( + pt_dt: Quantity = dataclasses.field( metadata={ "name": "temperature_tendency_due_to_physics", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "K/s", "intent": "inout", } ) @classmethod - def init_zeros(cls, quantity_factory: pace.util.QuantityFactory) -> "TendencyState": + def init_zeros(cls, quantity_factory: QuantityFactory) -> "TendencyState": initial_quantities = {} for _field in dataclasses.fields(cls): initial_quantities[_field.name] = quantity_factory.zeros( @@ -61,9 +66,9 @@ class DriverState: dycore_state: fv3core.DycoreState physics_state: pace.physics.PhysicsState tendency_state: TendencyState - grid_data: pace.util.grid.GridData - damping_coefficients: pace.util.grid.DampingCoefficients - driver_grid_data: pace.util.grid.DriverGridData + grid_data: GridData + damping_coefficients: DampingCoefficients + driver_grid_data: DriverGridData # TODO: the driver_config argument here isn't type hinted from # import due to a circular dependency. This can be fixed by refactoring @@ -73,26 +78,24 @@ def load_state_from_restart( cls, restart_path: str, driver_config, - damping_coefficients: pace.util.grid.DampingCoefficients, - driver_grid_data: pace.util.grid.DriverGridData, - grid_data: pace.util.grid.GridData, + damping_coefficients: DampingCoefficients, + driver_grid_data: DriverGridData, + grid_data: GridData, schemes: List[pace.physics.PHYSICS_PACKAGES], ) -> "DriverState": comm = driver_config.comm_config.get_comm() - communicator = pace.util.Communicator.from_layout( - comm=comm, layout=driver_config.layout - ) - sizer = pace.util.SubtileGridSizer.from_tile_params( + communicator = Communicator.from_layout(comm=comm, layout=driver_config.layout) + sizer = SubtileGridSizer.from_tile_params( nx_tile=driver_config.nx_tile, ny_tile=driver_config.nx_tile, nz=driver_config.nz, - n_halo=pace.util.N_HALO_DEFAULT, + n_halo=N_HALO_DEFAULT, extra_dim_lengths={}, layout=driver_config.layout, tile_partitioner=communicator.partitioner.tile, tile_rank=communicator.tile.rank, ) - quantity_factory = pace.util.QuantityFactory.from_backend( + quantity_factory = QuantityFactory.from_backend( sizer, backend=driver_config.stencil_config.compilation_config.backend ) @@ -174,14 +177,14 @@ def _overwrite_state_from_restart( def _restart_driver_state( path: str, rank: int, - quantity_factory: pace.util.QuantityFactory, - communicator: pace.util.Communicator, - damping_coefficients: pace.util.grid.DampingCoefficients, - driver_grid_data: pace.util.grid.DriverGridData, - grid_data: pace.util.grid.GridData, + quantity_factory: QuantityFactory, + communicator: Communicator, + damping_coefficients: DampingCoefficients, + driver_grid_data: DriverGridData, + grid_data: GridData, schemes: List[pace.physics.PHYSICS_PACKAGES], ): - fs = pace.util.get_fs(path) + fs = get_fs(path) restart_files = fs.ls(path) is_fortran_restart = any( diff --git a/driver/pace/driver/tools.py b/driver/pace/driver/tools.py deleted file mode 100644 index c58eb6fa9..000000000 --- a/driver/pace/driver/tools.py +++ /dev/null @@ -1,75 +0,0 @@ -from typing import Optional - -import click - -from pace.dsl.dace.utils import ( - kernel_theoretical_timing_from_path, - memory_static_analysis_from_path, -) - - -# Count the memory from a given SDFG -ACTION_SDFG_MEMORY_STATIC_ANALYSIS = "sdfg_memory_static_analysis" -ACTION_SDFG_KERNEL_THEORETICAL_TIMING = "sdfg_kernel_theoretical_timing" - - -@click.command() -@click.argument( - "action", - required=True, - type=click.Choice( - [ACTION_SDFG_MEMORY_STATIC_ANALYSIS, ACTION_SDFG_KERNEL_THEORETICAL_TIMING] - ), -) -@click.option( - "--sdfg_path", - required=True, - type=click.STRING, -) -@click.option("--report_detail", is_flag=True, type=click.BOOL, default=False) -@click.option( - "--hardware_bw_in_gb_s", - required=False, - type=click.FLOAT, - default=0.0, -) -@click.option( - "--output_format", - required=False, - type=click.STRING, - default=None, -) -@click.option( - "--backend", - required=False, - type=click.STRING, - default="dace:gpu", -) -def command_line( - action: str, - sdfg_path: Optional[str], - report_detail: Optional[bool], - hardware_bw_in_gb_s: Optional[float], - output_format: Optional[str], - backend: Optional[str], -): - """ - Run tooling. - """ - if action == ACTION_SDFG_MEMORY_STATIC_ANALYSIS: - print(memory_static_analysis_from_path(sdfg_path, detail_report=report_detail)) - elif action == ACTION_SDFG_KERNEL_THEORETICAL_TIMING: - print( - kernel_theoretical_timing_from_path( - sdfg_path, - hardware_bw_in_GB_s=( - None if hardware_bw_in_gb_s == 0 else hardware_bw_in_gb_s - ), - backend=backend, - output_format=output_format, - ) - ) - - -if __name__ == "__main__": - command_line() diff --git a/driver/setup.py b/driver/setup.py index 7607cbc5c..6f217e23a 100644 --- a/driver/setup.py +++ b/driver/setup.py @@ -6,10 +6,8 @@ setup_requirements: List[str] = [] requirements = [ - "pace-util", "pace-fv3core", "pace-physics", - "pace-stencils", "dacite", "pyyaml", "mpi4py", diff --git a/driver/tests/mpi/test_restart.py b/driver/tests/mpi/test_restart.py index 92c6f72be..99c8e3b1f 100644 --- a/driver/tests/mpi/test_restart.py +++ b/driver/tests/mpi/test_restart.py @@ -6,9 +6,11 @@ import yaml import zarr from mpi4py import MPI +from ndsl.comm.communicator import CubedSphereCommunicator +from ndsl.comm.null_comm import NullComm +from ndsl.comm.partitioner import CubedSpherePartitioner, TilePartitioner +from ndsl.quantity import Quantity -import pace.dsl -import pace.util from pace.driver import DriverConfig from pace.driver.state import DriverState from pace.physics import PHYSICS_PACKAGES @@ -52,11 +54,9 @@ def test_restart(): with open("RESTART/restart.yaml", "r") as f: restart_config = DriverConfig.from_dict(yaml.safe_load(f)) - mpi_comm = pace.util.NullComm(rank=0, total_ranks=6, fill_value=0.0) - partitioner = pace.util.CubedSpherePartitioner( - pace.util.TilePartitioner((1, 1)) - ) - communicator = pace.util.CubedSphereCommunicator(mpi_comm, partitioner) + mpi_comm = NullComm(rank=0, total_ranks=6, fill_value=0.0) + partitioner = CubedSpherePartitioner(TilePartitioner((1, 1))) + communicator = CubedSphereCommunicator(mpi_comm, partitioner) (damping_coefficients, driver_grid_data, grid_data,) = restart_config.get_grid( communicator=communicator, ) @@ -75,7 +75,7 @@ def test_restart(): f"RESTART/restart_dycore_state_{communicator.rank}.nc" ) for var in driver_state.dycore_state.__dict__.keys(): - if isinstance(driver_state.dycore_state.__dict__[var], pace.util.Quantity): + if isinstance(driver_state.dycore_state.__dict__[var], Quantity): np.testing.assert_allclose( driver_state.dycore_state.__dict__[var].data, restart_dycore[var].values, diff --git a/dsl/pace/dsl/__init__.py b/dsl/pace/dsl/__init__.py deleted file mode 100644 index 9718e4019..000000000 --- a/dsl/pace/dsl/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -import gt4py.cartesian.config - -from pace.util.mpi import MPI - -from . import dace -from .dace.dace_config import DaceConfig, DaCeOrchestration -from .dace.orchestration import orchestrate, orchestrate_function -from .stencil import ( - CompilationConfig, - FrozenStencil, - GridIndexing, - StencilConfig, - StencilFactory, -) - - -if MPI is not None: - import os - - gt4py.cartesian.config.cache_settings["dir_name"] = os.environ.get( - "GT_CACHE_DIR_NAME", f".gt_cache_{MPI.COMM_WORLD.Get_rank():06}" - ) - -__version__ = "0.2.0" diff --git a/dsl/pace/dsl/caches/cache_location.py b/dsl/pace/dsl/caches/cache_location.py deleted file mode 100644 index 5c1de5f6a..000000000 --- a/dsl/pace/dsl/caches/cache_location.py +++ /dev/null @@ -1,46 +0,0 @@ -from pace.dsl.caches.codepath import FV3CodePath -from pace.util import Partitioner - - -def identify_code_path( - rank: int, - partitioner: Partitioner, -) -> FV3CodePath: - if partitioner.layout == (1, 1) or partitioner.layout == [1, 1]: - return FV3CodePath.All - elif partitioner.layout[0] == 1 or partitioner.layout[1] == 1: - raise NotImplementedError( - f"Build for layout {partitioner.layout} is not handled" - ) - else: - if partitioner.tile.on_tile_bottom(rank): - if partitioner.tile.on_tile_left(rank): - return FV3CodePath.BottomLeft - if partitioner.tile.on_tile_right(rank): - return FV3CodePath.BottomRight - else: - return FV3CodePath.Bottom - if partitioner.tile.on_tile_top(rank): - if partitioner.tile.on_tile_left(rank): - return FV3CodePath.TopLeft - if partitioner.tile.on_tile_right(rank): - return FV3CodePath.TopRight - else: - return FV3CodePath.Top - else: - if partitioner.tile.on_tile_left(rank): - return FV3CodePath.Left - if partitioner.tile.on_tile_right(rank): - return FV3CodePath.Right - else: - return FV3CodePath.Center - - -def get_cache_fullpath(code_path: FV3CodePath) -> str: - from gt4py.cartesian import config as gt_config - - return f"{gt_config.cache_settings['root_path']}/.gt_cache_{code_path}" - - -def get_cache_directory(code_path: FV3CodePath) -> str: - return f".gt_cache_{code_path}" diff --git a/dsl/pace/dsl/caches/codepath.py b/dsl/pace/dsl/caches/codepath.py deleted file mode 100644 index 8ebf94926..000000000 --- a/dsl/pace/dsl/caches/codepath.py +++ /dev/null @@ -1,33 +0,0 @@ -import enum - - -class FV3CodePath(enum.Enum): - """Enum listing all possible code paths on a cube sphere. - For any layout the cube sphere has up to 9 different code paths depending on - the positioning of the rank on the tile and which of the edge/corner cases - it has to handle, as well as the possibility for all boundary computations in - the 1x1 layout case. - Since the framework inlines code to optimize, we _cannot_ pre-suppose which code - being kept and/or ejected. This enum serves as the ground truth to map rank to - the proper generated code. - """ - - All = "FV3_A" - BottomLeft = "FV3_BL" - Left = "FV3_L" - TopLeft = "FV3_TL" - Top = "FV3_T" - TopRight = "FV3_TR" - Right = "FV3_R" - BottomRight = "FV3_BR" - Bottom = "FV3_B" - Center = "FV3_C" - - def __str__(self): - return self.value - - def __repr__(self): - return self.value - - def __format__(self, format_spec: str) -> str: - return self.value diff --git a/dsl/pace/dsl/dace/__init__.py b/dsl/pace/dsl/dace/__init__.py deleted file mode 100644 index 5dd618262..000000000 --- a/dsl/pace/dsl/dace/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from pace.dsl.dace.dace_config import DaceConfig -from pace.dsl.dace.orchestration import orchestrate diff --git a/dsl/pace/dsl/dace/build.py b/dsl/pace/dsl/dace/build.py deleted file mode 100644 index 999d9e8e7..000000000 --- a/dsl/pace/dsl/dace/build.py +++ /dev/null @@ -1,141 +0,0 @@ -from typing import List, Optional, Tuple - -from dace.sdfg import SDFG - -import pace.util -from pace.dsl.caches.cache_location import get_cache_directory, get_cache_fullpath -from pace.dsl.dace.dace_config import DaceConfig, DaCeOrchestration - - -################################################ -# Distributed compilation - - -def unblock_waiting_tiles(comm, sdfg_path: str) -> None: - if comm and comm.Get_size() > 1: - for tile in range(1, 6): - tilesize = comm.Get_size() / 6 - comm.send(sdfg_path, dest=tile * tilesize + comm.Get_rank()) - - -def build_info_filepath() -> str: - return "build_info.txt" - - -def write_build_info( - sdfg: SDFG, layout: Tuple[int, int], resolution_per_tile: List[int], backend: str -): - """Write down all relevant information on the build to identify - it at load time.""" - # Dev NOTE: we should be able to leverage sdfg.make_key to get a hash or - # even go to a complete hash base system and read the data from the SDFG itself - import os - - path_to_sdfg_dir = os.path.abspath(sdfg.build_folder) - with open(f"{path_to_sdfg_dir}/{build_info_filepath()}", "w") as build_info_read: - build_info_read.write("#Schema: Backend Layout Resolution per tile\n") - build_info_read.write(f"{backend}\n") - build_info_read.write(f"{str(layout)}\n") - build_info_read.write(f"{str(resolution_per_tile)}\n") - - -################################################ - -################################################ -# SDFG load (both .sdfg file and build directory containing .so) - - -def get_sdfg_path( - daceprog_name: str, - config: DaceConfig, - sdfg_file_path: Optional[str] = None, - override_run_only=False, -) -> Optional[str]: - """Build an SDFG path from the qualified program name or it's direct path to .sdfg - - Args: - program_name: qualified name in the form module_qualname if module is not locals - sdfg_file_path: absolute path to a .sdfg file - """ - import os - - # TODO: check DaceConfig for cache.strategy == name - # Guarding against bad usage of this function - if not override_run_only and config.get_orchestrate() != DaCeOrchestration.Run: - return None - - # Case of a .sdfg file given by the user to be compiled - if sdfg_file_path is not None: - if not os.path.isfile(sdfg_file_path): - raise RuntimeError( - f"SDFG filepath {sdfg_file_path} cannot be found or is not a file" - ) - return sdfg_file_path - - # Case of loading a precompiled .so - lookup using GT_CACHE - cache_fullpath = get_cache_fullpath(config.code_path) - sdfg_dir_path = f"{cache_fullpath}/dacecache/{daceprog_name}" - if not os.path.isdir(sdfg_dir_path): - raise RuntimeError(f"Precompiled SDFG is missing at {sdfg_dir_path}") - - # Check layout in build time matches layout now - import ast - - with open(f"{sdfg_dir_path}/{build_info_filepath()}") as build_info_file: - # Jump over schema comment - build_info_file.readline() - # Read in - build_backend = build_info_file.readline().rstrip() - if config.get_backend() != build_backend: - raise RuntimeError( - f"SDFG build for {build_backend}, {config._backend} has been asked" - ) - # Check resolution per tile - build_layout = ast.literal_eval(build_info_file.readline()) - build_resolution = ast.literal_eval(build_info_file.readline()) - if (config.tile_resolution[0] / config.layout[0]) != ( - build_resolution[0] / build_layout[0] - ): - raise RuntimeError( - f"SDFG build for resolution {build_resolution}, " - f"cannot be run with current resolution {config.tile_resolution}" - ) - - print(f"[DaCe Config] Rank {config.my_rank} loading SDFG {sdfg_dir_path}") - - return sdfg_dir_path - - -def set_distributed_caches(config: "DaceConfig"): - """In Run mode, check required file then point current rank cache to source cache""" - - # Execute specific initialization per orchestration state - orchestration_mode = config.get_orchestrate() - if orchestration_mode == DaCeOrchestration.Python: - return - - # Check that we have all the file we need to early out in case - # of issues. - if orchestration_mode == DaCeOrchestration.Run: - import os - - cache_directory = get_cache_fullpath(config.code_path) - if not os.path.exists(cache_directory): - raise RuntimeError( - f"{orchestration_mode} error: Could not find caches for rank " - f"{config.my_rank} at {cache_directory}" - ) - - # Set read/write caches to the target rank - from gt4py.cartesian import config as gt_config - - if config.do_compile: - verb = "reading/writing" - else: - verb = "reading" - - gt_config.cache_settings["dir_name"] = get_cache_directory(config.code_path) - pace.util.pace_log.info( - f"[{orchestration_mode}] Rank {config.my_rank} " - f"{verb} cache {gt_config.cache_settings['dir_name']}" - ) diff --git a/dsl/pace/dsl/dace/dace_config.py b/dsl/pace/dsl/dace/dace_config.py deleted file mode 100644 index a19069633..000000000 --- a/dsl/pace/dsl/dace/dace_config.py +++ /dev/null @@ -1,340 +0,0 @@ -import enum -import os -from typing import Any, Dict, Optional, Tuple - -import dace.config -from dace.codegen.compiled_sdfg import CompiledSDFG -from dace.frontend.python.parser import DaceProgram - -from pace.dsl.caches.cache_location import identify_code_path -from pace.dsl.caches.codepath import FV3CodePath -from pace.dsl.gt4py_utils import is_gpu_backend -from pace.util._optional_imports import cupy as cp -from pace.util.communicator import Communicator, Partitioner - - -# This can be turned on to revert compilation for orchestration -# in a rank-compile-itself more, instead of the distributed top-tile -# mechanism. -DEACTIVATE_DISTRIBUTED_DACE_COMPILE = False - - -def _is_corner(rank: int, partitioner: Partitioner) -> bool: - if partitioner.tile.on_tile_bottom(rank): - if partitioner.tile.on_tile_left(rank): - return True - if partitioner.tile.on_tile_right(rank): - return True - if partitioner.tile.on_tile_top(rank): - if partitioner.tile.on_tile_left(rank): - return True - if partitioner.tile.on_tile_right(rank): - return True - return False - - -def _smallest_rank_bottom(x: int, y: int, layout: Tuple[int, int]): - return y == 0 and x == 1 - - -def _smallest_rank_top(x: int, y: int, layout: Tuple[int, int]): - return y == layout[1] - 1 and x == 1 - - -def _smallest_rank_left(x: int, y: int, layout: Tuple[int, int]): - return x == 0 and y == 1 - - -def _smallest_rank_right(x: int, y: int, layout: Tuple[int, int]): - return x == layout[0] - 1 and y == 1 - - -def _smallest_rank_middle(x: int, y: int, layout: Tuple[int, int]): - return layout[0] > 1 and layout[1] > 1 and x == 1 and y == 1 - - -def _determine_compiling_ranks( - config: "DaceConfig", - partitioner: Partitioner, -) -> bool: - """ - We try to map every layout to a 3x3 layout which MPI ranks - looks like - 6 7 8 - 3 4 5 - 0 1 2 - Using the partitionner we find mapping of the given layout - to all of those. For example on 4x4 layout - 12 13 14 15 - 8 9 10 11 - 4 5 6 7 - 0 1 2 3 - therefore we map - 0 -> 0 - 1 -> 1 - 2 -> NOT COMPILING - 3 -> 2 - 4 -> 3 - 5 -> 4 - 6 -> NOT COMPILING - 7 -> 5 - 8 -> NOT COMPILING - 9 -> NOT COMPILING - 10 -> NOT COMPILING - 11 -> NOT COMPILING - 12 -> 6 - 13 -> 7 - 14 -> NOT COMPILING - 15 -> 8 - """ - - # Tile 0 compiles - if partitioner.tile_index(config.my_rank) != 0: - return False - - # Corners compile - if _is_corner(config.my_rank, partitioner): - return True - - y, x = partitioner.tile.subtile_index(config.my_rank) - - # If edge or center tile, we give way to the smallest rank - return ( - _smallest_rank_left(x, y, config.layout) - or _smallest_rank_bottom(x, y, config.layout) - or _smallest_rank_middle(x, y, config.layout) - or _smallest_rank_right(x, y, config.layout) - or _smallest_rank_top(x, y, config.layout) - ) - - -class DaCeOrchestration(enum.Enum): - """ - Orchestration mode for DaCe - - Python: python orchestration - Build: compile & save SDFG only - BuildAndRun: compile & save SDFG, then run - Run: load from .so and run, will fail if .so is not available - """ - - Python = 0 - Build = 1 - BuildAndRun = 2 - Run = 3 - - -class FrozenCompiledSDFG: - """ - Cache transform args to allow direct execution of the CSDFG - - Args: - csdfg: compiled SDFG, e.g. loaded .so - sdfg_args: transformed args to align for CSDFG direct execution - - WARNING: No checks are done on arguments, any memory swap (free/realloc) - will lead to difficult to debug misbehavior - """ - - def __init__( - self, daceprog: DaceProgram, csdfg: CompiledSDFG, args, kwargs - ) -> None: - self.csdfg = csdfg - self.sdfg_args = daceprog._create_sdfg_args(csdfg.sdfg, args, kwargs) - - def __call__(self): - return self.csdfg(**self.sdfg_args) - - -class DaceConfig: - def __init__( - self, - communicator: Optional[Communicator], - backend: str, - tile_nx: int = 0, - tile_nz: int = 0, - orchestration: Optional[DaCeOrchestration] = None, - ): - # Recording SDFG loaded for fast re-access - # ToDo: DaceConfig becomes a bit more than a read-only config - # with this. Should be refactor into a DaceExecutor carrying a config - self.loaded_precompiled_SDFG: Dict[DaceProgram, FrozenCompiledSDFG] = {} - - # Temporary. This is a bit too out of the ordinary for the common user. - # We should refactor the architecture to allow for a `gtc:orchestrated:dace:X` - # backend that would signify both the `CPU|GPU` split and the orchestration mode - if orchestration is None: - fv3_dacemode_env_var = os.getenv("FV3_DACEMODE", "Python") - # The below condition guard against defining empty FV3_DACEMODE and - # awkward behavior of os.getenv returning "" even when not defined - if fv3_dacemode_env_var is None or fv3_dacemode_env_var == "": - fv3_dacemode_env_var = "Python" - self._orchestrate = DaCeOrchestration[fv3_dacemode_env_var] - else: - self._orchestrate = orchestration - - # Debugging Dace orchestration deeper can be done by turning on `syncdebug` - # We control this Dace configuration below with our own override - dace_debug_env_var = os.getenv("PACE_DACE_DEBUG", "False") == "True" - - # Set the configuration of DaCe to a rigid & tested set of divergence - # from the defaults when orchestrating - if orchestration != DaCeOrchestration.Python: - # Required to True for gt4py storage/memory - dace.config.Config.set( - "compiler", - "allow_view_arguments", - value=True, - ) - # Removed --fmath - dace.config.Config.set( - "compiler", - "cpu", - "args", - value="-std=c++14 -fPIC -Wall -Wextra -O3", - ) - # Potentially buggy - deactivate - dace.config.Config.set( - "compiler", - "cpu", - "openmp_sections", - value=0, - ) - # Removed --fast-math - dace.config.Config.set( - "compiler", - "cuda", - "args", - value="-std=c++14 -Xcompiler -fPIC -O3 -Xcompiler -march=native", - ) - - cuda_sm = 60 - if cp: - cuda_sm = cp.cuda.Device(0).compute_capability - dace.config.Config.set("compiler", "cuda", "cuda_arch", value=f"{cuda_sm}") - # Block size/thread count is defaulted to an average value for recent - # hardware (Pascal and upward). The problem of setting an optimized - # block/thread is both hardware and problem dependant. Fine tuners - # available in DaCe should be relied on for futher tuning of this value. - dace.config.Config.set( - "compiler", "cuda", "default_block_size", value="64,8,1" - ) - # Potentially buggy - deactivate - dace.config.Config.set( - "compiler", - "cuda", - "max_concurrent_streams", - value=-1, # no concurrent streams, every kernel on defaultStream - ) - # Speed up built time - dace.config.Config.set( - "compiler", - "cuda", - "unique_functions", - value="none", - ) - # Required for HaloEx callbacks and general code sanity - dace.config.Config.set( - "frontend", - "dont_fuse_callbacks", - value=True, - ) - # Unroll all loop - outer loop should be exempted with dace.nounroll - dace.config.Config.set( - "frontend", - "unroll_threshold", - value=False, - ) - # Allow for a longer stack dump when parsing fails - dace.config.Config.set( - "frontend", - "verbose_errors", - value=True, - ) - # Build speed up by removing some deep copies - dace.config.Config.set( - "store_history", - value=False, - ) - - # Enable to debug GPU failures - dace.config.Config.set( - "compiler", "cuda", "syncdebug", value=dace_debug_env_var - ) - - # attempt to kill the dace.conf to avoid confusion - if dace.config.Config._cfg_filename: - try: - os.remove(dace.config.Config._cfg_filename) - except OSError: - pass - - self._backend = backend - self.tile_resolution = [tile_nx, tile_nx, tile_nz] - from pace.dsl.dace.build import set_distributed_caches - - # Distributed build required info - if communicator: - self.my_rank = communicator.rank - self.rank_size = communicator.comm.Get_size() - self.code_path = identify_code_path(self.my_rank, communicator.partitioner) - self.layout = communicator.partitioner.layout - self.do_compile = ( - DEACTIVATE_DISTRIBUTED_DACE_COMPILE - or _determine_compiling_ranks(self, communicator.partitioner) - ) - else: - self.my_rank = 0 - self.rank_size = 1 - self.code_path = FV3CodePath.All - self.layout = (1, 1) - self.do_compile = True - - set_distributed_caches(self) - - if ( - self._orchestrate != DaCeOrchestration.Python - and "dace" not in self._backend - ): - raise RuntimeError( - "DaceConfig: orchestration can only be leverage " - f"on dace or dace:gpu not on {self._backend}" - ) - - def is_dace_orchestrated(self) -> bool: - return self._orchestrate != DaCeOrchestration.Python - - def is_gpu_backend(self) -> bool: - return is_gpu_backend(self._backend) - - def get_backend(self) -> str: - return self._backend - - def get_orchestrate(self) -> DaCeOrchestration: - return self._orchestrate - - def get_sync_debug(self) -> bool: - return dace.config.Config.get_bool("compiler", "cuda", "syncdebug") - - def as_dict(self) -> Dict[str, Any]: - return { - "_orchestrate": str(self._orchestrate.name), - "_backend": self._backend, - "my_rank": self.my_rank, - "rank_size": self.rank_size, - "layout": self.layout, - "tile_resolution": self.tile_resolution, - } - - @classmethod - def from_dict(cls, data: dict): - config = cls( - None, - backend=data["_backend"], - orchestration=DaCeOrchestration[data["_orchestrate"]], - ) - config.my_rank = data["my_rank"] - config.rank_size = data["rank_size"] - config.layout = data["layout"] - config.tile_resolution = data["tile_resolution"] - return config diff --git a/dsl/pace/dsl/dace/orchestration.py b/dsl/pace/dsl/dace/orchestration.py deleted file mode 100644 index 5e5ea52a5..000000000 --- a/dsl/pace/dsl/dace/orchestration.py +++ /dev/null @@ -1,561 +0,0 @@ -import os -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union - -import dace -import gt4py.storage -from dace import compiletime as DaceCompiletime -from dace.dtypes import DeviceType as DaceDeviceType -from dace.dtypes import StorageType as DaceStorageType -from dace.frontend.python.common import SDFGConvertible -from dace.frontend.python.parser import DaceProgram -from dace.transformation.auto.auto_optimize import make_transients_persistent -from dace.transformation.helpers import get_parent_map -from dace.transformation.passes.simplify import SimplifyPass - -from pace.dsl.dace.build import get_sdfg_path, write_build_info -from pace.dsl.dace.dace_config import ( - DEACTIVATE_DISTRIBUTED_DACE_COMPILE, - DaceConfig, - DaCeOrchestration, - FrozenCompiledSDFG, -) -from pace.dsl.dace.sdfg_debug_passes import ( - negative_delp_checker, - negative_qtracers_checker, - sdfg_nan_checker, -) -from pace.dsl.dace.sdfg_opt_passes import splittable_region_expansion -from pace.dsl.dace.utils import ( - DaCeProgress, - memory_static_analysis, - report_memory_static_analysis, -) -from pace.util import pace_log -from pace.util.mpi import MPI - - -try: - import cupy as cp -except ImportError: - cp = None - - -def dace_inhibitor(func: Callable): - """Triggers callback generation wrapping `func` while doing DaCe parsing.""" - return func - - -def _upload_to_device(host_data: List[Any]): - """Make sure any ndarrays gets uploaded to the device - - This will raise an assertion if cupy is not installed. - """ - assert cp is not None - for i, data in enumerate(host_data): - if isinstance(data, cp.ndarray): - host_data[i] = cp.asarray(data) - - -def _download_results_from_dace( - config: DaceConfig, dace_result: Optional[List[Any]], args: List[Any] -): - """Move all data from DaCe memory space to GT4Py""" - gt4py_results = None - if dace_result is not None: - if config.is_gpu_backend(): - gt4py_results = [ - gt4py.storage.from_array( - r, - backend=config.get_backend(), - ) - for r in dace_result - ] - else: - gt4py_results = [ - gt4py.storage.from_array(r, backend=config.get_backend()) - for r in dace_result - ] - return gt4py_results - - -def _to_gpu(sdfg: dace.SDFG): - """Flag memory in SDFG to GPU. - Force deactivate OpenMP sections for sanity.""" - - # Gather all maps - allmaps = [ - (me, state) - for me, state in sdfg.all_nodes_recursive() - if isinstance(me, dace.nodes.MapEntry) - ] - topmaps = [ - (me, state) for me, state in allmaps if get_parent_map(state, me) is None - ] - - # Set storage of arrays to GPU, scalarizable arrays will be set on registers - for sd, _aname, arr in sdfg.arrays_recursive(): - if arr.shape == (1,): - arr.storage = dace.StorageType.Register - else: - arr.storage = dace.StorageType.GPU_Global - - # All maps will be scedule on GPU - for mapentry, state in topmaps: - mapentry.schedule = dace.ScheduleType.GPU_Device - - # Deactivate OpenMP sections - for sd in sdfg.all_sdfgs_recursive(): - sd.openmp_sections = False - - -def _simplify(sdfg: dace.SDFG, validate=True, verbose=False): - """Override of sdfg.simplify to skip failing transformation - per https://github.com/spcl/dace/issues/1328 - """ - return SimplifyPass( - validate=validate, - verbose=verbose, - skip=["ConstantPropagation"], - ).apply_pass(sdfg, {}) - - -def _build_sdfg( - daceprog: DaceProgram, sdfg: dace.SDFG, config: DaceConfig, args, kwargs -): - """Build the .so out of the SDFG on the top tile ranks only""" - if DEACTIVATE_DISTRIBUTED_DACE_COMPILE: - is_compiling = True - else: - is_compiling = config.do_compile - if is_compiling: - # Make the transients array persistents - if config.is_gpu_backend(): - _to_gpu(sdfg) - make_transients_persistent(sdfg=sdfg, device=DaceDeviceType.GPU) - - # Upload args to device - _upload_to_device(list(args) + list(kwargs.values())) - else: - for sd, _aname, arr in sdfg.arrays_recursive(): - if arr.shape == (1,): - arr.storage = DaceStorageType.Register - make_transients_persistent(sdfg=sdfg, device=DaceDeviceType.CPU) - - # Build non-constants & non-transients from the sdfg_kwargs - sdfg_kwargs = daceprog._create_sdfg_args(sdfg, args, kwargs) - for k in daceprog.constant_args: - if k in sdfg_kwargs: - del sdfg_kwargs[k] - sdfg_kwargs = {k: v for k, v in sdfg_kwargs.items() if v is not None} - for k, tup in daceprog.resolver.closure_arrays.items(): - if k in sdfg_kwargs and tup[1].transient: - del sdfg_kwargs[k] - - with DaCeProgress(config, "Simplify (1/2)"): - _simplify(sdfg, validate=False, verbose=True) - - # Perform pre-expansion fine tuning - with DaCeProgress(config, "Split regions"): - splittable_region_expansion(sdfg, verbose=True) - - # Expand the stencil computation Library Nodes with the right expansion - with DaCeProgress(config, "Expand"): - sdfg.expand_library_nodes() - - with DaCeProgress(config, "Simplify (2/2)"): - _simplify(sdfg, validate=False, verbose=True) - - # Move all memory that can be into a pool to lower memory pressure. - # Change Persistent memory (sub-SDFG) into Scope and flag it. - with DaCeProgress(config, "Turn Persistents into pooled Scope"): - memory_pooled = 0.0 - for _sd, _aname, arr in sdfg.arrays_recursive(): - if arr.lifetime == dace.AllocationLifetime.Persistent: - arr.pool = True - memory_pooled += arr.total_size * arr.dtype.bytes - arr.lifetime = dace.AllocationLifetime.Scope - memory_pooled = float(memory_pooled) / (1024 * 1024) - pace_log.debug( - f"{DaCeProgress.default_prefix(config)} Pooled {memory_pooled} mb", - ) - - # Set of debug tools inserted in the SDFG when dace.conf "syncdebug" - # is turned on. - if config.get_sync_debug(): - with DaCeProgress(config, "Tooling the SDFG for debug"): - sdfg_nan_checker(sdfg) - negative_delp_checker(sdfg) - negative_qtracers_checker(sdfg) - - # Compile - with DaCeProgress(config, "Codegen & compile"): - sdfg.compile() - write_build_info(sdfg, config.layout, config.tile_resolution, config._backend) - - # Printing analysis of the compiled SDFG - with DaCeProgress(config, "Build finished. Running memory static analysis"): - report = report_memory_static_analysis( - sdfg, memory_static_analysis(sdfg), False - ) - pace_log.info(f"{DaCeProgress.default_prefix(config)} {report}") - - # Compilation done. - # On Build: all ranks sync, then exit. - # On BuildAndRun: all ranks sync, then load the SDFG from - # the expected path (made available by build). - # We use a "FrozenCompiledSDFG" to minimize re-entry cost at call time - # DEV NOTE: we explicitly use MPI.COMM_WORLD here because it is - # a true multi-machine sync, outside of our own communicator class. - if config.get_orchestrate() == DaCeOrchestration.Build: - MPI.COMM_WORLD.Barrier() # Protect against early exist which kill SLURM jobs - pace_log.info(f"{DaCeProgress.default_prefix(config)} Build only, exiting.") - exit(0) - elif config.get_orchestrate() == DaCeOrchestration.BuildAndRun: - if not is_compiling: - pace_log.info( - f"{DaCeProgress.default_prefix(config)} Rank is not compiling." - "Waiting for compilation to end on all other ranks..." - ) - MPI.COMM_WORLD.Barrier() - - with DaCeProgress(config, "Loading"): - sdfg_path = get_sdfg_path(daceprog.name, config, override_run_only=True) - csdfg, _ = daceprog.load_precompiled_sdfg(sdfg_path, *args, **kwargs) - config.loaded_precompiled_SDFG[daceprog] = FrozenCompiledSDFG( - daceprog, csdfg, args, kwargs - ) - - return _call_sdfg(daceprog, sdfg, config, args, kwargs) - - -def _call_sdfg( - daceprog: DaceProgram, sdfg: dace.SDFG, config: DaceConfig, args, kwargs -): - """Dispatch the SDFG execution and/or build""" - # Pre-compiled SDFG code path does away with any data checks and - # cached the marshalling - leading to almost direct C call - # DaceProgram performs argument transformation & checks for a cost ~200ms - # of overhead - if daceprog in config.loaded_precompiled_SDFG: - with DaCeProgress(config, "Run"): - if config.is_gpu_backend(): - _upload_to_device(list(args) + list(kwargs.values())) - res = config.loaded_precompiled_SDFG[daceprog]() - res = _download_results_from_dace( - config, res, list(args) + list(kwargs.values()) - ) - return res - else: - if ( - config.get_orchestrate() == DaCeOrchestration.Build - or config.get_orchestrate() == DaCeOrchestration.BuildAndRun - ): - pace_log.info("Building DaCe orchestration") - res = _build_sdfg(daceprog, sdfg, config, args, kwargs) - elif config.get_orchestrate() == DaCeOrchestration.Run: - # We should never hit this, it should be caught by the - # loaded_precompiled_SDFG check above - raise RuntimeError("Unexpected call - csdfg didn't get caught") - else: - raise NotImplementedError( - f"Mode {config.get_orchestrate()} unimplemented at call time" - ) - return res - - -def _parse_sdfg( - daceprog: DaceProgram, - config: DaceConfig, - *args, - **kwargs, -) -> Optional[dace.SDFG]: - """Return an SDFG depending on cache existence. - Either parses, load a .sdfg or load .so (as a compiled sdfg) - - Attributes: - daceprog: the DaceProgram carrying reference to the original method/function - config: the DaceConfig configuration for this execution - """ - # Check cache for already loaded SDFG - if daceprog in config.loaded_precompiled_SDFG: - return config.loaded_precompiled_SDFG[daceprog] - - # Build expected path - sdfg_path = get_sdfg_path(daceprog.name, config) - if sdfg_path is None: - if DEACTIVATE_DISTRIBUTED_DACE_COMPILE: - is_compiling = True - else: - is_compiling = config.do_compile - if not is_compiling: - # We can not parse the SDFG since we will load the proper - # compiled SDFG from the compiling rank - return None - with DaCeProgress(config, f"Parse code of {daceprog.name} to SDFG"): - sdfg = daceprog.to_sdfg( - *args, - **daceprog.__sdfg_closure__(), - **kwargs, - save=False, - simplify=False, - ) - return sdfg - else: - if os.path.isfile(sdfg_path): - with DaCeProgress(config, "Load .sdfg"): - sdfg, _ = daceprog.load_sdfg(sdfg_path, *args, **kwargs) - return sdfg - else: - with DaCeProgress(config, "Load precompiled .sdfg (.so)"): - csdfg, _ = daceprog.load_precompiled_sdfg(sdfg_path, *args, **kwargs) - config.loaded_precompiled_SDFG[daceprog] = FrozenCompiledSDFG( - daceprog, csdfg, args, kwargs - ) - return csdfg - - -class _LazyComputepathFunction(SDFGConvertible): - """JIT wrapper around a function for DaCe orchestration. - - Attributes: - func: function to either orchestrate or directly execute - load_sdfg: folder path to a pre-compiled SDFG or file path to a .sdfg graph - that will be compiled but not regenerated. - """ - - def __init__(self, func: Callable, config: DaceConfig): - self.func = func - self.config = config - self.daceprog: DaceProgram = dace.program(self.func) - self._sdfg = None - - def __call__(self, *args, **kwargs): - assert self.config.is_dace_orchestrated() - sdfg = _parse_sdfg( - self.daceprog, - self.config, - *args, - **kwargs, - ) - return _call_sdfg( - self.daceprog, - sdfg, - self.config, - args, - kwargs, - ) - - @property - def global_vars(self): - return self.daceprog.global_vars - - @global_vars.setter - def global_vars(self, value): - self.daceprog.global_vars = value - - def __sdfg__(self, *args, **kwargs): - return _parse_sdfg(self.daceprog, self.config, *args, **kwargs) - - def __sdfg_closure__(self, *args, **kwargs): - return self.daceprog.__sdfg_closure__(*args, **kwargs) - - def __sdfg_signature__(self): - return self.daceprog.argnames, self.daceprog.constant_args - - def closure_resolver(self, constant_args, given_args, parent_closure=None): - return self.daceprog.closure_resolver(constant_args, given_args, parent_closure) - - -class _LazyComputepathMethod: - """JIT wrapper around a class method for DaCe orchestration. - - Attributes: - method: class method to either orchestrate or directly execute - load_sdfg: folder path to a pre-compiled SDFG or file path to a .sdfg graph - that will be compiled but not regenerated. - """ - - # In order to not regenerate SDFG for the same obj.method callable - # we cache the SDFGEnabledCallable we have already init - bound_callables: Dict[Tuple[int, int], "SDFGEnabledCallable"] = dict() - - class SDFGEnabledCallable(SDFGConvertible): - def __init__(self, lazy_method: "_LazyComputepathMethod", obj_to_bind): - methodwrapper = dace.method(lazy_method.func) - self.obj_to_bind = obj_to_bind - self.lazy_method = lazy_method - self.daceprog: DaceProgram = methodwrapper.__get__(obj_to_bind) - - @property - def global_vars(self): - return self.daceprog.global_vars - - @global_vars.setter - def global_vars(self, value): - self.daceprog.global_vars = value - - def __call__(self, *args, **kwargs): - assert self.lazy_method.config.is_dace_orchestrated() - sdfg = _parse_sdfg( - self.daceprog, - self.lazy_method.config, - *args, - **kwargs, - ) - return _call_sdfg( - self.daceprog, - sdfg, - self.lazy_method.config, - args, - kwargs, - ) - - def __sdfg__(self, *args, **kwargs): - return _parse_sdfg(self.daceprog, self.lazy_method.config, *args, **kwargs) - - def __sdfg_closure__(self, reevaluate=None): - return self.daceprog.__sdfg_closure__(reevaluate) - - def __sdfg_signature__(self): - return self.daceprog.argnames, self.daceprog.constant_args - - def closure_resolver(self, constant_args, given_args, parent_closure=None): - return self.daceprog.closure_resolver( - constant_args, given_args, parent_closure - ) - - def __init__(self, func: Callable, config: DaceConfig): - self.func = func - self.config = config - - def __get__(self, obj, objtype=None) -> SDFGEnabledCallable: - """Return SDFGEnabledCallable wrapping original obj.method from cache. - Update cache first if need be""" - if (id(obj), id(self.func)) not in _LazyComputepathMethod.bound_callables: - _LazyComputepathMethod.bound_callables[ - (id(obj), id(self.func)) - ] = _LazyComputepathMethod.SDFGEnabledCallable(self, obj) - - return _LazyComputepathMethod.bound_callables[(id(obj), id(self.func))] - - -def orchestrate( - *, - obj: object, - config: DaceConfig, - method_to_orchestrate: str = "__call__", - dace_compiletime_args: Optional[Sequence[str]] = None, -): - """ - Orchestrate a method of an object with DaCe. - The method object is patched in place, replacing the orignal Callable with - a wrapper that will trigger orchestration at call time. - If the model configuration doesn't demand orchestration, this won't do anything. - - Args: - obj: object which methods is to be orchestrated - config: DaceConfig carrying model configuration - method_to_orchestrate: string representing the name of the method - dace_compiletime_args: list of names of arguments to be flagged has - dace.compiletime for orchestration to behave - """ - if dace_compiletime_args is None: - dace_compiletime_args = [] - - if config.is_dace_orchestrated(): - if hasattr(obj, method_to_orchestrate): - func = type.__getattribute__(type(obj), method_to_orchestrate) - - # Flag argument as dace.constant - for argument in dace_compiletime_args: - func.__annotations__[argument] = DaceCompiletime - - # Build DaCe orchestrated wrapper - # This is a JIT object, e.g. DaCe compilation will happen on call - wrapped = _LazyComputepathMethod(func, config).__get__(obj) - - if method_to_orchestrate == "__call__": - # Grab the function from the type of the child class - # Dev note: we need to use type for dunder call because: - # a = A() - # a() - # resolved to: type(a).__call__(a) - # therefore patching the instance call (e.g a.__call__) is not enough. - # We could patch the type(self), ergo the class itself - # but that would patch _every_ instance of A. - # What we can do is patch the instance.__class__ with a local made class - # in order to keep each instance with it's own patch. - # - # Re: type:ignore - # Mypy is unhappy about dynamic class name and the devs (per github - # issues discussion) is to make a plugin. Too much work -> ignore mypy - - class _(type(obj)): # type: ignore - __qualname__ = f"{type(obj).__qualname__}_patched" - __name__ = f"{type(obj).__name__}_patched" - - def __call__(self, *arg, **kwarg): - return wrapped(*arg, **kwarg) - - def __sdfg__(self, *args, **kwargs): - return wrapped.__sdfg__(*args, **kwargs) - - def __sdfg_closure__(self, reevaluate=None): - return wrapped.__sdfg_closure__(reevaluate) - - def __sdfg_signature__(self): - return wrapped.__sdfg_signature__() - - def closure_resolver( - self, constant_args, given_args, parent_closure=None - ): - return wrapped.closure_resolver( - constant_args, given_args, parent_closure - ) - - # We keep the original class type name to not perturb - # the workflows that uses it to build relevant info (path, hash...) - previous_cls_name = type(obj).__name__ - obj.__class__ = _ - type(obj).__name__ = previous_cls_name - else: - # For regular attribute - we can just patch as usual - setattr(obj, method_to_orchestrate, wrapped) - - else: - raise RuntimeError( - f"Could not orchestrate, " - f"{type(obj).__name__}.{method_to_orchestrate} " - "does not exists" - ) - - -def orchestrate_function( - config: DaceConfig = None, - dace_compiletime_args: Optional[Sequence[str]] = None, -) -> Union[Callable[..., Any], _LazyComputepathFunction]: - """ - Decorator orchestrating a method of an object with DaCe. - If the model configuration doesn't demand orchestration, this won't do anything. - - Args: - config: DaceConfig carrying model configuration - dace_compiletime_args: list of names of arguments to be flagged has - dace.compiletime for orchestration to behave - """ - - if dace_compiletime_args is None: - dace_compiletime_args = [] - - def _decorator(func: Callable[..., Any]): - def _wrapper(*args, **kwargs): - for argument in dace_compiletime_args: - func.__annotations__[argument] = DaceCompiletime - return _LazyComputepathFunction(func, config) - - if config.is_dace_orchestrated(): - return _wrapper(func) - else: - return func - - return _decorator diff --git a/dsl/pace/dsl/dace/sdfg_debug_passes.py b/dsl/pace/dsl/dace/sdfg_debug_passes.py deleted file mode 100644 index 40247eb5a..000000000 --- a/dsl/pace/dsl/dace/sdfg_debug_passes.py +++ /dev/null @@ -1,315 +0,0 @@ -import copy -from typing import List, Optional, Tuple - -import dace -import sympy as sp -from dace import data as dt -from dace import symbolic -from dace.sdfg import graph as gr -from dace.sdfg import utils as sdutil -from dace.transformation.helpers import get_parent_map - -from pace.util.logging import pace_log - - -def _filter_all_maps( - sdfg: dace.SDFG, - whitelist: List[str] = None, - blacklist: List[str] = None, - skip_dynamic_memlet=True, -) -> List[ - Tuple[dace.SDFGState, dace.nodes.AccessNode, gr.MultiConnectorEdge[dace.Memlet]] -]: - """ - Grab all maps outputs and filter by variable name (either black or whitelist) - - Arguments: - sdfg: SDFG to be read. Read-only - whitelist: filter out every variable NOT in this list - blacklist: filter out every variable in this list - skip_dynamic_memlet: skip the memlet flagged as dynamic (regions) - - Return: - A list of access nodes, with their state & edges organized as - [state, node, edges] - """ - - checks: List[ - Tuple[dace.SDFGState, dace.nodes.AccessNode, gr.MultiConnectorEdge[dace.Memlet]] - ] = [] - all_maps = [ - (me, state) - for me, state in sdfg.all_nodes_recursive() - if isinstance(me, dace.nodes.MapEntry) - ] - top_maps = [ - (me, state) for me, state in all_maps if get_parent_map(state, me) is None - ] - dynamic_skipped = 0 - for me, state in top_maps: - mx = state.exit_node(me) - for e in state.out_edges(mx): - if isinstance(e.dst, dace.nodes.AccessNode): - if isinstance(e.dst.desc(state.parent), dt.View): # Skip views for now - continue - node = sdutil.get_last_view_node(state, e.dst) - # Whitelist - if whitelist is not None: - if all([varname not in node.data for varname in whitelist]): - continue - # Blacklist - if blacklist is not None: - if any([varname in node.data for varname in blacklist]): - continue - # Skip dynamic (region) outputs - if skip_dynamic_memlet and state.memlet_path(e)[0].data.dynamic: - dynamic_skipped += 1 - continue - - checks.append((state, node, e)) - if dynamic_skipped > 0: - print(f"Skipped {dynamic_skipped} dynamic Access Nodes") - return checks - - -def _check_node( - state: dace.sdfg.SDFGState, - node: dace.nodes.Node, - edge: dace.InterstateEdge, - kernel_name: str, - c_varname: str, - check_c_code: str, - comment_c_code: str, - assert_out: bool = False, - array_range: Optional[List[Tuple[int, int, int]]] = None, -): - """ - Grab all maps outputs and filter by variable name (either black or whitelist) - - Arguments: - state: SDFG-state to be modified in-place. - node: original node to insert check after - edge: original output edge of the node - kernel_name: kernel name for C code generation - c_varname: variable name for C code generation (must - be reused in check_c_code) - check_c_code: conditional code for C code generation - comment_c_code: pure string printed on hit for C code - generation - assert_out: insert an assert if the conditional is met (after - the print). WARNING: on GPU the assert might put CUDA in an - unrecoverable state. - - Return: - None. The SDFG was modified in-place via the state, node, edge combo - """ - - # Append node that will go after the map - new_node: dace.nodes.AccessNode = copy.deepcopy(node) - # Move all outgoing edges to new node - for oe in list(state.out_edges(node)): - state.remove_edge(oe) - state.add_edge(new_node, oe.src_conn, oe.dst, oe.dst_conn, oe.data) - - # Add map in between node and new_node - sdfg = state.parent - input_array = sdfg.arrays[new_node.data] - input_dims = len(input_array.shape) - index_expr = ", ".join(["__i%d" % i for i in range(len(input_array.shape))]) - index_printf = ", ".join(["%d"] * len(input_array.shape)) - - # Get range from memlet (which may not be the entire array size) - def evaluate(expr): - return expr.subs({sp.Function("int_floor"): symbolic.int_floor}) - - # A bug in DaCe can lead to an edge labeled for storage on CPU - # wrongly, which can lead to access of device storage on the host - # (therefore crash) - if ( - input_array.storage != dace.StorageType.GPU_Global - and input_array.storage != dace.StorageType.GPU_Shared - ): - return - - # Infer schedule - schedule_type = dace.ScheduleType.Default - if ( - input_array.storage == dace.StorageType.GPU_Global - or input_array.storage == dace.StorageType.GPU_Shared - ): - schedule_type = dace.ScheduleType.GPU_Device - - ranges = [] - if array_range: - for i, range_tuple in enumerate(array_range): - if i >= input_dims: - break - ranges.append((f"__i{i}", (range_tuple))) - else: - # evaluate being used to resolve views & actively read/write domains - for i, (begin, end, step) in enumerate(edge.data.subset): - if i >= input_dims: - break - ranges.append((f"__i{i}", (evaluate(begin), evaluate(end), evaluate(step)))) - if_str = f"if({check_c_code})" if check_c_code != "" else "if(true)" - state.add_mapped_tasklet( - name=kernel_name, - map_ranges=ranges, - inputs={f"{c_varname}": dace.Memlet.simple(new_node.data, index_expr)}, - code=f""" - {if_str}{{ - printf("{node.data} value (%f) {comment_c_code} at line %d, index {index_printf}\\n", {c_varname}, __LINE__, {index_expr}); - {'assert(0);' if assert_out else ''} - }} - """, # noqa: E501 - schedule=schedule_type, - language=dace.Language.CPP, - outputs={ - "__out": dace.Memlet.simple(new_node.data, index_expr, num_accesses=-1) - }, - input_nodes={node.data: node}, - output_nodes={new_node.data: new_node}, - external_edges=True, - ) - - -def trace_all_outputs_at_index(sdfg: dace.SDFG, i: int, j: int, k: int): - """Prints value for all variable when written for a specific index. - - - Args: - sdfg (dace.SDFG): sdfg to analyze - i (int): i coordinate of the index to trace - j (int): j coordinate of the index to trace - k (int): k coordinate of the index to trace - """ - all_maps_filtered = _filter_all_maps( - sdfg, - skip_dynamic_memlet=True, - ) - - for state, node, e in all_maps_filtered: - _check_node( - state, - node, - e, - "print_all_outputs", - "_inp", - "", - "tracking", - assert_out=False, - array_range=[(i, i, 1), (j, j, 1), (k, k, 1)], - ) - - pace_log.info(f"Added {len(all_maps_filtered)} outputs trace at {i},{j},{k}") - - -def negative_delp_checker(sdfg: dace.SDFG) -> None: - """ - Adds a negative check on every variable name containing "delp" when - written to. Assert when check is True. - """ - all_maps_filtered = _filter_all_maps( - sdfg, - whitelist=["delp"], - skip_dynamic_memlet=False, - ) - - for state, node, e in all_maps_filtered: - _check_node( - state, - node, - e, - "neg_delp_check", - "_inp", - "_inp < 0", - "delp* is negative", - assert_out=True, - ) - - pace_log.info(f"Added {len(all_maps_filtered)} delp* < 0 checks") - - -def negative_qtracers_checker(sdfg: dace.SDFG): - """ - Adds a negative check on every tracers via their name when - written to. Assert when check is True. - """ - all_maps_filtered = _filter_all_maps( - sdfg, - whitelist=[ - "qvapor", - "qliquid", - "qrain", - "qice", - "qsnow", - "qgraupel", - "qo3mr", - "qsgs_tke", - "qcld", - ], - skip_dynamic_memlet=False, - ) - - for state, node, e in all_maps_filtered: - _check_node( - state, - node, - e, - "neg_tracers_check", - "_inp", - "_inp < -1e-8", - "tracer is negative", - assert_out=True, - ) - - pace_log.info(f"Added {len(all_maps_filtered)} tracer < 0 checks") - - -def sdfg_nan_checker( - sdfg: dace.SDFG, - i_range: Optional[Tuple[int, int, int]] = None, - j_range: Optional[Tuple[int, int, int]] = None, - k_range: Optional[Tuple[int, int, int]] = None, -): - """ - Insert a check on array after each computational map to check for NaN - in the domain. Assert when check is True. - """ - all_maps_filtered = _filter_all_maps(sdfg, blacklist=["diss_estd"]) - - if i_range or j_range or k_range: - array_range = [i_range, j_range, k_range] - else: - array_range = None - - for state, node, e in all_maps_filtered: - _check_node( - state, - node, - e, - "nan_check", - "_inp", - "_inp != _inp", - "NaN found", - assert_out=True, - array_range=array_range, - ) - - pace_log.info(f"Added {len(all_maps_filtered)} NaN checks") - - -def sdfg_execution_progress(sdfg: dace.SDFG): - all_maps_filtered = _filter_all_maps(sdfg) - - for state, node, e in all_maps_filtered: - _check_node( - state, - node, - e, - "execution_progress", - "_unused", - "", - "Progress", - array_range=[(0, 0, 1), (0, 0, 1), (0, 0, 1)], - ) diff --git a/dsl/pace/dsl/dace/sdfg_opt_passes.py b/dsl/pace/dsl/dace/sdfg_opt_passes.py deleted file mode 100644 index 17ec21808..000000000 --- a/dsl/pace/dsl/dace/sdfg_opt_passes.py +++ /dev/null @@ -1,24 +0,0 @@ -import dace - -from pace.util.logging import pace_log - - -def splittable_region_expansion(sdfg: dace.SDFG, verbose: bool = False): - """ - Set certain StencilComputation library nodes to expand to a different - schedule if they contain small splittable regions. - """ - from gt4py.cartesian.gtc.dace.nodes import StencilComputation - - for node, _ in sdfg.all_nodes_recursive(): - if isinstance(node, StencilComputation): - if node.has_splittable_regions() and "corner" in node.label: - node.expansion_specification = [ - "Sections", - "Stages", - "J", - "I", - "K", - ] - if verbose: - pace_log.debug(f"Reordered schedule for {node.label}") diff --git a/dsl/pace/dsl/dace/utils.py b/dsl/pace/dsl/dace/utils.py deleted file mode 100644 index 28d8abe54..000000000 --- a/dsl/pace/dsl/dace/utils.py +++ /dev/null @@ -1,361 +0,0 @@ -import json -import time -from dataclasses import dataclass, field -from typing import Dict, List, Optional - -import dace -import numpy as np -from dace.transformation.helpers import get_parent_map -from gt4py.cartesian.gtscript import PARALLEL, computation, interval - -from pace.dsl.dace.dace_config import DaceConfig -from pace.dsl.stencil import CompilationConfig, FrozenStencil, StencilConfig -from pace.dsl.typing import Float, FloatField -from pace.util._optional_imports import cupy as cp -from pace.util.logging import pace_log - - -# ---------------------------------------------------------- -# Rough timer & log for major operations of DaCe build stack -# ---------------------------------------------------------- -class DaCeProgress: - """Timer and log to track build progress""" - - def __init__(self, config: DaceConfig, label: str): - self.prefix = DaCeProgress.default_prefix(config) - self.prefix = f"[{config.get_orchestrate()}]" - self.label = label - - @classmethod - def default_prefix(cls, config: DaceConfig) -> str: - return f"[{config.get_orchestrate()}]" - - def __enter__(self): - pace_log.debug(f"{self.prefix} {self.label}...") - self.start = time.time() - - def __exit__(self, _type, _val, _traceback): - elapsed = time.time() - self.start - pace_log.debug(f"{self.prefix} {self.label}...{elapsed}s.") - - -def _is_ref(sd: dace.sdfg.SDFG, aname: str): - found = False - for node, state in sd.all_nodes_recursive(): - if not isinstance(state, dace.sdfg.SDFGState): - continue - if state.parent is sd: - if isinstance(node, dace.nodes.AccessNode) and aname == node.data: - found = True - break - - return found - - -# ---------------------------------------------------------- -# Memory analyser from SDFG -# ---------------------------------------------------------- -@dataclass -class ArrayReport: - name: str = "" - total_size_in_bytes: int = 0 - referenced: bool = False - transient: bool = False - pool: bool = False - top_level: bool = False - - -@dataclass -class StorageReport: - name: str = "" - referenced_in_bytes: int = 0 - unreferenced_in_bytes: int = 0 - in_pooled_in_bytes: int = 0 - top_level_in_bytes: int = 0 - details: List[ArrayReport] = field(default_factory=list) - - -def memory_static_analysis( - sdfg: dace.sdfg.SDFG, -) -> Dict[dace.StorageType, StorageReport]: - """Analysis an SDFG for memory pressure. - - The results split memory by type (dace.StorageType) and account for - allocated, unreferenced and top lovel (e.g. top-most SDFG) memory - """ - # We report all allocation type - allocations: Dict[dace.StorageType, StorageReport] = {} - for storage_type in dace.StorageType: - allocations[storage_type] = StorageReport(name=storage_type) - - for sd, aname, arr in sdfg.arrays_recursive(): - array_size_in_bytes = arr.total_size * arr.dtype.bytes - ref = _is_ref(sd, aname) - - # Transient in maps (refrence and not referenced) - if sd is not sdfg and arr.transient: - if arr.pool: - allocations[arr.storage].in_pooled_in_bytes += array_size_in_bytes - allocations[arr.storage].details.append( - ArrayReport( - name=aname, - total_size_in_bytes=array_size_in_bytes, - referenced=ref, - transient=arr.transient, - pool=arr.pool, - top_level=False, - ) - ) - if ref: - allocations[arr.storage].referenced_in_bytes += array_size_in_bytes - else: - allocations[arr.storage].unreferenced_in_bytes += array_size_in_bytes - - # SDFG-level memory (refrence, not referenced and pooled) - elif sd is sdfg: - if arr.pool: - allocations[arr.storage].in_pooled_in_bytes += array_size_in_bytes - allocations[arr.storage].details.append( - ArrayReport( - name=aname, - total_size_in_bytes=array_size_in_bytes, - referenced=ref, - transient=arr.transient, - pool=arr.pool, - top_level=True, - ) - ) - allocations[arr.storage].top_level_in_bytes += array_size_in_bytes - if ref: - allocations[arr.storage].referenced_in_bytes += array_size_in_bytes - else: - allocations[arr.storage].unreferenced_in_bytes += array_size_in_bytes - - return allocations - - -def report_memory_static_analysis( - sdfg: dace.sdfg.SDFG, - allocations: Dict[dace.StorageType, StorageReport], - detail_report=False, -) -> str: - """Create a human readable report form the memory analysis results""" - report = f"{sdfg.name}:\n" - for storage, allocs in allocations.items(): - alloc_in_mb = float(allocs.referenced_in_bytes / (1024 * 1024)) - unref_alloc_in_mb = float(allocs.unreferenced_in_bytes / (1024 * 1024)) - in_pooled_in_mb = float(allocs.in_pooled_in_bytes / (1024 * 1024)) - toplvlalloc_in_mb = float(allocs.top_level_in_bytes / (1024 * 1024)) - if alloc_in_mb or toplvlalloc_in_mb > 0: - report += ( - f"{storage}:\n" - f" Alloc ref {alloc_in_mb:.2f} mb\n" - f" Alloc unref {unref_alloc_in_mb:.2f} mb\n" - f" Pooled {in_pooled_in_mb:.2f} mb\n" - f" Top lvl alloc: {toplvlalloc_in_mb:.2f}mb\n" - ) - if detail_report: - report += "\n" - report += " Referenced\tTransient \tPooled\tTotal size(mb)\tName\n" - for detail in allocs.details: - size_in_mb = float(detail.total_size_in_bytes / (1024 * 1024)) - ref_str = " X " if detail.referenced else " " - transient_str = " X " if detail.transient else " " - pooled_str = " X " if detail.pool else " " - report += ( - f" {ref_str}\t{transient_str}" - f"\t {pooled_str}" - f"\t {size_in_mb:.2f}" - f"\t {detail.name}\n" - ) - - return report - - -def memory_static_analysis_from_path(sdfg_path: str, detail_report=False) -> str: - """Open a SDFG and report the memory analysis""" - sdfg = dace.SDFG.from_file(sdfg_path) - return report_memory_static_analysis( - sdfg, - memory_static_analysis(sdfg), - detail_report=detail_report, - ) - - -# ---------------------------------------------------------- -# Theoritical bandwith from SDFG -# ---------------------------------------------------------- -def copy_defn(q_in: FloatField, q_out: FloatField): - with computation(PARALLEL), interval(...): - q_in = q_out - - -class MaxBandwithBenchmarkProgram: - def __init__(self, size, backend) -> None: - from pace.dsl.dace.orchestration import DaCeOrchestration, orchestrate - - dconfig = DaceConfig(None, backend, orchestration=DaCeOrchestration.BuildAndRun) - c = CompilationConfig(backend=backend) - s = StencilConfig(dace_config=dconfig, compilation_config=c) - self.copy_stencil = FrozenStencil( - func=copy_defn, - origin=(0, 0, 0), - domain=size, - stencil_config=s, - ) - orchestrate(obj=self, config=dconfig) - - def __call__(self, A, B, n: int): - for i in dace.nounroll(range(n)): - self.copy_stencil(A, B) - - -def kernel_theoretical_timing( - sdfg: dace.sdfg.SDFG, - hardware_bw_in_GB_s=None, - backend=None, -) -> Dict[str, float]: - """Compute a lower timing bound for kernels with the following hypothesis: - - - Performance is memory bound, e.g. arithmetic intensity isn't counted - - Hardware bandwidth comes from a GT4Py/DaCe test rather than a spec sheet for - for higher accuracy. Best is to run a copy_stencils on a full domain - - Memory pressure is mostly in read/write from global memory, inner scalar & shared - memory is not counted towards memory movement. - """ - if not hardware_bw_in_GB_s: - size = np.array(sdfg.arrays["__g_self__w"].shape) - print( - f"Calculating experimental hardware bandwith on {size}" - f" arrays at {Float} precision..." - ) - bench = MaxBandwithBenchmarkProgram(size, backend) - if backend == "dace:gpu": - A = cp.ones(size, dtype=Float) - B = cp.ones(size, dtype=Float) - else: - A = np.ones(size, dtype=Float) - B = np.ones(size, dtype=Float) - n = 1000 - m = 4 - dt = [] - # Warm up run (build, allocation) - # to remove from timing the common runtime - bench(A, B, n) - # Time - for _ in range(m): - s = time.time() - bench(A, B, n) - dt.append((time.time() - s) / n) - memory_size_in_b = np.prod(size) * np.dtype(Float).itemsize * 8 - bandwidth_in_bytes_s = memory_size_in_b / np.median(dt) - print( - f"Hardware bandwith computed: {bandwidth_in_bytes_s/(1024*1024*1024)} GB/s" - ) - else: - bandwidth_in_bytes_s = hardware_bw_in_GB_s * 1024 * 1024 * 1024 - print(f"Given hardware bandwith: {bandwidth_in_bytes_s/(1024*1024*1024)} GB/s") - - allmaps = [ - (me, state) - for me, state in sdfg.all_nodes_recursive() - if isinstance(me, dace.nodes.MapEntry) - ] - topmaps = [ - (me, state) for me, state in allmaps if get_parent_map(state, me) is None - ] - - result: Dict[str, float] = {} - for node, state in topmaps: - nsdfg = state.parent - mx = state.exit_node(node) - - # Gather all memory read & write by reading all - # in-node & out-node memory. All in bytes - alldata_in_bytes = sum( - [ - dace.data._prod(e.data.subset.size()) - * nsdfg.arrays[e.data.data].dtype.bytes - for e in state.in_edges(node) - ] - ) - alldata_in_bytes += sum( - [ - dace.data._prod(e.data.subset.size()) - * nsdfg.arrays[e.data.data].dtype.bytes - for e in state.out_edges(mx) - ] - ) - - in_us = 1000 * 1000 - - # Theoretical fastest timing - try: - newresult_in_us = (float(alldata_in_bytes) / bandwidth_in_bytes_s) * in_us - except TypeError: - newresult_in_us = (alldata_in_bytes / bandwidth_in_bytes_s) * in_us - - # We keep sympy import here because sympy is known to be a problematic - # import and an heavy module which should be avoided if possible. - # TODO: refactor it out by shadow-coding the sympy.Max/Eval functions - import sympy - - if node.label in result: - newresult_in_us = sympy.Max(result[node.label], newresult_in_us).expand() - try: - newresult_in_us = float(newresult_in_us) - except TypeError: - pass - - # Bad expansion - if not isinstance(newresult_in_us, sympy.core.numbers.Float) and not isinstance( - newresult_in_us, float - ): - continue - - result[node.label] = float(newresult_in_us) - - return result - - -def report_kernel_theoretical_timing( - timings: Dict[str, float], - human_readable: bool = True, - out_format: Optional[str] = None, -) -> str: - """Produce a human readable or CSV of the kernel timings""" - result_string = f"Maps processed: {len(timings)}.\n" - if human_readable: - result_string += "Timing in microseconds Map name:\n" - result_string += "\n".join(f"{v:.2f}\t{k}," for k, v in sorted(timings.items())) - if out_format == "csv": - csv_string = "" - csv_string += "#Map name,timing in microseconds\n" - csv_string += "\n".join(f"{k},{v}," for k, v in sorted(timings.items())) - with open("kernel_theoretical_timing.csv", "w") as f: - f.write(csv_string) - elif out_format == "json": - with open("kernel_theoretical_timing.json", "w") as f: - json.dump(timings, f, indent=2) - - return result_string - - -def kernel_theoretical_timing_from_path( - sdfg_path: str, - hardware_bw_in_GB_s: Optional[float] = None, - backend: Optional[str] = None, - output_format: Optional[str] = None, -) -> str: - """Load an SDFG and report the theoretical kernel timings""" - print(f"Running kernel_theoretical_timing for {sdfg_path}") - timings = kernel_theoretical_timing( - dace.SDFG.from_file(sdfg_path), - hardware_bw_in_GB_s=hardware_bw_in_GB_s, - backend=backend, - ) - return report_kernel_theoretical_timing( - timings, - human_readable=True, - out_format=output_format, - ) diff --git a/dsl/pace/dsl/dace/wrapped_halo_exchange.py b/dsl/pace/dsl/dace/wrapped_halo_exchange.py deleted file mode 100644 index 7d7eed44f..000000000 --- a/dsl/pace/dsl/dace/wrapped_halo_exchange.py +++ /dev/null @@ -1,73 +0,0 @@ -import dataclasses -from typing import List, Optional - -from pace.dsl.dace.orchestration import dace_inhibitor -from pace.util.communicator import Communicator -from pace.util.halo_updater import HaloUpdater - - -class WrappedHaloUpdater: - """Wrapping the original Halo Updater for critical runtime. - - Because DaCe cannot parse the complexity of the HaloUpdater and - because it cannot pass in Quantity to callback easily, we made a wrapper - that goes around those two problems, using a .get_attr on a cached state - to look up the proper quantities. - """ - - def __init__( - self, - updater: HaloUpdater, - state, - qty_x_names: List[str], - qty_y_names: List[str] = None, - comm: Optional[Communicator] = None, - ) -> None: - self._updater = updater - self._state = state - self._qtx_x_names = qty_x_names - self._qtx_y_names = qty_y_names - self._comm = comm - - @dace_inhibitor - def start(self): - if self._qtx_y_names is None: - if dataclasses.is_dataclass(self._state): - self._updater.start( - [self._state.__getattribute__(x) for x in self._qtx_x_names] - ) - elif isinstance(self._state, dict): - self._updater.start([self._state[x] for x in self._qtx_x_names]) - else: - raise NotImplementedError - else: - if dataclasses.is_dataclass(self._state): - self._updater.start( - [self._state.__getattribute__(x) for x in self._qtx_x_names], - [self._state.__getattribute__(y) for y in self._qtx_y_names], - ) - elif isinstance(self._state, dict): - self._updater.start( - [self._state[x] for x in self._qtx_x_names], - [self._state[y] for y in self._qtx_y_names], - ) - else: - raise NotImplementedError - - @dace_inhibitor - def wait(self): - self._updater.wait() - - @dace_inhibitor - def update(self): - self.start() - self.wait() - - @dace_inhibitor - def interface(self): - assert len(self._qtx_x_names) == 1 - assert len(self._qtx_y_names) == 1 - self._comm.synchronize_vector_interfaces( - self._state.__getattribute__(self._qtx_x_names[0]), - self._state.__getattribute__(self._qtx_y_names[0]), - ) diff --git a/dsl/pace/dsl/gt4py_utils.py b/dsl/pace/dsl/gt4py_utils.py deleted file mode 100644 index 7b033fee7..000000000 --- a/dsl/pace/dsl/gt4py_utils.py +++ /dev/null @@ -1,485 +0,0 @@ -from functools import wraps -from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union - -import gt4py -import numpy as np - -from pace.dsl.typing import DTypes, Field, Float -from pace.util.logging import pace_log - - -try: - import cupy as cp -except ImportError: - cp = None - -# If True, automatically transfers memory between CPU and GPU (see gt4py.storage) -managed_memory = True - -# Number of halo lines for each field and default origin -halo = 3 -origin = (halo, halo, 0) - -# TODO get from field_table -tracer_variables = [ - "qvapor", - "qliquid", - "qrain", - "qice", - "qsnow", - "qgraupel", - "qo3mr", - "qsgs_tke", - "qcld", -] - - -def mark_untested(msg="This is not tested"): - def inner(func) -> Callable[..., Any]: - @wraps(func) - def wrapper(*args, **kwargs) -> Any: - print(f"{func.__name__}: {msg}") - func(*args, **kwargs) - - return wrapper - - return inner - - -def _mask_to_dimensions( - mask: Tuple[bool, ...], shape: Sequence[int] -) -> List[Union[str, int]]: - assert len(mask) == 3 - dimensions: List[Union[str, int]] = [] - for i, axis in enumerate(("I", "J", "K")): - if mask[i]: - dimensions.append(axis) - offset = int(sum(mask)) - dimensions.extend(shape[offset:]) - return dimensions - - -def _translate_origin(origin: Sequence[int], mask: Tuple[bool, ...]) -> Sequence[int]: - if len(origin) == int(sum(mask)): - # Correct length. Assumedd to be correctly specified. - return origin - - assert len(mask) == 3 - final_origin: List[int] = [] - for i, has_axis in enumerate(mask): - if has_axis: - final_origin.append(origin[i]) - - final_origin.extend(origin[len(mask) :]) - return final_origin - - -def make_storage_data( - data: Field, - shape: Optional[Tuple[int, ...]] = None, - origin: Tuple[int, ...] = origin, - *, - backend: str, - dtype: DTypes = Float, - mask: Optional[Tuple[bool, ...]] = None, - start: Tuple[int, ...] = (0, 0, 0), - dummy: Optional[Tuple[int, ...]] = None, - axis: int = 2, - max_dim: int = 3, - read_only: bool = True, -) -> Field: - """Create a new gt4py storage from the given data. - - Args: - data: Data array for new storage - shape: Shape of the new storage. Number of indices should be equal - to number of unmasked axes - origin: Default origin for gt4py stencil calls - dtype: Data type - mask: Tuple indicating the axes used when initializing the storage. - True indicates a masked axis, False is a used axis. - start: Starting points for slices in data copies - dummy: Dummy axes - axis: Axis for 2D to 3D arrays - backend: gt4py backend to use - - Returns: - Field[..., dtype]: New storage - - Examples: - 1) ptop = utils.make_storage_data(top_p, q4_1.shape) - 2) ws3 = utils.make_storage_data(ws3[:, :, -1], shape, origin=(0, 0, 0)) - 3) data_dict[names[i]] = make_storage_data( - data[:, :, :, i], - shape, - origin=origin, - start=start, - dummy=dummy, - axis=axis, - ) - - """ - n_dims = len(data.shape) - if shape is None: - shape = data.shape - - if mask is None: - if not read_only: - default_mask: Tuple[bool, ...] = (True, True, True) - else: - if n_dims == 1: - if axis == 1: - # Convert J-fields to IJ-fields - default_mask = (True, True, False) - shape = (1, shape[axis]) - else: - default_mask = tuple( - [i == axis for i in range(max_dim)] - ) # type: ignore - elif dummy or axis != 2: - default_mask = (True, True, True) - else: - default_mask = (n_dims * (True,)) + ((max_dim - n_dims) * (False,)) - mask = default_mask - - if n_dims == 1: - data = _make_storage_data_1d( - data, shape, start, dummy, axis, read_only, backend=backend - ) - elif n_dims == 2: - data = _make_storage_data_2d( - data, shape, start, dummy, axis, read_only, backend=backend - ) - else: - data = _make_storage_data_3d(data, shape, start, backend=backend) - - storage = gt4py.storage.from_array( - data, - dtype, - backend=backend, - aligned_index=_translate_origin(origin, mask), - dimensions=_mask_to_dimensions(mask, data.shape), - ) - return storage - - -def _make_storage_data_1d( - data: Field, - shape: Tuple[int, ...], - start: Tuple[int, ...] = (0, 0, 0), - dummy: Optional[Tuple[int, ...]] = None, - axis: int = 2, - read_only: bool = True, - *, - backend: str, -) -> Field: - # axis refers to a repeated axis, dummy refers to a singleton axis - axis = min(axis, len(shape) - 1) - buffer = zeros(shape[axis], backend=backend) - if dummy: - axis = list(set((0, 1, 2)).difference(dummy))[0] - - kstart = start[2] - buffer[kstart : kstart + len(data)] = asarray(data, type(buffer)) - - if not read_only: - tile_spec = list(shape) - tile_spec[axis] = 1 - if axis == 2: - buffer = tile(buffer, tuple(tile_spec)) - elif axis == 1: - x = repeat(buffer[np.newaxis, :], shape[0], axis=0) - buffer = repeat(x[:, :, np.newaxis], shape[2], axis=2) - else: - y = repeat(buffer[:, np.newaxis], shape[1], axis=1) - buffer = repeat(y[:, :, np.newaxis], shape[2], axis=2) - elif axis == 1: - buffer = buffer.reshape((1, buffer.shape[0])) - - return buffer - - -def _make_storage_data_2d( - data: Field, - shape: Tuple[int, ...], - start: Tuple[int, ...] = (0, 0, 0), - dummy: Optional[Tuple[int, ...]] = None, - axis: int = 2, - read_only: bool = True, - *, - backend: str, -) -> Field: - # axis refers to which axis should be repeated (when making a full 3d data), - # dummy refers to a singleton axis - do_reshape = dummy or axis != 2 - if do_reshape: - d_axis = dummy[0] if dummy else axis - shape2d = shape[:d_axis] + shape[d_axis + 1 :] - else: - shape2d = shape[0:2] - - start1, start2 = start[0:2] - size1, size2 = data.shape - buffer = zeros(shape2d, backend=backend) - buffer[start1 : start1 + size1, start2 : start2 + size2] = asarray( - data, type(buffer) - ) - - if not read_only: - buffer = repeat(buffer[:, :, np.newaxis], shape[axis], axis=2) - if axis != 2: - buffer = moveaxis(buffer, 2, axis) - elif do_reshape: - buffer = buffer.reshape(shape) - - return buffer - - -def _make_storage_data_3d( - data: Field, - shape: Tuple[int, ...], - start: Tuple[int, ...] = (0, 0, 0), - *, - backend: str, -) -> Field: - istart, jstart, kstart = start - isize, jsize, ksize = data.shape - buffer = zeros(shape, backend=backend) - buffer[ - istart : istart + isize, - jstart : jstart + jsize, - kstart : kstart + ksize, - ] = asarray(data, type(buffer)) - return buffer - - -def make_storage_from_shape( - shape: Tuple[int, ...], - origin: Tuple[int, ...] = origin, - *, - backend: str, - dtype: DTypes = Float, - mask: Optional[Tuple[bool, ...]] = None, -) -> Field: - """Create a new gt4py storage of a given shape filled with zeros. - - Args: - shape: Shape of the new storage - origin: Default origin for gt4py stencil calls - dtype: Data type - mask: Tuple indicating the axes used when initializing the storage - backend: gt4py backend to use when making the storage - - Returns: - Field[..., dtype]: New storage - - Examples: - 1) utmp = utils.make_storage_from_shape(ua.shape) - 2) qx = utils.make_storage_from_shape( - qin.shape, origin=(grid().is_, grid().jsd, kstart) - ) - 3) q_out = utils.make_storage_from_shape(q_in.shape, origin,) - """ - if not mask: - n_dims = len(shape) - if n_dims == 1: - mask = (False, False, True) # Assume 1D is a k-field - else: - mask = (n_dims * (True,)) + ((3 - n_dims) * (False,)) - storage = gt4py.storage.zeros( - shape, - dtype, - backend=backend, - aligned_index=_translate_origin(origin, mask), - dimensions=_mask_to_dimensions(mask, shape), - ) - return storage - - -def make_storage_dict( - data: Field, - shape: Optional[Tuple[int, ...]] = None, - origin: Tuple[int, ...] = origin, - start: Tuple[int, ...] = (0, 0, 0), - dummy: Optional[Tuple[int, ...]] = None, - names: Optional[List[str]] = None, - axis: int = 2, - *, - backend: str, -) -> Dict[str, "Field"]: - assert names is not None, "for 4d variable storages, specify a list of names" - if shape is None: - shape = data.shape - data_dict: Dict[str, Field] = dict() - for i in range(data.shape[3]): - data_dict[names[i]] = make_storage_data( - squeeze(data[:, :, :, i]), - shape, - origin=origin, - start=start, - dummy=dummy, - axis=axis, - backend=backend, - ) - return data_dict - - -def storage_dict(st_dict, names, shape, origin, *, backend: str): - for name in names: - st_dict[name] = make_storage_from_shape(shape, origin, backend=backend) - - -def get_kstarts(column_info, npz): - compare = None - kstarts = [] - for k in range(npz): - column_vals = {} - for q, v in column_info.items(): - if k < len(v): - column_vals[q] = v[k] - if column_vals != compare: - kstarts.append(k) - compare = column_vals - for i in range(len(kstarts) - 1): - kstarts[i] = (kstarts[i], kstarts[i + 1] - kstarts[i]) - kstarts[-1] = (kstarts[-1], npz - kstarts[-1]) - return kstarts - - -def k_split_run(func, data, k_indices, splitvars_values): - for ki, nk in k_indices: - splitvars = {} - for name, value_array in splitvars_values.items(): - splitvars[name] = value_array[ki] - data.update(splitvars) - data["kstart"] = ki - data["nk"] = nk - pace_log.debug( - "Running kstart: {}, num k:{}, variables:{}".format(ki, nk, splitvars) - ) - func(**data) - - -def asarray(array, to_type=np.ndarray, dtype=None, order=None): - if cp and (isinstance(array, list)): - if to_type is np.ndarray: - order = "F" if order is None else order - return cp.asnumpy(array, order=order) - else: - return cp.asarray(array, dtype, order) - elif isinstance(array, list): - if to_type is np.ndarray: - return np.asarray(array, dtype, order) - else: - return cp.asarray(array, dtype, order) - if cp and ( - isinstance(array, memoryview) - or ( - hasattr(array, "data") - and isinstance(array.data, (cp.ndarray, cp.cuda.memory.MemoryPointer)) - ) - ): - if to_type is np.ndarray: - order = "F" if order is None else order - return cp.asnumpy(array, order=order) - else: - return cp.asarray(array, dtype, order) - else: - if to_type is np.ndarray: - return np.asarray(array, dtype, order) - else: - return cp.asarray(array, dtype, order) - - -def is_gpu_backend(backend: str) -> bool: - return gt4py.cartesian.backend.from_name(backend).storage_info["device"] == "gpu" - - -def zeros(shape, dtype=Float, *, backend: str): - storage_type = cp.ndarray if is_gpu_backend(backend) else np.ndarray - xp = cp if cp and storage_type is cp.ndarray else np - return xp.zeros(shape, dtype=dtype) - - -def sum(array, axis=None, dtype=Float, out=None, keepdims=False): - xp = cp if cp and type(array) is cp.ndarray else np - return xp.sum(array, axis, dtype, out, keepdims) - - -def repeat(array, repeats, axis=None): - xp = cp if cp and type(array) is cp.ndarray else np - return xp.repeat(array, repeats, axis) - - -def index(array, key): - return asarray(array, type(key))[key] - - -def moveaxis(array, source: int, destination: int): - xp = cp if cp and type(array) is cp.ndarray else np - return xp.moveaxis(array, source, destination) - - -def tile(array, reps: Union[int, Tuple[int, ...]]): - xp = cp if cp and type(array) is cp.ndarray else np - return xp.tile(array, reps) - - -def squeeze(array, axis: Union[int, Tuple[int]] = None): - xp = cp if cp and type(array) is cp.ndarray else np - return xp.squeeze(array, axis) - - -def reshape(array, new_shape): - if array.shape != new_shape: - old_dims = len(array.shape) - new_dims = len(new_shape) - if old_dims < new_dims: - # Upcast using repeat... - if old_dims == 2: # IJ -> IJK - return repeat(array[:, :, np.newaxis], new_shape[2], axis=2) - else: # K -> IJK - arr_2d = repeat(array[:, np.newaxis], new_shape[1], axis=1) - return repeat(arr_2d[:, :, np.newaxis], new_shape[2], axis=2) - else: - return array.reshape(new_shape) - return array - - -def unique( - array, - return_index: bool = False, - return_inverse: bool = False, - return_counts: bool = False, - axis: Union[int, Tuple[int]] = None, -): - xp = cp if cp and type(array) is cp.ndarray else np - return xp.unique(array, return_index, return_inverse, return_counts, axis) - - -def stack(tup, axis: int = 0, out=None): - array_tup = [] - for array in tup: - array_tup.append(array) - xp = cp if cp and type(array_tup[0]) is cp.ndarray else np - return xp.stack(array_tup, axis, out) - - -def device_sync(backend: str) -> None: - if cp and is_gpu_backend(backend): - cp.cuda.Device(0).synchronize() - - -def split_cartesian_into_storages(var: np.ndarray) -> Sequence[np.ndarray]: - """ - Provided a storage of dims [X_DIM, Y_DIM, CARTESIAN_DIM] - or [X_INTERFACE_DIM, Y_INTERFACE_DIM, CARTESIAN_DIM] - Split it into separate 2D storages for each cartesian - dimension, and return these in a list. - """ - var_data = [] - for cart in range(3): - var_data.append( - asarray(var, type(var))[:, :, cart], - ) - return var_data diff --git a/dsl/pace/dsl/stencil.py b/dsl/pace/dsl/stencil.py deleted file mode 100644 index 29a66e15f..000000000 --- a/dsl/pace/dsl/stencil.py +++ /dev/null @@ -1,1005 +0,0 @@ -import copy -import dataclasses -import inspect -from typing import ( - Any, - Callable, - Dict, - Iterable, - List, - Mapping, - Optional, - Sequence, - Tuple, - Type, - Union, - cast, -) - -import dace -import gt4py -import numpy as np -from gt4py.cartesian import gtscript -from gt4py.cartesian.gtc.passes.oir_pipeline import DefaultPipeline, OirPipeline - -import pace.util -from pace.dsl.dace.orchestration import SDFGConvertible -from pace.dsl.stencil_config import CompilationConfig, RunMode, StencilConfig -from pace.dsl.typing import Float, Index3D, cast_to_index3d -from pace.util import testing -from pace.util.decomposition import block_waiting_for_compilation, unblock_waiting_tiles -from pace.util.mpi import MPI - - -try: - import cupy as cp -except ImportError: - cp = np - - -def report_difference(args, kwargs, args_copy, kwargs_copy, function_name, gt_id): - report_head = f"comparing against numpy for func {function_name}, gt_id {gt_id}:" - report_segments = [] - for i, (arg, numpy_arg) in enumerate(zip(args, args_copy)): - if isinstance(arg, pace.util.Quantity): - arg = arg.data - numpy_arg = numpy_arg.data - if isinstance(arg, np.ndarray): - report_segments.append(report_diff(arg, numpy_arg, label=f"arg {i}")) - for name in kwargs: - if isinstance(kwargs[name], pace.util.Quantity): - kwarg = kwargs[name].data - numpy_kwarg = kwargs_copy[name].data - else: - kwarg = kwargs[name] - numpy_kwarg = kwargs_copy[name] - if isinstance(kwarg, np.ndarray): - report_segments.append( - report_diff(kwarg, numpy_kwarg, label=f"kwarg {name}") - ) - report_body = "".join(report_segments) - if len(report_body) > 0: - print("") # newline - print(report_head + report_body) - - -def report_diff(arg: np.ndarray, numpy_arg: np.ndarray, label) -> str: - metric_err = testing.compare_arr(arg, numpy_arg) - nans_match = np.logical_and(np.isnan(arg), np.isnan(numpy_arg)) - n_points = np.product(arg.shape) - failures_14 = n_points - np.sum( - np.logical_or( - nans_match, - metric_err < 1e-14, - ) - ) - failures_10 = n_points - np.sum( - np.logical_or( - nans_match, - metric_err < 1e-10, - ) - ) - failures_8 = n_points - np.sum( - np.logical_or( - nans_match, - metric_err < 1e-8, - ) - ) - greatest_error = np.max(metric_err[~np.isnan(metric_err)]) - if greatest_error == 0.0 and failures_14 == 0: - report = "" - else: - report = f"\n {label}: " - report += f"max_err={greatest_error}" - if failures_14 > 0: - report += f" 1e-14 failures: {failures_14}" - if failures_10 > 0: - report += f" 1e-10 failures: {failures_10}" - if failures_8 > 0: - report += f" 1e-8 failures: {failures_8}" - return report - - -@dataclasses.dataclass -class TimingCollector: - """ - Attributes: - build_info: contains info about the generation process for each stencil. - exec_info: contains info about the execution of each stencil. - """ - - build_info: Dict[str, dict] = dataclasses.field(default_factory=dict) - exec_info: Dict[str, Any] = dataclasses.field( - default_factory=lambda: {"__aggregate_data": True} - ) - - def build_report(self, key: str = "build_time", **kwargs) -> str: - return type(self)._show_report( - self.build_info, self.build_info.keys(), key, **kwargs - ) - - def exec_report(self, key: str = "total_run_time", **kwargs) -> str: - # NOTE: Uses the build_info keys to distinguish stencils - return type(self)._show_report( - self.exec_info, self.build_info.keys(), key, **kwargs - ) - - @staticmethod - def _show_report( - infos: Dict[str, Any], - keys: Iterable[str], - secondary_key: str, - *, - name_width: int = 40, - bar_width: int = 40, - delimiter: str = " | ", - show_bar: bool = True, - reverse: bool = True, - digits: int = 3, - ) -> str: - assert name_width > 10 - - data = [(key, infos[key][secondary_key]) for key in keys] - sorted_data = tuple( - sorted(data, key=lambda name_time: name_time[1], reverse=reverse) - ) - max_val = sorted_data[0 if reverse else -1][1] - - format = f".{digits}e" - - outputs: List[str] = [f"Total: {sum(d[1] for d in data):{format}}"] - for name, val in sorted_data: - if len(name) > name_width: - width = int(name_width / 2) - 3 - disp_name = f"{name[:width]}...{name[-width:]:{format}}" - else: - disp_name = name - line = f"{disp_name.rjust(name_width)}{delimiter}{val:{format}}" - if show_bar and max_val > 0: - bar_data = bar = "â–ˆ" * int(val / max_val * bar_width) - line += f"{delimiter}{bar_data}" - outputs.append(line) - - return "\n".join(outputs) - - -class CompareToNumpyStencil: - """ - A wrapper over FrozenStencil which executes a numpy version of the stencil as well, - and compares the results. - """ - - def __init__( - self, - func: Callable[..., None], - origin: Union[Tuple[int, ...], Mapping[str, Tuple[int, ...]]], - domain: Tuple[int, ...], - stencil_config: StencilConfig, - externals: Optional[Mapping[str, Any]] = None, - skip_passes: Optional[Tuple[str, ...]] = None, - timing_collector: Optional[TimingCollector] = None, - comm: Optional[pace.util.Comm] = None, - ): - self._actual = FrozenStencil( - func=func, - origin=origin, - domain=domain, - stencil_config=stencil_config, - externals=externals, - skip_passes=skip_passes, - timing_collector=timing_collector, - comm=comm, - ) - compilation_config = CompilationConfig( - backend="numpy", - rebuild=stencil_config.compilation_config.rebuild, - validate_args=stencil_config.compilation_config.validate_args, - format_source=True, - device_sync=None, - run_mode=RunMode.BuildAndRun, - use_minimal_caching=False, - ) - numpy_stencil_config = StencilConfig( - dace_config=stencil_config.dace_config, - compilation_config=compilation_config, - ) - self._numpy = FrozenStencil( - func=func, - origin=origin, - domain=domain, - stencil_config=numpy_stencil_config, - externals=externals, - skip_passes=skip_passes, - timing_collector=timing_collector, - comm=comm, - ) - self._func_name = func.__name__ - - def __call__( - self, - *args, - **kwargs, - ) -> None: - args_copy = copy.deepcopy(args) - kwargs_copy = copy.deepcopy(kwargs) - self._actual(*args, **kwargs) - self._numpy(*args_copy, **kwargs_copy) - report_difference( - args, - kwargs, - args_copy, - kwargs_copy, - self._func_name, - self._actual.stencil_object._gt_id_, - ) - - -def _stencil_object_name(stencil_object) -> str: - """Returns a unique name for each gt4py stencil object, including the hash.""" - return type(stencil_object).__name__ - - -def get_pair_rank(rank: int, size: int): - dycore_ranks = size // 2 - if rank < dycore_ranks: - return rank + dycore_ranks - else: - return rank - dycore_ranks - - -def compare_ranks(comm: pace.util.Comm, data) -> Mapping[str, int]: - rank = comm.Get_rank() - size = comm.Get_size() - pair_rank = get_pair_rank(rank, size) - differences = {} - for name, maybe_array in sorted(data.items(), key=lambda x: x[0]): - if isinstance(maybe_array, pace.util.Quantity): - maybe_array = maybe_array.data - if hasattr(maybe_array, "data") and isinstance(maybe_array.data, np.ndarray): - array = maybe_array.data - other = comm.sendrecv(array, pair_rank) - arr_diffs = np.sum(np.logical_and(~np.isnan(array), array != other)) - if arr_diffs > 0: - print(name, rank, pair_rank, array, other) - differences[name] = arr_diffs - return differences - - -class FrozenStencil(SDFGConvertible): - """ - Wrapper for gt4py stencils which stores origin and domain at compile time, - and uses their stored values at call time. - - This is useful when the stencil itself is meant to be used on a certain - grid, for example if a compile-time external variable is tied to the - values of origin and domain. - """ - - def __init__( - self, - func: Callable[..., None], - origin: Union[Tuple[int, ...], Mapping[str, Tuple[int, ...]]], - domain: Tuple[int, ...], - stencil_config: StencilConfig, - externals: Optional[Mapping[str, Any]] = None, - skip_passes: Tuple[str, ...] = (), - timing_collector: Optional[TimingCollector] = None, - comm: Optional[pace.util.Comm] = None, - ): - """ - Args: - func: stencil definition function - origin: gt4py origin to use at call time - domain: gt4py domain to use at call time - stencil_config: container for stencil configuration - externals: compile-time external variables required by stencil - skip_passes: compiler passes to skip when building stencil - timing_collector: Optional object that accumulates timings - comm: if given, inputs and outputs will be compared to the "twin" - rank of this rank - """ - if isinstance(origin, tuple): - origin = cast_to_index3d(origin) - origin = cast(Union[Index3D, Mapping[str, Tuple[int, ...]]], origin) - self.origin = origin - self.domain: Index3D = cast_to_index3d(domain) - self.stencil_config: StencilConfig = stencil_config - self.comm = comm - - if timing_collector is None: - self._timing_collector = TimingCollector() - else: - self._timing_collector = timing_collector - - if externals is None: - externals = {} - self.externals = externals - self._func_name = func.__name__ - stencil_kwargs = self.stencil_config.stencil_kwargs( - skip_passes=skip_passes, func=func - ) - self.stencil_object = None - - self._argument_names = tuple(inspect.getfullargspec(func).args) - - if "dace" in self.stencil_config.compilation_config.backend: - dace.Config.set( - "default_build_folder", - value="{gt_root}/{gt_cache}/dacecache".format( - gt_root=gt4py.cartesian.config.cache_settings["root_path"], - gt_cache=gt4py.cartesian.config.cache_settings["dir_name"], - ), - ) - - assert ( - len(self._argument_names) > 0 - ), "A stencil with no arguments? You may be double decorating" - - # Keep compilation at __init__ if we are not orchestrated. - # If we orchestrate, move the compilation at call time to make sure - # disable_codegen do not lead to call to uncompiled stencils, which fails - # silently - if self.stencil_config.dace_config.is_dace_orchestrated(): - self.stencil_object = gtscript.lazy_stencil( - definition=func, - externals=externals, - dtypes={float: Float}, - **stencil_kwargs, - build_info=(build_info := {}), # type: ignore - ) - else: - compilation_config = stencil_config.compilation_config - if ( - compilation_config.use_minimal_caching - and not compilation_config.is_compiling - and compilation_config.run_mode != RunMode.Run - ): - block_waiting_for_compilation(MPI.COMM_WORLD, compilation_config) - - self.stencil_object = gtscript.stencil( - definition=func, - externals=externals, - dtypes={float: Float}, - **stencil_kwargs, - build_info=(build_info := {}), - ) - - if ( - compilation_config.use_minimal_caching - and compilation_config.is_compiling - and compilation_config.run_mode != RunMode.Run - ): - unblock_waiting_tiles(MPI.COMM_WORLD) - - self._timing_collector.build_info[ - _stencil_object_name(self.stencil_object) - ] = build_info - field_info = self.stencil_object.field_info - - self._field_origins: Dict[ - str, Tuple[int, ...] - ] = FrozenStencil._compute_field_origins(field_info, self.origin) - """mapping from field names to field origins""" - - self._stencil_run_kwargs: Dict[str, Any] = { - "_origin_": self._field_origins, - "_domain_": self.domain, - } - - self._written_fields: List[str] = FrozenStencil._get_written_fields(field_info) - - if stencil_config.compilation_config.run_mode == RunMode.Build: - - def nothing_function(*args, **kwargs): - pass - - setattr(self, "__call__", nothing_function) - - def __call__(self, *args, **kwargs) -> None: - args_list = list(args) - _convert_quantities_to_storage(args_list, kwargs) - args = tuple(args_list) - - args_as_kwargs = dict(zip(self._argument_names, args)) - if self.comm is not None: - differences = compare_ranks(self.comm, {**args_as_kwargs, **kwargs}) - if len(differences) > 0: - raise ValueError( - f"rank {self.comm.Get_rank()} has differences {differences} " - f"before calling {self._func_name}" - ) - if self.stencil_config.compilation_config.validate_args: - if __debug__ and "origin" in kwargs: - raise TypeError("origin cannot be passed to FrozenStencil call") - if __debug__ and "domain" in kwargs: - raise TypeError("domain cannot be passed to FrozenStencil call") - self.stencil_object( - *args, - **kwargs, - origin=self._field_origins, - domain=self.domain, - validate_args=True, - exec_info=self._timing_collector.exec_info, - ) - else: - self.stencil_object.run( - **args_as_kwargs, - **kwargs, - **self._stencil_run_kwargs, - exec_info=self._timing_collector.exec_info, - ) - if self.comm is not None: - differences = compare_ranks(self.comm, {**args_as_kwargs, **kwargs}) - if len(differences) > 0: - raise ValueError( - f"rank {self.comm.Get_rank()} has differences {differences} " - f"after calling {self._func_name}" - ) - - @classmethod - def _compute_field_origins( - cls, field_info_mapping, origin: Union[Index3D, Mapping[str, Tuple[int, ...]]] - ) -> Dict[str, Tuple[int, ...]]: - """ - Computes the origin for each field in the stencil call. - - Args: - field_info_mapping: from stencil.field_info, a mapping which gives the - dimensionality of each input field - origin: the (i, j, k) coordinate of the origin - - Returns: - origin_mapping: a mapping from field names to origins - """ - if isinstance(origin, tuple): - field_origins: Dict[str, Tuple[int, ...]] = {"_all_": origin} - origin_tuple: Tuple[int, ...] = origin - else: - field_origins = {**origin} - origin_tuple = origin["_all_"] - field_names = tuple(field_info_mapping.keys()) - for i, field_name in enumerate(field_names): - if field_name not in field_origins: - field_info = field_info_mapping[field_name] - if field_info is not None: - field_origin_list = [] - for ax in field_info.axes: - origin_index = {"I": 0, "J": 1, "K": 2}[ax] - field_origin_list.append(origin_tuple[origin_index]) - field_origin = tuple(field_origin_list) - else: - field_origin = origin_tuple - field_origins[field_name] = field_origin - return field_origins - - @classmethod - def _get_written_fields(cls, field_info) -> List[str]: - """Returns the list of fields that are written. - - Args: - field_info: field_info attribute of gt4py stencil object - """ - write_fields = [ - field_name - for field_name in field_info - if field_info[field_name] - and bool( - field_info[field_name].access - & gt4py.cartesian.definitions.AccessKind.WRITE # type: ignore - ) - ] - return write_fields - - @classmethod - def _get_oir_pipeline(cls, skip_passes: Sequence[str]) -> OirPipeline: - step_map = {step.__name__: step for step in DefaultPipeline.all_steps()} - skip_steps = [step_map[pass_name] for pass_name in skip_passes] - return DefaultPipeline(skip=skip_steps) - - def __sdfg__(self, *args, **kwargs): - """Implemented SDFG generation""" - args_as_kwargs = dict(zip(self._argument_names, args)) - return self.stencil_object.__sdfg__( - origin=self._field_origins, - domain=self.domain, - **args_as_kwargs, - **kwargs, - ) - - def __sdfg_signature__(self): - """Implemented SDFG signature lookup""" - return self.stencil_object.__sdfg_signature__() - - def __sdfg_closure__(self, *args, **kwargs): - """Implemented SDFG closure build""" - return self.stencil_object.__sdfg_closure__(*args, **kwargs) - - def closure_resolver(self, constant_args, given_args, parent_closure=None): - """Implemented SDFG closure resolver build""" - return self.stencil_object.closure_resolver( - constant_args, given_args, parent_closure=parent_closure - ) - - -def _convert_quantities_to_storage(args, kwargs): - for i, arg in enumerate(args): - try: - # Check that 'dims' is an attribute of arg. If so, - # this means it's a pace.util.Quantity, so we need - # to pull off the ndarray. - arg.dims - args[i] = arg.data - except AttributeError: - pass - for name, arg in kwargs.items(): - try: - # Check that 'dims' is an attribute of arg. If so, - # this means it's a pace.util.Quantity, so we need - # to pull off the ndarray. - arg.dims - kwargs[name] = arg.data - except AttributeError: - pass - - -class GridIndexing: - """ - Provides indices for cell-centered variables with halos. - - These indices can be used with horizontal interface variables by adding 1 - to the domain shape along any interface axis. - """ - - def __init__( - self, - domain: Index3D, - n_halo: int, - south_edge: bool, - north_edge: bool, - west_edge: bool, - east_edge: bool, - ): - """ - Initialize a grid indexing object. - - Args: - domain: size of the compute domain for cell-centered variables - n_halo: number of halo points - south_edge: whether the current rank is on the south edge of a tile - north_edge: whether the current rank is on the north edge of a tile - west_edge: whether the current rank is on the west edge of a tile - east_edge: whether the current rank is on the east edge of a tile - """ - self.origin = (n_halo, n_halo, 0) - self.n_halo = n_halo - self.domain = domain - self.south_edge = south_edge - self.north_edge = north_edge - self.west_edge = west_edge - self.east_edge = east_edge - - @property - def domain(self): - return self._domain - - @domain.setter - def domain(self, domain): - self._domain = domain - self._sizer = pace.util.SubtileGridSizer( - nx=domain[0], - ny=domain[1], - nz=domain[2], - n_halo=self.n_halo, - extra_dim_lengths={}, - ) - - @classmethod - def from_sizer_and_communicator( - cls, sizer: pace.util.GridSizer, comm: pace.util.Communicator - ) -> "GridIndexing": - # TODO: if this class is refactored to split off the *_edge booleans, - # this init routine can be refactored to require only a GridSizer - domain = cast( - Tuple[int, int, int], - sizer.get_extent([pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM]), - ) - south_edge = comm.tile.partitioner.on_tile_bottom(comm.rank) - north_edge = comm.tile.partitioner.on_tile_top(comm.rank) - west_edge = comm.tile.partitioner.on_tile_left(comm.rank) - east_edge = comm.tile.partitioner.on_tile_right(comm.rank) - return cls( - domain=domain, - n_halo=sizer.n_halo, - south_edge=south_edge, - north_edge=north_edge, - west_edge=west_edge, - east_edge=east_edge, - ) - - @property - def max_shape(self): - """ - Maximum required storage shape, corresponding to the shape of a cell-corner - variable with maximum halo points. - - This should rarely be required, consider using appropriate calls to helper - methods that get the correct shape for your particular variable. - """ - # need to add back origin as buffer points, what we're returning here - # isn't a domain - it's an array size - return self.domain_full(add=(1, 1, 1 + self.origin[2])) - - @property - def isc(self): - """start of the compute domain along the x-axis""" - return self.origin[0] - - @property - def iec(self): - """last index of the compute domain along the x-axis""" - return self.origin[0] + self.domain[0] - 1 - - @property - def jsc(self): - """start of the compute domain along the y-axis""" - return self.origin[1] - - @property - def jec(self): - """last index of the compute domain along the y-axis""" - return self.origin[1] + self.domain[1] - 1 - - @property - def isd(self): - """start of the full domain including halos along the x-axis""" - return self.origin[0] - self.n_halo - - @property - def ied(self): - """index of the last data point along the x-axis""" - return self.isd + self.domain[0] + 2 * self.n_halo - 1 - - @property - def jsd(self): - """start of the full domain including halos along the y-axis""" - return self.origin[1] - self.n_halo - - @property - def jed(self): - """index of the last data point along the y-axis""" - return self.jsd + self.domain[1] + 2 * self.n_halo - 1 - - @property - def nw_corner(self): - return self.north_edge and self.west_edge - - @property - def sw_corner(self): - return self.south_edge and self.west_edge - - @property - def ne_corner(self): - return self.north_edge and self.east_edge - - @property - def se_corner(self): - return self.south_edge and self.east_edge - - def origin_full(self, add: Index3D = (0, 0, 0)): - """ - Returns the origin of the full domain including halos, plus an optional offset. - """ - return (self.isd + add[0], self.jsd + add[1], self.origin[2] + add[2]) - - def origin_compute(self, add: Index3D = (0, 0, 0)): - """ - Returns the origin of the compute domain, plus an optional offset - """ - return (self.isc + add[0], self.jsc + add[1], self.origin[2] + add[2]) - - def domain_full(self, add: Index3D = (0, 0, 0)): - """ - Returns the shape of the full domain including halos, plus an optional offset. - """ - return ( - self.ied + 1 - self.isd + add[0], - self.jed + 1 - self.jsd + add[1], - self.domain[2] + add[2], - ) - - def domain_compute(self, add: Index3D = (0, 0, 0)): - """ - Returns the shape of the compute domain, plus an optional offset. - """ - return ( - self.iec + 1 - self.isc + add[0], - self.jec + 1 - self.jsc + add[1], - self.domain[2] + add[2], - ) - - def axis_offsets( - self, - origin: Tuple[int, ...], - domain: Tuple[int, ...], - ) -> Dict[str, Any]: - if self.west_edge: - i_start = gtscript.I[0] + self.origin[0] - origin[0] - else: - i_start = gtscript.I[0] - np.iinfo(np.int16).max - - if self.east_edge: - i_end = ( - gtscript.I[-1] - + (self.origin[0] + self.domain[0]) - - (origin[0] + domain[0]) - ) - else: - i_end = gtscript.I[-1] + np.iinfo(np.int16).max - - if self.south_edge: - j_start = gtscript.J[0] + self.origin[1] - origin[1] - else: - j_start = gtscript.J[0] - np.iinfo(np.int16).max - - if self.north_edge: - j_end = ( - gtscript.J[-1] - + (self.origin[1] + self.domain[1]) - - (origin[1] + domain[1]) - ) - else: - j_end = gtscript.J[-1] + np.iinfo(np.int16).max - - return { - "i_start": i_start, - "local_is": gtscript.I[0] + self.isc - origin[0], - "i_end": i_end, - "local_ie": gtscript.I[-1] + self.iec - origin[0] - domain[0] + 1, - "j_start": j_start, - "local_js": gtscript.J[0] + self.jsc - origin[1], - "j_end": j_end, - "local_je": gtscript.J[-1] + self.jec - origin[1] - domain[1] + 1, - } - - def get_origin_domain( - self, dims: Sequence[str], halos: Sequence[int] = tuple() - ) -> Tuple[Tuple[int, ...], Tuple[int, ...]]: - """ - Get the origin and domain for a computation that occurs over a certain grid - configuration (given by dims) and a certain number of halo points. - - Args: - dims: dimension names, using dimension constants from pace.util - halos: number of halo points for each dimension, defaults to zero - - Returns: - origin: origin of the computation - domain: shape of the computation - """ - origin = self._origin_from_dims(dims) - domain = list(self._sizer.get_extent(dims)) - for i, n in enumerate(halos): - origin[i] -= n - domain[i] += 2 * n - return tuple(origin), tuple(domain) - - def _origin_from_dims(self, dims: Iterable[str]) -> List[int]: - return_origin = [] - for dim in dims: - if dim in pace.util.X_DIMS: - return_origin.append(self.origin[0]) - elif dim in pace.util.Y_DIMS: - return_origin.append(self.origin[1]) - elif dim in pace.util.Z_DIMS: - return_origin.append(self.origin[2]) - return return_origin - - def get_shape( - self, dims: Sequence[str], halos: Sequence[int] = tuple() - ) -> Tuple[int, ...]: - """ - Get the storage shape required for an array with the given dimensions - which is accessed up to a given number of halo points. - - Args: - dims: dimension names, using dimension constants from pace.util - halos: number of halo points for each dimension, defaults to zero - - Returns: - origin: origin of the computation - domain: shape of the computation - """ - shape = list(self._sizer.get_extent(dims)) - for i, d in enumerate(dims): - # need n_halo points at the start of the domain, regardless of whether - # they are read, so that data is aligned in memory - if d in (pace.util.X_DIMS + pace.util.Y_DIMS): - shape[i] += self.n_halo - for i, n in enumerate(halos): - shape[i] += n - return tuple(shape) - - def restrict_vertical(self, k_start=0, nk=None) -> "GridIndexing": - """ - Returns a copy of itself with modified vertical origin and domain. - - Args: - k_start: offset to apply to current vertical origin, must be - greater than 0 and less than the size of the vertical domain - nk: new vertical domain size as a number of grid cells, - defaults to remaining grid cells in the current domain, - can be at most the size of the vertical domain minus k_start - """ - if k_start < 0: - raise ValueError("k_start must be positive") - if k_start > self.domain[2]: - raise ValueError( - "k_start must be less than the number of vertical levels " - f"(received {k_start} for {self.domain[2]} vertical levels" - ) - if nk is None: - nk = self.domain[2] - k_start - elif nk < 0: - raise ValueError("number of vertical levels should be positive") - elif nk > (self.domain[2] - k_start): - raise ValueError( - "nk can be at most the size of the vertical domain minus k_start" - ) - - new = GridIndexing( - self.domain[:2] + (nk,), - self.n_halo, - self.south_edge, - self.north_edge, - self.west_edge, - self.east_edge, - ) - new.origin = self.origin[:2] + (self.origin[2] + k_start,) - return new - - -class StencilFactory: - """Configurable class which creates stencil objects.""" - - def __init__( - self, - config: StencilConfig, - grid_indexing: GridIndexing, - comm: Optional[pace.util.Comm] = None, - ): - """ - Args: - config: gt4py-specific stencil configuration - grid_indexing: configuration for domain and halo indexing - comm: if given, stencils will compare all data before and after - stencil execution to their "pair" rank on the comm. This is very - expensive and only used for debugging. - """ - self.config: StencilConfig = config - self.grid_indexing: GridIndexing = grid_indexing - self.timing_collector = TimingCollector() - self.comm = comm - - @property - def backend(self): - return self.config.compilation_config.backend - - def from_origin_domain( - self, - func: Callable[..., None], - origin: Union[Tuple[int, ...], Mapping[str, Tuple[int, ...]]], - domain: Tuple[int, ...], - externals: Optional[Mapping[str, Any]] = None, - skip_passes: Tuple[str, ...] = (), - ) -> Union[FrozenStencil, CompareToNumpyStencil]: - """ - Args: - func: stencil definition function - origin: gt4py origin to use at call time - domain: gt4py domain to use at call time - stencil_config: container for stencil configuration - externals: compile-time external variables required by stencil - skip_passes: compiler passes to skip when building stencil - """ - if self.config.compare_to_numpy: - cls: Type = CompareToNumpyStencil - else: - cls = FrozenStencil - return cls( - func=func, - origin=origin, - domain=domain, - stencil_config=self.config, - externals=externals, - skip_passes=skip_passes, - timing_collector=self.timing_collector, - comm=self.comm, - ) - - def from_dims_halo( - self, - func: Callable[..., None], - compute_dims: Sequence[str], - compute_halos: Sequence[int] = tuple(), - externals: Optional[Mapping[str, Any]] = None, - skip_passes: Tuple[str, ...] = (), - ) -> Union[FrozenStencil, CompareToNumpyStencil]: - """ - Initialize a stencil from dimensions and number of halo points. - - Automatically injects axis_offsets into stencil externals. - - Args: - func: stencil definition function - compute_dims: dimensionality of compute domain - compute_halos: number of halo points to include in compute domain - externals: compile-time external variables required by stencil - skip_passes: compiler passes to skip when building stencil - """ - if externals is None: - externals = {} - if len(compute_dims) != 3: - raise ValueError( - f"must have 3 dimensions to create stencil, got {compute_dims}" - ) - origin, domain = self.grid_indexing.get_origin_domain( - dims=compute_dims, halos=compute_halos - ) - origin = cast_to_index3d(origin) - domain = cast_to_index3d(domain) - all_externals = self.grid_indexing.axis_offsets(origin=origin, domain=domain) - all_externals.update(externals) - return self.from_origin_domain( - func=func, - origin=origin, - domain=domain, - externals=all_externals, - skip_passes=skip_passes, - ) - - def restrict_vertical(self, k_start=0, nk=None) -> "StencilFactory": - return StencilFactory( - config=self.config, - grid_indexing=self.grid_indexing.restrict_vertical(k_start=k_start, nk=nk), - comm=self.comm, - ) - - def build_report(self, key: str = "build_time", **kwargs) -> str: - """Report all stencils built by this factory.""" - return self.timing_collector.build_report(key, **kwargs) - - def exec_report(self, key: str = "total_run_time", **kwargs) -> str: - """Report all stencils executed that were built by this factory.""" - return self.timing_collector.exec_report(key, **kwargs) - - -def get_stencils_with_varied_bounds( - func: Callable[..., None], - origins: List[Index3D], - domains: List[Index3D], - stencil_factory: StencilFactory, - externals: Optional[Mapping[str, Any]] = None, -) -> List[Union[FrozenStencil, CompareToNumpyStencil]]: - assert len(origins) == len(domains), ( - "Lists of origins and domains need to have the same length, you provided " - + str(len(origins)) - + " origins and " - + str(len(domains)) - + " domains" - ) - if externals is None: - externals = {} - stencils = [] - for origin, domain in zip(origins, domains): - ax_offsets = stencil_factory.grid_indexing.axis_offsets( - origin=origin, domain=domain - ) - stencils.append( - stencil_factory.from_origin_domain( - func, - origin=origin, - domain=domain, - externals={**externals, **ax_offsets}, - ) - ) - return stencils diff --git a/dsl/pace/dsl/stencil_config.py b/dsl/pace/dsl/stencil_config.py deleted file mode 100644 index 79eff9316..000000000 --- a/dsl/pace/dsl/stencil_config.py +++ /dev/null @@ -1,246 +0,0 @@ -import dataclasses -import enum -import hashlib -from typing import Any, Callable, Dict, Hashable, Iterable, Optional, Sequence, Tuple - -from gt4py.cartesian.gtc.passes.oir_pipeline import DefaultPipeline, OirPipeline - -from pace.dsl.dace.dace_config import DaceConfig, DaCeOrchestration -from pace.dsl.gt4py_utils import is_gpu_backend -from pace.util.communicator import Communicator -from pace.util.decomposition import determine_rank_is_compiling, set_distributed_caches -from pace.util.partitioner import Partitioner - - -class RunMode(enum.Enum): - """ - Run-Mode for the model - Build: compile & save compiled files only - BuildAndRun: compile & save compiled files, then run - Run: load from .so and run, will fail if .so is not available - """ - - Build = 0 - BuildAndRun = 1 - Run = 2 - - -class CompilationConfig: - def __init__( - self, - backend: str = "numpy", - rebuild: bool = True, - validate_args: bool = True, - format_source: bool = False, - device_sync: bool = False, - run_mode: RunMode = RunMode.BuildAndRun, - use_minimal_caching: bool = False, - communicator: Optional[Communicator] = None, - ) -> None: - if (not ("gpu" in backend or "cuda" in backend)) and device_sync is True: - raise RuntimeError("Device sync is true on a CPU based backend") - # GT4Py backend args - self.backend = backend - self.rebuild = rebuild - self.validate_args = validate_args - self.format_source = format_source - self.device_sync = device_sync - # Caching strategy - self.run_mode = run_mode - self.use_minimal_caching = use_minimal_caching - ( - self.rank, - self.size, - self.compiling_equivalent, - self.is_compiling, - ) = self.get_decomposition_info_from_comm(communicator) - if communicator: - set_distributed_caches(self) - - def check_communicator(self, communicator: Communicator) -> None: - """Checks that the communicator has a square layout - - Args: - communicator (Communicator): communicator to use - - Raises: - RuntimeError: If non-square layout is given - """ - if communicator.partitioner.layout[0] != communicator.partitioner.layout[1]: - raise RuntimeError( - "Trying to run with a non-square layout is not supported" - ) - - def determine_compiling_equivalent( - self, rank: int, partitioner: Partitioner - ) -> int: - """From my rank & the current partitioner we determine which - rank we should read from""" - if self.run_mode == RunMode.Run: - if partitioner.layout == (1, 1): - return 0 - elif partitioner.layout == (2, 2): - if partitioner.tile.on_tile_bottom(rank): - if partitioner.tile.on_tile_left(rank): - return 0 # "00" - if partitioner.tile.on_tile_right(rank): - return 1 # "10" - if partitioner.tile.on_tile_top(rank): - if partitioner.tile.on_tile_left(rank): - return 2 # "01" - if partitioner.tile.on_tile_right(rank): - return 3 # "11" - else: - if partitioner.tile.on_tile_bottom(rank): - if partitioner.tile.on_tile_left(rank): - return 0 # "00" - if partitioner.tile.on_tile_right(rank): - return 2 # "20" - else: - return 1 # "10" - if partitioner.tile.on_tile_top(rank): - if partitioner.tile.on_tile_left(rank): - return 6 # "02" - if partitioner.tile.on_tile_right(rank): - return 8 # "22" - else: - return 7 # "12" - else: - if partitioner.tile.on_tile_left(rank): - return 3 # "01" - if partitioner.tile.on_tile_right(rank): - return 5 # "21" - else: - return 4 # "11" - else: - return rank % partitioner.tile.total_ranks - raise RuntimeError("Illegal partition specified") - - def get_decomposition_info_from_comm( - self, communicator: Optional[Communicator] - ) -> Tuple[int, int, int, bool]: - if communicator: - self.check_communicator(communicator) - rank = communicator.rank - size = communicator.size - if self.use_minimal_caching: - equivalent_compiling_rank = self.determine_compiling_equivalent( - rank, communicator.partitioner - ) - is_compiling = determine_rank_is_compiling(rank, size) - else: - equivalent_compiling_rank = rank - is_compiling = True - else: - rank = 1 - size = rank - equivalent_compiling_rank = rank - is_compiling = True - return rank, size, equivalent_compiling_rank, is_compiling - - def as_dict(self) -> Dict[str, Any]: - return { - "backend": self.backend, - "rebuild": self.rebuild, - "validate_args": self.validate_args, - "format_source": self.format_source, - "device_sync": self.device_sync, - "run_mode": str(self.run_mode.name), - "use_minimal_caching": self.use_minimal_caching, - } - - @classmethod - def from_dict(cls, data: dict): - instance = cls( - backend=data.get("backend", "numpy"), - rebuild=data.get("rebuild", False), - validate_args=data.get("validate_args", True), - format_source=data.get("format_source", False), - device_sync=data.get("device_sync", False), - run_mode=RunMode[data.get("run_mode", "BuildAndRun")], - use_minimal_caching=data.get("use_minimal_caching", False), - communicator=None, - ) - return instance - - -@dataclasses.dataclass -class StencilConfig(Hashable): - compare_to_numpy: bool = False - compilation_config: CompilationConfig = CompilationConfig() - dace_config: Optional[DaceConfig] = None - - def __post_init__(self): - self.backend_opts = { - "device_sync": self.compilation_config.device_sync, - "format_source": self.compilation_config.format_source, - } - self._hash = self._compute_hash() - - # We need a DaceConfig to know if orchestration is part of the build system - # but we can't hash it very well (for now). The workaround is to make - # sure we have a default Python orchestrated config. - if self.dace_config is None: - self.dace_config = DaceConfig( - communicator=None, - backend=self.compilation_config.backend, - orchestration=DaCeOrchestration.Python, - ) - - @property - def backend(self): - return self.compilation_config.backend - - def _compute_hash(self): - md5 = hashlib.md5() - md5.update(self.compilation_config.backend.encode()) - for attr in ( - self.compilation_config.rebuild, - self.compilation_config.validate_args, - self.compilation_config.use_minimal_caching, - self.compare_to_numpy, - self.backend_opts["format_source"], - ): - md5.update(bytes(attr)) - attr = self.backend_opts.get("device_sync", None) - if attr: - md5.update(bytes(attr)) - md5.update(bytes(self.compilation_config.run_mode.value)) - return int(md5.hexdigest(), base=16) - - def __hash__(self): - return self._hash - - def __eq__(self, other): - try: - return self.__hash__() == other.__hash__() - except AttributeError: - return False - - def stencil_kwargs( - self, *, func: Callable[..., None], skip_passes: Iterable[str] = () - ): - kwargs = { - "backend": self.compilation_config.backend, - "rebuild": self.compilation_config.rebuild, - "name": func.__module__ + "." + func.__name__, - **self.backend_opts, - } - if not self.is_gpu_backend: - kwargs.pop("device_sync", None) - if skip_passes or kwargs.get("skip_passes", ()): - kwargs["oir_pipeline"] = StencilConfig._get_oir_pipeline( - list(kwargs.pop("skip_passes", ())) + list(skip_passes) # type: ignore - ) - return kwargs - - @property - def is_gpu_backend(self) -> bool: - return is_gpu_backend(self.compilation_config.backend) - - @classmethod - def _get_oir_pipeline(cls, skip_passes: Sequence[str]) -> OirPipeline: - """Creates a DefaultPipeline with skip_passes properly initialized.""" - step_map = {step.__name__: step for step in DefaultPipeline.all_steps()} - skip_steps = [step_map[pass_name] for pass_name in skip_passes] - return DefaultPipeline(skip=skip_steps) diff --git a/dsl/pace/dsl/typing.py b/dsl/pace/dsl/typing.py deleted file mode 100644 index d67dd7b66..000000000 --- a/dsl/pace/dsl/typing.py +++ /dev/null @@ -1,66 +0,0 @@ -import os -from typing import Tuple, Union, cast - -import gt4py.cartesian.gtscript as gtscript -import numpy as np - - -# A Field -Field = gtscript.Field -"""A gt4py field""" - -# Axes -IJK = gtscript.IJK -IJ = gtscript.IJ -IK = gtscript.IK -JK = gtscript.JK -I = gtscript.I # noqa: E741 -J = gtscript.J # noqa: E741 -K = gtscript.K # noqa: E741 - -# Union of valid data types (from gt4py.cartesian.gtscript) -DTypes = Union[bool, np.bool_, int, np.int32, np.int64, float, np.float32, np.float64] - - -def floating_point_precision() -> int: - return int(os.getenv("PACE_FLOAT_PRECISION", "64")) - - -def global_set_floating_point_precision(): - """Set the global floating point precision for all reference - to Float in the codebase. Defaults to 64 bit.""" - global Float - precision_in_bit = floating_point_precision() - if precision_in_bit == 64: - return np.float64 - elif precision_in_bit == 32: - return np.float32 - else: - NotImplementedError( - f"{precision_in_bit} bit precision not implemented or tested" - ) - return None - - -# Default float and int types -Float = global_set_floating_point_precision() -Int = np.int_ -Bool = np.bool_ - -FloatField = Field[gtscript.IJK, Float] -FloatFieldI = Field[gtscript.I, Float] -FloatFieldJ = Field[gtscript.J, Float] -FloatFieldIJ = Field[gtscript.IJ, Float] -FloatFieldK = Field[gtscript.K, Float] -IntField = Field[gtscript.IJK, Int] -IntFieldIJ = Field[gtscript.IJ, Int] -IntFieldK = Field[gtscript.K, Int] -BoolField = Field[gtscript.IJK, Bool] - -Index3D = Tuple[int, int, int] - - -def cast_to_index3d(val: Tuple[int, ...]) -> Index3D: - if len(val) != 3: - raise ValueError(f"expected 3d index, received {val}") - return cast(Index3D, val) diff --git a/dsl/setup.py b/dsl/setup.py deleted file mode 100644 index 448fce83d..000000000 --- a/dsl/setup.py +++ /dev/null @@ -1,36 +0,0 @@ -from typing import List - -from setuptools import find_namespace_packages, setup - - -setup_requirements: List[str] = [] - -requirements = ["gt4py", "pace-util", "dace"] - -test_requirements: List[str] = [] - - -setup( - author="Allen Institute for AI", - author_email="elynnw@allenai.org", - python_requires=">=3.8", - classifiers=[ - "Development Status :: 2 - Pre-Alpha", - "Intended Audience :: Developers", - "License :: OSI Approved :: BSD License", - "Natural Language :: English", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - ], - install_requires=requirements, - setup_requires=setup_requirements, - tests_require=test_requirements, - name="pace-dsl", - license="BSD license", - packages=find_namespace_packages(include=["pace.*"]), - include_package_data=True, - url="https://github.com/ai2cm/pace", - version="0.2.0", - zip_safe=False, -) diff --git a/examples/Dockerfile b/examples/Dockerfile index 49fe934e7..7b030f20f 100644 --- a/examples/Dockerfile +++ b/examples/Dockerfile @@ -39,7 +39,7 @@ COPY . /pace # See https://github.com/ai2cm/pace/issues/419 for more details. RUN cd /pace && \ pip3 install -r /pace/requirements_dev.txt -c /pace/constraints.txt && \ - pip install ./driver ./dsl ./fv3core ./physics ./stencils ./util -c /pace/constraints.txt + pip install ./driver ./ndsl ./fv3core ./physics -c /pace/constraints.txt RUN cd / && \ git clone https://github.com/ai2cm/fv3net diff --git a/examples/notebooks/functions.py b/examples/notebooks/functions.py index 44d40f12b..2a797a66f 100644 --- a/examples/notebooks/functions.py +++ b/examples/notebooks/functions.py @@ -8,24 +8,13 @@ from fv3viz import pcolormesh_cube from IPython.display import HTML, display from matplotlib import animation -from units_config import units - -from pace.dsl.dace.dace_config import DaceConfig, DaCeOrchestration -from pace.dsl.stencil import GridIndexing, StencilConfig, StencilFactory -from pace.dsl.stencil_config import CompilationConfig, RunMode -from pace.fv3core.stencils.fvtp2d import FiniteVolumeTransport -from pace.fv3core.stencils.fxadv import FiniteVolumeFluxPrep -from pace.fv3core.stencils.tracer_2d_1l import TracerAdvection -from pace.util import ( - CubedSphereCommunicator, - CubedSpherePartitioner, - Quantity, - QuantityFactory, - SubtileGridSizer, - TilePartitioner, -) -from pace.util.constants import RADIUS -from pace.util.grid import ( +from ndsl.comm.communicator import CubedSphereCommunicator +from ndsl.comm.partitioner import CubedSpherePartitioner, TilePartitioner +from ndsl.constants import RADIUS +from ndsl.dsl.dace.dace_config import DaceConfig, DaCeOrchestration +from ndsl.dsl.stencil import GridIndexing, StencilConfig, StencilFactory +from ndsl.dsl.stencil_config import CompilationConfig, RunMode +from ndsl.grid import ( AngleGridData, ContravariantGridData, DampingCoefficients, @@ -34,7 +23,15 @@ MetricTerms, VerticalGridData, ) -from pace.util.grid.gnomonic import great_circle_distance_lon_lat +from ndsl.grid.gnomonic import great_circle_distance_lon_lat +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from ndsl.quantity import Quantity +from units_config import units + +from pace.fv3core.stencils.fvtp2d import FiniteVolumeTransport +from pace.fv3core.stencils.fxadv import FiniteVolumeFluxPrep +from pace.fv3core.stencils.tracer_2d_1l import TracerAdvection class GridType(enum.Enum): @@ -504,7 +501,6 @@ def create_initial_tracer( for jj in range(tracer_input.shape[1] - 1): for ii in range(tracer_input.shape[0] - 1): - p_dist = [lon[ii, jj], lat[ii, jj]] r = great_circle_distance_lon_lat( p_center[0], p_dist[0], p_center[1], p_dist[1], RADIUS, np diff --git a/examples/notebooks/grid_generation.ipynb b/examples/notebooks/grid_generation.ipynb index 9d1517ed8..34518f60c 100644 --- a/examples/notebooks/grid_generation.ipynb +++ b/examples/notebooks/grid_generation.ipynb @@ -360,7 +360,7 @@ } ], "source": [ - "from pace.util import (\n", + "from ndsl.util import (\n", " CubedSphereCommunicator,\n", " CubedSpherePartitioner,\n", " Quantity,\n", @@ -383,7 +383,7 @@ "source": [ "## Data storages and fields\n", "\n", - "Furthermore `pace.util` contains helper classes which facilitate the allocation of data storages for fields on the partitiones cubed-sphere grid.\n", + "Furthermore `ndsl.util` contains helper classes which facilitate the allocation of data storages for fields on the partitiones cubed-sphere grid.\n", "\n", "- `SubtileGridSizer`: determines the size of a local array (subtile aka subdomain) for a given MPI-rank\n", "- `Quantity`: Basic data storage for a field with the associated meta-data (location on the grid, units, ...)\n", @@ -451,7 +451,7 @@ "\n", "Once we have decomposed the computational domain on the cube, we still need to project the cube onto the sphere and compute the associated metric terms that are essential for numerical discretization on the cubed-sphere.\n", "\n", - "The `pace.util.grid` package implements helper functions which make this very easy:\n", + "The `ndsl.util.grid` package implements helper functions which make this very easy:\n", "- `MetricTerms`: class to compute the metric terms of the cubed-sphere grid\n", "- `GridData`: storage of basic grid data (e.g. lat, lon, area, dx, dy, ...)" ] @@ -493,7 +493,7 @@ } ], "source": [ - "from pace.util.grid import GridData, MetricTerms\n", + "from ndsl.util.grid import GridData, MetricTerms\n", "\n", "# create the object to compute metric terms\n", "metric_terms = MetricTerms(quantity_factory=quantity_factory, communicator=communicator)\n", @@ -638,7 +638,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6IAAAH4CAYAAABQclA/AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOydd7wVxfn/P7dyL713qSJVEQFBRUQRQTHYe77YsSf5fmOMiRq7MYlRYw+xxpLYY4y9JYIVRVBEBREsiCIgvVzg7O8Pf3uzd5nZnWfazp4z79eLF3DOM888OzufmXlm9pxTFgRBAI/H4/F4PB6Px+PxeCxRnnUAHo/H4/F4PB6Px+MpLXwi6vF4PB6Px+PxeDweq/hE1OPxeDwej8fj8Xg8VvGJqMfj8Xg8Ho/H4/F4rOITUY/H4/F4PB6Px+PxWMUnoh6Px+PxeDwej8fjsYpPRD0ej8fj8Xg8Ho/HYxWfiHo8Ho/H4/F4PB6Pxyo+EfV4PB6Px+PxeDwej1V8IurxeJS45JJLUFZWhmXLlhmva8yYMRgzZozxeqIsWrQIZWVluOaaa6zWm3eyarcTTjgBPXr0ELZt2rSp2YA8UoTjSpQePXrghBNOyCYgi8Sv89///jfKysrw73//W2s9b7/9Nqqrq/H5559r9SvD+eefjxEjRmQdhsfjsYxPRD2eEmPBggU47bTT0KtXL9TU1KB58+bYY4898Kc//QkbNmzIOjyPRyvr16/HJZdcon0RXygUcPfdd2PSpEnYbrvt0KRJEwwaNAhXXHEFNm7cyCxzxx13oH///qipqUGfPn1w4403ao2Jxccff4zzzjsPO++8M5o1a4ZOnTph4sSJeOedd5j2ixcvxpFHHomWLVuiefPmOOigg/DZZ58Zj7PUeP3113HJJZdg5cqVmcVwwQUX4JhjjkH37t1J5R577DEcddRR6NWrFxo3boy+ffvi5z//Ofda/vnPf2KXXXZBTU0NunXrhosvvhhbtmxpYPOzn/0Ms2fPxj//+U/Zy/F4PDmkMusAPB6PPZ566ikcccQRaNSoESZPnoxBgwahrq4O06dPxy9+8Qt8+OGHmDp1atZhejzS/OUvf0GhUKj///r163HppZcCgNbT9PXr1+PEE0/EyJEjcfrpp6N9+/Z44403cPHFF+Oll17Cyy+/3OBE789//jNOP/10HHbYYfi///s/TJs2DT/5yU+wfv16/PKXv9QWV5zbb78dd9xxBw477DCceeaZWLVqFf785z9j5MiRePbZZ7HvvvvW265duxZ77703Vq1ahV//+teoqqrCddddh7322guzZs1CmzZtjMVZarz++uu49NJLccIJJ6Bly5YN3vvkk09QXm72nGDWrFl48cUX8frrr5PLTpkyBZ07d8aPf/xjdOvWDR988AFuuukmPP3005g5cyZqa2vrbZ955hkcfPDBGDNmDG688UZ88MEHuOKKK7B06VLceuut9XYdO3bEQQcdhGuuuQaTJk3Sco0ej8d9fCLq8ZQICxcuxNFHH43u3bvj5ZdfRqdOnerfO+uss/Dpp5/iqaeeyjDC0mbdunVo0qRJ1mHknqqqKiv1VFdX47XXXsPuu+9e/9qpp56KHj161CejYZK3YcMGXHDBBZg4cSIeeeSRettCoYDLL78cU6ZMQatWrYzEecwxx+CSSy5p8AjySSedhP79++OSSy5pkIjecsstmD9/Pt5++20MHz4cALD//vtj0KBB+OMf/4irrrrKSIzFiqymGzVqZCCahtx1113o1q0bRo4cSS77yCOPbLOpM3ToUBx//PG4//77ccopp9S/fu6552KnnXbC888/j8rKH5aczZs3x1VXXYWf/vSn6NevX73tkUceiSOOOAKfffYZevXqJXdhHo8nV/hHcz2eEuH3v/891q5dizvuuKNBEhqy/fbb46c//SmA/36+7+67797GrqysDJdccsk2ry9btgxHHnkkmjdvjjZt2uCnP/0p8xHF++67D0OHDkVtbS1at26No48+Gl9++eU2dlOnTkXv3r1RW1uLXXfdFdOmTRO+1s2bN+PSSy9Fnz59UFNTgzZt2mDUqFF44YUX6m3Czwd+9tlnGD9+PJo0aYLOnTvjsssuQxAETL9hTI0aNcLw4cMxY8aMbWw+/vhjHH744WjdujVqamowbNiwbR43u/vuu1FWVob//Oc/OPPMM9G+fXt07dq1/v1nnnkGe+65J5o0aYJmzZph4sSJ+PDDD1OvO/Q7ffp0/OQnP0G7du3QsmVLnHbaaairq8PKlSsxefJktGrVCq1atcJ55523zbUWCgVcf/31GDhwIGpqatChQwecdtpp+P777xvYvfPOOxg/fjzatm2L2tpa9OzZEyeddJJ0u0VZuXIlKioqcMMNN9S/tmzZMpSXl6NNmzYNYj7jjDPQsWPH+v9HPyO6aNEitGvXDgBw6aWXoqysjNl/Fy9ejIMPPhhNmzZFu3btcO6552Lr1q2JMVZXVzdIQkMOOeQQAMBHH31U/9orr7yC5cuX48wzz2xge9ZZZ2HdunWJG0AbNmxAv3790K9fvwaPzq9YsQKdOnXC7rvvnhjr0KFDt/kcbJs2bbDnnns2iBH4IcEYPnx4fRIKAP369cPYsWPx0EMPceuIct9992HXXXdF48aN0apVK4wePRrPP/98AxvZ/h1HROcsQp28+uqrOO2009CmTRs0b94ckydP3qafi8YbjicLFizAAQccgGbNmuG4445j1n/JJZfgF7/4BQCgZ8+e9f1y0aJFAMQ/C/vWW29hwoQJaNGiBRo3boy99toLr732Wmo5APjHP/6BffbZZ5vP4YbXu9dee6FZs2Zo3rw5hg8fjgceeKD+fdaTBax+P3fuXMydOxdTpkypT0IB4Mwzz0QQBPWbMiHhpsgTTzwhdA0ejyf/+ETU4ykRnnzySfTq1Yu5eNbBkUceiY0bN+K3v/0tDjjgANxwww2YMmVKA5srr7wSkydPRp8+fXDttdfiZz/7GV566SWMHj26weeL7rjjDpx22mno2LEjfv/732OPPfbApEmTmAkri0suuQSXXnop9t57b9x000244IIL0K1bN8ycObOB3datWzFhwgR06NABv//97zF06FBcfPHFuPjii7fx+cADD+APf/gDTjvtNFxxxRVYtGgRDj30UGzevLne5sMPP8TIkSPx0Ucf4fzzz8cf//hHNGnSBAcffDAef/zxbXyeeeaZmDt3Ln7zm9/g/PPPBwDce++9mDhxIpo2bYrf/e53uOiiizB37lyMGjWqfqGaxjnnnIP58+fj0ksvxaRJkzB16lRcdNFF+NGPfoStW7fiqquuwqhRo/CHP/wB9957b4Oyp512Gn7xi1/Uf274xBNPxP3334/x48fXX+vSpUux3377YdGiRTj//PNx44034rjjjsObb74p1W5xWrZsiUGDBuHVV1+tf2369OkoKyvDihUrMHfu3PrXp02bhj333JPpp127dvWP/x1yyCG49957ce+99+LQQw+tt9m6dSvGjx+PNm3a4JprrsFee+2FP/7xj9KPqH/zzTcAgLZt29a/9t577wEAhg0b1sB26NChKC8vr3+fRW1tLe655x58+umnuOCCC+pfP+uss7Bq1SrcfffdqKiokIozGmOhUMD777+/TYwAsOuuu2LBggVYs2ZNos9LL70U//M//4OqqipcdtlluPTSS7Hddtvh5ZdfrrfR0b9DRHXO4+yzz8ZHH32ESy65BJMnT8b999+Pgw8+uMFGByXeLVu2YPz48Wjfvj2uueYaHHbYYcx6Dz30UBxzzDEAgOuuu66+X4abJiK8/PLLGD16NFavXo2LL74YV111FVauXIl99tkHb7/9dmLZxYsX44svvsAuu+yyzXt33303Jk6ciBUrVuBXv/oVrr76auy888549tlnE31S+n3nzp3RtWvXbfp9ixYt0Lt3b+Fk2uPxFAGBx+MpelatWhUACA466CAh+4ULFwYAgrvuumub9wAEF198cf3/L7744gBAMGnSpAZ2Z555ZgAgmD17dhAEQbBo0aKgoqIiuPLKKxvYffDBB0FlZWX963V1dUH79u2DnXfeOdi0aVO93dSpUwMAwV577ZUa/+DBg4OJEycm2hx//PEBgOCcc86pf61QKAQTJ04Mqqurg++++65BW7Rp0yZYsWJFve0TTzwRAAiefPLJ+tfGjh0b7LjjjsHGjRsb+Nx9992DPn361L921113BQCCUaNGBVu2bKl/fc2aNUHLli2DU089tUGs33zzTdCiRYttXo8T+h0/fnxQKBTqX99tt92CsrKy4PTTT69/bcuWLUHXrl0btOe0adMCAMH999/fwO+zzz7b4PXHH388ABDMmDGDGwul3VicddZZQYcOHer//3//93/B6NGjg/bt2we33nprEARBsHz58qCsrCz405/+VG93/PHHB927d6///3fffbdNn43aAgguu+yyBq8PGTIkGDp0aGJ8PPbdd9+gefPmwffff9/gWioqKpj27dq1C44++uhUv7/61a+C8vLy4NVXXw0efvjhAEBw/fXXS8X46quvBmVlZcFFF11U/1rYTvG2CIIguPnmmwMAwccff8z1OX/+/KC8vDw45JBDgq1btzZ4L+yLlP4djitRunfvHhx//PH1/xfROYtQJ0OHDg3q6urqX//9738fAAieeOIJcrxhXzr//POFYvjDH/4QAAgWLly4zXvx63zllVcCAMErr7wSBMEP7dmnT59tdL5+/fqgZ8+ewbhx4xLrfvHFF5kaXLlyZdCsWbNgxIgRwYYNGxq8F62HxcknnxxUVFQE8+bN2+Yav/jii23shw8fHowcOXKb1/fbb7+gf//+iXV5PJ7iwZ+IejwlwOrVqwEAzZo1M1bHWWed1eD/55xzDgDg6aefBvDDNy0WCgUceeSRWLZsWf2fjh07ok+fPnjllVcA/PDI59KlS3H66aejurq63t8JJ5yAFi1aCMXSsmVLfPjhh5g/f36q7dlnn13/77KyMpx99tmoq6vDiy++2MDuqKOOavA5vvAULvxG0RUrVuDll1/GkUceiTVr1tRf3/LlyzF+/HjMnz8fixcvbuDz1FNPbXCa9cILL2DlypU45phjGrRRRUUFRowYUd9GaZx88skNHrkbMWIEgiDAySefXP9aRUUFhg0b1uAbUR9++GG0aNEC48aNa1B/+HhnWH/45Sr/+te/Ek82RdqNx5577olvv/0Wn3zyCYAfTj5Hjx6NPffcs/4x7enTpyMIAu6JqCinn376NnXLfFPsVVddhRdffBFXX311gy+g2bBhQ4O+HKWmpkbo26ovueQSDBw4EMcffzzOPPNM7LXXXvjJT35CjnHp0qU49thj0bNnT5x33nkNYgTYn0+sqalpYMPiH//4BwqFAn7zm99s80U7YV/U1b9DKDpnMWXKlAafKT7jjDNQWVlZP2bJxHvGGWdIxUJh1qxZmD9/Po499lgsX768Pq5169Zh7NixePXVVxt8YVec5cuXA8A2n0t+4YUXsGbNGpx//vn19zyE9QhvyAMPPIA77rgDP//5z9GnT5/619P6FKs/tWrVyspPgXk8HjfwX1bk8ZQAzZs3B4DUR+tUiC5AAKB3794oLy+vf3xt/vz5CIJgG7uQcEEY/qZd3K6qqmqbL7AIHwcLadGiBWpra3HZZZfhoIMOwg477IBBgwZhwoQJ+J//+R/stNNODezLy8u38bnDDjsAwDaP3XXr1q3B/8NFXPiZsk8//RRBEOCiiy7CRRddxLzGpUuXokuXLvX/79mzZ4P3wwX1Pvvswywf3sc04rGGCfx22223zevRz8TNnz8fq1atQvv27bnxA8Bee+2Fww47DJdeeimuu+46jBkzBgcffDCOPfbYbRadae3GI0wup02bVv8Y3xVXXIF27drV/zbptGnT0Lx5cwwePDjRVxI1NTXbPBLZqlWr1PjiPPjgg7jwwgtx8sknb5OM1NbWoq6ujllu48aNDb5llEd1dTXuvPNODB8+HDU1NbjrrrsSkwMW69atw4EHHog1a9Zg+vTpDT47GsawadMmZoxRGxYLFixAeXk5BgwYwLXR1b9DRHXOIz7GNG3aFJ06dWowZlHiraysbPBZb1OEcR1//PFcm1WrVqV+AVYQ+3z4ggULAACDBg0SjmXatGk4+eSTMX78eFx55ZUN3kvrU6z+FAQBuV97PJ784hNRj6cEaN68OTp37ow5c+YI2fMWAmlf4JLko1AooKysDM888wzzM23xL1QRIf6lS3fddRdOOOEEjB49GgsWLMATTzyB559/Hrfffjuuu+463HbbbQ2+0ZEC73N44WIuPIE499xzMX78eKbt9ttv3+D/8YVY6OPee+9t8AU8IdEv/JCJlfV6dDFaKBTQvn173H///czyYcJWVlaGRx55BG+++SaefPJJPPfcczjppJPwxz/+EW+++WaDe5nWbjw6d+6Mnj174tVXX0WPHj0QBAF22203tGvXDj/96U/x+eefY9q0adh9992VfupC5vOVcV544QVMnjwZEydOxG233bbN+506dcLWrVuxdOnSBkl+XV0dli9fjs6dOwvV89xzzwH4YRE/f/78bTYykqirq8Ohhx6K999/H88999w2yUbr1q3RqFEjLFmyZJuy4WuicfLQ1b9DTOhcJd5GjRoZ/9mVaFx/+MMfsPPOOzNtksbT8Gd4qJstcWbPno1JkyZh0KBBeOSRR7Zpj3B8XrJkyTabYEuWLMGuu+66jc/vv/++wedMPR5PceMTUY+nRDjwwAMxdepUvPHGG9htt90SbcOd9PgPlIenlSziC+NPP/0UhUKh/htMe/fujSAI0LNnz/pTRxbhj6vPnz+/wUnE5s2bsXDhwganX/Fvxxw4cGD9v1u3bo0TTzwRJ554ItauXYvRo0fjkksuabBALRQK+OyzzxrEM2/ePACoj1uU8GS1qqqqwU9iUOjduzcAoH379tI+VOjduzdefPFF7LHHHkKndCNHjsTIkSNx5ZVX4oEHHsBxxx2Hv//971qSAOCHU9FXX30VPXv2xM4774xmzZph8ODBaNGiBZ599lnMnDmz/jdCeZg+XXnrrbdwyCGHYNiwYXjooYeYyVSYLLzzzjs44IAD6l9/5513UCgUuMlElPfffx+XXXYZTjzxRMyaNQunnHIKPvjgA6HH1QuFAiZPnoyXXnoJDz30EPbaa69tbMrLy7HjjjvinXfeYV5jr169Eh/t7927NwqFAubOncu9HhP9W0TnPObPn4+99967/v9r167FkiVL6u+RST2q9MswrubNm0vFFf5kysKFC5l+58yZs82mWZwFCxZgwoQJaN++PZ5++mlm4hvt99Gk8+uvv8ZXX321zZfZhTGpPOHg8Xjyhf+MqMdTIpx33nlo0qQJTjnlFHz77bfbvL9gwQL86U9/AvDDAqdt27YNvrUU+OF3BnncfPPNDf5/4403AvjhdwiBH74psqKiApdeeuk2p2FBENR/bmnYsGFo164dbrvttgaPM959993bJMb77rtvgz/hDnzoK6Rp06bYfvvtmY+I3XTTTQ3iuOmmm1BVVYWxY8dyr5VF+/btMWbMGPz5z39mnip99913qT7Gjx9f/xt7rM9eivhQ4cgjj8TWrVtx+eWXb/Peli1b6tv/+++/3+YehotOVhvLsueee2LRokV48MEH6x/VLS8vx+67745rr70WmzdvTv18aOPGjQFsu6mig48++ggTJ05Ejx498K9//YubvO+zzz5o3bp1/Tf4htx6661o3LgxJk6cmFjP5s2bccIJJ6Bz587405/+hLvvvhvffvst/vd//1coznPOOQcPPvggbrnllgbfGBzn8MMPx4wZMxoko5988glefvllHHHEEYl1HHzwwSgvL8dll122zecTw76iu39TdM5i6tSpDeK49dZbsWXLlvoxy6Qew98XlemXQ4cORe/evXHNNddg7dq15Li6dOmC7bbbbptNh/322w/NmjXDb3/7221+eiuq92+++Qb77bcfysvL8dxzz3G/7XfgwIHo168fpk6d2uBpmltvvRVlZWU4/PDDG9ivWrUKCxYsMPbN7h6Pxz38iajHUyL07t0bDzzwAI466ij0798fkydPxqBBg1BXV4fXX38dDz/8cIPfrjvllFNw9dVX45RTTsGwYcPw6quv1p8Wsli4cCEmTZqECRMm4I033sB9992HY489tn53u3fv3rjiiivwq1/9CosWLcLBBx+MZs2aYeHChXj88ccxZcoUnHvuuaiqqsIVV1yB0047Dfvssw+OOuooLFy4EHfddZfwj5wPGDAAY8aMwdChQ9G6dWu88847eOSRRxp8MRHww+cDn332WRx//PEYMWIEnnnmGTz11FP49a9/Tfop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qKuYp0w+YSHKJLJixQpcffXVeP/999GzZ0906dJlrwElKEhNTz6U/lSOeVHHYXp3QfTdGldIitfGkW7TuRgWg644TO8s5CkfXbh3qjb92DjCbrNvq74iYRrOxR9frzMOF2oe6lyUFaF79uzBokWLsHDhQpx99tkYN24c2rZtSxobky9YiDLCvPHGG7j66quxa9cuHHvssWjTps1efzctSAE9x2HS2tAhTG0IUSDbO2thfkz4CvpT8alqh1qU5qF4jfNlMjeydA8p8siFsVkWkz5Njok2jsrazsOgnSy9lmEqD6mO4a5duxYfffQRWrVqhQkTJuDEE0+kCI/JOSxEmVTs2LED99xzD8aOHYuOHTuiV69eaNSo0Y+uy5Io1THYq4rTLBYNafwAZnPC9feETK3cy8SUxwURz1cec9DvM41fXYW2il2bIjRvueH6nKL7pJFLfSKNX5OLtrIidPPmzZg3bx6qqqrwl7/8BVdffTXq169PFSKTc1iIMlKsWrUK1157LaZPn46jjjoKRxxxROj5fxcEaZRfW4O9n7gjX7a+6CGPBZiHS4LU9vGuOJ95F6GevzyKm6DPKL82vthFNOdt99m8jYGeP5fmFBvfvRD0a+OIeRQ25wNZAbp7924sWrQIn332Gc4//3zce++9PzopxzBJsBBllJg2bRquuuoqbN26FT179kT79u1Rp06d0GtdEKWeTxuFoZ+4SdhWbFk8Qijjz5ZPz6+tVfYgSV88Uwr5l2ehHebXhviMIqlvuCTadflz4XsATPm1JTyjCD5zF3Y/TfilEKDFYhHLly/HJ598ggMPPBATJkzA8ccfTxUiU2KwEGWUqampwcMPP4z/+7//Q4sWLdCrVy+0bNky8nobghSwswOQhrgvG+DinNafLZ+mfYtiu0gshcLc9jFxD869cP959WfDpwtzmQg2x2bbc5GsCK2qqsL8+fOxa9cujB07Fpdeemntb80zjAwsRBkyvv/+e9x111146KGHcMghh6Bnz55o2rRpbJuo3ySlIG6SsV38RBEsGOImdA8d7xTmuUjy+6T2K1KAubIj6hF1L0wWk6WWdybGOo8s5B0gNubp6qt5yAHTPtPMTbZPIHm4UBNkVYB+//33mD9/PqqqqnDzzTfjxhtvROPGjalCbSZKKwAADQRJREFUZEoYFqIMOatWrcLNN9+MV155BV27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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6IAAAH4CAYAAABQclA/AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOydd7wVxfn/P7dyL713qSJVEQFBRUQRQTHYe77YsSf5fmOMiRq7MYlRYw+xxpLYY4y9JYIVRVBEBREsiCIgvVzg7O8Pf3uzd5nZnWfazp4z79eLF3DOM888OzufmXlm9pxTFgRBAI/H4/F4PB6Px+PxeCxRnnUAHo/H4/F4PB6Px+MpLXwi6vF4PB6Px+PxeDweq/hE1OPxeDwej8fj8Xg8VvGJqMfj8Xg8Ho/H4/F4rOITUY/H4/F4PB6Px+PxWMUnoh6Px+PxeDwej8fjsYpPRD0ej8fj8Xg8Ho/HYxWfiHo8Ho/H4/F4PB6Pxyo+EfV4PB6Px+PxeDwej1V8IurxeJS45JJLUFZWhmXLlhmva8yYMRgzZozxeqIsWrQIZWVluOaaa6zWm3eyarcTTjgBPXr0ELZt2rSp2YA8UoTjSpQePXrghBNOyCYgi8Sv89///jfKysrw73//W2s9b7/9Nqqrq/H5559r9SvD+eefjxEjRmQdhsfjsYxPRD2eEmPBggU47bTT0KtXL9TU1KB58+bYY4898Kc//QkbNmzIOjyPRyvr16/HJZdcon0RXygUcPfdd2PSpEnYbrvt0KRJEwwaNAhXXHEFNm7cyCxzxx13oH///qipqUGfPn1w4403ao2Jxccff4zzzjsPO++8M5o1a4ZOnTph4sSJeOedd5j2ixcvxpFHHomWLVuiefPmOOigg/DZZ58Zj7PUeP3113HJJZdg5cqVmcVwwQUX4JhjjkH37t1J5R577DEcddRR6NWrFxo3boy+ffvi5z//Ofda/vnPf2KXXXZBTU0NunXrhosvvhhbtmxpYPOzn/0Ms2fPxj//+U/Zy/F4PDmkMusAPB6PPZ566ikcccQRaNSoESZPnoxBgwahrq4O06dPxy9+8Qt8+OGHmDp1atZhejzS/OUvf0GhUKj///r163HppZcCgNbT9PXr1+PEE0/EyJEjcfrpp6N9+/Z44403cPHFF+Oll17Cyy+/3OBE789//jNOP/10HHbYYfi///s/TJs2DT/5yU+wfv16/PKXv9QWV5zbb78dd9xxBw477DCceeaZWLVqFf785z9j5MiRePbZZ7HvvvvW265duxZ77703Vq1ahV//+teoqqrCddddh7322guzZs1CmzZtjMVZarz++uu49NJLccIJJ6Bly5YN3vvkk09QXm72nGDWrFl48cUX8frrr5PLTpkyBZ07d8aPf/xjdOvWDR988AFuuukmPP3005g5cyZqa2vrbZ955hkcfPDBGDNmDG688UZ88MEHuOKKK7B06VLceuut9XYdO3bEQQcdhGuuuQaTJk3Sco0ej8d9fCLq8ZQICxcuxNFHH43u3bvj5ZdfRqdOnerfO+uss/Dpp5/iqaeeyjDC0mbdunVo0qRJ1mHknqqqKiv1VFdX47XXXsPuu+9e/9qpp56KHj161CejYZK3YcMGXHDBBZg4cSIeeeSRettCoYDLL78cU6ZMQatWrYzEecwxx+CSSy5p8AjySSedhP79++OSSy5pkIjecsstmD9/Pt5++20MHz4cALD//vtj0KBB+OMf/4irrrrKSIzFiqymGzVqZCCahtx1113o1q0bRo4cSS77yCOPbLOpM3ToUBx//PG4//77ccopp9S/fu6552KnnXbC888/j8rKH5aczZs3x1VXXYWf/vSn6NevX73tkUceiSOOOAKfffYZevXqJXdhHo8nV/hHcz2eEuH3v/891q5dizvuuKNBEhqy/fbb46c//SmA/36+7+67797GrqysDJdccsk2ry9btgxHHnkkmjdvjjZt2uCnP/0p8xHF++67D0OHDkVtbS1at26No48+Gl9++eU2dlOnTkXv3r1RW1uLXXfdFdOmTRO+1s2bN+PSSy9Fnz59UFNTgzZt2mDUqFF44YUX6m3Czwd+9tlnGD9+PJo0aYLOnTvjsssuQxAETL9hTI0aNcLw4cMxY8aMbWw+/vhjHH744WjdujVqamowbNiwbR43u/vuu1FWVob//Oc/OPPMM9G+fXt07dq1/v1nnnkGe+65J5o0aYJmzZph4sSJ+PDDD1OvO/Q7ffp0/OQnP0G7du3QsmVLnHbaaairq8PKlSsxefJktGrVCq1atcJ55523zbUWCgVcf/31GDhwIGpqatChQwecdtpp+P777xvYvfPOOxg/fjzatm2L2tpa9OzZEyeddJJ0u0VZuXIlKioqcMMNN9S/tmzZMpSXl6NNmzYNYj7jjDPQsWPH+v9HPyO6aNEitGvXDgBw6aWXoqysjNl/Fy9ejIMPPhhNmzZFu3btcO6552Lr1q2JMVZXVzdIQkMOOeQQAMBHH31U/9orr7yC5cuX48wzz2xge9ZZZ2HdunWJG0AbNmxAv3790K9fvwaPzq9YsQKdOnXC7rvvnhjr0KFDt/kcbJs2bbDnnns2iBH4IcEYPnx4fRIKAP369cPYsWPx0EMPceuIct9992HXXXdF48aN0apVK4wePRrPP/98AxvZ/h1HROcsQp28+uqrOO2009CmTRs0b94ckydP3qafi8YbjicLFizAAQccgGbNmuG4445j1n/JJZfgF7/4BQCgZ8+e9f1y0aJFAMQ/C/vWW29hwoQJaNGiBRo3boy99toLr732Wmo5APjHP/6BffbZZ5vP4YbXu9dee6FZs2Zo3rw5hg8fjgceeKD+fdaTBax+P3fuXMydOxdTpkypT0IB4Mwzz0QQBPWbMiHhpsgTTzwhdA0ejyf/+ETU4ykRnnzySfTq1Yu5eNbBkUceiY0bN+K3v/0tDjjgANxwww2YMmVKA5srr7wSkydPRp8+fXDttdfiZz/7GV566SWMHj26weeL7rjjDpx22mno2LEjfv/732OPPfbApEmTmAkri0suuQSXXnop9t57b9x000244IIL0K1bN8ycObOB3datWzFhwgR06NABv//97zF06FBcfPHFuPjii7fx+cADD+APf/gDTjvtNFxxxRVYtGgRDj30UGzevLne5sMPP8TIkSPx0Ucf4fzzz8cf//hHNGnSBAcffDAef/zxbXyeeeaZmDt3Ln7zm9/g/PPPBwDce++9mDhxIpo2bYrf/e53uOiiizB37lyMGjWqfqGaxjnnnIP58+fj0ksvxaRJkzB16lRcdNFF+NGPfoStW7fiqquuwqhRo/CHP/wB9957b4Oyp512Gn7xi1/Uf274xBNPxP3334/x48fXX+vSpUux3377YdGiRTj//PNx44034rjjjsObb74p1W5xWrZsiUGDBuHVV1+tf2369OkoKyvDihUrMHfu3PrXp02bhj333JPpp127dvWP/x1yyCG49957ce+99+LQQw+tt9m6dSvGjx+PNm3a4JprrsFee+2FP/7xj9KPqH/zzTcAgLZt29a/9t577wEAhg0b1sB26NChKC8vr3+fRW1tLe655x58+umnuOCCC+pfP+uss7Bq1SrcfffdqKiokIozGmOhUMD777+/TYwAsOuuu2LBggVYs2ZNos9LL70U//M//4OqqipcdtlluPTSS7Hddtvh5ZdfrrfR0b9DRHXO4+yzz8ZHH32ESy65BJMnT8b999+Pgw8+uMFGByXeLVu2YPz48Wjfvj2uueYaHHbYYcx6Dz30UBxzzDEAgOuuu66+X4abJiK8/PLLGD16NFavXo2LL74YV111FVauXIl99tkHb7/9dmLZxYsX44svvsAuu+yyzXt33303Jk6ciBUrVuBXv/oVrr76auy888549tlnE31S+n3nzp3RtWvXbfp9ixYt0Lt3b+Fk2uPxFAGBx+MpelatWhUACA466CAh+4ULFwYAgrvuumub9wAEF198cf3/L7744gBAMGnSpAZ2Z555ZgAgmD17dhAEQbBo0aKgoqIiuPLKKxvYffDBB0FlZWX963V1dUH79u2DnXfeOdi0aVO93dSpUwMAwV577ZUa/+DBg4OJEycm2hx//PEBgOCcc86pf61QKAQTJ04Mqqurg++++65BW7Rp0yZYsWJFve0TTzwRAAiefPLJ+tfGjh0b7LjjjsHGjRsb+Nx9992DPn361L921113BQCCUaNGBVu2bKl/fc2aNUHLli2DU089tUGs33zzTdCiRYttXo8T+h0/fnxQKBTqX99tt92CsrKy4PTTT69/bcuWLUHXrl0btOe0adMCAMH999/fwO+zzz7b4PXHH388ABDMmDGDGwul3VicddZZQYcOHer//3//93/B6NGjg/bt2we33nprEARBsHz58qCsrCz405/+VG93/PHHB927d6///3fffbdNn43aAgguu+yyBq8PGTIkGDp0aGJ8PPbdd9+gefPmwffff9/gWioqKpj27dq1C44++uhUv7/61a+C8vLy4NVXXw0efvjhAEBw/fXXS8X46quvBmVlZcFFF11U/1rYTvG2CIIguPnmmwMAwccff8z1OX/+/KC8vDw45JBDgq1btzZ4L+yLlP4djitRunfvHhx//PH1/xfROYtQJ0OHDg3q6urqX//9738fAAieeOIJcrxhXzr//POFYvjDH/4QAAgWLly4zXvx63zllVcCAMErr7wSBMEP7dmnT59tdL5+/fqgZ8+ewbhx4xLrfvHFF5kaXLlyZdCsWbNgxIgRwYYNGxq8F62HxcknnxxUVFQE8+bN2+Yav/jii23shw8fHowcOXKb1/fbb7+gf//+iXV5PJ7iwZ+IejwlwOrVqwEAzZo1M1bHWWed1eD/55xzDgDg6aefBvDDNy0WCgUceeSRWLZsWf2fjh07ok+fPnjllVcA/PDI59KlS3H66aejurq63t8JJ5yAFi1aCMXSsmVLfPjhh5g/f36q7dlnn13/77KyMpx99tmoq6vDiy++2MDuqKOOavA5vvAULvxG0RUrVuDll1/GkUceiTVr1tRf3/LlyzF+/HjMnz8fixcvbuDz1FNPbXCa9cILL2DlypU45phjGrRRRUUFRowYUd9GaZx88skNHrkbMWIEgiDAySefXP9aRUUFhg0b1uAbUR9++GG0aNEC48aNa1B/+HhnWH/45Sr/+te/Ek82RdqNx5577olvv/0Wn3zyCYAfTj5Hjx6NPffcs/4x7enTpyMIAu6JqCinn376NnXLfFPsVVddhRdffBFXX311gy+g2bBhQ4O+HKWmpkbo26ovueQSDBw4EMcffzzOPPNM7LXXXvjJT35CjnHp0qU49thj0bNnT5x33nkNYgTYn0+sqalpYMPiH//4BwqFAn7zm99s80U7YV/U1b9DKDpnMWXKlAafKT7jjDNQWVlZP2bJxHvGGWdIxUJh1qxZmD9/Po499lgsX768Pq5169Zh7NixePXVVxt8YVec5cuXA8A2n0t+4YUXsGbNGpx//vn19zyE9QhvyAMPPIA77rgDP//5z9GnT5/619P6FKs/tWrVyspPgXk8HjfwX1bk8ZQAzZs3B4DUR+tUiC5AAKB3794oLy+vf3xt/vz5CIJgG7uQcEEY/qZd3K6qqmqbL7AIHwcLadGiBWpra3HZZZfhoIMOwg477IBBgwZhwoQJ+J//+R/stNNODezLy8u38bnDDjsAwDaP3XXr1q3B/8NFXPiZsk8//RRBEOCiiy7CRRddxLzGpUuXokuXLvX/79mzZ4P3wwX1Pvvswywf3sc04rGGCfx22223zevRz8TNnz8fq1atQvv27bnxA8Bee+2Fww47DJdeeimuu+46jBkzBgcffDCOPfbYbRadae3GI0wup02bVv8Y3xVXXIF27drV/zbptGnT0Lx5cwwePDjRVxI1NTXbPBLZqlWr1PjiPPjgg7jwwgtx8sknb5OM1NbWoq6ujllu48aNDb5llEd1dTXuvPNODB8+HDU1NbjrrrsSkwMW69atw4EHHog1a9Zg+vTpDT47GsawadMmZoxRGxYLFixAeXk5BgwYwLXR1b9DRHXOIz7GNG3aFJ06dWowZlHiraysbPBZb1OEcR1//PFcm1WrVqV+AVYQ+3z4ggULAACDBg0SjmXatGk4+eSTMX78eFx55ZUN3kvrU6z+FAQBuV97PJ784hNRj6cEaN68OTp37ow5c+YI2fMWAmlf4JLko1AooKysDM888wzzM23xL1QRIf6lS3fddRdOOOEEjB49GgsWLMATTzyB559/Hrfffjuuu+463HbbbQ2+0ZEC73N44WIuPIE499xzMX78eKbt9ttv3+D/8YVY6OPee+9t8AU8IdEv/JCJlfV6dDFaKBTQvn173H///czyYcJWVlaGRx55BG+++SaefPJJPPfcczjppJPwxz/+EW+++WaDe5nWbjw6d+6Mnj174tVXX0WPHj0QBAF22203tGvXDj/96U/x+eefY9q0adh9992VfupC5vOVcV544QVMnjwZEydOxG233bbN+506dcLWrVuxdOnSBkl+XV0dli9fjs6dOwvV89xzzwH4YRE/f/78bTYykqirq8Ohhx6K999/H88999w2yUbr1q3RqFEjLFmyZJuy4WuicfLQ1b9DTOhcJd5GjRoZ/9mVaFx/+MMfsPPOOzNtksbT8Gd4qJstcWbPno1JkyZh0KBBeOSRR7Zpj3B8XrJkyTabYEuWLMGuu+66jc/vv/++wedMPR5PceMTUY+nRDjwwAMxdepUvPHGG9htt90SbcOd9PgPlIenlSziC+NPP/0UhUKh/htMe/fujSAI0LNnz/pTRxbhj6vPnz+/wUnE5s2bsXDhwganX/Fvxxw4cGD9v1u3bo0TTzwRJ554ItauXYvRo0fjkksuabBALRQK+OyzzxrEM2/ePACoj1uU8GS1qqqqwU9iUOjduzcAoH379tI+VOjduzdefPFF7LHHHkKndCNHjsTIkSNx5ZVX4oEHHsBxxx2Hv//971qSAOCHU9FXX30VPXv2xM4774xmzZph8ODBaNGiBZ599lnMnDmz/jdCeZg+XXnrrbdwyCGHYNiwYXjooYeYyVSYLLzzzjs44IAD6l9/5513UCgUuMlElPfffx+XXXYZTjzxRMyaNQunnHIKPvjgA6HH1QuFAiZPnoyXXnoJDz30EPbaa69tbMrLy7HjjjvinXfeYV5jr169Eh/t7927NwqFAubOncu9HhP9W0TnPObPn4+99967/v9r167FkiVL6u+RST2q9MswrubNm0vFFf5kysKFC5l+58yZs82mWZwFCxZgwoQJaN++PZ5++mlm4hvt99Gk8+uvv8ZXX321zZfZhTGpPOHg8Xjyhf+MqMdTIpx33nlo0qQJTjnlFHz77bfbvL9gwQL86U9/AvDDAqdt27YNvrUU+OF3BnncfPPNDf5/4403AvjhdwiBH74psqKiApdeeuk2p2FBENR/bmnYsGFo164dbrvttgaPM959993bJMb77rtvgz/hDnzoK6Rp06bYfvvtmY+I3XTTTQ3iuOmmm1BVVYWxY8dyr5VF+/btMWbMGPz5z39mnip99913qT7Gjx9f/xt7rM9eivhQ4cgjj8TWrVtx+eWXb/Peli1b6tv/+++/3+YehotOVhvLsueee2LRokV48MEH6x/VLS8vx+67745rr70WmzdvTv18aOPGjQFsu6mig48++ggTJ05Ejx498K9//YubvO+zzz5o3bp1/Tf4htx6661o3LgxJk6cmFjP5s2bccIJJ6Bz587405/+hLvvvhvffvst/vd//1coznPOOQcPPvggbrnllgbfGBzn8MMPx4wZMxoko5988glefvllHHHEEYl1HHzwwSgvL8dll122zecTw76iu39TdM5i6tSpDeK49dZbsWXLlvoxy6Qew98XlemXQ4cORe/evXHNNddg7dq15Li6dOmC7bbbbptNh/322w/NmjXDb3/7221+eiuq92+++Qb77bcfysvL8dxzz3G/7XfgwIHo168fpk6d2uBpmltvvRVlZWU4/PDDG9ivWrUKCxYsMPbN7h6Pxz38iajHUyL07t0bDzzwAI466ij0798fkydPxqBBg1BXV4fXX38dDz/8cIPfrjvllFNw9dVX45RTTsGwYcPw6quv1p8Wsli4cCEmTZqECRMm4I033sB9992HY489tn53u3fv3rjiiivwq1/9CosWLcLBBx+MZs2aYeHChXj88ccxZcoUnHvuuaiqqsIVV1yB0047Dfvssw+OOuooLFy4EHfddZfwj5wPGDAAY8aMwdChQ9G6dWu88847eOSRRxp8MRHww+cDn332WRx//PEYMWIEnnnmGTz11FP49a9/Tfop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qKuYp0w+YSHKJLJixQpcffXVeP/999GzZ0906dJlrwElKEhNTz6U/lSOeVHHYXp3QfTdGldIitfGkW7TuRgWg644TO8s5CkfXbh3qjb92DjCbrNvq74iYRrOxR9frzMOF2oe6lyUFaF79uzBokWLsHDhQpx99tkYN24c2rZtSxobky9YiDLCvPHGG7j66quxa9cuHHvssWjTps1efzctSAE9x2HS2tAhTG0IUSDbO2thfkz4CvpT8alqh1qU5qF4jfNlMjeydA8p8siFsVkWkz5Njok2jsrazsOgnSy9lmEqD6mO4a5duxYfffQRWrVqhQkTJuDEE0+kCI/JOSxEmVTs2LED99xzD8aOHYuOHTuiV69eaNSo0Y+uy5Io1THYq4rTLBYNafwAZnPC9feETK3cy8SUxwURz1cec9DvM41fXYW2il2bIjRvueH6nKL7pJFLfSKNX5OLtrIidPPmzZg3bx6qqqrwl7/8BVdffTXq169PFSKTc1iIMlKsWrUK1157LaZPn46jjjoKRxxxROj5fxcEaZRfW4O9n7gjX7a+6CGPBZiHS4LU9vGuOJ95F6GevzyKm6DPKL82vthFNOdt99m8jYGeP5fmFBvfvRD0a+OIeRQ25wNZAbp7924sWrQIn332Gc4//3zce++9PzopxzBJsBBllJg2bRquuuoqbN26FT179kT79u1Rp06d0GtdEKWeTxuFoZ+4SdhWbFk8Qijjz5ZPz6+tVfYgSV88Uwr5l2ehHebXhviMIqlvuCTadflz4XsATPm1JTyjCD5zF3Y/TfilEKDFYhHLly/HJ598ggMPPBATJkzA8ccfTxUiU2KwEGWUqampwcMPP4z/+7//Q4sWLdCrVy+0bNky8nobghSwswOQhrgvG+DinNafLZ+mfYtiu0gshcLc9jFxD869cP959WfDpwtzmQg2x2bbc5GsCK2qqsL8+fOxa9cujB07Fpdeemntb80zjAwsRBkyvv/+e9x111146KGHcMghh6Bnz55o2rRpbJuo3ySlIG6SsV38RBEsGOImdA8d7xTmuUjy+6T2K1KAubIj6hF1L0wWk6WWdybGOo8s5B0gNubp6qt5yAHTPtPMTbZPIHm4UBNkVYB+//33mD9/PqqqqnDzzTfjxhtvROPGjalCbSZKKwAADQRJREFUZEoYFqIMOatWrcLNN9+MV155BV27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", "text/plain": [ "
" ] @@ -715,7 +715,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -821,7 +821,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6IAAAH4CAYAAABQclA/AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOydd7wVxfn/P7dyL713qSJVEQFBRUQRQTHYe77YsSf5fmOMiRq7MYlRYw+xxpLYY4y9JYIVRVBEBREsiCIgvVzg7O8Pf3uzd5nZnWfazp4z79eLF3DOM888OzufmXlm9pxTFgRBAI/H4/F4PB6Px+PxeCxRnnUAHo/H4/F4PB6Px+MpLXwi6vF4PB6Px+PxeDweq/hE1OPxeDwej8fj8Xg8VvGJqMfj8Xg8Ho/H4/F4rOITUY/H4/F4PB6Px+PxWMUnoh6Px+PxeDwej8fjsYpPRD0ej8fj8Xg8Ho/HYxWfiHo8Ho/H4/F4PB6Pxyo+EfV4PB6Px+PxeDwej1V8IurxeJS45JJLUFZWhmXLlhmva8yYMRgzZozxeqIsWrQIZWVluOaaa6zWm3eyarcTTjgBPXr0ELZt2rSp2YA8UoTjSpQePXrghBNOyCYgi8Sv89///jfKysrw73//W2s9b7/9Nqqrq/H5559r9SvD+eefjxEjRmQdhsfjsYxPRD2eEmPBggU47bTT0KtXL9TU1KB58+bYY4898Kc//QkbNmzIOjyPRyvr16/HJZdcon0RXygUcPfdd2PSpEnYbrvt0KRJEwwaNAhXXHEFNm7cyCxzxx13oH///qipqUGfPn1w4403ao2Jxccff4zzzjsPO++8M5o1a4ZOnTph4sSJeOedd5j2ixcvxpFHHomWLVuiefPmOOigg/DZZ58Zj7PUeP3113HJJZdg5cqVmcVwwQUX4JhjjkH37t1J5R577DEcddRR6NWrFxo3boy+ffvi5z//Ofda/vnPf2KXXXZBTU0NunXrhosvvhhbtmxpYPOzn/0Ms2fPxj//+U/Zy/F4PDmkMusAPB6PPZ566ikcccQRaNSoESZPnoxBgwahrq4O06dPxy9+8Qt8+OGHmDp1atZhejzS/OUvf0GhUKj///r163HppZcCgNbT9PXr1+PEE0/EyJEjcfrpp6N9+/Z44403cPHFF+Oll17Cyy+/3OBE789//jNOP/10HHbYYfi///s/TJs2DT/5yU+wfv16/PKXv9QWV5zbb78dd9xxBw477DCceeaZWLVqFf785z9j5MiRePbZZ7HvvvvW265duxZ77703Vq1ahV//+teoqqrCddddh7322guzZs1CmzZtjMVZarz++uu49NJLccIJJ6Bly5YN3vvkk09QXm72nGDWrFl48cUX8frrr5PLTpkyBZ07d8aPf/xjdOvWDR988AFuuukmPP3005g5cyZqa2vrbZ955hkcfPDBGDNmDG688UZ88MEHuOKKK7B06VLceuut9XYdO3bEQQcdhGuuuQaTJk3Sco0ej8d9fCLq8ZQICxcuxNFHH43u3bvj5ZdfRqdOnerfO+uss/Dpp5/iqaeeyjDC0mbdunVo0qRJ1mHknqqqKiv1VFdX47XXXsPuu+9e/9qpp56KHj161CejYZK3YcMGXHDBBZg4cSIeeeSRettCoYDLL78cU6ZMQatWrYzEecwxx+CSSy5p8AjySSedhP79++OSSy5pkIjecsstmD9/Pt5++20MHz4cALD//vtj0KBB+OMf/4irrrrKSIzFiqymGzVqZCCahtx1113o1q0bRo4cSS77yCOPbLOpM3ToUBx//PG4//77ccopp9S/fu6552KnnXbC888/j8rKH5aczZs3x1VXXYWf/vSn6NevX73tkUceiSOOOAKfffYZevXqJXdhHo8nV/hHcz2eEuH3v/891q5dizvuuKNBEhqy/fbb46c//SmA/36+7+67797GrqysDJdccsk2ry9btgxHHnkkmjdvjjZt2uCnP/0p8xHF++67D0OHDkVtbS1at26No48+Gl9++eU2dlOnTkXv3r1RW1uLXXfdFdOmTRO+1s2bN+PSSy9Fnz59UFNTgzZt2mDUqFF44YUX6m3Czwd+9tlnGD9+PJo0aYLOnTvjsssuQxAETL9hTI0aNcLw4cMxY8aMbWw+/vhjHH744WjdujVqamowbNiwbR43u/vuu1FWVob//Oc/OPPMM9G+fXt07dq1/v1nnnkGe+65J5o0aYJmzZph4sSJ+PDDD1OvO/Q7ffp0/OQnP0G7du3QsmVLnHbaaairq8PKlSsxefJktGrVCq1atcJ55523zbUWCgVcf/31GDhwIGpqatChQwecdtpp+P777xvYvfPOOxg/fjzatm2L2tpa9OzZEyeddJJ0u0VZuXIlKioqcMMNN9S/tmzZMpSXl6NNmzYNYj7jjDPQsWPH+v9HPyO6aNEitGvXDgBw6aWXoqysjNl/Fy9ejIMPPhhNmzZFu3btcO6552Lr1q2JMVZXVzdIQkMOOeQQAMBHH31U/9orr7yC5cuX48wzz2xge9ZZZ2HdunWJG0AbNmxAv3790K9fvwaPzq9YsQKdOnXC7rvvnhjr0KFDt/kcbJs2bbDnnns2iBH4IcEYPnx4fRIKAP369cPYsWPx0EMPceuIct9992HXXXdF48aN0apVK4wePRrPP/98AxvZ/h1HROcsQp28+uqrOO2009CmTRs0b94ckydP3qafi8YbjicLFizAAQccgGbNmuG4445j1n/JJZfgF7/4BQCgZ8+e9f1y0aJFAMQ/C/vWW29hwoQJaNGiBRo3boy99toLr732Wmo5APjHP/6BffbZZ5vP4YbXu9dee6FZs2Zo3rw5hg8fjgceeKD+fdaTBax+P3fuXMydOxdTpkypT0IB4Mwzz0QQBPWbMiHhpsgTTzwhdA0ejyf/+ETU4ykRnnzySfTq1Yu5eNbBkUceiY0bN+K3v/0tDjjgANxwww2YMmVKA5srr7wSkydPRp8+fXDttdfiZz/7GV566SWMHj26weeL7rjjDpx22mno2LEjfv/732OPPfbApEmTmAkri0suuQSXXnop9t57b9x000244IIL0K1bN8ycObOB3datWzFhwgR06NABv//97zF06FBcfPHFuPjii7fx+cADD+APf/gDTjvtNFxxxRVYtGgRDj30UGzevLne5sMPP8TIkSPx0Ucf4fzzz8cf//hHNGnSBAcffDAef/zxbXyeeeaZmDt3Ln7zm9/g/PPPBwDce++9mDhxIpo2bYrf/e53uOiiizB37lyMGjWqfqGaxjnnnIP58+fj0ksvxaRJkzB16lRcdNFF+NGPfoStW7fiqquuwqhRo/CHP/wB9957b4Oyp512Gn7xi1/Uf274xBNPxP3334/x48fXX+vSpUux3377YdGiRTj//PNx44034rjjjsObb74p1W5xWrZsiUGDBuHVV1+tf2369OkoKyvDihUrMHfu3PrXp02bhj333JPpp127dvWP/x1yyCG49957ce+99+LQQw+tt9m6dSvGjx+PNm3a4JprrsFee+2FP/7xj9KPqH/zzTcAgLZt29a/9t577wEAhg0b1sB26NChKC8vr3+fRW1tLe655x58+umnuOCCC+pfP+uss7Bq1SrcfffdqKiokIozGmOhUMD777+/TYwAsOuuu2LBggVYs2ZNos9LL70U//M//4OqqipcdtlluPTSS7Hddtvh5ZdfrrfR0b9DRHXO4+yzz8ZHH32ESy65BJMnT8b999+Pgw8+uMFGByXeLVu2YPz48Wjfvj2uueYaHHbYYcx6Dz30UBxzzDEAgOuuu66+X4abJiK8/PLLGD16NFavXo2LL74YV111FVauXIl99tkHb7/9dmLZxYsX44svvsAuu+yyzXt33303Jk6ciBUrVuBXv/oVrr76auy888549tlnE31S+n3nzp3RtWvXbfp9ixYt0Lt3b+Fk2uPxFAGBx+MpelatWhUACA466CAh+4ULFwYAgrvuumub9wAEF198cf3/L7744gBAMGnSpAZ2Z555ZgAgmD17dhAEQbBo0aKgoqIiuPLKKxvYffDBB0FlZWX963V1dUH79u2DnXfeOdi0aVO93dSpUwMAwV577ZUa/+DBg4OJEycm2hx//PEBgOCcc86pf61QKAQTJ04Mqqurg++++65BW7Rp0yZYsWJFve0TTzwRAAiefPLJ+tfGjh0b7LjjjsHGjRsb+Nx9992DPn361L921113BQCCUaNGBVu2bKl/fc2aNUHLli2DU089tUGs33zzTdCiRYttXo8T+h0/fnxQKBTqX99tt92CsrKy4PTTT69/bcuWLUHXrl0btOe0adMCAMH999/fwO+zzz7b4PXHH388ABDMmDGDGwul3VicddZZQYcOHer//3//93/B6NGjg/bt2we33nprEARBsHz58qCsrCz405/+VG93/PHHB927d6///3fffbdNn43aAgguu+yyBq8PGTIkGDp0aGJ8PPbdd9+gefPmwffff9/gWioqKpj27dq1C44++uhUv7/61a+C8vLy4NVXXw0efvjhAEBw/fXXS8X46quvBmVlZcFFF11U/1rYTvG2CIIguPnmmwMAwccff8z1OX/+/KC8vDw45JBDgq1btzZ4L+yLlP4djitRunfvHhx//PH1/xfROYtQJ0OHDg3q6urqX//9738fAAieeOIJcrxhXzr//POFYvjDH/4QAAgWLly4zXvx63zllVcCAMErr7wSBMEP7dmnT59tdL5+/fqgZ8+ewbhx4xLrfvHFF5kaXLlyZdCsWbNgxIgRwYYNGxq8F62HxcknnxxUVFQE8+bN2+Yav/jii23shw8fHowcOXKb1/fbb7+gf//+iXV5PJ7iwZ+IejwlwOrVqwEAzZo1M1bHWWed1eD/55xzDgDg6aefBvDDNy0WCgUceeSRWLZsWf2fjh07ok+fPnjllVcA/PDI59KlS3H66aejurq63t8JJ5yAFi1aCMXSsmVLfPjhh5g/f36q7dlnn13/77KyMpx99tmoq6vDiy++2MDuqKOOavA5vvAULvxG0RUrVuDll1/GkUceiTVr1tRf3/LlyzF+/HjMnz8fixcvbuDz1FNPbXCa9cILL2DlypU45phjGrRRRUUFRowYUd9GaZx88skNHrkbMWIEgiDAySefXP9aRUUFhg0b1uAbUR9++GG0aNEC48aNa1B/+HhnWH/45Sr/+te/Ek82RdqNx5577olvv/0Wn3zyCYAfTj5Hjx6NPffcs/4x7enTpyMIAu6JqCinn376NnXLfFPsVVddhRdffBFXX311gy+g2bBhQ4O+HKWmpkbo26ovueQSDBw4EMcffzzOPPNM7LXXXvjJT35CjnHp0qU49thj0bNnT5x33nkNYgTYn0+sqalpYMPiH//4BwqFAn7zm99s80U7YV/U1b9DKDpnMWXKlAafKT7jjDNQWVlZP2bJxHvGGWdIxUJh1qxZmD9/Po499lgsX768Pq5169Zh7NixePXVVxt8YVec5cuXA8A2n0t+4YUXsGbNGpx//vn19zyE9QhvyAMPPIA77rgDP//5z9GnT5/619P6FKs/tWrVyspPgXk8HjfwX1bk8ZQAzZs3B4DUR+tUiC5AAKB3794oLy+vf3xt/vz5CIJgG7uQcEEY/qZd3K6qqmqbL7AIHwcLadGiBWpra3HZZZfhoIMOwg477IBBgwZhwoQJ+J//+R/stNNODezLy8u38bnDDjsAwDaP3XXr1q3B/8NFXPiZsk8//RRBEOCiiy7CRRddxLzGpUuXokuXLvX/79mzZ4P3wwX1Pvvswywf3sc04rGGCfx22223zevRz8TNnz8fq1atQvv27bnxA8Bee+2Fww47DJdeeimuu+46jBkzBgcffDCOPfbYbRadae3GI0wup02bVv8Y3xVXXIF27drV/zbptGnT0Lx5cwwePDjRVxI1NTXbPBLZqlWr1PjiPPjgg7jwwgtx8sknb5OM1NbWoq6ujllu48aNDb5llEd1dTXuvPNODB8+HDU1NbjrrrsSkwMW69atw4EHHog1a9Zg+vTpDT47GsawadMmZoxRGxYLFixAeXk5BgwYwLXR1b9DRHXOIz7GNG3aFJ06dWowZlHiraysbPBZb1OEcR1//PFcm1WrVqV+AVYQ+3z4ggULAACDBg0SjmXatGk4+eSTMX78eFx55ZUN3kvrU6z+FAQBuV97PJ784hNRj6cEaN68OTp37ow5c+YI2fMWAmlf4JLko1AooKysDM888wzzM23xL1QRIf6lS3fddRdOOOEEjB49GgsWLMATTzyB559/Hrfffjuuu+463HbbbQ2+0ZEC73N44WIuPIE499xzMX78eKbt9ttv3+D/8YVY6OPee+9t8AU8IdEv/JCJlfV6dDFaKBTQvn173H///czyYcJWVlaGRx55BG+++SaefPJJPPfcczjppJPwxz/+EW+++WaDe5nWbjw6d+6Mnj174tVXX0WPHj0QBAF22203tGvXDj/96U/x+eefY9q0adh9992VfupC5vOVcV544QVMnjwZEydOxG233bbN+506dcLWrVuxdOnSBkl+XV0dli9fjs6dOwvV89xzzwH4YRE/f/78bTYykqirq8Ohhx6K999/H88999w2yUbr1q3RqFEjLFmyZJuy4WuicfLQ1b9DTOhcJd5GjRoZ/9mVaFx/+MMfsPPOOzNtksbT8Gd4qJstcWbPno1JkyZh0KBBeOSRR7Zpj3B8XrJkyTabYEuWLMGuu+66jc/vv/++wedMPR5PceMTUY+nRDjwwAMxdepUvPHGG9htt90SbcOd9PgPlIenlSziC+NPP/0UhUKh/htMe/fujSAI0LNnz/pTRxbhj6vPnz+/wUnE5s2bsXDhwganX/Fvxxw4cGD9v1u3bo0TTzwRJ554ItauXYvRo0fjkksuabBALRQK+OyzzxrEM2/ePACoj1uU8GS1qqqqwU9iUOjduzcAoH379tI+VOjduzdefPFF7LHHHkKndCNHjsTIkSNx5ZVX4oEHHsBxxx2Hv//971qSAOCHU9FXX30VPXv2xM4774xmzZph8ODBaNGiBZ599lnMnDmz/jdCeZg+XXnrrbdwyCGHYNiwYXjooYeYyVSYLLzzzjs44IAD6l9/5513UCgUuMlElPfffx+XXXYZTjzxRMyaNQunnHIKPvjgA6HH1QuFAiZPnoyXXnoJDz30EPbaa69tbMrLy7HjjjvinXfeYV5jr169Eh/t7927NwqFAubOncu9HhP9W0TnPObPn4+99967/v9r167FkiVL6u+RST2q9MswrubNm0vFFf5kysKFC5l+58yZs82mWZwFCxZgwoQJaN++PZ5++mlm4hvt99Gk8+uvv8ZXX321zZfZhTGpPOHg8Xjyhf+MqMdTIpx33nlo0qQJTjnlFHz77bfbvL9gwQL86U9/AvDDAqdt27YNvrUU+OF3BnncfPPNDf5/4403AvjhdwiBH74psqKiApdeeuk2p2FBENR/bmnYsGFo164dbrvttgaPM959993bJMb77rtvgz/hDnzoK6Rp06bYfvvtmY+I3XTTTQ3iuOmmm1BVVYWxY8dyr5VF+/btMWbMGPz5z39mnip99913qT7Gjx9f/xt7rM9eivhQ4cgjj8TWrVtx+eWXb/Peli1b6tv/+++/3+YehotOVhvLsueee2LRokV48MEH6x/VLS8vx+67745rr70WmzdvTv18aOPGjQFsu6mig48++ggTJ05Ejx498K9//YubvO+zzz5o3bp1/Tf4htx6661o3LgxJk6cmFjP5s2bccIJJ6Bz587405/+hLvvvhvffvst/vd//1coznPOOQcPPvggbrnllgbfGBzn8MMPx4wZMxoko5988glefvllHHHEEYl1HHzwwSgvL8dll122zecTw76iu39TdM5i6tSpDeK49dZbsWXLlvoxy6Qew98XlemXQ4cORe/evXHNNddg7dq15Li6dOmC7bbbbptNh/322w/NmjXDb3/7221+eiuq92+++Qb77bcfysvL8dxzz3G/7XfgwIHo168fpk6d2uBpmltvvRVlZWU4/PDDG9ivWrUKCxYsMPbN7h6Pxz38iajHUyL07t0bDzzwAI466ij0798fkydPxqBBg1BXV4fXX38dDz/8cIPfrjvllFNw9dVX45RTTsGwYcPw6quv1p8Wsli4cCEmTZqECRMm4I033sB9992HY489tn53u3fv3rjiiivwq1/9CosWLcLBBx+MZs2aYeHChXj88ccxZcoUnHvuuaiqqsIVV1yB0047Dfvssw+OOuooLFy4EHfddZfwj5wPGDAAY8aMwdChQ9G6dWu88847eOSRRxp8MRHww+cDn332WRx//PEYMWIEnnnmGTz11FP49a9/Tfop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qKuYp0w+YSHKJLJixQpcffXVeP/999GzZ0906dJlrwElKEhNTz6U/lSOeVHHYXp3QfTdGldIitfGkW7TuRgWg644TO8s5CkfXbh3qjb92DjCbrNvq74iYRrOxR9frzMOF2oe6lyUFaF79uzBokWLsHDhQpx99tkYN24c2rZtSxobky9YiDLCvPHGG7j66quxa9cuHHvssWjTps1efzctSAE9x2HS2tAhTG0IUSDbO2thfkz4CvpT8alqh1qU5qF4jfNlMjeydA8p8siFsVkWkz5Njok2jsrazsOgnSy9lmEqD6mO4a5duxYfffQRWrVqhQkTJuDEE0+kCI/JOSxEmVTs2LED99xzD8aOHYuOHTuiV69eaNSo0Y+uy5Io1THYq4rTLBYNafwAZnPC9feETK3cy8SUxwURz1cec9DvM41fXYW2il2bIjRvueH6nKL7pJFLfSKNX5OLtrIidPPmzZg3bx6qqqrwl7/8BVdffTXq169PFSKTc1iIMlKsWrUK1157LaZPn46jjjoKRxxxROj5fxcEaZRfW4O9n7gjX7a+6CGPBZiHS4LU9vGuOJ95F6GevzyKm6DPKL82vthFNOdt99m8jYGeP5fmFBvfvRD0a+OIeRQ25wNZAbp7924sWrQIn332Gc4//3zce++9PzopxzBJsBBllJg2bRquuuoqbN26FT179kT79u1Rp06d0GtdEKWeTxuFoZ+4SdhWbFk8Qijjz5ZPz6+tVfYgSV88Uwr5l2ehHebXhviMIqlvuCTadflz4XsATPm1JTyjCD5zF3Y/TfilEKDFYhHLly/HJ598ggMPPBATJkzA8ccfTxUiU2KwEGWUqampwcMPP4z/+7//Q4sWLdCrVy+0bNky8nobghSwswOQhrgvG+DinNafLZ+mfYtiu0gshcLc9jFxD869cP959WfDpwtzmQg2x2bbc5GsCK2qqsL8+fOxa9cujB07Fpdeemntb80zjAwsRBkyvv/+e9x111146KGHcMghh6Bnz55o2rRpbJuo3ySlIG6SsV38RBEsGOImdA8d7xTmuUjy+6T2K1KAubIj6hF1L0wWk6WWdybGOo8s5B0gNubp6qt5yAHTPtPMTbZPIHm4UBNkVYB+//33mD9/PqqqqnDzzTfjxhtvROPGjalCbSZKKwAADQRJREFUZEoYFqIMOatWrcLNN9+MV155BV27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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6IAAAH4CAYAAABQclA/AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOydd7wVxfn/P7dyL713qSJVEQFBRUQRQTHYe77YsSf5fmOMiRq7MYlRYw+xxpLYY4y9JYIVRVBEBREsiCIgvVzg7O8Pf3uzd5nZnWfazp4z79eLF3DOM888OzufmXlm9pxTFgRBAI/H4/F4PB6Px+PxeCxRnnUAHo/H4/F4PB6Px+MpLXwi6vF4PB6Px+PxeDweq/hE1OPxeDwej8fj8Xg8VvGJqMfj8Xg8Ho/H4/F4rOITUY/H4/F4PB6Px+PxWMUnoh6Px+PxeDwej8fjsYpPRD0ej8fj8Xg8Ho/HYxWfiHo8Ho/H4/F4PB6Pxyo+EfV4PB6Px+PxeDwej1V8IurxeJS45JJLUFZWhmXLlhmva8yYMRgzZozxeqIsWrQIZWVluOaaa6zWm3eyarcTTjgBPXr0ELZt2rSp2YA8UoTjSpQePXrghBNOyCYgi8Sv89///jfKysrw73//W2s9b7/9Nqqrq/H5559r9SvD+eefjxEjRmQdhsfjsYxPRD2eEmPBggU47bTT0KtXL9TU1KB58+bYY4898Kc//QkbNmzIOjyPRyvr16/HJZdcon0RXygUcPfdd2PSpEnYbrvt0KRJEwwaNAhXXHEFNm7cyCxzxx13oH///qipqUGfPn1w4403ao2Jxccff4zzzjsPO++8M5o1a4ZOnTph4sSJeOedd5j2ixcvxpFHHomWLVuiefPmOOigg/DZZ58Zj7PUeP3113HJJZdg5cqVmcVwwQUX4JhjjkH37t1J5R577DEcddRR6NWrFxo3boy+ffvi5z//Ofda/vnPf2KXXXZBTU0NunXrhosvvhhbtmxpYPOzn/0Ms2fPxj//+U/Zy/F4PDmkMusAPB6PPZ566ikcccQRaNSoESZPnoxBgwahrq4O06dPxy9+8Qt8+OGHmDp1atZhejzS/OUvf0GhUKj///r163HppZcCgNbT9PXr1+PEE0/EyJEjcfrpp6N9+/Z44403cPHFF+Oll17Cyy+/3OBE789//jNOP/10HHbYYfi///s/TJs2DT/5yU+wfv16/PKXv9QWV5zbb78dd9xxBw477DCceeaZWLVqFf785z9j5MiRePbZZ7HvvvvW265duxZ77703Vq1ahV//+teoqqrCddddh7322guzZs1CmzZtjMVZarz++uu49NJLccIJJ6Bly5YN3vvkk09QXm72nGDWrFl48cUX8frrr5PLTpkyBZ07d8aPf/xjdOvWDR988AFuuukmPP3005g5cyZqa2vrbZ955hkcfPDBGDNmDG688UZ88MEHuOKKK7B06VLceuut9XYdO3bEQQcdhGuuuQaTJk3Sco0ej8d9fCLq8ZQICxcuxNFHH43u3bvj5ZdfRqdOnerfO+uss/Dpp5/iqaeeyjDC0mbdunVo0qRJ1mHknqqqKiv1VFdX47XXXsPuu+9e/9qpp56KHj161CejYZK3YcMGXHDBBZg4cSIeeeSRettCoYDLL78cU6ZMQatWrYzEecwxx+CSSy5p8AjySSedhP79++OSSy5pkIjecsstmD9/Pt5++20MHz4cALD//vtj0KBB+OMf/4irrrrKSIzFiqymGzVqZCCahtx1113o1q0bRo4cSS77yCOPbLOpM3ToUBx//PG4//77ccopp9S/fu6552KnnXbC888/j8rKH5aczZs3x1VXXYWf/vSn6NevX73tkUceiSOOOAKfffYZevXqJXdhHo8nV/hHcz2eEuH3v/891q5dizvuuKNBEhqy/fbb46c//SmA/36+7+67797GrqysDJdccsk2ry9btgxHHnkkmjdvjjZt2uCnP/0p8xHF++67D0OHDkVtbS1at26No48+Gl9++eU2dlOnTkXv3r1RW1uLXXfdFdOmTRO+1s2bN+PSSy9Fnz59UFNTgzZt2mDUqFF44YUX6m3Czwd+9tlnGD9+PJo0aYLOnTvjsssuQxAETL9hTI0aNcLw4cMxY8aMbWw+/vhjHH744WjdujVqamowbNiwbR43u/vuu1FWVob//Oc/OPPMM9G+fXt07dq1/v1nnnkGe+65J5o0aYJmzZph4sSJ+PDDD1OvO/Q7ffp0/OQnP0G7du3QsmVLnHbaaairq8PKlSsxefJktGrVCq1atcJ55523zbUWCgVcf/31GDhwIGpqatChQwecdtpp+P777xvYvfPOOxg/fjzatm2L2tpa9OzZEyeddJJ0u0VZuXIlKioqcMMNN9S/tmzZMpSXl6NNmzYNYj7jjDPQsWPH+v9HPyO6aNEitGvXDgBw6aWXoqysjNl/Fy9ejIMPPhhNmzZFu3btcO6552Lr1q2JMVZXVzdIQkMOOeQQAMBHH31U/9orr7yC5cuX48wzz2xge9ZZZ2HdunWJG0AbNmxAv3790K9fvwaPzq9YsQKdOnXC7rvvnhjr0KFDt/kcbJs2bbDnnns2iBH4IcEYPnx4fRIKAP369cPYsWPx0EMPceuIct9992HXXXdF48aN0apVK4wePRrPP/98AxvZ/h1HROcsQp28+uqrOO2009CmTRs0b94ckydP3qafi8YbjicLFizAAQccgGbNmuG4445j1n/JJZfgF7/4BQCgZ8+e9f1y0aJFAMQ/C/vWW29hwoQJaNGiBRo3boy99toLr732Wmo5APjHP/6BffbZZ5vP4YbXu9dee6FZs2Zo3rw5hg8fjgceeKD+fdaTBax+P3fuXMydOxdTpkypT0IB4Mwzz0QQBPWbMiHhpsgTTzwhdA0ejyf/+ETU4ykRnnzySfTq1Yu5eNbBkUceiY0bN+K3v/0tDjjgANxwww2YMmVKA5srr7wSkydPRp8+fXDttdfiZz/7GV566SWMHj26weeL7rjjDpx22mno2LEjfv/732OPPfbApEmTmAkri0suuQSXXnop9t57b9x000244IIL0K1bN8ycObOB3datWzFhwgR06NABv//97zF06FBcfPHFuPjii7fx+cADD+APf/gDTjvtNFxxxRVYtGgRDj30UGzevLne5sMPP8TIkSPx0Ucf4fzzz8cf//hHNGnSBAcffDAef/zxbXyeeeaZmDt3Ln7zm9/g/PPPBwDce++9mDhxIpo2bYrf/e53uOiiizB37lyMGjWqfqGaxjnnnIP58+fj0ksvxaRJkzB16lRcdNFF+NGPfoStW7fiqquuwqhRo/CHP/wB9957b4Oyp512Gn7xi1/Uf274xBNPxP3334/x48fXX+vSpUux3377YdGiRTj//PNx44034rjjjsObb74p1W5xWrZsiUGDBuHVV1+tf2369OkoKyvDihUrMHfu3PrXp02bhj333JPpp127dvWP/x1yyCG49957ce+99+LQQw+tt9m6dSvGjx+PNm3a4JprrsFee+2FP/7xj9KPqH/zzTcAgLZt29a/9t577wEAhg0b1sB26NChKC8vr3+fRW1tLe655x58+umnuOCCC+pfP+uss7Bq1SrcfffdqKiokIozGmOhUMD777+/TYwAsOuuu2LBggVYs2ZNos9LL70U//M//4OqqipcdtlluPTSS7Hddtvh5ZdfrrfR0b9DRHXO4+yzz8ZHH32ESy65BJMnT8b999+Pgw8+uMFGByXeLVu2YPz48Wjfvj2uueYaHHbYYcx6Dz30UBxzzDEAgOuuu66+X4abJiK8/PLLGD16NFavXo2LL74YV111FVauXIl99tkHb7/9dmLZxYsX44svvsAuu+yyzXt33303Jk6ciBUrVuBXv/oVrr76auy888549tlnE31S+n3nzp3RtWvXbfp9ixYt0Lt3b+Fk2uPxFAGBx+MpelatWhUACA466CAh+4ULFwYAgrvuumub9wAEF198cf3/L7744gBAMGnSpAZ2Z555ZgAgmD17dhAEQbBo0aKgoqIiuPLKKxvYffDBB0FlZWX963V1dUH79u2DnXfeOdi0aVO93dSpUwMAwV577ZUa/+DBg4OJEycm2hx//PEBgOCcc86pf61QKAQTJ04Mqqurg++++65BW7Rp0yZYsWJFve0TTzwRAAiefPLJ+tfGjh0b7LjjjsHGjRsb+Nx9992DPn361L921113BQCCUaNGBVu2bKl/fc2aNUHLli2DU089tUGs33zzTdCiRYttXo8T+h0/fnxQKBTqX99tt92CsrKy4PTTT69/bcuWLUHXrl0btOe0adMCAMH999/fwO+zzz7b4PXHH388ABDMmDGDGwul3VicddZZQYcOHer//3//93/B6NGjg/bt2we33nprEARBsHz58qCsrCz405/+VG93/PHHB927d6///3fffbdNn43aAgguu+yyBq8PGTIkGDp0aGJ8PPbdd9+gefPmwffff9/gWioqKpj27dq1C44++uhUv7/61a+C8vLy4NVXXw0efvjhAEBw/fXXS8X46quvBmVlZcFFF11U/1rYTvG2CIIguPnmmwMAwccff8z1OX/+/KC8vDw45JBDgq1btzZ4L+yLlP4djitRunfvHhx//PH1/xfROYtQJ0OHDg3q6urqX//9738fAAieeOIJcrxhXzr//POFYvjDH/4QAAgWLly4zXvx63zllVcCAMErr7wSBMEP7dmnT59tdL5+/fqgZ8+ewbhx4xLrfvHFF5kaXLlyZdCsWbNgxIgRwYYNGxq8F62HxcknnxxUVFQE8+bN2+Yav/jii23shw8fHowcOXKb1/fbb7+gf//+iXV5PJ7iwZ+IejwlwOrVqwEAzZo1M1bHWWed1eD/55xzDgDg6aefBvDDNy0WCgUceeSRWLZsWf2fjh07ok+fPnjllVcA/PDI59KlS3H66aejurq63t8JJ5yAFi1aCMXSsmVLfPjhh5g/f36q7dlnn13/77KyMpx99tmoq6vDiy++2MDuqKOOavA5vvAULvxG0RUrVuDll1/GkUceiTVr1tRf3/LlyzF+/HjMnz8fixcvbuDz1FNPbXCa9cILL2DlypU45phjGrRRRUUFRowYUd9GaZx88skNHrkbMWIEgiDAySefXP9aRUUFhg0b1uAbUR9++GG0aNEC48aNa1B/+HhnWH/45Sr/+te/Ek82RdqNx5577olvv/0Wn3zyCYAfTj5Hjx6NPffcs/4x7enTpyMIAu6JqCinn376NnXLfFPsVVddhRdffBFXX311gy+g2bBhQ4O+HKWmpkbo26ovueQSDBw4EMcffzzOPPNM7LXXXvjJT35CjnHp0qU49thj0bNnT5x33nkNYgTYn0+sqalpYMPiH//4BwqFAn7zm99s80U7YV/U1b9DKDpnMWXKlAafKT7jjDNQWVlZP2bJxHvGGWdIxUJh1qxZmD9/Po499lgsX768Pq5169Zh7NixePXVVxt8YVec5cuXA8A2n0t+4YUXsGbNGpx//vn19zyE9QhvyAMPPIA77rgDP//5z9GnT5/619P6FKs/tWrVyspPgXk8HjfwX1bk8ZQAzZs3B4DUR+tUiC5AAKB3794oLy+vf3xt/vz5CIJgG7uQcEEY/qZd3K6qqmqbL7AIHwcLadGiBWpra3HZZZfhoIMOwg477IBBgwZhwoQJ+J//+R/stNNODezLy8u38bnDDjsAwDaP3XXr1q3B/8NFXPiZsk8//RRBEOCiiy7CRRddxLzGpUuXokuXLvX/79mzZ4P3wwX1Pvvswywf3sc04rGGCfx22223zevRz8TNnz8fq1atQvv27bnxA8Bee+2Fww47DJdeeimuu+46jBkzBgcffDCOPfbYbRadae3GI0wup02bVv8Y3xVXXIF27drV/zbptGnT0Lx5cwwePDjRVxI1NTXbPBLZqlWr1PjiPPjgg7jwwgtx8sknb5OM1NbWoq6ujllu48aNDb5llEd1dTXuvPNODB8+HDU1NbjrrrsSkwMW69atw4EHHog1a9Zg+vTpDT47GsawadMmZoxRGxYLFixAeXk5BgwYwLXR1b9DRHXOIz7GNG3aFJ06dWowZlHiraysbPBZb1OEcR1//PFcm1WrVqV+AVYQ+3z4ggULAACDBg0SjmXatGk4+eSTMX78eFx55ZUN3kvrU6z+FAQBuV97PJ784hNRj6cEaN68OTp37ow5c+YI2fMWAmlf4JLko1AooKysDM888wzzM23xL1QRIf6lS3fddRdOOOEEjB49GgsWLMATTzyB559/Hrfffjuuu+463HbbbQ2+0ZEC73N44WIuPIE499xzMX78eKbt9ttv3+D/8YVY6OPee+9t8AU8IdEv/JCJlfV6dDFaKBTQvn173H///czyYcJWVlaGRx55BG+++SaefPJJPPfcczjppJPwxz/+EW+++WaDe5nWbjw6d+6Mnj174tVXX0WPHj0QBAF22203tGvXDj/96U/x+eefY9q0adh9992VfupC5vOVcV544QVMnjwZEydOxG233bbN+506dcLWrVuxdOnSBkl+XV0dli9fjs6dOwvV89xzzwH4YRE/f/78bTYykqirq8Ohhx6K999/H88999w2yUbr1q3RqFEjLFmyZJuy4WuicfLQ1b9DTOhcJd5GjRoZ/9mVaFx/+MMfsPPOOzNtksbT8Gd4qJstcWbPno1JkyZh0KBBeOSRR7Zpj3B8XrJkyTabYEuWLMGuu+66jc/vv/++wedMPR5PceMTUY+nRDjwwAMxdepUvPHGG9htt90SbcOd9PgPlIenlSziC+NPP/0UhUKh/htMe/fujSAI0LNnz/pTRxbhj6vPnz+/wUnE5s2bsXDhwganX/Fvxxw4cGD9v1u3bo0TTzwRJ554ItauXYvRo0fjkksuabBALRQK+OyzzxrEM2/ePACoj1uU8GS1qqqqwU9iUOjduzcAoH379tI+VOjduzdefPFF7LHHHkKndCNHjsTIkSNx5ZVX4oEHHsBxxx2Hv//971qSAOCHU9FXX30VPXv2xM4774xmzZph8ODBaNGiBZ599lnMnDmz/jdCeZg+XXnrrbdwyCGHYNiwYXjooYeYyVSYLLzzzjs44IAD6l9/5513UCgUuMlElPfffx+XXXYZTjzxRMyaNQunnHIKPvjgA6HH1QuFAiZPnoyXXnoJDz30EPbaa69tbMrLy7HjjjvinXfeYV5jr169Eh/t7927NwqFAubOncu9HhP9W0TnPObPn4+99967/v9r167FkiVL6u+RST2q9MswrubNm0vFFf5kysKFC5l+58yZs82mWZwFCxZgwoQJaN++PZ5++mlm4hvt99Gk8+uvv8ZXX321zZfZhTGpPOHg8Xjyhf+MqMdTIpx33nlo0qQJTjnlFHz77bfbvL9gwQL86U9/AvDDAqdt27YNvrUU+OF3BnncfPPNDf5/4403AvjhdwiBH74psqKiApdeeuk2p2FBENR/bmnYsGFo164dbrvttgaPM959993bJMb77rtvgz/hDnzoK6Rp06bYfvvtmY+I3XTTTQ3iuOmmm1BVVYWxY8dyr5VF+/btMWbMGPz5z39mnip99913qT7Gjx9f/xt7rM9eivhQ4cgjj8TWrVtx+eWXb/Peli1b6tv/+++/3+YehotOVhvLsueee2LRokV48MEH6x/VLS8vx+67745rr70WmzdvTv18aOPGjQFsu6mig48++ggTJ05Ejx498K9//YubvO+zzz5o3bp1/Tf4htx6661o3LgxJk6cmFjP5s2bccIJJ6Bz587405/+hLvvvhvffvst/vd//1coznPOOQcPPvggbrnllgbfGBzn8MMPx4wZMxoko5988glefvllHHHEEYl1HHzwwSgvL8dll122zecTw76iu39TdM5i6tSpDeK49dZbsWXLlvoxy6Qew98XlemXQ4cORe/evXHNNddg7dq15Li6dOmC7bbbbptNh/322w/NmjXDb3/7221+eiuq92+++Qb77bcfysvL8dxzz3G/7XfgwIHo168fpk6d2uBpmltvvRVlZWU4/PDDG9ivWrUKCxYsMPbN7h6Pxz38iajHUyL07t0bDzzwAI466ij0798fkydPxqBBg1BXV4fXX38dDz/8cIPfrjvllFNw9dVX45RTTsGwYcPw6quv1p8Wsli4cCEmTZqECRMm4I033sB9992HY489tn53u3fv3rjiiivwq1/9CosWLcLBBx+MZs2aYeHChXj88ccxZcoUnHvuuaiqqsIVV1yB0047Dfvssw+OOuooLFy4EHfddZfwj5wPGDAAY8aMwdChQ9G6dWu88847eOSRRxp8MRHww+cDn332WRx//PEYMWIEnnnmGTz11FP49a9/Tfop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qKuYp0w+YSHKJLJixQpcffXVeP/999GzZ0906dJlrwElKEhNTz6U/lSOeVHHYXp3QfTdGldIitfGkW7TuRgWg644TO8s5CkfXbh3qjb92DjCbrNvq74iYRrOxR9frzMOF2oe6lyUFaF79uzBokWLsHDhQpx99tkYN24c2rZtSxobky9YiDLCvPHGG7j66quxa9cuHHvssWjTps1efzctSAE9x2HS2tAhTG0IUSDbO2thfkz4CvpT8alqh1qU5qF4jfNlMjeydA8p8siFsVkWkz5Njok2jsrazsOgnSy9lmEqD6mO4a5duxYfffQRWrVqhQkTJuDEE0+kCI/JOSxEmVTs2LED99xzD8aOHYuOHTuiV69eaNSo0Y+uy5Io1THYq4rTLBYNafwAZnPC9feETK3cy8SUxwURz1cec9DvM41fXYW2il2bIjRvueH6nKL7pJFLfSKNX5OLtrIidPPmzZg3bx6qqqrwl7/8BVdffTXq169PFSKTc1iIMlKsWrUK1157LaZPn46jjjoKRxxxROj5fxcEaZRfW4O9n7gjX7a+6CGPBZiHS4LU9vGuOJ95F6GevzyKm6DPKL82vthFNOdt99m8jYGeP5fmFBvfvRD0a+OIeRQ25wNZAbp7924sWrQIn332Gc4//3zce++9PzopxzBJsBBllJg2bRquuuoqbN26FT179kT79u1Rp06d0GtdEKWeTxuFoZ+4SdhWbFk8Qijjz5ZPz6+tVfYgSV88Uwr5l2ehHebXhviMIqlvuCTadflz4XsATPm1JTyjCD5zF3Y/TfilEKDFYhHLly/HJ598ggMPPBATJkzA8ccfTxUiU2KwEGWUqampwcMPP4z/+7//Q4sWLdCrVy+0bNky8nobghSwswOQhrgvG+DinNafLZ+mfYtiu0gshcLc9jFxD869cP959WfDpwtzmQg2x2bbc5GsCK2qqsL8+fOxa9cujB07Fpdeemntb80zjAwsRBkyvv/+e9x111146KGHcMghh6Bnz55o2rRpbJuo3ySlIG6SsV38RBEsGOImdA8d7xTmuUjy+6T2K1KAubIj6hF1L0wWk6WWdybGOo8s5B0gNubp6qt5yAHTPtPMTbZPIHm4UBNkVYB+//33mD9/PqqqqnDzzTfjxhtvROPGjalCbSZKKwAADQRJREFUZEoYFqIMOatWrcLNN9+MV155BV27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", "text/plain": [ "
" ] @@ -842,7 +842,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] diff --git a/examples/notebooks/initial_condition_definition.ipynb b/examples/notebooks/initial_condition_definition.ipynb index 5f0023aca..4b194a015 100644 --- a/examples/notebooks/initial_condition_definition.ipynb +++ b/examples/notebooks/initial_condition_definition.ipynb @@ -366,7 +366,7 @@ "outputs": [], "source": [ "import numpy as np\n", - "from pace.util.constants import RADIUS\n", + "from ndsl.util.constants import RADIUS\n", "from units_config import units\n", "\n", "psi_agrid = quantity_factory.empty(\n", @@ -455,7 +455,7 @@ "metadata": {}, "outputs": [], "source": [ - "from pace.util.grid.gnomonic import great_circle_distance_lon_lat\n", + "from ndsl.util.grid.gnomonic import great_circle_distance_lon_lat\n", "\n", "tracer = quantity_factory.zeros(\n", " dims=(\"x\", \"y\", \"z\"), units=units[\"tracer\"], dtype=\"float\"\n", @@ -545,7 +545,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA3QAAAHwCAYAAADuLi1cAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAACD1klEQVR4nO3dd1QU198G8GeWXqRYsaBgwS4qKrGbSLFERY2Kmkiwxi7GRGOKGnvsiRW7poAtdlEk9hoLlsQuihqxoICAtN15//CFn0hxd5lldtnnc86chNm7d75LkX24d+4VRFEUQURERERERAZHIXcBREREREREpB0GOiIiIiIiIgPFQEdERERERGSgGOiIiIiIiIgMFAMdERERERGRgWKgIyIiIiIiMlAMdERERERERAaKgY6IiIiIiMhAMdAREREREREZKAY6IiIiIiIiA8VAR0RERERERuno0aPo1KkTypUrB0EQsH379vc+5/Dhw2jYsCEsLCxQtWpVrFu3Tud15oeBjoiIiIiIjFJSUhLc3d2xZMkStdpHRUWhY8eO+PDDDxEZGYkxY8Zg4MCB2L9/v44rzZsgiqIo29WJiIiIiIj0gCAI+PPPP+Hn55dnm/Hjx2PPnj24evVq1jl/f3/ExcUhLCysEKrMiSN0REREREREajh16hS8vLyynfP19cWpU6dkqggwle3KRERERERklFJSUpCWlqaTvkVRhCAI2c5ZWFjAwsKiwH3HxMSgTJky2c6VKVMGCQkJeP36NaysrAp8DU0x0BERERERUaFJSUmBayVbxDxV6qR/W1tbJCYmZjs3adIkTJ48WSfXkxsDHRERERERFZq0tDTEPFUi6nwl2BWT9g6whFcquHrcx4MHD2BnZ5d1XorROQBwcnLCkydPsp178uQJ7OzsZBmdAxjoiIiIiIhIBnbFFJIHuqy+7eyyBTqpNG3aFHv37s12Ljw8HE2bNpX8WurioihERERERFTolKJKJ4cmEhMTERkZicjISABvtiWIjIxEdHQ0AOCbb75Bv379stp/8cUXuHv3Lr7++mtcv34dS5cuxaZNmxAUFCTZ50VTDHRERERERGSUzp07hwYNGqBBgwYAgLFjx6JBgwb44YcfAACPHz/OCncA4Orqij179iA8PBzu7u6YN28eVq1aBV9fX1nqB7gPHRERERERFaKEhATY29sj5kZF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90ft2rXxzTffwMHBARcvXkRYWBj69OkDAPjrr7/Qvn17eHh4YNKkSVAoFFmB8dixY2jSpEm2unv06IFq1aphxowZEPPZd2by5MmYOXMmBg4ciCZNmiAhIQHnzp3DhQsX4O3tjSFDhuC///5DeHg4Nm7cmOP5ixYtQufOndG3b1+kpaUhJCQEPXr0wO7du9GxY0cAwMaNG7P6zwwkmQHsyZMn+OCDDyAIAkaMGIFSpUph3759GDBgABISEjBmzJh8vz4nT55Ew4YN822TKTExEYmJiVnfPwBw5coVZGRkoFGjRtnampubo379+rh48WK+fS5atAh//fUXAgICcOrUKZiYmGDFihU4cOAANm7cqNH3WqbMKaFv13nx4kW4ubllC50Asr7ukZGRcHZ2zrffly9fokOHDujZsyd69+6NTZs2YejQoTA3N0f//v0BvJka2KZNG9y+fRsjRoyAq6srNm/ejM8//xxxcXEYPXr0e+vv2bMnXF1dMXPmTFy4cAGrVq1C6dKlMXv2bAD5fz988cUX2LJlC0aMGIFatWohNjYWx48fx7Vr19T6Ovfs2RMuLi6YOXMmTp8+jZ9//hkvX77Ehg0bstpMnz4d33//PXr27ImBAwfi2bNn+OWXX9CqVStcvHgRDg4OWW1jY2PRvn17+Pv749NPP0WZMmVyve77fk7UsXHjRgQEBMDX1xezZ89GcnIyli1bhhYtWuDixYtwcXHJamtvb48qVargxIkTCAoK0up6RERGQSQira1du1YEIP79999Z5wICAkQA4o8//pitbYMGDUQPD49s5wCIkyZNyvp4zpw5IgAxKioqx7UqVaokBgQEZH2ckpIiKpXKbG2ioqJECwuLbNeOiooSAYhr167N97Vs3rxZBCAeOnQo12sDEMPCwnI8lpycnOOcr6+vWLly5ayP4+LixGLFiomenp7i69evs7VVqVRZ/61WrZro6+ubdS6zf1dXV9Hb2zvr3KRJk0QAYu/evfN9TZnc3d3Fjh075ttm+PDhYl7/JL77GtPS0sQ6deqIH330UbbzNjY22b5GmQYMGCCWLVtWfP78ebbz/v7+or29fa6fw0zp6emiIAjil19+mW/9maZOnSoCECMiIrLOZX5tjx49mqN9jx49RCcnp/f2u3//fhGAOG3aNPHu3buira2t6Ofnp1ZN74qNjRVLly4ttmzZ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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA3QAAAHwCAYAAADuLi1cAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAACD1klEQVR4nO3dd1QU198G8GeWXqRYsaBgwS4qKrGbSLFERY2Kmkiwxi7GRGOKGnvsiRW7poAtdlEk9hoLlsQuihqxoICAtN15//CFn0hxd5lldtnnc86chNm7d75LkX24d+4VRFEUQURERERERAZHIXcBREREREREpB0GOiIiIiIiIgPFQEdERERERGSgGOiIiIiIiIgMFAMdERERERGRgWKgIyIiIiIiMlAMdERERERERAaKgY6IiIiIiMhAMdAREREREREZKAY6IiIiIiIiA8VAR0RERERERuno0aPo1KkTypUrB0EQsH379vc+5/Dhw2jYsCEsLCxQtWpVrFu3Tud15oeBjoiIiIiIjFJSUhLc3d2xZMkStdpHRUWhY8eO+PDDDxEZGYkxY8Zg4MCB2L9/v44rzZsgiqIo29WJiIiIiIj0gCAI+PPPP+Hn55dnm/Hjx2PPnj24evVq1jl/f3/ExcUhLCysEKrMiSN0REREREREajh16hS8vLyynfP19cWpU6dkqggwle3KRERERERklFJSUpCWlqaTvkVRhCAI2c5ZWFjAwsKiwH3HxMSgTJky2c6VKVMGCQkJeP36NaysrAp8DU0x0BERERERUaFJSUmBayVbxDxV6qR/W1tbJCYmZjs3adIkTJ48WSfXkxsDHRERERERFZq0tDTEPFUi6nwl2BWT9g6whFcquHrcx4MHD2BnZ5d1XorROQBwcnLCkydPsp178uQJ7OzsZBmdAxjoiIiIiIhIBnbFFJIHuqy+7eyyBTqpNG3aFHv37s12Ljw8HE2bNpX8WurioihERERERFTolKJKJ4cmEhMTERkZicjISABvtiWIjIxEdHQ0AOCbb75Bv379stp/8cUXuHv3Lr7++mtcv34dS5cuxaZNmxAUFCTZ50VTDHRERERERGSUzp07hwYNGqBBgwYAgLFjx6JBgwb44YcfAACPHz/OCncA4Orqij179iA8PBzu7u6YN28eVq1aBV9fX1nqB7gPHRERERERFaKEhATY29sj5kZF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90ft2rXxzTffwMHBARcvXkRYWBj69OkDAPjrr7/Qvn17eHh4YNKkSVAoFFmB8dixY2jSpEm2unv06IFq1aphxowZEPPZd2by5MmYOXMmBg4ciCZNmiAhIQHnzp3DhQsX4O3tjSFDhuC///5DeHg4Nm7cmOP5ixYtQufOndG3b1+kpaUhJCQEPXr0wO7du9GxY0cAwMaNG7P6zwwkmQHsyZMn+OCDDyAIAkaMGIFSpUph3759GDBgABISEjBmzJh8vz4nT55Ew4YN822TKTExEYmJiVnfPwBw5coVZGRkoFGjRtnampubo379+rh48WK+fS5atAh//fUXAgICcOrUKZiYmGDFihU4cOAANm7cqNH3WqbMKaFv13nx4kW4ubllC50Asr7ukZGRcHZ2zrffly9fokOHDujZsyd69+6NTZs2YejQoTA3N0f//v0BvJka2KZNG9y+fRsjRoyAq6srNm/ejM8//xxxcXEYPXr0e+vv2bMnXF1dMXPmTFy4cAGrVq1C6dKlMXv2bAD5fz988cUX2LJlC0aMGIFatWohNjYWx48fx7Vr19T6Ovfs2RMuLi6YOXMmTp8+jZ9//hkvX77Ehg0bstpMnz4d33//PXr27ImBAwfi2bNn+OWXX9CqVStcvHgRDg4OWW1jY2PRvn17+Pv749NPP0WZMmVyve77fk7UsXHjRgQEBMDX1xezZ89GcnIyli1bhhYtWuDixYtwcXHJamtvb48qVargxIkTCAoK0up6RERGQSQira1du1YEIP79999Z5wICAkQA4o8//pitbYMGDUQPD49s5wCIkyZNyvp4zpw5IgAxKioqx7UqVaokBgQEZH2ckpIiKpXKbG2ioqJECwuLbNeOiooSAYhr167N97Vs3rxZBCAeOnQo12sDEMPCwnI8lpycnOOcr6+vWLly5ayP4+LixGLFiomenp7i69evs7VVqVRZ/61WrZro6+ubdS6zf1dXV9Hb2zvr3KRJk0QAYu/evfN9TZnc3d3Fjh075ttm+PDhYl7/JL77GtPS0sQ6deqIH330UbbzNjY22b5GmQYMGCCWLVtWfP78ebbz/v7+or29fa6fw0zp6emiIAjil19+mW/9maZOnSoCECMiIrLOZX5tjx49mqN9jx49RCcnp/f2u3//fhGAOG3aNPHu3buira2t6Ofnp1ZN74qNjRVLly4ttmzZ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", "text/plain": [ "
" ] @@ -566,7 +566,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -587,7 +587,7 @@ }, { "data": { - "image/png": "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rx97PK3EQJGI7G7xYmFJud1uNDc3Y8OGDVi/fj2ampqQkZGBnJwcZGZm4tprrxV2LqJQpwRzyclygrnGRgZzRLbz448/YuPGjdiwYQO2bNmC+Ph4ZGVlISsrC8OGDUMk19WEFgaLRNYTGAw5kcvlQn19PTZs2IANGzbg22+/xb333ousrCyMHz8ecXFxVmeRyJGUYO722+UEc01NDOaIbO3s2bOora3Fhg0bsGnTJkRFRSE9PR1paWlIS0tDz549rc4i2R2DRTJLmAdETnPy5EnU1taitrYWW7duxcWLF5GZmYmsrCykpaXxfXBEAjCYE4fBHDlee3s76urqsHXrVmzduhV79+7FbbfdhvT0dPTu3ZtbQJM1li+3OgehJS/P6hxQCFOmUG7duhUHDhzAoEGDkJ6ejvT0dIwcORIduV6RSCglmLvtNjnB3IEDDOaIHOv06dP44IMPsHPnTnz55ZdwiXopMZFdnD8PXLhw5X/z/v/R0Vf//5gYufkicrAbb7wR6enpGDNmDK6//nqrs0MU0hjMicNgjoiIiIiITKMEc/36yQnmmpvDJ5jjjhFEREREREQOxEngRERERERkOpcLEP2WqXBbXcOROSIiIiIiIgfiyBwREREREZmOI3PGMZgjIiIiIiLTMZgzjtMsiYiIiIiIHIgjc0REREREZDq3W/xIWri9dI0jc0RERERERA7EkTkiIiIiIjKdjPVtXDNHREREREREtseROSIiIiIiMh1H5ozjyBwREREREZEDcWSOiIiIiIhMx5E54xjMERERERGR6RjMGcdplkRERERERA7EkTkiIiIiIjIdR+aM48gcERERERGRA3FkjoiIiIiITMeROeM4MkdERERERORAHJkjIiIiIiLTcWTOOI7MERERERERORBH5oiIiIiIyHQcmTOOwRwREREREZnO7RYffLndYtOzO06zJCIiIiIiciCOzBERERERkelcLiAiQmyaHJkjIiIiIiIi2+PIHBERERERmY4jc8ZxZI6IiIiIiMiBODJHRERERESm48iccRyZIyIiIiIiciCOzBERERERkek4MmccgzkiIiIiIjIdgznjOM2SiIiIiIjIgTgyR0REREREpuPInHEcmSMiIiIiInIgjswREREREZHpODJnHEfmiIiIiIiIHIjBHBERERERmc7lkvMny7hx45CQkIBOnTrhhhtuwLRp03D8+HF5J1SBwRwREREREVEQ99xzD9auXYsvvvgC69atw5EjRzBx4kRL8xThdofbzFIiIiIiIrJKW1sbYmNjAbQC6Co6dQCxaG1tRdeuotO+UnV1NbKysnD+/HlERUVJPZc/3ACFiIiIiIgs0CYtzba2K9OOiYlBTEyMsLP88MMPeOuttzBixAjLAjmA0yyJiIiIiMhE0dHR6NmzJ4B4ALGC/+Jx7bXXIj4+HrGxsf/7e+GFF4Tkfc6cObjmmmtw/fXX45tvvsHGjRuFpKsXp1kSEREREZGpzp07hwsXLkhJ2+12I8LrnQf+RuZKSkowb968gOk1NzcjKSkJAHDq1Cn88MMP+Prrr/HXv/4VsbGx2Lx581XnMwuDOSIiIiIiCkvff/89Tp8+HfAzN910E6Kjo6/679999x3i4+Oxa9cuDB8+XFYWA+KaOSIiIiIiCks9evRAjx49dB3r+vU9COfPnxeZJU04MkdERERERBTA7t278dlnnyE1NRVxcXE4cuQI/vKXv+Df//43Dhw4IHRzFS24AQoREREREVEAXbp0wfr16zFmzBgkJiaioKAAAwYMwI4dOywL5ACOzBERERERETkSR+aIiIiIiIgciMEcERERERGRAzGYIyIiIiIiciAGc0RERERERA7EYI6IiIiIiMiBGMwRERERERE5EIM5IiIiIiIiB2IwR0RERERE5EAM5oiIiIiIiByIwRwREREREZEDMZgjIiIiIiJyoP8HaxrW0YkM+kAAAAAASUVORK5CYII=\n", + "image/png": "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rx97PK3EQJGI7G7xYmFJud1uNDc3Y8OGDVi/fj2ampqQkZGBnJwcZGZm4tprrxV2LqJQpwRzyclygrnGRgZzRLbz448/YuPGjdiwYQO2bNmC+Ph4ZGVlISsrC8OGDUMk19WEFgaLRNYTGAw5kcvlQn19PTZs2IANGzbg22+/xb333ousrCyMHz8ecXFxVmeRyJGUYO722+UEc01NDOaIbO3s2bOora3Fhg0bsGnTJkRFRSE9PR1paWlIS0tDz549rc4i2R2DRTJLmAdETnPy5EnU1taitrYWW7duxcWLF5GZmYmsrCykpaXxfXBEAjCYE4fBHDlee3s76urqsHXrVmzduhV79+7FbbfdhvT0dPTu3ZtbQJM1li+3OgehJS/P6hxQCFOmUG7duhUHDhzAoEGDkJ6ejvT0dIwcORIduV6RSCglmLvtNjnB3IEDDOaIHOv06dP44IMPsHPnTnz55ZdwiXopMZFdnD8PXLhw5X/z/v/R0Vf//5gYufkicrAbb7wR6enpGDNmDK6//nqrs0MU0hjMicNgjoiIiIiITKMEc/36yQnmmpvDJ5jjjhFEREREREQOxEngRERERERkOpcLEP2WqXBbXcOROSIiIiIiIgfiyBwREREREZmOI3PGMZgjIiIiIiLTMZgzjtMsiYiIiIiIHIgjc0REREREZDq3W/xIWri9dI0jc0RERERERA7EkTkiIiIiIjKdjPVtXDNHREREREREtseROSIiIiIiMh1H5ozjyBwREREREZEDcWSOiIiIiIhMx5E54xjMERERERGR6RjMGcdplkRERERERA7EkTkiIiIiIjIdR+aM48gcERERERGRA3FkjoiIiIiITMeROeM4MkdERERERORAHJkjIiIiIiLTcWTOOI7MERERERERORBH5oiIiIiIyHQcmTOOwRwREREREZnO7RYffLndYtOzO06zJCIiIiIiciCOzBERERERkelcLiAiQmyaHJkjIiIiIiIi2+PIHBERERERmY4jc8ZxZI6IiIiIiMiBODJHRERERESm48iccRyZIyIiIiIiciCOzBERERERkek4MmccgzkiIiIiIjIdgznjOM2SiIiIiIjIgTgyR0REREREpuPInHEcmSMiIiIiInIgjswREREREZHpODJnHEfmiIiIiIiIHIjBHBERERERmc7lkvMny7hx45CQkIBOnTrhhhtuwLRp03D8+HF5J1SBwRwREREREVEQ99xzD9auXYsvvvgC69atw5EjRzBx4kRL8xThdofbzFIiIiIiIrJKW1sbYmNjAbQC6Co6dQCxaG1tRdeuotO+UnV1NbKysnD+/HlERUVJPZc/3ACFiIiIiIgs0CYtzba2K9OOiYlBTEyMsLP88MMPeOuttzBixAjLAjmA0yyJiIiIiMhE0dHR6NmzJ4B4ALGC/+Jx7bXXIj4+HrGxsf/7e+GFF4Tkfc6cObjmmmtw/fXX45tvvsHGjRuFpKsXp1kSEREREZGpzp07hwsXLkhJ2+12I8LrnQf+RuZKSkowb968gOk1NzcjKSkJAHDq1Cn88MMP+Prrr/HXv/4VsbGx2Lx581XnMwuDOSIiIiIiCkvff/89Tp8+HfAzN910E6Kjo6/679999x3i4+Oxa9cuDB8+XFYWA+KaOSIiIiIiCks9evRAjx49dB3r+vU9COfPnxeZJU04MkdERERERBTA7t278dlnnyE1NRVxcXE4cuQI/vKXv+Df//43Dhw4IHRzFS24AQoREREREVEAXbp0wfr16zFmzBgkJiaioKAAAwYMwI4dOywL5ACOzBERERERETkSR+aIiIiIiIgciMEcERERERGRAzGYIyIiIiIiciAGc0RERERERA7EYI6IiIiIiMiBGMwRERERERE5EIM5IiIiIiIiB2IwR0RERERE5EAM5oiIiIiIiByIwRwREREREZEDMZgjIiIiIiJyoP8HaxrW0YkM+kAAAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -724,7 +724,7 @@ }, { "data": { - "image/png": "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kH799VdJkiTp77//lipUqCCNHj064nOHDh2S0tPTS70uSZLUo0cP6bzzzmPqG0EQhBYnT56UAEgna9aUpFq1hP6drFmzqO2TJ73+mr6BJDBBxBirV68GANxxxx0Rr995550AgA8//DDi9fPPPx+XX3558b+rVq2Kpk2bRqT9aZGdnQ0AKF++vOW+fv311zh27BhGjx4dUXji+uuvR8WKFTU/k5mZibJly5q2e+TIEYwbNy4iAjhixAikp6eb9uv48eOQJEm3D0o2btyIRx55BIMHD8aVV15Z/Prp06cBFKW2qklOTi5+34gePXpg7NixePTRR3HttdciOTkZCxYsMP2cmnA4jOuvvx5ZWVl4/vnnI947ffq0bh+V38OI+Pj44kgaUBTFHDt2LI4cOYLt27cDKLLLGjVqYNiwYcXHJSQkFFct3bBhg+l5xo0bF/Hvyy+/HMeOHSu2RSMqVKiArVu3GqbCGjF+/PiIf0+cOBFAyf32zjvvIBwOY/DgwTh69GjxX40aNdC4cWOsX78+4vNJSUkYOXKkpb7w8MknnyArKwvDhg2L6FeZMmVw6aWXluoXAFSsWFG3UjBBEAQXFOFzBSraQhBRhnL9jha//fYb4uLi0KhRo4jXa9SogQoVKuC3336LeL1OnTql2qhYsSJOnDhheB45BfDvv/9GhQoVDI89ffo0Tp48Wao/cl/UfY2Pj0e9evU026pfv77huQAUt9u4ceOI1xMSErgKUUiSZPj+7t27cc0116B58+Z46aWXIt6TRal63SRQVGzGTLTKzJ49G++99x527NiBN954A9WqVWPsfQkTJ07EmjVr8Morr6Bly5al+qnXR/l9M2rWrFlcBEamSZMmAIB9+/ahXbt2+O2339C4ceNS6x/PO+88AChll1qobVUW5CdOnCiVkqrmySefRGZmJmrXro3WrVujd+/eGD58OLM9qG2pYcOGiIuLK06J3Lt3LyRJKnWcTEJCQsS/zz33XKFVZfXYu3cvAERMRijRum6SJJmOMwRBEEyQQHMFEnwEESDMoiq5ubnMVflYHTbllgNKzMROs2bNABStVVNGCLVYvnx5qWiGWft6sAolO1SqVAmhUMhQ9O7fvx89evRAeno6Vq9eXSrSec455wCA5v58Bw8eZF6D9+233+LIkSMAiq61MkLGwiOPPIK5c+fi8ccf11xvec455+CPP/7Q7CMAS2sFncKqrQJFa/Auv/xyvPvuu1i7di1mzZqFJ554Au+88w569erF3Rf1/RUOhxEKhfDRRx9p9jM1NTXi327YsdwvoGgdn3LLEBmtLR1OnDgRsc6TIAiC8Dck+AgiQMiVFffs2YPatWtHvJebm1ssMszaCIfD2Lt3b3H0BAAOHz6MrKysUtUbrdK3b1/MnDkTr732mqngy8jI0NzIW+7Lzz//HFG0oqCgAPv27cOFF15oqW9yu3v37o2IbJw9exa//vprqSiXmvj4eDRs2BC//vqr5vvHjh1Djx49cObMGaxbt65Y3Clp3rw54uPj8fXXX0ds7ZCfn48dO3aU2u5Bi1OnTmHkyJE4//zz0aFDBzz55JO45ppr0KZNG9PPAijeu+3222/H5MmTNY9p1aoV1q9fj+zs7Ihoz9atW4vfN+PPP//EqVOnIqJ8P/30EwAUR2rr1q2LnTt3IhwOR0T5du/eXfy+CIwmOs455xzccsstuOWWW3DkyBFcfPHFeOyxx5gE3969eyOiyz///DPC4XDx92vYsCEkSUL9+vWLo5uisBNtk6vMVqtWrbgCpxks9whBEAQTFOFzBbrCBBEgunbtisTERMybN694Zl5m4cKFKCgoMHVOe/fuDQB49tlnI15/+umnAQB9+vQR0tf27dujZ8+eeOmll7By5cpS7+fn5xfv63bOOeegW7duEX8AcMkll6By5cp48cUXUVBQUPzZ119/3TSl1IhLLrkEVatWxfz58yM2fl+yZEmpaolG3+/rr78u9fqpU6fQu3dv/PHHH1i9erVuCl96ejq6deuG1157DX///Xfx66+++ipycnIwaNAg0z5MnjwZv//+O5YuXYqnn34a9erVQ2ZmpmYKpprly5fj1ltvxfXXX1/822sxcOBAFBYWYuHChcWvnTlzBosXL8all15aauJBi4KCgoi1hfn5+ViwYAGqVq2K1q1bAyiyy0OHDmH58uURn3v++eeRmpqKzp07m56HhXLlypX6jQsLC0ulFFerVg01a9ZkupYAirdGkJHXQsr347XXXosyZcrgkUceKRVxlCQJx44d4/kaEchCmtV2lWRkZCAtLQ0zZszA2bNnS73/119/Rfz75MmT+N///ocOHTpY6itBEAThPhThI4gAUa1aNTz44IOYOnUqOnXqhH79+iElJQWbN2/Gm2++iR49eqBv376GbbRs2RKZmZlYuHAhsrKy0LlzZ2zbtg1Lly5F//79dcu/W+GVV15Bjx49cO2116Jv377o2rUrypUrh71792LZsmU4ePCg4V58iYmJePjhhzFx4kRceeWVGDx4MPbt24clS5agYcOGliMbCQkJmD59OsaOHYsrr7wSQ4YMwa+//orFixczr9m6+uqr8eqrr+Knn36KiNhcf/312LZtG2688Ub8+OOPEWX9U1NT0b9//+J/P/bYY+jQoQM6d+6MMWPG4MCBA3jqqafQo0cP9OzZ0/D8//3vfzF37lw89NBDxdtDLF68GF26dMEDDzyAJ598Uvez27Ztw/Dhw1G5cmV07doVr7/+esT7HTp0KL4Ol156KQYNGoR7770XR44cQaNGjbB06VLs27cPixYtYrpWNWvWxBNPPIF9+/ahSZMmWL58OXbs2IGFCxcWr10bM2YMFixYgBEjRmD79u2oV68eVqxYgS+++ALPPvusreI/Slq3bo1PP/0UTz/9NGrWrIn69eujadOmqFWrFgYOHIiWLVsiNTUVn376Kb766is89dRTTO3++uuv6NevH3r27IktW7bgtddew3XXXVccCWvYsCGmT5+Oe++9F/v27UP//v1Rvnx5/Prrr3j33XcxZsyY4gkQK98JAG699VZkZGSgTJkymlusaJGWloZ58+bhX//6Fy6++GIMHToUVatWxe+//44PP/wQl112GebMmVN8/KeffgpJknD11Vdb6itBEEQEFOFzB4+qgxIEYYPXXntNateunVSuXDkpKSlJatasmfTII49IeXl5TJ8/e/as9Mgjj0j169eXEhISpNq1a0v33ntvqc/XrVtX6tOnT6nPd+7c2XTrApnc3Fxp9uzZUps2baTU1FQpMTFRaty4sTRx4kTp559/Zmrj3//+t1S3bl0pKSlJatu2rfTFF19IrVu3lnr27Fl8jLz1wltvvVXq8+ptGWTmzp0r1a9fX0pKSpIuueQSaePGjczf7cyZM1KVKlWkadOmRbwub2Wh9Ve3bt1S7Xz++edShw4dpOTkZKlq1arS+PHjI7Yg0CI7O1uqW7eudPHFF0dsVyFJkjRp0iQpLi5O2rJli+7n5dL8en+LFy+OOP706dPSXXfdJdWoUUNKSkqS2rRpI61Zs8b4Av1D586dpQsuuED6+uuvpfbt20vJyclS3bp1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\n", + "image/png": "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kH799VdJkiTp77//lipUqCCNHj064nOHDh2S0tPTS70uSZLUo0cP6bzzzmPqG0EQhBYnT56UAEgna9aUpFq1hP6drFmzqO2TJ73+mr6BJDBBxBirV68GANxxxx0Rr995550AgA8//DDi9fPPPx+XX3558b+rVq2Kpk2bRqT9aZGdnQ0AKF++vOW+fv311zh27BhGjx4dUXji+uuvR8WKFTU/k5mZibJly5q2e+TIEYwbNy4iAjhixAikp6eb9uv48eOQJEm3D0o2btyIRx55BIMHD8aVV15Z/Prp06cBFKW2qklOTi5+34gePXpg7NixePTRR3HttdciOTkZCxYsMP2cmnA4jOuvvx5ZWVl4/vnnI947ffq0bh+V38OI+Pj44kgaUBTFHDt2LI4cOYLt27cDKLLLGjVqYNiwYcXHJSQkFFct3bBhg+l5xo0bF/Hvyy+/HMeOHSu2RSMqVKiArVu3GqbCGjF+/PiIf0+cOBFAyf32zjvvIBwOY/DgwTh69GjxX40aNdC4cWOsX78+4vNJSUkYOXKkpb7w8MknnyArKwvDhg2L6FeZMmVw6aWXluoXAFSsWFG3UjBBEAQXFOFzBSraQhBRhnL9jha//fYb4uLi0KhRo4jXa9SogQoVKuC3336LeL1OnTql2qhYsSJOnDhheB45BfDvv/9GhQoVDI89ffo0Tp48Wao/cl/UfY2Pj0e9evU026pfv77huQAUt9u4ceOI1xMSErgKUUiSZPj+7t27cc0116B58+Z46aWXIt6TRal63SRQVGzGTLTKzJ49G++99x527NiBN954A9WqVWPsfQkTJ07EmjVr8Morr6Bly5al+qnXR/l9M2rWrFlcBEamSZMmAIB9+/ahXbt2+O2339C4ceNS6x/PO+88AChll1qobVUW5CdOnCiVkqrmySefRGZmJmrXro3WrVujd+/eGD58OLM9qG2pYcOGiIuLK06J3Lt3LyRJKnWcTEJCQsS/zz33XKFVZfXYu3cvAERMRijRum6SJJmOMwRBEEyQQHMFEnwEESDMoiq5ubnMVflYHTbllgNKzMROs2bNABStVVNGCLVYvnx5qWiGWft6sAolO1SqVAmhUMhQ9O7fvx89evRAeno6Vq9eXSrSec455wCA5v58Bw8eZF6D9+233+LIkSMAiq61MkLGwiOPPIK5c+fi8ccf11xvec455+CPP/7Q7CMAS2sFncKqrQJFa/Auv/xyvPvuu1i7di1mzZqFJ554Au+88w569erF3Rf1/RUOhxEKhfDRRx9p9jM1NTXi327YsdwvoGgdn3LLEBmtLR1OnDgRsc6TIAiC8Dck+AgiQMiVFffs2YPatWtHvJebm1ssMszaCIfD2Lt3b3H0BAAOHz6MrKysUtUbrdK3b1/MnDkTr732mqngy8jI0NzIW+7Lzz//HFG0oqCgAPv27cOFF15oqW9yu3v37o2IbJw9exa//vprqSiXmvj4eDRs2BC//vqr5vvHjh1Djx49cObMGaxbt65Y3Clp3rw54uPj8fXXX0ds7ZCfn48dO3aU2u5Bi1OnTmHkyJE4//zz0aFDBzz55JO45ppr0KZNG9PPAijeu+3222/H5MmTNY9p1aoV1q9fj+zs7Ihoz9atW4vfN+PPP//EqVOnIqJ8P/30EwAUR2rr1q2LnTt3IhwOR0T5du/eXfy+CIwmOs455xzccsstuOWWW3DkyBFcfPHFeOyxx5gE3969eyOiyz///DPC4XDx92vYsCEkSUL9+vWLo5uisBNtk6vMVqtWrbgCpxks9whBEAQTFOFzBbrCBBEgunbtisTERMybN694Zl5m4cKFKCgoMHVOe/fuDQB49tlnI15/+umnAQB9+vQR0tf27dujZ8+eeOmll7By5cpS7+fn5xfv63bOOeegW7duEX8AcMkll6By5cp48cUXUVBQUPzZ119/3TSl1IhLLrkEVatWxfz58yM2fl+yZEmpaolG3+/rr78u9fqpU6fQu3dv/PHHH1i9erVuCl96ejq6deuG1157DX///Xfx66+++ipycnIwaNAg0z5MnjwZv//+O5YuXYqnn34a9erVQ2ZmpmYKpprly5fj1ltvxfXXX1/822sxcOBAFBYWYuHChcWvnTlzBosXL8all15aauJBi4KCgoi1hfn5+ViwYAGqVq2K1q1bAyiyy0OHDmH58uURn3v++eeRmpqKzp07m56HhXLlypX6jQsLC0ulFFerVg01a9ZkupYAirdGkJHXQsr347XXXosyZcrgkUceKRVxlCQJx44d4/kaEchCmtV2lWRkZCAtLQ0zZszA2bNnS73/119/Rfz75MmT+N///ocOHTpY6itBEAThPhThI4gAUa1aNTz44IOYOnUqOnXqhH79+iElJQWbN2/Gm2++iR49eqBv376GbbRs2RKZmZlYuHAhsrKy0LlzZ2zbtg1Lly5F//79dcu/W+GVV15Bjx49cO2116Jv377o2rUrypUrh71792LZsmU4ePCg4V58iYmJePjhhzFx4kRceeWVGDx4MPbt24clS5agYcOGliMbCQkJmD59OsaOHYsrr7wSQ4YMwa+//orFixczr9m6+uqr8eqrr+Knn36KiNhcf/312LZtG2688Ub8+OOPEWX9U1NT0b9//+J/P/bYY+jQoQM6d+6MMWPG4MCBA3jqqafQo0cP9OzZ0/D8//3vfzF37lw89NBDxdtDLF68GF26dMEDDzyAJ598Uvez27Ztw/Dhw1G5cmV07doVr7/+esT7HTp0KL4Ol156KQYNGoR7770XR44cQaNGjbB06VLs27cPixYtYrpWNWvWxBNPPIF9+/ahSZMmWL58OXbs2IGFCxcWr10bM2YMFixYgBEjRmD79u2oV68eVqxYgS+++ALPPvusreI/Slq3bo1PP/0UTz/9NGrWrIn69eujadOmqFWrFgYOHIiWLVsiNTUVn376Kb766is89dRTTO3++uuv6NevH3r27IktW7bgtddew3XXXVccCWvYsCGmT5+Oe++9F/v27UP//v1Rvnx5/Prrr3j33XcxZsyY4gkQK98JAG699VZkZGSgTJkymlusaJGWloZ58+bhX//6Fy6++GIMHToUVatWxe+//44PP/wQl112GebMmVN8/KeffgpJknD11Vdb6itBEEQEFOFzB4+qgxIEYYPXXntNateunVSuXDkpKSlJatasmfTII49IeXl5TJ8/e/as9Mgjj0j169eXEhISpNq1a0v33ntvqc/XrVtX6tOnT6nPd+7c2XTrApnc3Fxp9uzZUps2baTU1FQpMTFRaty4sTRx4kTp559/Zmrj3//+t1S3bl0pKSlJatu2rfTFF19IrVu3lnr27Fl8jLz1wltvvVXq8+ptGWTmzp0r1a9fX0pKSpIuueQSaePGjczf7cyZM1KVKlWkadOmRbwub2Wh9Ve3bt1S7Xz++edShw4dpOTkZKlq1arS+PHjI7Yg0CI7O1uqW7eudPHFF0dsVyFJkjRp0iQpLi5O2rJli+7n5dL8en+LFy+OOP706dPSXXfdJdWoUUNKSkqS2rRpI61Zs8b4Av1D586dpQsuuED6+uuvpfbt20vJyclS3bp1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", "text/plain": [ "
" ] @@ -745,7 +745,7 @@ }, { "data": { - "image/png": "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7733Xtx5553o2bMnnn/+edStWxdXXnklFi9e7Fgbjdi1axdeeuklS+dGq+B78MEHNQWfnWulJjk5GZmZmXj66ach0Qp4BEEQwUIiCCIQ5ObmSuXLl5d69+6t+f3ChQslANLixYtdbpk248ePlwBIzzzzTKnvCgsLpWnTpkn79u1zrP6CggLp1KlTXOdkZmZK9erVMz3um2++kQBI69ati/j8s88+K1Xn7t27pTJlykhXXXVVxOfjxo2TypYtK/3xxx8ln3344YcSAGn27Nlc7ebh77//lnbs2FHq81GjRkkApD179pR8tn//fikxMVEaP358yWfhcFi68MILpdq1a0uFhYWOtdMJzj77bKlLly5eN4ObnJwc3e+mTZsmAZB+++0303I2bNggAZA2bNhgqR1ff/21BEBav369pfMJgiBkjh8/LgGQjlevLkk1awr9O169enHZx497/TN9A0X4CCIglC1bFoMGDcL69etx+PDhUt8vXLgQ5cuXxyWXXGJa1syZM3H22WejTJkyqFmzJsaPH18qQtC1a1c0b94cP/74I7p164aUlBTUqlULTz75pGn5+/fvx+zZs9GzZ0/ccsstpb6Pj4/Hbbfdhtq1a5uWtXTpUpx11llITk5G8+bNsWLFilJz7eR5etOnT8ezzz6LM844A2XKlMGPP/6oO4dv5cqVaN68eUS5rKxcuRJJSUno3LlzxOcdO3ZEUlJSxGeNGzfG2WefjZ9++ini8+XLl+Piiy9G3bp1Sz7r0aMHmjRpgjfffNOw/smTJyMuLg7r16+P+Hzs2LFISkrCd999p3tu5cqVcfbZZ5f6/LLLLgOAiHauWrUKBQUFuPHGG0s+C4VCGDduHPbv348tW7YYtnPkyJFITU3Fr7/+it69e6NcuXKoWbMmHnrooVJRohMnTmDSpEmoU6cOypQpg6ZNm2L69OmljlPPS5s/fz5CoRA+++wz3HrrrahSpQrKlSuHyy67LCI9tn79+vjhhx+wceNGhEIhhEIhdO3aFQBQUFCABx98EI0bN0ZycjIqVaqETp064cMPPzT8fXLdmzZtwvXXX49KlSohLS0NI0aMwLFjx0od/9577+HCCy9EuXLlUL58efTv3x8//PCD5jX75Zdf0K9fP5QvXx5XXXWVZv1TpkzB7bffDgBo0KBBye/6/fffNa+VHl988QX69OmD9PR0pKSkoEuXLvjss89KHde2bVtUrFgRq1atMi2TIAiC8A8k+AgiQFx11VUoLCwsJQiOHj2KDz74AJdddhnKli1rWMaUKVMwfvx41KxZE0899RQGDx6M2bNno1evXigoKIg49tixY+jTpw9atWqFp556Cs2aNcOdd96J9957z7CO9957D4WFhbbTKNesWYNhw4YhMTERjz32GAYNGoTRo0dj69atmsfPmzcPzz//PMaOHYunnnoKFStW1Dxu7dq1GDx4MEKhEB577DEMHDiQa17h5s2b0bx5cyQmJpoeK0kS/vrrL1SuXLnkswMHDuDw4cM499xzSx3fvn17fPvtt4Zl3nfffWjdujVGjx5dMqfzgw8+wEsvvYQHHngArVq1YvodSg4dOgQAEe389ttvUa5cOZx55pml2ih/b0ZRURH69OmDatWq4cknn0Tbtm0xefJkTJ48ueQYSZJwySWX4JlnnkGfPn3w9NNPo2nTprj99ttx6623MrX/pptuwnfffYfJkydj3LhxeOeddyLmVz777LOoXbs2mjVrhtdeew2vvfYa7r33XgDFz8SDDz6Ibt26YcaMGbj33ntRt25dfPPNN0x1T5gwAT/99BOmTJmCESNG4I033sDAgQMjxOprr72G/v37IzU1FU888QTuv/9+/Pjjj+jUqVOJQJMpLCxE7969UbVqVUyfPh2DBw/WrHfQoEG44oorAADPPPNMye+qUqUKU7sB4KOPPkLnzp2RnZ2NyZMnY+rUqcjKysJFF12EL7/8stTx55xzjqYYJAiCsATN4XMHT+OLBEFwUVhYKNWoUUPq0KFDxOcvvviiBED64IMPDM8/fPiwlJSUJPXq1UsqKioq+XzGjBkSAOmVV14p+axLly4SAOnVV18t+ezUqVNS9erVpcGDBxvWM3HiRAmA9O2333L8utK0aNFCql27tvTvv/+WfPbxxx9LACJSL3/77TcJgJSWliYdPnw4ogz5u3nz5pV81rp1a6lGjRpSVlZWyWdr164tVa4etWvXNr0GMq+99poEQJo7d27JZ1999VWpaytz++23SwCkvLw8w3K///57KSkpSRozZox07NgxqVatWtK5554rFRQUMLVLyalTp6SzzjpLatCgQcT5/fv3lxo2bFjq+BMnTkgApLvuusuw3MzMTAmAdNNNN5V8Fg6Hpf79+0tJSUnS33//LUmS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M2bMiDh/xowZSExMLJlz2q9fPxQVFUUcBxSvPBkKhdC3b1+meswoV66c5gbl//zzT8S/U1NT0ahRI810Vi3mzJkTscLtrFmzUFhYWNLu3r17Iy0tDVOnTi21Ei6AiO0jeClXrhwAaP4uM9q2bYszzjgD06dPj3jGjNr1zTffMN93giAIwh9QhI8gAkiDBg3QsWPHkv2wWAVflSpVcPfdd+PBBx9Enz59cMkll2DXrl2YOXMm2rVrF7FAi12eeuop/PLLL/jf//6Ht956CxdffDEqVKiAvXv3YunSpdi5cyeGDx9uWMbUqVNx6aWX4oILLsCoUaNw7NgxzJgxA82bN9d0UFl57LHH0L9/f3Tq1AnXXnstjh49iueffx5nn302U7mXXnopHn74YWzcuBG9evUq+XzSpEl4++23MWDAABw9ehSvv/56xHnK63vPPfdg6dKl6NatG26++Wbk5ORg2rRpaNGiBUaNGmVY/08//YT7778fI0eOxIABAwAUp2e2bt0aN954o+E+fn/88QcuueQShEIhDBkyBEuXLo34vmXLlmjZsiWA4jmct9xyC6ZNm4aCggK0a9cOK1euxCeffII33njDdM4oULzAy/vvv4/MzEycd955eO+997BmzRrcc889JQvsDBgwAN26dcO9996L33//Ha1atcLatWuxatUq3HLLLSWRKLu0bdsWs2bNwiOPPIJGjRqhatWquOiii3DWWWeha9euJfvMff3111i2bFnEYjNG5Ofno3v37hg6dGjJ89SpU6eSPTHT0tIwa9YsXHPNNTjnnHMwfPhwVKlSBXv37sWaNWtwwQUXlBK7PL8JAO69914MHz4ciYmJGDBgQIkQNCIuLg4vv/wy+vbti7PPPhujRo1CrVq1cODAAWzYsAFpaWl45513So7funUrjh49iksvvdRSWwmCIEpBET538Gp5UIIg7PHCCy9IAKT27dtznztjxgypWbNmUmJiolStWjVp3Lhx0rFjxyKO6dKli3T22WeXOjczM5Np6wJJKt5G4uWXX5YuvPBCKT09XUpMTJTq1asnjRo1innLhsWLF0vNmjWTypQpIzVv3lx6++23pcGDB0vNmjUrOUbeemHatGmlztfalkGSJGn58uXSmWeeKZUpU0Y666yzpLfeeovrt7Vs2VIaPXp0xGfyVhZ6f2p27Ngh9erVS0pJSZEy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ePHFF7Ft2zZ88MEHaGpq8nqTiJQKBIBTp1r+W3LgpOUfLA3UhATwkVei0Lp164b8/HwMHToUHTp08HpziGIaA5+7GPiIiIiIiMg1RuDr2VNP4KupYeAz4ygXREREREREMYqd0omIiIiIyHVNTVD+uAGf5DkbK3xEREREREQxihU+IiIiIiJyHSt87mDgIyIiIiIi1zHwuYNdOomIiIiIiGIUK3xEREREROS6QEB9RY4Tzp2NFT4iIiIiIqIYxQofERERERG5TsfzdnyG72ys8BEREREREcUoVviIiIiIiMh1rPC5gxU+IiIiIiKiGMUKHxERERERuY4VPncw8BERERERkesY+NzBLp1EREREREQxihU+IiIiIiJyHSt87mCFj4iIiIiIKEaxwkdERERERK5jhc8drPARERERERHFKFb4iIiIiIjIdazwuYMVPiIiIiIiohjFCh8REREREbmOFT53MPAREREREZHrAgH1AS0QULu8WMAunURERERERDGKFT4iIiIiInJdUxOQkKB2mazwnY0VPiIiIiIiohjFCh8REREREbmOFT53sMJHREREREQUo1jhIyIiIiIi17HC5w5W+IiIiIiIiGIUK3xEREREROQ6VvjcwcBHRERERESuY+BzB7t0EhERERERxShW+IiIiIiIyHWs8LmDFT4iIiIiIqIYxQofERERERG5jhU+d7DCR0REREREFKMY+IiIiIiIyHVNTXpeup04cQJ9+/ZFQkICqqqqWvysuroagwcPRlpaGrKysrBs2TL9GxQBAx8REREREZFNv/3tb/H973//rH+vr69Hfn4+unXrhrfeegvLly/HXXfdhZKSEg+28gw+w0dERERERK4LBKLvmbvy8nJUVFRg7dq1KC8vb/GzZ555Bo2NjXjssceQkpKCXr16oaqqCitWrMCcOXM82mIGPiIiIiIi8kS9tmXW17dcdmpqKlJTU6WWfOTIEcyePRvr169HmzZtzvr59u3bMWTIEKSkpJz+t+HDh6O4uBhfffUVMjIypNYvil06iYiIiIjINSkpKcjMzASQBSBd8SsLbdu2RVZWFtLT00+/li5dKrXNgUAA1157LebNm4cBAwYEfU9tbS3OP//8Fv9m/Hdtba3U+mWwwkdERERERK5JS0vDRx99hMbGRi3LDwQCSLDM9xCquldUVITi4uKwy6upqUFFRQX+85//4Pbbb1e2nW5h4CMiIiIiIlelpaUhLS3N683Ab37zG1x77bVh33PRRRfhpZdewvbt288KjgMGDMCUKVPw5JNPIjMzE0eOHGnxc+O/myua3kgIBKLtUUkiIiIiIiL3fPzxxy2eCzx06BCGDx+O559/HpdddhkuuOACrFq1CosWLcKRI0fQqlUrAMDChQuxbt067Nu3z6tNZ+AjIiIiIiJy4sCBA7jwwguxe/du9O3bFwBQV1eH7Oxs5Ofno7CwEO+88w6uu+46rFy5kqN0EhERERERRbP09HRUVFRg/vz5yMvLQ8eOHbF48WJPwx7ACh8REREREVHM4rQMREREREREMYqBj4iIiIiIKEYx8BEREREREcUoBj4iIiIiIqIYxcBHREREREQUoxj4iIiIiIiIYhQDHxERERERUYxi4CMiIiIiIopRDHxEREREREQxioGPiIiIiIgoRjHwERERERERxaj/B0YzFoustYjfAAAAAElFTkSuQmCC\n", + "image/png": "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7733Xtx5553o2bMnnn/+edStWxdXXnklFi9e7Fgbjdi1axdeeuklS+dGq+B78MEHNQWfnWulJjk5GZmZmXj66ach0Qp4BEEQwUIiCCIQ5ObmSuXLl5d69+6t+f3ChQslANLixYtdbpk248ePlwBIzzzzTKnvCgsLpWnTpkn79u1zrP6CggLp1KlTXOdkZmZK9erVMz3um2++kQBI69ati/j8s88+K1Xn7t27pTJlykhXXXVVxOfjxo2TypYtK/3xxx8ln3344YcSAGn27Nlc7ebh77//lnbs2FHq81GjRkkApD179pR8tn//fikxMVEaP358yWfhcFi68MILpdq1a0uFhYWOtdMJzj77bKlLly5eN4ObnJwc3e+mTZsmAZB+++0303I2bNggAZA2bNhgqR1ff/21BEBav369pfMJgiBkjh8/LgGQjlevLkk1awr9O169enHZx497/TN9A0X4CCIglC1bFoMGDcL69etx+PDhUt8vXLgQ5cuXxyWXXGJa1syZM3H22WejTJkyqFmzJsaPH18qQtC1a1c0b94cP/74I7p164aUlBTUqlULTz75pGn5+/fvx+zZs9GzZ0/ccsstpb6Pj4/Hbbfdhtq1a5uWtXTpUpx11llITk5G8+bNsWLFilJz7eR5etOnT8ezzz6LM844A2XKlMGPP/6oO4dv5cqVaN68eUS5rKxcuRJJSUno3LlzxOcdO3ZEUlJSxGeNGzfG2WefjZ9++ini8+XLl+Piiy9G3bp1Sz7r0aMHmjRpgjfffNOw/smTJyMuLg7r16+P+Hzs2LFISkrCd999p3tu5cqVcfbZZ5f6/LLLLgOAiHauWrUKBQUFuPHGG0s+C4VCGDduHPbv348tW7YYtnPkyJFITU3Fr7/+it69e6NcuXKoWbMmHnrooVJRohMnTmDSpEmoU6cOypQpg6ZNm2L69OmljlPPS5s/fz5CoRA+++wz3HrrrahSpQrKlSuHyy67LCI9tn79+vjhhx+wceNGhEIhhEIhdO3aFQBQUFCABx98EI0bN0ZycjIqVaqETp064cMPPzT8fXLdmzZtwvXXX49KlSohLS0NI0aMwLFjx0od/9577+HCCy9EuXLlUL58efTv3x8//PCD5jX75Zdf0K9fP5QvXx5XXXWVZv1TpkzB7bffDgBo0KBBye/6/fffNa+VHl988QX69OmD9PR0pKSkoEuXLvjss89KHde2bVtUrFgRq1atMi2TIAiC8A8k+AgiQFx11VUoLCwsJQiOHj2KDz74AJdddhnKli1rWMaUKVMwfvx41KxZE0899RQGDx6M2bNno1evXigoKIg49tixY+jTpw9atWqFp556Cs2aNcOdd96J9957z7CO9957D4WFhbbTKNesWYNhw4YhMTERjz32GAYNGoTRo0dj69atmsfPmzcPzz//PMaOHYunnnoKFStW1Dxu7dq1GDx4MEKhEB577DEMHDiQa17h5s2b0bx5cyQmJpoeK0kS/vrrL1SuXLnkswMHDuDw4cM499xzSx3fvn17fPvtt4Zl3nfffWjdujVGjx5dMqfzgw8+wEsvvYQHHngArVq1YvodSg4dOgQAEe389ttvUa5cOZx55pml2ih/b0ZRURH69OmDatWq4cknn0Tbtm0xefJkTJ48ueQYSZJwySWX4JlnnkGfPn3w9NNPo2nTprj99ttx6623MrX/pptuwnfffYfJkydj3LhxeOeddyLmVz777LOoXbs2mjVrhtdeew2vvfYa7r33XgDFz8SDDz6Ibt26YcaMGbj33ntRt25dfPPNN0x1T5gwAT/99BOmTJmCESNG4I033sDAgQMjxOprr72G/v37IzU1FU888QTuv/9+/Pjjj+jUqVOJQJMpLCxE7969UbVqVUyfPh2DBw/WrHfQoEG44oorAADPPPNMye+qUqUKU7sB4KOPPkLnzp2RnZ2NyZMnY+rUqcjKysJFF12EL7/8stTx55xzjqYYJAiCsATN4XMHT+OLBEFwUVhYKNWoUUPq0KFDxOcvvviiBED64IMPDM8/fPiwlJSUJPXq1UsqKioq+XzGjBkSAOmVV14p+axLly4SAOnVV18t+ezUqVNS9erVpcGDBxvWM3HiRAmA9O2333L8utK0aNFCql27tvTvv/+WfPbxxx9LACJSL3/77TcJgJSWliYdPnw4ogz5u3nz5pV81rp1a6lGjRpSVlZWyWdr164tVa4etWvXNr0GMq+99poEQJo7d27JZ1999VWpaytz++23SwCkvLw8w3K///57KSkpSRozZox07NgxqVatWtK5554rFRQUMLVLyalTp6SzzjpLatCgQcT5/fv3lxo2bFjq+BMnTkgApLvuusuw3MzMTAmAdNNNN5V8Fg6Hpf79+0tJSUnS33//LUmS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M2bMiDh/xowZSExMLJlz2q9fPxQVFUUcBxSvPBkKhdC3b1+meswoV66c5gbl//zzT8S/U1NT0ahRI810Vi3mzJkTscLtrFmzUFhYWNLu3r17Iy0tDVOnTi21Ei6AiO0jeClXrhwAaP4uM9q2bYszzjgD06dPj3jGjNr1zTffMN93giAIwh9QhI8gAkiDBg3QsWPHkv2wWAVflSpVcPfdd+PBBx9Enz59cMkll2DXrl2YOXMm2rVrF7FAi12eeuop/PLLL/jf//6Ht956CxdffDEqVKiAvXv3YunSpdi5cyeGDx9uWMbUqVNx6aWX4oILLsCoUaNw7NgxzJgxA82bN9d0UFl57LHH0L9/f3Tq1AnXXnstjh49iueffx5nn302U7mXXnopHn74YWzcuBG9evUq+XzSpEl4++23MWDAABw9ehSvv/56xHnK63vPPfdg6dKl6NatG26++Wbk5ORg2rRpaNGiBUaNGmVY/08//YT7778fI0eOxIABAwAUp2e2bt0aN954o+E+fn/88QcuueQShEIhDBkyBEuXLo34vmXLlmjZsiWA4jmct9xyC6ZNm4aCggK0a9cOK1euxCeffII33njDdM4oULzAy/vvv4/MzEycd955eO+997BmzRrcc889JQvsDBgwAN26dcO9996L33//Ha1atcLatWuxatUq3HLLLSWRKLu0bdsWs2bNwiOPPIJGjRqhatWquOiii3DWWWeha9euJfvMff3111i2bFnEYjNG5Ofno3v37hg6dGjJ89SpU6eSPTHT0tIwa9YsXHPNNTjnnHMwfPhwVKlSBXv37sWaNWtwwQUXlBK7PL8JAO69914MHz4ciYmJGDBgQIkQNCIuLg4vv/wy+vbti7PPPhujRo1CrVq1cODAAWzYsAFpaWl45513So7funUrjh49iksvvdRSWwmCIEpBET538Gp5UIIg7PHCCy9IAKT27dtznztjxgypWbNmUmJiolStWjVp3Lhx0rFjxyKO6dKli3T22WeXOjczM5Np6wJJKt5G4uWXX5YuvPBCKT09XUpMTJTq1asnjRo1innLhsWLF0vNmjWTypQpIzVv3lx6++23pcGDB0vNmjUrOUbeemHatGmlztfalkGSJGn58uXSmWeeKZUpU0Y666yzpLfeeovrt7Vs2VIaPXp0xGfyVhZ6f2p27Ngh9erVS0pJSZEy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ePHFF7Ft2zZ88MEHaGpq8nqTiJQKBIBTp1r+W3LgpOUfLA3UhATwkVei0Lp164b8/HwMHToUHTp08HpziGIaA5+7GPiIiIiIiMg1RuDr2VNP4KupYeAz4ygXREREREREMYqd0omIiIiIyHVNTVD+uAGf5DkbK3xEREREREQxihU+IiIiIiJyHSt87mDgIyIiIiIi1zHwuYNdOomIiIiIiGIUK3xEREREROS6QEB9RY4Tzp2NFT4iIiIiIqIYxQofERERERG5TsfzdnyG72ys8BEREREREcUoVviIiIiIiMh1rPC5gxU+IiIiIiKiGMUKHxERERERuY4VPncw8BERERERkesY+NzBLp1EREREREQxihU+IiIiIiJyHSt87mCFj4iIiIiIKEaxwkdERERERK5jhc8drPARERERERHFKFb4iIiIiIjIdazwuYMVPiIiIiIiohjFCh8REREREbmOFT53MPAREREREZHrAgH1AS0QULu8WMAunURERERERDGKFT4iIiIiInJdUxOQkKB2mazwnY0VPiIiIiIiohjFCh8REREREbmOFT53sMJHREREREQUo1jhIyIiIiIi17HC5w5W+IiIiIiIiGIUK3xEREREROQ6VvjcwcBHRERERESuY+BzB7t0EhERERERxShW+IiIiIiIyHWs8LmDFT4iIiIiIqIYxQofERERERG5jhU+d7DCR0REREREFKMY+IiIiIiIyHVNTXpeup04cQJ9+/ZFQkICqqqqWvysuroagwcPRlpaGrKysrBs2TL9GxQBAx8REREREZFNv/3tb/H973//rH+vr69Hfn4+unXrhrfeegvLly/HXXfdhZKSEg+28gw+w0dERERERK4LBKLvmbvy8nJUVFRg7dq1KC8vb/GzZ555Bo2NjXjssceQkpKCXr16oaqqCitWrMCcOXM82mIGPiIiIiIi8kS9tmXW17dcdmpqKlJTU6WWfOTIEcyePRvr169HmzZtzvr59u3bMWTIEKSkpJz+t+HDh6O4uBhfffUVMjIypNYvil06iYiIiIjINSkpKcjMzASQBSBd8SsLbdu2RVZWFtLT00+/li5dKrXNgUAA1157LebNm4cBAwYEfU9tbS3OP//8Fv9m/Hdtba3U+mWwwkdERERERK5JS0vDRx99hMbGRi3LDwQCSLDM9xCquldUVITi4uKwy6upqUFFRQX+85//4Pbbb1e2nW5h4CMiIiIiIlelpaUhLS3N683Ab37zG1x77bVh33PRRRfhpZdewvbt288KjgMGDMCUKVPw5JNPIjMzE0eOHGnxc+O/myua3kgIBKLtUUkiIiIiIiL3fPzxxy2eCzx06BCGDx+O559/HpdddhkuuOACrFq1CosWLcKRI0fQqlUrAMDChQuxbt067Nu3z6tNZ+AjIiIiIiJy4sCBA7jwwguxe/du9O3bFwBQV1eH7Oxs5Ofno7CwEO+88w6uu+46rFy5kqN0EhERERERRbP09HRUVFRg/vz5yMvLQ8eOHbF48WJPwx7ACh8REREREVHM4rQMREREREREMYqBj4iIiIiIKEYx8BEREREREcUoBj4iIiIiIqIYxcBHREREREQUoxj4iIiIiIiIYhQDHxERERERUYxi4CMiIiIiIopRDHxEREREREQxioGPiIiIiIgoRjHwERERERERxaj/B0YzFoustYjfAAAAAElFTkSuQmCC", "text/plain": [ "
" ] @@ -906,7 +906,7 @@ }, { "data": { - "image/png": "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qjJaVvwz7uLiovHPwvXr10uN5BIRUUl8ho7IgBTfhJa1sfjTzMzMSo0G/Prrr2WOcEh97SdrAEqOSmRmZpYKOz179oSdnR3mz59fann14teGhYXB398fX331FbKzs0td6969exrX9bT09PQSH9va2qJhw4YlpveV9/7NzMwgCEKJKa2JiYllbhhdu3btMl//3HPPYcuWLbhw4UKp12jyvsLDw3Hy5MlS53NychAZGYnk5GTs2rWr3Cl2Dg4O6N69O3766Sc8fPhQfX79+vXIzs7WaHPxWbNmISkpCT/88AMWLVoEHx8fjB07tswpkk/buHEjpk+fjlGjRmHRokXlthsyZAiUSmWJqan5+flYu3Yt2rZtW+kKlwBQVFRU4tm+goICfPfdd6hXrx7CwsIAAJGRkUhJScHGjRtLvO7bb7+Fra0tunTpUul1NFHW94NSqVQ/W1rMxcUFHh4eGn0tAai3DihW/CxicRgcPHgwzMzMMHfu3FJ/R4iiWOrnQRu6/D1RrFevXrC3t8dnn32GwsLCUp9/+mchMzMT8fHxaN++vU61EpHhKx6hk/owNRyhIzIgxTec77//PkaMGAELCwv069evzA2z+/bti48//hjjx49H+/btcf78efz3v//VeQPe5s2bw8zMDAsWLEBmZiasrKzU+8uVp2fPnrC0tES/fv3w8ssvIzs7G6tXr4aLi0uJ6X329vb4+uuvMXHiRLRu3Vq9d9zZs2eRm5uLH374AQqFAmvWrMGzzz6L4OBgjB8/HvXr10dycjIOHjwIe3t7/PHHHzq9tyZNmqBr164ICwuDs7MzTp48qV42vljx13769Ono1asXzMzMMGLECPTp0weLFi1C79698fzzz+Pu3btYtmwZGjZsiHPnzpW4TlhYGPbv349FixbBw8MDvr6+aNu2LT7//HMcPHgQbdu2xaRJk9CkSRPcv38fp0+fxv79+3H//v0K6x8wYADWr1+PuLi4EiMuo0aNwvHjxzFhwgRcvny5xD5xtra2GDhwoPrjefPmoX379ujSpQteeukl3Lp1CwsXLkTPnj3Ru3fvCq9/4MABLF++HLNnz1Yvq7927Vp07doVH374Ib744otyX3v8+HGMGTMGderUQUREBP773/+W+Hz79u3V37Nt27bF0KFD8e677+Lu3bto2LAhfvjhByQmJpYaiS6Ph4cHFixY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bXfGgCN0RERERERERoojdEREREREVP34DJ0kOEJHRERERERkpDhCR0RERERE1U+lAqDSQ5+mhSN0RERERERERoojdEREREREVP34DJ0kGOiIiIiIiKj6MdBJglMuiYiIiIiIjBRH6IiIiIiIqPqpREi+E7iKI3RERERERERkJDhCR0RERERE1U4UVRBFabcZkLo/Y8AROiIiIiIiIiPFEToiIiIiIqp+oij9M29c5ZKIiIiIiIiMBUfoiIiIiIio+ol6WOXSBEfoGOiIiIiIiKj6qVSAIPEiJlwUhYiIiIiIiIwFR+iIiIiIiKj6ccqlJDhCR0REREREZKQ4QkdERERERNVOVKkgSvwMHTcWJyIiIiIiIqPBEToiIiIiIqp+fIZOEhyhIyIiIiIiMlIcoSMiIiIiouqnEgGBI3RVxUBHRERERETVTxQBSL2xuOkFOk65JCIiIiIiMlIcoSMiIiIiomonqkSIEk+5FDlCR0RERERERMaCI3RERERERFT9RBWkf4aOG4sTERERERGZjGXLlsHHxwfW1tZo27Ytjh8/XmH7X3/9FY0aNYK1tTWaNm2KXbt2VVOlZWOgIyIiIiKiaieqRL0c2ti4cSNmzpyJ2bNn4/Tp0wgNDUWvXr1w9+7dMtsfO3YMI0eOxIsvvogzZ85g4MCBGDhwIC5cuCDFl0QngmiKTw4SEREREZEssrKy4ODggK7CIJgLFpL2XSQW4pD4GzIzM2Fvb19p+7Zt26J169ZYunQpAEClUsHT0xPTpk3DO++8U6r98OHDkZOTgx07dqjPtWvXDs2bN8fKlSuleyNa4AgdERERERFVP1Gln0NDBQUFOHXqFLp3764+p1Ao0L17d0RHR5f5mujo6BLtAaBXr17ltq8OXBSFiIiIiIiqXREKAYnnChahEMDjUcAnWVlZwcrKqsS5tLQ0KJVKuLq6ljjv6uqK2NjYMvtPSUkps31KSkpVS9cZAx0REREREVUbS0tLuLm54UiKfhYTsbW1haenZ4lzs2fPxpw5c/RyPbkx0BERERERUbWxtrbG9evXUVBQoJf+RVGEIAglzj09OgcAdevWhZmZGVJTU0ucT01NhZubW5l9u7m5adW+OjDQERERERFRtbK2toa1tbWsNVhaWiIsLAxRUVEYOHAggMeLokRFRWHq1KllviY8PBxRUVF4/fXX1ef27duH8PDwaqi4bAx0RERERERkkmbOnImxY8eiVatWaNOmDRYvXoycnByMHz8eADBmzBjUr18f8+fPBwC89tpr6NKlCxYuXIg+ffpgw4YNOHnyJFatWiXbe2CgIyIiIiIikzR8+HDcu3cPH330EVJSUtC8eXPs2bNHvfBJUlISFIr/3xigffv2+Pnnn/HBBx/gvffeQ0BAALZt24aQkBC53gL3oSMiIiIiIjJW3IeOiIiIiIjISDHQERERERERGSkGOiIiIiIiIiPFQEdERERERGSkGOiIiIiIiIiMFAMdERERERGRkWKgIyIiIiIiMlIMdEREREREREaKgY6IiIiIiMhIMdAREREREREZKQY6IiIiIiIiI8VAR0REREREZKT+D260lH+RayGUAAAAAElFTkSuQmCC\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA3QAAAHwCAYAAADuLi1cAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAACCs0lEQVR4nO3deXxMV/8H8M+d7GRHNrJLgoQgttgrtsau1qq1tKVo6aI72qpqS2ltxVNafVoUVbUVsbRIa409QiJCSEhIIolsM/f3hyfzE9lmJndyZzKf9+t1X21uzpz7nUi4n5xzzxFEURRBRERERERERkchdwFERERERESkGwY6IiIiIiIiI8VAR0REREREZKQY6IiIiIiIiIwUAx0REREREZGRYqAjIiIiIiIyUgx0RERERERERoqBjoiIiIiIyEgx0BERERERERkpBjoiIiIiIiIjxUBHREREREQm6a+//kK/fv3g4eEBQRCwbdu2Sl9z6NAhtGzZElZWVmjYsCHWrVun9zorwkBHREREREQmKScnB6GhoVi2bJlG7a9fv44+ffrgmWeeQUxMDF5//XVMnDgRf/75p54rLZ8giqIo29WJiIiIiIgMgCAI+O233zBw4MBy28yaNQs7d+7EhQsX1OdGjBiBjIwM7NmzpxqqLI0jdERERERERBqIjo5G9+7dS5zr1asXoqOjZaoIMJftykREREREZJLy8vJQUFCgl75FUYQgCCXOWVlZwcrKqsp9p6SkwNXVtcQ5V1dXZGVl4dGjR7CxsanyNbTFQEdERERERNUmLy8Pvt62SLmr1Ev/tra2yM7OLnFu9uzZmDNnjl6uJzcGOiIiIiIiqjYFBQVIuavE9VPesLeT9gmwrIcq+IbdwM2bN2Fvb68+L8XoHAC4ubkhNTW1xLnU1FTY29vLMjoHMNAREREREZEM7O0Ukgc6dd/29iUCnVTCw8Oxa9euEuf27duH8PBwya+lKS6KQkRERERE1U4pqvRyaCM7OxsxMTGIiYkB8HhbgpiYGCQlJQEA3n33XYwZM0bd/pVXXkFCQgLefvttxMbGYvny5di0aRNmzJgh2ddFWwx0RERERERkkk6ePIkWLVqgRYsWAICZM2eiRYsW+OijjwAAd+7cUYc7APD19cXOnTuxb98+hIaGYuHChVizZg169eolS/0A96EjIiIiIqJqlJWVBQcHB6Rc8dLLM3RuQUnIzMzUy5RLQ8QROiIiIiIiIiPFRVGIiIiIiKjaqaCCdk+8adanqeEIHRERERERkZHiCB0REREREVU7pShCKfFyHlL3ZwwY6IiIiIiIqNqpIEIFaQOY1P0ZA065JCIiIiIiMlIcoSMiIiIiomqnggglR+iqjCN0RERERERERoojdEREREREVO34DJ00OEJHRERERERkpDhCR0RERERE1Y7bFkiDI3RERERERERGiiN0RERERERU7VT/O6Tu09RwhI5IRoIgYM6cORq19fHxwbhx47S+RmJiIgRBwLp167R+LRmO7OxsuLi44L///a/cpZgUbX5GTd3TX6t169ZBEAQkJiZq3dc777yDtm3bSlccERkk5f+2LZD6MDUMdERVUHzDcvLkSUn6O3bsGObMmYOMjAxJ+tPGpUuXMGfOHJ1uvmqCXbt2VfnG/bPPPsO2bdskqedpS5YsgZ2dHUaMGKE+FxUVhQkTJiAwMBC1atWCn58fJk6ciDt37pTZx7Fjx9CxY0fUqlULbm5umD59OrKzs/VSb7H09HR8+eWX6Ny5M+rVqwdHR0e0a9cOGzduLLN9fn4+Zs2aBQ8PD9jY2KBt27bYt2+fXmvUF31+P8hFip8TTbz++us4e/Ystm/frvdrEREZOwY6Ihk9evQIH3zwgfrjY8eOYe7cuWUGuitXrmD16tV6q+XSpUuYO3euSQe6uXPnVqkPfd3AFxYWYsmSJZg4cSLMzMzU52fNmoVDhw5h0KBB+OabbzBixAhs2rQJLVq0QEpKSok+YmJiEBERgdzcXCxatAgTJ07EqlWrMHToUMnrfVJ0dDTef/99ODs744MPPsC8efNQq1YtjBgxArNnzy7Vfty4cVi0aBFGjRqFJUuWwMzMDJGRkThy5Ihe6yzP0z+j2qipga68n5OqfK2e5ubmhgEDBuCrr76SpD8iMkxKUT+HqeEzdEQysra21ritlZWVHivRjiiKyMvLg42NjdylqOXk5KB27dpyl6EXO3bswL179zBs2LAS5xctWoSOHTtCofj/38317t0bXbp0wdKlS/Hpp5+qz7/33ntwcnLCoUOHYG9vD+DxNN5JkyZh79696Nmzp15qDw4OxtWrV+Ht7a0+N2XKFHTv3h0LFizA22+/rf5zO378ODZs2IAvv/wSb775JgBgzJgxCAkJwdtvv41jx47ppcaKaPMzWlPk5uaiVq1aWr9O6q/VsGHDMHToUCQkJMDPz0/SvomIahKO0BFJbNy4cbC1tUVycjIGDhwIW1tb1KtXD2+++SaUSmWJtk8+czJnzhy89dZbAABfX18IglDi+ZOnn6G7f/8+3nzzTTRt2hS2trawt7fHs88+i7Nnz2pd87p169QjNc8884z62ocOHVJfu2/fvvjzzz/RqlUr2NjY4LvvvgMArF27Ft26dYOLiwusrKzQpEkTrFixoszr7N69G126dIGdnR3s7e3RunVr/PzzzyXa/Pvvv+jduzccHBxQq1YtdOnSBUePHi3RZs6cORAEAZcuXcLzzz8PJycndOzYsdz3V1hYiLlz5yIgIADW1taoU6cOOnbsqJ7KN27cOCxbtgwA1O9dEAT167/66iu0b98ederUgY2NDcLCwrB58+YS1xAEATk5Ofjhhx/Ur3/yzys5ORkTJkyAq6srrKysEBwcjO+//77cmp+0bds2+Pj4wN/fv8T5zp07lwhzxeecnZ1x+fJl9bmsrCzs27cPL7zwgjrMAY/Dkq2tLTZt2lTh9ceOHQtra+sSfQJAr1694OTkhNu3b5f7Wl9f3xJhDnj8tRo4cCDy8/ORkJCgPr9582aYmZnhpZdeUp+ztrbGiy++iOjoaNy8ebPCOrt27YqQkBCcOnUK7du3h42NDXx9fbFy5cpSbe/evYsXX3wRrq6usLa2RmhoKH744YdS7Z5+Lqz4e+/atWsYN24cHB0d4eDggPHjxyM3N7fE68r7fnj48CFef/11+Pj4wMrKCi4uLujRowdOnz5d4fsrvnZsbCyGDRsGe3t71KlTB6+99hry8vJKtf/pp58QFhYGGxsbODs7Y8SIEaW+hk9+zTp37oxatWrhvffeK/P6lf2caPq84e7du9GpUyfUrl0bdnZ26NOnDy5evFiqXffu3QEAv//+e6V9EpFxUunpMDUcoSPSA6VSiV69eqFt27b46quvsH//fixcuBD+/v6YPHlyma8ZPHgw4uLi8Msvv+Drr79G3bp1AQD16tUrs31CQgK2bduGoUOHwtfXF6mpqfjuu+/QpUsXXLp0CR4eHhrX27lzZ0yfPh3ffPMN3nvvPTRu3BgA1P8FHk/5HDlyJF5++WVMmjQJQUFBAIAVK1YgODgY/fv3h7m5Of744w9MmTIFKpUKr776qvr169atw4QJExAcHIx3330Xjo6OOHPmDPbs2YPnn38eAHDgwAE8++yzCAsLw+zZs6FQKNSB8e+//0abNm1K1D106FAEBATgs88+g1jBvjNz5szB/PnzMXHiRLRp0wZZWVk4efIkTp8+jR49euDll1/G7du3sW/fPqxfv77U65csWYL+/ftj1KhRKCgowIYNGzB06FDs2LEDffr0AQCsX79e3X9xICkOYKmpqWjXrh0EQcDUqVNRr1497N69Gy+++CKysrLw+uuvV/jnc+zYMbRs2bLCNsWys7ORnZ2t/v4BgPPnz6OoqAitWrUq0dbS0hLNmzfHmTNnKuxzyZIlOHDgAMaOHYvo6GiYmZnhu+++w969e7F+/XqtvteKFU8JfbLOM2fOIDAwsEToBKD+c4+JiYGnp2eF/T548ACRkZEYNmwYRo4ciU2bNmHy5MmwtLTEhAkTADyeGti1a1dcu3YNU6dOha+vL3799VeMGzcOGRkZeO211yqtf9iwYfD19cX8+fNx+vRprFmzBi4uLliwYAGAir8fXnnlFWzevBlTp05FkyZNkJ6ejiNHjuDy5csa/TkPGzYMPj4+mD9/Pv755x988803ePDgAX788Ud1m3nz5uHDDz/EsGHDMHHiRNy7dw/ffvstOnfujDNnzsDR0VHdNj09Hc8++yxGjBiBF154Aa6urmVet7KfE02sX78eY8eORa9evbBgwQLk5uZixYoV6NixI86cOQMfHx91WwcHB/j7++Po0aOYMWOGTtcjIjIJIhHpbO3atSIA8cSJE+pzY8eOFQGIH3/8cYm2LVq0EMPCwkqcAyDOnj1b/fGXX34pAhCvX79e6lre3t7i2LFj1R/n5eWJSqWyRJvr16+LVlZWJa59/fp1EYC4du3aCt/Lr7/+KgIQDx48WOa1AYh79uwp9bnc3NxS53r16iX6+fmpP87IyBDt7OzEtm3bio8ePSrRVqVSqf8bEBAg9urVS32uuH9fX1+xR48e6nOzZ88WAYgjR46s8D0VCw0NFfv06VNhm1dffVUs76/Ep99jQUGBGBISInbr1q3E+dq1a5f4Myr24osviu7u7mJaWlqJ8yNGjBAdHBzK/BoWKywsFAVBEN94440K6y/2ySefiADEqKgo9bniP9u//vqrVPuhQ4eKbm5ulfb7559/igDETz/9VExISBBtbW3FgQMHalTT09LT00UXFxexU6dOJc4HBweX+pqKoihevHhRBCCuXLmywn67dOkiAhAXLlyoPpefny82b95cdHFxEQsKCkRRFMXFixeLAMSffvpJ3a6goEAMDw8XbW1txaysLPX5p39Gi7/3JkyYUOLagwYNEuvUqVPiXHnfDw4ODuKrr75a4XspS/G1+/fvX+L8lClTRADi2bNnRVEUxcTERNHMzEycN29eiXbnz58Xzc3NS5wv/ppV9rUtVtHPydNfq+K/H4v/Pnv48KHo6OgoTpo0qcTrUlJSRAcHh1LnRVEUe/bsKTZu3Fij2ojIeGRmZooAxNOXXMW4m+6SHqcvuYoAxMzMTLnfZrXhlEsiPXnllVdKfNypU6cS08uqysrKSj3dTqlUIj09Hba2tggKCqp06pYufH190atXr1Lnn3yOLjMzE2lpaejSpQsSEhKQmZkJANi3bx8ePnyId955p9RzNsVTtmJiYnD16lU8//zzSE9PR1paGtLS0pCTk4OIiAj89ddfUKlKTqR4+mtcHkdHR1y8eBFXr17V6j2X9R4fPHiAzMxMdOrUSaOvsyiK2LJlC/r16wdRFNXvKy0tDb169UJmZmaF/dy/fx+iKMLJyanSa/3111+YO3cuhg0bhm7duqnPP3r0CEDZz2FaW1urP1+Rnj174uWXX8bHH3+MwYMHw9raWj3tVhsqlQqjRo1CRkYGvv322xKfe/ToUbk1Pvk+KmJubo6XX35Z/bGlpSVefvll3L17F6dOnQLweGEPNzc3jBw5Ut3OwsJCvern4cOHK71OWT/f6enpyMrKqvS1jo6O+PfffyucqlqRJ0e+AWDatGkAHr8vANi6dStUKhWGDRtW4vvNzc0NAQEBOHjwYInXW1lZYfz48TrVoo19+/YhIyMDI0eOLFGXmZkZ2rZtW6ouAHByckJaWpreayMiMmacckmkB9bW1qWmSjo5OeHBgweSXUOlUmHJkiVYvnw5rl+/XuL5vDp16kh2nWK+vr5lnj969Chmz56N6OjoEs8QAY8DnoODA+Lj4wEAISEh5fZfHLbGjh1bbpvMzMwSwaa8mp728ccfY8CAAQgMDERISAh69+6N0aNHo1mzZhq9fseOHfj0008RExOD/Px89fknnx8qz71795CRkYFVq1Zh1apVZba5e/dupf2IFUwpBYDY2FgMGjQIISEhWLNmTYnPFQfSJ2svps3iNl999RV+//13xMTE4Oeff4aLi4tGr3vStGnTsGfPHvz4448IDQ0tVWd5NRZ/vjIeHh6lFscJDAwE8HhPxnbt2uHGjRsICAgo9fxh8RTjGzduVHodLy+vEh8Xf18+ePCg1JTRp33xxRcYO3YsPD09ERYWhsjISIwZM0bjhT8CAgJKfOzv7w+FQqF+3vbq1asQRbFUu2IWFhYlPq5fvz4sLS01unZVFP+MP/nLhieV9XUTRVGjnzMiMk4q8fEhdZ+mhoGOSA+eXFpeXz777DN8+OGHmDBhAj755BM4OztDoVDg9ddfLzWSJYWybqbj4+MRERGBRo0aYdGiRfD09ISlpSV27dqFr7/+Wqs6itt++eWXaN68eZltbG1tK62pLJ07d0Z8fDx+//137N27F2vWrMHXX3+NlStXYuLEiRW+9u+//0b//v3RuXNnLF++HO7u7rCwsMDatWtLLehS0ft64YUXyg2rFQVLZ2dnCIJQ4S8Dbt68iZ49e8LBwQG7du2CnZ1dic+7u7sDQJn70925c0fjZ+DOnDmjDp/nz58vMcKliblz52L58uX4/PPPMXr06FKfd3d3R3Jycpk1AtDpWT19Ke9nvLLgDTx+Bq5Tp0747bffsHfvXnz55ZdYsGABtm7dimeffVbrWp4OPCqVCoIgYPfu3WXWqevPUVUV/yysX78ebm5upT5vbl76luTBgwclnrMkoppFCQFKSPtLG6n7MwYMdEQGRJvfRG/evBnPPPMM/vOf/5Q4n5GRodMNkC6/Bf/jjz+Qn5+P7du3lxixeHrqVPFiEBcuXEDDhg3L7Ku4jb29vXp1Oyk5Oztj/PjxGD9+PLKzs9G5c2fMmTNHHejKe/9btmyBtbU1/vzzzxLTAdeuXVuqbVl91KtXD3Z2dlAqlTq9L3Nzc/j7++P69etlfj49PR09e/ZEfn4+oqKi1OHtSSEhITA3N8fJkydLbH1QUFCAmJiYUtshlCUnJwfjx49HkyZN0L59e3zxxRcYNGgQWrdurdH7WLZsGebMmYPXX38ds2bNKrNN8+bNcfDgQWRlZZUYrfn333/Vn6/M7du3S21hERcXBwDqBTe8vb1x7tw5qFSqEqN0sbGx6s9LoaKfKXd3d0yZMgVTpkzB3bt30bJlS8ybN0+jQHf16tUSo9PXrl2DSqVSvz9/f3+IoghfX1/16KRUqjJaVvwz7uLiovHPwvXr10uN5BIRUUl8ho7IgBTfhJa1sfjTzMzMSo0G/Prrr2WOcEh97SdrAEqOSmRmZpYKOz179oSdnR3mz59fann14teGhYXB398fX331FbKzs0td6969exrX9bT09PQSH9va2qJhw4YlpveV9/7NzMwgCEKJKa2JiYllbhhdu3btMl//3HPPYcuWLbhw4UKp12jyvsLDw3Hy5MlS53NychAZGYnk5GTs2rWr3Cl2Dg4O6N69O3766Sc8fPhQfX79+vXIzs7WaHPxWbNmISkpCT/88AMWLVoEHx8fjB07tswpkk/buHEjpk+fjlGjRmHRokXlthsyZAiUSmWJqan5+flYu3Yt2rZtW+kKlwBQVFRU4tm+goICfPfdd6hXrx7CwsIAAJGRkUhJScHGjRtLvO7bb7+Fra0tunTpUul1NFHW94NSqVQ/W1rMxcUFHh4eGn0tAai3DihW/CxicRgcPHgwzMzMMHfu3FJ/R4iiWOrnQRu6/D1RrFevXrC3t8dnn32GwsLCUp9/+mchMzMT8fHxaN++vU61EpHhKx6hk/owNRyhIzIgxTec77//PkaMGAELCwv069evzA2z+/bti48//hjjx49H+/btcf78efz3v//VeQPe5s2bw8zMDAsWLEBmZiasrKzU+8uVp2fPnrC0tES/fv3w8ssvIzs7G6tXr4aLi0uJ6X329vb4+uuvMXHiRLRu3Vq9d9zZs2eRm5uLH374AQqFAmvWrMGzzz6L4OBgjB8/HvXr10dycjIOHjwIe3t7/PHHHzq9tyZNmqBr164ICwuDs7MzTp48qV42vljx13769Ono1asXzMzMMGLECPTp0weLFi1C79698fzzz+Pu3btYtmwZGjZsiHPnzpW4TlhYGPbv349FixbBw8MDvr6+aNu2LT7//HMcPHgQbdu2xaRJk9CkSRPcv38fp0+fxv79+3H//v0K6x8wYADWr1+PuLi4EiMuo0aNwvHjxzFhwgRcvny5xD5xtra2GDhwoPrjefPmoX379ujSpQteeukl3Lp1CwsXLkTPnj3Ru3fvCq9/4MABLF++HLNnz1Yvq7927Vp07doVH374Ib744otyX3v8+HGMGTMGderUQUREBP773/+W+Hz79u3V37Nt27bF0KFD8e677+Lu3bto2LAhfvjhByQmJpYaiS6Ph4cHFixY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bXfGgCN0RERERERERoojdEREREREVP34DJ0kOEJHRERERERkpDhCR0RERERE1U+lAqDSQ5+mhSN0RERERERERoojdEREREREVP34DJ0kGOiIiIiIiKj6MdBJglMuiYiIiIiIjBRH6IiIiIiIqPqpREi+E7iKI3RERERERERkJDhCR0RERERE1U4UVRBFabcZkLo/Y8AROiIiIiIiIiPFEToiIiIiIqp+oij9M29c5ZKIiIiIiIiMBUfoiIiIiIio+ol6WOXSBEfoGOiIiIiIiKj6qVSAIPEiJlwUhYiIiIiIiIwFR+iIiIiIiKj6ccqlJDhCR0REREREZKQ4QkdERERERNVOVKkgSvwMHTcWJyIiIiIiIqPBEToiIiIiIqp+fIZOEhyhIyIiIiIiMlIcoSMiIiIiouqnEgGBI3RVxUBHRERERETVTxQBSL2xuOkFOk65JCIiIiIiMlIcoSMiIiIiomonqkSIEk+5FDlCR0RERERERMaCI3RERERERFT9RBWkf4aOG4sTERERERGZjGXLlsHHxwfW1tZo27Ytjh8/XmH7X3/9FY0aNYK1tTWaNm2KXbt2VVOlZWOgIyIiIiKiaieqRL0c2ti4cSNmzpyJ2bNn4/Tp0wgNDUWvXr1w9+7dMtsfO3YMI0eOxIsvvogzZ85g4MCBGDhwIC5cuCDFl0QngmiKTw4SEREREZEssrKy4ODggK7CIJgLFpL2XSQW4pD4GzIzM2Fvb19p+7Zt26J169ZYunQpAEClUsHT0xPTpk3DO++8U6r98OHDkZOTgx07dqjPtWvXDs2bN8fKlSuleyNa4AgdERERERFVP1Gln0NDBQUFOHXqFLp3764+p1Ao0L17d0RHR5f5mujo6BLtAaBXr17ltq8OXBSFiIiIiIiqXREKAYnnChahEMDjUcAnWVlZwcrKqsS5tLQ0KJVKuLq6ljjv6uqK2NjYMvtPSUkps31KSkpVS9cZAx0REREREVUbS0tLuLm54UiKfhYTsbW1haenZ4lzs2fPxpw5c/RyPbkx0BERERERUbWxtrbG9evXUVBQoJf+RVGEIAglzj09OgcAdevWhZmZGVJTU0ucT01NhZubW5l9u7m5adW+OjDQERERERFRtbK2toa1tbWsNVhaWiIsLAxRUVEYOHAggMeLokRFRWHq1KllviY8PBxRUVF4/fXX1ef27duH8PDwaqi4bAx0RERERERkkmbOnImxY8eiVatWaNOmDRYvXoycnByMHz8eADBmzBjUr18f8+fPBwC89tpr6NKlCxYuXIg+ffpgw4YNOHnyJFatWiXbe2CgIyIiIiIikzR8+HDcu3cPH330EVJSUtC8eXPs2bNHvfBJUlISFIr/3xigffv2+Pnnn/HBBx/gvffeQ0BAALZt24aQkBC53gL3oSMiIiIiIjJW3IeOiIiIiIjISDHQERERERERGSkGOiIiIiIiIiPFQEdERERERGSkGOiIiIiIiIiMFAMdERERERGRkWKgIyIiIiIiMlIMdEREREREREaKgY6IiIiIiMhIMdAREREREREZKQY6IiIiIiIiI8VAR0REREREZKT+D260lH+RayGUAAAAAElFTkSuQmCC", "text/plain": [ "
" ] @@ -927,7 +927,7 @@ }, { "data": { - "image/png": "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EWla8f2IIq2HOjo6aNu2Lezt7TF79mzs378f69evh5WVlbrCpGqgSBCjSMUtfKqurzbhK1cFzp49i+bNm+POnTsYOHCgwkmhMn37iYiIiNRJmXuTBg0aYODAgbh9+zY8PT1x9uxZNURGRMpgYqhGEokE3333HQICAtCwYUP06NEDhgosVs+EkIiIiLSZMvcphoaG6NGjBxo2bIiAgAAsXLgQEolEDdGRthMggkTFm8AF7pXGrqRq8uTJE4waNQoRERHo3bs36tWrJ/e5TAaJiIioulD6vqV5E9Tt2A4//fQT/v33X2zZskWh+yUiUi22GKrBqVOn0Lx5c8THx6N///5y/5FjCyERERHVJgaODWD2yUzExcWhefPmOH36tKZDoipUPMZQ1Rsph6+cCkkkEnz77bcICgqCu7s7unXrBn19/QrPY0JIREREtZXYyAgF0yajcePG6NmzJxYsWMCupUQawK6kKpKamopRo0bhypUr6NOnD6ytrSs8h8kgERER0as1DxOHD0IfW1ssW7YM586dw5YtW5Ra1ouqD4kggkRQ7ZhAVddXmzAxVIGIiAj0798fenp66NevHwwMDMotz4SQiIiIqKRrXTuin5kZTp8+jRYtWmDfvn3w9vbWdFikJkUQo0jFHRhVXV9twleuktavXw9fX1/Y2dnB39+fSSERERFRJZxu7YWAgADY2dmhQ4cO+OuvvzQdElGtwBZDJeXl5eH999/H5s2b0b17dzg6OpZbngkhERERkXyON28CNG+C7oetMW3aNJw7dw7//e9/K/wCnqoXdiXVLkwMlZCcnIx+/fohISEB/fv3h5mZWZllmRASERERKeduL3/0t7TE/v37ERERgb1798LOzk7TYRHVSOxKqqCwsDC0bNkSWVlZCA4OZlJIREREpEYXO/ggODgYGRkZaNWqFcLCwjQdEqmIBGK1bKQcvnIK2LhxIzp37gxXV1d07twZurqlN7hy+QkiIiIi1Tnh3QxdunSBs7MzOnfujE2bNmk6JKIah11J5VBUVITZs2fj119/LXc8IZNBIiIiIvUQiUTw9vaGlZUVpkyZgmvXrmHJkiXQ0dHRdGikpCJBhCIVjwlUdX21CVsMK5CRkYFevXph06ZN6Nu3b6lJIVsIiYiIiNSr+F7L0dERffv2xcaNG9GrVy9kZGRoODKimoGJYTni4uLQvn17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\n", + "image/png": "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EWla8f2IIq2HOjo6aNu2Lezt7TF79mzs378f69evh5WVlbrCpGqgSBCjSMUtfKqurzbhK1cFzp49i+bNm+POnTsYOHCgwkmhMn37iYiIiNRJmXuTBg0aYODAgbh9+zY8PT1x9uxZNURGRMpgYqhGEokE3333HQICAtCwYUP06NEDhgosVs+EkIiIiLSZMvcphoaG6NGjBxo2bIiAgAAsXLgQEolEDdGRthMggkTFm8AF7pXGrqRq8uTJE4waNQoRERHo3bs36tWrJ/e5TAaJiIioulD6vqV5E9Tt2A4//fQT/v33X2zZskWh+yUiUi22GKrBqVOn0Lx5c8THx6N///5y/5FjCyERERHVJgaODWD2yUzExcWhefPmOH36tKZDoipUPMZQ1Rsph6+cCkkkEnz77bcICgqCu7s7unXrBn19/QrPY0JIREREtZXYyAgF0yajcePG6NmzJxYsWMCupUQawK6kKpKamopRo0bhypUr6NOnD6ytrSs8h8kgERER0as1DxOHD0IfW1ssW7YM586dw5YtW5Ra1ouqD4kggkRQ7ZhAVddXmzAxVIGIiAj0798fenp66NevHwwMDMotz4SQiIiIqKRrXTuin5kZTp8+jRYtWmDfvn3w9vbWdFikJkUQo0jFHRhVXV9twleuktavXw9fX1/Y2dnB39+fSSERERFRJZxu7YWAgADY2dmhQ4cO+OuvvzQdElGtwBZDJeXl5eH999/H5s2b0b17dzg6OpZbngkhERERkXyON28CNG+C7oetMW3aNJw7dw7//e9/K/wCnqoXdiXVLkwMlZCcnIx+/fohISEB/fv3h5mZWZllmRASERERKeduL3/0t7TE/v37ERERgb1798LOzk7TYRHVSOxKqqCwsDC0bNkSWVlZCA4OZlJIREREpEYXO/ggODgYGRkZaNWqFcLCwjQdEqmIBGK1bKQcvnIK2LhxIzp37gxXV1d07twZurqlN7hy+QkiIiIi1Tnh3QxdunSBs7MzOnfujE2bNmk6JKIah11J5VBUVITZs2fj119/LXc8IZNBIiIiIvUQiUTw9vaGlZUVpkyZgmvXrmHJkiXQ0dHRdGikpCJBhCIVjwlUdX21CVsMK5CRkYFevXph06ZN6Nu3b6lJIVsIiYiIiNSr+F7L0dERffv2xcaNG9GrVy9kZGRoODKimoGJYTni4uLQvn17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", "text/plain": [ "
" ] @@ -948,7 +948,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA3MAAAH5CAYAAAAr/WftAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAADh30lEQVR4nOydd3gVxfrHvycJSSAhCb2XUEIJVQQJXap0pCnXK2DF3q6oWFGvWLiWa0FRrmJHQRAFFRUBpQkiTZEiAgGkiJDEEEIgZ39/8Nu42WyZ3Z3dnT3n/TxPHiXZnZ2z+z2zb5l5JyRJkgSCIAiCIAiCIAgiUMT43QGCIAiCIAiCIAjCOuTMEQRBEARBEARBBBBy5giCIAiCIAiCIAIIOXMEQRAEQRAEQRABhJw5giAIgiAIgiCIAELOHEEQBEEQBEEQRAAhZ44gCIIgCIIgCCKAkDNHEARBEARBEAQRQMiZIwiCIAiCIAiCCCDkzBEEQRAEQRAEQQQQcuYIgiAIgiAIgvCEb7/9FkOHDkXt2rURCoXw8ccfW25jyZIl6Ny5MypWrIhq1aph1KhR2Lt3L/e+BgFy5giCIAiCIAiC8ISTJ0+ibdu2eOmll2ydv2fPHgwfPhy9e/fGpk2bsGTJEhw7dgwjR47k3NNgEJIkSfK7EwRBEARBEARBRBehUAgLFizAiBEjSn53+vRp3HfffXj//feRk5ODVq1a4cknn0SvXr0AAPPmzcO4ceNw+vRpxMScy0t9+umnGD58OE6fPo1y5cr58En8gzJzBEEQBEEQBEEIwU033YQ1a9Zgzpw52LJlC8aMGYOLLroIu3btAgB06NABMTExeOONN1BcXIzc3Fy8/fbb6Nu3b9Q5cgBl5giCIAiCIAiC8AF1Zi47OxuNGjVCdnY2ateuXXJc37590alTJ0ybNg0AsGLFCowdOxZ//vkniouLkZWVhc8++wxpaWk+fAp/ocwcQRAEQRAEQRC+s3XrVhQXFyMjIwPJycklPytWrMDu3bsBAIcPH8Y111yDCRMmYP369VixYgXi4+MxevRoRGOOKs7vDhAEQRAEQRAEQeTn5yM2NhYbNmxAbGxsqb8lJycDAF566SWkpqbiqaeeKvnbO++8g3r16uH7779H586dPe2z35AzRxAEQRAEQRCE77Rv3x7FxcU4evQounfvrnlMQUFBSeETGdnxC4fDrvdRNGiaJUEQBEEQBEEQnpCfn49NmzZh06ZNAM5tNbBp0yZkZ2cjIyMDl112GcaPH4/58+djz549WLduHR5//HEsXrwYADB48GCsX78ejzzyCHbt2oUff/wRV1xxBRo0aID27dv7+Mn8gQqgEARBEARBEAThCcuXL8eFF15Y5vcTJkzA7NmzcebMGfz73//GW2+9hYMHD6Jq1aro3LkzHn74YbRu3RoAMGfOHDz11FPYuXMnKlSogKysLDz55JNo3ry51x/Hd8iZIwiCIAiCIAgi6nj55Zfx8ssvY+/evQCAzMxMPPjggxg4cKC/HbMAOXMEQRAEQRAEQUQdn376KWJjY9G0aVNIkoQ333wT06dPx8aNG5GZmel395ggZ44gCIIgCIIgCAJA5cqVMX36dFx11VV+d4UJqmZJEARBEARBEISnFBYWoqioyJW2JUlCKBQq9buEhAQkJCTonlNcXIy5c+fi5MmTyMrKcqVfbkDOHEEQBEEQBEEQnlFYWIj08uVx2KX2k5OTkZ+fX+p3Dz30EKZOnVrm2K1btyIrKwuFhYVITk7GggUL0LJlS5d6xh+aZkkQBEEQBEEQhGfk5eUhNTUV+0MhpPBuG0A9ScL+/fuRkvJ363qZuaKiImRnZyM3Nxfz5s3DrFmzsGLFisA4dOTMEQRBEARBEAThGbIzlxsKIUU1HdJx25KEVElCbm5uKWeOlb59+6Jx48aYOXMm1365BU2zJAiCIAiCIAjCe2JiAM7OHCQJKC62fXo4HMbp06c5dshdyJkjCIIgCIIgCCLqmDJlCgYOHIj69evjr7/+wnvvvYfly5djyZIlfneNGXLmCIIgCIIgCILwHp8zc0ePHsX48eNx6NAhpKamok2bNliyZAn69evHt08uQmvmCIIgCIIgCILwjJI1c+XKubNm7swZ22vmggZl5giCIAiCIAiC8B63MnNRRIzfHSAIgiAIgiAIgiCsQ5k5giAIgiAIgiC8hzJzjiFnjiAIgiAIgiAI7yFnzjE0zZIgCIIgCIIgCCKAUGaOIAiCIAiCIAjvocycYygzRxAEQRAEQRAEEUAoM0cQBEEQBEEQhPdQZs4xlJkjCIIgCIIgCIIIIJSZIwiCIAiCIAjCeygz5xjKzBEEQRAEQRAEQQQQyswRBEEQBEEQBOE9odC57BxPwmG+7QkOOXMEQRAEQRAEQXhPTAx/Zy7KoLtHEIRr7Nq1C/3790dqaipCoRA+/vhjv7ukSa9evdCrVy/frv/hhx+icuXKyM/P960P0cbs2bMRCoWwd+9ev7siPFr3yu535syZM6hXrx5mzJjBr4MEQRBRDDlzBOEhW7duxejRo9GgQQMkJiaiTp066NevH1544YVSx02bNk1Yx8cKEyZMwNatW/HYY4/h7bffxvnnn+9bX7Zt24apU6cKZ7wXFxfjoYcews0334zk5GQAQEFBAV566SX0798ftWrVQsWKFdG+fXu8/PLLKC4uLtNGOBzGU089hfT0dCQmJqJNmzZ4//33Xe/7+vXrcdNNNyEzMxNJSUmoX78+xo4di507d2oe/8svv+Ciiy5CcnIyKleujMsvvxx//PGH6/3kjahacooX4065cuVwxx134LHHHkNhYaGr1yIIIgDImTneP1FESJKirOQLQfjE6tWrceGFF6J+/fqYMGECatasif3792Pt2rXYvXs3fv3115Jjk5OTMXr0aMyePdu/Djvk1KlTqFChAu677z78+9//9rs7mDdvHsaMGYNly5aVySgUFRUBAOLj4z3v18cff4yRI0di//79qFOnDgDgp59+Qps2bdCnTx/0798fKSkpWLJkCRYsWIDx48fjzTffLNXGlClT8MQTT+Caa65Bx44dsXDhQixevBjvv/8+Lr30Utf6Pnr0aKxatQpjxoxBmzZtcPjwYbz44ovIz8/H2rVr0apVq5JjDxw4gPbt2yM1NRW33HIL8vPz8Z///Af169fHunXrPL/3xcXFOHPmDBISEhCyWEnNSEtBRm/c0bpX8udevny55evk5OSgRo0aePnll3HllVc67DVBEEEkLy8PqampyK1eHSmcna+8cBipR48iNzcXKSkpXNsWEVozRxAe8dhjjyE1NRXr169HWlpaqb8dPXrUdrsnT55EUlKSw97xR864qD+riPjhxMm88cYb6Nq1a4kjBwA1a9bE1q1bkZmZWfK7SZMm4corr8Qbb7yBBx54AE2aNAEAHDx4EE8//TRuvPFGvPjiiwCAq6++Gj179sTkyZMxZswYxMbGutL3O+64A++9916p+3fJJZegdevWeOKJJ/DOO++U/H7atGk4efIkNmzYgPr16wMAOnXqhH79+mH27Nm49tprXemjHrGxsa7dF1E5e/YswuGwZb3zvldpaWno378/Zs+eTc4cQUQ7UZhJ4w3dPYLwiN27dyMzM1PTualevXrJ/4dCIZw8eRJvvvkmQqEQQqEQJk6cCACYOnUqQqEQtm3bhn/84x+oVKkSunXrVnLuO++8gw4dOqB8+fKoXLkyLr30Uuzfv7/Utb777juMGTMG9evXR0JCAurVq4fbb78dp06dKnXcxIkTkZycjOzsbAwZMgTJycmoU6cOXnrpJQDnpoz27t0bSUlJaNCgAd57772Sc6dOnYoGDRoAACZPnoxQKISGDRuWtCv/vxL5sykJhUK46aab8PHHH6NVq1ZISEhAZmYmvvjiizLnHzx4EFdddRVq166NhIQEpKen4/rrr0dRURFmz56NMWPGAAAuvPDCkvsqZxW01v8cPXoUV111FWrUqIHExES0bdu2TEZs7969CIVC+M9//oNXX30VjRs3RkJCAjp27Ij169eX6aOawsJCfPHFF+jbt2+p31etWrWUIydz8cUXAzg3XVFm4cKFOHPmDG644YZS9+3666/HgQMHsGbNGt3rHz16FNWqVUOvXr2gnKTx66+/IikpCZdccolh/7t06VLGMWjatCkyMzNL9REAPvroIwwZMqTEkQOAvn37IiMjAx9++KHhdZT3+dlnn0WDBg1Qvnx59OzZEz/99FOZ47/55ht0794dSUlJSEtLw/Dhw8v0R2sdWMOGDTFkyBCsXLkSnTp1QmJiIho1aoS33nqr1HlGWvrhhx8wYMAAVK1aFeXLl0d6ejqTwyJf+8svv0S7du2QmJiIli1bYv78+WWOzcnJwW233YZ69eohISEBTZo0wZNPPomwooKb8p4999xzJdrctm2b5vWNxh3W9YWnT5/GQw89hCZNmpSMLXfddRdOnz5d5th+/fph5cqVOH78uOm9IQiCIPShzBxBeESDBg2wZs0a/PTTT6Wmn6l5++23cfXVV6NTp04l2YrGjRuXOmbMmDFo2rQppk2bVmKEP/bYY3jggQcwduxYXH311fjjjz/wwgsvoEePHti4cWOJEzl37lwUFBTg+uuvR5UqVbBu3Tq88MILOHDgAObOnVvqOsXFxRg4cCB69OiBp556Cu+++y5uuukmJCUl4b777sNll12GkSNH4pVXXsH48eORlZWF9PR0jBw5Emlpabj99tsxbtw4DBo0qGQ9mFVWrlyJ+fPn44YbbkDFihXx/PPPY9SoUcjOzkaVKlUAAL///js6deqEnJwcXHvttWjevDkOHjyIefPmoaCgAD169MAtt9yC559/Hvfeey9atGgBACX/VXPq1Cn06tULv/76K2666Sakp6dj7ty5mDhxInJycnDrrbeWOv69997DX3/9hUmTJiEUCuGpp57CyJEj8dtvv6FcuXK6n23Dhg0oKirCeeedx3QvDh8+DOCcsyezceNGJCUllfksnTp1Kvm70uFXUr16dbz88ssYM2YMXnjhBdxyyy0Ih8OYOHEiKlasaKtIhSRJOHLkSCln9ODBgzh69KjmmslOnTrhs88+Y2r7rbfewl9//YUbb7wRhYWF+O9//4vevXtj69atqFGjBgDg66+/xsCBA9GoUSNMnToVp06dwgsvvICuXbvixx9/1AwkKPn1118xevRoXHXVVZgwYQJef/11TJw4ER06dEBmZqahlo4ePYr+/fujWrVquOeee5CWloa9e/dqOmRa7Nq1C5dccgmuu+46TJgwAW+88QbGjBmDL774Av369QNwbj1lz549cfDgQUyaNAn169fH6tWrMWXKFBw6dAjPPfdcqTbfeOMNFBYW4tprr0VCQgIqV66seW2WcceIcDiMYcOGYeXKlbj22mvRokULbN26Fc8++yx27txZZi1ehw4dIEkSVq9ejSFDhjBfhyCICIMyc86RCILwhC+//FKKjY2VYmNjpaysLOmuu+6SlixZIhUVFZU5NikpSZowYUKZ3z/00EMSAGncuHGlfr93714pNjZWeuyxx0r9fuvWrVJcXFyp3xcUFJRp9/HHH5dCoZC0b9++kt9NmDBBAiBNmzat5HcnTpyQypcvL4VCIWnOnDklv9++fbsEQHrooYdKfrdnzx4JgDR9+vRS15owYYLUoEED3c+mBIAUHx8v/frrryW/27x5swRAeuGFF0p+N378eCkmJkZav359mXbD4bAkSZI0d+5cCYC0bNmyMsf07NlT6tmzZ8m/n3vuOQmA9M4775T8rqioSMrKypKSk5OlvLy8Up+xSpUq0vHjx0uOXbhwoQRA+vTTT8tcS8msWbMkANLWrVsNj5MkSTp9+rTUsmVLKT09XTpz5kzJ7wcPHiw1atSozPEnT56UAEj33HOPadvjxo2TKlSoIO3cuVOaPn26BED6+OOPTc/T4u2335YASP/73/9Kfrd+/XoJgPTWW2+VOX7y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Pv30U01nQf6sshHPcl8HDRqEw4cP44MPPij53dmzZ/HCCy8gOTm5ZFqqUzp06ID4+HjNfn/77be49NJL0aNHD7z77rtlpnzKDB8+HOXKlStVeVKSJLzyyiuoU6cOunTpYtiHnJyckiqG06ZNw6xZs/Djjz9i2rRppv0vLi7GJZdcgjVr1mDu3LnIysrSPXbUqFFYtGhRqa0yli5dip07d5aU+jfj448/xsGDB0v+vW7dOnz//fcYOHAggHMZwHbt2uHNN98s9Zx/+uknfPnll2WmqNpFT0snTpwo8/2THVWWqZa///57qe9BXl4e3nrrLbRr1w41a9YEAIwdOxZr1qwpyaQqycnJwdmzZ618lFJYHXeUjB07FgcPHsRrr71W5m+nTp0qM711w4YNCIVChpohCIIgzKHMHEF4xM0334yCggJcfPHFaN68OYqKirB69Wp88MEHaNiwIa644oqSYzt06ICvv/4azzzzDGrXro309HRccMEFum03btwY//73vzFlyhTs3bsXI0aMQMWKFbFnzx4sWLAA1157Le688040b94cjRs3xp133omDBw8iJSUFH330kStr3fS49NJLcffdd+Piiy/GLbfcgoKCArz88svIyMjAjz/+aKvNadOm4csvv0TPnj1LyqIfOnQIc+fOxcqVK5GWloZ27dohNjYWTz75JHJzc5GQkIDevXuX2uNP5tprr8XMmTMxceJEbNiwAQ0bNsS8efOwatUqPPfcc6hYsaLT2wDg3JrE/v374+uvv8YjjzxS8vt9+/Zh2LBhCIVCGD16dJktI9q0aYM2bdoAAOrWrYvbbrsN06dPx5kzZ9CxY0d8/PHH+O677/Duu++abvZ866234s8//8TXX3+N2NhYXHTRRbj66qvx73//G8OHD0fbtm11z/3Xv/6FTz75BEOHDsXx48dLbRIOAP/85z9L/v/ee+/F3LlzceGFF+LWW29Ffn4+pk+fjtatW5fSvhFNmjRBt27dcP311+P06dN47rnnUKVKlVJTDqdPn46BAwciKysLV111VcnWBKmpqZg6dSrTdczQ09J7772HGTNm4OKLL0bjxo3x119/4bXXXkNKSgqTI5mRkYGrrroK69evR40aNfD666/jyJEjeOONN0qOmTx5Mj755BMMGTKkZMuEkydPYuvWrZg3bx727t1re+qi1XFHyeWXX44P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PXsWTU1NAICZM2dizpw5mDJlCt8HRyQAgzlxGMyR7XV3d2PPnj34+9//jsLCQlRVVeGOO+7AoEGD0LdvX8u87oBCy1NmZyDI/K/ZGaCg19bWhrNnz+LcuXMYOXIkpk+fjqlTpyIrK4vPESLBXMHcyJFygrmqKgZzRLZ1/vx5FBcX45NPPkF1dTUcol5KTGQRYZ2dCPN4F2KYx4YcTo/GpzMiAs6ICOl5I7Kr5ORkTJs2DZMnT8bAgQPNzg5RUGMwJw6DOSIiIiIiMowrmLvrLjnB3JEjoRPM8U2sRERERERENsRJ4EREREREZDiHAxC9GXmora7hyBwREREREZENcWSOiIiIiIgMx5E5/RjMERERERGR4RjM6cdplkRERERERDbEkTkiIiIiIjKc0yl+JC3UXrrGkTkiIiIiIiIb4sgcEREREREZTsb6Nq6ZIyIiIiIiIsvjyBwRERERERmOI3P6cWSOiIiIiIjIhjgyR0REREREhuPInH4M5oiIiIiIyHAM5vTjNEsiIiIiIiIb4sgcEREREREZjiNz+nFkjoiIiIiIyIY4MkdERERERIbjyJx+HJkjIiIiIiKyIY7MERERERGR4Tgypx9H5oiIiIiIiGyII3NERERERGQ4jszpx2COiIiIiIgM53SKD76cTrHpWR2nWRIREREREdkQR+aIiIiIiMhwDgcQFiY2TY7MERERERERkeVxZI6IiIiIiAzHkTn9ODJHRERERERkQxyZIyIiIiIiw3FkTj+OzBEREREREdkQR+aIiIiIiMhwHJnTj8EcEREREREZjsGcfpxmSUREREREZEMcmSMiIiIiIsNxZE4/jswRERERERHZEEfmiIiIiIjIcByZ048jc0RERERERDbEYI6IiIiIiAzncMj5k+X73/8+EhMTERUVhcGDB2P+/Pk4deqUvBMqwGCOiIiIiIgogIcffhhbtmzB0aNHkZeXh7q6OsyZM8fUPIU5naE2s5SIiIiIiMzS3t6OmJgYAG0AokWnDiAGbW1tiI4WnfaNCgoK8MMf/hDXrl3DLbfcIvVcvnADFCIiIiIiMkG7tDTb229MOzIyEpGRkcLOcuHCBfz1r3/F/fffb1ogB3CaJRERERERGSgiIgLx8fEAEgDECP5LQL9+/ZCQkICYmJiev9dff11I3l966SX07dsXAwcORENDA7Zv3y4kXa04zZKIiIiIiAx19epVdHZ2Sknb6XQizOOdB75G5pYuXYo333zTb3pHjhxBeno6AKClpQUXLlzAiRMn8OqrryImJgY7d+686XxGYTBHREREREQhqbm5GefPn/f7meTkZERERNz030+ePImEhATs3bsXEydOlJVFv7hmjoiIiIiIQlJcXBzi4uI0Hev49j0I165dE5klVTgyR0RERERE5Mf+/ftx4MABPPDAA4iNjUVdXR1+97vf4ezZs6iqqhK6uYoa3ACFiIiIiIjIjz59+mDbtm2YPHky0tLS8PTTT2PMmDH47LPPTAvkAI7MERERERER2RJH5oiIiIiIiGyIwRwREREREZENMZgjIiIiIiKyIQZzRERERERENsRgjoiIiIiIyIYYzBEREREREdkQgzkiIiIiIiIbYjBHRERERERkQwzmiIiIiIiIbIjBHBERERERkQ0xmCMiIiIiIrKh/wdI0yLF+9AlxwAAAABJRU5ErkJggg==\n", + "image/png": "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QXhPTAx/Zy7KoLtHEIRr7Nq1C/3790dqaipCoRA+/vhjv7ukSa9evdCrVy/frv/hhx+icuXKyM/P960P0cbs2bMRCoWwd+9ev7siPFr3yu535syZM6hXrx5mzJjBr4MEQRBRDDlzBOEhW7duxejRo9GgQQMkJiaiTp066NevH1544YVSx02bNk1Yx8cKEyZMwNatW/HYY4/h7bffxvnnn+9bX7Zt24apU6cKZ7wXFxfjoYcews0334zk5GQAQEFBAV566SX0798ftWrVQsWKFdG+fXu8/PLLKC4uLtNGOBzGU089hfT0dCQmJqJNmzZ4//33Xe/7+vXrcdNNNyEzMxNJSUmoX78+xo4di507d2oe/8svv+Ciiy5CcnIyKleujMsvvxx//PGH6/3kjahacooX4065cuVwxx134LHHHkNhYaGr1yIIIgDImTneP1FESJKirOQLQfjE6tWrceGFF6J+/fqYMGECatasif3792Pt2rXYvXs3fv3115Jjk5OTMXr0aMyePdu/Djvk1KlTqFChAu677z78+9//9rs7mDdvHsaMGYNly5aVySgUFRUBAOLj4z3v18cff4yRI0di//79qFOnDgDgp59+Qps2bdCnTx/0798fKSkpWLJkCRYsWIDx48fjzTffLNXGlClT8MQTT+Caa65Bx44dsXDhQixevBjvv/8+Lr30Utf6Pnr0aKxatQpjxoxBmzZtcPjwYbz44ovIz8/H2rVr0apVq5JjDxw4gPbt2yM1NRW33HIL8vPz8Z///Af169fHunXrPL/3xcXFOHPmDBISEhCyWEnNSEtBRm/c0bpX8udevny55evk5OSgRo0aePnll3HllVc67DVBEEEkLy8PqampyK1eHSmcna+8cBipR48iNzcXKSkpXNsWEVozRxAe8dhjjyE1NRXr169HWlpaqb8dPXrUdrsnT55EUlKSw97xR864qD+riPjhxMm88cYb6Nq1a4kjBwA1a9bE1q1bkZmZWfK7SZMm4corr8Qbb7yBBx54AE2aNAEAHDx4EE8//TRuvPFGvPjiiwCAq6++Gj179sTkyZMxZswYxMbGutL3O+64A++9916p+3fJJZegdevWeOKJJ/DOO++U/H7atGk4efIkNmzYgPr16wMAOnXqhH79+mH27Nm49tprXemjHrGxsa7dF1E5e/YswuGwZb3zvldpaWno378/Zs+eTc4cQUQ7UZhJ4w3dPYLwiN27dyMzM1PTualevXrJ/4dCIZw8eRJvvvkmQqEQQqEQJk6cCACYOnUqQqEQtm3bhn/84x+oVKkSunXrVnLuO++8gw4dOqB8+fKoXLkyLr30Uuzfv7/Utb777juMGTMG9evXR0JCAurVq4fbb78dp06dKnXcxIkTkZycjOzsbAwZMgTJycmoU6cOXnrpJQDnpoz27t0bSUlJaNCgAd57772Sc6dOnYoGDRoAACZPnoxQKISGDRuWtCv/vxL5sykJhUK46aab8PHHH6NVq1ZISEhAZmYmvvjiizLnHzx4EFdddRVq166NhIQEpKen4/rrr0dRURFmz56NMWPGAAAuvPDCkvsqZxW01v8cPXoUV111FWrUqIHExES0bdu2TEZs7969CIVC+M9//oNXX30VjRs3RkJCAjp27Ij169eX6aOawsJCfPHFF+jbt2+p31etWrWUIydz8cUXAzg3XVFm4cKFOHPmDG644YZS9+3666/HgQMHsGbNGt3rHz16FNWqVUOvXr2gnKTx66+/IikpCZdccolh/7t06VLGMWjatCkyMzNL9REAPvroIwwZMqTEkQOAvn37IiMjAx9++KHhdZT3+dlnn0WDBg1Qvnx59OzZEz/99FOZ47/55ht0794dSUlJSEtLw/Dhw8v0R2sdWMOGDTFkyBCsXLkSnTp1QmJiIho1aoS33nqr1HlGWvrhhx8wYMAAVK1aFeXLl0d6ejqTwyJf+8svv0S7du2QmJiIli1bYv78+WWOzcnJwW233YZ69eohISEBTZo0wZNPPomwooKb8p4999xzJdrctm2b5vWNxh3W9YWnT5/GQw89hCZNmpSMLXfddRdOnz5d5th+/fph5cqVOH78uOm9IQiCIPShzBxBeESDBg2wZs0a/PTTT6Wmn6l5++23cfXVV6NTp04l2YrGjRuXOmbMmDFo2rQppk2bVmKEP/bYY3jggQcwduxYXH311fjjjz/wwgsvoEePHti4cWOJEzl37lwUFBTg+uuvR5UqVbBu3Tq88MILOHDgAObOnVvqOsXFxRg4cCB69OiBp556Cu+++y5uuukmJCUl4b777sNll12GkSNH4pVXXsH48eORlZWF9PR0jBw5Emlpabj99tsxbtw4DBo0qGQ9mFVWrlyJ+fPn44YbbkDFihXx/PPPY9SoUcjOzkaVKlUAAL///js6deqEnJwcXHvttWjevDkOHjyIefPmoaCgAD169MAtt9yC559/Hvfeey9atGgBACX/VXPq1Cn06tULv/76K2666Sakp6dj7ty5mDhxInJycnDrrbeWOv69997DX3/9hUmTJiEUCuGpp57CyJEj8dtvv6FcuXK6n23Dhg0oKirCeeedx3QvDh8+DOCcsyezceNGJCUllfksnTp1Kvm70uFXUr16dbz88ssYM2YMXnjhBdxyyy0Ih8OYOHEiKlasaKtIhSRJOHLkSCln9ODBgzh69KjmmslOnTrhs88+Y2r7rbfewl9//YUbb7wRhYWF+O9//4vevXtj69atqFGjBgDg66+/xsCBA9GoUSNMnToVp06dwgsvvICuXbvixx9/1AwkKPn1118xevRoXHXVVZgwYQJef/11TJw4ER06dEBmZqahlo4ePYr+/fujWrVquOeee5CWloa9e/dqOmRa7Nq1C5dccgmuu+46TJgwAW+88QbGjBmDL774Av369QNwbj1lz549cfDgQUyaNAn169fH6tWrMWXKFBw6dAjPPfdcqTbfeOMNFBYW4tprr0VCQgIqV66seW2WcceIcDiMYcOGYeXKlbj22mvRokULbN26Fc8++yx27txZZi1ehw4dIEkSVq9ejSFDhjBfhyCICIMyc86RCILwhC+//FKKjY2VYmNjpaysLOmuu+6SlixZIhUVFZU5NikpSZowYUKZ3z/00EMSAGncuHGlfr93714pNjZWeuyxx0r9fuvWrVJcXFyp3xcUFJRp9/HHH5dCoZC0b9++kt9NmDBBAiBNmzat5HcnTpyQypcvL4VCIWnOnDklv9++fbsEQHrooYdKfrdnzx4JgDR9+vRS15owYYLUoEED3c+mBIAUHx8v/frrryW/27x5swRAeuGFF0p+N378eCkmJkZav359mXbD4bAkSZI0d+5cCYC0bNmyMsf07NlT6tmzZ8m/n3vuOQmA9M4775T8rqioSMrKypKSk5OlvLy8Up+xSpUq0vHjx0uOXbhwoQRA+vTTT8tcS8msWbMkANLWrVsNj5MkSTp9+rTUsmVLKT09XTpz5kzJ7wcPHiw1atSozPEnT56UAEj33HOPadvjxo2TKlSoIO3cuVOaPn26BED6+OOPTc/T4u2335YASP/73/9Kfrd+/XoJgPTWW2+VOX7y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Pv30U01nQf6sshHPcl8HDRqEw4cP44MPPij53dmzZ/HCCy8gOTm5ZFqqUzp06ID4+HjNfn/77be49NJL0aNHD7z77rtlpnzKDB8+HOXKlStVeVKSJLzyyiuoU6cOunTpYtiHnJyckiqG06ZNw6xZs/Djjz9i2rRppv0vLi7GJZdcgjVr1mDu3LnIysrSPXbUqFFYtGhRqa0yli5dip07d5aU+jfj448/xsGDB0v+vW7dOnz//fcYOHAggHMZwHbt2uHNN98s9Zx/+uknfPnll2WmqNpFT0snTpwo8/2THVWWqZa///57qe9BXl4e3nrrLbRr1w41a9YEAIwdOxZr1qwpyaQqycnJwdmzZ618lFJYHXeUjB07FgcPHsRrr71W5m+nTp0qM711w4YNCIVChpohCIIgzKHMHEF4xM0334yCggJcfPHFaN68OYqKirB69Wp88MEHaNiwIa644oqSYzt06ICvv/4azzzzDGrXro309HRccMEFum03btwY//73vzFlyhTs3bsXI0aMQMWKFbFnzx4sWLAA1157Le688040b94cjRs3xp133omDBw8iJSUFH330kStr3fS49NJLcffdd+Piiy/GLbfcgoKCArz88svIyMjAjz/+aKvNadOm4csvv0TPnj1LyqIfOnQIc+fOxcqVK5GWloZ27dohNjYWTz75JHJzc5GQkIDevXuX2uNP5tprr8XMmTMxceJEbNiwAQ0bNsS8efOwatUqPPfcc6hYsaLT2wDg3JrE/v374+uvv8YjjzxS8vt9+/Zh2LBhCIVCGD16dJktI9q0aYM2bdoAAOrWrYvbbrsN06dPx5kzZ9CxY0d8/PHH+O677/Duu++abvZ866234s8//8TXX3+N2NhYXHTRRbj66qvx73//G8OHD0fbtm11z/3Xv/6FTz75BEOHDsXx48dLbRIOAP/85z9L/v/ee+/F3LlzceGFF+LWW29Ffn4+pk+fjtatW5fSvhFNmjRBt27dcP311+P06dN47rnnUKVKlVJTDqdPn46BAwciKysLV111VcnWBKmpqZg6dSrTdczQ09J7772HGTNm4OKLL0bjxo3x119/4bXXXkNKSgqTI5mRkYGrrroK69evR40aNfD666/jyJEjeOONN0qOmTx5Mj755BMMGTKkZMuEkydPYuvWrZg3bx727t1re+qi1XFHyeWXX44P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PXsWTU1NAICZM2dizpw5mDJlCt8HRyQAgzlxGMyR7XV3d2PPnj34+9//jsLCQlRVVeGOO+7AoEGD0LdvX8u87oBCy1NmZyDI/K/ZGaCg19bWhrNnz+LcuXMYOXIkpk+fjqlTpyIrK4vPESLBXMHcyJFygrmqKgZzRLZ1/vx5FBcX45NPPkF1dTUcol5KTGQRYZ2dCPN4F2KYx4YcTo/GpzMiAs6ICOl5I7Kr5ORkTJs2DZMnT8bAgQPNzg5RUGMwJw6DOSIiIiIiMowrmLvrLjnB3JEjoRPM8U2sRERERERENsRJ4EREREREZDiHAxC9GXmora7hyBwREREREZENcWSOiIiIiIgMx5E5/RjMERERERGR4RjM6cdplkRERERERDbEkTkiIiIiIjKc0yl+JC3UXrrGkTkiIiIiIiIb4sgcEREREREZTsb6Nq6ZIyIiIiIiIsvjyBwRERERERmOI3P6cWSOiIiIiIjIhjgyR0REREREhuPInH4M5oiIiIiIyHAM5vTjNEsiIiIiIiIb4sgcEREREREZjiNz+nFkjoiIiIiIyIY4MkdERERERIbjyJx+HJkjIiIiIiKyIY7MERERERGR4Tgypx9H5oiIiIiIiGyII3NERERERGQ4jszpx2COiIiIiIgM53SKD76cTrHpWR2nWRIREREREdkQR+aIiIiIiMhwDgcQFiY2TY7MERERERERkeVxZI6IiIiIiAzHkTn9ODJHRERERERkQxyZIyIiIiIiw3FkTj+OzBEREREREdkQR+aIiIiIiMhwHJnTj8EcEREREREZjsGcfpxmSUREREREZEMcmSMiIiIiIsNxZE4/jswRERERERHZEEfmiIiIiIjIcByZ048jc0RERERERDbEYI6IiIiIiAzncMj5k+X73/8+EhMTERUVhcGDB2P+/Pk4deqUvBMqwGCOiIiIiIgogIcffhhbtmzB0aNHkZeXh7q6OsyZM8fUPIU5naE2s5SIiIiIiMzS3t6OmJgYAG0AokWnDiAGbW1tiI4WnfaNCgoK8MMf/hDXrl3DLbfcIvVcvnADFCIiIiIiMkG7tDTb229MOzIyEpGRkcLOcuHCBfz1r3/F/fffb1ogB3CaJRERERERGSgiIgLx8fEAEgDECP5LQL9+/ZCQkICYmJiev9dff11I3l966SX07dsXAwcORENDA7Zv3y4kXa04zZKIiIiIiAx19epVdHZ2Sknb6XQizOOdB75G5pYuXYo333zTb3pHjhxBeno6AKClpQUXLlzAiRMn8OqrryImJgY7d+686XxGYTBHREREREQhqbm5GefPn/f7meTkZERERNz030+ePImEhATs3bsXEydOlJVFv7hmjoiIiIiIQlJcXBzi4uI0Hev49j0I165dE5klVTgyR0RERERE5Mf+/ftx4MABPPDAA4iNjUVdXR1+97vf4ezZs6iqqhK6uYoa3ACFiIiIiIjIjz59+mDbtm2YPHky0tLS8PTTT2PMmDH47LPPTAvkAI7MERERERER2RJH5oiIiIiIiGyIwRwREREREZENMZgjIiIiIiKyIQZzRERERERENsRgjoiIiIiIyIYYzBEREREREdkQgzkiIiIiIiIbYjBHRERERERkQwzmiIiIiIiIbIjBHBERERERkQ0xmCMiIiIiIrKh/wdI0yLF+9AlxwAAAABJRU5ErkJggg==", "text/plain": [ "
" ] @@ -1046,7 +1046,7 @@ }, { "data": { - "image/png": "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4gv06dPHtX6acfjwYSQni72+pk2bhtGjR+Oss86S2ykfWbhwIZ566ilD0efkXunJzs7GmWeeiYcffhgjR46U0iZBEAThPiT4CIJwjfHjx2Pt2rV46623cM4558T87d5778Udd9zh6vWLi4uRmpqKpKQkpKenS237ww8/xJ9//omxY8fG/H7mzJno06cPkjQjjEOGDEG/fv3w5JNP4r777qv4/e23345atWphyZIlyMzMBAA0b94cEyZMwKJFi5Cbmyu1zyodOnTA5s2b0axZs4rfTZo0CQMHDsRDDz2Em2++GdWrVwcArFq1Cq+99hpmzJiBG2+8EQBw8cUXo2PHjrj55puxYsUKV/pohezvMgwUFRWhWrVq3OfJvldjx47FmDFjsGXLFrRs2VJq2wRBJCCUkfMEusMEkYCUlpbi3nvvRatWrZCWlobmzZvj9ttvx5EjR2KOa968Oc444wwsW7YMPXr0QHp6Olq2bImXXnrJ9hrffPMNFixYgMsuu6yS2AOAtLQ0PPzww0z9feqpp9CyZUtUrVoVPXr0wFdffVVprZ26Tu+1117DlClT0KhRI1SrVg0FBQWma/jmzJmDVq1axbTLyrvvvovmzZujVatWMb/v27dvjNhTf1e7dm388ssvFb8rKCjAp59+in/84x8VYg8oF1MZGRl44403LK8/btw4pKenx7QJAIMHD0atWrWwa9cu03NbtGgRI/aA8rVeZ511Fo4cOYItW7ZU/P6tt95ClSpVcPnll1f8Lj09HZdddhlWrlyJHTt2WPazf//+6NixI9asWYPevXujatWqaNGiBZ555plKx+7btw+XXXYZGjRogPT0dHTu3BkvvvhipeP069LUqc6//vorxo8fj5o1ayIrKwuXXHIJioqKYs47dOgQXnzxRUQiEUQiEYwfPx4A8Pfff+Paa69F8+bNkZaWhvr162PQoEH47rvvLD+feu0NGzZg7NixyMzMRJ06dfCvf/0LxcXFlY6fN28eunbtiqpVq6J27do477zzKt1D7T3r27cvqlWrhttvv93w+uPHj8dTTz1V8fnUH7N7ZcZHH32EU089FdWrV0eNGjUwfPhw/PTTT5WOGzhwIADgvffes22TIAiCCAYk+AgiAfnnP/+JO++8EyeddBIeeeQR9OvXDw888EDMWjSVX3/9FaNHj8agQYPwf//3f6hVqxbG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MXDgQIwcORK/+MUvkJKS4vYhEvmSFviuv15O4PvqKwY+PQY+8qUzZ85g7dq1yM3NxfLlFytvrVu3RmpqKq655hrOgEYRRVOgjLbAF22BLNZDk99UVlbi4MGDKC0tRUlJCQBg+PDhGDFiBAYNGsT18ogEYOBTi4GPfO/8+fPYuHEjPvzwQ6xcuRI7d+7EVVddhauvvhqXX365Z5Z6oNjyi1/8t7J9ffedsl3VykS+up21b4/5//ynuv1RTCovL0dpaSmOHj2Kbt26YdiwYbjzzjvRt29f3keIBNMCX7ducgLfzp0MfHoMfBR1vv/+e6xbtw4ff/wxCgsLUVNT4/YhEQkVp/tfTc25uud5g/i6fw80aAAW9kShdejQAUOHDsXAgQNx5ZVXun04RFGNgU8tBj4iIiIiIlJGC3xdu8oJfLt2MfDpxbt9AERERERERCQHO6UTEREREZFyNTWA6EnWOZKnPrbwERERERERRSm28BERERERkXJs4VODgY+IiIiIiJRj4FODXTqJiIiIiIiiFFv4iIiIiIhIuUBAfIscF5yrjy18REREREREUYotfEREREREpJyM8XYcw1cfW/iIiIiIiIiiFFv4iIiIiIhIObbwqcEWPiIiIiIioijFFj4iIiIiIlKOLXxqMPAREREREZFyDHxqsEsnERERERFRlGILHxERERERKccWPjXYwkdERERERBSl2MJHRERERETKsYVPDbbwERERERERRSm28BERERERkXJs4VODLXxERERERERRii18RERERESkHFv41GDgIyIiIiIi5QIB8QEtEBC7vWjALp1ERERERERRii18RERERESkXE0NEBcndpts4auPLXxERERERERRii18RERERESkHFv41GALHxERERERUZRiCx8RERERESnHFj412MJHREREREQUpdjCR0REREREyrGFTw0GPiIiIiIiUo6BTw126SQiIiIiIopSbOEjIiIiIiLl2MKnBlv4iIiIiIiIohRb+IiIiIiISDm28KnBFj4iIiIiIqIoxcBHRERERETK1dTI+SNbVVUVMjMzERcXh/z8/Do/2759O/r164ekpCS0bdsWL730kvwDioCBj4iIiIiIyKTJkyejdevW9f69oqICgwcPRrt27bB161a8/PLLmDFjBubOnevCUV7CMXxERERERKRcIOC/MXerV6/GmjVrsHjxYqxevbrOz/7yl7+guroa7733HhISEtCtWzfk5+fjtddew/jx4106YgY+IiIiIiJyRYW0bVZU1N12YmIiEhMTHW25tLQU48aNw9KlS9G4ceN6P8/Ly8Ntt92GhISE2n8bMmQIZs6ciZMnTyIlJcXR/u1il04iIiIiIlImISEBqampANoCSBb8py2aNGmCtm3bIjk5ufbPH/7wB0fHHAgE8NBDD2HChAno3bt30NccOXIEV199dZ1/0/5+5MgRR/t3gi18RERERESkTFJSEoqKilBdXS1l+4FAAHGG9R5Cte5NnToVM2fODLu9Xbt2Yc2aNTh16hSmTZsm7DhVYeAjIiIiIiKlkpKSkJSU5PZh4PHHH8dDDz0U9jUdOnTAxx9/jLy8vHrBsXfv3njggQcwf/58pKamorS0tM7Ptb9fbNF0R1wg4LehkkREREREROoUFxfXGRd46NAhDBkyBLm5ufjJT36Ca665Bm+//TamT5+O0tJSNGrUCADw5JNPYsmSJSgsLHTr0Bn4iIiIiIiIrPjuu++Qnp6Obdu2ITMzEwBQXl6OjIwMDB48GFOmTMGOHTswZswYzJo1i7N0EhERERER+VlycjLWrFmDSZMmISsrCy1atMDTTz/tatgD2MJHREREREQUtbgsAxERERERUZRi4CMiIiIiIopSDHxERERERERRioGPiIiIiIgoSjHwERERERERRSkGPiIiIiIioijFwEdERERERBSlGPiIiIiIiIiiFAMfERERERFRlGLgIyIiIiIiilIMfERERERERFHq/wFQJYvX+PvLSQAAAABJRU5ErkJggg==\n", + "image/png": "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4gv06dPHtX6acfjwYSQni72+pk2bhtGjR+Oss86S2ykfWbhwIZ566ilD0efkXunJzs7GmWeeiYcffhgjR46U0iZBEAThPiT4CIJwjfHjx2Pt2rV46623cM4558T87d5778Udd9zh6vWLi4uRmpqKpKQkpKenS237ww8/xJ9//omxY8fG/H7mzJno06cPkjQjjEOGDEG/fv3w5JNP4r777qv4/e23345atWphyZIlyMzMBAA0b94cEyZMwKJFi5Cbmyu1zyodOnTA5s2b0axZs4rfTZo0CQMHDsRDDz2Em2++GdWrVwcArFq1Cq+99hpmzJiBG2+8EQBw8cUXo2PHjrj55puxYsUKV/pohezvMgwUFRWhWrVq3OfJvldjx47FmDFjsGXLFrRs2VJq2wRBJCCUkfMEusMEkYCUlpbi3nvvRatWrZCWlobmzZvj9ttvx5EjR2KOa968Oc444wwsW7YMPXr0QHp6Olq2bImXXnrJ9hrffPMNFixYgMsuu6yS2AOAtLQ0PPzww0z9feqpp9CyZUtUrVoVPXr0wFdffVVprZ26Tu+1117DlClT0KhRI1SrVg0FBQWma/jmzJmDVq1axbTLyrvvvovmzZujVatWMb/v27dvjNhTf1e7dm388ssvFb8rKCjAp59+in/84x8VYg8oF1MZGRl44403LK8/btw4pKenx7QJAIMHD0atWrWwa9cu03NbtGgRI/aA8rVeZ511Fo4cOYItW7ZU/P6tt95ClSpVcPnll1f8Lj09HZdddhlWrlyJHTt2WPazf//+6NixI9asWYPevXujatWqaNGiBZ555plKx+7btw+XXXYZGjRogPT0dHTu3BkvvvhipeP069LUqc6//vorxo8fj5o1ayIrKwuXXHIJioqKYs47dOgQXnzxRUQiEUQiEYwfPx4A8Pfff+Paa69F8+bNkZaWhvr162PQoEH47rvvLD+feu0NGzZg7NixyMzMRJ06dfCvf/0LxcXFlY6fN28eunbtiqpVq6J27do477zzKt1D7T3r27cvqlWrhttvv93w+uPHj8dTTz1V8fnUH7N7ZcZHH32EU089FdWrV0eNGjUwfPhw/PTTT5WOGzhwIADgvffes22TIAiCCAYk+AgiAfnnP/+JO++8EyeddBIeeeQR9OvXDw888EDMWjSVX3/9FaNHj8agQYPwf//3f6hVqxbG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MXDgQIwcORK/+MUvkJKS4vYhEvmSFviuv15O4PvqKwY+PQY+8qUzZ85g7dq1yM3NxfLlFytvrVu3RmpqKq655hrOgEYRRVOgjLbAF22BLNZDk99UVlbi4MGDKC0tRUlJCQBg+PDhGDFiBAYNGsT18ogEYOBTi4GPfO/8+fPYuHEjPvzwQ6xcuRI7d+7EVVddhauvvhqXX365Z5Z6oNjyi1/8t7J9ffedsl3VykS+up21b4/5//ynuv1RTCovL0dpaSmOHj2Kbt26YdiwYbjzzjvRt29f3keIBNMCX7ducgLfzp0MfHoMfBR1vv/+e6xbtw4ff/wxCgsLUVNT4/YhEQkVp/tfTc25uud5g/i6fw80aAAW9kShdejQAUOHDsXAgQNx5ZVXun04RFGNgU8tBj4iIiIiIlJGC3xdu8oJfLt2MfDpxbt9AERERERERCQHO6UTEREREZFyNTWA6EnWOZKnPrbwERERERERRSm28BERERERkXJs4VODgY+IiIiIiJRj4FODXTqJiIiIiIiiFFv4iIiIiIhIuUBAfIscF5yrjy18REREREREUYotfEREREREpJyM8XYcw1cfW/iIiIiIiIiiFFv4iIiIiIhIObbwqcEWPiIiIiIioijFFj4iIiIiIlKOLXxqMPAREREREZFyDHxqsEsnERERERFRlGILHxERERERKccWPjXYwkdERERERBSl2MJHRERERETKsYVPDbbwERERERERRSm28BERERERkXJs4VODLXxERERERERRii18RERERESkHFv41GDgIyIiIiIi5QIB8QEtEBC7vWjALp1ERERERERRii18RERERESkXE0NEBcndpts4auPLXxERERERERRii18RERERESkHFv41GALHxERERERUZRiCx8RERERESnHFj412MJHREREREQUpdjCR0REREREyrGFTw0GPiIiIiIiUo6BTw126SQiIiIiIopSbOEjIiIiIiLl2MKnBlv4iIiIiIiIohRb+IiIiIiISDm28KnBFj4iIiIiIqIoxcBHRERERETK1dTI+SNbVVUVMjMzERcXh/z8/Do/2759O/r164ekpCS0bdsWL730kvwDioCBj4iIiIiIyKTJkyejdevW9f69oqICgwcPRrt27bB161a8/PLLmDFjBubOnevCUV7CMXxERERERKRcIOC/MXerV6/GmjVrsHjxYqxevbrOz/7yl7+guroa7733HhISEtCtWzfk5+fjtddew/jx4106YgY+IiIiIiJyRYW0bVZU1N12YmIiEhMTHW25tLQU48aNw9KlS9G4ceN6P8/Ly8Ntt92GhISE2n8bMmQIZs6ciZMnTyIlJcXR/u1il04iIiIiIlImISEBqampANoCSBb8py2aNGmCtm3bIjk5ufbPH/7wB0fHHAgE8NBDD2HChAno3bt30NccOXIEV199dZ1/0/5+5MgRR/t3gi18RERERESkTFJSEoqKilBdXS1l+4FAAHGG9R5Cte5NnToVM2fODLu9Xbt2Yc2aNTh16hSmTZsm7DhVYeAjIiIiIiKlkpKSkJSU5PZh4PHHH8dDDz0U9jUdOnTAxx9/jLy8vHrBsXfv3njggQcwf/58pKamorS0tM7Ptb9fbNF0R1wg4LehkkREREREROoUFxfXGRd46NAhDBkyBLm5ufjJT36Ca665Bm+//TamT5+O0tJSNGrUCADw5JNPYsmSJSgsLHTr0Bn4iIiIiIiIrPjuu++Qnp6Obdu2ITMzEwBQXl6OjIwMDB48GFOmTMGOHTswZswYzJo1i7N0EhERERER+VlycjLWrFmDSZMmISsrCy1atMDTTz/tatgD2MJHREREREQUtbgsAxERERERUZRi4CMiIiIiIopSDHxERERERERRioGPiIiIiIgoSjHwERERERERRSkGPiIiIiIioijFwEdERERERBSlGPiIiIiIiIiiFAMfERERERFRlGLgIyIiIiIiilIMfERERERERFHq/wFQJYvX+PvLSQAAAABJRU5ErkJggg==", "text/plain": [ "
" ] @@ -1067,7 +1067,7 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAA3wAAAHvCAYAAAAPed3mAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAD2SklEQVR4nOydd3gVRffHvzedEJLQIUDoRTpSFEWadAQVUPG1ADYE1NfeFWxYsP0sIFZe9UVfQbGAShMQBUVRpChgASkSEEOIIYSUu78/4iZ7N1tmdmfbvefzPHmUe3dn5u6enT3fOWdmQpIkSSAIgiAIgiAIgiCijjivG0AQBEEQBEEQBEE4Awk+giAIgiAIgiCIKIUEH0EQBEEQBEEQRJRCgo8gCIIgCIIgCCJKIcFHEARBEARBEAQRpZDgIwiCIAiCIAiCiFJI8BEEQRAEQRAEQUQpJPgIgiAIgiAIgiCiFBJ8BEEQBEEQBEEQUQoJPoIgCIIgCIIgiCiFBB9BEARBEARBEDHPI488glAohOuvv77is6KiIkybNg21a9dGWloaxo4di4MHD3rXSAuQ4CMIgiAIgiAIIqb55ptvMHfuXHTu3Dni8xtuuAEfffQRFixYgDVr1uCPP/7AmDFjPGqlNUjwEQRBEARBEAQRsxQUFOCiiy7CSy+9hJo1a1Z8fvToUbzyyit48sknMXDgQHTv3h2vvfYa1q1bh6+++srDFvOR4HUDCIIgCIIgCIKILYqKilBcXOxI2ZIkIRQKRXyWnJyM5ORkzeOnTZuGkSNHYtCgQXjwwQcrPt+4cSNKSkowaNCgis/atWuH7OxsrF+/Hqeeeqoj7RcNCT6CIAiCIAiCIFyjqKgIzatVQ45D5aelpaGgoCDis+nTp2PGjBlVjn377bfx3Xff4ZtvvqnyXU5ODpKSkpCZmRnxef369ZGT41TrxUOCjyAIgiAIgiAI1yguLkYOgL2hENIFl50PoElBAfbu3Yv09MrStaJ7e/fuxb///W8sX74cKSkpglviH0jwEQRBEARBEAThOukA0lWpl7aRpPKy09MjBJ8WGzduxKFDh3DyySdXfFZWVobPP/8czz33HJYuXYri4mLk5eVFRPkOHjyIBg0aiG23g5DgIwiCIAiCIAjCfeLiACcEX1kZ06FnnnkmtmzZEvHZpEmT0K5dO9x2221o0qQJEhMTsXLlSowdOxYAsGPHDuzZswe9e/cW224HIcFHEARBEARBEETMUaNGDXTs2DHis+rVq6N27doVn19++eW48cYbUatWLaSnp+Paa69F7969A7NgC0CCjyAIgiAIgiAIL/A4wsfCU089hbi4OIwdOxYnTpzA0KFDMXv2bGHlu0FIkv5JdCUIgiAIgiAIgnCY/Px8ZGRk4GhiovA5fPmShIySEhw9etR0Dl+sQBE+giAIgiAIgiDcx6kIHxFBnNcNIAiCIAiCIAiCIJyBInwEQRAEQRAEQbgPRfhcgQQfQRAEQRAEQRDuQ4LPFSilkyAIgiAIgiAIIkqhCB9BEARBEARBEO5DET5XoAgfQRAEQRAEQRBElEIRPoIgCIIgCIIg3IcifK5AET6CIAiCIAiCIIgohSJ8BEEQBEEQBEG4D0X4XIEifARBEARBEARBEFEKRfgIgiAIgiAIgnCfUKg8yieScFhseVEACT6CIAiCIAiCINwnLk684COqQFeYIIioZvfu3QiFQpg3b57psRMnTkSzZs2Yyg2Hw+jYsSMeeughew0kuGjWrBkmTpzodTMCgfparV69GqFQCKtXr+Yu64UXXkB2djZOnDghroEEQRCEK5DgI4iAMHr0aKSmpuLvv//WPeaiiy5CUlIS/vrrLxdbpk9ZWRlee+019O/fH7Vq1UJycjKaNWuGSZMm4dtvv/W6ebZ46623sHfvXlxzzTUVn33zzTe45ppr0KFDB1SvXh3Z2dk4//zzsXPnTs0yfvrpJwwbNgxpaWmoVasWLrnkEvz555+OtruwsBDPP/88hgwZgoYNG6JGjRro1q0b5syZg7KysirHh8NhPPbYY2jevDlSUlLQuXNnvPXWW4620Slmz57NJPyDxLp16zBjxgzk5eU5Ws/EiRNRXFyMuXPnOloPQRAxhhzhE/1HREBXhCACwkUXXYTjx49j0aJFmt8XFhbigw8+wLBhw1C7dm2XW1eV48eP46yzzsJll10GSZJw5513Ys6cObj00kuxfv169OrVC/v27XO8HU2bNsXx48dxySWXCC131qxZGD9+PDIyMio+e/TRR/Huu+/izDPPxP/93//hqquuwueff46TTz4ZW7dujTh/37596Nu3L3755RfMnDkTN998M5YsWYLBgwejuLhYaFuV/Pbbb7j22mshSRJuvPFGPP7442jevDmmTp2Kyy67rMrxd911F2677TYMHjwYzz77LLKzs/Gvf/0Lb7/9tmNtNGLHjh146aWXLJ0brYLvvvvu0xR8dq6VmpSUFEyYMAFPPvkkJFoBjyAIIlhIBEEEgsLCQqlGjRrS0KFDNb+fP3++BEB6++23XW6ZNtOmTZMASE899VSV70pLS6VZs2ZJe/fudaz+kpIS6cSJE1znTJgwQWratKnpcd99950EQFqxYkXE519++WWVOnfu3CklJydLF110UcTnU6ZMkapVqyb9/vvvFZ8tX75cAiDNnTuXq908/Pnnn9LWrVurfD5p0iQJgPTzzz9XfLZv3z4pMTFRmjZtWsVn4XBYOuOMM6TGjRtLpaWljrXTCTp06CD169fP62ZwU1BQoPvdrFmzJADSrl27TMtZtWqVBEBatWqVpXZ8++23EgBp5cqVls4nCIKQOXr0qARAOtqggSRlZQn9O9qgQXnZR496/TN9A0X4CCIgVKtWDWPGjMHKlStx6NChKt/Pnz8fNWrUwOjRo03Lmj17Njp06IDk5GRkZWVh2rRpVSIE/fv3R8eOHfHjjz9iwIABSE1NRaNGjfDYY4+Zlr9v3z7MnTsXgwcPxvXXX1/l+/j4eNx8881o3LixaVkLFixA+/btkZKSgo4dO2LRokVV5trJ8/Qef/xxPP3002jZsiWSk5Px448/6s7he//999GxY8eIcll5//33kZSUhL59+0Z8ftpppyEpKSnis9atW6NDhw746aefIj5/9913cdZZZyE7O7vis0GDBqFNmzZ45513DOufPn064uLisHLlyojPr7rqKiQlJeGHH37QPbdOnTro0KFDlc/PPfdcAIho5wcffICSkhJMnTq14rNQKIQpU6Zg3759WL9+vWE7J06ciLS0NPz2228YOnQoqlevjqysLNx///1VokTHjh3DTTfdhCZNmiA5ORlt27bF448/XuU49by0efPmIRQK4csvv8SNN96IunXronr16jj33HMj0mObNWuGbdu2Yc2aNQiFQgiFQujfvz8AoKSkBPfddx9at26NlJQU1K5dG3369MHy5csNf59c9+eff47Jkyejdu3aSE9Px6WXXoojR45UOf6TTz7BGWecgerVq6NGjRoYOXIktm3bpnnNfv31V4wYMQI1atTARRddpFn/jBkzcMsttwAAmjdvXvG7du/erXmt9Pj6668xbNgwZGRk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aaZ1AcBzzz0Xcf5zzz2HxMTEijmnI0aMQFlZWcRxQPnKk6FQCMOHD2eqx4zq1atrblD+119/Rfw7LS0NrVq10kxn1eLFF1+MWOF2zpw5KC0trWj30KFDkZ6ejpkzZ1ZZCRdAxPYRvFSvXh0ANH+XGd27d0fLli3x+OOPRzxjRu367rvvmO87QRAE4Q8owkcQAaR58+Y47bTTKvbDYhV8devWxR133IH77rsPw4YNw+jRo7Fjxw7Mnj0bPXv2jFigxS5PPPEEfv31V1x33XV47733cNZZZ6FmzZrYs2cPFixYgO3bt2P8+PGGZcycORNnn302Tj/9dEyaNAlHjhzBc889h44dO2o6qKw8/PDDGDlyJPr06YPLLrsMubm5ePbZZ9GhQwemcs8++2w88MADWLNmDYYMGVLx+U033YQPP/wQo0aNQm5uLt58882I85TX984778SCBQswYMAA/Pvf/0ZBQQFmzZqFTp06YdKkSYb1//TTT7jnnnswceJEjBo1CkB5embXrl0xdepUw338fv/9d4wePRqhUAjjxo3DggULIr7v3LkzOnfuDKB8Duf111+PWbNmoaSkBD179sT777+PtWvX4r///a/pnFGgfIGXTz/9FBMmTMApp5yCTz75BEuWLMGdd95ZscDOqFGjMGDAANx1113YvXs3unTpgmXLluGDDz7A9ddfXxGJskv37t0xZ84cPPjgg2jVqhXq1auHgQMHon379ujfv3/FPnPffvstFi5cGLHYjBHFxcU488wzcf7551c8T3369KnYEzM9PR1z5szBJZdcgpNPPhnjx49H3bp1sWfPHixZsgSnn356FbHL85sA4K677sL48eORmJiIUaNGVQhBI+Li4vDyyy9j+PDh6NChAyZNmoRGjRph//79WLVqFdLT0/HRRx9VHL9x40bk5ubi7LPPttRWgiCIKlCEzx28Wh6UIAh7PP/88xIAqVevXtznPvfcc1K7du2kxMREqX79+tKUKVOkI0eORBzTr18/qUOHDlXOnTBhAtPWBZJUvo3Eyy+/LJ1xxhlSRkaGlJiYKDVt2lSaNGkS85YNb7/9ttSuXTspOTlZ6tixo/Thhx9KY8eOldq1a1dxjLz1wqxZs6qcr7UtgyRJ0rvvviuddNJJUnJystS+fXvpvffe4/ptnTt3li6//PKIz+StLPT+1GzdulUaMmSIlJqaKmVmZkoXXXSRlJOTY1hvaWmp1LNnT6lx48YRWw5IkiT93//9nwRA+t///qd7vrw0v97f9OnTI44vKyuTZs6cKTVt2lRKSkqSOnToIL355psmV6ecCRMmSNWrV5d+/fXXit9Zv359afr06RHbgkhS+dYFN9xwg5SVlSUlJiZKrVu3lmbNmhWxXYAk6W/L8M0332j+TnkLAkkq3wZh5MiRUo0aNSQAFVs0PPjgg1KvXr2kzMxMqVq1alK7du2khx56KGKrBS3kutesWSNdddVVUs2aNaW0tDTpoosukv76668qx69atUoaOnSolJGRIaWkpEgtW7aUJk6cKH377bdVrhkPDzzwgNSoUSMpLi4uYosGs20ZZL7//ntpzJgxUu3ataXk5GSpadOm0vnnny+tXLky4rjbbrtNys7OrnJPCIIgeKnYlqFFC0lq1Uro39EWLWhbBhUhSWKY0U4QBOEjunbtirp161aZ++cmb7zxBqZNm4Y9e/YgMzPTs3b4mYkTJ2LhwoW2orF+Zt68eZg0aRK++eYb9OjRw+vmOMqJEyfQrFkz3H777fj3v//tdXMIggg4+fn5yMjIwNGWLZHOkC3CVXZZGTJ+/RVHjx6tWDU81qEYKkEQvqWkpASlpaURn61evRo//PAD+vfv702j/uGiiy5Cdna27oInBBFNvPbaa0hMTMTVV1/tdVMIgiAITmgOH0EQvmX//v0YNGgQLr74YmRlZWH79u144YUX0KBBA88dz7i4OGzdutXTNhCEW1x99dWeP3MEQUQhTszho+TFKpDgIwjCt9SsWRPdu3fHyy+/jD///BPVq1fHyJEj8cgjj6B27dpeN48gCIIgCDuQ4HMFmsNHEARBEARBEIRrVMzha9vWmTl8O3bQHD4FFOEjCIIgCIIgCMJ9KMLnCrRoC0EQBEEQBEEQRJRCET4i6jh8+DBWrlyJjz/+GLt27fK6OQQhnFBZGcrCleN1IQBSXNWUGOUYZ3y8pPqEIAglLVq0wPDhw3HmmWeiTp06XjeHIGIDivC5Agk+IvCUlpbiiy++wKeffoolS5bgxx9/RP369VGvXj1kZGR43TwiBpnQpQs2oavXzYgamjUDPvjgP143g4hyNm3ahGXLluHgwYNo3749Ro4ciWHDhqFPnz5ISCB3iSCI4EKLthCB5NixY1i2bBkWLlyIxYsXAwAaNWqEBg0aoFGjRkhNTfW4hYTfOeusuV43gYgRFi+e7HUTCA4KCwuxf/9+5OTkYP/+/QCAs846C+PGjcOQIUNQvXp1j1tIEMGnYtGWTp2cWbRlyxZatEUBCT4iMBw5cgTvv/8+3nnnHXz22WfIyMhAo0aN0LRpU9SrVw+hUMjrJhICIUFGEN4T62JVkiQcOnQIv//+O/bv34+jR49i4MCBOP/883HOOeegZs2aXjeRIAIJCT53IcFH+JqCggJ8+OGHeP3117Fy5UrUr18fWVlZaNasGTIzM0nkeQgJMoIg/EyPHsCMGeIEqyRJyMvLw+7du/HHH3/g0KFDOPPMM3HJJZdg9OjRSEtLE1YXQUQ7FYKvSxdnBN8PP5DgU0CCj/AdRUVF+Pjjj/HGG2/gk08+Qc2aNdGkSRO0bNmSHlxOZsywJ8oa4oCl8z76tqGtegmCIETRqpX1c59+Wl8wHj16FL/++iv27duHI0eOYMSIEbjkkkswfPhwpKSkWK+UIGKACsHXrZszgu/770nwKSDBR/gCSZKwbt06vPrqq/jf//6HatWqITs7Gy1atECtWrW8bp6j2BVlTmFV7DkBCUgiWhk0iP3YvDzHmuE7/PhbjcRfbm4ufv31V+zduxfHjx/HBRdcgMsuuwynnXYaZaIQhAYk+NyFBB/hKb///jtef/11vPzyyzh8+DBatGiBVq1aoW7dur58SV5/fbk4y8z0th1O4yexJ4y8PHz0y0lCihpVZ72QcoThN4P0W3sAX7XpOKp53YQIRIsrP4o1kRgJP3nO36+//orffvsNdevWxeWXX44JEyYgOzvbxVYShL+pEHzduzsj+DZuJMGngAQf4TqFhYVYuHAhXnrpJXz11Vdo2rQpmjdvjuzsbN8sfS0LOyN85D8KIyqFnozaC40mrzQajVGmWTOvW+AIfhN9IigsrPz/Q4e8a4ebGIm/0tJS7NmzB7/99hv27NmDU089FVdeeSXGjRtHK0kTMQ8JPnchwUe4xubNmzFnzhy8+eabqF69Opo3b45WrVp5+uJjEXZmRIuvHVVij1fMBV38RYsRAkC9esbfR5GjHC2iTyn0zIhWIWgk/IDygc5ffvkFu3btwrFjx3DJJZfg6quvRufOnV1qIUH4iwrB16MH0gUP9ueXliLj229J8CkgwUc4yrFjx/C///0Pzz33HLZt24aWLVuiTZs2rm+jIELYmRFUnzvwQo/y0YJrfDJmIs+MgIvAIAo/HpFnRrSJQJaUz507d+LXX39Fhw4dcM011+CCCy6g/f2ImIIEn7uQ4CMcYdOmTZg9ezb++9//Ij09HS1btkSrVq2QnJzsaL1uCDszguR7B1LsuSnIgiL+gmR0gH2BZ0YABWBQRJ9IoWdG0IWgWdTvxIkT+OWXX/Drr78iPz8fF110EaZOnYquXbu600CC8JAKwderlzOCb8MGEnwKSPARwiguLsZ7772HJ598Eps3b66I5jmxAIsfhJ0ZTvjgosqshuPWT45lweW39sgEQfA5LfLMCIAI9LPoc1PomeGmEBThK95/v7HwkyQJf/75Z0XUr0uXLrjxxhsxZswYJCYm2m8AQfgQEnzuQoKPsM2BAwfwwgsvYPbs2ZAkCa1bt0bbtm2FRPPuvXcu8vMFNNIj6tXzn59pS+yJQks4+VVM6SGqvSKEkJ09v5x6wLwWeGY4+WAmJVk+tQz2Fi8oLrZ1ehX8JPTM0BKCfvL1zIQfUB7127FjB37++WeEQiFMnToVU6ZMQYMGDVxoIUG4R4XgO/VUZwTfV18xCb45c+Zgzpw52L17NwCgQ4cOuPfeezF8+HAA5XtD33TTTXj77bdx4sQJDB06FLNnz0b9+vWFttlpSPARlpAkCevXr8eTTz6JDz74ANnZ2WjTpg2aNGliK5p3773GkTs/ir8grTHhC7EHaHuRQcvfSk8Hioq8boU9sScaP7XFCj6JlNoVfaIoLQUKCrxuBT9K39Gv7WeJ+u3duxc7d+7Enj17cM455+CGG25A7969fbllEUHwUiH4TjvNGcG3bh2T4Pvoo48QHx+P1q1bQ5Ik/Oc//8GsWbPw/fffo0OHDpgyZQqWLFmCefPmISMjA9dccw3i4uLw5ZdfCm2z05DgI7goLS3Fu+++i5kzZ+Lnn39GmzZt0K5dO2RkZFgu00zk6eG2+LMasPCL4POF2Avicn5mIQKvRZ9fRFZamvbnpaXutoMHvTb7YHsYP4g+o1vnJyHFerv81GYZlqjf0aNHsX37duzcuROtW7fGnXfeibFjx/pmGyOCsIIbgm/v3r0Rgi85OZkp+6xWrVqYNWsWxo0bh7p162L+/PkYN24cAGD79u046aSTsH79epx66qlC2+0kJPgIJgoKCvDyyy9j1qxZKCoqQrt27dC2bVtL8wusCjwjRIk/J7LQvBZ8gRN6ejgtAO3kfnkp+rwWfHqiyQgvRKCVdnrsUHst+qzeJjeElYhb4ycByCL8SkpKsGPHDmzfvh3VqlXDLbfcgssvvxxpVmybIDymQvD16eOM4PviiyqfT58+HTNmzNA9r6ysDAsWLMCECRPw/fffIycnB2eeeSaOHDmCTEUGSNOmTXH99dfjhhtuENpuJ6HhIcKQAwcO4P/+7/8we/ZspKeno3379mjWrBni4uK4ynFC5ClR+upm4s/vU4tE4qnYEz35R33j7AhA0RN7UlK8j/R5gVVHU+vlLloEinCC5TZ5JPziUea56LOC3qW3K7BE3wZlO70Wf/I70kj4JSYmomPHjmjfvj12796NWbNm4Z577sHUqVPx73//Gw0bNnSruQQRCLQifFps2bIFvXv3RlFREdLS0rBo0SK0b98emzZtQlJSUoTYA4D69esjJyfHyaYLhwQfocmOHTvw0EMP4e2330Z2djb69++PBg0acM0dcFrk6SE/22lp/s4mcxrPxJ5bqzywCEA3V2yINdEnOqqg582zPMRORzg8FH5BFX1aGN0mPcHl1iX3i/hjEX5xcXFo0aIFmjdvjpycHCxcuBBPPvkkxo8fj7vuugtt27Z1q7kEYZ+4uPI/0WUCSE9PZ1qls23btti0aROOHj2KhQsXYsKECVizZo3YNnkMCT4igh07dmD69Ol477330Lp1a5x77rlVRjb08ErgyWg5EwkJsSn6PBF7Xi/nl5VV/l8vvbVYEX1uppBpefxepbF6JPyiSfTpoTYpeaFTLxbq8oP4YxF+oVAIDRs2RMOGDXHkyBFs3LgRnTp1wtixYzFjxgwSfgTBSFJSElq1agUA6N69O7755hv83//9Hy644AIUFxcjLy8vwhc+ePBg4FbOJcFHACifhDpjxgy89957aNOmDcaNG4caNWqYnuelyGP1OYMu+nhWeI9HmXyW9gHRtma7luMtG4ZXnlo0iz6v5wqpR2pF2zMrHgg/t0Wfl32mss9T33K3BaDT4q9OHePvn3mm/B173XXGc/xq1qyJPn36oHPnztiyZQs6deqEMWPG4L777iPhR/gbByN8VgmHwzhx4gS6d++OxMRErFy5EmPHjgVQHhjZs2cPevfuLaKlrkGLtsQ427dvx/Tp07Fo0SK0adMGnTt3NhR68svn8GG3WliJXV/TbQdGbq9bPmGl2HMQ2cH2UujxXlCvhJ8I0ccygmh0PUQ+qF6KPZbUXK/EHyD0IZfijEVdCOav7LKw/WX7vRJ8PANcXm7To+xWzESbSMyEn8zff/+NzZs3Y+fOnRgzZgxmzJiBdu3aOdw6gmCnYtGW/v2dWbRl9WqmbRnuuOMODB8+HNnZ2fj7778xf/58PProo1i6dCkGDx6MKVOm4OOPP8a8efOQnp6Oa6+9FgCwbt06oW12GhJ8Mcrvv/+OO+64AwsXLuQSeno4IQCd8C+9WBfCDcHnitgDtC8gLclXlTp13PGY3RpN8CpiaXUOpofiT0oyX/LbLiyizzbhME6UuptGamO/egDuCcCM9KrX/0Sxu3vjWRF+48aNwyOPPILs7GyHW0cQ5lQIvoEDnRF8n33GJPguv/xyrFy5EgcOHEBGRgY6d+6M2267DYMHDwZQufH6W2+9FbHxetBSOknwxRh5eXl44IEH8Pzzz6NFixbo2rWrLaGnhxUB6FYAgdcPt9OuqBF7vBdNhLhy6uKJFH5mQ/tOiz4XDMxIwITyjzpTqcjFdhwSf2UJ+tdFdHaSGrcEnxGixaBdsaeFCAGoJe6McFP4sYo+oFz4ff/999i1axeuueYa3H333czz8wnCCSoE36BBzgi+FSuYBF+sQIIvRiguLsbzzz+PGTNmoFatWjj55JNRR8dZtSryjNASgF5liGn54E61xWl/3JdiTw8WoeVWxIpX9FnN2YpywaeFLRHo9IvZovgzEnd6xILo04NXDDoh9rRgEYC8Ak8Pvwq/w4cPY+PGjcjLy8OMGTMwdepUJLl1AwhCAQk+dyHBF+VIkoQFCxbg5ptvRnFxMbp164YmTZpobq/ghNBTkpxUbmpH891NfVEiP/duZHwFXuw5LVZk0eXl5tZq4efEZBwnr6PD105keqKhEPTihazTCVgRd3oEXvRZFHx6aAlBL7WGLABFiTwt/Cj8JEnC3r178d133yE5ORmPP/44zjvvPK5tlwjCLhWCb/BgpCcmii27pAQZy5eT4FNAgi+K2bRpEyZPnozt27eja9euaNOmTZUN090SeVo4LfyMnvGgCz5HxZ4bc8/UXp4Hqy9I6RkAgFDxCWcrCqjgi5q5aCaIWODEDCeFn6PXULDg06S4GFJKNefr0SBUpNi+xoWtPtwQfzzRvnA4jJ07d2LTpk1o164dXnzxRXTp0sXB1hFEJST43IUEXxRy5MgR3HnnnXj11VfRoUMHdO3aFYmqh8lJoWck8rQQJfx4nukgC75Aiz2z4XwHhZ8s8LQIrOgLsODTWgemWoo7r6PjRVX7HKcjTYEUfU4LPp2O2GkBGCH0tHBY/PlN+JWUlGDTpk3Ytm0bLr/8csycOZPm9xGOUyH4hg51RvAtXUqCTwEJvigiHA7jtddewy233IKMjAz06tUrotP2MppnhhXRZ/cZdlL0BU7seS30tBAg/oxEnhpHRV/ABJ8XYk+NaPGnJfK0cFL4OSX6ok3waSFCBJoKPTUxJvzy8vKwYcMGHD16FLNmzcKkSZOqZAURhChI8LkLCb4oYePGjbjqqquwa9cu9OjRA82aNavIx/dTNM8MI+En+pn1g+CLj2O/fhLMnYNQ2IIgdFLsifCeOYQfj8DTInCizwHB56TYs7q7gx3xxyr01ARN+AVS9NnohHkFILfYU+Og+LMq/JKL2BZImnzrrcxlSpKE3bt349tvv0WLFi0wd+5cdO/e3VL7CMKICsE3fLgzgu+TT0jwKSDBF3AKCgpw5513Yu7cuejYsSO6du2KhH+cwLmPPRZx7IkUe86wjGiRp+ZofsiVNRxECb7khEiRdaI0Xvg1YhF7PCh9uPhSB0SOU96yhvizK/LUOCb6OATf3+HqTMex+OIZKey/x49iTwszAWhV5Knxk+hjudfMGQA8lTsl+ASPuOkJQNtCTwunxF9uLk6k1WYWcrzwCL/S0lJs2rQJW7duxeTJkzFz5kykebW0NhGVkOBzFxJ8AWbJkiW44oorkJiYiN69e1ekb6qFnh48AtBpkQcgwiN0YxI/j7+hFnWGCB6+Fy32AHMfzrIIdHgi1PGikBtrKwgTfUeLIgWU6MiOaF9c1qS1aokt18l925XiT5TQUyParOXr7ERGrvC0b+VAhcgGOzyRWkqp5ozYU2KnM8rNNf7eoXRtHtEHlK8J8NVXX6G0tBQvvfQSRo4c6Ui7iNijQvCNHOmM4FuyhASfAhJ8ASQnJwfTpk3Dp59+ih49eqBt27YIhULMQs8IpQh0W+SpcVr0Kf0NLkFnhs8Fnx2RoCsEXVhbXe3MOy38eESfWtjp4WfBxxKAtCIEnRR7MoWFQGqq8/VYMXOz6yrar3dU8BnB80PcWDWrsLDy/90wDqMOyUzc6eHgoky8aZ7bt2/Hxo0bMWzYMDz//PNo0KCBY20jYoMKwTdqlDOC76OPSPApIMEXIMLhMF5++WXcfPPNaNiwIXr16oXU1FQhQi8C5Qve46F+0aKvyoivaKHiY7EnOhpUXOz8qopmERs3RR+rqDNCpHk4Fd2zilZX4bTYU/r0Spz277W6DbvXT6Rv75no00P945wWfHqGAbgn/qyKPC18Eu0rLCzEhg0bcODAATz++OO48sorae8+wjIk+NyFBF9A2L17Ny699FJs2bIFp556KrKzs8UKPbMXuh3hZ8Prsyv4DFN6nIhKCfTo/S721IgUf7ypeaKFn9JXE+lrRbPgU1NcDDi1sruRP6/EKd9etn/Rdudb0SfaOOR3ghN9MKtxAOINJC8v8t+if59PhN+ePXvw1VdfoVOnTnj99dfRrFkzR9pFRDcVgu/ss50RfB98QIJPAa2363PC4TBmz56N9u3bIzc3F+eccw4+efttcWKvtJTtZZ6byzdiWVRU+WcDnjkYoaLjVf5cJYbFHlAu0uQ/q1g9324kSTZvXjPnxY19rK3ghNgDyv1f+U8UPP58YSHf8UYUF1f+yYiOYDq9O4rvUF5U9cW1Au/Nlg3EjpEYGbmI36SE9X3NCa8/kZ2djXPOOQe5ubno0KED5syZg7BfOzeCIABQhM/X7Nq1C5deeim2bduG3r17Y8n8+eIKD1j+llakz7ag82k6p1/FnlW/xa0VFWVYoi68os6PUT635++xwmonvNE/EcKNN6DD+lv8GunzbZSP513B2k+LUvYAm6FYGcUIQMSPN9q3b98+rF+/Hh07dqRoH8FFRYTv3HOdifAtWkQRPgUU4fMh4XAYzz//PDp06IC8vDz8vnmzGLEnjw6KeHHLoRBBkTwzPI/emeEzsRcO+0PsAfqRP7vRQD20TNFuBC+aIy9eiD0gMjBi5juL8uVZgjlWgk2iu0BR96QM8WIK8hLRUUAWjCJ/dkLWTkT8BMMb7WvcuDHOPvts5Obmon379pg9ezZF+wjCh1CEz2fs378fF198MX744Qe889prGNS/v/1CncrXUiJ6so7Wi1b0fAuRo60C9rXScs6s6Ei/CD0t5Nvq9LoJeXn+HkwXMT4g6j6L6h5E2orcnYgM2uiRmiq27SKjfb6K9HkV4WPBjRGZggJn5hyKKtOqsRw6pPnx5Mcf5y5KjvZ16dIFb775Jho1amStTURMUBHhGzvWmQjfu+9ShE8BCT4fMX/+fFx99dVo3Lgxvlq61L6RuiH0lNgVfWbenV8En/q6CvLK7I7Gi9wuy4lBdDc0fFDWTOAVfFo+mVrw1avH3w6vons85Tm517Nch2g79JvoE5baKcpgRAs+ZefihCgrKKj6meh6RJR3+DDQoIGuiLMCr/ArLi7G119/jX379mHu3Lm48MILhbWFiC5I8LkLCT4fkJubi8mTJ+PTTz9F79690bx584rvLC3O4qUX5+TEHLcEH+/1E+CRiUi9Ymk2S1OdiurpYfe2mmVXifTL7NxqpQ/mlwifXEadOvbKcUrsqREl/vTK95vwk59pEQJSiOhTCjU7D4NIwWfWwdjtALTEnsjyrZR3+LD5MQIXEbMS7du1axfWrVuH4cOH48UXX0TNmjWFtYeIDioE33nnOSP4FiwgwaeABJ/HLFu2DJdccgnS0tJw2mmnIZXB49AUgTk55f+167nJ2PHgjESfnRwtUd6YyDXVAyT2jEhIcF/oqeG5vbxTaNwSfawD634TfEaYdSluiT0lVoUfa1tFCj+zbob12bXbXQkXfGYYPShuCj4lvB2BmdizUzZreSziTg+PRV9hYSHWrVuHgoICvPnmmxg8eLCw9hDBhwSfu5Dg84gTJ07glltuwUsvvYSePXuiXbt2ljYwnXvjjdpfWBF+TkzCAdxfPU2J0W/ygeDzg9gDIv0vu36L3dttdIvtLO8vyh8TsW2DHwSfCMEo8j1qtfthEX9WyhYd7RORmhk40aeHyCwUqx2OUYfAI/R4y2ZB9EagHgo/SZKwfft2fPPNN7jyyisxa9YsJCcnC2sPEVwqBN/55yNd8IBJfnExMt55hwSfAhJ8HvDTTz9h3LhxOHLkCM444wxkWpj7piv0tHB7iF4u04nJN2ZemJvrqPsguida7GnhxaroQOWtFrmHm5V3itYAuwj/yW4ZfhB8avvT2q2FBRFdkFZ3I6JcO8JPfX3sdju+SO0UIfi0yrDSn4rqdJQdg12xp1euGWYjST4SflaifXl5eVi7di1q1qyJhQsX4qSTThLSFiK4VAi+8eOdEXxvv02CTwFty+AikiRh7ty5OPnkk5GcnIwRI0Y4L/aAco9V/pNxYolrN5fNVtfnZr2C8FrssS4lb3Z5RW5uLVNQUJ4eKVLsAeYmonxU1I8MEYmW/VnZ/kLUY1tQUPknsjvgsW/lzjda18euVnJ49xtvUV88N/dCkQ0mL0/8HHgjQ+R5WERcE0FL+869+WbuczIzMzFixAgkJyfj5JNPxosvvgiKNxCEe1CEzyX++usvTJw4EZ9//jnOOOMMS8sVcws9LeQXhtWheDVmXpXoVRZE5VnZHSr3OJVThNizQ2FhedauE0JPjeipMbm55QvZAd5Oj7Fzvh+jeyyoux0nxmiU7RKdlqlVnpXr4HWkz/Mon9Xzlf2uE3t2qMt0YGNzJCXZzwsPeLRv3759+OKLL9CvXz/MmzcPtUT5I0SgqIjw/etfzkT45s+nCJ8CEnwu8MUXX+C8885D9erVcfrppyOF820tVOgpcSv/yoroc3oZPQ8FX9DFHiB+FXSWLCoR9ch+lh/8pSALPhFBENEZ33ptcmLPRxG2GGjR54dQpVyGqPlpZgJSRKehTFkQUZ7dMjwUfUVFRfjyyy9x7NgxLFiwAH369BHSFiI4kOBzF0rpdJBwOIyHHnoIgwYNQosWLTBw4EAusTf3xhvtiT2z1BievCvA+bRJt1IzY1TssaZwGqGV3mbnlskpeCxYrUMra0qEYBG5wX2QEHHtSkvLfV/5T0R5eohKOQ6HK/+cmsbm5vlRg/LGWIXFQOymVKoNXUSKpt0y7F63f7CS4pmSkoKBAweiRYsWGDRoEGbOnIlwrHaqsU5cnDN/RAQO5CsQAHDo0CFceOGF2LRpE0aMGIG6desyn2s7osf7AsjN1Y/2iRBfBQXOrajgBiJ3NLdIUZH3216Z+UTK22k2WGd1XYTiYrboCuuUGI9up6f40adS+sK805pZuzvZfnkjfnrXq6jI/tiR3TLsnF+GeOtRvpQUfypO9c1ywunjfR+YjWjI5dnpjOyWEQ7bnrA8d+JEy+du3L4dQ26+GZ999hneeustLn+JIAg2YtDdcZ41a9bgvPPOQ2ZmJkaPHo0kxlC160JPiewh16rlnBDzq8DjuW4+je45ueWVleiIfKvVpi9iATw90SdiuwRewmF+n1LEBux2RZvV7TpFRfeMYBV/VtvCKvxYrrH8bHkl2kScH9Uob6Lew2Yn/Gsk/nhD124JP6dWorLSGf5D93bt8Nvbb6PntGno2LEjFixYgL59+wpuIOFbnIjIUYSvCiT4BCKncD700EPo0aMH2rdvz7S33txLLy3/n8OHrXliIr2wQ4f4h9hZys3Lc2YyDW87UlLcXf3tH+yIPRbBprcioN0Ilt1UuOLi8jJER9Jk0WdX5DkV5WPdgN0rjHw+q2KQBd5HT0/8iXiEtYSfVSEdVNHmWZTPiwihVvRP5MIvSrFlJ09ZlPCTO0c3HV8boi8jLQ075s3DGbfeiiFDhuDuu+/GnXfeiThy3AlCCLRoiyCOHDmCCy+8EN988w369++POgxeU4XQ08OsDCeH2+2IPidXTzArw+ya2PGqLJ7rtNjjOY/VhxDlBynLESmsZH9KVJlWyhExUO5VhM9qnXYW0xM1zuLE9p6lpeLK9aCLsX2uZdFnR7QVFlp/AESJRTnlQGTnlJ9f+f8ixApP27RGwLwQTDbrHPv441i9ejV69eqFt956y9L2VYT/qVi0ZeJEZxZtmTePFm1RQBE+AWzatAmjR49GYmIiRo0aheTkZMPjTYWejNKjVIo/t/KqeDpZD6JmntTpIqLFHlD1kmn5EiLEnlYZdgeutQbN3ZyHR3vyVfUnWQWgqEc1HK70p0W9w+W26U015oUnWqcW7oWF1sfFApnaqTdy4YZIUeaXi5qnrRR7QOXvs/N7zDpOszQHEW3gxUakDwDevflmTKxRA59//jk6d+6Mjz76CF26dBHYQMJXUEqnK5Dgs8m8efMwZcoUdOrUCV27djVN4WQWe2oOH67suK0Os1vJpxI5icaONyP/dq9EnsvRPSfEnhby5Swqcm91c16RxrLmgV3Rpy6DxF0ken65lq+p7p5Eij0lSt/aivjTapesAewKPz3xxRKZ9UL0WU7tdCo1U+tCueXAWRV/arGnRLTws5LLblOEWaoPsFznvMmTcVVSEjZt2oRTTz0VL7zwAiZMmCCwgQQRW5Dgs8iJEydw7bXXYv78+RgwYACaNGlieLxloQdUffkpF1hhwe5S0qInz7DgRM6ay8Pffhd7aljWNzCCJzLIEu3jmQZjV/Tl5tKAoCjUvqjdSBxLV8AT9WPpwkQIv6Ii6/v12RF9UYvSENwSL6xpCUZiT4ld4afsFK2UEbBo34uTJgEARjzwAKZNm4Yvv/wSzz77rGkWFREwKMLnCiT4LJCTk4NRo0Zh//79GD16NGrUqKF7rFChp8ZM+IkSZ3l5zkycUeLHteJlXBSKXog9rXN5/AK7i9wpfSm7ax2wij6tAXK3B8CDgp1HMxy2t+UCb91mwo+3S7Sa5im3284qnlZFn+tRPq+wswUD73LBRlE/VrGnhFd4aXWMdsSbF9E+G/V9fM89+Nezz2Lx4sXYtGkTPvzwQzRo0EBgAwki+iH3hpNvv/0WXbt2RUFBAYYPH+6M2OPdDFW5q7TZZutW2uGEGFOW7WexZxEr0T2/iD0lZrdIxHw/eUE5pzfg1tqAnXAOLZvh2WzdTreQnx/ph9vpEgsK2PSB0bNi9Rm1+ny5ugCm1QEx0SFMt94pynesFbGnxKy9LA+L1d/r9rvXZl3zr70Ww4cPR35+Prp164Zvv/1WUMMIz6GN112BInwcvPHGG7jqqqvQtWtXdOrUSXe+ni2hZxV541S7q1nptSE/335ulvyCdDpaqIVVp8TCebxiz0nBJvI85YCyqFU8lf6SqEFn5e4mvOIuYAPfjuOkP2gU+RNVr1yHiC5HK9rH006rkTc3I32Bi/IZoRcBFLEZqLocEQ+xsoO1MvpltTMRkebJM+m5Xj3L+9a8Mno0roqPx+bNm3HGGWfgpZdewsUXX2ypLIKINUjwMVBWVoZbbrkFc+fONZyv55nQUyK/KJzOnWIh6KtouiD27OBFRFDp44hczE5GlACyE8VzU4S5tTiMk3vracHbnSj9W1GrbyrbIGoxFrkctxdVsSP6eOcRhhGPRJTwnZSUVL45pp+RDcKJB9zuBGgZL+foGV0XkR2VzU1KQ6EQunTpglq1amHy5Mn4/vvv8dhjjyE+3r13LyGYUEj8M8mwB3asQfvwmZCfn4+xY8fihx9+wIABAzT3g5k7YkTkB6zelUihp4WZ6LNSv5k3xiLy7HhdVtc7t+ItuST4eAWYMrrG20eKEntKRC1kp4T3d2kNiNt5f4h69wRltU+tLstq9ySyW7OasGDWBqtdkLJcN7oxNVrdmNlvtVIXt+AD2DoX9YPlRc6quiOz8rCzRAlFdGJWyrFzrtxh+TntAMDkjz8GAOTl5WHVqlXo0qUL3n33XdpvLWBU7MM3eTLSBS/Ek3/iBDLmzqV9+BSQ4DNgz549GDp0KIqKitC/f38kaQyVVhF7Wqi9KaeFnhItj8lO/VoPDm8kT6SnxPpbXBB8bs3bM/KR9N7TTgg9NUbCz8pUFzOfgyXryQ1fKSiijhf50eKNDjrRvfEIP9b6ebohvTK9EH1WznNF9FnpZLxOU9DC7MG3khLqZWdmdJ5R5xUQ0VdcXIzVq1cjJSUFS5cuRXZ2tsctI1ipEHxTpjgj+ObMIcGngASfDhs2bMCIESPQsGFDnHrqqYhTdX5MQk+NVQ9Kea4VMjPFpmymp9tL17Sz7J0Vz8Wn0T3RYk+LuDh3xJ4SpfCzu6aBls/BO71FpJ8UreJOC6MuQ68Lc2MsS0/8Wa3bqDtyQjwq8bPocyzKZ+d4u+fxdmjqTsDu/D91eVbm6tnt0Hg7MR8LP1n0hcNhfPXVVzhw4AA++eQT9OzZ0+OWESxUCL5p05wRfM8/T4JPgX+fZA9ZsGAB+vXrhzZt2qB3795ixR5Q3uGydrp2V9IKh8UtSyi3RcRyiqx1BWQVTz+KPfkcK5eQdWVCLeSxALtiD6g0X57VHUVx6FDlo8rzyEYDZvaivi6HD7uXuKBlB3bq1rJ13mfG6rNSVORuYIyHEiQ6X4nLe6NyI/odpCzLamdmpS25udY7MR+/f2VfLC4uDr1790abNm3Qt29fLFy40OOWEYT/oEVbFEiShEceeQT3338/+vXrh6ZNm0Z8b1voqVF2viLTPrXOV2+gbrUcp/DTS8XhVE63xJ66HtZ1BewOYotcvE6EwGNdoyGWBJ0TKMeV9LYG1cLqoy/bhqjBW7sLsvDu2af83W5stG51wRhfYmcPPquIWt0TsN+xsSzOInL/GR8vJzx3xAhM/vhjhEIhdOrUCTVq1MAll1yCX375BbfddpvuauqEj6CN112BBN8/lJWV4dprr8V///tfjBgxAnVUAky42FMje5s8nhJvfTyiz0kBZrVst9I5fYYIsadGT/zZ8Wm0zrXqJ2hFcOz031rnk8DTRsSjr/Y19bo1EXWZbbbOix3xZbYaqMhu1YqA4z2nBIl8qZ0pKS5vAvgPLAJQpGCzg4jUBxkt4efURqMitm9wCFn0AUCzZs2QlpaGhx9+GHv37sUzzzxDK3gSBEjwAQCKiopw4YUX4osvvsDIkSMjNlN3XOipkTtrp4bIjUQfbw6T1eFs3nPdxGfRPSfEnppwuNIXsvouN/KlePwEo4FvEYPMvCLPxwPbgUIr+id6TEmk8JOfOxHRPtbfaUVoRlXUTiSijcuJjUdFEg6Xl+1GpoxPO0Wl6KtTpw5GjBiBd955BwcOHMD8+fORQg+Kf6EInyvEvODLy8vDyJEj8fvvv2PEiBERnQK32BPZ2bIIPzu5ULLoc+oF4acUTR442s06x0Xud5wWeyLWMeAdxOUZNNfzE3iym6z4Gk4NeBPWkO9HXJy4qJwS0cLPiuiLiys/l9fHdEP0OR7l8yvKjsOL95NTYk9Zrvwbnf59dqN9LCNvdepwj9ApRV96ejpGjBiBlStXYtCgQViyZAkyMjKstJYgooKYXqVz//79GDRoEIqLi9GvXz8kJpY78K5H9cxQiz5Rddn1iNRROp52WYnw8XpPqal8beIsn2dRA94tqrwQe1rovc/tZEfl55ePN9iZxmLmZ4gWeW4MFopMMbW60bpbfrDW9XRqITVR5bIIMa3f5deFhXmOd3yLBi9TH8yMXkR0zwmxx1KmGw+0D3PlJ2/YUPH/JSUlFds2rFixAllZWR62jFBSsUrnDTc4s0rnU0/RKp0KYjbC99tvv6Fv377IyMjAwIEDK1binNurV9UOy8h7cqNDlb1Xq7sQO0VBgb/nyDl4b0SLPaCyuW6sbM4q2LQGckVMhRGxZoHaz/BjJM8r34e1XqvC0A564lnpv4p8P4sq1yj6ZjQgYCXt0m/pnVET5dNCffNEvzecmDvIKiDj4px7Dyo7XAvROCeZ26tXhehLTEzEmWeeiXXr1qFXr15Yu3Ytmjdv7nELCcJ9YlLwbd++Hf369UPDhg3Rq1cvhEKhcqGnh1ZHZmdxFV7kF1J+vnhPiEY+yuHwlJxcrtxPYk9JOGx/oFv0IHdenn8yh33k63Bh1G4nujjWSKkT4i8uzv70YeXcPp6or/yc8ggyp1fujKn5fzwdpcjUT/XkaBHl8ZYhqm6jETUfdoBK0RcXF4fTTz8dX3/9NXr37o01a9agbdu2HreQqIDm8LlCzF2RzZs34/TTT0fjxo3ZxJ4eubmVf06h9RDk54v1nJ2aV2AX9T58vC8rn3gyPH6Glawmt/YL85PYUz4CbvXp8jXW2n/Oh76OEJRdnBvdnR529oSUUUeo7ZZn9Xnw6zxeFrgGunzS/9pG1GItMvI73UrHpRSPVs7nPU+54aUf0yc4CYVCOOWUU9CoUSOcdtpp2LJli9dNImSUz4XIP0Yefvhh9OzZEzVq1EC9evVwzjnnYMeOHRHHFBUVYdq0aahduzbS0tIwduxYHDx4UPSVcJSYEnzffvstzjjjDLRs2RI9evSwLvbUiPaGWIzVL0JNxAuRRdw5OdTtUHTPabGnhEUXW3FyCwvt3WKR4xN6ZTkl+tRCJ1qFHS+5uZW+IE9qrt37ZEWoGXWldoWfnc3WWYmLczbq78UOCkKwI5zcgmWCNEv79QzVjvDTQ+vBzsvz93U2QO3fhUIh9OjRAy1btkSfPn2wceNGj1pG+Ik1a9Zg2rRp+Oqrr7B8+XKUlJRgyJAhOHbsWMUxN9xwAz766CMsWLAAa9aswR9//IExY8Z42Gp+YmbRlvXr12PIkCHo1KkTOnXqJEboGREXxz/nzkqnKirfyU45vGIsLs7aAiw88JQfMMHHI8CKiqxn8tgVeqJwa22CKBjEdg2jrkqr27PqL5qdZ5SeyVOnnTRPq+dqdTtGbXZyURbWY7nm8TmpPHk2GrVSPuD+aIBWJ8Y72dpKnbzLJAcQ5SIuMlu2bMGWLVuwbNky9O7d24NWERWLttx2mzOLtjz6qKVFW/7880/Uq1cPa9asQd++fXH06FHUrVsX8+fPx7hx4wCUTw076aSTsH79epx66qlC2+4UwRy24WTjxo0YMmQIunTp4rzYU466sQ6B2xmpFDEhXJ7c4hQWw+yuEMViT4b3stuJ6tmN6MlmKJfDszYBL3l53qYqRivKIIGd4IDd4AcPdqJ9Vs8tKir/Y+0a/RCNcyytU3QKqJfvHKuGpG4rTzlWfmdeXnkHy3Oe397fjGj5fJ06dUKXLl0wZMgQivRFMfn5+RF/J06cMD3n6NGjAIBa/0xk37hxI0pKSjBo0KCKY9q1a4fs7GysX7/emYY7QDCfXg42b96MgQMHolOnTujQoYNzYs+ow9UTfnZz8eVzRb1grKJWB14LPI/nj/hF7KnLZrklVoWe7PSKuN12zNkMdcZSQP0XT7HiVzqd/qm0Pzv31K7wcxqn+hY/iElfYedm2u1U4uKsd8QsD4DWw8gr+gLYcWr5fh06dECnTp0wcOBAmtPnJaGQ+Pl7oRAAoEmTJsjIyKj4e/jhhw2bEg6Hcf311+P0009Hx44dAQA5OTlISkpCpip9pX79+sjJyXHkkjhBVK/SuX37dvTv3x9t27bFussvd64i1s5P7mStLn9nVA/r8nMiyuAtNwpgHdn2q9hTI98uZYaOHbGnLps380dEGXrn2d0CgrCOultQ3gu9jHc7EUHZjux2Y1ZXyLTShfLWxbO6phMrcQZuiwbRC6+w1KXVwbIiYmVP9bmsmUY8dVntpFlxaHN2NZ06dUJpaSn69++PL7/8Eu3atbNVHuEv9u7dG5HSmWySOjpt2jRs3boVX3zxhdNNc52oFXy//vor+vXrh+bNm2PD5MnOVGI1Oid3vqxz/FjrMfI2olyQVeBlGhEHXoo9JXayeY3OY/UFRJShhlfgOe23sODEgjBO7LEnshvREn+i0j+tCD91GcotGHiwUreToo+nTIC1HYw3KjXVXcHlJVq/U2lUVjtEEeKRFd66rHSeIvPnOTvOuS1aYPJvv1X5vFu3bigrK0O/fv2wbt06tGzZUlQLCRaciBr/U156ejrzHL5rrrkGixcvxueff47GjRtXfN6gQQMUFxcjLy8vIsp38OBBNGjQQGiznSQqBd8ff/yBvn37omHDhujevTsmb9ggPpWT1zi1jjcTflYeAKXos3s+AUB8dM8vYg9wNn3NyHdgrZfHn1CmaXot4IByv8bLdrD6VU5tKcrT/eTlAQn/vI14148yS1oA7C3uYiXal5DAL8qc2nePT8ixUYZ4xKOM7WBWQ/DLg1tUVGmMpaXiyjUTUyyrehqdr0Y5ATohge+38NwLvXbpjbyxlu2QPeiJvu7du1eIvg0bNiArK0t43YQ/kSQJ1157LRYtWoTVq1ejefPmEd93794diYmJWLlyJcaOHQsA2LFjB/bs2ROoBX+ibpXOvLw89O7dG/JGm6F/8ni1qBCB6o7JKPImQujpYXeYW1mnF8vO8Z5n5A2prwGr5yT4OCcWauE9jvWd54bYsyoQ5d9g93w1RtE8Xl/Bqm9hJKy88l9FrMOg7gadXNshQWfo0Uz88daj7qJ4zmcRTFq/w8kFiXlW+hTdhTILPlEdo/Jh8mLUzEgwWY1i2ukY9ToXs5WueEUsz4hbejp7igVruQ51olqiT5KkilS+9evXIyMjw5G6iXIqVum8+26kC05ZyC8qQsaDDzKt0jl16lTMnz8fH3zwAdq2bVvxeUZGBqpVqwYAmDJlCj7++GPMmzcP6enpuPbaawEA69atE9puJ4kqwVdUVISBAwfi4MGDGDhwIOIY3uZz27QxPkDp9Ti9mpWdoXat+twWfVYFH8u18rngc0rsaWF3xXEvFqWQz7Xz7uaZjqI+R8Sxyno99lVM4Qmq8JQpOgtdRk/wyWi9r+2Mi4nehcas/U6KPrsC0c5xTKLPiYnNPALLiTQJtWiyk7ZaWGgvkih3MjzLI4sQfXodschO10qZjGgJvvKqwli5ciUaNmyIlStXIsXjReCimQrBd++9zgi+++9nEnx6gaHXXnsNEydOBFCuL2666Sa89dZbOHHiBIYOHYrZs2cHKqUzagRfWVkZzjnnHHz//fcYOnQoEkzewKZCT4nSs2DxeER4O6weiVldrCJMXY6V/B9ewcdahxPz8hiO8zKV0wm/B7C++TogbgqJE5E0PaxG+cxEpRM+jUhECz6j4+xEAgFzsaQmPd2e2JPrs5PimJrK324/iL7AR/lknBJ8VpYrtSPY1G2zWk5BgbVzrQg/ryJ4Loq+kpISLFu2DCeffDIWLVqE+Ph44XUT/hF8sUJUrOQhSRKuvvpqfP311zjzzDOdE3uA8friViae6rXVbLROxCRXo3X6gzjRXrQ3I5Cgiz2Az9yMlrfnKUe5Hx+vg81Tl3rvOFHlxgLK68ZrY1buaWGh9Wizsj47+00WFzs/v9aJrEUnBqd8j5MPq3zhExL4jVnrpvGWo+xorbSB5RxlJ8y7N6AXx3Ewt0ULzc8TExNx5pln4quvvsKUKVMQJXER/yJ6SwYnFoGJAqLiijz88MNYsGABBg8ebBp+ZxZ7Zgaj3lnYitBj6Wh526VGb9UvJx4GNzaicgkntmEQWZ7TYk/PGWYxHZ4FXfTQ23RdpOjTEnix9I5wys9S+odG41ZW7qXyHJ4984y6Wx7hpy7HiugzesbVvorfhVcZfB75kC+gW46gbCBmxm1mOCxl6Bm/VeGnxOgB5ik/wKIvJSUFgwcPxjvvvINHHnlEeL0E4TaBd2/eeustPPDAAzjzzDORZpJSyCX2WElIMPds1MfzdMZyuXZeVModiXnKYPFmlC84Kx5cgHFz3p4S3gwlXqeRpXwtU+LdtFrLFFkeJatmxhvFCypeiVajZAX1fbUr9pSY2R1rXUZ2byYYeVE+k2Zds+h+wZMon9/mQWkJQNEdpZ7R8BiMXhksHa0V0VdYyOfLsBAA0adHWloazjzzTNx///14++23Xas35qAInysE2kP/4osvcNlll6F///6oY7DplGNCT43cUWrlC9vxcOQXhJWFVJRliFqXOyjC7v77I//NcX9Z4nvKY/6++1HNY7wWezIsq4xbdVztrDcQF2dt+gnrKuM86xgo2+ThquFRjXw/EhL4Fk5h6XK0tmCwmmUnd5W8YpG1i42LK08LFb2BOms3L3IfP64tGvyK2kEU+WArjchqZ6nswHlG1Vi3l7C6hQPrsSI61UOHqh4riLk6azNMzstDnTp10L9/f0yaNAmNGzdGnz59hNVLEG4SEM+9Kjt37sTIkSPRs2dPZGdn6x7nmthTohR+ooeyWUSfaEHmN4GnTq9guXcOj/bUePC2yA/+eWnVUHz0562zNM91Wuwp0fM9rIg95fQVdXksKP0W3m2ijM6xIvLcZurUyH+zON+JKDE/SOPGz3qhRpXPRA+m83QR8rHK+2Qk/ni7n4KC8nPsLFJcXGxtfMxMcKmvJ4/wEi369FD624WFbHXGg8GZ13Lk/ToKbyb+7Ez+tNLZAZFz9ax0lkDkeSz51iz1sB4rX1M9QffHH9rH6xEOO24/FUIwMxNzw2GMGj4cG777Dq1bt3a03pjDiYicX/sWD/GZJ8/GX3/9hcGDB6Nly5Y46aSTdI+bm5ZW2YkYbaLplFcjvxRYh7JZh7H1PBmWeQOsnoBclvyCcpvHH49sRxRQ97FbIj/458W39/onTM91YqE52USt+B566w2wlGU09YS3LbJJs4g8nvLtRO/+WcUZgD8y2W65+u/IDzQM5InX67rSFpY1qpTdpZ3xMpZN143O543ayai7WbPXi8homxlWxJwwUlKq2p76IUtKqnqMG46b2cRKJVY7BmWnyRv1U3eaVkfZEhLKyyouZj9edLRvz57K4wPE5K5d8XNeHoYMHIhvN21C7dq1vW4SQXARuG0ZiouLK/baGzBggO7+GXPN3vJZWWKjeizH6gk/Kx2f/Pt4zzXyXvTKcmKjJ7lcWdjxtEeJD6J7VWBxCEyOUYpAp1YVt7IiOGtbtMpizURi9S9kkcDr87Aeb3SLzj+fzdRFLhxrNcJn55inFjYxPVRE16hFUpJ1saaFWVlG57qxS40XW42KtGEv7NP149THsnYmLB2nXlksHSdrO5RlsYo+3jqUx+3erX9cAN/vYUnCue+/j9xatfDZ2rVITGRb3I3QpmJbhpkzndmW4c47aVsGBYESfJIk4corr8SSJUswfPhw3YfNVOwBVTuvZs20j3PCm5GNz84IF+sOyFoovRfWNogQfc88w16vyAnhARR8ACJsdMfU/zM9XNQy7nrvdd4sJrkcK4u36rVBL5LHI/p4Bd/552t/H8sOtVIIsj6qvGJPichMdq2yRHWDWuV4tI2o62UJs0/W47wQhkbHiu44Af7O04po5BF+LJ3n9u3l/2V5qAIo+o4VF+OU+fPRe+RIvPjKK7pBB8KcCsH3yCPOCL7bbyfBpyBQMfVnnnkG77zzDkaNGiVW7AGRI1HNmjk3bA2Ue621avGdo67Lar6SsgwnUYo7p+r32YsAgLjJ/iobbTv73xH/VgtAkXt2qbOFrE5XsbPKnzo7iGXlThGZRyNGlP9X1PpG0coN4/ZGGMazy9oaHm9H7AGR/qodwaYsKy3N2qIuWrZhVI7oeXrhMFt2vpuposxopXU6ibI/dvpdIGJxFmU5VjpedefNIhiTkvhSPJXlA5UCz0tcmM8nUz0pCR+PGYPub7yBTl274rrrrnOlXoKwS2AE36efforbbrsNw4YNM91+wTa//FL5/+3aGR/L6zHI3gyPYBMhkJRliFyxU2b27Kr1mLXDzjFBRoAobDv73xUv3R+uep7pHF7/gTfjR4ndBVmAcr+Qpw1W6pEFHqGC0zG/dsiOiH+bCUA9tMSeGnXXabW7KC62tjiLcm4fa912RF9QVoItQSJblE8ULDaamlp5w9QX0sp2DDwTpAHrwk9us/xA8HbG8lw9Vnjr2bq1sh49SkvNHxCWY1wUc6xkp6fjw3POwZm33IK2bdti6NChXjcp2IRC4u8xRV6rEIiUzl9//RXdunVDjx49DFdHshzdYz1GKf6sCj0trC7CYna+WRm8no7yeFngsdYl+hg/RvcAR9I5eY7RE3+8Yk/reDsLsrCer1WGyIyjvn3ZHG+WRyOqUzpZjzMzrH/KmLOuC1OVLIJPidxV8IwBatXB2xXK9fKex3qvw2HzY920UdbjmAWfmymbLJ2fcoN2u/Xp1Stivh9LZ6jVCfMKT716Nm2K/HeMv/Pf2LYN16xeje83b0YLnQ3cCX0qUjoffRTp1aqJLfv4cWTcdhuldCrwveArLCxEz549kZCQgFNPPVX3OMfFnpKOHc2PkWH1YOxsHmX1fB5vZd4882PcjO75sPP3WuypkcWfCLFnVjXPYLLb00z69o38Nwk+9wWfEj3xxyP29LoJs9eAWR1W5uixnKdE736ruwayUw8EnxKtPTR4cHKitF6HKGLETV2HWuSpifH3/rQVK7CmoAAbvv8eqTQXgIsKwTdrljOC75ZbSPAp8HXunCRJuOKKK5Cfn28YMndV7JWWVnaAXbvqH8c7VC131FYXY7EiEs1SO198sfL/zX6Pm2mYyg49N9f8GKexOh/TSUpL0WX25Ip/rp841/QUVl9DmTppZUEWK+fzTDNRCzxe6J3tLFNO+yHi33PWdREi9gDjTHmWOoy2YjCqlydLXtYNKSnBSdf0BJaUTd60Tp5y7Nwc3onSLOcoUadgsnSkvGmmGzZE1mUVUamdWvjg/f/UgAE44+23ceVll+HNt96iRVwI3+JrwTd79mwsXrwYo0ePRnx8vNfNqdpRagk/K52jsqNj3VxdXZ+oTaOUIk9dhx2sjPL5oDNnIjfX2DnwgSDsPa9c/OkJPzfn9wHlvhXvgLOR6Dv55PL/urVIhe8WwwgwU07+uuL/X9l6iuGxrD6hUvhZ6b6U3SJrnayiT+4qgib2hC4C4/biLSJQ7hFo9A7i6Uxl47J6LZKS+DtvM+H3xRd85YkSdFrHaPkAPnv/Jx09ikV9+6LbBx9gzpw5mDp1qtdNCh608bor+Dalc8OGDejbty+GDBmChg0b6h43V+0BajnXIqJ7LGX06mV+jBI7m0YZeTE8ou/NN82PERHd0zsmL6/y/0WmawQhndMpW2U8Zv3EuZYWglOfwyP+1APRVtY0kOuTRZ4SM4fUzTQ51uN8OTeK9Tir6XIm32sJPysBAPnaWonayt2eFZGjVZ+VlE235vGJao9MINOPWcrR+175vuHtVNVl8nSo6rqsCMfSUnOR56QPAFT6AXXq6A/0KvFhaueaAwcwfPlyrF67Fr14fcEYpSKl84knnEnpvOkmSulU4EvBl5+fj44dOyIrKwtduuhP9q8i9rRgudEiHGhlW/r0MT7W6mIsrEPVZl7Aq6+yl8lSJ0sOv1LYaSFSyAV5sRYR9spizwp7XXnxa+bHw9yPMXocRU4tMZpC67Tgk28hq4AItOBT3nC9Z8pJJ/ofXtl6ii2xp4Tlvul1ebzCLzXV+JEXZRt6v0lZt9sLvLi+J59btspyjKhVP838G6Pfw9OGZcvY3vOiRJ8IX8CnA7+P/PAD5uzbh607dqBGjRqu1h1EKgTfU085I/huuIEEnwJfpnROmTIFcXFx6Ny5s+4xTGIPqNq5qOfIiRZ7QOVomVr48Xotcnonb06SVm6RUuTJOCX21NfczX33vEBkbpaZvYpAZa9nvjkJgLHwY/GVtFb2Zp1aYvaItWjh/tw6u7c1qtI+tS6GS8/j5S1WVfz/f/YMYDpH79qbZb4bdXk8KY3hsLspm27VFYi0Tr2LwTKXT3T9Rs+I2W9XGqOyU2X5DfJNMqpj2bLI8p2cq6d8r4nYhsGHWzUAwK2dO+OT/fsx5cor8ebbb3vdnOBAKZ2u4DvB99Zbb+GDDz7AOeecY3/yq1bHr3aozVIn7WygKgu//v2tnZ+SUl5/aam1uXlOdzhyx200Yuf2nnp+fcitRgB57dUGWsLPin9UWsrvx2lNK+Fd5VqUIxq0uVWe4daFUjjqE7LLxZ+e8GO1AbXwY/V1lQuuaMFzSUSJJ1G3QaSYE7onn6iFWVgulAgRqrX3n933ktX9+LSEn1Lo8cAjCs2ieCLwoTCMC4Uwv18/dFy0CG+//TbGjx/vWt0EYYavBN/vv/+Oq666CqeffjqqV6+uexxTdI91+Xtlx2QlmmLWluLi8g52yBC28oyGpllF3+uv24/eGX0vXzM3I3d+FXJuY9deGTjz1YsAAB+N/y/3ubKfY8dvou2MCDNk4QdUij8rYqWwsLyr4w1uKMWR3quGp8smAoSVzk0d9bPSOSo3Y7ci/BYuNDZ0u1E+Vr/A7c3WXRZ9japXx6t9+mDi5Zejd+/eaNq0qWt1BxaK8LmCb+bwhcNh9OnTB3///TdOO+003eOYUznNBJ9R5E52pHlTOVm+1xN+rN6Kngfx+uuR/xYp+PRG6/y4oaofF2thPc7OHn2sNgtw2y2L8LM7naRePfsLVLi535jbi2V4PofPyfoE7ff3v/zh5uUoUHeBvOJMxOboZLOIaZtlfl/plcXqDy1cWPn/fvAN3N53zwPn/4ovvsBPNWpg7VdfIY7EhyYVc/iefdaZOXzXXktz+BT4xgpnz56NHTt2oGfPnvYLs5vjkpcHHD7sTFqCOp0iJYVvaFrd8b/+unixV1hY/tvlPy3cFHus+LVTdWNDdrP7JWNhkGLU2xdh1NsXaR5eWMi2xZUe9eqV/xGEXS5I/wQXpH/CdKxWF8hiy4D78/MI+G9CrMj8cTODMjJKs/D0woWRYk8ULO8aI+xMlbGCBw/s06ecgj07dmDOnDmu1x045Aif6D8iAl+kdO7evRu33norBg4ciMTERN3jhKZysiJ3aur0OSvRPRlZ9I0ezd4OJWqBZxd1xy1i3z2RGD24vNs6WMWh9ElHcCjtUxZ9csSPZ36feiqJWuSJWH6etQ12jyEEI3jxDqXoU0f97Gy+Hgsiz7fz+GIBrfl+rJ2seo6fkcgzS93U+175XjF7kKxupK5GxDw9Xh8hM9O6mFW8b9MSEzHv9NMx+qabMHLkSDRr1sxamQQhCM8FnyRJmDhxIlq0aIFGjRrpHsecyikCLUEo0olWdsrjxrGfN3++uHQMO6NzTkf31G3zQ8qG1vXS8gD9JgxFi7/iYox6/Tz8b9wCS6dTNI9wE1n8/S9/uK3Fjp0Se0JXvQwqIgU/y+ItLPWJOMasLXrn2zG2pCRg3jyxg7ZOLcBiVxRa8ROslGvj3DOrV8e/srIw6eKL8dnatfYXIoxWaA6fK3gu+F5++WX88MMPOOecc4wPZHFcRUf39Dh0yLgdPOJUHonTE37z57OXZUZ+vnkH60Z0T76XfhByolG/LJQ26bQYNLPtvLxy27TaDoVdX7DwPABgFn7RlEIvciGOmHf2XeKCpEUAgEU4l+u8wkLv75EoUShyERlPhKpT2zhEE/Pmlf/XahRP5vBhY1+BZYEXFkHHckxubmAXcAGAxzt3xkkrVuDll1/GlVde6WrdBKHE00VbDh48iFatWqFPnz7Izs7WPW6uLLCMcGuDdaCqoONJ9zT6Tin6tISelehefn7l/7OMponaXBWI6g1WAYiZm5eZKW6gwsoiQ4JsV0/4yeZkd0N0vyx+ERcndmELoRtZA2IXwJCPM7JPUfWxLJJhpx2q73mEX6zZrkj7BjzYhJ3FbnnLsluGQNvVRBZ6Spz2F6zu06t3jJG/INIP8MBX+PjAAVz4/ffY+dtvqF+/vuv1+5WKRVvmznVm0ZbJk2nRFgWeRvhuuOEGZGVlGYo9ZtzYsBrQdnqV8/zspJ6KiuYpO20eRCzJDMTGYi2icrzy8qqW5WZaqCDbvWBhZZqnqCCx18Fdr+v3DXoXwu1Jbcp22Kz7XFiL+LHipe3YrTvw0Tu5LDfslrXdAm23ClpiD+DbZkHLZzCLvtmN8onejJ0VD6J8Ixo2xIDff8eN112H//7vf67WHQhCIfH3hNJnq+CZ4FuzZg0WLVqEMWPGGB7HFN0TtWG13XTPvLzyMvRGE+yIQbOOtajI+MUjYgK12xutB93jtvpid2vwQl2nke0yEGShJ9cZdJNzFfW8CzcFoFyvz4Qf2a7DiBCGehfMLftV265XqarFxe7W65fN2HmOE8iznTuj3aJFWLNmDfr16+dq3QQBeCT4iouLceWVV6Jr165IMxBiTGKPFRGLV5gJNlkw5ufzO85WxKByVM6ut+23jdaJSmQxJqNlv6KWuZZtysUUCLc3pybzcwitC+u0Ey3XybJYh8NNsApvRM1OfSKjd4FfcEYttLQEoAgxplcG64200wa9KJzcz9v1G8yifH7djN0DmqSmYka7drhq4kRs3bnTcEX6mIMWbXEFT67I008/jfz8fHTs2NF+YVbmP2ntWSZ6X5j8/EhBJjK6py5bxLw7Jcrr48aonB2CnM7JWhaL/YpGoP3adQpFOZW0NY8H0AUXAsvWUn5dz6QEHji2IjoN1g7Da9U7cSLf8Tz9uhW/yMn3k6g9bXmOE8j1rVsjdOQInnrqKdfrJgjX38YHDx7Efffdh549eyLOoDMVGt0zgnWTdasdo9pxtopcjoiy1Li50Tor5CiyIWrDdaftN8bw2geMOvwyauARbgcvPRGPAb9Hhrixso8ZTvXlxcXm7yFRC+ax4tNNMxPj4vBCly64f/p0HHLLxw0CtPG6K7h+Re6++25kZWUhKyvLfmFObLKu1WnZ3QOwuNi4s9Urn0XkWUnJUJbrtjMfKw+hFy8cJ0dWAy783E4bJaIHu+LHr5E3EQReGLKUxdJ5+FmsHj5s3HfbHQx0+73gdoaNYPrXq4cBtWvj7ttvd71uIrZxdQ7fli1b8Prrr+Pcc40nyLsW3QP0OzPl6oVWy9CCZX6fyLl5ctTNTqcsMnLHglIUiliqWRSsWyiwIqosLfsTveG6jAdz/MwQ5Wv52Wcj/IvI/e2ilRIksm8tIopY2rdv4kTt1TpFizG98kTtuWd3M3Ylyjl/Rn5ErVquT115smNHdHrjDVx3441ipjYFHZrD5wquefKSJOG6667DSSedhIyMDPsFurXJ+uHDlf8vyslVOs3K0TUnOmezzlNU52plnqAefn1QtbZQUCN6RU0RNqxc9MUJGwaw6F9sG7ATBOEtvl5sJZpFmtlvM1t4iOfaqH0Juxux5+a6P/BrBKuYY/ElRG7szkjrsjJc3bAh/j1lClauXetq3UTs4toTvGzZMnzzzTcYp9xcXIO5O3dW/VDtRHuVn60V3bCy2bWyPKPveTdOVXfyXnfQ6o7Yr0JOJPJv1rJRN/fXU6K0UdEROisr0nIQCyZDMBIX59u5OXbxtQjzI07s22eEqFVgnbThiROBZ54RWybPILSo6JxeOVb8CR+v7Dm9RQu0+OorLFu2DEOGDPG6Od5CET5XcEURSJKEW2+9FR07dkRycjJ/AeoHXe4wjRxoJycJi3Ka7c4NVLbFKVg68IICZ9ughZ8fZr0XupYdeyUClXZjZsdmdmpgg1bXKvDz7SU4EbllgkP7/p2LRcI3YRdtwyypo7TtgoeI2ITdw+1FKrCTtmkGaxlurw7ugTCsmZiIO5o0wW3XX4/B27YhRBuFEw7jioV/9NFH2L17Nzp06GB4nGZ0zwintw8wE4S5ufYmQxthFN0rKCh/sdgVe1Y6b/WCL6IFp589fSfm76lt2IttMMzs2CW0FtcStZm7KMgB9hE+XY3Nh01yFF9nYPrtgVV3aLw2bOf3mPkjXr0HtHwKkdsv+JhpTZpg765dWLx4sddN8RZapdMVHL8i4XAYt912Gzp06IAEEeF+o4dcdphZOi6RSwBbET5WxGBBAXs0TcS1Finu6OFjJ0h2bBPqmwkhxMV5msJOdmwO8358fhNpMk6vzCMbkB07vu46/nN4/AozWN5H8nvNrfeNj/flqx4fj7uzs3H7jTciHAUC1jIk+FzB8Svy7rvv4sCBAzjppJMMj+OO7rFgR6xYcaSV9YhI1wQqO2PRaZNaLxX19fJ6DqAesfYgu72Nhgv1JCT417wIBzC72aKcfNmwXDIu1qpEvQ5E4euoHCtub88AuGPHKSnO2bHSEK34FXamwTjxXokCkXR1o0bI3b8f7733ntdNIaIcR9+KkiTh3nvvRceOHZ2P7rEcI3c2IkbqjDq+/Pzy79PSrJVdXGzsIYhYeVNUxytSfEWDkHPjBaS+d06NPCvrMXBkFl29lKk4NwUeiUkfor4pIqPTRvUJqEc9n80t+yI79iF27TgpiW8EQFlfaan9BWuMRJ6oeXpm8xBZ6hE5r461LA/m8qXEx+Oe7Gzce9ttGDt2bGzO5aNFW1zB0SuybNky7N+/H23btjU8zpHonhFmERNRjojeCJpeZ+9EJE8JbbZuHb+OJJaWOm/LpaWWbdONgIuyDoocBgi3bpqgOoyKEREx86MdUySQATdvGksdemmd0epf+PXdzMGkrCzk7N+P5cuXe90UIopxtHeaOXMm2rZt6150jwUtB5hnxUK9Moy+lztZrYgfbwfMcy31Ol6WMvzgbUQrTr6geG3ZDB5bVuCG38OK3xZ+iSpELo+vjmSIbovye47y3bJlUatierG6JmudnmzALhKW6FxaWqQdOhHJ5n1WlH6G2Z57ZtE35fdOi7sYifJVi4/HdY0a4eEZM2JziwaK8LmCY6+y77//Hl9//TUuuOACw+OERvdEONJyOiYgfn+xgoJKR1lP6NnxTgsK3DVyJ9M5fbBqpGdbJgBstmz2omexZavOiI7w43GOeZ1SrbL9ur4DYRO74o+1fIOynQ46WsHMV48aWAcS3N6PzwpaKaBmwpFn8MLIlp2I6LH4GSwpm6L27bODH/wMAMjMxDWNG+PRdeuwadMmdO3a1esWEVGIY0/bo48+ijZt2iBFhEfmZsjeyU2qgfIVqkTixR54PChfDEadqx9HY3i2SEhP93dqiejIn8w/9ueEGPNLWpsI9Myb3ewZDiwq0i/Qz7ZphmwE8m8QKQA1nGWnbI5sueJIexUB0WPPTtgyUJ7WOXOmuLKBSF/Dbxuaq9sTQF+jDoBJNWvikfvvx9uxtoALRfhcwZFX0KFDh/Dee+9hzJgxhsfN/fZb7S+sOKQiIiJ6KDsPswUynFyIQO7Q7Yg8J9M5tTrZWHnojPYOEh0ptguPPTMg0pH1yim2Ik6NTNt3Zq9skFnj/O5MOxH9S0hw5GXoZ5GnTsO0L+RchNeenYre2cWpSLaZ4bGmdfphQFlPXKr9DV8aKh/X16+Pjh9+iD///BN169b1ujlElOHI62jevHlo1KgRMjIyrBWgfpBlB8QPjjPjHCZLmG227hfvIT8/KjpX14hVe2ZEz6z9kLqmbltMmL38I7VujNMraxqhlQbndOqnBfzSTWthxZ69mBMoFNH2zDKPz4rAVLePJ61TNCL8DVFpnaz+ht+ijhZok5KCU9LSMG/ePNxyyy1eN8c9QiHx9y4WVzs1QfjTIUkSnn/+ebRs2VJMgcrRZr2NwJ1c0EUPK/vj8W7GxFuH6AdG63o7kfMe8E6aCxZ7FoXT9gzgo9u/5GxUJX5J2dRaHdEvbQOAeJR53YRK/HyxbLZjFD7ysnpheHWLWLVHGeKdbQgP6guUlubejTQb0bJ74+69l+94p/b85cENf8PnGQzTatfGnKeegiRJXjfFPWjjdVcQ3qutXr0aubm5aNasmeFxuumcvGil0mlFTkSM/up1FHIHKWIY1KvOVlmvqAeFHjh+tAYx3I4EOhj189oh9rp+JYGOmmjhl4igi1E/HntyYsEVvfoDH5UDvFm4RYlf7BlgWmTIMlZ9DrsRNbnezExzYRcF0TtWzs3MxNR9+7BmzRr079/f6+YQUYTwJ2j27Nlo2bIl4uM9HMVzeoRID6ujY4WF5d6A0bkiPFVlGcrRPCfEHmEd9cCClj274Xjk5QkZgPAqCOTHIFTM4fVNcKher+yJ7NkGItR2NNmzWf8uag9XGT2fg2dxNDN8Hr1jITkuDhNr1sTs2bO9bop7+CDC9/nnn2PUqFHIyspCKBTC+++/H/G9JEm499570bBhQ1SrVg2DBg3Czz//LPAiOI9Q7/7YsWNYvHgxWrVqJaZAUQ+v3LE53bnJaNWlTucsLKz8E4GRcas7WrtOPInCqrj5osnPF3MvWdtsoa6kJPf9IXKGA4JXNyohwZbT73aTvdYWhAFKO9K7USJCrEZlyCmovDYt0u8wQqTPIRqfC8MJtWtj8fvv49ixY143JWY4duwYunTpgueff17z+8ceewzPPPMMXnjhBXz99deoXr06hg4diiI/Lgalg9BXyOLFi5Geno5atWoZHicsnRPgf3DVHQ9r2ppZPUZ74CjrcKujJWIHqzZtpy6dOtxcaEUWlX4j8Kl0biPfRNl4eOc686I0Uoa6lM0ysm8RaZThsPkzFDN78QUZVptmWQCGBT2bvvde4P77y//fCd9DnWrppO8RQ2mdnatVQ6OkJCxZsgTnn3++181xHh9syzB8+HAMHz5c8ztJkvD000/j7rvvxtlnnw0AeP3111G/fn28//77GD9+vO3muoHQK/zmm2+iSZMmCAVpdRw3RqAKCoxH1cy8VrPv/TySZkaMdOCu4pZNK8pPSnLeCZXrcKMuwkPcvNEGdcSCTTutrQOJEyM2Xtq00xE9s/cNS/aUzyNubhMKhXBRRgbefOUVr5sSePLz8yP+Tpw4wV3Grl27kJOTg0GDBlV8lpGRgVNOOQXr168X2VxHETY+np+fj6VLl+Lcc88VU6AXm60rOyyRURI/TLRmCYWIFF9OCzkrczP9sA2C2zhl0/+g57uY+TQsPhWJOgJApCGI3qxaVYfTJhdUm2aNXrIeV4Z4ttVn/bp/nl1ctGlDzLZF0Pvez/P+WSOBViOGdtaF4PBBxtesiYc/+wz5+flIj3bfxcEIX5MmTSI+nj59OmbMmMFVVE5ODgCgfv36EZ/Xr1+/4rsgIEzwLVmyBHXq1EFmZqbhca6nc1oVjsoOTcDm1LYxEnh+63CN8HKzVFEL+FjtfL0exXRY/InAjymahM/w4d57RpBNu0DQhaGRTZv9NlFpoWYELXtIC683a+fwQdoBaJOQgI8//jgwKYN+ZO/evRGCOTk52cPWeIuwV9H777+Phg0bmh+oNvggjFyYOcpOOR1yGoafBJ3Z4jCxgFanzbI1iJuY2WRBQWWbfbjpOgtuR0tSUvQ1u/Kx8OxxZa1Y6zivByOs4lPxFy0iL9B2rWXTIsURS1lW6lMbj5d2XVhofv3dnFtnVJfS/0hPd3eFdocYWa0aPnr33egXfA5G+NLT021HSBs0aAAAOHjwYITOOXjwILp27WqrbDcR8loqLS3FJ598goEDB/KfbPZQ+i0SITpKou7c3VjUxSoFBf4Sn35By7Ewsmsju/HC8XY58peS4p5DLEIU+sLpdRqtH8biQPuJhITKfEIPoj1u2rVdYtamtT732q7NInh27frJJ4Ebb2Q/Xu2DiBB0ZqmjrPWw+iBRIPYAYHj16hi3dCnC4TDiovZBhS8WbTGiefPmaNCgAVauXFkh8PLz8/H1119jypQpwupxGiGvJ3nSYt26dQ2Pm/vZZ/yFa0WN0tLEddJ2Rs9EbbhuJPJEGC2vF+JWpC6aOzAj9K6vqBVj7aBsm4ldL33sB+Zi/bxyZUJC7JoiF3oXKSHBV9E1AJEG56D487Ndl5YGd86gq2jZdWpqeWQuFuy6tNR/q/e45YP4fOXP06pVQ1FODn744Qd069bN6+ZENQUFBfjll18q/r1r1y5s2rQJtWrVQnZ2Nq6//no8+OCDaN26NZo3b4577rkHWVlZOOecc7xrNCdCBN+HH36Ixo0buzcCoUxHk9FylkU4xmZlhMORgk0930/vhSGf4+WQsJ8nXscirHYtApZnw8iuGfCbMxyU6Esg0bu4fnCY1YZo07klu44hgmLXVm06iH6Iz0WaSBJDIZxZrRqWLFkS3YLPBxG+b7/9FgMGDKj4943/RMUnTJiAefPm4dZbb8WxY8dw1VVXIS8vD3369MGnn36KFL+9EAwQ8pR/9NFHaNy4sYiirKM1IuTFYityB6pVtxPpmqxGHSvz66INr+xaLQiN7FqB3PfZjSzY7UPl+skZ9hi9G+BVRCElpbLP5IyQpKTYt2u7e/WRXfsEt+3aLIqenl5Zt5ldu7Efnx7kh3Azslo1vDR/Pu6++26vmxLV9O/fH5Ik6X4fCoVw//334355X8sAYvu1kZOTg59//hmnnHKKiPaIxc0NqdXInaoXI4HqDl3UyEmMjKr5Hr00ZzfQcRa8HOSitLUAonXTRDjLPOmlDOlxsWDXvt/InXXhEz+s1Kl3Id0c4NCy6yefBK6+2r02yPD6IjEUvWNlWPXqmLJ9O/Ly8kxXwQ8sPojwxQK2Bd+KFSvQsGFD07Cmpfl7eljdjkHtKHsdijUbpmU1WD8v9EK4gwe27cXjo/SnfO2kEvyob6gHTrKXbwT554vYPi0IMO/FJxqRK3WyDDA4NbjBgqhOmlWIBdEX8bnIbJKYiFbVqmHFihUYN26c180hAoztV8Ynn3xiuliLb1F3Tup0NbtzAJ3ergEw76h83JERDmJm2wGBRF0Mo3XzvY7gCMLIrv0acWNNR/Vr+32F32zb6ggCjy9CWOas5GQsXrw4egVfKCTefkIhseVFAbYEnyRJWL58OXr16iWqPd6idpLN3m5uLeesN2oW5FRNejm4i80FWNxC1BxAHsg5DRAOr77ZD2uwBv2Elwt4Y9uEDdza0FyuS4mfBzb8EMXzeVRONCOqV8dFH3wASZIQIiFDWMSW4NuxYwfy8vJQv359Ue3xF145yX7ccN1teCd3s14rpUgXMe/N6z2ctDBrU2Fh5DEeCkCvs6qJAKM2Hp85yWTbhGWs2LZTApXVH4lmEWZlsRmBPslpKSnI/eMP7Ny5E23btuVvi9+hOXyuYEvwrVq1CllZWUgwSQVwff6eE+WIFn/Ka+aHETMzeB+eIPwmuyuGiV4oxSvxKNi2jSIYsh8T9PlHdnDsPaQs2I8DEU4jG5ecSu+yACTbJtt2DLdt26n3N4sodEo4BtgnSQFwWmIiVq1aRYKPp0wiAluvpqVLl7LN32N50ERGGZx+Ici/Jxy23m6za+JXYw1Cp+kWrIIx1mxbRbRFOkStteQoRo1gUSRerC4sOkLhwubrZNseQLZtzbbnzQMmTjQ+xuj97tcIXoz4JAOTkrDsgw9wtRerrRJRgWXBJ0kS1qxZg759+4ppidFD60XKGcuG64B+dET9UlF3yn7sOAHn5wvGIn6zbVYsRv7MnGA/R0CMopN+brdwWH+sV/vp8aI0yoQEy05icXH5lmdBhGz7H0TbNs9WIE5gx7bJLwkMA5KS8H9r10bnPD6K8LmC5W5+27ZtKCwsdGeFTuXDrhZifnKYle1MSvJ+TomRwdM8QX8QRNtOTcWal3+O+NpPTTVCy+mlRTRsYLbcpF9RGiyDgxwE+9a7FVFh36yiijWSZnU7BRknbFtUFNDMtr32S/SIthU/WSOicXFMmTu9kpJQmJeHH3/8ER06dBDQQCLWsCz4PvvsM2RlZSE+Pt7wuLmLF1utoipaD4VWh2aWjubGHACnO9Vo3ROHqETv/tnNI7Nr//+0y69OsNJPi6nIhd9Q3gh1f+UnMajhIPvVtoHKyxoNtu3ZXnx2UYtBpX371bYB5/0SUfv1+TV91EOSQiGckpyMVatWRZ/gowifK1h+ZSxbtgz16tUT2RYxaKVayvj5LW4Xv47aEWIJh31h2354lKIichGr6N08r53l1FT4wLTJtv2Claibl7btdXqpFuSbCGNIfDyWvv8+rrnmGq+bQgQQS4IvHA5j7dq1GDhwoOj2OAvvPntOYXez9KIid0cv/D5S4vf2uYGWCLRq3z5cBS/aFscgdNC60THgMHpt31b33XarvKhA7ybz2LddQffhh8Do0dbPN8Nt3yTGGJCcjMfWrUM4HEZcNF1nivC5gqUuefPmzSguLkadOnVEt8ddtDralBT2BVusfs9DDDg7ruFDIeMoevbtc1JTzZ1FciYDhh1HVWmzKSnl5QQ4XT0Aj6AuxcUUfRSOetEVwL/2rUy19INv4vfUT8Hz+LonJqKkuBhbtmxBly5dBDSQiCUsuU1ffPEFsrKyTEcYhM7fc4uiosgHz823s9fpTET046V9a+CH1FAigGgZjg+dZLJvogKeQQ+v7NtIoJB/4jmJoRB6pqTgiy++iC7BRxE+V7Ak+L788ktkZmYKbooJXkVn1KNYIh1kqx0oGTIhCiftWwOW6B1BWEJ2kmWn2gMByGLfotIdKW0yCjEShW7bNwk8X3JGKIQvv/wS06ZN87op4iDB5wqWXhfr16/HSSedJLot9vFi9U2e/Ba5A/WLIfqlHUaITBvxcy6VX9JN7di3BlYiHOTEEkJwIUpCETwCgDeLpYi2b1H+iag0S7+nawKe+CenJCXhzVWrxNVLxAzcrlVubi5+//139OvXz/zgoiJ/O9kiUI+CKR1krREyv3dgdvBDTr8RTrQvlu1bg7Q0/5i434Uj+3ViPJBxHkhMk5oaeY0KCrhOd8u+oyF655l9i9yLL2jIIlC+Tkb2HWsRvCjxT3qFw9iVk4MjR46gZs2aDjfKJSjC5wrcr5RvvvkGtWvXRgqro2tmxMoO3A/DpXYdJr93Kjzw/JZYfbhYrpFsU3bt2w/OvMpJSEvzqB0ewOqAe/oosFTOoySizSFWozRgDeeY7Lsqntk3j0Bj/TGxZN9ApY1Hi9iLQR+lblwcspOTsWHDBgwdOtTr5hABglvwbdq0CbVr1zY9bu7ChfytYUlHiPaIiltES4cfJKLIvqPFEU5JiRo/wBlYHGc/rdpnh3+MOkpMGwDZtyks9p2QUDnY5gcbtxOZTEsDPvsM6NNHbJucgHwUXbrGxeGHH36IHsEXConvqEIhseVFAdyCb+PGjUhPT3eiLWyYdbi0ZnQ51FkGE7JvYQREO0cPZhe8tNQfDnOUkJIS/LTPwGFk47IIC7qNuzV3zm0fJQhzAhnpDuC7777zuhlEwLAU4WvevLkTbRGDXicSjY4yibrYw+ieR6ON60BiLqCY3TjOOXXRTKzYuIQQQpC8boY4jG5cOOzL7UMchfwU4XSOj8db69Z53Qxx0Bw+V+ASfMXFxfjtt9/QvXt3p9rjHEF1lNXtJiMOFm7Ou/PBYIdo8/TDtF7CRYxueJQ6yk7beBQFNoJPXFx02nisLVDnMZ3j4/Hr/v0oLi5Gkp/9V8JXcAm+HTt2ICEhATVq1HCqPd6g7KxkB93th4hGwQinUNuWVzZugNIHojQ1QhP1PmQyvE6yB6uZqn18snFCE1E27iTkq3hOs7g4JIZC2LlzJzp27Oh1c+xDET5X4Hrt7Ny5E3Xq1EFI1GRIP6w6qIcT0RLZAKnDJLxC+cxp2aHDItBP2zYQUYJaTbEsSe8gFJUuJxq2lvANXtg4+Sm+JS4UQovERBJ8ZmUSEXB1xz///DPSGJbns7RCpx9gEaBGTrL6/Ghf8pmIPhhE4E+f/2laTLSs4kkEGD0jFOQkk40TEXixr5+RjfMMqJOvEjjahEL4+eefvW4GESC4BN+PP/6I6tWrO9WW4EIjYUQ0Y2LfSp/DbFCNBt0Iz0lLq+oMm4hAHhsP6pw51ogcRe4CAIuNk8gLNO0lCT/++KPXzRADRfhcgavb/umnn5CRkeFUW4igQg9WTEGRDSLqUBg1mTcRlSg77k2bgGhIBeQlqKMxGrSJj8eyjRu9bgYRILgE3++//47evXs71RYi6MRSpNNHC54QzkMRjdihCfZiL5p43QzCDbxIwxSBBwsPRRVR4Ku0CIexd9cur5shBorwuQKzG1NaWoq//vqLaQ6f7YeJvCv3CeJLz0vIxmMK2S80u22evmNYK2e1PeoTYhIW8/DMzlkrTkpiE0Rk48GE7hsah0I4dPw4ysrKEB8f73VzCIHk5eVh0aJFWLt2LX7//XcUFhaibt266NatG4YOHYrTTjvNUrnMXufBgwchSRJS3ViCjPdhJue5KmaChEY/vIVs3BPsbGYdc7fAbhS7qEhMOwgu7Nh4zL0WEhLs/WiycfuwDJ7GnGGa0zAUQpkk4eDBg8jKyvK6OfagCB8A4I8//sC9996L//73v8jKykKvXr3QtWtXVKtWDbm5uVi1ahUef/xxNG3aFNOnT8cFF1zAVT6zC7Nv3z6kpaUhzo8XkTXaEg1peFGQikBYoLSUbcQ6GmycEbOxJz92VTGFWnmY2a+f9hrzEUZ2TjbuMbw2Dni2XYjrkK/iKEmhEGonJGDfvn3BF3wEAKBbt26YMGECNm7ciPbt22sec/z4cbz//vt4+umnsXfvXtx8883M5TMLvv379wd/w3WWDsjLYXxKUyDs4ncbZ4AliYAc3SgkNZXNYc7PN/4+APObyMYtEoB7awrLzQ+H/S8MyV/xnKy4OOzfv9/rZtiHInwAyndCqF27tuEx1apVw4UXXogLL7wQf/31F1f5XBG+atWqmR43d/58rgb4DrNOzKqzTJ0j4RecsnEGaIVPwjYsRmQmCh2G7Jywjdd2Tj6L72mMct888JDgAwBTsWf3eGbPbu/evUhOTuYqPCqhTpCIdmzYeHq6wHYQhFXMDDEvz3LR4TCQmWn5dCLWERmlNLLzcNhYEJIvE3iahsPYu3ev180gHOA///kP6tSpg5EjRwIAbr31Vrz44oto37493nrrLTRt2pS7TGbB9/vvv9Om69FCAEc+CP9Aoo4IPCZGHBQTj6JtxQgnoM46qmkcF4fNv//udTPsEwqJ78hCIbHluczMmTMxZ84cAMD69evx/PPP46mnnsLixYtxww034L333uMuk1nw7dmzhwQfQXhF0OetEARBEGxEw1xFwnEahUL4ePt2r5tBOMDevXvRqlUrAMD777+PsWPH4qqrrsLpp5+O/v37WyqTWVLn5OS4syUDQRAEQRAEQRC6NAqFcODgQa+bYR95Dp/ovwCTlpZWsSjLsmXLMHjwYABASkoKjh8/bqlM5gjf0aNHkWJngx+CIAiCIAgVEkIIQfK6GQQRKGqFQjjq99VcCUsMHjwYV1xxBbp164adO3dixIgRAIBt27ahWbNmlspkEnySJCE/Px9JMbTHF+Egfpws7vOtCgiCIAif46dUTD+1Jcj40V/5h8y4OOQfPw5JkhAK8pw1WqWzCs8//zzuvvtu7N27F++++27FipwbN27EhRdeaKlMJi+3oKAA4XCYbZVOJx8Ocsqto+z46SVQFT916mTngSU+TkJZOIT4OA+iFawvuLg4f9k7EVh8a+f0jgs+5LOYUrOsDKXhMI4dO4Y02gsmKnj11VcxevRo1KlTB88991yV7++77z7LZTN5lnl5eQiFQt5H+EQ7KX4eAaAOLnaJJTsXTLUU79PCPHGCefF6UKGoyNv6A44f7NzX+GUOj5/t/I8/gKwsceWRz+I6Gf/8Ny8vL9iCjyJ8Fbz55puYOnUqTj75ZJx99tk4++yz0a5dOyFlM731jxw5gmrVqgU7ZKyF3Q7KyKCo8yP8gpN2bpMaaeS4xiSi54P7fB4L2XmMEiQ7V78nKCXU98SHQqgRH48jR46gcePGXjfHOiT4Kvjss89w5MgRLFmyBB9++CEeeugh1K9fH6NHj8bZZ5+NPn36IM7ib2MWfLRgiwbUGRKxgIGdZ6STI0v4ALuj20YbVIPsnPAJou3cyIch/yYQpMfF4ciRI143gxBIzZo1cfHFF+Piiy9GcXExPvvsM3z44Ye46KKLcPz4cYwYMQKjR4/G8OHDubbLY07pJMFHEARAzi8Rhag2qM6gFSOJaIQ2Yo86MkMh5OXled0Me1CET5ekpCQMGzYMw4YNw+zZs/Htt9/iww8/xAMPPICffvoJ99xzD3NZzBE+pgVbCIIgCIIgCIJwnMxQiCJ8MUSPHj3Qo0cP3H///SgpKeE6l1nwJSYmWmocQRAEQRAEQRBiqSlJwRd8FOGrgiRJWLhwIVatWoVDhw4hrEixDoVCePfdd7l1GZPgO378OOLj4/laSxAEQRAEQRCEI1RHuY9ORBfXX3895s6diwEDBqB+/fpCFs1kEnwlJSXRt0InQRAEQRAEQQSUREniTu3zHT6J8D3//POYNWsWcnJy0KVLFzz77LPo1auX2HYx8sYbb+C9997DiBEjhJXJdEVYjWnu66/bagxBEARBEARBEOYkRYPg8wH/+9//cOONN2L69On47rvv0KVLFwwdOhSHDh3ypD0ZGRlo0aKF0DKZBF9xcbHlfR8IgiAIgiAIghBLMsp99EAjR/hE/3Hw5JNP4sorr8SkSZPQvn17vPDCC0hNTcWrr77q0I82ZsaMGbjvvvuEpusypXSWlZUJq5AgCIIgCIIgCHskSRJKS0u9boZvyVftPZmcnFxl14Hi4mJs3LgRd9xxR8VncXFxGDRoENavX+9KO9Wcf/75eOutt1CvXj00a9asygIt3333HXeZTIKPFmwhCKICo02qRWQCsJQh6hhWWMviqZPxWAls86dZ90kWfRwrLOWJOsZuGRk4anwA2bnwMsnO+Y+xW0aG/SoIjykOhVAjgcmV9y0SQszPP0+ZANCkSZOIz6dPn44ZM2ZEfHb48GGUlZWhfv36EZ/Xr18f27dvF9ouViZMmICNGzfi4osvdnfRlqSkpIglQQmCIAiCIAiC8I4TAGonJXndDFuEw84NvOzduxfp6ekVnwdlT/ElS5Zg6dKl6NOnj7AymYbeWPd6mHzppbYaQxAEQRAEAr+PFIDo+A0E4WOKQyHaJ9uA9PT0iD8twVenTh3Ex8fj4MGDEZ8fPHgQDRo0cKupETRp0iRCqIqAWfBJkiS0YoIgCIIgCIIgrFESBYJPjvCJ/mMlKSkJ3bt3x8qVKxVtCmPlypXo3bu3A7/YnCeeeAK33nordu/eLaxMppTOatWq0cItBEEQBEEQBOETjqHcRyfsceONN2LChAno0aMHevXqhaeffhrHjh3DpEmTPGnPxRdfjMLCQrRs2RKpqalVRH1ubi53mUyCr2bNmrTPB0EQBEEQBEH4hCOhEGrWrOl1M2zh5Bw+Vi644AL8+eefuPfee5GTk4OuXbvi008/rbKQi1s8/fTTwstkFnwnTpwQXjlBEARBEARBEPzkSVLgBZ9fuOaaa3DNNdd43QwA5at0ioZJ8GVmZqKoqEh45YHGbDI6rWpKRAu08AJBEET0oe7byW8JHHmShMzMTK+bYQs/RPj8wLFjx1C9enXHjmfy5GrWrBl9gi8uzt6f0+WTk02IwAk7zM+v/COIKCHCrJX/cMLOqX8nPMLQrMlnCRz54TBF+KKEVq1a4ZFHHsGBAwd0j5EkCcuXL8fw4cPxzDPPcJXPnNJ5/PhxSJIkZPM/S+htLFlaGr0djejfFcQhj1hDz879eu/UXoOZzaq/T0sT2x4iZikoqPx/s8eF+3EiOyd8AI+Nsx4jFPJZXKVMkvB3WVngBR9F+MpZvXo17rzzTsyYMQNdunRBjx49kJWVhZSUFBw5cgQ//vgj1q9fj4SEBNxxxx2YPHkyV/nMKZ2SJKG4uNh800I9h9UpEhKCeWe9QO6MvRbIpaXe1q+H27ZLRHowMiz3Qc+GU1PttYdwhcJC7c9ZunK/dh+GqO3cjo0DZOcBwc923qQdeyqYZ5DPok9CAo5KEnDiBKV06pQZNNq2bYt3330Xe/bswYIFC7B27VqsW7cOx48fR506ddCtWze89NJLGD58OOLj47nLZ/Jw09LSEBcXhxMnTgRml3rCx5CwIpxC6WHZdaqVsNqs8jivnRQNwmF234X1ONYXqx99psBCdm4I2TkhFJ/6LEckCQlxcVzzuAj/k52djZtuugk33XST0HKZrDgUCiE9PR3FxcVCKycIgvCUcNg5h9XMQxRcbxBHNIkowMjwHHi2/GznfhJ7fr5OhBjyJAnp1ap5N9VKEBThcwfm3jgjIyP6Fm4hCIIgCMJTJATbYSUIL8iVJGTQ/GCCEeY4dYMGDVCol5BOEARBEARBEIQr7JckNPRoY3CRUITPHZgjfNnZ2Th27JiTbSEIQg8fzpMhCIIgxOOn1FDCv+yXJDRu187rZhABgTnC17RpU2zbts3JtvgfuxN3/dKLOzlviQg+Pp2gThCECnpWCauY2Y5f/BVCl33hMJo2bep1M2wjSeIjcpIktjy32Lp1Kzp27OhI2cxviyZNmuDEiROONMI3OP3ypA6W8AN27VxrKwWZ9HR7ZROESxiZMWDwZVwc7atHWMbNVDNjGzeB/BXf83tcHIY3aeJ1MwiBdO7cGT179sQVV1yB8ePHo0aNGsLKZg7zNG7cGMePHzc9bvK//mWrQY6RlGT+5zUJCeZ/BGGEmY07bUMFBcZ/BOESjpoi2TjhAzztbslf8Zx9KPfNg448h0/0XxBZs2YNOnTogJtuugkNGzbEhAkTsHbtWiFlMz+RjRo1wt9//y2kUqHEWqfCKkxpC43oIlrsnGXhJ4oSEgaYmZDngYeCAvPnlWzcEp7fW5dg6SYDcS3IX3GUP8JhNGrUyOtm2IYWbankjDPOwBlnnIFnn30W77zzDubNm4d+/fqhVatWuPzyyzFhwgQ0aNDAUtnMXmTjxo1RUFCAcDiMOCfnf0WLY+s1vBHLQLw9ogiyc31YvJ2EBCAlxfm2EK4SMwtBk40HCpHOY8zYOI+faCXDKsZ9lmJJwl+lpVER4SOqUr16dUyaNAmTJk3CL7/8gtdeew3PP/887rnnHgwbNgwffvghd5nMXmf9+vURCoVQWFiINLP5C6wPb1AleDRiR4DIHXssjdKRjXuP2b6gapsm59lV1Lcnxv0za/DaOEB27jLKW0Q27iJWfZYo8VcOSBLiQyHUp20ZdMuMFlq1aoU777wTTZs2xR133IElS5ZYKof5iUlISEDt2rVRUFBgLviI2MQP8yAJQg8955nHblkWMoiS6C2r8xpwvyn60LJzkTYeAIqK2H5GaSmbnZONRyEB91f2lZSgXrVqiI+P97ophIN8/vnnePXVV/Huu+8iLi4O559/Pi6//HJLZXH17E2bNsXff/9tOX+UIAgikMhCjsU7ZE1lYhyCDIPthc46oklRCGNOwk9eN8FbosDGAbafEdRnIajtJsTxWziMJs2be90MIVCEL5I//vgD8+bNw7x58/DLL7/gtNNOwzPPPIPzzz8f1atXt1wul+A76aSTaC8+NcpRIi0Li4Wemfb1i24CPhJKEARBVHJSn9pVQ6Cx4KtEkZ+ys6wM7bp397oZhGCGDx+OFStWoE6dOrj00ktx2WWXoW3btkLK5hJ87du3x4YNG4RUHEisOL7KTjVKcseJKIbFxpXrffOmd0dRyiMRPUQuYa9az57XxoNq36ztpgGgQGK6TQP5KoHix1AIvdq397oZQqAIXyWJiYlYuHAhzjrrLOHpulxvptatW6OAYXOXyePGYe7ChZYb5RlxceVWYvWFJp9vhl751LkSbmHHaRsxAvj44/L/V/cHstOQmmq9fIJwkMJCzmAG2TjBgJ8CZPn5ggoiX8W37JQkXNS6tdfNIARjZfVNVrgEX5s2bXD48GFIkoRQKGS/dlaB5CTqDs3J9pilPlLnSjiBmzYuo7X2ODnIhMs4ugQ+2bgxQY10BgxPtnnQ8lXIT3GNsCTht5IStGnTxuumCIEifO7A1SO3bdsWpaWl+Pvvv5EepI1jg56Com4/pVsQaoJg47JnonYEyUkmbKJ0es0iLY5GYgoLtYUO2TjBiJ598ti4J+j5KQD5KoLZHQ6jRJJI8JmUSUTCJfiSkpLQokUL5Obm+lPwBcHpFYnR76UO1h+IjmL73catzNFTD1HLv5H2EyNUFBUFtGvz0sb93mfEEGZCLbD2rUadyUQRQaFsLitDy0aNkETPNsEBd85F165dsWvXLjRr1syB5phg9nIkSV+JWUdAna0/MbLxWLNvo02naS/QqMRsn/Gog2wcZYxbMkQDMWffRrCIFfJTNNlcVoYup53mdTOEQRE+d+AWfN27d8cPP/wgviVmKS9098SSlGS+RDG9ncRiZONk33yYOQI08ulbyIdjhGw8kATevv20dQFLBJzVT/HT77LJRgCnn3yy180gAoalCN9ff/1letzkceMwd/FiS40KLElJ5Z2P/CIOes8vd7asHWWsCcRYSzkMkoNZXGwuooP0ewKCUZfny3lHQYZs3BUKCthe6W7Zt916eo5uGD0+ClD+HmbxUaLIP9kUDmNqly5eN0MYkiR+zFuSxJYXDXALvp49e+Kvv/5CUVERUqLR4eWZc6X1Mk1JqTxf/X00dK5GiLYH0R100O3V7VVtjZzFwsLgL0TB+zzG2KqDrJcnmrq18ql2/8y3C7p9A3w3x+f27YSgijUbr7KiZzT4KKwD0k69/0X5KampTO/3P8vKsOfECfTq1UtMvUTMwN3D16pVC02bNsWhQ4eQnZ3tRJv8i9xhWHW65c6VVtlkg7WDZu3wKW3SGF77VnsPfnOQRW/yzupxeuQ4s942irRVYrikvZf27UVkLkrsm9X/jtbXr/I2cm/ZoJ7qEa0XSSRmfopg/2RDSQmaN2iAmjVrspUbAGgOnztY6rl79+6NnTt3+k/wiY6AOB0R8nrlKrN9AQn38GJPStH2LXsXdlcgLC6mVDTCEWytgijKvomowy+DKMJX+bQSARTlU5BvosnXxcU4dehQr5tBBBBLgu/000/Hhg0bRLfFGDccYrsRPBGoR9i0hitJqBFWcNu+1bZLDjLhMo5O27Fq36IGM3yegknwwyvWXJ+WxuKfEI6yVpIw7vTTvW6GUCjC5w6WVEOfPn3wxx9/IGxyRSefdZalRrlCSkrVPz8SlHYS/sKPdlNUVPWPIAThuXl53gDCz9iNvLliXrwDyX58z0QxJZKEb4qK0KdPH6+bIhRZ8In+IyKxNETYuXNnJCUl4fDhw6hXr57oNjmDcv6FmSWYRRPtfm8XrVWpyLkwx4u0STdQzy0K0m+0GiWhtM9AISrlLT+/0kQC0eVFW5Q76O0PEL60bxZBqGUjTv0Yv2c6CZ6/t7GkBEnJyejUqZONRhGxiiXBFxcXhzPOOAN//PGHPwWf3xaPUGOWkmklZVPvRSyio/V7Cqnf2ycSN2zbS2GsZa8k7GIeZXTEl44wK361b9Ft8MNvCgg8tm134KTf+Ib2CrCK2j8J9EPsHatOnMDpvXsjLsr8HUrpdAfLkwCGDBmCp556SmRb+NFzfr2+06mplT2zlx1bXJz+NeJevotwFb/aNuD+gIpeLhQ5lVFHTC4KqPWjybZ9gUh7dMO2TevwQ3ic/BLLLCsrw9hzzvG6GURAsSz4Bg4ciFtuuQVlZWWIj4/XPW7yWWfZ24DdiXQ1JyIYeh2YcmRLZCdrN6qlbK+6HOp03YMn1VgUVuzfj1FzEoKBxdfCrqjI+9TFGLHtMuj7DkHG1/YNOOeX2I08ye8ZrXJi3C8pliR8VVSE5wYM8LopwqEInztYFnwdOnRAamoq/vzzTzRo0MBeK1JTg7mRM297lZ2sG28Eq6JQ63cpy4nxjpeLoNm0EqO2X3EF8Nxzlf/22kFWYvRs0cqGriInOvjdAa7i8yo/CLJtR4m9s9qPm3vwKdMrRZTnVNDNtFy3/RKrGPklfvRJBM/f+7q4GNWrVUP79u1tNIqIZSy/DUKhEPr164f9+/ebCz4Wp9dvjrFeFIQ1IpOQYJxwr/69fuyw9GC9V0H6TVZIS4uuYSQ70UalV2EWhRC9IToPWs+k3JYomxfhBuGwf/Yg44HLueaxbS/Rs+1YmuMsEFbb9qNGsiQeExIi+2W/v7+VNh0DPsmq4mL0PeMMhEIhr5siHIrwuYMtr2vo0KF47LHHRLVFHKJTNt0Qo1oCMOgvaaPrZvbbCgrEtkWLtDTn6xBNEGzbr9ERM8yuq/x90J9LBrxY1tppx1k2S9v1yAWRbQeSWLXtoVc35ytU+W6IBn8E8LdPYuKPfHbkCMaffbazbSCiGluCb8CAAfj3v/9tPo9v4EDM/ewzO1VVIsrhNSsnNdXZt4JZlCM11V/pCm6PEgdRjNnFrdUxnbZt5ZYJ0bYsPcDuPOvhwnNk1IRYGvl0feP1oKdQkm37loICD9dcUfojgHWfhMU+vBCWLHV66JMUhcNYf+IE5kbh/D2AInxuYevt1LZtW2RmZiInJweNGjUS1SZv8FtKqZIgp39GO37c20/dJj/ZtjI6EnTn2CoO2YvfzNALSks9XIBQudgL2XYQig0cRrbtamqpOvoHREcE0KesKypCzRo10KZNG6+b4ggk+NzB1lspFAph+PDh+OGHH4In+NLS7E8+8crZV6+waVcAejHHg+aVOIcI23YDdRu9cpL9sCojYQnRZj4US8UU5BfbJizj9VZxQejCAVRdWdONAekY8x2WHjuGQWedFZXz9wj3sP0WOuuss7B0qaCXpJNYCcfbFXRmC7eIQiuCI3e6JKyin2hJf1Uve+fnBTIITwiME6yGx7b9avesgyI0eMKNG1PWDRE5IEEZScL5pLgYtw0f7nUzHEOSxMdOJElsedGA7ad88ODB+PPPP1FQUIA0A8fT9Xl86enmxzglyJQdnrp8ZednNo/PjlhTtkGuw/O3CiEELwWem+mhtCF1zOP6CohuDTSofxhvnVHwHHi1B58fNlP3ZGVPrTRMVkTt+ZuQ4D8/xOcD4n+WlmJbYSEGDRrkdVOIgGNb8GVmZqJr167Yt28f2rVrJ6JN/PglwsGz/YQXo15a14mn86Voofto3TO304j17Fr2Wtx0PpWeUlwcpcpFEV7vZVZRf6zZtc/FI+s99ToFUw+v9U1xMTDq9g6RH9oRf1aRbdrIDyH/ogorCwvRrmlT1K9f3+umOAbN4XMHIW+Vc845B6+//ro7gk/uLPx0N61EPeRzEhLsdbh2RZh8PZVleP2GikX8Ztfp6ezRb6WzKsp5ZI20GO2rR/gWv6RmGopMJ+yatRyy60DilF2biVm1HXMNnqSm2vdD7Ao18kN0+ej4cYy4+GKvm0FEAULeICNHjsTMmTMRDocRJ3KExm7kTsSiKnplKNtm1MuzpI36IeddKRyNrjvl49vDL9FoFru2guxpeBl9Uz5vyv6IHGZPKC31j8Cz7EN6EfVTQ3btK/xk10JSRL2I+hmh9y7yQ9tcokyS8Mnx4/gwyvffowifOwh5U3Tt2hXVqlXDwYMH0bBhQ93jqszjS0/XPpDlTolaIZNnHp9bzrroDU/N5gryYHQNeL2paE0RtWPXLIheHdaqXd99N/Dgg/rfK58rPziles+5H9oWBfjF+dVCWNv8ZtOA/o+jxVMsU1BQeXuj3q617Nhv4k+JSB/E5/7HhqIiSAkJOPXUU71uChEFCHljxcXFYdiwYfjpp58MBR8AfWc4skD/yPO0NO83YA/KoivKjtioI83Pd74tThE0MaeH03atxitHmSU11Gio3i9OvQ/Qu0R+dYgdb5cfxZ8asmtTvLZr3ugcb7uqzN/jRfnOs+qDsNibCPGllRqqJkD+x+JjxzB06FAkRPnzGrQI30MPPYQlS5Zg06ZNSEpKQl5eXpVj9uzZgylTpmDVqlVIS0vDhAkT8PDDD3t6L4XVPGrUKKxevVpUcd7CG/Fwa/sFZbu8En8ionLKF4jVsqx02iyDDdGClk36JZ1UKbDsdH5u7J+nvIalpfr1+Xyk2Aytl6NfhZwRnrVZrlhkNoWTsIjVgNs0UNWuRS7swiLURNTnp9RRTR/ETTsRUVeA/I8P9+7Fneedx19XwAia4CsuLsZ5552H3r1745VXXqnyfVlZGUaOHIkGDRpg3bp1OHDgAC699FIkJiZi5syZzjXMBGFvppEjR2LChAnIy8tDZmam7nGTe/TA3G+/FVMpSzSENWJi5Az7KeIoo26v39IunCaI4s1tO/KLwDMiCFESFpT3lfUeq4+z4HyIqDbo+MYZlolGm9b6txYpKZ7YtV9X6LSK0oTMfptnv11+v8Sa7wG44n/8dPw4dpaUYOTIkY7XFc3kq8R5cnIykpOTbZV53333AQDmzZun+f2yZcvw448/YsWKFahfvz66du2KBx54ALfddhtmzJiBJI/mggsbmklPT8fQoUPx22+/iSnQjVGjtLTyPwOBKqSOzMzy1Ez5z6l6lH9qWLwikZ5gtHmVQcHIBtysw4qXIg9l+86Ddwl5mFP1p/NxzD5iSjPxvakEqrEG2ImkaxhuSTieya6jTcjp4aiZGPkeZgMSLAMWZr6H27D6jj6PYL+dm4uhAwciPYiD25wY9QV2/gCgSZMmyMjIqPh7+OGHHf8969evR6dOnSK20hg6dCjy8/Oxbds2x+vXQ+jw48UXX4zrrrsO3bp1QygUElm0GNzsjIzqUu/FZ5YGZCVNSF2/X+f/RevCLW7htU07lcJWWkorERIVKDMmna3DINVYRPqw36J/tLBLFdwSme7ZtAI39gFWp326NX8vipAkCfPz8/HQ5Zd73ZTAs3fv3gjRbDe6x0JOTk6VfRPlf+fk5Dhevx5Cn7KzzjoL+fn5yM3NNTxuco8e4io16yjkGy1iiwcjlJuKstbldNRPid9G4QhrpKeX/7l5H83qciN6EaRISayEJRzEzdutWYeVinnFk9aPZHGOfb5ROqGN1u0Wsp2CQT3nzuypfZAov8PMLxLpd8SQKNx8/Dj+iKF0TicjfOnp6RF/eoLv9ttvRygUMvzbvn27i1dFPEKHGKtXr46zzjoLP//8M2rXrm2/QCtznrTC35mZ5i9vuwuvpKUZn5+UZNy7212QhTdSptX5stZLUbmqODU/z8l0DqM2y/bB80y4Gb1QD4/7IVpCWMZtHc9cl5v2JUfLyaZ9j5lQKy0VM+5jVobt7SPkft6tDCC/ZB753H/5z19/YeTZZ6N69epeNyVmuOmmmzBx4kTDY1q0aMFUVoMGDbBhw4aIzw4ePFjxnVcIf6NMnToVo0ePRo8ePRAfHy+6+EhkZ9jLySyioizK5eO1xJ+I1DmzMuR6lccEaAnjqIDVpp1aGVaUPcsevFtOq9a1IIfZl3gZoLVct6iVZXnrVEL2bAsnA++BtGllpFhL+ImwN7My0tKqHmPH5/C5kGPhRDiMeUeO4L2pU71uimv4YZXOunXrom7dukLq7t27Nx566CEcOnQI9erVAwAsX74c6enpaN++vZA6rCD8DdK/f3/UqlULu3fvRsuWLXWP416t026kQ4SDLEdE9JxiJ5xwt0fg1Ghdd9YOmSKBxvhlMraTqaFezlmS6/ZrCpwb20r4hEA6xGYF8tqzXTvksecosCtWgeZFBnVU2bMS5bvA7MI69W7Xei/6dQ0CB1iUl4fM2rXRr18/r5tC6LBnzx7k5uZiz549KCsrw6ZNmwAArVq1QlpaGoYMGYL27dvjkksuwWOPPYacnBzcfffdmDZtmitzCPUQ7oGFQiFMmzYNc+bMMRR8umg97KK2XjDDTLClp9vrbc3SOo1Qj4RpdYBuCaz0dP16rIzORbMwtGLPonDangHg8ceBm29mO9ZvC1YEhESUoASJXjcjUFgx63OxyHolZM/MItPPtuymeORxBSzZs978PVa8HmxWojc4asXf8Lmv8fxff2HKXXf5c+FDh/BDhI+He++9F//5z38q/t2tWzcAwKpVq9C/f3/Ex8dj8eLFmDJlCnr37o3q1atjwoQJuP/++51rFAOOvKUmTpyIu+++G0ePHkVGRobxwX6JcujhZvuUaZ1meL0Ju55IU18v5THRmh7qh9RiVvzyvJWWVl4vvRcwz/NARD1mDnI47PHG62b2HFSiIFooEpYFLkUIR7PXumvi1KqvwTIIYnegxGgT9QD6GzuLivB1QQHeM5lLFm1Iknj3SZLElqdk3rx5unvwyTRt2hQff/yxc42wgCOCr169ehgzZgx+/PFH9O7dW/e4yT16YO7OnWIqZYny8aRc6jnGZmUYfZ+WVum1WBFpenOilB2y2duIZV6VU3OvjMSGHztr5f6MQRBzejgl8kSlgiqvrVfOcgylV0YTvnwsgyL8Ysjeg7JwrlB7NorQmQ2k6b3/vYj6WX2O9N57fvM1FH7G0z/9hDGjRwubS0YQShzLQ7n99ttx6qmnolu3bkix+2JxagVENXIH4eRiGHJap1MRutRUfy26YjVdk7Wz9hNu2SkLbtiyGVZElB/EX0BJSQmOY2sHvzxippAtEww4Yc/nPjOg8h9OiDTlYKjXPgZgb7N1LV/Dg+f1cHExXjt4EF9Nn+563V4TtJTOoOKYVXft2hWnnHIKfvzxR8PjJrdpI65Sq8JC/nMClv1nlMeI3pjHyd8n8oliLStWnmIWW1aPwlq51zyRXNF7/5lFo1nudSwoHAKAM06Ba4hquBt7tvoALxZscbMrKSoytmezrtFSW51anEvrveNGOmeU8dy+fTi1Vy906dLF66YQUYqjT9ydd96J8847D507d0aC3Ydb5MIsdl+aLGmdVqKayg5ZT/jZSbdUCwGjt4qbS+rHGiIjgU7PybNqy36isDBmHGW38ZPedsRJdhNRz5kXz2sULNjCglvz9xxDOa1ED7P3vtH38vsoIUFM5E9kpM1OFNBhjpeV4Zn9+/H2nDmu1+0HKMLnDo5a9pAhQ9CoUSPs2LHD8DihUT49eKIfdoQOSx1m+fNJSZXRFKdG5RISIq+Jk8IhGp48v6Rk8d4zp22ZIIjoHVAI+mAPfC7AHCAinVMLp30LGbf8C7+8m23w2h9/oEGjRhg8eLDXTSGiGEeflFAohPvvvx9bt25FqYi5RCwPtnyMUWfjxIaiIjs19QicunM2u5ZWr7WVDtqLtE4/I/rl49ZLU6tOVl54wbm2EIQfiALhQ/gDuwJUqIBV+xZObraufI+x1BND0b379+zB/Y8+GlNbMSiRI3yi/4hIHLfusWPHomHDhvjpp58Mj7Md5cvMrPwT4Rizdnx6zrETy8mLHJljEYWpqd4IDjOi+UkWbces+O0eEzFF1Edh/CYY/dYeC/hx/p6IcljSRi2j55ew+hWipnmI8iuiILo3d/9+1G7UCGPGjPG6KUSU4/gkrbi4ODz66KO45JJLcNJJJ4mby6dcJUoNy/YLPFs0aOHlJuxy/TJaufJubq3AsvpXNG+uboeg23FQUA8SkC06TjSPy3hGgO2Ydf6e38S/fMn91i4tTNM5zZDf71bn31ldrMWqX8GCj6N7x8rK8OCePXjtnXcQF6BnWTQ0h88dXFmVY9SoUWjevDm2bdtmuALR5DZtqu7Lp+UQu3UntZxp9UpURs4yi6hLT9fuXM02nVZ+byb+9BAlCtPS9MvJy+Mry8/C0M5iK17asRqtFGe7otEqZnuWObU/ntVrT/v1aeL1y9Xr+j3be88PAtDHzwOvSHPajszaY1a/6e/R8ycAtrUDlOXIeLHtQkKC9jtT6U/41U/g4Lm9e5HdogXOOussr5viKST43MEVwRcKhfDoo49i7NixaNeuHZKTk/UPNop48CA6OiI61U0ur7jY/qiaVrmAmNwQu6JQeT/VHTSvGFTiV2Eo/14/9jZWbVhv4IKlPDOBJH/vhz3LtO6ZH23MQ9SXyOudM0Q9ZudikZiCnBR+LMIqKUmcHftYyNnFih2bYdXOlXULeVZE+hPK8kT4E3YHmPX8CTu+hLosl8gtKcHDe/bgnY8+itm5e4S7uLbu/pAhQ9CrVy9s2rQJp5xyiu5xk+vVw9xDh4wLc2uD68xM4PBhY8eWN8pnVJZ6VI0nyqeF3zdh1xP3IjtykWRm+lPIGSFfY5H7Ozo9z88P4k8maPdbIH796X5tVwS8Nuy0uArERWOHVRiJGpAQPWjhyGbr886O/MAp4adXnqgpJFbKCZIv8U9b79+0CT169cKQIUO8bY8PoAifO7gm+EKhEJ555hl0794d7dq1Q0ZGhr0CWUSf1VQ1ZedRp444Z1lvcRej6InIN41WmoaotE6n5gwaRXy9FgNuYMWGRUXJ1RgJvfnzgX/9S3yd1GsT/xBYU/Bbw328hUQQ5slZxe4+kZavTXq6+clm6Z7Kd7vX6Z6AtXc/iyh0iZ1//40Xdu/Gt4sEZRYQBAOuWnrHjh1x6aWXYuPGjYbHTa5Xz6UWobIjU66OaLUMI6xGRVJS7K1kpScWlCtkmTkAbi/qweogeeFIebFUtBlqGxaN31fv9NMSe0TsEcWpj6LwYsN1R1e79BlVontqnOrDebZZEHUMKz4eEL5p61Zceskl6Nixo9dN8QW0LYM7uBbhk3nwwQfRokUL/PHHH8jKyrJXmN0on+wcHz5sXIbVFTWVHazR+azla6VUmKV1spCUFFmGk6kPfp17Jxo30o6V4s4JUS7KQXArBdsIWmwlprHV5cgDYlZt2McRNdt48Ey5vR2DFymfQtFajEXpQ/BE9/RQDzQ66UP4cdCVg9WHDmH1X3/h10cecb1uIrZx3drr16+P6dOn45tvvkHY4AXqWJRPK5JXp475ebwpD05GRETvmaYWm8prJF8nFkEhUnR4LRD8itVItNf2GxdX+RcL+NoDDB5WozWyyQmJ9nhpv24Lq4ALOb9hNZ1TNjnh10Zk/671blG/pyi6BwAoCYdx9Q8/4J777kM9NzPZfA5F+NzBk6fi+uuvR3p6OrZu3Wq/MJYHu04dcydZ5IaiWtiJwhlF/9LTy1/ORi9ou0JMLQCdmiNmhWhP68zMZLNfERgJPTv2q/Z2eB3nWMrNIoTgqDbz68CFTyPY0Z7O6YRQ5TEx03ROPdLTxUT3zBDpN7BcFB/vu/f0zz9DqlkTN9xwg+t1E4TrKZ0AkJSUhJdeegnDhg1DixYtkJaWpnkc04qdWjjlGBulXtpdDdHuRuzqtEzeydS8qaF6e+SwLN4SK2mdVrBqu3b20nNiJU8WZBugdEvCJrLputqtiKrMTdsXmV4a8GfWrVRNVvGpZ062xKvZO93uAiwsPoPSH9BL/WQRlgH3GfYWFmLG9u34ZMUKJCa6PwjiZ2iVTnfwRPABQL9+/XDuuefi22+/Rf/+/XWPYxJ9tWqJWbHT6RURjUSd1gqH8+ZV/j/vFg3qjlzEKppmZWilb0TjXnussMxd83KrB1EDI+PGlf9Xtm3eaKByOJt6aYIT2XSsdBWyyf4P5wIALkiysGoe2a5rRFvap5yuaec1t2jiBwAsRPrU/bTobRxYUPsMbu2n54Ffce3mzTjn3HPRt29f1+smCMBDwQcATz31FFq1aoU9e/YgOzub7SSv0wll0abXDiuROr3l7CdOLP+vUvhZgXUzdhELwKjRu055eeI6XS+EIe9CJF7brRJRtisLPTVWhR8QeR+9TNcl590UL8di7NatZ+b/KxYg/IBg227A5++xRMRE2a6Vdjv13Cya+EGk6LP6LmfdaJ03usdyjN67SaQI9aDjWnLgAFbl5mLnM8+4XncQkCTxXaYkiS0vGvBU8NWvXx9PPvkkbr31VjRo0ABJOh3I5Hr1MNfMERW1L5/ZMZmZ9lMv5fNZ9y1TCj87G7EDkR2qldE0lkghyzGZmfodr182SLWC+oXF0os5uaekjOi0TT2xp8SO8AP4HFjRaaF6thmDQtBPQXanhJ4aZuGnZ3NyQ1NT3bEZZaqm1kXyyG69mL+nxE6apAgRKpeh1w6zOnjTOS1H+7Sw6yuIxGjgWMZPHZWCoyUluHLTJjz+9NOoX7++183xJZTS6Q4hSfJWB0uShAEDBuDw4cM4/fTTdY8zFXwyLHfZzHFWf6/V2Zi1x+j74mL7m1TPn6/9uZlzrfe9suMUMZFbZE6+0XFyu53s7PVeNiL3CxRht+pjRNstAIwebd4GI/SupZlYY1ka36wMFkHIOseJpSxWAcpwHKvjLHJeEstxohxno2NYVtk0q8OOv3pB5lL9L1ntFtC3XbfsVqA9spZFdmuvDjvz986df57+l3b9BCeie3oE3E+4cu1a/FqnDlauXYtQKORc/QEkPz8fGRkZmDPnKKpVE7sy+PHj+ZgyJQNHjx5Fup/3EXYRTyN8ABAKhTBv3jy0b98ezZo1Q6NGjTSPm5yUxC767CJHU5xKw7viish/8/Tq8jWQIywLF1b93koUUP1bjdokKsonIhVT2W6/p3W6hRN2O2SI9XOVzqioqB/gz2tPCEHUoyzilfGfnKEAgAkNDIQfC1oR64AvfCICt/fVc1LsKe3WqtjTGpyw0l0uvWIBAGDoywbCjxf53SJiGVQ3t2GQ2+2yj7Bi/37M370bPy5dSmLPAIrwuYPngg8AmjVrhsceewzTp0/H2WefrbuCEZPo88tm7FrfX3qp9rGyQ2zWiWrVp0ytU4s/O/gpnSPoi7e4Ac9+iTyohZ7spbA6qnqRB7XwM0vJLCysWhav+GNJ+9Sqh3AU0StsanWTqanWfFSlUy5c+PkRgQLU63ROtxB1O41eszzT69XdVxXhZzW6p/xeeYxWw0WJuQBvw1BQUoJJX36Jx554Ak2bNnW1boLQwvOUTplwOIw+ffrg77//xmmnnaZ7nLDUTpa0TTPnmTU9Tk/o6aHlmfAMVS9cKKZT14NnKWVRKRs+7dQ9Teu0YrMAm92yRvSMHEQe4ZSUxJceZ9YWq+lzLPWwlkMpnablsG4qzRItYe0iRUV4JjRYSjZrANmseR28Y6lGr2UWExj68nn+8A1YBaEo38CDQZYrvvgCP9WogbVffYU4Pw/yeIic0vnss86kdF57LaV0KvFFhA8A4uLi8NZbb6Fjx47IyspCs2bNNI8TltrJkrZptlAGS5RPXnCFJ29FHfHj/b3jxlXWt2wZ37ksiF5KOci4mdaZmenM1iJK+vThG53VippZiZAVF1fWK2J0mFI/fYkTfk9pKV8XaRTt4+mmKyJ+zdawn2SEls2yLPoicv4eCwLLCkI6pxWbNapn9+7K/+e9lFqRPp7udukVC5CSAvR78SLtA+yKwcxMd7dY8KmQWrR7Nxbs2YMtP/1EYo/wDb4RfADQtGlTvPjii7jyyitRt25dVK9eXfM4y6mdViMiRuiJPlnoycg9O6/wkx1hnnwkZR3KSI1S/Fmd66eF3ibsrLCkbMZiWqebWzn06VP5/7x7NirTPK2mQyrPk59JJ9KC/DrvMopxSuTZQT2mZlV4lJYCr/zSDwBweSuV8LOTGkw26xlm9mrVVpRCzw7yq9mKecluyJqr/gtAJfxEbMnkx03WXfYb9h87hsu++AJzX3uNfbuxGIfm8LmDrwQfAFx44YVYvHgxvvjiCwwZMsTeRNc6dex7BrwRE7XQU8Mq/NQiknWenxF64s8qRsJA2dm7GQn0qzBkcdpY7NVuBE+NUugp4RV9aWnl/+Xdy9HIa1H+Tpa2sG7NoLYPejMIw4lHT9nl6Zm+1Tl6qalAbi7/eVrtkIUfoCH+tOAJ77hhsz6dvycy5VON+rKKiDgq7dBM5FnZTcbqOIJWPWuu+q9+tE+NXUGozAwS4Qv4MAIYliT8a80ajDz7bIwfP97VugnCDN/M4VPy999/o0OHDsjKykKXLl10j6sS5atVq+pBvEvZWz2muNhc7Gmh9YZhyU8SkZMks3q1/ncill82+55nE3YfdvIA+OfoadkqIMYWWcro1cv8GBmz+yeLPTVmtmPFczHLxRexxL3Lc52CPB9KxDFm3/Puucwq/NTdbEEB23k84y2Xd/5G/0s3bdFlu2exV7/ZoahjfvzRvAw1dqaCmnWzrF1Vv3mTjA9wersmnq0TfDqn/5EffsAL+/djy/btqFGjhqt1BxF5Dt9TTzkzh++GG2gOnxLfRfgAoEaNGli4cCH69u2LevXqoWHDhprHTU5Kwlw9Z1NGxGbrZtjZZkEd8WOdjKJ8A9jJSyotjYzyfPFF5Pe8ERu9Oow6evWcQBkrQ++Av6J8SmHnViTJyJ67duUvT+/+mT17RlswWBF7qan8UT8isFjtks2ifXpdrGzOesLPSnvmfNsTADClh4HwswPrgi4BjWKLnOMnAr32bN4c+W/erkkv0sfSTeq9onkjh99MfQ0A0HO2hvBzY29e5fw/JVb9AJd9gDUHDuD+H37A6rVrSexxQimd7uBbj6lXr1544okncMcdd2D06NH68/kKCtwRferv1SJPiZX0y5QU/tUHlPVZOU/r96pT/NQCUK8cJ5xvvSiYsiO3+jIQBY+gs7tlCM8xSrREHq+QV86rS0nhu99q4WdV7Om1SW4XC1ZyqLRwOS00ESWuLHMv2kfiddi1zNpKuqbWOaxdZFpaVdFnRewp65OFH8Ah/kQutGK2iJFP0zmNkH+SG5uoq1ELPDVWXonKrom3i1R251ZupbI+WfgB/4g/EXP77KD2A9SdlJYP4JbY+6dt+//+G+etWoXHn3oKvXiyZwjCRXwr+ABg6tSpWLduHdasWYOhQ4ciPj7e2wYlJPClbbIKP6U3YUUsyp6FUviy5ieZoRSAGzZYL0fUZu1q9EQh4J8on1eYRfOsbIJuxzEsLjaPCmrB4v3Iz1BBgbU6eFHv16dnaz5aLVRuit8eCxYxZaVbTE21PlVINiEr55sJy4qoX58t/IWLQMsAWOxUYKSQZc01dbO8hvf1Z+V1lpBgXV9ZGXM161oron4vT7ZXsZNbOGn5AC4aTnFZGcZ8+CGGjB6NKVOmuFZvNEERPnfw5Rw+JYWFhejZsycSEhJw6qmn6h5nGuUD7M2Puvrqqp/xDl9reStmbbKyGbsaLfHHO2StVc+mTZH/FrH3jtv784jEib32eI9p167y/3k8ADMvQ+v5srKoC+/5vEPdWser7UDUXCWX9z4rg/mAl8hIhojIid73yseAN3rHerzyEbEy/mXlfJ5EC/UjfG1/lQAkOzXFyeieXnILjyBj6eK0uka7616Z1cvbrcq3vtNzGsIvxt/701aswOfHjmHD99+jWrVqrtYddOQ5fLNmOTOH75ZbaA6fEl9H+AAgNTUVH374Ibp164batWujdevWmsc5ktqpJfKU8G61oM4zcmpoW416cooIsQdUjSBt3WpcjlNRPr/AkrLpRFqnUuQp4bmWetE+o2eKdfsEvTLMUjJFiD0g8nr7KWQQQxiZPG/KptnxWo+OVpom7/mAfhm8GfVadTy7ulPF/1cRf1q4KfYYYRF7foZlBgMPdqY/21nzSq9rtir0ZLZcM7fi/zs9N9ndd7UPxd4b27bhzR078P3mzST2bEARPncIhGfdsmVLLFiwAGeffTbS09NRv359zeOEiL5rrqn8f1Yhl5LCJ/pKS61NSpGxuiG7fG1KS8WlfCrp2DHy2m7fLr4OmVjeu69Zs/L/srxseQW07GnwpEUaCT/WctRliBJ7atRvlmi0D5cw6vLkS8z60rUr+ljGsMxEn9UyRIg9Nc+u7lRx3A1n/cxXgRO4vNm6W4u1fPpp5f87pV2UXTBPt6on+ni6RmXddsWeGln8paQArZ+epn2Qk6mcVo4RyPr9+zF5+XIs+vBDtGjRwtW6CcIKgRB8ADB06FA8+uijuOeeezBq1CikiZynoxR5SngieKzHym9xO5E7+Vw7C7U4Md9PjTrytH179Ef5WLCykbIs8pSwXieejczl1Acr90BZj9Xns7TUObEHVPVi1PeBBCAA/m5Jz5x5x8J4RR/vlg16kTqepAe5DFH795nx1OLIrBZfCEAN3I7u8aZzKsWdHXjXu0pLs/46U9Zldf893jmBPNpePvbn65+v+KxC/Lkp9lxmT34+Rr3/Ph6ZNQtDhw71ujmBR5LER+T8PVnNG3w/h0+JJEm48sorsWTJEgwfPhyJidqrgZlG+a6/vvL/RW4GZHS83bl6RmXxCDazdtgZvubxZuRj9XamDXBOv5C5fFlZ7O3m8Sb0jtXLcbfiqcjPn6hVBIzKET1szVNujM+NYu2yeLpOK/PzrGa729n7WVk/q+i00j0aIXchN52/V/sA1mdDkI2Ksk/W44zu+8KFlf/P2g35acqzuiyRC7LolWVF6LEc1+Txf+sfEMDoXkFxMU6dPx+9R47Ei6+8glAo5Frd0YY8h++RR44iJUXsPLuionzcfjvN4VMSKMEHACUlJRgwYAAOHjyIAQMG6D5sEaJPKfC04PFIeI/lHdLlWdFTC7s5S+qynBZ8euzeHciXAQB+wZeVpX0MT7utij7WjpC1fDuejpmDaneeH49H46bgYzzOb4KP5zgRos+oy+AVfXYWdDFqh574Ey32AONu5qbz98bEgIRS2OnhhOAD+KY789bhZDeqVZZTYk+PJo//O5Dv97Ak4Zz338eR2rXx2eef6wYdCDZkwTdzpjOC7847SfApCZzgA4C//voLJ598MmrXro2ePXvqHjf37rv5ChYt/OQ3spUhaCsreioRsZEU7zC2W17NH39E/ttnLwUA2u2uVy/y36LbzeOxpKdbWzNcD7veDm+kLiHB2+ieUXnKexYQwac2V5ErefKWqS6XtatgaYteWSyij6d7k7tL3m5XhNgzOu6Wy/6K/MDF6B5g3T7nzav6mZsJEFrIgo83e91ONyq6C+WdmimwOwMQ2ebaM2+K/NKH7/WbV6/Gu3/8gW83bULt2rVdrTsakQXfgw86I/juvpsEn5JACj4A2LlzJ3r27InOnTujffv2use5LvqM3sR2hJ8VwQZYX5nT7BwtAej2MLbZMYcOVf6/0y8Gs81htWBtkyjRp9XpWckVUp9j1+OxuxE7y28QHd1jLZNFFDKWZVXwWRVzokUfT9dqZV0ro7awdjd6ws9q98kzx9Bpscd63G3XHIv8wEHbnD276meiu0XRgk/ZjYroPgG+LlR09wmYX0snIoBWAtDVZ9wS+YGLgu+F77/HnV99ha83btRdLZ7ggwSfuwRW8AHAF198gcGDB6N///7Izs7WPY5b9AH8wo9nxqmV+Xp2tmVQbkpt5TwzrAxne+HduL1Or19En1lnZ3VySXq6vReulSgdYHyO1m9xQuyxlitwSLwE5ulDIsWc21E+rS7BrujzYpxM7zwj8cdTD3WJfMf5bYqzfJ6ddeesdp2A+XlWti3lOY6lDazlsRwTjzLzgwDgzjsj/jlZMcl3z549WL16NVasWIHTTz+drTzCFFnw3X+/M4Lv3ntJ8CkJ9FKIffr0wauvvorLLrsMI0aMQJ06dTSPm/zggwA4hR/r8nLhcHluB49AZF2hU+kFaG3LwIKyDJ6VOXk8EOXKjgD/0nmxDOvWETxbTJSWApmZfMfzpoPaRbZF3q0zzDwFs739RCFwmXq/wtoF8qyuqS7TrJvhXblTPicctrf4cFqatUVdjH6P/Niou0evxB5RFaW9sXRzVhYztrvAuNwF8tbNs3NNXJx3UT2e8kQxeepU3e8OHz6M1atX47XXXiOxRwQa/613y8mFF16Ie+65BytXrkSByRteFn7MpKTo9zzq/byMjtWDZedUvfNYek6jMtLS7L959OpKT4/88wt+mMfn5HGZmZV/POUC5fePxfNU308rO6aq7Y61DN4h7dJS56J7PiUIOjQlhd3cAL7bojQlq92bXAZv98X6e5Rdo5diz4/RPSfguS/yf0W/tuTXrdImeaPHWq99ljJY3QUlSUmVz4GZnXgl9oRG93QoKCjAihUrcO+992L8+PG2yiL0UdqayD8iksALPgC44447cN5552H58uUoMhmS5hZ9QGXPwmJJvMLPai+udy4vIt5EZvhVALqB016aWuRZLVdG796b3TvWHtbICxfdS4sc0HCSIKg0E5zWymbl65kOjwnolcHSbfF2mXJdZo+v8njWckUeF82Iei3ZGVcVIdiMBk+srGul1R1pPRs8ro6fxZ5edK+oqAjLly/HBRdcgNtvv52tYQThYwI9h09JWVkZzj33XHz33XcYMmQI03K53HP7eHOLePfuA+ylQ4qYvCLDm89kxeNhqY/HM/HjpBUZURNTlJ4hz5C5leH1hARrnpBeXVYEmFyWFUXBU19KCvs1Ej2phfE4ljl8gPhFWZzYRw+wlnKpLp/ncTaqj6ccOymZPHXJXaLoLpC3TFGInpvHO62Zpyuzs4CxlW7O7o4z6nKcWsBYhqf8IIq9kpISLFu2DCeffDIWLVqE+Hi2VWgJPuQ5fPfe68wcvvvvpzl8SqIiwgcA8fHxeOedd5CdnY01a9YgzPBG44728UbUeIbA5GE6O1E7+Vw7Yk+dz+TWg6Ic6mYZ8raKV3lFrBhF8OxcE14PLzPTfk6cjJ304XDYebGnrItyQSwhIrOXBXl+nqj6rJSjTMd0SuwB5Y9gejr7Y+9nsec26m7T6ddYaqq4WRJ2XICkJPNN4dVEm9hjRU/shcNhrF69Gk2bNsU777xDYo+IGgK9aIualJQUfPzxx+jduze+/PJL9OnTR3djdgCYqxZ8rEPZrIuuVDZMv3yzXAzeqGI4zLc4CwvKt6Xd7RgAdo9Dby6aldUUvIZlcRL11g4sZQLsIpalDWrvkrcO9bl2PSAr5/Oeo5fDpMTvAwUOol5oxSyjnScimJbG30VZOUd9rl3RI6djAuzdEW+dyuO1RJ+yXr+LPSeidjJOjQ2aoTWd2Wo3UVpqT5TqzQoxilQ6KfTc3shdiZ15e5Ik4csvv6zwJVOiIN0+CDgxzhoLA1u8RJXgA4DMzEysXLkSvXr1woYNG9CrVy+EQqGq4k4LI2GmBe8SckpviHfFApZ6jCaxsHhILE+ImfhzA6M3fG6ua83gRvYIeIUda7msxwJVj2eZRMTrzShX4tSqk/V8PyD/hihY2EWGR5w5+fJ0W/TJt9DK+VrXgUX42RF7emg9sn7u/uyi/r1OjsHorYDpxGIuMla6SZZFi+3uVMNSj17ZenYs/0avxJ5WdE+SJGzYsAH5+fnYsGEDMjIy2ColbBMkwbd792488MAD+Oyzz5CTk4OsrCxcfPHFuOuuu5CkCK9v3rwZ06ZNwzfffIO6devi2muvxa233upMoxiJOsEHAFlZWVizZg1OO+00bNy4ERs//ZSvAB5PyGq0j9fbMKvHzLpFR/2AyrdfOOyfqBurmDp8WHzdOtuCuAKvIJOP5xkeZ/VI9IQaj0djVeyJiO4FHN4oGwt2tl5wCl7Rp+4i7Z6vRk/4OSH29NDr/nJzgzPi7VXETg8ekcfaDZutXWVWBo8AU0b7nBR6AHv5sl9sZJO8otDuvL2NGzfiwIEDWLduHbKystgqJWKO7du3IxwOY+7cuWjVqhW2bt2KK6+8EseOHcPjjz8OoHxu4pAhQzBo0CC88MIL2LJlCy677DJkZmbiqquu8qztUbNoixbbt2/H6aefjpYtW6Jbt25sUT41Tq1YIGNVfCnrsvomV9ZtxxvQOtft4W6iHBZvw+rCLyz18AgukYu7AJXeCc9v8nJTds5jWRdtAbxfkIW3bMB6V2h2Hkv3IWpBFyVWom1ed3VBGgfj7bp4jufZxpSnLrvdo9UEA6vzZVlxIoWT59hElDAdN/maazQ///777/Hrr7/iyy+/RLt27VibR9hEXrTl9tudWbTlkUfcWbRl1qxZmDNnDn777TcAwJw5c3DXXXchJyenIup3++234/3338f27dsdbYsRURnhk2nXrh1Wr16NPn36ICEhAZPvvptf9DkZ7QP4Ui616rK7u7CM1fRMPQ9FPUzrlwhgtKM3PGy2bQOvd6M+z+oiKeq67Yo9ZbnqstVEYXSPF97uzcqYlhHKW2W1fL1IHY94ElGG+jzlI8fS/Xkt9gBvkxS8RKt7tDMnT4md9arsLFJstX4nV/j0UuzpsXnzZuzcuRNr164lsReF5Kt82+TkZCQnJwut4+jRo6ilSK9Yv349+vbtG5HiOXToUDz66KM4cuQIatasKbR+VqJ+JYJOnTrhs88+w5YtW7Bt2zZM5t2KARCzt54ZVpf40tpHjxd5cQ3Rm7ErUS6ZJnoOGxGJerUHlhwpO56tXZuRE/hFiD29sv3gTdvErmPjNnpdptEtERHBsHq7ld2fHZPRm+cncrtMwj5OLggtatVOOyt2Wqk/msWeVnRv27Zt2Lp1Kz777DN06tSJuSxCLJIU+V4Q8SfnLjZp0gQZGRkVfw8//LDQtv/yyy949tlnMXny5IrPcnJyUL9+/Yjj5H/n5OQIrZ+HqI7wyXTv3h3Lli3DkCFDEA6HK0Sf8Gif+q1tZTKL1Yif1XONFnqx2g6WOikC6Ax2xDTvkLaoNAm3tv5Q2npaGp+XHUWLtdjB6jpVvJfaaqQPsL+WlJ1yeBdbycsjsecWbswNVA88WI0Q2hGKVs6VBRZrm3mTI5zYdsGu2NuyZQu2bNmC5cuX4+STT2avmAgUe/fujUjp1Ivu3X777Xj00UcNy/rpp58iosD79+/HsGH/396dR1dRHX4A/yZAEiMSgoABJBAoBApCMLhEZFE2C9JFkeoP5cfhsCO1v+JhEauxR624USkKAbUuWFoKlCpIy6KgQESgBAQJIEYCAQIISVgkIcn7/YETJi9vmeXeOzMv38856Snmzcx9LzP33e/cO/fegwceeABjxowRU2CJakXgA4CMjAxs2LABd999N8rLy9GtWzfrQzyBq0Eu3Le12Zk/NaqDn5V9iWyphJt3nIIT2WNqZIinyIBmd1921ujTv8cIa3WbudckY5IVux+tneGjDRqImUBYOzWN7Mvq6aOv9iJ5hk0niAh4RgKQ3QlYjO5L1rb+ISvciHine/UA+2Fv586d2L9/PzZs2ID09HTjByYpZM7S2aBBA0PP8E2ZMgUjR44M+Zo2bdpU/f9jx47hrrvuwh133IEFCxZUe11SUhIKCwur/Tft30lJSQZKL0etCXzAlZ6+TZs2oU+fPqioqEB6erq10AdcqZ3M3uoGnAl+wbY3+5BLqH3JUNvmHTeqcWP5ASVQS0V0T5wTYS+YQC0bq59xhD8bGCiMhWrUWl1CwQ2hT9sXEHx/oi5F//s2rOqMc2JmT5FPP7gh6AXiH/68HvZ8Ph927NiBw4cPY9OmTRzGSVWaNGmCJk2aGHptQUEB7rrrLqSnp+Mvf/kLov2+ADMyMjBz5kxcvnwZ9epdmWxt7dq1SE1Ndez5PSDCZ+kMZv/+/ejduzeSkpKq1ukDLAzx1FhplZgNflrNa3fWBFEzc2pkjXsyK1JbR8FmUVDZI9WokfjjORX27Ix3csHrZczUafa1Vl4PiJmQ2AqRy4X670vVZRgdLWcGTS+yM6DB7qTEVsOV6AmJ7Wxv5X6UW57tsxv2tm7disLCQmzcuBGpqanGD0xSaLN0TplSjNhYsTeUS0tL8Mor4mfpLCgoQJ8+fdCqVSu8++67qFOnTtXvtN674uJipKamYsCAAZg2bRr27NmDUaNGYfbs2Y4uy1Crevg0qampyM7ORs+ePbF582bccccdiI6Ott7bZ+VWtNFxVP4tCiszgeqJetBF438hObUYu38rQP8N64WWktnp8aKj5bc2ZU2uY7fy9V/Q3ctc0htodlinqrX2RJDR26dytLlWlQWqIrxQtVnllrm9RLQV9QMmRPQMWr3fVVvCnr/Kykps2bIFxcXFyM7ORkpKiuV9kXheWnh97dq1+Oabb/DNN9/gxhtvrPY7rf8sISEBa9aswaRJk5Ceno7GjRvjqaeecjTsAbW0h09z7Ngx9O3bF2VlZejdu3dV16vlnj5AbG+fkTNWxDzpskKa7DFQoVi9lSu6BSV7nnMZn2Wolpad42njruzsI9yi7la2DcVuC8noM74Gyejh0y4V2evsAeZ6+fwvYbsjyUVVc/7lkjm4wC3VmCz66tFNXwsy5pESsc9g4Svc+3Jb0DP7erNhT9+7d/nyZWzYsAFxcXFYt24dF1V3Ea2H7//+T04P3+zZatbh84paHfgAoKioCIMHD8bhw4fRt29fxOlqIceCn5VvPlELZMnsodP27aZv9kgg6yEikccLttCVGUYDW7iZZ80w24qx2koy+FkYDXzR0eYDmYqR6UDo4BbusrUa+vT7tdo7F65sooOfqirMDfe4VA6NDURme1Bm0PPn//6sDiCIlLB36dIlrFu3DikpKVi1ahUSEhJM7Yvk0gLfY4/JCXyvvcbAp1frAx9wpVJ46KGHsGnTJvTv3x/XXXdd1e+Uhj6ttrZzK9sLwS86Ws0zd7Up9AHWWk12JoAxOwe9nf0A9hZ3j4SHXQBUoE74F+nIDn1Wh3Xqqzizl6mdXkKN2dBnpowiqjZWXXLoP1e3hzzA2tBN7T2qqL6sHEdV2CspKcG6devQs2dPLF68WPhi22QfA59aDHw/qqiowOTJk/HBBx+gX79+aOx3m1Jq8Av27e6G4AeID3/B3q9Xb5G7iZGWk/8teLutrWDbm506L1Q5RExjZ/Z9MvBJOYbV4+iFqxqNXvrhgp/dKsRKlcZqSw5tAIOsY4lsU9qZgNh/LUBZx5M9l5WdsHf69GmsW7cODz/8MP785z/XmEWR3EELfJMnywl8f/4zA58er4If1alTB6+//jpmzJiBjz/+GIcPH672e22xdkvi42vWqNHRV3+CqV/fekNXO6aIqesbNLj6Y1eo99uoUfUfMi/Y59u48dWfQNvY+UIMtK2VedKDlUPUnOVGrjmSRv/xy5qd0OyfN9Rpavc0iY4OfdnJOCZdperrRNRXo92v7EDNBSNVXqSFve+++w4ff/wxZsyYgblz5zLsEf2IPXwBLF26FI888gi6deuGzp07Vy3boLHV22dnajsrPX76yk7E+nl2H4axU/nydrlxlZXOPEzTsKG4W+iVlermLfcvs0vHQ8nu4QPE9fIZufTsVkna9iIuc606ExH0wgn03FxtraoAMVWGzEeQ/YnqMKhf3355zFaR2vFUBD0r21gNez6fD3v27MHOnTuxaNEi3H///eYOTMppPXyTJsnp4Xv9dfbw6dXKZRnCGTp0KJKTkzFo0CCcO3cOt99+e7W7RFpvn+UF2wFrLTGzi7D7tyDsLOIeiP72uIp5yoMFGK9MSSebiKGa2jljdlv9uSBiyQh9BV1ebm0fZlpCEdraVr18gtmP0eqi7JqGDcWNOG/Y8Er57VRlRt+//lI9fTpiTz+pVA8C0VdxIkKjVj1ZrS7trAmoIrhZ2cZq2KusrMQXX3yBEydO4LPPPsMtt9xi7sBEtQB7+ELIz8/HwIEDcenSJfTp0wcxMTE1XmOrtw+Q1+NntAUhYgYEf6FaTKKHDgajhcBIbkkZ6cGz0zIRMSmLleOHuhtnNPzZ6RkM1koJ915c2MMHyOvl87+0VA5eqOt3q9Ju6AtUTcic2CXcdrXpHla4yypYNSe7agNCV29Wjx+qapK1uozG6qydsodwAtbDXllZWdWyC//5z3+QnJxs/uDkCK2Hb8IEOT188+axh0+PgS+MkpISDB06FDk5ObjrrrvQMMg3gKuCn9WWh4gA6c+/1aQq8IXbzkstKhFr+YmeidPMM3pmjm2mYg4V/lS1ivTvLYIDn9FLT2bo8w95gZgNfkbel8yJXYxu66Xqyiz9JWSmqpMV+IxWbWaOb6Y6CrZfJ4KemSVF7RzLatgrKirCJ598gm7dumHZsmXVZlgn99MC37hxcgJfVhYDnx4DnwEVFRWYOnUq5s+fj969e6Nly5YBX2c79AH2WkyiZuYM1PIS9ZCMWwJfOCpbWLIXZ9eIaCFZmYzF6PGtVsr+wc8Lt8Atbqcq8FmthmQEPiNBT89I6LNSJQQKfk5UZ3peDIKiJgkWGfisVmvhymCnKtLv2+mwF45WVpVhLz8/Hxs3bsTEiRMxa9Ys1Kljvm4kZzHwqcXAZ8KiRYswZswYdO3aFV26dKkxmYvGkeAnenIW/b5EDou0M+mLysBnlZVjqVqEys6xtAdmrD5PF64MIheusvN5qgx8Fo9VG0Kf2ZDnL1Tos1sdiJjcxauLqoejcp4ou4HPzr2rcOWwO9eUtg8nqjJVk7nUQYXpbcZNnAifz4fdu3dj165dePPNNzF8+HDzBydX0ALf2LHFiIkRG8rKykqwYAEDnx4Dn0nbt2/Hvffei4YNG6JHjx6oG6JloiT4hWs5iAh/deuKmRkhXFndMHbKLrcHPrPHCzQzgojQpy+HrFWKVay7Z2fbCA18VrfVLh1ZS4iKqgK0Kt/qsqGqHyt2e5WkMvCJnngFuFJ9FRWJCXmaQPuSOaQSsL4chMqwV15ejs2bN6O4uBgrV65Eenq6+YOTazDwqRXBM1rI0b17d+Tk5KBBgwZYvXo1zp07F/S1ttbu08TFBa5RjS44ZWctP+Bq60bkWnzBNGxY/ceL7MyMqUq4cyfc4lV169rvgtEfR4RArRVV6+7ZCYoupuJtBfoTiVg6VNOggdhTQH/aW1njjWFP7bFUfaWI2Lf2VW11jclgTQUjvBD2zp07h9WrV6NBgwbYuXMnw14EqayU80PVsYfPotLSUkyePBl//etf0atXr6DP9WmE9fbZbTGY6fETPUuC3bLb6WVkSyv0Ma0GLyu9faFaR1b2Z6W1ImLdPbvburyHz852obY1emnY7enzr77sLLdg5v5GsJ4/L1RBgHcCX6BtzQYvq8cPdt/TSvVl9X6svuxeCHqA9bB35MgRfPbZZxg+fDjmzJmD2NhYawUgV9F6+EaPltPD9+ab7OHTY+Cz6d1338X48eNx0003IS0tLehzfRpLwU/k/Od6ocKflR4cmQ/OAIHLZHRcFVtbNekfuLE7TNPo9kZbZEb3J6I7KD7e3vv3QOADnA19di4/s8EvVNVlNvTZ6cjWqiYnVobxQvVj93ginsOTMYGwipVjgOrVh5XP0Qthb+yECdi5cyf27NmDrKwsjBgxwtrByZW0wDdqlJzA9/bbDHx6DHwC7Nq1C0OGDEG9evXQs2dPQ3efwgY/FfOga/yDn4jhev7hT1bgC4S32AMLN6OCiGfzgu3DasssVJlEjf3z34+Zz8GBnkEvBD7tUhX1PJ6R/ZiptowEPxHVoH4fKidQcVvVI+J4/oMQRD9KHIioiYP1RDzrF6rqkLFcaLhjhmIl6AHA/44ahc8//xwVFRX48MMP0bVrV2sFINdi4FOLgU+Qs2fP4qGHHsK2bdvQp08fNDYwXVmN0GcnkIgKfiJaOf5KStQGvkDOnKl9t9qtTJknI/SJenhGv19ZYc/IsfVqQeALt224y1Jm6LNbXQUKfqKqwHD7kRUAvRL2Qh3T6AhzN08aLHK1GI3ZKsP/vXkl7N0/bBg+/fRT3HbbbVi8eHHQ9Y/J27TAN3KknMD3zjsMfHoMfAJVVlbi+eefx7PPPovu3bvjpz/9adghnsCPwU9UGLHTqtOXQeRUefqWj6oHacxuL/P2u4oWWNOm1rcNRERLqlEjoKzM/n781a8vZr92QqP2+dTCwGflMhQd+kTel9JXSaJ79cwQUQV5Kexpx7Uzb5PIwCe6TWh3hRg9Jx4xtru9lbDn8/lwZ+/e2LFjB5588kk88cQTiHbiRi0poQW+ESPkBL733mPg02Pgk2Djxo0YNmwYEhIS0KNHD8TExBjaLuv558UVwkzrLlyFKnr2BD0zAdCrrTE7X1j6FoN/qDOzrRVWW1P+LTiRoc//NrmdfdvtJQzWEjLyudlohVkNfIDxaiHQZWJ3EIGI0BcTI3aZUf1+rS6zoGe3igpUVZw8aX1bo2QHvmCDDVQ9OhyM1nEkanioxu4KMRqnwprdba2EveLiYnS/7TaUlJTgH//4B3r16mW9AOQJDHxqMfBJcurUKTz44IPIyclB79690aRJE8PbKg1+ZloJVlpsZltAoQKgk4EPsN8L68TtdxEtOaOtoXC36u0Gv3BjoszsX8SQUKstovJyxwOflctAxKhxK1VIoPtlokJfsHtxVsKfjLAXjj4McvR4eKInCNYLV6WY+ZydDHp2t7cS9rZv346BgwahW7duWLx4san2EnmXFvgeflhO4Fu0iIFPj4FPosrKSrzwwgv4wx/+gPT0dHTq1MnQEE+N1OBnN7wYbbnZaQX5hz+nAx/g3OLvbg19VsZjWQl+Zh+ACXUMJ8OexsZ5aCfw2W3Uqgp9BgdFWA5+RvdvJPiJqJacupcEOFe1qAh8Zh/9UrEqTKjPTMTal0716k2cOM70Nj6fD19//TW2b9+Op59+GtOmTeMQzlqEgU8tBj4FNm3ahAceeADXXnstevTogTiTtarQ4AeIf64qWAtO9AQwIm7rezXwAfaDm8jgJ2LBdCPnoYiZDvyPU4sDH2CvoS0z8BkNYf7MVAtWjxEs+DHsWScr8Nmd38NIuURUISLW0dNzslfPSti7dOkSNm/ejAsXLmDp0qXo0aOH9QKQJ2mB73/+R07g++tfGfj0GPgUOXPmDEaOHImNGzeiZ8+eaNGihel92A5+/q0TkROzBNqn6MDn31qz+tANQ581+nFbIm8aBNuXiLDnfxw3hD3As4EPEBv6rAawQEIFP5HH0aqd2hz2RGwvKvCJnsBRxUow+n3Z/RycHv5pJewdPXoUmzZtQu/evfHOO++gkYgbiOQ5DHxqMfAp5PP5sHDhQjz22GPo0KED0tPTUaeO+cabqeBnpFUiI/jJmJ3RSKtNxRgsJ1tpgNqWWqiHc0T/jfX7Ex32gJqtNavlr+WBD7AX+rTLWEa14x/6RAa9QPt0ai4nEdt7NfDJnBNKI2MFGL1g+1S1BKiIfVgJehUVFdixYwdyc3MxZ84cjB492tRjLhRZtMD34INyAt/f/sbAp8fA54Dc3FwMHToUZ86cQc+ePS2vMRM0+NkJNKKm0vMnYjimqPFYXr81D8htrZmdgUFki0u7FkSnAaOtNiPvxcHhnBqnQ5/RwBfukpUZ+kSHvXD7MxP+Irn6MMrIOWik48fNK7/omQ2OMpb+FLUPK2GvqKgIn3/+ORo1aoSlS5eiQ4cO9gpBnsfApxYDn0NKS0sxdepULFiwAN27d0fHjh0t3+mqCn6ih1CKmlLPn5XwJ7r1VlJib3sRD5Y73WrT9mFlij1/dltHwW56iEgEdm7R+78vh3v3NE4HPiBw6LNymYoMffo/tZ0lP/1ZeV/BAqDTYQ9wb+CzOrJPRDgLNKjA6eU+NSKW/RSxPWA+7Pl8Puzbtw/bt2/H2LFj8eKLLyI2NtZ+QcjztMA3bJicwLdkCQOfnuCEQEbFxsbitddew7333ouHH34YBQUF6NGjB+INfjtkzZkT+gUiHrTRymK0RWa0VeT/zSpjYa1wwoWccLfrKyvFtLzsiI62tzi7RkTrX/vbW2khherh1l8PVpKB3daW/pyOiRG/YJfHibgPY7aaCbUPPe20shP87Lw/fRVz+rQ77hEBzi2y7s8Nj22FGzlup1oTORQ0UDnNVkVO9OpdvHgRW7Zswfnz5/Hhhx+if//+9gpBEcnnE18vsSurJgY+h/Xv3x+5ubkYN24c/vnPf+KOO+5ASkpK1e/DBrtgtNpdZPADxE+xB1T/NnMi/AUSKhDaeXBHT0RoDBT6zC7QXreuuCBjpoVkdiiz2fAn4+GbUL1zHgqDZv/kgd626GFv8fHmQp/RP6+V4Cd6QEFSUvDfGV1YXQRRgwKMCHdPTeS5ExNjfH9WHg82un/RVU6okBasKvK/rp3o1QOAb7/9FtnZ2Rg0aBCysrKQmJhovyBEZBkDnwskJiZiyZIlWLx4McaNG4ejR48ie8MGJCQk2N+5yOAHBL4dL7J15Mbw50/fkrEyPE/fwgsV+swEN7stOe19qAh+IqbVC9ctJLrlZeQc93gYtHIqm2loGxEu9Nn5sxoNfqLDXrjPNdhl7h8EnR5QEIiI0eCyiZr/KdS5rjLohaOdb6Ke8DAb9srKyrB161YUFBTgzTffxIMPPiimIBSxKivF9/C5ZSSDmzDwuchDDz2EXr164eGHH0ZKhw5YsmgR+vXtK2bnMoKfzOn2gOrf1PHxYh/KcVKgFp6Mnj4rZAY/0fOnA4F7/WT07Nmlfa5W/s4m/q5mdi+qQagi9In8kwYLfqqDXjj6asLM3zVYj2Gg08jsYADAE/cupEzyC1Q/190U8vyJuLatLreQnZ2NtLQ0rF271tLyU0QkBwOfy7Ro0QLr16/H/Pnz8fOhQ9GmTRts+fRTcQ+d6r9VrIY//5aR3eeswtH27x8Y3BAAy8vFfLvKGt5plahhnv4P6oi64RBIfDx8cdcAAKIu/SBuvzLm9jcjwHkhorNH5OkiI/TJJmtCWEDs/Flmq4VAIU7U39nNYa9pU3n3HvX0X0Miznm3BT3AWq/etm3bkJeXh5deegkTJkzgcgtkGHv41GDgc6Ho6GhMnDgRgwYNwogRI9A6NRUZGRlYtXy52AOZ7fUz0vAVHf5CtfwC9Ri5IQQ6SWsdOtnbF2o2BtE9zT/Sgl6wf1sOgE6HvVrmmriaT9r/cElOw1E7FfUNbiPLeIbjZNirLYINFjD7HKhRwb6G7EzqEglBD7jaq9e5c2esXLkSrVu3FlMYIhKKgc/FWrdujQ0bNiArKwtTpkxB5/R03HLLLfjL/PliDxSuEW610Su75y8QJ0Kgm3r5NKp7+8xOuScw+PmHu3CvEdr7Z4YLW+9O9/IFCniBXiMy9IVqaOtPY7PhT/SqOKJOl0i4021mNLio0Geml9lM8BMZ9AB39Oq98sorGDduHHv1yBL28KnBwOdy0dHRmDBhAn72s59hxIgRWLFiBU6cOIHk5GTrM3gG498IF9m7YSX8iRrX5cahoMG4OfQB1YOfiHnVbQwxNhL0jGwXNACyd8+0cKHPSMALtZ2d4Ge2oW0m/NWGsKdyOKfdx32thj6Rq7jIWMJTT+Q5ZzbsHT58GFu3bkWXLl3Yq0fkEVx43UN8Ph8WLlyIxx9/HM2aNcOtt96K+Ph4ccEv0DeIyAdzAlE1y6K/QN++dsdzuXUsl6BWX2nc1VljY2MkVhsGgp/VsGdE1KUfUBp9DWLrVojdscC/qQ9i76SLvhuqrzashrxQzAQ/0Q1t4GpV4dagp3Fz4NPOERlzOWmcWr1FU1Z2ZQIZkZ+dk0Hv4sWL+PLLL3H8+HG88sorGD16NHv1yDJt4fUhQ4pRr57YxdEvXy7BRx9x4XU9Bj4POnHiBB599FGsXr0a6enp6NChA6KioswHP7PfHLLDH3DlG1rFjA1mW4FGwqCbW38mW376cBeM1NAHBAx+MoOeJtBpLiT8RXjgq1NeWv0/SO4hDRX6ZIQ8f1FlV99v8aVY2/tzc9gD7IeWQAMCZM7hpAkU+lR8xYQ7/c1+nqK/XsyEPZ/Ph9zcXGzfvh2DBg3C3LlzkRRqcUkiAxj41GLg87BVq1ZhzJgxqFu3LjIyMtDwx1ulAYOf6G8LieFPykyL/kS3CD16y99IsAtHevADgEuXHAt74RgKgxKe33Mq9NUIdqEoGBarD36qg144RoNgpIQ9s6O8VQY+N4S8cAJ9zk4GPQA4e/YssrOzUVFRgYULF2Lw4MFiC0S1lhb4Bg+WE/hWrWLg02Pg87jz589j5syZmD9/Pjp37oy0tDTU/fEbImvOHPHfFoEICn/hGvRCA6CklmFpmblGeOyl4vAvMtgavBB9naHXyTolZAS/4pKan6esulv0PYxqQdCDgc9UsAtFxbOQJSXwNbB/8yIUM0EvHH0QlDGXj8zAJ+LRXY3swKcfTixrtldZp7eR88Ls39lM2Lt8+TJ27dqFPXv2YPz48XjuuedQX9YCh1QraYHvZz+TE/hWr2bg02PgixA7duzA2LFjkZeXh/T0dKSkpFSNrc964w01hbDYYrbTc2M5BErsCjAb+owQ/fyMzPsAIoJfoKAXiKh6XOZoZbOfdZ1oY5+f0cAXVWliOKqsmTlEt4pLSoL+SnTwExn0ajDxeZ+rvNbQ64yEgIQ4c+/JF2N/yGowIkOfkedFRQU/J4OeWePHmxu+mZeXh+3bt6Nt27ZYsGABbr75ZvGFolqPgU8tBr4IUllZiXfeeQePP/44EhIScOutt1YN8wQUBj/AcAta9DA9wwGwlgc+jZuCn9GQF4zVOl32o6myPuM6EDypDCB/KkY7reQQIS8YO+FPatAD5HzWkk42twY+OxMCWQl+MjurZa3aYibsFRUV4csvv0RxcTFefvlljBw5EtEuXE6GIoMW+AYOlBP4/vMfBj49Br4IdPbsWcycORNvvfUWOnXqhLS0NNSrV6/aa5wOfyqexwKCBEDJD/rICHyAN0MfED742Q16wRip470a9gBJgQ9wV+izEPKCMRP+3NKrZ4oHw57GSOiTMdsrED74yR6R7Iagd/nyZeTk5GDv3r0YPXo0nnvuuWo3i4lkYOBTi4Evgu3atQvjxo3Dvn37kJaWhvbt29e4W6c0+AFAWZmysBdMFOSf8l4LfYD64Ccr6AUSqL5XMemsJwMf4FzoExjwggkV/DzZq6eJsMAnK+AF4x/8akPQq6ysxIEDB5CTk4OOHTsiKysLXbt2lVMwIj9a4OvfX07gW7uWgU+PgS/C+Xw+LF26FFOmTEFpaSluvvlmtGzZMuDaObLCX2l5naC/c2Jt62BtyoQG4i4FWYEPkN8Wl9FuPH26+r+dfva/vFx+GWQHaE8HPuDqxa8g5AWjhT/pQQ/wZNgD1AU+1QHP3w+XonBN9JXzoKKunPcse3Sk0bDn8/lw5MgR/Pe//0VcXBxefvllDB06lGvqkVIMfGox8NUSZWVleOONN/D0008jMTER6enpaNy4ccDX2g1+oQJeOLIDoNW2pZUwWFtDn3+4C0V18Av1uYkui6cDHyDnJDt/vuZ/UzGTcCCByhKkTrTFzRerAaIDX1RJiJmJVTfMDHbz2w2Abgl6AHD69Gns2LEDRUVFeOaZZzBhwgTEOHHnlWo9LfD161eMunXFXvvl5SVYt46BT4+Br5YpKirCs88+i7lz5yIlJQXdunXDddcFn87fSPizE/DCEfk9JKsjIVgYlBn4ADWdMEbakmYCXigyw5+dz8pKuVRkGOmBD7D+wQUKU+GoCn5my2YnBHo87AHWAl/IUBeO7MaZgLHcRgOgm4LeuXPnsHPnTuTl5WHy5MmYOXMmn9MjRzHwqcXAV0vl5+dj+vTpWLp0Kdq3b48uXboYDn4yA144VgOgE6PGVCwCrTr0iQp34YgKfzI/n1BlrDWBz0qwC0fGhyejnKGCoFvuxtgULuzZCnahiGygqXhYF9VDoJuCXklJCXbv3o2DBw9i6NCheOGFF5CcnCyxdETGaIHv7rvlBL5PPmHg02Pgq+Vyc3ORmZmJ5cuXo127dujSpUvYi2POnCxFpQvPSAB08BEhYe1MEW3LEyfslUFFgA3ESvhT0d4OJj5e3bOpykKfjMAUjt1A40SZGzdWd/IpCnzSQl04bl1nJRgbfw9ftPGbqEbDXklJCb766iscOHAA999/PzIzM5Gammq1iETCaYGvTx85gW/DBgY+PQY+AgDs378fmZmZWLZsGdq3b4+bbrrJ0EXipvAH1GxoOxn2ALVtTpELGIfiVPADwoc/J4MecCXsiWIkNBoKfCIawBcv2t+HVWYa0k6EPI2ICzApydjrwn0mIrvinZxhyQ1rq4SiaBiyL7qOqaCn9egx6JGbMfCpxcBH1eiDX7t27dCpUyckJiYa2tZt4Q9QF4KCUd3+VPl+nQx+QM12aCSFPaOuQYB1JmVyY/BzMuQB6isZ1Ree01PqOrWmSjCKJxkaN3GiodedPXsWe/furRq6mZmZifbt20suHZF1WuDr1UtO4PvsMzmB7+c//zlycnJw8uRJJCYmol+/fpg1axaaN29e9Zrdu3dj0qRJ2LZtG5o0aYLJkydj6tSpQsthFgMfBXTgwAE8++yz+Nvf/obk5GR07NgRzZo1MzVtsxMB0Gjbz63zQ4jgRMh1Ivzpe2+bNlV/fD0nwh7gQOADnA19wNWLt7YFPcCZC80Nge/MGWfL4sBMskaCns/nw/Hjx7Fv3z7k5+fjwQcfxJNPPsmgR57g1cA3e/ZsZGRkoFmzZigoKMDjjz8OANiyZQuAK++rffv26NevH2bMmIGvvvoKo0aNwp/+9CeMHTtWaFnMYOCjkI4fP47XXnsNb7zxBho0aIAOHTogJSWlxgLu4cgMf6LbfSK/251qkzrVsymrPWp1aK6KIOhU2AMcCnyA2tB38mT416gcshNpF1c4qkKWlS56mWVzaLkQI0GvsrISeXl5yM3NRUlJCSZNmoTf/OY3aNasmYISEomhBb4775QT+DZtUjOk88MPP8Qvf/lLlJaWol69epg3bx5mzpyJEydOVC15Mn36dKxYsQK5ublSyxIKAx8Zcv78ebz11lt46aWX8MMPP6BDhw5ITU1FvXr1LO3PbgD0yhwSXn+kyCq7bVOZz16KDIFOhj3AwcAHyAl9RsKdETK+4L18QdkhOlTJGnstopxOrQkJY0Hv8uXL2L9/P3Jzc3HNNddg6tSpGDVqFOo73QtLZIGKwHfkyJFqgS82NhaxseLWFj1z5gwmTJiAgoICbNq0CQAwYsQIlJSUYMWKFVWv+/TTT3H33XfjzJkzhh+TEo2Bj0wpLy/H8uXL8dxzz+HgwYNo164dOnbsiISEBMv7NBr+nB7BFYpbHy8CnH+O0Uhb1enJdQDzQdDpsAc4HPg0VoOfqHBnlNUQ6IULSCarYcLJh2qNltnBgKcxEvSKi4uxb9++qu/cmTNn4r777kNdF5SfyCot8N1xh5zAt2VLzXbp008/jczMTNv7nzZtGubOnYuLFy/i9ttvx8qVK3H99dcDAAYMGICUlBRkZV1t23799dfo1KkTvv76a3Ts2NH28a1g4CNLfD4fvvjiC7z66qtYsWIFkpOT0b59e7Rs2dLUc37+/MOfGwKTHU63FTVuKIe+3eqGgGdEsBDohrAHuCTwAaFDn+pgZ1SoAOiGCwZwPuxpggUop2dKMkpffheEJKPP5x05cgQHDhxAfn4+7rvvPvz2t7/F7bffbus7lsgtVAQ+oz1806dPx6xZs0Luc9++fejQoQMA4PTp0zhz5gwOHz6MZ555BgkJCVi5ciWioqIY+ChyHT9+HFlZWXj99dfh8/nQrl07pKamCuk2f/559838aYTMNq7THRUi3lvDhvb3oZq+zG4pv2sCHwB8953TJbBP1QKKRrgl7LlpdiSr7N6hEXReGAl6paWl2L9/Pw4ePIioqChMmjQJ48ePR5LRJTuIPEILfLffLifwffGF8Wf4Tp06he+//z7ka9q0aVP1TJ7e0aNH0bJlS2zZsgUZGRkc0kmR7/Lly1i+fDleffVV7Nq1C23btkX79u3RpEkT4Xck3RoE3dqZoVdU5HQJanJLgPKnolx2j2E79Mk6Idx4ovmTUUYRocjND8EC7g1+bul61/zYOAwX9Hw+H06dOoUDBw7g0KFDSEtLw+9+9zv86le/svycPJHbaYHv1lvlBL4vv1QzaUt+fj5atWqFTz/9FH369KmatKWwsLDq+n3iiSewfPlyTtpCkScnJwfz5s3DokWL0KBBA7Rt2xY/+clPhD4sG4iTQdALYU/jhba4EyHQrcEzlGY47nQRwnPDCeeGMhjhpZPQyeDntnAXwLjf/jbk70tLS3Hw4EF8++23OHfuHIYPH46JEyeia9euagpI5CAvBr6tW7di27ZtuPPOO5GYmIhDhw7h97//PQoLC7F3717ExsaiuLgYqampGDBgAKZNm4Y9e/Zg1KhRmD17NpdloMh14cIFLFmyBHPnzsWePXvQtm1btGvXDjfccIPS5xBkBkEvBT09r7R/9WS0hb3Uvg7EE4HPn4qTjye4OjKDnweCnb9QQc/n86GwsBAHDx7EoUOH0LlzZzz66KMYNmwYrr32WnWFJHKYFvi6d5cT+LZvFx/4vvrqKzz22GPYtWsXLly4gGbNmuGee+7Bk08+iRYtWlS9Tr/weuPGjTF58mRMmzZNWDmsYOAjZXbv3o358+fj/fffR3x8PFJSUtCuXTvEO/iFbicIejXo+fNiu1hjtX3s1XZ1IJ4MfHqiTsDaeCK7kdXw58FgpxeuN+/ixYs4ePAg8vLycPHiRYwYMQLjx4/HTTfdpKaARC7jxcDnZQx8pNzFixexbNkyLFy4ENnZ2UhOTkZKSgpatWrlmmmmQwXBSAl6el5uK/sL1naOpDa1nucDnz8jJ2NtOGG9zu1T3AoSKuiVl5fj8OHDyMvLQ35+PjIyMjBmzBjcf//9jt7oJHIDLfClpxejTh2xoayiogQ7djDw6THwkaPy8/Px3nvvYeHChTh9+jTatGmDtm3bomnTpq6cejoz052TxUSy7dvt76N7d/v7cKuIC3x6WrCLpICnF6lhD7D/3lz82YQbsnny5El88803yMvLQ5MmTTB69GiMGDECycnJ6gpJ5HIMfGox8JEr+Hw+ZGdn4+2338bf//53xMXFoWXLlmjbti0aNWrkdPGkirQQKSKguZ2bAqQrA5/bToLGjZ0uQU1uCzRuK49Igt5bqKB35swZHDp0CPn5+SgtLcWvf/1rjBo1ChkZGa68eUnkNC3wdesmJ/Dt3MnAp8fAR65z6dIlrF69Gu+//z4+/vhjNGzYsCr8JSQkOF08T7EbJt3Wbo9kdkKkrdDHP7I1dkIkHz51vx8/61Ahr7i4GIcOHcKRI0dQVFSEwYMH45FHHsE999yDOLeso0jkUgx8ajHwkaudP38eH330Ed577z2sX78eTZo0QYsWLdC6dWs0bNiQd04ddO+9kdUz6WVD8JHTRSCNm7p/a7njaIbMzHHC9ufz+VBUVITvvvsOBQUFOHXqFPr27YsRI0ZgyJAhqF+/vrBjEUU6LfB17Son8O3axcCnx8BHnnH27Fn861//wpIlS7B+/XokJCSgefPmaNWqlfJlHkg+BkrjGPhMYigzbFxmptNFcJS2jMLhw4dx7NgxFBcXo2/fvhg2bBh+8YtfIDEx0ekiEnmSFvhuuklO4PvqKwY+PQY+8qQLFy5g7dq1WLp0KT766Epjt3nz5khKSsKNN97IGdAorEgKlBEX+CIskNX20OQ1Fy9exNGjR1FYWIiCggIAwJAhQzB06FD079+f6+URCcDApxYDH3leeXk5Nm/ejH//+99YtWoV9u7di6ZNm+KGG27Atdde65qlHqh26dr1f5UdKw05yo5VpXVrZYcqQkP861/vKjse1U7FxcUoLCzEyZMn0alTJwwePBj33HMPevTowe8RIsG0wNepk5zAt3cvA58eAx9FnO+//x7r16/HJ598gtzcXFRWVjpdJCLBolBRUX0Icz2UV/u3r06d6v/W/S8R1dSmTRsMGjQIffv2xfXXX+90cYgiGgOfWgx8RERERESkjBb4OnaUE/j27WPg04t2ugBEREREREQkBwelExERERGRcpWVgOhJ1vkkT03s4SMiIiIiIopQ7OEjIiIiIiLl2MOnBgMfEREREREpx8CnBod0EhERERERRSj28BERERERkXI+n/geOS44VxN7+IiIiIiIiCIUe/iIiIiIiEg5Gc/b8Rm+mtjDR0REREREFKHYw0dERERERMqxh08N9vARERERERFFKPbwERERERGRcuzhU4OBj4iIiIiIlGPgU4NDOomIiIiIiCIUe/iIiIiIiEg59vCpwR4+IiIiIiKiCMUePiIiIiIiUo49fGqwh4+IiIiIiChCsYePiIiIiIiUYw+fGuzhIyIiIiIiilDs4SMiIiIiIuXYw6cGAx8RERERESnn84kPaD6f2P1FAg7pJCIiIiIiilDs4SMiIiIiIuUqK4GoKLH7ZA9fTezhIyIiIiIiilDs4SMiIiIiIuXYw6cGe/iIiIiIiIgiFHv4iIiIiIhIOfbwqcEePiIiIiIiogjFHj4iIiIiIlKOPXxqMPAREREREZFyDHxqcEgnERERERFRhGIPHxERERERKccePjXYw0dERERERBSh2MNHRERERETKsYdPDfbwERERERERRSgGPiIiIiIiUq6yUs6PbKWlpUhLS0NUVBRycnKq/W737t3o2bMn4uLi0LJlS7z44ovyCxQGAx8REREREZFBU6dORfPmzWv895KSEgwYMACtWrXCjh078NJLLyEzMxMLFixwoJRX8Rk+IiIiIiJSzufz3jN3q1evxpo1a7Bs2TKsXr262u8++OADlJWV4e2330ZMTAw6deqEnJwcvPrqqxg7dqxDJWbgIyIiIiIiR5RI22dJSfV9x8bGIjY21taeCwsLMWbMGKxYsQLx8fE1fp+dnY1evXohJiam6r8NHDgQs2bNwtmzZ5GYmGjr+FZxSCcRERERESkTExODpKQkAC0BJAj+aYn69eujZcuWSEhIqPr54x//aKvMPp8PI0eOxPjx49G9e/eArzlx4gRuuOGGav9N+/eJEydsHd8O9vAREREREZEycXFxyMvLQ1lZmZT9+3w+RPmt9xCsd2/69OmYNWtWyP3t27cPa9aswblz5zBjxgxh5VSFgY+IiIiIiJSKi4tDXFyc08XAlClTMHLkyJCvadOmDT755BNkZ2fXCI7du3fH8OHD8e677yIpKQmFhYXVfq/9+0qPpjOifD6vPSpJRERERESkTn5+frXnAo8dO4aBAwdi6dKluO2223DjjTdi3rx5mDlzJgoLC1GvXj0AwBNPPIHly5cjNzfXqaIz8BEREREREZnx3XffISUlBTt37kRaWhoAoLi4GKmpqRgwYACmTZuGPXv2YNSoUZg9ezZn6SQiIiIiIvKyhIQErFmzBpMmTUJ6ejoaN26Mp556ytGwB7CHj4iIiIiIKGJxWQYiIiIiIqIIxcBHREREREQUoRj4iIiIiIiIIhQDHxERERERUYRi4CMiIiIiIopQDHxEREREREQRioGPiIiIiIgoQjHwERERERERRSgGPiIiIiIiogjFwEdERERERBShGPiIiIiIiIgi1P8DkQvxiZPVPwkAAAAASUVORK5CYII=\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA3wAAAHvCAYAAAAPed3mAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAA9hAAAPYQGoP6dpAAD2SklEQVR4nOydd3gVRffHvzedEJLQIUDoRTpSFEWadAQVUPG1ADYE1NfeFWxYsP0sIFZe9UVfQbGAShMQBUVRpChgASkSEEOIIYSUu78/4iZ7N1tmdmfbvefzPHmUe3dn5u6enT3fOWdmQpIkSSAIgiAIgiAIgiCijjivG0AQBEEQBEEQBEE4Awk+giAIgiAIgiCIKIUEH0EQBEEQBEEQRJRCgo8gCIIgCIIgCCJKIcFHEARBEARBEAQRpZDgIwiCIAiCIAiCiFJI8BEEQRAEQRAEQUQpJPgIgiAIgiAIgiCiFBJ8BEEQBEEQBEEQUQoJPoIgCIIgCIIgiCiFBB9BEARBEARBEDHPI488glAohOuvv77is6KiIkybNg21a9dGWloaxo4di4MHD3rXSAuQ4CMIgiAIgiAIIqb55ptvMHfuXHTu3Dni8xtuuAEfffQRFixYgDVr1uCPP/7AmDFjPGqlNUjwEQRBEARBEAQRsxQUFOCiiy7CSy+9hJo1a1Z8fvToUbzyyit48sknMXDgQHTv3h2vvfYa1q1bh6+++srDFvOR4HUDCIIgCIIgCIKILYqKilBcXOxI2ZIkIRQKRXyWnJyM5ORkzeOnTZuGkSNHYtCgQXjwwQcrPt+4cSNKSkowaNCgis/atWuH7OxsrF+/Hqeeeqoj7RcNCT6CIAiCIAiCIFyjqKgIzatVQ45D5aelpaGgoCDis+nTp2PGjBlVjn377bfx3Xff4ZtvvqnyXU5ODpKSkpCZmRnxef369ZGT41TrxUOCjyAIgiAIgiAI1yguLkYOgL2hENIFl50PoElBAfbu3Yv09MrStaJ7e/fuxb///W8sX74cKSkpglviH0jwEQRBEARBEAThOukA0lWpl7aRpPKy09MjBJ8WGzduxKFDh3DyySdXfFZWVobPP/8czz33HJYuXYri4mLk5eVFRPkOHjyIBg0aiG23g5DgIwiCIAiCIAjCfeLiACcEX1kZ06FnnnkmtmzZEvHZpEmT0K5dO9x2221o0qQJEhMTsXLlSowdOxYAsGPHDuzZswe9e/cW224HIcFHEARBEARBEETMUaNGDXTs2DHis+rVq6N27doVn19++eW48cYbUatWLaSnp+Paa69F7969A7NgC0CCjyAIgiAIgiAIL/A4wsfCU089hbi4OIwdOxYnTpzA0KFDMXv2bGHlu0FIkv5JdCUIgiAIgiAIgnCY/Px8ZGRk4GhiovA5fPmShIySEhw9etR0Dl+sQBE+giAIgiAIgiDcx6kIHxFBnNcNIAiCIAiCIAiCIJyBInwEQRAEQRAEQbgPRfhcgQQfQRAEQRAEQRDuQ4LPFSilkyAIgiAIgiAIIkqhCB9BEARBEARBEO5DET5XoAgfQRAEQRAEQRBElEIRPoIgCIIgCIIg3IcifK5AET6CIAiCIAiCIIgohSJ8BEEQBEEQBEG4D0X4XIEifARBEARBEARBEFEKRfgIgiAIgiAIgnCfUKg8yieScFhseVEACT6CIAiCIAiCINwnLk684COqQFeYIIioZvfu3QiFQpg3b57psRMnTkSzZs2Yyg2Hw+jYsSMeeughew0kuGjWrBkmTpzodTMCgfparV69GqFQCKtXr+Yu64UXXkB2djZOnDghroEEQRCEK5DgI4iAMHr0aKSmpuLvv//WPeaiiy5CUlIS/vrrLxdbpk9ZWRlee+019O/fH7Vq1UJycjKaNWuGSZMm4dtvv/W6ebZ46623sHfvXlxzzTUVn33zzTe45ppr0KFDB1SvXh3Z2dk4//zzsXPnTs0yfvrpJwwbNgxpaWmoVasWLrnkEvz555+OtruwsBDPP/88hgwZgoYNG6JGjRro1q0b5syZg7KysirHh8NhPPbYY2jevDlSUlLQuXNnvPXWW4620Slmz57NJPyDxLp16zBjxgzk5eU5Ws/EiRNRXFyMuXPnOloPQRAxhhzhE/1HREBXhCACwkUXXYTjx49j0aJFmt8XFhbigw8+wLBhw1C7dm2XW1eV48eP46yzzsJll10GSZJw5513Ys6cObj00kuxfv169OrVC/v27XO8HU2bNsXx48dxySWXCC131qxZGD9+PDIyMio+e/TRR/Huu+/izDPPxP/93//hqquuwueff46TTz4ZW7dujTh/37596Nu3L3755RfMnDkTN998M5YsWYLBgwejuLhYaFuV/Pbbb7j22mshSRJuvPFGPP7442jevDmmTp2Kyy67rMrxd911F2677TYMHjwYzz77LLKzs/Gvf/0Lb7/9tmNtNGLHjh146aWXLJ0brYLvvvvu0xR8dq6VmpSUFEyYMAFPPvkkJFoBjyAIIlhIBEEEgsLCQqlGjRrS0KFDNb+fP3++BEB6++23XW6ZNtOmTZMASE899VSV70pLS6VZs2ZJe/fudaz+kpIS6cSJE1znTJgwQWratKnpcd99950EQFqxYkXE519++WWVOnfu3CklJydLF110UcTnU6ZMkapVqyb9/vvvFZ8tX75cAiDNnTuXq908/Pnnn9LWrVurfD5p0iQJgPTzzz9XfLZv3z4pMTFRmjZtWsVn4XBYOuOMM6TGjRtLpaWljrXTCTp06CD169fP62ZwU1BQoPvdrFmzJADSrl27TMtZtWqVBEBatWqVpXZ8++23EgBp5cqVls4nCIKQOXr0qARAOtqggSRlZQn9O9qgQXnZR496/TN9A0X4CCIgVKtWDWPGjMHKlStx6NChKt/Pnz8fNWrUwOjRo03Lmj17Njp06IDk5GRkZWVh2rRpVSIE/fv3R8eOHfHjjz9iwIABSE1NRaNGjfDYY4+Zlr9v3z7MnTsXgwcPxvXXX1/l+/j4eNx8881o3LixaVkLFixA+/btkZKSgo4dO2LRokVV5trJ8/Qef/xxPP3002jZsiWSk5Px448/6s7he//999GxY8eIcll5//33kZSUhL59+0Z8ftpppyEpKSnis9atW6NDhw746aefIj5/9913cdZZZyE7O7vis0GDBqFNmzZ45513DOufPn064uLisHLlyojPr7rqKiQlJeGHH37QPbdOnTro0KFDlc/PPfdcAIho5wcffICSkhJMnTq14rNQKIQpU6Zg3759WL9+vWE7J06ciLS0NPz2228YOnQoqlevjqysLNx///1VokTHjh3DTTfdhCZNmiA5ORlt27bF448/XuU49by0efPmIRQK4csvv8SNN96IunXronr16jj33HMj0mObNWuGbdu2Yc2aNQiFQgiFQujfvz8AoKSkBPfddx9at26NlJQU1K5dG3369MHy5csNf59c9+eff47Jkyejdu3aSE9Px6WXXoojR45UOf6TTz7BGWecgerVq6NGjRoYOXIktm3bpnnNfv31V4wYMQI1atTARRddpFn/jBkzcMsttwAAmjdvXvG7du/erXmt9Pj6668xbNgwZGRk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aaZ1AcBzzz0Xcf5zzz2HxMTEijmnI0aMQFlZWcRxQPnKk6FQCMOHD2eqx4zq1atrblD+119/Rfw7LS0NrVq10kxn1eLFF1+MWOF2zpw5KC0trWj30KFDkZ6ejpkzZ1ZZCRdAxPYRvFSvXh0ANH+XGd27d0fLli3x+OOPRzxjRu367rvvmO87QRAE4Q8owkcQAaR58+Y47bTTKvbDYhV8devWxR133IH77rsPw4YNw+jRo7Fjxw7Mnj0bPXv2jFigxS5PPPEEfv31V1x33XV47733cNZZZ6FmzZrYs2cPFixYgO3bt2P8+PGGZcycORNnn302Tj/9dEyaNAlHjhzBc889h44dO2o6qKw8/PDDGDlyJPr06YPLLrsMubm5ePbZZ9GhQwemcs8++2w88MADWLNmDYYMGVLx+U033YQPP/wQo0aNQm5uLt58882I85TX984778SCBQswYMAA/Pvf/0ZBQQFmzZqFTp06YdKkSYb1//TTT7jnnnswceJEjBo1CkB5embXrl0xdepUw338fv/9d4wePRqhUAjjxo3DggULIr7v3LkzOnfuDKB8Duf111+PWbNmoaSkBD179sT777+PtWvX4r///a/pnFGgfIGXTz/9FBMmTMApp5yCTz75BEuWLMGdd95ZscDOqFGjMGDAANx1113YvXs3unTpgmXLluGDDz7A9ddfXxGJskv37t0xZ84cPPjgg2jVqhXq1auHgQMHon379ujfv3/FPnPffvstFi5cGLHYjBHFxcU488wzcf7551c8T3369KnYEzM9PR1z5szBJZdcgpNPPhnjx49H3bp1sWfPHixZsgSnn356FbHL85sA4K677sL48eORmJiIUaNGVQhBI+Li4vDyyy9j+PDh6NChAyZNmoRGjRph//79WLVqFdLT0/HRRx9VHL9x40bk5ubi7LPPttRWgiCIKlCEzx28Wh6UIAh7PP/88xIAqVevXtznPvfcc1K7du2kxMREqX79+tKUKVOkI0eORBzTr18/qUOHDlXOnTBhAtPWBZJUvo3Eyy+/LJ1xxhlSRkaGlJiYKDVt2lSaNGkS85YNb7/9ttSuXTspOTlZ6tixo/Thhx9KY8eOldq1a1dxjLz1wqxZs6qcr7UtgyRJ0rvvviuddNJJUnJystS+fXvpvffe4/ptnTt3li6//PKIz+StLPT+1GzdulUaMmSI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+IiIiIiIiCIUe/iIiIiIiEg5Gc/b8Rm+mtjDR0REREREFKHYw0dERERERMqxh08N9vARERERERFFKPbwERERERGRcuzhU4OBj4iIiIiIlGPgU4NDOomIiIiIiCIUe/iIiIiIiEg59vCpwR4+IiIiIiKiCMUePiIiIiIiUo49fGqwh4+IiIiIiChCsYePiIiIiIiUYw+fGuzhIyIiIiIiilDs4SMiIiIiIuXYw6cGAx8RERERESnn84kPaD6f2P1FAg7pJCIiIiIiilDs4SMiIiIiIuUqK4GoKLH7ZA9fTezhIyIiIiIiilDs4SMiIiIiIuXYw6cGe/iIiIiIiIgiFHv4iIiIiIhIOfbwqcEePiIiIiIiogjFHj4iIiIiIlKOPXxqMPAREREREZFyDHxqcEgnERERERFRhGIPHxERERERKccePjXYw0dERERERBSh2MNHRERERETKsYdPDfbwERERERERRSgGPiIiIiIiUq6yUs6PbKWlpUhLS0NUVBRycnKq/W737t3o2bMn4uLi0LJlS7z44ovyCxQGAx8REREREZFBU6dORfPmzWv895KSEgwYMACtWrXCjh078NJLLyEzMxMLFixwoJRX8Rk+IiIiIiJSzufz3jN3q1evxpo1a7Bs2TKsXr262u8++OADlJWV4e2330ZMTAw6deqEnJwcvPrqqxg7dqxDJWbgIyIiIiIiR5RI22dJSfV9x8bGIjY21taeCwsLMWbMGKxYsQLx8fE1fp+dnY1evXohJiam6r8NHDgQs2bNwtmzZ5GYmGjr+FZxSCcRERERESkTExODpKQkAC0BJAj+aYn69eujZcuWSEhIqPr54x//aKvMPp8PI0eOxPjx49G9e/eArzlx4gRuuOGGav9N+/eJEydsHd8O9vAREREREZEycXFxyMvLQ1lZmZT9+3w+RPmt9xCsd2/69OmYNWtWyP3t27cPa9aswblz5zBjxgxh5VSFgY+IiIiIiJSKi4tDXFyc08XAlClTMHLkyJCvadOmDT755BNkZ2fXCI7du3fH8OHD8e677yIpKQmFhYXVfq/9+0qPpjOifD6vPSpJRERERESkTn5+frXnAo8dO4aBAwdi6dKluO2223DjjTdi3rx5mDlzJgoLC1GvXj0AwBNPPIHly5cjNzfXqaIz8BEREREREZnx3XffISUlBTt37kRaWhoAoLi4GKmpqRgwYACmTZuGPXv2YNSoUZg9ezZn6SQiIiIiIvKyhIQErFmzBpMmTUJ6ejoaN26Mp556ytGwB7CHj4iIiIiIKGJxWQYiIiIiIqIIxcBHREREREQUoRj4iIiIiIiIIhQDHxERERERUYRi4CMiIiIiIopQDHxEREREREQRioGPiIiIiIgoQjHwERERERERRSgGPiIiIiIiogjFwEdERERERBShGPiIiIiIiIgi1P8DkQvxiZPVPwkAAAAASUVORK5CYII=", "text/plain": [ "
" ] diff --git a/examples/notebooks/stencil_definition.ipynb b/examples/notebooks/stencil_definition.ipynb index 2afcc2445..a5efcc51d 100644 --- a/examples/notebooks/stencil_definition.ipynb +++ b/examples/notebooks/stencil_definition.ipynb @@ -68,7 +68,7 @@ ], "source": [ "from gt4py.cartesian.gtscript import PARALLEL, computation\n", - "from pace.dsl.typing import FloatField\n", + "from ndsl.dsl.typing import FloatField\n", "\n", "def set_field_to_value_def(f: FloatField, value: float):\n", " with computation(PARALLEL), interval(...):\n", @@ -84,7 +84,7 @@ "source": [ "## Setup helpers for building stencils\n", "\n", - "The `pace.dsl` package contains provides a helper class for compiling stencils. The helper class is called a stencil factory. In order to setup a stencil factory, several configuration objects have to be defined and passed in.\n", + "The `ndsl.dsl` package contains provides a helper class for compiling stencils. The helper class is called a stencil factory. In order to setup a stencil factory, several configuration objects have to be defined and passed in.\n", "\n", "- `DaceConfig`: configuration of DaCe backend\n", "- `CompilationConfig`: specification of how to compile\n", @@ -102,9 +102,9 @@ }, "outputs": [], "source": [ - "from pace.dsl.dace.dace_config import DaceConfig, DaCeOrchestration\n", - "from pace.dsl.stencil import GridIndexing, StencilConfig, StencilFactory\n", - "from pace.dsl.stencil_config import CompilationConfig, RunMode\n", + "from ndsl.dsl.dace.dace_config import DaceConfig, DaCeOrchestration\n", + "from ndsl.dsl.stencil import GridIndexing, StencilConfig, StencilFactory\n", + "from ndsl.dsl.stencil_config import CompilationConfig, RunMode\n", "\n", "dace_config = DaceConfig(\n", " communicator=None, backend=backend, orchestration=DaCeOrchestration.Python\n", @@ -155,8 +155,8 @@ "metadata": {}, "outputs": [], "source": [ - "from pace.dsl.stencil import StencilFactory\n", - "from pace.dsl.typing import FloatField\n", + "from ndsl.dsl.stencil import StencilFactory\n", + "from ndsl.dsl.typing import FloatField\n", "\n", "\n", "class SetFieldToValue:\n", @@ -183,7 +183,7 @@ "source": [ "## Compiling and running the stencil\n", "\n", - "To compile and run the stencil we first have to instanciate the wrapper class. This will compile the stencil and return a callable object. Next we have to define a GT4Py data storage (field). This could also be done using the `pace.util.Quantity` class, but here we use plain GT4Py data storages for simplicity. Finally, we can call the stencil and pass in the field and value." + "To compile and run the stencil we first have to instanciate the wrapper class. This will compile the stencil and return a callable object. Next we have to define a GT4Py data storage (field). This could also be done using the `ndsl.util.Quantity` class, but here we use plain GT4Py data storages for simplicity. Finally, we can call the stencil and pass in the field and value." ] }, { @@ -582,10 +582,10 @@ "metadata": {}, "outputs": [], "source": [ - "from pace.dsl.dace.dace_config import DaceConfig, DaCeOrchestration\n", - "from pace.dsl.stencil import GridIndexing, StencilConfig, StencilFactory\n", - "from pace.dsl.stencil_config import CompilationConfig, RunMode\n", - "from pace.util.grid import AngleGridData, ContravariantGridData, DampingCoefficients, GridData, HorizontalGridData, MetricTerms, VerticalGridData\n", + "from ndsl.dsl.dace.dace_config import DaceConfig, DaCeOrchestration\n", + "from ndsl.dsl.stencil import GridIndexing, StencilConfig, StencilFactory\n", + "from ndsl.dsl.stencil_config import CompilationConfig, RunMode\n", + "from ndsl.util.grid import AngleGridData, ContravariantGridData, DampingCoefficients, GridData, HorizontalGridData, MetricTerms, VerticalGridData\n", "\n", "\n", "if nz == 1:\n", diff --git a/external/dace b/external/dace deleted file mode 160000 index b0cd25b92..000000000 --- a/external/dace +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b0cd25b9263a3c615ee2f3325167944628fbfde5 diff --git a/external/gt4py b/external/gt4py deleted file mode 160000 index d7cf10fb3..000000000 --- a/external/gt4py +++ /dev/null @@ -1 +0,0 @@ -Subproject commit d7cf10fb31de4e60b33c25a6807e07605d5ecde0 diff --git a/fv3core/examples/standalone/runfile/acoustics.py b/fv3core/examples/standalone/runfile/acoustics.py index 4f898e05c..7c673e5b4 100755 --- a/fv3core/examples/standalone/runfile/acoustics.py +++ b/fv3core/examples/standalone/runfile/acoustics.py @@ -5,19 +5,19 @@ import click import f90nml +import ndsl.dsl +import ndsl.util as util import serialbox import yaml +from ndsl.comm.null_comm import NullComm +from ndsl.dsl.dace.orchestration import DaceConfig +from ndsl.dsl.stencil import CompilationConfig +from ndsl.stencils.testing.grid import Grid from timing import collect_data_and_write_to_file -import pace.dsl -import pace.util as util -from pace.dsl.dace.orchestration import DaceConfig -from pace.dsl.stencil import CompilationConfig from pace.fv3core._config import DynamicalCoreConfig from pace.fv3core.stencils.dyn_core import AcousticDynamics from pace.fv3core.testing import TranslateDynCore -from pace.stencils.testing.grid import Grid -from pace.util.null_comm import NullComm try: @@ -48,7 +48,7 @@ def initialize_serializer(data_directory: str, rank: int = 0) -> serialbox.Seria def read_input_data( grid: Grid, namelist: DynamicalCoreConfig, - stencil_factory: pace.dsl.stencil.StencilFactory, + stencil_factory: ndsl.dsl.stencil.StencilFactory, serializer: serialbox.Serializer, ) -> Dict[str, Any]: """Uses the serializer to read the input data from disk""" @@ -150,13 +150,13 @@ def driver( tile_nx=dycore_config.npx, tile_nz=dycore_config.npz, ) - stencil_config = pace.dsl.stencil.StencilConfig( + stencil_config = ndsl.dsl.stencil.StencilConfig( compilation_config=CompilationConfig( backend=backend, rebuild=False, validate_args=True ), dace_config=dace_config, ) - stencil_factory = pace.dsl.stencil.StencilFactory( + stencil_factory = ndsl.dsl.stencil.StencilFactory( config=stencil_config, grid_indexing=grid.grid_indexing, ) diff --git a/fv3core/examples/standalone/runfile/compile.py b/fv3core/examples/standalone/runfile/compile.py index d61e70812..ce72a88c0 100755 --- a/fv3core/examples/standalone/runfile/compile.py +++ b/fv3core/examples/standalone/runfile/compile.py @@ -7,10 +7,10 @@ import f90nml import gt4py.cartesian.config +import ndsl.dsl.stencil # noqa: F401 +from ndsl.comm.null_comm import NullComm -import pace.dsl.stencil # noqa: F401 from pace.fv3core._config import DynamicalCoreConfig -from pace.util.null_comm import NullComm try: diff --git a/fv3core/examples/standalone/runfile/dynamics.py b/fv3core/examples/standalone/runfile/dynamics.py index dde65b063..b23a3fc45 100755 --- a/fv3core/examples/standalone/runfile/dynamics.py +++ b/fv3core/examples/standalone/runfile/dynamics.py @@ -9,26 +9,27 @@ from typing import Any, Dict, List, Tuple import f90nml + +# NOTE: we need to import dsl.stencil prior to +# ndsl.util, otherwise xarray precedes gt4py, causing +# very strange errors on some systems (e.g. daint) +import ndsl.dsl.stencil +import ndsl.util as util import numpy as np import xarray as xr import yaml from mpi4py import MPI +from ndsl.comm.null_comm import NullComm +from ndsl.dsl import StencilFactory +from ndsl.dsl.dace.orchestration import DaceConfig +from ndsl.grid import DampingCoefficients, GridData, MetricTerms +from ndsl.stencils.testing import dataset_to_dict +from ndsl.stencils.testing.grid import Grid -# NOTE: we need to import dsl.stencil prior to -# pace.util, otherwise xarray precedes gt4py, causing -# very strange errors on some systems (e.g. daint) -import pace.dsl.stencil -import pace.util as util -from pace.dsl import StencilFactory -from pace.dsl.dace.orchestration import DaceConfig from pace.fv3core import DynamicalCore, DynamicalCoreConfig from pace.fv3core.dycore_state import DycoreState from pace.fv3core.initialization.baroclinic import init_baroclinic_state from pace.fv3core.testing import TranslateFVDynamics -from pace.stencils.testing import dataset_to_dict -from pace.stencils.testing.grid import Grid -from pace.util.grid import DampingCoefficients, GridData, MetricTerms -from pace.util.null_comm import NullComm def parse_args() -> Namespace: @@ -222,8 +223,8 @@ def setup_dycore( tile_nx=dycore_config.npx, tile_nz=dycore_config.npz, ) - stencil_config = pace.dsl.stencil.StencilConfig( - compilation_config=pace.dsl.stencil.CompilationConfig( + stencil_config = ndsl.dsl.stencil.StencilConfig( + compilation_config=ndsl.dsl.stencil.CompilationConfig( backend=backend, rebuild=False, validate_args=False ), dace_config=dace_config, diff --git a/fv3core/pace/fv3core/_config.py b/fv3core/pace/fv3core/_config.py index e2f5c1f5c..127ce3d8f 100644 --- a/fv3core/pace/fv3core/_config.py +++ b/fv3core/pace/fv3core/_config.py @@ -2,8 +2,7 @@ from typing import Optional, Tuple import f90nml - -from pace.util import Namelist, NamelistDefaults +from ndsl.namelist import Namelist, NamelistDefaults DEFAULT_INT = 0 @@ -65,7 +64,6 @@ class RiemannConfig: @dataclasses.dataclass(frozen=True) class DGridShallowWaterLagrangianDynamicsConfig: - dddmp: float d2_bg: float d2_bg_k1: float @@ -92,7 +90,6 @@ class DGridShallowWaterLagrangianDynamicsConfig: @dataclasses.dataclass(frozen=True) class AcousticDynamicsConfig: - tau: float k_split: int n_split: int diff --git a/fv3core/pace/fv3core/dycore_state.py b/fv3core/pace/fv3core/dycore_state.py index 0f73e728a..f90a3d883 100644 --- a/fv3core/pace/fv3core/dycore_state.py +++ b/fv3core/pace/fv3core/dycore_state.py @@ -1,271 +1,281 @@ from dataclasses import asdict, dataclass, field, fields from typing import Any, Dict, Mapping, Union +import ndsl.dsl.gt4py_utils as gt_utils import xarray as xr - -import pace.dsl.gt4py_utils as gt_utils -import pace.util -from pace.dsl.typing import Float -from pace.util.quantity import Quantity +from ndsl.comm.communicator import Communicator +from ndsl.constants import ( + X_DIM, + X_INTERFACE_DIM, + Y_DIM, + Y_INTERFACE_DIM, + Z_DIM, + Z_INTERFACE_DIM, +) +from ndsl.dsl.typing import Float +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import GridSizer +from ndsl.quantity import Quantity +from ndsl.restart._legacy_restart import open_restart @dataclass() class DycoreState: - u: pace.util.Quantity = field( + u: Quantity = field( metadata={ "name": "x_wind", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", "intent": "inout", } ) - v: pace.util.Quantity = field( + v: Quantity = field( metadata={ "name": "y_wind", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", "intent": "inout", } ) - w: pace.util.Quantity = field( + w: Quantity = field( metadata={ "name": "vertical_wind", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", "intent": "inout", } ) # TODO: move a-grid winds to temporary internal storage - ua: pace.util.Quantity = field( + ua: Quantity = field( metadata={ "name": "eastward_wind", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", "intent": "inout", } ) - va: pace.util.Quantity = field( + va: Quantity = field( metadata={ "name": "northward_wind", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", } ) - uc: pace.util.Quantity = field( + uc: Quantity = field( metadata={ "name": "x_wind_on_c_grid", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", "intent": "inout", } ) - vc: pace.util.Quantity = field( + vc: Quantity = field( metadata={ "name": "y_wind_on_c_grid", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", "intent": "inout", } ) - delp: pace.util.Quantity = field( + delp: Quantity = field( metadata={ "name": "pressure_thickness_of_atmospheric_layer", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "Pa", "intent": "inout", } ) - delz: pace.util.Quantity = field( + delz: Quantity = field( metadata={ "name": "vertical_thickness_of_atmospheric_layer", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m", "intent": "inout", } ) - ps: pace.util.Quantity = field( + ps: Quantity = field( metadata={ "name": "surface_pressure", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "Pa", "intent": "inout", } ) - pe: pace.util.Quantity = field( + pe: Quantity = field( metadata={ "name": "interface_pressure", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_INTERFACE_DIM], + "dims": [X_DIM, Y_DIM, Z_INTERFACE_DIM], "units": "Pa", "n_halo": 1, "intent": "inout", } ) - pt: pace.util.Quantity = field( + pt: Quantity = field( metadata={ "name": "air_temperature", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "degK", "intent": "inout", } ) - peln: pace.util.Quantity = field( + peln: Quantity = field( metadata={ "name": "logarithm_of_interface_pressure", "dims": [ - pace.util.X_DIM, - pace.util.Y_DIM, - pace.util.Z_INTERFACE_DIM, + X_DIM, + Y_DIM, + Z_INTERFACE_DIM, ], "units": "ln(Pa)", "n_halo": 0, "intent": "inout", } ) - pk: pace.util.Quantity = field( + pk: Quantity = field( metadata={ "name": "interface_pressure_raised_to_power_of_kappa", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_INTERFACE_DIM], + "dims": [X_DIM, Y_DIM, Z_INTERFACE_DIM], "units": "unknown", "n_halo": 0, "intent": "inout", } ) - pkz: pace.util.Quantity = field( + pkz: Quantity = field( metadata={ "name": "layer_mean_pressure_raised_to_power_of_kappa", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "unknown", "n_halo": 0, "intent": "inout", } ) - qvapor: pace.util.Quantity = field( + qvapor: Quantity = field( metadata={ "name": "specific_humidity", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", } ) - qliquid: pace.util.Quantity = field( + qliquid: Quantity = field( metadata={ "name": "cloud_water_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - qice: pace.util.Quantity = field( + qice: Quantity = field( metadata={ "name": "cloud_ice_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - qrain: pace.util.Quantity = field( + qrain: Quantity = field( metadata={ "name": "rain_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - qsnow: pace.util.Quantity = field( + qsnow: Quantity = field( metadata={ "name": "snow_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - qgraupel: pace.util.Quantity = field( + qgraupel: Quantity = field( metadata={ "name": "graupel_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - qo3mr: pace.util.Quantity = field( + qo3mr: Quantity = field( metadata={ "name": "ozone_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - qsgs_tke: pace.util.Quantity = field( + qsgs_tke: Quantity = field( metadata={ "name": "turbulent_kinetic_energy", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m**2/s**2", "intent": "inout", } ) - qcld: pace.util.Quantity = field( + qcld: Quantity = field( metadata={ "name": "cloud_fraction", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "", "intent": "inout", } ) - q_con: pace.util.Quantity = field( + q_con: Quantity = field( metadata={ "name": "total_condensate_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - omga: pace.util.Quantity = field( + omga: Quantity = field( metadata={ "name": "vertical_pressure_velocity", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "Pa/s", "intent": "inout", } ) - mfxd: pace.util.Quantity = field( + mfxd: Quantity = field( metadata={ "name": "accumulated_x_mass_flux", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "unknown", "n_halo": 0, "intent": "inout", } ) - mfyd: pace.util.Quantity = field( + mfyd: Quantity = field( metadata={ "name": "accumulated_y_mass_flux", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "unknown", "n_halo": 0, "intent": "inout", } ) - cxd: pace.util.Quantity = field( + cxd: Quantity = field( metadata={ "name": "accumulated_x_courant_number", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "", "n_halo": (0, 3), "intent": "inout", } ) - cyd: pace.util.Quantity = field( + cyd: Quantity = field( metadata={ "name": "accumulated_y_courant_number", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "", "n_halo": (3, 0), "intent": "inout", } ) - diss_estd: pace.util.Quantity = field( + diss_estd: Quantity = field( metadata={ "name": "dissipation_estimate_from_heat_source", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "unknown", "n_halo": (3, 3), "intent": "inout", @@ -275,11 +285,11 @@ class DycoreState: how much energy is dissipated, is mainly captured to send to the stochastic physics (in contrast to heat_source) """ - phis: pace.util.Quantity = field( + phis: Quantity = field( metadata={ "name": "surface_geopotential", "units": "m^2 s^-2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "intent": "in", } ) @@ -301,7 +311,7 @@ def __post_init__(self): ) @classmethod - def init_zeros(cls, quantity_factory: pace.util.QuantityFactory): + def init_zeros(cls, quantity_factory: QuantityFactory): initial_storages = {} for _field in fields(cls): if "dims" in _field.metadata.keys(): @@ -316,7 +326,7 @@ def init_zeros(cls, quantity_factory: pace.util.QuantityFactory): @classmethod def init_from_numpy_arrays( - cls, dict_of_numpy_arrays, sizer: pace.util.GridSizer, backend: str + cls, dict_of_numpy_arrays, sizer: GridSizer, backend: str ): field_names = [_field.name for _field in fields(cls)] for variable_name in dict_of_numpy_arrays.keys(): @@ -328,7 +338,7 @@ def init_from_numpy_arrays( for _field in fields(cls): if "dims" in _field.metadata.keys(): dims = _field.metadata["dims"] - dict_state[_field.name] = pace.util.Quantity( + dict_state[_field.name] = Quantity( dict_of_numpy_arrays[_field.name], dims, _field.metadata["units"], @@ -343,7 +353,7 @@ def init_from_numpy_arrays( def init_from_storages( cls, storages: Mapping[str, Any], - sizer: pace.util.GridSizer, + sizer: GridSizer, bdt: float = 0.0, mdt: float = 0.0, ): @@ -351,7 +361,7 @@ def init_from_storages( for _field in fields(cls): if "dims" in _field.metadata.keys(): dims = _field.metadata["dims"] - quantity = pace.util.Quantity( + quantity = Quantity( storages[_field.name], dims, _field.metadata["units"], @@ -365,11 +375,11 @@ def init_from_storages( def from_fortran_restart( cls, *, - quantity_factory: pace.util.QuantityFactory, - communicator: pace.util.Communicator, + quantity_factory: QuantityFactory, + communicator: Communicator, path: str, ): - state_dict: Mapping[str, pace.util.Quantity] = pace.util.open_restart( + state_dict: Mapping[str, Quantity] = open_restart( dirname=path, communicator=communicator, tracer_properties=TRACER_PROPERTIES, @@ -434,7 +444,7 @@ def from_fortran_restart( def xr_dataset(self): data_vars = {} for name, field_info in self.__dataclass_fields__.items(): - if issubclass(field_info.type, pace.util.Quantity): + if issubclass(field_info.type, Quantity): dims = [ f"{dim_name}_{name}" for dim_name in field_info.metadata["dims"] ] @@ -460,47 +470,47 @@ def as_dict(self, quantity_only=True) -> Dict[str, Union[Quantity, int]]: TRACER_PROPERTIES = { "specific_humidity": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], + "dims": [Z_DIM, Y_DIM, X_DIM], "restart_name": "sphum", "units": "g/kg", }, "cloud_liquid_water_mixing_ratio": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], + "dims": [Z_DIM, Y_DIM, X_DIM], "restart_name": "liq_wat", "units": "g/kg", }, "cloud_ice_mixing_ratio": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], + "dims": [Z_DIM, Y_DIM, X_DIM], "restart_name": "ice_wat", "units": "g/kg", }, "rain_mixing_ratio": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], + "dims": [Z_DIM, Y_DIM, X_DIM], "restart_name": "rainwat", "units": "g/kg", }, "snow_mixing_ratio": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], + "dims": [Z_DIM, Y_DIM, X_DIM], "restart_name": "snowwat", "units": "g/kg", }, "graupel_mixing_ratio": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], + "dims": [Z_DIM, Y_DIM, X_DIM], "restart_name": "graupel", "units": "g/kg", }, "ozone_mixing_ratio": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], + "dims": [Z_DIM, Y_DIM, X_DIM], "restart_name": "o3mr", "units": "g/kg", }, "turbulent_kinetic_energy": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], + "dims": [Z_DIM, Y_DIM, X_DIM], "restart_name": "sgs_tke", "units": "g/kg", }, "cloud_fraction": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], + "dims": [Z_DIM, Y_DIM, X_DIM], "restart_name": "cld_amt", "units": "g/kg", }, diff --git a/fv3core/pace/fv3core/initialization/analytic_init.py b/fv3core/pace/fv3core/initialization/analytic_init.py index 544c62836..f2c2bb984 100644 --- a/fv3core/pace/fv3core/initialization/analytic_init.py +++ b/fv3core/pace/fv3core/initialization/analytic_init.py @@ -1,9 +1,11 @@ from enum import Enum -import pace.util as fv3util +from ndsl.comm.communicator import Communicator, CubedSphereCommunicator +from ndsl.grid import GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.utils import MetaEnumStr + from pace.fv3core.dycore_state import DycoreState -from pace.util import MetaEnumStr -from pace.util.grid import GridData class Cases(Enum, metaclass=MetaEnumStr): @@ -14,11 +16,11 @@ class Cases(Enum, metaclass=MetaEnumStr): def init_analytic_state( analytic_init_case: str, grid_data: GridData, - quantity_factory: fv3util.QuantityFactory, + quantity_factory: QuantityFactory, adiabatic: bool, hydrostatic: bool, moist_phys: bool, - comm: fv3util.Communicator, + comm: Communicator, ) -> DycoreState: """ This method initializes the choosen analytic test case type @@ -34,11 +36,11 @@ def init_analytic_state( Returns: an instance of DycoreState class """ - if analytic_init_case in Cases: - if analytic_init_case == Cases.baroclinic.value: + if analytic_init_case in Cases: # type: ignore + if analytic_init_case == Cases.baroclinic.value: # type: ignore import pace.fv3core.initialization.test_cases.initialize_baroclinic as bc - assert isinstance(comm, fv3util.CubedSphereCommunicator) + assert isinstance(comm, CubedSphereCommunicator) return bc.init_baroclinic_state( grid_data=grid_data, @@ -49,10 +51,10 @@ def init_analytic_state( comm=comm, ) - elif analytic_init_case == Cases.tropicalcyclone.value: + elif analytic_init_case == Cases.tropicalcyclone.value: # type: ignore import pace.fv3core.initialization.test_cases.initialize_tc as tc - assert isinstance(comm, fv3util.CubedSphereCommunicator) + assert isinstance(comm, CubedSphereCommunicator) return tc.init_tc_state( grid_data=grid_data, diff --git a/fv3core/pace/fv3core/initialization/init_utils.py b/fv3core/pace/fv3core/initialization/init_utils.py index 42252e87e..1032fa7b7 100644 --- a/fv3core/pace/fv3core/initialization/init_utils.py +++ b/fv3core/pace/fv3core/initialization/init_utils.py @@ -2,14 +2,13 @@ from dataclasses import fields from types import SimpleNamespace +import ndsl.constants as constants import numpy as np +from ndsl.dsl.typing import Float +from ndsl.grid import lon_lat_midpoint +from ndsl.grid.gnomonic import get_lonlat_vect, get_unit_vector_direction -import pace.util as fv3util -import pace.util.constants as constants -from pace.dsl.typing import Float from pace.fv3core.dycore_state import DycoreState -from pace.util.grid import lon_lat_midpoint -from pace.util.grid.gnomonic import get_lonlat_vect, get_unit_vector_direction # maximum windspeed amplitude - close to windspeed of zonal-mean time-mean @@ -29,7 +28,7 @@ SURFACE_PRESSURE = 1.0e5 # units of (Pa), from Table VI of DCMIP2016 # NOTE RADIUS = 6.3712e6 in FV3 vs Jabowski paper 6.371229e6 R = constants.RADIUS / 10.0 # Perturbation radiusfor test case 13 -NHALO = fv3util.N_HALO_DEFAULT +NHALO = constants.N_HALO_DEFAULT def cell_average_nine_components( @@ -128,7 +127,6 @@ def empty_numpy_dycore_state(shape): def _find_midpoint_unit_vectors(p1, p2): - midpoint = np.array( lon_lat_midpoint(p1[:, :, 0], p2[:, :, 0], p1[:, :, 1], p2[:, :, 1], np) ).transpose([1, 2, 0]) diff --git a/fv3core/pace/fv3core/initialization/test_cases/initialize_baroclinic.py b/fv3core/pace/fv3core/initialization/test_cases/initialize_baroclinic.py index c3fa1de9a..ab98c23b3 100644 --- a/fv3core/pace/fv3core/initialization/test_cases/initialize_baroclinic.py +++ b/fv3core/pace/fv3core/initialization/test_cases/initialize_baroclinic.py @@ -1,13 +1,14 @@ import math +import ndsl.constants as constants +import ndsl.dsl.gt4py_utils as utils import numpy as np +from ndsl.comm.communicator import CubedSphereCommunicator +from ndsl.grid import GridData, great_circle_distance_lon_lat, lon_lat_midpoint +from ndsl.initialization.allocator import QuantityFactory -import pace.dsl.gt4py_utils as utils import pace.fv3core.initialization.init_utils as init_utils -import pace.util as fv3util -import pace.util.constants as constants from pace.fv3core.dycore_state import DycoreState -from pace.util.grid import GridData, great_circle_distance_lon_lat, lon_lat_midpoint # maximum windspeed amplitude - close to windspeed of zonal-mean time-mean @@ -19,7 +20,7 @@ SURFACE_PRESSURE = 1.0e5 # units of (Pa), from Table VI of DCMIP2016 # NOTE RADIUS = 6.3712e6 in FV3 vs Jabowski paper 6.371229e6 R = constants.RADIUS / 10.0 # Perturbation radiusfor test case 13 -NHALO = fv3util.N_HALO_DEFAULT +NHALO = constants.N_HALO_DEFAULT def apply_perturbation(u_component, up, lon, lat): @@ -245,11 +246,11 @@ def baroclinic_initialization( def init_baroclinic_state( grid_data: GridData, - quantity_factory: fv3util.QuantityFactory, + quantity_factory: QuantityFactory, adiabatic: bool, hydrostatic: bool, moist_phys: bool, - comm: fv3util.CubedSphereCommunicator, + comm: CubedSphereCommunicator, ) -> DycoreState: """ Create a DycoreState object with quantities initialized to the Jablonowski & diff --git a/fv3core/pace/fv3core/initialization/test_cases/initialize_tc.py b/fv3core/pace/fv3core/initialization/test_cases/initialize_tc.py index 33689344a..3ffa2abe8 100644 --- a/fv3core/pace/fv3core/initialization/test_cases/initialize_tc.py +++ b/fv3core/pace/fv3core/initialization/test_cases/initialize_tc.py @@ -1,14 +1,14 @@ +import ndsl.constants as constants import numpy as np +from ndsl.comm.communicator import CubedSphereCommunicator +from ndsl.grid import GridData, great_circle_distance_lon_lat +from ndsl.initialization.allocator import QuantityFactory import pace.fv3core.initialization.init_utils as init_utils -import pace.util as fv3util -import pace.util.constants as constants from pace.fv3core.dycore_state import DycoreState -from pace.util.grid import GridData, great_circle_distance_lon_lat def _calculate_distance_from_tc_center(pe_v, ps_v, muv, calc, tc_properties): - d1 = np.sin(calc["p0"][1]) * np.cos(muv["midpoint"][:, :, 1]) - np.cos( calc["p0"][1] ) * np.sin(muv["midpoint"][:, :, 1]) * np.cos( @@ -37,7 +37,6 @@ def _calculate_distance_from_tc_center(pe_v, ps_v, muv, calc, tc_properties): def _calculate_pt_height(height, qvapor, r, tc_properties, calc): - aa = height / tc_properties["zp"] bb = np.exp(aa ** tc_properties["exppz"]) cc = r / tc_properties["rp"] @@ -54,7 +53,6 @@ def _calculate_pt_height(height, qvapor, r, tc_properties, calc): def _calculate_utmp(height, dist, calc, tc_properties): - aa = height / tc_properties["zp"] # (134, 135, 79) bb = dist["r"] / tc_properties["rp"] # (134, 135) cc = aa ** tc_properties["exppz"] # (134, 135, 79) @@ -322,7 +320,6 @@ def _initialize_vortex_ps_phis(grid_data, shape, tc_properties, calc): def _initialize_qvapor_temperature(grid_data, pe, ps, tc_properties, calc, shape): - qvapor = np.zeros(shape) pt = np.zeros(shape) height = np.zeros(shape) @@ -407,7 +404,6 @@ def _initialize_wind_dgrid( def _interpolate_winds_dgrid_agrid(grid_data, ud, vd, tc_properties, shape): - ua = np.zeros(shape) va = np.zeros(shape) if tc_properties["vort"] is True: @@ -468,7 +464,6 @@ def _some_inital_calculations(tc_properties): def _initialize_delz_w(pe, ps, pt, qvapor, tc_properties, calc, shape): - delz = np.zeros(shape) w = np.zeros(shape) delz[:, :, :-1] = ( @@ -484,9 +479,9 @@ def _initialize_delz_w(pe, ps, pt, qvapor, tc_properties, calc, shape): def init_tc_state( grid_data: GridData, - quantity_factory: fv3util.QuantityFactory, + quantity_factory: QuantityFactory, hydrostatic: bool, - comm: fv3util.CubedSphereCommunicator, + comm: CubedSphereCommunicator, ) -> DycoreState: """ --WARNING--WARNING--WARNING--WARNING--WARNING--WARNING--WARNING--- diff --git a/fv3core/pace/fv3core/stencils/a2b_ord4.py b/fv3core/pace/fv3core/stencils/a2b_ord4.py index b4a748985..82f8896ca 100644 --- a/fv3core/pace/fv3core/stencils/a2b_ord4.py +++ b/fv3core/pace/fv3core/stencils/a2b_ord4.py @@ -10,14 +10,14 @@ sin, sqrt, ) +from ndsl.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import GridIndexing, StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldI, FloatFieldIJ +from ndsl.grid import GridData +from ndsl.initialization.allocator import QuantityFactory -import pace.util -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import GridIndexing, StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldI, FloatFieldIJ from pace.fv3core.stencils.basic_operations import copy_defn -from pace.util import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM -from pace.util.grid import GridData # comact 4-pt cubic interpolation @@ -534,7 +534,7 @@ class AGrid2BGridFourthOrder: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, grid_data: GridData, grid_type: int, z_dim=Z_DIM, diff --git a/fv3core/pace/fv3core/stencils/basic_operations.py b/fv3core/pace/fv3core/stencils/basic_operations.py index 85d86ad3a..883763302 100644 --- a/fv3core/pace/fv3core/stencils/basic_operations.py +++ b/fv3core/pace/fv3core/stencils/basic_operations.py @@ -1,7 +1,6 @@ import gt4py.cartesian.gtscript as gtscript from gt4py.cartesian.gtscript import PARALLEL, computation, interval - -from pace.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ def copy_defn(q_in: FloatField, q_out: FloatField): diff --git a/fv3core/pace/fv3core/stencils/c_sw.py b/fv3core/pace/fv3core/stencils/c_sw.py index e74b9319a..3c1a3cb11 100644 --- a/fv3core/pace/fv3core/stencils/c_sw.py +++ b/fv3core/pace/fv3core/stencils/c_sw.py @@ -6,15 +6,16 @@ interval, region, ) +from ndsl.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.grid import GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity +from ndsl.stencils import corners -import pace.util -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ from pace.fv3core.stencils.d2a2c_vect import DGrid2AGrid2CGridVectors -from pace.stencils import corners -from pace.util import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM -from pace.util.grid import GridData def zero_delpc_ptc(delpc: FloatField, ptc: FloatField): @@ -507,7 +508,7 @@ class CGridShallowWaterDynamics: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, grid_data: GridData, nested: bool, grid_type: int, @@ -552,7 +553,7 @@ def __init__( dord4=self._dord4, ) - def make_quantity() -> pace.util.Quantity: + def make_quantity() -> Quantity: return quantity_factory.zeros( [X_DIM, Y_DIM, Z_DIM], units="unknown", diff --git a/fv3core/pace/fv3core/stencils/d2a2c_vect.py b/fv3core/pace/fv3core/stencils/d2a2c_vect.py index 1b3e4d334..5754919f2 100644 --- a/fv3core/pace/fv3core/stencils/d2a2c_vect.py +++ b/fv3core/pace/fv3core/stencils/d2a2c_vect.py @@ -1,14 +1,14 @@ import gt4py.cartesian.gtscript as gtscript from gt4py.cartesian.gtscript import PARALLEL, computation, horizontal, interval, region +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.grid import GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.stencils import corners -import pace.util -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ from pace.fv3core.stencils.a2b_ord4 import a1, a2, lagrange_x_func, lagrange_y_func -from pace.stencils import corners -from pace.util import X_DIM, Y_DIM, Z_DIM -from pace.util.grid import GridData c1 = -2.0 / 14.0 @@ -385,7 +385,7 @@ class DGrid2AGrid2CGridVectors: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, grid_data: GridData, nested: bool, grid_type: int, diff --git a/fv3core/pace/fv3core/stencils/d_sw.py b/fv3core/pace/fv3core/stencils/d_sw.py index 319054b62..a1542f24d 100644 --- a/fv3core/pace/fv3core/stencils/d_sw.py +++ b/fv3core/pace/fv3core/stencils/d_sw.py @@ -9,12 +9,15 @@ interval, region, ) +from ndsl.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ, FloatFieldK +from ndsl.grid import DampingCoefficients, GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity import pace.fv3core.stencils.delnflux as delnflux -import pace.util -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ, FloatFieldK from pace.fv3core._config import DGridShallowWaterLagrangianDynamicsConfig from pace.fv3core.stencils.d2a2c_vect import contravariant from pace.fv3core.stencils.delnflux import DelnFluxNoSG @@ -23,8 +26,6 @@ from pace.fv3core.stencils.fxadv import FiniteVolumeFluxPrep from pace.fv3core.stencils.xtp_u import advect_u_along_x from pace.fv3core.stencils.ytp_v import advect_v_along_y -from pace.util import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM -from pace.util.grid import DampingCoefficients, GridData dcon_threshold = 1e-5 @@ -624,7 +625,7 @@ def update_u_and_v( # Set the unique parameters for the smallest # k-values, e.g. k = 0, 1, 2 when generating # the column namelist -def set_low_kvals(col: Mapping[str, pace.util.Quantity], k): +def set_low_kvals(col: Mapping[str, Quantity], k): for name in ["nord", "nord_w", "d_con"]: col[name].view[k] = 0 col["damp_w"].view[k] = col["d2_divg"].view[k] @@ -645,7 +646,7 @@ def lowest_kvals(column, k, do_vort_damp): def get_column_namelist( config: DGridShallowWaterLagrangianDynamicsConfig, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, ): """ Generate a dictionary of columns that specify how parameters (such as nord, damp) @@ -662,7 +663,7 @@ def get_column_namelist( "damp_t", "d2_divg", ] - col: Dict[str, pace.util.Quantity] = {} + col: Dict[str, Quantity] = {} for name in all_names: # TODO: fill units information col[name] = quantity_factory.zeros( @@ -748,7 +749,7 @@ class DGridShallowWaterLagrangianDynamics: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, grid_data: GridData, damping_coefficients: DampingCoefficients, column_namelist, diff --git a/fv3core/pace/fv3core/stencils/del2cubed.py b/fv3core/pace/fv3core/stencils/del2cubed.py index d4676eacb..55fde9b97 100644 --- a/fv3core/pace/fv3core/stencils/del2cubed.py +++ b/fv3core/pace/fv3core/stencils/del2cubed.py @@ -1,13 +1,13 @@ +import ndsl.stencils.corners as corners from gt4py.cartesian.gtscript import PARALLEL, computation, horizontal, interval, region +from ndsl.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory, get_stencils_with_varied_bounds +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ, cast_to_index3d +from ndsl.grid import DampingCoefficients +from ndsl.initialization.allocator import QuantityFactory -import pace.stencils.corners as corners -import pace.util -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory, get_stencils_with_varied_bounds -from pace.dsl.typing import Float, FloatField, FloatFieldIJ, cast_to_index3d from pace.fv3core.stencils.basic_operations import copy_defn -from pace.util import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM -from pace.util.grid import DampingCoefficients # @@ -83,7 +83,7 @@ class HyperdiffusionDamping: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, damping_coefficients: DampingCoefficients, rarea, nmax: int, diff --git a/fv3core/pace/fv3core/stencils/delnflux.py b/fv3core/pace/fv3core/stencils/delnflux.py index 898a8a7f7..ba6172088 100644 --- a/fv3core/pace/fv3core/stencils/delnflux.py +++ b/fv3core/pace/fv3core/stencils/delnflux.py @@ -9,25 +9,23 @@ interval, region, ) +from ndsl.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory, get_stencils_with_varied_bounds +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ, FloatFieldK +from ndsl.grid import DampingCoefficients +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity -import pace.util -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory, get_stencils_with_varied_bounds -from pace.dsl.typing import Float, FloatField, FloatFieldIJ, FloatFieldK -from pace.util import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM -from pace.util.grid import DampingCoefficients - -def calc_damp( - damp_c: pace.util.Quantity, da_min: Float, nord: pace.util.Quantity -) -> pace.util.Quantity: +def calc_damp(damp_c: Quantity, da_min: Float, nord: Quantity) -> Quantity: if damp_c.dims != nord.dims or damp_c.data.shape != nord.data.shape: raise NotImplementedError( "current implementation requires damp_c and nord to have " "identical data shape and dims" ) data = (damp_c.data * da_min) ** (nord.data + 1) - return pace.util.Quantity( + return Quantity( data=data, dims=damp_c.dims, # TODO: find and document units @@ -953,11 +951,11 @@ class DelnFlux: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, damping_coefficients: DampingCoefficients, - rarea: pace.util.Quantity, - nord_col: pace.util.Quantity, - damp_c: pace.util.Quantity, + rarea: Quantity, + nord_col: Quantity, + damp_c: Quantity, ): """ nord sets the order of damping to apply: @@ -1074,8 +1072,8 @@ def __init__( self, stencil_factory: StencilFactory, damping_coefficients: DampingCoefficients, - rarea: pace.util.Quantity, - nord: pace.util.Quantity, + rarea: Quantity, + nord: Quantity, nk: Optional[int] = None, ): """ diff --git a/fv3core/pace/fv3core/stencils/divergence_damping.py b/fv3core/pace/fv3core/stencils/divergence_damping.py index 5c63175a0..fb28a0462 100644 --- a/fv3core/pace/fv3core/stencils/divergence_damping.py +++ b/fv3core/pace/fv3core/stencils/divergence_damping.py @@ -1,4 +1,5 @@ import gt4py.cartesian.gtscript as gtscript +import ndsl.stencils.corners as corners from gt4py.cartesian.gtscript import ( __INLINED, PARALLEL, @@ -8,20 +9,20 @@ region, sqrt, ) +from ndsl.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import dace_inhibitor, orchestrate +from ndsl.dsl.stencil import StencilFactory, get_stencils_with_varied_bounds +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ, FloatFieldK +from ndsl.grid import DampingCoefficients, GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity import pace.fv3core.stencils.basic_operations as basic -import pace.stencils.corners as corners -import pace.util -from pace.dsl.dace.orchestration import dace_inhibitor, orchestrate -from pace.dsl.stencil import StencilFactory, get_stencils_with_varied_bounds -from pace.dsl.typing import Float, FloatField, FloatFieldIJ, FloatFieldK from pace.fv3core.stencils.a2b_ord4 import ( AGrid2BGridFourthOrder, doubly_periodic_a2b_ord4, ) from pace.fv3core.stencils.d2a2c_vect import contravariant -from pace.util import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM -from pace.util.grid import DampingCoefficients, GridData @gtscript.function @@ -307,7 +308,7 @@ class DivergenceDamping: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, grid_data: GridData, damping_coefficients: DampingCoefficients, nested: bool, @@ -316,7 +317,7 @@ def __init__( d4_bg, nord: int, grid_type, - nord_col: pace.util.Quantity, + nord_col: Quantity, d2_bg: FloatFieldK, ): orchestrate( diff --git a/fv3core/pace/fv3core/stencils/dyn_core.py b/fv3core/pace/fv3core/stencils/dyn_core.py index 45173c803..f3de801da 100644 --- a/fv3core/pace/fv3core/stencils/dyn_core.py +++ b/fv3core/pace/fv3core/stencils/dyn_core.py @@ -1,5 +1,6 @@ from typing import Dict, Mapping, Optional +import ndsl.constants as constants from dace.frontend.python.interface import nounroll as dace_nounroll from gt4py.cartesian.gtscript import ( __INLINED, @@ -11,6 +12,23 @@ interval, region, ) +from ndsl.checkpointer import Checkpointer, NullCheckpointer +from ndsl.comm.communicator import Communicator +from ndsl.constants import ( + X_DIM, + X_INTERFACE_DIM, + Y_DIM, + Y_INTERFACE_DIM, + Z_DIM, + Z_INTERFACE_DIM, +) +from ndsl.dsl.dace.orchestration import dace_inhibitor, orchestrate +from ndsl.dsl.dace.wrapped_halo_exchange import WrappedHaloUpdater +from ndsl.dsl.stencil import GridIndexing, StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.grid import DampingCoefficients, GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity import pace.fv3core.stencils.basic_operations as basic import pace.fv3core.stencils.d_sw as d_sw @@ -20,13 +38,6 @@ import pace.fv3core.stencils.temperature_adjust as temperature_adjust import pace.fv3core.stencils.updatedzc as updatedzc import pace.fv3core.stencils.updatedzd as updatedzd -import pace.util -import pace.util as fv3util -import pace.util.constants as constants -from pace.dsl.dace.orchestration import dace_inhibitor, orchestrate -from pace.dsl.dace.wrapped_halo_exchange import WrappedHaloUpdater -from pace.dsl.stencil import GridIndexing, StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ from pace.fv3core._config import AcousticDynamicsConfig from pace.fv3core.dycore_state import DycoreState from pace.fv3core.stencils.c_sw import CGridShallowWaterDynamics @@ -34,15 +45,6 @@ from pace.fv3core.stencils.pk3_halo import PK3Halo from pace.fv3core.stencils.riem_solver3 import NonhydrostaticVerticalSolver from pace.fv3core.stencils.riem_solver_c import NonhydrostaticVerticalSolverCGrid -from pace.util import ( - X_DIM, - X_INTERFACE_DIM, - Y_DIM, - Y_INTERFACE_DIM, - Z_DIM, - Z_INTERFACE_DIM, -) -from pace.util.grid import DampingCoefficients, GridData HUGE_R = 1.0e40 @@ -190,9 +192,9 @@ def get_nk_heat_dissipation( def dyncore_temporaries( - quantity_factory: pace.util.QuantityFactory, -) -> Mapping[str, pace.util.Quantity]: - temporaries: Dict[str, pace.util.Quantity] = {} + quantity_factory: QuantityFactory, +) -> Mapping[str, Quantity]: + temporaries: Dict[str, Quantity] = {} for name in ["ut", "vt", "gz", "zh", "pem", "pkc", "pk3", "heat_source", "cappa"]: # TODO: the dimensions of ut and vt may not be correct, # because they are not used. double-check and correct as needed. @@ -243,41 +245,41 @@ class _HaloUpdaters(object): def __init__( self, - comm: pace.util.Communicator, + comm: Communicator, grid_indexing: GridIndexing, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, state: DycoreState, - cappa: pace.util.Quantity, - gz: pace.util.Quantity, - zh: pace.util.Quantity, - divgd: pace.util.Quantity, - heat_source: pace.util.Quantity, - pkc: pace.util.Quantity, + cappa: Quantity, + gz: Quantity, + zh: Quantity, + divgd: Quantity, + heat_source: Quantity, + pkc: Quantity, ): # Define the memory specification required # Those can be re-used as they are read-only descriptors full_size_xyz_halo_spec = quantity_factory.get_quantity_halo_spec( - dims=[fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + dims=[X_DIM, Y_DIM, Z_DIM], n_halo=grid_indexing.n_halo, dtype=Float, ) full_size_xyiz_halo_spec = quantity_factory.get_quantity_halo_spec( - dims=[fv3util.X_DIM, fv3util.Y_INTERFACE_DIM, fv3util.Z_DIM], + dims=[X_DIM, Y_INTERFACE_DIM, Z_DIM], n_halo=grid_indexing.n_halo, dtype=Float, ) full_size_xiyz_halo_spec = quantity_factory.get_quantity_halo_spec( - dims=[fv3util.X_INTERFACE_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + dims=[X_INTERFACE_DIM, Y_DIM, Z_DIM], n_halo=grid_indexing.n_halo, dtype=Float, ) full_size_xyzi_halo_spec = quantity_factory.get_quantity_halo_spec( - dims=[fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_INTERFACE_DIM], + dims=[X_DIM, Y_DIM, Z_INTERFACE_DIM], n_halo=grid_indexing.n_halo, dtype=Float, ) full_size_xiyiz_halo_spec = quantity_factory.get_quantity_halo_spec( - dims=[fv3util.X_INTERFACE_DIM, fv3util.Y_INTERFACE_DIM, fv3util.Z_DIM], + dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM], n_halo=grid_indexing.n_halo, dtype=Float, ) @@ -339,7 +341,7 @@ def __init__( ) if grid_indexing.domain[0] == grid_indexing.domain[1]: full_3Dfield_2pts_halo_spec = quantity_factory.get_quantity_halo_spec( - dims=[fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_INTERFACE_DIM], + dims=[X_DIM, Y_DIM, Z_INTERFACE_DIM], n_halo=2, dtype=Float, ) @@ -364,9 +366,9 @@ def __init__( def __init__( self, - comm: pace.util.Communicator, + comm: Communicator, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, grid_data: GridData, damping_coefficients: DampingCoefficients, grid_type, @@ -376,7 +378,7 @@ def __init__( phis: FloatFieldIJ, wsd: FloatFieldIJ, state, # [DaCe] hack to get around quantity as parameters for halo updates - checkpointer: Optional[pace.util.Checkpointer] = None, + checkpointer: Optional[Checkpointer] = None, ): """ Args: @@ -424,7 +426,7 @@ def __init__( self.call_checkpointer = checkpointer is not None if checkpointer is None: - self.checkpointer: pace.util.Checkpointer = pace.util.NullCheckpointer() + self.checkpointer: Checkpointer = NullCheckpointer() else: self.checkpointer = checkpointer grid_indexing = stencil_factory.grid_indexing diff --git a/fv3core/pace/fv3core/stencils/fillz.py b/fv3core/pace/fv3core/stencils/fillz.py index 8079a202a..0a1190477 100644 --- a/fv3core/pace/fv3core/stencils/fillz.py +++ b/fv3core/pace/fv3core/stencils/fillz.py @@ -1,14 +1,14 @@ import typing from typing import Dict +import ndsl.dsl.gt4py_utils as utils from gt4py.cartesian.gtscript import BACKWARD, FORWARD, PARALLEL, computation, interval - -import pace.dsl.gt4py_utils as utils -import pace.util -from pace.dsl.dace import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ, IntFieldIJ -from pace.util import X_DIM, Y_DIM, Z_DIM +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.dace import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ, IntFieldIJ +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity @typing.no_type_check @@ -118,9 +118,9 @@ class FillNegativeTracerValues: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, nq: int, - tracers: Dict[str, pace.util.Quantity], + tracers: Dict[str, Quantity], ): orchestrate( obj=self, @@ -154,7 +154,7 @@ def __init__( def __call__( self, dp2: FloatField, - tracers: Dict[str, pace.util.Quantity], + tracers: Dict[str, Quantity], ): """ Args: diff --git a/fv3core/pace/fv3core/stencils/fv_dynamics.py b/fv3core/pace/fv3core/stencils/fv_dynamics.py index d4ef8959f..26e83d678 100644 --- a/fv3core/pace/fv3core/stencils/fv_dynamics.py +++ b/fv3core/pace/fv3core/stencils/fv_dynamics.py @@ -1,16 +1,25 @@ from datetime import timedelta from typing import Mapping, Optional +import ndsl.dsl.gt4py_utils as utils from dace.frontend.python.interface import nounroll as dace_no_unroll from gt4py.cartesian.gtscript import PARALLEL, computation, interval +from ndsl.checkpointer import Checkpointer, NullCheckpointer +from ndsl.comm.communicator import Communicator +from ndsl.comm.mpi import MPI +from ndsl.constants import KAPPA, NQ, X_DIM, Y_DIM, Z_DIM, Z_INTERFACE_DIM, ZVIR +from ndsl.dsl.dace.orchestration import dace_inhibitor, orchestrate +from ndsl.dsl.dace.wrapped_halo_exchange import WrappedHaloUpdater +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField +from ndsl.grid import DampingCoefficients, GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.logging import ndsl_log +from ndsl.performance.timer import NullTimer, Timer +from ndsl.quantity import Quantity +from ndsl.stencils.c2l_ord import CubedToLatLon -import pace.dsl.gt4py_utils as utils import pace.fv3core.stencils.moist_cv as moist_cv -import pace.util -from pace.dsl.dace.orchestration import dace_inhibitor, orchestrate -from pace.dsl.dace.wrapped_halo_exchange import WrappedHaloUpdater -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField from pace.fv3core._config import DynamicalCoreConfig from pace.fv3core.dycore_state import DycoreState from pace.fv3core.stencils import fvtp2d, tracer_2d_1l @@ -19,11 +28,6 @@ from pace.fv3core.stencils.dyn_core import AcousticDynamics from pace.fv3core.stencils.neg_adj3 import AdjustNegativeTracerMixingRatio from pace.fv3core.stencils.remapping import LagrangianToEulerian -from pace.stencils.c2l_ord import CubedToLatLon -from pace.util import X_DIM, Y_DIM, Z_INTERFACE_DIM, Timer, constants -from pace.util.grid import DampingCoefficients, GridData -from pace.util.logging import pace_log -from pace.util.mpi import MPI def pt_to_potential_density_pt( @@ -55,19 +59,19 @@ def omega_from_w(delp: FloatField, delz: FloatField, w: FloatField, omega: Float def fvdyn_temporaries( - quantity_factory: pace.util.QuantityFactory, -) -> Mapping[str, pace.util.Quantity]: + quantity_factory: QuantityFactory, +) -> Mapping[str, Quantity]: tmps = {} for name in ["te_2d", "te0_2d", "wsd"]: quantity = quantity_factory.zeros( - dims=[pace.util.X_DIM, pace.util.Y_DIM], + dims=[X_DIM, Y_DIM], units="unknown", dtype=Float, ) tmps[name] = quantity for name in ["dp1", "cvm"]: quantity = quantity_factory.zeros( - dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + dims=[X_DIM, Y_DIM, Z_DIM], units="unknown", dtype=Float, ) @@ -79,7 +83,7 @@ def fvdyn_temporaries( def log_on_rank_0(msg: str): """Print when rank is 0 - outside of DaCe critical path""" if not MPI or MPI.COMM_WORLD.Get_rank() == 0: - pace_log.info(msg) + ndsl_log.info(msg) class DynamicalCore: @@ -89,16 +93,16 @@ class DynamicalCore: def __init__( self, - comm: pace.util.Communicator, + comm: Communicator, grid_data: GridData, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, damping_coefficients: DampingCoefficients, config: DynamicalCoreConfig, - phis: pace.util.Quantity, + phis: Quantity, state: DycoreState, timestep: timedelta, - checkpointer: Optional[pace.util.Checkpointer] = None, + checkpointer: Optional[Checkpointer] = None, ): """ Args: @@ -180,7 +184,7 @@ def __init__( # have not implemented, so they are hard-coded here. self.call_checkpointer = checkpointer is not None if checkpointer is None: - self.checkpointer: pace.util.Checkpointer = pace.util.NullCheckpointer() + self.checkpointer: Checkpointer = NullCheckpointer() else: self.checkpointer = checkpointer nested = False @@ -213,7 +217,7 @@ def __init__( ) self.tracers = {} - for name in utils.tracer_variables[0 : constants.NQ]: + for name in utils.tracer_variables[0:NQ]: self.tracers[name] = state.__dict__[name] temporaries = fvdyn_temporaries(quantity_factory) @@ -294,7 +298,7 @@ def __init__( ) self._cappa = self.acoustic_dynamics.cappa - if not (not self.config.inline_q and constants.NQ != 0): + if not (not self.config.inline_q and NQ != 0): raise NotImplementedError( "Dynamical core (fv_dynamics):" "tracer_2d not implemented. z_tracer available" @@ -311,14 +315,14 @@ def __init__( quantity_factory=quantity_factory, config=config.remapping, area_64=grid_data.area_64, - nq=constants.NQ, + nq=NQ, pfull=self._pfull, tracers=self.tracers, checkpointer=checkpointer, ) full_xyz_spec = quantity_factory.get_quantity_halo_spec( - dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + dims=[X_DIM, Y_DIM, Z_DIM], n_halo=grid_indexing.n_halo, dtype=Float, ) @@ -441,7 +445,7 @@ def _checkpoint_tracer_advection_out( def step_dynamics( self, state: DycoreState, - timer: Timer = pace.util.NullTimer(), + timer: Timer = NullTimer(), ): """ Step the model state forward by one timestep. @@ -506,7 +510,7 @@ def compute_preamble(self, state: DycoreState, is_root_rank: bool): def __call__(self, *args, **kwargs): return self.step_dynamics(*args, **kwargs) - def _compute(self, state: DycoreState, timer: pace.util.Timer): + def _compute(self, state: DycoreState, timer: Timer): last_step = False self.compute_preamble( state, @@ -593,8 +597,8 @@ def _compute(self, state: DycoreState, timer: pace.util.Timer): self._bk, self._dp_initial, self._ptop, - constants.KAPPA, - constants.ZVIR, + KAPPA, + ZVIR, last_step, self._conserve_total_energy, self._timestep / self._k_split, diff --git a/fv3core/pace/fv3core/stencils/fv_subgridz.py b/fv3core/pace/fv3core/stencils/fv_subgridz.py index 908ba2960..aa7a30800 100644 --- a/fv3core/pace/fv3core/stencils/fv_subgridz.py +++ b/fv3core/pace/fv3core/stencils/fv_subgridz.py @@ -2,6 +2,7 @@ import collections import gt4py.cartesian.gtscript as gtscript +import ndsl.dsl.gt4py_utils as utils from gt4py.cartesian.gtscript import ( __INLINED, BACKWARD, @@ -9,15 +10,7 @@ computation, interval, ) - -import pace.dsl.gt4py_utils as utils -import pace.util -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField -from pace.fv3core.dycore_state import DycoreState -from pace.fv3core.stencils.basic_operations import dim -from pace.util import X_DIM, Y_DIM, Z_DIM -from pace.util.constants import ( +from ndsl.constants import ( C_ICE, C_LIQ, CP_AIR, @@ -26,8 +19,18 @@ CV_VAP, GRAV, RDGAS, + X_DIM, + Y_DIM, + Z_DIM, ZVIR, ) +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity + +from pace.fv3core.dycore_state import DycoreState +from pace.fv3core.stencils.basic_operations import dim RK = CP_AIR / RDGAS + 1.0 @@ -776,7 +779,7 @@ class DryConvectiveAdjustment: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, nwat: int, fv_sg_adj: Float, n_sponge: int, @@ -855,8 +858,8 @@ def make_quantity(): def __call__( self, state: DycoreState, - u_dt: pace.util.Quantity, - v_dt: pace.util.Quantity, + u_dt: Quantity, + v_dt: Quantity, timestep: Float, ): """ diff --git a/fv3core/pace/fv3core/stencils/fvtp2d.py b/fv3core/pace/fv3core/stencils/fvtp2d.py index 3369bcab7..f038c05db 100644 --- a/fv3core/pace/fv3core/stencils/fvtp2d.py +++ b/fv3core/pace/fv3core/stencils/fvtp2d.py @@ -1,18 +1,18 @@ from typing import Optional import gt4py.cartesian.gtscript as gtscript +import ndsl.stencils.corners as corners from gt4py.cartesian.gtscript import PARALLEL, computation, horizontal, interval, region +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.grid import DampingCoefficients, GridData +from ndsl.initialization.allocator import QuantityFactory -import pace.stencils.corners as corners -import pace.util -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ from pace.fv3core.stencils.delnflux import DelnFlux from pace.fv3core.stencils.xppm import XPiecewiseParabolic from pace.fv3core.stencils.yppm import YPiecewiseParabolic -from pace.util import X_DIM, Y_DIM, Z_DIM -from pace.util.grid import DampingCoefficients, GridData @gtscript.function @@ -129,7 +129,7 @@ class FiniteVolumeTransport: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, grid_data: GridData, damping_coefficients: DampingCoefficients, grid_type: int, diff --git a/fv3core/pace/fv3core/stencils/fxadv.py b/fv3core/pace/fv3core/stencils/fxadv.py index 1527c8983..83e7ab6b6 100644 --- a/fv3core/pace/fv3core/stencils/fxadv.py +++ b/fv3core/pace/fv3core/stencils/fxadv.py @@ -6,12 +6,12 @@ interval, region, ) +from ndsl.dsl.dace import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.grid import GridData -from pace.dsl.dace import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ from pace.fv3core.stencils.d2a2c_vect import contravariant -from pace.util.grid import GridData def main_uc_vc_contra( @@ -583,7 +583,7 @@ def __init__( ) # self._set_nans = get_set_nan_func( # grid_indexing, - # dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + # dims=[X_DIM, Y_DIM, Z_DIM], # n_halo=((2, 2), (2, 2)), # ) diff --git a/fv3core/pace/fv3core/stencils/map_single.py b/fv3core/pace/fv3core/stencils/map_single.py index 1f4395842..a6dd875e0 100644 --- a/fv3core/pace/fv3core/stencils/map_single.py +++ b/fv3core/pace/fv3core/stencils/map_single.py @@ -1,14 +1,14 @@ from typing import Optional, Sequence from gt4py.cartesian.gtscript import FORWARD, PARALLEL, computation, interval +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.dace import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ, IntFieldIJ # noqa: F401 +from ndsl.initialization.allocator import QuantityFactory -import pace.util -from pace.dsl.dace import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ, IntFieldIJ # noqa: F401 from pace.fv3core.stencils.basic_operations import copy_defn from pace.fv3core.stencils.remap_profile import RemapProfile -from pace.util import X_DIM, Y_DIM, Z_DIM def set_dp(dp1: FloatField, pe1: FloatField, lev: IntFieldIJ): @@ -89,7 +89,7 @@ class MapSingle: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, kord: int, mode: int, dims: Sequence[str], diff --git a/fv3core/pace/fv3core/stencils/mapn_tracer.py b/fv3core/pace/fv3core/stencils/mapn_tracer.py index c7c978f93..a55f875e9 100644 --- a/fv3core/pace/fv3core/stencils/mapn_tracer.py +++ b/fv3core/pace/fv3core/stencils/mapn_tracer.py @@ -1,13 +1,15 @@ from typing import Dict -import pace.dsl.gt4py_utils as utils -import pace.util -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField +import ndsl.dsl.gt4py_utils as utils +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity + from pace.fv3core.stencils.fillz import FillNegativeTracerValues from pace.fv3core.stencils.map_single import MapSingle -from pace.util import X_DIM, Y_DIM, Z_DIM class MapNTracer: @@ -18,11 +20,11 @@ class MapNTracer: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, kord: int, nq: int, fill: bool, - tracers: Dict[str, pace.util.Quantity], + tracers: Dict[str, Quantity], ): orchestrate( obj=self, @@ -66,7 +68,7 @@ def __call__( pe1: FloatField, pe2: FloatField, dp2: FloatField, - tracers: Dict[str, pace.util.Quantity], + tracers: Dict[str, Quantity], ): """ Remaps the tracer species onto the Eulerian grid diff --git a/fv3core/pace/fv3core/stencils/moist_cv.py b/fv3core/pace/fv3core/stencils/moist_cv.py index 2c8d698b6..a467d7816 100644 --- a/fv3core/pace/fv3core/stencils/moist_cv.py +++ b/fv3core/pace/fv3core/stencils/moist_cv.py @@ -1,4 +1,5 @@ import gt4py.cartesian.gtscript as gtscript +import ndsl.constants as constants from gt4py.cartesian.gtscript import ( __INLINED, PARALLEL, @@ -7,9 +8,7 @@ interval, log, ) - -import pace.util.constants as constants -from pace.dsl.typing import Float, FloatField +from ndsl.dsl.typing import Float, FloatField @gtscript.function diff --git a/fv3core/pace/fv3core/stencils/neg_adj3.py b/fv3core/pace/fv3core/stencils/neg_adj3.py index b6aa77ee2..36761756f 100644 --- a/fv3core/pace/fv3core/stencils/neg_adj3.py +++ b/fv3core/pace/fv3core/stencils/neg_adj3.py @@ -1,11 +1,10 @@ import gt4py.cartesian.gtscript as gtscript +import ndsl.constants as constants from gt4py.cartesian.gtscript import BACKWARD, FORWARD, PARALLEL, computation, interval - -import pace.util -import pace.util.constants as constants -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ -from pace.util import X_DIM, Y_DIM +from ndsl.constants import X_DIM, Y_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.initialization.allocator import QuantityFactory ZVIR = constants.RVGAS / constants.RDGAS - 1.0 @@ -335,7 +334,7 @@ class AdjustNegativeTracerMixingRatio: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, check_negative: bool, hydrostatic: bool, ): diff --git a/fv3core/pace/fv3core/stencils/nh_p_grad.py b/fv3core/pace/fv3core/stencils/nh_p_grad.py index 5504ba2b4..145d986eb 100644 --- a/fv3core/pace/fv3core/stencils/nh_p_grad.py +++ b/fv3core/pace/fv3core/stencils/nh_p_grad.py @@ -1,12 +1,12 @@ from gt4py.cartesian.gtscript import PARALLEL, computation, interval +from ndsl.constants import X_DIM, Y_DIM, Z_INTERFACE_DIM +from ndsl.dsl.dace import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.grid import GridData +from ndsl.initialization.allocator import QuantityFactory -import pace.util -from pace.dsl.dace import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ from pace.fv3core.stencils.a2b_ord4 import AGrid2BGridFourthOrder -from pace.util import X_DIM, Y_DIM, Z_INTERFACE_DIM -from pace.util.grid import GridData def set_k0_and_calc_wk( @@ -127,7 +127,7 @@ class NonHydrostaticPressureGradient: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, grid_data: GridData, grid_type, ): diff --git a/fv3core/pace/fv3core/stencils/pe_halo.py b/fv3core/pace/fv3core/stencils/pe_halo.py index e02ef01e7..48a5bb85e 100644 --- a/fv3core/pace/fv3core/stencils/pe_halo.py +++ b/fv3core/pace/fv3core/stencils/pe_halo.py @@ -1,6 +1,5 @@ from gt4py.cartesian.gtscript import FORWARD, computation, horizontal, interval, region - -from pace.dsl.typing import Float, FloatField +from ndsl.dsl.typing import Float, FloatField def edge_pe(pe: FloatField, delp: FloatField, ptop: Float): diff --git a/fv3core/pace/fv3core/stencils/pk3_halo.py b/fv3core/pace/fv3core/stencils/pk3_halo.py index 17ddaba1f..16e1ddd79 100644 --- a/fv3core/pace/fv3core/stencils/pk3_halo.py +++ b/fv3core/pace/fv3core/stencils/pk3_halo.py @@ -1,9 +1,8 @@ from gt4py.cartesian.gtscript import FORWARD, computation, horizontal, interval, region - -import pace.util -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ -from pace.util import X_DIM, Y_DIM +from ndsl.constants import X_DIM, Y_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.initialization.allocator import QuantityFactory # TODO merge with pe_halo? reuse partials? @@ -41,7 +40,7 @@ class PK3Halo: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, ): grid_indexing = stencil_factory.grid_indexing origin = grid_indexing.origin_full() diff --git a/fv3core/pace/fv3core/stencils/ppm.py b/fv3core/pace/fv3core/stencils/ppm.py index ee6a2f2da..c6d0a2c07 100644 --- a/fv3core/pace/fv3core/stencils/ppm.py +++ b/fv3core/pace/fv3core/stencils/ppm.py @@ -1,6 +1,5 @@ from gt4py.cartesian import gtscript - -from pace.dsl.typing import FloatField +from ndsl.dsl.typing import FloatField # volume-conserving cubic with 2nd drv=0 at end point: diff --git a/fv3core/pace/fv3core/stencils/ray_fast.py b/fv3core/pace/fv3core/stencils/ray_fast.py index db0a410eb..6f857d37f 100644 --- a/fv3core/pace/fv3core/stencils/ray_fast.py +++ b/fv3core/pace/fv3core/stencils/ray_fast.py @@ -1,4 +1,5 @@ import gt4py.cartesian.gtscript as gtscript +import ndsl.constants as constants from gt4py.cartesian.gtscript import ( __INLINED, BACKWARD, @@ -11,16 +12,15 @@ region, sin, ) - -import pace.util.constants as constants -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldK -from pace.util import X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.constants import X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldK SDAY = 86400.0 + # NOTE: The fortran version of this computes rf in the first timestep only. Then # rf_initialized let's you know you can skip it. Here we calculate it every # time. @@ -191,7 +191,6 @@ def __call__( dt: Float, ptop: Float, ): - rf_cutoff_nudge = self._rf_cutoff + min(100.0, 10.0 * ptop) self._ray_fast_wind_compute( diff --git a/fv3core/pace/fv3core/stencils/remap_profile.py b/fv3core/pace/fv3core/stencils/remap_profile.py index 563e9f198..ea60f7755 100644 --- a/fv3core/pace/fv3core/stencils/remap_profile.py +++ b/fv3core/pace/fv3core/stencils/remap_profile.py @@ -9,12 +9,11 @@ computation, interval, ) - -import pace.util -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import BoolField, Float, FloatField, FloatFieldIJ -from pace.util import X_DIM, Y_DIM, Z_DIM, Z_INTERFACE_DIM +from ndsl.constants import X_DIM, Y_DIM, Z_DIM, Z_INTERFACE_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import BoolField, Float, FloatField, FloatFieldIJ +from ndsl.initialization.allocator import QuantityFactory @gtscript.function @@ -571,7 +570,7 @@ class RemapProfile: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, kord: int, iv: int, dims: Sequence[str], diff --git a/fv3core/pace/fv3core/stencils/remapping.py b/fv3core/pace/fv3core/stencils/remapping.py index 50f8c1647..51fa41d1b 100644 --- a/fv3core/pace/fv3core/stencils/remapping.py +++ b/fv3core/pace/fv3core/stencils/remapping.py @@ -12,27 +12,28 @@ log, region, ) +from ndsl.checkpointer import Checkpointer +from ndsl.constants import ( + X_DIM, + X_INTERFACE_DIM, + Y_DIM, + Y_INTERFACE_DIM, + Z_DIM, + Z_INTERFACE_DIM, +) +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ, FloatFieldK +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity import pace.fv3core.stencils.moist_cv as moist_cv -import pace.util -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ, FloatFieldK from pace.fv3core._config import RemappingConfig from pace.fv3core.stencils.basic_operations import adjust_divide_stencil from pace.fv3core.stencils.map_single import MapSingle from pace.fv3core.stencils.mapn_tracer import MapNTracer from pace.fv3core.stencils.moist_cv import moist_pt_func, moist_pt_last_step from pace.fv3core.stencils.saturation_adjustment import SatAdjust3d -from pace.util import ( - X_DIM, - X_INTERFACE_DIM, - Y_DIM, - Y_INTERFACE_DIM, - Z_DIM, - Z_INTERFACE_DIM, - Quantity, -) # TODO: Should this be set here or in global_constants? @@ -291,13 +292,13 @@ class LagrangianToEulerian: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, config: RemappingConfig, area_64, nq, pfull, tracers: Dict[str, Quantity], - checkpointer: Optional[pace.util.Checkpointer] = None, + checkpointer: Optional[Checkpointer] = None, ): orchestrate( obj=self, @@ -709,7 +710,6 @@ def __call__( ) if last_step: - # on the last step, we need the regular temperature to send # to the physics, but if we're staying in dynamics we need # to keep it as the virtual potential temperature diff --git a/fv3core/pace/fv3core/stencils/riem_solver3.py b/fv3core/pace/fv3core/stencils/riem_solver3.py index 4275747ad..faf0ff0ee 100644 --- a/fv3core/pace/fv3core/stencils/riem_solver3.py +++ b/fv3core/pace/fv3core/stencils/riem_solver3.py @@ -1,6 +1,7 @@ import math import typing +import ndsl.constants as constants from gt4py.cartesian.gtscript import ( __INLINED, BACKWARD, @@ -11,15 +12,14 @@ interval, log, ) +from ndsl.constants import X_DIM, Y_DIM, Z_DIM, Z_INTERFACE_DIM +from ndsl.dsl.dace import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.initialization.allocator import QuantityFactory -import pace.util -import pace.util.constants as constants -from pace.dsl.dace import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ from pace.fv3core._config import RiemannConfig from pace.fv3core.stencils.sim1_solver import Sim1Solver -from pace.util import X_DIM, Y_DIM, Z_DIM, Z_INTERFACE_DIM @typing.no_type_check @@ -158,7 +158,7 @@ class NonhydrostaticVerticalSolver: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, config: RiemannConfig, ): grid_indexing = stencil_factory.grid_indexing diff --git a/fv3core/pace/fv3core/stencils/riem_solver_c.py b/fv3core/pace/fv3core/stencils/riem_solver_c.py index d3ab86113..2873255ee 100644 --- a/fv3core/pace/fv3core/stencils/riem_solver_c.py +++ b/fv3core/pace/fv3core/stencils/riem_solver_c.py @@ -1,5 +1,6 @@ import typing +import ndsl.constants as constants from gt4py.cartesian.gtscript import ( BACKWARD, FORWARD, @@ -8,13 +9,12 @@ interval, log, ) +from ndsl.constants import X_DIM, Y_DIM, Z_DIM, Z_INTERFACE_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.initialization.allocator import QuantityFactory -import pace.util -import pace.util.constants as constants -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ from pace.fv3core.stencils.sim1_solver import Sim1Solver -from pace.util import X_DIM, Y_DIM, Z_DIM, Z_INTERFACE_DIM @typing.no_type_check @@ -138,7 +138,7 @@ class NonhydrostaticVerticalSolverCGrid: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, p_fac: Float, ): grid_indexing = stencil_factory.grid_indexing diff --git a/fv3core/pace/fv3core/stencils/saturation_adjustment.py b/fv3core/pace/fv3core/stencils/saturation_adjustment.py index 41f3f39a5..98239f3b2 100644 --- a/fv3core/pace/fv3core/stencils/saturation_adjustment.py +++ b/fv3core/pace/fv3core/stencils/saturation_adjustment.py @@ -1,6 +1,7 @@ import math import gt4py.cartesian.gtscript as gtscript +import ndsl.constants as constants from gt4py.cartesian.gtscript import ( __INLINED, PARALLEL, @@ -10,10 +11,9 @@ interval, log, ) +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ -import pace.util.constants as constants -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ from pace.fv3core._config import SatAdjustConfig from pace.fv3core.stencils.basic_operations import dim from pace.fv3core.stencils.moist_cv import compute_pkz_func diff --git a/fv3core/pace/fv3core/stencils/sim1_solver.py b/fv3core/pace/fv3core/stencils/sim1_solver.py index 9fc322b9f..d183d6e93 100644 --- a/fv3core/pace/fv3core/stencils/sim1_solver.py +++ b/fv3core/pace/fv3core/stencils/sim1_solver.py @@ -1,5 +1,6 @@ import typing +import ndsl.constants as constants from gt4py.cartesian.gtscript import ( BACKWARD, FORWARD, @@ -9,11 +10,9 @@ interval, log, ) - -import pace.util.constants as constants -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ -from pace.util import X_DIM, Y_DIM, Z_INTERFACE_DIM +from ndsl.constants import X_DIM, Y_DIM, Z_INTERFACE_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ @typing.no_type_check diff --git a/fv3core/pace/fv3core/stencils/temperature_adjust.py b/fv3core/pace/fv3core/stencils/temperature_adjust.py index 0226df388..9e8c7819b 100644 --- a/fv3core/pace/fv3core/stencils/temperature_adjust.py +++ b/fv3core/pace/fv3core/stencils/temperature_adjust.py @@ -1,7 +1,7 @@ +import ndsl.constants as constants from gt4py.cartesian.gtscript import PARALLEL, computation, exp, interval, log +from ndsl.dsl.typing import Float, FloatField -import pace.util.constants as constants -from pace.dsl.typing import Float, FloatField from pace.fv3core.stencils.basic_operations import sign diff --git a/fv3core/pace/fv3core/stencils/tracer_2d_1l.py b/fv3core/pace/fv3core/stencils/tracer_2d_1l.py index 02bc2dd6f..b287fd862 100644 --- a/fv3core/pace/fv3core/stencils/tracer_2d_1l.py +++ b/fv3core/pace/fv3core/stencils/tracer_2d_1l.py @@ -3,15 +3,23 @@ import gt4py.cartesian.gtscript as gtscript from gt4py.cartesian.gtscript import PARALLEL, computation, horizontal, interval, region +from ndsl.comm.communicator import Communicator +from ndsl.constants import ( + N_HALO_DEFAULT, + X_DIM, + X_INTERFACE_DIM, + Y_DIM, + Y_INTERFACE_DIM, + Z_DIM, +) +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.dace.wrapped_halo_exchange import WrappedHaloUpdater +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity -import pace.dsl.gt4py_utils as utils -import pace.util -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.dace.wrapped_halo_exchange import WrappedHaloUpdater -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ from pace.fv3core.stencils.fvtp2d import FiniteVolumeTransport -from pace.util import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM @gtscript.function @@ -178,11 +186,11 @@ class TracerAdvection: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, transport: FiniteVolumeTransport, grid_data, - comm: pace.util.Communicator, - tracers: Dict[str, pace.util.Quantity], + comm: Communicator, + tracers: Dict[str, Quantity], ): orchestrate( obj=self, @@ -268,8 +276,8 @@ def __init__( # Setup halo updater for tracers tracer_halo_spec = quantity_factory.get_quantity_halo_spec( - dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], - n_halo=utils.halo, + dims=[X_DIM, Y_DIM, Z_DIM], + n_halo=N_HALO_DEFAULT, dtype=Float, ) self._tracers_halo_updater = WrappedHaloUpdater( @@ -280,7 +288,7 @@ def __init__( def __call__( self, - tracers: Dict[str, pace.util.Quantity], + tracers: Dict[str, Quantity], dp1, x_mass_flux, y_mass_flux, diff --git a/fv3core/pace/fv3core/stencils/updatedzc.py b/fv3core/pace/fv3core/stencils/updatedzc.py index 74761ea94..ad610c0af 100644 --- a/fv3core/pace/fv3core/stencils/updatedzc.py +++ b/fv3core/pace/fv3core/stencils/updatedzc.py @@ -1,12 +1,12 @@ import gt4py.cartesian.gtscript as gtscript +import ndsl.constants as constants from gt4py.cartesian.gtscript import BACKWARD, FORWARD, PARALLEL, computation, interval - -import pace.util -import pace.util.constants as constants -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ, FloatFieldK -from pace.stencils import corners -from pace.util import X_DIM, Y_DIM, Z_DIM +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ, FloatFieldK +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity +from ndsl.stencils import corners DZ_MIN = constants.DZ_MIN @@ -121,9 +121,9 @@ class UpdateGeopotentialHeightOnCGrid: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, - area: pace.util.Quantity, - dp_ref: pace.util.Quantity, + quantity_factory: QuantityFactory, + area: Quantity, + dp_ref: Quantity, grid_type, ): grid_indexing = stencil_factory.grid_indexing diff --git a/fv3core/pace/fv3core/stencils/updatedzd.py b/fv3core/pace/fv3core/stencils/updatedzd.py index 92dd1c206..c84cf5e59 100644 --- a/fv3core/pace/fv3core/stencils/updatedzd.py +++ b/fv3core/pace/fv3core/stencils/updatedzd.py @@ -1,16 +1,9 @@ from typing import Tuple import gt4py.cartesian.gtscript as gtscript +import ndsl.constants as constants from gt4py.cartesian.gtscript import BACKWARD, FORWARD, PARALLEL, computation, interval - -import pace.util -import pace.util.constants as constants -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ, FloatFieldK -from pace.fv3core.stencils.delnflux import DelnFluxNoSG -from pace.fv3core.stencils.fvtp2d import FiniteVolumeTransport -from pace.util import ( +from ndsl.constants import ( X_DIM, X_INTERFACE_DIM, Y_DIM, @@ -18,7 +11,15 @@ Z_DIM, Z_INTERFACE_DIM, ) -from pace.util.grid import DampingCoefficients, GridData +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ, FloatFieldK +from ndsl.grid import DampingCoefficients, GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity + +from pace.fv3core.stencils.delnflux import DelnFluxNoSG +from pace.fv3core.stencils.fvtp2d import FiniteVolumeTransport DZ_MIN = constants.DZ_MIN @@ -127,8 +128,8 @@ def apply_height_fluxes( def cubic_spline_interpolation_constants( - dp0: pace.util.Quantity, quantity_factory: pace.util.QuantityFactory -) -> Tuple[pace.util.Quantity, pace.util.Quantity, pace.util.Quantity]: + dp0: Quantity, quantity_factory: QuantityFactory +) -> Tuple[Quantity, Quantity, Quantity]: """ Computes constants used in cubic spline interpolation from cell center to interface levels. @@ -216,7 +217,7 @@ class UpdateHeightOnDGrid: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, damping_coefficients: DampingCoefficients, grid_data: GridData, grid_type: int, @@ -265,7 +266,7 @@ def __init__( domain=grid_indexing.domain_compute(add=(0, 0, 1)), ) - def _allocate_temporary_storages(self, quantity_factory: pace.util.QuantityFactory): + def _allocate_temporary_storages(self, quantity_factory: QuantityFactory): self._crx_interface = quantity_factory.zeros( [X_INTERFACE_DIM, Y_DIM, Z_INTERFACE_DIM], "", diff --git a/fv3core/pace/fv3core/stencils/xppm.py b/fv3core/pace/fv3core/stencils/xppm.py index afa9c2df4..4fba0dc4d 100644 --- a/fv3core/pace/fv3core/stencils/xppm.py +++ b/fv3core/pace/fv3core/stencils/xppm.py @@ -8,9 +8,9 @@ interval, region, ) +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import FloatField, FloatFieldIJ, Index3D -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import FloatField, FloatFieldIJ, Index3D from pace.fv3core.stencils import ppm from pace.fv3core.stencils.basic_operations import sign diff --git a/fv3core/pace/fv3core/stencils/xtp_u.py b/fv3core/pace/fv3core/stencils/xtp_u.py index 1b511e008..0d5e43f94 100644 --- a/fv3core/pace/fv3core/stencils/xtp_u.py +++ b/fv3core/pace/fv3core/stencils/xtp_u.py @@ -1,7 +1,7 @@ from gt4py.cartesian import gtscript from gt4py.cartesian.gtscript import __INLINED, compile_assert, horizontal, region +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ -from pace.dsl.typing import Float, FloatField, FloatFieldIJ from pace.fv3core.stencils import ppm, xppm diff --git a/fv3core/pace/fv3core/stencils/yppm.py b/fv3core/pace/fv3core/stencils/yppm.py index d61b0ca34..59f1dd39d 100644 --- a/fv3core/pace/fv3core/stencils/yppm.py +++ b/fv3core/pace/fv3core/stencils/yppm.py @@ -8,10 +8,10 @@ interval, region, ) +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import FloatField, FloatFieldIJ, Index3D -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import FloatField, FloatFieldIJ, Index3D from pace.fv3core.stencils import ppm from pace.fv3core.stencils.basic_operations import sign diff --git a/fv3core/pace/fv3core/stencils/ytp_v.py b/fv3core/pace/fv3core/stencils/ytp_v.py index 8b4cb7d3f..8e729f023 100644 --- a/fv3core/pace/fv3core/stencils/ytp_v.py +++ b/fv3core/pace/fv3core/stencils/ytp_v.py @@ -1,7 +1,7 @@ from gt4py.cartesian import gtscript from gt4py.cartesian.gtscript import __INLINED, compile_assert, horizontal, region +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ -from pace.dsl.typing import Float, FloatField, FloatFieldIJ from pace.fv3core.stencils import ppm, yppm diff --git a/fv3core/pace/fv3core/testing/map_single.py b/fv3core/pace/fv3core/testing/map_single.py index 30db7458d..8cf1fd8a3 100644 --- a/fv3core/pace/fv3core/testing/map_single.py +++ b/fv3core/pace/fv3core/testing/map_single.py @@ -1,9 +1,10 @@ from typing import Dict, Tuple -import pace.dsl -import pace.util +from ndsl.constants import X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.initialization.allocator import QuantityFactory + from pace.fv3core.stencils.map_single import MapSingle -from pace.util import X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_DIM class MapSingleFactory: @@ -12,8 +13,8 @@ class MapSingleFactory: def __init__( self, - stencil_factory: pace.dsl.StencilFactory, - quantity_factory: pace.util.QuantityFactory, + stencil_factory: StencilFactory, + quantity_factory: QuantityFactory, ): self.stencil_factory = stencil_factory self.quantity_factory = quantity_factory diff --git a/fv3core/pace/fv3core/testing/translate_dyncore.py b/fv3core/pace/fv3core/testing/translate_dyncore.py index 6c7da4b7f..e05308140 100644 --- a/fv3core/pace/fv3core/testing/translate_dyncore.py +++ b/fv3core/pace/fv3core/testing/translate_dyncore.py @@ -1,47 +1,50 @@ -import pace.dsl -import pace.dsl.gt4py_utils as utils +import ndsl.dsl.gt4py_utils as utils +from ndsl.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist +from ndsl.quantity import Quantity +from ndsl.stencils.testing import ParallelTranslate2PyState + import pace.fv3core.stencils.dyn_core as dyn_core -import pace.util from pace.fv3core import DycoreState, DynamicalCoreConfig -from pace.stencils.testing import ParallelTranslate2PyState class TranslateDynCore(ParallelTranslate2PyState): inputs = { "q_con": { - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "default", }, "cappa": { - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "default", }, "delp": { - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "default", }, "pt": { - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "K", }, "u": { - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", }, "v": { - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "uc": { - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "vc": { - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", }, "w": { - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", }, } @@ -49,8 +52,8 @@ class TranslateDynCore(ParallelTranslate2PyState): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self._base.in_vars["data_vars"] = { @@ -140,20 +143,20 @@ def compute_parallel(self, inputs, communicator): grid_data.ptop = inputs["ptop"] self._base.make_storage_data_input_vars(inputs) state = DycoreState.init_zeros(quantity_factory=self.grid.quantity_factory) - wsd: pace.util.Quantity = self.grid.quantity_factory.zeros( - dims=[pace.util.X_DIM, pace.util.Y_DIM], + wsd: Quantity = self.grid.quantity_factory.zeros( + dims=[X_DIM, Y_DIM], units="unknown", ) for name, value in inputs.items(): - if hasattr(state, name) and isinstance(state[name], pace.util.Quantity): + if hasattr(state, name) and isinstance(state[name], Quantity): # the ndarray can have buffer points at the end, so value.shape # is often not equal to state[name].shape selection = tuple(slice(0, end) for end in value.shape) state[name].data[selection] = value else: setattr(state, name, value) - phis: pace.util.Quantity = self.grid.quantity_factory.zeros( - dims=[pace.util.X_DIM, pace.util.Y_DIM], + phis: Quantity = self.grid.quantity_factory.zeros( + dims=[X_DIM, Y_DIM], units="m", ) phis.data[:] = phis.np.asarray(inputs["phis"]) @@ -178,7 +181,7 @@ def compute_parallel(self, inputs, communicator): # on variables attached to `state` storages_only = {} for name, value in vars(state).items(): - if isinstance(value, pace.util.Quantity): + if isinstance(value, Quantity): storages_only[name] = value.data else: storages_only[name] = value diff --git a/fv3core/pace/fv3core/testing/translate_fvdynamics.py b/fv3core/pace/fv3core/testing/translate_fvdynamics.py index cdd773f71..afd26d5e7 100644 --- a/fv3core/pace/fv3core/testing/translate_fvdynamics.py +++ b/fv3core/pace/fv3core/testing/translate_fvdynamics.py @@ -2,25 +2,35 @@ from datetime import timedelta from typing import Any, Dict, Optional, Tuple +import ndsl.dsl.gt4py_utils as utils import pytest +from ndsl.constants import ( + X_DIM, + X_INTERFACE_DIM, + Y_DIM, + Y_INTERFACE_DIM, + Z_DIM, + Z_INTERFACE_DIM, +) +from ndsl.dsl.stencil import StencilFactory +from ndsl.grid import GridData +from ndsl.namelist import Namelist +from ndsl.performance.timer import NullTimer +from ndsl.quantity import Quantity +from ndsl.stencils.testing import ParallelTranslateBaseSlicing +from ndsl.stencils.testing.translate import TranslateFortranData2Py -import pace.dsl -import pace.dsl.gt4py_utils as utils import pace.fv3core.stencils.fv_dynamics as fv_dynamics -import pace.util from pace.fv3core._config import DynamicalCoreConfig from pace.fv3core.dycore_state import DycoreState -from pace.stencils.testing import ParallelTranslateBaseSlicing -from pace.stencils.testing.translate import TranslateFortranData2Py -from pace.util.grid import GridData class TranslateDycoreFortranData2Py(TranslateFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, stencil_factory) self.namelist = DynamicalCoreConfig.from_namelist(namelist) @@ -31,180 +41,180 @@ class TranslateFVDynamics(ParallelTranslateBaseSlicing): inputs: Dict[str, Any] = { "q_con": { "name": "total_condensate_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "delp": { "name": "pressure_thickness_of_atmospheric_layer", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "Pa", }, "delz": { "name": "vertical_thickness_of_atmospheric_layer", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m", }, "ps": { "name": "surface_pressure", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "Pa", }, "pe": { "name": "interface_pressure", - "dims": [pace.util.X_DIM, pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Z_INTERFACE_DIM, Y_DIM], "units": "Pa", "n_halo": 1, }, "ak": { "name": "atmosphere_hybrid_a_coordinate", - "dims": [pace.util.Z_INTERFACE_DIM], + "dims": [Z_INTERFACE_DIM], "units": "Pa", }, "bk": { "name": "atmosphere_hybrid_b_coordinate", - "dims": [pace.util.Z_INTERFACE_DIM], + "dims": [Z_INTERFACE_DIM], "units": "", }, "pk": { "name": "interface_pressure_raised_to_power_of_kappa", "units": "unknown", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_INTERFACE_DIM], + "dims": [X_DIM, Y_DIM, Z_INTERFACE_DIM], "n_halo": 0, }, "pkz": { "name": "layer_mean_pressure_raised_to_power_of_kappa", "units": "unknown", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "n_halo": 0, }, "peln": { "name": "logarithm_of_interface_pressure", "units": "ln(Pa)", - "dims": [pace.util.X_DIM, pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Z_INTERFACE_DIM, Y_DIM], "n_halo": 0, }, "mfxd": { "name": "accumulated_x_mass_flux", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "unknown", "n_halo": 0, }, "mfyd": { "name": "accumulated_y_mass_flux", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "unknown", "n_halo": 0, }, "cxd": { "name": "accumulated_x_courant_number", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "", "n_halo": (0, 3), }, "cyd": { "name": "accumulated_y_courant_number", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "", "n_halo": (3, 0), }, "diss_estd": { "name": "dissipation_estimate_from_heat_source", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "unknown", }, "pt": { "name": "air_temperature", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "degK", }, "u": { "name": "x_wind", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", }, "v": { "name": "y_wind", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "ua": { "name": "eastward_wind", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "va": { "name": "northward_wind", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "uc": { "name": "x_wind_on_c_grid", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "vc": { "name": "y_wind_on_c_grid", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", }, "w": { "name": "vertical_wind", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "phis": { "name": "surface_geopotential", "units": "m^2 s^-2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], }, "qvapor": { "name": "specific_humidity", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qliquid": { "name": "cloud_water_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qice": { "name": "cloud_ice_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qrain": { "name": "rain_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qsnow": { "name": "snow_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qgraupel": { "name": "graupel_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qo3mr": { "name": "ozone_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qsgs_tke": { "name": "turbulent_kinetic_energy", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m**2/s**2", }, "qcld": { "name": "cloud_fraction", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "", }, "omga": { "name": "vertical_pressure_velocity", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "Pa/s", }, "bdt": {"dims": []}, @@ -219,8 +229,8 @@ class TranslateFVDynamics(ParallelTranslateBaseSlicing): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, *args, **kwargs, ): @@ -335,7 +345,7 @@ def compute_parallel(self, inputs, communicator): state=state, timestep=timedelta(seconds=inputs["bdt"]), ) - self.dycore.step_dynamics(state, pace.util.NullTimer()) + self.dycore.step_dynamics(state, NullTimer()) outputs = self.outputs_from_state(state) return outputs @@ -345,7 +355,7 @@ def outputs_from_state(self, state: dict): outputs = {} storages = {} for name, properties in self.outputs.items(): - if isinstance(state[name], pace.util.Quantity): + if isinstance(state[name], Quantity): storages[name] = state[name].data elif len(self.outputs[name]["dims"]) > 0: storages[name] = state[name] # assume it's a storage diff --git a/fv3core/pace/fv3core/testing/validation.py b/fv3core/pace/fv3core/testing/validation.py index 757074416..d8e8d6bed 100644 --- a/fv3core/pace/fv3core/testing/validation.py +++ b/fv3core/pace/fv3core/testing/validation.py @@ -2,11 +2,11 @@ from typing import Callable, Mapping, Tuple import numpy as np +from ndsl.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.quantity import Quantity import pace.fv3core.stencils.divergence_damping import pace.fv3core.stencils.updatedzd -from pace.util.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM -from pace.util.quantity import Quantity def get_selective_class( @@ -30,7 +30,6 @@ class SelectivelyValidated: """ def __init__(self, *args, **kwargs): - self.wrapped = cls(*args, **kwargs) self._validation_slice = {} diff --git a/fv3core/pace/fv3core/utils/functional_validation.py b/fv3core/pace/fv3core/utils/functional_validation.py index 871dcac9d..cfbe17820 100644 --- a/fv3core/pace/fv3core/utils/functional_validation.py +++ b/fv3core/pace/fv3core/utils/functional_validation.py @@ -2,8 +2,7 @@ from typing import Callable, Sequence, Tuple import numpy as np - -from pace.dsl.stencil import GridIndexing +from ndsl.dsl.stencil import GridIndexing def get_subset_func( diff --git a/fv3core/pace/fv3core/wrappers/geos_wrapper.py b/fv3core/pace/fv3core/wrappers/geos_wrapper.py index 9f8347f30..1a5fbe9c1 100644 --- a/fv3core/pace/fv3core/wrappers/geos_wrapper.py +++ b/fv3core/pace/fv3core/wrappers/geos_wrapper.py @@ -8,17 +8,28 @@ import numpy as np from gt4py.cartesian.config import build_settings as gt_build_settings from mpi4py import MPI +from ndsl.comm.comm_abc import Comm +from ndsl.comm.communicator import CubedSphereCommunicator +from ndsl.comm.null_comm import NullComm +from ndsl.comm.partitioner import CubedSpherePartitioner, TilePartitioner +from ndsl.dsl.dace import orchestrate +from ndsl.dsl.dace.build import set_distributed_caches +from ndsl.dsl.dace.dace_config import DaceConfig, DaCeOrchestration +from ndsl.dsl.gt4py_utils import is_gpu_backend +from ndsl.dsl.stencil import GridIndexing, StencilFactory +from ndsl.dsl.stencil_config import CompilationConfig, StencilConfig +from ndsl.dsl.typing import floating_point_precision +from ndsl.grid import GridData +from ndsl.grid.generation import MetricTerms +from ndsl.grid.helper import DampingCoefficients +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from ndsl.logging import ndsl_log +from ndsl.optional_imports import cupy as cp +from ndsl.performance.collector import PerformanceCollector +from ndsl.utils import safe_assign_array -import pace.util from pace import fv3core -from pace.driver.performance.collector import PerformanceCollector -from pace.dsl.dace import orchestrate -from pace.dsl.dace.build import set_distributed_caches -from pace.dsl.dace.dace_config import DaceConfig, DaCeOrchestration -from pace.dsl.gt4py_utils import is_gpu_backend -from pace.dsl.typing import floating_point_precision -from pace.util._optional_imports import cupy as cp -from pace.util.logging import pace_log class StencilBackendCompilerOverride: @@ -48,7 +59,7 @@ def __init__(self, comm: MPI.Intracomm, config: DaceConfig): # We remove warnings from the stencils compiling when in critical and/or # error - if pace_log.level > logging.WARNING: + if ndsl_log.level > logging.WARNING: gt_build_settings["extra_compile_args"]["cxx"].append("-w") gt_build_settings["extra_compile_args"]["cuda"].append("-w") @@ -56,18 +67,18 @@ def __enter__(self): if self.no_op: return if self.config.do_compile: - pace_log.info(f"Stencil backend compiles on {self.comm.Get_rank()}") + ndsl_log.info(f"Stencil backend compiles on {self.comm.Get_rank()}") else: - pace_log.info(f"Stencil backend waits on {self.comm.Get_rank()}") + ndsl_log.info(f"Stencil backend waits on {self.comm.Get_rank()}") self.comm.Barrier() def __exit__(self, type, value, traceback): if self.no_op: return if not self.config.do_compile: - pace_log.info(f"Stencil backend read cache on {self.comm.Get_rank()}") + ndsl_log.info(f"Stencil backend read cache on {self.comm.Get_rank()}") else: - pace_log.info(f"Stencil backend compiled on {self.comm.Get_rank()}") + ndsl_log.info(f"Stencil backend compiled on {self.comm.Get_rank()}") self.comm.Barrier() @@ -87,14 +98,14 @@ def __init__( self, namelist: f90nml.Namelist, bdt: int, - comm: pace.util.Comm, + comm: Comm, backend: str, fortran_mem_space: MemorySpace = MemorySpace.HOST, ): # Look for an override to run on a single node gtfv3_single_rank_override = int(os.getenv("GTFV3_SINGLE_RANK_OVERRIDE", -1)) if gtfv3_single_rank_override >= 0: - comm = pace.util.NullComm(gtfv3_single_rank_override, 6, 42) + comm = NullComm(gtfv3_single_rank_override, 6, 42) # Make a custom performance collector for the GEOS wrapper self.perf_collector = PerformanceCollector("GEOS wrapper", comm) @@ -106,32 +117,28 @@ def __init__( assert self.dycore_config.dt_atmos != 0 self.layout = self.dycore_config.layout - partitioner = pace.util.CubedSpherePartitioner( - pace.util.TilePartitioner(self.layout) - ) - self.communicator = pace.util.CubedSphereCommunicator( + partitioner = CubedSpherePartitioner(TilePartitioner(self.layout)) + self.communicator = CubedSphereCommunicator( comm, partitioner, timer=self.perf_collector.timestep_timer, ) - sizer = pace.util.SubtileGridSizer.from_namelist( + sizer = SubtileGridSizer.from_namelist( self.namelist, partitioner.tile, self.communicator.tile.rank ) - quantity_factory = pace.util.QuantityFactory.from_backend( - sizer=sizer, backend=backend - ) + quantity_factory = QuantityFactory.from_backend(sizer=sizer, backend=backend) # set up the metric terms and grid data - metric_terms = pace.util.grid.MetricTerms( + metric_terms = MetricTerms( quantity_factory=quantity_factory, communicator=self.communicator, eta_file=namelist["grid_config"]["config"]["eta_file"], ) - grid_data = pace.util.grid.GridData.new_from_metric_terms(metric_terms) + grid_data = GridData.new_from_metric_terms(metric_terms) - stencil_config = pace.dsl.stencil.StencilConfig( - compilation_config=pace.dsl.stencil.CompilationConfig( + stencil_config = StencilConfig( + compilation_config=CompilationConfig( backend=backend, rebuild=False, validate_args=False ), ) @@ -154,10 +161,10 @@ def __init__( method_to_orchestrate="_critical_path", ) - self._grid_indexing = pace.dsl.stencil.GridIndexing.from_sizer_and_communicator( + self._grid_indexing = GridIndexing.from_sizer_and_communicator( sizer=sizer, comm=self.communicator ) - stencil_factory = pace.dsl.StencilFactory( + stencil_factory = StencilFactory( config=stencil_config, grid_indexing=self._grid_indexing ) @@ -166,9 +173,7 @@ def __init__( ) self.dycore_state.bdt = self.dycore_config.dt_atmos - damping_coefficients = pace.util.grid.DampingCoefficients.new_from_metric_terms( - metric_terms - ) + damping_coefficients = DampingCoefficients.new_from_metric_terms(metric_terms) with StencilBackendCompilerOverride(MPI.COMM_WORLD, stencil_config.dace_config): self.dynamical_core = fv3core.DynamicalCore( @@ -203,7 +208,7 @@ def __init__( and is_gpu_backend(backend) and os.path.exists(f"{MPS_pipe_directory}/log") ) - pace_log.info( + ndsl_log.info( "Pace GEOS wrapper initialized: \n" f" dt : {self.dycore_state.bdt}\n" f" bridge : {self._fortran_mem_space} > {self._pace_mem_space}\n" @@ -332,62 +337,42 @@ def _put_fortran_data_in_dycore( state = self.dycore_state # Assign compute domain: - pace.util.utils.safe_assign_array(state.u.view[:], u[isc:iec, jsc : jec + 1, :]) - pace.util.utils.safe_assign_array(state.v.view[:], v[isc : iec + 1, jsc:jec, :]) - pace.util.utils.safe_assign_array(state.w.view[:], w[isc:iec, jsc:jec, :]) - pace.util.utils.safe_assign_array(state.ua.view[:], ua[isc:iec, jsc:jec, :]) - pace.util.utils.safe_assign_array(state.va.view[:], va[isc:iec, jsc:jec, :]) - pace.util.utils.safe_assign_array( - state.uc.view[:], uc[isc : iec + 1, jsc:jec, :] - ) - pace.util.utils.safe_assign_array( - state.vc.view[:], vc[isc:iec, jsc : jec + 1, :] - ) - - pace.util.utils.safe_assign_array(state.delz.view[:], delz[isc:iec, jsc:jec, :]) - pace.util.utils.safe_assign_array(state.pt.view[:], pt[isc:iec, jsc:jec, :]) - pace.util.utils.safe_assign_array(state.delp.view[:], delp[isc:iec, jsc:jec, :]) - - pace.util.utils.safe_assign_array(state.mfxd.view[:], mfxd) - pace.util.utils.safe_assign_array(state.mfyd.view[:], mfyd) - pace.util.utils.safe_assign_array(state.cxd.view[:], cxd[:, jsc:jec, :]) - pace.util.utils.safe_assign_array(state.cyd.view[:], cyd[isc:iec, :, :]) - - pace.util.utils.safe_assign_array(state.ps.view[:], ps[isc:iec, jsc:jec]) - pace.util.utils.safe_assign_array( - state.pe.data[isc - 1 : iec + 1, jsc - 1 : jec + 1, :], pe - ) - pace.util.utils.safe_assign_array(state.pk.view[:], pk) - pace.util.utils.safe_assign_array(state.peln.view[:], peln) - pace.util.utils.safe_assign_array(state.pkz.view[:], pkz) - pace.util.utils.safe_assign_array(state.phis.view[:], phis[isc:iec, jsc:jec]) - pace.util.utils.safe_assign_array( - state.q_con.view[:], q_con[isc:iec, jsc:jec, :] - ) - pace.util.utils.safe_assign_array(state.omga.view[:], omga[isc:iec, jsc:jec, :]) - pace.util.utils.safe_assign_array( - state.diss_estd.view[:], diss_estd[isc:iec, jsc:jec, :] - ) + safe_assign_array(state.u.view[:], u[isc:iec, jsc : jec + 1, :]) + safe_assign_array(state.v.view[:], v[isc : iec + 1, jsc:jec, :]) + safe_assign_array(state.w.view[:], w[isc:iec, jsc:jec, :]) + safe_assign_array(state.ua.view[:], ua[isc:iec, jsc:jec, :]) + safe_assign_array(state.va.view[:], va[isc:iec, jsc:jec, :]) + safe_assign_array(state.uc.view[:], uc[isc : iec + 1, jsc:jec, :]) + safe_assign_array(state.vc.view[:], vc[isc:iec, jsc : jec + 1, :]) + + safe_assign_array(state.delz.view[:], delz[isc:iec, jsc:jec, :]) + safe_assign_array(state.pt.view[:], pt[isc:iec, jsc:jec, :]) + safe_assign_array(state.delp.view[:], delp[isc:iec, jsc:jec, :]) + + safe_assign_array(state.mfxd.view[:], mfxd) + safe_assign_array(state.mfyd.view[:], mfyd) + safe_assign_array(state.cxd.view[:], cxd[:, jsc:jec, :]) + safe_assign_array(state.cyd.view[:], cyd[isc:iec, :, :]) + + safe_assign_array(state.ps.view[:], ps[isc:iec, jsc:jec]) + safe_assign_array(state.pe.data[isc - 1 : iec + 1, jsc - 1 : jec + 1, :], pe) + safe_assign_array(state.pk.view[:], pk) + safe_assign_array(state.peln.view[:], peln) + safe_assign_array(state.pkz.view[:], pkz) + safe_assign_array(state.phis.view[:], phis[isc:iec, jsc:jec]) + safe_assign_array(state.q_con.view[:], q_con[isc:iec, jsc:jec, :]) + safe_assign_array(state.omga.view[:], omga[isc:iec, jsc:jec, :]) + safe_assign_array(state.diss_estd.view[:], diss_estd[isc:iec, jsc:jec, :]) # tracer quantities should be a 4d array in order: # vapor, liquid, ice, rain, snow, graupel, cloud - pace.util.utils.safe_assign_array( - state.qvapor.view[:], q[isc:iec, jsc:jec, :, 0] - ) - pace.util.utils.safe_assign_array( - state.qliquid.view[:], q[isc:iec, jsc:jec, :, 1] - ) - pace.util.utils.safe_assign_array(state.qice.view[:], q[isc:iec, jsc:jec, :, 2]) - pace.util.utils.safe_assign_array( - state.qrain.view[:], q[isc:iec, jsc:jec, :, 3] - ) - pace.util.utils.safe_assign_array( - state.qsnow.view[:], q[isc:iec, jsc:jec, :, 4] - ) - pace.util.utils.safe_assign_array( - state.qgraupel.view[:], q[isc:iec, jsc:jec, :, 5] - ) - pace.util.utils.safe_assign_array(state.qcld.view[:], q[isc:iec, jsc:jec, :, 6]) + safe_assign_array(state.qvapor.view[:], q[isc:iec, jsc:jec, :, 0]) + safe_assign_array(state.qliquid.view[:], q[isc:iec, jsc:jec, :, 1]) + safe_assign_array(state.qice.view[:], q[isc:iec, jsc:jec, :, 2]) + safe_assign_array(state.qrain.view[:], q[isc:iec, jsc:jec, :, 3]) + safe_assign_array(state.qsnow.view[:], q[isc:iec, jsc:jec, :, 4]) + safe_assign_array(state.qgraupel.view[:], q[isc:iec, jsc:jec, :, 5]) + safe_assign_array(state.qcld.view[:], q[isc:iec, jsc:jec, :, 6]) return state @@ -399,102 +384,90 @@ def _prep_outputs_for_geos(self) -> Dict[str, np.ndarray]: jec = self._grid_indexing.jec + 1 if self._fortran_mem_space != self._pace_mem_space: - pace.util.utils.safe_assign_array( - output_dict["u"], self.dycore_state.u.data[:-1, :, :-1] - ) - pace.util.utils.safe_assign_array( - output_dict["v"], self.dycore_state.v.data[:, :-1, :-1] - ) - pace.util.utils.safe_assign_array( - output_dict["w"], self.dycore_state.w.data[:-1, :-1, :-1] - ) - pace.util.utils.safe_assign_array( + safe_assign_array(output_dict["u"], self.dycore_state.u.data[:-1, :, :-1]) + safe_assign_array(output_dict["v"], self.dycore_state.v.data[:, :-1, :-1]) + safe_assign_array(output_dict["w"], self.dycore_state.w.data[:-1, :-1, :-1]) + safe_assign_array( output_dict["ua"], self.dycore_state.ua.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["va"], self.dycore_state.va.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( - output_dict["uc"], self.dycore_state.uc.data[:, :-1, :-1] - ) - pace.util.utils.safe_assign_array( - output_dict["vc"], self.dycore_state.vc.data[:-1, :, :-1] - ) + safe_assign_array(output_dict["uc"], self.dycore_state.uc.data[:, :-1, :-1]) + safe_assign_array(output_dict["vc"], self.dycore_state.vc.data[:-1, :, :-1]) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["delz"], self.dycore_state.delz.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["pt"], self.dycore_state.pt.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["delp"], self.dycore_state.delp.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["mfxd"], self.dycore_state.mfxd.data[isc : iec + 1, jsc:jec, :-1], ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["mfyd"], self.dycore_state.mfyd.data[isc:iec, jsc : jec + 1, :-1], ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["cxd"], self.dycore_state.cxd.data[isc : iec + 1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["cyd"], self.dycore_state.cyd.data[:-1, jsc : jec + 1, :-1] ) - pace.util.utils.safe_assign_array( - output_dict["ps"], self.dycore_state.ps.data[:-1, :-1] - ) - pace.util.utils.safe_assign_array( + safe_assign_array(output_dict["ps"], self.dycore_state.ps.data[:-1, :-1]) + safe_assign_array( output_dict["pe"], self.dycore_state.pe.data[isc - 1 : iec + 1, jsc - 1 : jec + 1, :], ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["pk"], self.dycore_state.pk.data[isc:iec, jsc:jec, :] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["peln"], self.dycore_state.peln.data[isc:iec, jsc:jec, :] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["pkz"], self.dycore_state.pkz.data[isc:iec, jsc:jec, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["phis"], self.dycore_state.phis.data[:-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["q_con"], self.dycore_state.q_con.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["omga"], self.dycore_state.omga.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["diss_estd"], self.dycore_state.diss_estd.data[:-1, :-1, :-1], ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["qvapor"], self.dycore_state.qvapor.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["qliquid"], self.dycore_state.qliquid.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["qice"], self.dycore_state.qice.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["qrain"], self.dycore_state.qrain.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["qsnow"], self.dycore_state.qsnow.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["qgraupel"], self.dycore_state.qgraupel.data[:-1, :-1, :-1] ) - pace.util.utils.safe_assign_array( + safe_assign_array( output_dict["qcld"], self.dycore_state.qcld.data[:-1, :-1, :-1] ) else: diff --git a/fv3core/setup.py b/fv3core/setup.py index aa7093862..23b6345ad 100644 --- a/fv3core/setup.py +++ b/fv3core/setup.py @@ -11,11 +11,8 @@ requirements = [ "f90nml>=1.1.0", - "gt4py", "numpy", - "pace-util>=0.4.3", - "pace-stencils", - "pace-dsl", + "ndsl", "xarray", ] diff --git a/fv3core/tests/mpi/test_doubly_periodic.py b/fv3core/tests/mpi/test_doubly_periodic.py index 5a4e6aa6b..9b9cdff63 100644 --- a/fv3core/tests/mpi/test_doubly_periodic.py +++ b/fv3core/tests/mpi/test_doubly_periodic.py @@ -1,13 +1,19 @@ from datetime import timedelta from typing import Any, List, Tuple, cast -import pace.dsl.stencil +import ndsl.dsl.stencil +import ndsl.stencils.testing +from ndsl.comm.communicator import CubedSphereCommunicator, TileCommunicator +from ndsl.comm.mpi import MPIComm +from ndsl.comm.partitioner import TilePartitioner +from ndsl.dsl.stencil import GridIndexing +from ndsl.grid import DampingCoefficients, GridData, MetricTerms +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer + import pace.fv3core import pace.fv3core._config import pace.fv3core.initialization.baroclinic as baroclinic_init -import pace.stencils.testing -import pace.util -from pace.util.grid import DampingCoefficients, GridData, MetricTerms def setup_dycore() -> Tuple[pace.fv3core.DynamicalCore, List[Any]]: @@ -57,26 +63,26 @@ def setup_dycore() -> Tuple[pace.fv3core.DynamicalCore, List[Any]]: z_tracer=True, do_qa=True, ) - mpi_comm = pace.util.MPIComm() - partitioner = pace.util.TilePartitioner(config.layout) + mpi_comm = MPIComm() + partitioner = TilePartitioner(config.layout) # TODO: cleanup typing of tile vs cubed sphere communicators, # currently both have a .tile attribute that reference a TileCommunicator # instead both should have the methods specific to a TileCommunicator # (to be put on the Communicator abstract base class) and # the CubedSphere implementation should defer to the tile. communicator = cast( - pace.util.CubedSphereCommunicator, - pace.util.TileCommunicator(mpi_comm, partitioner), + CubedSphereCommunicator, + TileCommunicator(mpi_comm, partitioner), ) - stencil_config = pace.dsl.stencil.StencilConfig( - compilation_config=pace.dsl.stencil.CompilationConfig( + stencil_config = ndsl.dsl.stencil.StencilConfig( + compilation_config=ndsl.dsl.stencil.CompilationConfig( communicator=communicator, backend=backend, rebuild=False, validate_args=True, ) ) - sizer = pace.util.SubtileGridSizer.from_tile_params( + sizer = SubtileGridSizer.from_tile_params( nx_tile=config.npx - 1, ny_tile=config.npy - 1, nz=config.npz, @@ -86,12 +92,10 @@ def setup_dycore() -> Tuple[pace.fv3core.DynamicalCore, List[Any]]: tile_partitioner=partitioner, tile_rank=communicator.rank, ) - grid_indexing = pace.dsl.stencil.GridIndexing.from_sizer_and_communicator( + grid_indexing = GridIndexing.from_sizer_and_communicator( sizer=sizer, comm=communicator ) - quantity_factory = pace.util.QuantityFactory.from_backend( - sizer=sizer, backend=backend - ) + quantity_factory = QuantityFactory.from_backend(sizer=sizer, backend=backend) metric_terms = MetricTerms( quantity_factory=quantity_factory, communicator=communicator, @@ -108,7 +112,7 @@ def setup_dycore() -> Tuple[pace.fv3core.DynamicalCore, List[Any]]: moist_phys=config.moist_phys, comm=communicator, ) - stencil_factory = pace.dsl.stencil.StencilFactory( + stencil_factory = ndsl.dsl.stencil.StencilFactory( config=stencil_config, grid_indexing=grid_indexing, ) diff --git a/fv3core/tests/savepoint/conftest.py b/fv3core/tests/savepoint/conftest.py index 02081ab20..ae6d75adb 100644 --- a/fv3core/tests/savepoint/conftest.py +++ b/fv3core/tests/savepoint/conftest.py @@ -10,10 +10,10 @@ # this must happen before any classes from fv3core are instantiated pace.fv3core.testing.enable_selective_validation() -import pace.stencils.testing.conftest -from pace.stencils.testing.conftest import * # noqa: F403,F401 +import ndsl.stencils.testing.conftest +from ndsl.stencils.testing.conftest import * # noqa: F403,F401 from . import translate -pace.stencils.testing.conftest.translate = translate # type: ignore +ndsl.stencils.testing.conftest.translate = translate # type: ignore diff --git a/fv3core/tests/savepoint/test_translate.py b/fv3core/tests/savepoint/test_translate.py index 5550ff1f2..8dadf15a9 100644 --- a/fv3core/tests/savepoint/test_translate.py +++ b/fv3core/tests/savepoint/test_translate.py @@ -1 +1 @@ -from pace.stencils.testing.test_translate import * # noqa: F403,F401 +from ndsl.stencils.testing.test_translate import * # noqa: F403,F401 diff --git a/fv3core/tests/savepoint/translate/translate_a2b_ord4.py b/fv3core/tests/savepoint/translate/translate_a2b_ord4.py index 3cb124e53..8c6d5074a 100644 --- a/fv3core/tests/savepoint/translate/translate_a2b_ord4.py +++ b/fv3core/tests/savepoint/translate/translate_a2b_ord4.py @@ -1,9 +1,10 @@ from typing import Any, Dict -import pace.dsl -import pace.util -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory +from ndsl.constants import Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + from pace.fv3core.stencils.divergence_damping import DivergenceDamping from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -49,8 +50,8 @@ class TranslateA2B_Ord4(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) assert namelist.grid_type < 3 @@ -62,9 +63,7 @@ def __init__( self.compute_obj = A2B_Ord4Compute(stencil_factory) def compute_from_storage(self, inputs): - nord_col = self.grid.quantity_factory.zeros( - dims=[pace.util.Z_DIM], units="unknown" - ) + nord_col = self.grid.quantity_factory.zeros(dims=[Z_DIM], units="unknown") nord_col.data[:] = nord_col.np.asarray(inputs.pop("nord_col")) divdamp = DivergenceDamping( self.stencil_factory, diff --git a/fv3core/tests/savepoint/translate/translate_c_sw.py b/fv3core/tests/savepoint/translate/translate_c_sw.py index bcf4d0f4a..a6aa731ce 100644 --- a/fv3core/tests/savepoint/translate/translate_c_sw.py +++ b/fv3core/tests/savepoint/translate/translate_c_sw.py @@ -1,14 +1,16 @@ -import pace.dsl -import pace.util +from ndsl.dsl.stencil import StencilFactory +from ndsl.initialization.allocator import QuantityFactory +from ndsl.namelist import Namelist + from pace.fv3core.stencils.c_sw import CGridShallowWaterDynamics from pace.fv3core.testing import TranslateDycoreFortranData2Py def get_c_sw_instance( grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, - quantity_factory: pace.util.QuantityFactory, + namelist: Namelist, + stencil_factory: StencilFactory, + quantity_factory: QuantityFactory, ): return CGridShallowWaterDynamics( stencil_factory, @@ -71,8 +73,8 @@ class TranslateC_SW(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) cgrid_shallow_water_lagrangian_dynamics = get_c_sw_instance( @@ -117,8 +119,8 @@ class TranslateDivergenceCorner(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.max_error = 9e-10 @@ -175,8 +177,8 @@ class TranslateCirculation_Cgrid(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.max_error = 5e-9 @@ -217,8 +219,8 @@ class TranslateVorticityTransport_Cgrid(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) cgrid_sw_lagrangian_dynamics = get_c_sw_instance( diff --git a/fv3core/tests/savepoint/translate/translate_corners.py b/fv3core/tests/savepoint/translate/translate_corners.py index e5045ef5c..a426b2e30 100644 --- a/fv3core/tests/savepoint/translate/translate_corners.py +++ b/fv3core/tests/savepoint/translate/translate_corners.py @@ -1,18 +1,19 @@ from typing import Any, Dict -import pace.dsl -import pace.dsl.gt4py_utils as utils -import pace.util +import ndsl.dsl.gt4py_utils as utils +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist +from ndsl.stencils import corners + from pace.fv3core.testing import TranslateDycoreFortranData2Py -from pace.stencils import corners class TranslateFill4Corners(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = {"q4c": {}} @@ -47,8 +48,8 @@ class TranslateFillCorners(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = {"divg_d": {}, "nord_col": {}} @@ -94,8 +95,8 @@ class TranslateCopyCorners(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = {"q": {}} @@ -139,8 +140,8 @@ class TranslateFillCornersVector(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = {"vc": {}, "uc": {}, "nord_col": {}} diff --git a/fv3core/tests/savepoint/translate/translate_cubedtolatlon.py b/fv3core/tests/savepoint/translate/translate_cubedtolatlon.py index 526a61e31..54ed2f1ed 100644 --- a/fv3core/tests/savepoint/translate/translate_cubedtolatlon.py +++ b/fv3core/tests/savepoint/translate/translate_cubedtolatlon.py @@ -1,17 +1,19 @@ -import pace.dsl -import pace.util -from pace.stencils.c2l_ord import CubedToLatLon -from pace.stencils.testing import ParallelTranslate2Py +from ndsl.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist +from ndsl.quantity import Quantity +from ndsl.stencils.c2l_ord import CubedToLatLon +from ndsl.stencils.testing import ParallelTranslate2Py class TranslateCubedToLatLon(ParallelTranslate2Py): inputs = { "u": { - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", }, "v": { - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", }, } @@ -19,8 +21,8 @@ class TranslateCubedToLatLon(ParallelTranslate2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self._base.in_vars["data_vars"] = {"u": {}, "v": {}, "ua": {}, "va": {}} @@ -62,7 +64,7 @@ def compute_parallel(self, inputs, communicator): def _quantity_wrap(storage, dims, grid_indexing): origin, extent = grid_indexing.get_origin_domain(dims) - return pace.util.Quantity( + return Quantity( storage, dims=dims, units="unknown", diff --git a/fv3core/tests/savepoint/translate/translate_d2a2c_vect.py b/fv3core/tests/savepoint/translate/translate_d2a2c_vect.py index 89534085a..c35721c32 100644 --- a/fv3core/tests/savepoint/translate/translate_d2a2c_vect.py +++ b/fv3core/tests/savepoint/translate/translate_d2a2c_vect.py @@ -1,5 +1,6 @@ -import pace.dsl -import pace.util +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + from pace.fv3core.stencils.d2a2c_vect import DGrid2AGrid2CGridVectors from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -8,8 +9,8 @@ class TranslateD2A2C_Vect(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) dord4 = True diff --git a/fv3core/tests/savepoint/translate/translate_d_sw.py b/fv3core/tests/savepoint/translate/translate_d_sw.py index be8a9d2bb..3e19e61f0 100644 --- a/fv3core/tests/savepoint/translate/translate_d_sw.py +++ b/fv3core/tests/savepoint/translate/translate_d_sw.py @@ -1,10 +1,10 @@ from gt4py.cartesian.gtscript import PARALLEL, computation, interval +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import FloatField, FloatFieldIJ +from ndsl.namelist import Namelist -import pace.dsl import pace.fv3core.stencils.d_sw as d_sw -import pace.util from pace import fv3core -from pace.dsl.typing import FloatField, FloatFieldIJ from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -12,8 +12,8 @@ class TranslateD_SW(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.max_error = 3.2e-10 @@ -85,8 +85,8 @@ class TranslateUbKE(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { @@ -132,8 +132,8 @@ class TranslateVbKE(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { @@ -163,8 +163,8 @@ class TranslateFluxCapacitor(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { @@ -192,8 +192,8 @@ class TranslateHeatDiss(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { @@ -236,8 +236,8 @@ class TranslateWdivergence(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { diff --git a/fv3core/tests/savepoint/translate/translate_del2cubed.py b/fv3core/tests/savepoint/translate/translate_del2cubed.py index 2dfd0f558..b50c677f0 100644 --- a/fv3core/tests/savepoint/translate/translate_del2cubed.py +++ b/fv3core/tests/savepoint/translate/translate_del2cubed.py @@ -1,7 +1,8 @@ from typing import Any, Dict -import pace.dsl -import pace.util +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + from pace.fv3core.stencils.del2cubed import HyperdiffusionDamping from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -10,8 +11,8 @@ class TranslateDel2Cubed(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = {"qdel": {}} diff --git a/fv3core/tests/savepoint/translate/translate_del6vtflux.py b/fv3core/tests/savepoint/translate/translate_del6vtflux.py index 5df4e4fc0..31fc42a13 100644 --- a/fv3core/tests/savepoint/translate/translate_del6vtflux.py +++ b/fv3core/tests/savepoint/translate/translate_del6vtflux.py @@ -1,6 +1,8 @@ -import pace.dsl +from ndsl.constants import Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + import pace.fv3core.stencils.delnflux as delnflux -import pace.util from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -8,8 +10,8 @@ class TranslateDel6VtFlux(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) fxstat = grid.x3d_domain_dict() @@ -36,9 +38,7 @@ def __init__( # use_sg -- 'dx', 'dy', 'rdxc', 'rdyc', 'sin_sg needed def compute(self, inputs): self.make_storage_data_input_vars(inputs) - nord_col = self.grid.quantity_factory.zeros( - dims=[pace.util.Z_DIM], units="unknown" - ) + nord_col = self.grid.quantity_factory.zeros(dims=[Z_DIM], units="unknown") nord_col.data[:] = nord_col.np.asarray(inputs.pop("nord_w")) self.compute_func = delnflux.DelnFluxNoSG( # type: ignore self.stencil_factory, diff --git a/fv3core/tests/savepoint/translate/translate_delnflux.py b/fv3core/tests/savepoint/translate/translate_delnflux.py index a3112fa35..3442e5af4 100644 --- a/fv3core/tests/savepoint/translate/translate_delnflux.py +++ b/fv3core/tests/savepoint/translate/translate_delnflux.py @@ -1,6 +1,8 @@ -import pace.dsl +from ndsl.constants import Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + import pace.fv3core.stencils.delnflux as delnflux -import pace.util from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -8,8 +10,8 @@ class TranslateDelnFlux(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { @@ -29,13 +31,9 @@ def compute(self, inputs): if "mass" not in inputs: inputs["mass"] = None self.make_storage_data_input_vars(inputs) - nord_col = self.grid.quantity_factory.zeros( - dims=[pace.util.Z_DIM], units="unknown" - ) + nord_col = self.grid.quantity_factory.zeros(dims=[Z_DIM], units="unknown") nord_col.data[:] = nord_col.np.asarray(inputs.pop("nord_column")) - damp_c = self.grid.quantity_factory.zeros( - dims=[pace.util.Z_DIM], units="unknown" - ) + damp_c = self.grid.quantity_factory.zeros(dims=[Z_DIM], units="unknown") damp_c.data[:] = damp_c.np.asarray(inputs.pop("damp_c")) self.compute_func = delnflux.DelnFlux( # type: ignore self.stencil_factory, @@ -53,8 +51,8 @@ class TranslateDelnFlux_2(TranslateDelnFlux): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) del self.in_vars["data_vars"]["mass"] diff --git a/fv3core/tests/savepoint/translate/translate_divergencedamping.py b/fv3core/tests/savepoint/translate/translate_divergencedamping.py index 26e4c3d0d..0d4cb80fd 100644 --- a/fv3core/tests/savepoint/translate/translate_divergencedamping.py +++ b/fv3core/tests/savepoint/translate/translate_divergencedamping.py @@ -1,7 +1,9 @@ from typing import Optional -import pace.dsl -import pace.util +from ndsl.constants import Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + from pace.fv3core.stencils.divergence_damping import DivergenceDamping from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -10,8 +12,8 @@ class TranslateDivergenceDamping(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { @@ -40,13 +42,9 @@ def __init__( self.namelist = namelist # type: ignore def compute_from_storage(self, inputs): - nord_col = self.grid.quantity_factory.zeros( - dims=[pace.util.Z_DIM], units="unknown" - ) + nord_col = self.grid.quantity_factory.zeros(dims=[Z_DIM], units="unknown") nord_col.data[:] = nord_col.np.asarray(inputs.pop("nord_col")) - d2_bg = self.grid.quantity_factory.zeros( - dims=[pace.util.Z_DIM], units="unknown" - ) + d2_bg = self.grid.quantity_factory.zeros(dims=[Z_DIM], units="unknown") d2_bg.data[:] = d2_bg.np.asarray(inputs.pop("d2_bg")) self.divdamp = DivergenceDamping( self.stencil_factory, diff --git a/fv3core/tests/savepoint/translate/translate_fillz.py b/fv3core/tests/savepoint/translate/translate_fillz.py index b90c7c5be..489e388f1 100644 --- a/fv3core/tests/savepoint/translate/translate_fillz.py +++ b/fv3core/tests/savepoint/translate/translate_fillz.py @@ -1,20 +1,20 @@ +import ndsl.dsl.gt4py_utils as utils import numpy as np +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist +from ndsl.stencils.testing import pad_field_in_j +from ndsl.utils import safe_assign_array -import pace.dsl -import pace.dsl.gt4py_utils as utils import pace.fv3core.stencils.fillz as fillz -import pace.util from pace.fv3core.testing import TranslateDycoreFortranData2Py -from pace.stencils.testing import pad_field_in_j -from pace.util.utils import safe_assign_array class TranslateFillz(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { diff --git a/fv3core/tests/savepoint/translate/translate_fvsubgridz.py b/fv3core/tests/savepoint/translate/translate_fvsubgridz.py index fdc0bc550..e7f297a63 100644 --- a/fv3core/tests/savepoint/translate/translate_fvsubgridz.py +++ b/fv3core/tests/savepoint/translate/translate_fvsubgridz.py @@ -1,11 +1,12 @@ from types import SimpleNamespace -import pace.dsl -import pace.dsl.gt4py_utils as utils +import ndsl.dsl.gt4py_utils as utils +from ndsl.constants import X_DIM, Y_DIM, Z_DIM, Z_INTERFACE_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist +from ndsl.stencils.testing import ParallelTranslateBaseSlicing + import pace.fv3core.stencils.fv_subgridz as fv_subgridz -import pace.util -import pace.util as fv3util -from pace.stencils.testing import ParallelTranslateBaseSlicing # NOTE, does no halo updates, does not need to be a Parallel test, @@ -15,105 +16,105 @@ class TranslateFVSubgridZ(ParallelTranslateBaseSlicing): inputs = { "delp": { "name": "pressure_thickness_of_atmospheric_layer", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "Pa", }, "delz": { "name": "vertical_thickness_of_atmospheric_layer", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m", }, "pe": { "name": "interface_pressure", - "dims": [fv3util.X_DIM, fv3util.Z_INTERFACE_DIM, fv3util.Y_DIM], + "dims": [X_DIM, Z_INTERFACE_DIM, Y_DIM], "units": "Pa", "n_halo": 1, }, "pkz": { "name": "layer_mean_pressure_raised_to_power_of_kappa", "units": "unknown", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "n_halo": 0, }, "peln": { "name": "logarithm_of_interface_pressure", "units": "ln(Pa)", - "dims": [fv3util.X_DIM, fv3util.Z_INTERFACE_DIM, fv3util.Y_DIM], + "dims": [X_DIM, Z_INTERFACE_DIM, Y_DIM], "n_halo": 0, }, "pt": { "name": "air_temperature", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "degK", }, "ua": { "name": "eastward_wind", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "va": { "name": "northward_wind", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "w": { "name": "vertical_wind", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "qvapor": { "name": "specific_humidity", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qliquid": { "name": "cloud_water_mixing_ratio", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qice": { "name": "cloud_ice_mixing_ratio", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qrain": { "name": "rain_mixing_ratio", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qsnow": { "name": "snow_mixing_ratio", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qgraupel": { "name": "graupel_mixing_ratio", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qo3mr": { "name": "ozone_mixing_ratio", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", }, "qsgs_tke": { "name": "turbulent_kinetic_energy", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m**2/s**2", }, "qcld": { "name": "cloud_fraction", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "", }, "u_dt": { "name": "eastward_wind_tendency_due_to_physics", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s**2", }, "v_dt": { "name": "northward_wind_tendency_due_to_physics", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s**2", }, "dt": {"dims": []}, @@ -126,8 +127,8 @@ class TranslateFVSubgridZ(ParallelTranslateBaseSlicing): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, *args, **kwargs, ): diff --git a/fv3core/tests/savepoint/translate/translate_fvtp2d.py b/fv3core/tests/savepoint/translate/translate_fvtp2d.py index b807254d1..1dab6e64f 100644 --- a/fv3core/tests/savepoint/translate/translate_fvtp2d.py +++ b/fv3core/tests/savepoint/translate/translate_fvtp2d.py @@ -1,7 +1,9 @@ -import pace.dsl -import pace.dsl.gt4py_utils as utils -import pace.util -from pace.dsl.typing import Float +import ndsl.dsl.gt4py_utils as utils +from ndsl.constants import Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float +from ndsl.namelist import Namelist + from pace.fv3core.stencils.fvtp2d import FiniteVolumeTransport from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -10,8 +12,8 @@ class TranslateFvTp2d(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { @@ -52,11 +54,11 @@ def compute_from_storage(self, inputs): backend=self.stencil_factory.backend, ) nord_col = self.grid.quantity_factory.zeros( - dims=[pace.util.Z_DIM], units="unknown", dtype=Float + dims=[Z_DIM], units="unknown", dtype=Float ) nord_col.data[:] = nord_col.np.asarray(inputs.pop("nord")) damp_c = self.grid.quantity_factory.zeros( - dims=[pace.util.Z_DIM], units="unknown", dtype=Float + dims=[Z_DIM], units="unknown", dtype=Float ) damp_c.data[:] = damp_c.np.asarray(inputs.pop("damp_c")) for optional_arg in ["mass"]: @@ -80,8 +82,8 @@ class TranslateFvTp2d_2(TranslateFvTp2d): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) del self.in_vars["data_vars"]["mass"] diff --git a/fv3core/tests/savepoint/translate/translate_fxadv.py b/fv3core/tests/savepoint/translate/translate_fxadv.py index 3dec82930..d28a01cc6 100644 --- a/fv3core/tests/savepoint/translate/translate_fxadv.py +++ b/fv3core/tests/savepoint/translate/translate_fxadv.py @@ -1,7 +1,8 @@ import numpy as np +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist -import pace.dsl -import pace.util from pace.fv3core.stencils.fxadv import FiniteVolumeFluxPrep from pace.fv3core.testing import TranslateDycoreFortranData2Py from pace.fv3core.utils.functional_validation import get_subset_func @@ -11,8 +12,8 @@ class TranslateFxAdv(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) utinfo = grid.x3d_domain_dict() @@ -51,7 +52,7 @@ def __init__( self._subset = get_subset_func( self.grid.grid_indexing, - dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + dims=[X_DIM, Y_DIM, Z_DIM], n_halo=((2, 2), (2, 2)), ) diff --git a/fv3core/tests/savepoint/translate/translate_grid.py b/fv3core/tests/savepoint/translate/translate_grid.py index b625b47be..a4f56811e 100644 --- a/fv3core/tests/savepoint/translate/translate_grid.py +++ b/fv3core/tests/savepoint/translate/translate_grid.py @@ -1,30 +1,35 @@ from typing import Any, Dict +import ndsl.dsl.gt4py_utils as utils import numpy as np import pytest - -import pace.dsl -import pace.dsl.gt4py_utils as utils -import pace.util -from pace.stencils.testing.parallel_translate import ParallelTranslateGrid -from pace.util.grid import MetricTerms, set_hybrid_pressure_coefficients -from pace.util.grid.global_setup import global_mirror_grid, gnomonic_grid +from ndsl.constants import ( + X_DIM, + X_INTERFACE_DIM, + Y_DIM, + Y_INTERFACE_DIM, + Z_INTERFACE_DIM, +) +from ndsl.dsl.stencil import StencilFactory +from ndsl.grid import MetricTerms, set_hybrid_pressure_coefficients +from ndsl.grid.global_setup import global_mirror_grid, gnomonic_grid +from ndsl.namelist import Namelist +from ndsl.stencils.testing.parallel_translate import ParallelTranslateGrid class TranslateGnomonicGrids(ParallelTranslateGrid): - max_error = 2e-14 inputs = { "lon": { "name": "longitude_on_cell_corners", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "radians", "n_halo": 0, }, "lat": { "name": "latitude_on_cell_corners", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "radians", "n_halo": 0, }, @@ -32,13 +37,13 @@ class TranslateGnomonicGrids(ParallelTranslateGrid): outputs = { "lon": { "name": "longitude_on_cell_corners", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "radians", "n_halo": 0, }, "lat": { "name": "latitude_on_cell_corners", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "radians", "n_halo": 0, }, @@ -65,13 +70,12 @@ def compute(self, inputs): class TranslateMirrorGrid(ParallelTranslateGrid): - inputs = { "master_grid_global": { "name": "grid_global", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, MetricTerms.TILE_DIM, ], @@ -86,8 +90,8 @@ class TranslateMirrorGrid(ParallelTranslateGrid): "master_grid_global": { "name": "grid_global", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, MetricTerms.TILE_DIM, ], @@ -122,8 +126,8 @@ class TranslateGridAreas(ParallelTranslateGrid): def __init__( self, rank_grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(rank_grids, namelist, stencil_factory) self.max_error = 1e-10 @@ -136,77 +140,77 @@ def __init__( "grid": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, ], "units": "radians", }, "agrid": { "name": "agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.LON_OR_LAT_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.LON_OR_LAT_DIM], "units": "radians", }, "area": { "name": "area", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "m^2", }, "area_c": { "name": "area_cgrid", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "m^2", }, "dxa": { "name": "dx_agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "m", }, "dya": { "name": "dy_agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "m", }, "dxc": { "name": "dx_cgrid", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "m", }, "dyc": { "name": "dy_cgrid", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "m", }, } outputs = { "area": { "name": "area", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "m^2", }, "area_c": { "name": "area_cgrid", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "m^2", }, "dxa": { "name": "dx_agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "m", }, "dya": { "name": "dy_agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "m", }, "dxc": { "name": "dx_cgrid", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "m", }, "dyc": { "name": "dy_cgrid", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "m", }, } @@ -231,14 +235,13 @@ def compute_parallel(self, inputs, communicator): class TranslateGridGrid(ParallelTranslateGrid): - max_error = 1e-14 inputs: Dict[str, Any] = { "grid_global": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, MetricTerms.TILE_DIM, ], @@ -249,8 +252,8 @@ class TranslateGridGrid(ParallelTranslateGrid): "grid": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, ], "units": "radians", @@ -260,8 +263,8 @@ class TranslateGridGrid(ParallelTranslateGrid): def __init__( self, grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grids, namelist, stencil_factory) self.max_error = 1.0e-13 @@ -290,8 +293,8 @@ class TranslateDxDy(ParallelTranslateGrid): def __init__( self, rank_grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(rank_grids, namelist, stencil_factory) self.max_error = 3e-14 @@ -302,8 +305,8 @@ def __init__( "grid": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, ], "units": "radians", @@ -312,12 +315,12 @@ def __init__( outputs = { "dx": { "name": "dx", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "m", }, "dy": { "name": "dy", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "m", }, } @@ -344,8 +347,8 @@ class TranslateAGrid(ParallelTranslateGrid): def __init__( self, rank_grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(rank_grids, namelist, stencil_factory) self.max_error = 1e-13 @@ -355,14 +358,14 @@ def __init__( inputs = { "agrid": { "name": "agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.LON_OR_LAT_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.LON_OR_LAT_DIM], "units": "radians", }, "grid": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, ], "units": "radians", @@ -371,14 +374,14 @@ def __init__( outputs = { "agrid": { "name": "agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.LON_OR_LAT_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.LON_OR_LAT_DIM], "units": "radians", }, "grid": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, ], "units": "radians", @@ -436,55 +439,55 @@ class TranslateInitGrid(ParallelTranslateGrid): "gridvar": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, ], "units": "radians", }, "agrid": { "name": "agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.LON_OR_LAT_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.LON_OR_LAT_DIM], "units": "radians", }, "area": { "name": "area", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "m^2", }, "area_c": { "name": "area_cgrid", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "m^2", }, "dx": { "name": "dx", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "m", }, "dy": { "name": "dy", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "m", }, "dxc": { "name": "dx_cgrid", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "m", }, "dyc": { "name": "dy_cgrid", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "m", }, "dxa": { "name": "dx_agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "m", }, "dya": { "name": "dy_agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "m", }, } @@ -492,8 +495,8 @@ class TranslateInitGrid(ParallelTranslateGrid): def __init__( self, grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grids, namelist, stencil_factory) self.max_error = 3e-12 @@ -535,12 +538,12 @@ class TranslateSetEta(ParallelTranslateGrid): }, "ak": { "name": "ak", - "dims": [pace.util.Z_INTERFACE_DIM], + "dims": [Z_INTERFACE_DIM], "units": "mb", }, "bk": { "name": "bk", - "dims": [pace.util.Z_INTERFACE_DIM], + "dims": [Z_INTERFACE_DIM], "units": "", }, } @@ -552,12 +555,12 @@ class TranslateSetEta(ParallelTranslateGrid): }, "ak": { "name": "ak", - "dims": [pace.util.Z_INTERFACE_DIM], + "dims": [Z_INTERFACE_DIM], "units": "mb", }, "bk": { "name": "bk", - "dims": [pace.util.Z_INTERFACE_DIM], + "dims": [Z_INTERFACE_DIM], "units": "", }, } @@ -589,8 +592,8 @@ class TranslateUtilVectors(ParallelTranslateGrid): def __init__( self, grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grids, namelist, stencil_factory) self.max_error = 3e-12 @@ -636,33 +639,33 @@ def __init__( "grid": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, ], "units": "radians", }, "agrid": { "name": "agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.LON_OR_LAT_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.LON_OR_LAT_DIM], "units": "radians", }, "ec1": { "name": "ec1", - "dims": [MetricTerms.CARTESIAN_DIM, pace.util.X_DIM, pace.util.Y_DIM], + "dims": [MetricTerms.CARTESIAN_DIM, X_DIM, Y_DIM], "units": "", }, "ec2": { "name": "ec2", - "dims": [MetricTerms.CARTESIAN_DIM, pace.util.X_DIM, pace.util.Y_DIM], + "dims": [MetricTerms.CARTESIAN_DIM, X_DIM, Y_DIM], "units": "", }, "ew1": { "name": "ew1", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_INTERFACE_DIM, - pace.util.Y_DIM, + X_INTERFACE_DIM, + Y_DIM, ], "units": "", }, @@ -670,8 +673,8 @@ def __init__( "name": "ew2", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_INTERFACE_DIM, - pace.util.Y_DIM, + X_INTERFACE_DIM, + Y_DIM, ], "units": "", }, @@ -679,8 +682,8 @@ def __init__( "name": "es1", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_DIM, - pace.util.Y_INTERFACE_DIM, + X_DIM, + Y_INTERFACE_DIM, ], "units": "", }, @@ -688,8 +691,8 @@ def __init__( "name": "es2", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_DIM, - pace.util.Y_INTERFACE_DIM, + X_DIM, + Y_INTERFACE_DIM, ], "units": "", }, @@ -697,20 +700,20 @@ def __init__( outputs: Dict[str, Any] = { "ec1": { "name": "ec1", - "dims": [MetricTerms.CARTESIAN_DIM, pace.util.X_DIM, pace.util.Y_DIM], + "dims": [MetricTerms.CARTESIAN_DIM, X_DIM, Y_DIM], "units": "", }, "ec2": { "name": "ec2", - "dims": [MetricTerms.CARTESIAN_DIM, pace.util.X_DIM, pace.util.Y_DIM], + "dims": [MetricTerms.CARTESIAN_DIM, X_DIM, Y_DIM], "units": "", }, "ew1": { "name": "ew1", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_INTERFACE_DIM, - pace.util.Y_DIM, + X_INTERFACE_DIM, + Y_DIM, ], "units": "", }, @@ -718,8 +721,8 @@ def __init__( "name": "ew2", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_INTERFACE_DIM, - pace.util.Y_DIM, + X_INTERFACE_DIM, + Y_DIM, ], "units": "", }, @@ -727,8 +730,8 @@ def __init__( "name": "es1", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_DIM, - pace.util.Y_INTERFACE_DIM, + X_DIM, + Y_INTERFACE_DIM, ], "units": "", }, @@ -736,8 +739,8 @@ def __init__( "name": "es2", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_DIM, - pace.util.Y_INTERFACE_DIM, + X_DIM, + Y_INTERFACE_DIM, ], "units": "", }, @@ -766,8 +769,8 @@ class TranslateTrigSg(ParallelTranslateGrid): def __init__( self, grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grids, namelist, stencil_factory) self.max_error = 2.5e-10 @@ -804,207 +807,207 @@ def __init__( "grid": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, ], "units": "", }, "agrid": { "name": "agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.LON_OR_LAT_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.LON_OR_LAT_DIM], "units": "radians", }, "cos_sg1": { "name": "cos_sg1", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg1": { "name": "sin_sg1", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg2": { "name": "cos_sg2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg2": { "name": "sin_sg2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg3": { "name": "cos_sg3", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg3": { "name": "sin_sg3", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg4": { "name": "cos_sg4", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg4": { "name": "sin_sg4", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg5": { "name": "cos_sg5", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg5": { "name": "sin_sg5", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg6": { "name": "cos_sg6", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg6": { "name": "sin_sg6", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg7": { "name": "cos_sg7", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg7": { "name": "sin_sg7", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg8": { "name": "cos_sg8", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg8": { "name": "sin_sg8", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg9": { "name": "cos_sg9", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg9": { "name": "sin_sg9", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "ec1": { "name": "ec1", - "dims": [MetricTerms.CARTESIAN_DIM, pace.util.X_DIM, pace.util.Y_DIM], + "dims": [MetricTerms.CARTESIAN_DIM, X_DIM, Y_DIM], "units": "", }, "ec2": { "name": "ec2", - "dims": [MetricTerms.CARTESIAN_DIM, pace.util.X_DIM, pace.util.Y_DIM], + "dims": [MetricTerms.CARTESIAN_DIM, X_DIM, Y_DIM], "units": "", }, } outputs: Dict[str, Any] = { "cos_sg1": { "name": "cos_sg1", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg1": { "name": "sin_sg1", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg2": { "name": "cos_sg2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg2": { "name": "sin_sg2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg3": { "name": "cos_sg3", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg3": { "name": "sin_sg3", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg4": { "name": "cos_sg4", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg4": { "name": "sin_sg4", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg5": { "name": "cos_sg5", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg5": { "name": "sin_sg5", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg6": { "name": "cos_sg6", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg6": { "name": "sin_sg6", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg7": { "name": "cos_sg7", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg7": { "name": "sin_sg7", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg8": { "name": "cos_sg8", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg8": { "name": "sin_sg8", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg9": { "name": "cos_sg9", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg9": { "name": "sin_sg9", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, } @@ -1038,8 +1041,8 @@ class TranslateAAMCorrection(ParallelTranslateGrid): def __init__( self, rank_grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(rank_grids, namelist, stencil_factory) self.max_error = 1e-14 @@ -1052,21 +1055,21 @@ def __init__( "grid": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, ], "units": "radians", }, "l2c_v": { "name": "l2c_v", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", "n_halo": 0, }, "l2c_u": { "name": "l2c_u", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", "n_halo": 0, }, @@ -1074,13 +1077,13 @@ def __init__( outputs: Dict[str, Any] = { "l2c_v": { "name": "l2c_v", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", "n_halo": 0, }, "l2c_u": { "name": "l2c_u", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", "n_halo": 0, }, @@ -1108,8 +1111,8 @@ class TranslateDerivedTrig(ParallelTranslateGrid): def __init__( self, grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grids, namelist, stencil_factory) self.max_error = 8.5e-14 @@ -1132,108 +1135,108 @@ def __init__( "grid": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, ], "units": "radians", }, "cos_sg1": { "name": "cos_sg1", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg1": { "name": "sin_sg1", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg2": { "name": "cos_sg2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg2": { "name": "sin_sg2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg3": { "name": "cos_sg3", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg3": { "name": "sin_sg3", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg4": { "name": "cos_sg4", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg4": { "name": "sin_sg4", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg5": { "name": "cos_sg5", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg5": { "name": "sin_sg5", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg6": { "name": "cos_sg6", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg6": { "name": "sin_sg6", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg7": { "name": "cos_sg7", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg7": { "name": "sin_sg7", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg8": { "name": "cos_sg8", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg8": { "name": "sin_sg8", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg9": { "name": "cos_sg9", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg9": { "name": "sin_sg9", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "ee1": { "name": "ee1", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, ], "units": "", }, @@ -1241,65 +1244,65 @@ def __init__( "name": "ee2", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, ], "units": "", }, "cosa_u": { "name": "cosa_u", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "cosa_v": { "name": "cosa_v", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "cosa_s": { "name": "cosa_s", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sina_u": { "name": "sina_u", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "sina_v": { "name": "sina_v", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "rsin_u": { "name": "rsin_u", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "rsin_v": { "name": "rsin_v", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "rsina": { "name": "rsina", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "", "n_halo": 0, }, "rsin2": { "name": "rsin2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cosa": { "name": "cosa", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "", }, "sina": { "name": "sina", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "", }, } @@ -1308,8 +1311,8 @@ def __init__( "name": "ee1", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, ], "units": "", }, @@ -1317,65 +1320,65 @@ def __init__( "name": "ee2", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, ], "units": "", }, "cosa_u": { "name": "cosa_u", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "cosa_v": { "name": "cosa_v", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "cosa_s": { "name": "cosa_s", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sina_u": { "name": "sina_u", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "sina_v": { "name": "sina_v", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "rsin_u": { "name": "rsin_u", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "rsin_v": { "name": "rsin_v", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "rsina": { "name": "rsina", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "", "n_halo": 0, }, "rsin2": { "name": "rsin2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cosa": { "name": "cosa", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "", }, "sina": { "name": "sina", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "", }, } @@ -1421,8 +1424,8 @@ class TranslateDivgDel6(ParallelTranslateGrid): def __init__( self, rank_grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(rank_grids, namelist, stencil_factory) self.max_error = 4e-14 @@ -1432,94 +1435,94 @@ def __init__( inputs: Dict[str, Any] = { "sin_sg1": { "name": "sin_sg1", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg2": { "name": "sin_sg2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg3": { "name": "sin_sg3", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg4": { "name": "sin_sg4", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sina_u": { "name": "sina_u", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "sina_v": { "name": "sina_v", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "dx": { "name": "dx", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "m", }, "dy": { "name": "dy", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "m", }, "dxc": { "name": "dx_cgrid", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "m", }, "dyc": { "name": "dy_cgrid", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "divg_u": { "name": "divg_u", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "divg_v": { "name": "divg_v", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "m", }, "del6_u": { "name": "del6_u", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "del6_v": { "name": "del6_v", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, } outputs: Dict[str, Any] = { "divg_u": { "name": "divg_u", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "divg_v": { "name": "divg_v", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "del6_u": { "name": "del6_u", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "del6_v": { "name": "del6_v", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, } @@ -1556,8 +1559,8 @@ class TranslateInitCubedtoLatLon(ParallelTranslateGrid): def __init__( self, grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grids, namelist, stencil_factory) self.max_error = 3.0e-14 @@ -1577,83 +1580,83 @@ def __init__( inputs: Dict[str, Any] = { "agrid": { "name": "agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.LON_OR_LAT_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.LON_OR_LAT_DIM], "units": "radians", }, "ec1": { "name": "ec1", - "dims": [MetricTerms.CARTESIAN_DIM, pace.util.X_DIM, pace.util.Y_DIM], + "dims": [MetricTerms.CARTESIAN_DIM, X_DIM, Y_DIM], "units": "", }, "ec2": { "name": "ec2", - "dims": [MetricTerms.CARTESIAN_DIM, pace.util.X_DIM, pace.util.Y_DIM], + "dims": [MetricTerms.CARTESIAN_DIM, X_DIM, Y_DIM], "units": "", }, "sin_sg5": { "name": "sin_sg5", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, } outputs: Dict[str, Any] = { "vlon": { "name": "vlon", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.CARTESIAN_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.CARTESIAN_DIM], "units": "", "n_halo": 2, }, "vlat": { "name": "vlat", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.CARTESIAN_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.CARTESIAN_DIM], "units": "", "n_halo": 2, }, "z11": { "name": "z11", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "z12": { "name": "z12", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "z21": { "name": "z21", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "z22": { "name": "z22", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "a11": { "name": "a11", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "a12": { "name": "a12", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "a21": { "name": "a21", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "a22": { "name": "a22", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, @@ -1684,8 +1687,8 @@ class TranslateEdgeFactors(ParallelTranslateGrid): def __init__( self, rank_grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(rank_grids, namelist, stencil_factory) self.max_error = 3e-13 @@ -1696,105 +1699,105 @@ def __init__( "grid": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, ], "units": "radians", }, "agrid": { "name": "agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.LON_OR_LAT_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.LON_OR_LAT_DIM], "units": "radians", }, "edge_s": { "name": "edge_s", - "dims": [pace.util.X_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM], "units": "", "n_halo": 0, }, "edge_n": { "name": "edge_n", - "dims": [pace.util.X_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM], "units": "", "n_halo": 0, }, "edge_e": { "name": "edge_e", - "dims": [pace.util.Y_INTERFACE_DIM], + "dims": [Y_INTERFACE_DIM], "units": "", "n_halo": 0, }, "edge_w": { "name": "edge_w", - "dims": [pace.util.Y_INTERFACE_DIM], + "dims": [Y_INTERFACE_DIM], "units": "", "n_halo": 0, }, "edge_vect_s": { "name": "edge_vect_s", - "dims": [pace.util.X_DIM], + "dims": [X_DIM], "units": "", }, "edge_vect_n": { "name": "edge_vect_n", - "dims": [pace.util.X_DIM], + "dims": [X_DIM], "units": "", }, "edge_vect_e": { "name": "edge_vect_e", - "dims": [pace.util.Y_DIM], + "dims": [Y_DIM], "units": "", }, "edge_vect_w": { "name": "edge_vect_w", - "dims": [pace.util.Y_DIM], + "dims": [Y_DIM], "units": "", }, } outputs: Dict[str, Any] = { "edge_s": { "name": "edge_s", - "dims": [pace.util.X_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM], "units": "", "n_halo": 0, }, "edge_n": { "name": "edge_n", - "dims": [pace.util.X_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM], "units": "", "n_halo": 0, }, "edge_e": { "name": "edge_e", - "dims": [pace.util.Y_INTERFACE_DIM], + "dims": [Y_INTERFACE_DIM], "units": "", "n_halo": 0, }, "edge_w": { "name": "edge_w", - "dims": [pace.util.Y_INTERFACE_DIM], + "dims": [Y_INTERFACE_DIM], "units": "", "n_halo": 0, }, "edge_vect_s": { "name": "edge_vect_s", - "dims": [pace.util.X_DIM], + "dims": [X_DIM], "units": "", }, "edge_vect_n": { "name": "edge_vect_n", - "dims": [pace.util.X_DIM], + "dims": [X_DIM], "units": "", }, "edge_vect_e": { "name": "edge_vect_e", - "dims": [pace.util.Y_DIM], + "dims": [Y_DIM], "units": "", }, "edge_vect_w": { "name": "edge_vect_w", - "dims": [pace.util.Y_DIM], + "dims": [Y_DIM], "units": "", }, } @@ -1823,8 +1826,8 @@ class TranslateInitGridUtils(ParallelTranslateGrid): def __init__( self, grids, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grids, namelist, stencil_factory) self.max_error = 2.5e-10 @@ -1888,55 +1891,55 @@ def __init__( "gridvar": { "name": "grid", "dims": [ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, MetricTerms.LON_OR_LAT_DIM, ], "units": "radians", }, "agrid": { "name": "agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.LON_OR_LAT_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.LON_OR_LAT_DIM], "units": "radians", }, "area": { "name": "area", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "m^2", }, "area_c": { "name": "area_cgrid", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "m^2", }, "dx": { "name": "dx", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "m", }, "dy": { "name": "dy", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "m", }, "dxc": { "name": "dx_cgrid", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "m", }, "dyc": { "name": "dy_cgrid", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "m", }, "dxa": { "name": "dx_agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "m", }, "dya": { "name": "dy_agrid", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "m", }, "npz": { @@ -1958,30 +1961,30 @@ def __init__( }, "ak": { "name": "ak", - "dims": [pace.util.Z_INTERFACE_DIM], + "dims": [Z_INTERFACE_DIM], "units": "mb", }, "bk": { "name": "bk", - "dims": [pace.util.Z_INTERFACE_DIM], + "dims": [Z_INTERFACE_DIM], "units": "", }, "ec1": { "name": "ec1", - "dims": [MetricTerms.CARTESIAN_DIM, pace.util.X_DIM, pace.util.Y_DIM], + "dims": [MetricTerms.CARTESIAN_DIM, X_DIM, Y_DIM], "units": "", }, "ec2": { "name": "ec2", - "dims": [MetricTerms.CARTESIAN_DIM, pace.util.X_DIM, pace.util.Y_DIM], + "dims": [MetricTerms.CARTESIAN_DIM, X_DIM, Y_DIM], "units": "", }, "ew1": { "name": "ew1", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_INTERFACE_DIM, - pace.util.Y_DIM, + X_INTERFACE_DIM, + Y_DIM, ], "units": "", }, @@ -1989,8 +1992,8 @@ def __init__( "name": "ew2", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_INTERFACE_DIM, - pace.util.Y_DIM, + X_INTERFACE_DIM, + Y_DIM, ], "units": "", }, @@ -1998,8 +2001,8 @@ def __init__( "name": "es1", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_DIM, - pace.util.Y_INTERFACE_DIM, + X_DIM, + Y_INTERFACE_DIM, ], "units": "", }, @@ -2007,110 +2010,110 @@ def __init__( "name": "es2", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_DIM, - pace.util.Y_INTERFACE_DIM, + X_DIM, + Y_INTERFACE_DIM, ], "units": "", }, "cos_sg1": { "name": "cos_sg1", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg1": { "name": "sin_sg1", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg2": { "name": "cos_sg2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg2": { "name": "sin_sg2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg3": { "name": "cos_sg3", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg3": { "name": "sin_sg3", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg4": { "name": "cos_sg4", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg4": { "name": "sin_sg4", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg5": { "name": "cos_sg5", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg5": { "name": "sin_sg5", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg6": { "name": "cos_sg6", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg6": { "name": "sin_sg6", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg7": { "name": "cos_sg7", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg7": { "name": "sin_sg7", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg8": { "name": "cos_sg8", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg8": { "name": "sin_sg8", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cos_sg9": { "name": "cos_sg9", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sin_sg9": { "name": "sin_sg9", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "l2c_v": { "name": "l2c_v", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", "n_halo": 0, }, "l2c_u": { "name": "l2c_u", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", "n_halo": 0, }, @@ -2118,8 +2121,8 @@ def __init__( "name": "ee1", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, ], "units": "", }, @@ -2127,165 +2130,165 @@ def __init__( "name": "ee2", "dims": [ MetricTerms.CARTESIAN_DIM, - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, ], "units": "", }, "cosa_u": { "name": "cosa_u", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "cosa_v": { "name": "cosa_v", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "cosa_s": { "name": "cosa_s", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "sina_u": { "name": "sina_u", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "sina_v": { "name": "sina_v", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "rsin_u": { "name": "rsin_u", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "rsin_v": { "name": "rsin_v", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "rsina": { "name": "rsina", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "", "n_halo": 0, }, "rsin2": { "name": "rsin2", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", }, "cosa": { "name": "cosa", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "", }, "sina": { "name": "sina", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_INTERFACE_DIM, Y_INTERFACE_DIM], "units": "", }, "divg_u": { "name": "divg_u", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "divg_v": { "name": "divg_v", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "del6_u": { "name": "del6_u", - "dims": [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM], "units": "", }, "del6_v": { "name": "del6_v", - "dims": [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM], "units": "", }, "vlon": { "name": "vlon", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.CARTESIAN_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.CARTESIAN_DIM], "units": "", "n_halo": 2, }, "vlat": { "name": "vlat", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, MetricTerms.CARTESIAN_DIM], + "dims": [X_DIM, Y_DIM, MetricTerms.CARTESIAN_DIM], "units": "", "n_halo": 2, }, "z11": { "name": "z11", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "z12": { "name": "z12", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "z21": { "name": "z21", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "z22": { "name": "z22", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "a11": { "name": "a11", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "a12": { "name": "a12", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "a21": { "name": "a21", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "a22": { "name": "a22", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "", "n_halo": 1, }, "edge_vect_s": { "name": "edge_vect_s", - "dims": [pace.util.X_DIM], + "dims": [X_DIM], "units": "", }, "edge_vect_n": { "name": "edge_vect_n", - "dims": [pace.util.X_DIM], + "dims": [X_DIM], "units": "", }, "edge_vect_e": { "name": "edge_vect_e", - "dims": [pace.util.Y_DIM], + "dims": [Y_DIM], "units": "", }, "edge_vect_w": { "name": "edge_vect_w", - "dims": [pace.util.Y_DIM], + "dims": [Y_DIM], "units": "", }, "da_min": { diff --git a/fv3core/tests/savepoint/translate/translate_haloupdate.py b/fv3core/tests/savepoint/translate/translate_haloupdate.py index e0a66f165..c510125ec 100644 --- a/fv3core/tests/savepoint/translate/translate_haloupdate.py +++ b/fv3core/tests/savepoint/translate/translate_haloupdate.py @@ -1,28 +1,34 @@ -import pace.dsl -import pace.util -import pace.util as fv3util -from pace.dsl import gt4py_utils as utils -from pace.stencils.testing import ParallelTranslate -from pace.util.logging import pace_log +from ndsl.constants import ( + N_HALO_DEFAULT, + X_DIM, + X_INTERFACE_DIM, + Y_DIM, + Y_INTERFACE_DIM, + Z_DIM, + Z_INTERFACE_DIM, +) +from ndsl.dsl.stencil import StencilFactory +from ndsl.logging import ndsl_log +from ndsl.namelist import Namelist +from ndsl.stencils.testing import ParallelTranslate class TranslateHaloUpdate(ParallelTranslate): - inputs = { "array": { "name": "air_temperature", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "degK", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, } } outputs = { "array": { "name": "air_temperature", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "degK", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, } } halo_update_varname = "air_temperature" @@ -30,15 +36,15 @@ class TranslateHaloUpdate(ParallelTranslate): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) def compute_parallel(self, inputs, communicator): state = self.state_from_inputs(inputs) req = communicator.start_halo_update( - state[self.halo_update_varname], n_points=utils.halo + state[self.halo_update_varname], n_points=N_HALO_DEFAULT ) req.wait() return self.outputs_from_state(state) @@ -47,35 +53,34 @@ def compute_sequential(self, inputs_list, communicator_list): state_list = self.state_list_from_inputs_list(inputs_list) req_list = [] for state, communicator in zip(state_list, communicator_list): - pace_log.debug(f"starting on {communicator.rank}") + ndsl_log.debug(f"starting on {communicator.rank}") req_list.append( communicator.start_halo_update( - state[self.halo_update_varname], n_points=utils.halo + state[self.halo_update_varname], n_points=N_HALO_DEFAULT ) ) for communicator, req in zip(communicator_list, req_list): - pace_log.debug(f"finishing on {communicator.rank}") + ndsl_log.debug(f"finishing on {communicator.rank}") req.wait() return self.outputs_list_from_state_list(state_list) class TranslateHaloUpdate_2(TranslateHaloUpdate): - inputs = { "array2": { "name": "height_on_interface_levels", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_INTERFACE_DIM], + "dims": [X_DIM, Y_DIM, Z_INTERFACE_DIM], "units": "m", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, } } outputs = { "array2": { "name": "height_on_interface_levels", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_INTERFACE_DIM], + "dims": [X_DIM, Y_DIM, Z_INTERFACE_DIM], "units": "m", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, } } @@ -83,22 +88,21 @@ class TranslateHaloUpdate_2(TranslateHaloUpdate): class TranslateMPPUpdateDomains(TranslateHaloUpdate): - inputs = { "update_arr": { "name": "z_wind_as_tendency_of_pressure", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "Pa/s", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, } } outputs = { "update_arr": { "name": "z_wind_as_tendency_of_pressure", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "Pa/s", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, } } @@ -106,53 +110,54 @@ class TranslateMPPUpdateDomains(TranslateHaloUpdate): class TranslateHaloVectorUpdate(ParallelTranslate): - inputs = { "array_u": { "name": "x_wind_on_c_grid", - "dims": [fv3util.X_INTERFACE_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, }, "array_v": { "name": "y_wind_on_c_grid", - "dims": [fv3util.X_DIM, fv3util.Y_INTERFACE_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, }, } outputs = { "array_u": { "name": "x_wind_on_c_grid", - "dims": [fv3util.X_INTERFACE_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, }, "array_v": { "name": "y_wind_on_c_grid", - "dims": [fv3util.X_DIM, fv3util.Y_INTERFACE_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, }, } def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super(TranslateHaloVectorUpdate, self).__init__(grid, namelist, stencil_factory) def compute_parallel(self, inputs, communicator): - pace_log.debug(f"starting on {communicator.rank}") + ndsl_log.debug(f"starting on {communicator.rank}") state = self.state_from_inputs(inputs) req = communicator.start_vector_halo_update( - state["x_wind_on_c_grid"], state["y_wind_on_c_grid"], n_points=utils.halo + state["x_wind_on_c_grid"], + state["y_wind_on_c_grid"], + n_points=N_HALO_DEFAULT, ) - pace_log.debug(f"finishing on {communicator.rank}") + ndsl_log.debug(f"finishing on {communicator.rank}") req.wait() return self.outputs_from_state(state) @@ -160,69 +165,68 @@ def compute_sequential(self, inputs_list, communicator_list): state_list = self.state_list_from_inputs_list(inputs_list) req_list = [] for state, communicator in zip(state_list, communicator_list): - pace_log.debug(f"starting on {communicator.rank}") + ndsl_log.debug(f"starting on {communicator.rank}") req_list.append( communicator.start_vector_halo_update( state["x_wind_on_c_grid"], state["y_wind_on_c_grid"], - n_points=utils.halo, + n_points=N_HALO_DEFAULT, ) ) for communicator, req in zip(communicator_list, req_list): - pace_log.debug(f"finishing on {communicator.rank}") + ndsl_log.debug(f"finishing on {communicator.rank}") req.wait() return self.outputs_list_from_state_list(state_list) class TranslateMPPBoundaryAdjust(ParallelTranslate): - inputs = { "u": { "name": "x_wind_on_d_grid", - "dims": [fv3util.X_DIM, fv3util.Y_INTERFACE_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, }, "v": { "name": "y_wind_on_d_grid", - "dims": [fv3util.X_INTERFACE_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, }, } outputs = { "u": { "name": "x_wind_on_d_grid", - "dims": [fv3util.X_DIM, fv3util.Y_INTERFACE_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, }, "v": { "name": "y_wind_on_d_grid", - "dims": [fv3util.X_INTERFACE_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", - "n_halo": utils.halo, + "n_halo": N_HALO_DEFAULT, }, } def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super(TranslateMPPBoundaryAdjust, self).__init__( grid, namelist, stencil_factory ) def compute_parallel(self, inputs, communicator): - pace_log.debug(f"starting on {communicator.rank}") + ndsl_log.debug(f"starting on {communicator.rank}") state = self.state_from_inputs(inputs) req = communicator.start_synchronize_vector_interfaces( state["x_wind_on_d_grid"], state["y_wind_on_d_grid"] ) - pace_log.debug(f"finishing on {communicator.rank}") + ndsl_log.debug(f"finishing on {communicator.rank}") req.wait() return self.outputs_from_state(state) @@ -236,6 +240,6 @@ def compute_sequential(self, inputs_list, communicator_list): ) ) for communicator, req in zip(communicator_list, req_list): - pace_log.debug(f"finishing on {communicator.rank}") + ndsl_log.debug(f"finishing on {communicator.rank}") req.wait() return self.outputs_list_from_state_list(state_list) diff --git a/fv3core/tests/savepoint/translate/translate_init_case.py b/fv3core/tests/savepoint/translate/translate_init_case.py index 906555299..db0aa3986 100644 --- a/fv3core/tests/savepoint/translate/translate_init_case.py +++ b/fv3core/tests/savepoint/translate/translate_init_case.py @@ -1,110 +1,122 @@ from typing import Any, Dict +import ndsl.constants as constants +import ndsl.dsl.gt4py_utils as utils import numpy as np import pytest +from ndsl.constants import ( + N_HALO_DEFAULT, + X_DIM, + X_INTERFACE_DIM, + Y_DIM, + Y_INTERFACE_DIM, + Z_DIM, + Z_INTERFACE_DIM, +) +from ndsl.dsl.stencil import StencilFactory +from ndsl.grid import GridData, MetricTerms +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from ndsl.namelist import Namelist +from ndsl.quantity import Quantity +from ndsl.stencils.testing import ParallelTranslateBaseSlicing +from ndsl.stencils.testing.grid import TRACER_DIM # type: ignore -import pace.dsl -import pace.dsl.gt4py_utils as utils import pace.fv3core.initialization.analytic_init as analytic_init import pace.fv3core.initialization.init_utils as init_utils import pace.fv3core.initialization.test_cases.initialize_baroclinic as baroclinic_init -import pace.util -import pace.util as fv3util from pace.fv3core.testing import TranslateDycoreFortranData2Py -from pace.stencils.testing import ParallelTranslateBaseSlicing -from pace.stencils.testing.grid import TRACER_DIM # type: ignore -from pace.util.grid import GridData, MetricTerms class TranslateInitCase(ParallelTranslateBaseSlicing): outputs: Dict[str, Any] = { "u": { "name": "x_wind", - "dims": [fv3util.X_DIM, fv3util.Y_INTERFACE_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", }, "v": { "name": "y_wind", - "dims": [fv3util.X_INTERFACE_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "ua": { "name": "eastward_wind", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "va": { "name": "northward_wind", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "uc": { "name": "x_wind_on_c_grid", - "dims": [fv3util.X_INTERFACE_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_INTERFACE_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "vc": { "name": "y_wind_on_c_grid", - "dims": [fv3util.X_DIM, fv3util.Y_INTERFACE_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_INTERFACE_DIM, Z_DIM], "units": "m/s", }, "w": { "name": "vertical_wind", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", }, "phis": { "name": "surface_geopotential", "units": "m^2 s^-2", - "dims": [fv3util.X_DIM, fv3util.Y_DIM], + "dims": [X_DIM, Y_DIM], }, "delp": { "name": "pressure_thickness_of_atmospheric_layer", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "Pa", }, "delz": { "name": "vertical_thickness_of_atmospheric_layer", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m", }, "ps": { "name": "surface_pressure", - "dims": [fv3util.X_DIM, fv3util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "Pa", }, "pe": { "name": "interface_pressure", - "dims": [fv3util.X_DIM, fv3util.Z_INTERFACE_DIM, fv3util.Y_DIM], + "dims": [X_DIM, Z_INTERFACE_DIM, Y_DIM], "units": "Pa", "n_halo": 1, }, "pk": { "name": "interface_pressure_raised_to_power_of_kappa", "units": "unknown", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_INTERFACE_DIM], + "dims": [X_DIM, Y_DIM, Z_INTERFACE_DIM], "n_halo": 0, }, "pkz": { "name": "layer_mean_pressure_raised_to_power_of_kappa", "units": "unknown", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "n_halo": 0, }, "peln": { "name": "logarithm_of_interface_pressure", "units": "ln(Pa)", - "dims": [fv3util.X_DIM, fv3util.Z_INTERFACE_DIM, fv3util.Y_DIM], + "dims": [X_DIM, Z_INTERFACE_DIM, Y_DIM], "n_halo": 0, }, "pt": { "name": "air_temperature", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "degK", }, "q4d": { "name": "tracers", - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM, TRACER_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM, TRACER_DIM], "units": "kg/kg", }, } @@ -112,8 +124,8 @@ class TranslateInitCase(ParallelTranslateBaseSlicing): def __init__( self, grid_list, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid_list, namelist, stencil_factory) grid = grid_list[0] @@ -184,11 +196,11 @@ def compute_parallel(self, inputs, communicator): state = {} full_shape = ( *self.grid.domain_shape_full(add=(1, 1, 1)), - pace.util.constants.NQ, + constants.NQ, ) for variable, properties in self.outputs.items(): dims = properties["dims"] - state[variable] = fv3util.Quantity( + state[variable] = Quantity( np.zeros(full_shape[0 : len(dims)]), dims, properties["units"], @@ -205,23 +217,23 @@ def compute_parallel(self, inputs, communicator): backend=self.stencil_factory.backend, ) - sizer = pace.util.SubtileGridSizer.from_tile_params( + sizer = SubtileGridSizer.from_tile_params( nx_tile=self.namelist.nx_tile, ny_tile=self.namelist.nx_tile, nz=self.namelist.nz, - n_halo=pace.util.N_HALO_DEFAULT, + n_halo=N_HALO_DEFAULT, extra_dim_lengths={}, layout=self.namelist.layout, tile_partitioner=communicator.partitioner.tile, tile_rank=communicator.tile.rank, ) - quantity_factory = pace.util.QuantityFactory.from_backend( + quantity_factory = QuantityFactory.from_backend( sizer, backend=self.stencil_factory.backend ) grid_data = GridData.new_from_metric_terms(metric_terms) - quantity_factory = fv3util.QuantityFactory() + quantity_factory = QuantityFactory() state = analytic_init.init_analytic_state( analytic_init_case="baroclinic", @@ -257,8 +269,8 @@ class TranslateInitPreJab(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = {"ak": {}, "bk": {}, "delp": {}} @@ -316,8 +328,8 @@ class TranslateJablonowskiBaroclinic(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { @@ -398,8 +410,8 @@ class TranslatePVarAuxiliaryPressureVars(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { diff --git a/fv3core/tests/savepoint/translate/translate_last_step.py b/fv3core/tests/savepoint/translate/translate_last_step.py index bebb525cb..934dbb197 100644 --- a/fv3core/tests/savepoint/translate/translate_last_step.py +++ b/fv3core/tests/savepoint/translate/translate_last_step.py @@ -1,6 +1,7 @@ -import pace.dsl +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + import pace.fv3core.stencils.moist_cv as moist_cv -import pace.util from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -8,8 +9,8 @@ class TranslateLastStep(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.compute_func = stencil_factory.from_origin_domain( # type: ignore diff --git a/fv3core/tests/savepoint/translate/translate_moistcvpluspkz_2d.py b/fv3core/tests/savepoint/translate/translate_moistcvpluspkz_2d.py index 26dff791c..cc60fc0c6 100644 --- a/fv3core/tests/savepoint/translate/translate_moistcvpluspkz_2d.py +++ b/fv3core/tests/savepoint/translate/translate_moistcvpluspkz_2d.py @@ -1,9 +1,10 @@ +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import FloatField +from ndsl.namelist import Namelist +from ndsl.stencils.testing import pad_field_in_j + import pace.fv3core.stencils.moist_cv as moist_cv -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import FloatField from pace.fv3core.testing import TranslateDycoreFortranData2Py -from pace.stencils.testing import pad_field_in_j -from pace.util import Namelist class MoistPKZ: @@ -40,7 +41,6 @@ def __call__( delz: FloatField, r_vir: float, ): - self._moist_cv_pkz( qvapor, qliquid, diff --git a/fv3core/tests/savepoint/translate/translate_moistcvpluspt_2d.py b/fv3core/tests/savepoint/translate/translate_moistcvpluspt_2d.py index c0d2c937b..2edb43eeb 100644 --- a/fv3core/tests/savepoint/translate/translate_moistcvpluspt_2d.py +++ b/fv3core/tests/savepoint/translate/translate_moistcvpluspt_2d.py @@ -1,9 +1,9 @@ from gt4py.cartesian.gtscript import PARALLEL, computation, interval +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import FloatField +from ndsl.stencils.testing import TranslateFortranData2Py, pad_field_in_j import pace.fv3core.stencils.moist_cv as moist_cv -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import FloatField -from pace.stencils.testing import TranslateFortranData2Py, pad_field_in_j def moist_pt( diff --git a/fv3core/tests/savepoint/translate/translate_neg_adj3.py b/fv3core/tests/savepoint/translate/translate_neg_adj3.py index fb05fd637..775ad529e 100644 --- a/fv3core/tests/savepoint/translate/translate_neg_adj3.py +++ b/fv3core/tests/savepoint/translate/translate_neg_adj3.py @@ -1,8 +1,9 @@ from typing import Any, Dict -import pace.dsl -import pace.dsl.gt4py_utils as utils -import pace.util +import ndsl.dsl.gt4py_utils as utils +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + from pace.fv3core.stencils.neg_adj3 import AdjustNegativeTracerMixingRatio from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -11,8 +12,8 @@ class TranslateNeg_Adj3(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { diff --git a/fv3core/tests/savepoint/translate/translate_nh_p_grad.py b/fv3core/tests/savepoint/translate/translate_nh_p_grad.py index 6047a0950..e07b36b37 100644 --- a/fv3core/tests/savepoint/translate/translate_nh_p_grad.py +++ b/fv3core/tests/savepoint/translate/translate_nh_p_grad.py @@ -1,6 +1,7 @@ -import pace.dsl +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + import pace.fv3core.stencils.nh_p_grad as NH_P_Grad -import pace.util from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -10,8 +11,8 @@ class TranslateNH_P_Grad(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { diff --git a/fv3core/tests/savepoint/translate/translate_pe_halo.py b/fv3core/tests/savepoint/translate/translate_pe_halo.py index f807e9d35..49ebd1eb4 100644 --- a/fv3core/tests/savepoint/translate/translate_pe_halo.py +++ b/fv3core/tests/savepoint/translate/translate_pe_halo.py @@ -1,5 +1,6 @@ -import pace.dsl -import pace.util +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + from pace.fv3core.stencils import pe_halo from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -26,10 +27,9 @@ class TranslatePE_Halo(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): - super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { "pe": { diff --git a/fv3core/tests/savepoint/translate/translate_pk3_halo.py b/fv3core/tests/savepoint/translate/translate_pk3_halo.py index 739a204ac..0c78bea31 100644 --- a/fv3core/tests/savepoint/translate/translate_pk3_halo.py +++ b/fv3core/tests/savepoint/translate/translate_pk3_halo.py @@ -1,5 +1,6 @@ -import pace.dsl -import pace.util +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + from pace.fv3core.stencils.pk3_halo import PK3Halo from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -8,8 +9,8 @@ class TranslatePK3_Halo(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.stencil_factory = stencil_factory diff --git a/fv3core/tests/savepoint/translate/translate_pressureadjustedtemperature_nonhydrostatic.py b/fv3core/tests/savepoint/translate/translate_pressureadjustedtemperature_nonhydrostatic.py index 536f6c7b6..d402ce0df 100644 --- a/fv3core/tests/savepoint/translate/translate_pressureadjustedtemperature_nonhydrostatic.py +++ b/fv3core/tests/savepoint/translate/translate_pressureadjustedtemperature_nonhydrostatic.py @@ -1,6 +1,9 @@ -import pace.dsl +from typing import Any, Dict + +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + import pace.fv3core -import pace.util from pace.fv3core.stencils import temperature_adjust from pace.fv3core.stencils.dyn_core import get_nk_heat_dissipation from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -12,8 +15,8 @@ class TranslatePressureAdjustedTemperature_NonHydrostatic( def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) dycore_config = pace.fv3core.DynamicalCoreConfig.from_namelist(namelist) @@ -37,7 +40,7 @@ def __init__( "heat_source": {"serialname": "heat_source_dyn"}, } self.in_vars["parameters"] = ["bdt"] - self.out_vars = {"pt": {}} + self.out_vars: Dict[str, Dict[Any, Any]] = {"pt": {}} self.stencil_factory = stencil_factory def compute_from_storage(self, inputs): diff --git a/fv3core/tests/savepoint/translate/translate_qsinit.py b/fv3core/tests/savepoint/translate/translate_qsinit.py index d9f145ec4..3095f715a 100644 --- a/fv3core/tests/savepoint/translate/translate_qsinit.py +++ b/fv3core/tests/savepoint/translate/translate_qsinit.py @@ -1,9 +1,9 @@ +import ndsl.dsl.gt4py_utils as utils import numpy as np +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist -import pace.dsl -import pace.dsl.gt4py_utils as utils import pace.fv3core.stencils.saturation_adjustment as satadjust -import pace.util from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -11,8 +11,8 @@ class TranslateQSInit(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { diff --git a/fv3core/tests/savepoint/translate/translate_ray_fast.py b/fv3core/tests/savepoint/translate/translate_ray_fast.py index 5b8c069b3..56a404942 100644 --- a/fv3core/tests/savepoint/translate/translate_ray_fast.py +++ b/fv3core/tests/savepoint/translate/translate_ray_fast.py @@ -1,5 +1,6 @@ -import pace.dsl -import pace.util +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + from pace.fv3core.stencils.ray_fast import RayleighDamping from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -8,8 +9,8 @@ class TranslateRay_Fast(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.compute_func = RayleighDamping( # type: ignore diff --git a/fv3core/tests/savepoint/translate/translate_remapping.py b/fv3core/tests/savepoint/translate/translate_remapping.py index 9a2e1f84c..5845d8808 100644 --- a/fv3core/tests/savepoint/translate/translate_remapping.py +++ b/fv3core/tests/savepoint/translate/translate_remapping.py @@ -1,18 +1,19 @@ -import pace.dsl -import pace.dsl.gt4py_utils as utils -import pace.util +import ndsl.dsl.gt4py_utils as utils +from ndsl.constants import Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + from pace.fv3core import DynamicalCoreConfig from pace.fv3core.stencils.remapping import LagrangianToEulerian from pace.fv3core.testing import TranslateDycoreFortranData2Py -from pace.util import Z_DIM class TranslateRemapping(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { diff --git a/fv3core/tests/savepoint/translate/translate_riem_solver3.py b/fv3core/tests/savepoint/translate/translate_riem_solver3.py index 70840bd0a..3328a5f29 100644 --- a/fv3core/tests/savepoint/translate/translate_riem_solver3.py +++ b/fv3core/tests/savepoint/translate/translate_riem_solver3.py @@ -1,5 +1,6 @@ -import pace.dsl -import pace.util +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + from pace.fv3core import _config as spec from pace.fv3core.stencils.riem_solver3 import NonhydrostaticVerticalSolver from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -9,8 +10,8 @@ class TranslateRiem_Solver3(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.vertical_solver = NonhydrostaticVerticalSolver( diff --git a/fv3core/tests/savepoint/translate/translate_riem_solver_c.py b/fv3core/tests/savepoint/translate/translate_riem_solver_c.py index 16261789d..30351b915 100644 --- a/fv3core/tests/savepoint/translate/translate_riem_solver_c.py +++ b/fv3core/tests/savepoint/translate/translate_riem_solver_c.py @@ -1,5 +1,6 @@ -import pace.dsl -import pace.util +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + from pace.fv3core.stencils.riem_solver_c import NonhydrostaticVerticalSolverCGrid from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -8,8 +9,8 @@ class TranslateRiem_Solver_C(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.compute_func = NonhydrostaticVerticalSolverCGrid( # type: ignore diff --git a/fv3core/tests/savepoint/translate/translate_satadjust3d.py b/fv3core/tests/savepoint/translate/translate_satadjust3d.py index a3022026e..b358d74bf 100644 --- a/fv3core/tests/savepoint/translate/translate_satadjust3d.py +++ b/fv3core/tests/savepoint/translate/translate_satadjust3d.py @@ -1,6 +1,7 @@ -import pace.dsl +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist + import pace.fv3core -import pace.util from pace.fv3core import DynamicalCoreConfig from pace.fv3core.stencils.saturation_adjustment import SatAdjust3d from pace.fv3core.testing import TranslateDycoreFortranData2Py @@ -10,8 +11,8 @@ class TranslateSatAdjust3d(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { diff --git a/fv3core/tests/savepoint/translate/translate_tracer2d1l.py b/fv3core/tests/savepoint/translate/translate_tracer2d1l.py index 994eabd69..0313c14c0 100644 --- a/fv3core/tests/savepoint/translate/translate_tracer2d1l.py +++ b/fv3core/tests/savepoint/translate/translate_tracer2d1l.py @@ -1,19 +1,19 @@ +import ndsl.dsl.gt4py_utils as utils import pytest +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist +from ndsl.stencils.testing import ParallelTranslate -import pace.dsl -import pace.dsl.gt4py_utils as utils import pace.fv3core.stencils.fvtp2d import pace.fv3core.stencils.tracer_2d_1l -import pace.util -import pace.util as fv3util from pace.fv3core.utils.functional_validation import get_subset_func -from pace.stencils.testing import ParallelTranslate class TranslateTracer2D1L(ParallelTranslate): inputs = { "tracers": { - "dims": [fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/m^2", } } @@ -21,8 +21,8 @@ class TranslateTracer2D1L(ParallelTranslate): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self._base.in_vars["data_vars"] = { @@ -39,7 +39,7 @@ def __init__( self.namelist = namelist self._subset = get_subset_func( self.grid.grid_indexing, - dims=[fv3util.X_DIM, fv3util.Y_DIM, fv3util.Z_DIM], + dims=[X_DIM, Y_DIM, Z_DIM], n_halo=((0, 0), (0, 0)), ) @@ -48,7 +48,6 @@ def collect_input_data(self, serializer, savepoint): return input_data def compute_parallel(self, inputs, communicator): - self._base.make_storage_data_input_vars(inputs) all_tracers = inputs["tracers"] inputs["tracers"] = self.get_advected_tracer_dict( diff --git a/fv3core/tests/savepoint/translate/translate_updatedzc.py b/fv3core/tests/savepoint/translate/translate_updatedzc.py index ab0d11fad..7d0fee1eb 100644 --- a/fv3core/tests/savepoint/translate/translate_updatedzc.py +++ b/fv3core/tests/savepoint/translate/translate_updatedzc.py @@ -1,8 +1,9 @@ import numpy as np +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist -import pace.dsl import pace.fv3core.stencils.updatedzc as updatedzc -import pace.util from pace.fv3core.testing import TranslateDycoreFortranData2Py from pace.fv3core.utils.functional_validation import get_subset_func @@ -11,8 +12,8 @@ class TranslateUpdateDzC(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.stencil_factory = stencil_factory @@ -43,12 +44,12 @@ def compute(**kwargs): } self._subset = get_subset_func( self.grid.grid_indexing, - dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + dims=[X_DIM, Y_DIM, Z_DIM], n_halo=((0, 0), (0, 0)), ) self._subset_2d = get_subset_func( self.grid.grid_indexing, - dims=[pace.util.X_DIM, pace.util.Y_DIM], + dims=[X_DIM, Y_DIM], n_halo=((0, 0), (0, 0)), ) diff --git a/fv3core/tests/savepoint/translate/translate_updatedzd.py b/fv3core/tests/savepoint/translate/translate_updatedzd.py index 83ba701a5..e65b7c5e6 100644 --- a/fv3core/tests/savepoint/translate/translate_updatedzd.py +++ b/fv3core/tests/savepoint/translate/translate_updatedzd.py @@ -1,9 +1,10 @@ import numpy as np +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist -import pace.dsl import pace.fv3core import pace.fv3core.stencils.updatedzd -import pace.util from pace.fv3core.stencils import d_sw from pace.fv3core.testing import TranslateDycoreFortranData2Py from pace.fv3core.utils.functional_validation import get_subset_func @@ -13,8 +14,8 @@ class TranslateUpdateDzD(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { @@ -52,7 +53,7 @@ def __init__( self.namelist = pace.fv3core.DynamicalCoreConfig.from_namelist(namelist) self._subset = get_subset_func( self.grid.grid_indexing, - dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + dims=[X_DIM, Y_DIM, Z_DIM], n_halo=((0, 0), (0, 0)), ) self.ignore_near_zero_errors = {"zh": True, "wsd": True} diff --git a/fv3core/tests/savepoint/translate/translate_xppm.py b/fv3core/tests/savepoint/translate/translate_xppm.py index 9809faf0e..94ccc090f 100644 --- a/fv3core/tests/savepoint/translate/translate_xppm.py +++ b/fv3core/tests/savepoint/translate/translate_xppm.py @@ -1,17 +1,18 @@ -import pace.dsl -import pace.dsl.gt4py_utils as utils -import pace.util +import ndsl.dsl.gt4py_utils as utils +from ndsl.dsl.stencil import StencilFactory +from ndsl.namelist import Namelist +from ndsl.stencils.testing import TranslateGrid + from pace.fv3core.stencils import xppm from pace.fv3core.testing import TranslateDycoreFortranData2Py -from pace.stencils.testing import TranslateGrid class TranslateXPPM(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { @@ -62,8 +63,8 @@ class TranslateXPPM_2(TranslateXPPM): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"]["q"]["serialname"] = "q" diff --git a/fv3core/tests/savepoint/translate/translate_xtp_u.py b/fv3core/tests/savepoint/translate/translate_xtp_u.py index 39832a3d9..66b176406 100644 --- a/fv3core/tests/savepoint/translate/translate_xtp_u.py +++ b/fv3core/tests/savepoint/translate/translate_xtp_u.py @@ -1,11 +1,10 @@ from gt4py.cartesian.gtscript import PARALLEL, computation, interval +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import FloatField, FloatFieldIJ +from ndsl.grid import GridData +from ndsl.namelist import Namelist -import pace.dsl import pace.fv3core.stencils.xtp_u as xtp_u -import pace.util -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import FloatField, FloatFieldIJ -from pace.util.grid import GridData from .translate_ytp_v import TranslateYTP_V @@ -79,8 +78,8 @@ class TranslateXTP_U(TranslateYTP_V): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"]["u"] = {} diff --git a/fv3core/tests/savepoint/translate/translate_yppm.py b/fv3core/tests/savepoint/translate/translate_yppm.py index 175be9bb2..a80e85108 100644 --- a/fv3core/tests/savepoint/translate/translate_yppm.py +++ b/fv3core/tests/savepoint/translate/translate_yppm.py @@ -1,18 +1,19 @@ -import pace.dsl -import pace.dsl.gt4py_utils as utils -import pace.util -from pace.dsl.typing import Float +import ndsl.dsl.gt4py_utils as utils +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float +from ndsl.namelist import Namelist +from ndsl.stencils.testing import TranslateGrid + from pace.fv3core.stencils import yppm from pace.fv3core.testing import TranslateDycoreFortranData2Py -from pace.stencils.testing import TranslateGrid class TranslateYPPM(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"] = { @@ -66,8 +67,8 @@ class TranslateYPPM_2(TranslateYPPM): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.in_vars["data_vars"]["q"]["serialname"] = "q_2" diff --git a/fv3core/tests/savepoint/translate/translate_ytp_v.py b/fv3core/tests/savepoint/translate/translate_ytp_v.py index bf0afd160..733af9464 100644 --- a/fv3core/tests/savepoint/translate/translate_ytp_v.py +++ b/fv3core/tests/savepoint/translate/translate_ytp_v.py @@ -1,13 +1,12 @@ from gt4py.cartesian.gtscript import PARALLEL, computation, interval +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import FloatField, FloatFieldIJ +from ndsl.grid import GridData +from ndsl.namelist import Namelist -import pace.dsl import pace.fv3core import pace.fv3core.stencils.ytp_v as ytp_v -import pace.util -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import FloatField, FloatFieldIJ from pace.fv3core.testing import TranslateDycoreFortranData2Py -from pace.util.grid import GridData def ytp_v_stencil_defn( @@ -74,8 +73,8 @@ class TranslateYTP_V(TranslateDycoreFortranData2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) c_info = self.grid.compute_dict_buffer_2d() diff --git a/physics/pace/physics/_config.py b/physics/pace/physics/_config.py index 4ce3715a6..91963bca0 100644 --- a/physics/pace/physics/_config.py +++ b/physics/pace/physics/_config.py @@ -3,8 +3,8 @@ from typing import List, Optional, Tuple import f90nml - -from pace.util import MetaEnumStr, Namelist, NamelistDefaults +from ndsl.namelist import Namelist, NamelistDefaults +from ndsl.utils import MetaEnumStr DEFAULT_INT = 0 diff --git a/physics/pace/physics/functions/microphysics_funcs.py b/physics/pace/physics/functions/microphysics_funcs.py index 6f1c5a515..7fdf45c2e 100644 --- a/physics/pace/physics/functions/microphysics_funcs.py +++ b/physics/pace/physics/functions/microphysics_funcs.py @@ -1,8 +1,7 @@ +import ndsl.constants as constants from gt4py.cartesian import gtscript from gt4py.cartesian.gtscript import exp, log, sqrt -import pace.util.constants as constants - # Marshall-Palmer constants ### VCONS = 6.6280504 @@ -44,7 +43,6 @@ @gtscript.function def dim(x, y): - diff = x - y return diff if diff > 0.0 else 0.0 @@ -53,7 +51,6 @@ def dim(x, y): # Compute the saturated specific humidity @gtscript.function def wqs1(ta, den): - return ( constants.E00 * exp( @@ -69,7 +66,6 @@ def wqs1(ta, den): # Compute saturated specific humidity and its gradient @gtscript.function def wqs2(ta, den): - tmp = wqs1(ta, den) return tmp, tmp * (constants.DC_VAP + constants.LV0 / ta) / (constants.RVGAS * ta) @@ -78,12 +74,9 @@ def wqs2(ta, den): # Compute the saturated specific humidity @gtscript.function def iqs1(ta, den): - if ta < constants.TICE: - # Over ice between -160 degrees Celsius and 0 degrees Celsius if ta >= constants.T_SAT_MIN: - tmp = ( constants.E00 * exp( @@ -96,7 +89,6 @@ def iqs1(ta, den): ) / (constants.RVGAS * ta * den) else: - tmp = ( constants.E00 * exp( @@ -108,14 +100,11 @@ def iqs1(ta, den): ) ) / (constants.RVGAS * constants.T_SAT_MIN * den) else: - # Over water between 0 degrees Celsius and 102 degrees Celsius if ta <= constants.TICE + 102.0: - tmp = wqs1(ta, den) else: - tmp = wqs1(constants.TICE + 102.0, den) return tmp @@ -124,18 +113,14 @@ def iqs1(ta, den): # Compute the gradient of saturated specific humidity @gtscript.function def iqs2(ta, den): - tmp = iqs1(ta, den) if ta < constants.TICE: - # Over ice between -160 degrees Celsius and 0 degrees Celsius if ta >= constants.T_SAT_MIN: - dtmp = tmp * (constants.D2ICE + constants.LI2 / ta) / (constants.RVGAS * ta) else: - dtmp = ( tmp * (constants.D2ICE + constants.LI2 / constants.T_SAT_MIN) @@ -143,16 +128,13 @@ def iqs2(ta, den): ) else: - # Over water between 0 degrees Celsius and 102 degrees Celsius if ta <= constants.TICE + 102.0: - dtmp = ( tmp * (constants.DC_VAP + constants.LV0 / ta) / (constants.RVGAS * ta) ) else: - dtmp = ( tmp * (constants.DC_VAP + constants.LV0 / (constants.TICE + 102.0)) @@ -165,7 +147,6 @@ def iqs2(ta, den): # Accretion function @gtscript.function def acr3d(v1, v2, q1, q2, c, cac_ik, cac_i1k, cac_i2k, rho): - t1 = sqrt(q1 * rho) s1 = sqrt(q2 * rho) s2 = sqrt(s1) @@ -183,7 +164,6 @@ def acr3d(v1, v2, q1, q2, c, cac_ik, cac_i1k, cac_i2k, rho): # called) @gtscript.function def smlt(tc, dqs, qsrho, psacw, psacr, c_0, c_1, c_2, c_3, c_4, rho, rhofac): - return (c_0 * tc / rho - c_1 * dqs) * ( c_2 * sqrt(qsrho) + c_3 * qsrho ** 0.65625 * sqrt(rhofac) ) + c_4 * tc * (psacw + psacr) @@ -193,7 +173,6 @@ def smlt(tc, dqs, qsrho, psacw, psacr, c_0, c_1, c_2, c_3, c_4, rho, rhofac): # is called) @gtscript.function def gmlt(tc, dqs, qgrho, pgacw, pgacr, c_0, c_1, c_2, c_3, c_4, rho): - return (c_0 * tc / rho - c_1 * dqs) * ( c_2 * sqrt(qgrho) + c_3 * qgrho ** 0.6875 / rho ** 0.25 ) + c_4 * tc * (pgacw + pgacr) @@ -225,10 +204,8 @@ def revap_racc( den, denfac, ): - # Evaporation and accretion of rain for the first 1/2 time step if (tz > t_wfr) and (qr > QRMIN): - # Define heat capacity and latent heat coefficient lhl = lv00 + d0_vap * tz q_liq = ql + qr @@ -251,13 +228,10 @@ def revap_racc( # qsat must be < q_plus to activate accretion # Rain evaporation if (dqv > QVMIN) and (qsat > q_minus): - if qsat > q_plus: - dq = qsat - qpz else: - # q_minus < qsat < q_plus # dq == dqh if qsat == q_minus dq = 0.25 * (q_minus - qsat) ** 2 / dqh @@ -282,7 +256,6 @@ def revap_racc( # Accretion: pracc if (qr > QRMIN) and (ql > 1.0e-6) and (qsat < q_minus): - sink = dt * denfac * cracw * exp(0.95 * log(qr * den)) sink = sink / (1.0 + sink) * ql ql = ql - sink @@ -314,21 +287,17 @@ def fall_speed(log_10, qg, qi, ql, qs, tk, den): # Ice if const_vi: - vti = vi_fac else: - # Use deng and mace (2008, grl), which gives smaller fall speed # than hd90 formula vi0 = 0.01 * vi_fac if qi < THI: - vti = VF_MIN else: - tc = tk - tice """ THE LOG10 HAD TO BE TRANSFORMED DUE TO THE LOG10 @@ -346,33 +315,25 @@ def fall_speed(log_10, qg, qi, ql, qs, tk, den): # Snow if const_vs: - vts = vs_fac else: - if qs < THS: - vts = VF_MIN else: - vts = vs_fac * VCONS * rhof * exp(0.0625 * log(qs * den / NORMS)) vts = min(vs_max, max(VF_MIN, vts)) # Graupel if const_vg: - vtg = vg_fac else: - if qg < THG: - vtg = VF_MIN else: - vtg = vg_fac * VCONG * rhof * sqrt(sqrt(sqrt(qg * den / NORMG))) vtg = min(vg_max, max(VF_MIN, vtg)) @@ -384,27 +345,21 @@ def compute_rain_fspeed(no_fall, qrz, den): from __externals__ import const_vr, vr_fac, vr_max if no_fall == 1: - vtrz = VF_MIN r1 = 0.0 else: - # Fall speed of rain if const_vr: - vtrz = vr_fac else: - qden = qrz * den if qrz < THR: - vtrz = VR_MIN else: - vtrz = ( vr_fac * VCONR @@ -420,25 +375,20 @@ def compute_rain_fspeed(no_fall, qrz, den): def autoconv_no_subgrid_var( use_ccn, fac_rc, t_wfr, so3, dt_rain, qlz, qrz, tz, den, ccn, c_praut ): - # No subgrid variability qc0 = fac_rc * ccn if tz > t_wfr: - if use_ccn: - # ccn is formulted as ccn = ccn_surface * (den / den_surface) qc = qc0 else: - qc = qc0 / den dq = qlz - qc if dq > 0.0: - sink = min(dq, dt_rain * c_praut * den * exp(so3 * log(qlz))) qlz = qlz - sink qrz = qrz + sink @@ -450,21 +400,17 @@ def autoconv_no_subgrid_var( def autoconv_subgrid_var( use_ccn, fac_rc, t_wfr, so3, dt_rain, qlz, qrz, tz, den, ccn, c_praut, dl ): - qc0 = fac_rc * ccn if tz > t_wfr + DT_FR: - dl = min(max(1.0e-6, dl), 0.5 * qlz) # As in klein's gfdl am2 stratiform scheme (with subgrid variations) if use_ccn: - # ccn is formulted as ccn = ccn_surface * (den / den_surface) qc = qc0 else: - qc = qc0 / den dq = 0.5 * (qlz + dl - qc) @@ -472,7 +418,6 @@ def autoconv_subgrid_var( # dq = dl if qc == q_minus = ql - dl # dq = 0 if qc == q_plus = ql + dl if dq > 0.0: # q_plus > qc - # Revised continuous form: linearly decays # (with subgrid dl) to zero at qc == ql + dl sink = min(1.0, dq / dl) * dt_rain * c_praut * den * exp(so3 * log(qlz)) @@ -538,10 +483,8 @@ def subgrid_z_proc( tcp3 = lcpk + icpk * min(1.0, dim(tice, tz) / (tice - t_wfr)) if p1 >= P_MIN: - # Instant deposit all water vapor to cloud ice when temperature is super low if tz < constants.T_MIN: - sink = dim(1.0e-7, qvz) qvz = qvz - sink qiz = qiz + sink @@ -555,7 +498,6 @@ def subgrid_z_proc( qaz = qaz + 1.0 # Air fully saturated; 100% cloud cover else: - # Update heat capacity and latent heat coefficient lhl = lv00 + d0_vap * tz lhi = constants.LI00 + constants.DC_ICE * tz @@ -575,25 +517,21 @@ def subgrid_z_proc( ) if tin > t_sub + 6.0: - rh = qpz / iqs1(tin, den) if rh < rh_adj: # qpz / rh_adj < qs - tz = tin qvz = qpz qlz = 0.0 qiz = 0.0 if ((tin > t_sub + 6.0) and (rh >= rh_adj)) or (tin <= t_sub + 6.0): - # Cloud water < -- > vapor adjustment qsw, dwsdt = wqs2(tz, den) dq0 = qsw - qvz if dq0 > 0.0: - # Added ql factor to prevent the situation of high ql and low RH factor = min( 1.0, fac_l2v * (10.0 * dq0 / qsw) @@ -601,7 +539,6 @@ def subgrid_z_proc( evap = min(qlz, factor * dq0 / (1.0 + tcp3 * dwsdt)) else: # Condensate all excess vapor into cloud water - evap = dq0 / (1.0 + tcp3 * dwsdt) qvz = qvz + evap @@ -623,7 +560,6 @@ def subgrid_z_proc( dtmp = t_wfr - tz # [-40, -48] if (dtmp > 0.0) and (qlz > QCMIN): - sink = min(qlz, min(qlz * dtmp * 0.125, dtmp / icpk)) qlz = qlz - sink qiz = qiz + sink @@ -643,17 +579,14 @@ def subgrid_z_proc( # Bigg mechanism if fast_sat_adj: - dt_pisub = 0.5 * dts else: - dt_pisub = dts tc = tice - tz if (qlz > QRMIN) and (tc > 0.0): - sink = ( 3.3333e-10 * dts * (exp(0.66 * tc) - 1.0) * den * qlz * qlz ) @@ -679,14 +612,12 @@ def subgrid_z_proc( # Sublimation / deposition of ice if tz < tice: - qsi, dqsdt = iqs2(tz, den) dq = qvz - qsi sink = dq / (1.0 + tcpk * dqsdt) if qiz > QRMIN: - # - Eq 9, hong et al. 2004, mwr # - For a and b, see dudhia 1989: page 3103 eq (b7) and (b8) pidep = ( @@ -704,11 +635,9 @@ def subgrid_z_proc( ) else: - pidep = 0.0 if dq > 0.0: # Vapor -- > ice - tmp = tice - tz # The following should produce more ice at higher altitude @@ -716,7 +645,6 @@ def subgrid_z_proc( sink = min(sink, min(max(qi_crt - qiz, pidep), tmp / tcpk)) else: # Ice -- > vapor - pidep = pidep * min(1.0, dim(tz, t_sub) * 0.2) sink = max(pidep, max(sink, -qiz)) @@ -741,7 +669,6 @@ def subgrid_z_proc( # - Sublimation / deposition of snow # - This process happens for the whole temperature range if qsz > QRMIN: - qsi, dqsdt = iqs2(tz, den) qden = qsz * den @@ -757,17 +684,13 @@ def subgrid_z_proc( pssub = (qsi - qvz) * dts * pssub if pssub > 0.0: # qs -- > qv, sublimation - pssub = min(pssub * min(1.0, dim(tz, t_sub) * 0.2), qsz) else: - if tz > tice: - pssub = 0.0 # No deposition else: - pssub = max(pssub, max(dq, (tz - tice) / tcpk)) qsz = qsz - pssub @@ -790,27 +713,22 @@ def subgrid_z_proc( # Simplified 2-way grapuel sublimation-deposition mechanism if qgz > QRMIN: - qsi, dqsdt = iqs2(tz, den) dq = (qvz - qsi) / (1.0 + tcpk * dqsdt) pgsub = (qvz / qsi - 1.0) * qgz if pgsub > 0.0: # Deposition - if tz > tice: - pgsub = 0.0 else: - pgsub = min( min(fac_v2g * pgsub, 0.2 * dq), min(qlz + qrz, (tice - tz) / tcpk), ) else: # Sublimation - pgsub = max(fac_g2v * pgsub, dq) * min( 1.0, dim(tz, t_sub) * 0.1 ) @@ -835,7 +753,6 @@ def subgrid_z_proc( # Minimum evap of rain in dry environmental air if qrz > QCMIN: - qsw, dqsdt = wqs2(tz, den) sink = min(qrz, dim(rh_rain * qsw, qvz) / (1.0 + lcpk * dqsdt)) @@ -861,7 +778,6 @@ def subgrid_z_proc( # Compute cloud fraction # Combine water species if not do_qa: - if rad_snow: q_sol = qiz + qsz else: @@ -887,27 +803,22 @@ def subgrid_z_proc( """ t_wfr_tmp = t_wfr if tin <= t_wfr: - # Ice phase qstar = iqs1(tin, den) elif tin >= tice: - # Liquid phase qstar = wqs1(tin, den) else: - # Mixed phase qsi = iqs1(tin, den) qsw = wqs1(tin, den) if q_cond > 3.0e-6: - rqi = q_sol / q_cond else: - # Mostly liquid water q_cond (k) at # initial cloud development stage """ @@ -922,18 +833,15 @@ def subgrid_z_proc( # Assuming subgrid linear distribution in horizontal; this is # effectively a smoother for the binary cloud scheme if qpz > QRMIN: - # Partial cloudiness by pdf dq = max(QCMIN, h_var * qpz) q_plus = qpz + dq # Cloud free if qstar > q_plus q_minus = qpz - dq if qstar < q_minus: - qaz = qaz + 1.0 # Air fully saturated; 100% cloud cover elif (qstar < q_plus) and (q_cond > qc_crt): - qaz = qaz + (q_plus - qstar) / ( dq + dq ) # Partial cloud cover @@ -1021,34 +929,28 @@ def icloud_main( icpk = lhi / cvm if p1 >= P_MIN: - pgacr = 0.0 pgacw = 0.0 tc = tz - tice if tc >= 0.0: - # Melting of snow dqs0 = ces0 / p1 - qvz if qsz > QCMIN: - # psacw: accretion of cloud water by snow (only rate is used (for # snow melt) since tc > 0.) if qlz > QRMIN: - factor = denfac * csacw * exp(0.8125 * log(qsz * den)) psacw = factor / (1.0 + dts * factor) * qlz # Rate else: - psacw = 0.0 # psacr: accretion of rain by melted snow # pracs: accretion of snow by rain if qrz > QRMIN: - psacr = min( acr3d( vtsz, vtrz, qrz, qsz, csacr, acco_01, acco_11, acco_21, den @@ -1060,7 +962,6 @@ def icloud_main( ) else: - psacr = 0.0 pracs = 0.0 @@ -1106,10 +1007,8 @@ def icloud_main( # Melting of graupel if (qgz > QCMIN) and (tc > 0.0): - # pgacr: accretion of rain by graupel if qrz > QRMIN: - pgacr = min( acr3d( vtgz, vtrz, qrz, qgz, cgacr, acco_02, acco_12, acco_22, den @@ -1121,7 +1020,6 @@ def icloud_main( qden = qgz * den if qlz > QRMIN: - factor = cgacw * qden / sqrt(den * sqrt(sqrt(qden))) pgacw = factor / (1.0 + dts * factor) * qlz # Rate @@ -1153,13 +1051,10 @@ def icloud_main( tz = tz - pgmlt * lhi / cvm else: - # Cloud ice proc # psaci: accretion of cloud ice by snow if qiz > 3.0e-7: # Cloud ice sink terms - if qsz > 1.0e-7: - # sjl added (following lin eq. 23) the temperature dependency to # reduce accretion, use esi = exp(0.05 * tc) as in hong et al 2004 factor = ( @@ -1168,7 +1063,6 @@ def icloud_main( psaci = factor / (1.0 + factor) * qiz else: - psaci = 0.0 # pasut: autoconversion: cloud ice -- > snow @@ -1180,30 +1074,24 @@ def icloud_main( # - Assuming linear subgrid vertical distribution of cloud ice # - The mismatch computation following lin et al. 1994, mwr if const_vi: - tmp = fac_i2s else: - tmp = fac_i2s * exp(0.025 * tc) di = max(di, QRMIN) q_plus = qiz + di if q_plus > (qim + QRMIN): - if qim > (qiz - di): - dq = (0.25 * (q_plus - qim) ** 2) / di else: - dq = qiz - qim psaut = tmp * dq else: - psaut = 0.0 # sink is no greater than 75% of qi @@ -1213,7 +1101,6 @@ def icloud_main( # pgaci: accretion of cloud ice by graupel if qgz > 1.0e-6: - # - factor = dts * cgaci / sqrt (den (k)) * # exp (0.05 * tc + 0.875 * log (qg * den (k))) # - Simplified form: remove temp dependency & @@ -1228,19 +1115,16 @@ def icloud_main( tc = tz - tice if (qrz > 1e-7) and (tc < 0.0): - # - Sink terms to qr: psacr + pgfr # - Source terms to qs: psacr # - Source terms to qg: pgfr # psacr accretion of rain by snow if qsz > 1.0e-7: # If snow exists - psacr = dts * acr3d( vtsz, vtrz, qrz, qsz, csacr, acco_01, acco_11, acco_21, den ) else: - psacr = 0.0 # pgfr: rain freezing -- > graupel @@ -1279,23 +1163,19 @@ def icloud_main( # Graupel production terms if qsz > 1.0e-7: - # Accretion: snow -- > graupel if qgz > QRMIN: - sink = dts * acr3d( vtgz, vtsz, qsz, qgz, cgacs, acco_03, acco_13, acco_23, den ) else: - sink = 0.0 # Autoconversion snow -- > graupel qsm = qs0_crt / den if qsz > qsm: - factor = dts * 1.0e-3 * exp(0.09 * (tz - tice)) sink = sink + factor / (1.0 + factor) * (qsz - qsm) @@ -1304,21 +1184,17 @@ def icloud_main( qgz = qgz + sink if (qgz > 1.0e-7) and (tz < tice0): - # pgacw: accretion of cloud water by graupel if qlz > 1.0e-6: - qden = qgz * den factor = dts * cgacw * qden / sqrt(den * sqrt(sqrt(qden))) pgacw = factor / (1.0 + factor) * qlz else: - pgacw = 0.0 # pgacr: accretion of rain by graupel if qrz > 1.0e-6: - pgacr = min( dts * acr3d( @@ -1328,7 +1204,6 @@ def icloud_main( ) else: - pgacr = 0.0 sink = pgacr + pgacw diff --git a/physics/pace/physics/physics_state.py b/physics/pace/physics/physics_state.py index 834639982..261736d11 100644 --- a/physics/pace/physics/physics_state.py +++ b/physics/pace/physics/physics_state.py @@ -1,11 +1,14 @@ from dataclasses import InitVar, dataclass, field, fields from typing import Any, Dict, List, Mapping, Optional +import ndsl.dsl.gt4py_utils as gt_utils import xarray as xr +from ndsl.constants import X_DIM, Y_DIM, Z_DIM, Z_INTERFACE_DIM +from ndsl.dsl.typing import Float +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import GridSizer +from ndsl.quantity import Quantity -import pace.dsl.gt4py_utils as gt_utils -import pace.util -from pace.dsl.typing import Float from pace.physics.stencils.microphysics import MicrophysicsState from ._config import PHYSICS_PACKAGES @@ -13,287 +16,287 @@ @dataclass() class PhysicsState: - qvapor: pace.util.Quantity = field( + qvapor: Quantity = field( metadata={ "name": "specific_humidity", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", } ) - qliquid: pace.util.Quantity = field( + qliquid: Quantity = field( metadata={ "name": "cloud_water_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - qice: pace.util.Quantity = field( + qice: Quantity = field( metadata={ "name": "cloud_ice_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - qrain: pace.util.Quantity = field( + qrain: Quantity = field( metadata={ "name": "rain_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - qsnow: pace.util.Quantity = field( + qsnow: Quantity = field( metadata={ "name": "snow_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - qgraupel: pace.util.Quantity = field( + qgraupel: Quantity = field( metadata={ "name": "graupel_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - qo3mr: pace.util.Quantity = field( + qo3mr: Quantity = field( metadata={ "name": "ozone_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - qsgs_tke: pace.util.Quantity = field( + qsgs_tke: Quantity = field( metadata={ "name": "turbulent_kinetic_energy", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m**2/s**2", "intent": "inout", } ) - qcld: pace.util.Quantity = field( + qcld: Quantity = field( metadata={ "name": "cloud_fraction", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "", "intent": "inout", } ) - pt: pace.util.Quantity = field( + pt: Quantity = field( metadata={ "name": "air_temperature", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "degK", "intent": "inout", } ) - delp: pace.util.Quantity = field( + delp: Quantity = field( metadata={ "name": "pressure_thickness_of_atmospheric_layer", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "Pa", "intent": "inout", } ) - delz: pace.util.Quantity = field( + delz: Quantity = field( metadata={ "name": "vertical_thickness_of_atmospheric_layer", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m", "intent": "inout", } ) - ua: pace.util.Quantity = field( + ua: Quantity = field( metadata={ "name": "eastward_wind", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", "intent": "inout", } ) - va: pace.util.Quantity = field( + va: Quantity = field( metadata={ "name": "northward_wind", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", } ) - w: pace.util.Quantity = field( + w: Quantity = field( metadata={ "name": "vertical_wind", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", "intent": "inout", } ) - omga: pace.util.Quantity = field( + omga: Quantity = field( metadata={ "name": "vertical_pressure_velocity", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "Pa/s", "intent": "inout", } ) - physics_updated_specific_humidity: pace.util.Quantity = field( + physics_updated_specific_humidity: Quantity = field( metadata={ "name": "physics_updated_specific_humidity", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", } ) - physics_updated_qliquid: pace.util.Quantity = field( + physics_updated_qliquid: Quantity = field( metadata={ "name": "physics_updated_liquid_water_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - physics_updated_qice: pace.util.Quantity = field( + physics_updated_qice: Quantity = field( metadata={ "name": "physics_updated_ice_water_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - physics_updated_qrain: pace.util.Quantity = field( + physics_updated_qrain: Quantity = field( metadata={ "name": "physics_updated_rain_water_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - physics_updated_qsnow: pace.util.Quantity = field( + physics_updated_qsnow: Quantity = field( metadata={ "name": "physics_updated_snow_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - physics_updated_qgraupel: pace.util.Quantity = field( + physics_updated_qgraupel: Quantity = field( metadata={ "name": "physics_updated_graupel_mixing_ratio", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "kg/kg", "intent": "inout", } ) - physics_updated_cloud_fraction: pace.util.Quantity = field( + physics_updated_cloud_fraction: Quantity = field( metadata={ "name": "physics_cloud_fraction", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "", "intent": "inout", } ) - physics_updated_pt: pace.util.Quantity = field( + physics_updated_pt: Quantity = field( metadata={ "name": "physics_air_temperature", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "degK", "intent": "inout", } ) - physics_updated_ua: pace.util.Quantity = field( + physics_updated_ua: Quantity = field( metadata={ "name": "physics_eastward_wind", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", "intent": "inout", } ) - physics_updated_va: pace.util.Quantity = field( + physics_updated_va: Quantity = field( metadata={ "name": "physics_northward_wind", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", "intent": "inout", } ) - delprsi: pace.util.Quantity = field( + delprsi: Quantity = field( metadata={ "name": "model_level_pressure_thickness_in_physics", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "Pa", "intent": "inout", } ) - phii: pace.util.Quantity = field( + phii: Quantity = field( metadata={ "name": "interface_geopotential_height", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_INTERFACE_DIM], + "dims": [X_DIM, Y_DIM, Z_INTERFACE_DIM], "units": "m", "intent": "inout", } ) - phil: pace.util.Quantity = field( + phil: Quantity = field( metadata={ "name": "layer_geopotential_height", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m", "intent": "inout", } ) - dz: pace.util.Quantity = field( + dz: Quantity = field( metadata={ "name": "geopotential_height_thickness", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m", "intent": "inout", } ) - wmp: pace.util.Quantity = field( + wmp: Quantity = field( metadata={ "name": "layer_mean_vertical_velocity_microph", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + "dims": [X_DIM, Y_DIM, Z_DIM], "units": "m/s", "intent": "inout", } ) - prsi: pace.util.Quantity = field( + prsi: Quantity = field( metadata={ "name": "interface_pressure", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_INTERFACE_DIM], + "dims": [X_DIM, Y_DIM, Z_INTERFACE_DIM], "units": "Pa", "intent": "inout", } ) - prsik: pace.util.Quantity = field( + prsik: Quantity = field( metadata={ "name": "log_interface_pressure", - "dims": [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_INTERFACE_DIM], + "dims": [X_DIM, Y_DIM, Z_INTERFACE_DIM], "units": "Pa", "intent": "inout", } ) - land: pace.util.Quantity = field( + land: Quantity = field( metadata={ "name": "land_mask", - "dims": [pace.util.X_DIM, pace.util.Y_DIM], + "dims": [X_DIM, Y_DIM], "units": "-", "intent": "in", } ) - quantity_factory: InitVar[pace.util.QuantityFactory] + quantity_factory: InitVar[QuantityFactory] schemes: InitVar[List[PHYSICS_PACKAGES]] def __post_init__( self, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, schemes: List[PHYSICS_PACKAGES], ): # storage for tendency variables not in PhysicsState if "GFS_microphysics" in [scheme.value for scheme in schemes]: tendency = quantity_factory.zeros( - [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + [X_DIM, Y_DIM, Z_DIM], "unknown", dtype=Float, ) @@ -342,15 +345,15 @@ def init_zeros( def init_from_storages( cls, storages: Mapping[str, Any], - sizer: pace.util.GridSizer, - quantity_factory: pace.util.QuantityFactory, + sizer: GridSizer, + quantity_factory: QuantityFactory, schemes: List[PHYSICS_PACKAGES], ) -> "PhysicsState": - inputs: Dict[str, pace.util.Quantity] = {} + inputs: Dict[str, Quantity] = {} for _field in fields(cls): if "dims" in _field.metadata.keys(): dims = _field.metadata["dims"] - quantity = pace.util.Quantity( + quantity = Quantity( storages[_field.name], dims, _field.metadata["units"], @@ -365,7 +368,7 @@ def xr_dataset(self): data_vars = {} for name, field_info in self.__dataclass_fields__.items(): if name not in ["quantity_factory", "schemes"]: - if issubclass(field_info.type, pace.util.Quantity): + if issubclass(field_info.type, Quantity): dims = [ f"{dim_name}_{name}" for dim_name in field_info.metadata["dims"] ] diff --git a/physics/pace/physics/stencils/get_phi_fv3.py b/physics/pace/physics/stencils/get_phi_fv3.py index 192ccdaba..93e67f937 100644 --- a/physics/pace/physics/stencils/get_phi_fv3.py +++ b/physics/pace/physics/stencils/get_phi_fv3.py @@ -1,7 +1,6 @@ from gt4py.cartesian.gtscript import BACKWARD, PARALLEL, computation, interval - -from pace.dsl.typing import FloatField -from pace.util.constants import ZVIR +from ndsl.constants import ZVIR +from ndsl.dsl.typing import FloatField def get_phi_fv3( diff --git a/physics/pace/physics/stencils/get_prs_fv3.py b/physics/pace/physics/stencils/get_prs_fv3.py index 348a77b16..8c3554449 100644 --- a/physics/pace/physics/stencils/get_prs_fv3.py +++ b/physics/pace/physics/stencils/get_prs_fv3.py @@ -1,7 +1,6 @@ from gt4py.cartesian.gtscript import PARALLEL, computation, interval - -from pace.dsl.typing import FloatField -from pace.util.constants import ZVIR +from ndsl.constants import ZVIR +from ndsl.dsl.typing import FloatField def get_prs_fv3( diff --git a/physics/pace/physics/stencils/microphysics.py b/physics/pace/physics/stencils/microphysics.py index 064bc1c72..50a9613bc 100644 --- a/physics/pace/physics/stencils/microphysics.py +++ b/physics/pace/physics/stencils/microphysics.py @@ -1,6 +1,7 @@ import copy import typing +import ndsl.constants as constants import numpy as np from gt4py.cartesian.gtscript import ( BACKWARD, @@ -10,15 +11,15 @@ interval, sqrt, ) +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ, Int +from ndsl.grid import GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity import pace.physics.functions.microphysics_funcs as functions -import pace.util -import pace.util.constants as constants -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ, Int -from pace.util import X_DIM, Y_DIM, Z_DIM -from pace.util.grid import GridData from .._config import PhysicsConfig @@ -98,7 +99,6 @@ def fields_init( ) with computation(PARALLEL), interval(...): - # Initialize precipitation graupel = 0.0 rain = 0.0 @@ -108,12 +108,10 @@ def fields_init( # This is to prevent excessive build-up of cloud ice from # external sources if de_ice: - qio = qi - dt_in * qi_dt # Orginal qi before phys qin = max(qio, qi0_max) # Adjusted value if qi > qin: - qs = qs + qi - qin qi = qin @@ -167,26 +165,19 @@ def fields_init( v1 = v0 if prog_ccn: - # Convert #/cc to #/m^3 ccn = qn * 1.0e6 c_praut = cpaut * (ccn * functions.RHOR) ** (-1.0 / 3.0) else: - ccn = (ccn_l * land + ccn_o * (1.0 - land)) * 1.0e6 with computation(BACKWARD): - with interval(-1, None): - if not prog_ccn and use_ccn: - # ccn is formulted as ccn = ccn_surface * (den / den_surface) ccn = ccn * constants.RDGAS * tz / p1 with interval(0, -1): - if not prog_ccn and use_ccn: - # Propagate downwards previously computed values of ccn ccn = ccn[0, 0, +1] @@ -209,7 +200,6 @@ def fields_init( # Fix all negative water species if fix_negative: - # Define heat capacity and latent heat coefficient cvm = ( c_air @@ -224,19 +214,16 @@ def fields_init( # If cloud ice < 0, borrow from snow if qiz < 0.0: - qsz = qsz + qiz qiz = 0.0 # If snow < 0, borrow from graupel if qsz < 0.0: - qgz = qgz + qsz qsz = 0.0 # If graupel < 0, borrow from rain if qgz < 0.0: - qrz = qrz + qgz tz = tz - qgz * icpk # Heating qgz = 0.0 @@ -245,61 +232,47 @@ def fields_init( # If rain < 0, borrow from cloud water if qrz < 0.0: - qlz = qlz + qrz qrz = 0.0 # If cloud water < 0, borrow from water vapor if qlz < 0.0: - qvz = qvz + qlz tz = tz - qlz * lcpk # Heating qlz = 0.0 with computation(FORWARD), interval(1, None): - # Fix water vapor; borrow from below if fix_negative and (qvz[0, 0, -1] < 0.0): qvz[0, 0, 0] = qvz[0, 0, 0] + qvz[0, 0, -1] * dp1[0, 0, -1] / dp1[0, 0, 0] with computation(PARALLEL), interval(0, -1): - if fix_negative and (qvz < 0.0): qvz = 0.0 # Bottom layer; borrow from above with computation(PARALLEL): - with interval(-2, -1): - flag = 0 if fix_negative and (qvz[0, 0, +1] < 0.0) and (qvz > 0.0): - dq = min(-qvz[0, 0, +1] * dp1[0, 0, +1], qvz[0, 0, 0] * dp1[0, 0, 0]) flag = 1 with interval(-1, None): - flag = 0 if fix_negative and (qvz < 0.0) and (qvz[0, 0, -1] > 0.0): - dq = min(-qvz[0, 0, 0] * dp1[0, 0, 0], qvz[0, 0, -1] * dp1[0, 0, -1]) flag = 1 with computation(PARALLEL): - with interval(-2, -1): - if flag == 1: - qvz = qvz - dq / dp1 with interval(-1, None): - if flag == 1: - qvz = qvz + dq / dp1 @@ -355,18 +328,14 @@ def warm_rain( ) with computation(PARALLEL), interval(...): - if is_first: - # Define air density based on hydrostatical property if p_nonhydro: - dz1 = dz0 den = den0 # Dry air density remains the same denfac = sqrt(functions.SFCRHO / den) else: - dz1 = dz0 * tz / t0 # Hydrostatic balance den = den0 * dz0 / dz1 denfac = sqrt(functions.SFCRHO / den) @@ -378,52 +347,40 @@ def warm_rain( m1_rain = 0.0 with computation(FORWARD): - with interval(0, 1): - if qrz > functions.QRMIN: no_fall = 0 else: no_fall = 1 with interval(1, None): - if no_fall[0, 0, -1] == 1: - if qrz > functions.QRMIN: no_fall = 0 else: no_fall = 1 else: - no_fall = 0 with computation(BACKWARD), interval(0, -1): - if no_fall[0, 0, +1] == 0: no_fall = no_fall[0, 0, +1] with computation(PARALLEL), interval(...): - vtrz, r1 = functions.compute_rain_fspeed(no_fall, qrz, den) with computation(BACKWARD): - with interval(-1, None): - if no_fall == 0: ze = zs - dz1 with interval(0, -1): - if no_fall == 0: ze = ze[0, 0, +1] - dz1 # dz < 0 with computation(PARALLEL), interval(...): - if no_fall == 0: - # Evaporation and accretion of rain for the first 1/2 time step qgz, qiz, qlz, qrz, qsz, qvz, tz = functions.revap_racc( dt5, @@ -454,36 +411,27 @@ def warm_rain( # Mass flux induced by falling rain with computation(PARALLEL): - with interval(0, 1): - if use_ppm and (no_fall == 0): zt = ze with interval(1, -1): - if use_ppm and (no_fall == 0): zt = ze - dt5 * (vtrz[0, 0, -1] + vtrz) with interval(-1, None): - if use_ppm and (no_fall == 0): - zt = ze - dt5 * (vtrz[0, 0, -1] + vtrz) zt_kbot1 = zs - dt_rain * vtrz with computation(FORWARD): - with interval(1, -1): - if use_ppm and (no_fall[0, 0, -1] == 0) and (zt >= zt[0, 0, -1]): zt = zt[0, 0, -1] - functions.DZ_MIN_FLIP with interval(-1, None): - if use_ppm: - if (no_fall[0, 0, -1] == 0) and (zt >= zt[0, 0, -1]): zt = zt[0, 0, -1] - functions.DZ_MIN_FLIP @@ -491,81 +439,60 @@ def warm_rain( zt_kbot1 = zt - functions.DZ_MIN_FLIP with computation(BACKWARD), interval(0, -1): - if use_ppm and (no_fall == 0): zt_kbot1 = zt_kbot1[0, 0, +1] with computation(PARALLEL): - with interval(0, -1): - if (not use_ppm) and (no_fall == 0): dz = ze - ze[0, 0, +1] with interval(-1, None): - if (not use_ppm) and (no_fall == 0): dz = ze - zs with computation(PARALLEL), interval(...): - if (not use_ppm) and (no_fall == 0): - dd = dt_rain * vtrz qrz = qrz * dp1 # Sedimentation with computation(FORWARD): - with interval(0, 1): - if (not use_ppm) and (no_fall == 0): qm = qrz / (dz + dd) with interval(1, None): - if (not use_ppm) and (no_fall == 0): qm = (qrz[0, 0, 0] + dd[0, 0, -1] * qm[0, 0, -1]) / (dz + dd) with computation(PARALLEL), interval(...): - if (not use_ppm) and (no_fall == 0): - # qm is density at this stage qm = qm * dz # Output mass fluxes with computation(FORWARD): - with interval(0, 1): - if (not use_ppm) and (no_fall == 0): m1_rain = qrz - qm with interval(1, None): - if (not use_ppm) and (no_fall == 0): m1_rain = m1_rain[0, 0, -1] + qrz[0, 0, 0] - qm with computation(BACKWARD): - with interval(-1, None): - if (not use_ppm) and (no_fall == 0): r1 = m1_rain with interval(0, -1): - if (not use_ppm) and (no_fall == 0): r1 = r1[0, 0, +1] with computation(PARALLEL): - with interval(0, 1): - if no_fall == 0: - if not use_ppm: - # Update qrz = qm / dp1 @@ -574,17 +501,13 @@ def warm_rain( w = (dm * w + m1_rain * vtrz) / (dm - m1_rain) with interval(1, None): - if no_fall == 0: - if not use_ppm: - # Update qrz = qm / dp1 # Vertical velocity transportation during sedimentation if do_sedi_w: - w[0, 0, 0] = ( dm * w[0, 0, 0] - m1_rain[0, 0, -1] * vtrz[0, 0, -1] @@ -592,11 +515,8 @@ def warm_rain( ) / (dm + m1_rain[0, 0, -1] - m1_rain) # Heat transportation during sedimentation with computation(PARALLEL): - with interval(0, 1): - if do_sedi_heat and (no_fall == 0): - # Input q fields are dry mixing ratios, and dm is dry air mass dgz = -0.5 * constants.GRAV * dz1 cvn = dp1 * ( @@ -617,9 +537,7 @@ def warm_rain( tz = tz + m1_rain * dgz / tmp with interval(1, None): - if do_sedi_heat and (no_fall == 0): - # Input q fields are dry mixing ratios, and dm is dry air mass dgz = -0.5 * constants.GRAV * dz1 cvn = dp1 * ( @@ -631,9 +549,7 @@ def warm_rain( # Implicit algorithm with computation(FORWARD), interval(1, None): - if do_sedi_heat and (no_fall == 0): - tz[0, 0, 0] = ( (cvn + constants.C_LIQ * (m1_rain - m1_rain[0, 0, -1])) * tz[0, 0, 0] + m1_rain[0, 0, -1] * constants.C_LIQ * tz[0, 0, -1] @@ -641,9 +557,7 @@ def warm_rain( ) / (cvn + constants.C_LIQ * m1_rain) with computation(PARALLEL), interval(...): - if no_fall == 0: - # Evaporation and accretion of rain for the remaining 1/2 time step qgz, qiz, qlz, qrz, qsz, qvz, tz = functions.revap_racc( dt5, @@ -673,61 +587,46 @@ def warm_rain( # Auto-conversion assuming linear subgrid vertical distribution of # cloud water following lin et al. 1994, mwr if irain_f != 0: - qlz, qrz = functions.autoconv_no_subgrid_var( use_ccn, fac_rc, t_wfr, so3, dt_rain, qlz, qrz, tz, den, ccn, c_praut ) # With subgrid variability with computation(FORWARD): - with interval(0, 1): - if (irain_f == 0) and z_slope_liq: dl = 0.0 with interval(1, None): - if (irain_f == 0) and z_slope_liq: dq = 0.5 * (qlz[0, 0, 0] - qlz[0, 0, -1]) with computation(PARALLEL): - with interval(1, -1): - if (irain_f == 0) and z_slope_liq: - # Use twice the strength of the # positive definiteness limiter (lin et al 1994) dl = 0.5 * min(abs(dq + dq[0, 0, +1]), 0.5 * qlz[0, 0, 0]) if dq * dq[0, 0, +1] <= 0.0: - if dq > 0.0: # Local maximum - dl = min(dl, min(dq, -dq[0, 0, +1])) else: - dl = 0.0 with interval(-1, None): - if (irain_f == 0) and z_slope_liq: dl = 0.0 with computation(PARALLEL), interval(...): - if irain_f == 0: - if z_slope_liq: - # Impose a presumed background horizontal variability that is # proportional to the value itself dl = max(dl, max(functions.QVMIN, h_var * qlz)) else: - dl = max(functions.QVMIN, h_var * qlz) qlz, qrz = functions.autoconv_subgrid_var( @@ -748,11 +647,9 @@ def warm_rain( rain = rain + r1 if is_first: - m1 = m1 + m1_rain else: - m1 = m1 + m1_rain + m1_sol @@ -788,7 +685,6 @@ def sedimentation( from __externals__ import do_sedi_heat, do_sedi_w, ql_mlt, tice, use_ppm, vi_fac with computation(PARALLEL), interval(...): - # Sedimentation of cloud ice, snow, and graupel vtgz, vtiz, vtsz = functions.fall_speed(log_10, qgz, qiz, qlz, qsz, tz, den) @@ -808,40 +704,31 @@ def sedimentation( k0 removed to avoid having to introduce a k_idx field """ with computation(FORWARD): - with interval(0, 1): - if tz > tice: stop_k = 1 else: stop_k = 0 with interval(1, -1): - if stop_k[0, 0, -1] == 0: - if tz > tice: stop_k = 1 else: stop_k = 0 else: - stop_k = 1 with interval(-1, None): - stop_k = 1 with computation(PARALLEL), interval(...): - if stop_k == 1: - # Melting of cloud ice (before fall) tc = tz - tice if (qiz > functions.QCMIN) and (tc > 0.0): - sink = min(qiz, fac_imlt * tc / icpk) tmp = min(sink, functions.dim(ql_mlt, qlz)) qlz = qlz + tmp @@ -859,7 +746,6 @@ def sedimentation( tc = tz - tice with computation(PARALLEL), interval(0, -1): - # Turn off melting when cloud microphysics time step is small if dts < 60.0: stop_k = 0 @@ -868,84 +754,64 @@ def sedimentation( stop_k = 0 with computation(BACKWARD): - with interval(-1, None): - ze = zs - dz1 with interval(1, -1): - ze = ze[0, 0, +1] - dz1 # dz < 0 with interval(0, 1): - ze = ze[0, 0, +1] - dz1 # dz < 0 zt = ze with computation(PARALLEL), interval(...): - if stop_k == 1: - # Update capacity heat and latent heat coefficient lhi = constants.LI00 + constants.DC_ICE * tz icpk = lhi / cvm # Melting of falling cloud ice into rain with computation(FORWARD): - with interval(0, 1): - if qiz > functions.QRMIN: no_fall = 0 else: no_fall = 1 with interval(1, None): - if no_fall[0, 0, -1] == 1: - if qiz > functions.QRMIN: no_fall = 0 else: no_fall = 1 else: - no_fall = 0 with computation(BACKWARD), interval(0, -1): - if no_fall[0, 0, +1] == 0: no_fall = no_fall[0, 0, +1] with computation(PARALLEL), interval(...): - if (vi_fac < 1.0e-5) or (no_fall == 1): i1 = 0.0 with computation(PARALLEL): - with interval(1, -1): - if (vi_fac >= 1.0e-5) and (no_fall == 0): zt = ze - dt5 * (vtiz[0, 0, -1] + vtiz) with interval(-1, None): - if (vi_fac >= 1.0e-5) and (no_fall == 0): - zt = ze - dt5 * (vtiz[0, 0, -1] + vtiz) zt_kbot1 = zs - dts * vtiz with computation(FORWARD): - with interval(1, -1): - if (vi_fac >= 1.0e-5) and (no_fall[0, 0, -1] == 0) and (zt >= zt[0, 0, -1]): zt = zt[0, 0, -1] - functions.DZ_MIN_FLIP with interval(-1, None): - if (vi_fac >= 1.0e-5) and (no_fall[0, 0, -1] == 0) and (zt >= zt[0, 0, -1]): zt = zt[0, 0, -1] - functions.DZ_MIN_FLIP @@ -953,89 +819,66 @@ def sedimentation( zt_kbot1 = zt - functions.DZ_MIN_FLIP with computation(BACKWARD), interval(0, -1): - if (vi_fac >= 1.0e-5) and (no_fall == 0): zt_kbot1 = zt_kbot1[0, 0, +1] - functions.DZ_MIN_FLIP with computation(PARALLEL), interval(...): - if (vi_fac >= 1.0e-5) and (no_fall == 0): - if do_sedi_w: dm = dp1 * (1.0 + qvz + qlz + qrz + qiz + qsz + qgz) with computation(PARALLEL): - with interval(0, -1): - if (not use_ppm) and (vi_fac >= 1.0e-5) and (no_fall == 0): dz = ze - ze[0, 0, +1] with interval(-1, None): - if (not use_ppm) and (vi_fac >= 1.0e-5) and (no_fall == 0): dz = ze - zs with computation(PARALLEL), interval(...): - if (not use_ppm) and (vi_fac >= 1.0e-5) and (no_fall == 0): - dd = dts * vtiz qiz = qiz * dp1 # Sedimentation with computation(FORWARD): - with interval(0, 1): - if (not use_ppm) and (vi_fac >= 1.0e-5) and (no_fall == 0): qm = qiz / (dz + dd) with interval(1, None): - if (not use_ppm) and (vi_fac >= 1.0e-5) and (no_fall == 0): qm = (qiz[0, 0, 0] + dd[0, 0, -1] * qm[0, 0, -1]) / (dz + dd) with computation(PARALLEL), interval(...): - if (not use_ppm) and (vi_fac >= 1.0e-5) and (no_fall == 0): - # qm is density at this stage qm = qm * dz # Output mass fluxes with computation(FORWARD): - with interval(0, 1): - if (not use_ppm) and (vi_fac >= 1.0e-5) and (no_fall == 0): m1_sol = qiz - qm with interval(1, None): - if (not use_ppm) and (vi_fac >= 1.0e-5) and (no_fall == 0): m1_sol = m1_sol[0, 0, -1] + qiz[0, 0, 0] - qm with computation(BACKWARD): - with interval(-1, None): - if (not use_ppm) and (vi_fac >= 1.0e-5) and (no_fall == 0): i1 = m1_sol with interval(0, -1): - if (not use_ppm) and (vi_fac >= 1.0e-5) and (no_fall == 0): i1 = i1[0, 0, +1] with computation(PARALLEL): - with interval(0, 1): - if (vi_fac >= 1.0e-5) and (no_fall == 0): - if not use_ppm: - # Update qiz = qm / dp1 @@ -1044,16 +887,12 @@ def sedimentation( w = (dm * w + m1_sol * vtiz) / (dm - m1_sol) with interval(1, None): - if (vi_fac >= 1.0e-5) and (no_fall == 0): - if not use_ppm: - # Update qiz = qm / dp1 if do_sedi_w: - w[0, 0, 0] = ( dm * w[0, 0, 0] - m1_sol[0, 0, -1] * vtiz[0, 0, -1] @@ -1062,62 +901,48 @@ def sedimentation( # Melting of falling snow into rain with computation(FORWARD): - with interval(0, 1): - if qsz > functions.QRMIN: no_fall = 0 else: no_fall = 1 with interval(1, None): - if no_fall[0, 0, -1] == 1: - if qsz > functions.QRMIN: no_fall = 0 else: no_fall = 1 else: - no_fall = 0 with computation(BACKWARD), interval(0, -1): - if no_fall[0, 0, +1] == 0: no_fall = no_fall[0, 0, +1] with computation(PARALLEL), interval(...): - r1 = 0.0 if no_fall == 1: s1 = 0.0 with computation(PARALLEL): - with interval(1, -1): - if no_fall == 0: zt = ze - dt5 * (vtsz[0, 0, -1] + vtsz) with interval(-1, None): - if no_fall == 0: - zt = ze - dt5 * (vtsz[0, 0, -1] + vtsz) zt_kbot1 = zs - dts * vtsz with computation(FORWARD): - with interval(1, -1): - if (no_fall[0, 0, -1] == 0) and (zt >= zt[0, 0, -1]): zt = zt[0, 0, -1] - functions.DZ_MIN_FLIP with interval(-1, None): - if (no_fall[0, 0, -1] == 0) and (zt >= zt[0, 0, -1]): zt = zt[0, 0, -1] - functions.DZ_MIN_FLIP @@ -1125,89 +950,66 @@ def sedimentation( zt_kbot1 = zt - functions.DZ_MIN_FLIP with computation(BACKWARD), interval(0, -1): - if no_fall == 0: zt_kbot1 = zt_kbot1[0, 0, +1] - functions.DZ_MIN_FLIP with computation(PARALLEL), interval(...): - if no_fall == 0: - if do_sedi_w: dm = dp1 * (1.0 + qvz + qlz + qrz + qiz + qsz + qgz) with computation(PARALLEL): - with interval(0, -1): - if (not use_ppm) and (no_fall == 0): dz = ze - ze[0, 0, +1] with interval(-1, None): - if (not use_ppm) and (no_fall == 0): dz = ze - zs with computation(PARALLEL), interval(...): - if (not use_ppm) and (no_fall == 0): - dd = dts * vtsz qsz = qsz * dp1 # Sedimentation with computation(FORWARD): - with interval(0, 1): - if (not use_ppm) and (no_fall == 0): qm = qsz / (dz + dd) with interval(1, None): - if (not use_ppm) and (no_fall == 0): qm = (qsz[0, 0, 0] + dd[0, 0, -1] * qm[0, 0, -1]) / (dz + dd) with computation(PARALLEL), interval(...): - if (not use_ppm) and (no_fall == 0): - # qm is density at this stage qm = qm * dz # Output mass fluxes with computation(FORWARD): - with interval(0, 1): - if (not use_ppm) and (no_fall == 0): m1_tf = qsz - qm with interval(1, None): - if (not use_ppm) and (no_fall == 0): m1_tf = m1_tf[0, 0, -1] + qsz[0, 0, 0] - qm with computation(BACKWARD): - with interval(-1, None): - if (not use_ppm) and (no_fall == 0): s1 = m1_tf with interval(0, -1): - if (not use_ppm) and (no_fall == 0): s1 = s1[0, 0, +1] with computation(PARALLEL): - with interval(0, 1): - if no_fall == 0: - if not use_ppm: - # Update qsz = qm / dp1 @@ -1218,18 +1020,14 @@ def sedimentation( w = (dm * w + m1_tf * vtsz) / (dm - m1_tf) with interval(1, None): - if no_fall == 0: - if not use_ppm: - # Update qsz = qm / dp1 m1_sol = m1_sol + m1_tf if do_sedi_w: - w[0, 0, 0] = ( dm * w[0, 0, 0] - m1_tf[0, 0, -1] * vtsz[0, 0, -1] @@ -1238,60 +1036,46 @@ def sedimentation( # Melting of falling graupel into rain with computation(FORWARD): - with interval(0, 1): - if qgz > functions.QRMIN: no_fall = 0 else: no_fall = 1 with interval(1, None): - if no_fall[0, 0, -1] == 1: - if qgz > functions.QRMIN: no_fall = 0 else: no_fall = 1 else: - no_fall = 0 with computation(BACKWARD), interval(0, -1): - if no_fall[0, 0, +1] == 0: no_fall = no_fall[0, 0, +1] with computation(PARALLEL), interval(...): - if no_fall == 1: g1 = 0.0 with computation(PARALLEL): - with interval(1, -1): - if no_fall == 0: zt = ze - dt5 * (vtgz[0, 0, -1] + vtgz) with interval(-1, None): - if no_fall == 0: - zt = ze - dt5 * (vtgz[0, 0, -1] + vtgz) zt_kbot1 = zs - dts * vtgz with computation(FORWARD): - with interval(1, -1): - if (no_fall[0, 0, -1] == 0) and (zt >= zt[0, 0, -1]): zt = zt[0, 0, -1] - functions.DZ_MIN_FLIP with interval(-1, None): - if (no_fall[0, 0, -1] == 0) and (zt >= zt[0, 0, -1]): zt = zt[0, 0, -1] - functions.DZ_MIN_FLIP @@ -1299,89 +1083,66 @@ def sedimentation( zt_kbot1 = zt - functions.DZ_MIN_FLIP with computation(BACKWARD), interval(0, -1): - if no_fall == 0: zt_kbot1 = zt_kbot1[0, 0, +1] - functions.DZ_MIN_FLIP with computation(PARALLEL), interval(...): - if no_fall == 0: - if do_sedi_w: dm = dp1 * (1.0 + qvz + qlz + qrz + qiz + qsz + qgz) with computation(PARALLEL): - with interval(0, -1): - if (not use_ppm) and (no_fall == 0): dz = ze - ze[0, 0, +1] with interval(-1, None): - if (not use_ppm) and (no_fall == 0): dz = ze - zs with computation(PARALLEL), interval(...): - if (not use_ppm) and (no_fall == 0): - dd = dts * vtgz qgz = qgz * dp1 # Sedimentation with computation(FORWARD): - with interval(0, 1): - if (not use_ppm) and (no_fall == 0): qm = qgz / (dz + dd) with interval(1, None): - if (not use_ppm) and (no_fall == 0): qm = (qgz[0, 0, 0] + dd[0, 0, -1] * qm[0, 0, -1]) / (dz + dd) with computation(PARALLEL), interval(...): - if (not use_ppm) and (no_fall == 0): - # qm is density at this stage qm = qm * dz # Output mass fluxes with computation(FORWARD): - with interval(0, 1): - if (not use_ppm) and (no_fall == 0): m1_tf = qgz - qm with interval(1, None): - if (not use_ppm) and (no_fall == 0): m1_tf = m1_tf[0, 0, -1] + qgz[0, 0, 0] - qm with computation(BACKWARD): - with interval(-1, None): - if (not use_ppm) and (no_fall == 0): g1 = m1_tf with interval(0, -1): - if (not use_ppm) and (no_fall == 0): g1 = g1[0, 0, +1] with computation(PARALLEL): - with interval(0, 1): - if no_fall == 0: - if not use_ppm: - # Update qgz = qm / dp1 @@ -1392,18 +1153,14 @@ def sedimentation( w = (dm * w + m1_tf * vtgz) / (dm - m1_tf) with interval(1, None): - if no_fall == 0: - if not use_ppm: - # Update qgz = qm / dp1 m1_sol = m1_sol + m1_tf if do_sedi_w: - w[0, 0, 0] = ( dm * w[0, 0, 0] - m1_tf[0, 0, -1] * vtgz[0, 0, -1] @@ -1411,7 +1168,6 @@ def sedimentation( ) / (dm + m1_tf[0, 0, -1] - m1_tf) with computation(PARALLEL), interval(...): - rain = rain + r1 # From melted snow and ice that reached the ground snow = snow + s1 graupel = graupel + g1 @@ -1419,11 +1175,8 @@ def sedimentation( # Heat transportation during sedimentation with computation(PARALLEL): - with interval(0, 1): - if do_sedi_heat: - # Input q fields are dry mixing ratios, and dm is dry air mass dgz = -0.5 * constants.GRAV * dz1 cvn = dp1 * ( @@ -1444,9 +1197,7 @@ def sedimentation( tz = tz + m1_sol * dgz / tmp with interval(1, None): - if do_sedi_heat: - # Input q fields are dry mixing ratios, and dm is dry air mass dgz = -0.5 * constants.GRAV * dz1 cvn = dp1 * ( @@ -1458,9 +1209,7 @@ def sedimentation( # Implicit algorithm with computation(FORWARD), interval(1, None): - if do_sedi_heat: - tz[0, 0, 0] = ( (cvn + constants.C_ICE * (m1_sol - m1_sol[0, 0, -1])) * tz[0, 0, 0] + m1_sol[0, 0, -1] * constants.C_ICE * tz[0, 0, -1] @@ -1540,7 +1289,6 @@ def icloud( from __externals__ import qi_gen, qi_lim, ql_mlt, t_wfr, tice, z_slope_ice with computation(PARALLEL), interval(...): - # Ice-phase microphysics # Define heat capacity and latent heat coefficient @@ -1557,7 +1305,6 @@ def icloud( t_wfr_tmp = t_wfr if (tz > tice) and (qiz > functions.QCMIN): - # pimlt: instant melting of cloud ice melt = min(qiz, fac_imlt * (tz - tice) / icpk) tmp = min(melt, functions.dim(ql_mlt, qlz)) # Maximum ql amount @@ -1572,7 +1319,6 @@ def icloud( tz = tz - melt * lhi / cvm elif (tz < t_wfr) and (qlz > functions.QCMIN): - # - pihom: homogeneous freezing of cloud water into cloud ice # - This is the 1st occurence of liquid water freezing # in the split mp process @@ -1594,52 +1340,39 @@ def icloud( # Vertical subgrid variability with computation(FORWARD): - with interval(0, 1): - if z_slope_ice: di = 0.0 with interval(1, None): - if z_slope_ice: dq = 0.5 * (qiz[0, 0, 0] - qiz[0, 0, -1]) with computation(PARALLEL): - with interval(1, -1): - if z_slope_ice: - # Use twice the strength of the # positive definiteness limiter (lin et al 1994) di = 0.5 * min(abs(dq + dq[0, 0, +1]), 0.5 * qiz[0, 0, 0]) if dq * dq[0, 0, +1] <= 0.0: - if dq > 0.0: # Local maximum - di = min(di, min(dq, -dq[0, 0, +1])) else: - di = 0.0 with interval(-1, None): - if z_slope_ice: di = 0.0 with computation(PARALLEL), interval(...): - if z_slope_ice: - # Impose a presumed background horizontal variability that is # proportional to the value itself di = max(di, max(functions.QVMIN, h_var * qiz)) else: - di = max(functions.QVMIN, h_var * qiz) qaz, qgz, qiz, qlz, qrz, qsz, qvz, tz = functions.icloud_main( @@ -1764,9 +1497,7 @@ def fields_update( # Momentum transportation during sedimentation (dp1 is dry mass; dp0 # is the old moist total mass) with computation(FORWARD), interval(1, None): - if sedi_transport: - u1[0, 0, 0] = (dp0[0, 0, 0] * u1[0, 0, 0] + m1[0, 0, -1] * u1[0, 0, -1]) / ( dp0[0, 0, 0] + m1[0, 0, -1] ) @@ -1775,14 +1506,11 @@ def fields_update( ) with computation(PARALLEL), interval(1, None): - if sedi_transport: - udt = udt + (u1 - u0) * rdt vdt = vdt + (v1 - v0) * rdt with computation(PARALLEL), interval(...): - # Update moist air mass (actually hydrostatic pressure) and convert # to dry mixing ratios omq = dp1 / dp0 @@ -1804,11 +1532,9 @@ def fields_update( # Update cloud fraction tendency if do_qa: - qa_dt = 0.0 else: - qa_dt = qa_dt + rdt * (qaz / ntimes - qa0) """ @@ -1846,24 +1572,24 @@ class MicrophysicsState: def __init__( self, - pt: pace.util.Quantity, - qvapor: pace.util.Quantity, - qliquid: pace.util.Quantity, - qrain: pace.util.Quantity, - qice: pace.util.Quantity, - qsnow: pace.util.Quantity, - qgraupel: pace.util.Quantity, - qcld: pace.util.Quantity, - ua: pace.util.Quantity, - va: pace.util.Quantity, - delp: pace.util.Quantity, - delz: pace.util.Quantity, - omga: pace.util.Quantity, - delprsi: pace.util.Quantity, - wmp: pace.util.Quantity, - dz: pace.util.Quantity, - tendency: pace.util.Quantity, - land: pace.util.Quantity, + pt: Quantity, + qvapor: Quantity, + qliquid: Quantity, + qrain: Quantity, + qice: Quantity, + qsnow: Quantity, + qgraupel: Quantity, + qcld: Quantity, + ua: Quantity, + va: Quantity, + delp: Quantity, + delz: Quantity, + omga: Quantity, + delprsi: Quantity, + wmp: Quantity, + dz: Quantity, + tendency: Quantity, + land: Quantity, ): self.pt = pt self.qvapor = qvapor @@ -1898,7 +1624,7 @@ class Microphysics: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, grid_data: GridData, namelist: PhysicsConfig, ): diff --git a/physics/pace/physics/stencils/physics.py b/physics/pace/physics/stencils/physics.py index 2de7d0a87..b9b7f6237 100644 --- a/physics/pace/physics/stencils/physics.py +++ b/physics/pace/physics/stencils/physics.py @@ -1,4 +1,5 @@ import gt4py.cartesian.gtscript as gtscript +import ndsl.constants as constants from gt4py.cartesian.gtscript import ( BACKWARD, FORWARD, @@ -8,20 +9,18 @@ interval, log, ) +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField +from ndsl.grid import GridData +from ndsl.initialization.allocator import QuantityFactory -import pace.util -import pace.util.constants as constants -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField +from pace.physics import PHYSICS_PACKAGES, PhysicsConfig from pace.physics.physics_state import PhysicsState from pace.physics.stencils.get_phi_fv3 import get_phi_fv3 from pace.physics.stencils.get_prs_fv3 import get_prs_fv3 from pace.physics.stencils.microphysics import Microphysics -from pace.util import X_DIM, Y_DIM, Z_DIM -from pace.util.grid import GridData - -from .._config import PHYSICS_PACKAGES, PhysicsConfig def atmos_phys_driver_statein( @@ -199,13 +198,13 @@ class Physics: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, grid_data: GridData, namelist: PhysicsConfig, ): schemes = [scheme.value for scheme in namelist.schemes] for scheme in schemes: - if scheme not in PHYSICS_PACKAGES: + if scheme not in PHYSICS_PACKAGES: # type: ignore raise NotImplementedError( f"{scheme} is not an implemented physics parameterization" ) @@ -275,7 +274,6 @@ def _setup_statein(self): self._p00 = 1.0e5 def __call__(self, physics_state: PhysicsState, timestep: float): - self._atmos_phys_driver_statein( self._prsik, physics_state.phii, diff --git a/stencils/pace/stencils/fv_update_phys.py b/physics/pace/physics/update/fv_update_phys.py similarity index 87% rename from stencils/pace/stencils/fv_update_phys.py rename to physics/pace/physics/update/fv_update_phys.py index fe027cd0b..bc1c1e8b8 100644 --- a/stencils/pace/stencils/fv_update_phys.py +++ b/physics/pace/physics/update/fv_update_phys.py @@ -1,17 +1,19 @@ import gt4py.cartesian.gtscript as gtscript +import ndsl.constants as constants from gt4py.cartesian.gtscript import FORWARD, PARALLEL, computation, exp, interval, log +from ndsl.comm.communicator import Communicator +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.dace.wrapped_halo_exchange import WrappedHaloUpdater +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField, FloatFieldIJ +from ndsl.grid import DriverGridData, GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.quantity import Quantity +from ndsl.stencils.c2l_ord import CubedToLatLon -import pace.util -import pace.util.constants as constants from pace import fv3core -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.dace.wrapped_halo_exchange import WrappedHaloUpdater -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ -from pace.stencils.c2l_ord import CubedToLatLon -from pace.stencils.update_dwind_phys import AGrid2DGridPhysics -from pace.util import X_DIM, Y_DIM -from pace.util.grid import DriverGridData, GridData +from pace.physics.update.update_dwind_phys import AGrid2DGridPhysics # TODO: This is the same as moist_cv.py in fv3core, should move to integration dir @@ -61,7 +63,6 @@ def update_pressure_and_surface_winds( u_srf: FloatFieldIJ, v_srf: FloatFieldIJ, ): - with computation(FORWARD), interval(1, None): pe = pe[0, 0, -1] + delp[0, 0, -1] with computation(PARALLEL), interval(1, None): @@ -84,14 +85,14 @@ class ApplyPhysicsToDycore: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, grid_data: GridData, namelist, - comm: pace.util.Communicator, + comm: Communicator, grid_info: DriverGridData, state: fv3core.DycoreState, - u_dt: pace.util.Quantity, - v_dt: pace.util.Quantity, + u_dt: Quantity, + v_dt: Quantity, ): self._grid_type = grid_info.grid_type orchestrate( @@ -131,7 +132,7 @@ def __init__( origin = grid_indexing.origin_compute() shape = grid_indexing.max_shape full_3Dfield_1pts_halo_spec = quantity_factory.get_quantity_halo_spec( - dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + dims=[X_DIM, Y_DIM, Z_DIM], n_halo=1, ) self._udt_halo_updater = WrappedHaloUpdater( diff --git a/stencils/pace/stencils/update_atmos_state.py b/physics/pace/physics/update/update_atmos_state.py similarity index 94% rename from stencils/pace/stencils/update_atmos_state.py rename to physics/pace/physics/update/update_atmos_state.py index 789e40ea6..472eb31db 100644 --- a/stencils/pace/stencils/update_atmos_state.py +++ b/physics/pace/physics/update/update_atmos_state.py @@ -1,15 +1,17 @@ from typing import Optional from gt4py.cartesian.gtscript import BACKWARD, FORWARD, PARALLEL, computation, interval +from ndsl.comm.communicator import Communicator +from ndsl.constants import X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_INTERFACE_DIM +from ndsl.dsl.dace.orchestration import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import Float, FloatField +from ndsl.grid import DriverGridData, GridData +from ndsl.initialization.allocator import QuantityFactory import pace.fv3core.stencils.fv_subgridz as fv_subgridz -import pace.util from pace import fv3core -from pace.dsl.dace.orchestration import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField -from pace.stencils.fv_update_phys import ApplyPhysicsToDycore -from pace.util.grid import DriverGridData, GridData +from pace.physics.update.fv_update_phys import ApplyPhysicsToDycore # TODO: when this file is not importable from physics or fv3core, import @@ -17,9 +19,7 @@ def fill_gfs_delp(delp: FloatField, q: FloatField, q_min: Float): - with computation(BACKWARD): - with interval(0, -2): if q[0, 0, 1] < q_min: q = q[0, 0, 0] + (q[0, 0, 1] - q_min) * delp[0, 0, 1] / delp[0, 0, 0] @@ -149,7 +149,7 @@ class DycoreToPhysics: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, dycore_config: fv3core.DynamicalCoreConfig, do_dry_convective_adjust: bool, dycore_only: bool, @@ -163,9 +163,9 @@ def __init__( self._copy_dycore_to_physics = stencil_factory.from_dims_halo( copy_dycore_to_physics, compute_dims=[ - pace.util.X_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, - pace.util.Z_INTERFACE_DIM, + X_INTERFACE_DIM, + Y_INTERFACE_DIM, + Z_INTERFACE_DIM, ], compute_halos=(0, 0), ) @@ -242,10 +242,10 @@ def __init__( stencil_factory: StencilFactory, grid_data: GridData, namelist, - comm: pace.util.Communicator, + comm: Communicator, grid_info: DriverGridData, state: fv3core.DycoreState, - quantity_factory: pace.util.QuantityFactory, + quantity_factory: QuantityFactory, dycore_only: bool, apply_tendencies: bool, tendency_state, diff --git a/stencils/pace/stencils/update_dwind_phys.py b/physics/pace/physics/update/update_dwind_phys.py similarity index 98% rename from stencils/pace/stencils/update_dwind_phys.py rename to physics/pace/physics/update/update_dwind_phys.py index f5d3242d9..2d671eaa6 100644 --- a/stencils/pace/stencils/update_dwind_phys.py +++ b/physics/pace/physics/update/update_dwind_phys.py @@ -1,11 +1,11 @@ from gt4py.cartesian.gtscript import PARALLEL, computation, interval - -import pace.util -from pace.dsl.dace import orchestrate -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import FloatField, FloatFieldI, FloatFieldIJ -from pace.util import X_DIM, Y_DIM, Z_DIM -from pace.util.grid import DriverGridData +from ndsl.comm.partitioner import TilePartitioner +from ndsl.constants import X_DIM, Y_DIM, Z_DIM +from ndsl.dsl.dace import orchestrate +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import FloatField, FloatFieldI, FloatFieldIJ +from ndsl.grid import DriverGridData +from ndsl.initialization.allocator import QuantityFactory def set_winds_zero( @@ -170,8 +170,8 @@ class AGrid2DGridPhysics: def __init__( self, stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, - partitioner: pace.util.TilePartitioner, + quantity_factory: QuantityFactory, + partitioner: TilePartitioner, rank: int, namelist, grid_info: DriverGridData, diff --git a/physics/setup.py b/physics/setup.py index 785e96ee5..cd1c6c17a 100755 --- a/physics/setup.py +++ b/physics/setup.py @@ -10,11 +10,8 @@ requirements = [ "f90nml>=1.1.0", - "gt4py", "numpy", - "pace-util>=0.4.3", - "pace-stencils", - "pace-dsl", + "ndsl", "xarray", ] diff --git a/physics/tests/savepoint/conftest.py b/physics/tests/savepoint/conftest.py index 0c3956cfe..2eeb1dcbf 100644 --- a/physics/tests/savepoint/conftest.py +++ b/physics/tests/savepoint/conftest.py @@ -1,10 +1,10 @@ # This magical series of imports is to de-duplicate the conftest.py file # between the dycore and physics tests. We can avoid this if we refactor the tests # to all run from one directory -import pace.stencils.testing.conftest -from pace.stencils.testing.conftest import * # noqa: F403,F401 +import ndsl.stencils.testing.conftest +from ndsl.stencils.testing.conftest import * # noqa: F403,F401 from . import translate -pace.stencils.testing.conftest.translate = translate # type: ignore +ndsl.stencils.testing.conftest.translate = translate # type: ignore diff --git a/physics/tests/savepoint/test_translate.py b/physics/tests/savepoint/test_translate.py index 5550ff1f2..8dadf15a9 100644 --- a/physics/tests/savepoint/test_translate.py +++ b/physics/tests/savepoint/test_translate.py @@ -1 +1 @@ -from pace.stencils.testing.test_translate import * # noqa: F403,F401 +from ndsl.stencils.testing.test_translate import * # noqa: F403,F401 diff --git a/physics/tests/savepoint/translate/__init__.py b/physics/tests/savepoint/translate/__init__.py index bc2e9f0b8..82a08c761 100644 --- a/physics/tests/savepoint/translate/__init__.py +++ b/physics/tests/savepoint/translate/__init__.py @@ -1,14 +1,11 @@ # flake8: noqa: F401 -from pace.stencils.testing.translate_update_dwind_phys import TranslateUpdateDWindsPhys - from .translate_atmos_phy_statein import TranslateAtmosPhysDriverStatein -from .translate_driver import TranslateDriver from .translate_fillgfs import TranslateFillGFS from .translate_fv_update_phys import TranslateFVUpdatePhys -from .translate_gfs_physics_driver import TranslateGFSPhysicsDriver from .translate_microphysics import TranslateMicroph from .translate_phifv3 import TranslatePhiFV3 from .translate_prsfv3 import TranslatePrsFV3 +from .translate_update_dwind_phys import TranslateUpdateDWindsPhys from .translate_update_pressure_sfc_winds_phys import ( TranslatePhysUpdatePressureSurfaceWinds, ) diff --git a/physics/tests/savepoint/translate/translate_atmos_phy_statein.py b/physics/tests/savepoint/translate/translate_atmos_phy_statein.py index f08c69bbb..ed5f5e79f 100644 --- a/physics/tests/savepoint/translate/translate_atmos_phy_statein.py +++ b/physics/tests/savepoint/translate/translate_atmos_phy_statein.py @@ -1,9 +1,9 @@ +import ndsl.dsl.gt4py_utils as utils import numpy as np +from ndsl.constants import KAPPA +from translate_physics import TranslatePhysicsFortranData2Py -import pace.dsl.gt4py_utils as utils from pace.physics.stencils.physics import atmos_phys_driver_statein -from pace.stencils.testing.translate_physics import TranslatePhysicsFortranData2Py -from pace.util.constants import KAPPA class TranslateAtmosPhysDriverStatein(TranslatePhysicsFortranData2Py): diff --git a/physics/tests/savepoint/translate/translate_fillgfs.py b/physics/tests/savepoint/translate/translate_fillgfs.py index 50a1c1421..479a9ca8a 100644 --- a/physics/tests/savepoint/translate/translate_fillgfs.py +++ b/physics/tests/savepoint/translate/translate_fillgfs.py @@ -1,9 +1,9 @@ +import ndsl.dsl.gt4py_utils as utils import numpy as np +from ndsl.utils import safe_assign_array +from translate_physics import TranslatePhysicsFortranData2Py -import pace.dsl.gt4py_utils as utils -from pace.stencils.testing.translate_physics import TranslatePhysicsFortranData2Py -from pace.stencils.update_atmos_state import fill_gfs_delp -from pace.util.utils import safe_assign_array +from pace.physics.update.update_atmos_state import fill_gfs_delp class TranslateFillGFS(TranslatePhysicsFortranData2Py): diff --git a/physics/tests/savepoint/translate/translate_fv_update_phys.py b/physics/tests/savepoint/translate/translate_fv_update_phys.py index 9d2fbeebf..c57ed2ce0 100644 --- a/physics/tests/savepoint/translate/translate_fv_update_phys.py +++ b/physics/tests/savepoint/translate/translate_fv_update_phys.py @@ -1,17 +1,19 @@ import dataclasses +import ndsl.dsl.gt4py_utils as utils import numpy as np - -import pace.dsl -import pace.dsl.gt4py_utils as utils -import pace.util -from pace.dsl.typing import FloatField, FloatFieldIJ -from pace.stencils.fv_update_phys import ApplyPhysicsToDycore -from pace.stencils.testing.translate_physics import ( +from ndsl.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM +from ndsl.dsl.stencil import StencilFactory +from ndsl.dsl.typing import FloatField, FloatFieldIJ +from ndsl.namelist import Namelist +from ndsl.quantity import Quantity +from ndsl.utils import safe_assign_array +from translate_physics import ( ParallelPhysicsTranslate2Py, transform_dwind_serialized_data, ) -from pace.util.utils import safe_assign_array + +from pace.physics.update.fv_update_phys import ApplyPhysicsToDycore try: @@ -53,8 +55,8 @@ class TranslateFVUpdatePhys(ParallelPhysicsTranslate2Py): def __init__( self, grid, - namelist: pace.util.Namelist, - stencil_factory: pace.dsl.StencilFactory, + namelist: Namelist, + stencil_factory: StencilFactory, ): super().__init__(grid, namelist, stencil_factory) self.stencil_factory = stencil_factory @@ -173,9 +175,9 @@ def compute_parallel(self, inputs, communicator): tendencies = {} for key in ["u_dt", "v_dt", "t_dt"]: storage = inputs.pop(key) - tendencies[key] = pace.util.Quantity( + tendencies[key] = Quantity( storage, - dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], + dims=[X_DIM, Y_DIM, Z_DIM], units="test", origin=(0, 0, 0), extent=storage.shape, @@ -192,14 +194,14 @@ def compute_parallel(self, inputs, communicator): tendencies["u_dt"], tendencies["v_dt"], ) - dims_u = [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM, pace.util.Z_DIM] + dims_u = [X_DIM, Y_INTERFACE_DIM, Z_DIM] u_quantity = self.grid.make_quantity( state.u, dims=dims_u, origin=self.grid.sizer.get_origin(dims_u), extent=self.grid.sizer.get_extent(dims_u), ) - dims_v = [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM, pace.util.Z_DIM] + dims_v = [X_INTERFACE_DIM, Y_DIM, Z_DIM] v_quantity = self.grid.make_quantity( state.v, dims=dims_v, diff --git a/physics/tests/savepoint/translate/translate_gfs_physics_driver.py b/physics/tests/savepoint/translate/translate_gfs_physics_driver.py index ab8f870b7..6e9b5ac49 100644 --- a/physics/tests/savepoint/translate/translate_gfs_physics_driver.py +++ b/physics/tests/savepoint/translate/translate_gfs_physics_driver.py @@ -1,11 +1,12 @@ import copy -import pace.dsl.gt4py_utils as utils -import pace.util as util +import ndsl.dsl.gt4py_utils as utils +import ndsl.util as util +from translate_physics import TranslatePhysicsFortranData2Py + from pace.physics import PHYSICS_PACKAGES from pace.physics.stencils.physics import Physics, PhysicsState -from pace.stencils import update_atmos_state -from pace.stencils.testing.translate_physics import TranslatePhysicsFortranData2Py +from pace.physics.update import update_atmos_state class TranslateGFSPhysicsDriver(TranslatePhysicsFortranData2Py): diff --git a/physics/tests/savepoint/translate/translate_microphysics.py b/physics/tests/savepoint/translate/translate_microphysics.py index 49ebc4dc4..afee50af5 100644 --- a/physics/tests/savepoint/translate/translate_microphysics.py +++ b/physics/tests/savepoint/translate/translate_microphysics.py @@ -1,14 +1,15 @@ import copy +import ndsl.dsl.gt4py_utils as utils import numpy as np +from ndsl.dsl.typing import Float +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from translate_physics import TranslatePhysicsFortranData2Py -import pace.dsl.gt4py_utils as utils -import pace.util -from pace.dsl.typing import Float from pace.physics import PHYSICS_PACKAGES from pace.physics.stencils.microphysics import Microphysics from pace.physics.stencils.physics import PhysicsState -from pace.stencils.testing.translate_physics import TranslatePhysicsFortranData2Py class TranslateMicroph(TranslatePhysicsFortranData2Py): @@ -73,7 +74,7 @@ def compute(self, inputs): inputs["omga"] = copy.deepcopy(storage) inputs["prsi"] = copy.deepcopy(storage) inputs["prsik"] = copy.deepcopy(storage) - sizer = pace.util.SubtileGridSizer.from_tile_params( + sizer = SubtileGridSizer.from_tile_params( nx_tile=self.namelist.npx - 1, ny_tile=self.namelist.npy - 1, nz=self.namelist.npz, @@ -82,7 +83,7 @@ def compute(self, inputs): layout=self.namelist.layout, ) - quantity_factory = pace.util.QuantityFactory.from_backend( + quantity_factory = QuantityFactory.from_backend( sizer, self.stencil_factory.backend ) physics_state = PhysicsState.init_from_storages( diff --git a/physics/tests/savepoint/translate/translate_phifv3.py b/physics/tests/savepoint/translate/translate_phifv3.py index fb6e88776..34d1ef22e 100644 --- a/physics/tests/savepoint/translate/translate_phifv3.py +++ b/physics/tests/savepoint/translate/translate_phifv3.py @@ -1,5 +1,6 @@ +from translate_physics import TranslatePhysicsFortranData2Py + from pace.physics.stencils.get_phi_fv3 import get_phi_fv3 -from pace.stencils.testing.translate_physics import TranslatePhysicsFortranData2Py class TranslatePhiFV3(TranslatePhysicsFortranData2Py): diff --git a/stencils/pace/stencils/testing/translate_physics.py b/physics/tests/savepoint/translate/translate_physics.py similarity index 97% rename from stencils/pace/stencils/testing/translate_physics.py rename to physics/tests/savepoint/translate/translate_physics.py index 1afdbb3f5..1ddd9d24c 100644 --- a/stencils/pace/stencils/testing/translate_physics.py +++ b/physics/tests/savepoint/translate/translate_physics.py @@ -1,10 +1,10 @@ +import ndsl.dsl.gt4py_utils as utils import numpy as np +from ndsl.dsl.stencil import GridIndexing +from ndsl.stencils.testing.parallel_translate import ParallelTranslate2Py +from ndsl.stencils.testing.translate import TranslateFortranData2Py, as_numpy -import pace.dsl.gt4py_utils as utils -from pace.dsl.stencil import GridIndexing from pace.physics import PhysicsConfig -from pace.stencils.testing.parallel_translate import ParallelTranslate2Py -from pace.stencils.testing.translate import TranslateFortranData2Py, as_numpy def transform_dwind_serialized_data(data, grid_indexing: GridIndexing, backend: str): diff --git a/physics/tests/savepoint/translate/translate_prsfv3.py b/physics/tests/savepoint/translate/translate_prsfv3.py index 72b48d3d1..71dad355a 100644 --- a/physics/tests/savepoint/translate/translate_prsfv3.py +++ b/physics/tests/savepoint/translate/translate_prsfv3.py @@ -1,5 +1,6 @@ +from translate_physics import TranslatePhysicsFortranData2Py + from pace.physics.stencils.get_prs_fv3 import get_prs_fv3 -from pace.stencils.testing.translate_physics import TranslatePhysicsFortranData2Py class TranslatePrsFV3(TranslatePhysicsFortranData2Py): diff --git a/stencils/pace/stencils/testing/translate_update_dwind_phys.py b/physics/tests/savepoint/translate/translate_update_dwind_phys.py similarity index 84% rename from stencils/pace/stencils/testing/translate_update_dwind_phys.py rename to physics/tests/savepoint/translate/translate_update_dwind_phys.py index d7e7f847c..d166c3bee 100644 --- a/stencils/pace/stencils/testing/translate_update_dwind_phys.py +++ b/physics/tests/savepoint/translate/translate_update_dwind_phys.py @@ -1,9 +1,9 @@ import numpy as np +from ndsl.comm.partitioner import TilePartitioner +from ndsl.utils import safe_assign_array +from translate_physics import TranslatePhysicsFortranData2Py -import pace.util -from pace.stencils.testing.translate_physics import TranslatePhysicsFortranData2Py -from pace.stencils.update_dwind_phys import AGrid2DGridPhysics -from pace.util.utils import safe_assign_array +from pace.physics.update.update_dwind_phys import AGrid2DGridPhysics class TranslateUpdateDWindsPhys(TranslatePhysicsFortranData2Py): @@ -24,7 +24,7 @@ def __init__(self, grid, namelist, stencil_factory): def compute(self, inputs): self.make_storage_data_input_vars(inputs) - partitioner = pace.util.TilePartitioner(self.namelist.layout) + partitioner = TilePartitioner(self.namelist.layout) self.compute_func = AGrid2DGridPhysics( self.stencil_factory, self.grid.quantity_factory, diff --git a/physics/tests/savepoint/translate/translate_update_pressure_sfc_winds_phys.py b/physics/tests/savepoint/translate/translate_update_pressure_sfc_winds_phys.py index 58ffea1e4..583127c63 100644 --- a/physics/tests/savepoint/translate/translate_update_pressure_sfc_winds_phys.py +++ b/physics/tests/savepoint/translate/translate_update_pressure_sfc_winds_phys.py @@ -1,6 +1,7 @@ -from pace.stencils.fv_update_phys import update_pressure_and_surface_winds -from pace.stencils.testing.translate_physics import TranslatePhysicsFortranData2Py -from pace.util.constants import KAPPA +from ndsl.constants import KAPPA +from translate_physics import TranslatePhysicsFortranData2Py + +from pace.physics.update.fv_update_phys import update_pressure_and_surface_winds class TranslatePhysUpdatePressureSurfaceWinds(TranslatePhysicsFortranData2Py): diff --git a/physics/tests/savepoint/translate/translate_update_tracers_phys.py b/physics/tests/savepoint/translate/translate_update_tracers_phys.py index d8e712ee4..bc60b8512 100644 --- a/physics/tests/savepoint/translate/translate_update_tracers_phys.py +++ b/physics/tests/savepoint/translate/translate_update_tracers_phys.py @@ -1,5 +1,6 @@ -from pace.stencils.testing.translate_physics import TranslatePhysicsFortranData2Py -from pace.stencils.update_atmos_state import prepare_tendencies_and_update_tracers +from translate_physics import TranslatePhysicsFortranData2Py + +from pace.physics.update.update_atmos_state import prepare_tendencies_and_update_tracers class TranslatePhysUpdateTracers(TranslatePhysicsFortranData2Py): diff --git a/requirements_dev.txt b/requirements_dev.txt index 4978ff368..0dfbc3176 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -14,11 +14,7 @@ cftime fv3config>=0.9.0 f90nml>=1.1.0 numpy>=1.15 --e external/gt4py --e external/dace --e stencils --e dsl +-e NDSL -e physics -e fv3core -e driver --e util diff --git a/setup.cfg b/setup.cfg index 736403002..894956b62 100644 --- a/setup.cfg +++ b/setup.cfg @@ -29,7 +29,7 @@ ignore_missing_imports = True follow_imports = normal namespace_packages = True strict_optional = False -mypy_path = driver:dsl:fv3core:physics:stencils:util +mypy_path = driver:ndsl:fv3core:physics warn_unreachable = True explicit_package_bases = True diff --git a/stencils/pace/stencils/__init__.py b/stencils/pace/stencils/__init__.py deleted file mode 100644 index d3ec452c3..000000000 --- a/stencils/pace/stencils/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "0.2.0" diff --git a/stencils/pace/stencils/c2l_ord.py b/stencils/pace/stencils/c2l_ord.py deleted file mode 100644 index e4610b69b..000000000 --- a/stencils/pace/stencils/c2l_ord.py +++ /dev/null @@ -1,273 +0,0 @@ -from gt4py.cartesian.gtscript import ( - __INLINED, - PARALLEL, - computation, - horizontal, - interval, - region, -) - -import pace.dsl.gt4py_utils as utils -import pace.util -from pace import fv3core -from pace.dsl.dace.wrapped_halo_exchange import WrappedHaloUpdater -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Float, FloatField, FloatFieldIJ -from pace.util.constants import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_DIM -from pace.util.grid import GridData - - -A1 = 0.5625 -A2 = -0.0625 -C1 = 1.125 -C2 = -0.125 - - -def mock_exchange( - quantity, - domain_2d, -): - isc = domain_2d[0][0] - iec = domain_2d[0][1] - isd = domain_2d[1][0] - ied = domain_2d[1][1] - jsc = domain_2d[2][0] - jec = domain_2d[2][1] - jsd = domain_2d[3][0] - jed = domain_2d[3][1] - nhalo = isc - isd - - quantity[isd:isc, :, :] = quantity[iec - nhalo + 1 : iec + 1, :, :] - quantity[iec + 1 : ied + 1, :, :] = quantity[isc : isc + nhalo, :, :] - quantity[:, jsd:jsc, :] = quantity[:, jec - nhalo + 1 : jec + 1, :] - quantity[:, jec + 1 : jed + 1, :] = quantity[:, jsc : jsc + nhalo, :] - - quantity[isd:isc, jsd:jsc, :] = quantity[ - iec - nhalo + 1 : iec + 1, jec - nhalo + 1 : jec + 1, : - ] - quantity[isd:isc, jec + 1 : jed + 1, :] = quantity[ - iec - nhalo + 1 : iec + 1, jsc : jsc + nhalo, : - ] - quantity[iec + 1 : ied + 1, jsd:jsc, :] = quantity[ - isc : isc + nhalo, jec - nhalo + 1 : jec + 1, : - ] - quantity[iec + 1 : ied + 1, jec + 1 : jed + 1, :] = quantity[ - isc : isc + nhalo, jsc : jsc + nhalo, : - ] - - -@utils.mark_untested("This namelist option is not tested") -def c2l_ord2( - u: FloatField, - v: FloatField, - dx: FloatFieldIJ, - dy: FloatFieldIJ, - a11: FloatFieldIJ, - a12: FloatFieldIJ, - a21: FloatFieldIJ, - a22: FloatFieldIJ, - ua: FloatField, - va: FloatField, -): - """ - Args: - u (in): - v (in): - dx (in): - dy (in): - a11 (in): - a12 (in): - a21 (in): - a22 (in): - ua (out): - va (out): - """ - from __externals__ import grid_type - - with computation(PARALLEL), interval(...): - if __INLINED(grid_type < 4): - wu = u * dx - wv = v * dy - # Co-variant vorticity-conserving interpolation - u1 = 2.0 * (wu + wu[0, 1, 0]) / (dx + dx[0, 1]) - v1 = 2.0 * (wv + wv[1, 0, 0]) / (dy + dy[1, 0]) - # Cubed (cell center co-variant winds) to lat-lon - ua = a11 * u1 + a12 * v1 - va = a21 * u1 + a22 * v1 - else: - ua = 0.5 * (u + u[0, 1, 0]) - va = 0.5 * (v + v[1, 0, 0]) - - -def ord4_transform( - u: FloatField, - v: FloatField, - dx: FloatFieldIJ, - dy: FloatFieldIJ, - a11: FloatFieldIJ, - a12: FloatFieldIJ, - a21: FloatFieldIJ, - a22: FloatFieldIJ, - ua: FloatField, - va: FloatField, -): - """ - Args: - u (in): - v (in): - dx (in): - dy (in): - a11 (in): - a12 (in): - a21 (in): - a22 (in): - ua (out): - va (out): - """ - with computation(PARALLEL), interval(...): - from __externals__ import grid_type, i_end, i_start, j_end, j_start - - if __INLINED(grid_type < 4): - utmp = C2 * (u[0, -1, 0] + u[0, 2, 0]) + C1 * (u + u[0, 1, 0]) - vtmp = C2 * (v[-1, 0, 0] + v[2, 0, 0]) + C1 * (v + v[1, 0, 0]) - - # south/north edge - with horizontal(region[:, j_start], region[:, j_end]): - vtmp = 2.0 * ((v * dy) + (v[1, 0, 0] * dy[1, 0])) / (dy + dy[1, 0]) - utmp = 2.0 * (u * dx + u[0, 1, 0] * dx[0, 1]) / (dx + dx[0, 1]) - - # west/east edge - with horizontal(region[i_start, :], region[i_end, :]): - utmp = 2.0 * ((u * dx) + (u[0, 1, 0] * dx[0, 1])) / (dx + dx[0, 1]) - vtmp = 2.0 * ((v * dy) + (v[1, 0, 0] * dy[1, 0])) / (dy + dy[1, 0]) - - # Transform local a-grid winds into latitude-longitude coordinates - ua = a11 * utmp + a12 * vtmp - va = a21 * utmp + a22 * vtmp - else: - ua = A2 * (u[0, -1, 0] + u[0, 2, 0]) + A1 * (u + u[0, 1, 0]) - va = A2 * (v[-1, 0, 0] + v[2, 0, 0]) + A1 * (v + v[1, 0, 0]) - - -class CubedToLatLon: - """ - Fortan name is c2l_ord2 - """ - - def __init__( - self, - state: fv3core.DycoreState, - stencil_factory: StencilFactory, - quantity_factory: pace.util.QuantityFactory, - grid_data: GridData, - grid_type: int, - order: int, - comm: pace.util.Communicator, - ): - """ - Initializes stencils to use either 2nd or 4th order of interpolation - based on namelist setting - Args: - stencil_factory: creates stencils - grid_data: object with metric terms - order: Order of interpolation, must be 2 or 4 - """ - grid_indexing = stencil_factory.grid_indexing - isc = grid_indexing.isc - jsc = grid_indexing.jsc - iec = grid_indexing.iec - jec = grid_indexing.jec - isd = grid_indexing.isd - jsd = grid_indexing.jsd - ied = grid_indexing.ied - jed = grid_indexing.jed - self._domain = [[isc, iec], [isd, ied], [jsc, jec], [jsd, jed]] - - self._n_halo = grid_indexing.n_halo - self._dx = grid_data.dx - self._dy = grid_data.dy - if comm.size == 1: - self.one_rank = True - else: - self.one_rank = False - - # TODO: maybe compute locally a* variables - # They depend on z* and sin_sg5, which - # currently aren't in GridData but are used - # in other parts of the model and might be added. - self._a11 = grid_data.a11 - self._a12 = grid_data.a12 - self._a21 = grid_data.a21 - self._a22 = grid_data.a22 - if order == 2: - self._do_ord4 = False - halos = (1, 1) - func = c2l_ord2 - else: - self._do_ord4 = True - halos = (0, 0) - func = ord4_transform - self._compute_cubed_to_latlon = stencil_factory.from_dims_halo( - func=func, - externals={"grid_type": grid_type}, - compute_dims=[X_DIM, Y_DIM, Z_DIM], - compute_halos=halos, - ) - - origin = grid_indexing.origin_compute() - shape = grid_indexing.max_shape - if not self.one_rank: - full_size_xyiz_halo_spec = quantity_factory.get_quantity_halo_spec( - dims=[X_DIM, Y_INTERFACE_DIM, Z_DIM], - n_halo=grid_indexing.n_halo, - dtype=Float, - ) - full_size_xiyz_halo_spec = quantity_factory.get_quantity_halo_spec( - dims=[X_INTERFACE_DIM, Y_DIM, Z_DIM], - n_halo=grid_indexing.n_halo, - dtype=Float, - ) - self.u__v = WrappedHaloUpdater( - comm.get_vector_halo_updater( - [full_size_xyiz_halo_spec], [full_size_xiyz_halo_spec] - ), - state, - ["u"], - ["v"], - comm=comm, - ) - - def __call__( - self, - u: FloatField, - v: FloatField, - ua: FloatField, - va: FloatField, - ): - """ - Interpolate D-grid to A-grid winds at latitude-longitude coordinates. - Args: - u: x-wind on D-grid (in) - v: y-wind on D-grid (in) - ua: x-wind on A-grid (out) - va: y-wind on A-grid (out) - comm: Cubed-sphere or Tile communicator - """ - if self._do_ord4: - if self.one_rank: - mock_exchange(u[:, :-1, :], self._domain) - mock_exchange(v[:-1, :, :], self._domain) - else: - self.u__v.update() - self._compute_cubed_to_latlon( - u, - v, - self._dx, - self._dy, - self._a11, - self._a12, - self._a21, - self._a22, - ua, - va, - ) diff --git a/stencils/pace/stencils/corners.py b/stencils/pace/stencils/corners.py deleted file mode 100644 index a521bf2b9..000000000 --- a/stencils/pace/stencils/corners.py +++ /dev/null @@ -1,1129 +0,0 @@ -from typing import Optional, Sequence, Tuple - -from gt4py.cartesian import gtscript -from gt4py.cartesian.gtscript import PARALLEL, computation, horizontal, interval, region - -from pace.dsl.stencil import GridIndexing, StencilFactory -from pace.dsl.typing import FloatField -from pace.util.constants import ( - X_DIM, - X_INTERFACE_DIM, - Y_DIM, - Y_INTERFACE_DIM, - Z_INTERFACE_DIM, -) - - -class CopyCorners: - """ - Helper-class to copy corners corresponding to the fortran functions - copy_corners_x or copy_corners_y respectively - """ - - def __init__(self, direction: str, stencil_factory: StencilFactory) -> None: - """The grid for this stencil""" - grid_indexing = stencil_factory.grid_indexing - - n_halo = grid_indexing.n_halo - origin, domain = grid_indexing.get_origin_domain( - dims=[X_DIM, Y_DIM, Z_INTERFACE_DIM], halos=(n_halo, n_halo) - ) - - ax_offsets = grid_indexing.axis_offsets(origin, domain) - if direction == "x": - self._copy_corners = stencil_factory.from_origin_domain( - func=copy_corners_x_stencil_defn, - origin=origin, - domain=domain, - externals={ - **ax_offsets, - }, - ) - elif direction == "y": - self._copy_corners = stencil_factory.from_origin_domain( - func=copy_corners_y_stencil_defn, - origin=origin, - domain=domain, - externals={ - **ax_offsets, - }, - ) - else: - raise ValueError("Direction must be either 'x' or 'y'") - - def __call__(self, field: FloatField): - """ - Fills cell quantity field using corners from itself and multipliers - in the dirction specified initialization of the instance of this class. - """ - self._copy_corners(field, field) - - -class CopyCornersXY: - """ - Helper-class to copy corners corresponding to the Fortran functions - copy_corners_x and copy_corners_y - """ - - def __init__( - self, - stencil_factory: StencilFactory, - dims: Sequence[str], - y_field, - ) -> None: - """ - Args: - stencil_factory: creates stencils - dims: dimensionality of the data to be copied - y_field: 3D gt4py storage to use for y-differenceable field - (x-differenceable field uses same memory as base field) - """ - grid_indexing = stencil_factory.grid_indexing - origin, domain = grid_indexing.get_origin_domain( - dims=dims, halos=(grid_indexing.n_halo, grid_indexing.n_halo) - ) - - self._y_field = y_field - - ax_offsets = grid_indexing.axis_offsets(origin, domain) - self._copy_corners_xy = stencil_factory.from_origin_domain( - func=copy_corners_xy_stencil_defn, - origin=origin, - domain=domain, - externals={ - **ax_offsets, - }, - ) - - def __call__(self, field: FloatField): - """ - Fills cell quantity field using corners from itself. - - Args: - field: field to fill corners - - Returns: - x_differenceable: input field, updated so it can be differenced - in x-direction - y_differenceable: copy of input field which can be differenced - in y-direction - """ - # we could avoid aliasing field for the x-differenceable output, but this - # requires selectively validating the halos, since the Fortran code does the - # final (x-direction) corners copy directly on the base field - self._copy_corners_xy(field, field, self._y_field) - return field, self._y_field - - -def kslice_from_inputs( - kstart: int, nk: Optional[int], grid_indexer: GridIndexing -) -> Tuple[slice, int]: - # This expects ints, but it casts in case something was implicitly converted - # to a float before this call. - if nk is None: - nk = grid_indexer.domain[2] - kstart - kslice = slice(int(kstart), int(kstart + nk)) - return (kslice, int(nk)) - - -@gtscript.function -def fill_corners_2cells_mult_x( - q: FloatField, - q_corner: FloatField, - sw_mult: float, - se_mult: float, - nw_mult: float, - ne_mult: float, -): - """ - Fills cell quantity q using corners from q_corner and multipliers in x-dir. - """ - from __externals__ import i_end, i_start, j_end, j_start - - # Southwest - with horizontal(region[i_start - 1, j_start - 1]): - q = sw_mult * q_corner[0, 1, 0] - with horizontal(region[i_start - 2, j_start - 1]): - q = sw_mult * q_corner[1, 2, 0] - - # Southeast - with horizontal(region[i_end + 1, j_start - 1]): - q = se_mult * q_corner[0, 1, 0] - with horizontal(region[i_end + 2, j_start - 1]): - q = se_mult * q_corner[-1, 2, 0] - - # Northwest - with horizontal(region[i_start - 1, j_end + 1]): - q = nw_mult * q_corner[0, -1, 0] - with horizontal(region[i_start - 2, j_end + 1]): - q = nw_mult * q_corner[1, -2, 0] - - # Northeast - with horizontal(region[i_end + 1, j_end + 1]): - q = ne_mult * q_corner[0, -1, 0] - with horizontal(region[i_end + 2, j_end + 1]): - q = ne_mult * q_corner[-1, -2, 0] - - return q - - -def fill_corners_2cells_x_stencil(q_out: FloatField, q_in: FloatField): - with computation(PARALLEL), interval(...): - q_out = fill_corners_2cells_mult_x(q_out, q_in, 1.0, 1.0, 1.0, 1.0) - - -def fill_corners_2cells_y_stencil(q_out: FloatField, q_in: FloatField): - with computation(PARALLEL), interval(...): - q_out = fill_corners_2cells_mult_y(q_out, q_in, 1.0, 1.0, 1.0, 1.0) - - -@gtscript.function -def fill_corners_2cells_x(q: FloatField): - """ - Fills cell quantity q in x-dir. - """ - return fill_corners_2cells_mult_x(q, q, 1.0, 1.0, 1.0, 1.0) - - -@gtscript.function -def fill_corners_3cells_mult_x( - q: FloatField, - q_corner: FloatField, - sw_mult: float, - se_mult: float, - nw_mult: float, - ne_mult: float, -): - """ - Fills cell quantity q using corners from q_corner and multipliers in x-dir. - """ - from __externals__ import i_end, i_start, j_end, j_start - - q = fill_corners_2cells_mult_x(q, q_corner, sw_mult, se_mult, nw_mult, ne_mult) - - # Southwest - with horizontal(region[i_start - 3, j_start - 1]): - q = sw_mult * q_corner[2, 3, 0] - - # Southeast - with horizontal(region[i_end + 3, j_start - 1]): - q = se_mult * q_corner[-2, 3, 0] - - # Northwest - with horizontal(region[i_start - 3, j_end + 1]): - q = nw_mult * q_corner[2, -3, 0] - - # Northeast - with horizontal(region[i_end + 3, j_end + 1]): - q = ne_mult * q_corner[-2, -3, 0] - - return q - - -@gtscript.function -def fill_corners_2cells_mult_y( - q: FloatField, - q_corner: FloatField, - sw_mult: float, - se_mult: float, - nw_mult: float, - ne_mult: float, -): - """ - Fills cell quantity q using corners from q_corner and multipliers in y-dir. - """ - from __externals__ import i_end, i_start, j_end, j_start - - # Southwest - with horizontal(region[i_start - 1, j_start - 1]): - q = sw_mult * q_corner[1, 0, 0] - with horizontal(region[i_start - 1, j_start - 2]): - q = sw_mult * q_corner[2, 1, 0] - - # Southeast - with horizontal(region[i_end + 1, j_start - 1]): - q = se_mult * q_corner[-1, 0, 0] - with horizontal(region[i_end + 1, j_start - 2]): - q = se_mult * q_corner[-2, 1, 0] - - # Northwest - with horizontal(region[i_start - 1, j_end + 1]): - q = nw_mult * q_corner[1, 0, 0] - with horizontal(region[i_start - 1, j_end + 2]): - q = nw_mult * q_corner[2, -1, 0] - - # Northeast - with horizontal(region[i_end + 1, j_end + 1]): - q = ne_mult * q_corner[-1, 0, 0] - with horizontal(region[i_end + 1, j_end + 2]): - q = ne_mult * q_corner[-2, -1, 0] - - return q - - -@gtscript.function -def fill_corners_2cells_y(q: FloatField): - """ - Fills cell quantity q in y-dir. - """ - return fill_corners_2cells_mult_y(q, q, 1.0, 1.0, 1.0, 1.0) - - -@gtscript.function -def fill_corners_3cells_mult_y( - q: FloatField, - q_corner: FloatField, - sw_mult: float, - se_mult: float, - nw_mult: float, - ne_mult: float, -): - """ - Fills cell quantity q using corners from q_corner and multipliers in y-dir. - """ - from __externals__ import i_end, i_start, j_end, j_start - - q = fill_corners_2cells_mult_y(q, q_corner, sw_mult, se_mult, nw_mult, ne_mult) - - # Southwest - with horizontal(region[i_start - 1, j_start - 3]): - q = sw_mult * q_corner[3, 2, 0] - - # Southeast - with horizontal(region[i_end + 1, j_start - 3]): - q = se_mult * q_corner[-3, 2, 0] - - # Northwest - with horizontal(region[i_start - 1, j_end + 3]): - q = nw_mult * q_corner[3, -2, 0] - - # Northeast - with horizontal(region[i_end + 1, j_end + 3]): - q = ne_mult * q_corner[-3, -2, 0] - - return q - - -def copy_corners_x_stencil_defn(q_in: FloatField, q_out: FloatField): - from __externals__ import i_end, i_start, j_end, j_start - - with computation(PARALLEL), interval(...): - with horizontal( - region[i_start - 3, j_start - 3], region[i_end + 3, j_start - 3] - ): - q_out = q_in[0, 5, 0] - with horizontal( - region[i_start - 2, j_start - 3], region[i_end + 3, j_start - 2] - ): - q_out = q_in[-1, 4, 0] - with horizontal( - region[i_start - 1, j_start - 3], region[i_end + 3, j_start - 1] - ): - q_out = q_in[-2, 3, 0] - with horizontal( - region[i_start - 3, j_start - 2], region[i_end + 2, j_start - 3] - ): - q_out = q_in[1, 4, 0] - with horizontal( - region[i_start - 2, j_start - 2], region[i_end + 2, j_start - 2] - ): - q_out = q_in[0, 3, 0] - with horizontal( - region[i_start - 1, j_start - 2], region[i_end + 2, j_start - 1] - ): - q_out = q_in[-1, 2, 0] - with horizontal( - region[i_start - 3, j_start - 1], region[i_end + 1, j_start - 3] - ): - q_out = q_in[2, 3, 0] - with horizontal( - region[i_start - 2, j_start - 1], region[i_end + 1, j_start - 2] - ): - q_out = q_in[1, 2, 0] - with horizontal( - region[i_start - 1, j_start - 1], region[i_end + 1, j_start - 1] - ): - q_out = q_in[0, 1, 0] - with horizontal(region[i_start - 3, j_end + 1], region[i_end + 1, j_end + 3]): - q_out = q_in[2, -3, 0] - with horizontal(region[i_start - 2, j_end + 1], region[i_end + 1, j_end + 2]): - q_out = q_in[1, -2, 0] - with horizontal(region[i_start - 1, j_end + 1], region[i_end + 1, j_end + 1]): - q_out = q_in[0, -1, 0] - with horizontal(region[i_start - 3, j_end + 2], region[i_end + 2, j_end + 3]): - q_out = q_in[1, -4, 0] - with horizontal(region[i_start - 2, j_end + 2], region[i_end + 2, j_end + 2]): - q_out = q_in[0, -3, 0] - with horizontal(region[i_start - 1, j_end + 2], region[i_end + 2, j_end + 1]): - q_out = q_in[-1, -2, 0] - with horizontal(region[i_start - 3, j_end + 3], region[i_end + 3, j_end + 3]): - q_out = q_in[0, -5, 0] - with horizontal(region[i_start - 2, j_end + 3], region[i_end + 3, j_end + 2]): - q_out = q_in[-1, -4, 0] - with horizontal(region[i_start - 1, j_end + 3], region[i_end + 3, j_end + 1]): - q_out = q_in[-2, -3, 0] - - -def copy_corners_y_stencil_defn(q_in: FloatField, q_out: FloatField): - from __externals__ import i_end, i_start, j_end, j_start - - with computation(PARALLEL), interval(...): - with horizontal( - region[i_start - 3, j_start - 3], region[i_start - 3, j_end + 3] - ): - q_out = q_in[5, 0, 0] - with horizontal( - region[i_start - 2, j_start - 3], region[i_start - 3, j_end + 2] - ): - q_out = q_in[4, 1, 0] - with horizontal( - region[i_start - 1, j_start - 3], region[i_start - 3, j_end + 1] - ): - q_out = q_in[3, 2, 0] - with horizontal( - region[i_start - 3, j_start - 2], region[i_start - 2, j_end + 3] - ): - q_out = q_in[4, -1, 0] - with horizontal( - region[i_start - 2, j_start - 2], region[i_start - 2, j_end + 2] - ): - q_out = q_in[3, 0, 0] - with horizontal( - region[i_start - 1, j_start - 2], region[i_start - 2, j_end + 1] - ): - q_out = q_in[2, 1, 0] - with horizontal( - region[i_start - 3, j_start - 1], region[i_start - 1, j_end + 3] - ): - q_out = q_in[3, -2, 0] - with horizontal( - region[i_start - 2, j_start - 1], region[i_start - 1, j_end + 2] - ): - q_out = q_in[2, -1, 0] - with horizontal( - region[i_start - 1, j_start - 1], region[i_start - 1, j_end + 1] - ): - q_out = q_in[1, 0, 0] - with horizontal(region[i_end + 1, j_start - 3], region[i_end + 3, j_end + 1]): - q_out = q_in[-3, 2, 0] - with horizontal(region[i_end + 2, j_start - 3], region[i_end + 3, j_end + 2]): - q_out = q_in[-4, 1, 0] - with horizontal(region[i_end + 3, j_start - 3], region[i_end + 3, j_end + 3]): - q_out = q_in[-5, 0, 0] - with horizontal(region[i_end + 1, j_start - 2], region[i_end + 2, j_end + 1]): - q_out = q_in[-2, 1, 0] - with horizontal(region[i_end + 2, j_start - 2], region[i_end + 2, j_end + 2]): - q_out = q_in[-3, 0, 0] - with horizontal(region[i_end + 3, j_start - 2], region[i_end + 2, j_end + 3]): - q_out = q_in[-4, -1, 0] - with horizontal(region[i_end + 1, j_start - 1], region[i_end + 1, j_end + 1]): - q_out = q_in[-1, 0, 0] - with horizontal(region[i_end + 2, j_start - 1], region[i_end + 1, j_end + 2]): - q_out = q_in[-2, -1, 0] - with horizontal(region[i_end + 3, j_start - 1], region[i_end + 1, j_end + 3]): - q_out = q_in[-3, -2, 0] - - -def copy_corners_xy_stencil_defn( - q_in: FloatField, q_out_x: FloatField, q_out_y: FloatField -): - from __externals__ import i_end, i_start, j_end, j_start - - with computation(PARALLEL), interval(...): - q_out_x = q_in - q_out_y = q_in - with horizontal( - region[i_start - 3, j_start - 3], region[i_end + 3, j_start - 3] - ): - q_out_x = q_in[0, 5, 0] - with horizontal( - region[i_start - 2, j_start - 3], region[i_end + 3, j_start - 2] - ): - q_out_x = q_in[-1, 4, 0] - with horizontal( - region[i_start - 1, j_start - 3], region[i_end + 3, j_start - 1] - ): - q_out_x = q_in[-2, 3, 0] - with horizontal( - region[i_start - 3, j_start - 2], region[i_end + 2, j_start - 3] - ): - q_out_x = q_in[1, 4, 0] - with horizontal( - region[i_start - 2, j_start - 2], region[i_end + 2, j_start - 2] - ): - q_out_x = q_in[0, 3, 0] - with horizontal( - region[i_start - 1, j_start - 2], region[i_end + 2, j_start - 1] - ): - q_out_x = q_in[-1, 2, 0] - with horizontal( - region[i_start - 3, j_start - 1], region[i_end + 1, j_start - 3] - ): - q_out_x = q_in[2, 3, 0] - with horizontal( - region[i_start - 2, j_start - 1], region[i_end + 1, j_start - 2] - ): - q_out_x = q_in[1, 2, 0] - with horizontal( - region[i_start - 1, j_start - 1], region[i_end + 1, j_start - 1] - ): - q_out_x = q_in[0, 1, 0] - with horizontal(region[i_start - 3, j_end + 1], region[i_end + 1, j_end + 3]): - q_out_x = q_in[2, -3, 0] - with horizontal(region[i_start - 2, j_end + 1], region[i_end + 1, j_end + 2]): - q_out_x = q_in[1, -2, 0] - with horizontal(region[i_start - 1, j_end + 1], region[i_end + 1, j_end + 1]): - q_out_x = q_in[0, -1, 0] - with horizontal(region[i_start - 3, j_end + 2], region[i_end + 2, j_end + 3]): - q_out_x = q_in[1, -4, 0] - with horizontal(region[i_start - 2, j_end + 2], region[i_end + 2, j_end + 2]): - q_out_x = q_in[0, -3, 0] - with horizontal(region[i_start - 1, j_end + 2], region[i_end + 2, j_end + 1]): - q_out_x = q_in[-1, -2, 0] - with horizontal(region[i_start - 3, j_end + 3], region[i_end + 3, j_end + 3]): - q_out_x = q_in[0, -5, 0] - with horizontal(region[i_start - 2, j_end + 3], region[i_end + 3, j_end + 2]): - q_out_x = q_in[-1, -4, 0] - with horizontal(region[i_start - 1, j_end + 3], region[i_end + 3, j_end + 1]): - q_out_x = q_in[-2, -3, 0] - with horizontal( - region[i_start - 3, j_start - 3], region[i_start - 3, j_end + 3] - ): - q_out_y = q_in[5, 0, 0] - with horizontal( - region[i_start - 2, j_start - 3], region[i_start - 3, j_end + 2] - ): - q_out_y = q_in[4, 1, 0] - with horizontal( - region[i_start - 1, j_start - 3], region[i_start - 3, j_end + 1] - ): - q_out_y = q_in[3, 2, 0] - with horizontal( - region[i_start - 3, j_start - 2], region[i_start - 2, j_end + 3] - ): - q_out_y = q_in[4, -1, 0] - with horizontal( - region[i_start - 2, j_start - 2], region[i_start - 2, j_end + 2] - ): - q_out_y = q_in[3, 0, 0] - with horizontal( - region[i_start - 1, j_start - 2], region[i_start - 2, j_end + 1] - ): - q_out_y = q_in[2, 1, 0] - with horizontal( - region[i_start - 3, j_start - 1], region[i_start - 1, j_end + 3] - ): - q_out_y = q_in[3, -2, 0] - with horizontal( - region[i_start - 2, j_start - 1], region[i_start - 1, j_end + 2] - ): - q_out_y = q_in[2, -1, 0] - with horizontal( - region[i_start - 1, j_start - 1], region[i_start - 1, j_end + 1] - ): - q_out_y = q_in[1, 0, 0] - with horizontal(region[i_end + 1, j_start - 3], region[i_end + 3, j_end + 1]): - q_out_y = q_in[-3, 2, 0] - with horizontal(region[i_end + 2, j_start - 3], region[i_end + 3, j_end + 2]): - q_out_y = q_in[-4, 1, 0] - with horizontal(region[i_end + 3, j_start - 3], region[i_end + 3, j_end + 3]): - q_out_y = q_in[-5, 0, 0] - with horizontal(region[i_end + 1, j_start - 2], region[i_end + 2, j_end + 1]): - q_out_y = q_in[-2, 1, 0] - with horizontal(region[i_end + 2, j_start - 2], region[i_end + 2, j_end + 2]): - q_out_y = q_in[-3, 0, 0] - with horizontal(region[i_end + 3, j_start - 2], region[i_end + 2, j_end + 3]): - q_out_y = q_in[-4, -1, 0] - with horizontal(region[i_end + 1, j_start - 1], region[i_end + 1, j_end + 1]): - q_out_y = q_in[-1, 0, 0] - with horizontal(region[i_end + 2, j_start - 1], region[i_end + 1, j_end + 2]): - q_out_y = q_in[-2, -1, 0] - with horizontal(region[i_end + 3, j_start - 1], region[i_end + 1, j_end + 3]): - q_out_y = q_in[-3, -2, 0] - - -class FillCornersBGrid: - """ - Helper-class to fill corners corresponding to the fortran function - fill_corners with BGRID=.true. and either FILL=YDir or FILL=YDIR - """ - - def __init__( - self, - direction: str, - stencil_factory: StencilFactory, - origin=None, - domain=None, - ) -> None: - - n_halo = stencil_factory.grid_indexing.n_halo - ( - default_origin, - default_domain, - ) = stencil_factory.grid_indexing.get_origin_domain( - dims=[X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_INTERFACE_DIM], - halos=(n_halo, n_halo), - ) - - if origin is None: - origin = default_origin - """The origin for the corner computation""" - if domain is None: - domain = default_domain - """The full domain required to do corner computation everywhere""" - - if direction == "x": - defn = fill_corners_bgrid_x_defn - elif direction == "y": - defn = fill_corners_bgrid_y_defn - else: - raise ValueError("Direction must be either 'x' or 'y'") - externals = stencil_factory.grid_indexing.axis_offsets( - origin=origin, domain=domain - ) - self._fill_corners_bgrid = stencil_factory.from_origin_domain( - func=defn, origin=origin, domain=domain, externals=externals - ) - - def __call__(self, field: FloatField): - self._fill_corners_bgrid(field, field) - - -def fill_corners_bgrid_x_defn(q_in: FloatField, q_out: FloatField): - from __externals__ import i_end, i_start, j_end, j_start - - with computation(PARALLEL), interval(...): - # sw and se corner - with horizontal( - region[i_start - 1, j_start - 1], region[i_end + 2, j_start - 1] - ): - q_out = q_in[0, 2, 0] - with horizontal( - region[i_start - 1, j_start - 2], region[i_end + 3, j_start - 1] - ): - q_out = q_in[-1, 3, 0] - with horizontal( - region[i_start - 1, j_start - 3], region[i_end + 4, j_start - 1] - ): - q_out = q_in[-2, 4, 0] - with horizontal( - region[i_start - 2, j_start - 1], region[i_end + 2, j_start - 2] - ): - q_out = q_in[1, 3, 0] - with horizontal( - region[i_start - 2, j_start - 2], region[i_end + 3, j_start - 2] - ): - q_out = q_in[0, 4, 0] - with horizontal( - region[i_start - 2, j_start - 3], region[i_end + 4, j_start - 2] - ): - q_out = q_in[-1, 5, 0] - with horizontal( - region[i_start - 3, j_start - 1], region[i_end + 2, j_start - 3] - ): - q_out = q_in[2, 4, 0] - with horizontal( - region[i_start - 3, j_start - 2], region[i_end + 3, j_start - 3] - ): - q_out = q_in[1, 5, 0] - with horizontal( - region[i_start - 3, j_start - 3], region[i_end + 4, j_start - 3] - ): - q_out = q_in[0, 6, 0] - # nw and ne corner - with horizontal(region[i_start - 1, j_end + 2], region[i_end + 2, j_end + 2]): - q_out = q_in[0, -2, 0] - with horizontal(region[i_start - 1, j_end + 3], region[i_end + 3, j_end + 2]): - q_out = q_in[-1, -3, 0] - with horizontal(region[i_start - 1, j_end + 4], region[i_end + 4, j_end + 2]): - q_out = q_in[-2, -4, 0] - with horizontal(region[i_start - 2, j_end + 2], region[i_end + 2, j_end + 3]): - q_out = q_in[1, -3, 0] - with horizontal(region[i_start - 2, j_end + 3], region[i_end + 3, j_end + 3]): - q_out = q_in[0, -4, 0] - with horizontal(region[i_start - 2, j_end + 4], region[i_end + 4, j_end + 3]): - q_out = q_in[-1, -5, 0] - with horizontal(region[i_start - 3, j_end + 2], region[i_end + 2, j_end + 4]): - q_out = q_in[2, -4, 0] - with horizontal(region[i_start - 3, j_end + 3], region[i_end + 3, j_end + 4]): - q_out = q_in[1, -5, 0] - with horizontal(region[i_start - 3, j_end + 4], region[i_end + 4, j_end + 4]): - q_out = q_in[0, -6, 0] - - -def fill_corners_bgrid_y_defn(q_in: FloatField, q_out: FloatField): - from __externals__ import i_end, i_start, j_end, j_start - - with computation(PARALLEL), interval(...): - # sw and nw corners - with horizontal( - region[i_start - 1, j_start - 1], region[i_start - 1, j_end + 2] - ): - q_out = q_in[2, 0, 0] - with horizontal( - region[i_start - 1, j_start - 2], region[i_start - 2, j_end + 2] - ): - q_out = q_in[3, 1, 0] - with horizontal( - region[i_start - 1, j_start - 3], region[i_start - 3, j_end + 2] - ): - q_out = q_in[4, 2, 0] - with horizontal( - region[i_start - 2, j_start - 1], region[i_start - 1, j_end + 3] - ): - q_out = q_in[3, -1, 0] - with horizontal( - region[i_start - 2, j_start - 2], region[i_start - 2, j_end + 3] - ): - q_out = q_in[4, 0, 0] - with horizontal( - region[i_start - 2, j_start - 3], region[i_start - 3, j_end + 3] - ): - q_out = q_in[5, 1, 0] - with horizontal( - region[i_start - 3, j_start - 1], region[i_start - 1, j_end + 4] - ): - q_out = q_in[4, -2, 0] - with horizontal( - region[i_start - 3, j_start - 2], region[i_start - 2, j_end + 4] - ): - q_out = q_in[5, -1, 0] - with horizontal( - region[i_start - 3, j_start - 3], region[i_start - 3, j_end + 4] - ): - q_out = q_in[6, 0, 0] - # se and ne corners - with horizontal(region[i_end + 2, j_start - 1], region[i_end + 2, j_end + 2]): - q_out = q_in[-2, 0, 0] - with horizontal(region[i_end + 2, j_start - 2], region[i_end + 3, j_end + 2]): - q_out = q_in[-3, 1, 0] - with horizontal(region[i_end + 2, j_start - 3], region[i_end + 4, j_end + 2]): - q_out = q_in[-4, 2, 0] - with horizontal(region[i_end + 3, j_start - 1], region[i_end + 2, j_end + 3]): - q_out = q_in[-3, -1, 0] - with horizontal(region[i_end + 3, j_start - 2], region[i_end + 3, j_end + 3]): - q_out = q_in[-4, 0, 0] - with horizontal(region[i_end + 3, j_start - 3], region[i_end + 4, j_end + 3]): - q_out = q_in[-5, 1, 0] - with horizontal(region[i_end + 4, j_start - 1], region[i_end + 2, j_end + 4]): - q_out = q_in[-4, -2, 0] - with horizontal(region[i_end + 4, j_start - 2], region[i_end + 3, j_end + 4]): - q_out = q_in[-5, -1, 0] - with horizontal(region[i_end + 4, j_start - 3], region[i_end + 4, j_end + 4]): - q_out = q_in[-6, 0, 0] - - -# TODO these fill corner 2d, agrid, bgrid routines need to be tested and integrated; -# they've just been copied from an older version of the code - -# TODO these can definitely be consolidated/made simpler -def fill_sw_corner_2d_bgrid(q, i, j, direction, grid_indexer): - if direction == "x": - q[grid_indexer.isc - i, grid_indexer.jsc - j, :] = q[ - grid_indexer.isc - j, grid_indexer.jsc + i, : - ] - if direction == "y": - q[grid_indexer.isc - j, grid_indexer.jsc - i, :] = q[ - grid_indexer.isc + i, grid_indexer.jsc - j, : - ] - - -def fill_nw_corner_2d_bgrid(q, i, j, direction, grid_indexer): - if direction == "x": - q[grid_indexer.isc - i, grid_indexer.jec + 1 + j, :] = q[ - grid_indexer.isc - j, grid_indexer.jec + 1 - i, : - ] - if direction == "y": - q[grid_indexer.isc - j, grid_indexer.jec + 1 + i, :] = q[ - grid_indexer.isc + i, grid_indexer.jec + 1 + j, : - ] - - -def fill_se_corner_2d_bgrid(q, i, j, direction, grid_indexer): - if direction == "x": - q[grid_indexer.iec + 1 + i, grid_indexer.jsc - j, :] = q[ - grid_indexer.iec + 1 + j, grid_indexer.jsc + i, : - ] - if direction == "y": - q[grid_indexer.iec + 1 + j, grid_indexer.jsc - i, :] = q[ - grid_indexer.iec + 1 - i, grid_indexer.jsc - j, : - ] - - -def fill_ne_corner_2d_bgrid(q, i, j, direction, grid_indexer): - if direction == "x": - q[grid_indexer.iec + 1 + i, grid_indexer.jec + 1 + j :] = q[ - grid_indexer.iec + 1 + j, grid_indexer.jec + 1 - i, : - ] - if direction == "y": - q[grid_indexer.iec + 1 + i, grid_indexer.jec + 1 + j :] = q[ - grid_indexer.iec + 1 - i, grid_indexer.jec + 1 + j, : - ] - - -def fill_sw_corner_2d_agrid(q, i, j, direction, grid_indexer, kstart=0, nk=None): - kslice, nk = kslice_from_inputs(kstart, nk, grid_indexer) - if direction == "x": - q[grid_indexer.isc - i, grid_indexer.jsc - j, kslice] = q[ - grid_indexer.isc - j, grid_indexer.jsc + i - 1, kslice - ] - if direction == "y": - q[grid_indexer.isc - j, grid_indexer.jsc - i, kslice] = q[ - grid_indexer.isc + i - 1, grid_indexer.jsc - j, kslice - ] - - -def fill_nw_corner_2d_agrid(q, i, j, direction, grid_indexer, kstart=0, nk=None): - kslice, nk = kslice_from_inputs(kstart, nk, grid_indexer) - if direction == "x": - q[grid_indexer.isc - i, grid_indexer.jec + j, kslice] = q[ - grid_indexer.isc - j, grid_indexer.jec - i + 1, kslice - ] - if direction == "y": - q[grid_indexer.isc - j, grid_indexer.jec + i, kslice] = q[ - grid_indexer.isc + i - 1, grid_indexer.jec + j, kslice - ] - - -def fill_se_corner_2d_agrid(q, i, j, direction, grid_indexer, kstart=0, nk=None): - kslice, nk = kslice_from_inputs(kstart, nk, grid_indexer) - if direction == "x": - q[grid_indexer.iec + i, grid_indexer.jsc - j, kslice] = q[ - grid_indexer.iec + j, grid_indexer.isc + i - 1, kslice - ] - if direction == "y": - q[grid_indexer.iec + j, grid_indexer.jsc - i, kslice] = q[ - grid_indexer.iec - i + 1, grid_indexer.jsc - j, kslice - ] - - -def fill_ne_corner_2d_agrid( - q, i, j, direction, grid_indexer, mysign=1.0, kstart=0, nk=None -): - kslice, nk = kslice_from_inputs(kstart, nk, grid_indexer) - if direction == "x": - q[grid_indexer.iec + i, grid_indexer.jec + j, kslice] = q[ - grid_indexer.iec + j, grid_indexer.jec - i + 1, kslice - ] - if direction == "y": - q[grid_indexer.iec + j, grid_indexer.jec + i, kslice] = q[ - grid_indexer.iec - i + 1, grid_indexer.jec + j, kslice - ] - - -def fill_corners_2d(q, grid_indexer, gridtype, direction="x"): - if gridtype == "B": - fill_corners_2d_bgrid(q, grid_indexer, gridtype, direction) - elif gridtype == "A": - fill_corners_2d_agrid(q, grid_indexer, gridtype, direction) - else: - raise NotImplementedError() - - -def fill_corners_2d_bgrid(q, grid_indexer, gridtype, direction="x"): - for i in range(1, 1 + grid_indexer.n_halo): - for j in range(1, 1 + grid_indexer.n_halo): - if grid_indexer.sw_corner: - fill_sw_corner_2d_bgrid(q, i, j, direction, grid_indexer) - if grid_indexer.nw_corner: - fill_nw_corner_2d_bgrid(q, i, j, direction, grid_indexer) - if grid_indexer.se_corner: - fill_se_corner_2d_bgrid(q, i, j, direction, grid_indexer) - if grid_indexer.ne_corner: - fill_ne_corner_2d_bgrid(q, i, j, direction, grid_indexer) - - -def fill_corners_2d_agrid(q, grid_indexer, gridtype, direction="x"): - for i in range(1, 1 + grid_indexer.n_halo): - for j in range(1, 1 + grid_indexer.n_halo): - if grid_indexer.sw_corner: - fill_sw_corner_2d_agrid(q, i, j, direction, grid_indexer) - if grid_indexer.nw_corner: - fill_nw_corner_2d_agrid(q, i, j, direction, grid_indexer) - if grid_indexer.se_corner: - fill_se_corner_2d_agrid(q, i, j, direction, grid_indexer) - if grid_indexer.ne_corner: - fill_ne_corner_2d_agrid(q, i, j, direction, grid_indexer) - - -def fill_corners_agrid(x, y, grid_indexer, vector): - if vector: - mysign = -1.0 - else: - mysign = 1.0 - # i_end = grid_indexer.n_halo + grid_indexer.npx - 2 - # ^index of last value in compute domain - # j_end = grid_indexer.n_halo + grid_indexer.npy - 2 - i_end = grid_indexer.iec - j_end = grid_indexer.jec - for i in range(1, 1 + grid_indexer.n_halo): - for j in range(1, 1 + grid_indexer.n_halo): - if grid_indexer.sw_corner: - x[grid_indexer.n_halo - i, grid_indexer.n_halo - j, :] = ( - mysign * y[grid_indexer.n_halo - j, grid_indexer.n_halo - 1 + i, :] - ) - y[grid_indexer.n_halo - j, grid_indexer.n_halo - i, :] = ( - mysign * x[grid_indexer.n_halo - 1 + i, grid_indexer.n_halo - j, :] - ) - if grid_indexer.nw_corner: - x[grid_indexer.n_halo - i, j_end + j, :] = y[ - grid_indexer.n_halo - j, j_end - i + 1, : - ] - y[grid_indexer.n_halo - j, j_end + i, :] = x[ - grid_indexer.n_halo - 1 + i, j_end + j, : - ] - if grid_indexer.se_corner: - x[i_end + i, grid_indexer.n_halo - j, :] = y[ - i_end + j, grid_indexer.n_halo - 1 + i, : - ] - y[i_end + j, grid_indexer.n_halo - i, :] = x[ - i_end - i + 1, grid_indexer.n_halo - j, : - ] - if grid_indexer.ne_corner: - x[i_end + i, j_end + j, :] = mysign * y[i_end + j, j_end - i + 1, :] - y[i_end + j, j_end + i, :] = mysign * x[i_end - i + 1, j_end + j, :] - - -def fill_sw_corner_vector_dgrid(x, y, i, j, grid_indexer, mysign): - x[grid_indexer.isc - i, grid_indexer.jsc - j, :] = ( - mysign * y[grid_indexer.isc - j, i + 2, :] - ) - y[grid_indexer.isc - i, grid_indexer.jsc - j, :] = ( - mysign * x[j + 2, grid_indexer.jsc - i, :] - ) - - -def fill_nw_corner_vector_dgrid(x, y, i, j, grid_indexer): - x[grid_indexer.isc - i, grid_indexer.jec + 1 + j, :] = y[ - grid_indexer.isc - j, grid_indexer.jec + 1 - i, : - ] - y[grid_indexer.isc - i, grid_indexer.jec + j, :] = x[ - j + 2, grid_indexer.jec + 1 + i, : - ] - - -def fill_se_corner_vector_dgrid(x, y, i, j, grid_indexer): - x[grid_indexer.iec + i, grid_indexer.jsc - j, :] = y[ - grid_indexer.iec + 1 + j, i + 2, : - ] - y[grid_indexer.iec + 1 + i, grid_indexer.jsc - j, :] = x[ - grid_indexer.iec - j + 1, grid_indexer.jsc - i, : - ] - - -def fill_ne_corner_vector_dgrid(x, y, i, j, grid_indexer, mysign): - x[grid_indexer.iec + i, grid_indexer.jec + 1 + j, :] = ( - mysign * y[grid_indexer.iec + 1 + j, grid_indexer.jec - i + 1, :] - ) - y[grid_indexer.iec + 1 + i, grid_indexer.jec + j, :] = ( - mysign * x[grid_indexer.iec - j + 1, grid_indexer.jec + 1 + i, :] - ) - - -def fill_corners_dgrid(x, y, grid_indexer, vector): - mysign = 1.0 - if vector: - mysign = -1.0 - for i in range(1, 1 + grid_indexer.n_halo): - for j in range(1, 1 + grid_indexer.n_halo): - if grid_indexer.sw_corner: - fill_sw_corner_vector_dgrid(x, y, i, j, grid_indexer, mysign) - if grid_indexer.nw_corner: - fill_nw_corner_vector_dgrid(x, y, i, j, grid_indexer) - if grid_indexer.se_corner: - fill_se_corner_vector_dgrid(x, y, i, j, grid_indexer) - if grid_indexer.ne_corner: - fill_ne_corner_vector_dgrid(x, y, i, j, grid_indexer, mysign) - - -def fill_sw_corner_vector_cgrid(x, y, i, j, grid_indexer): - x[grid_indexer.isc - i, grid_indexer.jsc - j, :] = y[j + 2, grid_indexer.jsc - i, :] - y[grid_indexer.isc - i, grid_indexer.jsc - j, :] = x[grid_indexer.isc - j, i + 2, :] - - -def fill_nw_corner_vector_cgrid(x, y, i, j, grid_indexer, mysign): - x[grid_indexer.isc - i, grid_indexer.jec + j, :] = ( - mysign * y[j + 2, grid_indexer.jec + 1 + i, :] - ) - y[grid_indexer.isc - i, grid_indexer.jec + 1 + j, :] = ( - mysign * x[grid_indexer.isc - j, grid_indexer.jec + 1 - i, :] - ) - - -def fill_se_corner_vector_cgrid(x, y, i, j, grid_indexer, mysign): - x[grid_indexer.iec + 1 + i, grid_indexer.jsc - j, :] = ( - mysign * y[grid_indexer.iec + 1 - j, grid_indexer.jsc - i, :] - ) - y[grid_indexer.iec + i, grid_indexer.jsc - j, :] = ( - mysign * x[grid_indexer.iec + 1 + j, i + 2, :] - ) - - -def fill_ne_corner_vector_cgrid(x, y, i, j, grid_indexer): - x[grid_indexer.iec + 1 + i, grid_indexer.jec + j, :] = y[ - grid_indexer.iec + 1 - j, grid_indexer.jec + 1 + i, : - ] - y[grid_indexer.iec + i, grid_indexer.jec + 1 + j, :] = x[ - grid_indexer.iec + 1 + j, grid_indexer.jec + 1 - i, : - ] - - -def fill_corners_cgrid(x, y, grid_indexer, vector): - mysign = 1.0 - if vector: - mysign = -1.0 - for i in range(1, 1 + grid_indexer.n_halo): - for j in range(1, 1 + grid_indexer.n_halo): - if grid_indexer.sw_corner: - fill_sw_corner_vector_cgrid(x, y, i, j, grid_indexer) - if grid_indexer.nw_corner: - fill_nw_corner_vector_cgrid(x, y, i, j, grid_indexer, mysign) - if grid_indexer.se_corner: - fill_se_corner_vector_cgrid(x, y, i, j, grid_indexer, mysign) - if grid_indexer.ne_corner: - fill_ne_corner_vector_cgrid(x, y, i, j, grid_indexer) - - -def fill_corners_dgrid_defn( - x_in: FloatField, - x_out: FloatField, - y_in: FloatField, - y_out: FloatField, - mysign: float, -): - """ - Args: - x_in (in): - x_out (inout): - y_in (in): - y_out (inout): - """ - from __externals__ import i_end, i_start, j_end, j_start - - with computation(PARALLEL), interval(...): - # sw corner - with horizontal(region[i_start - 1, j_start - 1]): - x_out = mysign * y_in[0, 1, 0] - y_out = mysign * x_in[1, 0, 0] - with horizontal(region[i_start - 1, j_start - 2]): - x_out = mysign * y_in[-1, 2, 0] - y_out = mysign * x_in[2, 1, 0] - with horizontal(region[i_start - 1, j_start - 3]): - x_out = mysign * y_in[-2, 3, 0] - y_out = mysign * x_in[3, 2, 0] - with horizontal(region[i_start - 2, j_start - 1]): - x_out = mysign * y_in[1, 2, 0] - y_out = mysign * x_in[2, -1, 0] - with horizontal(region[i_start - 2, j_start - 2]): - x_out = mysign * y_in[0, 3, 0] - y_out = mysign * x_in[3, 0, 0] - with horizontal(region[i_start - 2, j_start - 3]): - x_out = mysign * y_in[-1, 4, 0] - y_out = mysign * x_in[4, 1, 0] - with horizontal(region[i_start - 3, j_start - 1]): - x_out = mysign * y_in[2, 3, 0] - y_out = mysign * x_in[3, -2, 0] - with horizontal(region[i_start - 3, j_start - 2]): - x_out = mysign * y_in[1, 4, 0] - y_out = mysign * x_in[4, -1, 0] - with horizontal(region[i_start - 3, j_start - 3]): - x_out = mysign * y_in[0, 5, 0] - y_out = mysign * x_in[5, 0, 0] - - # ne corner - with horizontal(region[i_end + 1, j_end + 2]): - x_out = mysign * y_in[1, -2, 0] - with horizontal(region[i_end + 2, j_end + 1]): - y_out = mysign * x_in[-2, 1, 0] - with horizontal(region[i_end + 1, j_end + 3]): - x_out = mysign * y_in[2, -3, 0] - with horizontal(region[i_end + 2, j_end + 2]): - y_out = mysign * x_in[-3, 0, 0] - x_out = mysign * y_in[0, -3, 0] - with horizontal(region[i_end + 1, j_end + 4]): - x_out = mysign * y_in[3, -4, 0] - with horizontal(region[i_end + 2, j_end + 3]): - y_out = mysign * x_in[-4, -1, 0] - x_out = mysign * y_in[1, -4, 0] - with horizontal(region[i_end + 3, j_end + 1]): - y_out = mysign * x_in[-3, 2, 0] - with horizontal(region[i_end + 3, j_end + 2]): - y_out = mysign * x_in[-4, 1, 0] - x_out = mysign * y_in[-1, -4, 0] - with horizontal(region[i_end + 2, j_end + 4]): - x_out = mysign * y_in[2, -5, 0] - with horizontal(region[i_end + 3, j_end + 3]): - y_out = mysign * x_in[-5, 0, 0] - x_out = mysign * y_in[0, -5, 0] - with horizontal(region[i_end + 4, j_end + 1]): - y_out = mysign * x_in[-4, 3, 0] - with horizontal(region[i_end + 4, j_end + 2]): - y_out = mysign * x_in[-5, 2, 0] - with horizontal(region[i_end + 3, j_end + 4]): - x_out = mysign * y_in[1, -6, 0] - with horizontal(region[i_end + 4, j_end + 3]): - y_out = mysign * x_in[-6, 1, 0] - - # nw corner - with horizontal(region[i_start - 1, j_end + 2]): - x_out = y_in[0, -2, 0] - y_out = x_in[2, 0, 0] - with horizontal(region[i_start - 1, j_end + 1]): - y_out = x_in[1, 1, 0] - with horizontal(region[i_start - 1, j_end + 3]): - x_out = y_in[-1, -3, 0] - y_out = x_in[3, -1, 0] - with horizontal(region[i_start - 1, j_end + 4]): - x_out = y_in[-2, -4, 0] - with horizontal(region[i_start - 2, j_end + 2]): - x_out = y_in[1, -3, 0] - y_out = x_in[3, 1, 0] - with horizontal(region[i_start - 2, j_end + 1]): - y_out = x_in[2, 2, 0] - with horizontal(region[i_start - 2, j_end + 3]): - x_out = y_in[0, -4, 0] - y_out = x_in[4, 0, 0] - with horizontal(region[i_start - 2, j_end + 4]): - x_out = y_in[-1, -5, 0] - with horizontal(region[i_start - 3, j_end + 2]): - x_out = y_in[2, -4, 0] - y_out = x_in[4, 2, 0] - with horizontal(region[i_start - 3, j_end + 1]): - y_out = x_in[3, 3, 0] - with horizontal(region[i_start - 3, j_end + 3]): - x_out = y_in[1, -5, 0] - y_out = x_in[5, 1, 0] - with horizontal(region[i_start - 3, j_end + 4]): - x_out = y_in[0, -6, 0] - - # se corner - with horizontal(region[i_end + 1, j_start - 1]): - x_out = y_in[1, 1, 0] - with horizontal(region[i_end + 2, j_start - 1]): - y_out = x_in[-2, 0, 0] - x_out = y_in[0, 2, 0] - with horizontal(region[i_end + 1, j_start - 2]): - x_out = y_in[2, 2, 0] - with horizontal(region[i_end + 2, j_start - 2]): - y_out = x_in[-3, 1, 0] - x_out = y_in[1, 3, 0] - with horizontal(region[i_end + 1, j_start - 3]): - x_out = y_in[3, 3, 0] - with horizontal(region[i_end + 2, j_start - 3]): - y_out = x_in[-4, 2, 0] - x_out = y_in[2, 4, 0] - with horizontal(region[i_end + 3, j_start - 1]): - y_out = x_in[-3, -1, 0] - x_out = y_in[-1, 3, 0] - with horizontal(region[i_end + 3, j_start - 2]): - y_out = x_in[-4, 0, 0] - x_out = y_in[0, 4, 0] - with horizontal(region[i_end + 3, j_start - 3]): - y_out = x_in[-5, 1, 0] - x_out = y_in[1, 5, 0] - with horizontal(region[i_end + 4, j_start - 1]): - y_out = x_in[-4, -2, 0] - with horizontal(region[i_end + 4, j_start - 2]): - y_out = x_in[-5, -1, 0] - with horizontal(region[i_end + 4, j_start - 3]): - y_out = x_in[-6, 0, 0] diff --git a/stencils/pace/stencils/testing/README.md b/stencils/pace/stencils/testing/README.md deleted file mode 100644 index f8b0f04f1..000000000 --- a/stencils/pace/stencils/testing/README.md +++ /dev/null @@ -1,86 +0,0 @@ -# Translate Test Guide - -First, make sure you have followed the instruction in the top level [README](../../../../README.md) to install the Python requirements, GT4Py, and Pace. - -## Downloading test data - -The unit and regression tests of pace require data generated from the Fortran reference implementation which has to be downloaded from a Google Cloud Platform storage bucket. Since the bucket is setup as "requester pays", you need a valid GCP account to download the test data. - -First, make sure you have configured the authentication with user credientials and configured Docker with the following commands: - -```shell -gcloud auth login -gcloud auth configure-docker -``` - -Next, you can download the test data for the dynamical core and the physics tests. - -```shell -cd $(git rev-parse --show-toplevel)/fv3core -make get_test_data -cd $(git rev-parse --show-toplevel)/physics -make get_test_data -``` - -If you do not have a GCP account, there is an option to download basic test data from a public FTP server and you can skip the GCP authentication step above. To download test data from the FTP server, use `make USE_FTP=yes get_test_data` instead and this will avoid fetching from a GCP storage bucket. You will need a valid in stallation of the `lftp` command. - -## Running the tests (manually) - -There are two ways to run the tests, manually by explicitly invoking `pytest` or autmatically using make targets. The former can be used both inside the Docker container as well as for a bare-metal installation and will be described here. - -First enter the container and navigate to the pace directory: - -```shell -cd $(git rev-parse --show-toplevel) -make dev -cd /pace -``` - -Note that by entering the container with the `make dev` command, volumes for code and test data will be mounted into the container and modifications inside the container will be retained. - -There are two sets of tests. The "sequential tests" test components which do not require MPI-parallelism. The "parallel tests" can only within an MPI environment. - -To run the sequential and parallel tests for the dynmical core (fv3core), you can execute the following commands (these take a bit of time): - -```shell -pytest -v -s --data_path=/pace/fv3core/test_data/8.1.1/c12_6ranks_standard/dycore/ ./fv3core/tests -mpirun -np 6 python -m mpi4py -m pytest -v -s -m parallel --data_path=/pace/fv3core/test_data/8.1.1/c12_6ranks_standard/dycore ./fv3core/tests -``` - -Note that you must have already downloaded the test data according to the instructions above. The precise path needed for `--data_path` may be different, particularly the version directory. - -Similarly, you can run the sequential and parallel tests for the physical parameterizations (physics). Currently, only the microphysics is integrated into pace and will be tested. - -```shell -pytest -v -s --data_path=/pace/test_data/8.1.1/c12_6ranks_baroclinic_dycore_microphysics/physics/ ./physics/tests --threshold_overrides_file=/pace/physics/tests/savepoint/translate/overrides/baroclinic.yaml -mpirun -np 6 python -m mpi4py -m pytest -v -s -m parallel --data_path=/pace/test_data/8.1.1/c12_6ranks_baroclinic_dycore_microphysics/physics/ ./physics/tests --threshold_overrides_file=/pace/physics/tests/savepoint/translate/overrides/baroclinic.yaml -``` - -Finally, to test the pace infrastructure utilities (util), you can run the following commands: - -```shell -cd $(git rev-parse --show-toplevel)/util -make test -make test_mpi -``` - -## Running the tests automatically using Docker - -To automatize testing, a set of convenience commands is available that build the Docker image, run the container and execute the tests (dynamical core and physics only). This is mainly useful for CI/CD workflows. - -```shell -cd $(git rev-parse --show-toplevel) -DEV=y make savepoint_tests -DEV=y make savepoint_tests_mpi -DEV=y make physics_savepoint_tests -DEV=y make physics_savepoint_tests_mpi -``` - -## Test failure - -Test are running for each gridpoint of the domain, unless the Translate class for the test specifically restricts it. -Upon failure, the test will drop a `netCDF` faile in a `./.translate-errors` directory and named `translate-TestCase(-Rank).nc` containing input, computed output, reference and errors. - -## Environment variables - -- `PACE_TEST_N_THRESHOLD_SAMPLES`: Upon failure the system will try to pertub the output in an attempt to check for numerical instability. This means re-running the test for N samples. Default is `10`, `0` or less turns this feature off. diff --git a/stencils/pace/stencils/testing/__init__.py b/stencils/pace/stencils/testing/__init__.py deleted file mode 100644 index d676e8716..000000000 --- a/stencils/pace/stencils/testing/__init__.py +++ /dev/null @@ -1,15 +0,0 @@ -from . import parallel_translate, translate -from .parallel_translate import ( - ParallelTranslate, - ParallelTranslate2Py, - ParallelTranslate2PyState, - ParallelTranslateBaseSlicing, -) -from .savepoint import SavepointCase, Translate, dataset_to_dict -from .temporaries import assert_same_temporaries, copy_temporaries -from .translate import ( - TranslateFortranData2Py, - TranslateGrid, - pad_field_in_j, - read_serialized_data, -) diff --git a/stencils/pace/stencils/testing/conftest.py b/stencils/pace/stencils/testing/conftest.py deleted file mode 100644 index 1b93f06c5..000000000 --- a/stencils/pace/stencils/testing/conftest.py +++ /dev/null @@ -1,301 +0,0 @@ -import os -import re -from typing import Optional, Tuple - -import f90nml -import pytest -import xarray as xr -import yaml - -import pace.dsl -import pace.util -from pace.dsl.dace.dace_config import DaceConfig -from pace.stencils.testing import ParallelTranslate, TranslateGrid -from pace.stencils.testing.savepoint import SavepointCase, dataset_to_dict -from pace.util.mpi import MPI - - -@pytest.fixture() -def data_path(pytestconfig): - return data_path_and_namelist_filename_from_config(pytestconfig) - - -def data_path_and_namelist_filename_from_config(config) -> Tuple[str, str]: - data_path = config.getoption("data_path") - namelist_filename = os.path.join(data_path, "input.nml") - return data_path, namelist_filename - - -@pytest.fixture -def threshold_overrides(pytestconfig): - return thresholds_from_file(pytestconfig) - - -def thresholds_from_file(config): - thresholds_file = config.getoption("threshold_overrides_file") - if thresholds_file is None: - return None - return yaml.safe_load(open(thresholds_file, "r")) - - -def get_test_class(test_name): - translate_class_name = f"Translate{test_name.replace('-', '_')}" - try: - return_class = getattr(translate, translate_class_name) # noqa: F821 - except AttributeError as err: - if translate_class_name in err.args[0]: - return_class = None - else: - raise err - return return_class - - -def is_parallel_test(test_name): - test_class = get_test_class(test_name) - if test_class is None: - return False - else: - return issubclass(test_class, ParallelTranslate) - - -def get_test_class_instance(test_name, grid, namelist, stencil_factory): - translate_class = get_test_class(test_name) - if translate_class is None: - return None - else: - return translate_class(grid, namelist, stencil_factory) - - -def get_all_savepoint_names(metafunc, data_path): - only_names = metafunc.config.getoption("which_modules") - if only_names is None: - savepoint_names = [ - fname[:-3] for fname in os.listdir(data_path) if re.match(r".*\.nc", fname) - ] - savepoint_names = [s[:-3] for s in savepoint_names if s.endswith("-In")] - else: - savepoint_names = set(only_names.split(",")) - savepoint_names.discard("") - skip_names = metafunc.config.getoption("skip_modules") - if skip_names is not None: - savepoint_names.difference_update(skip_names.split(",")) - return savepoint_names - - -def get_sequential_savepoint_names(metafunc, data_path): - all_names = get_all_savepoint_names(metafunc, data_path) - sequential_names = [] - for name in all_names: - if not is_parallel_test(name): - sequential_names.append(name) - return sequential_names - - -def get_parallel_savepoint_names(metafunc, data_path): - all_names = get_all_savepoint_names(metafunc, data_path) - parallel_names = [] - for name in all_names: - if is_parallel_test(name): - parallel_names.append(name) - return parallel_names - - -def get_ranks(metafunc, layout): - only_rank = metafunc.config.getoption("which_rank") - dperiodic = metafunc.config.getoption("dperiodic") - if only_rank is None: - if dperiodic: - total_ranks = layout[0] * layout[1] - else: - total_ranks = 6 * layout[0] * layout[1] - return range(total_ranks) - else: - return [int(only_rank)] - - -def get_namelist(namelist_filename): - return pace.util.Namelist.from_f90nml(f90nml.read(namelist_filename)) - - -def get_config(backend: str, communicator: Optional[pace.util.Communicator]): - stencil_config = pace.dsl.stencil.StencilConfig( - compilation_config=pace.dsl.stencil.CompilationConfig( - backend=backend, rebuild=False, validate_args=True - ), - dace_config=DaceConfig( - communicator=communicator, - backend=backend, - ), - ) - return stencil_config - - -def sequential_savepoint_cases(metafunc, data_path, namelist_filename, *, backend: str): - savepoint_names = get_sequential_savepoint_names(metafunc, data_path) - namelist = get_namelist(namelist_filename) - stencil_config = get_config(backend, None) - ranks = get_ranks(metafunc, namelist.layout) - compute_grid = metafunc.config.getoption("compute_grid") - dperiodic = metafunc.config.getoption("dperiodic") - return _savepoint_cases( - savepoint_names, - ranks, - stencil_config, - namelist, - backend, - data_path, - compute_grid, - dperiodic, - ) - - -def _savepoint_cases( - savepoint_names, - ranks, - stencil_config, - namelist, - backend, - data_path, - compute_grid: bool, - dperiodic: bool, -): - return_list = [] - ds_grid: xr.Dataset = xr.open_dataset(os.path.join(data_path, "Grid-Info.nc")).isel( - savepoint=0 - ) - for rank in ranks: - grid = TranslateGrid( - dataset_to_dict(ds_grid.isel(rank=rank)), - rank=rank, - layout=namelist.layout, - backend=backend, - ).python_grid() - if compute_grid: - compute_grid_data(grid, namelist, backend, namelist.layout, dperiodic) - stencil_factory = pace.dsl.stencil.StencilFactory( - config=stencil_config, - grid_indexing=grid.grid_indexing, - ) - for test_name in sorted(list(savepoint_names)): - testobj = get_test_class_instance( - test_name, grid, namelist, stencil_factory - ) - n_calls = xr.open_dataset( - os.path.join(data_path, f"{test_name}-In.nc") - ).dims["savepoint"] - for i_call in range(n_calls): - return_list.append( - SavepointCase( - savepoint_name=test_name, - data_dir=data_path, - rank=rank, - i_call=i_call, - testobj=testobj, - grid=grid, - ) - ) - return return_list - - -def compute_grid_data(grid, namelist, backend, layout, dperiodic): - grid.make_grid_data( - npx=namelist.npx, - npy=namelist.npy, - npz=namelist.npz, - communicator=get_communicator(MPI.COMM_WORLD, layout, dperiodic), - backend=backend, - ) - - -def parallel_savepoint_cases( - metafunc, data_path, namelist_filename, mpi_rank, *, backend: str, comm -): - namelist = get_namelist(namelist_filename) - dperiodic = metafunc.config.getoption("dperiodic") - communicator = get_communicator(comm, namelist.layout, dperiodic) - stencil_config = get_config(backend, communicator) - savepoint_names = get_parallel_savepoint_names(metafunc, data_path) - compute_grid = metafunc.config.getoption("compute_grid") - return _savepoint_cases( - savepoint_names, - [mpi_rank], - stencil_config, - namelist, - backend, - data_path, - compute_grid, - dperiodic, - ) - - -def pytest_generate_tests(metafunc): - backend = metafunc.config.getoption("backend") - if MPI is not None and MPI.COMM_WORLD.Get_size() > 1: - if metafunc.function.__name__ == "test_parallel_savepoint": - generate_parallel_stencil_tests(metafunc, backend=backend) - elif metafunc.function.__name__ == "test_sequential_savepoint": - generate_sequential_stencil_tests(metafunc, backend=backend) - - -def generate_sequential_stencil_tests(metafunc, *, backend: str): - data_path, namelist_filename = data_path_and_namelist_filename_from_config( - metafunc.config - ) - savepoint_cases = sequential_savepoint_cases( - metafunc, data_path, namelist_filename, backend=backend - ) - metafunc.parametrize( - "case", savepoint_cases, ids=[str(item) for item in savepoint_cases] - ) - - -def generate_parallel_stencil_tests(metafunc, *, backend: str): - data_path, namelist_filename = data_path_and_namelist_filename_from_config( - metafunc.config - ) - # get MPI environment - comm = MPI.COMM_WORLD - mpi_rank = comm.Get_rank() - savepoint_cases = parallel_savepoint_cases( - metafunc, - data_path, - namelist_filename, - mpi_rank, - backend=backend, - comm=comm, - ) - metafunc.parametrize( - "case", savepoint_cases, ids=[str(item) for item in savepoint_cases] - ) - - -def get_communicator(comm, layout, dperiodic): - if (MPI.COMM_WORLD.Get_size() > 1) and (not dperiodic): - partitioner = pace.util.CubedSpherePartitioner( - pace.util.TilePartitioner(layout) - ) - communicator = pace.util.CubedSphereCommunicator(comm, partitioner) - else: - partitioner = pace.util.TilePartitioner(layout) - communicator = pace.util.TileCommunicator(comm, partitioner) - return communicator - - -@pytest.fixture() -def print_failures(pytestconfig): - return pytestconfig.getoption("print_failures") - - -@pytest.fixture() -def failure_stride(pytestconfig): - return int(pytestconfig.getoption("failure_stride")) - - -@pytest.fixture() -def compute_grid(pytestconfig): - return pytestconfig.getoption("compute_grid") - - -@pytest.fixture() -def dperiodic(pytestconfig): - return pytestconfig.getoption("dperiodic") diff --git a/stencils/pace/stencils/testing/grid.py b/stencils/pace/stencils/testing/grid.py deleted file mode 100644 index 23d25882b..000000000 --- a/stencils/pace/stencils/testing/grid.py +++ /dev/null @@ -1,791 +0,0 @@ -# type: ignore -from typing import Dict, Tuple - -import numpy as np - -import pace.util -from pace.dsl import gt4py_utils as utils -from pace.dsl.stencil import GridIndexing -from pace.dsl.typing import Float -from pace.util.grid import ( - AngleGridData, - ContravariantGridData, - DampingCoefficients, - DriverGridData, - GridData, - GridDefinitions, - HorizontalGridData, - MetricTerms, - VerticalGridData, -) -from pace.util.halo_data_transformer import QuantityHaloSpec - - -TRACER_DIM = "tracers" - - -class Grid: - # indices = ["is_", "ie", "isd", "ied", "js", "je", "jsd", "jed"] - index_pairs = [("is_", "js"), ("ie", "je"), ("isd", "jsd"), ("ied", "jed")] - shape_params = ["npz", "npx", "npy"] - # npx -- number of grid corners on one tile of the domain - # grid.ie == npx - 1identified east edge in fortran - # But we need to add the halo - 1 to change this check to 0 based python arrays - # grid.ie == npx + halo - 2 - - @classmethod - def _make(cls, npx, npy, npz, layout, rank, backend): - shape_params = { - "npx": npx, - "npy": npy, - "npz": npz, - } - # TODO this won't work with variable sized domains - # but this entire method will be refactored away - # and not used soon - nx = int((npx - 1) / layout[0]) - ny = int((npy - 1) / layout[1]) - indices = { - "isd": 0, - "ied": nx + 2 * utils.halo - 1, - "is_": utils.halo, - "ie": nx + utils.halo - 1, - "jsd": 0, - "jed": ny + 2 * utils.halo - 1, - "js": utils.halo, - "je": ny + utils.halo - 1, - } - return cls(indices, shape_params, rank, layout, backend, local_indices=True) - - @classmethod - def from_namelist(cls, namelist, rank, backend): - return cls._make( - namelist.npx, namelist.npy, namelist.npz, namelist.layout, rank, backend - ) - - @classmethod - def with_data_from_namelist(cls, namelist, communicator, backend): - grid = cls.from_namelist(namelist, communicator.rank, backend) - grid.make_grid_data( - npx=namelist.npx, - npy=namelist.npy, - npz=namelist.npz, - communicator=communicator, - backend=backend, - ) - return grid - - def __init__( - self, - indices, - shape_params, - rank, - layout, - backend, - data_fields={}, - local_indices=False, - ): - self.rank = rank - self.backend = backend - self.partitioner = pace.util.TilePartitioner(layout) - self.subtile_index = self.partitioner.subtile_index(self.rank) - self.layout = layout - for s in self.shape_params: - setattr(self, s, int(shape_params[s])) - self.subtile_width_x = int((self.npx - 1) / self.layout[0]) - self.subtile_width_y = int((self.npy - 1) / self.layout[1]) - for ivar, jvar in self.index_pairs: - local_i, local_j = int(indices[ivar]), int(indices[jvar]) - if not local_indices: - local_i, local_j = self.global_to_local_indices(local_i, local_j) - setattr(self, ivar, int(local_i)) - setattr(self, jvar, int(local_j)) - self.nid = int(self.ied - self.isd + 1) - self.njd = int(self.jed - self.jsd + 1) - self.nic = int(self.ie - self.is_ + 1) - self.njc = int(self.je - self.js + 1) - self.halo = utils.halo - self.global_is, self.global_js = self.local_to_global_indices(self.is_, self.js) - self.global_ie, self.global_je = self.local_to_global_indices(self.ie, self.je) - self.global_isd, self.global_jsd = self.local_to_global_indices( - self.isd, self.jsd - ) - self.global_ied, self.global_jed = self.local_to_global_indices( - self.ied, self.jed - ) - self.west_edge = self.global_is == self.halo - self.east_edge = self.global_ie == self.npx + self.halo - 2 - self.south_edge = self.global_js == self.halo - self.north_edge = self.global_je == self.npy + self.halo - 2 - - self.j_offset = self.js - self.jsd - 1 - self.i_offset = self.is_ - self.isd - 1 - self.sw_corner = self.west_edge and self.south_edge - self.se_corner = self.east_edge and self.south_edge - self.nw_corner = self.west_edge and self.north_edge - self.ne_corner = self.east_edge and self.north_edge - self.data_fields = {} - self.add_data(data_fields) - self._sizer = None - self._quantity_factory = None - self._grid_data = None - self._driver_grid_data = None - self._damping_coefficients = None - - @property - def sizer(self): - if self._sizer is None: - # in the future this should use from_namelist, when we have a non-flattened - # namelist - self._sizer = pace.util.SubtileGridSizer.from_tile_params( - nx_tile=self.npx - 1, - ny_tile=self.npy - 1, - nz=self.npz, - n_halo=self.halo, - extra_dim_lengths={ - MetricTerms.LON_OR_LAT_DIM: 2, - MetricTerms.TILE_DIM: 6, - MetricTerms.CARTESIAN_DIM: 3, - TRACER_DIM: len(utils.tracer_variables), - }, - layout=self.layout, - ) - return self._sizer - - @property - def quantity_factory(self) -> pace.util.QuantityFactory: - if self._quantity_factory is None: - self._quantity_factory = pace.util.QuantityFactory.from_backend( - self.sizer, backend=self.backend - ) - return self._quantity_factory - - def make_quantity( - self, - array, - dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], - units="Unknown", - origin=None, - extent=None, - ): - if origin is None: - origin = self.compute_origin() - if extent is None: - extent = self.domain_shape_compute() - return pace.util.Quantity( - array, dims=dims, units=units, origin=origin, extent=extent - ) - - def quantity_dict_update( - self, - data_dict, - varname, - dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], - units="Unknown", - ): - data_dict[varname + "_quantity"] = self.quantity_wrap( - data_dict[varname], dims=dims, units=units - ) - - def quantity_wrap( - self, - data, - dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], - units="unknown", - ): - origin = self.sizer.get_origin(dims) - extent = self.sizer.get_extent(dims) - return pace.util.Quantity( - data, dims=dims, units=units, origin=origin, extent=extent - ) - - def global_to_local_1d(self, global_value, subtile_index, subtile_length): - return int(global_value - subtile_index * subtile_length) - - def global_to_local_x(self, i_global): - return self.global_to_local_1d( - i_global, self.subtile_index[1], self.subtile_width_x - ) - - def global_to_local_y(self, j_global): - return self.global_to_local_1d( - j_global, self.subtile_index[0], self.subtile_width_y - ) - - def global_to_local_indices(self, i_global, j_global): - i_local = self.global_to_local_x(i_global) - j_local = self.global_to_local_y(j_global) - return i_local, j_local - - def local_to_global_1d(self, local_value, subtile_index, subtile_length): - return int(local_value + subtile_index * subtile_length) - - def local_to_global_indices(self, i_local, j_local): - i_global = self.local_to_global_1d( - i_local, self.subtile_index[1], self.subtile_width_x - ) - j_global = self.local_to_global_1d( - j_local, self.subtile_index[0], self.subtile_width_y - ) - return i_global, j_global - - def add_data(self, data_dict): - self.data_fields.update(data_dict) - for k, v in self.data_fields.items(): - setattr(self, k, v) - - def irange_compute(self): - return range(self.is_, self.ie + 1) - - def irange_compute_x(self): - return range(self.is_, self.ie + 2) - - def jrange_compute(self): - return range(self.js, self.je + 1) - - def jrange_compute_y(self): - return range(self.js, self.je + 2) - - def irange_domain(self): - return range(self.isd, self.ied + 1) - - def jrange_domain(self): - return range(self.jsd, self.jed + 1) - - def krange(self): - return range(0, self.npz) - - def compute_interface(self): - return self.slice_dict(self.compute_dict()) - - def x3d_interface(self): - return self.slice_dict(self.x3d_compute_dict()) - - def y3d_interface(self): - return self.slice_dict(self.y3d_compute_dict()) - - def x3d_domain_interface(self): - return self.slice_dict(self.x3d_domain_dict()) - - def y3d_domain_interface(self): - return self.slice_dict(self.y3d_domain_dict()) - - def add_one(self, num): - if num is None: - return None - return num + 1 - - def slice_dict(self, d, ndim: int = 3): - iters: str = "ijk" if ndim > 1 else "k" - return tuple( - [ - slice( - int(d[f"{iters[i]}start"]), int(self.add_one(d[f"{iters[i]}end"])) - ) - for i in range(ndim) - ] - ) - - def default_domain_dict(self): - return { - "istart": self.isd, - "iend": self.ied, - "jstart": self.jsd, - "jend": self.jed, - "kstart": 0, - "kend": self.npz - 1, - } - - def default_dict_buffer_2d(self): - mydict = self.default_domain_dict() - mydict["iend"] += 1 - mydict["jend"] += 1 - return mydict - - def compute_dict(self): - return { - "istart": self.is_, - "iend": self.ie, - "jstart": self.js, - "jend": self.je, - "kstart": 0, - "kend": self.npz - 1, - } - - def compute_dict_buffer_2d(self): - mydict = self.compute_dict() - mydict["iend"] += 1 - mydict["jend"] += 1 - return mydict - - def default_buffer_k_dict(self): - mydict = self.default_domain_dict() - mydict["kend"] = self.npz - return mydict - - def compute_buffer_k_dict(self): - mydict = self.compute_dict() - mydict["kend"] = self.npz - return mydict - - def x3d_domain_dict(self): - horizontal_dict = { - "istart": self.isd, - "iend": self.ied + 1, - "jstart": self.jsd, - "jend": self.jed, - } - return {**self.default_domain_dict(), **horizontal_dict} - - def y3d_domain_dict(self): - horizontal_dict = { - "istart": self.isd, - "iend": self.ied, - "jstart": self.jsd, - "jend": self.jed + 1, - } - return {**self.default_domain_dict(), **horizontal_dict} - - def x3d_compute_dict(self): - horizontal_dict = { - "istart": self.is_, - "iend": self.ie + 1, - "jstart": self.js, - "jend": self.je, - } - return {**self.default_domain_dict(), **horizontal_dict} - - def y3d_compute_dict(self): - horizontal_dict = { - "istart": self.is_, - "iend": self.ie, - "jstart": self.js, - "jend": self.je + 1, - } - return {**self.default_domain_dict(), **horizontal_dict} - - def x3d_compute_domain_y_dict(self): - horizontal_dict = { - "istart": self.is_, - "iend": self.ie + 1, - "jstart": self.jsd, - "jend": self.jed, - } - return {**self.default_domain_dict(), **horizontal_dict} - - def y3d_compute_domain_x_dict(self): - horizontal_dict = { - "istart": self.isd, - "iend": self.ied, - "jstart": self.js, - "jend": self.je + 1, - } - return {**self.default_domain_dict(), **horizontal_dict} - - def domain_shape_full(self, *, add: Tuple[int, int, int] = (0, 0, 0)): - """Domain shape for the full array including halo points.""" - return (self.nid + add[0], self.njd + add[1], self.npz + add[2]) - - def domain_shape_compute(self, *, add: Tuple[int, int, int] = (0, 0, 0)): - """Compute domain shape excluding halo points.""" - return (self.nic + add[0], self.njc + add[1], self.npz + add[2]) - - def copy_right_edge(self, var, i_index, j_index): - return np.copy(var[i_index:, :, :]), np.copy(var[:, j_index:, :]) - - def insert_left_edge(self, var, edge_data_i, i_index, edge_data_j, j_index): - if len(var.shape) < 3: - var[:i_index, :] = edge_data_i - var[:, :j_index] = edge_data_j - else: - var[:i_index, :, :] = edge_data_i - var[:, :j_index, :] = edge_data_j - - def insert_right_edge(self, var, edge_data_i, i_index, edge_data_j, j_index): - if len(var.shape) < 3: - var[i_index:, :] = edge_data_i - var[:, j_index:] = edge_data_j - else: - var[i_index:, :, :] = edge_data_i - var[:, j_index:, :] = edge_data_j - - def uvar_edge_halo(self, var): - return self.copy_right_edge(var, self.ie + 2, self.je + 1) - - def vvar_edge_halo(self, var): - return self.copy_right_edge(var, self.ie + 1, self.je + 2) - - def compute_origin(self, add: Tuple[int, int, int] = (0, 0, 0)): - """Start of the compute domain (e.g. (halo, halo, 0))""" - return (self.is_ + add[0], self.js + add[1], add[2]) - - def full_origin(self, add: Tuple[int, int, int] = (0, 0, 0)): - """Start of the full array including halo points (e.g. (0, 0, 0))""" - return (self.isd + add[0], self.jsd + add[1], add[2]) - - def horizontal_starts_from_shape(self, shape): - if shape[0:2] in [ - self.domain_shape_compute()[0:2], - self.domain_shape_compute(add=(1, 0, 0))[0:2], - self.domain_shape_compute(add=(0, 1, 0))[0:2], - self.domain_shape_compute(add=(1, 1, 0))[0:2], - ]: - return self.is_, self.js - elif shape[0:2] == (self.nic + 2, self.njc + 2): - return self.is_ - 1, self.js - 1 - else: - return 0, 0 - - def get_halo_update_spec( - self, - shape, - origin, - halo_points, - dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], - ) -> QuantityHaloSpec: - """Build memory specifications for the halo update.""" - return self.quantity_factory.get_quantity_halo_spec( - dims=dims, - n_halo=halo_points, - ) - - @property - def grid_indexing(self) -> "GridIndexing": - return GridIndexing( - domain=tuple(int(item) for item in self.domain_shape_compute()), - n_halo=self.halo, - south_edge=self.south_edge, - north_edge=self.north_edge, - west_edge=self.west_edge, - east_edge=self.east_edge, - ) - - @property - def damping_coefficients(self) -> "DampingCoefficients": - if self._damping_coefficients is not None: - return self._damping_coefficients - self._damping_coefficients = DampingCoefficients( - divg_u=self.divg_u, - divg_v=self.divg_v, - del6_u=self.del6_u, - del6_v=self.del6_v, - da_min=self.da_min, - da_min_c=self.da_min_c, - ) - return self._damping_coefficients - - def set_damping_coefficients(self, damping_coefficients: "DampingCoefficients"): - self._damping_coefficients = damping_coefficients - - @property - def grid_data(self) -> "GridData": - if self._grid_data is not None: - return self._grid_data - - # The translate code pads ndarray axes with zeros in certain cases, - # in particular the vertical axis. Since we're deprecating those tests, - # we simply "fix" those arrays here. - clipped_data: Dict[str, pace.util.Quantity] = {} - for name in ( - "ee1", - "ee2", - "es1", - "ew2", - "edge_w", - "edge_e", - "edge_s", - "edge_n", - ): - grid_defs = getattr(GridDefinitions, name, None) - assert grid_defs is not None - - dims = grid_defs.dims - units = grid_defs.units - - data = getattr(self, name) - assert data is not None - - quantity = self.quantity_factory.zeros(dims=dims, units=units, dtype=Float) - if len(quantity.shape) == 3: - quantity.data[:] = data[:, :, : quantity.shape[2]] - elif len(quantity.shape) == 2: - quantity.data[:] = data[:, : quantity.shape[1]] - elif len(quantity.shape) == 1: - quantity.data[:] = data[: quantity.shape[0]] - else: - raise NotImplementedError( - "The data filtering is not implemented for a quantity of this shape" - ) - - clipped_data[name] = quantity - - horizontal = HorizontalGridData( - lon=self.quantity_factory.from_array( - data=self.bgrid1, - dims=GridDefinitions.lon.dims, - units=GridDefinitions.lon.units, - ), - lat=self.quantity_factory.from_array( - data=self.bgrid2, - dims=GridDefinitions.lat.dims, - units=GridDefinitions.lat.units, - ), - lon_agrid=self.quantity_factory.from_array( - data=self.agrid1, - dims=GridDefinitions.lon_agrid.dims, - units=GridDefinitions.lon_agrid.units, - ), - lat_agrid=self.quantity_factory.from_array( - data=self.agrid2, - dims=GridDefinitions.lat_agrid.dims, - units=GridDefinitions.lat_agrid.units, - ), - area=self.quantity_factory.from_array( - data=self.area, - dims=GridDefinitions.area.dims, - units=GridDefinitions.area.units, - ), - area_64=self.quantity_factory.from_array( - data=self.area_64, - dims=GridDefinitions.area.dims, - units=GridDefinitions.area.units, - ), - rarea=self.quantity_factory.from_array( - data=self.rarea, - dims=GridDefinitions.rarea.dims, - units=GridDefinitions.rarea.units, - ), - rarea_c=self.quantity_factory.from_array( - data=self.rarea_c, - dims=GridDefinitions.rarea_c.dims, - units=GridDefinitions.rarea_c.units, - ), - dx=self.quantity_factory.from_array( - data=self.dx, - dims=GridDefinitions.dx.dims, - units=GridDefinitions.dx.units, - ), - dy=self.quantity_factory.from_array( - data=self.dy, - dims=GridDefinitions.dy.dims, - units=GridDefinitions.dy.units, - ), - dxc=self.quantity_factory.from_array( - data=self.dxc, - dims=GridDefinitions.dxc.dims, - units=GridDefinitions.dxc.units, - ), - dyc=self.quantity_factory.from_array( - data=self.dyc, - dims=GridDefinitions.dyc.dims, - units=GridDefinitions.dyc.units, - ), - dxa=self.quantity_factory.from_array( - data=self.dxa, - dims=GridDefinitions.dxa.dims, - units=GridDefinitions.dxa.units, - ), - dya=self.quantity_factory.from_array( - data=self.dya, - dims=GridDefinitions.dya.dims, - units=GridDefinitions.dya.units, - ), - rdx=self.quantity_factory.from_array( - data=self.rdx, - dims=GridDefinitions.rdx.dims, - units=GridDefinitions.rdx.units, - ), - rdy=self.quantity_factory.from_array( - data=self.rdy, - dims=GridDefinitions.rdy.dims, - units=GridDefinitions.rdy.units, - ), - rdxc=self.quantity_factory.from_array( - data=self.rdxc, - dims=GridDefinitions.rdxc.dims, - units=GridDefinitions.rdxc.units, - ), - rdyc=self.quantity_factory.from_array( - data=self.rdyc, - dims=GridDefinitions.rdyc.dims, - units=GridDefinitions.rdyc.units, - ), - rdxa=self.quantity_factory.from_array( - data=self.rdxa, - dims=GridDefinitions.rdxa.dims, - units=GridDefinitions.rdxa.units, - ), - rdya=self.quantity_factory.from_array( - data=self.rdya, - dims=GridDefinitions.rdya.dims, - units=GridDefinitions.rdya.units, - ), - ee1=clipped_data["ee1"], - ee2=clipped_data["ee2"], - es1=clipped_data["es1"], - ew2=clipped_data["ew2"], - a11=self.quantity_factory.from_array( - data=self.a11, - dims=GridDefinitions.a11.dims, - units=GridDefinitions.a11.units, - ), - a12=self.quantity_factory.from_array( - data=self.a12, - dims=GridDefinitions.a12.dims, - units=GridDefinitions.a12.units, - ), - a21=self.quantity_factory.from_array( - data=self.a21, - dims=GridDefinitions.a21.dims, - units=GridDefinitions.a21.units, - ), - a22=self.quantity_factory.from_array( - data=self.a22, - dims=GridDefinitions.a22.dims, - units=GridDefinitions.a22.units, - ), - edge_w=clipped_data["edge_w"], - edge_e=clipped_data["edge_e"], - edge_n=clipped_data["edge_n"], - edge_s=clipped_data["edge_s"], - ) - vertical = VerticalGridData( - ak=self.quantity_factory.from_array( - data=self.ak, - dims=GridDefinitions.ak.dims, - units=GridDefinitions.ak.units, - ), - bk=self.quantity_factory.from_array( - data=self.bk, - dims=GridDefinitions.bk.dims, - units=GridDefinitions.bk.units, - ), - ) - contravariant = ContravariantGridData( - cosa=self.quantity_factory.from_array( - data=self.cosa, - dims=GridDefinitions.cosa.dims, - units=GridDefinitions.cosa.units, - ), - cosa_u=self.quantity_factory.from_array( - data=self.cosa_u, - dims=GridDefinitions.cosa_u.dims, - units=GridDefinitions.cosa_u.units, - ), - cosa_v=self.quantity_factory.from_array( - data=self.cosa_v, - dims=GridDefinitions.cosa_v.dims, - units=GridDefinitions.cosa_v.units, - ), - cosa_s=self.quantity_factory.from_array( - data=self.cosa_s, - dims=GridDefinitions.cosa_s.dims, - units=GridDefinitions.cosa_s.units, - ), - sina_u=self.quantity_factory.from_array( - data=self.sina_u, - dims=GridDefinitions.sina_u.dims, - units=GridDefinitions.sina_u.units, - ), - sina_v=self.quantity_factory.from_array( - data=self.sina_v, - dims=GridDefinitions.sina_v.dims, - units=GridDefinitions.sina_v.units, - ), - rsina=self.quantity_factory.from_array( - data=self.rsina, - dims=GridDefinitions.rsina.dims, - units=GridDefinitions.rsina.units, - ), - rsin_u=self.quantity_factory.from_array( - data=self.rsin_u, - dims=GridDefinitions.rsin_u.dims, - units=GridDefinitions.rsin_u.units, - ), - rsin_v=self.quantity_factory.from_array( - data=self.rsin_v, - dims=GridDefinitions.rsin_v.dims, - units=GridDefinitions.rsin_v.units, - ), - rsin2=self.quantity_factory.from_array( - data=self.rsin2, - dims=GridDefinitions.rsin2.dims, - units=GridDefinitions.rsin2.units, - ), - ) - angle = AngleGridData( - sin_sg1=self.quantity_factory.from_array( - data=self.sin_sg1, - dims=GridDefinitions.sin_sg1.dims, - units=GridDefinitions.sin_sg1.units, - ), - sin_sg2=self.quantity_factory.from_array( - data=self.sin_sg2, - dims=GridDefinitions.sin_sg2.dims, - units=GridDefinitions.sin_sg2.units, - ), - sin_sg3=self.quantity_factory.from_array( - data=self.sin_sg3, - dims=GridDefinitions.sin_sg3.dims, - units=GridDefinitions.sin_sg3.units, - ), - sin_sg4=self.quantity_factory.from_array( - data=self.sin_sg4, - dims=GridDefinitions.sin_sg4.dims, - units=GridDefinitions.sin_sg4.units, - ), - cos_sg1=self.quantity_factory.from_array( - data=self.cos_sg1, - dims=GridDefinitions.cos_sg1.dims, - units=GridDefinitions.cos_sg1.units, - ), - cos_sg2=self.quantity_factory.from_array( - data=self.cos_sg2, - dims=GridDefinitions.cos_sg2.dims, - units=GridDefinitions.cos_sg2.units, - ), - cos_sg3=self.quantity_factory.from_array( - data=self.cos_sg3, - dims=GridDefinitions.cos_sg3.dims, - units=GridDefinitions.cos_sg3.units, - ), - cos_sg4=self.quantity_factory.from_array( - data=self.cos_sg4, - dims=GridDefinitions.cos_sg4.dims, - units=GridDefinitions.cos_sg4.units, - ), - ) - self._grid_data = GridData( - horizontal_data=horizontal, - vertical_data=vertical, - contravariant_data=contravariant, - angle_data=angle, - ) - return self._grid_data - - @property - def driver_grid_data(self) -> "GridData": - if self._driver_grid_data is None: - self._driver_grid_data = DriverGridData.new_from_grid_variables( - vlon=self.vlon, - vlat=self.vlat, - edge_vect_w=self.edge_vect_w, - edge_vect_e=self.edge_vect_e, - edge_vect_s=self.edge_vect_s, - edge_vect_n=self.edge_vect_n, - es1=self.es1, - ew2=self.ew2, - ) - return self._driver_grid_data - - def set_grid_data(self, grid_data: "GridData"): - self._grid_data = grid_data - - def make_grid_data(self, npx, npy, npz, communicator, backend): - metric_terms = MetricTerms.from_tile_sizing( - npx=npx, npy=npy, npz=npz, communicator=communicator, backend=backend - ) - self.set_grid_data(GridData.new_from_metric_terms(metric_terms)) - self.set_damping_coefficients( - DampingCoefficients.new_from_metric_terms(metric_terms) - ) diff --git a/stencils/pace/stencils/testing/parallel_translate.py b/stencils/pace/stencils/testing/parallel_translate.py deleted file mode 100644 index f10b9b27e..000000000 --- a/stencils/pace/stencils/testing/parallel_translate.py +++ /dev/null @@ -1,260 +0,0 @@ -import copy -from types import SimpleNamespace -from typing import Any, Dict, List - -import numpy as np -import pytest - -import pace.util as fv3util -from pace.dsl import gt4py_utils as utils - -from .translate import TranslateFortranData2Py, read_serialized_data - - -class ParallelTranslate: - max_error = TranslateFortranData2Py.max_error - near_zero = TranslateFortranData2Py.near_zero - compute_grid_option = False - tests_grid = False - inputs: Dict[str, Any] = {} - outputs: Dict[str, Any] = {} - - def __init__(self, rank_grids, namelist, stencil_factory, *args, **kwargs): - if len(args) > 0: - raise TypeError( - "received {} positional arguments, expected 0".format(len(args)) - ) - if len(kwargs) > 0: - raise TypeError( - "received {} keyword arguments, expected 0".format(len(kwargs)) - ) - if not hasattr(rank_grids, "__getitem__"): - rank_grid = rank_grids - else: - rank_grid = rank_grids[0] - self.grid = rank_grid - self._base = TranslateFortranData2Py(rank_grid, stencil_factory) - self._base.in_vars = { - "data_vars": { - name: {} - for name, data in self.inputs.items() - if len(data.get("dims", [])) > 0 - }, - "parameters": [ - name - for name, data in self.inputs.items() - if len(data.get("dims", [])) == 0 - ], - } - self._base.out_vars = {name: {} for name in self.outputs} - self.max_error = self._base.max_error - self._rank_grids = rank_grids - self.ignore_near_zero_errors = {} - self.namelist = namelist - self.skip_test = False - - def state_list_from_inputs_list(self, inputs_list: List[dict]) -> list: - state_list = [] - for inputs in inputs_list: - state_list.append(self.state_from_inputs(inputs)) - return state_list - - def state_from_inputs(self, inputs: dict, grid=None) -> dict: - if grid is None: - grid = self.grid - state = copy.copy(inputs) - self._base.make_storage_data_input_vars(state) - for name, properties in self.inputs.items(): - if "name" not in properties: - properties["name"] = name - input_data = state[name] - if len(properties["dims"]) > 0: - dims = properties["dims"] - state[properties["name"]] = fv3util.Quantity( - input_data, - dims, - properties["units"], - origin=grid.sizer.get_origin(dims), - extent=grid.sizer.get_extent(dims), - ) - else: - state[properties["name"]] = input_data - return state - - def outputs_list_from_state_list(self, state_list): - outputs_list = [] - for state in state_list: - outputs_list.append(self.outputs_from_state(state)) - return outputs_list - - def collect_input_data(self, serializer, savepoint): - input_data = {} - for varname in self.inputs.keys(): - input_data[varname] = read_serialized_data(serializer, savepoint, varname) - return input_data - - def outputs_from_state(self, state: dict): - return_dict: Dict[str, np.ndarray] = {} - if len(self.outputs) == 0: - return return_dict - for name, properties in self.outputs.items(): - standard_name = properties["name"] - if name in self._base.in_vars["data_vars"].keys(): - if "kaxis" in self._base.in_vars["data_vars"][name].keys(): - kaxis = int(self._base.in_vars["data_vars"][name]["kaxis"]) - dims = list(state[standard_name].dims) - dims.insert(kaxis, dims.pop(-1)) - state[standard_name] = state[standard_name].transpose(dims) - if len(properties["dims"]) > 0: - output_slice = _serialize_slice( - state[standard_name], properties.get("n_halo", utils.halo) - ) - return_dict[name] = utils.asarray( - state[standard_name].data[output_slice] - ) - else: - return_dict[name] = state[standard_name] - return return_dict - - @property - def rank_grids(self): - return self._rank_grids - - @property - def layout(self): - return self.namelist.layout - - def compute_sequential(self, inputs_list, communicator_list): - """Compute the outputs while iterating over a set of communicator - objects sequentially.""" - raise NotImplementedError() - - def compute_parallel(self, inputs, communicator): - """Compute the outputs using one communicator operating in parallel.""" - self.compute_sequential([inputs], [communicator]) - - -class ParallelTranslateBaseSlicing(ParallelTranslate): - def outputs_from_state(self, state: dict): - if len(self.outputs) == 0: - return {} - outputs = {} - storages = {} - for name, properties in self.outputs.items(): - standard_name = properties.get("name", name) - if isinstance(state[standard_name], fv3util.Quantity): - storages[name] = state[standard_name].data - elif len(self.outputs[name]["dims"]) > 0: - storages[name] = state[standard_name] # assume it's a storage - else: - outputs[name] = state[standard_name] # scalar - outputs.update(self._base.slice_output(storages)) - return outputs - - -def _serialize_slice(quantity, n_halo, real_dims=None): - if real_dims is None: - real_dims = quantity.dims - slice_list = [] - for dim, origin, extent in zip(quantity.dims, quantity.origin, quantity.extent): - if dim in real_dims: - if dim in fv3util.HORIZONTAL_DIMS: - if isinstance(n_halo, int): - halo = n_halo - elif dim in fv3util.X_DIMS: - halo = n_halo[0] - elif dim in fv3util.Y_DIMS: - halo = n_halo[1] - else: - raise RuntimeError(n_halo) - else: - halo = 0 - slice_list.append(slice(origin - halo, origin + extent + halo)) - else: - slice_list.append(-1) - return tuple(slice_list) - - -class ParallelTranslateGrid(ParallelTranslate): - """ - Translation class which only uses quantity factory for initialization, to - support some non-standard array dimension layouts not supported by the - TranslateFortranData2Py initializers. - """ - - tests_grid = True - - def state_from_inputs(self, inputs: dict, grid=None) -> dict: - if grid is None: - grid = self.grid - state = {} - for name, properties in self.inputs.items(): - standard_name = properties.get("name", name) - if len(properties["dims"]) > 0: - state[standard_name] = grid.quantity_factory.zeros( - properties["dims"], properties["units"], dtype=inputs[name].dtype - ) - input_slice = _serialize_slice( - state[standard_name], properties.get("n_halo", utils.halo) - ) - if len(properties["dims"]) > 0: - state[standard_name].data[input_slice] = utils.asarray( - inputs[name], to_type=type(state[standard_name].data) - ) - else: - state[standard_name].data[:] = inputs[name] - if name in self._base.in_vars["data_vars"].keys(): - if "kaxis" in self._base.in_vars["data_vars"][name].keys(): - kaxis = int(self._base.in_vars["data_vars"][name]["kaxis"]) - dims = list(state[standard_name].dims) - k_dim = dims.pop(kaxis) - dims.insert(len(dims), k_dim) - state[standard_name] = state[standard_name].transpose(dims) - else: - state[standard_name] = inputs[name] - return state - - def compute_sequential(self, *args, **kwargs): - pytest.skip( - f"{self.__class__} only has a mpirun implementation, " - "not running in mock-parallel" - ) - - -class ParallelTranslate2Py(ParallelTranslate): - def collect_input_data(self, serializer, savepoint): - input_data = super().collect_input_data(serializer, savepoint) - input_data.update(self._base.collect_input_data(serializer, savepoint)) - return input_data - - def compute_parallel(self, inputs, communicator): - inputs = {**inputs} - inputs = self.state_from_inputs(inputs) - inputs["comm"] = communicator - result = self._base.compute_from_storage(inputs) - quantity_result = self.outputs_from_state(result) - result.update(quantity_result) - for name, data in result.items(): - if isinstance(data, fv3util.Quantity): - result[name] = data.data - result.update(self._base.slice_output(result)) - return result - - def compute_sequential(self, a, b): - pytest.skip( - f"{self.__class__} only has a mpirun implementation, " - "not running in mock-parallel" - ) - - -class ParallelTranslate2PyState(ParallelTranslate2Py): - def compute_parallel(self, inputs, communicator): - self._base.make_storage_data_input_vars(inputs) - for name, properties in self.inputs.items(): - self.grid.quantity_dict_update( - inputs, name, dims=properties["dims"], units=properties["units"] - ) - statevars = SimpleNamespace(**inputs) - state = {"state": statevars} - self._base.compute_func(**state) - return self._base.slice_output(vars(state["state"])) diff --git a/stencils/pace/stencils/testing/savepoint.py b/stencils/pace/stencils/testing/savepoint.py deleted file mode 100644 index 04d01e219..000000000 --- a/stencils/pace/stencils/testing/savepoint.py +++ /dev/null @@ -1,64 +0,0 @@ -import dataclasses -import os -from typing import Dict, Protocol, Union - -import numpy as np -import xarray as xr - -from .grid import Grid # type: ignore - - -def dataset_to_dict(ds: xr.Dataset) -> Dict[str, Union[np.ndarray, float, int]]: - return { - name: _process_if_scalar(array.values) for name, array in ds.data_vars.items() - } - - -def _process_if_scalar(value: np.ndarray) -> Union[np.ndarray, float, int]: - if len(value.shape) == 0: - return value.item() - else: - return value - - -class Translate(Protocol): - def collect_input_data(self, ds: xr.Dataset) -> dict: - ... - - def compute(self, data: dict): - ... - - -@dataclasses.dataclass -class SavepointCase: - """ - Represents a savepoint with data on one rank. - """ - - savepoint_name: str - data_dir: str - rank: int - i_call: int - testobj: Translate - grid: Grid - - def __str__(self): - return f"{self.savepoint_name}-rank={self.rank}-call={self.i_call}" - - @property - def ds_in(self) -> xr.Dataset: - return ( - xr.open_dataset(os.path.join(self.data_dir, f"{self.savepoint_name}-In.nc")) - .isel(rank=self.rank) - .isel(savepoint=self.i_call) - ) - - @property - def ds_out(self) -> xr.Dataset: - return ( - xr.open_dataset( - os.path.join(self.data_dir, f"{self.savepoint_name}-Out.nc") - ) - .isel(rank=self.rank) - .isel(savepoint=self.i_call) - ) diff --git a/stencils/pace/stencils/testing/temporaries.py b/stencils/pace/stencils/testing/temporaries.py deleted file mode 100644 index 2dd46663d..000000000 --- a/stencils/pace/stencils/testing/temporaries.py +++ /dev/null @@ -1,51 +0,0 @@ -import copy -from typing import List - -import numpy as np - -import pace.util - - -def copy_temporaries(obj, max_depth: int) -> dict: - temporaries = {} - attrs = [a for a in dir(obj) if not a.startswith("__")] - for attr_name in attrs: - try: - attr = getattr(obj, attr_name) - except AttributeError: - attr = None - if isinstance(attr, pace.util.Quantity): - temporaries[attr_name] = copy.deepcopy(np.asarray(attr.data)) - elif attr.__class__.__module__.split(".")[0] in ( # type: ignore - "fv3core", - "pace", - ): - if max_depth > 0: - sub_temporaries = copy_temporaries(attr, max_depth - 1) - if len(sub_temporaries) > 0: - temporaries[attr_name] = sub_temporaries - return temporaries - - -def assert_same_temporaries(dict1: dict, dict2: dict): - diffs = _assert_same_temporaries(dict1, dict2) - if len(diffs) > 0: - raise AssertionError(f"{len(diffs)} differing temporaries found: {diffs}") - - -def _assert_same_temporaries(dict1: dict, dict2: dict) -> List[str]: - differences = [] - for attr in dict1: - attr1 = dict1[attr] - attr2 = dict2[attr] - if isinstance(attr1, np.ndarray): - try: - assert np.allclose(attr1, attr2, equal_nan=True) - except AssertionError as e: - print(e) - differences.append(attr) - else: - sub_differences = _assert_same_temporaries(attr1, attr2) - for d in sub_differences: - differences.append(f"{attr}.{d}") - return differences diff --git a/stencils/pace/stencils/testing/test_translate.py b/stencils/pace/stencils/testing/test_translate.py deleted file mode 100644 index 796f30c1d..000000000 --- a/stencils/pace/stencils/testing/test_translate.py +++ /dev/null @@ -1,495 +0,0 @@ -# type: ignore -import copy -import os -from typing import Any, Dict, List - -import numpy as np -import pytest - -import pace.dsl -import pace.dsl.gt4py_utils as gt_utils -import pace.util -from pace.dsl.dace.dace_config import DaceConfig -from pace.dsl.stencil import CompilationConfig -from pace.stencils.testing import SavepointCase, dataset_to_dict -from pace.util.mpi import MPI -from pace.util.testing import compare_scalar, perturb, success, success_array - - -# this only matters for manually-added print statements -np.set_printoptions(threshold=4096) - -OUTDIR = "./.translate-errors" -GPU_MAX_ERR = 1e-10 -GPU_NEAR_ZERO = 1e-15 - - -def platform(): - in_docker = os.environ.get("IN_DOCKER", False) - return "docker" if in_docker else "metal" - - -def sample_wherefail( - computed_data, - ref_data, - eps, - print_failures, - failure_stride, - test_name, - ignore_near_zero_errors, - near_zero, - xy_indices=False, -): - found_indices = np.where( - np.logical_not( - success_array( - computed_data, ref_data, eps, ignore_near_zero_errors, near_zero - ) - ) - ) - computed_failures = computed_data[found_indices] - reference_failures = ref_data[found_indices] - - # List all errors - return_strings = [] - bad_indices_count = len(found_indices[0]) - # Determine worst result - worst_metric_err = 0.0 - for b in range(bad_indices_count): - full_index = [f[b] for f in found_indices] - metric_err = compare_scalar(computed_failures[b], reference_failures[b]) - abs_err = abs(computed_failures[b] - reference_failures[b]) - if print_failures and b % failure_stride == 0: - return_strings.append( - f"index: {full_index}, computed {computed_failures[b]}, " - f"reference {reference_failures[b]}, " - f"absolute diff {abs_err:.3e}, " - f"metric diff: {metric_err:.3e}" - ) - if np.isnan(metric_err) or (metric_err > worst_metric_err): - worst_metric_err = metric_err - worst_full_idx = full_index - worst_abs_err = abs_err - computed_worst = computed_failures[b] - reference_worst = reference_failures[b] - # Summary and worst result - fullcount = len(ref_data.flatten()) - return_strings.append( - f"Failed count: {bad_indices_count}/{fullcount} " - f"({round(100.0 * (bad_indices_count / fullcount), 2)}%),\n" - f"Worst failed index {worst_full_idx}\n" - f"\tcomputed:{computed_worst}\n" - f"\treference: {reference_worst}\n" - f"\tabsolute diff: {worst_abs_err:.3e}\n" - f"\tmetric diff: {worst_metric_err:.3e}\n" - ) - - if xy_indices: - if len(computed_data.shape) == 3: - axis = 2 - any = np.any - elif len(computed_data.shape) == 4: - axis = (2, 3) - any = np.any - else: - axis = None - - def any(array, axis): - return array - - found_xy_indices = np.where( - any( - np.logical_not( - success_array( - computed_data, ref_data, eps, ignore_near_zero_errors, near_zero - ) - ), - axis=axis, - ) - ) - - return_strings.append( - "failed horizontal indices:" + str(list(zip(*found_xy_indices))) - ) - - return "\n".join(return_strings) - - -def process_override(threshold_overrides, testobj, test_name, backend): - override = threshold_overrides.get(test_name, None) - if override is not None: - for spec in override: - if "platform" not in spec: - spec["platform"] = platform() - if "backend" not in spec: - spec["backend"] = backend - matches = [ - spec - for spec in override - if spec["backend"] == backend and spec["platform"] == platform() - ] - if len(matches) == 1: - match = matches[0] - if "max_error" in match: - testobj.max_error = float(match["max_error"]) - if "near_zero" in match: - testobj.near_zero = float(match["near_zero"]) - if "ignore_near_zero_errors" in match: - parsed_ignore_zero = match["ignore_near_zero_errors"] - if isinstance(parsed_ignore_zero, list): - testobj.ignore_near_zero_errors.update( - {field: True for field in match["ignore_near_zero_errors"]} - ) - elif isinstance(parsed_ignore_zero, dict): - for key in parsed_ignore_zero.keys(): - testobj.ignore_near_zero_errors[key] = {} - testobj.ignore_near_zero_errors[key]["near_zero"] = float( - parsed_ignore_zero[key] - ) - if "all_other_near_zero" in match: - for key in testobj.out_vars.keys(): - if key not in testobj.ignore_near_zero_errors: - testobj.ignore_near_zero_errors[key] = {} - testobj.ignore_near_zero_errors[key][ - "near_zero" - ] = float(match["all_other_near_zero"]) - - else: - raise TypeError( - "ignore_near_zero_errors is either a list or a dict" - ) - if "skip_test" in match: - testobj.skip_test = bool(match["skip_test"]) - elif len(matches) > 1: - raise Exception( - "misconfigured threshold overrides file, more than 1 specification for " - + test_name - + " with backend=" - + backend - + ", platform=" - + platform() - ) - - -N_THRESHOLD_SAMPLES = int(os.getenv("PACE_TEST_N_THRESHOLD_SAMPLES", 10)) - - -def get_thresholds(testobj, input_data): - _get_thresholds(testobj.compute, input_data) - - -def get_thresholds_parallel(testobj, input_data, communicator): - def compute(input): - return testobj.compute_parallel(input, communicator) - - _get_thresholds(compute, input_data) - - -def _get_thresholds(compute_function, input_data) -> None: - if N_THRESHOLD_SAMPLES <= 0: - return - output_list = [] - for _ in range(N_THRESHOLD_SAMPLES): - input = copy.deepcopy(input_data) - perturb(input) - output_list.append(compute_function(input)) - - output_varnames = output_list[0].keys() - for varname in output_varnames: - if output_list[0][varname].dtype in ( - np.float64, - np.int64, - np.float32, - np.int32, - ): - samples = [out[varname] for out in output_list] - pointwise_max_abs_errors = np.max(samples, axis=0) - np.min(samples, axis=0) - max_rel_diff = np.nanmax( - pointwise_max_abs_errors / np.min(np.abs(samples), axis=0) - ) - max_abs_diff = np.nanmax(pointwise_max_abs_errors) - print( - f"{varname}: max rel diff {max_rel_diff}, max abs diff {max_abs_diff}" - ) - - -@pytest.mark.sequential -@pytest.mark.skipif( - MPI is not None and MPI.COMM_WORLD.Get_size() > 1, - reason="Running in parallel with mpi", -) -def test_sequential_savepoint( - case: SavepointCase, - backend, - print_failures, - failure_stride, - subtests, - caplog, - threshold_overrides, - xy_indices=True, -): - if case.testobj is None: - pytest.xfail( - f"no translate object available for savepoint {case.savepoint_name}" - ) - stencil_config = pace.dsl.StencilConfig( - compilation_config=CompilationConfig(backend=backend), - dace_config=DaceConfig( - communicator=None, - backend=backend, - ), - ) - # Reduce error threshold for GPU - if stencil_config.is_gpu_backend: - case.testobj.max_error = max(case.testobj.max_error, GPU_MAX_ERR) - case.testobj.near_zero = max(case.testobj.near_zero, GPU_NEAR_ZERO) - if threshold_overrides is not None: - process_override( - threshold_overrides, case.testobj, case.savepoint_name, backend - ) - if case.testobj.skip_test: - return - input_data = dataset_to_dict(case.ds_in) - input_names = ( - case.testobj.serialnames(case.testobj.in_vars["data_vars"]) - + case.testobj.in_vars["parameters"] - ) - input_data = {name: input_data[name] for name in input_names} - original_input_data = copy.deepcopy(input_data) - # run python version of functionality - output = case.testobj.compute(input_data) - failing_names: List[str] = [] - passing_names: List[str] = [] - all_ref_data = dataset_to_dict(case.ds_out) - ref_data_out = {} - for varname in case.testobj.serialnames(case.testobj.out_vars): - ignore_near_zero = case.testobj.ignore_near_zero_errors.get(varname, False) - ref_data = all_ref_data[varname] - if hasattr(case.testobj, "subset_output"): - ref_data = case.testobj.subset_output(varname, ref_data) - with subtests.test(varname=varname): - failing_names.append(varname) - output_data = gt_utils.asarray(output[varname]) - assert success( - output_data, - ref_data, - case.testobj.max_error, - ignore_near_zero, - case.testobj.near_zero, - ), sample_wherefail( - output_data, - ref_data, - case.testobj.max_error, - print_failures, - failure_stride, - case.savepoint_name, - ignore_near_zero_errors=ignore_near_zero, - near_zero=case.testobj.near_zero, - xy_indices=xy_indices, - ) - passing_names.append(failing_names.pop()) - ref_data_out[varname] = [ref_data] - if len(failing_names) > 0: - get_thresholds(case.testobj, input_data=original_input_data) - os.makedirs(OUTDIR, exist_ok=True) - out_filename = os.path.join(OUTDIR, f"translate-{case.savepoint_name}.nc") - input_data_on_host = {} - for key, _input in input_data.items(): - input_data_on_host[key] = gt_utils.asarray(_input) - save_netcdf( - case.testobj, - [input_data_on_host], - [output], - ref_data_out, - failing_names, - out_filename, - ) - assert failing_names == [], f"only the following variables passed: {passing_names}" - assert len(passing_names) > 0, "No tests passed" - - -def state_from_savepoint(serializer, savepoint, name_to_std_name): - properties = pace.util.fortran_info.properties_by_std_name - origin = gt_utils.origin - state = {} - for name, std_name in name_to_std_name.items(): - array = serializer.read(name, savepoint) - extent = tuple(np.asarray(array.shape) - 2 * np.asarray(origin)) - state["air_temperature"] = pace.util.Quantity( - array, - dims=reversed(properties["air_temperature"]["dims"]), - units=properties["air_temperature"]["units"], - origin=origin, - extent=extent, - ) - return state - - -def get_communicator(comm, layout): - partitioner = pace.util.CubedSpherePartitioner(pace.util.TilePartitioner(layout)) - communicator = pace.util.CubedSphereCommunicator(comm, partitioner) - return communicator - - -def get_tile_communicator(comm, layout): - partitioner = pace.util.TilePartitioner(layout) - communicator = pace.util.TileCommunicator(comm, partitioner) - return communicator - - -@pytest.mark.parallel -@pytest.mark.skipif( - MPI is None or MPI.COMM_WORLD.Get_size() == 1, - reason="Not running in parallel with mpi", -) -def test_parallel_savepoint( - case: SavepointCase, - backend, - print_failures, - failure_stride, - subtests, - caplog, - threshold_overrides, - compute_grid, - xy_indices=True, -): - if MPI.COMM_WORLD.Get_size() % 6 != 0: - layout = ( - int(MPI.COMM_WORLD.Get_size() ** 0.5), - int(MPI.COMM_WORLD.Get_size() ** 0.5), - ) - communicator = get_tile_communicator(MPI.COMM_WORLD, layout) - else: - layout = ( - int((MPI.COMM_WORLD.Get_size() // 6) ** 0.5), - int((MPI.COMM_WORLD.Get_size() // 6) ** 0.5), - ) - communicator = get_communicator(MPI.COMM_WORLD, layout) - if case.testobj is None: - pytest.xfail( - f"no translate object available for savepoint {case.savepoint_name}" - ) - stencil_config = pace.dsl.StencilConfig( - compilation_config=CompilationConfig(backend=backend), - dace_config=DaceConfig( - communicator=communicator, - backend=backend, - ), - ) - # Increase minimum error threshold for GPU - if stencil_config.is_gpu_backend: - case.testobj.max_error = max(case.testobj.max_error, GPU_MAX_ERR) - case.testobj.near_zero = max(case.testobj.near_zero, GPU_NEAR_ZERO) - if threshold_overrides is not None: - process_override( - threshold_overrides, case.testobj, case.savepoint_name, backend - ) - if case.testobj.skip_test: - return - if compute_grid and not case.testobj.compute_grid_option: - pytest.xfail(f"compute_grid option not used for test {case.savepoint_name}") - input_data = dataset_to_dict(case.ds_in) - # run python version of functionality - output = case.testobj.compute_parallel(input_data, communicator) - out_vars = set(case.testobj.outputs.keys()) - out_vars.update(list(case.testobj._base.out_vars.keys())) - failing_names = [] - passing_names = [] - ref_data: Dict[str, Any] = {} - all_ref_data = dataset_to_dict(case.ds_out) - for varname in out_vars: - ref_data[varname] = [] - new_ref_data = all_ref_data[varname] - if hasattr(case.testobj, "subset_output"): - new_ref_data = case.testobj.subset_output(varname, new_ref_data) - ref_data[varname].append(new_ref_data) - ignore_near_zero = case.testobj.ignore_near_zero_errors.get(varname, False) - with subtests.test(varname=varname): - failing_names.append(varname) - output_data = gt_utils.asarray(output[varname]) - assert success( - output_data, - ref_data[varname][0], - case.testobj.max_error, - ignore_near_zero, - case.testobj.near_zero, - ), sample_wherefail( - output_data, - ref_data[varname][0], - case.testobj.max_error, - print_failures, - failure_stride, - case.savepoint_name, - ignore_near_zero, - case.testobj.near_zero, - xy_indices, - ) - passing_names.append(failing_names.pop()) - if len(failing_names) > 0: - os.makedirs(OUTDIR, exist_ok=True) - out_filename = os.path.join( - OUTDIR, f"translate-{case.savepoint_name}-{case.grid.rank}.nc" - ) - try: - input_data_on_host = {} - for key, _input in input_data.items(): - input_data_on_host[key] = gt_utils.asarray(_input) - save_netcdf( - case.testobj, - [input_data_on_host], - [output], - ref_data, - failing_names, - out_filename, - ) - except Exception as error: - print(f"TestParallel SaveNetCDF Error: {error}") - assert failing_names == [], f"only the following variables passed: {passing_names}" - assert len(passing_names) > 0, "No tests passed" - - -def save_netcdf( - testobj, - # first list over rank, second list over savepoint - inputs_list: List[Dict[str, List[np.ndarray]]], - output_list: List[Dict[str, List[np.ndarray]]], - ref_data: Dict[str, List[np.ndarray]], - failing_names, - out_filename, -): - import xarray as xr - - data_vars = {} - for i, varname in enumerate(failing_names): - if hasattr(testobj, "outputs"): - dims = [dim_name + f"_{i}" for dim_name in testobj.outputs[varname]["dims"]] - attrs = {"units": testobj.outputs[varname]["units"]} - else: - dims = [ - f"dim_{varname}_{j}" for j in range(len(ref_data[varname][0].shape)) - ] - attrs = {"units": "unknown"} - try: - data_vars[f"{varname}_in"] = xr.DataArray( - np.stack([in_data[varname] for in_data in inputs_list]), - dims=("rank",) + tuple([f"{d}_in" for d in dims]), - attrs=attrs, - ) - except KeyError as error: - print(f"No input data found for {error}") - data_vars[f"{varname}_ref"] = xr.DataArray( - np.stack(ref_data[varname]), - dims=("rank",) + tuple([f"{d}_out" for d in dims]), - attrs=attrs, - ) - data_vars[f"{varname}_out"] = xr.DataArray( - np.stack([output[varname] for output in output_list]), - dims=("rank",) + tuple([f"{d}_out" for d in dims]), - attrs=attrs, - ) - data_vars[f"{varname}_error"] = ( - data_vars[f"{varname}_ref"] - data_vars[f"{varname}_out"] - ) - data_vars[f"{varname}_error"].attrs = attrs - print(f"File saved to {out_filename}") - xr.Dataset(data_vars=data_vars).to_netcdf(out_filename) diff --git a/stencils/pace/stencils/testing/translate.py b/stencils/pace/stencils/testing/translate.py deleted file mode 100644 index ac807813b..000000000 --- a/stencils/pace/stencils/testing/translate.py +++ /dev/null @@ -1,420 +0,0 @@ -import logging -from typing import Any, Dict, List, Optional, Tuple, Union - -import numpy as np - -import pace.dsl.gt4py_utils as utils -import pace.util -from pace.dsl.stencil import StencilFactory -from pace.dsl.typing import Field # noqa: F401 -from pace.stencils.testing.grid import Grid # type: ignore - - -try: - import cupy as cp -except ImportError: - cp = None - -logger = logging.getLogger(__name__) - - -def read_serialized_data(serializer, savepoint, variable): - data = serializer.read(variable, savepoint) - if len(data.flatten()) == 1: - return data[0] - return data - - -def pad_field_in_j(field, nj: int, backend: str): - utils.device_sync(backend) - outfield = utils.tile(field[:, 0, :], (nj, 1, 1)).transpose(1, 0, 2) - return outfield - - -def as_numpy( - value: Union[Dict[str, Any], pace.util.Quantity, np.ndarray] -) -> Union[np.ndarray, Dict[str, np.ndarray]]: - def _convert(value: Union[pace.util.Quantity, np.ndarray]) -> np.ndarray: - if isinstance(value, pace.util.Quantity): - return value.data - elif cp is not None and isinstance(value, cp.ndarray): - return cp.asnumpy(value) - elif isinstance(value, np.ndarray): - return value - else: - raise TypeError(f"Unrecognized value type: {type(value)}") - - if isinstance(value, dict): - return {k: _convert(v) for k, v in value.items()} - else: - return _convert(value) - - -class TranslateFortranData2Py: - max_error = 1e-14 - near_zero = 1e-18 - - def __init__(self, grid, stencil_factory: StencilFactory, origin=utils.origin): - self.origin = origin - self.stencil_factory = stencil_factory - self.in_vars: Dict[str, Any] = {"data_vars": {}, "parameters": []} - self.out_vars: Dict[str, Any] = {} - self.write_vars: List = [] - self.grid = grid - self.maxshape: Tuple[int, ...] = grid.domain_shape_full(add=(1, 1, 1)) - self.ordered_input_vars = None - self.ignore_near_zero_errors: Dict[str, Any] = {} - self.skip_test: bool = False - - def setup(self, inputs): - self.make_storage_data_input_vars(inputs) - - def compute_func(self, **inputs): - raise NotImplementedError("Implement a child class compute method") - - def compute(self, inputs): - self.setup(inputs) - return self.slice_output(self.compute_from_storage(inputs)) - - # assume inputs already has been turned into gt4py storages (or Quantities) - def compute_from_storage(self, inputs): - outputs = self.compute_func(**inputs) - if outputs is not None: - inputs.update(outputs) - return inputs - - def column_split_compute(self, inputs, info_mapping): - column_info = {} - for pyfunc_var, serialbox_var in info_mapping.items(): - column_info[pyfunc_var] = self.column_namelist_vals(serialbox_var, inputs) - self.make_storage_data_input_vars(inputs) - for k in info_mapping.values(): - del inputs[k] - kstarts = utils.get_kstarts(column_info, self.grid.npz) - utils.k_split_run(self.compute_func, inputs, kstarts, column_info) - return self.slice_output(inputs) - - def make_storage_data( - self, - array: np.ndarray, - istart: int = 0, - jstart: int = 0, - kstart: int = 0, - dummy_axes: Optional[Tuple[int, int, int]] = None, - axis: int = 2, - names_4d: Optional[List[str]] = None, - read_only: bool = False, - full_shape: bool = False, - ) -> Dict[str, "Field"]: - use_shape = list(self.maxshape) - if dummy_axes: - for axis in dummy_axes: - use_shape[axis] = 1 - elif not full_shape and len(array.shape) < 3 and axis == len(array.shape) - 1: - use_shape[1] = 1 - start = (int(istart), int(jstart), int(kstart)) - if names_4d: - return utils.make_storage_dict( - array, - tuple(use_shape), - start=start, - origin=start, - dummy=dummy_axes, - axis=axis, - names=names_4d, - backend=self.stencil_factory.backend, - ) - else: - return utils.make_storage_data( - array, - tuple(use_shape), - start=start, - origin=start, - dummy=dummy_axes, - axis=axis, - read_only=read_only, - backend=self.stencil_factory.backend, - ) - - def storage_vars(self): - return self.in_vars["data_vars"] - - def get_index_from_info(self, varinfo, index_name, initial_index): - index = initial_index - if index_name in varinfo: - index = varinfo[index_name] - return index - - def update_info(self, info, inputs): - for k, v in info.items(): - if k == "serialname" or isinstance(v, list): - continue - if v in inputs.keys(): - info[k] = inputs[v] - - def collect_start_indices(self, datashape, varinfo): - istart, jstart = self.grid.horizontal_starts_from_shape(datashape) - istart = self.get_index_from_info(varinfo, "istart", istart) - jstart = self.get_index_from_info(varinfo, "jstart", jstart) - kstart = self.get_index_from_info(varinfo, "kstart", 0) - return istart, jstart, kstart - - def make_storage_data_input_vars(self, inputs, storage_vars=None): - inputs_in = {**inputs} - inputs_out = {} - if storage_vars is None: - storage_vars = self.storage_vars() - for p in self.in_vars["parameters"]: - if type(inputs_in[p]) in [np.int64, np.int32]: - inputs_out[p] = int(inputs_in[p]) - else: - inputs_out[p] = inputs_in[p] - for d, info in storage_vars.items(): - serialname = info["serialname"] if "serialname" in info else d - self.update_info(info, inputs_in) - if "kaxis" in info: - inputs_in[serialname] = np.moveaxis( - inputs_in[serialname], info["kaxis"], 2 - ) - else: - inputs_in[serialname] = inputs_in[serialname] - istart, jstart, kstart = self.collect_start_indices( - inputs_in[serialname].shape, info - ) - - names_4d = None - if len(inputs_in[serialname].shape) == 4: - names_4d = info.get("names_4d", utils.tracer_variables) - - dummy_axes = info.get("dummy_axes", None) - axis = info.get("axis", 2) - inputs_out[d] = self.make_storage_data( - np.squeeze(inputs_in[serialname]), - istart=istart, - jstart=jstart, - kstart=kstart, - dummy_axes=dummy_axes, - axis=axis, - names_4d=names_4d, - read_only=d not in self.write_vars, - full_shape="full_shape" in storage_vars[d], - ) - # update the input in-place because that's how it was originally written - # feel free to refactor - inputs.clear() - inputs.update(inputs_out) - - def slice_output(self, inputs, out_data=None): - utils.device_sync(backend=self.stencil_factory.backend) - if out_data is None: - out_data = inputs - else: - out_data.update(inputs) - out = {} - for var in self.out_vars.keys(): - info = self.out_vars[var] - self.update_info(info, inputs) - serialname = info["serialname"] if "serialname" in info else var - ds = self.grid.default_domain_dict() - ds.update(info) - data_result = as_numpy(out_data[var]) - if isinstance(data_result, dict): - names_4d = info.get("names_4d", utils.tracer_variables) - var4d = np.zeros( - ( - ds["iend"] - ds["istart"] + 1, - ds["jend"] - ds["jstart"] + 1, - ds["kend"] - ds["kstart"] + 1, - len(data_result), - ) - ) - for varname, data_element in data_result.items(): - index = names_4d.index(varname) - var4d[:, :, :, index] = np.squeeze( - np.asarray(data_element)[self.grid.slice_dict(ds)] - ) - out[serialname] = var4d - else: - slice_tuple = self.grid.slice_dict(ds, len(data_result.shape)) - out[serialname] = np.squeeze(data_result[slice_tuple]) - if "kaxis" in info: - out[serialname] = np.moveaxis(out[serialname], 2, info["kaxis"]) - return out - - def serialnames(self, dict): - return [ - info["serialname"] if "serialname" in info else d - for d, info in dict.items() - ] - - def column_namelist_vals(self, varname, inputs): - info = self.in_vars["data_vars"][varname] - name = info["serialname"] if "serialname" in info else varname - if len(inputs[name].shape) == 1: - return inputs[name] - return [i for i in inputs[name][0, 0, :]] - - -class TranslateGrid: - fpy_model_index_offset = 2 - fpy_index_offset = -1 - composite_grid_vars = ["sin_sg", "cos_sg"] - vvars = ["vlon", "vlat"] - edge_var_axis = { - "edge_w": 1, - "edge_e": 1, - "edge_s": 0, - "edge_n": 0, - } - edge_vect_axis = { - "edge_vect_w": 1, - "edge_vect_e": 1, - "edge_vect_s": 0, - "edge_vect_n": 0, - } - ee_vars = ["ee1", "ee2", "ew1", "ew2", "es1", "es2"] - edge_vect_axis = { - "edge_vect_s": 0, - "edge_vect_n": 0, - "edge_vect_w": 1, - "edge_vect_e": 1, - } - # Super (composite) grid - # 9---4---8 - # | | - # 1 5 3 - # | | - # 6---2---7 - - @classmethod - def new_from_serialized_data(cls, serializer, rank, layout, backend): - grid_savepoint = serializer.get_savepoint("Grid-Info")[0] - grid_data = {} - grid_fields = serializer.fields_at_savepoint(grid_savepoint) - for field in grid_fields: - grid_data[field] = read_serialized_data(serializer, grid_savepoint, field) - return cls(grid_data, rank, layout, backend=backend) - - def __init__(self, inputs, rank, layout, *, backend: str): - self.backend = backend - self.indices = {} - self.shape_params = {} - self.data = {} - for s in Grid.shape_params: - self.shape_params[s] = inputs[s] - del inputs[s] - self.rank = rank - self.layout = layout - for i, j in Grid.index_pairs: - for index in [i, j]: - self.indices[index] = inputs[index] + self.fpy_model_index_offset - del inputs[index] - - self.data = inputs - - def _make_composite_var_storage(self, varname, data3d, shape, count): - - for s in range(count): - self.data[varname + str(s + 1)] = utils.make_storage_data( - np.squeeze(data3d[:, :, s]), - shape, - origin=(0, 0, 0), - backend=self.backend, - ) - - def _edge_vector_storage(self, varname, axis, max_shape): - default_origin = (0, 0, 0) - mask = None - if axis == 1: - buffer = np.zeros(max_shape[1]) - buffer[: self.data[varname].shape[0]] = self.data[varname] - default_origin = (0, 0) - buffer = buffer[np.newaxis, ...] - buffer = np.repeat(buffer, max_shape[0], axis=0) - if axis == 0: - buffer = np.zeros(max_shape[0]) - buffer[: self.data[varname].shape[0]] = self.data[varname] - default_origin = (0,) - mask = (True, False, False) - self.data[varname] = utils.make_storage_data( - data=buffer, - origin=default_origin, - shape=buffer.shape, - backend=self.backend, - mask=mask, - ) - - def _make_composite_vvar_storage(self, varname, data3d, shape): - """This function is needed to transform vlat, vlon""" - - size1, size2 = data3d.shape[0:2] - buffer = np.zeros((shape[0], shape[1], 3)) - buffer[1 : 1 + size1, 1 : 1 + size2, :] = data3d - self.data[varname] = utils.make_storage_data( - data=buffer, - shape=buffer.shape, - origin=(1, 1, 0), - backend=self.backend, - ) - - def make_grid_storage(self, pygrid): - shape = pygrid.domain_shape_full(add=(1, 1, 1)) - for key in TranslateGrid.composite_grid_vars: - if key in self.data: - self._make_composite_var_storage(key, self.data[key], shape, 9) - del self.data[key] - - for key in TranslateGrid.vvars: - if key in self.data: - self._make_composite_vvar_storage(key, self.data[key], shape) - - for key in TranslateGrid.ee_vars: - if key in self.data: - self.data[key] = np.moveaxis(self.data[key], 0, 2) - self.data[key] = utils.make_storage_data( - self.data[key], - (shape[0], shape[1], 3), - origin=(0, 0, 0), - backend=self.backend, - ) - for key, axis in TranslateGrid.edge_var_axis.items(): - if key in self.data: - self.data[key] = utils.make_storage_data( - self.data[key], - shape, - start=(0, 0, pygrid.halo), - axis=axis, - read_only=True, - backend=self.backend, - ) - for key, axis in TranslateGrid.edge_vect_axis.items(): - if key in self.data: - self._edge_vector_storage(key, axis, shape) - - for key, value in self.data.items(): - if type(value) is np.ndarray and len(value.shape) > 0: - # TODO: when grid initialization model exists, may want to use - # it to inform this - istart, jstart = pygrid.horizontal_starts_from_shape(value.shape) - logger.debug( - "Storage for Grid variable {}, {}, {}, {}".format( - key, istart, jstart, value.shape - ) - ) - origin = (istart, jstart, 0) - self.data[key] = utils.make_storage_data( - value, - shape, - origin=origin, - start=origin, - read_only=True, - backend=self.backend, - ) - - def python_grid(self): - pygrid = Grid( - self.indices, self.shape_params, self.rank, self.layout, self.backend - ) - self.make_grid_storage(pygrid) - pygrid.add_data(self.data) - return pygrid diff --git a/stencils/setup.py b/stencils/setup.py deleted file mode 100644 index 539b3c18a..000000000 --- a/stencils/setup.py +++ /dev/null @@ -1,36 +0,0 @@ -from typing import List - -from setuptools import find_namespace_packages, setup - - -setup_requirements: List[str] = [] - -requirements = ["gt4py", "pace-util", "pace-dsl"] - -test_requirements: List[str] = [] - - -setup( - author="Allen Institute for AI", - author_email="elynnw@allenai.org", - python_requires=">=3.8", - classifiers=[ - "Development Status :: 2 - Pre-Alpha", - "Intended Audience :: Developers", - "License :: OSI Approved :: BSD License", - "Natural Language :: English", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - ], - install_requires=requirements, - setup_requires=setup_requirements, - tests_require=test_requirements, - name="pace-stencils", - license="BSD license", - packages=find_namespace_packages(include=["pace.*"]), - include_package_data=True, - url="https://github.com/ai2cm/pace", - version="0.2.0", - zip_safe=False, -) diff --git a/util/tests/data/c12_restart/coupler.res b/tests/main/data/c12_restart/coupler.res similarity index 100% rename from util/tests/data/c12_restart/coupler.res rename to tests/main/data/c12_restart/coupler.res diff --git a/util/tests/data/c12_restart/fv_core.res.nc b/tests/main/data/c12_restart/fv_core.res.nc similarity index 100% rename from util/tests/data/c12_restart/fv_core.res.nc rename to tests/main/data/c12_restart/fv_core.res.nc diff --git a/util/tests/data/c12_restart/fv_core.res.tile1.nc b/tests/main/data/c12_restart/fv_core.res.tile1.nc similarity index 100% rename from util/tests/data/c12_restart/fv_core.res.tile1.nc rename to tests/main/data/c12_restart/fv_core.res.tile1.nc diff --git a/util/tests/data/c12_restart/fv_core.res.tile2.nc b/tests/main/data/c12_restart/fv_core.res.tile2.nc similarity index 100% rename from util/tests/data/c12_restart/fv_core.res.tile2.nc rename to tests/main/data/c12_restart/fv_core.res.tile2.nc diff --git a/util/tests/data/c12_restart/fv_core.res.tile3.nc b/tests/main/data/c12_restart/fv_core.res.tile3.nc similarity index 100% rename from util/tests/data/c12_restart/fv_core.res.tile3.nc rename to tests/main/data/c12_restart/fv_core.res.tile3.nc diff --git a/util/tests/data/c12_restart/fv_core.res.tile4.nc b/tests/main/data/c12_restart/fv_core.res.tile4.nc similarity index 100% rename from util/tests/data/c12_restart/fv_core.res.tile4.nc rename to tests/main/data/c12_restart/fv_core.res.tile4.nc diff --git a/util/tests/data/c12_restart/fv_core.res.tile5.nc b/tests/main/data/c12_restart/fv_core.res.tile5.nc similarity index 100% rename from util/tests/data/c12_restart/fv_core.res.tile5.nc rename to tests/main/data/c12_restart/fv_core.res.tile5.nc diff --git a/util/tests/data/c12_restart/fv_core.res.tile6.nc b/tests/main/data/c12_restart/fv_core.res.tile6.nc similarity index 100% rename from util/tests/data/c12_restart/fv_core.res.tile6.nc rename to tests/main/data/c12_restart/fv_core.res.tile6.nc diff --git a/util/tests/data/c12_restart/fv_srf_wnd.res.tile1.nc b/tests/main/data/c12_restart/fv_srf_wnd.res.tile1.nc similarity index 100% rename from util/tests/data/c12_restart/fv_srf_wnd.res.tile1.nc rename to tests/main/data/c12_restart/fv_srf_wnd.res.tile1.nc diff --git a/util/tests/data/c12_restart/fv_srf_wnd.res.tile2.nc b/tests/main/data/c12_restart/fv_srf_wnd.res.tile2.nc similarity index 100% rename from util/tests/data/c12_restart/fv_srf_wnd.res.tile2.nc rename to tests/main/data/c12_restart/fv_srf_wnd.res.tile2.nc diff --git a/util/tests/data/c12_restart/fv_srf_wnd.res.tile3.nc b/tests/main/data/c12_restart/fv_srf_wnd.res.tile3.nc similarity index 100% rename from util/tests/data/c12_restart/fv_srf_wnd.res.tile3.nc rename to tests/main/data/c12_restart/fv_srf_wnd.res.tile3.nc diff --git a/util/tests/data/c12_restart/fv_srf_wnd.res.tile4.nc b/tests/main/data/c12_restart/fv_srf_wnd.res.tile4.nc similarity index 100% rename from util/tests/data/c12_restart/fv_srf_wnd.res.tile4.nc rename to tests/main/data/c12_restart/fv_srf_wnd.res.tile4.nc diff --git a/util/tests/data/c12_restart/fv_srf_wnd.res.tile5.nc b/tests/main/data/c12_restart/fv_srf_wnd.res.tile5.nc similarity index 100% rename from util/tests/data/c12_restart/fv_srf_wnd.res.tile5.nc rename to tests/main/data/c12_restart/fv_srf_wnd.res.tile5.nc diff --git a/util/tests/data/c12_restart/fv_srf_wnd.res.tile6.nc b/tests/main/data/c12_restart/fv_srf_wnd.res.tile6.nc similarity index 100% rename from util/tests/data/c12_restart/fv_srf_wnd.res.tile6.nc rename to tests/main/data/c12_restart/fv_srf_wnd.res.tile6.nc diff --git a/util/tests/data/c12_restart/fv_tracer.res.tile1.nc b/tests/main/data/c12_restart/fv_tracer.res.tile1.nc similarity index 100% rename from util/tests/data/c12_restart/fv_tracer.res.tile1.nc rename to tests/main/data/c12_restart/fv_tracer.res.tile1.nc diff --git a/util/tests/data/c12_restart/fv_tracer.res.tile2.nc b/tests/main/data/c12_restart/fv_tracer.res.tile2.nc similarity index 100% rename from util/tests/data/c12_restart/fv_tracer.res.tile2.nc rename to tests/main/data/c12_restart/fv_tracer.res.tile2.nc diff --git a/util/tests/data/c12_restart/fv_tracer.res.tile3.nc b/tests/main/data/c12_restart/fv_tracer.res.tile3.nc similarity index 100% rename from util/tests/data/c12_restart/fv_tracer.res.tile3.nc rename to tests/main/data/c12_restart/fv_tracer.res.tile3.nc diff --git a/util/tests/data/c12_restart/fv_tracer.res.tile4.nc b/tests/main/data/c12_restart/fv_tracer.res.tile4.nc similarity index 100% rename from util/tests/data/c12_restart/fv_tracer.res.tile4.nc rename to tests/main/data/c12_restart/fv_tracer.res.tile4.nc diff --git a/util/tests/data/c12_restart/fv_tracer.res.tile5.nc b/tests/main/data/c12_restart/fv_tracer.res.tile5.nc similarity index 100% rename from util/tests/data/c12_restart/fv_tracer.res.tile5.nc rename to tests/main/data/c12_restart/fv_tracer.res.tile5.nc diff --git a/util/tests/data/c12_restart/fv_tracer.res.tile6.nc b/tests/main/data/c12_restart/fv_tracer.res.tile6.nc similarity index 100% rename from util/tests/data/c12_restart/fv_tracer.res.tile6.nc rename to tests/main/data/c12_restart/fv_tracer.res.tile6.nc diff --git a/util/tests/data/c12_restart/phy_data.tile1.nc b/tests/main/data/c12_restart/phy_data.tile1.nc similarity index 100% rename from util/tests/data/c12_restart/phy_data.tile1.nc rename to tests/main/data/c12_restart/phy_data.tile1.nc diff --git a/util/tests/data/c12_restart/phy_data.tile2.nc b/tests/main/data/c12_restart/phy_data.tile2.nc similarity index 100% rename from util/tests/data/c12_restart/phy_data.tile2.nc rename to tests/main/data/c12_restart/phy_data.tile2.nc diff --git a/util/tests/data/c12_restart/phy_data.tile3.nc b/tests/main/data/c12_restart/phy_data.tile3.nc similarity index 100% rename from util/tests/data/c12_restart/phy_data.tile3.nc rename to tests/main/data/c12_restart/phy_data.tile3.nc diff --git a/util/tests/data/c12_restart/phy_data.tile4.nc b/tests/main/data/c12_restart/phy_data.tile4.nc similarity index 100% rename from util/tests/data/c12_restart/phy_data.tile4.nc rename to tests/main/data/c12_restart/phy_data.tile4.nc diff --git a/util/tests/data/c12_restart/phy_data.tile5.nc b/tests/main/data/c12_restart/phy_data.tile5.nc similarity index 100% rename from util/tests/data/c12_restart/phy_data.tile5.nc rename to tests/main/data/c12_restart/phy_data.tile5.nc diff --git a/util/tests/data/c12_restart/phy_data.tile6.nc b/tests/main/data/c12_restart/phy_data.tile6.nc similarity index 100% rename from util/tests/data/c12_restart/phy_data.tile6.nc rename to tests/main/data/c12_restart/phy_data.tile6.nc diff --git a/util/tests/data/c12_restart/sfc_data.tile1.nc b/tests/main/data/c12_restart/sfc_data.tile1.nc similarity index 100% rename from util/tests/data/c12_restart/sfc_data.tile1.nc rename to tests/main/data/c12_restart/sfc_data.tile1.nc diff --git a/util/tests/data/c12_restart/sfc_data.tile2.nc b/tests/main/data/c12_restart/sfc_data.tile2.nc similarity index 100% rename from util/tests/data/c12_restart/sfc_data.tile2.nc rename to tests/main/data/c12_restart/sfc_data.tile2.nc diff --git a/util/tests/data/c12_restart/sfc_data.tile3.nc b/tests/main/data/c12_restart/sfc_data.tile3.nc similarity index 100% rename from util/tests/data/c12_restart/sfc_data.tile3.nc rename to tests/main/data/c12_restart/sfc_data.tile3.nc diff --git a/util/tests/data/c12_restart/sfc_data.tile4.nc b/tests/main/data/c12_restart/sfc_data.tile4.nc similarity index 100% rename from util/tests/data/c12_restart/sfc_data.tile4.nc rename to tests/main/data/c12_restart/sfc_data.tile4.nc diff --git a/util/tests/data/c12_restart/sfc_data.tile5.nc b/tests/main/data/c12_restart/sfc_data.tile5.nc similarity index 100% rename from util/tests/data/c12_restart/sfc_data.tile5.nc rename to tests/main/data/c12_restart/sfc_data.tile5.nc diff --git a/util/tests/data/c12_restart/sfc_data.tile6.nc b/tests/main/data/c12_restart/sfc_data.tile6.nc similarity index 100% rename from util/tests/data/c12_restart/sfc_data.tile6.nc rename to tests/main/data/c12_restart/sfc_data.tile6.nc diff --git a/tests/main/driver/test_diagnostics.py b/tests/main/driver/test_diagnostics.py index d332f1684..eeccab4a4 100644 --- a/tests/main/driver/test_diagnostics.py +++ b/tests/main/driver/test_diagnostics.py @@ -4,7 +4,6 @@ import yaml import pace.driver -import pace.dsl from pace.driver.run import main diff --git a/tests/main/driver/test_diagnostics_config.py b/tests/main/driver/test_diagnostics_config.py index f22c9179f..0355c30e4 100644 --- a/tests/main/driver/test_diagnostics_config.py +++ b/tests/main/driver/test_diagnostics_config.py @@ -1,6 +1,8 @@ import unittest.mock import pytest +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer import pace.driver import pace.driver.diagnostics @@ -41,10 +43,8 @@ def test_zselect_raises_error_if_not_3d(tmpdir): z_select=[pace.driver.diagnostics.ZSelect(level=0, names=["phis"])], ) result = config.diagnostics_factory(unittest.mock.MagicMock()) - quantity_factory = pace.util.QuantityFactory.from_backend( - sizer=pace.util.SubtileGridSizer( - nx=12, ny=12, nz=79, n_halo=3, extra_dim_lengths={} - ), + quantity_factory = QuantityFactory.from_backend( + sizer=SubtileGridSizer(nx=12, ny=12, nz=79, n_halo=3, extra_dim_lengths={}), backend="numpy", ) state = DycoreState.init_zeros(quantity_factory) @@ -58,10 +58,8 @@ def test_zselect_raises_error_if_3rd_dim_not_z(tmpdir): z_select=[pace.driver.diagnostics.ZSelect(level=0, names=["foo"])], ) result = config.diagnostics_factory(unittest.mock.MagicMock()) - quantity_factory = pace.util.QuantityFactory.from_backend( - sizer=pace.util.SubtileGridSizer( - nx=12, ny=12, nz=79, n_halo=3, extra_dim_lengths={} - ), + quantity_factory = QuantityFactory.from_backend( + sizer=SubtileGridSizer(nx=12, ny=12, nz=79, n_halo=3, extra_dim_lengths={}), backend="numpy", ) state = DycoreState.init_zeros(quantity_factory) diff --git a/tests/main/driver/test_driver.py b/tests/main/driver/test_driver.py index ad292e16f..57c906572 100644 --- a/tests/main/driver/test_driver.py +++ b/tests/main/driver/test_driver.py @@ -3,17 +3,16 @@ from typing import Literal, Tuple import pytest - -import pace.driver -import pace.dsl -from pace.driver import CreatesCommSelector, DriverConfig, NullCommConfig -from pace.driver.performance.report import ( +from ndsl.comm.null_comm import NullComm +from ndsl.dsl.stencil import StencilConfig +from ndsl.performance.report import ( TimeReport, gather_hit_counts, gather_timing_data, get_sypd, ) -from pace.util.null_comm import NullComm + +from pace.driver import CreatesCommSelector, DriverConfig, NullCommConfig def get_driver_config( @@ -35,7 +34,7 @@ def get_driver_config( else: initialization_config.start_time = datetime(2000, 1, 1) return DriverConfig( - stencil_config=pace.dsl.StencilConfig(), + stencil_config=StencilConfig(), nx_tile=nx_tile, nz=nz, dt_atmos=dt_atmos, diff --git a/tests/main/driver/test_restart_fortran.py b/tests/main/driver/test_restart_fortran.py index 518ceed10..52670c483 100644 --- a/tests/main/driver/test_restart_fortran.py +++ b/tests/main/driver/test_restart_fortran.py @@ -2,18 +2,16 @@ import numpy as np import xarray as xr +from ndsl.comm.communicator import CubedSphereCommunicator +from ndsl.comm.local_comm import LocalComm +from ndsl.comm.null_comm import NullComm +from ndsl.comm.partitioner import CubedSpherePartitioner, TilePartitioner +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer import pace.driver -import pace.util from pace.driver.initialization import FortranRestartInit from pace.physics import PHYSICS_PACKAGES -from pace.util import ( - CubedSphereCommunicator, - CubedSpherePartitioner, - QuantityFactory, - SubtileGridSizer, - TilePartitioner, -) DIR = os.path.dirname(os.path.abspath(__file__)) @@ -25,8 +23,8 @@ def test_state_from_fortran_restart(): partitioner = CubedSpherePartitioner(TilePartitioner(layout)) # need a local communicator to mock "scatter" for the restart data, # but need null communicator to handle grid initialization - local_comm = pace.util.LocalComm(rank=0, total_ranks=6, buffer_dict={}) - null_comm = pace.util.NullComm(rank=0, total_ranks=6) + local_comm = LocalComm(rank=0, total_ranks=6, buffer_dict={}) + null_comm = NullComm(rank=0, total_ranks=6) local_communicator = CubedSphereCommunicator(local_comm, partitioner) null_communicator = CubedSphereCommunicator(null_comm, partitioner) @@ -42,7 +40,7 @@ def test_state_from_fortran_restart(): ) quantity_factory = QuantityFactory.from_backend(sizer=sizer, backend="numpy") - restart_dir = os.path.join(PACE_DIR, "util/tests/data/c12_restart") + restart_dir = os.path.join(PACE_DIR, "tests/main/data/c12_restart") ( damping_coefficients, diff --git a/tests/main/driver/test_restart_serial.py b/tests/main/driver/test_restart_serial.py index 4c4542f51..1e36cde08 100644 --- a/tests/main/driver/test_restart_serial.py +++ b/tests/main/driver/test_restart_serial.py @@ -5,13 +5,18 @@ import numpy as np import xarray as xr import yaml - -import pace.dsl +from ndsl.comm.communicator import CubedSphereCommunicator +from ndsl.comm.null_comm import NullComm +from ndsl.comm.partitioner import CubedSpherePartitioner, TilePartitioner +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from ndsl.quantity import Quantity + +import pace.driver from pace.driver import CreatesComm, DriverConfig from pace.driver.driver import RestartConfig from pace.driver.initialization import AnalyticInit from pace.physics import PHYSICS_PACKAGES -from pace.util.null_comm import NullComm DIR = os.path.dirname(os.path.abspath(__file__)) @@ -49,11 +54,9 @@ def test_restart_save_to_disk(): driver_config = DriverConfig.from_dict(yaml.safe_load(f)) backend = "numpy" mpi_comm = NullComm(rank=0, total_ranks=6, fill_value=0.0) - partitioner = pace.util.CubedSpherePartitioner( - pace.util.TilePartitioner((1, 1)) - ) - communicator = pace.util.CubedSphereCommunicator(mpi_comm, partitioner) - sizer = pace.util.SubtileGridSizer.from_tile_params( + partitioner = CubedSpherePartitioner(TilePartitioner((1, 1))) + communicator = CubedSphereCommunicator(mpi_comm, partitioner) + sizer = SubtileGridSizer.from_tile_params( nx_tile=12, ny_tile=12, nz=79, @@ -63,9 +66,7 @@ def test_restart_save_to_disk(): tile_partitioner=partitioner.tile, tile_rank=communicator.tile.rank, ) - quantity_factory = pace.util.QuantityFactory.from_backend( - sizer=sizer, backend=backend - ) + quantity_factory = QuantityFactory.from_backend(sizer=sizer, backend=backend) eta_file = driver_config.grid_config.config.eta_file ( @@ -98,7 +99,7 @@ def test_restart_save_to_disk(): f"RESTART/restart_dycore_state_{mpi_comm.rank}.nc" ) for var in driver_state.dycore_state.__dict__.keys(): - if isinstance(driver_state.dycore_state.__dict__[var], pace.util.Quantity): + if isinstance(driver_state.dycore_state.__dict__[var], Quantity): np.testing.assert_allclose( driver_state.dycore_state.__dict__[var].data, restart_dycore[var].values, @@ -151,7 +152,7 @@ def test_restart_save_to_disk(): for var in driver_state.dycore_state.__dict__.keys(): before_restart = driver_state.dycore_state.__dict__[var] after_restart = restart_state.dycore_state.__dict__[var] - if isinstance(before_restart, pace.util.Quantity): + if isinstance(before_restart, Quantity): np.testing.assert_allclose( before_restart.view[:], after_restart.view[:], diff --git a/tests/main/driver/test_safety_checks.py b/tests/main/driver/test_safety_checks.py index c42fd0c44..ef7e733c5 100644 --- a/tests/main/driver/test_safety_checks.py +++ b/tests/main/driver/test_safety_checks.py @@ -2,9 +2,9 @@ import numpy as np import pytest +from ndsl.quantity import Quantity from pace.driver.safety_checks import SafetyChecker -from pace.util import Quantity def test_register_variable(): diff --git a/tests/main/dsl/test_caches.py b/tests/main/dsl/test_caches.py deleted file mode 100644 index c1f01303e..000000000 --- a/tests/main/dsl/test_caches.py +++ /dev/null @@ -1,176 +0,0 @@ -import pytest -from gt4py.cartesian.gtscript import PARALLEL, Field, computation, interval -from gt4py.storage import empty, ones - -import pace.dsl -from pace.dsl.dace import orchestrate -from pace.dsl.dace.dace_config import DaceConfig, DaCeOrchestration -from pace.dsl.stencil import CompilationConfig, GridIndexing - - -def _make_storage( - func, - grid_indexing, - stencil_config: pace.dsl.StencilConfig, - *, - dtype=float, - aligned_index=(0, 0, 0), -): - return func( - backend=stencil_config.compilation_config.backend, - shape=grid_indexing.domain, - dtype=dtype, - aligned_index=aligned_index, - ) - - -def _stencil(inp: Field[float], out: Field[float], scalar: float): - with computation(PARALLEL), interval(...): - out = inp - - -def _build_stencil(backend, orchestrated: DaCeOrchestration): - # Make stencil and verify it ran - grid_indexing = GridIndexing( - domain=(5, 5, 5), - n_halo=2, - south_edge=True, - north_edge=True, - west_edge=True, - east_edge=True, - ) - - stencil_config = pace.dsl.StencilConfig( - compilation_config=CompilationConfig(backend=backend, rebuild=True), - dace_config=DaceConfig(None, backend, 5, 5, orchestrated), - ) - - stencil_factory = pace.dsl.StencilFactory(stencil_config, grid_indexing) - - built_stencil = stencil_factory.from_origin_domain( - _stencil, (0, 0, 0), domain=grid_indexing.domain - ) - - return built_stencil, grid_indexing, stencil_config - - -class OrchestratedProgam: - def __init__(self, backend, orchestration): - self.stencil, grid_indexing, stencil_config = _build_stencil( - backend, orchestration - ) - orchestrate(obj=self, config=stencil_config.dace_config) - self.inp = _make_storage(ones, grid_indexing, stencil_config, dtype=float) - self.out = _make_storage(empty, grid_indexing, stencil_config, dtype=float) - - def __call__(self): - self.stencil(self.inp, self.out, self.inp[0, 0, 0]) - - -@pytest.mark.parametrize( - "backend", - [ - pytest.param("dace:cpu"), - ], -) -def test_relocatability_orchestration(backend): - import os - import shutil - - from gt4py.cartesian import config as gt_config - - original_root_directory = gt_config.cache_settings["root_path"] - working_dir = str(os.getcwd()) - - # Compile on default - p0 = OrchestratedProgam(backend, DaCeOrchestration.BuildAndRun) - p0() - assert os.path.exists( - f"{working_dir}/.gt_cache_FV3_A/dacecache/" - "test_caches_OrchestratedProgam___call__", - ) or os.path.exists( - f"{working_dir}/.gt_cache_FV3_A/dacecache/OrchestratedProgam___call__", - ) - - # Compile in another directory - - custom_path = f"{working_dir}/.my_cache_path" - gt_config.cache_settings["root_path"] = custom_path - p1 = OrchestratedProgam(backend, DaCeOrchestration.BuildAndRun) - p1() - assert os.path.exists( - f"{custom_path}/.gt_cache_FV3_A/dacecache/" - "test_caches_OrchestratedProgam___call__", - ) or os.path.exists( - f"{working_dir}/.gt_cache_FV3_A/dacecache/OrchestratedProgam___call__", - ) - - # Check relocability by copying the second cache directory, - # changing the path of gt_config.cache_settings and trying to Run on it - relocated_path = f"{working_dir}/.my_relocated_cache_path" - shutil.copytree(custom_path, relocated_path, dirs_exist_ok=True) - gt_config.cache_settings["root_path"] = relocated_path - p2 = OrchestratedProgam(backend, DaCeOrchestration.Run) - p2() - - # Generate a file exists error to check for bad path - bogus_path = "./nope/notatall/nothappening" - gt_config.cache_settings["root_path"] = bogus_path - with pytest.raises(RuntimeError): - OrchestratedProgam(backend, DaCeOrchestration.Run) - - # Restore cache settings - gt_config.cache_settings["root_path"] = original_root_directory - - -@pytest.mark.parametrize( - "backend", - [ - pytest.param("dace:cpu"), - ], -) -def test_relocatability(backend: str): - import os - import shutil - - import gt4py - from gt4py.cartesian import config as gt_config - - from pace.util.mpi import MPI - - # Restore original dir name - gt4py.cartesian.config.cache_settings["dir_name"] = os.environ.get( - "GT_CACHE_DIR_NAME", f".gt_cache_{MPI.COMM_WORLD.Get_rank():06}" - ) - - backend_sanitized = backend.replace(":", "") - - # Compile on default - p0 = OrchestratedProgam(backend, DaCeOrchestration.Python) - p0() - assert os.path.exists( - f"./.gt_cache_000000/py38_1013/{backend_sanitized}/test_caches/_stencil/" - ) - - # Compile in another directory - - custom_path = "./.my_cache_path" - gt_config.cache_settings["root_path"] = custom_path - p1 = OrchestratedProgam(backend, DaCeOrchestration.Python) - p1() - assert os.path.exists( - f"{custom_path}/.gt_cache_000000/py38_1013/{backend_sanitized}" - "/test_caches/_stencil/" - ) - - # Check relocability by copying the second cache directory, - # changing the path of gt_config.cache_settings and trying to Run on it - relocated_path = "./.my_relocated_cache_path" - shutil.copytree("./.gt_cache_000000", relocated_path, dirs_exist_ok=True) - gt_config.cache_settings["root_path"] = relocated_path - p2 = OrchestratedProgam(backend, DaCeOrchestration.Python) - p2() - assert os.path.exists( - f"{relocated_path}/.gt_cache_000000/py38_1013/{backend_sanitized}" - "/test_caches/_stencil/" - ) diff --git a/tests/main/dsl/test_compilation_config.py b/tests/main/dsl/test_compilation_config.py deleted file mode 100644 index c78ccea7e..000000000 --- a/tests/main/dsl/test_compilation_config.py +++ /dev/null @@ -1,192 +0,0 @@ -import unittest.mock -from math import sqrt - -import pytest - -from pace.dsl.stencil import CompilationConfig, RunMode -from pace.util.communicator import CubedSphereCommunicator -from pace.util.partitioner import CubedSpherePartitioner, TilePartitioner - - -def test_safety_checks(): - with pytest.raises(RuntimeError): - CompilationConfig(backend="numpy", device_sync=True) - with pytest.raises(RuntimeError): - CompilationConfig(backend="gt:cpu_ifirst", device_sync=True) - - -@pytest.mark.parametrize( - "size, use_minimal_caching, run_mode", - [ - pytest.param(54, True, RunMode.Run, id="3x3 layout Run minimal"), - pytest.param(96, False, RunMode.BuildAndRun, id="4x4 layout BnR normal"), - pytest.param(96, True, RunMode.Run, id="4x4 layout Run minimal"), - ], -) -def test_check_communicator_valid( - size: int, use_minimal_caching: bool, run_mode: RunMode -): - partitioner = CubedSpherePartitioner( - TilePartitioner((int(sqrt(size / 6)), int((sqrt(size / 6))))) - ) - comm = unittest.mock.MagicMock() - comm.Get_size.return_value = size - cubed_sphere_comm = CubedSphereCommunicator(comm, partitioner) - config = CompilationConfig( - run_mode=run_mode, use_minimal_caching=use_minimal_caching - ) - config.check_communicator(cubed_sphere_comm) - - -@pytest.mark.parametrize( - "nx, ny, use_minimal_caching, run_mode", - [ - pytest.param(2, 3, False, RunMode.BuildAndRun, id="2x3 layout BnR normal"), - ], -) -def test_check_communicator_invalid( - nx: int, ny: int, use_minimal_caching: bool, run_mode: RunMode -): - partitioner = CubedSpherePartitioner(TilePartitioner((nx, ny))) - comm = unittest.mock.MagicMock() - comm.Get_size.return_value = nx * ny * 6 - cubed_sphere_comm = CubedSphereCommunicator(comm, partitioner) - config = CompilationConfig( - run_mode=run_mode, use_minimal_caching=use_minimal_caching - ) - with pytest.raises(RuntimeError): - config.check_communicator(cubed_sphere_comm) - - -def test_get_decomposition_info_from_no_comm(): - config = CompilationConfig() - ( - computed_rank, - computed_size, - computed_equivalent, - computed_is_compiling, - ) = config.get_decomposition_info_from_comm(None) - assert computed_rank == 1 - assert computed_size == 1 - assert computed_equivalent == 1 - assert computed_is_compiling is True - - -@pytest.mark.parametrize( - "rank, size, is_compiling, equivalent", - [ - pytest.param(0, 6, True, 0, id="1x1 layout - 0"), - pytest.param(1, 6, False, 0, id="1x1 layout - 1"), - pytest.param(2, 24, True, 2, id="2x2 layout - 2"), - pytest.param(4, 24, False, 0, id="2x2 layout - 2"), - ], -) -def test_get_decomposition_info_from_comm( - rank: int, size: int, is_compiling: bool, equivalent: int -): - partitioner = CubedSpherePartitioner( - TilePartitioner((int(sqrt(size / 6)), int(sqrt(size / 6)))) - ) - comm = unittest.mock.MagicMock() - comm.Get_rank.return_value = rank - comm.Get_size.return_value = size - cubed_sphere_comm = CubedSphereCommunicator(comm, partitioner) - config = CompilationConfig(use_minimal_caching=True, run_mode=RunMode.Run) - ( - computed_rank, - computed_size, - computed_equivalent, - computed_is_compiling, - ) = config.get_decomposition_info_from_comm(cubed_sphere_comm) - assert rank == computed_rank - assert size == computed_size - assert equivalent == computed_equivalent - assert is_compiling == computed_is_compiling - - -@pytest.mark.parametrize( - "rank, size, minimal_caching, run_mode, equivalent", - [ - pytest.param(0, 6, True, RunMode.Run, 0, id="1x1 layout - 0 - R"), - pytest.param(1, 6, False, RunMode.Run, 0, id="1x1 layout - 1 - R"), - pytest.param(2, 24, True, RunMode.Run, 2, id="2x2 layout - 2 - R"), - pytest.param(4, 24, False, RunMode.Run, 0, id="2x2 layout - 4 - R"), - pytest.param(5, 54, True, RunMode.Run, 5, id="3x3 layout - 5 - R"), - pytest.param(28, 54, False, RunMode.Run, 1, id="3x3 layout - 28 - R"), - pytest.param(10, 96, False, RunMode.Run, 4, id="4x4 layout - 10 - R"), - pytest.param(20, 96, False, RunMode.Run, 3, id="4x4 layout - 20 - R"), - pytest.param( - 10, 96, False, RunMode.BuildAndRun, 10, id="4x4 layout - 10 - BnR" - ), - pytest.param(20, 96, False, RunMode.BuildAndRun, 4, id="4x4 layout - 20 - BnR"), - ], -) -def test_determine_compiling_equivalent( - rank, size, minimal_caching, run_mode, equivalent -): - config = CompilationConfig(use_minimal_caching=minimal_caching, run_mode=run_mode) - partitioner = CubedSpherePartitioner( - TilePartitioner((sqrt(size / 6), sqrt(size / 6))) - ) - comm = unittest.mock.MagicMock() - comm.Get_rank.return_value = rank - comm.Get_size.return_value = size - cubed_sphere_comm = CubedSphereCommunicator(comm, partitioner) - assert ( - config.determine_compiling_equivalent(rank, cubed_sphere_comm.partitioner) - == equivalent - ) - - -def test_as_dict(): - config = CompilationConfig() - asdict = config.as_dict() - assert asdict["backend"] == "numpy" - assert asdict["rebuild"] is True - assert asdict["validate_args"] is True - assert asdict["format_source"] is False - assert asdict["device_sync"] is False - assert asdict["run_mode"] == "BuildAndRun" - assert asdict["use_minimal_caching"] is False - assert len(asdict) == 7 - - -def test_from_dict(): - specification_dict = {} - config = CompilationConfig.from_dict(specification_dict) - assert config.backend == "numpy" - assert config.rebuild is False - assert config.validate_args is True - assert config.format_source is False - assert config.device_sync is False - assert config.run_mode == RunMode.BuildAndRun - assert config.use_minimal_caching is False - - specification_dict["backend"] = "gt:gpu" - config = CompilationConfig.from_dict(specification_dict) - assert config.backend == "gt:gpu" - - specification_dict["rebuild"] = True - config = CompilationConfig.from_dict(specification_dict) - assert config.rebuild is True - - specification_dict["validate_args"] = False - config = CompilationConfig.from_dict(specification_dict) - assert config.validate_args is False - - specification_dict["format_source"] = True - config = CompilationConfig.from_dict(specification_dict) - assert config.format_source is True - - specification_dict["device_sync"] = True - config = CompilationConfig.from_dict(specification_dict) - assert config.device_sync is True - - specification_dict["run_mode"] = "Build" - config = CompilationConfig.from_dict(specification_dict) - assert config.run_mode == RunMode.Build - - specification_dict["use_minimal_caching"] = True - specification_dict["run_mode"] = "Run" - config = CompilationConfig.from_dict(specification_dict) - assert config.use_minimal_caching is True diff --git a/tests/main/dsl/test_dace_config.py b/tests/main/dsl/test_dace_config.py deleted file mode 100644 index cb3566dd2..000000000 --- a/tests/main/dsl/test_dace_config.py +++ /dev/null @@ -1,159 +0,0 @@ -import unittest.mock - -from pace.dsl.dace.dace_config import DaceConfig, _determine_compiling_ranks -from pace.dsl.dace.orchestration import ( - DaCeOrchestration, - orchestrate, - orchestrate_function, -) -from pace.util.communicator import CubedSpherePartitioner, TilePartitioner - - -""" -Tests that the dace configuration pace.dsl.dace.dace_config -which determines whether we use dace to run wrapped functions. -""" - - -def test_orchestrate_function_calls_dace(): - def foo(): - pass - - dace_config = DaceConfig( - communicator=None, - backend="gtc:dace", - orchestration=DaCeOrchestration.BuildAndRun, - ) - wrapped = orchestrate_function(config=dace_config)(foo) - with unittest.mock.patch( - "pace.dsl.dace.orchestration._call_sdfg" - ) as mock_call_sdfg: - wrapped() - assert mock_call_sdfg.called - assert mock_call_sdfg.call_args.args[0].f == foo - - -def test_orchestrate_function_does_not_call_dace(): - def foo(): - pass - - dace_config = DaceConfig( - communicator=None, - backend="gtc:dace", - orchestration=DaCeOrchestration.Python, - ) - wrapped = orchestrate_function(config=dace_config)(foo) - with unittest.mock.patch( - "pace.dsl.dace.orchestration._call_sdfg" - ) as mock_call_sdfg: - wrapped() - assert not mock_call_sdfg.called - - -def test_orchestrate_calls_dace(): - dace_config = DaceConfig( - communicator=None, - backend="gtc:dace", - orchestration=DaCeOrchestration.BuildAndRun, - ) - - class A: - def __init__(self): - orchestrate(obj=self, config=dace_config, method_to_orchestrate="foo") - - def foo(self): - pass - - with unittest.mock.patch( - "pace.dsl.dace.orchestration._call_sdfg" - ) as mock_call_sdfg: - a = A() - a.foo() - assert mock_call_sdfg.called - - -def test_orchestrate_does_not_call_dace(): - dace_config = DaceConfig( - communicator=None, - backend="gtc:dace", - orchestration=DaCeOrchestration.Python, - ) - - class A: - def __init__(self): - orchestrate(obj=self, config=dace_config, method_to_orchestrate="foo") - - def foo(self): - pass - - with unittest.mock.patch( - "pace.dsl.dace.orchestration._call_sdfg" - ) as mock_call_sdfg: - a = A() - a.foo() - assert not mock_call_sdfg.called - - -def test_orchestrate_distributed_build(): - dummy_dace_config = DaceConfig( - communicator=None, - backend="gtc:dace", - orchestration=DaCeOrchestration.BuildAndRun, - ) - - def _does_compile(rank, partitioner) -> bool: - dummy_dace_config.layout = partitioner.layout - dummy_dace_config.rank_size = partitioner.layout[0] * partitioner.layout[1] * 6 - dummy_dace_config.my_rank = rank - return _determine_compiling_ranks(dummy_dace_config, partitioner) - - # (1, 1) layout, one rank which compiles - cube_partitioner_11 = CubedSpherePartitioner(TilePartitioner((1, 1))) - assert _does_compile(0, cube_partitioner_11) - assert not _does_compile(1, cube_partitioner_11) # not compiling face - - # (2, 2) layout, 4 ranks, all compiling - cube_partitioner_22 = CubedSpherePartitioner(TilePartitioner((2, 2))) - assert _does_compile(0, cube_partitioner_22) - assert _does_compile(1, cube_partitioner_22) - assert _does_compile(2, cube_partitioner_22) - assert _does_compile(3, cube_partitioner_22) - assert not _does_compile(4, cube_partitioner_22) # not compiling face - - # (3, 3) layout, 9 ranks, all compiling - cube_partitioner_33 = CubedSpherePartitioner(TilePartitioner((3, 3))) - assert _does_compile(0, cube_partitioner_33) - assert _does_compile(1, cube_partitioner_33) - assert _does_compile(2, cube_partitioner_33) - assert _does_compile(3, cube_partitioner_33) - assert _does_compile(4, cube_partitioner_33) - assert _does_compile(5, cube_partitioner_33) - assert _does_compile(6, cube_partitioner_33) - assert _does_compile(7, cube_partitioner_33) - assert _does_compile(8, cube_partitioner_33) - assert not _does_compile(9, cube_partitioner_33) # not compiling face - - # (4, 4) layout, 16 ranks, - # expecting compiling:0, 1, 2, 3, 4, 5, 7, 12, 13, 15 - cube_partitioner_44 = CubedSpherePartitioner(TilePartitioner((4, 4))) - assert _does_compile(0, cube_partitioner_44) - assert _does_compile(1, cube_partitioner_44) - assert _does_compile(4, cube_partitioner_44) - assert _does_compile(5, cube_partitioner_44) - assert _does_compile(7, cube_partitioner_44) - assert _does_compile(12, cube_partitioner_44) - assert _does_compile(13, cube_partitioner_44) - assert _does_compile(15, cube_partitioner_44) - assert not _does_compile(2, cube_partitioner_44) # same code path as 3 - assert not _does_compile(6, cube_partitioner_44) # same code path as 5 - assert not _does_compile(8, cube_partitioner_44) # same code path as 4 - assert not _does_compile(11, cube_partitioner_44) # same code path as 7 - assert not _does_compile(16, cube_partitioner_44) # not compiling face - - # For a few other layouts, we check that we always have 9 compiling ranks - for layout in [(5, 5), (10, 10), (20, 20)]: - partition = CubedSpherePartitioner(TilePartitioner(layout)) - compiling = 0 - for i in range(layout[0] * layout[1] * 6): - compiling += 1 if _does_compile(i, partition) else 0 - assert compiling == 9 diff --git a/tests/main/dsl/test_skip_passes.py b/tests/main/dsl/test_skip_passes.py deleted file mode 100644 index 7cb4376f1..000000000 --- a/tests/main/dsl/test_skip_passes.py +++ /dev/null @@ -1,64 +0,0 @@ -import unittest.mock - -# will need to update this import when gt4py is updated -from gt4py.cartesian.gtc.passes.oir_optimizations.horizontal_execution_merging import ( - HorizontalExecutionMerging, -) -from gt4py.cartesian.gtc.passes.oir_pipeline import DefaultPipeline -from gt4py.cartesian.gtscript import PARALLEL, computation, interval - -from pace.dsl.dace.dace_config import DaceConfig -from pace.dsl.stencil import ( - CompilationConfig, - GridIndexing, - StencilConfig, - StencilFactory, -) -from pace.dsl.typing import FloatField -from pace.util import X_DIM, Y_DIM, Z_DIM - - -def stencil_definition(a: FloatField): - with computation(PARALLEL), interval(...): - a = 0.0 - - -def test_skip_passes_becomes_oir_pipeline(): - backend = "numpy" - dace_config = DaceConfig(None, backend) - config = StencilConfig( - compilation_config=CompilationConfig(backend=backend), dace_config=dace_config - ) - grid_indexing = GridIndexing( - domain=(4, 4, 7), - n_halo=3, - south_edge=False, - north_edge=False, - west_edge=False, - east_edge=False, - ) - factory = StencilFactory(config=config, grid_indexing=grid_indexing) - with unittest.mock.patch( - "gt4py.cartesian.gtscript.stencil" - ) as mock_stencil_builder: - factory.from_dims_halo( - stencil_definition, - compute_dims=[X_DIM, Y_DIM, Z_DIM], - ) - pipeline: DefaultPipeline = mock_stencil_builder.call_args.kwargs.get( - "oir_pipeline", DefaultPipeline() - ) - assert HorizontalExecutionMerging not in pipeline.skip - assert HorizontalExecutionMerging in pipeline.steps - with unittest.mock.patch( - "gt4py.cartesian.gtscript.stencil" - ) as mock_stencil_builder: - factory.from_dims_halo( - stencil_definition, - compute_dims=[X_DIM, Y_DIM, Z_DIM], - skip_passes=("HorizontalExecutionMerging",), - ) - assert "oir_pipeline" in mock_stencil_builder.call_args.kwargs - pipeline: DefaultPipeline = mock_stencil_builder.call_args.kwargs["oir_pipeline"] - assert HorizontalExecutionMerging in pipeline.skip - assert HorizontalExecutionMerging not in pipeline.steps diff --git a/tests/main/dsl/test_stencil.py b/tests/main/dsl/test_stencil.py deleted file mode 100644 index eb17eddd5..000000000 --- a/tests/main/dsl/test_stencil.py +++ /dev/null @@ -1,55 +0,0 @@ -from gt4py.cartesian.gtscript import PARALLEL, Field, computation, interval -from gt4py.storage import empty, ones - -import pace.dsl -from pace.dsl.stencil import CompilationConfig, GridIndexing - - -def _make_storage( - func, - grid_indexing, - stencil_config: pace.dsl.StencilConfig, - *, - dtype=float, - aligned_index=(0, 0, 0), -): - return func( - backend=stencil_config.compilation_config.backend, - shape=grid_indexing.domain, - dtype=dtype, - aligned_index=aligned_index, - ) - - -def test_timing_collector(): - grid_indexing = GridIndexing( - domain=(5, 5, 5), - n_halo=2, - south_edge=True, - north_edge=True, - west_edge=True, - east_edge=True, - ) - stencil_config = pace.dsl.StencilConfig( - compilation_config=CompilationConfig(backend="numpy", rebuild=True) - ) - - stencil_factory = pace.dsl.StencilFactory(stencil_config, grid_indexing) - - def func(inp: Field[float], out: Field[float]): - with computation(PARALLEL), interval(...): - out = inp - - test = stencil_factory.from_origin_domain( - func, (0, 0, 0), domain=grid_indexing.domain - ) - - build_report = stencil_factory.build_report(key="parse_time") - assert "func" in build_report - - inp = _make_storage(ones, grid_indexing, stencil_config, dtype=float) - out = _make_storage(empty, grid_indexing, stencil_config, dtype=float) - - test(inp, out) - exec_report = stencil_factory.exec_report() - assert "func" in exec_report diff --git a/tests/main/dsl/test_stencil_config.py b/tests/main/dsl/test_stencil_config.py deleted file mode 100644 index 6ebfddb3b..000000000 --- a/tests/main/dsl/test_stencil_config.py +++ /dev/null @@ -1,294 +0,0 @@ -import pytest - -from pace.dsl.dace.dace_config import DaceConfig -from pace.dsl.stencil import CompilationConfig, StencilConfig - - -@pytest.mark.parametrize("validate_args", [True, False]) -@pytest.mark.parametrize("rebuild", [True, False]) -@pytest.mark.parametrize("format_source", [True, False]) -@pytest.mark.parametrize("compare_to_numpy", [True, False]) -@pytest.mark.parametrize("backend", ["numpy", "gt_gpu"]) -def test_same_config_equal( - backend: str, - rebuild: bool, - validate_args: bool, - format_source: bool, - compare_to_numpy: bool, -): - dace_config = DaceConfig( - communicator=None, - backend=backend, - ) - config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=False, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - assert config == config - - same_config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=False, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - assert config == same_config - - -@pytest.mark.parametrize("validate_args", [True]) -@pytest.mark.parametrize("device_sync", [False]) -@pytest.mark.parametrize("rebuild", [True]) -@pytest.mark.parametrize("format_source", [True]) -@pytest.mark.parametrize("compare_to_numpy", [True]) -def test_different_backend_not_equal( - backend: str, - rebuild: bool, - validate_args: bool, - format_source: bool, - device_sync: bool, - compare_to_numpy: bool, -): - dace_config = DaceConfig( - communicator=None, - backend=backend, - ) - config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=device_sync, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - - different_config = StencilConfig( - compilation_config=CompilationConfig( - backend="fakebackend", - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=device_sync, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - assert config != different_config - - -@pytest.mark.parametrize("validate_args", [True]) -@pytest.mark.parametrize("device_sync", [False]) -@pytest.mark.parametrize("rebuild", [True]) -@pytest.mark.parametrize("format_source", [True]) -@pytest.mark.parametrize("compare_to_numpy", [True]) -def test_different_rebuild_not_equal( - backend: str, - rebuild: bool, - validate_args: bool, - format_source: bool, - device_sync: bool, - compare_to_numpy: bool, -): - dace_config = DaceConfig( - communicator=None, - backend=backend, - ) - config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=device_sync, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - - different_config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=not rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=device_sync, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - assert config != different_config - - -@pytest.mark.parametrize("validate_args", [True]) -@pytest.mark.parametrize("device_sync", [False]) -@pytest.mark.parametrize("rebuild", [True]) -@pytest.mark.parametrize("format_source", [True]) -@pytest.mark.parametrize("compare_to_numpy", [True]) -def test_different_device_sync_not_equal( - rebuild: bool, - validate_args: bool, - format_source: bool, - device_sync: bool, - compare_to_numpy: bool, -): - dace_config = DaceConfig( - communicator=None, - backend="gt:gpu", - ) - config = StencilConfig( - compilation_config=CompilationConfig( - backend="gt:gpu", - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=device_sync, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - - different_config = StencilConfig( - compilation_config=CompilationConfig( - backend="gt:gpu", - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=not device_sync, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - assert config != different_config - - -@pytest.mark.parametrize("validate_args", [True]) -@pytest.mark.parametrize("device_sync", [False]) -@pytest.mark.parametrize("rebuild", [True]) -@pytest.mark.parametrize("format_source", [True]) -@pytest.mark.parametrize("compare_to_numpy", [True]) -def test_different_validate_args_not_equal( - backend: str, - rebuild: bool, - validate_args: bool, - format_source: bool, - device_sync: bool, - compare_to_numpy: bool, -): - dace_config = DaceConfig( - None, - backend, - ) - config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=device_sync, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - - different_config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=rebuild, - validate_args=not validate_args, - format_source=format_source, - device_sync=device_sync, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - assert config != different_config - - -@pytest.mark.parametrize("validate_args", [True]) -@pytest.mark.parametrize("device_sync", [False]) -@pytest.mark.parametrize("rebuild", [True]) -@pytest.mark.parametrize("format_source", [True]) -@pytest.mark.parametrize("compare_to_numpy", [True]) -def test_different_format_source_not_equal( - backend: str, - rebuild: bool, - validate_args: bool, - format_source: bool, - device_sync: bool, - compare_to_numpy: bool, -): - dace_config = DaceConfig(communicator=None, backend=backend) - config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=device_sync, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - - different_config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=rebuild, - validate_args=validate_args, - format_source=not format_source, - device_sync=device_sync, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - assert config != different_config - - -@pytest.mark.parametrize("compare_to_numpy", [True, False]) -def test_different_compare_to_numpy_not_equal( - compare_to_numpy: bool, - backend: str = "numpy", - device_sync: bool = False, - format_source: bool = True, - rebuild: bool = True, - validate_args: bool = False, -): - dace_config = DaceConfig(communicator=None, backend=backend) - config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=device_sync, - ), - compare_to_numpy=compare_to_numpy, - dace_config=dace_config, - ) - - different_config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=device_sync, - ), - compare_to_numpy=not compare_to_numpy, - dace_config=dace_config, - ) - assert config != different_config diff --git a/tests/main/dsl/test_stencil_factory.py b/tests/main/dsl/test_stencil_factory.py deleted file mode 100644 index bf74bf415..000000000 --- a/tests/main/dsl/test_stencil_factory.py +++ /dev/null @@ -1,211 +0,0 @@ -import numpy as np -import pytest -from gt4py.cartesian.gtscript import PARALLEL, computation, horizontal, interval, region - -import pace.util -from pace.dsl.dace.dace_config import DaceConfig -from pace.dsl.gt4py_utils import make_storage_from_shape -from pace.dsl.stencil import ( - CompareToNumpyStencil, - FrozenStencil, - GridIndexing, - StencilFactory, - get_stencils_with_varied_bounds, -) -from pace.dsl.stencil_config import CompilationConfig, StencilConfig -from pace.dsl.typing import FloatField - - -def copy_stencil(q_in: FloatField, q_out: FloatField): - with computation(PARALLEL), interval(...): - q_out = q_in - - -def add_1_stencil(q: FloatField): - with computation(PARALLEL), interval(...): - qin = q - q = qin + 1.0 - - -def add_1_in_region_stencil(q_in: FloatField, q_out: FloatField): - from __externals__ import i_start - - with computation(PARALLEL), interval(...): - q_out = q_in - with horizontal(region[i_start, :]): - q_out = q_in + 1.0 - - -def setup_data_vars(backend: str): - shape = (7, 7, 3) - q = make_storage_from_shape(shape, backend=backend) - q[:] = 1.0 - q_ref = make_storage_from_shape(shape, backend=backend) - q_ref[:] = 1.0 - return q, q_ref - - -def get_stencil_factory(backend: str) -> StencilFactory: - dace_config = DaceConfig(communicator=None, backend=backend) - config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=False, - validate_args=False, - format_source=False, - device_sync=False, - ), - dace_config=dace_config, - ) - indexing = GridIndexing( - domain=(12, 12, 79), - n_halo=3, - south_edge=True, - north_edge=True, - west_edge=True, - east_edge=True, - ) - return StencilFactory(config=config, grid_indexing=indexing) - - -def test_get_stencils_with_varied_bounds(backend: str): - origins = [(2, 2, 0), (1, 1, 0)] - domains = [(1, 1, 3), (2, 2, 3)] - factory = get_stencil_factory(backend) - stencils = get_stencils_with_varied_bounds( - add_1_stencil, origins, domains, stencil_factory=factory - ) - assert len(stencils) == len(origins) - q, q_ref = setup_data_vars(backend=backend) - stencils[0](q) - q_ref[2:3, 2:3, :] = 2.0 - np.testing.assert_array_equal(q.data, q_ref.data) - stencils[1](q) - q_ref[2:3, 2:3, :] = 3.0 - q_ref[1, 1:3, :] = 2.0 - q_ref[2:3, 1, :] = 2.0 - np.testing.assert_array_equal(q.data, q_ref.data) - - -def test_get_stencils_with_varied_bounds_and_regions(backend: str): - factory = get_stencil_factory(backend) - origins = [(3, 3, 0), (2, 2, 0)] - domains = [(1, 1, 3), (2, 2, 3)] - stencils = get_stencils_with_varied_bounds( - add_1_in_region_stencil, - origins, - domains, - stencil_factory=factory, - ) - q_orig, q_ref = setup_data_vars(backend=backend) - stencils[0](q_orig, q_orig) - q_ref[3, 3] = 2.0 - np.testing.assert_array_equal(q_orig.data, q_ref.data) - stencils[1](q_orig, q_orig) - q_ref[3, 2] = 2.0 - q_ref[3, 3] = 3.0 - np.testing.assert_array_equal(q_orig.data, q_ref.data) - - -@pytest.mark.parametrize("enabled", [True, False]) -def test_stencil_factory_numpy_comparison_from_dims_halo(enabled: bool): - backend = "numpy" - dace_config = DaceConfig(communicator=None, backend=backend) - config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=False, - validate_args=False, - format_source=False, - device_sync=False, - ), - compare_to_numpy=enabled, - dace_config=dace_config, - ) - indexing = GridIndexing( - domain=(12, 12, 79), - n_halo=3, - south_edge=True, - north_edge=True, - west_edge=True, - east_edge=True, - ) - factory = StencilFactory(config=config, grid_indexing=indexing) - stencil = factory.from_dims_halo( - func=copy_stencil, - compute_dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], - compute_halos=(), - ) - if enabled: - assert isinstance(stencil, CompareToNumpyStencil) - else: - assert isinstance(stencil, FrozenStencil) - - -@pytest.mark.parametrize("enabled", [True, False]) -def test_stencil_factory_numpy_comparison_from_origin_domain(enabled: bool): - backend = "numpy" - dace_config = DaceConfig(communicator=None, backend=backend) - config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=False, - validate_args=False, - format_source=False, - device_sync=False, - ), - compare_to_numpy=enabled, - dace_config=dace_config, - ) - indexing = GridIndexing( - domain=(12, 12, 79), - n_halo=3, - south_edge=True, - north_edge=True, - west_edge=True, - east_edge=True, - ) - factory = StencilFactory(config=config, grid_indexing=indexing) - stencil = factory.from_origin_domain( - func=copy_stencil, origin=(3, 3, 0), domain=(6, 6, 79) - ) - if enabled: - assert isinstance(stencil, CompareToNumpyStencil) - else: - assert isinstance(stencil, FrozenStencil) - - -def test_stencil_factory_numpy_comparison_runs_without_exceptions(): - backend = "numpy" - dace_config = DaceConfig(communicator=None, backend=backend) - config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - rebuild=False, - validate_args=False, - format_source=False, - device_sync=False, - ), - compare_to_numpy=True, - dace_config=dace_config, - ) - indexing = GridIndexing( - domain=(12, 12, 79), - n_halo=3, - south_edge=True, - north_edge=True, - west_edge=True, - east_edge=True, - ) - factory = StencilFactory(config=config, grid_indexing=indexing) - stencil = factory.from_origin_domain( - func=copy_stencil, - origin=(0, 0, 0), - domain=indexing.max_shape, - ) - assert isinstance(stencil, CompareToNumpyStencil) - q_in = make_storage_from_shape(indexing.max_shape, backend=backend) - q_in[:] = np.random.randn(*q_in.shape) - q_out = make_storage_from_shape(indexing.max_shape, backend=backend) - stencil(q_in, q_out) - np.testing.assert_array_equal(q_in.data, q_out.data) diff --git a/tests/main/dsl/test_stencil_wrapper.py b/tests/main/dsl/test_stencil_wrapper.py deleted file mode 100644 index 551523f64..000000000 --- a/tests/main/dsl/test_stencil_wrapper.py +++ /dev/null @@ -1,350 +0,0 @@ -import contextlib -import unittest.mock - -import gt4py.cartesian.gtscript -import numpy as np -import pytest -from gt4py.cartesian.gtscript import PARALLEL, computation, interval - -import pace.util -from pace.dsl.dace.dace_config import DaceConfig, DaCeOrchestration -from pace.dsl.gt4py_utils import make_storage_from_shape -from pace.dsl.stencil import FrozenStencil, _convert_quantities_to_storage -from pace.dsl.stencil_config import CompilationConfig, StencilConfig -from pace.dsl.typing import Float, FloatField - - -def get_stencil_config( - *, - backend: str, - orchestration: DaCeOrchestration = DaCeOrchestration.Python, - **kwargs, -): - dace_config = DaceConfig(None, backend=backend, orchestration=orchestration) - config = StencilConfig( - compilation_config=CompilationConfig( - backend=backend, - **kwargs, - ), - dace_config=dace_config, - ) - return config - - -@contextlib.contextmanager -def mock_gtscript_stencil(mock): - original_stencil = gt4py.cartesian.gtscript.stencil - try: - gt4py.cartesian.gtscript.stencil = mock - yield - finally: - gt4py.cartesian.gtscript.stencil = original_stencil - - -class MockFieldInfo: - def __init__(self, axes): - self.axes = axes - - -@pytest.mark.parametrize( - "field_info, origin, field_origins", - [ - pytest.param( - {"a": MockFieldInfo(["I"])}, - (1, 2, 3), - {"_all_": (1, 2, 3), "a": (1,)}, - id="single_field_I", - ), - pytest.param( - {"a": MockFieldInfo(["J"])}, - (1, 2, 3), - {"_all_": (1, 2, 3), "a": (2,)}, - id="single_field_J", - ), - pytest.param( - {"a": MockFieldInfo(["K"])}, - (1, 2, 3), - {"_all_": (1, 2, 3), "a": (3,)}, - id="single_field_K", - ), - pytest.param( - {"a": MockFieldInfo(["I", "J"])}, - (1, 2, 3), - {"_all_": (1, 2, 3), "a": (1, 2)}, - id="single_field_IJ", - ), - pytest.param( - {"a": MockFieldInfo(["I", "J", "K"])}, - {"_all_": (1, 2, 3), "a": (1, 2, 3)}, - {"_all_": (1, 2, 3), "a": (1, 2, 3)}, - id="single_field_origin_mapping", - ), - pytest.param( - {"a": MockFieldInfo(["I", "J", "K"]), "b": MockFieldInfo(["I"])}, - {"_all_": (1, 2, 3), "a": (1, 2, 3)}, - {"_all_": (1, 2, 3), "a": (1, 2, 3), "b": (1,)}, - id="two_fields_update_origin_mapping", - ), - pytest.param( - {"a": None}, - (1, 2, 3), - {"_all_": (1, 2, 3), "a": (1, 2, 3)}, - id="single_field_None", - ), - pytest.param( - {"a": MockFieldInfo(["I", "J"]), "b": MockFieldInfo(["I", "J", "K"])}, - (1, 2, 3), - {"_all_": (1, 2, 3), "a": (1, 2), "b": (1, 2, 3)}, - id="two_fields", - ), - ], -) -def test_compute_field_origins(field_info, origin, field_origins): - result = FrozenStencil._compute_field_origins(field_info, origin) - assert result == field_origins - - -def copy_stencil(q_in: FloatField, q_out: FloatField): - with computation(PARALLEL), interval(...): - q_out = q_in - - -@pytest.mark.parametrize("validate_args", [True, False]) -@pytest.mark.parametrize("device_sync", [False]) -@pytest.mark.parametrize("rebuild", [False]) -@pytest.mark.parametrize("format_source", [False]) -def test_copy_frozen_stencil( - backend: str, - rebuild: bool, - validate_args: bool, - format_source: bool, - device_sync: bool, -): - config = get_stencil_config( - backend=backend, - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=device_sync, - ) - stencil = FrozenStencil( - copy_stencil, - origin=(0, 0, 0), - domain=(3, 3, 3), - stencil_config=config, - externals={}, - ) - q_in = make_storage_from_shape((3, 3, 3), backend=backend) - q_in[:] = 1.0 - q_out = make_storage_from_shape((3, 3, 3), backend=backend) - q_out[:] = 2.0 - stencil(q_in, q_out) - np.testing.assert_array_equal(q_in, q_out) - - -@pytest.mark.parametrize("device_sync", [False]) -@pytest.mark.parametrize("rebuild", [False]) -@pytest.mark.parametrize("format_source", [False]) -def test_frozen_stencil_raises_if_given_origin( - backend: str, - rebuild: bool, - format_source: bool, - device_sync: bool, -): - # only guaranteed when validating args - config = get_stencil_config( - backend=backend, - rebuild=rebuild, - validate_args=True, - format_source=format_source, - device_sync=device_sync, - ) - stencil = FrozenStencil( - copy_stencil, - origin=(0, 0, 0), - domain=(3, 3, 3), - stencil_config=config, - externals={}, - ) - q_in = make_storage_from_shape((3, 3, 3), backend=backend) - q_out = make_storage_from_shape((3, 3, 3), backend=backend) - with pytest.raises(TypeError, match="origin"): - stencil(q_in, q_out, origin=(0, 0, 0)) - - -@pytest.mark.parametrize("device_sync", [False]) -@pytest.mark.parametrize("rebuild", [False]) -@pytest.mark.parametrize("format_source", [False]) -def test_frozen_stencil_raises_if_given_domain( - backend: str, - rebuild: bool, - format_source: bool, - device_sync: bool, -): - # only guaranteed when validating args - config = get_stencil_config( - backend=backend, - rebuild=rebuild, - validate_args=True, - format_source=format_source, - device_sync=device_sync, - ) - stencil = FrozenStencil( - copy_stencil, - origin=(0, 0, 0), - domain=(3, 3, 3), - stencil_config=config, - externals={}, - ) - q_in = make_storage_from_shape((3, 3, 3), backend=backend) - q_out = make_storage_from_shape((3, 3, 3), backend=backend) - with pytest.raises(TypeError, match="domain"): - stencil(q_in, q_out, domain=(3, 3, 3)) - - -@pytest.mark.parametrize( - "rebuild, validate_args, format_source, device_sync", - [[False, False, False, False], [True, False, False, False]], -) -def test_frozen_stencil_kwargs_passed_to_init( - backend: str, - rebuild: bool, - validate_args: bool, - format_source: bool, - device_sync: bool, -): - config = get_stencil_config( - backend=backend, - rebuild=rebuild, - validate_args=validate_args, - format_source=format_source, - device_sync=device_sync, - ) - stencil_object = FrozenStencil( - copy_stencil, - origin=(0, 0, 0), - domain=(3, 3, 3), - stencil_config=config, - externals={}, - ).stencil_object - mock_stencil = unittest.mock.MagicMock(return_value=stencil_object) - with mock_gtscript_stencil(mock_stencil): - FrozenStencil( - copy_stencil, - origin=(0, 0, 0), - domain=(3, 3, 3), - stencil_config=config, - externals={}, - ) - mock_stencil.assert_called_once_with( - definition=copy_stencil, - externals={}, - **config.stencil_kwargs(func=copy_stencil), - build_info={}, - dtypes={float: Float}, - ) - - -def field_after_parameter_stencil(q_in: FloatField, param: float, q_out: FloatField): - with computation(PARALLEL), interval(...): - q_out = param * q_in - - -def test_frozen_field_after_parameter(backend): - config = get_stencil_config( - backend=backend, - rebuild=False, - validate_args=False, - format_source=False, - device_sync=False, - ) - FrozenStencil( - field_after_parameter_stencil, - origin=(0, 0, 0), - domain=(3, 3, 3), - stencil_config=config, - externals={}, - ) - - -@pytest.mark.parametrize("backend", ("numpy", "cuda")) -@pytest.mark.parametrize("rebuild", [True]) -@pytest.mark.parametrize("validate_args", [True]) -def test_backend_options( - backend: str, - rebuild: bool, - validate_args: bool, -): - expected_options = { - "numpy": { - "backend": "numpy", - "rebuild": True, - "format_source": False, - "name": "test_stencil_wrapper.copy_stencil", - }, - "cuda": { - "backend": "cuda", - "rebuild": True, - "device_sync": False, - "format_source": False, - "name": "test_stencil_wrapper.copy_stencil", - }, - } - - actual = get_stencil_config( - backend=backend, rebuild=rebuild, validate_args=validate_args - ).stencil_kwargs(func=copy_stencil) - expected = expected_options[backend] - assert actual == expected - - -def get_mock_quantity(): - return unittest.mock.MagicMock(spec=pace.util.Quantity) - - -def test_convert_quantities_to_storage_no_args(): - args = [] - kwargs = {} - _convert_quantities_to_storage(args, kwargs) - assert len(args) == 0 - assert len(kwargs) == 0 - - -def test_convert_quantities_to_storage_one_arg_quantity(): - quantity = get_mock_quantity() - args = [quantity] - kwargs = {} - _convert_quantities_to_storage(args, kwargs) - assert len(args) == 1 - assert args[0] == quantity.data - assert len(kwargs) == 0 - - -def test_convert_quantities_to_storage_one_kwarg_quantity(): - quantity = get_mock_quantity() - args = [] - kwargs = {"val": quantity} - _convert_quantities_to_storage(args, kwargs) - assert len(args) == 0 - assert len(kwargs) == 1 - assert kwargs["val"] == quantity.data - - -def test_convert_quantities_to_storage_one_arg_nonquantity(): - non_quantity = unittest.mock.MagicMock(spec=tuple) - args = [non_quantity] - kwargs = {} - _convert_quantities_to_storage(args, kwargs) - assert len(args) == 1 - assert args[0] == non_quantity - assert len(kwargs) == 0 - - -def test_convert_quantities_to_storage_one_kwarg_non_quantity(): - non_quantity = unittest.mock.MagicMock(spec=tuple) - args = [] - kwargs = {"val": non_quantity} - _convert_quantities_to_storage(args, kwargs) - assert len(args) == 0 - assert len(kwargs) == 1 - assert kwargs["val"] == non_quantity diff --git a/tests/main/fv3core/test_cartesian_grid.py b/tests/main/fv3core/test_cartesian_grid.py index 986f4eaf8..8155b1bec 100644 --- a/tests/main/fv3core/test_cartesian_grid.py +++ b/tests/main/fv3core/test_cartesian_grid.py @@ -1,9 +1,10 @@ import numpy as np import pytest - -import pace.util -from pace.util.constants import PI -from pace.util.grid.generation import MetricTerms +from ndsl.comm.communicator import TileCommunicator +from ndsl.comm.null_comm import NullComm +from ndsl.comm.partitioner import TilePartitioner +from ndsl.constants import PI +from ndsl.grid.generation import MetricTerms @pytest.mark.parametrize("npx", [8]) @@ -22,9 +23,9 @@ def test_cartesian_grid_generation( deglat: float, backend: str, ): - mpi_comm = pace.util.NullComm(rank=0, total_ranks=1) - partitioner = pace.util.TilePartitioner((1, 1)) - communicator = pace.util.TileCommunicator(mpi_comm, partitioner) + mpi_comm = NullComm(rank=0, total_ranks=1) + partitioner = TilePartitioner((1, 1)) + communicator = TileCommunicator(mpi_comm, partitioner) grid_generator = MetricTerms.from_tile_sizing( npx=npx, npy=npy, diff --git a/tests/main/fv3core/test_dycore_call.py b/tests/main/fv3core/test_dycore_call.py index 4fd7a4719..baf67b483 100644 --- a/tests/main/fv3core/test_dycore_call.py +++ b/tests/main/fv3core/test_dycore_call.py @@ -4,24 +4,29 @@ from datetime import timedelta from typing import Tuple -import pace.dsl.stencil +import ndsl.dsl.stencil +import ndsl.stencils.testing +from ndsl.comm.communicator import CubedSphereCommunicator +from ndsl.comm.null_comm import NullComm +from ndsl.comm.partitioner import CubedSpherePartitioner, TilePartitioner +from ndsl.dsl.dace.dace_config import DaceConfig +from ndsl.dsl.stencil import GridIndexing +from ndsl.grid import DampingCoefficients, GridData, MetricTerms +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from ndsl.performance.timer import NullTimer, Timer +from ndsl.quantity import Quantity +from ndsl.stencils.testing import assert_same_temporaries, copy_temporaries + import pace.fv3core.initialization.analytic_init as ai -import pace.stencils.testing -import pace.util from pace import fv3core -from pace.dsl.dace.dace_config import DaceConfig from pace.fv3core.dycore_state import DycoreState -from pace.stencils.testing import assert_same_temporaries, copy_temporaries -from pace.util.grid import DampingCoefficients, GridData, MetricTerms -from pace.util.null_comm import NullComm DIR = os.path.abspath(os.path.dirname(__file__)) -def setup_dycore() -> ( - Tuple[fv3core.DynamicalCore, fv3core.DycoreState, pace.util.Timer] -): +def setup_dycore() -> Tuple[fv3core.DynamicalCore, fv3core.DycoreState, Timer]: backend = "numpy" config = fv3core.DynamicalCoreConfig( layout=(1, 1), @@ -70,18 +75,16 @@ def setup_dycore() -> ( mpi_comm = NullComm( rank=0, total_ranks=6 * config.layout[0] * config.layout[1], fill_value=0.0 ) - partitioner = pace.util.CubedSpherePartitioner( - pace.util.TilePartitioner(config.layout) - ) - communicator = pace.util.CubedSphereCommunicator(mpi_comm, partitioner) + partitioner = CubedSpherePartitioner(TilePartitioner(config.layout)) + communicator = CubedSphereCommunicator(mpi_comm, partitioner) dace_config = DaceConfig(communicator=communicator, backend=backend) - stencil_config = pace.dsl.stencil.StencilConfig( - compilation_config=pace.dsl.stencil.CompilationConfig( + stencil_config = ndsl.dsl.stencil.StencilConfig( + compilation_config=ndsl.dsl.stencil.CompilationConfig( backend=backend, rebuild=False, validate_args=True ), dace_config=dace_config, ) - sizer = pace.util.SubtileGridSizer.from_tile_params( + sizer = SubtileGridSizer.from_tile_params( nx_tile=config.npx - 1, ny_tile=config.npy - 1, nz=config.npz, @@ -91,12 +94,10 @@ def setup_dycore() -> ( tile_partitioner=partitioner.tile, tile_rank=communicator.tile.rank, ) - grid_indexing = pace.dsl.stencil.GridIndexing.from_sizer_and_communicator( + grid_indexing = GridIndexing.from_sizer_and_communicator( sizer=sizer, comm=communicator ) - quantity_factory = pace.util.QuantityFactory.from_backend( - sizer=sizer, backend=backend - ) + quantity_factory = QuantityFactory.from_backend(sizer=sizer, backend=backend) eta_file = "tests/main/input/eta79.nc" metric_terms = MetricTerms( quantity_factory=quantity_factory, @@ -116,7 +117,7 @@ def setup_dycore() -> ( moist_phys=config.moist_phys, comm=communicator, ) - stencil_factory = pace.dsl.stencil.StencilFactory( + stencil_factory = ndsl.dsl.stencil.StencilFactory( config=stencil_config, grid_indexing=grid_indexing, ) @@ -133,16 +134,16 @@ def setup_dycore() -> ( state=state, ) - return dycore, state, pace.util.NullTimer() + return dycore, state, NullTimer() def copy_state(state1: DycoreState, state2: DycoreState): # copy all attributes of state1 to state2 for attr_name in dir(state1): for _field in fields(type(state1)): - if issubclass(_field.type, pace.util.Quantity): + if issubclass(_field.type, Quantity): attr = getattr(state1, attr_name) - if isinstance(attr, pace.util.Quantity): + if isinstance(attr, Quantity): getattr(state2, attr_name).data[:] = attr.data diff --git a/tests/main/fv3core/test_grid.py b/tests/main/fv3core/test_grid.py index ee4213705..108af13c3 100644 --- a/tests/main/fv3core/test_grid.py +++ b/tests/main/fv3core/test_grid.py @@ -3,10 +3,7 @@ import numpy as np import pytest from gt4py.cartesian import gtscript - -import pace.dsl.stencil -from pace.dsl.typing import Index3D -from pace.util import ( +from ndsl.constants import ( X_DIM, X_INTERFACE_DIM, Y_DIM, @@ -14,6 +11,8 @@ Z_DIM, Z_INTERFACE_DIM, ) +from ndsl.dsl.stencil import GridIndexing +from ndsl.dsl.typing import Index3D @pytest.mark.parametrize("domain, n_halo", [pytest.param((4, 4, 4), 3, id="3_halo")]) @@ -67,7 +66,7 @@ def test_axis_offsets( j_start, j_end, ): - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -137,7 +136,7 @@ def test_origin_full( add: Index3D, origin_full: Index3D, ): - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -185,7 +184,7 @@ def test_origin_compute( add: Index3D, origin_compute: Index3D, ): - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -223,7 +222,7 @@ def test_domain_full( add: Index3D, domain_full: Index3D, ): - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -262,7 +261,7 @@ def test_domain_compute( add: Index3D, domain_compute: Index3D, ): - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -437,7 +436,7 @@ def test_get_origin_domain( origin_expected: Sequence[int], domain_expected: Sequence[int], ): - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -496,7 +495,7 @@ def test_get_origin_domain_restricted_vertical( domain_expected: Sequence[int], ): k_start = 2 - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -610,7 +609,7 @@ def test_get_shape( halos: Sequence[int], shape_expected: Sequence[int], ): - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -637,7 +636,7 @@ def test_restrict_vertical_defaults( n_halo, south_edge, north_edge, west_edge, east_edge ): domain = (3, 4, 10) - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -665,7 +664,7 @@ def test_restrict_vertical_default_domain( n_halo, south_edge, north_edge, west_edge, east_edge ): domain = (3, 4, 10) - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -693,7 +692,7 @@ def test_restrict_vertical_max_shape( n_halo, south_edge, north_edge, west_edge, east_edge ): domain = (3, 4, 10) - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -722,7 +721,7 @@ def test_restrict_vertical( n_halo, south_edge, north_edge, west_edge, east_edge, k_start, nk ): domain = (3, 4, 10) - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -760,7 +759,7 @@ def test_restrict_vertical_twice( second_nk, ): domain = (3, 4, 10) - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, @@ -792,7 +791,7 @@ def test_restrict_vertical_raises( n_halo, south_edge, north_edge, west_edge, east_edge, k_start, nk ): domain = (3, 4, 10) - grid = pace.dsl.stencil.GridIndexing( + grid = GridIndexing( domain=domain, n_halo=n_halo, south_edge=south_edge, diff --git a/tests/main/fv3core/test_init_from_geos.py b/tests/main/fv3core/test_init_from_geos.py index 7e03caf08..67d340b8a 100644 --- a/tests/main/fv3core/test_init_from_geos.py +++ b/tests/main/fv3core/test_init_from_geos.py @@ -1,9 +1,9 @@ import f90nml import numpy as np import pytest # noqa +from ndsl.comm.null_comm import NullComm from pace import fv3core -from pace.util.null_comm import NullComm def test_geos_wrapper(): diff --git a/tests/main/physics/test_integration.py b/tests/main/physics/test_integration.py index 84cd6d311..eb954e24c 100644 --- a/tests/main/physics/test_integration.py +++ b/tests/main/physics/test_integration.py @@ -2,13 +2,19 @@ from datetime import timedelta import numpy as np +from ndsl.comm.communicator import CubedSphereCommunicator +from ndsl.comm.null_comm import NullComm +from ndsl.comm.partitioner import CubedSpherePartitioner, TilePartitioner +from ndsl.dsl.dace import DaceConfig +from ndsl.dsl.dace.orchestration import DaCeOrchestration +from ndsl.dsl.stencil import GridIndexing, StencilConfig, StencilFactory +from ndsl.dsl.stencil_config import CompilationConfig +from ndsl.grid import GridData, MetricTerms +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from ndsl.stencils.testing import assert_same_temporaries, copy_temporaries -import pace.dsl import pace.physics -import pace.util -import pace.util.grid -from pace.dsl.stencil_config import CompilationConfig -from pace.stencils.testing import assert_same_temporaries, copy_temporaries try: @@ -23,12 +29,10 @@ def setup_physics(): physics_config = pace.physics.PhysicsConfig( dt_atmos=225, hydrostatic=False, npx=13, npy=13, npz=79, nwat=6, do_qa=True ) - mpi_comm = pace.util.NullComm( - rank=0, total_ranks=6 * layout[0] * layout[1], fill_value=0.0 - ) - partitioner = pace.util.CubedSpherePartitioner(pace.util.TilePartitioner(layout)) - communicator = pace.util.CubedSphereCommunicator(mpi_comm, partitioner) - sizer = pace.util.SubtileGridSizer.from_tile_params( + mpi_comm = NullComm(rank=0, total_ranks=6 * layout[0] * layout[1], fill_value=0.0) + partitioner = CubedSpherePartitioner(TilePartitioner(layout)) + communicator = CubedSphereCommunicator(mpi_comm, partitioner) + sizer = SubtileGridSizer.from_tile_params( nx_tile=physics_config.npx - 1, ny_tile=physics_config.npy - 1, nz=physics_config.npz, @@ -38,18 +42,16 @@ def setup_physics(): tile_partitioner=partitioner.tile, tile_rank=communicator.tile.rank, ) - grid_indexing = pace.dsl.stencil.GridIndexing.from_sizer_and_communicator( + grid_indexing = GridIndexing.from_sizer_and_communicator( sizer=sizer, comm=communicator ) - quantity_factory = pace.util.QuantityFactory.from_backend( - sizer=sizer, backend=backend - ) - dace_config = pace.dsl.DaceConfig( + quantity_factory = QuantityFactory.from_backend(sizer=sizer, backend=backend) + dace_config = DaceConfig( communicator=communicator, backend=backend, - orchestration=pace.dsl.DaCeOrchestration.Python, + orchestration=DaCeOrchestration.Python, ) - stencil_config = pace.dsl.stencil.StencilConfig( + stencil_config = StencilConfig( compilation_config=CompilationConfig( backend=backend, rebuild=False, @@ -57,16 +59,16 @@ def setup_physics(): ), dace_config=dace_config, ) - stencil_factory = pace.dsl.stencil.StencilFactory( + stencil_factory = StencilFactory( config=stencil_config, grid_indexing=grid_indexing, ) - metric_terms = pace.util.grid.MetricTerms( + metric_terms = MetricTerms( quantity_factory=quantity_factory, communicator=communicator, eta_file="tests/main/input/eta79.nc", ) - grid_data = pace.util.grid.GridData.new_from_metric_terms(metric_terms) + grid_data = GridData.new_from_metric_terms(metric_terms) physics = pace.physics.Physics( stencil_factory, quantity_factory, diff --git a/tests/main/test_grid_init.py b/tests/main/test_grid_init.py index 55e00e81d..f34f05698 100644 --- a/tests/main/test_grid_init.py +++ b/tests/main/test_grid_init.py @@ -1,26 +1,26 @@ import numpy as np import pytest - -import pace.util -from pace.util.grid import MetricTerms +from ndsl.comm.communicator import CubedSphereCommunicator +from ndsl.comm.null_comm import NullComm +from ndsl.comm.partitioner import CubedSpherePartitioner, TilePartitioner +from ndsl.grid import MetricTerms +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from ndsl.quantity import Quantity def get_cube_comm(layout, rank: int): - return pace.util.CubedSphereCommunicator( - comm=pace.util.NullComm(rank=rank, total_ranks=6 * layout[0] * layout[1]), - partitioner=pace.util.CubedSpherePartitioner( - pace.util.TilePartitioner(layout=layout) - ), + return CubedSphereCommunicator( + comm=NullComm(rank=rank, total_ranks=6 * layout[0] * layout[1]), + partitioner=CubedSpherePartitioner(TilePartitioner(layout=layout)), ) def get_quantity_factory(layout, nx_tile, ny_tile, nz): nx = nx_tile // layout[0] ny = ny_tile // layout[1] - return pace.util.QuantityFactory( - sizer=pace.util.SubtileGridSizer( - nx=nx, ny=ny, nz=nz, n_halo=3, extra_dim_lengths={} - ), + return QuantityFactory( + sizer=SubtileGridSizer(nx=nx, ny=ny, nz=nz, n_halo=3, extra_dim_lengths={}), numpy=np, ) @@ -48,7 +48,7 @@ def test_grid_init_not_decomposition_dependent(rank: int): communicator=get_cube_comm(rank=rank, layout=(3, 3)), eta_file=eta_file, ) - partitioner = pace.util.TilePartitioner(layout=(3, 3)) + partitioner = TilePartitioner(layout=(3, 3)) assert allclose(metric_terms_1by1.grid, metric_terms_3by3.grid, partitioner, rank) assert allclose(metric_terms_1by1.agrid, metric_terms_3by3.agrid, partitioner, rank) assert allclose(metric_terms_1by1.area, metric_terms_3by3.area, partitioner, rank) @@ -84,9 +84,9 @@ def test_grid_init_not_decomposition_dependent(rank: int): def allclose( - q_1by1: pace.util.Quantity, - q_3by3: pace.util.Quantity, - partitioner: pace.util.TilePartitioner, + q_1by1: Quantity, + q_3by3: Quantity, + partitioner: TilePartitioner, rank: int, ): subtile_slice = partitioner.subtile_slice( diff --git a/tests/mpi_54rank/test_ext_grid/test_external_grid.py b/tests/mpi_54rank/test_ext_grid/test_external_grid.py index 03f50e65f..67ae54f37 100644 --- a/tests/mpi_54rank/test_ext_grid/test_external_grid.py +++ b/tests/mpi_54rank/test_ext_grid/test_external_grid.py @@ -5,11 +5,16 @@ import pytest import xarray as xr import yaml +from ndsl.comm.communicator import CubedSphereCommunicator +from ndsl.comm.mpi import MPIComm +from ndsl.comm.partitioner import ( + CubedSpherePartitioner, + TilePartitioner, + get_tile_number, +) +from ndsl.constants import PI, RADIUS, X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM -import pace.util from pace.driver import Driver, DriverConfig -from pace.util.constants import PI, RADIUS -from pace.util.mpi import MPIComm DIR = os.path.dirname(os.path.abspath(__file__)) @@ -25,16 +30,14 @@ def get_cube_comm(layout, comm: MPIComm): - return pace.util.CubedSphereCommunicator( + return CubedSphereCommunicator( comm=comm, - partitioner=pace.util.CubedSpherePartitioner( - pace.util.TilePartitioner(layout=layout) - ), + partitioner=CubedSpherePartitioner(TilePartitioner(layout=layout)), ) def get_tile_num(comm: MPIComm): - return pace.util.get_tile_number(comm.rank, comm.partitioner.total_ranks) + return get_tile_number(comm.rank, comm.partitioner.total_ranks) # TODO: Location of test configurations and data will be changed @@ -101,28 +104,28 @@ def test_extgrid_equals_generated(config_file_path: str, ranks: int): subtile_slice_grid = cube_comm.partitioner.tile.subtile_slice( rank=cube_comm.rank, - global_dims=[pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM], + global_dims=[Y_INTERFACE_DIM, X_INTERFACE_DIM], global_extent=(npy, npx), overlap=True, ) subtile_slice_dx = cube_comm.partitioner.tile.subtile_slice( rank=cube_comm.rank, - global_dims=[pace.util.Y_INTERFACE_DIM, pace.util.X_DIM], + global_dims=[Y_INTERFACE_DIM, X_DIM], global_extent=(npy, nx), overlap=True, ) subtile_slice_dy = cube_comm.partitioner.tile.subtile_slice( rank=cube_comm.rank, - global_dims=[pace.util.Y_DIM, pace.util.X_INTERFACE_DIM], + global_dims=[Y_DIM, X_INTERFACE_DIM], global_extent=(ny, npx), overlap=True, ) subtile_slice_area = cube_comm.partitioner.tile.subtile_slice( rank=cube_comm.rank, - global_dims=[pace.util.Y_DIM, pace.util.X_DIM], + global_dims=[Y_DIM, X_DIM], global_extent=(ny, nx), overlap=True, ) diff --git a/tests/mpi_54rank/test_grid_init.py b/tests/mpi_54rank/test_grid_init.py index 855c539ee..237b146f1 100644 --- a/tests/mpi_54rank/test_grid_init.py +++ b/tests/mpi_54rank/test_grid_init.py @@ -1,34 +1,33 @@ from typing import Dict import numpy as np +from ndsl.comm.communicator import CubedSphereCommunicator, TileCommunicator +from ndsl.comm.mpi import MPIComm +from ndsl.comm.partitioner import CubedSpherePartitioner, TilePartitioner +from ndsl.grid import MetricTerms +from ndsl.grid.helper import GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from ndsl.quantity import Quantity import pace.fv3core -import pace.util from pace.fv3core.initialization.test_cases.initialize_baroclinic import ( init_baroclinic_state, ) -from pace.util.grid import MetricTerms -from pace.util.mpi import MPIComm -from pace.util.quantity import Quantity -from util.pace.util.grid.helper import GridData def get_cube_comm(layout, comm: MPIComm): - return pace.util.CubedSphereCommunicator( + return CubedSphereCommunicator( comm=comm, - partitioner=pace.util.CubedSpherePartitioner( - pace.util.TilePartitioner(layout=layout) - ), + partitioner=CubedSpherePartitioner(TilePartitioner(layout=layout)), ) def get_quantity_factory(layout, nx_tile, ny_tile, nz): nx = nx_tile // layout[0] ny = ny_tile // layout[1] - return pace.util.QuantityFactory( - sizer=pace.util.SubtileGridSizer( - nx=nx, ny=ny, nz=nz, n_halo=3, extra_dim_lengths={} - ), + return QuantityFactory( + sizer=SubtileGridSizer(nx=nx, ny=ny, nz=nz, n_halo=3, extra_dim_lengths={}), numpy=np, ) @@ -144,7 +143,7 @@ def dycore_state_to_quantity_dict( def gather_all( - quantity_dict: Dict[str, Quantity], tile_comm: pace.util.TileCommunicator + quantity_dict: Dict[str, Quantity], tile_comm: TileCommunicator ) -> Dict[str, Quantity]: gathered = {} for name, quantity in quantity_dict.items(): @@ -235,7 +234,7 @@ def test_baroclinic_init_not_decomposition_dependent(): assert allclose(computed_1by1[name], gathered_3by3[name], name, global_rank) -def allclose(q_1by1: pace.util.Quantity, q_3by3: pace.util.Quantity, name: str, rank): +def allclose(q_1by1: Quantity, q_3by3: Quantity, name: str, rank): print("1by1", q_1by1.metadata, "3by3", q_3by3.metadata) assert q_1by1.view[:].shape == q_3by3.view[:].shape, name same = (q_1by1.view[:] == q_3by3.view[:]) | np.isnan(q_1by1.view[:]) diff --git a/tests/savepoint/test_checkpoints.py b/tests/savepoint/test_checkpoints.py index 4d1c8db6c..bf52a8a81 100644 --- a/tests/savepoint/test_checkpoints.py +++ b/tests/savepoint/test_checkpoints.py @@ -7,17 +7,33 @@ import f90nml import xarray as xr import yaml +from ndsl.checkpointer import ValidationCheckpointer +from ndsl.checkpointer.thresholds import ( + SavepointThresholds, + Threshold, + ThresholdCalibrationCheckpointer, +) +from ndsl.comm.communicator import CubedSphereCommunicator +from ndsl.comm.mpi import MPIComm +from ndsl.comm.partitioner import CubedSpherePartitioner, TilePartitioner +from ndsl.dsl.stencil import ( + CompilationConfig, + GridIndexing, + StencilConfig, + StencilFactory, +) +from ndsl.grid import DampingCoefficients, GridData +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from ndsl.namelist import Namelist +from ndsl.quantity import Quantity +from ndsl.stencils.testing import TranslateGrid, dataset_to_dict +from ndsl.stencils.testing.grid import Grid +from ndsl.testing import perturb -import pace.dsl -import pace.util from pace import fv3core from pace.fv3core.initialization.dycore_state import DycoreState from pace.fv3core.testing.translate_fvdynamics import TranslateFVDynamics -from pace.stencils.testing import TranslateGrid, dataset_to_dict -from pace.stencils.testing.grid import Grid -from pace.util.checkpointer.thresholds import SavepointThresholds -from pace.util.grid import DampingCoefficients, GridData -from pace.util.testing import perturb def get_grid(data_path: str, rank: int, layout: Tuple[int, int], backend: str) -> Grid: @@ -52,26 +68,24 @@ def test_fv_dynamics( backend: str, data_path: str, calibrate_thresholds: bool, threshold_path: str ): print("start test call") - namelist = pace.util.Namelist.from_f90nml( - f90nml.read(os.path.join(data_path, "input.nml")) - ) + namelist = Namelist.from_f90nml(f90nml.read(os.path.join(data_path, "input.nml"))) threshold_filename = os.path.join(threshold_path, "fv_dynamics.yaml") - communicator = pace.util.CubedSphereCommunicator( - comm=pace.util.MPIComm(), - partitioner=pace.util.CubedSpherePartitioner( - tile=pace.util.TilePartitioner(layout=namelist.layout) + communicator = CubedSphereCommunicator( + comm=MPIComm(), + partitioner=CubedSpherePartitioner( + tile=TilePartitioner(layout=namelist.layout) ), ) - stencil_factory = pace.dsl.StencilFactory( - config=pace.dsl.StencilConfig( - compilation_config=pace.dsl.CompilationConfig( + stencil_factory = StencilFactory( + config=StencilConfig( + compilation_config=CompilationConfig( backend=backend, communicator=communicator, rebuild=False, ) ), - grid_indexing=pace.dsl.GridIndexing.from_sizer_and_communicator( - sizer=pace.util.SubtileGridSizer.from_tile_params( + grid_indexing=GridIndexing.from_sizer_and_communicator( + sizer=SubtileGridSizer.from_tile_params( nx_tile=namelist.npx - 1, ny_tile=namelist.npy - 1, nz=namelist.npz, @@ -120,11 +134,11 @@ def test_fv_dynamics( with open(threshold_filename, "r") as f: data = yaml.safe_load(f) thresholds = dacite.from_dict( - data_class=pace.util.SavepointThresholds, + data_class=SavepointThresholds, data=data, config=dacite.Config(strict=True), ) - validation = pace.util.ValidationCheckpointer( + validation = ValidationCheckpointer( savepoint_data_path=data_path, thresholds=thresholds, rank=communicator.rank ) state, grid_data = initializer.new_state() @@ -146,15 +160,15 @@ def test_fv_dynamics( def _calibrate_thresholds( initializer: StateInitializer, - communicator: pace.util.CubedSphereCommunicator, - stencil_factory: pace.dsl.StencilFactory, - quantity_factory: pace.util.QuantityFactory, + communicator: CubedSphereCommunicator, + stencil_factory: StencilFactory, + quantity_factory: QuantityFactory, damping_coefficients: DampingCoefficients, dycore_config: fv3core.DynamicalCoreConfig, n_trials: int, factor: float, ): - calibration = pace.util.ThresholdCalibrationCheckpointer(factor=factor) + calibration = ThresholdCalibrationCheckpointer(factor=factor) for i in range(n_trials): print(f"running calibration trial {i}") trial_state, grid_data = initializer.new_state() @@ -185,10 +199,10 @@ def set_manual_thresholds(thresholds: SavepointThresholds): # all thresholds on the input data are 0 because no computation has happened yet for entry in thresholds.savepoints["FVDynamics-In"]: for name in entry: - entry[name] = pace.util.Threshold(relative=0.0, absolute=0.0) + entry[name] = Threshold(relative=0.0, absolute=0.0) -def merge_thresholds(all_thresholds: List[pace.util.SavepointThresholds]): +def merge_thresholds(all_thresholds: List[SavepointThresholds]): thresholds = all_thresholds[0] for other_thresholds in all_thresholds[1:]: for savepoint_name in thresholds.savepoints: @@ -210,5 +224,5 @@ def dycore_state_to_dict(state: DycoreState): return { name: getattr(state, name).data for name in dir(state) - if isinstance(getattr(state, name), pace.util.Quantity) + if isinstance(getattr(state, name), Quantity) } diff --git a/tests/savepoint/translate/__init__.py b/tests/savepoint/translate/__init__.py new file mode 100644 index 000000000..e7f366ac1 --- /dev/null +++ b/tests/savepoint/translate/__init__.py @@ -0,0 +1 @@ +from .translate_driver import TranslateDriver diff --git a/physics/tests/savepoint/translate/translate_driver.py b/tests/savepoint/translate/translate_driver.py similarity index 90% rename from physics/tests/savepoint/translate/translate_driver.py rename to tests/savepoint/translate/translate_driver.py index 6910df18b..7aab8f714 100644 --- a/physics/tests/savepoint/translate/translate_driver.py +++ b/tests/savepoint/translate/translate_driver.py @@ -1,5 +1,8 @@ -import pace.dsl -import pace.util +from ndsl.constants import N_HALO_DEFAULT +from ndsl.initialization.allocator import QuantityFactory +from ndsl.initialization.sizer import SubtileGridSizer +from ndsl.namelist import Namelist + from pace.driver.run import Driver, DriverConfig from pace.driver.state import TendencyState from pace.fv3core._config import DynamicalCoreConfig @@ -9,7 +12,6 @@ from pace.fv3core.testing.translate_fvdynamics import TranslateFVDynamics from pace.fv3core.testing.validation import enable_selective_validation from pace.physics import PHYSICS_PACKAGES, PhysicsConfig, PhysicsState -from pace.util.namelist import Namelist enable_selective_validation() @@ -28,18 +30,18 @@ def __init__(self, grid, namelist, stencil_factory): def compute_parallel(self, inputs, communicator): dycore_state = self.state_from_inputs(inputs) - sizer = pace.util.SubtileGridSizer.from_tile_params( + sizer = SubtileGridSizer.from_tile_params( nx_tile=self.namelist.npx - 1, ny_tile=self.namelist.npy - 1, nz=self.namelist.npz, - n_halo=pace.util.N_HALO_DEFAULT, + n_halo=N_HALO_DEFAULT, extra_dim_lengths={}, layout=self.namelist.layout, tile_partitioner=communicator.partitioner.tile, tile_rank=communicator.tile.rank, ) - quantity_factory = pace.util.QuantityFactory.from_backend( + quantity_factory = QuantityFactory.from_backend( sizer, backend=self.stencil_config.compilation_config.backend ) physics_state = PhysicsState.init_zeros( diff --git a/util/.gitignore b/util/.gitignore deleted file mode 100644 index c34444831..000000000 --- a/util/.gitignore +++ /dev/null @@ -1,110 +0,0 @@ -.DS_Store -.idea - -# Fortran compilation files -*.o -*.mod - -# Cython c-output -*.c - -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -parts/ -sdist/ -var/ -wheels/ -*.egg-info/ -.installed.cfg -*.egg - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -.hypothesis/ -.pytest_cache/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# pyenv -.python-version - -# celery beat schedule file -celerybeat-schedule - -# SageMath parsed files -*.sage.py - -# dotenv -.env - -# virtualenv -.venv -venv/ -ENV/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.vscode diff --git a/util/.jenkins/actions/test.sh b/util/.jenkins/actions/test.sh deleted file mode 100755 index 73afc3589..000000000 --- a/util/.jenkins/actions/test.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -f - -set -x -e - -################################################## -# functions -################################################## - -exitError() -{ - echo "ERROR $1: $3" 1>&2 - echo "ERROR LOCATION=$0" 1>&2 - echo "ERROR LINE=$2" 1>&2 - exit $1 -} - -showUsage() -{ - echo "usage: `basename $0` [-h]" - echo "" - echo "optional arguments:" - echo "-h show this help message and exit" -} - -parseOptions() -{ - # process command line options - while getopts "h" opt - do - case $opt in - h) showUsage; exit 0 ;; - \?) showUsage; exitError 301 ${LINENO} "invalid command line option (-${OPTARG})" ;; - :) showUsage; exitError 302 ${LINENO} "command line option (-${OPTARG}) requires argument" ;; - esac - done - -} - -# echo basic setup -echo "####### executing: $0 $* (PID=$$ HOST=$HOSTNAME TIME=`date '+%D %H:%M:%S'`)" - -JENKINS_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )/../" - -# start timer -T="$(date +%s)" - -# parse command line options (pass all of them to function) -parseOptions $* - -# run tests -echo "### run tests" -pytest --junitxml results.xml tests - -# end timer and report time taken -T="$(($(date +%s)-T))" -printf "####### time taken: %02d:%02d:%02d:%02d\n" "$((T/86400))" "$((T/3600%24))" "$((T/60%60))" "$((T%60))" - -# no errors encountered -echo "####### finished: $0 $* (PID=$$ HOST=$HOSTNAME TIME=`date '+%D %H:%M:%S'`)" -exit 0 - -# so long, Earthling! diff --git a/util/.jenkins/cache.sh b/util/.jenkins/cache.sh deleted file mode 120000 index b70ea14a5..000000000 --- a/util/.jenkins/cache.sh +++ /dev/null @@ -1 +0,0 @@ -../../.jenkins/cache.sh \ No newline at end of file diff --git a/util/.jenkins/checksum.sh b/util/.jenkins/checksum.sh deleted file mode 120000 index 1b7d08c92..000000000 --- a/util/.jenkins/checksum.sh +++ /dev/null @@ -1 +0,0 @@ -../../.jenkins/checksum.sh \ No newline at end of file diff --git a/util/.jenkins/env b/util/.jenkins/env deleted file mode 120000 index 913569ea3..000000000 --- a/util/.jenkins/env +++ /dev/null @@ -1 +0,0 @@ -../../external/buildenv \ No newline at end of file diff --git a/util/.jenkins/jenkins.sh b/util/.jenkins/jenkins.sh deleted file mode 100755 index 015bd14e0..000000000 --- a/util/.jenkins/jenkins.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash -f - -# This is the main script used to trigger Jenkins actions. -# The idea of this script is to keep the amount of code in the "Execute shell" field small -# -# Example syntax: -# .jenkins/jenkins.sh test -# -# Other actions such as test/build/deploy can be defined. - -### Some environment variables available from Jenkins -### Note: for a complete list see https://jenkins.ginko.ch/env-vars.html -# slave The name of the build worker (daint, kesch, ...). -# BUILD_NUMBER The current build number, such as "153". -# BUILD_ID The current build id, such as "2005-08-22_23-59-59" (YYYY-MM-DD_hh-mm-ss). -# BUILD_DISPLAY_NAME The display name of the current build, something like "#153" by default. -# NODE_NAME Name of the worker if the build is on a worker, or "master" if run on main worker. -# NODE_LABELS Whitespace-separated list of labels that the node is assigned. -# JENKINS_HOME The absolute path of the data storage directory assigned on the master node. -# JENKINS_URL Full URL of Jenkins, like http://server:port/jenkins/ -# BUILD_URL Full URL of this build, like http://server:port/jenkins/job/foo/15/ -# JOB_URL Full URL of this job, like http://server:port/jenkins/job/foo/ - -set -x +e - -JENKINS_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" -BUILDENV_DIR=$JENKINS_DIR/../../buildenv - -# some global variables -action="$1" -optarg="$2" - -# Timeout after this many minutes -minutes=45 - -# get latest version of buildenv -git submodule update --init - -# setup module environment and default queue -. ${BUILDENV_DIR}/machineEnvironment.sh - -# load machine dependent environment -. ${BUILDENV_DIR}/env.${host}.sh - -# load scheduler tools (provides run_command) -. ${BUILDENV_DIR}/schedulerTools.sh - -set -e - -# check if action script exists -script="${JENKINS_DIR}/actions/${action}.sh" -test -f "${script}" || exitError 1301 ${LINENO} "cannot find script ${script}" - -# set up virtual env -python3 --version -python3 -m venv venv -. ./venv/bin/activate -pip3 install --upgrade pip setuptools wheel -pip3 install -r $JENKINS_DIR/../requirements.txt -c $JENKINS_DIR/../../constraints.txt -pip3 install -e ${JENKINS_DIR}/../external/gt4py -c $JENKINS_DIR/../../constraints.txt -pip3 install -e ${JENKINS_DIR}/../ -c $JENKINS_DIR/../../constraints.txt - -set +e - -if [ "${target}" == "cpu" ] ; then - scheduler = "none" -fi - -echo "I am running on host ${host} with scheduler ${scheduler}." -run_command "${script} ${optarg}" "UtilAction${action}" $minutes - -if [ $? -ne 0 ] ; then - exitError 1510 ${LINENO} "problem while executing script ${script}" -fi -echo "### ACTION ${action} SUCCESSFUL" diff --git a/util/.jenkins/test_util.sh b/util/.jenkins/test_util.sh deleted file mode 100755 index 8b1696522..000000000 --- a/util/.jenkins/test_util.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash - -set -e - -SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" - -if [ "${target}" == "gpu" ] ; then - # we only run this on HPC - set +e - module load cray-python - module load pycuda - set -e -fi - -# run tests -echo "restoring cache" - -UTIL_DIR=$SCRIPT_DIR/.. - -cache_key=v1-util-$($SCRIPT_DIR/checksum.sh $SCRIPT_DIR/test_util.sh $UTIL_DIR/requirements.txt $UTIL_DIR/requirements_gpu.txt $UTIL_DIR/../constraints.txt)-$target - -$SCRIPT_DIR/cache.sh restore $cache_key - -echo "running tests" - -python3 -m venv venv -. ./venv/bin/activate - -if [ "${target}" == "gpu" ] ; then - set +e - module unload cray-python - module unload pycuda - set -e - pip3 install -r $UTIL_DIR/requirements.txt -r $UTIL_DIR/requirements_gpu.txt -c $UTIL_DIR/../constraints.txt -e $UTIL_DIR -else - pip3 install -r $UTIL_DIR/requirements.txt -c $UTIL_DIR/../constraints.txt -e $UTIL_DIR -fi - -pytest --junitxml results.xml $UTIL_DIR/tests - -echo "saving cache" - -$SCRIPT_DIR/cache.sh save $cache_key venv - -deactivate - -exit 0 diff --git a/util/HISTORY.md b/util/HISTORY.md deleted file mode 100644 index 0d54eca5d..000000000 --- a/util/HISTORY.md +++ /dev/null @@ -1,166 +0,0 @@ -History -======= - -latest ------- - -- Added `MetaEnumStr` to utils to make enums more functional -- Added `fill_for_translate_test` to MetricTerms to fill fields with NaNs only when required for testing -- Added `init_cartesian` method to MetricTerms to handle grid generation for orthogonal grids -- Added `from_layout` and `size` methods to TileCommunicator and Communicator -- Added `__init__` and `total_ranks` abstract methods to Partitioner -- Added `grid_type` to MetricTerms and DriverGridData -- Added `dx_const`, `dy_const`, `deglat`, and `u_max` namelist settings for doubly-periodic grids -- Added `dx_const`, `dy_const`, and `deglat` to grid generation code for doubly-periodic grids -- Added f32 support to halo exchange data transformation -- Use one single logger, from logging.py -- Removed hard-coded values of `ak` and `bk` arrays and added in the feature to read in `ak` and `bk` values - from a NetCDF file to compute the `eta` and `eta_v` values. - -v0.10.0 -------- - -Major changes: - -- Added the following attributes/methods to Communicator: `tile`, `halo_update`, `boundaries`, `start_halo_update`, `vector_halo_update`, `start_vector_halo_update`, `synchronize_vector_interfaces`, `start_synchronize_vector_interfaces`, `get_scalar_halo_updater`, and `get_vector_halo_updater` -- Added Checkpointer and NullCheckpointer classes -- Added SnapshotCheckpointer -- Comm and Request abstract base classes are added to the top level -- Added the following attributes/methods to the Comm abstract base classes: `allreduce`, `allgather` -- Added classes `Threshold`, `ThresholdCalibrationCheckpointer`, `ValidationCheckpointer`, and `SavepointThresholds` -- Added `get_fs` as publicly-available function -- Legacy restart routines can now load restart data from any fsspec-supported filesystem -- Legacy restart routines will raise an exception if no restart files are present instead of loading an empty state -- Added NetCDFMonitor for saving the global state in time-chunked NetCDF files - -Minor changes: - -- Deleted deprecated `finish_halo_update` method from CubedSphereCommunicator -- fixed a bug in `pace.util.grid` where `_reduce_global_area_minmaxes` would use local values instead of the gathered ones -- Added .cleanup() method to ZarrMonitor, used only for API compatibility with NetCDFMonitor and does nothing -- ZarrMonitor.partitioner may now be any Partitioner and not just a CubedSpherePartitioner -- Quantity no longer has a `storage` attribute - the ndarray is directly accessible through the `data` attribute. - -Minor changes: - -- Fixed a bug in normalize_vector(xyz) in `pace.util.grid.gnomonic` where it would divide the input by cells-per-tile, where it should not. -- Refactored `pace.util.grid.helper` so that `HorizontalGridData`, `VerticalGridData`, `ContravariantGridData` and `AngleGridData` have their own `new_from_metric_terms` class methods, and `GridData` calls those in its own method definition. -- Added `stretch_transformation` to `pace.util.grid` - stretches the grid as needed for refinement, tropical test case. - -v0.9.0 ------- - -Major changes: - -- Modified `pace.util.Quantity.transpose` to retain attributes, and loosened `pace.util.ZarrMonitor.store` requirements on attribute consistency, both to ease fv3net integration issues not addressed in v0.8.0 - -v0.8.0 ------- - -Major changes: - -- Changed `ZarrMonitor.store` behavior to allow passing quantities with different dimension orders -- Added `CachingCommWriter` which wraps a `Comm` object and can be serialized to a file-like object with a `.dump` method -- Added `CachingCommReader` which can be loaded from the dump output of `CachingCommWriter` and replays its communication in the order it occurred. -- `NullComm` is now public api in `pace-util` -- Deleted deprecated `finish_vector_halo_update` method from `CubedSphereCommunicator` -- Renamed DummyComm to LocalComm, and added support for message tags. The DummyComm symbol is still in place for backwards compatibility, but points to LocalComm -- added error in CubedSphereCommunicator init if given a communicator with a size not equal to the total ranks of the given partitioner -- `subtile_extent` method of Partitioner classes now takes in a required `rank` argument -- TilePartitioner has a new `edge_interior_ratio` argument which defaults to 1.0, and lets the user specify the relative 1-dimensional extent of the compute domains of ranks on tile edges and corners relative to ranks on the tile interior. In all cases, the closest valid value will be used, which enables some previously invalid configurations (e.g. C128 on a 3 by 3 layout will use the closest valid edge_interior_ratio to 1.0) - -Minor changes: - -- The `split_cartesian_into_storages` method is moved out of pace-util, as it is more generally used, and now lives in pace.dsl.gt4py_utils -- created `DriverGridData.new_from_grid_variables` class method to initialize from grid variable data -- updated QuantityFactory to accept the more generic GridSizer class on initialization -- added `sizer` as public attribute on QuantityFactory -- added `Namelist` class to initialize namelist files used in fv3gfs-fortran -- added `CubedSphereCommunicator.from_layout` constructor method -- added support for built-in `datetime` in ZarrMonitor -- `edge_interior_ratio` is now an optional argument of `tile_extent_from_rank_metadata` -- added support for writing constant data (written once, does not change with time) in ZarrMonitor - -v0.7.0 ------- - -Major changes: - -- Renamed package from fv3gfs-util to pace-util -- Added NullTimer to use for default Timer value, it is a disabled timer which cannot be enabled (raises NotImplementedError) -- Added pace.util.grid, keeping symbols out of top level as they are still unstable -- Added HaloUpdater and associated code, which compiles halo packing for more efficient halo updates -- Added physical constants to pace.util.constants - -Minor changes: - -- Added method set_extra_dim_lengths to QuantityFactory - -Fixes: - -- Fixed bug where ZarrMonitor depended on dict `.items()` always returning items in the same order - -Other changes may exist in this version, as we temporarily paused updating the history on each PR. - -v0.6.0 ------- - -Major changes: - -- Use `cftime.datetime` objects to represent datetimes instead -of `datetime.datetime` objects. This results in times stored in a format compatible with -the fortran model, and accurate internal representation of times with the calendar specified -in the `coupler_nml` namelist. -- `Timer` class is added, with methods `start` and `stop`, and properties `clock` (context manager), and `times` (dictionary of accumulated timing) -- `CubedSphereCommunicator` instances now have a `.timer` attribute, which accumulates times for "pack", "unpack", "Isend", and "Recv" during halo updates -- make `SubtileGridSizer.from_tile_params` public API -- New method `CubedSphereCommunicator.synchronize_vector_interfaces` which synchronizes edge values on interface variables which are duplicated between adjacent ranks -- Added `.sel` method to corner views (e.g. `quantity.view.northeast.sel(x=0, y=1)`) to allow indexing these corner views with arbitrary dimension ordering. -- Halo updates now use tagged send/recv operations, which prevents deadlocks in certain situations -- Quantity.data is now guaranteed to be a numpy or cupy array matching its `.np` module, and will no longer be a gt4py Storage -- Quantity accepts a `gt4py_backend` on initialize which is used to create its `.storage` if one was not used on initialize -- parent MPI rank now referred to as "root" rank in variable names and documentation -- Added TILE_DIM constant for tile dimension of global quantities -- Added Partitioner base class implementing features necessary for scatter/gather -- Moved scatter and gather from TileCommunicator to the Communicator base class, so its code can be re-used by the CubedSphereCommunicator -- Implemented subtile_slice, global_extent, and subtile_extent routines on CubedSpherePartitioner necessary for scatter/gather in CubedSphereCommunicator -- Renamed argument `tile_extent` and `tile_dims` to `global_extent` and `global_dims` in routines to refer generically to the tile in the case of tile scatter/gather or cube in the case of cube scatter/gather -- Fixed a bug where initializing a Quantity with a numpy array and a gpu backend would give CPUStorage -- raise TypeError if initializing a quantity with both a storage and a gt4py_backend argument -- eagerly create storage object when initializing Quantity -- make data type of quantity and storage reflect the gt4py_backend chosen, instead of being determined based on the data type being numpy/cupy - -Fixes: - -- If `only_names` is provided to `open_restart`, it will return those fields and nothing more. Previously it would include `"time"` in the returned state even if it was not requested. -- Fixed a bug where quantity.storage and quantity.data could be out of sync if the quantity was initialized using data and a gt4py backend string -- Default slice for corner views when not given at all as an index (e.g. when providing one index to a 2D view) now gives the same result as providing an empty slice (:) -- Fixed a bug where quantity.view could refer to a different array than quantity.data if the quantity was initialized using data and a gt4py backend string, and then quantity.storage was accessed - -v0.5.1 ------- - -- enable MPI tests on CircleCI - -v0.5.0 ------- - -Breaking changes: - -- `send_buffer` and `recv_buffer` are modified to take in a `callable`, which is more easily serialized than a `numpy`-like module (necessary because we serialize the arguments to re-use buffers), and allows custom specification of the initialization if zeros are needed instead of empty. - -Major changes: - -- Added additional regional views to Quantity as attributes on Quantity.view, including `northeast`, `northwest`, `southeast`, `southwest`, and `interior` -- Separated fv3util into its own repository and began tracking history separately from fv3gfs-python -- Added getters and setters for additional dynamics quantities needed to call an alternative dynamical core -- Added `storage` property to Quantity, implemented as short-term shortcut to .data until gt4py GDP-3 is implemented - -Deprecations: - -- `Quantity.values` is deprecated - -v0.4.3 (2020-05-15) -------------------- - -Last release of fv3util with history contained in fv3gfs-python. diff --git a/util/LICENSE b/util/LICENSE deleted file mode 100644 index 4c477d658..000000000 --- a/util/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ - - -BSD License - -Copyright (c) 2019, Vulcan Technologies LLC -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - -* Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from this - software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED -OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/util/MANIFEST.in b/util/MANIFEST.in deleted file mode 100644 index b95d675e0..000000000 --- a/util/MANIFEST.in +++ /dev/null @@ -1,12 +0,0 @@ -include LICENSE -include README.md -include HISTORY.md - -recursive-include fv3gfs *.json *.yml -recursive-include tests *.py *.sh -recursive-include tests/data * - -recursive-exclude * __pycache__ -recursive-exclude * *.py[co] -recursive-exclude * *.mod *.o -recursive-exclude * *.log diff --git a/util/Makefile b/util/Makefile deleted file mode 100644 index 15569e11d..000000000 --- a/util/Makefile +++ /dev/null @@ -1,87 +0,0 @@ -PYTEST_ARGS?= -SHELL = /bin/sh - -define BROWSER_PYSCRIPT -import os, webbrowser, sys - -try: - from urllib import pathname2url -except: - from urllib.request import pathname2url - -webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) -endef -export BROWSER_PYSCRIPT - -define PRINT_HELP_PYSCRIPT -import re, sys - -for line in sys.stdin: - match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) - if match: - target, help = match.groups() - print("%-20s %s" % (target, help)) -endef -export PRINT_HELP_PYSCRIPT - -BROWSER := python3 -c "$$BROWSER_PYSCRIPT" - -PYTHON_FILES = $(shell git ls-files | grep -e 'py$$' | grep -v -e '__init__.py') -PYTHON_INIT_FILES = $(shell git ls-files | grep '__init__.py') - -help: - @python3 -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) - -coverage: ## check code coverage quickly with the default Python - pytest --cov=fv3gfs --cov-report=html - $(BROWSER) htmlcov/index.html - -test: ## run tests quickly with the default Python - pytest $(PYTEST_ARGS) tests - -test_mpi: - mpirun -n 6 --allow-run-as-root --mca btl_vader_single_copy_mechanism none --oversubscribe pytest $(PYTEST_ARGS) tests/mpi - $(MAKE) -C examples/mpi - -lint: - black --diff --check $(PYTHON_FILES) $(PYTHON_INIT_FILES) - flake8 $(PYTHON_FILES) - # ignore unused import error in __init__.py files - flake8 --ignore=F401 $(PYTHON_INIT_FILES) - mypy --follow-imports silent --show-error-codes fv3gfs - @echo "LINTING SUCCESSFUL" - -clean: clean-build clean-pyc clean-test - $(MAKE) -C examples/mpi clean - -clean-build: ## remove build artifacts - rm -fr build/ - rm -fr dist/ - rm -fr .eggs/ - find . -name '*.egg-info' -exec rm -fr {} + - find . -name '*.egg' -exec rm -f {} + - -clean-pyc: ## remove Python file artifacts - find . -name '*.pyc' -exec rm -f {} + - find . -name '*.pyo' -exec rm -f {} + - find . -name '*~' -exec rm -f {} + - find . -name '__pycache__' -exec rm -fr {} + - -clean-test: ## remove test and coverage artifacts - rm -fr .tox/ - rm -f .coverage - rm -fr htmlcov/ - rm -fr .pytest_cache - -reformat: - black $(PYTHON_FILES) $(PYTHON_INIT_FILES) - -dist: clean ## builds source and wheel package - python3 setup.py sdist - python3 setup.py bdist_wheel - ls -l dist - -release: dist ## package and upload a release - twine upload dist/* - -.PHONY: clean test lint reformat test_mpi coverage help diff --git a/util/README.md b/util/README.md deleted file mode 100644 index 1c9815c13..000000000 --- a/util/README.md +++ /dev/null @@ -1,5 +0,0 @@ -This package is a toolkit of Python objects and routines for writing weather and climate models. - -This is research software and still in development. We welcome external contributions. If you would like to contribute to this project, please get in touch with one of our developers! - -* Free software: BSD license diff --git a/util/RELEASE.rst b/util/RELEASE.rst deleted file mode 100644 index b630ecf85..000000000 --- a/util/RELEASE.rst +++ /dev/null @@ -1,25 +0,0 @@ -Release Instructions -==================== - -Versions should take the form "v..patch". For example, "v0.3.0" is a valid -version, while "v1" is not and "0.3.0" is not. - -1. Make sure all PRs are merged and tests pass. - -2. Prepare a release branch with `git checkout -b release/util/`. - -3. Update the HISTORY.md, replacing the "latest" version heading with the new version. - -4. Commit your changes so far to the release branch. - -5. In the pace-util directory, run `bumpversion `. This will create a new commit. - -6. `git push -u origin release/util/` and create a new pull request in Github. - -7. When the pull request is merged to main, `git checkout main` and `git pull`, - followed by `git tag util/`. - -8. Run `git push origin --tags` to push all local tags to Github. - -9. Run `make release` to push latest release to PyPI. Contact a core developer to get the - necessary API token. diff --git a/util/examples/mpi/.gitignore b/util/examples/mpi/.gitignore deleted file mode 100644 index 53752db25..000000000 --- a/util/examples/mpi/.gitignore +++ /dev/null @@ -1 +0,0 @@ -output diff --git a/util/examples/mpi/Makefile b/util/examples/mpi/Makefile deleted file mode 100644 index 93c84cb25..000000000 --- a/util/examples/mpi/Makefile +++ /dev/null @@ -1,14 +0,0 @@ - -MPI_ENV_VARS=PMIX_MCA_gds=hash - -all: global_timings zarr_monitor - -global_timings: - $(MPI_ENV_VARS) mpirun -n 4 python -m mpi4py global_timings.py - -zarr_monitor: - $(MPI_ENV_VARS) mpirun -n 6 python -m mpi4py zarr_monitor.py - -clean: - $(RM) -r output/* - touch output/.gitkeep diff --git a/util/examples/mpi/global_timings.py b/util/examples/mpi/global_timings.py deleted file mode 100644 index 91ef70e36..000000000 --- a/util/examples/mpi/global_timings.py +++ /dev/null @@ -1,48 +0,0 @@ -import contextlib - -import numpy as np -from mpi4py import MPI - -from pace.util import Timer - - -@contextlib.contextmanager -def nullcontext(): - yield - - -def print_global_timings(times, comm, root=0): - is_root = comm.Get_rank() == root - recvbuf = np.array(0.0) - for name, value in timer.times.items(): - if is_root: - print(name) - for label, op in [("min", MPI.MIN), ("max", MPI.MAX), ("mean", MPI.SUM)]: - comm.Reduce(np.array(value), recvbuf, op=op) - if is_root: - if label == "mean": - recvbuf /= comm.Get_size() - print(f" {label}: {recvbuf}") - - -if __name__ == "__main__": - # a Timer gathers statistics about the blocks it times - arr = np.random.randn(100, 100) - timer = Timer() - - # using a context manager ensures that stop is always called, even if there is an - # exception/error in the block. We strongly encourage using this method when - # possible. - with timer.clock("addition"): - arr += 1 - - # sometimes, you will need to trigger the start and end of the timer manually, if - # the start and end cannot be represented by a context manager - timer.start("context_manager") - with nullcontext(): - timer.stop("context_manager") - - comm = MPI.COMM_WORLD - # timer.times is a dictionary giving you the total time in seconds spent on each - # operation - print_global_timings(timer.times, comm) diff --git a/util/examples/mpi/zarr_monitor.py b/util/examples/mpi/zarr_monitor.py deleted file mode 100644 index 347029743..000000000 --- a/util/examples/mpi/zarr_monitor.py +++ /dev/null @@ -1,42 +0,0 @@ -from datetime import timedelta - -import cftime -import numpy as np -import zarr -from mpi4py import MPI - -import pace.util - - -OUTPUT_PATH = "output/zarr_monitor.zarr" - - -def get_example_state(time): - sizer = pace.util.SubtileGridSizer( - nx=48, ny=48, nz=70, n_halo=3, extra_dim_lengths={} - ) - allocator = pace.util.QuantityFactory(sizer, np) - air_temperature = allocator.zeros( - [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], units="degK" - ) - air_temperature.view[:] = np.random.randn(*air_temperature.extent) - return {"time": time, "air_temperature": air_temperature} - - -if __name__ == "__main__": - size = MPI.COMM_WORLD.Get_size() - # assume square tile faces - ranks_per_edge = int((size // 6) ** 0.5) - layout = (ranks_per_edge, ranks_per_edge) - - store = zarr.storage.DirectoryStore(OUTPUT_PATH) - partitioner = pace.util.CubedSpherePartitioner(pace.util.TilePartitioner(layout)) - monitor = pace.util.ZarrMonitor(store, partitioner, mpi_comm=MPI.COMM_WORLD) - - time = cftime.DatetimeJulian(2020, 1, 1) - timestep = timedelta(hours=1) - - for i in range(10): - state = get_example_state(time) - monitor.store(state) - time += timestep diff --git a/util/external/gt4py b/util/external/gt4py deleted file mode 120000 index 6e790a7fb..000000000 --- a/util/external/gt4py +++ /dev/null @@ -1 +0,0 @@ -../../external/gt4py \ No newline at end of file diff --git a/util/mypy.ini b/util/mypy.ini deleted file mode 100644 index 2cac006f0..000000000 --- a/util/mypy.ini +++ /dev/null @@ -1,55 +0,0 @@ -[mypy] -ignore_missing_imports = True - -# untyped vcm packages -[mypy-fv3viz] -ignore_missing_imports = True - -[mypy-report] -ignore_missing_imports = True - -[mypy-loaders] -ignore_missing_imports = True - -# External Libraries -[mypy-mappm] -ignore_missing_imports = True - -[mypy-gcsfs] -ignore_missing_imports = True - -[mypy-xgcm] -ignore_missing_imports = True - -[mypy-google.*] -ignore_missing_imports = True - -[mypy-numpy] -ignore_missing_imports = True - -[mypy-fsspec] -ignore_missing_imports = True - -[mypy-dask.*] -ignore_missing_imports = True - -[mypy-scipy.*] -ignore_missing_imports = True - -[mypy-skimage.*] -ignore_missing_imports = True - -[mypy-apache_beam.*] -ignore_missing_imports = True - -[mypy-intake] -ignore_missing_imports = True - -[mypy-joblib] -ignore_missing_imports = True - -[mypy-sklearn.*] -ignore_missing_imports = True - -[mypy-toolz] -ignore_missing_imports = True diff --git a/util/pace/util/__init__.py b/util/pace/util/__init__.py deleted file mode 100644 index deb3b0818..000000000 --- a/util/pace/util/__init__.py +++ /dev/null @@ -1,77 +0,0 @@ -from . import testing -from ._capture_stream import capture_stream -from ._corners import fill_scalar_corners -from ._exceptions import InvalidQuantityError, OutOfBoundsError -from ._legacy_restart import open_restart -from ._profiler import NullProfiler, Profiler -from ._timing import NullTimer, Timer -from ._xarray import to_dataset -from .buffer import Buffer, array_buffer, recv_buffer, send_buffer -from .caching_comm import CachingCommData, CachingCommReader, CachingCommWriter -from .checkpointer import ( - Checkpointer, - NullCheckpointer, - SavepointThresholds, - SnapshotCheckpointer, - Threshold, - ThresholdCalibrationCheckpointer, - ValidationCheckpointer, -) -from .comm import Comm, Request -from .communicator import Communicator, CubedSphereCommunicator, TileCommunicator -from .constants import ( - BOUNDARY_TYPES, - CORNER_BOUNDARY_TYPES, - EAST, - EDGE_BOUNDARY_TYPES, - HORIZONTAL_DIMS, - INTERFACE_DIMS, - N_HALO_DEFAULT, - NORTH, - NORTHEAST, - NORTHWEST, - ROOT_RANK, - SOUTH, - SOUTHEAST, - SOUTHWEST, - SPATIAL_DIMS, - TILE_DIM, - WEST, - X_DIM, - X_DIMS, - X_INTERFACE_DIM, - Y_DIM, - Y_DIMS, - Y_INTERFACE_DIM, - Z_DIM, - Z_DIMS, - Z_INTERFACE_DIM, - Z_SOIL_DIM, -) -from .filesystem import get_fs -from .halo_data_transformer import QuantityHaloSpec -from .halo_updater import HaloUpdater, HaloUpdateRequest -from .initialization import GridSizer, QuantityFactory, SubtileGridSizer -from .io import read_state, write_state -from .local_comm import LocalComm -from .logging import AVAILABLE_LOG_LEVELS, pace_log -from .monitor import Monitor, NetCDFMonitor, ZarrMonitor -from .mpi import MPIComm -from .namelist import Namelist, NamelistDefaults -from .nudging import apply_nudging, get_nudging_tendencies -from .null_comm import NullComm -from .partitioner import ( - CubedSpherePartitioner, - Partitioner, - TilePartitioner, - get_tile_index, - get_tile_number, -) -from .quantity import Quantity, QuantityMetadata -from .time import FMS_TO_CFTIME_TYPE, datetime64_to_datetime -from .units import UnitsError, ensure_equal_units, units_are_equal -from .utils import MetaEnumStr - - -__version__ = "0.10.0" -__all__ = list(key for key in locals().keys() if not key.startswith("_")) diff --git a/util/pace/util/_boundary_utils.py b/util/pace/util/_boundary_utils.py deleted file mode 100644 index 73f31d897..000000000 --- a/util/pace/util/_boundary_utils.py +++ /dev/null @@ -1,127 +0,0 @@ -import functools -from typing import Union - -from . import constants -from ._exceptions import OutOfBoundsError - - -def shift_boundary_slice_tuple(dims, origin, extent, boundary_type, slice_tuple): - slice_list = [] - for dim, entry, origin_1d, extent_1d in zip(dims, slice_tuple, origin, extent): - slice_list.append( - _shift_boundary_slice(dim, origin_1d, extent_1d, boundary_type, entry) - ) - return tuple(slice_list) - - -def bound_default_slice(slice_in, start=None, stop=None): - if slice_in.start is not None: - start = slice_in.start - if slice_in.stop is not None: - stop = slice_in.stop - return slice(start, stop, slice_in.step) - - -def _shift_boundary_slice(dim, origin, extent, boundary_type, slice_object): - """_get_boundary_slice for corner views""" - start_offset, stop_offset = _get_offset(boundary_type, dim, origin, extent) - if isinstance(slice_object, slice): - if slice_object.start is not None: - start = slice_object.start + start_offset - else: - start = slice_object.start - if slice_object.stop is not None: - stop = slice_object.stop + stop_offset - else: - stop = slice_object.stop - return bound_default_slice( - slice(start, stop, slice_object.step), origin, origin + extent - ) - else: - return slice_object + start_offset # usually an integer - - -def _get_offset(boundary_type, dim, origin, extent): - if boundary_type is constants.INTERIOR: - return origin, origin + extent - else: - boundary_at_start = boundary_at_start_of_dim(boundary_type, dim) - if boundary_at_start is None: # default is to index within compute domain - return origin, origin - elif boundary_at_start: - return origin, origin - else: - return origin + extent, origin + extent - - -@functools.lru_cache(maxsize=None) -def get_boundary_slice(dims, origin, extent, shape, boundary_type, n_halo, interior): - boundary_slice = [] - for dim, origin_1d, extent_1d, shape_1d in zip(dims, origin, extent, shape): - if dim in constants.INTERFACE_DIMS: - n_overlap = 1 - else: - n_overlap = 0 - n_points = n_halo - at_start = boundary_at_start_of_dim(boundary_type, dim) - if dim not in constants.HORIZONTAL_DIMS: - start, stop = origin_1d, origin_1d + extent_1d - elif at_start is None: - start, stop = origin_1d, origin_1d + extent_1d - elif at_start: - edge_index = origin_1d - if interior: - edge_index += n_overlap - start, stop = edge_index, edge_index + n_points - else: - start, stop = edge_index - n_points, edge_index - else: - edge_index = origin_1d + extent_1d - if interior: - edge_index -= n_overlap - start, stop = edge_index - n_points, edge_index - else: - start, stop = edge_index, edge_index + n_points - if start < 0: - raise OutOfBoundsError( - f"boundary slice extends past start of domain on dimension {dim}" - ) - elif stop > shape_1d: - raise OutOfBoundsError( - f"boundary slice extends past end of domain on dimension {dim}" - ) - else: - boundary_slice.append(slice(start, stop)) - return tuple(boundary_slice) - - -def boundary_at_start_of_dim(boundary: int, dim: str) -> Union[bool, None]: - """ - Return True if boundary is at the start of the dimension, - False if at the end, None if the boundary does not align with the dimension. - """ - return BOUNDARY_AT_START_OF_DIM_MAPPING[boundary].get(dim, None) - - -BOUNDARY_AT_START_OF_DIM_MAPPING = { - constants.WEST: {constants.X_DIM: True, constants.X_INTERFACE_DIM: True}, - constants.EAST: {constants.X_DIM: False, constants.X_INTERFACE_DIM: False}, - constants.SOUTH: {constants.Y_DIM: True, constants.Y_INTERFACE_DIM: True}, - constants.NORTH: {constants.Y_DIM: False, constants.Y_INTERFACE_DIM: False}, -} -BOUNDARY_AT_START_OF_DIM_MAPPING[constants.NORTHWEST] = { - **BOUNDARY_AT_START_OF_DIM_MAPPING[constants.NORTH], - **BOUNDARY_AT_START_OF_DIM_MAPPING[constants.WEST], -} -BOUNDARY_AT_START_OF_DIM_MAPPING[constants.NORTHEAST] = { - **BOUNDARY_AT_START_OF_DIM_MAPPING[constants.NORTH], - **BOUNDARY_AT_START_OF_DIM_MAPPING[constants.EAST], -} -BOUNDARY_AT_START_OF_DIM_MAPPING[constants.SOUTHWEST] = { - **BOUNDARY_AT_START_OF_DIM_MAPPING[constants.SOUTH], - **BOUNDARY_AT_START_OF_DIM_MAPPING[constants.WEST], -} -BOUNDARY_AT_START_OF_DIM_MAPPING[constants.SOUTHEAST] = { - **BOUNDARY_AT_START_OF_DIM_MAPPING[constants.SOUTH], - **BOUNDARY_AT_START_OF_DIM_MAPPING[constants.EAST], -} diff --git a/util/pace/util/_capture_stream.py b/util/pace/util/_capture_stream.py deleted file mode 100644 index 0e36eedd4..000000000 --- a/util/pace/util/_capture_stream.py +++ /dev/null @@ -1,25 +0,0 @@ -import contextlib -import io -import os -import tempfile - - -@contextlib.contextmanager -def capture_stream(stream): - - out_stream = io.BytesIO() - - # parent process: - # close the reading end, we won't need this - orig_file_handle = os.dup(stream.fileno()) - - with tempfile.NamedTemporaryFile() as out: - # overwrite the streams fileno with a the pipe to be read by the forked - # process below - os.dup2(out.fileno(), stream.fileno()) - yield out_stream - # restore the original file handle - os.dup2(orig_file_handle, stream.fileno()) - # print logging info - out.seek(0) - out_stream.write(out.read()) diff --git a/util/pace/util/_corners.py b/util/pace/util/_corners.py deleted file mode 100644 index 3b7927939..000000000 --- a/util/pace/util/_corners.py +++ /dev/null @@ -1,178 +0,0 @@ -""" -fill_scalar_corners - -The fill_corners routines put data into tile corners to make stencil operations more -convenient. - -The corners themselves do not map on to anything meaningful. At, say, the southwest -corner of a tile, the south edge and west edge correspond to different cube faces. -However, there is no cube face across the southwest corner - it's the edge between -the two adjacent tiles. - -(Figures as below depict grid cells near the edge of a tile domain. All symbols except -for C represent halo data.) - -W: west neighbor tile -S: south neighbor tile -C: compute domain -?: corner data, with no meaningful tile - -WWWCCC -WWWCCC -WWWCCC -???SSS -???SSS -???SSS - -However, when applying stencils to the data, it is useful to make use of these corners. -Take for example a stencil along the x-axis. This stencil might be applied in the -south halo, as below: - -X: 3-by-1 stencil being moved along the domain - -WWWCCC -WWWCCC -WWWCCC -???SSS -???XXX -???SSS - -Something interesting happens when the stencil tries to compute at the outermost -point. It wants to grab data from the western tile face, across the edge boundary -separating those two tiles! - -X: 3-by-1 stencil being applied across tile edge - -WWWCCC -WWWCCC -WXWCCC -???SSS -???XXS -???SSS - -In order to do this, the west tile data is copied into the corner before the 3-by-1 -stencil is called. Numbering the west-tile points, the data is copied like so: - -123CCC -456CCC -789CCC -369SSS -258SSS -147SSS - -This allows the 3-by-1 stencil to be applied naturally. Note the new X position within -the corner is being applied on the same number as the point across the edge -shown earlier. - -123CCC -456CCC -789CCC -369SSS -25XXXS -147SSS - -""" -from typing import Sequence - -from typing_extensions import Literal - -from . import constants -from .partitioner import TilePartitioner -from .quantity import Quantity - - -def fill_scalar_corners( - quantity: Quantity, - direction: Literal["x", "y"], - tile_partitioner: TilePartitioner, - rank: int, - n_halo: int, -): - """ - At the corners of tile faces, copy data from halo edges into halo corners to allow - stencils to be translated along those edges in a computationally-relevant way. - - The quantity is modified in-place. - - Args: - quantity: the quantity to modify, whose first two dimensions must be along - the x and y directions, respectively - direction: the direction along which we want to enable stencils to compute. - For example, calling with "x" would allow a stencil with length > 1 along - the x-direction to be convolved with Quantity. Note it is not possible - to use corner filling to convolve with stencils having length > 1 along - both x and y dimensions. - tile_partitioner: object to determine tile positions of ranks - rank: rank on which the quantity exists - n_halo: number of halo points to fill - """ - if quantity.dims[0] not in constants.X_DIMS: - raise ValueError("first dimension must be in x-direction") - elif quantity.dims[1] not in constants.Y_DIMS: - raise ValueError("second dimension must be in y-direction") - if direction not in ("x", "y"): - raise TypeError(f"direction must be one of 'x' or 'y', received {direction}") - on_north = tile_partitioner.on_tile_top(rank) - on_south = tile_partitioner.on_tile_bottom(rank) - on_east = tile_partitioner.on_tile_right(rank) - on_west = tile_partitioner.on_tile_left(rank) - # for interface variables, the edge exists on both sides of the corner, so - # we need to copy data *after* that edge. shift=1 does this, shift=0 - # does nothing - shift = _shared_edge_points(direction, quantity.dims) - if on_south and on_west: - if direction == "y": - quantity.view.southwest[-n_halo:0, -n_halo:0] = quantity.np.rot90( - quantity.view.southwest[shift : n_halo + shift, -n_halo:0], k=-1 - ) - else: - quantity.view.southwest[-n_halo:0, -n_halo:0] = quantity.np.rot90( - quantity.view.southwest[-n_halo:0, shift : n_halo + shift], k=1 - ) - if on_north and on_west: - if direction == "y": - quantity.view.northwest[-n_halo:0, 0:n_halo] = quantity.np.rot90( - quantity.view.northwest[shift : n_halo + shift, 0:n_halo], k=1 - ) - else: - quantity.view.northwest[-n_halo:0, 0:n_halo] = quantity.np.rot90( - quantity.view.northwest[-n_halo:0, -n_halo - shift : -shift], k=-1 - ) - if on_south and on_east: - if direction == "y": - quantity.view.southeast[0:n_halo, -n_halo:0] = quantity.np.rot90( - quantity.view.southeast[-n_halo - shift : -shift, -n_halo:0], k=1 - ) - else: - quantity.view.southeast[0:n_halo, -n_halo:0] = quantity.np.rot90( - quantity.view.southeast[0:n_halo, shift : n_halo + shift], k=-1 - ) - if on_north and on_east: - if direction == "y": - quantity.view.northeast[0:n_halo, 0:n_halo] = quantity.np.rot90( - quantity.view.northeast[-n_halo - shift : -shift, 0:n_halo], k=-1 - ) - else: - quantity.view.northeast[0:n_halo, 0:n_halo] = quantity.np.rot90( - quantity.view.northeast[0:n_halo, -n_halo - shift : -shift], k=1 - ) - - -def _shared_edge_points(fill_direction: Literal["x", "y"], dims: Sequence[str]): - """ - Returns the number of edge points shared by adjacent tiles along the direction - that is going to be copied when a given fill_direction is passed to a corner - filling routine. - - Note that the direction along which data is copied is the opposite of the - fill_direction, as the fill direction corresponds to the direction along which - stencils are going to be subsequently called. - """ - if fill_direction == "y": - # for interface variables, the edge exists on both sides of the corner, so - # we need to copy data *after* that edge. shift=1 does this, shift=0 - # does nothing - shift = int(dims[0] in constants.INTERFACE_DIMS) - else: - shift = int(dims[1] in constants.INTERFACE_DIMS) - return shift diff --git a/util/pace/util/_exceptions.py b/util/pace/util/_exceptions.py deleted file mode 100644 index 0b3782c1a..000000000 --- a/util/pace/util/_exceptions.py +++ /dev/null @@ -1,6 +0,0 @@ -class InvalidQuantityError(Exception): - pass - - -class OutOfBoundsError(ValueError): - pass diff --git a/util/pace/util/_legacy_restart.py b/util/pace/util/_legacy_restart.py deleted file mode 100644 index e43b7f8dd..000000000 --- a/util/pace/util/_legacy_restart.py +++ /dev/null @@ -1,174 +0,0 @@ -import copy -import os -from typing import BinaryIO, Generator, Iterable - -from . import _xarray as xr -from . import constants, filesystem, io -from ._properties import RESTART_PROPERTIES, RestartProperties -from .communicator import Communicator -from .partitioner import get_tile_index -from .quantity import Quantity - - -__all__ = ["open_restart"] - -RESTART_NAMES = ("fv_core.res", "fv_srf_wnd.res", "fv_tracer.res") -RESTART_OPTIONAL_NAMES = ("sfc_data", "phy_data") # not output for dycore-only runs -COUPLER_RES_NAME = "coupler.res" - - -def open_restart( - dirname: str, - communicator: Communicator, - label: str = "", - only_names: Iterable[str] = None, - to_state: dict = None, - tracer_properties: RestartProperties = None, -): - """Load restart files output by the Fortran model into a state dictionary. - - Args: - dirname: location of restart files, can be local or remote - communicator: object for communication over the cubed sphere or tile - label: prepended string on the restart files to load - only_names (optional): list of standard names to load - to_state (optional): if given, assign loaded data into pre-allocated quantities - in this state dictionary - - Returns: - state: model state dictionary - """ - if tracer_properties is None: - restart_properties = RESTART_PROPERTIES - else: - restart_properties = {**tracer_properties, **RESTART_PROPERTIES} - rank = communicator.rank - tile_index = communicator.partitioner.tile_index(rank) - state = {} - if communicator.tile.rank == constants.ROOT_RANK: - filenames = restart_filenames(dirname, tile_index, label) - if len(filenames) == 0: - raise ValueError("no restart files found at {}".format(dirname)) - - for filename in filenames: - with filesystem.open(filename, "rb") as file: - state.update( - load_partial_state_from_restart_file( - file, restart_properties, only_names=only_names - ) - ) - coupler_res_filename = get_coupler_res_filename(dirname, label) - if filesystem.is_file(coupler_res_filename): - if only_names is None or "time" in only_names: - with filesystem.open(coupler_res_filename, "r") as f: - state["time"] = io.get_current_date_from_coupler_res(f) - if to_state is None: - state = communicator.tile.scatter_state(state) - else: - state = communicator.tile.scatter_state(state, recv_state=to_state) - return state - - -def get_coupler_res_filename(dirname, label): - return os.path.join(dirname, prepend_label(COUPLER_RES_NAME, label)) - - -def restart_files(dirname, tile_index, label) -> Generator[BinaryIO, None, None]: - for filename in restart_filenames(dirname, tile_index, label): - with filesystem.open(filename, "rb") as f: - yield f - - -def restart_filenames(dirname, tile_index, label): - suffix = f".tile{tile_index + 1}.nc" - return_list = [] - for name in RESTART_NAMES + RESTART_OPTIONAL_NAMES: - filename = os.path.join(dirname, prepend_label(name, label) + suffix) - if ( - (name in RESTART_NAMES) - or filesystem.is_file(filename) - or os.path.exists(filename) - ): - return_list.append(filename) - return return_list - - -def get_rank_suffix(rank, total_ranks): - if total_ranks % 6 != 0: - raise ValueError( - f"total_ranks must be evenly divisible by 6, was given {total_ranks}" - ) - ranks_per_tile = total_ranks // 6 - tile = get_tile_index(rank, total_ranks) + 1 - count = rank % ranks_per_tile - if total_ranks > 6: - rank_suffix = f".tile{tile}.nc.{count:04}" - else: - rank_suffix = f".tile{tile}.nc" - return rank_suffix - - -def _apply_dims(da, new_dims): - """Applies new dimension names to the last dimensions of the given DataArray.""" - return da.rename(dict(zip(da.dims[-len(new_dims) :], new_dims))) - - -def _apply_restart_metadata(state, restart_properties: RestartProperties): - new_state = {} - for name, da in state.items(): - if name in restart_properties.keys(): - properties = restart_properties[name] - new_dims = properties["dims"] - new_state[name] = _apply_dims(da, new_dims) - new_state[name].attrs["units"] = properties["units"] - else: - new_state[name] = copy.deepcopy(da) - return new_state - - -def map_keys(old_dict, old_keys_to_new): - new_dict = {} - for old_key, new_key in old_keys_to_new.items(): - if old_key in old_dict: - new_dict[new_key] = old_dict[old_key] - for old_key in set(old_dict.keys()).difference(old_keys_to_new.keys()): - new_dict[old_key] = old_dict[old_key] - return new_dict - - -def prepend_label(filename, label=None): - if label is not None and len(label) > 0: - return f"{label}.{filename}" - else: - return filename - - -def load_partial_state_from_restart_file( - file, restart_properties: RestartProperties, only_names=None -): - ds = xr.open_dataset(file).isel(Time=0).drop_vars("Time") - state = map_keys(ds.data_vars, _get_restart_standard_names(restart_properties)) - state = _apply_restart_metadata(state, restart_properties) - if only_names is None: - only_names = state.keys() - state = { # remove any variables that don't have restart metadata - name: value - for name, value in state.items() - if ((name == "time") or ("units" in value.attrs)) and name in only_names - } - for name, array in state.items(): - if name != "time": - array.load() - state[name] = Quantity.from_data_array(array) - return state - - -def _get_restart_standard_names(restart_properties: RestartProperties = None): - """Return a list of variable names needed for a smooth restart. By default uses - restart_properties from RESTART_PROPERTIES.""" - if restart_properties is None: - restart_properties = RESTART_PROPERTIES - return_dict = {} - for std_name, properties in restart_properties.items(): - return_dict[properties["restart_name"]] = std_name - return return_dict diff --git a/util/pace/util/_optional_imports.py b/util/pace/util/_optional_imports.py deleted file mode 100644 index 990a954dd..000000000 --- a/util/pace/util/_optional_imports.py +++ /dev/null @@ -1,43 +0,0 @@ -class RaiseWhenAccessed: - def __init__(self, err): - self._err = err - - def __getattr__(self, _): - raise self._err - - def __call__(self, *args, **kwargs): - raise self._err - - -try: - import zarr -except ModuleNotFoundError as err: - zarr = RaiseWhenAccessed(err) - -try: - import xarray -except ModuleNotFoundError as err: - xarray = None - -try: - import cupy -except ImportError: - cupy = None - -if cupy is not None: - # Cupy might be available - but not the device - try: - cupy.cuda.runtime.deviceSynchronize() - except cupy.cuda.runtime.CUDARuntimeError: - cupy = None - - -try: - import gt4py -except ImportError: - gt4py = None - -try: - import dace -except ImportError: - dace = None diff --git a/util/pace/util/_profiler.py b/util/pace/util/_profiler.py deleted file mode 100644 index 3f4f45752..000000000 --- a/util/pace/util/_profiler.py +++ /dev/null @@ -1,43 +0,0 @@ -import cProfile - - -class Profiler: - def __init__(self): - self._enabled = True - self.profiler = cProfile.Profile() - self.profiler.disable() - - def enable(self): - self.profiler.enable() - - def dump_stats(self, filename: str): - self.profiler.disable() - self._enabled = False - self.profiler.dump_stats(filename) - - @property - def enabled(self) -> bool: - """Indicates whether the profiler is currently enabled.""" - return self._enabled - - -class NullProfiler: - """A profiler class which does not actually profile anything. - - Meant to be used in place of an optional profiler. - """ - - def __init__(self): - self.profiler = None - self._enabled = False - - def enable(self): - pass - - def dump_stats(self, filename: str): - pass - - @property - def enabled(self) -> bool: - """Indicates whether the profiler is enabled.""" - return False diff --git a/util/pace/util/_properties.py b/util/pace/util/_properties.py deleted file mode 100644 index 5beecc740..000000000 --- a/util/pace/util/_properties.py +++ /dev/null @@ -1,452 +0,0 @@ -from typing import Iterable, Mapping, Union - -from .constants import ( - X_DIM, - X_INTERFACE_DIM, - Y_DIM, - Y_INTERFACE_DIM, - Z_DIM, - Z_INTERFACE_DIM, - Z_SOIL_DIM, -) - - -RestartProperties = Mapping[str, Mapping[str, Union[str, Iterable[str]]]] -RESTART_PROPERTIES: RestartProperties = { - "accumulated_x_courant_number": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "cx", - "units": "", - }, - "accumulated_x_mass_flux": { - "dims": [Z_DIM, Y_DIM, X_INTERFACE_DIM], - "restart_name": "mfx", - "units": "unknown", - }, - "accumulated_y_courant_number": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "cy", - "units": "unknown", - }, - "accumulated_y_mass_flux": { - "dims": [Z_DIM, Y_INTERFACE_DIM, X_DIM], - "restart_name": "mfy", - "units": "unknown", - }, - "air_temperature": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "T", - "units": "degK", - }, - "air_temperature_after_physics": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "gt0", - "units": "K", - }, - "air_temperature_at_2m": { - "dims": [Y_DIM, X_DIM], - "restart_name": "t2m", - "units": "degK", - }, - "area_of_grid_cell": { - "dims": [Y_DIM, X_DIM], - "restart_name": "area", - "units": "m^2", - }, - "atmosphere_hybrid_a_coordinate": { - "dims": [Z_INTERFACE_DIM], - "restart_name": "ak", - "units": "Pa", - }, - "atmosphere_hybrid_b_coordinate": { - "dims": [Z_INTERFACE_DIM], - "restart_name": "bk", - "units": "", - }, - "canopy_water": { - "dims": [Y_DIM, X_DIM], - "restart_name": "canopy", - "units": "unknown", - }, - "clear_sky_downward_longwave_flux_at_surface": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "dnfx0", - "restart_name": "sfcflw", - "units": "W/m^2", - }, - "clear_sky_downward_shortwave_flux_at_surface": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "dnfx0", - "restart_name": "sfcfsw", - "units": "W/m^2", - }, - "clear_sky_upward_longwave_flux_at_surface": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "upfx0", - "restart_name": "sfcflw", - "units": "W/m^2", - }, - "clear_sky_upward_longwave_flux_at_top_of_atmosphere": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "upfx0", - "restart_name": "topflw", - "units": "W/m^2", - }, - "clear_sky_upward_shortwave_flux_at_surface": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "upfx0", - "restart_name": "sfcfsw", - "units": "W/m^2", - }, - "clear_sky_upward_shortwave_flux_at_top_of_atmosphere": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "upfx0", - "restart_name": "topfsw", - "units": "W/m^2", - }, - "convective_cloud_bottom_pressure": { - "dims": [Y_DIM, X_DIM], - "restart_name": "cvb", - "units": "Pa", - }, - "convective_cloud_fraction": { - "dims": [Y_DIM, X_DIM], - "restart_name": "cv", - "units": "", - }, - "convective_cloud_top_pressure": { - "dims": [Y_DIM, X_DIM], - "restart_name": "cvt", - "units": "Pa", - }, - "deep_soil_temperature": { - "dims": [Y_DIM, X_DIM], - "restart_name": "tg3", - "units": "degK", - }, - "dissipation_estimate_from_heat_source": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "diss_est", - "units": "unknown", - }, - "eastward_wind": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "ua", - "units": "m/s", - }, - "eastward_wind_after_physics": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "gu0", - "units": "m/s", - }, - "eastward_wind_at_surface": { - "dims": [Y_DIM, X_DIM], - "restart_name": "u_srf", - "units": "m/s", - }, - "fh_parameter": { - "description": "used in PBL scheme", - "dims": [Y_DIM, X_DIM], - "restart_name": "ffhh", - "units": "unknown", - }, - "fm_at_10m": { - "description": "Ratio of sigma level 1 wind and 10m wind", - "dims": [Y_DIM, X_DIM], - "restart_name": "f10m", - "units": "unknown", - }, - "fm_parameter": { - "description": "used in PBL scheme", - "dims": [Y_DIM, X_DIM], - "restart_name": "ffmm", - "units": "unknown", - }, - "fractional_coverage_with_strong_cosz_dependency": { - "dims": [Y_DIM, X_DIM], - "restart_name": "facsf", - "units": "", - }, - "fractional_coverage_with_weak_cosz_dependency": { - "dims": [Y_DIM, X_DIM], - "restart_name": "facwf", - "units": "", - }, - "friction_velocity": { - "dims": [Y_DIM, X_DIM], - "restart_name": "uustar", - "units": "m/s", - }, - "ice_fraction_over_open_water": { - "dims": [Y_DIM, X_DIM], - "restart_name": "fice", - "units": "", - }, - "interface_pressure": { - "dims": [Y_DIM, Z_INTERFACE_DIM, X_DIM], - "restart_name": "pe", - "units": "Pa", - }, - "interface_pressure_raised_to_power_of_kappa": { - "dims": [Z_INTERFACE_DIM, Y_DIM, X_DIM], - "restart_name": "pk", - "units": "unknown", - }, - "land_sea_mask": { - "description": "sea=0, land=1, sea-ice=2", - "dims": [Y_DIM, X_DIM], - "restart_name": "slmsk", - "units": "", - }, - "latent_heat_flux": { - "dims": [Y_DIM, X_DIM], - "restart_name": "dqsfci", - "units": "W/m^2", - }, - "latitude": {"dims": [Y_DIM, X_DIM], "restart_name": "xlat", "units": "radians"}, - "layer_mean_pressure_raised_to_power_of_kappa": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "pkz", - "units": "unknown", - }, - "liquid_soil_moisture": { - "dims": [Z_SOIL_DIM, Y_DIM, X_DIM], - "restart_name": "slc", - "units": "unknown", - }, - "logarithm_of_interface_pressure": { - "dims": [Y_DIM, Z_INTERFACE_DIM, X_DIM], - "restart_name": "peln", - "units": "ln(Pa)", - }, - "longitude": {"dims": [Y_DIM, X_DIM], "restart_name": "xlon", "units": "radians"}, - "maximum_fractional_coverage_of_green_vegetation": { - "dims": [Y_DIM, X_DIM], - "restart_name": "shdmax", - "units": "", - }, - "maximum_snow_albedo_in_fraction": { - "dims": [Y_DIM, X_DIM], - "restart_name": "snoalb", - "units": "", - }, - "mean_cos_zenith_angle": { - "dims": [Y_DIM, X_DIM], - "restart_name": "coszen", - "units": "", - }, - "mean_near_infrared_albedo_with_strong_cosz_dependency": { - "dims": [Y_DIM, X_DIM], - "restart_name": "alnsf", - "units": "", - }, - "mean_near_infrared_albedo_with_weak_cosz_dependency": { - "dims": [Y_DIM, X_DIM], - "restart_name": "alnwf", - "units": "", - }, - "mean_visible_albedo_with_strong_cosz_dependency": { - "dims": [Y_DIM, X_DIM], - "restart_name": "alvsf", - "units": "", - }, - "mean_visible_albedo_with_weak_cosz_dependency": { - "dims": [Y_DIM, X_DIM], - "restart_name": "alvwf", - "units": "", - }, - "minimum_fractional_coverage_of_green_vegetation": { - "dims": [Y_DIM, X_DIM], - "restart_name": "shdmin", - "units": "", - }, - "northward_wind": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "va", - "units": "m/s", - }, - "northward_wind_after_physics": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "gv0", - "units": "m/s", - }, - "northward_wind_at_surface": { - "dims": [Y_DIM, X_DIM], - "restart_name": "v_srf", - "units": "m/s", - }, - "pressure_thickness_of_atmospheric_layer": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "delp", - "units": "Pa", - }, - "sea_ice_thickness": { - "dims": [Y_DIM, X_DIM], - "restart_name": "hice", - "units": "unknown", - }, - "sensible_heat_flux": { - "dims": [Y_DIM, X_DIM], - "restart_name": "dtsfci", - "units": "W/m^2", - }, - "snow_cover_in_fraction": { - "dims": [Y_DIM, X_DIM], - "restart_name": "sncovr", - "units": "", - }, - "snow_depth_water_equivalent": { - "dims": [Y_DIM, X_DIM], - "restart_name": "snwdph", - "units": "mm", - }, - "snow_rain_flag": { - "description": "snow/rain flag for precipitation", - "dims": [Y_DIM, X_DIM], - "restart_name": "srflag", - "units": "", - }, - "soil_temperature": { - "dims": [Z_SOIL_DIM, Y_DIM, X_DIM], - "restart_name": "stc", - "units": "degK", - }, - "soil_type": {"dims": [Y_DIM, X_DIM], "restart_name": "stype", "units": ""}, - "specific_humidity_at_2m": { - "dims": [Y_DIM, X_DIM], - "restart_name": "q2m", - "units": "kg/kg", - }, - "surface_geopotential": { - "dims": [Y_DIM, X_DIM], - "restart_name": "phis", - "units": "m^2 s^-2", - }, - "surface_pressure": {"dims": [Y_DIM, X_DIM], "restart_name": "ps", "units": "Pa"}, - "surface_roughness": { - "dims": [Y_DIM, X_DIM], - "restart_name": "zorl", - "units": "cm", - }, - "surface_slope_type": { - "description": "used in land surface model", - "dims": [Y_DIM, X_DIM], - "restart_name": "slope", - "units": "", - }, - "surface_temperature": { - "description": "surface skin temperature", - "dims": [Y_DIM, X_DIM], - "restart_name": "tsea", - "units": "degK", - }, - "surface_temperature_over_ice_fraction": { - "dims": [Y_DIM, X_DIM], - "restart_name": "tisfc", - "units": "degK", - }, - "total_condensate_mixing_ratio": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "q_con", - "units": "kg/kg", - }, - "total_precipitation": { - "dims": [Y_DIM, X_DIM], - "restart_name": "tprcp", - "units": "m", - }, - "total_sky_downward_longwave_flux_at_surface": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "dnfxc", - "restart_name": "sfcflw", - "units": "W/m^2", - }, - "total_sky_downward_shortwave_flux_at_surface": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "dnfxc", - "restart_name": "sfcfsw", - "units": "W/m^2", - }, - "total_sky_downward_shortwave_flux_at_top_of_atmosphere": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "dnfxc", - "restart_name": "topfsw", - "units": "W/m^2", - }, - "total_sky_upward_longwave_flux_at_surface": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "upfxc", - "restart_name": "sfcflw", - "units": "W/m^2", - }, - "total_sky_upward_longwave_flux_at_top_of_atmosphere": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "upfxc", - "restart_name": "topflw", - "units": "W/m^2", - }, - "total_sky_upward_shortwave_flux_at_surface": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "upfxc", - "restart_name": "sfcfsw", - "units": "W/m^2", - }, - "total_sky_upward_shortwave_flux_at_top_of_atmosphere": { - "dims": [Y_DIM, X_DIM], - "fortran_subname": "upfxc", - "restart_name": "topfsw", - "units": "W/m^2", - }, - "total_soil_moisture": { - "dims": [Z_SOIL_DIM, Y_DIM, X_DIM], - "restart_name": "smc", - "units": "unknown", - }, - "vegetation_fraction": { - "dims": [Y_DIM, X_DIM], - "restart_name": "vfrac", - "units": "", - }, - "vegetation_type": {"dims": [Y_DIM, X_DIM], "restart_name": "vtype", "units": ""}, - "vertical_pressure_velocity": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "omga", - "units": "Pa/s", - }, - "vertical_thickness_of_atmospheric_layer": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "DZ", - "units": "m", - }, - "vertical_wind": { - "dims": [Z_DIM, Y_DIM, X_DIM], - "restart_name": "W", - "units": "m/s", - }, - "water_equivalent_of_accumulated_snow_depth": { - "description": "weasd in Fortran code, over land and sea ice only", - "dims": [Y_DIM, X_DIM], - "restart_name": "sheleg", - "units": "kg/m^2", - }, - "x_wind": { - "dims": [Z_DIM, Y_INTERFACE_DIM, X_DIM], - "restart_name": "u", - "units": "m/s", - }, - "x_wind_on_c_grid": { - "dims": [Z_DIM, Y_DIM, X_INTERFACE_DIM], - "restart_name": "uc", - "units": "m/s", - }, - "y_wind": { - "dims": [Z_DIM, Y_DIM, X_INTERFACE_DIM], - "restart_name": "v", - "units": "m/s", - }, - "y_wind_on_c_grid": { - "dims": [Z_DIM, Y_INTERFACE_DIM, X_DIM], - "restart_name": "vc", - "units": "m/s", - }, -} diff --git a/util/pace/util/_timing.py b/util/pace/util/_timing.py deleted file mode 100644 index d4d08f7f0..000000000 --- a/util/pace/util/_timing.py +++ /dev/null @@ -1,158 +0,0 @@ -import warnings -from timeit import default_timer as time -from typing import Mapping - -from ._optional_imports import cupy as cp -from .utils import GPU_AVAILABLE - - -class Timer: - """Class to accumulate timings for named operations.""" - - def __init__(self): - self._clock_starts = {} - self._accumulated_time = {} - self._hit_count = {} - self._enabled = True - # Check if we have CUDA device and it's ready to - # perform tasks - self._can_time_CUDA = GPU_AVAILABLE - - def start(self, name: str): - """Start timing a given named operation.""" - if self._can_time_CUDA: - cp.cuda.Device(0).synchronize() - cp.cuda.nvtx.RangePush(name) - if self._enabled: - if name in self._clock_starts: - raise ValueError(f"clock already started for '{name}'") - else: - self._clock_starts[name] = time() - - def stop(self, name: str): - """Stop timing a given named operation, add the time elapsed to - accumulated timing and increase the hit count. - """ - if self._can_time_CUDA: - cp.cuda.Device(0).synchronize() - cp.cuda.nvtx.RangePop() - if self._enabled: - if name not in self._accumulated_time: - self._accumulated_time[name] = time() - self._clock_starts.pop(name) - else: - self._accumulated_time[name] += time() - self._clock_starts.pop(name) - if name not in self._hit_count: - self._hit_count[name] = 1 - else: - self._hit_count[name] += 1 - - def clock(self, name: str): - """Context manager to produce timings of operations. - - Args: - name: the name of the operation being timed - - Example: - The context manager times operations that happen within its context. The - following would time a time.sleep operation:: - - >>> import time - >>> from pace.util import Timer - >>> timer = Timer() - >>> with timer.clock("sleep"): - ... time.sleep(1) - ... - >>> timer.times - {'sleep': 1.0032463260000029} - """ - # [DaCe] Because the contextlib is a "one-shot" object - # which self-destroys itself when called, we can't orchestrate - # it easily in DaCe. Waiting for a fix DaCe side to this Python - # ridiculousness (see contelib.py:_GeneratorContextManager.__enter__) - def dace_inhibitor(func): - return func - - class Wrapper: - def __init__(self, timer, name) -> None: - self.timer = timer - self.name = name - - @dace_inhibitor - def __enter__(self): - self.timer.start(name) - - @dace_inhibitor - def __exit__(self, type, value, traceback): - self.timer.stop(name) - - return Wrapper(self, name) - - @property - def times(self) -> Mapping[str, float]: - """accumulated timings for each operation name""" - if len(self._clock_starts) > 0: - warnings.warn( - "Retrieved times while clocks are still going, " - "incomplete times are not included: " - f"{list(self._clock_starts.keys())}", - RuntimeWarning, - ) - return self._accumulated_time.copy() - - @property - def hits(self) -> Mapping[str, int]: - """accumulated hit counts for each operation name""" - if len(self._clock_starts) > 0: - warnings.warn( - "Retrieved hit counts while clocks are still going, " - "incomplete times are not included: " - f"{list(self._clock_starts.keys())}", - RuntimeWarning, - ) - return self._hit_count.copy() - - def reset(self): - """Remove all accumulated timings.""" - self._accumulated_time.clear() - self._hit_count.clear() - - def enable(self): - """Enable the Timer.""" - self._enabled = True - - def disable(self): - """Disable the Timer.""" - if len(self._clock_starts) > 0: - raise RuntimeError( - "Cannot disable timer while clocks are still going: " - f"{list(self._clock_starts.keys())}" - ) - self._enabled = False - - @property - def enabled(self) -> bool: - """Indicates whether the timer is currently enabled.""" - return self._enabled - - -class NullTimer(Timer): - """A Timer class which does not actually accumulate timings. - - Meant to be used in place of an optional timer. - """ - - def __init__(self): - super().__init__() - self._enabled = False - - def enable(self): - """Enable the Timer.""" - raise NotImplementedError( - "NullTimer cannot be enabled, maybe create a Timer and " - "disable it instead of using NullTimer" - ) - - @property - def enabled(self) -> bool: - """Indicates whether the timer is currently enabled.""" - return False diff --git a/util/pace/util/_xarray.py b/util/pace/util/_xarray.py deleted file mode 100644 index b94ba945c..000000000 --- a/util/pace/util/_xarray.py +++ /dev/null @@ -1,19 +0,0 @@ -try: - import xarray as xr - from xarray import DataArray, Dataset, open_dataset -except ModuleNotFoundError as err: - from ._optional_imports import RaiseWhenAccessed - - xr = RaiseWhenAccessed(err) - DataArray = RaiseWhenAccessed(err) - Dataset = RaiseWhenAccessed(err) - open_dataset = RaiseWhenAccessed(err) - - -def to_dataset(state): - data_vars = { - name: value.data_array for name, value in state.items() if name != "time" - } - if "time" in state: - data_vars["time"] = state["time"] - return xr.Dataset(data_vars=data_vars) diff --git a/util/pace/util/boundary.py b/util/pace/util/boundary.py deleted file mode 100644 index 26822b616..000000000 --- a/util/pace/util/boundary.py +++ /dev/null @@ -1,113 +0,0 @@ -import dataclasses -from typing import Tuple - -from ._boundary_utils import get_boundary_slice -from .quantity import Quantity, QuantityHaloSpec - - -@dataclasses.dataclass -class Boundary: - """Maps part of a subtile domain to another rank which shares halo points.""" - - from_rank: int - to_rank: int - n_clockwise_rotations: int - """ - number of clockwise rotations data undergoes if it moves from the from_rank - to the to_rank. The same as the number of clockwise rotations to get from the - orientation of the axes in from_rank to the orientation of the axes in to_rank. - """ - - def send_view(self, quantity: Quantity, n_points: int): - """Return a sliced view of points which should be sent at this boundary. - - Args: - quantity: quantity for which to return a slice - n_points: the width of boundary to include - """ - return self._view(quantity, n_points, interior=True) - - def recv_view(self, quantity: Quantity, n_points: int): - """Return a sliced view of points which should be recieved at this boundary. - - Args: - quantity: quantity for which to return a slice - n_points: the width of boundary to include - """ - return self._view(quantity, n_points, interior=False) - - def send_slice(self, specification: QuantityHaloSpec) -> Tuple[slice]: - """Return the index slices which shoud be sent at this boundary. - - Args: - specification: data specifications for the halo. Including shape - and number of halo points. - - Returns: - A tuple of slices (one per dimensions) - """ - return self._slice(specification, interior=True) - - def recv_slice(self, specification: QuantityHaloSpec) -> Tuple[slice]: - """Return the index slices which should be received at this boundary. - - Args: - quantity: quantity for which to return slices - n_points: the width of boundary to include - - Returns: - A tuple of slices (one per dimensions) - """ - return self._slice(specification, interior=False) - - def _slice(self, specification: QuantityHaloSpec, interior: bool) -> Tuple[slice]: - """Returns a tuple of slices (one per dimensions) indexing the data to be exchange. - - Args: - specification: memory information on this halo, including halo size - - Return: - A tuple of slices (one per dimensions) - """ - raise NotImplementedError() - - def _view(self, quantity: Quantity, n_points: int, interior: bool): - """Return a sliced view of points in the given quantity at this boundary. - - Args: - quantity: quantity for which to return a slice - n_points: the width of boundary to include - interior: if True, give points inside the computational domain (default), - otherwise give points in the halo - """ - raise NotImplementedError() - - -@dataclasses.dataclass -class SimpleBoundary(Boundary): - """A boundary representing an edge or corner of a subtile.""" - - boundary_type: int - - def _view(self, quantity: Quantity, n_points: int, interior: bool): - boundary_slice = get_boundary_slice( - quantity.dims, - quantity.origin, - quantity.extent, - quantity.data.shape, - self.boundary_type, - n_points, - interior, - ) - return quantity.data[tuple(boundary_slice)] - - def _slice(self, specification: QuantityHaloSpec, interior: bool) -> Tuple[slice]: - return get_boundary_slice( - specification.dims, - specification.origin, - specification.extent, - specification.shape, - self.boundary_type, - specification.n_points, - interior, - ) diff --git a/util/pace/util/buffer.py b/util/pace/util/buffer.py deleted file mode 100644 index e7e6cb161..000000000 --- a/util/pace/util/buffer.py +++ /dev/null @@ -1,191 +0,0 @@ -import contextlib -from typing import Callable, Dict, Generator, Iterable, List, Optional, Tuple - -import numpy as np -from numpy.lib.index_tricks import IndexExpression - -from ._timing import NullTimer, Timer -from .types import Allocator -from .utils import ( - device_synchronize, - is_c_contiguous, - safe_assign_array, - safe_mpi_allocate, -) - - -BufferKey = Tuple[Callable, Iterable[int], type] -BUFFER_CACHE: Dict[BufferKey, List["Buffer"]] = {} - - -class Buffer: - """A buffer cached by default. - - _key: key into cache storage to allow easy re-caching - array: ndarray allocated - """ - - array: np.ndarray - - def __init__(self, key: BufferKey, array: np.ndarray): - """Init a cacheable buffer. - - Args: - key: a cache key made out of tuple of Allocator, shape and dtype - array: ndarray of actual data - """ - self._key = key - self.array = array - - @classmethod - def pop_from_cache( - cls, allocator: Allocator, shape: Iterable[int], dtype: type - ) -> "Buffer": - """Retrieve or insert then retrieve of buffer from cache. - - Args: - allocator: used to allocate memory - shape: shape of array - dtype: type of array elements - Return: - a buffer wrapping an allocated array - """ - key = (allocator, shape, dtype) - if key in BUFFER_CACHE and len(BUFFER_CACHE[key]) > 0: - return BUFFER_CACHE[key].pop() - else: - if key not in BUFFER_CACHE: - BUFFER_CACHE[key] = [] - array = safe_mpi_allocate(allocator, shape, dtype=dtype) - assert is_c_contiguous(array) - return cls(key, array) - - @staticmethod - def push_to_cache(buffer: "Buffer"): - """Push the buffer back into the cache. - - Args: - buffer: buffer to push back in cache, using internal key - """ - BUFFER_CACHE[buffer._key].append(buffer) - - def finalize_memory_transfer(self): - """Finalize any memory transfer""" - device_synchronize() - - def assign_to( - self, - destination_array: np.ndarray, - buffer_slice: IndexExpression = np.index_exp[:], - buffer_reshape: IndexExpression = None, - ): - """Assign internal array to destination_array. - - Args: - destination_array: target ndarray - """ - if buffer_reshape is None: - safe_assign_array(destination_array, self.array[buffer_slice]) - else: - safe_assign_array( - destination_array, - np.reshape(self.array[buffer_slice], buffer_reshape, order="C"), - ) - - def assign_from( - self, source_array: np.ndarray, buffer_slice: IndexExpression = np.index_exp[:] - ): - """Assign source_array to internal array. - - Args: - source_array: source ndarray - """ - safe_assign_array(self.array[buffer_slice], source_array) - - -@contextlib.contextmanager -def array_buffer( - allocator: Allocator, shape: Iterable[int], dtype: type -) -> Generator[Buffer, Buffer, None]: - """ - A context manager providing a contiguous array, which may be re-used between calls. - - Args: - allocator: a function with the same signature as numpy.zeros which returns - an ndarray - shape: the shape of the desired array - dtype: the dtype of the desired array - - Yields: - buffer_array: an ndarray created according to the specification in the args. - May be retained and re-used in subsequent calls. - """ - buffer = Buffer.pop_from_cache(allocator, shape, dtype) - yield buffer - Buffer.push_to_cache(buffer) - - -@contextlib.contextmanager -def send_buffer( - allocator: Callable, - array: np.ndarray, - timer: Optional[Timer] = None, -) -> np.ndarray: - """A context manager ensuring that `array` is contiguous in a context where it is - being sent as data, copying into a recycled buffer array if necessary. - - Args: - allocator: used to allocate memory - array: a possibly non-contiguous array for which to provide a buffer - timer: object to accumulate timings for "pack" - - Yields: - buffer_array: if array is non-contiguous, a contiguous buffer array containing - the data from array. Otherwise, yields array. - """ - if timer is None: - timer = NullTimer() - if array is None or is_c_contiguous(array): - yield array - else: - timer.start("pack") - with array_buffer(allocator, array.shape, array.dtype) as sendbuf: - sendbuf.assign_from(array) - # this is a little dangerous, because if there is an exception in the two - # lines above the timer may be started but never stopped. However, it - # cannot be avoided because we cannot put those two lines in a with or - # try block without also including the yield line. - timer.stop("pack") - yield sendbuf.array - - -@contextlib.contextmanager -def recv_buffer( - allocator: Callable, - array: np.ndarray, - timer: Optional[Timer] = None, -) -> np.ndarray: - """A context manager ensuring that array is contiguous in a context where it is - being used to receive data, using a recycled buffer array and then copying the - result into array if necessary. - - Args: - allocator: used to allocate memory - array: a possibly non-contiguous array for which to provide a buffer - timer: object to accumulate timings for "unpack" - - Yields: - buffer_array: if array is non-contiguous, a contiguous buffer array which is - copied into array when the context is exited. Otherwise, yields array. - """ - if timer is None: - timer = NullTimer() - if array is None or is_c_contiguous(array): - yield array - else: - timer.start("unpack") - with array_buffer(allocator, array.shape, array.dtype) as recvbuf: - timer.stop("unpack") - yield recvbuf.array - with timer.clock("unpack"): - recvbuf.assign_to(array) diff --git a/util/pace/util/caching_comm.py b/util/pace/util/caching_comm.py deleted file mode 100644 index a8fb8f0fa..000000000 --- a/util/pace/util/caching_comm.py +++ /dev/null @@ -1,235 +0,0 @@ -import copy -import dataclasses -import pickle -from typing import Any, BinaryIO, List, Optional, TypeVar - -import numpy as np - -from .comm import Comm, Request - - -T = TypeVar("T") - - -class CachingRequestWriter(Request): - def __init__(self, req: Request, buffer: np.ndarray, buffer_list: List[np.ndarray]): - self._req = req - self._buffer = buffer - self._buffer_list = buffer_list - - def wait(self): - self._req.wait() - self._buffer_list.append(copy.deepcopy(self._buffer)) - - -class CachingRequestReader(Request): - def __init__(self, recvbuf, data): - self._recvbuf = recvbuf - self._data = data - - def wait(self): - self._recvbuf[:] = self._data - - -class NullRequest(Request): - def wait(self): - pass - - -@dataclasses.dataclass -class CachingCommData: - """ - Data required to restore a CachingCommReader. - - Usually you will not want to initialize this class directly, but instead - use the CachingCommReader.load method. - """ - - rank: int - size: int - bcast_objects: List[Any] = dataclasses.field(default_factory=list) - received_buffers: List[np.ndarray] = dataclasses.field(default_factory=list) - generic_obj_buffers: List[Any] = dataclasses.field(default_factory=list) - split_data: List["CachingCommData"] = dataclasses.field(default_factory=list) - - def __post_init__(self): - self._i_bcast = 0 - self._i_buffers = 0 - self._i_split = 0 - self._i_generic_obj = 0 - - def get_bcast(self): - return_value = self.bcast_objects[self._i_bcast] - self._i_bcast += 1 - return return_value - - def get_buffer(self): - return_value = self.received_buffers[self._i_buffers] - self._i_buffers += 1 - return return_value - - def get_generic_obj(self): - return_value = self.generic_obj_buffers[self._i_generic_obj] - self._i_generic_obj += 1 - return return_value - - def get_split(self): - return_value = self.split_data[self._i_split] - self._i_split += 1 - return return_value - - def dump(self, file: BinaryIO): - pickle.dump(self, file) - - @classmethod - def load(self, file: BinaryIO) -> "CachingCommData": - return pickle.load(file) - - -class CachingCommReader(Comm): - """ - mpi4py Comm-like object which replays stored communications. - """ - - def __init__(self, data: CachingCommData): - """ - Initialize a CachingCommReader. - - Usually you will not want to initialize this class directly, but instead - use the CachingCommReader.load method. - - Args: - data: contains all data needed for mocked communication - """ - self._data = data - - def Get_rank(self) -> int: - return self._data.rank - - def Get_size(self) -> int: - return self._data.size - - def bcast(self, value: Optional[T], root=0) -> T: - return self._data.get_bcast() - - def barrier(self): - pass - - def Barrier(self): - pass - - def Scatter(self, sendbuf, recvbuf, root=0, **kwargs): - recvbuf[:] = self._data.get_buffer() - - def Gather(self, sendbuf, recvbuf, root=0, **kwargs): - if recvbuf is not None: - recvbuf[:] = self._data.get_buffer() - - def allgather(self, sendobj): - raise NotImplementedError("allgather not yet implemented for CachingCommReader") - - def Send(self, sendbuf, dest, tag: int = 0, **kwargs): - pass - - def Isend(self, sendbuf, dest, tag: int = 0, **kwargs) -> Request: - return NullRequest() - - def Recv(self, recvbuf, source, tag: int = 0, **kwargs): - recvbuf[:] = self._data.get_buffer() - - def Irecv(self, recvbuf, source, tag: int = 0, **kwargs) -> Request: - return CachingRequestReader(recvbuf, self._data.get_buffer()) - - def sendrecv(self, sendbuf, dest, **kwargs): - raise NotImplementedError() - - def Split(self, color, key) -> "CachingCommReader": - new_data = self._data.get_split() - return CachingCommReader(data=new_data) - - def allreduce(self, sendobj, op=None) -> Any: - return self._data.get_generic_obj() - - @classmethod - def load(cls, file: BinaryIO) -> "CachingCommReader": - data = CachingCommData.load(file) - return cls(data) - - -class CachingCommWriter(Comm): - """ - Wrapper around a mpi4py Comm object which can be serialized and then loaded - as a CachingCommReader. - """ - - def __init__(self, comm: Comm): - """ - Args: - comm: underlying mpi4py comm-like object - """ - self._comm = comm - self._data = CachingCommData( - rank=comm.Get_rank(), - size=comm.Get_size(), - ) - - def Get_rank(self) -> int: - return self._comm.Get_rank() - - def Get_size(self) -> int: - return self._comm.Get_size() - - def bcast(self, value: Optional[T], root=0) -> T: - result = self._comm.bcast(value=value, root=root) - self._data.bcast_objects.append(copy.deepcopy(result)) - return result - - def barrier(self): - return self._comm.barrier() - - def Barrier(self): - pass - - def Scatter(self, sendbuf, recvbuf, root=0, **kwargs): - self._comm.Scatter(sendbuf=sendbuf, recvbuf=recvbuf, root=root, **kwargs) - self._data.received_buffers.append(copy.deepcopy(recvbuf)) - - def Gather(self, sendbuf, recvbuf, root=0, **kwargs): - self._comm.Gather(sendbuf=sendbuf, recvbuf=recvbuf, root=root, **kwargs) - self._data.received_buffers.append(copy.deepcopy(recvbuf)) - - def allgather(self, sendobj): - raise NotImplementedError("allgather not yet implemented for CachingCommReader") - - def Send(self, sendbuf, dest, tag: int = 0, **kwargs): - self._comm.Send(sendbuf=sendbuf, dest=dest, tag=tag, **kwargs) - - def Isend(self, sendbuf, dest, tag: int = 0, **kwargs) -> Request: - return self._comm.Isend(sendbuf, dest, tag=tag, **kwargs) - - def Recv(self, recvbuf, source, tag: int = 0, **kwargs): - self._comm.Recv(recvbuf=recvbuf, source=source, tag=tag, **kwargs) - self._data.received_buffers.append(copy.deepcopy(recvbuf)) - - def Irecv(self, recvbuf, source, tag: int = 0, **kwargs) -> Request: - req = self._comm.Irecv(recvbuf, source, tag=tag, **kwargs) - return CachingRequestWriter( - req=req, buffer=recvbuf, buffer_list=self._data.received_buffers - ) - - def sendrecv(self, sendbuf, dest, **kwargs): - raise NotImplementedError() - - def Split(self, color, key) -> "CachingCommWriter": - new_comm = self._comm.Split(color=color, key=key) - new_wrapper = CachingCommWriter(new_comm) - self._data.split_data.append(new_wrapper._data) - return new_wrapper - - def dump(self, file: BinaryIO): - self._data.dump(file) - - def allreduce(self, sendobj, op=None) -> Any: - result = self._comm.allreduce(sendobj, op) - self._data.generic_obj_buffers.append(copy.deepcopy(result)) - return result diff --git a/util/pace/util/checkpointer/__init__.py b/util/pace/util/checkpointer/__init__.py deleted file mode 100644 index a51a4d9eb..000000000 --- a/util/pace/util/checkpointer/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from .base import Checkpointer -from .null import NullCheckpointer -from .snapshots import SnapshotCheckpointer -from .thresholds import ( - InsufficientTrialsError, - SavepointThresholds, - Threshold, - ThresholdCalibrationCheckpointer, -) -from .validation import ValidationCheckpointer diff --git a/util/pace/util/checkpointer/base.py b/util/pace/util/checkpointer/base.py deleted file mode 100644 index 8218bbfe8..000000000 --- a/util/pace/util/checkpointer/base.py +++ /dev/null @@ -1,7 +0,0 @@ -import abc - - -class Checkpointer(abc.ABC): - @abc.abstractmethod - def __call__(self, savepoint_name, **kwargs): - ... diff --git a/util/pace/util/checkpointer/null.py b/util/pace/util/checkpointer/null.py deleted file mode 100644 index e707d5891..000000000 --- a/util/pace/util/checkpointer/null.py +++ /dev/null @@ -1,6 +0,0 @@ -from .base import Checkpointer - - -class NullCheckpointer(Checkpointer): - def __call__(self, savepoint_name, **kwargs): - pass diff --git a/util/pace/util/checkpointer/snapshots.py b/util/pace/util/checkpointer/snapshots.py deleted file mode 100644 index 97912f6e3..000000000 --- a/util/pace/util/checkpointer/snapshots.py +++ /dev/null @@ -1,75 +0,0 @@ -import collections - -import numpy as np - -from pace.util._optional_imports import cupy as cp -from pace.util._optional_imports import xarray as xr - -from .base import Checkpointer - - -def make_dims(savepoint_dim, label, data_list): - """ - Helper which defines dimension names for an xarray variable. - - Used to ensure no dimensions have the same name but different sizes - when defining xarray datasets. - """ - data = np.concatenate([array[None, :] for array in data_list], axis=0) - dims = [savepoint_dim] + [f"{label}_dim{i}" for i in range(len(data.shape[1:]))] - if cp and isinstance(data, cp.ndarray): - data = data.get() - return dims, data - - -class _Snapshots: - def __init__(self): - self._savepoints = collections.defaultdict(list) - self._arrays = collections.defaultdict(list) - - def store(self, savepoint_name: str, variable_name: str, python_data): - self._savepoints[variable_name].append(savepoint_name) - self._arrays[variable_name].append(python_data) - - @property - def dataset(self) -> "xr.Dataset": - data_vars = {} - for variable_name, savepoint_list in self._savepoints.items(): - savepoint_dim = f"sp_{variable_name}" - data_vars[f"{variable_name}_savepoints"] = ([savepoint_dim], savepoint_list) - data_vars[f"{variable_name}"] = make_dims( - savepoint_dim, variable_name, self._arrays[variable_name] - ) - if xr is None: - raise ModuleNotFoundError( - "xarray must be installed to use Snapshots.dataset" - ) - else: - return xr.Dataset(data_vars=data_vars) - - -class SnapshotCheckpointer(Checkpointer): - """ - Checkpointer which can be used to save datasets showing the evolution - of variables between checkpointer calls. - """ - - def __init__(self, rank: int): - if xr is None: - raise ModuleNotFoundError( - "xarray must be installed to use SnapshotCheckpointer" - ) - self._rank = rank - self._snapshots = _Snapshots() - - def __call__(self, savepoint_name, **kwargs): - for name, value in kwargs.items(): - array_data = np.copy(value.data) - self._snapshots.store(savepoint_name, name, array_data) - - @property - def dataset(self) -> "xr.Dataset": - return self._snapshots.dataset - - def cleanup(self): - self.dataset.to_netcdf(f"comparison_rank{self._rank}.nc") diff --git a/util/pace/util/checkpointer/thresholds.py b/util/pace/util/checkpointer/thresholds.py deleted file mode 100644 index 86133a812..000000000 --- a/util/pace/util/checkpointer/thresholds.py +++ /dev/null @@ -1,162 +0,0 @@ -import collections -import contextlib -import dataclasses -from typing import Dict, List, Mapping, Union - -import numpy as np - -from ..quantity import Quantity -from .base import Checkpointer - - -try: - import cupy as cp -except ImportError: - cp = None - - -SavepointName = str -VariableName = str -ArrayLike = Union[Quantity, np.ndarray] - - -class InsufficientTrialsError(Exception): - pass - - -@dataclasses.dataclass -class Threshold: - relative: float - absolute: float - - def merge(self, other: "Threshold") -> "Threshold": - """ - Provide a threshold which is always satisfied - if both input thresholds are satisfied. - - This is generally a less strict threshold than either input. - """ - return Threshold( - relative=max(self.relative, other.relative), - absolute=max(self.absolute, other.absolute), - ) - - -@dataclasses.dataclass -class SavepointThresholds: - savepoints: Dict[SavepointName, List[Dict[VariableName, Threshold]]] - - -def cast_to_ndarray(array: ArrayLike) -> np.ndarray: - if isinstance(array, Quantity): - array = array.data - if isinstance(array.data, np.ndarray): - return array.data - else: - return array - - -class ThresholdCalibrationCheckpointer(Checkpointer): - """ - Calibrates thresholds to be used by a ValidationCheckpointer. - - Does this by recording the minimum and maximum values seen across trials, - and using them to derive the maximum relative and absolute error one could - have across any pair of trials, then multiplying this by a user-provided factor. - """ - - def __init__(self, factor: float = 1.0): - """ - Args: - factor: set thresholds equal to this factor of the maximum error - seen across trials - """ - # we keep dictionaries (over savepoint name) of lists (over call count) - # of dictionaries (over variable name) of numpy arrays - self._minimums: Mapping[ - SavepointName, List[Mapping[VariableName, np.ndarray]] - ] = collections.defaultdict(list) - self._maximums: Mapping[ - SavepointName, List[Mapping[VariableName, np.ndarray]] - ] = collections.defaultdict(list) - self._factor = factor - self._abs_sums: Mapping[ - SavepointName, List[Mapping[VariableName, np.ndarray]] - ] = collections.defaultdict(list) - self._n_trials = 0 - self._n_calls: Mapping[SavepointName, int] = collections.defaultdict(int) - - def __call__(self, savepoint_name, **kwargs): - """ - Record values for a savepoint. - - Args: - savepoint_name: name of the savepoint - **kwargs: data for the savepoint - """ - i_call = self._n_calls[savepoint_name] - if len(self._minimums[savepoint_name]) < i_call + 1: - self._minimums[savepoint_name].append( - collections.defaultdict(lambda: np.inf) - ) - self._maximums[savepoint_name].append( - collections.defaultdict(lambda: -np.inf) - ) - self._abs_sums[savepoint_name].append(collections.defaultdict(lambda: 0.0)) - for varname, array in kwargs.items(): - array: np.ndarray = cast_to_ndarray(array) - self._minimums[savepoint_name][i_call][varname] = np.minimum( - self._minimums[savepoint_name][i_call][varname], array - ) - self._maximums[savepoint_name][i_call][varname] = np.maximum( - self._maximums[savepoint_name][i_call][varname], array - ) - self._abs_sums[savepoint_name][i_call][varname] += np.abs(array) - - self._n_calls[savepoint_name] += 1 - - @contextlib.contextmanager - def trial(self): - """ - Context manager for a trial. - - A new context manager should entered each time the code being - calibrated is called, and exited at the end of code execution. - If each of these calls is done with slightly perturbed inputs, - this calibrator will be able to estimate an error tolerance for - each savepoint call. - """ - for name in self._n_calls: - self._n_calls[name] = 0 - yield - self._n_trials += 1 - - @property - def thresholds( - self, - ) -> SavepointThresholds: - if self._n_trials < 2: - raise InsufficientTrialsError( - "at least 2 trials required to generate thresholds" - ) - savepoints: Dict[SavepointName, List[Dict[VariableName, Threshold]]] = {} - for savepoint_name in self._minimums: - savepoints[savepoint_name] = [] - for i_call in range(self._n_calls[savepoint_name]): - savepoints[savepoint_name].append({}) - for varname, minimum in self._minimums[savepoint_name][i_call].items(): - maximum = self._maximums[savepoint_name][i_call][varname] - mean_abs = ( - self._abs_sums[savepoint_name][i_call][varname] / self._n_trials - ) - if np.all(mean_abs == 0.0): - relative = 0.0 - else: - relative = self._factor * np.nanmax( - (maximum - minimum) / mean_abs - ) - savepoints[savepoint_name][i_call][varname] = Threshold( - relative=float(relative), - absolute=float(self._factor * np.max(maximum - minimum)), - ) - return SavepointThresholds(savepoints=savepoints) diff --git a/util/pace/util/checkpointer/validation.py b/util/pace/util/checkpointer/validation.py deleted file mode 100644 index 2a50f5b67..000000000 --- a/util/pace/util/checkpointer/validation.py +++ /dev/null @@ -1,143 +0,0 @@ -import collections -import contextlib -import os.path -from typing import MutableMapping, Tuple - -import numpy as np - -from pace.util._optional_imports import xarray as xr - -from .base import Checkpointer -from .thresholds import ArrayLike, SavepointName, SavepointThresholds, cast_to_ndarray - - -def _clip_pace_array_to_target( - array: np.ndarray, target_shape: Tuple[int, ...] -) -> np.ndarray: - """ - Clip an array from pace to align it to a target shape from target serialized data. - - Assumes the target shape has the same number of halo points - at the start and end of each axis. - - Assumes the input array has the same number of halo points at the start and end of - each axis, but with an additional buffer point at the end of each axis if the - data is defined on cell centers. - - Args: - array: array to clip - target_shape: shape of target array - """ - array = _remove_buffer_if_needed(array, target_shape) - return _remove_symmetric_halos(array, target_shape) - - -def _remove_buffer_if_needed(array: np.ndarray, target_shape: Tuple[int, ...]): - selection = [] - # both arrays are assumed to have the same staggering and an even number of - # halo points for each dimension, so any odd difference in points must be - # due to a buffer point in the pace array - # (fortran data is assumed to never have buffer points) - for array_len, target_len in zip(array.shape, target_shape): - if (array_len - target_len) % 2 == 1: - # clip the buffer point - selection.append(slice(0, -1)) - else: - selection.append(slice(None, None)) - return array[tuple(selection)] - - -def _remove_symmetric_halos(array: np.ndarray, target_shape: Tuple[int, ...]): - selection = [] - for array_len, target_len in zip(array.shape, target_shape): - n_halo_clip = (array_len - target_len) // 2 - if n_halo_clip == 0: - selection.append(slice(None, None)) - else: - selection.append(slice(n_halo_clip, -n_halo_clip)) - return array[tuple(selection)] - - -class ValidationCheckpointer(Checkpointer): - """ - Checkpointer which can be used to validate the output of a test. - """ - - def __init__( - self, - savepoint_data_path: str, - thresholds: SavepointThresholds, - rank: int, - ): - """ - Args: - savepoint_data_path: path to directory containing netcdf savepoint data - thresholds: thresholds to check against - rank: rank of the process, needed to compare against - the correct savepoint data - """ - self._savepoint_data_path = savepoint_data_path - self._thresholds = thresholds - self._rank = rank - self._n_calls: MutableMapping[SavepointName, int] = collections.defaultdict(int) - - @contextlib.contextmanager - def trial(self): - """ - Context manager for a trial. - - When entered, resets reference data comparison back to the start of the data. - - A new context manager should entered before the code being tested is called, - and exited at the end of code execution. - """ - self._n_calls = collections.defaultdict(int) - yield - - def __call__(self, savepoint_name: str, **kwargs: ArrayLike) -> None: - """ - Checks the arrays passed as keyword arguments against thresholds specified. - - Args: - savepoint_name: name of the savepoint - **kwargs: array data for variables in that savepoint - - Raises: - AssertionError: if the thresholds on any variable are not met - """ - if xr is None: - raise ModuleNotFoundError("xarray is not installed") - nc_file = os.path.join(self._savepoint_data_path, savepoint_name + ".nc") - ds = xr.open_dataset(nc_file) - - n_calls = self._n_calls[savepoint_name] - var_thresholds = self._thresholds.savepoints[savepoint_name][n_calls] - for varname, array in kwargs.items(): - if varname not in ds: - raise ValueError(f"argument {varname} not in netCDF file {nc_file}") - - expected = ds[varname][n_calls, self._rank].values - output = _clip_pace_array_to_target(cast_to_ndarray(array), expected.shape) - - # cannot use relative threshold when comparing to zero value - expected_not_zero = expected != 0 - rtol = var_thresholds[varname].relative - atol = var_thresholds[varname].absolute - if not np.isnan(rtol): - np.testing.assert_allclose( - output[expected_not_zero], - expected[expected_not_zero], - rtol=var_thresholds[varname].relative, - atol=0.0, - err_msg=varname, - ) - - if not np.isnan(atol): - np.testing.assert_allclose( - output, - expected, - atol=var_thresholds[varname].absolute, - rtol=0.0, - err_msg=varname, - ) - self._n_calls[savepoint_name] += 1 diff --git a/util/pace/util/comm.py b/util/pace/util/comm.py deleted file mode 100644 index 77f565864..000000000 --- a/util/pace/util/comm.py +++ /dev/null @@ -1,73 +0,0 @@ -import abc -from typing import List, Optional, TypeVar - - -T = TypeVar("T") - - -class Request(abc.ABC): - @abc.abstractmethod - def wait(self): - ... - - -class Comm(abc.ABC): - @abc.abstractmethod - def Get_rank(self) -> int: - ... - - @abc.abstractmethod - def Get_size(self) -> int: - ... - - @abc.abstractmethod - def bcast(self, value: Optional[T], root=0) -> T: - ... - - @abc.abstractmethod - def barrier(self): - ... - - @abc.abstractmethod - def Barrier(self): - ... - - @abc.abstractmethod - def Scatter(self, sendbuf, recvbuf, root=0, **kwargs): - ... - - @abc.abstractmethod - def Gather(self, sendbuf, recvbuf, root=0, **kwargs): - ... - - @abc.abstractmethod - def allgather(self, sendobj: T) -> List[T]: - ... - - @abc.abstractmethod - def Send(self, sendbuf, dest, tag: int = 0, **kwargs): - ... - - @abc.abstractmethod - def sendrecv(self, sendbuf, dest, **kwargs): - ... - - @abc.abstractmethod - def Isend(self, sendbuf, dest, tag: int = 0, **kwargs) -> Request: - ... - - @abc.abstractmethod - def Recv(self, recvbuf, source, tag: int = 0, **kwargs): - ... - - @abc.abstractmethod - def Irecv(self, recvbuf, source, tag: int = 0, **kwargs) -> Request: - ... - - @abc.abstractmethod - def Split(self, color, key) -> "Comm": - ... - - @abc.abstractmethod - def allreduce(self, sendobj: T, op=None) -> T: - ... diff --git a/util/pace/util/communicator.py b/util/pace/util/communicator.py deleted file mode 100644 index e88d852e3..000000000 --- a/util/pace/util/communicator.py +++ /dev/null @@ -1,803 +0,0 @@ -import abc -from typing import List, Mapping, Optional, Sequence, Tuple, Union, cast - -import numpy as np - -from . import constants -from ._timing import NullTimer, Timer -from .boundary import Boundary -from .buffer import array_buffer, recv_buffer, send_buffer -from .halo_updater import HaloUpdater, HaloUpdateRequest, VectorInterfaceHaloUpdater -from .partitioner import CubedSpherePartitioner, Partitioner, TilePartitioner -from .quantity import Quantity, QuantityHaloSpec, QuantityMetadata -from .types import NumpyModule -from .utils import device_synchronize - - -try: - import cupy -except ImportError: - cupy = None - - -def to_numpy(array, dtype=None) -> np.ndarray: - """ - Input array can be a numpy array or a cupy array. Returns numpy array. - """ - try: - output = np.asarray(array) - except ValueError as err: - if err.args[0] == "object __array__ method not producing an array": - output = cupy.asnumpy(array) - else: - raise err - except TypeError as err: - if err.args[0].startswith( - "Implicit conversion to a NumPy array is not allowed." - ): - output = cupy.asnumpy(array) - else: - raise err - if dtype: - output = output.astype(dtype=dtype) - return output - - -def bcast_metadata_list(comm, quantity_list): - is_root = comm.Get_rank() == constants.ROOT_RANK - if is_root: - metadata_list = [] - for quantity in quantity_list: - metadata_list.append(quantity.metadata) - else: - metadata_list = None - return comm.bcast(metadata_list, root=constants.ROOT_RANK) - - -def bcast_metadata(comm, array): - return bcast_metadata_list(comm, [array])[0] - - -class Communicator(abc.ABC): - def __init__( - self, comm, partitioner, force_cpu: bool = False, timer: Optional[Timer] = None - ): - self.comm = comm - self.partitioner: Partitioner = partitioner - self._force_cpu = force_cpu - self._boundaries: Optional[Mapping[int, Boundary]] = None - self._last_halo_tag = 0 - self.timer: Timer = timer if timer is not None else NullTimer() - - @abc.abstractproperty - def tile(self) -> "TileCommunicator": - pass - - @classmethod - @abc.abstractmethod - def from_layout( - cls, - comm, - layout: Tuple[int, int], - force_cpu: bool = False, - timer: Optional[Timer] = None, - ): - pass - - @property - def rank(self) -> int: - """rank of the current process within this communicator""" - return self.comm.Get_rank() - - @property - def size(self) -> int: - """Total number of ranks in this communicator""" - return self.comm.Get_size() - - def _maybe_force_cpu(self, module: NumpyModule) -> NumpyModule: - """ - Get a numpy-like module depending on configuration and - Quantity original allocator. - """ - if self._force_cpu: - return np - return module - - @staticmethod - def _device_synchronize(): - """Wait for all work that could be in-flight to finish.""" - # this is a method so we can profile it separately from other device syncs - device_synchronize() - - def _Scatter(self, numpy_module, sendbuf, recvbuf, **kwargs): - with send_buffer(numpy_module.zeros, sendbuf) as send, recv_buffer( - numpy_module.zeros, recvbuf - ) as recv: - self.comm.Scatter(send, recv, **kwargs) - - def _Gather(self, numpy_module, sendbuf, recvbuf, **kwargs): - with send_buffer(numpy_module.zeros, sendbuf) as send, recv_buffer( - numpy_module.zeros, recvbuf - ) as recv: - self.comm.Gather(send, recv, **kwargs) - - def scatter( - self, - send_quantity: Optional[Quantity] = None, - recv_quantity: Optional[Quantity] = None, - ) -> Quantity: - """Transfer subtile regions of a full-tile quantity - from the tile root rank to all subtiles. - - Args: - send_quantity: quantity to send, only required/used on the tile root rank - recv_quantity: if provided, assign received data into this Quantity. - Returns: - recv_quantity - """ - if self.rank == constants.ROOT_RANK and send_quantity is None: - raise TypeError("send_quantity is a required argument on the root rank") - if self.rank == constants.ROOT_RANK: - send_quantity = cast(Quantity, send_quantity) - metadata = self.comm.bcast(send_quantity.metadata, root=constants.ROOT_RANK) - else: - metadata = self.comm.bcast(None, root=constants.ROOT_RANK) - shape = self.partitioner.subtile_extent(metadata, self.rank) - if recv_quantity is None: - recv_quantity = self._get_scatter_recv_quantity(shape, metadata) - if self.rank == constants.ROOT_RANK: - send_quantity = cast(Quantity, send_quantity) - with array_buffer( - self._maybe_force_cpu(metadata.np).zeros, - (self.partitioner.total_ranks,) + shape, - dtype=metadata.dtype, - ) as sendbuf: - for rank in range(0, self.partitioner.total_ranks): - subtile_slice = self.partitioner.subtile_slice( - rank=rank, - global_dims=metadata.dims, - global_extent=metadata.extent, - overlap=True, - ) - sendbuf.assign_from( - send_quantity.view[subtile_slice], - buffer_slice=np.index_exp[rank, :], - ) - self._Scatter( - metadata.np, - sendbuf.array, - recv_quantity.view[:], - root=constants.ROOT_RANK, - ) - else: - self._Scatter( - metadata.np, - None, - recv_quantity.view[:], - root=constants.ROOT_RANK, - ) - return recv_quantity - - def _get_gather_recv_quantity( - self, global_extent: Sequence[int], send_metadata: QuantityMetadata - ) -> Quantity: - """Initialize a Quantity for use when receiving global data during gather""" - recv_quantity = Quantity( - send_metadata.np.zeros(global_extent, dtype=send_metadata.dtype), - dims=send_metadata.dims, - units=send_metadata.units, - origin=tuple([0 for dim in send_metadata.dims]), - extent=global_extent, - gt4py_backend=send_metadata.gt4py_backend, - allow_mismatch_float_precision=True, - ) - return recv_quantity - - def _get_scatter_recv_quantity( - self, shape: Sequence[int], send_metadata: QuantityMetadata - ) -> Quantity: - """Initialize a Quantity for use when receiving subtile data during scatter""" - recv_quantity = Quantity( - send_metadata.np.zeros(shape, dtype=send_metadata.dtype), - dims=send_metadata.dims, - units=send_metadata.units, - gt4py_backend=send_metadata.gt4py_backend, - allow_mismatch_float_precision=True, - ) - return recv_quantity - - def gather( - self, send_quantity: Quantity, recv_quantity: Quantity = None - ) -> Optional[Quantity]: - """Transfer subtile regions of a full-tile quantity - from each rank to the tile root rank. - - Args: - send_quantity: quantity to send - recv_quantity: if provided, assign received data into this Quantity (only - used on the tile root rank) - Returns: - recv_quantity: quantity if on root rank, otherwise None - """ - result: Optional[Quantity] - if self.rank == constants.ROOT_RANK: - with array_buffer( - send_quantity.np.zeros, - (self.partitioner.total_ranks,) + tuple(send_quantity.extent), - dtype=send_quantity.data.dtype, - ) as recvbuf: - self._Gather( - send_quantity.np, - send_quantity.view[:], - recvbuf.array, - root=constants.ROOT_RANK, - ) - if recv_quantity is None: - global_extent = self.partitioner.global_extent( - send_quantity.metadata - ) - recv_quantity = self._get_gather_recv_quantity( - global_extent, send_quantity.metadata - ) - for rank in range(self.partitioner.total_ranks): - to_slice = self.partitioner.subtile_slice( - rank=rank, - global_dims=recv_quantity.dims, - global_extent=recv_quantity.extent, - overlap=True, - ) - recvbuf.assign_to( - recv_quantity.view[to_slice], buffer_slice=np.index_exp[rank, :] - ) - result = recv_quantity - else: - self._Gather( - send_quantity.np, - send_quantity.view[:], - None, - root=constants.ROOT_RANK, - ) - result = None - return result - - def gather_state(self, send_state=None, recv_state=None, transfer_type=None): - """Transfer a state dictionary from subtile ranks to the tile root rank. - - 'time' is assumed to be the same on all ranks, and its value will be set - to the value from the root rank. - - Args: - send_state: the model state to be sent containing the subtile data - recv_state: the pre-allocated state in which to recieve the full tile - state. Only variables which are scattered will be written to. - Returns: - recv_state: on the root rank, the state containing the entire tile - """ - if self.rank == constants.ROOT_RANK and recv_state is None: - recv_state = {} - for name, quantity in send_state.items(): - if name == "time": - if self.rank == constants.ROOT_RANK: - recv_state["time"] = send_state["time"] - else: - gather_value = to_numpy(quantity.view[:], dtype=transfer_type) - gather_quantity = Quantity( - data=gather_value, - dims=quantity.dims, - units=quantity.units, - allow_mismatch_float_precision=True, - ) - if recv_state is not None and name in recv_state: - tile_quantity = self.gather( - gather_quantity, recv_quantity=recv_state[name] - ) - else: - tile_quantity = self.gather(gather_quantity) - if self.rank == constants.ROOT_RANK: - recv_state[name] = tile_quantity - del gather_quantity - return recv_state - - def scatter_state(self, send_state=None, recv_state=None): - """Transfer a state dictionary from the tile root rank to all subtiles. - - Args: - send_state: the model state to be sent containing the entire tile, - required only from the root rank - recv_state: the pre-allocated state in which to recieve the scattered - state. Only variables which are scattered will be written to. - Returns: - rank_state: the state corresponding to this rank's subdomain - """ - - def scatter_root(): - if send_state is None: - raise TypeError("send_state is a required argument on the root rank") - name_list = list(send_state.keys()) - while "time" in name_list: - name_list.remove("time") - name_list = self.comm.bcast(name_list, root=constants.ROOT_RANK) - array_list = [send_state[name] for name in name_list] - for name, array in zip(name_list, array_list): - if name in recv_state: - self.scatter(send_quantity=array, recv_quantity=recv_state[name]) - else: - recv_state[name] = self.scatter(send_quantity=array) - recv_state["time"] = self.comm.bcast( - send_state.get("time", None), root=constants.ROOT_RANK - ) - - def scatter_client(): - name_list = self.comm.bcast(None, root=constants.ROOT_RANK) - for name in name_list: - if name in recv_state: - self.scatter(recv_quantity=recv_state[name]) - else: - recv_state[name] = self.scatter() - recv_state["time"] = self.comm.bcast(None, root=constants.ROOT_RANK) - - if recv_state is None: - recv_state = {} - if self.rank == constants.ROOT_RANK: - scatter_root() - else: - scatter_client() - if recv_state["time"] is None: - recv_state.pop("time") - return recv_state - - def halo_update(self, quantity: Union[Quantity, List[Quantity]], n_points: int): - """Perform a halo update on a quantity or quantities - - Args: - quantity: the quantity to be updated - n_points: how many halo points to update, starting from the interior - """ - if isinstance(quantity, Quantity): - quantities = [quantity] - else: - quantities = quantity - - halo_updater = self.start_halo_update(quantities, n_points) - halo_updater.wait() - - def start_halo_update( - self, quantity: Union[Quantity, List[Quantity]], n_points: int - ) -> HaloUpdater: - """Start an asynchronous halo update on a quantity. - - Args: - quantity: the quantity to be updated - n_points: how many halo points to update, starting from the interior - - Returns: - request: an asynchronous request object with a .wait() method - """ - if isinstance(quantity, Quantity): - quantities = [quantity] - else: - quantities = quantity - - specifications = [] - for quantity in quantities: - specification = QuantityHaloSpec( - n_points=n_points, - shape=quantity.data.shape, - strides=quantity.data.strides, - itemsize=quantity.data.itemsize, - origin=quantity.origin, - extent=quantity.extent, - dims=quantity.dims, - numpy_module=self._maybe_force_cpu(quantity.np), - dtype=quantity.metadata.dtype, - ) - specifications.append(specification) - - halo_updater = self.get_scalar_halo_updater(specifications) - halo_updater.force_finalize_on_wait() - halo_updater.start(quantities) - return halo_updater - - def vector_halo_update( - self, - x_quantity: Union[Quantity, List[Quantity]], - y_quantity: Union[Quantity, List[Quantity]], - n_points: int, - ): - """Perform a halo update of a horizontal vector quantity or quantities. - - Assumes the x and y dimension indices are the same between the two quantities. - - Args: - x_quantity: the x-component quantity to be halo updated - y_quantity: the y-component quantity to be halo updated - n_points: how many halo points to update, starting at the interior - """ - if isinstance(x_quantity, Quantity): - x_quantities = [x_quantity] - else: - x_quantities = x_quantity - if isinstance(y_quantity, Quantity): - y_quantities = [y_quantity] - else: - y_quantities = y_quantity - - halo_updater = self.start_vector_halo_update( - x_quantities, y_quantities, n_points - ) - halo_updater.wait() - - def start_vector_halo_update( - self, - x_quantity: Union[Quantity, List[Quantity]], - y_quantity: Union[Quantity, List[Quantity]], - n_points: int, - ) -> HaloUpdater: - """Start an asynchronous halo update of a horizontal vector quantity. - - Assumes the x and y dimension indices are the same between the two quantities. - - Args: - x_quantity: the x-component quantity to be halo updated - y_quantity: the y-component quantity to be halo updated - n_points: how many halo points to update, starting at the interior - - Returns: - request: an asynchronous request object with a .wait() method - """ - if isinstance(x_quantity, Quantity): - x_quantities = [x_quantity] - else: - x_quantities = x_quantity - if isinstance(y_quantity, Quantity): - y_quantities = [y_quantity] - else: - y_quantities = y_quantity - - x_specifications = [] - y_specifications = [] - for x_quantity, y_quantity in zip(x_quantities, y_quantities): - x_specification = QuantityHaloSpec( - n_points=n_points, - shape=x_quantity.data.shape, - strides=x_quantity.data.strides, - itemsize=x_quantity.data.itemsize, - origin=x_quantity.metadata.origin, - extent=x_quantity.metadata.extent, - dims=x_quantity.metadata.dims, - numpy_module=self._maybe_force_cpu(x_quantity.np), - dtype=x_quantity.metadata.dtype, - ) - x_specifications.append(x_specification) - y_specification = QuantityHaloSpec( - n_points=n_points, - shape=y_quantity.data.shape, - strides=y_quantity.data.strides, - itemsize=y_quantity.data.itemsize, - origin=y_quantity.metadata.origin, - extent=y_quantity.metadata.extent, - dims=y_quantity.metadata.dims, - numpy_module=self._maybe_force_cpu(y_quantity.np), - dtype=y_quantity.metadata.dtype, - ) - y_specifications.append(y_specification) - - halo_updater = self.get_vector_halo_updater(x_specifications, y_specifications) - halo_updater.force_finalize_on_wait() - halo_updater.start(x_quantities, y_quantities) - return halo_updater - - def synchronize_vector_interfaces(self, x_quantity: Quantity, y_quantity: Quantity): - """ - Synchronize shared points at the edges of a vector interface variable. - - Sends the values on the south and west edges to overwrite the values on adjacent - subtiles. Vector must be defined on the Arakawa C grid. - - For interface variables, the edges of the tile are computed on both ranks - bordering that edge. This routine copies values across those shared edges - so that both ranks have the same value for that edge. It also handles any - rotation of vector quantities needed to move data across the edge. - - Args: - x_quantity: the x-component quantity to be synchronized - y_quantity: the y-component quantity to be synchronized - """ - req = self.start_synchronize_vector_interfaces(x_quantity, y_quantity) - req.wait() - - def start_synchronize_vector_interfaces( - self, x_quantity: Quantity, y_quantity: Quantity - ) -> HaloUpdateRequest: - """ - Synchronize shared points at the edges of a vector interface variable. - - Sends the values on the south and west edges to overwrite the values on adjacent - subtiles. Vector must be defined on the Arakawa C grid. - - For interface variables, the edges of the tile are computed on both ranks - bordering that edge. This routine copies values across those shared edges - so that both ranks have the same value for that edge. It also handles any - rotation of vector quantities needed to move data across the edge. - - Args: - x_quantity: the x-component quantity to be synchronized - y_quantity: the y-component quantity to be synchronized - - Returns: - request: an asynchronous request object with a .wait() method - """ - halo_updater = VectorInterfaceHaloUpdater( - comm=self.comm, - boundaries=self.boundaries, - force_cpu=self._force_cpu, - timer=self.timer, - ) - req = halo_updater.start_synchronize_vector_interfaces(x_quantity, y_quantity) - return req - - def get_scalar_halo_updater(self, specifications: List[QuantityHaloSpec]): - if len(specifications) == 0: - raise RuntimeError("Cannot create updater with specifications list") - if specifications[0].n_points == 0: - raise ValueError("cannot perform a halo update on zero halo points") - return HaloUpdater.from_scalar_specifications( - self, - self._maybe_force_cpu(specifications[0].numpy_module), - specifications, - self.boundaries.values(), - self._get_halo_tag(), - self.timer, - ) - - def get_vector_halo_updater( - self, - specifications_x: List[QuantityHaloSpec], - specifications_y: List[QuantityHaloSpec], - ): - if len(specifications_x) == 0 and len(specifications_y) == 0: - raise RuntimeError("Cannot create updater with empty specifications list") - if specifications_x[0].n_points == 0 and specifications_y[0].n_points == 0: - raise ValueError("Cannot perform a halo update on zero halo points") - return HaloUpdater.from_vector_specifications( - self, - self._maybe_force_cpu(specifications_x[0].numpy_module), - specifications_x, - specifications_y, - self.boundaries.values(), - self._get_halo_tag(), - self.timer, - ) - - def _get_halo_tag(self) -> int: - self._last_halo_tag += 1 - return self._last_halo_tag - - @property - def boundaries(self) -> Mapping[int, Boundary]: - """boundaries of this tile with neighboring tiles""" - if self._boundaries is None: - self._boundaries = {} - for boundary_type in constants.BOUNDARY_TYPES: - boundary = self.partitioner.boundary(boundary_type, self.rank) - if boundary is not None: - self._boundaries[boundary_type] = boundary - return self._boundaries - - -class TileCommunicator(Communicator): - """Performs communications within a single tile or region of a tile""" - - def __init__( - self, - comm, - partitioner: TilePartitioner, - force_cpu: bool = False, - timer: Optional[Timer] = None, - ): - """Initialize a TileCommunicator. - - Args: - comm: communication object behaving like mpi4py.Comm - partitioner: tile partitioner - force_cpu: force all communication to go through central memory - timer: Time communication operations. - """ - super(TileCommunicator, self).__init__( - comm, partitioner, force_cpu=force_cpu, timer=timer - ) - self.partitioner: TilePartitioner = partitioner - - @classmethod - def from_layout( - cls, - comm, - layout: Tuple[int, int], - force_cpu: bool = False, - timer: Optional[Timer] = None, - ) -> "TileCommunicator": - partitioner = TilePartitioner(layout=layout) - return cls(comm=comm, partitioner=partitioner, force_cpu=force_cpu, timer=timer) - - @property - def tile(self): - return self - - def start_halo_update( - self, quantity: Union[Quantity, List[Quantity]], n_points: int - ) -> HaloUpdater: - """Start an asynchronous halo update on a quantity. - - Args: - quantity: the quantity to be updated - n_points: how many halo points to update, starting from the interior - - Returns: - request: an asynchronous request object with a .wait() method - """ - if self.partitioner.layout[0] < 3 or self.partitioner.layout[1] < 3: - raise NotImplementedError( - "implementing halo updates on smaller layouts requires " - "refactoring our code to remove the assumption that any pair " - "of ranks only share one boundary" - ) - else: - return super().start_halo_update(quantity, n_points) - - def start_vector_halo_update( - self, - x_quantity: Union[Quantity, List[Quantity]], - y_quantity: Union[Quantity, List[Quantity]], - n_points: int, - ) -> HaloUpdater: - """Start an asynchronous halo update of a horizontal vector quantity. - - Assumes the x and y dimension indices are the same between the two quantities. - - Args: - x_quantity: the x-component quantity to be halo updated - y_quantity: the y-component quantity to be halo updated - n_points: how many halo points to update, starting at the interior - - Returns: - request: an asynchronous request object with a .wait() method - """ - if self.partitioner.layout[0] < 3 or self.partitioner.layout[1] < 3: - raise NotImplementedError( - "implementing halo updates on smaller layouts requires " - "refactoring our code to remove the assumption that any pair " - "of ranks only share one boundary" - ) - else: - return super().start_vector_halo_update(x_quantity, y_quantity, n_points) - - def start_synchronize_vector_interfaces( - self, x_quantity: Quantity, y_quantity: Quantity - ) -> HaloUpdateRequest: - """ - Synchronize shared points at the edges of a vector interface variable. - - Sends the values on the south and west edges to overwrite the values on adjacent - subtiles. Vector must be defined on the Arakawa C grid. - - For interface variables, the edges of the tile are computed on both ranks - bordering that edge. This routine copies values across those shared edges - so that both ranks have the same value for that edge. It also handles any - rotation of vector quantities needed to move data across the edge. - - Args: - x_quantity: the x-component quantity to be synchronized - y_quantity: the y-component quantity to be synchronized - - Returns: - request: an asynchronous request object with a .wait() method - """ - if self.partitioner.layout[0] < 3 or self.partitioner.layout[1] < 3: - raise NotImplementedError( - "implementing halo updates on smaller layouts requires " - "refactoring our code to remove the assumption that any pair " - "of ranks only share one boundary" - ) - else: - return super().start_synchronize_vector_interfaces(x_quantity, y_quantity) - - -class CubedSphereCommunicator(Communicator): - """Performs communications within a cubed sphere""" - - timer: Timer - partitioner: CubedSpherePartitioner - - def __init__( - self, - comm, - partitioner: CubedSpherePartitioner, - force_cpu: bool = False, - timer: Optional[Timer] = None, - ): - """Initialize a CubedSphereCommunicator. - - Args: - comm: mpi4py.Comm object - partitioner: cubed sphere partitioner - force_cpu: Force all communication to go through central memory. - timer: Time communication operations. - """ - if comm.Get_size() != partitioner.total_ranks: - raise ValueError( - f"was given a partitioner for {partitioner.total_ranks} ranks but a " - f"comm object with only {comm.Get_size()} ranks, are we running " - "with mpi and the correct number of ranks?" - ) - self._tile_communicator: Optional[TileCommunicator] = None - self._force_cpu = force_cpu - super(CubedSphereCommunicator, self).__init__( - comm, partitioner, force_cpu, timer - ) - self.partitioner: CubedSpherePartitioner = partitioner - - @classmethod - def from_layout( - cls, - comm, - layout: Tuple[int, int], - force_cpu: bool = False, - timer: Optional[Timer] = None, - ) -> "CubedSphereCommunicator": - partitioner = CubedSpherePartitioner(tile=TilePartitioner(layout=layout)) - return cls(comm=comm, partitioner=partitioner, force_cpu=force_cpu, timer=timer) - - @property - def tile(self) -> TileCommunicator: - """communicator for within a tile""" - if self._tile_communicator is None: - self._initialize_tile_communicator() - return cast(TileCommunicator, self._tile_communicator) - - def _initialize_tile_communicator(self): - tile_comm = self.comm.Split( - color=self.partitioner.tile_index(self.rank), key=self.rank - ) - self._tile_communicator = TileCommunicator(tile_comm, self.partitioner.tile) - - def _get_gather_recv_quantity( - self, global_extent: Sequence[int], metadata: QuantityMetadata - ) -> Quantity: - """Initialize a Quantity for use when receiving global data during gather - - Args: - shape: ndarray shape, numpy-style - metadata: metadata to the created Quantity - """ - # needs to change the quantity dimensions since we add a "tile" dimension, - # unlike for tile scatter/gather which retains the same dimensions - recv_quantity = Quantity( - metadata.np.zeros(global_extent, dtype=metadata.dtype), - dims=(constants.TILE_DIM,) + metadata.dims, - units=metadata.units, - origin=(0,) + tuple([0 for dim in metadata.dims]), - extent=global_extent, - gt4py_backend=metadata.gt4py_backend, - allow_mismatch_float_precision=True, - ) - return recv_quantity - - def _get_scatter_recv_quantity( - self, shape: Sequence[int], metadata: QuantityMetadata - ) -> Quantity: - """Initialize a Quantity for use when receiving subtile data during scatter - - Args: - shape: ndarray shape, numpy-style - metadata: metadata to the created Quantity - """ - # needs to change the quantity dimensions since we remove a "tile" dimension, - # unlike for tile scatter/gather which retains the same dimensions - recv_quantity = Quantity( - metadata.np.zeros(shape, dtype=metadata.dtype), - dims=metadata.dims[1:], - units=metadata.units, - gt4py_backend=metadata.gt4py_backend, - allow_mismatch_float_precision=True, - ) - return recv_quantity diff --git a/util/pace/util/constants.py b/util/pace/util/constants.py deleted file mode 100644 index a470581d3..000000000 --- a/util/pace/util/constants.py +++ /dev/null @@ -1,153 +0,0 @@ -import os -from enum import Enum - -from pace.util.logging import pace_log - - -# The FV3GFS model ships with two sets of constants, one used in the GFS physics -# package and the other used for the Dycore. Their difference are small but significant -# In addition the GSFC's GEOS model as its own variables -class ConstantVersions(Enum): - GFDL = "GFDL" # NOAA's FV3 dynamical core constants (original port) - GFS = "GFS" # Constant as defined in NOAA GFS - GEOS = "GEOS" # Constant as defined in GEOS v13 - - -CONST_VERSION_AS_STR = os.environ.get("PACE_CONSTANTS", "GFS") - -try: - CONST_VERSION = ConstantVersions[CONST_VERSION_AS_STR] - pace_log.info(f"Constant selected: {CONST_VERSION}") -except KeyError as e: - raise RuntimeError(f"Constants {CONST_VERSION_AS_STR} is not implemented, abort.") - -##################### -# Common constants -##################### - -ROOT_RANK = 0 -X_DIM = "x" -X_INTERFACE_DIM = "x_interface" -Y_DIM = "y" -Y_INTERFACE_DIM = "y_interface" -Z_DIM = "z" -Z_INTERFACE_DIM = "z_interface" -Z_SOIL_DIM = "z_soil" -TILE_DIM = "tile" -X_DIMS = (X_DIM, X_INTERFACE_DIM) -Y_DIMS = (Y_DIM, Y_INTERFACE_DIM) -Z_DIMS = (Z_DIM, Z_INTERFACE_DIM) -HORIZONTAL_DIMS = X_DIMS + Y_DIMS -INTERFACE_DIMS = (X_INTERFACE_DIM, Y_INTERFACE_DIM, Z_INTERFACE_DIM) -SPATIAL_DIMS = X_DIMS + Y_DIMS + Z_DIMS - -WEST = 0 -EAST = 1 -NORTH = 2 -SOUTH = 3 -NORTHWEST = 4 -NORTHEAST = 5 -SOUTHWEST = 6 -SOUTHEAST = 7 -INTERIOR = 8 -EDGE_BOUNDARY_TYPES = (NORTH, SOUTH, WEST, EAST) -CORNER_BOUNDARY_TYPES = (NORTHWEST, NORTHEAST, SOUTHWEST, SOUTHEAST) -BOUNDARY_TYPES = EDGE_BOUNDARY_TYPES + CORNER_BOUNDARY_TYPES -N_HALO_DEFAULT = 3 - -####################### -# Tracers configuration -####################### - -# nq is actually given by ncnst - pnats, where those are given in atmosphere.F90 by: -# ncnst = Atm(mytile)%ncnst -# pnats = Atm(mytile)%flagstruct%pnats -# here we hard-coded it because 8 is the only supported value, refactor this later! -if CONST_VERSION == ConstantVersions.GEOS: - # 'qlcd' is exchanged in GEOS - NQ = 9 -elif CONST_VERSION == ConstantVersions.GFS or CONST_VERSION == ConstantVersions.GFDL: - NQ = 8 -else: - raise RuntimeError("Constant selector failed, bad code.") - -##################### -# Physical constants -##################### -if CONST_VERSION == ConstantVersions.GEOS: - RADIUS = 6.371e6 - PI = 3.14159265358979323846 - OMEGA = 2.0 * PI / 86164.0 - GRAV = 9.80665 - RGRAV = 1.0 / GRAV - RDGAS = 8314.47 / 28.965 - RVGAS = 8314.47 / 18.015 - HLV = 2.4665e6 - HLF = 3.3370e5 - KAPPA = RDGAS / (3.5 * RDGAS) - CP_AIR = RDGAS / KAPPA - TFREEZE = 273.15 - SAT_ADJUST_THRESHOLD = 1.0e-6 -elif CONST_VERSION == ConstantVersions.GFS: - RADIUS = 6.3712e6 # Radius of the Earth [m] - PI = 3.1415926535897931 - OMEGA = 7.2921e-5 # Rotation of the earth - GRAV = 9.80665 # Acceleration due to gravity [m/s^2].04 - RGRAV = 1.0 / GRAV # Inverse of gravitational acceleration - RDGAS = 287.05 # Gas constant for dry air [J/kg/deg] # 287.04 - RVGAS = 461.50 # Gas constant for water vapor [J/kg/deg] - HLV = 2.5e6 # Latent heat of evaporation [J/kg] - HLF = 3.3358e5 # Latent heat of fusion [J/kg] # 3.34e5 - CP_AIR = 1004.6 - KAPPA = RDGAS / CP_AIR # Specific heat capacity of dry air at - TFREEZE = 273.15 - SAT_ADJUST_THRESHOLD = 1.0e-8 -elif CONST_VERSION == ConstantVersions.GFDL: - RADIUS = 6371.0e3 # Radius of the Earth [m] #6371.0e3 - PI = 3.14159265358979323846 # 3.14159265358979323846 - OMEGA = 7.292e-5 # Rotation of the earth # 7.292e-5 - GRAV = 9.80 # Acceleration due to gravity [m/s^2].04 - RGRAV = 1.0 / GRAV # Inverse of gravitational acceleration - RDGAS = 287.04 # Gas constant for dry air [J/kg/deg] # 287.04 - RVGAS = 461.50 # Gas constant for water vapor [J/kg/deg] - HLV = 2.500e6 # Latent heat of evaporation [J/kg] - HLF = 3.34e5 # Latent heat of fusion [J/kg] # 3.34e5 - KAPPA = 2.0 / 7.0 - CP_AIR = RDGAS / KAPPA # Specific heat capacity of dry air at - TFREEZE = 273.16 # Freezing temperature of fresh water [K] - SAT_ADJUST_THRESHOLD = 1.0e-8 -else: - raise RuntimeError("Constant selector failed, bad code.") - -DZ_MIN = 2.0 -CV_AIR = CP_AIR - RDGAS # Heat capacity of dry air at constant volume -RDG = -RDGAS / GRAV -CNST_0P20 = 0.2 -K1K = RDGAS / CV_AIR -CNST_0P20 = 0.2 -CV_VAP = 3.0 * RVGAS # Heat capacity of water vapor at constant volume -ZVIR = RVGAS / RDGAS - 1 # con_fvirt in Fortran physics -C_ICE = 1972.0 # Heat capacity of ice at -15 degrees Celsius -C_LIQ = 4.1855e3 # Heat capacity of water at 15 degrees Celsius -CP_VAP = 4.0 * RVGAS # Heat capacity of water vapor at constant pressure -TICE = 273.16 # Freezing temperature -DC_ICE = C_LIQ - C_ICE # Isobaric heating / cooling -DC_VAP = CP_VAP - C_LIQ # Isobaric heating / cooling -D2ICE = DC_VAP + DC_ICE # Isobaric heating / cooling -LI0 = HLF - DC_ICE * TICE -EPS = RDGAS / RVGAS -LV0 = ( - HLV - DC_VAP * TICE -) # 3.13905782e6, evaporation latent heat coefficient at 0 degrees Kelvin -LI00 = ( - HLF - DC_ICE * TICE -) # -2.7105966e5, fusion latent heat coefficient at 0 degrees Kelvin -LI2 = ( - LV0 + LI00 -) # 2.86799816e6, sublimation latent heat coefficient at 0 degrees Kelvin -E00 = 611.21 # Saturation vapor pressure at 0 degrees Celsius -T_WFR = TICE - 40.0 # homogeneous freezing temperature -TICE0 = TICE - 0.01 -T_MIN = 178.0 # Minimum temperature to freeze-dry all water vapor -T_SAT_MIN = TICE - 160.0 -LAT2 = (HLV + HLF) ** 2 # used in bigg mechanism diff --git a/util/pace/util/cuda_kernels.py b/util/pace/util/cuda_kernels.py deleted file mode 100644 index 96396658d..000000000 --- a/util/pace/util/cuda_kernels.py +++ /dev/null @@ -1,236 +0,0 @@ -# flake8: noqa -from ._optional_imports import cupy as cp - - -def pack_scalar_code(float_dtype: str): - """Pack into o_destinationBuffer data from i_sourceArray. - - The indexation into i_sourceArray is stored in i_indexes. - i_offset is the offset in the destination buffer. - i_nIndex allows to protect from out-of-bound read in kernel. - - tid is the global unique index calculated from the CUDA scheduler inner data. - """ - return r""" - extern "C" __global__ - void pack_scalar_{fdtype}(const {fdtype}* i_sourceArray, - const int* i_indexes, - const int i_nIndex, - const int i_offset, - {fdtype}* o_destinationBuffer) - {{ - int tid = blockDim.x * blockIdx.x + threadIdx.x; - if (tid>=i_nIndex) - {{ - return; - }} - - o_destinationBuffer[i_offset+tid] = i_sourceArray[i_indexes[tid]]; - }} - - """.format( - fdtype=float_dtype - ) - - -def unpack_scalar_code(float_dtype: str): - """Unpack into o_destinationArray data from i_sourceBuffer. - - The indexation into o_destinationArray is stored in i_indexes. - i_offset is the offset in the source buffer. - i_nIndex allows to protect from out-of-bound read in kernel. - - tid is the global unique index calculated from the CUDA scheduler inner data. - """ - return r""" - extern "C" __global__ - void unpack_scalar_{fdtype}(const {fdtype}* i_sourceBuffer, - const int* i_indexes, - const int i_nIndex, - const int i_offset, - {fdtype}* o_destinationArray) - {{ - int tid = blockDim.x * blockIdx.x + threadIdx.x; - if (tid>=i_nIndex) - return; - - o_destinationArray[i_indexes[tid]] = i_sourceBuffer[i_offset+tid]; - }} - - """.format( - fdtype=float_dtype - ) - - -pack_scalar_f64_kernel = ( - None - if cp is None - else cp.RawKernel( - pack_scalar_code("double"), - "pack_scalar_double", - ) -) - -pack_scalar_f32_kernel = ( - None - if cp is None - else cp.RawKernel( - pack_scalar_code("float"), - "pack_scalar_float", - ) -) - -unpack_scalar_f64_kernel = ( - None - if cp is None - else cp.RawKernel( - unpack_scalar_code("double"), - "unpack_scalar_double", - ) -) - -unpack_scalar_f32_kernel = ( - None - if cp is None - else cp.RawKernel( - unpack_scalar_code("float"), - "unpack_scalar_float", - ) -) - - -def pack_vector_code(float_dtype: str) -> str: - """Pack into o_destinationBuffer data from i_sourceArrayX/Y. - - The indexation into i_sourceArrayX/Y is stored in i_indexesX/Y. - i_offset is the offset in the destination buffer. - i_nIndexX/Y allows to protect from out-of-bound read in kernel. - i_rotate refers to the rotation that needs to be applied prior to assignment. - - tid is the global unique index calculated from the CUDA scheduler inner data. - """ - # Expect rotate >= 0 in [0:4[ - return r""" - extern "C" __global__ - void pack_vector_{fdtype}(const {fdtype}* i_sourceArrayX, - const {fdtype}* i_sourceArrayY, - const int* i_indexesX, - const int* i_indexesY, - const int i_nIndexX, - const int i_nIndexY, - const int i_offset, - const int i_rotate, - {fdtype}* o_destinationBuffer) - {{ - int tid = blockDim.x * blockIdx.x + threadIdx.x; - if (tid>=i_nIndexX+i_nIndexY) - return; - - if (i_rotate == 0) - {{ - //pass - if (tid str: - """Unpack into o_destinationArrayX/Y data from i_sourceBuffer. - - The indexation into o_destinationArrayX/Y is stored in i_indexesX/Y. - i_offset is the offset in the source buffer. - i_nIndexX/Y allows to protect from out-of-bound read in kernel. - - tid is the global unique index calculated from the CUDA scheduler inner data. - """ - return r""" - extern "C" __global__ - void unpack_vector_{fdtype}(const {fdtype}* i_sourceBuffer, - const int* i_indexesX, - const int* i_indexesY, - const int i_nIndexX, - const int i_nIndexY, - const int i_offset, - {fdtype}* o_destinationArrayX, - {fdtype}* o_destinationArrayY) - {{ - int tid = blockDim.x * blockIdx.x + threadIdx.x; - - if (tid bool: - """Determines if a rank needs to be a compiling one - - Args: - rank (int): current rank - size (int): size of the communicator - - Returns: - bool: True if the rank is a compiling one - """ - return rank < (size / 6) - - -def block_waiting_for_compilation(comm, compilation_config: CompilationConfig) -> None: - """block moving on until an ok is received from the compiling rank - - Args: - comm (MPI.Comm): communicator over which the ok is sent - stencil_config (CompilationConfig): holding communicator and rank information - """ - if comm and comm.Get_size() > 1: - compiling_rank = compilation_config.compiling_equivalent - _ = comm.recv(source=compiling_rank) - - -def unblock_waiting_tiles(comm) -> None: - """sends a message to all the ranks waiting for compilation to finish - - Args: - comm (MPI.Comm): communicator over which the ok is sent - """ - rank = comm.Get_rank() - size = comm.Get_size() - if comm and size > 1: - for tile in range(1, 6): - tile_size = size / 6 - message = "compilation finished" - comm.send(message, dest=tile * tile_size + rank) - - -def check_cached_path_exists(cache_filepath: str) -> None: - if not os.path.exists(cache_filepath): - raise RuntimeError(f"Error: Could not find caches for rank at {cache_filepath}") - - -def build_cache_path(config: CompilationConfig) -> Tuple[str, str]: - """generate the GT-Cache path from the config - - Args: - config (CompilationConfig): stencil-config object at post-init state - - Returns: - Tuple[str, str]: path and individual rank string - """ - if config.size == 1: - target_rank_str = "" - else: - if config.use_minimal_caching: - target_rank_str = f"_{config.compiling_equivalent:06d}" - else: - target_rank_str = f"_{config.rank:06d}" - - path = f"{gt_config.cache_settings['root_path']}/.gt_cache{target_rank_str}" - return path, target_rank_str - - -def set_distributed_caches(config: CompilationConfig): - """In Run mode, check required file then point current rank cache to source cache""" - - # Check that we have all the file we need to early out in case - # of issues. - from pace.dsl.stencil_config import RunMode - - if config.run_mode == RunMode.Run: - cache_filepath, target_rank_str = build_cache_path(config) - check_cached_path_exists(cache_filepath) - gt_config.cache_settings["dir_name"] = f".gt_cache{target_rank_str}" - print( - f"[{config.run_mode}] Rank {config.rank} " - f"reading cache {gt_config.cache_settings['dir_name']}" - ) diff --git a/util/pace/util/filesystem.py b/util/pace/util/filesystem.py deleted file mode 100644 index 66c8142e9..000000000 --- a/util/pace/util/filesystem.py +++ /dev/null @@ -1,16 +0,0 @@ -import fsspec - - -def get_fs(path: str) -> fsspec.AbstractFileSystem: - """Return the fsspec filesystem required to handle a given path.""" - fs, _, _ = fsspec.get_fs_token_paths(path) - return fs - - -def is_file(filename): - return get_fs(filename).isfile(filename) - - -def open(filename, *args, **kwargs): - fs = get_fs(filename) - return fs.open(filename, *args, **kwargs) diff --git a/util/pace/util/global_config.py b/util/pace/util/global_config.py deleted file mode 100644 index 8cfc8a3bf..000000000 --- a/util/pace/util/global_config.py +++ /dev/null @@ -1,48 +0,0 @@ -import functools -import os -from typing import Optional - - -def getenv_bool(name: str, default: str) -> bool: - indicator = os.getenv(name, default).title() - return indicator == "True" - - -def set_backend(new_backend: str): - global _BACKEND - _BACKEND = new_backend - - -def get_backend() -> str: - return _BACKEND - - -def set_rebuild(flag: bool): - global _REBUILD - _REBUILD = flag - - -def get_rebuild() -> bool: - return _REBUILD - - -def set_validate_args(new_validate_args: bool): - global _VALIDATE_ARGS - _VALIDATE_ARGS = new_validate_args - - -# Set to "False" to skip validating gt4py stencil arguments -@functools.lru_cache(maxsize=None) -def get_validate_args() -> bool: - return _VALIDATE_ARGS - - -# Options -# CPU: numpy, gt:cpu_ifirst, gt:cpu_kfirst -# GPU: gt:gpu, cuda -_BACKEND: Optional[str] = None - -# If TRUE, all caches will bypassed and stencils recompiled -# if FALSE, caches will be checked and rebuild if code changes -_REBUILD: bool = getenv_bool("FV3_STENCIL_REBUILD_FLAG", "False") -_VALIDATE_ARGS: bool = True diff --git a/util/pace/util/grid/__init__.py b/util/pace/util/grid/__init__.py deleted file mode 100644 index 5e488743c..000000000 --- a/util/pace/util/grid/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -# flake8: noqa: F401 - -from .eta import set_hybrid_pressure_coefficients -from .generation import GridDefinitions, MetricTerms -from .gnomonic import ( - great_circle_distance_along_axis, - great_circle_distance_lon_lat, - lon_lat_corner_to_cell_center, - lon_lat_midpoint, - lon_lat_to_xyz, - xyz_midpoint, - xyz_to_lon_lat, -) -from .helper import ( - AngleGridData, - ContravariantGridData, - DampingCoefficients, - DriverGridData, - GridData, - HorizontalGridData, - VerticalGridData, -) -from .stretch_transformation import direct_transform diff --git a/util/pace/util/grid/eta.py b/util/pace/util/grid/eta.py deleted file mode 100644 index 52fe3552c..000000000 --- a/util/pace/util/grid/eta.py +++ /dev/null @@ -1,81 +0,0 @@ -import os -from dataclasses import dataclass - -import numpy as np -import xarray as xr - - -@dataclass -class HybridPressureCoefficients: - """ - Attributes: - - ks: The number of pure-pressure layers at the top of the model - Also the level where model transitions from pure pressure to - hybrid pressure levels - - ptop: The pressure at the top of the atmosphere - - ak: The additive coefficient in the pressure calculation - - bk: The multiplicative coefficient in the pressure calculation - """ - - ks: int - ptop: int - ak: np.ndarray - bk: np.ndarray - - -def set_hybrid_pressure_coefficients( - km: int, eta_file: str -) -> HybridPressureCoefficients: - """ - Sets the coefficients describing the hybrid pressure coordinates. - - The pressure of each k-level is calculated as Pk = ak + (bk * Ps) - where Ps is the surface pressure. Values are currently stored in - lookup tables. - - Args: - km: The number of vertical levels in the model - - Returns: - a HybridPressureCoefficients dataclass - """ - - if eta_file == "None": - raise ValueError("eta file not specified") - if not os.path.isfile(eta_file): - raise ValueError("file " + eta_file + " does not exist") - - # read file into ak, bk arrays - data = xr.open_dataset(eta_file) - ak = data["ak"].values - bk = data["bk"].values - - # check size of ak and bk array is km+1 - if ak.size - 1 != km: - raise ValueError(f"size of ak array is not equal to km={km}") - if bk.size - 1 != km: - raise ValueError(f"size of bk array is not equal to km={km}") - - # check that the eta values computed from ak and bk are monotonically increasing - eta, etav = check_eta(ak, bk) - - if not np.all(eta[:-1] <= eta[1:]): - raise ValueError("ETA values are not monotonically increasing") - if not np.all(etav[:-1] <= etav[1:]): - raise ValueError("ETAV values are not monotonically increasing") - - if 0.0 in bk: - ks = 0 if km == 91 else np.where(bk == 0)[0][-1] - ptop = ak[0] - else: - raise ValueError("bk must contain at least one 0.") - - pressure_data = HybridPressureCoefficients(ks, ptop, ak, bk) - - return pressure_data - - -def check_eta(ak, bk): - from pace.fv3core.initialization.init_utils import compute_eta - - return compute_eta(ak, bk) diff --git a/util/pace/util/grid/generation.py b/util/pace/util/grid/generation.py deleted file mode 100644 index 2c5565764..000000000 --- a/util/pace/util/grid/generation.py +++ /dev/null @@ -1,3393 +0,0 @@ -import dataclasses -import functools -import warnings -from typing import Tuple - -import numpy as np - -from pace import util -from pace.dsl.gt4py_utils import asarray -from pace.dsl.stencil import GridIndexing -from pace.dsl.typing import Float -from pace.stencils.corners import ( - fill_corners_2d, - fill_corners_agrid, - fill_corners_cgrid, - fill_corners_dgrid, -) -from pace.util import X_DIM, X_INTERFACE_DIM, Y_DIM, Y_INTERFACE_DIM, Z_INTERFACE_DIM -from pace.util.constants import N_HALO_DEFAULT, PI, RADIUS -from pace.util.grid import eta - -from .geometry import ( - calc_unit_vector_south, - calc_unit_vector_west, - calculate_divg_del6, - calculate_grid_a, - calculate_grid_z, - calculate_l2c_vu, - calculate_supergrid_cos_sin, - calculate_trig_uv, - calculate_xy_unit_vectors, - edge_factors, - efactor_a2c_v, - get_center_vector, - supergrid_corner_fix, - unit_vector_lonlat, -) -from .gnomonic import ( - get_area, - great_circle_distance_along_axis, - local_gnomonic_ed, - lon_lat_corner_to_cell_center, - lon_lat_midpoint, - lon_lat_to_xyz, - set_c_grid_tile_border_area, - set_corner_area_to_triangle_area, - set_tile_border_dxc, - set_tile_border_dyc, -) -from .mirror import mirror_grid - - -# TODO: when every environment in python3.8, remove -# this custom decorator -def cached_property(func): - @property - @functools.lru_cache() - def wrapper(self, *args, **kwargs): - return func(self, *args, **kwargs) - - return wrapper - - -def ignore_zero_division(func): - @functools.wraps(func) - def wrapped(*args, **kwargs): - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - return func(*args, **kwargs) - - return wrapped - - -def quantity_cast_to_model_float( - quantity_factory: util.QuantityFactory, qty_64: util.Quantity -) -> util.Quantity: - """Copy & cast from 64-bit float to model precision if need be""" - qty = quantity_factory.zeros(qty_64.dims, qty_64.units, dtype=Float) - qty.data[:] = qty_64.data[:] - return qty - - -@dataclasses.dataclass -class GridDefinition: - dims: Tuple[str, ...] - units: str - - -class GridDefinitions: - CELL_CENTER = (X_DIM, Y_DIM) - CELL_CORNERS = (X_INTERFACE_DIM, Y_INTERFACE_DIM) - LON_OR_LAT_DIM = "lon_or_lat" - TILE_DIM = "tile" - CARTESIAN_DIM = "xyz_direction" - - grid = GridDefinition(dims=CELL_CORNERS + (LON_OR_LAT_DIM,), units="radians") - agrid = GridDefinition(dims=CELL_CENTER + (LON_OR_LAT_DIM,), units="radians") - lon = GridDefinition(dims=CELL_CORNERS, units="radians") - lat = GridDefinition(dims=CELL_CORNERS, units="radians") - lon_agrid = GridDefinition(dims=CELL_CENTER, units="radians") - lat_agrid = GridDefinition(dims=CELL_CENTER, units="radians") - area = GridDefinition(dims=CELL_CENTER, units="m^2") - area_cgrid = GridDefinition(dims=CELL_CORNERS, units="m^2") - rarea = GridDefinition(dims=area.dims, units="1/m^2") - rarea_c = GridDefinition(dims=area_cgrid.dims, units="1/m^2") - dx = GridDefinition(dims=(X_DIM, Y_INTERFACE_DIM), units="m") - dy = GridDefinition(dims=(X_INTERFACE_DIM, Y_DIM), units="m") - dxc = GridDefinition(dims=(X_INTERFACE_DIM, Y_DIM), units="m") - dyc = GridDefinition(dims=(X_DIM, Y_INTERFACE_DIM), units="m") - dxa = GridDefinition(dims=CELL_CENTER, units="m") - dya = GridDefinition(dims=CELL_CENTER, units="m") - rdx = GridDefinition(dims=dx.dims, units="1/m") - rdy = GridDefinition(dims=dy.dims, units="1/m") - rdxc = GridDefinition(dims=dxc.dims, units="1/m") - rdyc = GridDefinition(dims=dyc.dims, units="1/m") - rdxa = GridDefinition(dims=dxa.dims, units="1/m") - rdya = GridDefinition(dims=dya.dims, units="1/m") - ak = GridDefinition(dims=(Z_INTERFACE_DIM,), units="m") - bk = GridDefinition(dims=(Z_INTERFACE_DIM,), units="m") - ec1 = GridDefinition(dims=CELL_CENTER + (CARTESIAN_DIM,), units="m") - ec2 = GridDefinition(dims=CELL_CENTER + (CARTESIAN_DIM,), units="m") - ew1 = GridDefinition(dims=CELL_CORNERS + (CARTESIAN_DIM,), units="m") - ew2 = GridDefinition(dims=CELL_CORNERS + (CARTESIAN_DIM,), units="m") - es1 = GridDefinition( - dims=( - X_DIM, - Y_INTERFACE_DIM, - CARTESIAN_DIM, - ), - units="m", - ) - es2 = GridDefinition( - dims=( - X_DIM, - Y_INTERFACE_DIM, - CARTESIAN_DIM, - ), - units="m", - ) - cosa_u = GridDefinition(dims=(X_INTERFACE_DIM, Y_DIM), units="") - cosa_v = GridDefinition(dims=(X_DIM, Y_INTERFACE_DIM), units="") - cosa_s = GridDefinition(dims=(X_DIM, Y_DIM), units="") - sina_u = GridDefinition(dims=(X_INTERFACE_DIM, Y_DIM), units="") - sina_v = GridDefinition(dims=(X_DIM, Y_INTERFACE_DIM), units="") - rsin_u = GridDefinition(dims=(X_INTERFACE_DIM, Y_DIM), units="") - rsin_v = GridDefinition(dims=(X_DIM, Y_INTERFACE_DIM), units="") - rsina = GridDefinition(dims=(X_INTERFACE_DIM, Y_INTERFACE_DIM), units="") - rsin2 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - cosa = GridDefinition(dims=(X_INTERFACE_DIM, Y_INTERFACE_DIM), units="") - sina = GridDefinition(dims=(X_INTERFACE_DIM, Y_INTERFACE_DIM), units="") - cos_sg1 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - cos_sg2 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - cos_sg3 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - cos_sg4 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - cos_sg5 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - cos_sg6 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - cos_sg7 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - cos_sg8 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - cos_sg9 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - sin_sg1 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - sin_sg2 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - sin_sg3 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - sin_sg4 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - sin_sg5 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - sin_sg6 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - sin_sg7 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - sin_sg8 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - sin_sg9 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - l2c_u = GridDefinition(dims=(X_DIM, Y_INTERFACE_DIM), units="") - l2c_v = GridDefinition(dims=(X_INTERFACE_DIM, Y_DIM), units="") - ee1 = GridDefinition(dims=CELL_CORNERS + (CARTESIAN_DIM,), units="") - ee2 = GridDefinition(dims=CELL_CORNERS + (CARTESIAN_DIM,), units="") - del6_u = GridDefinition(dims=(X_DIM, Y_INTERFACE_DIM), units="") - del6_v = GridDefinition(dims=(X_INTERFACE_DIM, Y_DIM), units="") - divg_u = GridDefinition(dims=(X_DIM, Y_INTERFACE_DIM), units="") - divg_v = GridDefinition(dims=(X_INTERFACE_DIM, Y_DIM), units="") - z11 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - z12 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - z21 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - z22 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - a11 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - a12 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - a21 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - a22 = GridDefinition(dims=(X_DIM, Y_DIM), units="") - edge_s = GridDefinition(dims=(X_INTERFACE_DIM,), units="") - edge_n = GridDefinition(dims=(X_INTERFACE_DIM,), units="") - edge_e = GridDefinition( - dims=( - X_DIM, - Y_INTERFACE_DIM, - ), - units="", - ) - edge_w = GridDefinition( - dims=( - X_DIM, - Y_INTERFACE_DIM, - ), - units="", - ) - edge_vect_s = GridDefinition(dims=(X_DIM,), units="") - edge_vect_n = GridDefinition(dims=(X_DIM,), units="") - edge_vect_e_1d = GridDefinition(dims=(Y_DIM,), units="") - edge_vect_w_1d = GridDefinition(dims=(Y_DIM,), units="") - edge_vect_e = GridDefinition(dims=(X_DIM, Y_DIM), units="") - edge_vect_w = GridDefinition(dims=(X_DIM, Y_DIM), units="") - - -# TODO -# corners use sizer + partitioner rather than GridIndexer, -# have to refactor fv3core calls to corners to do this as well -class MetricTerms: - LON_OR_LAT_DIM = GridDefinitions.LON_OR_LAT_DIM - TILE_DIM = GridDefinitions.TILE_DIM - CARTESIAN_DIM = GridDefinitions.CARTESIAN_DIM - N_TILES = 6 - RIGHT_HAND_GRID = False - - def __init__( - self, - *, - quantity_factory: util.QuantityFactory, - communicator: util.Communicator, - grid_type: int = 0, - dx_const: float = 1000.0, - dy_const: float = 1000.0, - deglat: float = 15.0, - extdgrid: bool = False, - eta_file: str = "None", - ): - self._grid_type = grid_type - self._dx_const = dx_const - self._dy_const = dy_const - self._deglat = deglat - self._halo = N_HALO_DEFAULT - self._comm = communicator - self._partitioner = self._comm.partitioner - self._tile_partitioner = self._comm.tile.partitioner - self._rank = self._comm.rank - self.quantity_factory = quantity_factory - self.quantity_factory.set_extra_dim_lengths( - **{ - self.LON_OR_LAT_DIM: 2, - self.TILE_DIM: 6, - self.CARTESIAN_DIM: 3, - } - ) - self._grid_indexing = GridIndexing.from_sizer_and_communicator( - self.quantity_factory.sizer, self._comm - ) - self._grid_dims = [ - util.X_INTERFACE_DIM, - util.Y_INTERFACE_DIM, - self.LON_OR_LAT_DIM, - ] - self._grid_64 = self.quantity_factory.zeros( - self._grid_dims, - "radians", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - # This will carry the public version of the grid - # for the selected floating point precision - self._grid = None - npx, npy, ndims = self._tile_partitioner.global_extent(self._grid_64) - self._npx = npx - self._npy = npy - self._npz = self.quantity_factory.sizer.get_extent(util.Z_DIM)[0] - self._agrid_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM, self.LON_OR_LAT_DIM], - "radians", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - # This will carry the public version of the agrid - # for the selected floating point precision - self._agrid = None - self._np = self._grid_64.np - self._dx = None - self._dy = None - self._dx_agrid = None - self._dy_agrid = None - self._dx_center = None - self._dy_center = None - self._area = None - self._area_c = None - ( - self._ks, - self._ptop, - self._ak, - self._bk, - ) = self._set_hybrid_pressure_coefficients(eta_file) - self._ec1 = None - self._ec2 = None - self._ew1 = None - self._ew2 = None - self._es1 = None - self._es2 = None - self._ee1 = None - self._ee2 = None - self._l2c_v = None - self._l2c_u = None - self._cos_sg1 = None - self._cos_sg2 = None - self._cos_sg3 = None - self._cos_sg4 = None - self._cos_sg5 = None - self._cos_sg6 = None - self._cos_sg7 = None - self._cos_sg8 = None - self._cos_sg9 = None - self._sin_sg1 = None - self._sin_sg2 = None - self._sin_sg3 = None - self._sin_sg4 = None - self._sin_sg5 = None - self._sin_sg6 = None - self._sin_sg7 = None - self._sin_sg8 = None - self._sin_sg9 = None - self._cosa = None - self._sina = None - self._cosa_u = None - self._cosa_v = None - self._cosa_s = None - self._sina_u = None - self._sina_v = None - self._rsin_u = None - self._rsin_v = None - self._rsina = None - self._rsin2 = None - self._del6_u = None - self._del6_v = None - self._divg_u = None - self._divg_v = None - self._vlon = None - self._vlat = None - self._z11 = None - self._z12 = None - self._z21 = None - self._z22 = None - self._a11 = None - self._a12 = None - self._a21 = None - self._a22 = None - self._edge_w = None - self._edge_e = None - self._edge_s = None - self._edge_n = None - self._edge_vect_w = None - self._edge_vect_e = None - self._edge_vect_s = None - self._edge_vect_n = None - self._edge_vect_w_2d = None - self._edge_vect_e_2d = None - self._da_min = None - self._da_max = None - self._da_min_c = None - self._da_max_c = None - - # Data held for calculation only - self._dx_64 = None - self._dy_64 = None - self._dxc_64 = None - self._dyc_64 = None - self._z11_64 = None - self._z12_64 = None - self._z21_64 = None - self._z22_64 = None - self._sina_u_64 = None - self._sina_v_64 = None - self._ec1_64 = None - self._ec2_64 = None - self._sin_sg5_64 = None - self._vlon_64 = None - self._vlat_64 = None - - # Initialize grids and configure internal numerics - if grid_type == 4: - self._compute_dxdy = self._compute_dxdy_cartesian - self._compute_dxdy_agrid = self._compute_dxdy_agrid_cartesian - self._compute_dxdy_center = self._compute_dxdy_center_cartesian - self._compute_area = self._compute_area_cartesian - self._compute_area_c = self._compute_area_c_cartesian - self._calculate_center_vectors = self._calculate_center_vectors_cartesian - self._calculate_vectors_west = self._calculate_vectors_west_cartesian - self._calculate_vectors_south = self._calculate_vectors_south_cartesian - self._init_cell_trigonometry = self._init_cell_trigonometry_cartesian - self._calculate_latlon_momentum_correction = ( - self._calculate_latlon_momentum_correction_cartesian - ) - self._calculate_xy_unit_vectors = self._calculate_xy_unit_vectors_cartesian - self._calculate_unit_vectors_lonlat = ( - self._calculate_unit_vectors_lonlat_cartesian - ) - self._init_cartesian() - elif grid_type < 3: - self._compute_dxdy = self._compute_dxdy_cube_sphere - self._compute_dxdy_agrid = self._compute_dxdy_agrid_cube_sphere - self._compute_dxdy_center = self._compute_dxdy_center_cube_sphere - self._compute_area = self._compute_area_cube_sphere - self._compute_area_c = self._compute_area_c_cube_sphere - self._calculate_center_vectors = self._calculate_center_vectors_cube_sphere - self._calculate_vectors_west = self._calculate_vectors_west_cube_sphere - self._calculate_vectors_south = self._calculate_vectors_south_cube_sphere - self._init_cell_trigonometry = self._init_cell_trigonometry_cube_sphere - self._calculate_latlon_momentum_correction = ( - self._calculate_latlon_momentum_correction_cube_sphere - ) - self._calculate_xy_unit_vectors = ( - self._calculate_xy_unit_vectors_cube_sphere - ) - self._calculate_unit_vectors_lonlat = ( - self._calculate_unit_vectors_lonlat_cube_sphere - ) - if extdgrid is False: - self._init_dgrid() - self._init_agrid() - else: - raise NotImplementedError(f"Unsupported grid_type = {grid_type}") - - @classmethod - def from_external( - cls, - x, - y, - quantity_factory, - communicator, - grid_type, - eta_file: str = "None", - ) -> "MetricTerms": - """ - Generates a metric terms object, using input from data contained in an - externally generated tile file - """ - terms = MetricTerms( - quantity_factory=quantity_factory, - communicator=communicator, - grid_type=grid_type, - extdgrid=True, - eta_file=eta_file, - ) - - rad_conv = PI / 180.0 - terms._grid_64.view[:, :, 0] = rad_conv * x - terms._grid_64.view[:, :, 1] = rad_conv * y - - terms._init_agrid() - - return terms - - @classmethod - def from_tile_sizing( - cls, - npx: int, - npy: int, - npz: int, - communicator: util.Communicator, - backend: str, - grid_type: int = 0, - dx_const: float = 1000.0, - dy_const: float = 1000.0, - deglat: float = 15.0, - eta_file: str = "None", - ) -> "MetricTerms": - sizer = util.SubtileGridSizer.from_tile_params( - nx_tile=npx - 1, - ny_tile=npy - 1, - nz=npz, - n_halo=N_HALO_DEFAULT, - extra_dim_lengths={ - cls.LON_OR_LAT_DIM: 2, - cls.TILE_DIM: 6, - cls.CARTESIAN_DIM: 3, - }, - layout=communicator.partitioner.tile.layout, - ) - quantity_factory = util.QuantityFactory.from_backend(sizer, backend=backend) - return cls( - quantity_factory=quantity_factory, - communicator=communicator, - grid_type=grid_type, - dx_const=dx_const, - dy_const=dy_const, - deglat=deglat, - eta_file=eta_file, - ) - - @property - def grid(self): - if not self._grid: - self._grid = quantity_cast_to_model_float( - self.quantity_factory, self._grid_64 - ) - return self._grid - - @property - def dgrid_lon_lat(self): - """ - the longitudes and latitudes of the cell corners - """ - return self.grid - - @property - def gridvar(self): - return self.grid - - @property - def agrid(self): - if not self._agrid: - self._agrid = quantity_cast_to_model_float( - self.quantity_factory, self._agrid_64 - ) - return self._agrid - - @property - def agrid_lon_lat(self): - """ - the longitudes and latitudes of the cell centers - """ - return self.agrid - - @property - def lon(self): - return util.Quantity( - data=self.grid.data[:, :, 0], - dims=self.grid.dims[:2], - origin=self.grid.origin[:2], - extent=self.grid.extent[:2], - units=self.grid.units, - gt4py_backend=self.grid.gt4py_backend, - ) - - @property - def lat(self) -> util.Quantity: - return util.Quantity( - data=self.grid.data[:, :, 1], - dims=self.grid.dims[:2], - origin=self.grid.origin[:2], - extent=self.grid.extent[:2], - units=self.grid.units, - gt4py_backend=self.grid.gt4py_backend, - ) - - @property - def lon_agrid(self) -> util.Quantity: - return util.Quantity( - data=self.agrid.data[:, :, 0], - dims=self.agrid.dims[:2], - origin=self.agrid.origin[:2], - extent=self.agrid.extent[:2], - units=self.agrid.units, - gt4py_backend=self.agrid.gt4py_backend, - ) - - @property - def lat_agrid(self) -> util.Quantity: - return util.Quantity( - data=self.agrid.data[:, :, 1], - dims=self.agrid.dims[:2], - origin=self.agrid.origin[:2], - extent=self.agrid.extent[:2], - units=self.agrid.units, - gt4py_backend=self.agrid.gt4py_backend, - ) - - @property - def dx(self) -> util.Quantity: - """ - the distance between grid corners along the x-direction - """ - if self._dx is None: - self._dx, self._dy = self._compute_dxdy() - return self._dx - - @property - def dy(self) -> util.Quantity: - """ - the distance between grid corners along the y-direction - """ - if self._dy is None: - self._dx, self._dy = self._compute_dxdy() - return self._dy - - @property - def dxa(self) -> util.Quantity: - """ - the with of each grid cell along the x-direction - """ - if self._dx_agrid is None: - self._dx_agrid, self._dy_agrid = self._compute_dxdy_agrid() - return self._dx_agrid - - @property - def dya(self) -> util.Quantity: - """ - the with of each grid cell along the y-direction - """ - if self._dy_agrid is None: - self._dx_agrid, self._dy_agrid = self._compute_dxdy_agrid() - return self._dy_agrid - - @property - def dxc(self) -> util.Quantity: - """ - the distance between cell centers along the x-direction - """ - if self._dx_center is None: - self._dx_center, self._dy_center = self._compute_dxdy_center() - return self._dx_center - - @property - def dyc(self) -> util.Quantity: - """ - the distance between cell centers along the y-direction - """ - if self._dy_center is None: - self._dx_center, self._dy_center = self._compute_dxdy_center() - return self._dy_center - - @property - def ks(self) -> util.Quantity: - """ - number of levels where the vertical coordinate is purely pressure-based - """ - return self._ks - - @property - def ak(self) -> util.Quantity: - """ - the ak coefficient used to calculate the pressure at a given k-level: - pk = ak + (bk * ps) - """ - return self._ak - - @property - def bk(self) -> util.Quantity: - """ - the bk coefficient used to calculate the pressure at a given k-level: - pk = ak + (bk * ps) - """ - return self._bk - - @property - def ptop(self) -> util.Quantity: - """ - the pressure of the top of atmosphere level - """ - return self._ptop - - @property - def ec1(self) -> util.Quantity: - """ - cartesian components of the local unit vetcor - in the x-direction at the cell centers - 3d array whose last dimension is length 3 and indicates cartesian x/y/z value - """ - if self._ec1 is None: - self._ec1, self._ec2 = self._calculate_center_vectors() - return self._ec1 - - @property - def ec2(self) -> util.Quantity: - """ - cartesian components of the local unit vetcor - in the y-direation at the cell centers - 3d array whose last dimension is length 3 and indicates cartesian x/y/z value - """ - if self._ec2 is None: - self._ec1, self._ec2 = self._calculate_center_vectors() - return self._ec2 - - @property - def ew1(self) -> util.Quantity: - """ - cartesian components of the local unit vetcor - in the x-direation at the left/right cell edges - 3d array whose last dimension is length 3 and indicates cartesian x/y/z value - """ - if self._ew1 is None: - self._ew1, self._ew2 = self._calculate_vectors_west() - return self._ew1 - - @property - def ew2(self) -> util.Quantity: - """ - cartesian components of the local unit vetcor - in the y-direation at the left/right cell edges - 3d array whose last dimension is length 3 and indicates cartesian x/y/z value - """ - if self._ew2 is None: - self._ew1, self._ew2 = self._calculate_vectors_west() - return self._ew2 - - @property - def cos_sg1(self) -> util.Quantity: - """ - Cosine of the angle at point 1 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._cos_sg1 is None: - self._init_cell_trigonometry() - return self._cos_sg1 - - @property - def cos_sg2(self) -> util.Quantity: - """ - Cosine of the angle at point 2 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._cos_sg2 is None: - self._init_cell_trigonometry() - return self._cos_sg2 - - @property - def cos_sg3(self) -> util.Quantity: - """ - Cosine of the angle at point 3 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._cos_sg3 is None: - self._init_cell_trigonometry() - return self._cos_sg3 - - @property - def cos_sg4(self) -> util.Quantity: - """ - Cosine of the angle at point 4 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._cos_sg4 is None: - self._init_cell_trigonometry() - return self._cos_sg4 - - @property - def cos_sg5(self) -> util.Quantity: - """ - Cosine of the angle at point 5 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - The inner product of ec1 and ec2 for point 5 - """ - if self._cos_sg5 is None: - self._init_cell_trigonometry() - return self._cos_sg5 - - @property - def cos_sg6(self) -> util.Quantity: - """ - Cosine of the angle at point 6 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._cos_sg6 is None: - self._init_cell_trigonometry() - return self._cos_sg6 - - @property - def cos_sg7(self) -> util.Quantity: - """ - Cosine of the angle at point 7 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._cos_sg7 is None: - self._init_cell_trigonometry() - return self._cos_sg7 - - @property - def cos_sg8(self) -> util.Quantity: - """ - Cosine of the angle at point 8 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._cos_sg8 is None: - self._init_cell_trigonometry() - return self._cos_sg8 - - @property - def cos_sg9(self) -> util.Quantity: - """ - Cosine of the angle at point 9 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._cos_sg9 is None: - self._init_cell_trigonometry() - return self._cos_sg9 - - @property - def sin_sg1(self) -> util.Quantity: - """ - Sine of the angle at point 1 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._sin_sg1 is None: - self._init_cell_trigonometry() - return self._sin_sg1 - - @property - def sin_sg2(self) -> util.Quantity: - """ - Sine of the angle at point 2 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._sin_sg2 is None: - self._init_cell_trigonometry() - return self._sin_sg2 - - @property - def sin_sg3(self) -> util.Quantity: - """ - Sine of the angle at point 3 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._sin_sg3 is None: - self._init_cell_trigonometry() - return self._sin_sg3 - - @property - def sin_sg4(self) -> util.Quantity: - """ - Sine of the angle at point 4 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._sin_sg4 is None: - self._init_cell_trigonometry() - return self._sin_sg4 - - @property - def sin_sg5(self) -> util.Quantity: - """ - Sine of the angle at point 5 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - For the center point this is one minus the inner product of ec1 and ec2 squared - """ - if self._sin_sg5 is None: - self._init_cell_trigonometry() - return self._sin_sg5 - - @property - def sin_sg6(self) -> util.Quantity: - """ - Sine of the angle at point 6 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._sin_sg6 is None: - self._init_cell_trigonometry() - return self._sin_sg6 - - @property - def sin_sg7(self) -> util.Quantity: - """ - Sine of the angle at point 7 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._sin_sg7 is None: - self._init_cell_trigonometry() - return self._sin_sg7 - - @property - def sin_sg8(self) -> util.Quantity: - """ - Sine of the angle at point 8 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._sin_sg8 is None: - self._init_cell_trigonometry() - return self._sin_sg8 - - @property - def sin_sg9(self) -> util.Quantity: - """ - Sine of the angle at point 9 of the 'supergrid' within each grid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - if self._sin_sg9 is None: - self._init_cell_trigonometry() - return self._sin_sg9 - - @property - def cosa(self) -> util.Quantity: - """ - cosine of angle between coordinate lines at the cell corners - averaged to ensure consistent answers - """ - if self._cosa is None: - self._init_cell_trigonometry() - return self._cosa - - @property - def sina(self) -> util.Quantity: - """ - as cosa but sine - """ - if self._sina is None: - self._init_cell_trigonometry() - return self._sina - - @property - def cosa_u(self) -> util.Quantity: - """ - as cosa but defined at the left and right cell edges - """ - if self._cosa_u is None: - self._init_cell_trigonometry() - return self._cosa_u - - @property - def cosa_v(self) -> util.Quantity: - """ - as cosa but defined at the top and bottom cell edges - """ - if self._cosa_v is None: - self._init_cell_trigonometry() - return self._cosa_v - - @property - def cosa_s(self) -> util.Quantity: - """ - as cosa but defined at cell centers - """ - if self._cosa_s is None: - self._init_cell_trigonometry() - return self._cosa_s - - @property - def sina_u(self) -> util.Quantity: - """ - as cosa_u but with sine - """ - if self._sina_u is None: - self._init_cell_trigonometry() - return self._sina_u - - @property - def sina_v(self) -> util.Quantity: - """ - as cosa_v but with sine - """ - if self._sina_v is None: - self._init_cell_trigonometry() - return self._sina_v - - @property - def rsin_u(self) -> util.Quantity: - """ - 1/sina_u**2, - defined as the inverse-squrared as it is only used as such - """ - if self._rsin_u is None: - self._init_cell_trigonometry() - return self._rsin_u - - @property - def rsin_v(self) -> util.Quantity: - """ - 1/sina_v**2, - defined as the inverse-squrared as it is only used as such - """ - if self._rsin_v is None: - self._init_cell_trigonometry() - return self._rsin_v - - @property - def rsina(self) -> util.Quantity: - """ - 1/sina**2, - defined as the inverse-squrared as it is only used as such - """ - if self._rsina is None: - self._init_cell_trigonometry() - return self._rsina - - @property - def rsin2(self) -> util.Quantity: - """ - 1/sin_sg5**2, - defined as the inverse-squrared as it is only used as such - """ - if self._rsin2 is None: - self._init_cell_trigonometry() - return self._rsin2 - - @property - def l2c_v(self) -> util.Quantity: - """ - angular momentum correction for converting v-winds - from lat/lon to cartesian coordinates - """ - if self._l2c_v is None: - self._l2c_v, self._l2c_u = self._calculate_latlon_momentum_correction() - return self._l2c_v - - @property - def l2c_u(self) -> util.Quantity: - """ - angular momentum correction for converting u-winds - from lat/lon to cartesian coordinates - """ - if self._l2c_u is None: - self._l2c_v, self._l2c_u = self._calculate_latlon_momentum_correction() - return self._l2c_u - - @property - def es1(self) -> util.Quantity: - """ - cartesian components of the local unit vetcor - in the x-direation at the top/bottom cell edges, - 3d array whose last dimension is length 3 and indicates cartesian x/y/z value - """ - if self._es1 is None: - self._es1, self._es2 = self._calculate_vectors_south() - return self._es1 - - @property - def es2(self) -> util.Quantity: - """ - cartesian components of the local unit vetcor - in the y-direation at the top/bottom cell edges, - 3d array whose last dimension is length 3 and indicates cartesian x/y/z value - """ - if self._es2 is None: - self._es1, self._es2 = self._calculate_vectors_south() - return self._es2 - - @property - def ee1(self) -> util.Quantity: - """ - cartesian components of the local unit vetcor - in the x-direation at the cell corners, - 3d array whose last dimension is length 3 and indicates cartesian x/y/z value - """ - if self._ee1 is None: - self._ee1, self._ee2 = self._calculate_xy_unit_vectors() - return self._ee1 - - @property - def ee2(self) -> util.Quantity: - """ - cartesian components of the local unit vetcor - in the y-direation at the cell corners, - 3d array whose last dimension is length 3 and indicates cartesian x/y/z value - """ - if self._ee2 is None: - self._ee1, self._ee2 = self._calculate_xy_unit_vectors() - return self._ee2 - - @property - def divg_u(self) -> util.Quantity: - """ - sina_v * dyc/dx - """ - if self._divg_u is None: - ( - self._del6_u, - self._del6_v, - self._divg_u, - self._divg_v, - ) = self._calculate_divg_del6() - return self._divg_u - - @property - def divg_v(self) -> util.Quantity: - """ - sina_u * dxc/dy - """ - if self._divg_v is None: - ( - self._del6_u, - self._del6_v, - self._divg_u, - self._divg_v, - ) = self._calculate_divg_del6() - return self._divg_v - - @property - def del6_u(self) -> util.Quantity: - """ - sina_v * dx/dyc - """ - if self._del6_u is None: - ( - self._del6_u, - self._del6_v, - self._divg_u, - self._divg_v, - ) = self._calculate_divg_del6() - return self._del6_u - - @property - def del6_v(self) -> util.Quantity: - """ - sina_u * dy/dxc - """ - if self._del6_v is None: - ( - self._del6_u, - self._del6_v, - self._divg_u, - self._divg_v, - ) = self._calculate_divg_del6() - return self._del6_v - - @property - def vlon(self) -> util.Quantity: - """ - unit vector in eastward longitude direction, - 3d array whose last dimension is length 3 and indicates x/y/z value - """ - if self._vlon is None: - self._vlon, self._vlat = self._calculate_unit_vectors_lonlat() - return self._vlon - - @property - def vlat(self) -> util.Quantity: - """ - unit vector in northward latitude direction, - 3d array whose last dimension is length 3 and indicates x/y/z value - """ - if self._vlat is None: - self._vlon, self._vlat = self._calculate_unit_vectors_lonlat() - return self._vlat - - @property - def z11(self) -> util.Quantity: - """ - vector product of horizontal component of the cell-center vector - with the unit longitude vector - """ - if self._z11 is None: - self._z11, self._z12, self._z21, self._z22 = self._calculate_grid_z() - return self._z11 - - @property - def z12(self) -> util.Quantity: - """ - vector product of horizontal component of the cell-center vector - with the unit latitude vector - """ - if self._z12 is None: - self._z11, self._z12, self._z21, self._z22 = self._calculate_grid_z() - return self._z12 - - @property - def z21(self) -> util.Quantity: - """ - vector product of vertical component of the cell-center vector - with the unit longitude vector - """ - if self._z21 is None: - self._z11, self._z12, self._z21, self._z22 = self._calculate_grid_z() - return self._z21 - - @property - def z22(self) -> util.Quantity: - """ - vector product of vertical component of the cell-center vector - with the unit latitude vector - """ - if self._z22 is None: - self._z11, self._z12, self._z21, self._z22 = self._calculate_grid_z() - return self._z22 - - @property - def a11(self) -> util.Quantity: - """ - 0.5*z22/sin_sg5 - """ - if self._a11 is None: - self._a11, self._a12, self._a21, self._a22 = self._calculate_grid_a() - return self._a11 - - @property - def a12(self) -> util.Quantity: - """ - 0.5*z21/sin_sg5 - """ - if self._a12 is None: - self._a11, self._a12, self._a21, self._a22 = self._calculate_grid_a() - return self._a12 - - @property - def a21(self) -> util.Quantity: - """ - 0.5*z12/sin_sg5 - """ - if self._a21 is None: - self._a11, self._a12, self._a21, self._a22 = self._calculate_grid_a() - return self._a21 - - @property - def a22(self) -> util.Quantity: - """ - 0.5*z11/sin_sg5 - """ - if self._a22 is None: - self._a11, self._a12, self._a21, self._a22 = self._calculate_grid_a() - return self._a22 - - @property - def edge_w(self) -> util.Quantity: - """ - factor to interpolate scalars from a to c grid at the western grid edge - """ - if self._edge_w is None: - ( - self._edge_w, - self._edge_e, - self._edge_s, - self._edge_n, - ) = self._calculate_edge_factors() - return self._edge_w - - @property - def edge_e(self) -> util.Quantity: - """ - factor to interpolate scalars from a to c grid at the eastern grid edge - """ - if self._edge_e is None: - ( - self._edge_w, - self._edge_e, - self._edge_s, - self._edge_n, - ) = self._calculate_edge_factors() - return self._edge_e - - @property - def edge_s(self) -> util.Quantity: - """ - factor to interpolate scalars from a to c grid at the southern grid edge - """ - if self._edge_s is None: - ( - self._edge_w, - self._edge_e, - self._edge_s, - self._edge_n, - ) = self._calculate_edge_factors() - return self._edge_s - - @property - def edge_n(self) -> util.Quantity: - """ - factor to interpolate scalars from a to c grid at the northern grid edge - """ - if self._edge_n is None: - ( - self._edge_w, - self._edge_e, - self._edge_s, - self._edge_n, - ) = self._calculate_edge_factors() - return self._edge_n - - @property - def edge_vect_w_1d(self) -> util.Quantity: - """ - factor to interpolate vectors from a to c grid at the western grid edge - """ - if self._edge_vect_w is None: - ( - self._edge_vect_w, - self._edge_vect_e, - self._edge_vect_s, - self._edge_vect_n, - ) = self._calculate_edge_a2c_vect_factors() - return self._edge_vect_w - - @property - def edge_vect_w(self) -> util.Quantity: - """ - factor to interpolate vectors from a to c grid at the western grid edge - repeated in x and y to be used in stencils - """ - if self._edge_vect_w_2d is None: - ( - self._edge_vect_e_2d, - self._edge_vect_w_2d, - ) = self._calculate_2d_edge_a2c_vect_factors() - return self._edge_vect_w_2d - - @property - def edge_vect_e_1d(self) -> util.Quantity: - """ - factor to interpolate vectors from a to c grid at the eastern grid edge - """ - if self._edge_vect_e is None: - ( - self._edge_vect_w, - self._edge_vect_e, - self._edge_vect_s, - self._edge_vect_n, - ) = self._calculate_edge_a2c_vect_factors() - return self._edge_vect_e - - @property - def edge_vect_e(self) -> util.Quantity: - """ - factor to interpolate vectors from a to c grid at the eastern grid edge - repeated in x and y to be used in stencils - """ - if self._edge_vect_e_2d is None: - ( - self._edge_vect_e_2d, - self._edge_vect_w_2d, - ) = self._calculate_2d_edge_a2c_vect_factors() - return self._edge_vect_e_2d - - @property - def edge_vect_s(self) -> util.Quantity: - """ - factor to interpolate vectors from a to c grid at the southern grid edge - """ - if self._edge_vect_s is None: - ( - self._edge_vect_w, - self._edge_vect_e, - self._edge_vect_s, - self._edge_vect_n, - ) = self._calculate_edge_a2c_vect_factors() - return self._edge_vect_s - - @property - def edge_vect_n(self) -> util.Quantity: - """ - factor to interpolate vectors from a to c grid at the northern grid edge - """ - if self._edge_vect_n is None: - ( - self._edge_vect_w, - self._edge_vect_e, - self._edge_vect_s, - self._edge_vect_n, - ) = self._calculate_edge_a2c_vect_factors() - return self._edge_vect_n - - @property - def da_min(self) -> float: - """ - the minimum agrid cell area across all ranks, - if mpi is not present and the communicator is a DummyComm this will be - the minimum on the local rank - """ - if self._da_min is None: - self._reduce_global_area_minmaxes() - return self._da_min - - @property - def da_max(self) -> float: - """ - the maximum agrid cell area across all ranks, - if mpi is not present and the communicator is a DummyComm this will be - the maximum on the local rank - """ - if self._da_max is None: - self._reduce_global_area_minmaxes() - return self._da_max - - @property - def da_min_c(self) -> float: - """ - the minimum cgrid cell area across all ranks, - if mpi is not present and the communicator is a DummyComm this will be - the minimum on the local rank - """ - if self._da_min_c is None: - self._reduce_global_area_minmaxes() - return self._da_min_c - - @property - def da_max_c(self) -> float: - """ - the maximum cgrid cell area across all ranks, - if mpi is not present and the communicator is a DummyComm this will be - the maximum on the local rank - """ - if self._da_max_c is None: - self._reduce_global_area_minmaxes() - return self._da_max_c - - @property - def area(self) -> util.Quantity: - """ - the area of each a-grid cell - """ - if self._area is None: - self._area = self._compute_area() - return self._area - - @property - def area_c(self) -> util.Quantity: - """ - the area of each c-grid cell - """ - if self._area_c is None: - self._area_c = self._compute_area_c() - return self._area_c - - @cached_property - def _dgrid_xyz_64(self) -> util.Quantity: - """ - cartesian coordinates of each dgrid cell center - """ - return lon_lat_to_xyz( - self._grid_64.data[:, :, 0], self._grid_64.data[:, :, 1], self._np - ) - - @cached_property - def _agrid_xyz_64(self) -> util.Quantity: - """ - cartesian coordinates of each agrid cell center - """ - return lon_lat_to_xyz( - self._agrid_64.data[:-1, :-1, 0], - self._agrid_64.data[:-1, :-1, 1], - self._np, - ) - - @cached_property - def rarea(self) -> util.Quantity: - """ - 1/cell area - """ - return util.Quantity( - data=1.0 / self.area.data, - dims=self.area.dims, - origin=self.area.origin, - extent=self.area.extent, - units="m^-2", - gt4py_backend=self.area.gt4py_backend, - ) - - @cached_property - def rarea_c(self) -> util.Quantity: - """ - 1/cgrid cell area - """ - return util.Quantity( - data=1.0 / self.area_c.data, - dims=self.area_c.dims, - origin=self.area_c.origin, - extent=self.area_c.extent, - units="m^-2", - gt4py_backend=self.area_c.gt4py_backend, - ) - - @cached_property - @ignore_zero_division - def rdx(self) -> util.Quantity: - """ - 1/dx - """ - return util.Quantity( - data=1.0 / self.dx.data, - dims=self.dx.dims, - origin=self.dx.origin, - extent=self.dx.extent, - units="m^-1", - gt4py_backend=self.dx.gt4py_backend, - ) - - @cached_property - @ignore_zero_division - def rdy(self) -> util.Quantity: - """ - 1/dy - """ - return util.Quantity( - data=1.0 / self.dy.data, - dims=self.dy.dims, - origin=self.dy.origin, - extent=self.dy.extent, - units="m^-1", - gt4py_backend=self.dy.gt4py_backend, - ) - - @cached_property - @ignore_zero_division - def rdxa(self) -> util.Quantity: - """ - 1/dxa - """ - return util.Quantity( - data=1.0 / self.dxa.data, - dims=self.dxa.dims, - origin=self.dxa.origin, - extent=self.dxa.extent, - units="m^-1", - gt4py_backend=self.dxa.gt4py_backend, - ) - - @cached_property - @ignore_zero_division - def rdya(self) -> util.Quantity: - """ - 1/dya - """ - return util.Quantity( - data=1.0 / self.dya.data, - dims=self.dya.dims, - origin=self.dya.origin, - extent=self.dya.extent, - units="m^-1", - gt4py_backend=self.dya.gt4py_backend, - ) - - @cached_property - @ignore_zero_division - def rdxc(self) -> util.Quantity: - """ - 1/dxc - """ - return util.Quantity( - data=1.0 / self.dxc.data, - dims=self.dxc.dims, - origin=self.dxc.origin, - extent=self.dxc.extent, - units="m^-1", - gt4py_backend=self.dxc.gt4py_backend, - ) - - @cached_property - @ignore_zero_division - def rdyc(self) -> util.Quantity: - """ - 1/dyc - """ - return util.Quantity( - data=1.0 / self.dyc.data, - dims=self.dyc.dims, - origin=self.dyc.origin, - extent=self.dyc.extent, - units="m^-1", - gt4py_backend=self.dyc.gt4py_backend, - ) - - def _init_cartesian(self): - - domain_rad = PI / 16.0 - lat_rad = self._deglat * PI / 180.0 - lon_rad = 0.0 - - self._grid_64.data[:, :, :] = self._np.nan - slice_x, slice_y = self._tile_partitioner.subtile_slice( - self._rank, self._grid_64.dims, (self._npx, self._npy) - ) - - isd = slice_x.start - self._halo - ied = slice_x.stop + self._halo - isg = max(isd, 0) - ieg = min(ied, self._npx) - isl = isg - isd - iel = isl + ieg - isg - - jsd = slice_y.start - self._halo - jed = slice_y.stop + self._halo - jsg = max(jsd, 0) - jeg = min(jed, self._npy) - jsl = jsg - jsd - jel = jsl + jeg - jsg - - lon_frac = np.array(range(isg, ieg)) / (self._npx - 1) - 0.5 - lon_frac = lon_frac[:, np.newaxis] - lat_frac = np.array(range(jsg, jeg)) / (self._npy - 1) - 0.5 - lat_frac = lat_frac[np.newaxis, :] - - self._grid_64.data[isl:iel, jsl:jel, 0] = lon_rad + lon_frac * domain_rad - self._grid_64.data[isl:iel, jsl:jel, 1] = lat_rad + lat_frac * domain_rad - - self._agrid_64.data[:, :, 0] = lon_rad - self._agrid_64.data[:, :, 1] = lat_rad - - def _init_dgrid(self): - grid_mirror_ew = self.quantity_factory.zeros( - self._grid_dims, - "radians", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - grid_mirror_ns = self.quantity_factory.zeros( - self._grid_dims, - "radians", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - grid_mirror_diag = self.quantity_factory.zeros( - self._grid_dims, - "radians", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - - local_west_edge = self._tile_partitioner.on_tile_left(self._rank) - local_east_edge = self._tile_partitioner.on_tile_right(self._rank) - local_south_edge = self._tile_partitioner.on_tile_bottom(self._rank) - local_north_edge = self._tile_partitioner.on_tile_top(self._rank) - # information on position of subtile in full tile - slice_x, slice_y = self._tile_partitioner.subtile_slice( - self._rank, self._grid_64.dims, (self._npx, self._npy), overlap=True - ) - section_global_is = self._halo + slice_x.start - section_global_js = self._halo + slice_y.start - subtile_width_x = slice_x.stop - slice_x.start - 1 - subtile_width_y = slice_y.stop - slice_y.start - 1 - - # compute gnomonic grid for this rank - local_gnomonic_ed( - self._grid_64.view[:, :, 0], - self._grid_64.view[:, :, 1], - npx=self._npx, - west_edge=local_west_edge, - east_edge=local_east_edge, - south_edge=local_south_edge, - north_edge=local_north_edge, - global_is=section_global_is, - global_js=section_global_js, - np=self._np, - rank=self._rank, - ) - - # Next compute gnomonic for the mirrored ranks that'll be averaged - j_subtile_index, i_subtile_index = self._tile_partitioner.subtile_index( - self._rank - ) - # compute the global index starting points for the mirrored ranks - ew_global_is = ( - self._halo - + (self._tile_partitioner.layout[0] - i_subtile_index - 1) * subtile_width_x - ) - ns_global_js = ( - self._halo - + (self._tile_partitioner.layout[1] - j_subtile_index - 1) * subtile_width_y - ) - - # compute mirror in the east-west direction - west_edge = True if local_east_edge else False - east_edge = True if local_west_edge else False - local_gnomonic_ed( - grid_mirror_ew.view[:, :, 0], - grid_mirror_ew.view[:, :, 1], - npx=self._npx, - west_edge=west_edge, - east_edge=east_edge, - south_edge=local_south_edge, - north_edge=local_north_edge, - global_is=ew_global_is, - global_js=section_global_js, - np=self._np, - rank=self._rank, - ) - - # compute mirror in the north-south direction - south_edge = True if local_north_edge else False - north_edge = True if local_south_edge else False - local_gnomonic_ed( - grid_mirror_ns.view[:, :, 0], - grid_mirror_ns.view[:, :, 1], - npx=self._npx, - west_edge=local_west_edge, - east_edge=local_east_edge, - south_edge=south_edge, - north_edge=north_edge, - global_is=section_global_is, - global_js=ns_global_js, - np=self._np, - rank=self._rank, - ) - - local_gnomonic_ed( - grid_mirror_diag.view[:, :, 0], - grid_mirror_diag.view[:, :, 1], - npx=self._npx, - west_edge=west_edge, - east_edge=east_edge, - south_edge=south_edge, - north_edge=north_edge, - global_is=ew_global_is, - global_js=ns_global_js, - np=self._np, - rank=self._rank, - ) - - # Average the mirrored gnomonic grids - tile_index = self._partitioner.tile_index(self._rank) - mirror_data = { - "local": self._grid_64.data, - "east-west": grid_mirror_ew.data, - "north-south": grid_mirror_ns.data, - "diagonal": grid_mirror_diag.data, - } - mirror_grid( - mirror_data=mirror_data, - tile_index=tile_index, - npx=self._npx, - npy=self._npy, - x_subtile_width=subtile_width_x + 1, - y_subtile_width=subtile_width_y + 1, - global_is=section_global_is, - global_js=section_global_js, - ng=self._halo, - np=self._grid_64.np, - right_hand_grid=self.RIGHT_HAND_GRID, - ) - - # Shift the corner away from Japan - # This will result in the corner close to east coast of China - # TODO if not config.do_schmidt and config.shift_fac > 1.0e-4 - shift_fac = 18 - self._grid_64.view[:, :, 0] -= PI / shift_fac - tile0_lon = self._grid_64.data[:, :, 0] - tile0_lon[tile0_lon < 0] += 2 * PI - self._grid_64.data[self._np.abs(self._grid_64.data[:]) < 1e-10] = 0.0 - - self._comm.halo_update(self._grid_64, n_points=self._halo) - - fill_corners_2d( - self._grid_64.data, self._grid_indexing, gridtype="B", direction="x" - ) - - def _init_agrid(self): - # Set up lat-lon a-grid, calculate side lengths on a-grid - lon_agrid, lat_agrid = lon_lat_corner_to_cell_center( - self._grid_64.data[:, :, 0], self._grid_64.data[:, :, 1], self._np - ) - self._agrid_64.data[:-1, :-1, 0], self._agrid_64.data[:-1, :-1, 1] = ( - lon_agrid, - lat_agrid, - ) - self._comm.halo_update(self._agrid_64, n_points=self._halo) - fill_corners_2d( - self._agrid_64.data[:, :, 0][:, :, None], - self._grid_indexing, - gridtype="A", - direction="x", - ) - fill_corners_2d( - self._agrid_64.data[:, :, 1][:, :, None], - self._grid_indexing, - gridtype="A", - direction="y", - ) - - def _compute_dxdy_cube_sphere(self): - dx_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "m", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - - dx_64.view[:, :] = great_circle_distance_along_axis( - self._grid_64.view[:, :, 0], - self._grid_64.view[:, :, 1], - RADIUS, - self._np, - axis=0, - ) - dy_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "m", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - dy_64.view[:, :] = great_circle_distance_along_axis( - self._grid_64.view[:, :, 0], - self._grid_64.view[:, :, 1], - RADIUS, - self._np, - axis=1, - ) - self._comm.vector_halo_update(dx_64, dy_64, n_points=self._halo) - - # at this point the Fortran code copies in the west and east edges from - # the halo for dy and performs a halo update, - # to ensure dx and dy mirror across the boundary. - # Not doing it here at the moment. - dx_64.data[dx_64.data < 0] *= -1 - dy_64.data[dy_64.data < 0] *= -1 - fill_corners_dgrid( - dx_64.data[:, :, None], - dy_64.data[:, :, None], - self._grid_indexing, - vector=False, - ) - - dx = quantity_cast_to_model_float(self.quantity_factory, dx_64) - self._dx_64 = dx_64 - dy = quantity_cast_to_model_float(self.quantity_factory, dy_64) - self._dy_64 = dy_64 - - return dx, dy - - def _compute_dxdy_cartesian(self): - dx_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "m", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - dx_64.data[:, :] = self._dx_const - - dy_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "m", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - dy_64.data[:, :] = self._dy_const - - dx = quantity_cast_to_model_float(self.quantity_factory, dx_64) - self._dx_64 = dx_64 - dy = quantity_cast_to_model_float(self.quantity_factory, dy_64) - self._dy_64 = dy_64 - - return dx, dy - - def _compute_dxdy_agrid_cube_sphere(self): - dx_agrid_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "m", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - dy_agrid_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "m", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - lon, lat = self._grid_64.data[:, :, 0], self._grid_64.data[:, :, 1] - lon_y_center, lat_y_center = lon_lat_midpoint( - lon[:, :-1], lon[:, 1:], lat[:, :-1], lat[:, 1:], self._np - ) - dx_agrid_tmp = great_circle_distance_along_axis( - lon_y_center, lat_y_center, RADIUS, self._np, axis=0 - ) - lon_x_center, lat_x_center = lon_lat_midpoint( - lon[:-1, :], lon[1:, :], lat[:-1, :], lat[1:, :], self._np - ) - dy_agrid_tmp = great_circle_distance_along_axis( - lon_x_center, lat_x_center, RADIUS, self._np, axis=1 - ) - fill_corners_agrid( - dx_agrid_tmp[:, :, None], - dy_agrid_tmp[:, :, None], - self._grid_indexing, - vector=False, - ) - - dx_agrid_64.data[:-1, :-1] = dx_agrid_tmp - dy_agrid_64.data[:-1, :-1] = dy_agrid_tmp - self._comm.vector_halo_update(dx_agrid_64, dy_agrid_64, n_points=self._halo) - - # at this point the Fortran code copies in the west and east edges from - # the halo for dy and performs a halo update, - # to ensure dx and dy mirror across the boundary. - # Not doing it here at the moment. - dx_agrid_64.data[dx_agrid_64.data < 0] *= -1 - dy_agrid_64.data[dy_agrid_64.data < 0] *= -1 - - dx_agrid = quantity_cast_to_model_float(self.quantity_factory, dx_agrid_64) - dy_agrid = quantity_cast_to_model_float(self.quantity_factory, dy_agrid_64) - - return dx_agrid, dy_agrid - - def _compute_dxdy_agrid_cartesian(self): - dx_agrid_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "m", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - dx_agrid_64.data[:, :] = self._dx_const - - dy_agrid_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "m", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - dy_agrid_64.data[:, :] = self._dy_const - - dx_agrid = quantity_cast_to_model_float(self.quantity_factory, dx_agrid_64) - dy_agrid = quantity_cast_to_model_float(self.quantity_factory, dy_agrid_64) - - return dx_agrid, dy_agrid - - def _compute_dxdy_center_cube_sphere(self): - dx_center_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "m", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - dy_center_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "m", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - - lon_agrid, lat_agrid = ( - self._agrid_64.data[:-1, :-1, 0], - self._agrid_64.data[:-1, :-1, 1], - ) - dx_center_tmp = great_circle_distance_along_axis( - lon_agrid, lat_agrid, RADIUS, self._np, axis=0 - ) - dy_center_tmp = great_circle_distance_along_axis( - lon_agrid, lat_agrid, RADIUS, self._np, axis=1 - ) - # copying the second-to-last values to the last values is what the Fortran - # code does, but is this correct/valid? - # Maybe we want to change this to use halo updates? - dx_center_64.data[1:-1, :-1] = dx_center_tmp - dx_center_64.data[0, :-1] = dx_center_tmp[0, :] - dx_center_64.data[-1, :-1] = dx_center_tmp[-1, :] - - dy_center_64.data[:-1, 1:-1] = dy_center_tmp - dy_center_64.data[:-1, 0] = dy_center_tmp[:, 0] - dy_center_64.data[:-1, -1] = dy_center_tmp[:, -1] - - set_tile_border_dxc( - self._dgrid_xyz_64[3:-3, 3:-3, :], - self._agrid_xyz_64[3:-3, 3:-3, :], - RADIUS, - dx_center_64.data[3:-3, 3:-4], - self._tile_partitioner, - self._rank, - self._np, - ) - set_tile_border_dyc( - self._dgrid_xyz_64[3:-3, 3:-3, :], - self._agrid_xyz_64[3:-3, 3:-3, :], - RADIUS, - dy_center_64.data[3:-4, 3:-3], - self._tile_partitioner, - self._rank, - self._np, - ) - self._comm.vector_halo_update(dx_center_64, dy_center_64, n_points=self._halo) - - # TODO: Add support for unsigned vector halo updates - # instead of handling ad-hoc here - dx_center_64.data[dx_center_64.data < 0] *= -1 - dy_center_64.data[dy_center_64.data < 0] *= -1 - - # TODO: fix issue with interface dimensions causing validation errors - fill_corners_cgrid( - dx_center_64.data[:, :, None], - dy_center_64.data[:, :, None], - self._grid_indexing, - vector=False, - ) - - dx_center = quantity_cast_to_model_float(self.quantity_factory, dx_center_64) - self._dxc_64 = dx_center_64 - dy_center = quantity_cast_to_model_float(self.quantity_factory, dy_center_64) - self._dyc_64 = dy_center_64 - - return dx_center, dy_center - - def _compute_dxdy_center_cartesian(self): - dx_center_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "m", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - dx_center_64.data[:, :] = self._dx_const - - dy_center_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "m", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - dy_center_64.data[:, :] = self._dy_const - - dx_center = quantity_cast_to_model_float(self.quantity_factory, dx_center_64) - self._dxc_64 = dx_center_64 - dy_center = quantity_cast_to_model_float(self.quantity_factory, dy_center_64) - self._dyc_64 = dy_center_64 - - return dx_center, dy_center - - def _compute_area_cube_sphere(self): - area_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "m^2", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - area_64.data[:, :] = -1.0e8 - - area_64.data[3:-4, 3:-4] = get_area( - self._grid_64.data[3:-3, 3:-3, 0], - self._grid_64.data[3:-3, 3:-3, 1], - RADIUS, - self._np, - ) - self._comm.halo_update(area_64, n_points=self._halo) - - return quantity_cast_to_model_float(self.quantity_factory, area_64) - - def _compute_area_cartesian(self): - area_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "m^2", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - area_64.data[:, :] = self._dx_const * self._dy_const - return quantity_cast_to_model_float(self.quantity_factory, area_64) - - def _compute_area_c_cube_sphere(self): - area_cgrid_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "m^2", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - area_cgrid_64.data[3:-3, 3:-3] = get_area( - self._agrid_64.data[2:-3, 2:-3, 0], - self._agrid_64.data[2:-3, 2:-3, 1], - RADIUS, - self._np, - ) - # TODO -- this does not seem to matter? running with or without does - # not change whether it validates - set_corner_area_to_triangle_area( - lon=self._agrid_64.data[2:-3, 2:-3, 0], - lat=self._agrid_64.data[2:-3, 2:-3, 1], - area=area_cgrid_64.data[3:-3, 3:-3], - tile_partitioner=self._tile_partitioner, - rank=self._rank, - radius=RADIUS, - np=self._np, - ) - - set_c_grid_tile_border_area( - self._dgrid_xyz_64[2:-2, 2:-2, :], - self._agrid_xyz_64[2:-2, 2:-2, :], - RADIUS, - area_cgrid_64.data[3:-3, 3:-3], - self._tile_partitioner, - self._rank, - self._np, - ) - self._comm.halo_update(area_cgrid_64, n_points=self._halo) - - fill_corners_2d( - area_cgrid_64.data[:, :, None], - self._grid_indexing, - gridtype="B", - direction="x", - ) - return quantity_cast_to_model_float(self.quantity_factory, area_cgrid_64) - - def _compute_area_c_cartesian(self): - area_cgrid_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "m^2", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - area_cgrid_64.data[:, :] = self._dx_const * self._dy_const - return quantity_cast_to_model_float(self.quantity_factory, area_cgrid_64) - - def _set_hybrid_pressure_coefficients(self, eta_file): - ks = self.quantity_factory.zeros( - [], - "", - dtype=Float, - ) - ptop = self.quantity_factory.zeros( - [], - "Pa", - dtype=Float, - ) - ak = self.quantity_factory.zeros( - [util.Z_INTERFACE_DIM], - "Pa", - dtype=Float, - ) - bk = self.quantity_factory.zeros( - [util.Z_INTERFACE_DIM], - "", - dtype=Float, - ) - pressure_coefficients = eta.set_hybrid_pressure_coefficients( - self._npz, eta_file - ) - ks = pressure_coefficients.ks - ptop = pressure_coefficients.ptop - ak.data[:] = asarray(pressure_coefficients.ak, type(ak.data)) - bk.data[:] = asarray(pressure_coefficients.bk, type(bk.data)) - return ks, ptop, ak, bk - - def _calculate_center_vectors_cube_sphere(self): - ec1_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ec2_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ec1_64.data[:] = self._np.nan - ec2_64.data[:] = self._np.nan - ec1_64.data[:-1, :-1, :3], ec2_64.data[:-1, :-1, :3] = get_center_vector( - self._dgrid_xyz_64, - self._grid_type, - self._halo, - self._tile_partitioner, - self._rank, - self._np, - ) - - ec1 = quantity_cast_to_model_float(self.quantity_factory, ec1_64) - self._ec1_64 = ec1_64 - ec2 = quantity_cast_to_model_float(self.quantity_factory, ec2_64) - self._ec2_64 = ec2_64 - return ec1, ec2 - - def _calculate_center_vectors_cartesian(self): - ec1_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ec2_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ec1_64.data[:, :, 0] = 1.0 - ec2_64.data[:, :, 1] = 1.0 - - ec1 = quantity_cast_to_model_float(self.quantity_factory, ec1_64) - self._ec1_64 = ec1_64 - ec2 = quantity_cast_to_model_float(self.quantity_factory, ec2_64) - self._ec2_64 = ec2_64 - return ec1, ec2 - - def _calculate_vectors_west_cube_sphere(self): - ew1_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ew2_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ew1_64.data[:] = self._np.nan - ew2_64.data[:] = self._np.nan - ew1_64.data[1:-1, :-1, :3], ew2_64.data[1:-1, :-1, :3] = calc_unit_vector_west( - self._dgrid_xyz_64, - self._agrid_xyz_64, - self._grid_type, - self._halo, - self._tile_partitioner, - self._rank, - self._np, - ) - - ew1 = quantity_cast_to_model_float(self.quantity_factory, ew1_64) - ew2 = quantity_cast_to_model_float(self.quantity_factory, ew2_64) - return ew1, ew2 - - def _calculate_vectors_west_cartesian(self): - ew1_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ew2_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ew1_64.data[:, :, 0] = 1.0 - ew2_64.data[:, :, 1] = 1.0 - - ew1 = quantity_cast_to_model_float(self.quantity_factory, ew1_64) - ew2 = quantity_cast_to_model_float(self.quantity_factory, ew2_64) - return ew1, ew2 - - def _calculate_vectors_south_cube_sphere(self): - es1_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM, self.CARTESIAN_DIM], - "", - allow_mismatch_float_precision=True, - ) - es2_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM, self.CARTESIAN_DIM], - "", - allow_mismatch_float_precision=True, - ) - es1_64.data[:] = self._np.nan - es2_64.data[:] = self._np.nan - es1_64.data[:-1, 1:-1, :3], es2_64.data[:-1, 1:-1, :3] = calc_unit_vector_south( - self._dgrid_xyz_64, - self._agrid_xyz_64, - self._grid_type, - self._halo, - self._tile_partitioner, - self._rank, - self._np, - ) - - es1 = quantity_cast_to_model_float(self.quantity_factory, es1_64) - es2 = quantity_cast_to_model_float(self.quantity_factory, es2_64) - return es1, es2 - - def _calculate_vectors_south_cartesian(self): - es1_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM, self.CARTESIAN_DIM], - "", - allow_mismatch_float_precision=True, - ) - es2_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM, self.CARTESIAN_DIM], - "", - allow_mismatch_float_precision=True, - ) - es1_64.data[:, :, 0] = 1.0 - es2_64.data[:, :, 1] = 1.0 - - es1 = quantity_cast_to_model_float(self.quantity_factory, es1_64) - es2 = quantity_cast_to_model_float(self.quantity_factory, es2_64) - return es1, es2 - - def _calculate_more_trig_terms(self, cos_sg, sin_sg): - cosa_u_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - cosa_v_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - cosa_s_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sina_u_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sina_v_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsin_u_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsin_v_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsina_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsin2_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - cosa_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sina_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ( - cosa_64.data[:, :], - sina_64.data[:, :], - cosa_u_64.data[:, :-1], - cosa_v_64.data[:-1, :], - cosa_s_64.data[:-1, :-1], - sina_u_64.data[:, :-1], - sina_v_64.data[:-1, :], - rsin_u_64.data[:, :-1], - rsin_v_64.data[:-1, :], - rsina_64.data[self._halo : -self._halo, self._halo : -self._halo], - rsin2_64.data[:-1, :-1], - ) = calculate_trig_uv( - self._dgrid_xyz_64, - cos_sg, - sin_sg, - self._halo, - self._tile_partitioner, - self._rank, - self._np, - ) - return ( - quantity_cast_to_model_float(self.quantity_factory, cosa_64), - quantity_cast_to_model_float(self.quantity_factory, sina_64), - quantity_cast_to_model_float(self.quantity_factory, cosa_u_64), - quantity_cast_to_model_float(self.quantity_factory, cosa_v_64), - quantity_cast_to_model_float(self.quantity_factory, cosa_s_64), - quantity_cast_to_model_float(self.quantity_factory, sina_u_64), - quantity_cast_to_model_float(self.quantity_factory, sina_v_64), - quantity_cast_to_model_float(self.quantity_factory, rsin_u_64), - quantity_cast_to_model_float(self.quantity_factory, rsin_v_64), - quantity_cast_to_model_float(self.quantity_factory, rsina_64), - quantity_cast_to_model_float(self.quantity_factory, rsin2_64), - ) - - def _init_cell_trigonometry_cube_sphere(self): - cosa_u_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - cosa_v_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - cosa_s_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sina_u_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sina_v_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsin_u_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsin_v_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsina_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsin2_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - cosa_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sina_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - - # This section calculates the cos_sg and sin_sg terms, which describe the - # angles of the corners and edges of each cell according to the supergrid: - # 9---4---8 - # | | - # 1 5 3 - # | | - # 6---2---7 - - if self._ec1_64 is None: - self._ec1, self._ec2 = self._calculate_center_vectors() - - cos_sg, sin_sg = calculate_supergrid_cos_sin( - self._dgrid_xyz_64, - self._agrid_xyz_64, - self._ec1_64.data[:-1, :-1], - self._ec2_64.data[:-1, :-1], - self._grid_type, - self._halo, - self._tile_partitioner, - self._rank, - self._np, - ) - - ( - cosa_64.data[:, :], - sina_64.data[:, :], - cosa_u_64.data[:, :-1], - cosa_v_64.data[:-1, :], - cosa_s_64.data[:-1, :-1], - sina_u_64.data[:, :-1], - sina_v_64.data[:-1, :], - rsin_u_64.data[:, :-1], - rsin_v_64.data[:-1, :], - rsina_64.data[self._halo : -self._halo, self._halo : -self._halo], - rsin2_64.data[:-1, :-1], - ) = calculate_trig_uv( - self._dgrid_xyz_64, - cos_sg, - sin_sg, - self._halo, - self._tile_partitioner, - self._rank, - self._np, - ) - - supergrid_corner_fix( - cos_sg, sin_sg, self._halo, self._tile_partitioner, self._rank - ) - - supergrid_trig = {} - for i in range(1, 10): - supergrid_trig[f"cos_sg{i}"] = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - supergrid_trig[f"cos_sg{i}"].data[:-1, :-1] = cos_sg[:, :, i - 1] - supergrid_trig[f"sin_sg{i}"] = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - supergrid_trig[f"sin_sg{i}"].data[:-1, :-1] = sin_sg[:, :, i - 1] - - self._cos_sg1 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["cos_sg1"] - ) - self._cos_sg2 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["cos_sg2"] - ) - self._cos_sg3 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["cos_sg3"] - ) - self._cos_sg4 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["cos_sg4"] - ) - self._cos_sg5 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["cos_sg5"] - ) - self._cos_sg6 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["cos_sg6"] - ) - self._cos_sg7 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["cos_sg7"] - ) - self._cos_sg8 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["cos_sg8"] - ) - self._cos_sg9 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["cos_sg9"] - ) - self._sin_sg1 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["sin_sg1"] - ) - self._sin_sg2 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["sin_sg2"] - ) - self._sin_sg3 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["sin_sg3"] - ) - self._sin_sg4 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["sin_sg4"] - ) - self._sin_sg5 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["sin_sg5"] - ) - self._sin_sg5_64 = supergrid_trig["sin_sg5"] - self._sin_sg6 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["sin_sg6"] - ) - self._sin_sg7 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["sin_sg7"] - ) - self._sin_sg8 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["sin_sg8"] - ) - self._sin_sg9 = quantity_cast_to_model_float( - self.quantity_factory, supergrid_trig["sin_sg9"] - ) - - # Casting - self._cosa_u = quantity_cast_to_model_float(self.quantity_factory, cosa_u_64) - self._cosa_v = quantity_cast_to_model_float(self.quantity_factory, cosa_v_64) - self._cosa_s = quantity_cast_to_model_float(self.quantity_factory, cosa_s_64) - self._sina_u = quantity_cast_to_model_float(self.quantity_factory, sina_u_64) - self._sina_u_64 = sina_u_64 - self._sina_v = quantity_cast_to_model_float(self.quantity_factory, sina_v_64) - self._sina_v_64 = sina_v_64 - self._rsin_u = quantity_cast_to_model_float(self.quantity_factory, rsin_u_64) - self._rsin_v = quantity_cast_to_model_float(self.quantity_factory, rsin_v_64) - self._rsina = quantity_cast_to_model_float(self.quantity_factory, rsina_64) - self._rsin2 = quantity_cast_to_model_float(self.quantity_factory, rsin2_64) - self._cosa = quantity_cast_to_model_float(self.quantity_factory, cosa_64) - self._sina = quantity_cast_to_model_float(self.quantity_factory, sina_64) - - def _init_cell_trigonometry_cartesian(self): - - cosa_u_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - cosa_v_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - cosa_s_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sina_u_64 = self.quantity_factory.ones( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sina_v_64 = self.quantity_factory.ones( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsin_u_64 = self.quantity_factory.ones( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsin_v_64 = self.quantity_factory.ones( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsina_64 = self.quantity_factory.ones( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsin2_64 = self.quantity_factory.ones( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - cosa_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sina_64 = self.quantity_factory.ones( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - - for i in range(1, 10): - sin_sg = self.quantity_factory.ones( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - setattr( - self, - f"_sin_sg{i}", - quantity_cast_to_model_float(self.quantity_factory, sin_sg), - ) - if i == 5: - self._sin_sg5_64 = sin_sg - cos_sg = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - setattr( - self, - f"_cos_sg{i}", - quantity_cast_to_model_float(self.quantity_factory, cos_sg), - ) - - self._cosa_u = quantity_cast_to_model_float(self.quantity_factory, cosa_u_64) - self._cosa_v = quantity_cast_to_model_float(self.quantity_factory, cosa_v_64) - self._cosa_s = quantity_cast_to_model_float(self.quantity_factory, cosa_s_64) - self._sina_u = quantity_cast_to_model_float(self.quantity_factory, sina_u_64) - self._sina_u_64 = sina_u_64 - self._sina_v = quantity_cast_to_model_float(self.quantity_factory, sina_v_64) - self._sina_v_64 = sina_v_64 - self._rsin_u = quantity_cast_to_model_float(self.quantity_factory, rsin_u_64) - self._rsin_v = quantity_cast_to_model_float(self.quantity_factory, rsin_v_64) - self._rsina = quantity_cast_to_model_float(self.quantity_factory, rsina_64) - self._rsin2 = quantity_cast_to_model_float(self.quantity_factory, rsin2_64) - self._cosa = quantity_cast_to_model_float(self.quantity_factory, cosa_64) - self._sina = quantity_cast_to_model_float(self.quantity_factory, sina_64) - - def _calculate_derived_trig_terms_for_testing(self): - """ - As _calculate_derived_trig_terms_for_testing but updates trig attributes - in-place without the halo updates. For use only in validation tests. - """ - cosa_u_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - cosa_v_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - cosa_s_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sina_u_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sina_v_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsin_u_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsin_v_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsina_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - rsin2_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - cosa_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sina_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - - cos_sg = self._np.array( - [ - self.cos_sg1.data[:-1, :-1], - self.cos_sg2.data[:-1, :-1], - self.cos_sg3.data[:-1, :-1], - self.cos_sg4.data[:-1, :-1], - self.cos_sg5.data[:-1, :-1], - self.cos_sg6.data[:-1, :-1], - self.cos_sg7.data[:-1, :-1], - self.cos_sg8.data[:-1, :-1], - self.cos_sg9.data[:-1, :-1], - ] - ).transpose([1, 2, 0]) - sin_sg = self._np.array( - [ - self.sin_sg1.data[:-1, :-1], - self.sin_sg2.data[:-1, :-1], - self.sin_sg3.data[:-1, :-1], - self.sin_sg4.data[:-1, :-1], - self.sin_sg5.data[:-1, :-1], - self.sin_sg6.data[:-1, :-1], - self.sin_sg7.data[:-1, :-1], - self.sin_sg8.data[:-1, :-1], - self.sin_sg9.data[:-1, :-1], - ] - ).transpose([1, 2, 0]) - - ( - cosa_64.data[:, :], - sina_64.data[:, :], - cosa_u_64.data[:, :-1], - cosa_v_64.data[:-1, :], - cosa_s_64.data[:-1, :-1], - sina_u_64.data[:, :-1], - sina_v_64.data[:-1, :], - rsin_u_64.data[:, :-1], - rsin_v_64.data[:-1, :], - rsina_64.data[self._halo : -self._halo, self._halo : -self._halo], - rsin2_64.data[:-1, :-1], - ) = calculate_trig_uv( - self._dgrid_xyz_64, - cos_sg, - sin_sg, - self._halo, - self._tile_partitioner, - self._rank, - self._np, - ) - - self._cosa = quantity_cast_to_model_float(self.quantity_factory, cosa_64) - self._sina = quantity_cast_to_model_float(self.quantity_factory, sina_64) - self._cosa_u = quantity_cast_to_model_float(self.quantity_factory, cosa_u_64) - self._cosa_v = quantity_cast_to_model_float(self.quantity_factory, cosa_v_64) - self._cosa_s = quantity_cast_to_model_float(self.quantity_factory, cosa_s_64) - self._sina_u = quantity_cast_to_model_float(self.quantity_factory, sina_u_64) - self._sina_v = quantity_cast_to_model_float(self.quantity_factory, sina_v_64) - self._rsin_u = quantity_cast_to_model_float(self.quantity_factory, rsin_u_64) - self._rsin_v = quantity_cast_to_model_float(self.quantity_factory, rsin_v_64) - self._rsina = quantity_cast_to_model_float(self.quantity_factory, rsina_64) - self._rsin2 = quantity_cast_to_model_float(self.quantity_factory, rsin2_64) - - def _calculate_latlon_momentum_correction_cube_sphere(self): - l2c_v_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=Float, - allow_mismatch_float_precision=True, - ) - l2c_u_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=Float, - allow_mismatch_float_precision=True, - ) - ( - l2c_v_64.data[self._halo : -self._halo, self._halo : -self._halo - 1], - l2c_u_64.data[self._halo : -self._halo - 1, self._halo : -self._halo], - ) = calculate_l2c_vu(self._grid_64.data[:], self._halo, self._np) - - l2c_u = quantity_cast_to_model_float(self.quantity_factory, l2c_u_64) - l2c_v = quantity_cast_to_model_float(self.quantity_factory, l2c_v_64) - - return l2c_v, l2c_u - - def _calculate_latlon_momentum_correction_cartesian(self): - l2c_v_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=Float, - allow_mismatch_float_precision=True, - ) - l2c_u_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=Float, - allow_mismatch_float_precision=True, - ) - l2c_v_64.data[:] = self._np.nan - l2c_u_64.data[:] = self._np.nan - - l2c_v = quantity_cast_to_model_float(self.quantity_factory, l2c_v_64) - l2c_u = quantity_cast_to_model_float(self.quantity_factory, l2c_u_64) - - return l2c_v, l2c_u - - def _calculate_xy_unit_vectors_cube_sphere(self): - ee1_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ee2_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ee1_64.data[:] = self._np.nan - ee2_64.data[:] = self._np.nan - ( - ee1_64.data[self._halo : -self._halo, self._halo : -self._halo, :], - ee2_64.data[self._halo : -self._halo, self._halo : -self._halo, :], - ) = calculate_xy_unit_vectors( - self._dgrid_xyz_64, self._halo, self._tile_partitioner, self._rank, self._np - ) - - ee1 = quantity_cast_to_model_float(self.quantity_factory, ee1_64) - ee2 = quantity_cast_to_model_float(self.quantity_factory, ee2_64) - - return ee1, ee2 - - def _calculate_xy_unit_vectors_cartesian(self): - ee1_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ee2_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_INTERFACE_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ee1_64.data[:] = self._np.nan - ee2_64.data[:] = self._np.nan - - ee1 = quantity_cast_to_model_float(self.quantity_factory, ee1_64) - ee2 = quantity_cast_to_model_float(self.quantity_factory, ee2_64) - - return ee1, ee2 - - def _calculate_divg_del6(self): - del6_u_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - del6_v_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - divg_u_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - divg_v_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sin_sg = [ - self.sin_sg1.data[:-1, :-1], - self.sin_sg2.data[:-1, :-1], - self.sin_sg3.data[:-1, :-1], - self.sin_sg4.data[:-1, :-1], - self.sin_sg5.data[:-1, :-1], - ] - sin_sg = self._np.array(sin_sg).transpose(1, 2, 0) - if self._sina_u_64 is None: - self._init_cell_trigonometry() - if self._dx_64 is None: - self._dx, self._dy = self._compute_dxdy() - if self._dxc_64 is None: - self._dx_center, self._dy_center = self._compute_dxdy_center() - ( - divg_u_64.data[:-1, :], - divg_v_64.data[:, :-1], - del6_u_64.data[:-1, :], - del6_v_64.data[:, :-1], - ) = calculate_divg_del6( - sin_sg, - self._sina_u_64.data[:, :-1], - self._sina_v_64.data[:-1, :], - self._dx_64.data[:-1, :], - self._dy_64.data[:, :-1], - self._dxc_64.data[:, :-1], - self._dyc_64.data[:-1, :], - self._halo, - self._tile_partitioner, - self._rank, - ) - - if self._grid_type < 3: - self._comm.vector_halo_update(divg_v_64, divg_u_64, n_points=self._halo) - self._comm.vector_halo_update(del6_v_64, del6_u_64, n_points=self._halo) - # TODO: Add support for unsigned vector halo updates - # instead of handling ad-hoc here - divg_v_64.data[divg_v_64.data < 0] *= -1 - divg_u_64.data[divg_u_64.data < 0] *= -1 - del6_v_64.data[del6_v_64.data < 0] *= -1 - del6_u_64.data[del6_u_64.data < 0] *= -1 - - divg_v = quantity_cast_to_model_float(self.quantity_factory, divg_v_64) - divg_u = quantity_cast_to_model_float(self.quantity_factory, divg_u_64) - del6_v = quantity_cast_to_model_float(self.quantity_factory, del6_v_64) - del6_u = quantity_cast_to_model_float(self.quantity_factory, del6_u_64) - - return del6_u, del6_v, divg_u, divg_v - - def _calculate_divg_del6_nohalos_for_testing(self): - """ - As _calculate_divg_del6 but updates self.divg and self.del6 attributes - in-place without the halo updates. For use only in validation tests. - """ - del6_u_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - del6_v_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - divg_u_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - divg_v_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - sin_sg = [ - self.sin_sg1.data[:-1, :-1], - self.sin_sg2.data[:-1, :-1], - self.sin_sg3.data[:-1, :-1], - self.sin_sg4.data[:-1, :-1], - self.sin_sg5.data[:-1, :-1], - ] - sin_sg = self._np.array(sin_sg).transpose(1, 2, 0) - if self._sina_u_64 is None: - self._init_cell_trigonometry() - if self._dx_64 is None: - self._dx, self._dy = self._compute_dxdy() - if self._dxc_64 is None: - self._dx_center, self._dy_center = self._compute_dxdy_center() - ( - divg_u_64.data[:-1, :], - divg_v_64.data[:, :-1], - del6_u_64.data[:-1, :], - del6_v_64.data[:, :-1], - ) = calculate_divg_del6( - sin_sg, - self._sina_u_64.data[:, :-1], - self._sina_v_64.data[:-1, :], - self._dx_64.data[:-1, :], - self._dy_64.data[:, :-1], - self._dxc_64.data[:, :-1], - self._dyc_64.data[:-1, :], - self._halo, - self._tile_partitioner, - self._rank, - ) - self._divg_v = quantity_cast_to_model_float(self.quantity_factory, divg_v_64) - self._divg_u = quantity_cast_to_model_float(self.quantity_factory, divg_u_64) - self._del6_v = quantity_cast_to_model_float(self.quantity_factory, del6_v_64) - self._del6_u = quantity_cast_to_model_float(self.quantity_factory, del6_u_64) - - def _calculate_unit_vectors_lonlat_cube_sphere(self): - vlon_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - vlat_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - - vlon_64.data[:-1, :-1], vlat_64.data[:-1, :-1] = unit_vector_lonlat( - self._agrid_64.data[:-1, :-1], self._np - ) - - vlon = quantity_cast_to_model_float(self.quantity_factory, vlon_64) - self._vlon_64 = vlon_64 - vlat = quantity_cast_to_model_float(self.quantity_factory, vlat_64) - self._vlat_64 = vlat_64 - - return vlon, vlat - - def _calculate_unit_vectors_lonlat_cartesian(self): - vlon_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - vlat_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM, self.CARTESIAN_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - vlon_64.data[:] = self._np.nan - vlat_64.data[:] = self._np.nan - - vlon = quantity_cast_to_model_float(self.quantity_factory, vlon_64) - self._vlon_64 = vlon_64 - vlat = quantity_cast_to_model_float(self.quantity_factory, vlat_64) - self._vlat_64 = vlat_64 - - return vlon, vlat - - def _calculate_grid_z(self): - z11_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - z12_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - z21_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - z22_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - - if self._ec1_64 is None: - self._ec1, self._ec2 = self._calculate_center_vectors() - if self._vlon_64 is None: - self._vlon, self._vlat = self._calculate_unit_vectors_lonlat() - - ( - z11_64.data[:-1, :-1], - z12_64.data[:-1, :-1], - z21_64.data[:-1, :-1], - z22_64.data[:-1, :-1], - ) = calculate_grid_z( - self._ec1_64.data[:-1, :-1], - self._ec2_64.data[:-1, :-1], - self._vlon_64.data[:-1, :-1], - self._vlat_64.data[:-1, :-1], - self._np, - ) - - z11 = quantity_cast_to_model_float(self.quantity_factory, z11_64) - self._z11_64 = z11_64 - z12 = quantity_cast_to_model_float(self.quantity_factory, z12_64) - self._z12_64 = z12_64 - z21 = quantity_cast_to_model_float(self.quantity_factory, z21_64) - self._z21_64 = z21_64 - z22 = quantity_cast_to_model_float(self.quantity_factory, z22_64) - self._z22_64 = z22_64 - - return z11, z12, z21, z22 - - def _calculate_grid_a(self): - a11_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - a12_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - a21_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - a22_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - - if self._z11_64 is None: - self._z11, self._z12, self._z21, self._z22 = self._calculate_grid_z() - if self._sin_sg5_64 is None: - self._init_cell_trigonometry() - - ( - a11_64.data[:-1, :-1], - a12_64.data[:-1, :-1], - a21_64.data[:-1, :-1], - a22_64.data[:-1, :-1], - ) = calculate_grid_a( - self._z11_64.data[:-1, :-1], - self._z12_64.data[:-1, :-1], - self._z21_64.data[:-1, :-1], - self._z22_64.data[:-1, :-1], - self._sin_sg5_64.data[:-1, :-1], - ) - - a11 = quantity_cast_to_model_float(self.quantity_factory, a11_64) - a12 = quantity_cast_to_model_float(self.quantity_factory, a12_64) - a21 = quantity_cast_to_model_float(self.quantity_factory, a21_64) - a22 = quantity_cast_to_model_float(self.quantity_factory, a22_64) - - return a11, a12, a21, a22 - - def _calculate_edge_factors(self): - nhalo = self._halo - edge_s_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - edge_n_64 = self.quantity_factory.zeros( - [util.X_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - edge_e_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - edge_w_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_INTERFACE_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ( - edge_w_64.data[:, nhalo:-nhalo], - edge_e_64.data[:, nhalo:-nhalo], - edge_s_64.data[nhalo:-nhalo], - edge_n_64.data[nhalo:-nhalo], - ) = edge_factors( - self.gridvar, - self._agrid_64.data[:-1, :-1], - self._grid_type, - nhalo, - self._tile_partitioner, - self._rank, - RADIUS, - self._np, - ) - - edge_w = quantity_cast_to_model_float(self.quantity_factory, edge_w_64) - edge_e = quantity_cast_to_model_float(self.quantity_factory, edge_e_64) - edge_s = quantity_cast_to_model_float(self.quantity_factory, edge_s_64) - edge_n = quantity_cast_to_model_float(self.quantity_factory, edge_n_64) - - return edge_w, edge_e, edge_s, edge_n - - def _calculate_edge_a2c_vect_factors(self): - edge_vect_s_64 = self.quantity_factory.zeros( - [util.X_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - edge_vect_n_64 = self.quantity_factory.zeros( - [util.X_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - edge_vect_e_64 = self.quantity_factory.zeros( - [util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - edge_vect_w_64 = self.quantity_factory.zeros( - [util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - ( - edge_vect_w_64.data[:-1], - edge_vect_e_64.data[:-1], - edge_vect_s_64.data[:-1], - edge_vect_n_64.data[:-1], - ) = efactor_a2c_v( - self.gridvar, - self._agrid_64.data[:-1, :-1], - self._grid_type, - self._halo, - self._tile_partitioner, - self._rank, - RADIUS, - self._np, - ) - - edge_vect_w = quantity_cast_to_model_float( - self.quantity_factory, edge_vect_w_64 - ) - edge_vect_e = quantity_cast_to_model_float( - self.quantity_factory, edge_vect_e_64 - ) - edge_vect_s = quantity_cast_to_model_float( - self.quantity_factory, edge_vect_s_64 - ) - edge_vect_n = quantity_cast_to_model_float( - self.quantity_factory, edge_vect_n_64 - ) - return edge_vect_w, edge_vect_e, edge_vect_s, edge_vect_n - - def _calculate_2d_edge_a2c_vect_factors(self): - edge_vect_e_2d_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - edge_vect_w_2d_64 = self.quantity_factory.zeros( - [util.X_DIM, util.Y_DIM], - "", - dtype=np.float64, - allow_mismatch_float_precision=True, - ) - shape = self.lon.data.shape - east_edge_data = self.edge_vect_e_1d.data[self._np.newaxis, ...] - east_edge_data = self._np.repeat(east_edge_data, shape[0], axis=0) - west_edge_data = self.edge_vect_w_1d.data[self._np.newaxis, ...] - west_edge_data = self._np.repeat(west_edge_data, shape[0], axis=0) - edge_vect_e_2d_64.data[:-1, :-1], edge_vect_w_2d_64.data[:-1, :-1] = ( - east_edge_data[:-1, :-1], - west_edge_data[:-1, :-1], - ) - - edge_vect_e_2d = quantity_cast_to_model_float( - self.quantity_factory, edge_vect_e_2d_64 - ) - edge_vect_w_2d = quantity_cast_to_model_float( - self.quantity_factory, edge_vect_w_2d_64 - ) - return edge_vect_e_2d, edge_vect_w_2d - - def _reduce_global_area_minmaxes(self): - min_area = self._np.min(self.area.data[3:-4, 3:-4])[()] - max_area = self._np.max(self.area.data[3:-4, 3:-4])[()] - min_area_c = self._np.min(self.area_c.data[3:-4, 3:-4])[()] - max_area_c = self._np.max(self.area_c.data[3:-4, 3:-4])[()] - self._da_min = float(self._comm.comm.allreduce(min_area, min)) - self._da_max = float(self._comm.comm.allreduce(max_area, max)) - self._da_min_c = float(self._comm.comm.allreduce(min_area_c, min)) - self._da_max_c = float(self._comm.comm.allreduce(max_area_c, max)) diff --git a/util/pace/util/grid/geometry.py b/util/pace/util/grid/geometry.py deleted file mode 100644 index 5ae7ee536..000000000 --- a/util/pace/util/grid/geometry.py +++ /dev/null @@ -1,930 +0,0 @@ -from pace.util import Quantity, TilePartitioner - -from .gnomonic import ( - get_lonlat_vect, - get_unit_vector_direction, - great_circle_distance_lon_lat, - lon_lat_midpoint, - normalize_xyz, - spherical_cos, - xyz_midpoint, -) - - -def get_center_vector( - xyz_gridpoints, - grid_type: int, - nhalo: int, - tile_partitioner: TilePartitioner, - rank: int, - np, -): - """ - Calculates the cartesian unit vectors at the center of each grid cell. - - Returns: - vector1: the horizontal unit vector - vector2: the vertical unit vector - """ - big_number = 1.0e8 - - if grid_type < 3: - center_points = xyz_midpoint( - xyz_gridpoints[:-1, :-1, :], - xyz_gridpoints[1:, :-1, :], - xyz_gridpoints[:-1, 1:, :], - xyz_gridpoints[1:, 1:, :], - ) - - p1 = xyz_midpoint(xyz_gridpoints[:-1, :-1, :], xyz_gridpoints[:-1, 1:, :]) - p2 = xyz_midpoint(xyz_gridpoints[1:, :-1, :], xyz_gridpoints[1:, 1:, :]) - p3 = np.cross(p2, p1) - vector1 = normalize_xyz(np.cross(center_points, p3)) - - p1 = xyz_midpoint(xyz_gridpoints[:-1, :-1, :], xyz_gridpoints[1:, :-1, :]) - p2 = xyz_midpoint(xyz_gridpoints[:-1, 1:, :], xyz_gridpoints[1:, 1:, :]) - p3 = np.cross(p2, p1) - vector2 = normalize_xyz(np.cross(center_points, p3)) - - # fill ghost on ec1 and ec2: - _fill_halo_corners(vector1, big_number, nhalo, tile_partitioner, rank) - _fill_halo_corners(vector2, big_number, nhalo, tile_partitioner, rank) - - else: - shape_dgrid = xyz_gridpoints.shape - vector1 = np.zeros((shape_dgrid[0] - 1, shape_dgrid[1] - 1, 3)) - vector2 = np.zeros((shape_dgrid[0] - 1, shape_dgrid[1] - 1, 3)) - vector1[:, :, 0] = 1 - vector2[:, :, 1] = 1 - - return vector1, vector2 - - -def calc_unit_vector_west( - xyz_dgrid, - xyz_agrid, - grid_type: int, - nhalo: int, - tile_partitioner: TilePartitioner, - rank: int, - np, -): - """ - Calculates the cartesian unit vectors at the left/right edges of each grid cell. - - Returns: - vector1: the horizontal unit vector - vector2: the vertical unit vector - - """ - ew1 = np.zeros((xyz_dgrid.shape[0], xyz_agrid.shape[1], 3)) - ew2 = np.zeros((xyz_dgrid.shape[0], xyz_agrid.shape[1], 3)) - if grid_type < 3: - - pp = xyz_midpoint(xyz_dgrid[1:-1, :-1, :3], xyz_dgrid[1:-1, 1:, :3]) - - p2 = np.cross(xyz_agrid[:-1, :, :3], xyz_agrid[1:, :, :3]) - if tile_partitioner.on_tile_left(rank): - p2[nhalo - 1] = np.cross(pp[nhalo - 1], xyz_agrid[nhalo, :, :3]) - if tile_partitioner.on_tile_right(rank): - p2[-nhalo] = np.cross(xyz_agrid[-nhalo - 1, :, :3], pp[-nhalo]) - - ew1[1:-1, :, :] = normalize_xyz(np.cross(p2, pp)) - p1 = np.cross(xyz_dgrid[1:-1, :-1, :], xyz_dgrid[1:-1, 1:, :]) - ew2[1:-1, :, :] = normalize_xyz(np.cross(p1, pp)) - - # fill ghost on ew: - _fill_halo_corners(ew1, 0.0, nhalo, tile_partitioner, rank) - _fill_halo_corners(ew2, 0.0, nhalo, tile_partitioner, rank) - - else: - ew1[:, :, 1] = 1.0 - ew2[:, :, 2] = 1.0 - - return ew1[1:-1, :, :], ew2[1:-1, :, :] - - -def calc_unit_vector_south( - xyz_dgrid, - xyz_agrid, - grid_type: int, - nhalo: int, - tile_partitioner: TilePartitioner, - rank: int, - np, -): - """ - Calculates the cartesian unit vectors at the top/bottom edges of each grid cell. - - Returns: - vector1: the horizontal unit vector - vector2: the vertical unit vector - """ - es1 = np.zeros((xyz_agrid.shape[0], xyz_dgrid.shape[1], 3)) - es2 = np.zeros((xyz_agrid.shape[0], xyz_dgrid.shape[1], 3)) - if grid_type < 3: - - pp = xyz_midpoint(xyz_dgrid[:-1, 1:-1, :3], xyz_dgrid[1:, 1:-1, :3]) - p2 = np.cross(xyz_agrid[:, :-1, :3], xyz_agrid[:, 1:, :3]) - if tile_partitioner.on_tile_bottom(rank): - p2[:, nhalo - 1] = np.cross(pp[:, nhalo - 1], xyz_agrid[:, nhalo, :3]) - if tile_partitioner.on_tile_top(rank): - p2[:, -nhalo] = np.cross(xyz_agrid[:, -nhalo - 1, :3], pp[:, -nhalo]) - - es2[:, 1:-1, :] = normalize_xyz(np.cross(p2, pp)) - - p1 = np.cross(xyz_dgrid[:-1, 1:-1, :], xyz_dgrid[1:, 1:-1, :]) - es1[:, 1:-1, :] = normalize_xyz(np.cross(p1, pp)) - - # fill ghost on es: - _fill_halo_corners(es1, 0.0, nhalo, tile_partitioner, rank) - _fill_halo_corners(es2, 0.0, nhalo, tile_partitioner, rank) - else: - es1[:, :, 1] = 1.0 - es2[:, :, 2] = 1.0 - - return es1[:, 1:-1, :], es2[:, 1:-1, :] - - -def calculate_supergrid_cos_sin( - xyz_dgrid, - xyz_agrid, - ec1, - ec2, - grid_type: int, - nhalo: int, - tile_partitioner: TilePartitioner, - rank: int, - np, -): - """ - Calculates the cosine and sine of the grid angles at each of the following points - in a supergrid cell: - 9---4---8 - | | - 1 5 3 - | | - 6---2---7 - """ - big_number = 1.0e8 - tiny_number = 1.0e-8 - - shape_a = xyz_agrid.shape - cos_sg = np.zeros((shape_a[0], shape_a[1], 9)) + big_number - sin_sg = np.zeros((shape_a[0], shape_a[1], 9)) + tiny_number - - if grid_type < 3: - cos_sg[:, :, 5] = spherical_cos( - xyz_dgrid[:-1, :-1, :], xyz_dgrid[1:, :-1, :], xyz_dgrid[:-1, 1:, :], np - ) - cos_sg[:, :, 6] = -1 * spherical_cos( - xyz_dgrid[1:, :-1, :], xyz_dgrid[:-1, :-1, :], xyz_dgrid[1:, 1:, :], np - ) - cos_sg[:, :, 7] = spherical_cos( - xyz_dgrid[1:, 1:, :], xyz_dgrid[1:, :-1, :], xyz_dgrid[:-1, 1:, :], np - ) - cos_sg[:, :, 8] = -1 * spherical_cos( - xyz_dgrid[:-1, 1:, :], xyz_dgrid[:-1, :-1, :], xyz_dgrid[1:, 1:, :], np - ) - - midpoint = xyz_midpoint(xyz_dgrid[:-1, :-1, :], xyz_dgrid[:-1, 1:, :]) - cos_sg[:, :, 0] = spherical_cos( - midpoint, xyz_agrid[:, :, :], xyz_dgrid[:-1, 1:, :], np - ) - midpoint = xyz_midpoint(xyz_dgrid[:-1, :-1, :], xyz_dgrid[1:, :-1, :]) - cos_sg[:, :, 1] = spherical_cos( - midpoint, xyz_dgrid[1:, :-1, :], xyz_agrid[:, :, :], np - ) - midpoint = xyz_midpoint(xyz_dgrid[1:, :-1, :], xyz_dgrid[1:, 1:, :]) - cos_sg[:, :, 2] = spherical_cos( - midpoint, xyz_agrid[:, :, :], xyz_dgrid[1:, :-1, :], np - ) - midpoint = xyz_midpoint(xyz_dgrid[:-1, 1:, :], xyz_dgrid[1:, 1:, :]) - cos_sg[:, :, 3] = spherical_cos( - midpoint, xyz_dgrid[:-1, 1:, :], xyz_agrid[:, :, :], np - ) - - cos_sg[:, :, 4] = np.sum(ec1 * ec2, axis=-1) - - cos_sg[abs(1.0 - cos_sg) < 1e-15] = 1.0 - - sin_sg_tmp = 1.0 - cos_sg ** 2 - sin_sg_tmp[sin_sg_tmp < 0] = 0.0 - sin_sg = np.sqrt(sin_sg_tmp) - sin_sg[sin_sg > 1.0] = 1.0 - - # Adjust for corners: - if tile_partitioner.on_tile_left(rank): - if tile_partitioner.on_tile_bottom(rank): # southwest corner - sin_sg[nhalo - 1, :nhalo, 2] = sin_sg[:nhalo, nhalo, 1] - sin_sg[:nhalo, nhalo - 1, 3] = sin_sg[nhalo, :nhalo, 0] - if tile_partitioner.on_tile_top(rank): # northwest corner - sin_sg[nhalo - 1, -nhalo:, 2] = sin_sg[:nhalo, -nhalo - 1, 3][::-1] - sin_sg[:nhalo, -nhalo, 1] = sin_sg[nhalo, -nhalo - 2 : -nhalo + 1, 0] - if tile_partitioner.on_tile_right(rank): - if tile_partitioner.on_tile_bottom(rank): # southeast corner - sin_sg[-nhalo, :nhalo, 0] = sin_sg[-nhalo:, nhalo, 1][::-1] - sin_sg[-nhalo:, nhalo - 1, 3] = sin_sg[-nhalo - 1, :nhalo, 2][::-1] - if tile_partitioner.on_tile_top(rank): # northeast corner - sin_sg[-nhalo, -nhalo:, 0] = sin_sg[-nhalo:, -nhalo - 1, 3] - sin_sg[-nhalo:, -nhalo, 1] = sin_sg[-nhalo - 1, -nhalo:, 2] - - else: - cos_sg[:] = 0.0 - sin_sg[:] = 1.0 - - return cos_sg, sin_sg - - -def calculate_l2c_vu(dgrid, nhalo: int, np): - # AAM correction - - point1v = dgrid[nhalo:-nhalo, nhalo : -nhalo - 1, :] - point2v = dgrid[nhalo:-nhalo, nhalo + 1 : -nhalo, :] - midpoint_y = np.array( - lon_lat_midpoint( - point1v[:, :, 0], point2v[:, :, 0], point1v[:, :, 1], point2v[:, :, 1], np - ) - ).transpose([1, 2, 0]) - unit_dir_y = get_unit_vector_direction(point1v, point2v, np) - exv, eyv = get_lonlat_vect(midpoint_y, np) - l2c_v = np.cos(midpoint_y[:, :, 1]) * np.sum(unit_dir_y * exv, axis=-1) - - point1u = dgrid[nhalo : -nhalo - 1, nhalo:-nhalo, :] - point2u = dgrid[nhalo + 1 : -nhalo, nhalo:-nhalo, :] - midpoint_x = np.array( - lon_lat_midpoint( - point1u[:, :, 0], point2u[:, :, 0], point1u[:, :, 1], point2u[:, :, 1], np - ) - ).transpose([1, 2, 0]) - unit_dir_x = get_unit_vector_direction(point1u, point2u, np) - exu, eyu = get_lonlat_vect(midpoint_x, np) - l2c_u = np.cos(midpoint_x[:, :, 1]) * np.sum(unit_dir_x * exu, axis=-1) - - return l2c_v, l2c_u - - -def calculate_xy_unit_vectors( - xyz_dgrid, nhalo: int, tile_partitioner: TilePartitioner, rank: int, np -): - """ - Calculates the cartesian unit vectors at the corners of each grid cell. - vector1 is the horizontal unit vector, while - vector2 is the vertical unit vector - """ - cross_vect_x = np.cross( - xyz_dgrid[nhalo - 1 : -nhalo - 1, nhalo:-nhalo, :], - xyz_dgrid[nhalo + 1 : -nhalo + 1, nhalo:-nhalo, :], - ) - if tile_partitioner.on_tile_left(rank): - cross_vect_x[0, :] = np.cross( - xyz_dgrid[nhalo, nhalo:-nhalo, :], xyz_dgrid[nhalo + 1, nhalo:-nhalo, :] - ) - if tile_partitioner.on_tile_right(rank): - cross_vect_x[-1, :] = np.cross( - xyz_dgrid[-nhalo - 2, nhalo:-nhalo, :], - xyz_dgrid[-nhalo - 1, nhalo:-nhalo, :], - ) - unit_x_vector = normalize_xyz( - np.cross(cross_vect_x, xyz_dgrid[nhalo:-nhalo, nhalo:-nhalo]) - ) - - cross_vect_y = np.cross( - xyz_dgrid[nhalo:-nhalo, nhalo - 1 : -nhalo - 1, :], - xyz_dgrid[nhalo:-nhalo, nhalo + 1 : -nhalo + 1, :], - ) - if tile_partitioner.on_tile_bottom(rank): - cross_vect_y[:, 0] = np.cross( - xyz_dgrid[nhalo:-nhalo, nhalo, :], xyz_dgrid[nhalo:-nhalo, nhalo + 1, :] - ) - if tile_partitioner.on_tile_top(rank): - cross_vect_y[:, -1] = np.cross( - xyz_dgrid[nhalo:-nhalo, -nhalo - 2, :], - xyz_dgrid[nhalo:-nhalo, -nhalo - 1, :], - ) - unit_y_vector = normalize_xyz( - np.cross(cross_vect_y, xyz_dgrid[nhalo:-nhalo, nhalo:-nhalo]) - ) - - return unit_x_vector, unit_y_vector - - -def calculate_trig_uv( - xyz_dgrid, - cos_sg, - sin_sg, - nhalo: int, - tile_partitioner: TilePartitioner, - rank: int, - np, -): - """ - Calculates more trig quantities - """ - - big_number = 1.0e8 - tiny_number = 1.0e-8 - - dgrid_shape_2d = xyz_dgrid[:, :, 0].shape - cosa = np.zeros(dgrid_shape_2d) + big_number - sina = np.zeros(dgrid_shape_2d) + big_number - cosa_u = np.zeros((dgrid_shape_2d[0], dgrid_shape_2d[1] - 1)) + big_number - sina_u = np.zeros((dgrid_shape_2d[0], dgrid_shape_2d[1] - 1)) + big_number - rsin_u = np.zeros((dgrid_shape_2d[0], dgrid_shape_2d[1] - 1)) + big_number - cosa_v = np.zeros((dgrid_shape_2d[0] - 1, dgrid_shape_2d[1])) + big_number - sina_v = np.zeros((dgrid_shape_2d[0] - 1, dgrid_shape_2d[1])) + big_number - rsin_v = np.zeros((dgrid_shape_2d[0] - 1, dgrid_shape_2d[1])) + big_number - - cosa[nhalo:-nhalo, nhalo:-nhalo] = 0.5 * ( - cos_sg[nhalo - 1 : -nhalo, nhalo - 1 : -nhalo, 7] - + cos_sg[nhalo : -nhalo + 1, nhalo : -nhalo + 1, 5] - ) - sina[nhalo:-nhalo, nhalo:-nhalo] = 0.5 * ( - sin_sg[nhalo - 1 : -nhalo, nhalo - 1 : -nhalo, 7] - + sin_sg[nhalo : -nhalo + 1, nhalo : -nhalo + 1, 5] - ) - - cosa_u[1:-1, :] = 0.5 * (cos_sg[:-1, :, 2] + cos_sg[1:, :, 0]) - sina_u[1:-1, :] = 0.5 * (sin_sg[:-1, :, 2] + sin_sg[1:, :, 0]) - sinu2 = sina_u[1:-1, :] ** 2 - sinu2[sinu2 < tiny_number] = tiny_number - rsin_u[1:-1, :] = 1.0 / sinu2 - - cosa_v[:, 1:-1] = 0.5 * (cos_sg[:, :-1, 3] + cos_sg[:, 1:, 1]) - sina_v[:, 1:-1] = 0.5 * (sin_sg[:, :-1, 3] + sin_sg[:, 1:, 1]) - sinv2 = sina_v[:, 1:-1] ** 2 - sinv2[sinv2 < tiny_number] = tiny_number - rsin_v[:, 1:-1] = 1.0 / sinv2 - - cosa_s = cos_sg[:, :, 4] - sin2 = sin_sg[:, :, 4] ** 2 - sin2[sin2 < tiny_number] = tiny_number - rsin2 = 1.0 / sin2 - - # fill ghost on cosa_s: - _fill_halo_corners(cosa_s, big_number, nhalo, tile_partitioner, rank) - - sina2 = sina[nhalo:-nhalo, nhalo:-nhalo] ** 2 - sina2[sina2 < tiny_number] = tiny_number - rsina = 1.0 / sina2 - - # Set special sin values at edges - if tile_partitioner.on_tile_left(rank): - rsina[0, :] = big_number - sina_u_limit = sina_u[nhalo, :] - sina_u_limit[abs(sina_u_limit) < tiny_number] = tiny_number * np.sign( - sina_u_limit[abs(sina_u_limit) < tiny_number] - ) - rsin_u[nhalo, :] = 1.0 / sina_u_limit - if tile_partitioner.on_tile_right(rank): - rsina[-1, :] = big_number - sina_u_limit = sina_u[-nhalo - 1, :] - sina_u_limit[abs(sina_u_limit) < tiny_number] = tiny_number * np.sign( - sina_u_limit[abs(sina_u_limit) < tiny_number] - ) - rsin_u[-nhalo - 1, :] = 1.0 / sina_u_limit - if tile_partitioner.on_tile_bottom(rank): - rsina[:, 0] = big_number - sina_v_limit = sina_v[:, nhalo] - sina_v_limit[abs(sina_v_limit) < tiny_number] = tiny_number * np.sign( - sina_v_limit[abs(sina_v_limit) < tiny_number] - ) - rsin_v[:, nhalo] = 1.0 / sina_v_limit - if tile_partitioner.on_tile_top(rank): - rsina[:, -1] = big_number - sina_v_limit = sina_v[:, -nhalo - 1] - sina_v_limit[abs(sina_v_limit) < tiny_number] = tiny_number * np.sign( - sina_v_limit[abs(sina_v_limit) < tiny_number] - ) - rsin_v[:, -nhalo - 1] = 1.0 / sina_v_limit - - return ( - cosa, - sina, - cosa_u, - cosa_v, - cosa_s, - sina_u, - sina_v, - rsin_u, - rsin_v, - rsina, - rsin2, - ) - - -def supergrid_corner_fix( - cos_sg, sin_sg, nhalo: int, tile_partitioner: TilePartitioner, rank: int -): - """ - filling the ghost cells overwrites some of the sin_sg - values along the outward-facing edge of a tile in the corners, which is incorrect. - This function resolves the issue by filling in the appropriate values - after the _fill_single_halo_corner call - """ - big_number = 1.0e8 - tiny_number = 1.0e-8 - - if tile_partitioner.on_tile_left(rank): - if tile_partitioner.on_tile_bottom(rank): - _fill_single_halo_corner(sin_sg, tiny_number, nhalo, "sw") - _fill_single_halo_corner(cos_sg, big_number, nhalo, "sw") - _rotate_trig_sg_sw_counterclockwise(sin_sg[:, :, 1], sin_sg[:, :, 2], nhalo) - _rotate_trig_sg_sw_counterclockwise(cos_sg[:, :, 1], cos_sg[:, :, 2], nhalo) - _rotate_trig_sg_sw_clockwise(sin_sg[:, :, 0], sin_sg[:, :, 3], nhalo) - _rotate_trig_sg_sw_clockwise(cos_sg[:, :, 0], cos_sg[:, :, 3], nhalo) - if tile_partitioner.on_tile_top(rank): - _fill_single_halo_corner(sin_sg, tiny_number, nhalo, "nw") - _fill_single_halo_corner(cos_sg, big_number, nhalo, "nw") - _rotate_trig_sg_nw_counterclockwise(sin_sg[:, :, 0], sin_sg[:, :, 1], nhalo) - _rotate_trig_sg_nw_counterclockwise(cos_sg[:, :, 0], cos_sg[:, :, 1], nhalo) - _rotate_trig_sg_nw_clockwise(sin_sg[:, :, 3], sin_sg[:, :, 2], nhalo) - _rotate_trig_sg_nw_clockwise(cos_sg[:, :, 3], cos_sg[:, :, 2], nhalo) - if tile_partitioner.on_tile_right(rank): - if tile_partitioner.on_tile_bottom(rank): - _fill_single_halo_corner(sin_sg, tiny_number, nhalo, "se") - _fill_single_halo_corner(cos_sg, big_number, nhalo, "se") - _rotate_trig_sg_se_clockwise(sin_sg[:, :, 1], sin_sg[:, :, 0], nhalo) - _rotate_trig_sg_se_clockwise(cos_sg[:, :, 1], cos_sg[:, :, 0], nhalo) - _rotate_trig_sg_se_counterclockwise(sin_sg[:, :, 2], sin_sg[:, :, 3], nhalo) - _rotate_trig_sg_se_counterclockwise(cos_sg[:, :, 2], cos_sg[:, :, 3], nhalo) - if tile_partitioner.on_tile_top(rank): - _fill_single_halo_corner(sin_sg, tiny_number, nhalo, "ne") - _fill_single_halo_corner(cos_sg, big_number, nhalo, "ne") - _rotate_trig_sg_ne_counterclockwise(sin_sg[:, :, 3], sin_sg[:, :, 0], nhalo) - _rotate_trig_sg_ne_counterclockwise(cos_sg[:, :, 3], cos_sg[:, :, 0], nhalo) - _rotate_trig_sg_ne_clockwise(sin_sg[:, :, 2], sin_sg[:, :, 1], nhalo) - _rotate_trig_sg_ne_clockwise(cos_sg[:, :, 2], cos_sg[:, :, 1], nhalo) - - -def _rotate_trig_sg_sw_counterclockwise(sg_field_in, sg_field_out, nhalo): - sg_field_out[nhalo - 1, :nhalo] = sg_field_in[:nhalo, nhalo] - - -def _rotate_trig_sg_sw_clockwise(sg_field_in, sg_field_out, nhalo): - sg_field_out[:nhalo, nhalo - 1] = sg_field_in[nhalo, :nhalo] - - -def _rotate_trig_sg_nw_counterclockwise(sg_field_in, sg_field_out, nhalo): - _rotate_trig_sg_sw_clockwise(sg_field_in[:, ::-1], sg_field_out[:, ::-1], nhalo) - - -def _rotate_trig_sg_nw_clockwise(sg_field_in, sg_field_out, nhalo): - _rotate_trig_sg_sw_counterclockwise( - sg_field_in[:, ::-1], sg_field_out[:, ::-1], nhalo - ) - - -def _rotate_trig_sg_se_counterclockwise(sg_field_in, sg_field_out, nhalo): - _rotate_trig_sg_sw_clockwise(sg_field_in[::-1, :], sg_field_out[::-1, :], nhalo) - - -def _rotate_trig_sg_se_clockwise(sg_field_in, sg_field_out, nhalo): - _rotate_trig_sg_sw_counterclockwise( - sg_field_in[::-1, :], sg_field_out[::-1, :], nhalo - ) - - -def _rotate_trig_sg_ne_counterclockwise(sg_field_in, sg_field_out, nhalo): - _rotate_trig_sg_sw_counterclockwise( - sg_field_in[::-1, ::-1], sg_field_out[::-1, ::-1], nhalo - ) - - -def _rotate_trig_sg_ne_clockwise(sg_field_in, sg_field_out, nhalo): - _rotate_trig_sg_sw_clockwise( - sg_field_in[::-1, ::-1], sg_field_out[::-1, ::-1], nhalo - ) - - -def calculate_divg_del6( - sin_sg, - sina_u, - sina_v, - dx, - dy, - dxc, - dyc, - nhalo: int, - tile_partitioner: TilePartitioner, - rank: int, -): - - divg_u = sina_v * dyc / dx - del6_u = sina_v * dx / dyc - divg_v = sina_u * dxc / dy - del6_v = sina_u * dy / dxc - - if tile_partitioner.on_tile_bottom(rank): - divg_u[:, nhalo] = ( - 0.5 - * (sin_sg[:, nhalo, 1] + sin_sg[:, nhalo - 1, 3]) - * dyc[:, nhalo] - / dx[:, nhalo] - ) - del6_u[:, nhalo] = ( - 0.5 - * (sin_sg[:, nhalo, 1] + sin_sg[:, nhalo - 1, 3]) - * dx[:, nhalo] - / dyc[:, nhalo] - ) - if tile_partitioner.on_tile_top(rank): - divg_u[:, -nhalo - 1] = ( - 0.5 - * (sin_sg[:, -nhalo, 1] + sin_sg[:, -nhalo - 1, 3]) - * dyc[:, -nhalo - 1] - / dx[:, -nhalo - 1] - ) - del6_u[:, -nhalo - 1] = ( - 0.5 - * (sin_sg[:, -nhalo, 1] + sin_sg[:, -nhalo - 1, 3]) - * dx[:, -nhalo - 1] - / dyc[:, -nhalo - 1] - ) - if tile_partitioner.on_tile_left(rank): - divg_v[nhalo, :] = ( - 0.5 - * (sin_sg[nhalo, :, 0] + sin_sg[nhalo - 1, :, 2]) - * dxc[nhalo, :] - / dy[nhalo, :] - ) - del6_v[nhalo, :] = ( - 0.5 - * (sin_sg[nhalo, :, 0] + sin_sg[nhalo - 1, :, 2]) - * dy[nhalo, :] - / dxc[nhalo, :] - ) - if tile_partitioner.on_tile_right(rank): - divg_v[-nhalo - 1, :] = ( - 0.5 - * (sin_sg[-nhalo, :, 0] + sin_sg[-nhalo - 1, :, 2]) - * dxc[-nhalo - 1, :] - / dy[-nhalo - 1, :] - ) - del6_v[-nhalo - 1, :] = ( - 0.5 - * (sin_sg[-nhalo, :, 0] + sin_sg[-nhalo - 1, :, 2]) - * dy[-nhalo - 1, :] - / dxc[-nhalo - 1, :] - ) - - return divg_u, divg_v, del6_u, del6_v - - -def calculate_grid_z(ec1, ec2, vlon, vlat, np): - z11 = np.sum(ec1 * vlon, axis=-1) - z12 = np.sum(ec1 * vlat, axis=-1) - z21 = np.sum(ec2 * vlon, axis=-1) - z22 = np.sum(ec2 * vlat, axis=-1) - return z11, z12, z21, z22 - - -def calculate_grid_a(z11, z12, z21, z22, sin_sg5): - a11 = 0.5 * z22 / sin_sg5 - a12 = -0.5 * z12 / sin_sg5 - a21 = -0.5 * z21 / sin_sg5 - a22 = 0.5 * z11 / sin_sg5 - return a11, a12, a21, a22 - - -def edge_factors( - grid_quantity: Quantity, - agrid, - grid_type: int, - nhalo: int, - tile_partitioner: TilePartitioner, - rank: int, - radius: float, - np, -): - """ - Creates interpolation factors from the A grid to the B grid on tile edges - """ - grid = grid_quantity.data[:] - big_number = 1.0e8 - i_range = grid[nhalo:-nhalo, nhalo:-nhalo].shape[0] - j_range = grid[nhalo:-nhalo, nhalo:-nhalo].shape[1] - edge_n = np.zeros(i_range) + big_number - edge_s = np.zeros(i_range) + big_number - edge_e = np.zeros(j_range) + big_number - edge_w = np.zeros(j_range) + big_number - npx, npy, ndims = tile_partitioner.global_extent(grid_quantity) - slice_x, slice_y = tile_partitioner.subtile_slice( - rank, grid_quantity.dims, (npx, npy) - ) - global_is = nhalo + slice_x.start - global_js = nhalo + slice_y.start - global_ie = nhalo + slice_x.stop - 1 - global_je = nhalo + slice_y.stop - 1 - jstart = max(4, global_js) - global_js + nhalo - jend = min(npy + nhalo - 1, global_je + 2) - global_js + nhalo - istart = max(4, global_is) - global_is + nhalo - iend = min(npx + nhalo - 1, global_ie + 2) - global_is + nhalo - if grid_type < 3: - if tile_partitioner.on_tile_left(rank): - edge_w[jstart - nhalo : jend - nhalo] = set_west_edge_factor( - grid, agrid, nhalo, radius, jstart, jend, np - ) - if tile_partitioner.on_tile_right(rank): - edge_e[jstart - nhalo : jend - nhalo] = set_east_edge_factor( - grid, agrid, nhalo, radius, jstart, jend, np - ) - if tile_partitioner.on_tile_bottom(rank): - edge_s[istart - nhalo : iend - nhalo] = set_south_edge_factor( - grid, agrid, nhalo, radius, istart, iend, np - ) - if tile_partitioner.on_tile_top(rank): - edge_n[istart - nhalo : iend - nhalo] = set_north_edge_factor( - grid, agrid, nhalo, radius, istart, iend, np - ) - - return edge_w[np.newaxis, :], edge_e[np.newaxis, :], edge_s, edge_n - - -def set_west_edge_factor(grid, agrid, nhalo, radius, jstart, jend, np): - py0, py1 = lon_lat_midpoint( - agrid[nhalo - 1, jstart - 1 : jend, 0], - agrid[nhalo, jstart - 1 : jend, 0], - agrid[nhalo - 1, jstart - 1 : jend, 1], - agrid[nhalo, jstart - 1 : jend, 1], - np, - ) - - d1 = great_circle_distance_lon_lat( - py0[:-1], - grid[nhalo, jstart:jend, 0], - py1[:-1], - grid[nhalo, jstart:jend, 1], - radius, - np, - ) - d2 = great_circle_distance_lon_lat( - py0[1:], - grid[nhalo, jstart:jend, 0], - py1[1:], - grid[nhalo, jstart:jend, 1], - radius, - np, - ) - west_edge_factor = d2 / (d1 + d2) - return west_edge_factor - - -def set_east_edge_factor(grid, agrid, nhalo, radius, jstart, jend, np): - return set_west_edge_factor( - grid[::-1, :, :], agrid[::-1, :, :], nhalo, radius, jstart, jend, np - ) - - -def set_south_edge_factor(grid, agrid, nhalo, radius, jstart, jend, np): - return set_west_edge_factor( - grid.transpose([1, 0, 2]), - agrid.transpose([1, 0, 2]), - nhalo, - radius, - jstart, - jend, - np, - ) - - -def set_north_edge_factor(grid, agrid, nhalo, radius, jstart, jend, np): - return set_west_edge_factor( - grid[:, ::-1, :].transpose([1, 0, 2]), - agrid[:, ::-1, :].transpose([1, 0, 2]), - nhalo, - radius, - jstart, - jend, - np, - ) - - -def efactor_a2c_v( - grid_quantity: Quantity, - agrid, - grid_type: int, - nhalo: int, - tile_partitioner: TilePartitioner, - rank: int, - radius: float, - np, -): - """ - Creates interpolation factors at tile edges - for interpolating vectors from A to C grids - """ - big_number = 1.0e8 - grid = grid_quantity.data[:] - npx, npy, ndims = tile_partitioner.global_extent(grid_quantity) - slice_x, slice_y = tile_partitioner.subtile_slice( - rank, grid_quantity.dims, (npx, npy) - ) - global_is = nhalo + slice_x.start - global_js = nhalo + slice_y.start - - if npx != npy: - raise ValueError("npx must equal npy") - if npx % 2 == 0: - raise ValueError("npx must be odd") - i_midpoint = int((npx - 1) / 2) - j_midpoint = int((npy - 1) / 2) - i_indices = np.arange(agrid.shape[0] - nhalo + 1) + global_is - nhalo - j_indices = np.arange(agrid.shape[1] - nhalo + 1) + global_js - nhalo - i_selection = i_indices[i_indices <= nhalo + i_midpoint] - j_selection = j_indices[j_indices <= nhalo + j_midpoint] - if len(i_selection) > 0: - im2 = max(i_selection) - global_is - else: - im2 = len(i_selection) - if len(i_selection) == len(i_indices): - im2 = len(i_selection) - nhalo - if len(j_selection) > 0: - jm2 = max(j_selection) - global_js - else: - jm2 = len(j_selection) - if len(j_selection) == len(j_indices): - jm2 = len(j_selection) - nhalo - im2 = max(im2, -1) - jm2 = max(jm2, -1) - - edge_vect_s = np.zeros(grid.shape[0] - 1) + big_number - edge_vect_n = np.zeros(grid.shape[0] - 1) + big_number - edge_vect_e = np.zeros(grid.shape[1] - 1) + big_number - edge_vect_w = np.zeros(grid.shape[1] - 1) + big_number - if grid_type < 3: - if tile_partitioner.on_tile_left(rank): - edge_vect_w[2:-2] = calculate_west_edge_vectors( - grid, agrid, jm2, nhalo, radius, np - ) - if tile_partitioner.on_tile_bottom(rank): - edge_vect_w[nhalo - 1] = edge_vect_w[nhalo] - if tile_partitioner.on_tile_top(rank): - edge_vect_w[-nhalo] = edge_vect_w[-nhalo - 1] - if tile_partitioner.on_tile_right(rank): - edge_vect_e[2:-2] = calculate_east_edge_vectors( - grid, agrid, jm2, nhalo, radius, np - ) - if tile_partitioner.on_tile_bottom(rank): - edge_vect_e[nhalo - 1] = edge_vect_e[nhalo] - if tile_partitioner.on_tile_top(rank): - edge_vect_e[-nhalo] = edge_vect_e[-nhalo - 1] - if tile_partitioner.on_tile_bottom(rank): - edge_vect_s[2:-2] = calculate_south_edge_vectors( - grid, agrid, im2, nhalo, radius, np - ) - if tile_partitioner.on_tile_left(rank): - edge_vect_s[nhalo - 1] = edge_vect_s[nhalo] - if tile_partitioner.on_tile_right(rank): - edge_vect_s[-nhalo] = edge_vect_s[-nhalo - 1] - if tile_partitioner.on_tile_top(rank): - edge_vect_n[2:-2] = calculate_north_edge_vectors( - grid, agrid, im2, nhalo, radius, np - ) - if tile_partitioner.on_tile_left(rank): - edge_vect_n[nhalo - 1] = edge_vect_n[nhalo] - if tile_partitioner.on_tile_right(rank): - edge_vect_n[-nhalo] = edge_vect_n[-nhalo - 1] - - return edge_vect_w, edge_vect_e, edge_vect_s, edge_vect_n - - -def calculate_west_edge_vectors(grid, agrid, jm2, nhalo, radius, np): - d2 = np.zeros(agrid.shape[0] - 2 * nhalo + 2) - d1 = np.zeros(agrid.shape[0] - 2 * nhalo + 2) - - py0, py1 = lon_lat_midpoint( - agrid[nhalo - 1, nhalo - 2 : -nhalo + 2, 0], - agrid[nhalo, nhalo - 2 : -nhalo + 2, 0], - agrid[nhalo - 1, nhalo - 2 : -nhalo + 2, 1], - agrid[nhalo, nhalo - 2 : -nhalo + 2, 1], - np, - ) - - p20, p21 = lon_lat_midpoint( - grid[nhalo, nhalo - 2 : -nhalo + 1, 0], - grid[nhalo, nhalo - 1 : -nhalo + 2, 0], - grid[nhalo, nhalo - 2 : -nhalo + 1, 1], - grid[nhalo, nhalo - 1 : -nhalo + 2, 1], - np, - ) - - py = np.array([py0, py1]).transpose([1, 0]) - p2 = np.array([p20, p21]).transpose([1, 0]) - - d1[: jm2 + 1] = great_circle_distance_lon_lat( - py[1 : jm2 + 2, 0], - p2[1 : jm2 + 2, 0], - py[1 : jm2 + 2, 1], - p2[1 : jm2 + 2, 1], - radius, - np, - ) - d2[: jm2 + 1] = great_circle_distance_lon_lat( - py[2 : jm2 + 3, 0], - p2[1 : jm2 + 2, 0], - py[2 : jm2 + 3, 1], - p2[1 : jm2 + 2, 1], - radius, - np, - ) - d1[jm2 + 1 :] = great_circle_distance_lon_lat( - py[jm2 + 2 : -1, 0], - p2[jm2 + 2 : -1, 0], - py[jm2 + 2 : -1, 1], - p2[jm2 + 2 : -1, 1], - radius, - np, - ) - d2[jm2 + 1 :] = great_circle_distance_lon_lat( - py[jm2 + 1 : -2, 0], - p2[jm2 + 2 : -1, 0], - py[jm2 + 1 : -2, 1], - p2[jm2 + 2 : -1, 1], - radius, - np, - ) - - return d1 / (d2 + d1) - - -def calculate_east_edge_vectors(grid, agrid, jm2, nhalo, radius, np): - return calculate_west_edge_vectors( - grid[::-1, :, :], agrid[::-1, :, :], jm2, nhalo, radius, np - ) - - -def calculate_south_edge_vectors(grid, agrid, im2, nhalo, radius, np): - return calculate_west_edge_vectors( - grid.transpose([1, 0, 2]), agrid.transpose([1, 0, 2]), im2, nhalo, radius, np - ) - - -def calculate_north_edge_vectors(grid, agrid, jm2, nhalo, radius, np): - return calculate_west_edge_vectors( - grid[:, ::-1, :].transpose([1, 0, 2]), - agrid[:, ::-1, :].transpose([1, 0, 2]), - jm2, - nhalo, - radius, - np, - ) - - -def unit_vector_lonlat(grid, np): - """ - Calculates the cartesian unit vectors for each point on a lat/lon grid - """ - - sin_lon = np.sin(grid[:, :, 0]) - cos_lon = np.cos(grid[:, :, 0]) - sin_lat = np.sin(grid[:, :, 1]) - cos_lat = np.cos(grid[:, :, 1]) - - unit_lon = np.array([-sin_lon, cos_lon, np.zeros(grid[:, :, 0].shape)]).transpose( - [1, 2, 0] - ) - unit_lat = np.array([-sin_lat * cos_lon, -sin_lat * sin_lon, cos_lat]).transpose( - [1, 2, 0] - ) - - return unit_lon, unit_lat - - -def _fill_halo_corners(field, value: float, nhalo: int, tile_partitioner, rank): - """ - Fills a tile halo corners (ghost cells) of a field - with a set value along the first 2 axes - """ - if tile_partitioner.on_tile_left(rank): - if tile_partitioner.on_tile_bottom(rank): # SW corner - field[:nhalo, :nhalo] = value - if tile_partitioner.on_tile_top(rank): # NW corner - field[:nhalo, -nhalo:] = value - if tile_partitioner.on_tile_right(rank): - if tile_partitioner.on_tile_bottom(rank): # SE corner - field[-nhalo:, :nhalo] = value - if tile_partitioner.on_tile_top(rank): - field[-nhalo:, -nhalo:] = value # NE corner - - -def _fill_single_halo_corner(field, value: float, nhalo: int, corner: str): - """ - Fills a tile halo corner (ghost cells) of a field - with a set value along the first 2 axes - Args: - field: the field to fill in, assumed to have x and y as the first 2 dimensions - value: the value to fill - nhalo: the number of halo points in the field - corner: which corner to fill - """ - if (corner == "sw") or (corner == "southwest"): - field[:nhalo, :nhalo] = value - elif (corner == "nw") or (corner == "northwest"): - field[:nhalo, -nhalo:] = value - elif (corner == "se") or (corner == "southeast"): - field[-nhalo:, :nhalo] = value - elif (corner == "ne") or (corner == "northeast"): - field[-nhalo:, -nhalo:] = value - else: - raise ValueError("fill ghost requires a corner to be one of: sw, se, nw, ne") diff --git a/util/pace/util/grid/global_setup.py b/util/pace/util/grid/global_setup.py deleted file mode 100644 index aa97f9364..000000000 --- a/util/pace/util/grid/global_setup.py +++ /dev/null @@ -1,280 +0,0 @@ -import math - -from pace.util.constants import PI, RADIUS - -from .generation import MetricTerms -from .gnomonic import ( - _cart_to_latlon, - _check_shapes, - _latlon2xyz, - _mirror_latlon, - symm_ed, -) -from .mirror import _rot_3d - - -def gnomonic_grid(grid_type: int, lon, lat, np): - """ - Apply gnomonic grid to lon and lat arrays for all tiles. Tiles must then be rotated - and mirrored to the correct orientations before use. - This global mesh generation is the way the Fortran code initializes the lon/lat - grids and is reproduced here for testing purposes. - - args: - grid_type: type of grid to apply - lon: longitute array with dimensions [x, y] - lat: latitude array with dimensionos [x, y] - """ - _check_shapes(lon, lat) - if grid_type == 0: - global_gnomonic_ed(lon, lat, np) - elif grid_type == 1: - raise NotImplementedError() - elif grid_type == 2: - raise NotImplementedError() - if grid_type < 3: - symm_ed(lon, lat) - lon[:] -= PI - - -# A tile global version of gnomonic_ed -# closer to the Fortran code -def global_gnomonic_ed(lon, lat, np): - im = lon.shape[0] - 1 - alpha = np.arcsin(3 ** -0.5) - dely = np.multiply(2.0, alpha) / float(im) - pp = np.zeros((3, im + 1, im + 1)) - - for j in range(0, im + 1): - lon[0, j] = 0.75 * PI # West edge - lon[im, j] = 1.25 * PI # East edge - lat[0, j] = -alpha + dely * float(j) # West edge - lat[im, j] = lat[0, j] # East edge - - # Get North-South edges by symmetry - for i in range(1, im): - lon[i, 0], lat[i, 0] = _mirror_latlon( - lon[0, 0], lat[0, 0], lon[im, im], lat[im, im], lon[0, i], lat[0, i], np - ) - lon[i, im] = lon[i, 0] - lat[i, im] = -lat[i, 0] - - # set 4 corners - pp[:, 0, 0] = _latlon2xyz(lon[0, 0], lat[0, 0], np) - pp[:, im, 0] = _latlon2xyz(lon[im, 0], lat[im, 0], np) - pp[:, 0, im] = _latlon2xyz(lon[0, im], lat[0, im], np) - pp[:, im, im] = _latlon2xyz(lon[im, im], lat[im, im], np) - - # map edges on the sphere back to cube: intersection at x = -1/sqrt(3) - i = 0 - for j in range(1, im): - pp[:, i, j] = _latlon2xyz(lon[i, j], lat[i, j], np) - pp[1, i, j] = -pp[1, i, j] * (3 ** -0.5) / pp[0, i, j] - pp[2, i, j] = -pp[2, i, j] * (3 ** -0.5) / pp[0, i, j] - - j = 0 - for i in range(1, im): - pp[:, i, j] = _latlon2xyz(lon[i, j], lat[i, j], np) - pp[1, i, j] = -pp[1, i, j] * (3 ** -0.5) / pp[0, i, j] - pp[2, i, j] = -pp[2, i, j] * (3 ** -0.5) / pp[0, i, j] - - pp[0, :, :] = -(3 ** -0.5) - for j in range(1, im + 1): - # copy y-z face of the cube along j=0 - pp[1, 1:, j] = pp[1, 1:, 0] - # copy along i=0 - pp[2, 1:, j] = pp[2, 0, j] - _cart_to_latlon(im + 1, pp, lon, lat, np) - - -# A tile global version of mirror_grid -# Closer to the Fortran code -def global_mirror_grid( - grid_global, ng: int, npx: int, npy: int, np, right_hand_grid: bool -): - """ - Mirrors and rotates all tiles of a lon/lat grid to the correct orientation. - The tiles must then be partitioned onto the appropriate ranks. - This global mesh generation is the way the Fortran code initializes the lon/lat - grids and is reproduced here for testing purposes. - """ - # first fix base region - nreg = 0 - for j in range(0, math.ceil(npy / 2)): - for i in range(0, math.ceil(npx / 2)): - x1 = np.multiply( - 0.25, - np.abs(grid_global[ng + i, ng + j, 0, nreg]) - + np.abs(grid_global[ng + npx - (i + 1), ng + j, 0, nreg]) - + np.abs(grid_global[ng + i, ng + npy - (j + 1), 0, nreg]) - + np.abs(grid_global[ng + npx - (i + 1), ng + npy - (j + 1), 0, nreg]), - ) - grid_global[ng + i, ng + j, 0, nreg] = np.copysign( - x1, grid_global[ng + i, ng + j, 0, nreg] - ) - grid_global[ng + npx - (i + 1), ng + j, 0, nreg] = np.copysign( - x1, grid_global[ng + npx - (i + 1), ng + j, 0, nreg] - ) - grid_global[ng + i, ng + npy - (j + 1), 0, nreg] = np.copysign( - x1, grid_global[ng + i, ng + npy - (j + 1), 0, nreg] - ) - grid_global[ng + npx - (i + 1), ng + npy - (j + 1), 0, nreg] = np.copysign( - x1, grid_global[ng + npx - (i + 1), ng + npy - (j + 1), 0, nreg] - ) - - y1 = np.multiply( - 0.25, - np.abs(grid_global[ng + i, ng + j, 1, nreg]) - + np.abs(grid_global[ng + npx - (i + 1), ng + j, 1, nreg]) - + np.abs(grid_global[ng + i, ng + npy - (j + 1), 1, nreg]) - + np.abs(grid_global[ng + npx - (i + 1), ng + npy - (j + 1), 1, nreg]), - ) - - grid_global[ng + i, ng + j, 1, nreg] = np.copysign( - y1, grid_global[ng + i, ng + j, 1, nreg] - ) - grid_global[ng + npx - (i + 1), ng + j, 1, nreg] = np.copysign( - y1, grid_global[ng + npx - (i + 1), ng + j, 1, nreg] - ) - grid_global[ng + i, ng + npy - (j + 1), 1, nreg] = np.copysign( - y1, grid_global[ng + i, ng + npy - (j + 1), 1, nreg] - ) - grid_global[ng + npx - (i + 1), ng + npy - (j + 1), 1, nreg] = np.copysign( - y1, grid_global[ng + npx - (i + 1), ng + npy - (j + 1), 1, nreg] - ) - - # force dateline/greenwich-meridion consistency - if npx % 2 != 0: - if i == (npx - 1) // 2: - grid_global[ng + i, ng + j, 0, nreg] = 0.0 - grid_global[ng + i, ng + npy - (j + 1), 0, nreg] = 0.0 - - i_mid = (npx - 1) // 2 - j_mid = (npy - 1) // 2 - for nreg in range(1, MetricTerms.N_TILES): - for j in range(0, npy): - x1 = grid_global[ng : ng + npx, ng + j, 0, 0] - y1 = grid_global[ng : ng + npx, ng + j, 1, 0] - z1 = np.add(RADIUS, np.multiply(0.0, x1)) - - if nreg == 1: - ang = -90.0 - x2, y2, z2 = _rot_3d( - 3, - [x1, y1, z1], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - elif nreg == 2: - ang = -90.0 - x2, y2, z2 = _rot_3d( - 3, - [x1, y1, z1], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - ang = 90.0 - x2, y2, z2 = _rot_3d( - 1, - [x2, y2, z2], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - # force North Pole and dateline/Greenwich-Meridian consistency - if npx % 2 != 0: - if j == i_mid: - x2[i_mid] = 0.0 - y2[i_mid] = PI / 2.0 - if j == j_mid: - x2[: i_mid + 1] = 0.0 - x2[i_mid + 1 :] = PI - elif nreg == 3: - ang = -180.0 - x2, y2, z2 = _rot_3d( - 3, - [x1, y1, z1], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - ang = 90.0 - x2, y2, z2 = _rot_3d( - 1, - [x2, y2, z2], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - # force dateline/Greenwich-Meridian consistency - if npx % 2 != 0: - if j == (npy - 1) // 2: - x2[:] = PI - elif nreg == 4: - ang = 90.0 - x2, y2, z2 = _rot_3d( - 3, - [x1, y1, z1], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - ang = 90.0 - x2, y2, z2 = _rot_3d( - 2, - [x2, y2, z2], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - elif nreg == 5: - ang = 90.0 - x2, y2, z2 = _rot_3d( - 2, - [x1, y1, z1], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - ang = 0.0 - x2, y2, z2 = _rot_3d( - 3, - [x2, y2, z2], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - # force South Pole and dateline/Greenwich-Meridian consistency - if npx % 2 != 0: - if j == i_mid: - x2[i_mid] = 0.0 - y2[i_mid] = -PI / 2.0 - if j > j_mid: - x2[i_mid] = 0.0 - elif j < j_mid: - x2[i_mid] = PI - - grid_global[ng : ng + npx, ng + j, 0, nreg] = x2 - grid_global[ng : ng + npx, ng + j, 1, nreg] = y2 - - return grid_global diff --git a/util/pace/util/grid/gnomonic.py b/util/pace/util/grid/gnomonic.py deleted file mode 100644 index f26af0f2f..000000000 --- a/util/pace/util/grid/gnomonic.py +++ /dev/null @@ -1,734 +0,0 @@ -import math - -from pace.util.constants import PI - - -def _check_shapes(lon, lat): - if len(lon.shape) != 2: - raise ValueError(f"longitude must be 2D, has shape {lon.shape}") - elif len(lat.shape) != 2: - raise ValueError(f"latitude must be 2D, has shape {lat.shape}") - elif lon.shape[0] != lon.shape[1]: - raise ValueError(f"longitude must be square, has shape {lon.shape}") - elif lat.shape[0] != lat.shape[1]: - raise ValueError(f"latitude must be square, has shape {lat.shape}") - elif lon.shape[0] != lat.shape[0]: - raise ValueError( - "longitude and latitude must have same shape, but they are " - f"{lon.shape} and {lat.shape}" - ) - - -def lat_tile_east_west_edge(alpha, dely, south_north_tile_index): - return -alpha + dely * float(south_north_tile_index) - - -def local_gnomonic_ed( - lon, - lat, - npx, - west_edge, - east_edge, - south_edge, - north_edge, - global_is, - global_js, - np, - rank, -): - _check_shapes(lon, lat) - # tile_im, wedge_dict, corner_dict, global_is, global_js - im = lon.shape[0] - 1 - alpha = np.arcsin(3 ** -0.5) - tile_im = npx - 1 - dely = np.multiply(2.0, alpha / float(tile_im)) - halo = 3 - pp = np.zeros((3, im + 1, im + 1)) - pp_west_tile_edge = np.zeros((3, 1, im + 1)) - pp_south_tile_edge = np.zeros((3, im + 1, 1)) - lon_west_tile_edge = np.zeros((1, im + 1)) - lon_south_tile_edge = np.zeros((im + 1, 1)) - lat_west_tile_edge = np.zeros((1, im + 1)) - lat_south_tile_edge = np.zeros((im + 1, 1)) - lat_west_tile_edge_mirror = np.zeros((1, im + 1)) - - lon_west = 0.75 * PI - lon_east = 1.25 * PI - lat_south = lat_tile_east_west_edge(alpha, dely, 0) - lat_north = lat_tile_east_west_edge(alpha, dely, tile_im) - - start_i = 1 if west_edge else 0 - end_i = im if east_edge else im + 1 - start_j = 1 if south_edge else 0 - lon_west_tile_edge[0, :] = lon_west - for j in range(0, im + 1): - lat_west_tile_edge[0, j] = lat_tile_east_west_edge( - alpha, dely, global_js - halo + j - ) - lat_west_tile_edge_mirror[0, j] = lat_tile_east_west_edge( - alpha, dely, global_is - halo + j - ) - - if east_edge: - lon_south_tile_edge[im, 0] = 1.25 * PI - lat_south_tile_edge[im, 0] = lat_tile_east_west_edge( - alpha, dely, global_js - halo - ) - - # Get North-South edges by symmetry - for i in range(start_i, end_i): - edge_lon, edge_lat = _mirror_latlon( - lon_west, - lat_south, - lon_east, - lat_north, - lon_west_tile_edge[0, i], - lat_west_tile_edge_mirror[0, i], - np, - ) - lon_south_tile_edge[i, 0] = edge_lon - lat_south_tile_edge[i, 0] = edge_lat - - # map edges on the sphere back to cube: intersection at x = -1/sqrt(3) - i = 0 - for j in range(im + 1): - pp_west_tile_edge[:, i, j] = _latlon2xyz( - lon_west_tile_edge[i, j], lat_west_tile_edge[i, j], np - ) - pp_west_tile_edge[1, i, j] = ( - -pp_west_tile_edge[1, i, j] * (3 ** -0.5) / pp_west_tile_edge[0, i, j] - ) - pp_west_tile_edge[2, i, j] = ( - -pp_west_tile_edge[2, i, j] * (3 ** -0.5) / pp_west_tile_edge[0, i, j] - ) - if west_edge: - pp[:, 0, :] = pp_west_tile_edge[:, 0, :] - - j = 0 - for i in range(im + 1): - pp_south_tile_edge[:, i, j] = _latlon2xyz( - lon_south_tile_edge[i, j], lat_south_tile_edge[i, j], np - ) - pp_south_tile_edge[1, i, j] = ( - -pp_south_tile_edge[1, i, j] * (3 ** -0.5) / pp_south_tile_edge[0, i, j] - ) - pp_south_tile_edge[2, i, j] = ( - -pp_south_tile_edge[2, i, j] * (3 ** -0.5) / pp_south_tile_edge[0, i, j] - ) - if south_edge: - pp[:, :, 0] = pp_south_tile_edge[:, :, 0] - - # set 4 corners - if south_edge or west_edge: - sw_xyz = _latlon2xyz(lon_west, lat_south, np) - if south_edge and west_edge: - pp[:, 0, 0] = sw_xyz - if south_edge: - pp_west_tile_edge[:, 0, 0] = sw_xyz - if west_edge: - pp_south_tile_edge[:, 0, 0] = sw_xyz - if east_edge: - se_xyz = _latlon2xyz(lon_east, lat_south, np) - pp_south_tile_edge[:, im, 0] = se_xyz - - if north_edge: - nw_xyz = _latlon2xyz(lon_west, lat_north, np) - pp_west_tile_edge[:, 0, im] = nw_xyz - - if north_edge and east_edge: - pp[:, im, im] = _latlon2xyz(lon_east, lat_north, np) - - pp[0, :, :] = -(3 ** -0.5) - for j in range(start_j, im + 1): - # copy y-z face of the cube along j=0 - pp[1, start_i:, j] = pp_south_tile_edge[1, start_i:, 0] # pp[1,:,0] - # copy along i=0 - pp[2, start_i:, j] = pp_west_tile_edge[2, 0, j] # pp[4,0,j] - - _cart_to_latlon(im + 1, pp, lon, lat, np) - # TODO replicating the last step of gnomonic_grid until api is finalized - # remove this if this method is called from gnomonic_grid - # if grid_type < 3: - symm_ed(lon, lat) - lon[:] -= PI - - -def _corner_to_center_mean(corner_array): - """Given a 2D array on cell corners, return a 2D array on cell centers with the - mean value of each of the corners.""" - return xyz_midpoint( - corner_array[1:, 1:], - corner_array[:-1, :-1], - corner_array[1:, :-1], - corner_array[:-1, 1:], - ) - - -def normalize_vector(np, *vector_components): - scale = np.divide( - 1.0, - np.sum(np.asarray([item ** 2.0 for item in vector_components]), axis=0) ** 0.5, - ) - return np.asarray([item * scale for item in vector_components]) - - -def normalize_xyz(xyz): - # double transpose to broadcast along last dimension instead of first - return (xyz.T / ((xyz ** 2).sum(axis=-1) ** 0.5).T).T - - -def lon_lat_midpoint(lon1, lon2, lat1, lat2, np): - p1 = lon_lat_to_xyz(lon1, lat1, np) - p2 = lon_lat_to_xyz(lon2, lat2, np) - midpoint = xyz_midpoint(p1, p2) - return xyz_to_lon_lat(midpoint, np) - - -def xyz_midpoint(*points): - return normalize_xyz(sum(points)) - - -def lon_lat_corner_to_cell_center(lon, lat, np): - # just perform the mean in x-y-z space and convert back - xyz = lon_lat_to_xyz(lon, lat, np) - center = _corner_to_center_mean(xyz) - return xyz_to_lon_lat(center, np) - - -def lon_lat_to_xyz(lon, lat, np): - """map (lon, lat) to (x, y, z) - Args: - lon: 2d array of longitudes - lat: 2d array of latitudes - np: numpy-like module for arrays - Returns: - xyz: 3d array whose last dimension is length 3 and indicates x/y/z value - """ - x = np.cos(lat) * np.cos(lon) - y = np.cos(lat) * np.sin(lon) - z = np.sin(lat) - x, y, z = normalize_vector(np, x, y, z) - if len(lon.shape) == 2: - xyz = np.concatenate([arr[:, :, None] for arr in (x, y, z)], axis=-1) - elif len(lon.shape) == 1: - xyz = np.concatenate([arr[:, None] for arr in (x, y, z)], axis=-1) - return xyz - - -def xyz_to_lon_lat(xyz, np): - """map (x, y, z) to (lon, lat) - Returns: - xyz: 3d array whose last dimension is length 3 and indicates x/y/z value - np: numpy-like module for arrays - Returns: - lon: 2d array of longitudes - lat: 2d array of latitudes - """ - xyz = normalize_xyz(xyz) - # double transpose to index last dimension, regardless of number of dimensions - x = xyz.T[0, :].T - y = xyz.T[1, :].T - z = xyz.T[2, :].T - lon = 0.0 * x - nonzero_lon = np.abs(x) + np.abs(y) >= 1.0e-10 - lon[nonzero_lon] = np.arctan2(y[nonzero_lon], x[nonzero_lon]) - negative_lon = lon < 0.0 - while np.any(negative_lon): - lon[negative_lon] += 2 * PI - negative_lon = lon < 0.0 - lat = np.arcsin(z) - return lon, lat - - -def _latlon2xyz(lon, lat, np): - """map (lon, lat) to (x, y, z)""" - x = np.cos(lat) * np.cos(lon) - y = np.cos(lat) * np.sin(lon) - z = np.sin(lat) - return normalize_vector(np, x, y, z) - - -def _xyz2latlon(x, y, z, np): - """map (x, y, z) to (lon, lat)""" - x, y, z = normalize_vector(np, x, y, z) - lon = 0.0 * x - nonzero_lon = np.abs(x) + np.abs(y) >= 1.0e-10 - lon[nonzero_lon] = np.arctan2(y[nonzero_lon], x[nonzero_lon]) - negative_lon = lon < 0.0 - while np.any(negative_lon): - lon[negative_lon] += 2 * PI - negative_lon = lon < 0.0 - lat = np.arcsin(z) - - return lon, lat - - -def _cart_to_latlon(im, q, xs, ys, np): - """map (x, y, z) to (lon, lat)""" - - esl = 1.0e-10 - - for j in range(im): - for i in range(im): - p = q[:, i, j] - dist = np.sqrt(p[0] ** 2 + p[1] ** 2 + p[2] ** 2) - p = p / dist - - if np.abs(p[0]) + np.abs(p[1]) < esl: - lon = 0.0 - else: - lon = np.arctan2(p[1], p[0]) # range [-PI, PI] - - if lon < 0.0: - lon = np.add(2.0 * PI, lon) - - lat = np.arcsin(p[2]) - - xs[i, j] = lon - ys[i, j] = lat - - q[:, i, j] = p - - -def _mirror_latlon(lon1, lat1, lon2, lat2, lon0, lat0, np): - - p0 = _latlon2xyz(lon0, lat0, np) - p1 = _latlon2xyz(lon1, lat1, np) - p2 = _latlon2xyz(lon2, lat2, np) - nb = _vect_cross(p1, p2, np) - - pdot = np.sqrt(nb[0] ** 2 + nb[1] ** 2 + nb[2] ** 2) - nb = nb / pdot - - pdot = p0[0] * nb[0] + p0[1] * nb[1] + p0[2] * nb[2] - pp = p0 - np.multiply(2.0, pdot) * nb - - lon3 = np.zeros((1, 1)) - lat3 = np.zeros((1, 1)) - pp3 = np.zeros((3, 1, 1)) - pp3[:, 0, 0] = pp - _cart_to_latlon(1, pp3, lon3, lat3, np) - - return lon3[0, 0], lat3[0, 0] - - -def _vect_cross(p1, p2, np): - return np.asarray( - [ - p1[1] * p2[2] - p1[2] * p2[1], - p1[2] * p2[0] - p1[0] * p2[2], - p1[0] * p2[1] - p1[1] * p2[0], - ] - ) - - -def symm_ed(lon, lat): - pass - - -def _great_circle_beta_lon_lat(lon1, lon2, lat1, lat2, np): - """Returns the great-circle distance between points along the desired axis, - as a fraction of the radius of the sphere.""" - return ( - np.arcsin( - np.sqrt( - np.sin((lat1 - lat2) / 2.0) ** 2 - + np.cos(lat1) * np.cos(lat2) * np.sin((lon1 - lon2) / 2.0) ** 2 - ) - ) - * 2.0 - ) - - -def great_circle_distance_along_axis(lon, lat, radius, np, axis=0): - """Returns the great-circle distance between points along the desired axis.""" - lon, lat = np.broadcast_arrays(lon, lat) - if len(lon.shape) == 1: - case_1d = True - # add singleton dimension so we can use the same indexing notation as n-d cases - lon, lat = lon[:, None], lat[:, None] - else: - case_1d = False - swap_dims = list(range(len(lon.shape))) - swap_dims[axis], swap_dims[0] = swap_dims[0], swap_dims[axis] - # below code computes distance along first axis, so we put the desired axis there - lon, lat = lon.transpose(swap_dims), lat.transpose(swap_dims) - result = great_circle_distance_lon_lat( - lon[:-1, :], lon[1:, :], lat[:-1, :], lat[1:, :], radius, np - ) - result = result.transpose(swap_dims) # remember to swap back - if case_1d: - result = result[:, 0] # remove the singleton dimension we added - return result - - -def great_circle_distance_lon_lat(lon1, lon2, lat1, lat2, radius, np): - return radius * _great_circle_beta_lon_lat(lon1, lon2, lat1, lat2, np) - - -def great_circle_distance_xyz(p1, p2, radius, np): - lon1, lat1 = xyz_to_lon_lat(p1, np) - lon2, lat2 = xyz_to_lon_lat(p2, np) - return great_circle_distance_lon_lat(lon1, lon2, lat1, lat2, radius, np) - - -def get_area(lon, lat, radius, np): - """ - Given latitude and longitude on cell corners, return the area of each cell. - """ - xyz = lon_lat_to_xyz(lon, lat, np) - lower_left = xyz[(slice(None, -1), slice(None, -1), slice(None, None))] - lower_right = xyz[(slice(1, None), slice(None, -1), slice(None, None))] - upper_left = xyz[(slice(None, -1), slice(1, None), slice(None, None))] - upper_right = xyz[(slice(1, None), slice(1, None), slice(None, None))] - return get_rectangle_area( - lower_left, upper_left, upper_right, lower_right, radius, np - ) - - -def set_corner_area_to_triangle_area( - lon, lat, area, tile_partitioner, rank, radius, np -): - """ - Given latitude and longitude on cell corners, and an array of cell areas, set the - four corner areas to the area of the inner triangle at those corners. - """ - xyz = lon_lat_to_xyz(lon, lat, np) - lower_left = xyz[(slice(None, -1), slice(None, -1), slice(None, None))] - lower_right = xyz[(slice(1, None), slice(None, -1), slice(None, None))] - upper_left = xyz[(slice(None, -1), slice(1, None), slice(None, None))] - upper_right = xyz[(slice(1, None), slice(1, None), slice(None, None))] - if tile_partitioner.on_tile_left(rank) and tile_partitioner.on_tile_bottom(rank): - area[0, 0] = get_triangle_area( - upper_left[0, 0], upper_right[0, 0], lower_right[0, 0], radius, np - ) - if tile_partitioner.on_tile_right(rank) and tile_partitioner.on_tile_bottom(rank): - area[-1, 0] = get_triangle_area( - upper_right[-1, 0], upper_left[-1, 0], lower_left[-1, 0], radius, np - ) - if tile_partitioner.on_tile_right(rank) and tile_partitioner.on_tile_top(rank): - area[-1, -1] = get_triangle_area( - lower_right[-1, -1], lower_left[-1, -1], upper_left[-1, -1], radius, np - ) - if tile_partitioner.on_tile_left(rank) and tile_partitioner.on_tile_top(rank): - area[0, -1] = get_triangle_area( - lower_left[0, -1], lower_right[0, -1], upper_right[0, -1], radius, np - ) - - -def set_c_grid_tile_border_area( - xyz_dgrid, xyz_agrid, radius, area_cgrid, tile_partitioner, rank, np -): - """ - Using latitude and longitude without halo points, fix C-grid area at tile edges and - corners. - Naively, the c-grid area is calculated as the area between the rectangle at the - four corners of the grid cell. At tile edges however, this is not accurate, - because the area makes a butterfly-like shape as it crosses the tile boundary. - Instead we calculate the area on one side of that shape, and multiply it by two. - At corners, the corner is composed of three rectangles from each tile bordering - the corner. We calculate the area from one tile and multiply it by three. - Args: - xyz_dgrid: d-grid cartesian coordinates as a 3-d array, last dimension - of length 3 indicating x/y/z - xyz_agrid: a-grid cartesian coordinates as a 3-d array, last dimension - of length 3 indicating x/y/z - area_cgrid: 2d array of c-grid areas - radius: radius of Earth in metres - tile_partitioner: partitioner class to determine subtile position - rank: rank of current tile - np: numpy-like module to interact with arrays - """ - - if tile_partitioner.on_tile_left(rank): - _set_c_grid_west_edge_area(xyz_dgrid, xyz_agrid, area_cgrid, radius, np) - - if tile_partitioner.on_tile_top(rank): - _set_c_grid_north_edge_area(xyz_dgrid, xyz_agrid, area_cgrid, radius, np) - - if tile_partitioner.on_tile_right(rank): - _set_c_grid_east_edge_area(xyz_dgrid, xyz_agrid, area_cgrid, radius, np) - - if tile_partitioner.on_tile_bottom(rank): - _set_c_grid_south_edge_area(xyz_dgrid, xyz_agrid, area_cgrid, radius, np) - - """ -# TODO add these back if we change the fortran side, or -# decide the 'if sw_corner' should happen - if tile_partitioner.on_tile_left(rank): - if tile_partitioner.on_tile_top(rank): - _set_c_grid_northwest_corner_area( - xyz_dgrid, xyz_agrid, area_cgrid, radius, np - ) - if tile_partitioner.on_tile_bottom(rank): - _set_c_grid_southwest_corner_area_mod( - xyz_dgrid, xyz_agrid, area_cgrid, radius, np - ) - if tile_partitioner.on_tile_right(rank): - if tile_partitioner.on_tile_bottom(rank): - _set_c_grid_southeast_corner_area( - xyz_dgrid, xyz_agrid, area_cgrid, radius, np - ) - if tile_partitioner.on_tile_top(rank): - _set_c_grid_northeast_corner_area( - xyz_dgrid, xyz_agrid, area_cgrid, radius, np - ) - """ - - -def _set_c_grid_west_edge_area(xyz_dgrid, xyz_agrid, area_cgrid, radius, np): - xyz_y_center = 0.5 * (xyz_dgrid[1, :-1] + xyz_dgrid[1, 1:]) - area_cgrid[0, :] = 2 * get_rectangle_area( - xyz_y_center[:-1], - xyz_agrid[1, :-1], - xyz_agrid[1, 1:], - xyz_y_center[1:], - radius, - np, - ) - - -def _set_c_grid_east_edge_area(xyz_dgrid, xyz_agrid, area_cgrid, radius, np): - _set_c_grid_west_edge_area( - xyz_dgrid[::-1, :], xyz_agrid[::-1, :], area_cgrid[::-1, :], radius, np - ) - - -def _set_c_grid_north_edge_area(xyz_dgrid, xyz_agrid, area_cgrid, radius, np): - _set_c_grid_south_edge_area( - xyz_dgrid[:, ::-1], xyz_agrid[:, ::-1], area_cgrid[:, ::-1], radius, np - ) - - -def _set_c_grid_south_edge_area(xyz_dgrid, xyz_agrid, area_cgrid, radius, np): - _set_c_grid_west_edge_area( - xyz_dgrid.transpose(1, 0, 2), - xyz_agrid.transpose(1, 0, 2), - area_cgrid.transpose(1, 0), - radius, - np, - ) - - -def _set_c_grid_southwest_corner_area(xyz_dgrid, xyz_agrid, area_cgrid, radius, np): - lower_right = normalize_xyz((xyz_dgrid[0, 0, :] + xyz_dgrid[1, 0, :])) # Fortran P2 - upper_right = xyz_agrid[0, 0, :] # Fortran P3 - upper_left = normalize_xyz((xyz_dgrid[0, 0, :] + xyz_dgrid[0, 1, :])) # Fortran P4 - lower_left = xyz_dgrid[0, 0, :] # Fortran P1 - area_cgrid[0, 0] = 3.0 * get_rectangle_area( - lower_left, upper_left, upper_right, lower_right, radius, np - ) - - -def _set_c_grid_southwest_corner_area_mod(xyz_dgrid, xyz_agrid, area_cgrid, radius, np): - _set_c_grid_southwest_corner_area( - xyz_dgrid[1:, 1:], xyz_agrid[1:, 1:], area_cgrid[:, :], radius, np - ) - - -def _set_c_grid_northwest_corner_area(xyz_dgrid, xyz_agrid, area_cgrid, radius, np): - _set_c_grid_southwest_corner_area( - xyz_dgrid[1:, ::-1], xyz_agrid[1:, ::-1], area_cgrid[:, ::-1], radius, np - ) - - -def _set_c_grid_northeast_corner_area(xyz_dgrid, xyz_agrid, area_cgrid, radius, np): - _set_c_grid_southwest_corner_area( - xyz_dgrid[::-1, ::-1], xyz_agrid[::-1, ::-1], area_cgrid[::-1, ::-1], radius, np - ) - - -def _set_c_grid_southeast_corner_area(xyz_dgrid, xyz_agrid, area_cgrid, radius, np): - _set_c_grid_southwest_corner_area( - xyz_dgrid[::-1, 1:], xyz_agrid[::-1, 1:], area_cgrid[::-1, :], radius, np - ) - - -def set_tile_border_dxc(xyz_dgrid, xyz_agrid, radius, dxc, tile_partitioner, rank, np): - if tile_partitioner.on_tile_left(rank): - _set_tile_west_dxc(xyz_dgrid, xyz_agrid, radius, dxc, np) - if tile_partitioner.on_tile_right(rank): - _set_tile_east_dxc(xyz_dgrid, xyz_agrid, radius, dxc, np) - - -def _set_tile_west_dxc(xyz_dgrid, xyz_agrid, radius, dxc, np): - tile_edge_point = 0.5 * (xyz_dgrid[0, 1:] + xyz_dgrid[0, :-1]) - cell_center_point = xyz_agrid[0, :] - dxc[0, :] = 2 * great_circle_distance_xyz( - tile_edge_point, cell_center_point, radius, np - ) - - -def _set_tile_east_dxc(xyz_dgrid, xyz_agrid, radius, dxc, np): - _set_tile_west_dxc(xyz_dgrid[::-1, :], xyz_agrid[::-1, :], radius, dxc[::-1, :], np) - - -def set_tile_border_dyc(xyz_dgrid, xyz_agrid, radius, dyc, tile_partitioner, rank, np): - if tile_partitioner.on_tile_top(rank): - _set_tile_north_dyc(xyz_dgrid, xyz_agrid, radius, dyc, np) - if tile_partitioner.on_tile_bottom(rank): - _set_tile_south_dyc(xyz_dgrid, xyz_agrid, radius, dyc, np) - - -def _set_tile_north_dyc(xyz_dgrid, xyz_agrid, radius, dyc, np): - _set_tile_east_dxc( - xyz_dgrid.transpose(1, 0, 2), - xyz_agrid.transpose(1, 0, 2), - radius, - dyc.transpose(1, 0), - np, - ) - - -def _set_tile_south_dyc(xyz_dgrid, xyz_agrid, radius, dyc, np): - _set_tile_west_dxc( - xyz_dgrid.transpose(1, 0, 2), - xyz_agrid.transpose(1, 0, 2), - radius, - dyc.transpose(1, 0), - np, - ) - - -def get_rectangle_area(p1, p2, p3, p4, radius, np): - """ - Given four point arrays whose last dimensions are x/y/z in clockwise or - counterclockwise order, return an array of spherical rectangle areas. - NOTE, this is not the exact same order of operations as the Fortran code - This results in some errors in the last digit, but the spherical_angle - is an exact match. The errors in the last digit multipled out by the radius - end up causing relative errors larger than 1e-14, but still wtihin 1e-12. - """ - total_angle = spherical_angle(p2, p3, p1, np) - for ( - q1, - q2, - q3, - ) in ((p3, p2, p4), (p4, p3, p1), (p1, p4, p2)): - total_angle += spherical_angle(q1, q2, q3, np) - - return (total_angle - 2 * PI) * radius ** 2 - - -def get_triangle_area(p1, p2, p3, radius, np): - """ - Given three point arrays whose last dimensions are x/y/z, return an array of - spherical triangle areas. - """ - - total_angle = spherical_angle(p1, p2, p3, np) - for q1, q2, q3 in ((p2, p3, p1), (p3, p1, p2)): - total_angle += spherical_angle(q1, q2, q3, np) - return (total_angle - PI) * radius ** 2 - - -def fortran_vector_spherical_angle(e1, e2, e3): - """ - The Fortran version - Given x/y/z tuples, compute the spherical angle between - them according to: -! p3 -! / -! / -! p_center ---> angle -! \ -! \ -! p2 - This angle will always be less than Pi. - """ - - # Vector P: - px = e1[1] * e2[2] - e1[2] * e2[1] - py = e1[2] * e2[0] - e1[0] * e2[2] - pz = e1[0] * e2[1] - e1[1] * e2[0] - # Vector Q: - qx = e1[1] * e3[2] - e1[2] * e3[1] - qy = e1[2] * e3[0] - e1[0] * e3[2] - qz = e1[0] * e3[1] - e1[1] * e3[0] - ddd = (px * px + py * py + pz * pz) * (qx * qx + qy * qy + qz * qz) - - if ddd <= 0.0: - angle = 0.0 - else: - ddd = (px * qx + py * qy + pz * qz) / math.sqrt(ddd) - if abs(ddd) > 1.0: - # FIX (lmh) to correctly handle co-linear points (angle near pi or 0) - if ddd < 0.0: - angle = 4.0 * math.atan(1.0) # should be pi - else: - angle = 0.0 - else: - angle = math.acos(ddd) - return angle - - -def spherical_angle(p_center, p2, p3, np): - """ - Given ndarrays whose last dimension is x/y/z, compute the spherical angle between - them according to: -! p3 -! / -! / -! p_center ---> angle -! \ -! \ -! p2 - This angle will always be less than Pi. - """ - - p = np.cross(p_center, p2) - q = np.cross(p_center, p3) - angle = np.arccos( - np.sum(p * q, axis=-1) - / np.sqrt(np.sum(p ** 2, axis=-1) * np.sum(q ** 2, axis=-1)) - ) - if not np.isscalar(angle): - angle[np.isnan(angle)] = 0.0 - elif math.isnan(angle): - angle = 0.0 - - return angle - - -def spherical_cos(p_center, p2, p3, np): - """ - As Spherical angle, but returns cos(angle) - """ - p = np.cross(p_center, p2) - q = np.cross(p_center, p3) - return np.sum(p * q, axis=-1) / np.sqrt( - np.sum(p ** 2, axis=-1) * np.sum(q ** 2, axis=-1) - ) - - -def get_unit_vector_direction(p1, p2, np): - """ - Returms the unit vector pointing from a set of lonlat points p1 to lonlat points p2 - """ - xyz1 = lon_lat_to_xyz(p1[:, :, 0], p1[:, :, 1], np) - xyz2 = lon_lat_to_xyz(p2[:, :, 0], p2[:, :, 1], np) - midpoint = xyz_midpoint(xyz1, xyz2) - p3 = np.cross(xyz2, xyz1) - return normalize_xyz(np.cross(midpoint, p3)) - - -def get_lonlat_vect(lonlat_grid, np): - """ - Calculates the unit vectors pointing in the longitude/latitude directions - for a set of longitude/latitude points - """ - lon_vector = np.array( - [ - -np.sin(lonlat_grid[:, :, 0]), - np.cos(lonlat_grid[:, :, 0]), - np.zeros(lonlat_grid[:, :, 0].shape), - ] - ).transpose([1, 2, 0]) - lat_vector = np.array( - [ - -np.sin(lonlat_grid[:, :, 1]) * np.cos(lonlat_grid[:, :, 0]), - -np.sin(lonlat_grid[:, :, 1]) * np.sin(lonlat_grid[:, :, 0]), - np.cos(lonlat_grid[:, :, 1]), - ] - ).transpose([1, 2, 0]) - return lon_vector, lat_vector diff --git a/util/pace/util/grid/helper.py b/util/pace/util/grid/helper.py deleted file mode 100644 index 6b3003d11..000000000 --- a/util/pace/util/grid/helper.py +++ /dev/null @@ -1,759 +0,0 @@ -import dataclasses -import pathlib - -import xarray as xr - -import pace.util - - -# TODO: if we can remove translate tests in favor of checkpointer tests, -# we can remove this "disallowed" import (pace.util does not depend on pace.dsl) -try: - from pace.dsl.gt4py_utils import split_cartesian_into_storages -except ImportError: - split_cartesian_into_storages = None -from pace.util import Z_DIM, Z_INTERFACE_DIM, get_fs - -from .generation import MetricTerms - - -@dataclasses.dataclass(frozen=True) -class DampingCoefficients: - """ - Terms used to compute damping coefficients. - """ - - divg_u: pace.util.Quantity - divg_v: pace.util.Quantity - del6_u: pace.util.Quantity - del6_v: pace.util.Quantity - da_min: float - da_min_c: float - - @classmethod - def new_from_metric_terms(cls, metric_terms: MetricTerms): - return cls( - divg_u=metric_terms.divg_u, - divg_v=metric_terms.divg_v, - del6_u=metric_terms.del6_u, - del6_v=metric_terms.del6_v, - da_min=metric_terms.da_min, - da_min_c=metric_terms.da_min_c, - ) - - -@dataclasses.dataclass(frozen=True) -class HorizontalGridData: - """ - Terms defining the horizontal grid. - """ - - lon: pace.util.Quantity - lat: pace.util.Quantity - lon_agrid: pace.util.Quantity - lat_agrid: pace.util.Quantity - area: pace.util.Quantity - area_64: pace.util.Quantity - rarea: pace.util.Quantity - # TODO: refactor this to "area_c" and invert where used - rarea_c: pace.util.Quantity - dx: pace.util.Quantity - dy: pace.util.Quantity - dxc: pace.util.Quantity - dyc: pace.util.Quantity - dxa: pace.util.Quantity - dya: pace.util.Quantity - # TODO: refactor usages to invert "normal" versions instead - rdx: pace.util.Quantity - rdy: pace.util.Quantity - rdxc: pace.util.Quantity - rdyc: pace.util.Quantity - rdxa: pace.util.Quantity - rdya: pace.util.Quantity - ee1: pace.util.Quantity - ee2: pace.util.Quantity - es1: pace.util.Quantity - ew2: pace.util.Quantity - a11: pace.util.Quantity - a12: pace.util.Quantity - a21: pace.util.Quantity - a22: pace.util.Quantity - edge_w: pace.util.Quantity - edge_e: pace.util.Quantity - edge_s: pace.util.Quantity - edge_n: pace.util.Quantity - - @classmethod - def new_from_metric_terms(cls, metric_terms: MetricTerms) -> "HorizontalGridData": - return cls( - lon=metric_terms.lon, - lat=metric_terms.lat, - lon_agrid=metric_terms.lon_agrid, - lat_agrid=metric_terms.lat_agrid, - area=metric_terms.area, - area_64=metric_terms.area, - rarea=metric_terms.rarea, - rarea_c=metric_terms.rarea_c, - dx=metric_terms.dx, - dy=metric_terms.dy, - dxc=metric_terms.dxc, - dyc=metric_terms.dyc, - dxa=metric_terms.dxa, - dya=metric_terms.dya, - rdx=metric_terms.rdx, - rdy=metric_terms.rdy, - rdxc=metric_terms.rdxc, - rdyc=metric_terms.rdyc, - rdxa=metric_terms.rdxa, - rdya=metric_terms.rdya, - ee1=metric_terms.ee1, - ee2=metric_terms.ee2, - es1=metric_terms.es1, - ew2=metric_terms.ew2, - a11=metric_terms.a11, - a12=metric_terms.a12, - a21=metric_terms.a21, - a22=metric_terms.a22, - edge_w=metric_terms.edge_w, - edge_e=metric_terms.edge_e, - edge_s=metric_terms.edge_s, - edge_n=metric_terms.edge_n, - ) - - -@dataclasses.dataclass -class VerticalGridData: - """ - Terms defining the vertical grid. - - Eulerian vertical grid is defined by p = ak + bk * p_ref - """ - - # TODO: make these non-optional, make FloatFieldK a true type and use it - ak: pace.util.Quantity - bk: pace.util.Quantity - """ - reference pressure (Pa) used to define pressure at vertical interfaces, - where p = ak + bk * p_ref - """ - - def __post_init__(self): - self._dp_ref = None - self._p = None - self._p_interface = None - - @classmethod - def new_from_metric_terms(cls, metric_terms: MetricTerms) -> "VerticalGridData": - return cls( - ak=metric_terms.ak, - bk=metric_terms.bk, - ) - - @classmethod - def from_restart( - cls, restart_path: str, quantity_factory: pace.util.QuantityFactory - ): - fs = get_fs(restart_path) - restart_files = fs.ls(restart_path) - data_file = restart_files[ - [fname.endswith("fv_core.res.nc") for fname in restart_files].index(True) - ] - - ak_bk_data_file = pathlib.Path(restart_path) / data_file - if not fs.isfile(ak_bk_data_file): - raise ValueError( - """vertical_grid_from_restart is true, - but no fv_core.res.nc in restart data file.""" - ) - - ak = quantity_factory.zeros([Z_INTERFACE_DIM], units="Pa") - bk = quantity_factory.zeros([Z_INTERFACE_DIM], units="") - with fs.open(ak_bk_data_file, "rb") as f: - ds = xr.open_dataset(f).isel(Time=0).drop_vars("Time") - ak.view[:] = ds["ak"].values - bk.view[:] = ds["bk"].values - - return cls(ak=ak, bk=bk) - - @property - def p_ref(self) -> float: - """ - reference pressure (Pa) - """ - return 1e5 - - @property - def p_interface(self) -> pace.util.Quantity: - if self._p_interface is None: - p_interface_data = self.ak.view[:] + self.bk.view[:] * self.p_ref - self._p_interface = pace.util.Quantity( - p_interface_data, - dims=[Z_INTERFACE_DIM], - units="Pa", - gt4py_backend=self.ak.gt4py_backend, - ) - return self._p_interface - - @property - def p(self) -> pace.util.Quantity: - if self._p is None: - p_data = ( - self.p_interface.view[1:] - self.p_interface.view[:-1] - ) / self.p_interface.np.log( - self.p_interface.view[1:] / self.p_interface.view[:-1] - ) - self._p = pace.util.Quantity( - p_data, - dims=[Z_DIM], - units="Pa", - gt4py_backend=self.p_interface.gt4py_backend, - ) - return self._p - - @property - def dp(self) -> pace.util.Quantity: - if self._dp_ref is None: - dp_ref_data = ( - self.ak.view[1:] - - self.ak.view[:-1] - + (self.bk.view[1:] - self.bk.view[:-1]) * self.p_ref - ) - self._dp_ref = pace.util.Quantity( - dp_ref_data, - dims=[Z_DIM], - units="Pa", - gt4py_backend=self.ak.gt4py_backend, - ) - return self._dp_ref - - @property - def ptop(self) -> float: - """ - top of atmosphere pressure (Pa) - """ - if self.bk.view[0] != 0: - raise ValueError("ptop is not well-defined when top-of-atmosphere bk != 0") - return float(self.ak.view[0]) - - -@dataclasses.dataclass(frozen=True) -class ContravariantGridData: - """ - Grid variables used for converting vectors from covariant to - contravariant components. - """ - - cosa: pace.util.Quantity - cosa_u: pace.util.Quantity - cosa_v: pace.util.Quantity - cosa_s: pace.util.Quantity - sina_u: pace.util.Quantity - sina_v: pace.util.Quantity - rsina: pace.util.Quantity - rsin_u: pace.util.Quantity - rsin_v: pace.util.Quantity - rsin2: pace.util.Quantity - - @classmethod - def new_from_metric_terms( - cls, metric_terms: MetricTerms - ) -> "ContravariantGridData": - return cls( - cosa=metric_terms.cosa, - cosa_u=metric_terms.cosa_u, - cosa_v=metric_terms.cosa_v, - cosa_s=metric_terms.cosa_s, - sina_u=metric_terms.sina_u, - sina_v=metric_terms.sina_v, - rsina=metric_terms.rsina, - rsin_u=metric_terms.rsin_u, - rsin_v=metric_terms.rsin_v, - rsin2=metric_terms.rsin2, - ) - - -@dataclasses.dataclass(frozen=True) -class AngleGridData: - """ - sin and cos of certain angles used in metric calculations. - - Corresponds in the fortran code to sin_sg and cos_sg. - """ - - sin_sg1: pace.util.Quantity - sin_sg2: pace.util.Quantity - sin_sg3: pace.util.Quantity - sin_sg4: pace.util.Quantity - cos_sg1: pace.util.Quantity - cos_sg2: pace.util.Quantity - cos_sg3: pace.util.Quantity - cos_sg4: pace.util.Quantity - - @classmethod - def new_from_metric_terms(cls, metric_terms: MetricTerms) -> "AngleGridData": - return cls( - sin_sg1=metric_terms.sin_sg1, - sin_sg2=metric_terms.sin_sg2, - sin_sg3=metric_terms.sin_sg3, - sin_sg4=metric_terms.sin_sg4, - cos_sg1=metric_terms.cos_sg1, - cos_sg2=metric_terms.cos_sg2, - cos_sg3=metric_terms.cos_sg3, - cos_sg4=metric_terms.cos_sg4, - ) - - -class GridData: - # TODO: add docstrings to remaining properties - - def __init__( - self, - horizontal_data: HorizontalGridData, - vertical_data: VerticalGridData, - contravariant_data: ContravariantGridData, - angle_data: AngleGridData, - ): - self._horizontal_data = horizontal_data - self._vertical_data = vertical_data - self._contravariant_data = contravariant_data - self._angle_data = angle_data - self._fC = None - self._fC_agrid = None - - @classmethod - def new_from_metric_terms(cls, metric_terms: MetricTerms): - horizontal_data = HorizontalGridData.new_from_metric_terms(metric_terms) - vertical_data = VerticalGridData.new_from_metric_terms(metric_terms) - contravariant_data = ContravariantGridData.new_from_metric_terms(metric_terms) - angle_data = AngleGridData.new_from_metric_terms(metric_terms) - return cls(horizontal_data, vertical_data, contravariant_data, angle_data) - - @property - def lon(self): - """longitude of cell corners""" - return self._horizontal_data.lon - - @property - def lat(self): - """latitude of cell corners""" - return self._horizontal_data.lat - - @property - def lon_agrid(self) -> pace.util.Quantity: - """longitude on the A-grid (cell centers)""" - return self._horizontal_data.lon_agrid - - @property - def lat_agrid(self) -> pace.util.Quantity: - """latitude on the A-grid (cell centers)""" - return self._horizontal_data.lat_agrid - - @staticmethod - def _fC_from_lat(lat: pace.util.Quantity) -> pace.util.Quantity: - np = lat.np - data = 2.0 * pace.util.constants.OMEGA * np.sin(lat.data) - return pace.util.Quantity( - data, - units="1/s", - dims=lat.dims, - origin=lat.origin, - extent=lat.extent, - gt4py_backend=lat.gt4py_backend, - ) - - @property - def fC(self): - """Coriolis parameter at cell corners""" - if self._fC is None: - self._fC = self._fC_from_lat(self.lat) - return self._fC - - @property - def fC_agrid(self): - """Coriolis parameter at cell centers""" - if self._fC_agrid is None: - self._fC_agrid = self._fC_from_lat(self.lat_agrid) - return self._fC_agrid - - @property - def area(self): - """Gridcell area""" - return self._horizontal_data.area - - @property - def area_64(self): - """Gridcell area (64-bit)""" - return self._horizontal_data.area_64 - - @property - def rarea(self): - """1 / area""" - return self._horizontal_data.rarea - - @property - def rarea_c(self): - return self._horizontal_data.rarea_c - - @property - def dx(self): - """distance between cell corners in x-direction""" - return self._horizontal_data.dx - - @property - def dy(self): - """distance between cell corners in y-direction""" - return self._horizontal_data.dy - - @property - def dxc(self): - """distance between gridcell centers in x-direction""" - return self._horizontal_data.dxc - - @property - def dyc(self): - """distance between gridcell centers in y-direction""" - return self._horizontal_data.dyc - - @property - def dxa(self): - """distance between centers of west and east edges of gridcell""" - return self._horizontal_data.dxa - - @property - def dya(self): - """distance between centers of north and south edges of gridcell""" - return self._horizontal_data.dya - - @property - def rdx(self): - """1 / dx""" - return self._horizontal_data.rdx - - @property - def rdy(self): - """1 / dy""" - return self._horizontal_data.rdy - - @property - def rdxc(self): - """1 / dxc""" - return self._horizontal_data.rdxc - - @property - def rdyc(self): - """1 / dyc""" - return self._horizontal_data.rdyc - - @property - def rdxa(self): - """1 / dxa""" - return self._horizontal_data.rdxa - - @property - def rdya(self): - """1 / dya""" - return self._horizontal_data.rdya - - @property - def ee1(self) -> pace.util.Quantity: - return self._horizontal_data.ee1 - - @property - def ee2(self) -> pace.util.Quantity: - return self._horizontal_data.ee2 - - @property - def es1(self) -> pace.util.Quantity: - return self._horizontal_data.es1 - - @property - def ew2(self) -> pace.util.Quantity: - return self._horizontal_data.ew2 - - @property - def a11(self): - return self._horizontal_data.a11 - - @property - def a12(self): - return self._horizontal_data.a12 - - @property - def a21(self): - return self._horizontal_data.a21 - - @property - def a22(self): - return self._horizontal_data.a22 - - @property - def edge_w(self): - return self._horizontal_data.edge_w - - @property - def edge_e(self): - return self._horizontal_data.edge_e - - @property - def edge_s(self): - return self._horizontal_data.edge_s - - @property - def edge_n(self): - return self._horizontal_data.edge_n - - @property - def p_ref(self) -> float: - """ - reference pressure (Pa) used to define pressure at vertical interfaces, - where p = ak + bk * p_ref - """ - return self._vertical_data.p_ref - - @property - def p(self) -> pace.util.Quantity: - """ - Reference pressure profile for Eulerian grid, defined at cell centers. - """ - return self._vertical_data.p - - @property - def ak(self) -> pace.util.Quantity: - """ - constant used to define pressure at vertical interfaces, - where p = ak + bk * p_ref - """ - return self._vertical_data.ak - - @ak.setter - def ak(self, value: pace.util.Quantity): - self._vertical_data.ak = value - - @property - def bk(self) -> pace.util.Quantity: - """ - constant used to define pressure at vertical interfaces, - where p = ak + bk * p_ref - """ - return self._vertical_data.bk - - @bk.setter - def bk(self, value: pace.util.Quantity): - self._vertical_data.bk = value - - @property - def ks(self): - return self._vertical_data.ks - - @ks.setter - def ks(self, value): - self._vertical_data.ks = value - - @property - def ptop(self): - """pressure at top of atmosphere (Pa)""" - return self._vertical_data.ptop - - @ptop.setter - def ptop(self, value): - self._vertical_data.ptop = value - - @property - def dp_ref(self) -> pace.util.Quantity: - return self._vertical_data.dp - - @property - def cosa(self): - return self._contravariant_data.cosa - - @property - def cosa_u(self): - return self._contravariant_data.cosa_u - - @property - def cosa_v(self): - return self._contravariant_data.cosa_v - - @property - def cosa_s(self): - return self._contravariant_data.cosa_s - - @property - def sina_u(self): - return self._contravariant_data.sina_u - - @property - def sina_v(self): - return self._contravariant_data.sina_v - - @property - def rsina(self): - return self._contravariant_data.rsina - - @property - def rsin_u(self): - return self._contravariant_data.rsin_u - - @property - def rsin_v(self): - return self._contravariant_data.rsin_v - - @property - def rsin2(self): - return self._contravariant_data.rsin2 - - @property - def sin_sg1(self): - return self._angle_data.sin_sg1 - - @property - def sin_sg2(self): - return self._angle_data.sin_sg2 - - @property - def sin_sg3(self): - return self._angle_data.sin_sg3 - - @property - def sin_sg4(self): - return self._angle_data.sin_sg4 - - @property - def cos_sg1(self): - return self._angle_data.cos_sg1 - - @property - def cos_sg2(self): - return self._angle_data.cos_sg2 - - @property - def cos_sg3(self): - return self._angle_data.cos_sg3 - - @property - def cos_sg4(self): - return self._angle_data.cos_sg4 - - -@dataclasses.dataclass(frozen=True) -class DriverGridData: - """ - Terms used to Apply Physics changes to the Dycore. - Attributes: - vlon1: x-component of unit lon vector in eastward longitude direction - vlon2: y-component of unit lon vector in eastward longitude direction - vlon3: z-component of unit lon vector in eastward longitude direction - vlat1: x-component of unit lat vector in northward latitude direction - vlat2: y-component of unit lat vector in northward latitude direction - vlat3: z-component of unit lat vector in northward latitude direction - edge_vect_w: factor to interpolate A to C grids at the western grid edge - edge_vect_e: factor to interpolate A to C grids at the easter grid edge - edge_vect_s: factor to interpolate A to C grids at the southern grid edge - edge_vect_n: factor to interpolate A to C grids at the northern grid edge - es1_1: x-component of grid local unit vector in x-direction at cell edge - es1_2: y-component of grid local unit vector in x-direction at cell edge - es1_3: z-component of grid local unit vector in x-direction at cell edge - ew2_1: x-component of grid local unit vector in y-direction at cell edge - ew2_2: y-component of grid local unit vector in y-direction at cell edge - ew2_3: z-component of grid local unit vector in y-direction at cell edge - """ - - vlon1: pace.util.Quantity - vlon2: pace.util.Quantity - vlon3: pace.util.Quantity - vlat1: pace.util.Quantity - vlat2: pace.util.Quantity - vlat3: pace.util.Quantity - edge_vect_w: pace.util.Quantity - edge_vect_e: pace.util.Quantity - edge_vect_s: pace.util.Quantity - edge_vect_n: pace.util.Quantity - es1_1: pace.util.Quantity - es1_2: pace.util.Quantity - es1_3: pace.util.Quantity - ew2_1: pace.util.Quantity - ew2_2: pace.util.Quantity - ew2_3: pace.util.Quantity - grid_type: int - - @classmethod - def new_from_metric_terms(cls, metric_terms: MetricTerms) -> "DriverGridData": - return cls.new_from_grid_variables( - vlon=metric_terms.vlon, - vlat=metric_terms.vlon, - edge_vect_n=metric_terms.edge_vect_n, - edge_vect_s=metric_terms.edge_vect_s, - edge_vect_e=metric_terms.edge_vect_e, - edge_vect_w=metric_terms.edge_vect_w, - es1=metric_terms.es1, - ew2=metric_terms.ew2, - grid_type=metric_terms._grid_type, - ) - - @classmethod - def new_from_grid_variables( - cls, - vlon: pace.util.Quantity, - vlat: pace.util.Quantity, - edge_vect_n: pace.util.Quantity, - edge_vect_s: pace.util.Quantity, - edge_vect_e: pace.util.Quantity, - edge_vect_w: pace.util.Quantity, - es1: pace.util.Quantity, - ew2: pace.util.Quantity, - grid_type: int = 0, - ) -> "DriverGridData": - try: - vlon1, vlon2, vlon3 = split_quantity_along_last_dim(vlon) - vlat1, vlat2, vlat3 = split_quantity_along_last_dim(vlat) - es1_1, es1_2, es1_3 = split_quantity_along_last_dim(es1) - ew2_1, ew2_2, ew2_3 = split_quantity_along_last_dim(ew2) - except (AttributeError, TypeError): - vlon1, vlon2, vlon3 = split_cartesian_into_storages(vlon) - vlat1, vlat2, vlat3 = split_cartesian_into_storages(vlat) - es1_1, es1_2, es1_3 = split_cartesian_into_storages(es1) - ew2_1, ew2_2, ew2_3 = split_cartesian_into_storages(ew2) - - return cls( - vlon1=vlon1, - vlon2=vlon2, - vlon3=vlon3, - vlat1=vlat1, - vlat2=vlat2, - vlat3=vlat3, - es1_1=es1_1, - es1_2=es1_2, - es1_3=es1_3, - ew2_1=ew2_1, - ew2_2=ew2_2, - ew2_3=ew2_3, - edge_vect_w=edge_vect_w, - edge_vect_e=edge_vect_e, - edge_vect_s=edge_vect_s, - edge_vect_n=edge_vect_n, - grid_type=grid_type, - ) - - -def split_quantity_along_last_dim(quantity): - """Split a quantity along the last dimension into a list of quantities. - - Args: - quantity: Quantity to split. - - Returns: - List of quantities. - """ - return_list = [] - for i in range(quantity.data.shape[-1]): - return_list.append( - pace.util.Quantity( - data=quantity.data[..., i], - dims=quantity.dims[:-1], - units=quantity.units, - origin=quantity.origin[:-1], - extent=quantity.extent[:-1], - gt4py_backend=quantity.gt4py_backend, - ) - ) - return return_list diff --git a/util/pace/util/grid/mirror.py b/util/pace/util/grid/mirror.py deleted file mode 100644 index 6c3c7837b..000000000 --- a/util/pace/util/grid/mirror.py +++ /dev/null @@ -1,280 +0,0 @@ -from pace.util.constants import PI, RADIUS - - -__all__ = ["mirror_grid"] - -RIGHT_HAND_GRID = False - - -def mirror_grid( - mirror_data, - tile_index, - npx, - npy, - x_subtile_width, - y_subtile_width, - global_is, - global_js, - ng, - np, - right_hand_grid, -): - istart = ng - iend = ng + x_subtile_width - jstart = ng - jend = ng + y_subtile_width - x_center_tile = ( - global_is <= ng + (npx - 1) / 2 - and global_is + x_subtile_width > ng + (npx - 1) / 2 - ) - y_center_tile = ( - global_js <= ng + (npy - 1) / 2 - and global_js + y_subtile_width > ng + (npy - 1) / 2 - ) - - i_mid = npx // 2 - global_is + istart - j_mid = npy // 2 - global_js + jstart - - # first fix base region - for j in range(jstart, jend + 1): - for i in range(istart, iend + 1): - - iend_domain = iend - 1 + ng - jend_domain = jend - 1 + ng - x1 = np.multiply( - 0.25, - np.abs(mirror_data["local"][i, j, 0]) - + np.abs(mirror_data["east-west"][iend_domain - i, j, 0]) - + np.abs(mirror_data["north-south"][i, jend_domain - j, 0]) - + np.abs(mirror_data["diagonal"][iend_domain - i, jend_domain - j, 0]), - ) - mirror_data["local"][i, j, 0] = np.copysign( - x1, mirror_data["local"][i, j, 0] - ) - - y1 = np.multiply( - 0.25, - np.abs(mirror_data["local"][i, j, 1]) - + np.abs(mirror_data["east-west"][iend_domain - i, j, 1]) - + np.abs(mirror_data["north-south"][i, jend_domain - j, 1]) - + np.abs(mirror_data["diagonal"][iend_domain - i, jend_domain - j, 1]), - ) - - mirror_data["local"][i, j, 1] = np.copysign( - y1, mirror_data["local"][i, j, 1] - ) - - # force dateline/greenwich-meridion consistency - if npx % 2 != 0: - if x_center_tile and i == ng + i_mid: - mirror_data["local"][i, j, 0] = 0.0 - mirror_data["north-south"][i, -(j + 1), 0] = 0 - - if tile_index > 0: - - for j in range(jstart, jend + 1): - x1 = mirror_data["local"][istart : iend + 1, j, 0] - y1 = mirror_data["local"][istart : iend + 1, j, 1] - z1 = np.add(RADIUS, np.multiply(0.0, x1)) - - if tile_index == 1: - ang = -90.0 - x2, y2, z2 = _rot_3d( - 3, - [x1, y1, z1], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - elif tile_index == 2: - ang = -90.0 - x2, y2, z2 = _rot_3d( - 3, - [x1, y1, z1], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - ang = 90.0 - x2, y2, z2 = _rot_3d( - 1, - [x2, y2, z2], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - - # force North Pole and dateline/Greenwich-Meridian consistency - if npx % 2 != 0: - if ( - j == ng + j_mid - and x_center_tile - and y_center_tile - and i_mid == j_mid - ): - x2[i_mid] = 0.0 - y2[i_mid] = PI / 2.0 - if j == ng + j_mid and y_center_tile: - if x_center_tile: - x2[: i_mid + 1] = 0.0 - x2[i_mid + 1 :] = PI - elif global_is + i_mid < ng + (npx - 1) / 2: - x2[:] = 0.0 - elif global_is + i_mid > ng + (npx - 1) / 2: - x2[:] = PI - elif tile_index == 3: - ang = -180.0 - x2, y2, z2 = _rot_3d( - 3, - [x1, y1, z1], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - ang = 90.0 - x2, y2, z2 = _rot_3d( - 1, - [x2, y2, z2], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - # force dateline/Greenwich-Meridian consistency - if npx % 2 != 0: - if j == ng + j_mid and y_center_tile: - x2[:] = PI - elif tile_index == 4: - ang = 90.0 - x2, y2, z2 = _rot_3d( - 3, - [x1, y1, z1], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - ang = 90.0 - x2, y2, z2 = _rot_3d( - 2, - [x2, y2, z2], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - elif tile_index == 5: - ang = 90.0 - x2, y2, z2 = _rot_3d( - 2, - [x1, y1, z1], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - ang = 0.0 - x2, y2, z2 = _rot_3d( - 3, - [x2, y2, z2], - ang, - np, - right_hand_grid, - degrees=True, - convert=True, - ) - # force South Pole and dateline/Greenwich-Meridian consistency - if npx % 2 != 0: - if ( - i == ng + i_mid - and x_center_tile - and y_center_tile - and i_mid == j_mid - ): - x2[i_mid] = 0.0 - y2[i_mid] = -PI / 2.0 - if global_js + j_mid > ng + (npy - 1) / 2 and x_center_tile: - x2[i_mid] = 0.0 - elif global_js + j_mid < ng + (npy - 1) / 2 and x_center_tile: - x2[i_mid] = PI - - mirror_data["local"][istart : iend + 1, j, 0] = x2 - mirror_data["local"][istart : iend + 1, j, 1] = y2 - - -def _rot_3d(axis, p, angle, np, right_hand_grid, degrees=False, convert=False): - - if convert: - p1 = _spherical_to_cartesian(p, np, right_hand_grid) - else: - p1 = p - - if degrees: - angle = np.deg2rad(angle) - - c = np.cos(angle) - s = np.sin(angle) - - if axis == 1: - x2 = p1[0] - y2 = c * p1[1] + s * p1[2] - z2 = -s * p1[1] + c * p1[2] - elif axis == 2: - x2 = c * p1[0] - s * p1[2] - y2 = p1[1] - z2 = s * p1[0] + c * p1[2] - elif axis == 3: - x2 = c * p1[0] + s * p1[1] - y2 = -s * p1[0] + c * p1[1] - z2 = p1[2] - else: - assert False, "axis must be in [1,2,3]" - - if convert: - p2 = _cartesian_to_spherical([x2, y2, z2], np, right_hand_grid) - else: - p2 = [x2, y2, z2] - - return p2 - - -def _spherical_to_cartesian(p, np, right_hand_grid): - lon, lat, r = p - x = r * np.cos(lon) * np.cos(lat) - y = r * np.sin(lon) * np.cos(lat) - if right_hand_grid: - z = r * np.sin(lat) - else: - z = -r * np.sin(lat) - return [x, y, z] - - -def _cartesian_to_spherical(p, np, right_hand_grid): - x, y, z = p - r = np.sqrt(x * x + y * y + z * z) - lon = np.where(np.abs(x) + np.abs(y) < 1.0e-10, 0.0, np.arctan2(y, x)) - if right_hand_grid: - lat = np.arcsin(z / r) - else: - lat = np.arccos(z / r) - PI / 2.0 - return [lon, lat, r] - - -def set_halo_nan(grid, ng: int, np): - grid[:ng, :, :] = np.nan # west edge - grid[:, :ng, :] = np.nan # south edge - grid[-ng:, :, :] = np.nan # east edge - grid[:, -ng:, :] = np.nan # north edge - return grid diff --git a/util/pace/util/grid/stretch_transformation.py b/util/pace/util/grid/stretch_transformation.py deleted file mode 100644 index 2c1b16cd3..000000000 --- a/util/pace/util/grid/stretch_transformation.py +++ /dev/null @@ -1,105 +0,0 @@ -import copy -from typing import Tuple, TypeVar, Union - -import numpy as np - -from pace.util import Quantity - - -T = TypeVar("T", bound=Union[Quantity, np.ndarray]) - - -def direct_transform( - *, - lon: T, - lat: T, - stretch_factor: float, - lon_target: float, - lat_target: float, - np, -) -> Tuple[T, T]: - """ - The direct_transform subroutine from fv_grid_utils.F90. - Takes in latitude and longitude in radians. - Shrinks tile 6 by stretch factor in area to increse resolution locally. - Then performs translation of all tiles so that the now-smaller tile 6 is - centeres on lon_target, lat_target. - - Args: - lon (in) in radians - lat (in) in radians - stretch_factor (in) stretch_factor (e.g. 3.0 means that the resolution - on tile 6 becomes 3 times as fine) - lon_target (in) in degrees (from namelist) - lat_target (in) in degrees (from namelist) - np: numpy or cupy module - - Returns: - lon_transform (out) in radians - lat_transform (out) in radians - """ - - if isinstance(lon, Quantity): - lon_data = lon.data - lat_data = lat.data - elif isinstance(lon, np.ndarray): - lon_data = lon - lat_data = lat - else: - raise Exception("Input data type not supported.") - - STRETCH_GRID_ROTATION_LON_OFFSET_DEG = 190 - # this is added to all longitude values to match the SHiELD TC case - # 180 is to flip the orientation around the center tile (6) - # 10 is because the tile center is offset from the prime meridian by 10 - lon_data = lon_data + np.deg2rad(STRETCH_GRID_ROTATION_LON_OFFSET_DEG) - - lon_p, lat_p = np.deg2rad(lon_target), np.deg2rad(lat_target) - sin_p, cos_p = np.sin(lat_p), np.cos(lat_p) - c2p1 = 1.0 + stretch_factor ** 2 - c2m1 = 1.0 - stretch_factor ** 2 - - # first limit longitude so it's between 0 and 2pi - lon_data[lon_data < 0] += 2 * np.pi - lon_data[lon_data >= 2 * np.pi] -= 2 * np.pi - - if np.abs(c2m1) > 1e-7: # do stretching - lat_t = np.arcsin( - (c2m1 + c2p1 * np.sin(lat_data)) / (c2p1 + c2m1 * np.sin(lat_data)) - ) - else: # no stretching - lat_t = lat_data - - sin_lat = np.sin(lat_t) - cos_lat = np.cos(lat_t) - - sin_o = -(sin_p * sin_lat + cos_p * cos_lat * np.cos(lon_data)) - tmp = 1 - np.abs(sin_o) - - lon_transformed = np.zeros(lon_data.shape) * np.nan - lat_transformed = np.zeros(lat_data.shape) * np.nan - - lon_transformed[tmp < 1e-7] = 0.0 - lat_transformed[tmp < 1e-7] = np.abs(np.pi / 2) * np.sign(sin_o[tmp < 1e-7]) - - lon_transformed[tmp >= 1e-7] = lon_p + np.arctan2( - -np.cos(lat_t[tmp >= 1e-7]) * np.sin(lon_data[tmp >= 1e-7]), - -np.sin(lat_t[tmp >= 1e-7]) * np.cos(lat_p) - + np.cos(lat_t[tmp >= 1e-7]) * np.sin(lat_p) * np.cos(lon_data[tmp >= 1e-7]), - ) - lat_transformed[tmp >= 1e-7] = np.arcsin(sin_o[tmp >= 1e-7]) - - lon_transformed[lon_transformed < 0] += 2 * np.pi - lon_transformed[lon_transformed >= 2 * np.pi] -= 2 * np.pi - - if isinstance(lon, Quantity): - lon_out = copy.deepcopy(lon) - lat_out = copy.deepcopy(lat) - - lon_out.data[:] = lon_transformed - lat_out.data[:] = lat_transformed - else: - lon_out = lon_transformed - lat_out = lat_transformed - - return lon_out, lat_out # type: ignore diff --git a/util/pace/util/halo_data_transformer.py b/util/pace/util/halo_data_transformer.py deleted file mode 100644 index e97bb97ac..000000000 --- a/util/pace/util/halo_data_transformer.py +++ /dev/null @@ -1,992 +0,0 @@ -import abc -from dataclasses import dataclass -from enum import Enum -from typing import Dict, List, Optional, Sequence, Tuple -from uuid import UUID, uuid1 - -import numpy as np - -from ._optional_imports import cupy as cp -from .buffer import Buffer -from .cuda_kernels import ( - pack_scalar_f32_kernel, - pack_scalar_f64_kernel, - pack_vector_f32_kernel, - pack_vector_f64_kernel, - unpack_scalar_f32_kernel, - unpack_scalar_f64_kernel, - unpack_vector_f32_kernel, - unpack_vector_f64_kernel, -) -from .quantity import Quantity, QuantityHaloSpec -from .rotate import rotate_scalar_data, rotate_vector_data -from .types import NumpyModule -from .utils import device_synchronize - - -# ------------------------------------------------------------------------ -# Simple pool of streams to lower the driver pressure -# Use _pop/_push_stream to manipulate the pool - -STREAM_POOL: List["cp.cuda.Stream"] = [] - - -def _pop_stream() -> "cp.cuda.Stream": - if len(STREAM_POOL) == 0: - return cp.cuda.Stream(non_blocking=True) - return STREAM_POOL.pop() - - -def _push_stream(stream: "cp.cuda.Stream"): - STREAM_POOL.append(stream) - - -# ------------------------------------------------------------------------ -# Indices array - -# Keyed cached - key is a str at the moment to go around the fact that -# a slice is not hashable. getting a string from -# Tuple(slices, rotation, shape, strides, itemsize) e.g. # noqa -# str(Tuple[Any, int, Tuple[int], Tuple[int], int]) # noqa -INDICES_CACHE: Dict[str, "cp.ndarray"] = {} - - -def _build_flatten_indices( - key, - shape, - slices: Tuple[slice], - dims, - strides, - itemsize: int, - rotate: bool, - rotation: int, -) -> "cp.ndarray": - """Build an array of indexing from a slice & memory description to - build an indexation into the "flatten" memory. - - Go from a memory layout (strides, itemsize, shape) and slices into it to a - single array of indices. We leverage numpy iterator and calculate from - the multi_index using memory layout the index into the original memory buffer. - """ - - # Have to go down to numpy to leverage indices calculation - arr_indices = np.zeros(shape, dtype=np.int32, order="C")[slices] - - # Get offset from first index - offset_dims = [] - for s in slices: - offset_dims.append(s.start) - offset_to_slice = sum(np.array(offset_dims) * strides) // itemsize - - # Flatten the index into an indices array - with np.nditer( - arr_indices, - flags=["multi_index"], - op_flags=["writeonly"], - order="K", - ) as it: - for array_value in it: - offset = sum(np.array(it.multi_index) * strides) // itemsize - array_value[...] = offset_to_slice + offset - - if rotate: - # sending data across the boundary will rotate the data - # n_clockwise_rotations times, due to the difference in axis orientation. - # Thus we rotate that number of times counterclockwise before sending, - # to get the right final orientation. We apply those rotations to the - # indices here to prepare for a straightforward copy in cu kernel - arr_indices = rotate_scalar_data(arr_indices, dims, cp, -rotation) - return cp.asarray(arr_indices.flatten(order="C")) - - -# ------------------------------------------------------------------------ -# HaloDataTransformer helpers - - -def _slices_size(slices: Tuple[slice, ...]) -> int: - """Compute linear size from slices.""" - length = 1 - for s in slices: - assert s.step is None - length *= abs(s.start - s.stop) - return length - - -@dataclass -class HaloExchangeSpec: - """Memory description of the data exchanged. - - The data stored here target a single exchange, with an optional - rotation to give prior to pack. Slices are tupled following the - convention of one slice per dimension - - Args: - specification: memory layout of the data - pack_slices: indexing to pack, one slice per dimension - pack_clockwise_rotation: number of 90-degree rotations to perform - before packing - unpack_slices: indexing to unpack, one slice per dimension - """ - - specification: QuantityHaloSpec - pack_slices: Tuple[slice, ...] - pack_clockwise_rotation: int - unpack_slices: Tuple[slice, ...] - - def __post_init__(self): - self._id = uuid1() - self.pack_buffer_size = _slices_size(self.pack_slices) - self._unpack_buffer_size = _slices_size(self.unpack_slices) - - -class _HaloDataTransformerType(Enum): - """Dimensionality of the data in the packed buffer.""" - - UNKNOWN = 0 - SCALAR = 1 - VECTOR = 2 - - -# ------------------------------------------------------------------------ -# HaloDataTransformer classes - - -class HaloDataTransformer(abc.ABC): - """Transform data to exchange in a format optimized for network communication. - - Current strategy: pack/unpack multiple nD array into/from a single buffer. - Offers a pack and an unpack buffer to use for communicating data. - - The class is responsible for packing & unpacking, not communication. - Order of operations: - - get HaloDataTransformer via get() with N transformation - with the proper halo specifications. - At the end of get() a _compile() will be triggered, reading - the internal buffers. - - call async_pack(quantities) to start packing the quantities in the - internal buffer. - - synchronize() to make sure all operations are finished or use get_pack_buffer() - when ready to communicate which will internally call synchronize. - [... user should communicate the buffers...] - - call async_unpack(quantities) to start unpacking - - call synchronize() to finish all the unpacking operations and make sure - the quantities passed in async_unpack have been updated. - - The class will hold onto the buffers up until deletion, where they will be - returned to an internal buffer pool. - """ - - _pack_buffer: Optional[Buffer] - _unpack_buffer: Optional[Buffer] - - _infos_x: Tuple[HaloExchangeSpec, ...] - _infos_y: Tuple[HaloExchangeSpec, ...] - - def __init__( - self, - np_module: NumpyModule, - exchange_descriptors_x: Sequence[HaloExchangeSpec], - exchange_descriptors_y: Optional[Sequence[HaloExchangeSpec]] = None, - ) -> None: - """ - Args: - np_module: numpy-like module for allocation - exchange_descriptors_x: list of memory information describing an exchange. - Used for scalar data and the x-component of vectors. - exchange_descriptors_y: list of memory information describing an exchange. - Optional, used for the y-component of vectors only. If `none` the - data will packed as a scalar. - """ - self._type = ( - _HaloDataTransformerType.SCALAR - if exchange_descriptors_y is None - else _HaloDataTransformerType.VECTOR - ) - if exchange_descriptors_y is not None and len(exchange_descriptors_y) != len( - exchange_descriptors_x - ): - raise RuntimeError( - "Vector halo exchange must have same exchange data for X and Y" - ) - self._np_module = np_module - self._infos_x = tuple(exchange_descriptors_x) - self._infos_y = ( - tuple(exchange_descriptors_y) - if exchange_descriptors_y is not None - else tuple() - ) - self._pack_buffer = None - self._unpack_buffer = None - self._compile() - - def finalize(self): - """Deletion routine, making sure all buffers were inserted back into cache.""" - # Synchronize all work - self.synchronize() - - # Push the buffers back in the cache - Buffer.push_to_cache(self._pack_buffer) - self._pack_buffer = None - Buffer.push_to_cache(self._unpack_buffer) - self._unpack_buffer = None - - @staticmethod - def get( - np_module: NumpyModule, - exchange_descriptors_x: Sequence[HaloExchangeSpec], - exchange_descriptors_y: Optional[Sequence[HaloExchangeSpec]] = None, - ) -> "HaloDataTransformer": - """Construct a module from a numpy-like module. - - Args: - np_module: numpy-like module to determin child transformer type. - exchange_descriptors_x: list of memory information describing an exchange. - Used for scalar data and the x-component of vectors. - exchange_descriptors_y: list of memory information describing an exchange. - Optional, used for the y-component of vectors only. If `none` the data - will packed as a scalar. - - Returns: - an initialized packed buffer. - """ - if len(exchange_descriptors_x) == 0: - raise RuntimeError("Attempting to init an empty halo exchange") - - dtype = exchange_descriptors_x[0].specification.dtype - for desc in exchange_descriptors_x: - if dtype != desc.specification.dtype: - raise NotImplementedError("Halo exchange process mixed precision") - if exchange_descriptors_y: - for desc in exchange_descriptors_y: - if dtype != desc.specification.dtype: - raise NotImplementedError("Halo exchange process mixed precision") - - if np_module is np: - return HaloDataTransformerCPU( - np, - exchange_descriptors_x, - exchange_descriptors_y=exchange_descriptors_y, - ) - elif np_module is cp: - return HaloDataTransformerGPU( - cp, - exchange_descriptors_x, - exchange_descriptors_y=exchange_descriptors_y, - ) - - raise NotImplementedError( - f"Quantity module {np_module} has no HaloDataTransformer implemented" - ) - - def get_unpack_buffer(self) -> Buffer: - """Retrieve unpack buffer. - - Synchronizes operations. - """ - if self._unpack_buffer is None: - raise RuntimeError("Recv buffer can't be retrieved before allocate()") - self.synchronize() - return self._unpack_buffer - - def get_pack_buffer(self) -> Buffer: - """Retrieve pack buffer. - - Synchronizes operations. - """ - if self._pack_buffer is None: - raise RuntimeError("Send buffer can't be retrieved before allocate()") - self.synchronize() - return self._pack_buffer - - def _compile(self): - """Allocate contiguous memory buffers from description queued.""" - - # Compute required size - buffer_size = 0 - dtype = None - for edge_x in self._infos_x: - buffer_size += edge_x.pack_buffer_size - dtype = edge_x.specification.dtype - if self._type is _HaloDataTransformerType.VECTOR: - for edge_y in self._infos_y: - buffer_size += edge_y.pack_buffer_size - - # Retrieve two properly sized buffers - self._pack_buffer = Buffer.pop_from_cache( - self._np_module.zeros, (buffer_size), dtype - ) - self._unpack_buffer = Buffer.pop_from_cache( - self._np_module.zeros, (buffer_size), dtype - ) - - def ready(self) -> bool: - """Check if the buffers are ready for communication.""" - return self._pack_buffer is not None and self._unpack_buffer is not None - - @abc.abstractmethod - def async_pack( - self, - quantities_x: List[Quantity], - quantities_y: Optional[List[Quantity]] = None, - ): - """Pack all given quantities into a single send Buffer. - - Does not guarantee the buffer returned by `get_unpack_buffer` has - received data, doing so requires calling `synchronize`. - Reaching for the buffer via get_pack_buffer() will call synchronize(). - - Args: - quantities_x: scalar or vector x-component quantities to pack, - if one is vector they must all be vector - - quantities_y: if quantities are vector, the y-component - quantities. - """ - pass - - @abc.abstractmethod - def async_unpack( - self, - quantities_x: List[Quantity], - quantities_y: Optional[List[Quantity]] = None, - ): - """Unpack the buffer into destination quantities. - - Does not guarantee the buffer returned by `get_unpack_buffer` has - received data, doing so requires calling `synchronize`. - Reaching for the buffer via get_unpack_buffer() will call synchronize(). - - Args: - quantities_x: scalar or vector x-component quantities to be unpacked into, - if one is vector they must all be vector - quantities_y: if quantities are vector, the y-component - quantities. - """ - pass - - @abc.abstractmethod - def synchronize(self): - """Synchronize all operations. - - Guarantees all memory is now safe to access. - """ - pass - - -class HaloDataTransformerCPU(HaloDataTransformer): - """Pack/unpack data in a single buffer using numpy flattening & slicing. - - Default behavior, could be done with any numpy-like library. - """ - - def synchronize(self): - if self._pack_buffer is not None: - self._pack_buffer.finalize_memory_transfer() - if self._unpack_buffer is not None: - self._unpack_buffer.finalize_memory_transfer() - - def async_pack( - self, - quantities_x: List[Quantity], - quantities_y: Optional[List[Quantity]] = None, - ): - # Unpack per type - if self._type == _HaloDataTransformerType.SCALAR: - self._pack_scalar(quantities_x) - elif self._type == _HaloDataTransformerType.VECTOR: - assert quantities_y is not None - self._pack_vector(quantities_x, quantities_y) - else: - raise RuntimeError(f"Unimplemented {self._type} pack") - - assert isinstance(self._pack_buffer, Buffer) # e.g. allocate happened - - def _pack_scalar(self, quantities: List[Quantity]): - if __debug__: - if len(quantities) != len(self._infos_x): - raise RuntimeError( - f"Quantities count ({len(quantities)}" - f" is different that edges count {len(self._infos_x)}" - ) - # TODO Per quantity check - - assert isinstance(self._pack_buffer, Buffer) # e.g. allocate happened - offset = 0 - for quantity, info_x in zip(quantities, self._infos_x): - data_size = _slices_size(info_x.pack_slices) - # sending data across the boundary will rotate the data - # n_clockwise_rotations times, due to the difference in axis orientation.\ - # Thus we rotate that number of times counterclockwise before sending, - # to get the right final orientation - source_view = rotate_scalar_data( - quantity.data[info_x.pack_slices], - quantity.dims, - quantity.np, - -info_x.pack_clockwise_rotation, - ) - self._pack_buffer.assign_from( - source_view.flatten(), - buffer_slice=np.index_exp[offset : offset + data_size], - ) - offset += data_size - - def _pack_vector(self, quantities_x: List[Quantity], quantities_y: List[Quantity]): - if __debug__: - if len(quantities_x) != len(self._infos_x) and len(quantities_y) != len( - self._infos_y - ): - raise RuntimeError( - f"Quantities count (x: {len(quantities_x)}, y: {len(quantities_y)})" - " is different that specifications count " - f"(x: {len(self._infos_x)}, y: {len(self._infos_y)}" - ) - # TODO Per quantity check - - assert isinstance(self._pack_buffer, Buffer) # e.g. allocate happened - assert len(quantities_y) == len(quantities_x) - assert len(self._infos_x) == len(self._infos_y) - offset = 0 - for ( - quantity_x, - quantity_y, - info_x, - info_y, - ) in zip(quantities_x, quantities_y, self._infos_x, self._infos_y): - # sending data across the boundary will rotate the data - # n_clockwise_rotations times, due to the difference in axis orientation - # Thus we rotate that number of times counterclockwise before sending, - # to get the right final orientation - x_view, y_view = rotate_vector_data( - quantity_x.data[info_x.pack_slices], - quantity_y.data[info_y.pack_slices], - -info_x.pack_clockwise_rotation, - quantity_x.dims, - quantity_x.np, - ) - - # Pack X/Y data slices in the buffer - self._pack_buffer.assign_from( - x_view.flatten(), - buffer_slice=np.index_exp[offset : offset + x_view.size], - ) - offset += x_view.size - self._pack_buffer.assign_from( - y_view.flatten(), - buffer_slice=np.index_exp[offset : offset + y_view.size], - ) - offset += y_view.size - - def async_unpack( - self, - quantities_x: List[Quantity], - quantities_y: Optional[List[Quantity]] = None, - ): - # Unpack per type - if self._type == _HaloDataTransformerType.SCALAR: - self._unpack_scalar(quantities_x) - elif self._type == _HaloDataTransformerType.VECTOR: - assert quantities_y is not None - self._unpack_vector(quantities_x, quantities_y) - else: - raise RuntimeError(f"Unimplemented {self._type} unpack") - - assert isinstance(self._unpack_buffer, Buffer) # e.g. allocate happened - - def _unpack_scalar(self, quantities: List[Quantity]): - if __debug__: - if len(quantities) != len(self._infos_x): - raise RuntimeError( - f"Quantities count ({len(quantities)}" - f" is different that specifications count {len(self._infos_x)}" - ) - # TODO Per quantity check - - assert isinstance(self._unpack_buffer, Buffer) # e.g. allocate happened - offset = 0 - for quantity, info_x in zip(quantities, self._infos_x): - quantity_view = quantity.data[info_x.unpack_slices] - data_size = _slices_size(info_x.unpack_slices) - self._unpack_buffer.assign_to( - quantity_view, - buffer_slice=np.index_exp[offset : offset + data_size], - buffer_reshape=quantity_view.shape, - ) - offset += data_size - - def _unpack_vector( - self, quantities_x: List[Quantity], quantities_y: List[Quantity] - ): - if __debug__: - if len(quantities_x) != len(self._infos_x) and len(quantities_y) != len( - self._infos_y - ): - raise RuntimeError( - f"Quantities count (x: {len(quantities_x)}, y: {len(quantities_y)})" - " is different that specifications count " - f"(x: {len(self._infos_x)}, y: {len(self._infos_y)})" - ) - # TODO Per quantity check - - assert isinstance(self._unpack_buffer, Buffer) # e.g. allocate happened - offset = 0 - for quantity_x, quantity_y, info_x, info_y in zip( - quantities_x, quantities_y, self._infos_x, self._infos_y - ): - quantity_view = quantity_x.data[info_x.unpack_slices] - data_size = _slices_size(info_x.unpack_slices) - self._unpack_buffer.assign_to( - quantity_view, - buffer_slice=np.index_exp[offset : offset + data_size], - buffer_reshape=quantity_view.shape, - ) - offset += data_size - quantity_view = quantity_y.data[info_y.unpack_slices] - data_size = _slices_size(info_y.unpack_slices) - self._unpack_buffer.assign_to( - quantity_view, - buffer_slice=np.index_exp[offset : offset + data_size], - buffer_reshape=quantity_view.shape, - ) - offset += data_size - - -class HaloDataTransformerGPU(HaloDataTransformer): - """Pack/unpack data in a single buffer using CUDA Kernels. - - In order to efficiently pack/unpack on the GPU to a single GPU buffer - we use streamed (e.g. async) kernels per quantity per edge to send. The - kernels are store in `cuda_kernels.py`, they both follow the same simple pattern - by reading the indices to the device memory of the data to pack/unpack. - `_flatten_indices` is the routine that take the layout of the memory and - the slice and compute an array of index into the original memory. - """ - - # Temporary "safe" code path - # _CODE_PATH_DEVICE_WIDE_SYNC: turns off streaming and issue a single - # device wide synchronization call instead - _CODE_PATH_DEVICE_WIDE_SYNC = False - - @dataclass - class _CuKernelArgs: - """All arguments required for the CUDA kernels.""" - - stream: "cp.cuda.Stream" - x_send_indices: "cp.ndarray" - x_recv_indices: "cp.ndarray" - y_send_indices: Optional["cp.ndarray"] - y_recv_indices: Optional["cp.ndarray"] - - def __init__( - self, - np_module: NumpyModule, - exchange_descriptors_x: Sequence[HaloExchangeSpec], - exchange_descriptors_y: Optional[Sequence[HaloExchangeSpec]] = None, - ) -> None: - self._cu_kernel_args: Dict[UUID, HaloDataTransformerGPU._CuKernelArgs] = {} - super().__init__( - np_module, - exchange_descriptors_x, - exchange_descriptors_y=exchange_descriptors_y, - ) - - def _flatten_indices( - self, - exchange_data: HaloExchangeSpec, - slices: Tuple[slice], - rotate: bool, - ) -> "cp.ndarray": - """Extract a flat array of indices from the memory layout and the slice. - - Also take care of rotating the indices to account for axis orientation. - """ - key = str( - ( - slices, - exchange_data.pack_clockwise_rotation, - exchange_data.specification.shape, - exchange_data.specification.strides, - exchange_data.specification.itemsize, - ) - ) - - # We use a lazy caching mechanism here because in our use case - # (halo exchange) there is a limited set of index patterns but a - # large number of exchanges. - if key not in INDICES_CACHE.keys(): - INDICES_CACHE[key] = _build_flatten_indices( - key, - exchange_data.specification.shape, - slices, - exchange_data.specification.dims, - exchange_data.specification.strides, - exchange_data.specification.itemsize, - rotate, - exchange_data.pack_clockwise_rotation, - ) - - # We don't return a copy since the indices are read-only in the algorithm - return INDICES_CACHE[key] - - def _compile(self): - # Super to get buffer allocation - super()._compile() - # Allocate the streams & build the indices arrays - if self._type == _HaloDataTransformerType.SCALAR: - for info_x in self._infos_x: - self._cu_kernel_args[info_x._id] = HaloDataTransformerGPU._CuKernelArgs( - stream=_pop_stream(), - x_send_indices=self._flatten_indices( - info_x, info_x.pack_slices, True - ), - x_recv_indices=self._flatten_indices( - info_x, info_x.unpack_slices, False - ), - y_send_indices=None, - y_recv_indices=None, - ) - else: - assert self._type == _HaloDataTransformerType.VECTOR - for info_x, info_y in zip(self._infos_x, self._infos_y): - self._cu_kernel_args[info_x._id] = HaloDataTransformerGPU._CuKernelArgs( - stream=_pop_stream(), - x_send_indices=self._flatten_indices( - info_x, info_x.pack_slices, True - ), - x_recv_indices=self._flatten_indices( - info_x, info_x.unpack_slices, False - ), - y_send_indices=self._flatten_indices( - info_y, info_y.pack_slices, True - ), - y_recv_indices=self._flatten_indices( - info_y, info_y.unpack_slices, False - ), - ) - - def synchronize(self): - if self._CODE_PATH_DEVICE_WIDE_SYNC: - self._safe_synchronize() - else: - self._streamed_synchronize() - - def _streamed_synchronize(self): - for cu_kernel in self._cu_kernel_args.values(): - cu_kernel.stream.synchronize() - - def _safe_synchronize(self): - device_synchronize() - - def _get_stream(self, stream) -> "cp.cuda.stream": - if self._CODE_PATH_DEVICE_WIDE_SYNC: - return cp.cuda.Stream.null - else: - return stream - - def async_pack( - self, - quantities_x: List[Quantity], - quantities_y: Optional[List[Quantity]] = None, - ): - """Pack the quantities into a single buffer via streamed cuda kernels - - Writes into self._pack_buffer using self._x_infos and self._y_infos - to read the offsets and sizes per quantity. - - Args: - quantities_x: list of quantities to pack. Must fit the specifications given - at init time. - quantities_y: Same as above but optional, used only for vector transfer. - """ - - # Unpack per type - if self._type == _HaloDataTransformerType.SCALAR: - self._opt_pack_scalar(quantities_x) - elif self._type == _HaloDataTransformerType.VECTOR: - assert quantities_y is not None - self._opt_pack_vector(quantities_x, quantities_y) - else: - raise RuntimeError(f"Unimplemented {self._type} pack") - - def _opt_pack_scalar(self, quantities: List[Quantity]): - """Specialized packing for scalar. See async_pack docs for usage.""" - if __debug__: - if len(quantities) != len(self._infos_x): - raise RuntimeError( - f"Quantities count ({len(quantities)}" - f" is different that specifications count {len(self._infos_x)}" - ) - # TODO Per quantity check - - assert isinstance(self._pack_buffer, Buffer) # e.g. allocate happened - offset = 0 - for info_x, quantity in zip(self._infos_x, quantities): - cu_kernel_args = self._cu_kernel_args[info_x._id] - - # Use private stream - with self._get_stream(cu_kernel_args.stream): - # Launch kernel - blocks = 128 - grid_x = (info_x.pack_buffer_size // blocks) + 1 - # Pick a kernel looking at the precision set - pack_kernel = None - if info_x.specification.dtype == np.float32: - pack_kernel = pack_scalar_f32_kernel - elif ( - info_x.specification.dtype == np.float64 - or info_x.specification.dtype == float - ): - pack_kernel = pack_scalar_f64_kernel - else: - RuntimeError( - "Halo exchange pack kernel for precision " - f" {info_x.specification.dtype} isn't implemented." - ) - - # Check compile hasn't failed silently if this is the first - # call to the kernel - if pack_kernel is None: - RuntimeError("CUDA nvrtc failed") - else: - pack_kernel( - (grid_x,), - (blocks,), - ( - quantity.data[:], # source_array - cu_kernel_args.x_send_indices, # indices - info_x.pack_buffer_size, # nIndex - offset, - self._pack_buffer.array, - ), - ) - - # Next transformer offset into send buffer - offset += info_x.pack_buffer_size - - def _opt_pack_vector( - self, quantities_x: List[Quantity], quantities_y: List[Quantity] - ): - """Specialized packing for vectors. See async_pack docs for usage.""" - if __debug__: - if len(quantities_x) != len(self._infos_x) and len(quantities_y) != len( - self._infos_y - ): - raise RuntimeError( - f"Quantities count (x: {len(quantities_x)}, y: {len(quantities_y)}" - " is different that specifications count " - f"(x: {len(self._infos_x)}, y: {len(self._infos_y)}" - ) - # TODO Per quantity check - assert isinstance(self._pack_buffer, Buffer) # e.g. allocate happened - assert len(self._infos_x) == len(self._infos_y) - assert len(quantities_x) == len(quantities_y) - offset = 0 - for ( - quantity_x, - quantity_y, - info_x, - info_y, - ) in zip(quantities_x, quantities_y, self._infos_x, self._infos_y): - cu_kernel_args = self._cu_kernel_args[info_x._id] - - # Use private stream - with self._get_stream(cu_kernel_args.stream): - # Buffer sizes - transformer_size = info_x.pack_buffer_size + info_y.pack_buffer_size - - # Launch kernel - blocks = 128 - grid_x = (transformer_size // blocks) + 1 - # Pick a kernel looking at the precision set - pack_kernel = None - if info_x.specification.dtype == np.float32: - pack_kernel = pack_vector_f32_kernel - elif ( - info_x.specification.dtype == np.float64 - or info_x.specification.dtype == float - ): - pack_kernel = pack_vector_f64_kernel - else: - RuntimeError( - "Halo exchange pack kernel for precision " - f"{info_x.specification.dtype} isn't implemented." - ) - - # Check compile hasn't failed silently if this is the first - # call to the kernel - if pack_kernel is None: - RuntimeError("CUDA nvrtc failed") - else: - pack_kernel( - (grid_x,), - (blocks,), - ( - quantity_x.data[:], # source_array_x - quantity_y.data[:], # source_array_y - cu_kernel_args.x_send_indices, # indices_x - cu_kernel_args.y_send_indices, # indices_y - info_x.pack_buffer_size, # nIndex_x - info_y.pack_buffer_size, # nIndex_y - offset, - (-info_x.pack_clockwise_rotation) % 4, # rotation - self._pack_buffer.array, - ), - ) - - # Next transformer offset into send buffer - offset += transformer_size - - def async_unpack( - self, - quantities_x: List[Quantity], - quantities_y: Optional[List[Quantity]] = None, - ): - """Unpack the quantities from a single buffer via streamed cuda kernels - - Reads from self._unpack_buffer using self._x_infos and self._y_infos - to read the offsets and sizes per quantity. - - Args: - quantities_x: list of quantities to unpack. Must fit - the specifications given at init time. - quantities_y: Same as above but optional, used only for vector transfer. - """ - # Unpack per type - if self._type == _HaloDataTransformerType.SCALAR: - self._opt_unpack_scalar(quantities_x) - elif self._type == _HaloDataTransformerType.VECTOR: - assert quantities_y is not None - self._opt_unpack_vector(quantities_x, quantities_y) - else: - raise RuntimeError(f"Unimplemented {self._type} unpack") - - def _opt_unpack_scalar(self, quantities: List[Quantity]): - """Specialized unpacking for scalars. See async_unpack docs for usage.""" - if __debug__: - if len(quantities) != len(self._infos_x): - raise RuntimeError( - f"Quantities count ({len(quantities)})" - f" is different that specifications count ({len(self._infos_x)})" - ) - # TODO Per quantity check - assert isinstance(self._unpack_buffer, Buffer) # e.g. allocate happened - offset = 0 - for quantity, info_x in zip(quantities, self._infos_x): - cu_kernel_args = self._cu_kernel_args[info_x._id] - - # Use private stream - with self._get_stream(cu_kernel_args.stream): - # Launch kernel - blocks = 128 - grid_x = (info_x._unpack_buffer_size // blocks) + 1 - # Pick a kernel looking at the precision set - unpack_kernel = None - if info_x.specification.dtype == np.float32: - unpack_kernel = unpack_scalar_f32_kernel - elif ( - info_x.specification.dtype == np.float64 - or info_x.specification.dtype == float - ): - unpack_kernel = unpack_scalar_f64_kernel - else: - RuntimeError( - "Halo exchange pack kernel for precision " - f"{info_x.specification.dtype} isn't implemented." - ) - - # Check compile hasn't failed silently if this is the first - # call to the kernel - if unpack_kernel is None: - RuntimeError("CUDA nvrtc failed") - else: - unpack_kernel( - (grid_x,), - (blocks,), - ( - self._unpack_buffer.array, # source_buffer - cu_kernel_args.x_recv_indices, # indices - info_x._unpack_buffer_size, # nIndex - offset, - quantity.data[:], # destination_array - ), - ) - - # Next transformer offset into recv buffer - offset += info_x._unpack_buffer_size - - def _opt_unpack_vector( - self, quantities_x: List[Quantity], quantities_y: List[Quantity] - ): - """Specialized unpacking for vectors. See async_unpack docs for usage.""" - if __debug__: - if len(quantities_x) != len(self._infos_x) and len(quantities_y) != len( - self._infos_y - ): - raise RuntimeError( - f"Quantities count (x: {len(quantities_x)}, y: {len(quantities_y)}" - " is different that specifications count " - f"(x: {len(self._infos_x)}, y: {len(self._infos_y)}" - ) - # TODO Per quantity check - assert isinstance(self._unpack_buffer, Buffer) # e.g. allocate happened - assert len(self._infos_x) == len(self._infos_y) - assert len(quantities_x) == len(quantities_y) - offset = 0 - for ( - quantity_x, - quantity_y, - info_x, - info_y, - ) in zip(quantities_x, quantities_y, self._infos_x, self._infos_y): - cu_kernel_args = self._cu_kernel_args[info_x._id] - - # Use private stream - with self._get_stream(cu_kernel_args.stream): - # Buffer sizes - edge_size = info_x._unpack_buffer_size + info_y._unpack_buffer_size - - # Launch kernel - blocks = 128 - grid_x = (edge_size // blocks) + 1 - # Pick a kernel looking at the precision set - unpack_kernel = None - if info_x.specification.dtype == np.float32: - unpack_kernel = unpack_vector_f32_kernel - elif ( - info_x.specification.dtype == np.float64 - or info_x.specification.dtype == float - ): - unpack_kernel = unpack_vector_f64_kernel - else: - RuntimeError( - "Halo exchange pack kernel for precision " - f"{info_x.specification.dtype} isn't implemented." - ) - - # Check compile hasn't failed silently if this is the first - # call to the kernel - if unpack_kernel is None: - RuntimeError("CUDA nvrtc failed") - else: - unpack_kernel( - (grid_x,), - (blocks,), - ( - self._unpack_buffer.array, - cu_kernel_args.x_recv_indices, # indices_x - cu_kernel_args.y_recv_indices, # indices_y - info_x._unpack_buffer_size, # nIndex_x - info_y._unpack_buffer_size, # nIndex_y - offset, - quantity_x.data[:], # destination_array_x - quantity_y.data[:], # destination_array_y - ), - ) - - # Next transformer offset into send buffer - offset += edge_size - - def finalize(self): - super().finalize() - # Push the streams back in the pool - for cu_info in self._cu_kernel_args.values(): - _push_stream(cu_info.stream) diff --git a/util/pace/util/halo_updater.py b/util/pace/util/halo_updater.py deleted file mode 100644 index ac91d192d..000000000 --- a/util/pace/util/halo_updater.py +++ /dev/null @@ -1,536 +0,0 @@ -from collections import defaultdict -from typing import TYPE_CHECKING, Dict, Iterable, List, Mapping, Optional, Tuple - -import numpy as np - -from . import constants -from ._timing import NullTimer, Timer -from .boundary import Boundary -from .buffer import Buffer -from .halo_data_transformer import HaloDataTransformer, HaloExchangeSpec -from .quantity import Quantity, QuantityHaloSpec -from .rotate import rotate_scalar_data -from .types import AsyncRequest, NumpyModule -from .utils import device_synchronize - - -if TYPE_CHECKING: - from .communicator import Communicator - -_HaloSendTuple = Tuple[AsyncRequest, Buffer] -_HaloRecvTuple = Tuple[AsyncRequest, Buffer, np.ndarray] -_HaloRequestSendList = List[_HaloSendTuple] -_HaloRequestRecvList = List[_HaloRecvTuple] - - -TIMER_HALO_EX_KEY = "halo_exchange_global" - - -class HaloUpdater: - """Exchange halo information between ranks. - - The class is responsible for the entire exchange and uses the __init__ - to precompute the maximum of information to have minimum overhead at runtime. - Therefore it should be cached for early and re-used at runtime. - - - from_scalar_specifications/from_vector_specifications are used to - create a HaloUpdater from a list of memory specifications - - update and start/wait trigger the halo exchange - - the class creates a "pattern" of exchange that can fit - any memory given to do/start - - temporary references to the Quanitites are held between start and wait - """ - - def __init__( - self, - comm: "Communicator", - tag: int, - transformers: Dict[int, HaloDataTransformer], - timer: Timer, - ): - """Build the updater. - - Args: - comm: communicator responsible for send/recv commands. - tag: network tag to be used for communication - transformers: mapping from destination rank to transformers used to - pack/unpack before and after communication - timer: timing operations - """ - self._comm = comm - self._tag = tag - self._transformers = transformers - self._timer = timer - self._recv_requests: List[AsyncRequest] = [] - self._send_requests: List[AsyncRequest] = [] - self._inflight_x_quantities: Optional[Tuple[Quantity, ...]] = None - self._inflight_y_quantities: Optional[Tuple[Quantity, ...]] = None - self._finalize_on_wait = False - - def force_finalize_on_wait(self): - """HaloDataTransformer are finalized after a wait call - - This is a temporary fix. See DSL-816 which will remove self._finalize_on_wait. - """ - self._finalize_on_wait = True - - def __del__(self): - """Clean up all buffers on garbage collection""" - if ( - self._inflight_x_quantities is not None - or self._inflight_y_quantities is not None - ): - raise RuntimeError( - "An halo exchange wasn't completed and a wait() call was expected" - ) - if not self._finalize_on_wait: - for transformer in self._transformers.values(): - transformer.finalize() - - @classmethod - def from_scalar_specifications( - cls, - comm: "Communicator", - numpy_like_module: NumpyModule, - specifications: Iterable[QuantityHaloSpec], - boundaries: Iterable[Boundary], - tag: int, - optional_timer: Optional[Timer] = None, - ) -> "HaloUpdater": - """ - Create/retrieve as many packed buffer as needed and - queue the slices to exchange. - - Args: - comm: communicator to post network messages - numpy_like_module: module implementing numpy API - specifications: data specifications to exchange, including - number of halo points - boundaries: informations on the exchange boundaries. - tag: network tag (to differentiate messaging) for this node. - optional_timer: timing of operations. - - Returns: - HaloUpdater ready to exchange data. - """ - - timer = optional_timer if optional_timer is not None else NullTimer() - - # Sort the specification per target rank - exchange_specs_dict = defaultdict(list) - for boundary in boundaries: - for specification in specifications: - exchange_specs_dict[boundary.to_rank].append( - HaloExchangeSpec( - specification, - boundary.send_slice(specification), - boundary.n_clockwise_rotations, - boundary.recv_slice(specification), - ), - ) - - # Create the data transformers to support pack/unpack - # One transformer per target rank - transformers: Dict[int, HaloDataTransformer] = {} - for rank, exchange_specs in exchange_specs_dict.items(): - transformers[rank] = HaloDataTransformer.get( - numpy_like_module, exchange_specs - ) - - return cls(comm, tag, transformers, timer) - - @classmethod - def from_vector_specifications( - cls, - comm: "Communicator", - numpy_like_module: NumpyModule, - specifications_x: Iterable[QuantityHaloSpec], - specifications_y: Iterable[QuantityHaloSpec], - boundaries: Iterable[Boundary], - tag: int, - optional_timer: Optional[Timer] = None, - ) -> "HaloUpdater": - """ - Create/retrieve as many packed buffer as needed and queue - the slices to exchange. - - Args: - comm: communicator to post network messages - numpy_like_module: module implementing numpy API - specifications_x: specifications to exchange along the x axis. - Length must match y specifications. - specifications_y: specifications to exchange along the y axis. - Length must match x specifications. - boundaries: informations on the exchange boundaries. - tag: network tag (to differentiate messaging) for this node. - optional_timer: timing of operations. - - Returns: - HaloUpdater ready to exchange data. - """ - timer = optional_timer if optional_timer is not None else NullTimer() - - exchange_descriptors_x = defaultdict(list) - exchange_descriptors_y = defaultdict(list) - for boundary in boundaries: - for specification_x, specification_y in zip( - specifications_x, specifications_y - ): - exchange_descriptors_x[boundary.to_rank].append( - HaloExchangeSpec( - specification_x, - boundary.send_slice(specification_x), - boundary.n_clockwise_rotations, - boundary.recv_slice(specification_x), - ) - ) - exchange_descriptors_y[boundary.to_rank].append( - HaloExchangeSpec( - specification_y, - boundary.send_slice(specification_y), - boundary.n_clockwise_rotations, - boundary.recv_slice(specification_y), - ) - ) - - transformers = {} - for (rank_x, exchange_descriptor_x), (_rank_y, exchange_descriptor_y) in zip( - exchange_descriptors_x.items(), exchange_descriptors_y.items() - ): - transformers[rank_x] = HaloDataTransformer.get( - numpy_like_module, - exchange_descriptor_x, - exchange_descriptors_y=exchange_descriptor_y, - ) - - return cls(comm, tag, transformers, timer) - - def update( - self, - quantities_x: List[Quantity], - quantities_y: Optional[List[Quantity]] = None, - ): - """Exhange the data and blocks until finished.""" - self.start(quantities_x, quantities_y) - self.wait() - - def start( - self, - quantities_x: List[Quantity], - quantities_y: Optional[List[Quantity]] = None, - ): - """Start data exchange.""" - self._comm._device_synchronize() - - if ( - self._inflight_x_quantities is not None - or self._inflight_y_quantities is not None - ): - raise RuntimeError( - "Previous exchange hasn't been properly finished." - "E.g. previous start() call didn't have a wait() call." - ) - - self._timer.start(TIMER_HALO_EX_KEY) - - # Post recv MPI order - with self._timer.clock("Irecv"): - self._recv_requests = [] - for to_rank, transformer in self._transformers.items(): - self._recv_requests.append( - self._comm.comm.Irecv( - transformer.get_unpack_buffer().array, - source=to_rank, - tag=self._tag, - ) - ) - - # Pack quantities halo points data into buffers - with self._timer.clock("pack"): - for transformer in self._transformers.values(): - transformer.async_pack(quantities_x, quantities_y) - - self._inflight_x_quantities = tuple(quantities_x) - self._inflight_y_quantities = ( - tuple(quantities_y) if quantities_y is not None else None - ) - - # Post send MPI order - with self._timer.clock("Isend"): - self._send_requests = [] - for to_rank, transformer in self._transformers.items(): - self._send_requests.append( - self._comm.comm.Isend( - transformer.get_pack_buffer().array, - dest=to_rank, - tag=self._tag, - ) - ) - - self._timer.stop(TIMER_HALO_EX_KEY) - - def wait(self): - """Finalize data exchange.""" - if __debug__ and self._inflight_x_quantities is None: - raise RuntimeError('Halo update "wait" call before "start"') - - self._timer.start(TIMER_HALO_EX_KEY) - - # Wait message to be exchange - with self._timer.clock("wait"): - for send_req in self._send_requests: - send_req.wait() - for recv_req in self._recv_requests: - recv_req.wait() - - # Unpack buffers (updated by MPI with neighbouring halos) - # to proper quantities - with self._timer.clock("unpack"): - for buffer in self._transformers.values(): - buffer.async_unpack( - self._inflight_x_quantities, self._inflight_y_quantities - ) - if self._finalize_on_wait: - for transformer in self._transformers.values(): - transformer.finalize() - else: - for transformer in self._transformers.values(): - transformer.synchronize() - - self._inflight_x_quantities = None - self._inflight_y_quantities = None - - self._timer.stop(TIMER_HALO_EX_KEY) - - -class HaloUpdateRequest: - """Asynchronous request object for halo updates.""" - - def __init__( - self, - send_data: _HaloRequestSendList, - recv_data: _HaloRequestRecvList, - timer: Optional[Timer] = None, - ): - """Build a halo request. - Args: - send_data: a tuple of the MPI request and the buffer sent - recv_data: a tuple of the MPI request, the temporary buffer and - the destination buffer - timer: optional, time the wait & unpack of a halo exchange - """ - self._send_data = send_data - self._recv_data = recv_data - self._timer: Timer = timer if timer is not None else NullTimer() - - def wait(self): - """Wait & unpack data into destination buffers - Clean up by inserting back all buffers back in cache - for potential reuse - """ - for request, transfer_buffer in self._send_data: - with self._timer.clock("wait"): - request.wait() - with self._timer.clock("unpack"): - Buffer.push_to_cache(transfer_buffer) - for request, transfer_buffer, destination_array in self._recv_data: - with self._timer.clock("wait"): - request.wait() - with self._timer.clock("unpack"): - transfer_buffer.assign_to(destination_array) - Buffer.push_to_cache(transfer_buffer) - - -def on_c_grid(x_quantity, y_quantity): - if ( - constants.X_DIM not in x_quantity.dims - or constants.Y_INTERFACE_DIM not in x_quantity.dims - ): - return False - if ( - constants.Y_DIM not in y_quantity.dims - or constants.X_INTERFACE_DIM not in y_quantity.dims - ): - return False - else: - return True - - -class VectorInterfaceHaloUpdater: - def __init__( - self, - comm, - boundaries: Mapping[int, Boundary], - force_cpu: bool = False, - timer: Optional[Timer] = None, - ): - """Initialize a CubedSphereCommunicator. - - Args: - comm: mpi4py.Comm object - partitioner: cubed sphere partitioner - force_cpu: Force all communication to go through central memory. Optional. - timer: Time communication operations. Optional. - """ - self.timer: Timer = timer if timer is not None else NullTimer() - self._last_halo_tag = 0 - self._force_cpu = force_cpu - self.comm = comm - self.boundaries = boundaries - - def _get_halo_tag(self) -> int: - self._last_halo_tag += 1 - return self._last_halo_tag - - def start_synchronize_vector_interfaces( - self, x_quantity: Quantity, y_quantity: Quantity - ) -> HaloUpdateRequest: - """ - Synchronize shared points at the edges of a vector interface variable. - - Sends the values on the south and west edges to overwrite the values on adjacent - subtiles. Vector must be defined on the Arakawa C grid. - - For interface variables, the edges of the tile are computed on both ranks - bordering that edge. This routine copies values across those shared edges - so that both ranks have the same value for that edge. It also handles any - rotation of vector quantities needed to move data across the edge. - - Args: - x_quantity: the x-component quantity to be synchronized - y_quantity: the y-component quantity to be synchronized - - Returns: - request: an asynchronous request object with a .wait() method - """ - if not on_c_grid(x_quantity, y_quantity): - raise ValueError("vector must be defined on Arakawa C-grid") - device_synchronize() - tag = self._get_halo_tag() - send_requests = self._Isend_vector_shared_boundary( - x_quantity, y_quantity, tag=tag - ) - recv_requests = self._Irecv_vector_shared_boundary( - x_quantity, y_quantity, tag=tag - ) - return HaloUpdateRequest(send_requests, recv_requests, self.timer) - - def _Isend_vector_shared_boundary( - self, x_quantity, y_quantity, tag=0 - ) -> _HaloRequestSendList: - south_boundary = self.boundaries[constants.SOUTH] - west_boundary = self.boundaries[constants.WEST] - south_data = x_quantity.view.southwest.sel( - **{ - constants.Y_INTERFACE_DIM: 0, - constants.X_DIM: slice( - 0, x_quantity.extent[x_quantity.dims.index(constants.X_DIM)] - ), - } - ) - south_data = rotate_scalar_data( - south_data, - [constants.X_DIM], - x_quantity.np, - -south_boundary.n_clockwise_rotations, - ) - if south_boundary.n_clockwise_rotations in (3, 2): - south_data = -south_data - west_data = y_quantity.view.southwest.sel( - **{ - constants.X_INTERFACE_DIM: 0, - constants.Y_DIM: slice( - 0, y_quantity.extent[y_quantity.dims.index(constants.Y_DIM)] - ), - } - ) - west_data = rotate_scalar_data( - west_data, - [constants.Y_DIM], - y_quantity.np, - -west_boundary.n_clockwise_rotations, - ) - if west_boundary.n_clockwise_rotations in (1, 2): - west_data = -west_data - send_requests = [ - self._Isend( - self._maybe_force_cpu(x_quantity.np), - south_data, - dest=south_boundary.to_rank, - tag=tag, - ), - self._Isend( - self._maybe_force_cpu(y_quantity.np), - west_data, - dest=west_boundary.to_rank, - tag=tag, - ), - ] - return send_requests - - def _maybe_force_cpu(self, module: NumpyModule) -> NumpyModule: - """ - Get a numpy-like module depending on configuration and - Quantity original allocator. - """ - if self._force_cpu: - return np - return module - - def _Irecv_vector_shared_boundary( - self, x_quantity, y_quantity, tag=0 - ) -> _HaloRequestRecvList: - north_rank = self.boundaries[constants.NORTH].to_rank - east_rank = self.boundaries[constants.EAST].to_rank - north_data = x_quantity.view.northwest.sel( - **{ - constants.Y_INTERFACE_DIM: -1, - constants.X_DIM: slice( - 0, x_quantity.extent[x_quantity.dims.index(constants.X_DIM)] - ), - } - ) - east_data = y_quantity.view.southeast.sel( - **{ - constants.X_INTERFACE_DIM: -1, - constants.Y_DIM: slice( - 0, y_quantity.extent[y_quantity.dims.index(constants.Y_DIM)] - ), - } - ) - recv_requests = [ - self._Irecv( - self._maybe_force_cpu(x_quantity.np), - north_data, - source=north_rank, - tag=tag, - ), - self._Irecv( - self._maybe_force_cpu(y_quantity.np), - east_data, - source=east_rank, - tag=tag, - ), - ] - return recv_requests - - def _Isend(self, numpy_module, in_array, **kwargs) -> _HaloSendTuple: - # copy the resulting view in a contiguous array for transfer - with self.timer.clock("pack"): - buffer = Buffer.pop_from_cache( - numpy_module.zeros, in_array.shape, in_array.dtype - ) - buffer.assign_from(in_array) - buffer.finalize_memory_transfer() - with self.timer.clock("Isend"): - request = self.comm.Isend(buffer.array, **kwargs) - return (request, buffer) - - def _Irecv(self, numpy_module, out_array, **kwargs) -> _HaloRecvTuple: - # Prepare a contiguous buffer to receive data - with self.timer.clock("Irecv"): - buffer = Buffer.pop_from_cache( - numpy_module.zeros, out_array.shape, out_array.dtype - ) - recv_request = self.comm.Irecv(buffer.array, **kwargs) - return (recv_request, buffer, out_array) diff --git a/util/pace/util/initialization/__init__.py b/util/pace/util/initialization/__init__.py deleted file mode 100644 index fe15db8b2..000000000 --- a/util/pace/util/initialization/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .allocator import QuantityFactory -from .sizer import GridSizer, SubtileGridSizer diff --git a/util/pace/util/initialization/allocator.py b/util/pace/util/initialization/allocator.py deleted file mode 100644 index 1a68495e7..000000000 --- a/util/pace/util/initialization/allocator.py +++ /dev/null @@ -1,175 +0,0 @@ -from typing import Callable, Optional, Sequence - -import numpy as np - -from .._optional_imports import gt4py -from ..constants import SPATIAL_DIMS -from ..quantity import Quantity, QuantityHaloSpec -from .sizer import GridSizer - - -class StorageNumpy: - def __init__(self, backend: str): - """Initialize an object which behaves like the numpy module, but uses - gt4py storage objects for zeros, ones, and empty. - - Args: - backend: gt4py backend - """ - self.backend = backend - - def empty(self, *args, **kwargs) -> np.ndarray: - return gt4py.storage.empty(*args, backend=self.backend, **kwargs) - - def ones(self, *args, **kwargs) -> np.ndarray: - return gt4py.storage.ones(*args, backend=self.backend, **kwargs) - - def zeros(self, *args, **kwargs) -> np.ndarray: - return gt4py.storage.zeros(*args, backend=self.backend, **kwargs) - - -class QuantityFactory: - def __init__(self, sizer: GridSizer, numpy): - self.sizer: GridSizer = sizer - self._numpy = numpy - - def set_extra_dim_lengths(self, **kwargs): - """ - Set the length of extra (non-x/y/z) dimensions. - """ - self.sizer.extra_dim_lengths.update(kwargs) - - @classmethod - def from_backend(cls, sizer: GridSizer, backend: str): - """Initialize a QuantityFactory to use a specific gt4py backend. - - Args: - sizer: object which determines array sizes - backend: gt4py backend - """ - numpy = StorageNumpy(backend) - return cls(sizer, numpy) - - def _backend(self) -> Optional[str]: - try: - return self._numpy.backend - except AttributeError: - return None - - def empty( - self, - dims: Sequence[str], - units: str, - dtype: type = np.float64, - allow_mismatch_float_precision: bool = False, - ): - return self._allocate( - self._numpy.empty, dims, units, dtype, allow_mismatch_float_precision - ) - - def zeros( - self, - dims: Sequence[str], - units: str, - dtype: type = np.float64, - allow_mismatch_float_precision: bool = False, - ): - return self._allocate( - self._numpy.zeros, dims, units, dtype, allow_mismatch_float_precision - ) - - def ones( - self, - dims: Sequence[str], - units: str, - dtype: type = np.float64, - allow_mismatch_float_precision: bool = False, - ): - return self._allocate( - self._numpy.ones, dims, units, dtype, allow_mismatch_float_precision - ) - - def from_array( - self, - data: np.ndarray, - dims: Sequence[str], - units: str, - allow_mismatch_float_precision: bool = False, - ): - """ - Create a Quantity from a numpy array. - - That numpy array must correspond to the correct shape and extent - for the given dims. - """ - base = self.zeros( - dims=dims, - units=units, - dtype=data.dtype, - allow_mismatch_float_precision=allow_mismatch_float_precision, - ) - base.data[:] = base.np.asarray(data) - return base - - def _allocate( - self, - allocator: Callable, - dims: Sequence[str], - units: str, - dtype: type = np.float64, - allow_mismatch_float_precision: bool = False, - ): - origin = self.sizer.get_origin(dims) - extent = self.sizer.get_extent(dims) - shape = self.sizer.get_shape(dims) - dimensions = [ - axis - if any(dim in axis_dims for axis_dims in SPATIAL_DIMS) - else str(shape[index]) - for index, (dim, axis) in enumerate( - zip(dims, ("I", "J", "K", *([None] * (len(dims) - 3)))) - ) - ] - try: - data = allocator( - shape, dtype=dtype, aligned_index=origin, dimensions=dimensions - ) - except TypeError: - data = allocator(shape, dtype=dtype) - return Quantity( - data, - dims=dims, - units=units, - origin=origin, - extent=extent, - gt4py_backend=self._backend(), - allow_mismatch_float_precision=allow_mismatch_float_precision, - ) - - def get_quantity_halo_spec( - self, - dims: Sequence[str], - n_halo: Optional[int] = None, - dtype: type = np.float64, - ) -> QuantityHaloSpec: - """Build memory specifications for the halo update. - - Args: - dims: dimensionality of the data - n_halo: number of halo points to update, defaults to self.n_halo - dtype: data type of the data - backend: gt4py backend to use - """ - - # TEMPORARY: we do a nasty temporary allocation here to read in the hardware - # memory layout. Further work in GT4PY will allow for deferred allocation - # which will give access to those information while making sure - # we don't allocate - # Refactor is filed in ticket DSL-820 - - temp_quantity = self.zeros(dims=dims, units="", dtype=dtype) - - if n_halo is None: - n_halo = self.sizer.n_halo - - return temp_quantity.halo_spec(n_halo) diff --git a/util/pace/util/initialization/sizer.py b/util/pace/util/initialization/sizer.py deleted file mode 100644 index e787119fe..000000000 --- a/util/pace/util/initialization/sizer.py +++ /dev/null @@ -1,155 +0,0 @@ -import dataclasses -from typing import Dict, Iterable, Sequence, Tuple - -from .. import constants -from ..constants import N_HALO_DEFAULT -from ..partitioner import TilePartitioner - - -@dataclasses.dataclass -class GridSizer: - - nx: int - """length of the x compute dimension for produced arrays""" - ny: int - """length of the y compute dimension for produced arrays""" - nz: int - """length of the z compute dimension for produced arrays""" - n_halo: int - """number of horizontal halo points for produced arrays""" - extra_dim_lengths: Dict[str, int] - """lengths of any non-x/y/z dimensions, such as land or radiation dimensions""" - - def get_origin(self, dims: Sequence[str]) -> Tuple[int, ...]: - raise NotImplementedError() - - def get_extent(self, dims: Sequence[str]) -> Tuple[int, ...]: - raise NotImplementedError() - - def get_shape(self, dims: Sequence[str]) -> Tuple[int, ...]: - raise NotImplementedError() - - -class SubtileGridSizer(GridSizer): - @classmethod - def from_tile_params( - cls, - nx_tile: int, - ny_tile: int, - nz: int, - n_halo: int, - extra_dim_lengths: Dict[str, int], - layout: Tuple[int, int], - tile_partitioner: TilePartitioner = None, - tile_rank: int = 0, - ): - """Create a SubtileGridSizer from parameters about the full tile. - - Args: - nx_tile: number of x cell centers on the tile - ny_tile: number of y cell centers on the tile - nz: number of vertical levels - n_halo: number of halo points - extra_dim_lengths: lengths of any non-x/y/z dimensions, - such as land or radiation dimensions - layout: (y, x) number of ranks along tile edges - tile_partitioner (optional): partitioner object for the tile. By default, a - TilePartitioner is created with the given layout - tile_rank (optional): rank of this subtile. - """ - if tile_partitioner is None: - tile_partitioner = TilePartitioner(layout) - y_slice, x_slice = tile_partitioner.subtile_slice( - tile_rank, - [constants.Y_DIM, constants.X_DIM], - [ny_tile, nx_tile], - overlap=True, - ) - nx = x_slice.stop - x_slice.start - ny = y_slice.stop - y_slice.start - return cls(nx, ny, nz, n_halo, extra_dim_lengths) - - @classmethod - def from_namelist( - cls, - namelist: dict, - tile_partitioner: TilePartitioner = None, - tile_rank: int = 0, - ): - """Create a SubtileGridSizer from a Fortran namelist. - - Args: - namelist: A namelist for the fv3gfs fortran model - tile_partitioner (optional): a partitioner to use for segmenting the tile. - By default, a TilePartitioner is used. - tile_rank (optional): current rank on tile. Default is 0. Only matters if - different ranks have different domain shapes. If tile_partitioner - is a TilePartitioner, this argument does not matter. - """ - if "fv_core_nml" in namelist.keys(): - layout = namelist["fv_core_nml"]["layout"] - # npx and npy in the namelist are cell centers, but npz is mid levels - nx_tile = namelist["fv_core_nml"]["npx"] - 1 - ny_tile = namelist["fv_core_nml"]["npy"] - 1 - nz = namelist["fv_core_nml"]["npz"] - elif "nx_tile" in namelist.keys(): - layout = namelist["layout"] - # everything is cell centered in this format - nx_tile = namelist["nx_tile"] - ny_tile = namelist["nx_tile"] - nz = namelist["nz"] - else: - raise KeyError( - "Namelist format is unrecognized, " - "expected to find nx_tile or fv_core_nml" - ) - return cls.from_tile_params( - nx_tile, - ny_tile, - nz, - N_HALO_DEFAULT, - {}, - layout, - tile_partitioner, - tile_rank, - ) - - @property - def dim_extents(self) -> Dict[str, int]: - return_dict = self.extra_dim_lengths.copy() - return_dict.update( - { - constants.X_DIM: self.nx, - constants.X_INTERFACE_DIM: self.nx + 1, - constants.Y_DIM: self.ny, - constants.Y_INTERFACE_DIM: self.ny + 1, - constants.Z_DIM: self.nz, - constants.Z_INTERFACE_DIM: self.nz + 1, - } - ) - return return_dict - - def get_origin(self, dims: Iterable[str]) -> Tuple[int, ...]: - return_list = [ - self.n_halo if dim in constants.HORIZONTAL_DIMS else 0 for dim in dims - ] - return tuple(return_list) - - def get_extent(self, dims: Iterable[str]) -> Tuple[int, ...]: - extents = self.dim_extents - return tuple(extents[dim] for dim in dims) - - def get_shape(self, dims: Iterable[str]) -> Tuple[int, ...]: - shape_dict = self.extra_dim_lengths.copy() - # must pad non-interface variables to have the same shape as interface variables - shape_dict.update( - { - constants.X_DIM: self.nx + 1 + 2 * self.n_halo, - constants.X_INTERFACE_DIM: self.nx + 1 + 2 * self.n_halo, - constants.Y_DIM: self.ny + 1 + 2 * self.n_halo, - constants.Y_INTERFACE_DIM: self.ny + 1 + 2 * self.n_halo, - constants.Z_DIM: self.nz + 1, - constants.Z_INTERFACE_DIM: self.nz + 1, - } - ) - return tuple(shape_dict[dim] for dim in dims) diff --git a/util/pace/util/io.py b/util/pace/util/io.py deleted file mode 100644 index 536fc546d..000000000 --- a/util/pace/util/io.py +++ /dev/null @@ -1,69 +0,0 @@ -from typing import TextIO - -import cftime - -from . import _xarray as xr -from . import filesystem -from .quantity import Quantity -from .time import FMS_TO_CFTIME_TYPE - - -def write_state(state: dict, filename: str) -> None: - """Write a model state to a NetCDF file. - - Args: - state: a model state dictionary - filename: local or remote location to write the NetCDF file - """ - if "time" not in state: - raise ValueError('state must include a value for "time"') - ds = xr.to_dataset(state) - with filesystem.open(filename, "wb") as f: - ds.to_netcdf(f) - - -def _extract_time(value: xr.DataArray) -> cftime.datetime: - """Exctract time value from read-in state.""" - if value.ndim > 0: - raise ValueError( - "State must be representative of a single scalar time. " f"Got {value}." - ) - time = value.item() - if not isinstance(time, cftime.datetime): - raise ValueError( - "Time in stored state does not have the proper metadata " - "to be decoded as a cftime.datetime object." - ) - return time - - -def read_state(filename: str) -> dict: - """Read a model state from a NetCDF file. - - Args: - filename: local or remote location of the NetCDF file - - Returns: - state: a model state dictionary - """ - out_dict = {} - with filesystem.open(filename, "rb") as f: - ds = xr.open_dataset(f, use_cftime=True) - for name, value in ds.data_vars.items(): - if name == "time": - out_dict[name] = _extract_time(value) - else: - out_dict[name] = Quantity.from_data_array(value) - return out_dict - - -def _get_integer_tokens(line, n_tokens): - all_tokens = line.split() - return [int(token) for token in all_tokens[:n_tokens]] - - -def get_current_date_from_coupler_res(file: TextIO) -> cftime.datetime: - (fms_calendar_type,) = _get_integer_tokens(file.readline(), 1) - file.readline() - year, month, day, hour, minute, second = _get_integer_tokens(file.readline(), 6) - return FMS_TO_CFTIME_TYPE[fms_calendar_type](year, month, day, hour, minute, second) diff --git a/util/pace/util/local_comm.py b/util/pace/util/local_comm.py deleted file mode 100644 index 32fd0fb4a..000000000 --- a/util/pace/util/local_comm.py +++ /dev/null @@ -1,196 +0,0 @@ -import copy -from typing import Any - -from .comm import Comm -from .logging import pace_log -from .utils import ensure_contiguous, safe_assign_array - - -class ConcurrencyError(Exception): - """Exception to denote that a rank cannot proceed because it is waiting on a - call from another rank.""" - - pass - - -class AsyncResult: - def __init__(self, result): - self._result = result - - def wait(self): - return self._result() - - -class LocalComm(Comm): - def __init__(self, rank, total_ranks, buffer_dict): - self.rank = rank - self.total_ranks = total_ranks - self._buffer = buffer_dict - self._i_buffer = {} - - @property - def _split_comms(self): - self._buffer["split_comms"] = self._buffer.get("split_comms", {}) - return self._buffer["split_comms"] - - @property - def _split_buffers(self): - self._buffer["split_buffers"] = self._buffer.get("split_buffers", {}) - return self._buffer["split_buffers"] - - def __repr__(self): - return f"LocalComm(rank={self.rank}, total_ranks={self.total_ranks})" - - def Get_rank(self): - return self.rank - - def Get_size(self): - return self.total_ranks - - def _get_buffer(self, buffer_type, in_value): - i_buffer = self._i_buffer.get(buffer_type, 0) - self._i_buffer[buffer_type] = i_buffer + 1 - if buffer_type not in self._buffer: - self._buffer[buffer_type] = [] - if self.rank == 0: - self._buffer[buffer_type].append(in_value) - return self._buffer[buffer_type][i_buffer] - - def _get_send_recv(self, from_rank, tag: int): - key = (from_rank, self.rank, tag) - if "send_recv" not in self._buffer: - raise ConcurrencyError( - "buffer not initialized for send_recv, likely recv called before send" - ) - elif key not in self._buffer["send_recv"]: - raise ConcurrencyError( - f"rank-specific buffer not initialized for send_recv, likely " - f"recv called before send from rank {from_rank} to rank {self.rank}" - ) - return_value = self._buffer["send_recv"][key].pop(0) - return return_value - - def _put_send_recv(self, value, to_rank, tag: int): - key = (self.rank, to_rank, tag) - self._buffer["send_recv"] = self._buffer.get("send_recv", {}) - self._buffer["send_recv"][key] = self._buffer["send_recv"].get(key, []) - self._buffer["send_recv"][key].append(copy.deepcopy(value)) - - @property - def _bcast_buffer(self): - if "bcast" not in self._buffer: - self._buffer["bcast"] = [] - return self._buffer["bcast"] - - @property - def _scatter_buffer(self): - if "scatter" not in self._buffer: - self._buffer["scatter"] = [] - return self._buffer["scatter"] - - @property - def _gather_buffer(self): - if "gather" not in self._buffer: - self._buffer["gather"] = [None for i in range(self.total_ranks)] - return self._buffer["gather"] - - def bcast(self, value, root=0): - if root != 0: - raise NotImplementedError( - "LocalComm assumes ranks are called in order, so root must be " - "the bcast source" - ) - value = self._get_buffer("bcast", value) - pace_log.debug(f"bcast {value} to rank {self.rank}") - return value - - def Barrier(self): - return - - def barrier(self): - return - - def Scatter(self, sendbuf, recvbuf, root=0, **kwargs): - ensure_contiguous(sendbuf) - ensure_contiguous(recvbuf) - if root != 0: - raise NotImplementedError( - "LocalComm assumes ranks are called in order, so root must be " - "the scatter source" - ) - if sendbuf is not None: - sendbuf = self._get_buffer("scatter", copy.deepcopy(sendbuf)) - else: - sendbuf = self._get_buffer("scatter", None) - safe_assign_array(recvbuf, sendbuf[self.rank]) - - def Gather(self, sendbuf, recvbuf, root=0, **kwargs): - ensure_contiguous(sendbuf) - ensure_contiguous(recvbuf) - gather_buffer = self._gather_buffer - gather_buffer[self.rank] = copy.deepcopy(sendbuf) - if self.rank == root: - # ndarrays are finnicky, have to check for None like this: - if any(item is None for item in gather_buffer): - uncalled_ranks = [ - i for i, val in enumerate(gather_buffer) if val is None - ] - raise ConcurrencyError( - f"gather called on root rank before ranks {uncalled_ranks}" - ) - for i, sendbuf in enumerate(gather_buffer): - safe_assign_array(recvbuf[i, :], sendbuf) - - def allgather(self, sendobj): - raise NotImplementedError( - "cannot implement allgather on local comm due to its inherent parallelism" - ) - - def Send(self, sendbuf, dest, tag: int = 0, **kwargs): - ensure_contiguous(sendbuf) - self._put_send_recv(sendbuf, dest, tag) - - def Isend(self, sendbuf, dest, tag: int = 0, **kwargs): - result = self.Send(sendbuf, dest, tag) - - def send(): - return result - - return AsyncResult(send) - - def Recv(self, recvbuf, source, tag: int = 0, **kwargs): - ensure_contiguous(recvbuf) - safe_assign_array(recvbuf, self._get_send_recv(source, tag)) - - def Irecv(self, recvbuf, source, tag: int = 0, **kwargs): - def receive(): - return self.Recv(recvbuf, source, tag) - - return AsyncResult(receive) - - def sendrecv(self, sendbuf, dest, **kwargs): - raise NotImplementedError( - "sendrecv fundamentally cannot be written for LocalComm, " - "as it requires synchronicity" - ) - - def Split(self, color, key): - # key argument is ignored, assumes we're calling the ranks from least to - # greatest when mocking Split - self._split_comms[color] = self._split_comms.get(color, []) - self._split_buffers[color] = self._split_buffers.get(color, {}) - rank = len(self._split_comms[color]) - total_ranks = rank + 1 - new_comm = LocalComm( - rank=rank, total_ranks=total_ranks, buffer_dict=self._split_buffers[color] - ) - for comm in self._split_comms[color]: - comm.total_ranks = total_ranks - self._split_comms[color].append(new_comm) - return new_comm - - def allreduce(self, sendobj, op=None) -> Any: - raise NotImplementedError( - "sendrecv fundamentally cannot be written for LocalComm, " - "as it requires synchronicity" - ) diff --git a/util/pace/util/logging.py b/util/pace/util/logging.py deleted file mode 100644 index 1f9142fec..000000000 --- a/util/pace/util/logging.py +++ /dev/null @@ -1,39 +0,0 @@ -import logging -import os -import sys - -from mpi4py import MPI - - -LOGLEVEL = os.environ.get("PACE_LOGLEVEL", "INFO").upper() - -# Python log levels are hierarchical, therefore setting INFO -# means DEBUG and everything lower will be logged. -AVAILABLE_LOG_LEVELS = { - "info": logging.INFO, - "debug": logging.DEBUG, - "warning": logging.WARNING, - "error": logging.ERROR, - "critical": logging.CRITICAL, -} - - -def _pace_logger(): - name_log = logging.getLogger(__name__) - name_log.setLevel(LOGLEVEL) - - handler = logging.StreamHandler(sys.stdout) - handler.setLevel(LOGLEVEL) - formatter = logging.Formatter( - fmt=( - f"%(asctime)s|%(levelname)s|rank {MPI.COMM_WORLD.Get_rank()}|" - "%(name)s:%(message)s" - ), - datefmt="%Y-%m-%d %H:%M:%S", - ) - handler.setFormatter(formatter) - name_log.addHandler(handler) - return name_log - - -pace_log = _pace_logger() diff --git a/util/pace/util/monitor/__init__.py b/util/pace/util/monitor/__init__.py deleted file mode 100644 index a0c7e036f..000000000 --- a/util/pace/util/monitor/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .netcdf_monitor import NetCDFMonitor -from .protocol import Monitor -from .zarr_monitor import ZarrMonitor diff --git a/util/pace/util/monitor/convert.py b/util/pace/util/monitor/convert.py deleted file mode 100644 index 239f3bada..000000000 --- a/util/pace/util/monitor/convert.py +++ /dev/null @@ -1,26 +0,0 @@ -import numpy as np - -from .._optional_imports import cupy - - -def to_numpy(array, dtype=None) -> np.ndarray: - """ - Input array can be a numpy array or a cupy array. Returns numpy array. - """ - try: - output = np.asarray(array) - except ValueError as err: - if err.args[0] == "object __array__ method not producing an array": - output = cupy.asnumpy(array) - else: - raise err - except TypeError as err: - if err.args[0].startswith( - "Implicit conversion to a NumPy array is not allowed." - ): - output = cupy.asnumpy(array) - else: - raise err - if dtype: - output = output.astype(dtype=dtype) - return output diff --git a/util/pace/util/monitor/netcdf_monitor.py b/util/pace/util/monitor/netcdf_monitor.py deleted file mode 100644 index abcb7fe39..000000000 --- a/util/pace/util/monitor/netcdf_monitor.py +++ /dev/null @@ -1,204 +0,0 @@ -import os -from pathlib import Path -from typing import Any, Dict, List, Optional, Set - -import fsspec -import numpy as np - -from pace.util.communicator import Communicator - -from .. import _xarray as xr -from ..filesystem import get_fs -from ..logging import pace_log -from ..quantity import Quantity -from .convert import to_numpy - - -class _TimeChunkedVariable: - def __init__(self, initial: Quantity, time_chunk_size: int): - self._data = np.zeros( - (time_chunk_size, *initial.extent), dtype=initial.data.dtype - ) - self._data[0, ...] = to_numpy(initial.view[:]) - self._dims = initial.dims - self._units = initial.units - self._i_time = 1 - - def append(self, quantity: Quantity): - # Allow mismatch precision here since this is I/O - self._data[self._i_time, ...] = to_numpy( - quantity.transpose(self._dims, allow_mismatch_float_precision=True).view[:] - ) - self._i_time += 1 - - @property - def data(self) -> Quantity: - # Allow mismatch precision here since this is I/O - return Quantity( - data=self._data[: self._i_time, ...], - dims=("time",) + tuple(self._dims), - units=self._units, - allow_mismatch_float_precision=True, - ) - - -class _ChunkedNetCDFWriter: - FILENAME_FORMAT = "state_{chunk:04d}_tile{tile}.nc" - - def __init__( - self, path: str, tile: int, fs: fsspec.AbstractFileSystem, time_chunk_size: int - ): - self._path = path - self._tile = tile - self._fs = fs - self._time_chunk_size = time_chunk_size - self._i_time = 0 - self._chunked: Optional[Dict[str, _TimeChunkedVariable]] = None - self._times: List[Any] = [] - self._time_units: Optional[str] = None - - def append(self, state): - pace_log.debug("appending at time %d", self._i_time) - state = {**state} # copy so we don't mutate the input - time = state.pop("time", None) - if self._chunked is None: - self._chunked = { - name: _TimeChunkedVariable(quantity, self._time_chunk_size) - for name, quantity in state.items() - } - else: - for name, quantity in state.items(): - self._chunked[name].append(quantity) - self._times.append(time) - if (self._i_time + 1) % self._time_chunk_size == 0: - pace_log.debug("flushing on append at time %d", self._i_time) - self.flush() - self._i_time += 1 - - def flush(self): - if self._chunked is None: - pass - else: - data_vars = {"time": (["time"], self._times)} - for name, chunked in self._chunked.items(): - data_vars[name] = xr.DataArray( - chunked.data.view[:], - dims=chunked.data.dims, - attrs=chunked.data.attrs, - ).expand_dims({"tile": [self._tile]}, axis=1) - ds = xr.Dataset(data_vars=data_vars) - chunk_index = self._i_time // self._time_chunk_size - chunk_path = str( - Path(self._path) - / _ChunkedNetCDFWriter.FILENAME_FORMAT.format( - chunk=chunk_index, tile=self._tile - ) - ) - Path(self._path).mkdir(exist_ok=True) - if os.path.exists(chunk_path): - os.remove(chunk_path) - ds.to_netcdf(chunk_path, format="NETCDF4", engine="netcdf4") - - self._chunked = None - self._times.clear() - - -class NetCDFMonitor: - """ - sympl.Monitor-style object for storing model state dictionaries netCDF files. - """ - - _CONSTANT_FILENAME = "constants" - - def __init__( - self, - path: str, - communicator: Communicator, - time_chunk_size: int = 1, - ): - """Create a NetCDFMonitor. - - Args: - path: directory in which to store data - communicator: provides global communication to gather state - time_chunk_size: number of times per file - """ - rank = communicator.rank - self._tile_index = communicator.partitioner.tile_index(rank) - self._path = path - self._fs = get_fs(path) - self._communicator = communicator - self._time_chunk_size = time_chunk_size - self.__writer: Optional[_ChunkedNetCDFWriter] = None - self._expected_vars: Optional[Set[str]] = None - - @property - def _writer(self): - if self.__writer is None: - self.__writer = _ChunkedNetCDFWriter( - path=self._path, - tile=self._tile_index, - fs=self._fs, - time_chunk_size=self._time_chunk_size, - ) - return self.__writer - - def store(self, state: dict) -> None: - """Append the model state dictionary to the netcdf files. - - Will only write to disk when a full time chunk has been accumulated, - or when .cleanup() is called. - - Requires the state contain the same quantities with the same metadata as the - first time this is called. Dimension order metadata may change between calls - so long as the set of dimensions is the same. Quantities are stored with - dimensions [time, tile] followed by the dimensions included in the first - state snapshot. The one exception is "time" which is stored with dimensions - [time]. - """ - if self._expected_vars is None: - self._expected_vars = set(state.keys()) - elif self._expected_vars != set(state.keys()): - raise ValueError( - "state keys must be the same each time store is called, " - "got {} but previously got {}".format( - set(state.keys()), self._expected_vars - ) - ) - state = self._communicator.tile.gather_state(state, transfer_type=np.float32) - if state is not None: # we are on root rank - self._writer.append(state) - - def store_constant(self, state: Dict[str, Quantity]) -> None: - state = self._communicator.gather_state(state, transfer_type=np.float32) - if state is not None: # we are on root rank - constants_filename = str( - Path(self._path) / NetCDFMonitor._CONSTANT_FILENAME - ) - for name, quantity in state.items(): - path_for_grid = constants_filename + "_" + name + ".nc" - - if self._fs.exists(path_for_grid): - ds = xr.open_dataset(path_for_grid) - ds = ds.load() - ds[name] = xr.DataArray( - quantity.view[:], - dims=quantity.dims, - attrs=quantity.attrs, - ) - else: - ds = xr.Dataset( - data_vars={ - name: xr.DataArray( - quantity.view[:], - dims=quantity.dims, - attrs=quantity.attrs, - ) - } - ) - if os.path.exists(path_for_grid): - os.remove(path_for_grid) - ds.to_netcdf(path_for_grid, format="NETCDF4", engine="netcdf4") - - def cleanup(self): - self._writer.flush() diff --git a/util/pace/util/monitor/protocol.py b/util/pace/util/monitor/protocol.py deleted file mode 100644 index 6319aebb1..000000000 --- a/util/pace/util/monitor/protocol.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import Dict, Protocol - -from pace.util.quantity import Quantity - - -class Monitor(Protocol): - """ - sympl.Monitor-style object for storing model state dictionaries. - """ - - def store(self, state: dict) -> None: - """Append the model state dictionary to the stored data.""" - ... - - def store_constant(self, state: Dict[str, Quantity]) -> None: - ... - - def cleanup(self): - ... diff --git a/util/pace/util/monitor/zarr_monitor.py b/util/pace/util/monitor/zarr_monitor.py deleted file mode 100644 index 5d7729b95..000000000 --- a/util/pace/util/monitor/zarr_monitor.py +++ /dev/null @@ -1,385 +0,0 @@ -from datetime import datetime, timedelta -from typing import List, Tuple, Union - -import cftime - -from .. import _xarray as xr -from .. import constants, utils -from .._optional_imports import cupy, zarr -from ..logging import pace_log -from ..partitioner import Partitioner, subtile_slice -from .convert import to_numpy - - -__all__ = ["ZarrMonitor"] - - -class DummyComm: - def Get_rank(self): - return 0 - - def Get_size(self): - return 1 - - def bcast(self, value, root=0): - assert root == 0, ( - "DummyComm should only be used on a single core, " - "so root should only ever be 0" - ) - return value - - def barrier(self): - return - - -class ZarrMonitor: - """ - sympl.Monitor-style object for storing model state dictionaries in a Zarr store. - """ - - def __init__( - self, - store: Union[str, "zarr.storage.MutableMapping"], - partitioner: Partitioner, - mode: str = "w", - mpi_comm=DummyComm(), - ): - """Create a ZarrMonitor. - - Args: - store: Zarr store in which to store data - partitioner: object providing grid layout information to the Monitor - mode: mode to use to open the store. Options are as in zarr.open_group. - mpi_comm: mpi4py comm object to use for communications. By default, will - use a dummy comm object that works in single-core mode. - """ - if mpi_comm.Get_rank() == 0: - group = zarr.open_group(store, mode=mode) - else: - group = None - self._group = mpi_comm.bcast(group) - self._comm = mpi_comm - self._writers = None - self._constants: List[str] = [] - self.partitioner = partitioner - - def _init_writers(self, state): - self._writers = { - key: _ZarrVariableWriter( - self._comm, - self._group, - name=key, - partitioner=self.partitioner, - ) - for key in set(state.keys()).difference(["time"]) - } - self._writers["time"] = _ZarrTimeWriter( - self._comm, - self._group, - name="time", - partitioner=self.partitioner, - ) - - def _check_writers(self, state): - extra_names = set(state.keys()).difference(self._writers.keys()) - if len(extra_names) != 0: - raise ValueError( - f"provided state has keys {extra_names} " - "that were not present in earlier states" - ) - missing_names = set(self._writers.keys()).difference(state.keys()) - if len(missing_names) != 0: - raise ValueError( - f"provided state is missing keys {missing_names} " - "that were present in earlier states" - ) - - def _ensure_writers_are_consistent(self, state): - if self._writers is None: - self._init_writers(state) - else: - self._check_writers(state) - - def store(self, state: dict) -> None: - """Append the model state dictionary to the zarr store. - - Requires the state contain the same quantities with the same metadata as the - first time this is called. Dimension order metadata may change between calls - so long as the set of dimensions is the same. Quantities are stored with - dimensions [time, rank] followed by the dimensions included in the first - state snapshot. The one exception is "time" which is stored with dimensions - [time]. - """ - self._ensure_writers_are_consistent(state) - for name, quantity in sorted(state.items(), key=lambda x: x[0]): - self._writers[name].append(quantity) # type: ignore[index] - - def store_constant(self, state: dict) -> None: - for name, quantity in state.items(): - if name in self._constants: - raise RuntimeError( - f"constant fields can only be written once, {name} exists" - ) - constant_writer = _ZarrConstantWriter( - self._comm, - self._group, - name=name, - partitioner=self.partitioner, - ) - constant_writer.append(quantity) # type: ignore[index] - self._constants.append(name) - - def cleanup(self): - pass - - -class _ZarrVariableWriter: - def __init__(self, comm, group, name, partitioner): - self.i_time = 0 - self.comm = comm - self.group = group - self.name = name - self.array = None - - self._prepend_shape = (1, 6) - self._prepend_chunks = (1, 1) - self._y_chunks = partitioner.tile.layout[0] - self._x_chunks = partitioner.tile.layout[1] - self._PREPEND_DIMS = ("time", "tile") - self._partitioner = partitioner - - @property - def partitioner(self): - return self._partitioner - - @property - def rank(self): - return self.comm.Get_rank() - - def _get_array_dims(self): - if self.array is None: - raise ValueError("Array not yet set, must call .store first.") - else: - return self.array.attrs.get("_ARRAY_DIMENSIONS") - - def _init_zarr(self, quantity): - if self.rank == 0: - self._init_zarr_root(quantity) - self.array.attrs.update(self._get_attrs(quantity)) - self.sync_array() - - def _init_zarr_root(self, quantity): - tile_shape = self._partitioner.tile.global_extent(quantity.metadata) - chunks = self._prepend_chunks + array_chunks( - self._partitioner.layout, tile_shape, quantity.dims - ) - self.array = self.group.create_dataset( - self.name, - shape=self._prepend_shape + tile_shape, - dtype=quantity.data.dtype, - chunks=chunks, - fill_value=None, - ) - - def sync_array(self): - self.array = self.comm.bcast(self.array, root=0) - - def _match_dim_order(self, quantity): - self._check_dims(quantity) - if self._get_array_dims() != self._get_quantity_dims(quantity): - return quantity.transpose(self._get_array_dims()[2:]) - else: - return quantity - - def _check_dims(self, quantity): - quantity_dims = self._get_quantity_dims(quantity) - missing_dims = set(self._get_array_dims()).difference(quantity_dims) - extra_dims = set(quantity_dims).difference(self._get_array_dims()) - if len(extra_dims) > 0: - raise ValueError( - "Attempting to append a quantity with dimension(s)" - f"{extra_dims} not contained in previously stored array." - ) - if len(missing_dims) > 0: - raise ValueError( - "Attempting to append a quantity missing dimension(s)" - f"{missing_dims} contained in previously stored array." - ) - - def append(self, quantity): - # can't just use zarr_array.append because we only want to - # extend the dimension once, from the root rank - if self.array is None: - self._init_zarr(quantity) - - quantity = self._match_dim_order(quantity) - self._check_units(quantity) - - if self.i_time >= self.array.shape[0] and self.rank == 0: - new_shape = list( - self._prepend_shape - + self._partitioner.tile.global_extent(quantity.metadata) - ) - new_shape[0] = self.i_time + 1 - self.array.resize(*new_shape) - self.sync_array() - - target_slice = ( - self.i_time, - self._partitioner.tile_index(self.rank), - ) + subtile_slice( - quantity.dims, - self.array.shape[2:], # remove time and tile dimensions - self.partitioner.layout, - self.partitioner.tile.subtile_index(self.rank), - overlap=False, - ) - - from_slice = _get_from_slice(target_slice) - pace_log.debug( - f"assigning data from subtile slice {from_slice} to " - f"target slice {target_slice}" - ) - self.array[target_slice] = to_numpy(quantity.view[:])[from_slice] - self.i_time += 1 - - def _get_attrs(self, quantity): - return { - "_ARRAY_DIMENSIONS": self._get_quantity_dims(quantity), - **quantity.attrs, - } - - def _get_quantity_dims(self, quantity): - return list(self._PREPEND_DIMS + quantity.dims) - - def _check_units(self, new_quantity): - units = self.array.attrs.get("units") - if units != new_quantity.units: - raise ValueError( - f"value for {self.name} with units {new_quantity.units} " - f"does not match previously stored units {units}" - ) - - -def array_chunks( - layout: Tuple[int, int], - tile_array_shape: Tuple[int, ...], - array_dims: Tuple[str, ...], -): - layout_by_dims = utils.list_by_dims(array_dims, layout, 1) - chunks_list = [] - for extent, dim, n_ranks in zip(tile_array_shape, array_dims, layout_by_dims): - if dim in constants.INTERFACE_DIMS: - chunks_list.append(int((extent - 1) // n_ranks)) - else: - chunks_list.append(int(extent // n_ranks)) - return tuple(chunks_list) - - -def _get_from_slice(target_slice): - return_list = [] - for entry in target_slice: - if isinstance(entry, slice): - return_list.append(slice(0, entry.stop - entry.start)) - return tuple(return_list) - - -class _ZarrConstantWriter(_ZarrVariableWriter): - def __init__(self, *args, **kwargs): - super(_ZarrConstantWriter, self).__init__(*args, **kwargs) - self._prepend_shape = (6,) - self._prepend_chunks = (1,) - self._PREPEND_DIMS = ("tile",) - - def append(self, quantity): - # can't just use zarr_array.append because we only want to - # extend the dimension once, from the root rank - if self.array is None: - self._init_zarr(quantity) - - self.sync_array() - - target_slice = (self._partitioner.tile_index(self.rank),) + subtile_slice( - quantity.dims, - self.array.shape[1:], # remove tile dimensions - self.partitioner.layout, - self.partitioner.tile.subtile_index(self.rank), - overlap=False, - ) - - from_slice = _get_from_slice(target_slice) - pace_log.debug( - f"assigning data from subtile slice {from_slice} to " - f"target slice {target_slice}" - ) - - try: - self.array[target_slice] = quantity.view[:][from_slice] - except ValueError as err: - if err.args[0] == "object __array__ method not producing an array": - self.array[target_slice] = cupy.asnumpy(quantity.view[:][from_slice]) - else: - raise err - except TypeError as err: - if err.args[0].startswith( - "Implicit conversion to a NumPy array is not allowed." - ): - self.array[target_slice] = cupy.asnumpy(quantity.view[:][from_slice]) - else: - raise err - - -class _ZarrTimeWriter(_ZarrVariableWriter): - _TIME_CHUNK_SIZE = 1024 - - def __init__(self, *args, **kwargs): - super(_ZarrTimeWriter, self).__init__(*args, **kwargs) - self._prepend_shape = (1,) - self._prepend_chunks = (self._TIME_CHUNK_SIZE,) - self._PREPEND_DIMS = ("time",) - - def _init_zarr_root(self, array): - shape = self._prepend_shape - chunks = self._prepend_chunks - self.array = self.group.create_dataset( - self.name, shape=shape, dtype=array.dtype, chunks=chunks, fill_value=None - ) - - def _set_time_encoding_attrs(self, time): - self._encoding_units = f"seconds since {time}" - self._encoding_calendar = get_calendar(time) - if self.rank == 0: - self.array.attrs["units"] = self._encoding_units - self.array.attrs["calendar"] = self._encoding_calendar - - def _encode_time(self, time): - calendar = get_calendar(time) - if calendar != self._encoding_calendar: - raise ValueError( - f"Calendar type of time, {calendar}, does not match the original " - f"calendar encoding, {self._encoding_calendar}." - ) - return cftime.date2num( - time, units=self._encoding_units, calendar=self._encoding_calendar - ) - - def append(self, time): - array = xr.DataArray() - if self.array is None: - self._init_zarr(array) - self._set_time_encoding_attrs(time) - if self.i_time >= self.array.shape[0] and self.rank == 0: - new_shape = (self.i_time + 1,) - self.array.resize(*new_shape) - self.sync_array() - if self.rank == 0: - self.array[self.i_time] = self._encode_time(time) - self.i_time += 1 - self.comm.barrier() - - -def get_calendar(time: Union[datetime, timedelta, cftime.datetime]): - try: - return time.calendar # type: ignore - except AttributeError: - return "proleptic_gregorian" # the calendar for Python datetimes diff --git a/util/pace/util/mpi.py b/util/pace/util/mpi.py deleted file mode 100644 index 5acc2b000..000000000 --- a/util/pace/util/mpi.py +++ /dev/null @@ -1,79 +0,0 @@ -try: - from mpi4py import MPI -except ImportError: - MPI = None -from typing import List, Optional, TypeVar, cast - -from .comm import Comm, Request -from .logging import pace_log - - -T = TypeVar("T") - - -class MPIComm(Comm): - def __init__(self): - if MPI is None: - raise RuntimeError("MPI not available") - self._comm: Comm = cast(Comm, MPI.COMM_WORLD) - - def Get_rank(self) -> int: - return self._comm.Get_rank() - - def Get_size(self) -> int: - return self._comm.Get_size() - - def bcast(self, value: Optional[T], root=0) -> T: - pace_log.debug("bcast from root %s on rank %s", root, self._comm.Get_rank()) - return self._comm.bcast(value, root=root) - - def barrier(self): - pace_log.debug("barrier on rank %s", self._comm.Get_rank()) - self._comm.barrier() - - def Barrier(self): - pass - - def Scatter(self, sendbuf, recvbuf, root=0, **kwargs): - pace_log.debug("Scatter on rank %s with root %s", self._comm.Get_rank(), root) - self._comm.Scatter(sendbuf, recvbuf, root=root, **kwargs) - - def Gather(self, sendbuf, recvbuf, root=0, **kwargs): - pace_log.debug("Gather on rank %s with root %s", self._comm.Get_rank(), root) - self._comm.Gather(sendbuf, recvbuf, root=root, **kwargs) - - def allgather(self, sendobj: T) -> List[T]: - pace_log.debug("allgather on rank %s", self._comm.Get_rank()) - return self._comm.allgather(sendobj) - - def Send(self, sendbuf, dest, tag: int = 0, **kwargs): - pace_log.debug("Send on rank %s with dest %s", self._comm.Get_rank(), dest) - self._comm.Send(sendbuf, dest, tag=tag, **kwargs) - - def sendrecv(self, sendbuf, dest, **kwargs): - pace_log.debug("sendrecv on rank %s with dest %s", self._comm.Get_rank(), dest) - return self._comm.sendrecv(sendbuf, dest, **kwargs) - - def Isend(self, sendbuf, dest, tag: int = 0, **kwargs) -> Request: - pace_log.debug("Isend on rank %s with dest %s", self._comm.Get_rank(), dest) - return self._comm.Isend(sendbuf, dest, tag=tag, **kwargs) - - def Recv(self, recvbuf, source, tag: int = 0, **kwargs): - pace_log.debug("Recv on rank %s with source %s", self._comm.Get_rank(), source) - self._comm.Recv(recvbuf, source, tag=tag, **kwargs) - - def Irecv(self, recvbuf, source, tag: int = 0, **kwargs) -> Request: - pace_log.debug("Irecv on rank %s with source %s", self._comm.Get_rank(), source) - return self._comm.Irecv(recvbuf, source, tag=tag, **kwargs) - - def Split(self, color, key) -> "Comm": - pace_log.debug( - "Split on rank %s with color %s, key %s", self._comm.Get_rank(), color, key - ) - return self._comm.Split(color, key) - - def allreduce(self, sendobj: T, op=None) -> T: - pace_log.debug( - "allreduce on rank %s with operator %s", self._comm.Get_rank(), op - ) - return self._comm.allreduce(sendobj, op) diff --git a/util/pace/util/namelist.py b/util/pace/util/namelist.py deleted file mode 100644 index 0133e3f6d..000000000 --- a/util/pace/util/namelist.py +++ /dev/null @@ -1,487 +0,0 @@ -import dataclasses -from typing import Tuple - -import f90nml - - -DEFAULT_INT = 0 -DEFAULT_STR = "" -DEFAULT_FLOAT = 0.0 -DEFAULT_BOOL = False -# Global set of namelist defaults, attached to class for namespacing and static typing -class NamelistDefaults: - layout = (1, 1) - grid_type = 0 - dx_const = 1000.0 - dy_const = 1000.0 - deglat = 15.0 - u_max = 350.0 - do_f3d = False - inline_q = False - do_skeb = False # save dissipation estimate - use_logp = False - moist_phys = True - check_negative = False - # gfdl_cloud_mucrophys.F90 - tau_r2g = 900.0 # rain freezing during fast_sat - tau_smlt = 900.0 # snow melting - tau_g2r = 600.0 # graupel melting to rain - tau_imlt = 600.0 # cloud ice melting - tau_i2s = 1000.0 # cloud ice to snow auto - conversion - tau_l2r = 900.0 # cloud water to rain auto - conversion - tau_g2v = 1200.0 # graupel sublimation - tau_v2g = 21600.0 # graupel deposition -- make it a slow process - sat_adj0 = 0.90 # adjustment factor (0: no, 1: full) during fast_sat_adj - ql_gen = 1.0e-3 # max new cloud water during remapping step if fast_sat_adj = .t. - ql_mlt = 2.0e-3 # max value of cloud water allowed from melted cloud ice - qs_mlt = 1.0e-6 # max cloud water due to snow melt - ql0_max = 2.0e-3 # max cloud water value (auto converted to rain) - t_sub = 184.0 # min temp for sublimation of cloud ice - qi_gen = 1.82e-6 # max cloud ice generation during remapping step - qi_lim = 1.0 # cloud ice limiter to prevent large ice build up - qi0_max = 1.0e-4 # max cloud ice value (by other sources) - rad_snow = True # consider snow in cloud fraciton calculation - rad_rain = True # consider rain in cloud fraction calculation - rad_graupel = True # consider graupel in cloud fraction calculation - tintqs = False # use temperature in the saturation mixing in PDF - dw_ocean = 0.10 # base value for ocean - dw_land = 0.15 # base value for subgrid deviation / variability over land - # cloud scheme 0 - ? - # 1: old fvgfs gfdl) mp implementation - # 2: binary cloud scheme (0 / 1) - icloud_f = 0 - cld_min = 0.05 # !< minimum cloud fraction - tau_l2v = 300.0 # cloud water to water vapor (evaporation) - tau_v2l = 90.0 # water vapor to cloud water (condensation) - c2l_ord = 4 - regional = False - m_split = 0 - convert_ke = False - breed_vortex_inline = False - use_old_omega = True - use_logp = False - rf_fast = False - p_ref = 1e5 # Surface pressure used to construct a horizontally-uniform reference - adiabatic = False - nf_omega = 1 - fv_sg_adj = -1 - n_sponge = 1 - fast_sat_adj = True - qc_crt = 5.0e-8 # Minimum condensate mixing ratio to allow partial cloudiness - c_cracw = 0.8 # Rain accretion efficiency - c_paut = ( - 0.5 # Autoconversion cloud water to rain (use 0.5 to reduce autoconversion) - ) - c_pgacs = 0.01 # Snow to graupel "accretion" eff. (was 0.1 in zetac) - c_psaci = 0.05 # Accretion: cloud ice to snow (was 0.1 in zetac) - ccn_l = 300.0 # CCN over land (cm^-3) - ccn_o = 100.0 # CCN over ocean (cm^-3) - const_vg = False # Fall velocity tuning constant of graupel - const_vi = False # Fall velocity tuning constant of ice - const_vr = False # Fall velocity tuning constant of rain water - const_vs = False # Fall velocity tuning constant of snow - vi_fac = 1.0 # if const_vi: 1/3 - vs_fac = 1.0 # if const_vs: 1. - vg_fac = 1.0 # if const_vg: 2. - vr_fac = 1.0 # if const_vr: 4. - de_ice = False # To prevent excessive build-up of cloud ice from external sources - do_qa = True # Do inline cloud fraction - do_sedi_heat = False # Transport of heat in sedimentation - do_sedi_w = True # Transport of vertical motion in sedimentation - fix_negative = True # Fix negative water species - irain_f = 0 # Cloud water to rain auto conversion scheme - mono_prof = False # Perform terminal fall with mono ppm scheme - mp_time = 225.0 # Maximum microphysics timestep (sec) - prog_ccn = False # Do prognostic ccn (yi ming's method) - qi0_crt = 8e-05 # Cloud ice to snow autoconversion threshold - qs0_crt = 0.003 # Snow to graupel density threshold (0.6e-3 in purdue lin scheme) - rh_inc = 0.2 # RH increment for complete evaporation of cloud water and cloud ice - rh_inr = 0.3 # RH increment for minimum evaporation of rain - rthresh = 1e-05 # Critical cloud drop radius (micrometers) - sedi_transport = True # Transport of momentum in sedimentation - use_ppm = False # Use ppm fall scheme - vg_max = 16.0 # Maximum fall speed for graupel - vi_max = 1.0 # Maximum fall speed for ice - vr_max = 16.0 # Maximum fall speed for rain - vs_max = 2.0 # Maximum fall speed for snow - z_slope_ice = True # Use linear mono slope for autoconversions - z_slope_liq = True # Use linear mono slope for autoconversions - tice = 273.16 # set tice = 165. to turn off ice - phase phys (kessler emulator) - alin = 842.0 # "a" in lin1983 - clin = 4.8 # "c" in lin 1983, 4.8 -- > 6. (to ehance ql -- > qs) - - @classmethod - def as_dict(cls): - return { - name: default - for name, default in cls.__dict__.items() - if not name.startswith("_") - } - - -@dataclasses.dataclass -class Namelist: - # data_set: Any - # date_out_of_range: str - # do_sst_pert: bool - # interp_oi_sst: bool - # no_anom_sst: bool - # sst_pert: float - # sst_pert_type: str - # use_daily: bool - # use_ncep_ice: bool - # use_ncep_sst: bool - # blocksize: int - # chksum_debug: bool - """ - note: dycore_only may not be used in this model - the same way it is in the Fortran version, watch for - consequences of these inconsistencies, or more closely - parallel the Fortran structure - """ - dycore_only: bool = DEFAULT_BOOL - # fdiag: float - # knob_ugwp_azdir: Tuple[int, int, int, int] - # knob_ugwp_doaxyz: int - # knob_ugwp_doheat: int - # knob_ugwp_dokdis: int - # knob_ugwp_effac: Tuple[int, int, int, int] - # knob_ugwp_ndx4lh: int - # knob_ugwp_solver: int - # knob_ugwp_source: Tuple[int, int, int, int] - # knob_ugwp_stoch: Tuple[int, int, int, int] - # knob_ugwp_version: int - # knob_ugwp_wvspec: Tuple[int, int, int, int] - # launch_level: int - # reiflag: int - # reimax: float - # reimin: float - # rewmax: float - # rewmin: float - # atmos_nthreads: int - # calendar: Any - # current_date: Any - days: int = 0 - dt_atmos: int = DEFAULT_INT - # dt_ocean: Any - hours: int = 0 - # memuse_verbose: Any - minutes: int = 0 - # months: Any - # ncores_per_node: Any - seconds: int = 0 - # use_hyper_thread: Any - # max_axes: Any - # max_files: Any - # max_num_axis_sets: Any - # prepend_date: Any - # checker_tr: Any - # filtered_terrain: Any - # gfs_dwinds: Any - # levp: Any - # nt_checker: Any - # checksum_required: Any - # max_files_r: Any - # max_files_w: Any - # clock_grain: Any - # domains_stack_size: Any - # print_memory_usage: Any - a_imp: float = DEFAULT_FLOAT - # adjust_dry_mass: Any - beta: float = DEFAULT_FLOAT - # consv_am: Any - consv_te: float = DEFAULT_FLOAT - d2_bg: float = DEFAULT_FLOAT - d2_bg_k1: float = DEFAULT_FLOAT - d2_bg_k2: float = DEFAULT_FLOAT - d4_bg: float = DEFAULT_FLOAT - d_con: float = DEFAULT_FLOAT - d_ext: float = DEFAULT_FLOAT - dddmp: float = DEFAULT_FLOAT - delt_max: float = DEFAULT_FLOAT - # dnats: int - do_sat_adj: bool = DEFAULT_BOOL - do_vort_damp: bool = DEFAULT_BOOL - # dwind_2d: Any - # external_ic: Any - fill: bool = DEFAULT_BOOL - # fill_dp: bool - # fv_debug: Any - # gfs_phil: Any - hord_dp: int = DEFAULT_INT - hord_mt: int = DEFAULT_INT - hord_tm: int = DEFAULT_INT - hord_tr: int = DEFAULT_INT - hord_vt: int = DEFAULT_INT - hydrostatic: bool = DEFAULT_BOOL - # io_layout: Any - k_split: int = DEFAULT_INT - ke_bg: float = DEFAULT_FLOAT - kord_mt: int = DEFAULT_INT - kord_tm: int = DEFAULT_INT - kord_tr: int = DEFAULT_INT - kord_wz: int = DEFAULT_INT - layout: Tuple[int, int] = (1, 1) - # make_nh: bool - # mountain: bool - n_split: int = DEFAULT_INT - # na_init: Any - # ncep_ic: Any - # nggps_ic: Any - nord: int = DEFAULT_INT - npx: int = DEFAULT_INT - npy: int = DEFAULT_INT - npz: int = DEFAULT_INT - ntiles: int = DEFAULT_INT - # nudge: Any - # nudge_qv: Any - nwat: int = DEFAULT_INT - p_fac: float = DEFAULT_FLOAT - # phys_hydrostatic: Any - # print_freq: Any - # range_warn: Any - # reset_eta: Any - rf_cutoff: float = DEFAULT_FLOAT - tau: float = DEFAULT_FLOAT - # tau_h2o: Any - # use_hydro_pressure: Any - vtdm4: float = DEFAULT_FLOAT - # warm_start: bool - z_tracer: bool = DEFAULT_BOOL - c_cracw: float = NamelistDefaults.c_cracw - c_paut: float = NamelistDefaults.c_paut - c_pgacs: float = NamelistDefaults.c_pgacs - c_psaci: float = NamelistDefaults.c_psaci - ccn_l: float = NamelistDefaults.ccn_l - ccn_o: float = NamelistDefaults.ccn_o - const_vg: bool = NamelistDefaults.const_vg - const_vi: bool = NamelistDefaults.const_vi - const_vr: bool = NamelistDefaults.const_vr - const_vs: bool = NamelistDefaults.const_vs - qc_crt: float = NamelistDefaults.qc_crt - vs_fac: float = NamelistDefaults.vs_fac - vg_fac: float = NamelistDefaults.vg_fac - vi_fac: float = NamelistDefaults.vi_fac - vr_fac: float = NamelistDefaults.vr_fac - de_ice: bool = NamelistDefaults.de_ice - do_qa: bool = NamelistDefaults.do_qa - do_sedi_heat: bool = NamelistDefaults.do_sedi_heat - do_sedi_w: bool = NamelistDefaults.do_sedi_w - fast_sat_adj: bool = NamelistDefaults.fast_sat_adj - fix_negative: bool = NamelistDefaults.fix_negative - irain_f: int = NamelistDefaults.irain_f - mono_prof: bool = NamelistDefaults.mono_prof - mp_time: float = NamelistDefaults.mp_time - prog_ccn: bool = NamelistDefaults.prog_ccn - qi0_crt: float = NamelistDefaults.qi0_crt - qs0_crt: float = NamelistDefaults.qs0_crt - rh_inc: float = NamelistDefaults.rh_inc - rh_inr: float = NamelistDefaults.rh_inr - # rh_ins: Any - rthresh: float = NamelistDefaults.rthresh - sedi_transport: bool = NamelistDefaults.sedi_transport - # use_ccn: Any - use_ppm: bool = NamelistDefaults.use_ppm - vg_max: float = NamelistDefaults.vg_max - vi_max: float = NamelistDefaults.vi_max - vr_max: float = NamelistDefaults.vr_max - vs_max: float = NamelistDefaults.vs_max - z_slope_ice: bool = NamelistDefaults.z_slope_ice - z_slope_liq: bool = NamelistDefaults.z_slope_liq - tice: float = NamelistDefaults.tice - alin: float = NamelistDefaults.alin - clin: float = NamelistDefaults.clin - # c0s_shal: Any - # c1_shal: Any - # cal_pre: Any - # cdmbgwd: Any - # cnvcld: Any - # cnvgwd: Any - # debug: Any - # do_deep: Any - # dspheat: Any - # fhcyc: Any - # fhlwr: Any - # fhswr: Any - # fhzero: Any - # hybedmf: Any - # iaer: Any - # ialb: Any - # ico2: Any - # iems: Any - # imfdeepcnv: Any - # imfshalcnv: Any - # imp_physics: Any - # isol: Any - # isot: Any - # isubc_lw: Any - # isubc_sw: Any - # ivegsrc: Any - # ldiag3d: Any - # lwhtr: Any - # ncld: int - # nst_anl: Any - # pdfcld: Any - # pre_rad: Any - # prslrd0: Any - # random_clds: Any - # redrag: Any - # satmedmf: Any - # shal_cnv: Any - # swhtr: Any - # trans_trac: Any - # use_ufo: Any - # xkzm_h: Any - # xkzm_m: Any - # xkzminv: Any - # interp_method: Any - # lat_s: Any - # lon_s: Any - # ntrunc: Any - # fabsl: Any - # faisl: Any - # faiss: Any - # fnabsc: Any - # fnacna: Any - # fnaisc: Any - # fnalbc: Any - # fnalbc2: Any - # fnglac: Any - # fnmskh: Any - # fnmxic: Any - # fnslpc: Any - # fnsmcc: Any - # fnsnoa: Any - # fnsnoc: Any - # fnsotc: Any - # fntg3c: Any - # fntsfa: Any - # fntsfc: Any - # fnvegc: Any - # fnvetc: Any - # fnvmnc: Any - # fnvmxc: Any - # fnzorc: Any - # fsicl: Any - # fsics: Any - # fslpl: Any - # fsmcl: Any - # fsnol: Any - # fsnos: Any - # fsotl: Any - # ftsfl: Any - # ftsfs: Any - # fvetl: Any - # fvmnl: Any - # fvmxl: Any - # ldebug: Any - grid_type: int = NamelistDefaults.grid_type - dx_const: float = NamelistDefaults.dx_const - dy_const: float = NamelistDefaults.dy_const - deglat: float = NamelistDefaults.deglat - u_max: float = NamelistDefaults.u_max - do_f3d: bool = NamelistDefaults.do_f3d - inline_q: bool = NamelistDefaults.inline_q - do_skeb: bool = NamelistDefaults.do_skeb # save dissipation estimate - use_logp: bool = NamelistDefaults.use_logp - moist_phys: bool = NamelistDefaults.moist_phys - check_negative: bool = NamelistDefaults.check_negative - # gfdl_cloud_microphys.F90 - tau_r2g: float = NamelistDefaults.tau_r2g # rain freezing during fast_sat - tau_smlt: float = NamelistDefaults.tau_smlt # snow melting - tau_g2r: float = NamelistDefaults.tau_g2r # graupel melting to rain - tau_imlt: float = NamelistDefaults.tau_imlt # cloud ice melting - tau_i2s: float = NamelistDefaults.tau_i2s # cloud ice to snow auto - conversion - tau_l2r: float = NamelistDefaults.tau_l2r # cloud water to rain auto - conversion - tau_g2v: float = NamelistDefaults.tau_g2v # graupel sublimation - tau_v2g: float = ( - NamelistDefaults.tau_v2g - ) # graupel deposition -- make it a slow process - sat_adj0: float = ( - NamelistDefaults.sat_adj0 - ) # adjustment factor (0: no 1: full) during fast_sat_adj - ql_gen: float = ( - 1.0e-3 # max new cloud water during remapping step if fast_sat_adj = .t. - ) - ql_mlt: float = ( - NamelistDefaults.ql_mlt - ) # max value of cloud water allowed from melted cloud ice - qs_mlt: float = NamelistDefaults.qs_mlt # max cloud water due to snow melt - ql0_max: float = ( - NamelistDefaults.ql0_max - ) # max cloud water value (auto converted to rain) - t_sub: float = NamelistDefaults.t_sub # min temp for sublimation of cloud ice - qi_gen: float = ( - NamelistDefaults.qi_gen - ) # max cloud ice generation during remapping step - qi_lim: float = ( - NamelistDefaults.qi_lim - ) # cloud ice limiter to prevent large ice build up - qi0_max: float = NamelistDefaults.qi0_max # max cloud ice value (by other sources) - rad_snow: bool = ( - NamelistDefaults.rad_snow - ) # consider snow in cloud fraction calculation - rad_rain: bool = ( - NamelistDefaults.rad_rain - ) # consider rain in cloud fraction calculation - rad_graupel: bool = ( - NamelistDefaults.rad_graupel - ) # consider graupel in cloud fraction calculation - tintqs: bool = ( - NamelistDefaults.tintqs - ) # use temperature in the saturation mixing in PDF - dw_ocean: float = NamelistDefaults.dw_ocean # base value for ocean - dw_land: float = ( - NamelistDefaults.dw_land - ) # base value for subgrid deviation / variability over land - # cloud scheme 0 - ? - # 1: old fvgfs gfdl) mp implementation - # 2: binary cloud scheme (0 / 1) - icloud_f: int = NamelistDefaults.icloud_f - cld_min: float = NamelistDefaults.cld_min # !< minimum cloud fraction - tau_l2v: float = ( - NamelistDefaults.tau_l2v - ) # cloud water to water vapor (evaporation) - tau_v2l: float = ( - NamelistDefaults.tau_v2l - ) # water vapor to cloud water (condensation) - c2l_ord: int = NamelistDefaults.c2l_ord - regional: bool = NamelistDefaults.regional - m_split: int = NamelistDefaults.m_split - convert_ke: bool = NamelistDefaults.convert_ke - breed_vortex_inline: bool = NamelistDefaults.breed_vortex_inline - use_old_omega: bool = NamelistDefaults.use_old_omega - rf_fast: bool = NamelistDefaults.rf_fast - adiabatic: bool = NamelistDefaults.adiabatic - nf_omega: int = NamelistDefaults.nf_omega - fv_sg_adj: int = NamelistDefaults.fv_sg_adj - n_sponge: int = NamelistDefaults.n_sponge - - @classmethod - def from_f90nml(cls, namelist: f90nml.Namelist): - namelist_dict = namelist_to_flatish_dict(namelist.items()) - namelist_dict = { - key: value - for key, value in namelist_dict.items() - if key in cls.__dataclass_fields__ # type: ignore - } - return cls(**namelist_dict) - - -def namelist_to_flatish_dict(nml_input): - nml = dict(nml_input) - for name, value in nml.items(): - if isinstance(value, f90nml.Namelist): - nml[name] = namelist_to_flatish_dict(value) - flatter_namelist = {} - for key, value in nml.items(): - if isinstance(value, dict): - for subkey, subvalue in value.items(): - if subkey in flatter_namelist: - raise ValueError( - "Cannot flatten this namelist, duplicate keys: " + subkey - ) - flatter_namelist[subkey] = subvalue - else: - flatter_namelist[key] = value - return flatter_namelist diff --git a/util/pace/util/nudging.py b/util/pace/util/nudging.py deleted file mode 100644 index 147314b14..000000000 --- a/util/pace/util/nudging.py +++ /dev/null @@ -1,74 +0,0 @@ -from datetime import timedelta -from typing import Mapping - -from .quantity import Quantity - - -def apply_nudging( - state, - reference_state, - nudging_timescales: Mapping[str, timedelta], - timestep: timedelta, -): - """ - Nudge the given state towards the reference state according to the provided - nudging timescales. - - Nudging is applied to the state in-place. - - Args: - state (dict): A state dictionary. - reference_state (dict): A reference state dictionary. - nudging_timescales (dict): A dictionary whose keys are standard names and - values are timedelta objects indicating the relaxation timescale for that - variable. - timestep (timedelta): length of the timestep - - Returns: - nudging_tendencies (dict): A dictionary whose keys are standard names - and values are Quantity objects indicating the nudging tendency - of that standard name. - """ - tendencies = get_nudging_tendencies(state, reference_state, nudging_timescales) - _apply_tendencies(state, tendencies, timestep) - return tendencies - - -def _apply_tendencies(state, tendencies, timestep: timedelta): - """Apply a dictionary of tendencies to a state, in-place. Assumes the tendencies - are in units of per second. - """ - for name, tendency in tendencies.items(): - if name not in state: - raise ValueError(f"no state variable to apply tendency for {name}") - state[name].view[:] += tendency.view[:] * timestep.total_seconds() - - -def get_nudging_tendencies( - state, reference_state, nudging_timescales: Mapping[str, timedelta] -): - """ - Return the nudging tendency of the given state towards the reference state - according to the provided nudging timescales. - - Args: - state (dict): A state dictionary. - reference_state (dict): A reference state dictionary. - nudging_timescales (dict): A dictionary whose keys are standard names and - values are timedelta objects indicating the relaxation timescale for that - variable. - - Returns: - nudging_tendencies (dict): A dictionary whose keys are standard names - and values are Quantity objects indicating the nudging tendency - of that standard name. - """ - return_dict = {} - for name, timescale in nudging_timescales.items(): - quantity = state[name] - reference = reference_state[name] - return_data = (reference.view[:] - quantity.view[:]) / timescale.total_seconds() - return_dict[name] = Quantity( - return_data, dims=quantity.dims, units=quantity.units + " s^-1" - ) - return return_dict diff --git a/util/pace/util/null_comm.py b/util/pace/util/null_comm.py deleted file mode 100644 index c4fd5ebb8..000000000 --- a/util/pace/util/null_comm.py +++ /dev/null @@ -1,95 +0,0 @@ -import copy -from typing import Any, Mapping - -from pace.util.comm import Comm, Request - - -class NullAsyncResult(Request): - def __init__(self, recvbuf=None): - self._recvbuf = recvbuf - - def wait(self): - if self._recvbuf is not None: - self._recvbuf[:] = 0.0 - - -class NullComm(Comm): - """ - A class with a subset of the mpi4py Comm API, but which - 'receives' a fill value (default zero) instead of using MPI. - """ - - def __init__(self, rank, total_ranks, fill_value=0.0): - """ - Args: - rank: rank to mock - total_ranks: number of total MPI ranks to mock - fill_value: fill halos with this value when performing - halo updates. - """ - self.rank = rank - self.total_ranks = total_ranks - self._fill_value = fill_value - self._split_comms: Mapping[Any, NullComm] = {} - - def __repr__(self): - return f"NullComm(rank={self.rank}, total_ranks={self.total_ranks})" - - def Get_rank(self): - return self.rank - - def Get_size(self): - return self.total_ranks - - def bcast(self, value, root=0): - return value - - def barrier(self): - return - - def Barrier(self): - return - - def Scatter(self, sendbuf, recvbuf, root=0, **kwargs): - if recvbuf is not None: - recvbuf[:] = self._fill_value - - def Gather(self, sendbuf, recvbuf, root=0, **kwargs): - if recvbuf is not None: - recvbuf[:] = self._fill_value - - def allgather(self, sendobj): - return [copy.deepcopy(sendobj) for _ in range(self.total_ranks)] - - def Send(self, sendbuf, dest, **kwargs): - pass - - def Isend(self, sendbuf, dest, **kwargs): - return NullAsyncResult() - - def Recv(self, recvbuf, source, **kwargs): - recvbuf[:] = self._fill_value - - def Irecv(self, recvbuf, source, **kwargs): - return NullAsyncResult(recvbuf) - - def sendrecv(self, sendbuf, dest, **kwargs): - return sendbuf - - def Split(self, color, key): - # key argument is ignored, assumes we're calling the ranks from least to - # greatest when mocking Split - self._split_comms[color] = self._split_comms.get(color, []) - rank = len(self._split_comms[color]) - total_ranks = rank + 1 - new_comm = NullComm( - rank=rank, total_ranks=total_ranks, fill_value=self._fill_value - ) - for comm in self._split_comms[color]: - # won't know how many ranks there are until everything is split - comm.total_ranks = total_ranks - self._split_comms[color].append(new_comm) - return new_comm - - def allreduce(self, sendobj, op=None) -> Any: - return self._fill_value diff --git a/util/pace/util/partitioner.py b/util/pace/util/partitioner.py deleted file mode 100644 index 0e59ddfa3..000000000 --- a/util/pace/util/partitioner.py +++ /dev/null @@ -1,1042 +0,0 @@ -import abc -import copy -import functools -from typing import Callable, List, Optional, Sequence, Tuple, TypeVar, Union, cast - -import numpy as np - -from . import boundary as bd -from . import constants, utils -from .constants import ( - EAST, - NORTH, - NORTHEAST, - NORTHWEST, - SOUTH, - SOUTHEAST, - SOUTHWEST, - WEST, -) -from .quantity import Quantity, QuantityMetadata - - -# we're caching slice objects which are pretty small, and the number we -# generate depends on the number of different array shapes/sizes which -# should not be that many -DEFAULT_CACHE_SIZE = None - -__all__ = ["TilePartitioner", "CubedSpherePartitioner", "get_tile_index"] - - -def get_tile_index(rank: int, total_ranks: int) -> int: - """ - Returns the zero-indexed tile number, given a rank and total number of ranks. - """ - if total_ranks % 6 != 0: - raise ValueError(f"total_ranks {total_ranks} is not evenly divisible by 6") - ranks_per_tile = total_ranks // 6 - return rank // ranks_per_tile - - -def get_tile_number(tile_rank: int, total_ranks: int) -> int: - """Deprecated: use get_tile_index. - - Returns the tile number for a given rank and total number of ranks. - """ - FutureWarning( - "get_tile_number will be removed in a later version, " - "use get_tile_index(rank, total_ranks) + 1 instead" - ) - if total_ranks % 6 != 0: - raise ValueError(f"total_ranks {total_ranks} is not evenly divisible by 6") - ranks_per_tile = total_ranks // 6 - return tile_rank // ranks_per_tile + 1 - - -class Partitioner(abc.ABC): - @abc.abstractmethod - def __init__(self): - self.tile = None - self.layout = None - - @abc.abstractmethod - def boundary(self, boundary_type: int, rank: int) -> Optional[bd.SimpleBoundary]: - ... - - @abc.abstractmethod - def tile_index(self, rank: int): - pass - - @abc.abstractmethod - def global_extent(self, rank_metadata: QuantityMetadata) -> Tuple[int, ...]: - """Return the shape of a full tile representation for the given dimensions. - - Args: - metadata: quantity metadata - - Returns: - extent: shape of full tile representation - """ - pass - - @abc.abstractmethod - def subtile_slice( - self, - rank: int, - global_dims: Sequence[str], - global_extent: Sequence[int], - overlap: bool = False, - ) -> Tuple[Union[int, slice], ...]: - """Return the subtile slice of a given rank on an array. - - Global refers to the domain being partitioned. For example, for a partitioning - of a tile, the tile would be the "global" domain. - - Args: - rank: the rank of the process - global_dims: dimensions of the global quantity being partitioned - global_extent: extent of the global quantity being partitioned - overlap (optional): if True, for interface variables include the part - of the array shared by adjacent ranks in both ranks. If False, ensure - only one of those ranks (the greater rank) is assigned the overlapping - section. Default is False. - - Returns: - subtile_slice: the slice of the global compute domain corresponding - to the subtile compute domain - """ - pass - - @abc.abstractmethod - def subtile_extent( - self, - global_metadata: QuantityMetadata, - rank: int, - ) -> Tuple[int, ...]: - """Return the shape of a single rank representation for the given dimensions. - - Args: - global_metadata: quantity metadata. - rank: rank of the process. - - Returns: - extent: shape of a single rank representation for the given dimensions. - """ - pass - - @property - @abc.abstractmethod - def total_ranks(self) -> int: - pass - - -class TilePartitioner(Partitioner): - def __init__( - self, - layout: Tuple[int, int], - edge_interior_ratio: float = 1.0, - ): - """Create an object for fv3gfs tile decomposition.""" - self.layout = layout - self.edge_interior_ratio = edge_interior_ratio - self.tile = self - - def tile_index(self, rank: int): - return 0 - - @classmethod - def from_namelist(cls, namelist): - """Initialize a TilePartitioner from a Fortran namelist. - - Args: - namelist (dict): the Fortran namelist - """ - return cls(layout=namelist["fv_core_nml"]["layout"]) - - def subtile_index(self, rank: int) -> Tuple[int, int]: - """ - Return the (y, x) subtile position of a given rank - as an integer number of subtiles. - """ - return subtile_index(rank, self.total_ranks, self.layout) - - @property - def total_ranks(self) -> int: - return self.layout[0] * self.layout[1] - - def global_extent( - self, rank_metadata: Union[Quantity, QuantityMetadata] - ) -> Tuple[int, ...]: - """Return the shape of a full tile representation for the given dimensions. - - Args: - metadata: quantity metadata - - Returns: - extent: shape of full tile representation - """ - return tile_extent_from_rank_metadata( - rank_metadata.dims, rank_metadata.extent, self.layout - ) - - def subtile_extent( - self, - global_metadata: QuantityMetadata, - rank: int, - ) -> Tuple[int, ...]: - """Return the shape of a single rank representation for the given dimensions. - - Args: - global_metadata: quantity metadata. - rank: rank of the process. - - Returns: - extent: shape of a single rank representation for the given dimensions. - """ - rank_slice = rank_slice_from_tile_metadata( - global_metadata.dims, - extent=global_metadata.extent, - layout=self.layout, - subtile_index=self.subtile_index(rank), - edge_interior_ratio=self.edge_interior_ratio, - overlap=True, - ) - return tuple(item.stop - item.start for item in rank_slice) - - def subtile_slice( - self, - rank: int, - global_dims: Sequence[str], - global_extent: Sequence[int], - overlap: bool = False, - ) -> Tuple[slice, ...]: - """Return the subtile slice of a given rank on an array. - - Global refers to the domain being partitioned. For example, for a partitioning - of a tile, the tile would be the "global" domain. - - Args: - rank: the rank of the process - global_dims: dimensions of the global quantity being partitioned - global_extent: extent of the global quantity being partitioned - overlap (optional): if True, for interface variables include the part - of the array shared by adjacent ranks in both ranks. If False, ensure - only one of those ranks (the greater rank) is assigned the overlapping - section. Default is False. - - Returns: - subtile_slice: the slice of the global compute domain corresponding - to the subtile compute domain - """ - return subtile_slice( - dims=global_dims, - global_extent=global_extent, - layout=self.layout, - subtile_index=self.subtile_index(rank), - edge_interior_ratio=self.edge_interior_ratio, - overlap=overlap, - ) - - def on_tile_top(self, rank: int) -> bool: - return on_tile_top(self.subtile_index(rank), self.layout) - - def on_tile_bottom(self, rank: int) -> bool: - return on_tile_bottom(self.subtile_index(rank)) - - def on_tile_left(self, rank: int) -> bool: - return on_tile_left(self.subtile_index(rank)) - - def on_tile_right(self, rank: int) -> bool: - return on_tile_right(self.subtile_index(rank), self.layout) - - def boundary(self, boundary_type: int, rank: int) -> Optional[bd.SimpleBoundary]: - """Returns a boundary of the requested type for a given rank. - - Target ranks will be on the same tile as the given rank, wrapping around as - in a doubly-periodic boundary condition. - - Args: - boundary_type: the type of boundary - rank: the processor rank - - Returns: - boundary - """ - boundary = copy.copy(self._cached_boundary(boundary_type, rank)) - return boundary - - @functools.lru_cache(maxsize=DEFAULT_CACHE_SIZE) - def _cached_boundary( - self, boundary_type: int, rank: int - ) -> Optional[bd.SimpleBoundary]: - boundary = { - WEST: self._left_edge, - EAST: self._right_edge, - NORTH: self._top_edge, - SOUTH: self._bottom_edge, - NORTHWEST: self._top_left_corner, - NORTHEAST: self._top_right_corner, - SOUTHWEST: self._bottom_left_corner, - SOUTHEAST: self._bottom_right_corner, - }[boundary_type](rank) - return boundary - - def _left_edge(self, rank: int) -> bd.SimpleBoundary: - if self.on_tile_left(rank): - to_rank = rank + self.layout[1] - 1 - else: - to_rank = rank - 1 - return bd.SimpleBoundary( - boundary_type=constants.WEST, - from_rank=rank, - to_rank=to_rank, - n_clockwise_rotations=0, - ) - - def _right_edge(self, rank: int) -> bd.SimpleBoundary: - if self.on_tile_right(rank): - to_rank = rank - self.layout[1] + 1 - else: - to_rank = rank + 1 - return bd.SimpleBoundary( - boundary_type=constants.EAST, - from_rank=rank, - to_rank=to_rank, - n_clockwise_rotations=0, - ) - - def _top_edge(self, rank: int) -> bd.SimpleBoundary: - if self.on_tile_top(rank): - to_rank = rank - (self.layout[0] - 1) * self.layout[1] - else: - to_rank = rank + self.layout[1] - return bd.SimpleBoundary( - boundary_type=constants.NORTH, - from_rank=rank, - to_rank=to_rank, - n_clockwise_rotations=0, - ) - - def _bottom_edge(self, rank: int) -> bd.SimpleBoundary: - if self.on_tile_bottom(rank): - to_rank = rank + (self.layout[0] - 1) * self.layout[1] - else: - to_rank = rank - self.layout[1] - return bd.SimpleBoundary( - boundary_type=constants.SOUTH, - from_rank=rank, - to_rank=to_rank, - n_clockwise_rotations=0, - ) - - def _top_left_corner(self, rank: int) -> Optional[bd.SimpleBoundary]: - return _get_corner(constants.NORTHWEST, rank, self._left_edge, self._top_edge) - - def _top_right_corner(self, rank: int) -> Optional[bd.SimpleBoundary]: - return _get_corner(constants.NORTHEAST, rank, self._right_edge, self._top_edge) - - def _bottom_left_corner(self, rank: int) -> Optional[bd.SimpleBoundary]: - return _get_corner( - constants.SOUTHWEST, rank, self._left_edge, self._bottom_edge - ) - - def _bottom_right_corner(self, rank: int) -> Optional[bd.SimpleBoundary]: - return _get_corner( - constants.SOUTHEAST, rank, self._right_edge, self._bottom_edge - ) - - def fliplr_rank(self, rank: int) -> int: - return fliplr_subtile_rank(rank, self.layout) - - def rotate_rank(self, rank: int, n_clockwise_rotations: int) -> int: - return rotate_subtile_rank(rank, self.layout, n_clockwise_rotations) - - -def _get_corner( - boundary_type: int, - rank: int, - edge_func_1: Callable[[int], bd.Boundary], - edge_func_2: Callable[[int], bd.Boundary], -): - edge_1 = edge_func_1(rank) - edge_2 = edge_func_2(edge_1.to_rank) - rotations = edge_1.n_clockwise_rotations + edge_2.n_clockwise_rotations - return bd.SimpleBoundary( - boundary_type=boundary_type, - from_rank=rank, - to_rank=edge_2.to_rank, - n_clockwise_rotations=rotations, - ) - - -class CubedSpherePartitioner(Partitioner): - def __init__(self, tile: TilePartitioner): - """Create an object for fv3gfs cubed-sphere domain decomposition. - - Args: - tile: partitioner for the cube faces - """ - if not isinstance(tile, TilePartitioner): - raise TypeError("tile must be a TilePartitioner") - self.tile = tile - - @classmethod - def from_namelist(cls, namelist): - """Initialize a CubedSpherePartitioner from a Fortran namelist. - - Args: - namelist (dict): the Fortran namelist - """ - return cls(TilePartitioner.from_namelist(namelist)) - - def _ensure_square_layout(self) -> None: - if not self.tile.layout[0] == self.tile.layout[1]: - raise NotImplementedError("currently only square layouts are supported") - - def tile_index(self, rank: int) -> int: - """Returns the tile index of a given rank""" - return get_tile_index(rank, self.total_ranks) - - def tile_root_rank(self, rank: int) -> int: - """Returns the lowest rank on the same tile as a given rank.""" - return self.tile.total_ranks * (rank // self.tile.total_ranks) - - @property - def layout(self) -> Tuple[int, int]: - return self.tile.layout - - @property - def total_ranks(self) -> int: - """the number of ranks on the cubed sphere""" - return 6 * self.tile.total_ranks - - def boundary(self, boundary_type: int, rank: int) -> Optional[bd.SimpleBoundary]: - """Returns a boundary of the requested type for a given rank, or None. - - On tile corners, the boundary across that corner does not exist. - - Args: - boundary_type: the type of boundary - rank: the processor rank - - Returns: - boundary - """ - boundary = copy.copy(self._cached_boundary(boundary_type, rank)) - return boundary - - @functools.lru_cache(maxsize=DEFAULT_CACHE_SIZE) - def _cached_boundary( - self, boundary_type: int, rank: int - ) -> Optional[bd.SimpleBoundary]: - boundary = { - WEST: self._left_edge, - EAST: self._right_edge, - NORTH: self._top_edge, - SOUTH: self._bottom_edge, - NORTHWEST: self._top_left_corner, - NORTHEAST: self._top_right_corner, - SOUTHWEST: self._bottom_left_corner, - SOUTHEAST: self._bottom_right_corner, - }[boundary_type](rank) - if boundary is not None: - boundary.to_rank = boundary.to_rank % self.total_ranks - return boundary - - def _left_edge(self, rank: int) -> bd.SimpleBoundary: - self._ensure_square_layout() - if self.tile.on_tile_left(rank): - if is_even(self.tile_index(rank)): - to_root_rank = self.tile_root_rank(rank - 2 * self.tile.total_ranks) - tile_rank = rank % self.tile.total_ranks - to_tile_rank = self.tile.fliplr_rank( - self.tile.rotate_rank(tile_rank, 1) - ) - to_rank = to_root_rank + to_tile_rank - rotations = 1 - boundary = bd.SimpleBoundary( - boundary_type=constants.WEST, - from_rank=rank, - to_rank=to_rank, - n_clockwise_rotations=rotations, - ) - else: - boundary = cast(bd.SimpleBoundary, self.tile.boundary(WEST, rank=rank)) - boundary.to_rank -= self.tile.total_ranks - else: - boundary = cast(bd.SimpleBoundary, self.tile.boundary(WEST, rank=rank)) - return boundary - - def _right_edge(self, rank: int) -> bd.SimpleBoundary: - self._ensure_square_layout() - if self.tile.on_tile_right(rank): - if not is_even(self.tile_index(rank)): - to_root_rank = self.tile_root_rank(rank + 2 * self.tile.total_ranks) - tile_rank = rank % self.tile.total_ranks - to_tile_rank = self.tile.fliplr_rank( - self.tile.rotate_rank(tile_rank, 1) - ) - boundary = bd.SimpleBoundary( - boundary_type=constants.EAST, - from_rank=rank, - to_rank=to_root_rank + to_tile_rank, - n_clockwise_rotations=1, - ) - else: - boundary = cast(bd.SimpleBoundary, self.tile.boundary(EAST, rank=rank)) - boundary.to_rank += self.tile.total_ranks - else: - boundary = cast(bd.SimpleBoundary, self.tile.boundary(EAST, rank=rank)) - return boundary - - def _top_edge(self, rank: int) -> bd.SimpleBoundary: - self._ensure_square_layout() - if self.tile.on_tile_top(rank): - if is_even(self.tile_index(rank)): - to_root_rank = (self.tile_index(rank) + 2) * self.tile.total_ranks - tile_rank = rank % self.tile.total_ranks - to_tile_rank = self.tile.fliplr_rank( - self.tile.rotate_rank(tile_rank, 1) - ) - boundary = bd.SimpleBoundary( - boundary_type=constants.NORTH, - from_rank=rank, - to_rank=to_root_rank + to_tile_rank, - n_clockwise_rotations=3, - ) - else: - boundary = cast(bd.SimpleBoundary, self.tile.boundary(NORTH, rank)) - boundary.to_rank += self.tile.total_ranks - else: - boundary = cast(bd.SimpleBoundary, self.tile.boundary(NORTH, rank=rank)) - return boundary - - def _bottom_edge(self, rank: int) -> bd.SimpleBoundary: - self._ensure_square_layout() - if self.tile.on_tile_bottom(rank) and not is_even(self.tile_index(rank)): - to_root_rank = (self.tile_index(rank) - 2) * self.tile.total_ranks - tile_rank = rank % self.tile.total_ranks - to_tile_rank = self.tile.fliplr_rank(self.tile.rotate_rank(tile_rank, 1)) - boundary = bd.SimpleBoundary( - boundary_type=constants.SOUTH, - from_rank=rank, - to_rank=to_root_rank + to_tile_rank, - n_clockwise_rotations=3, - ) - else: - boundary = cast(bd.SimpleBoundary, self.tile.boundary(SOUTH, rank=rank)) - if self.tile.on_tile_bottom(rank): - boundary.to_rank -= self.tile.total_ranks - return boundary - - def _top_left_corner(self, rank: int) -> Optional[bd.SimpleBoundary]: - if self.tile.on_tile_top(rank) and self.tile.on_tile_left(rank): - corner = None - else: - if is_even(self.tile_index(rank)) and on_tile_left( - self.tile.subtile_index(rank) - ): - second_edge = self._left_edge - else: - second_edge = self._top_edge - corner = self._get_corner( - constants.NORTHWEST, rank, self._left_edge, second_edge - ) - return corner - - def _top_right_corner(self, rank: int) -> Optional[bd.SimpleBoundary]: - if on_tile_top(self.tile.subtile_index(rank), self.layout) and on_tile_right( - self.tile.subtile_index(rank), self.layout - ): - corner = None - else: - if is_even(self.tile_index(rank)) and on_tile_top( - self.tile.subtile_index(rank), self.layout - ): - second_edge = self._bottom_edge - else: - second_edge = self._right_edge - corner = self._get_corner( - constants.NORTHEAST, rank, self._top_edge, second_edge - ) - return corner - - def _bottom_left_corner(self, rank: int) -> Optional[bd.SimpleBoundary]: - if on_tile_bottom(self.tile.subtile_index(rank)) and on_tile_left( - self.tile.subtile_index(rank) - ): - corner = None - else: - if not is_even(self.tile_index(rank)) and on_tile_bottom( - self.tile.subtile_index(rank) - ): - second_edge = self._top_edge - else: - second_edge = self._left_edge - corner = self._get_corner( - constants.SOUTHWEST, rank, self._bottom_edge, second_edge - ) - return corner - - def _bottom_right_corner(self, rank: int) -> Optional[bd.SimpleBoundary]: - if on_tile_bottom(self.tile.subtile_index(rank)) and on_tile_right( - self.tile.subtile_index(rank), self.layout - ): - corner = None - else: - if not is_even(self.tile_index(rank)) and on_tile_bottom( - self.tile.subtile_index(rank) - ): - second_edge = self._bottom_edge - else: - second_edge = self._right_edge - corner = self._get_corner( - constants.SOUTHEAST, rank, self._bottom_edge, second_edge - ) - return corner - - def _get_corner( - self, - boundary_type: int, - rank: int, - edge_func_1: Callable[[int], bd.Boundary], - edge_func_2: Callable[[int], bd.Boundary], - ) -> bd.SimpleBoundary: - edge_1 = edge_func_1(rank) - edge_2 = edge_func_2(edge_1.to_rank) - rotations = edge_1.n_clockwise_rotations + edge_2.n_clockwise_rotations - return bd.SimpleBoundary( - boundary_type=boundary_type, - from_rank=rank, - to_rank=edge_2.to_rank, - n_clockwise_rotations=rotations, - ) - - def global_extent(self, rank_metadata: QuantityMetadata) -> Tuple[int, ...]: - """Return the shape of a full cube representation for the given dimensions. - - Args: - metadata: quantity metadata - - Returns: - extent: shape of full cube representation - """ - return (6,) + tile_extent_from_rank_metadata( - rank_metadata.dims, rank_metadata.extent, self.layout - ) - - def subtile_extent( - self, - cube_metadata: QuantityMetadata, - rank: int, - ) -> Tuple[int, ...]: - """Return the shape of a single rank representation for the given dimensions. - - Args: - global_metadata: quantity metadata. - rank: rank of the process. - - Returns: - extent: shape of a single rank representation for the given dimensions. - """ - - return self.tile.subtile_extent(cube_metadata, rank) - - def subtile_slice( - self, - rank: int, - global_dims: Sequence[str], - global_extent: Sequence[int], - overlap: bool = False, - ) -> Tuple[Union[int, slice], ...]: - """Return the subtile slice of a given rank on an array. - - Global refers to the domain being partitioned. For example, for a partitioning - of a tile, the tile would be the "global" domain. - - Args: - rank: the rank of the process - global_dims: dimensions of the global quantity being partitioned - global_extent: extent of the global quantity being partitioned - overlap (optional): if True, for interface variables include the part - of the array shared by adjacent ranks in both ranks. If False, ensure - only one of those ranks (the greater rank) is assigned the overlapping - section. Default is False. - - Returns: - subtile_slice: the tuple slice of the global compute domain corresponding - to the subtile compute domain - """ - if global_dims[0] != constants.TILE_DIM: - raise NotImplementedError( - "currently only supports tile dimension {constants.TILE_DIM} as the " - "first dimension, got dims {cube_metadata.dims}" - ) - i_tile = self.tile_index(rank) - return (i_tile,) + self.tile.subtile_slice( - rank=rank, - global_dims=global_dims[1:], - global_extent=global_extent[1:], - overlap=overlap, - ) - - -def on_tile_left(subtile_index: Tuple[int, int]) -> bool: - return subtile_index[1] == 0 - - -def on_tile_right(subtile_index: Tuple[int, int], layout: Tuple[int, int]) -> bool: - return subtile_index[1] == layout[1] - 1 - - -def on_tile_top(subtile_index: Tuple[int, int], layout: Tuple[int, int]) -> bool: - return subtile_index[0] == layout[0] - 1 - - -def on_tile_bottom(subtile_index: Tuple[int, int]) -> bool: - return subtile_index[0] == 0 - - -def rotate_subtile_rank( - rank: int, layout: Tuple[int, int], n_clockwise_rotations: int -) -> int: - """Returns the rank position where this rank would be if you rotated the - tile n_clockwise_rotations times. - """ - if n_clockwise_rotations == 0: - to_tile_rank = rank - elif n_clockwise_rotations == 1: - total_ranks = layout[0] * layout[1] - rank_array = np.arange(total_ranks).reshape(layout) - rotated_rank_array = np.rot90(rank_array) - to_tile_rank = rank_array[np.where(rotated_rank_array == rank)][0] - else: - raise NotImplementedError() - return to_tile_rank - - -def transpose_subtile_rank(rank, layout): - """Returns the rank position where this rank would be if you transposed - the tile. - """ - return transform_subtile_rank(np.transpose, rank, layout) - - -def fliplr_subtile_rank(rank, layout): - """Returns the rank position where this rank would be if you flipped the - tile along a vertical axis - """ - return transform_subtile_rank(np.fliplr, rank, layout) - - -def flipud_subtile_rank(rank, layout): - """Returns the rank position where this rank would be if you flipped the - tile along a horizontal axis - """ - return transform_subtile_rank(np.flipud, rank, layout) - - -def transform_subtile_rank( - transform_func: Callable[[np.ndarray], np.ndarray], - rank: int, - layout: Tuple[int, int], -): - """Returns the rank position where this rank would be if you performed - a transformation on the tile which strictly moves ranks. - """ - total_ranks = layout[0] * layout[1] - rank_array = np.arange(total_ranks).reshape(layout) - transformed_rank_array = transform_func(rank_array) - return rank_array[np.where(transformed_rank_array == rank)][0] - - -def subtile_index( - rank: int, ranks_per_tile: int, layout: Tuple[int, int] -) -> Tuple[int, int]: - within_tile_rank = rank % ranks_per_tile - j = within_tile_rank // layout[1] - i = within_tile_rank % layout[1] - return j, i - - -def is_even(value: Union[int, float]) -> bool: - return value % 2 == 0 - - -def tile_extent_from_rank_metadata( - dims: Sequence[str], - rank_extent: Sequence[int], - layout: Tuple[int, int], - edge_interior_ratio: float = 1.0, -) -> Tuple[int, ...]: - """ - Returns the extent of a tile given data about a single rank, and the tile - layout. - - Args: - dims: dimension names - rank_extent: the extent of one rank - layout: the (y, x) number of ranks along each tile axis - edge_interior_ratio: target value for the relative 1-dimensional - extent of the compute domains of ranks on tile edges and corners compared - to ranks on the tile interior. In all cases, the closest valid value will - be used, which enables some previously invalid configurations - (e.g. C128 on a 3 by 3 layout will use the closest valid - edge_interior_ratio to 1.0). - - Returns: - tile_extent: the extent of one tile - """ - if edge_interior_ratio != 1.0: - raise NotImplementedError( - "Only equal sized subdomains are supported, was given " - f"an edge_interior_ratio of {edge_interior_ratio}" - ) - layout_factors = np.asarray( - utils.list_by_dims(dims, layout, non_horizontal_value=1) - ) - return extent_from_metadata(dims, rank_extent, layout_factors) - - -def rank_slice_from_tile_metadata( - dims: Sequence[str], - *, - extent: Sequence[int], - layout: Tuple[int, int], - subtile_index: Tuple[int, int], - edge_interior_ratio: float, - overlap: bool, -) -> Tuple[slice, ...]: - return _rank_slice_from_tile_metadata_cached( - dims=tuple(dims), - extent=tuple(extent), - layout=tuple(layout), - subtile_index=tuple(subtile_index), - edge_interior_ratio=edge_interior_ratio, - overlap=overlap, - ) - - -@functools.lru_cache(maxsize=DEFAULT_CACHE_SIZE) -def _rank_slice_from_tile_metadata_cached( - dims: Tuple[str, ...], - *, - extent: Tuple[int, ...], - layout: Tuple[int, int], - subtile_index: Tuple[int, int], - edge_interior_ratio: float, - overlap: bool, -) -> Tuple[slice, ...]: - # detect if one of the given dims is the tile dimension and ignore it - cartesian_dims = discard_dimension(dims, constants.TILE_DIM, data=dims) - cartesian_extent = discard_dimension(dims, constants.TILE_DIM, data=extent) - - interior_extents, edge_extents = _subtile_extents_from_tile_metadata( - cartesian_dims, cartesian_extent, layout, edge_interior_ratio - ) - return_slice = [] - - for dim, dim_interior_extent, dim_edge_extent in zip( - cartesian_dims, interior_extents, edge_extents - ): - if dim in constants.HORIZONTAL_DIMS: - if dim in constants.Y_DIMS: - index = subtile_index[0] - n_ranks = layout[0] - else: - index = subtile_index[1] - n_ranks = layout[1] - start, end = 0, 0 - for i in range(index + 1): - if i == 0: - end += dim_edge_extent - elif i == n_ranks - 1: - start = end - end += dim_edge_extent - else: - start = end - end += dim_interior_extent - if dim in constants.INTERFACE_DIMS and (overlap or (index == n_ranks - 1)): - end += 1 - else: - start, end = 0, dim_interior_extent - if dim in constants.INTERFACE_DIMS: - end += 1 - return_slice.append(slice(start, end)) - return tuple(return_slice) - - -T = TypeVar("T") - - -def discard_dimension(dims, dim_name: str, data: Sequence[T]) -> List[T]: - return [item for (item, dim) in zip(data, dims) if dim != dim_name] - - -def _subtile_extents_from_tile_metadata( - dims: Sequence[str], - tile_extent: Sequence[int], - layout: Tuple[int, int], - edge_interior_ratio: float = 1.0, -) -> Tuple[Tuple[int, ...], Tuple[int, ...]]: - """ - Returns the extent of a given rank given data about a tile, and the tile - layout. - - Args: - dims: dimension names - tile_extent: the extent of a tile - layout: the (y, x) number of ranks along each tile axis - edge_interior_ratio: target value for the relative 1-dimensional - extent of the compute domains of ranks on tile edges and corners compared - to ranks on the tile interior. In all cases, the closest valid value will - be used, which enables some previously invalid configurations - (e.g. C128 on a 3 by 3 layout will use the closest valid - edge_interior_ratio to 1.0). - - Returns: - subtile_extents: the extents of first all interior tiles, - then all edge tiles along all dimensions. - """ - - def _valid_edge_tile_sizes( - dim_extent: int, subtile_count: int, start: int - ) -> Sequence[int]: - """ - Returns a list of valid edge tile sizes, counting down from the - starting edge size to the smallest possible one - that lets the interior tile sizes still be an integer. - After that, it counts up from the starting edge size. - """ - bottom = 1 - top = int((dim_extent - subtile_count + 2) / 2) + 1 - unsorted_valid_sizes = range(bottom, top) - valid_sizes = [] - - index = start - offset = 0 - factor = -1 - - # steps through all valid sizes to sort them: - # [start, counting down to 1, counting up from start] - for i in range(len(unsorted_valid_sizes) + 1): - index = start + factor * offset - if index in unsorted_valid_sizes and index not in valid_sizes: - valid_sizes.append(index) - offset = offset + 1 - if index == 1: - offset = 0 - factor = 1 - return valid_sizes - - layout_factors = np.asarray( - utils.list_by_dims(dims, layout, non_horizontal_value=1) - ) - - return_extents = [] - edge_extents = [] - # for each dimension, find a valid edge:interior decomposition - # that has a ratio close to the desired edge_interior_ratio - for dim, subtile_count, dim_extent in zip(dims, layout_factors, tile_extent): - dim_edge_interior_ratio = edge_interior_ratio - if dim in constants.INTERFACE_DIMS: - dim_extent = dim_extent - 1 - if (not subtile_count % 2) and dim_extent % 2: - raise ValueError( - f"Cannot find valid decomposition for odd ({dim_extent}) " - f"gridpoints along an even count ({subtile_count}) of ranks." - ) - - # only do shrinked edges in x,y and if there is interior - if subtile_count >= 3 and dim in constants.HORIZONTAL_DIMS: - # starting edge subtile size, rounded to an integer - edge_subtile_size = round( - dim_extent / (2 + (subtile_count - 2) / dim_edge_interior_ratio) - ) - - # searching of a valid integer pair for edge and interior tile sizes - # that add up to the entire dimension extent. - found = False - for edge_size in _valid_edge_tile_sizes( - dim_extent, subtile_count, edge_subtile_size - ): - dim_edge_interior_ratio = edge_size / ( - (dim_extent - 2 * edge_size) / (subtile_count - 2) - ) - # validation that the integer pair - # (edge_subtile_size, int(edge_size / dim_edge_interior_ratio)) - # multiplied by their respective subtile counts together - # add up to the entire dimension's extent - if ( - edge_size * 2 - + (subtile_count - 2) * int(edge_size / dim_edge_interior_ratio) - == dim_extent - ): - found = True - break - if not found: - raise ValueError( - f"No valid subdomain assignment found for dimension {dim} " - f"with {dim_extent} gridpoints along {subtile_count} ranks." - ) - return_extents.append(int(edge_size / dim_edge_interior_ratio)) - edge_extents.append(int(edge_size)) - else: - # trivial case of no special handling - subtile_size = int(dim_extent / subtile_count) - return_extents.append(subtile_size) - edge_extents.append(subtile_size) - - return tuple(return_extents), tuple(edge_extents) - - -def extent_from_metadata( - dims: Sequence[str], extent: Sequence[int], layout_factors: np.ndarray -) -> Tuple[int, ...]: - return_extents = [] - for dim, rank_extent, layout_factor in zip(dims, extent, layout_factors): - if dim in constants.INTERFACE_DIMS: - add_extent = -1 - else: - add_extent = 0 - tile_extent = (rank_extent + add_extent) * layout_factor - add_extent - return_extents.append(int(tile_extent)) # layout_factor is float, need to cast - return tuple(return_extents) - - -def subtile_slice( - dims: Sequence[str], - global_extent: Sequence[int], - layout: Tuple[int, int], - subtile_index: Tuple[int, int], - edge_interior_ratio: float = 1.0, - overlap: bool = False, -) -> Tuple[slice, ...]: - """ - Returns the slice of data within a tile's computational domain belonging - to a single rank. - - Args: - dims: dimension names for each axis - global_extent: size of the tile or cube's computational domain - layout: the (y, x) number of ranks along each tile axis - subtile_index: the (y, x) position of the rank on the tile - edge_interior_ratio: target value for the relative 1-dimensional - extent of the compute domains of ranks on tile edges and corners compared - to ranks on the tile interior. In all cases, the closest valid value will - be used, which enables some previously invalid configurations - (e.g. C128 on a 3 by 3 layout will use the closest valid - edge_interior_ratio to 1.0). - overlap (optional): if True, for interface variables include the part - of the array shared by adjacent ranks in both ranks. If False, ensure - only one of those ranks (the greater rank) is assigned the overlapping - section. Default is False. - """ - return rank_slice_from_tile_metadata( - dims=dims, - extent=global_extent, - layout=layout, - subtile_index=subtile_index, - edge_interior_ratio=edge_interior_ratio, - overlap=overlap, - ) diff --git a/util/pace/util/quantity.py b/util/pace/util/quantity.py deleted file mode 100644 index 313e5e740..000000000 --- a/util/pace/util/quantity.py +++ /dev/null @@ -1,644 +0,0 @@ -import dataclasses -import warnings -from typing import Any, Dict, Iterable, Optional, Sequence, Tuple, Union, cast - -import numpy as np - -from . import _xarray, constants -from ._boundary_utils import bound_default_slice, shift_boundary_slice_tuple -from ._optional_imports import cupy, dace, gt4py -from .types import NumpyModule - - -if cupy is None: - import numpy as cupy - -__all__ = ["Quantity", "QuantityMetadata"] - - -@dataclasses.dataclass -class QuantityMetadata: - origin: Tuple[int, ...] - "the start of the computational domain" - extent: Tuple[int, ...] - "the shape of the computational domain" - dims: Tuple[str, ...] - "names of each dimension" - units: str - "units of the quantity" - data_type: type - "ndarray-like type used to store the data" - dtype: type - "dtype of the data in the ndarray-like object" - gt4py_backend: Union[str, None] = None - "backend to use for gt4py storages" - - @property - def dim_lengths(self) -> Dict[str, int]: - """mapping of dimension names to their lengths""" - return dict(zip(self.dims, self.extent)) - - @property - def np(self) -> NumpyModule: - """numpy-like module used to interact with the data""" - if issubclass(self.data_type, cupy.ndarray): - return cupy - elif issubclass(self.data_type, np.ndarray): - return np - else: - raise TypeError( - f"quantity underlying data is of unexpected type {self.data_type}" - ) - - -@dataclasses.dataclass -class QuantityHaloSpec: - """Describe the memory to be exchanged, including size of the halo.""" - - n_points: int - strides: Tuple[int] - itemsize: int - shape: Tuple[int] - origin: Tuple[int, ...] - extent: Tuple[int, ...] - dims: Tuple[str, ...] - numpy_module: NumpyModule - dtype: Any - - -class BoundaryArrayView: - def __init__(self, data, boundary_type, dims, origin, extent): - self._data = data - self._boundary_type = boundary_type - self._dims = dims - self._origin = origin - self._extent = extent - - def __getitem__(self, index): - if len(self._origin) == 0: - if isinstance(index, tuple) and len(index) > 0: - raise IndexError("more than one index given for a zero-dimension array") - elif isinstance(index, slice) and index != slice(None, None, None): - raise IndexError("cannot slice a zero-dimension array") - else: - return self._data # array[()] does not return an ndarray - else: - return self._data[self._get_array_index(index)] - - def __setitem__(self, index, value): - self._data[self._get_array_index(index)] = value - - def _get_array_index(self, index): - if isinstance(index, list): - index = tuple(index) - if not isinstance(index, tuple): - index = (index,) - if len(index) > len(self._dims): - raise IndexError( - f"{len(index)} is too many indices for a " - f"{len(self._dims)}-dimensional quantity" - ) - if len(index) < len(self._dims): - index = index + (slice(None, None),) * (len(self._dims) - len(index)) - return shift_boundary_slice_tuple( - self._dims, self._origin, self._extent, self._boundary_type, index - ) - - def sel(self, **kwargs: Union[slice, int]) -> np.ndarray: - """Convenience method to perform indexing using dimension names - without knowing dimension order. - - Args: - **kwargs: slice/index to retrieve for a given dimension name - - Returns: - view_selection: an ndarray-like selection of the given indices - on `self.view` - """ - return self[tuple(kwargs.get(dim, slice(None, None)) for dim in self._dims)] - - -class BoundedArrayView: - """ - A container of objects which provide indexing relative to corners and edges - of the computational domain for convenience. - - Default start and end indices for all dimensions are modified to be the - start and end of the compute domain. When using edge and corner attributes, it is - recommended to explicitly write start and end offsets to avoid confusion. - - Indexing on the object itself (view[:]) is offset by the origin, and default - start and end indices are modified to be the start and end of the compute domain. - - For corner attributes e.g. `northwest`, modified indexing is done for the two - axes according to the edges which make up the corner. In other words, indexing - is offset relative to the intersection of the two edges which make the corner. - - For `interior`, start indices of the horizontal dimensions are relative to the - origin, and end indices are relative to the origin + extent. For example, - view.interior[0:0, 0:0, :] would retrieve the entire compute domain for an x/y/z - array, while view.interior[-1:1, -1:1, :] would also include one halo point. - """ - - def __init__( - self, array, dims: Sequence[str], origin: Sequence[int], extent: Sequence[int] - ): - self._data = array - self._dims = tuple(dims) - self._origin = tuple(origin) - self._extent = tuple(extent) - self._northwest = BoundaryArrayView( - array, constants.NORTHWEST, dims, origin, extent - ) - self._northeast = BoundaryArrayView( - array, constants.NORTHEAST, dims, origin, extent - ) - self._southwest = BoundaryArrayView( - array, constants.SOUTHWEST, dims, origin, extent - ) - self._southeast = BoundaryArrayView( - array, constants.SOUTHEAST, dims, origin, extent - ) - self._interior = BoundaryArrayView( - array, constants.INTERIOR, dims, origin, extent - ) - - @property - def origin(self) -> Tuple[int, ...]: - """the start of the computational domain""" - return self._origin - - @property - def extent(self) -> Tuple[int, ...]: - """the shape of the computational domain""" - return self._extent - - def __getitem__(self, index): - if len(self.origin) == 0: - if isinstance(index, tuple) and len(index) > 0: - raise IndexError("more than one index given for a zero-dimension array") - elif isinstance(index, slice) and index != slice(None, None, None): - raise IndexError("cannot slice a zero-dimension array") - else: - return self._data # array[()] does not return an ndarray - else: - return self._data[self._get_compute_index(index)] - - def __setitem__(self, index, value): - self._data[self._get_compute_index(index)] = value - - def _get_compute_index(self, index): - if not isinstance(index, (tuple, list)): - index = (index,) - if len(index) > len(self._dims): - raise IndexError( - f"{len(index)} is too many indices for a " - f"{len(self._dims)}-dimensional quantity" - ) - index = fill_index(index, len(self._data.shape)) - shifted_index = [] - for entry, origin, extent in zip(index, self.origin, self.extent): - if isinstance(entry, slice): - shifted_slice = shift_slice(entry, origin, extent) - shifted_index.append( - bound_default_slice(shifted_slice, origin, origin + extent) - ) - elif entry is None: - shifted_index.append(entry) - else: - shifted_index.append(entry + origin) - return tuple(shifted_index) - - @property - def northwest(self) -> BoundaryArrayView: - return self._northwest - - @property - def northeast(self) -> BoundaryArrayView: - return self._northeast - - @property - def southwest(self) -> BoundaryArrayView: - return self._southwest - - @property - def southeast(self) -> BoundaryArrayView: - return self._southeast - - @property - def interior(self) -> BoundaryArrayView: - return self._interior - - -def ensure_int_tuple(arg, arg_name): - return_list = [] - for item in arg: - try: - return_list.append(int(item)) - except ValueError: - raise TypeError( - f"tuple arg {arg_name}={arg} contains item {item} of " - f"unexpected type {type(item)}" - ) - return tuple(return_list) - - -def _validate_quantity_property_lengths(shape, dims, origin, extent): - n_dims = len(shape) - for var, desc in ( - (dims, "dimension names"), - (origin, "origins"), - (extent, "extents"), - ): - if len(var) != n_dims: - raise ValueError( - f"received {len(var)} {desc} for {n_dims} dimensions: {var}" - ) - - -def _is_float(dtype): - """Expected floating point type for Pace""" - return ( - dtype == float - or dtype == np.float32 - or dtype == np.float64 - or dtype == np.float16 - ) - - -class Quantity: - """ - Data container for physical quantities. - """ - - def __init__( - self, - data, - dims: Sequence[str], - units: str, - origin: Optional[Sequence[int]] = None, - extent: Optional[Sequence[int]] = None, - gt4py_backend: Union[str, None] = None, - allow_mismatch_float_precision: bool = False, - ): - """ - Initialize a Quantity. - - Args: - data: ndarray-like object containing the underlying data - dims: dimension names for each axis - units: units of the quantity - origin: first point in data within the computational domain - extent: number of points along each axis within the computational domain - gt4py_backend: backend to use for gt4py storages, if not given this will - be derived from a Storage if given as the data argument, otherwise the - storage attribute is disabled and will raise an exception. Will raise - a TypeError if this is given with a gt4py storage type as data - """ - # ToDo: [Florian 01/23] Kill the abomination. - # See https://github.com/NOAA-GFDL/pace/issues/3 - from pace.dsl.typing import Float - - if ( - not allow_mismatch_float_precision - and _is_float(data.dtype) - and data.dtype != Float - ): - raise ValueError( - f"Floating-point data type mismatch, asked for {data.dtype}, " - f"Pace configured for {Float}" - ) - if origin is None: - origin = (0,) * len(dims) # default origin at origin of array - else: - origin = tuple(origin) - - if extent is None: - extent = tuple(length - start for length, start in zip(data.shape, origin)) - else: - extent = tuple(extent) - - if isinstance(data, (int, float, list)): - # If converting basic data, use a numpy ndarray. - data = np.asarray(data) - - if not isinstance(data, (np.ndarray, cupy.ndarray)): - raise TypeError( - f"Only supports numpy.ndarray and cupy.ndarray, got {type(data)}" - ) - - if gt4py_backend is not None: - gt4py_backend_cls = gt4py.cartesian.backend.from_name(gt4py_backend) - assert gt4py_backend_cls is not None - is_optimal_layout = gt4py_backend_cls.storage_info["is_optimal_layout"] - - dimensions: Tuple[Union[str, int], ...] = tuple( - [ - axis - if any(dim in axis_dims for axis_dims in constants.SPATIAL_DIMS) - else str(data.shape[index]) - for index, (dim, axis) in enumerate( - zip(dims, ("I", "J", "K", *([None] * (len(dims) - 3)))) - ) - ] - ) - - self._data = ( - data - if is_optimal_layout(data, dimensions) - else self._initialize_data( - data, - origin=origin, - gt4py_backend=gt4py_backend, - dimensions=dimensions, - ) - ) - else: - if data is None: - raise TypeError("requires 'data' to be passed") - # We have no info about the gt4py_backend, so just assign it. - self._data = data - - _validate_quantity_property_lengths(data.shape, dims, origin, extent) - self._metadata = QuantityMetadata( - origin=ensure_int_tuple(origin, "origin"), - extent=ensure_int_tuple(extent, "extent"), - dims=tuple(dims), - units=units, - data_type=type(self._data), - dtype=data.dtype, - gt4py_backend=gt4py_backend, - ) - self._attrs = {} # type: ignore[var-annotated] - self._compute_domain_view = BoundedArrayView( - self.data, self.dims, self.origin, self.extent - ) - - @classmethod - def from_data_array( - cls, - data_array: _xarray.DataArray, - origin: Sequence[int] = None, - extent: Sequence[int] = None, - gt4py_backend: Union[str, None] = None, - ) -> "Quantity": - """ - Initialize a Quantity from an xarray.DataArray. - - Args: - data_array - origin: first point in data within the computational domain - extent: number of points along each axis within the computational domain - gt4py_backend: backend to use for gt4py storages, if not given this will - be derived from a Storage if given as the data argument, otherwise the - storage attribute is disabled and will raise an exception - """ - if "units" not in data_array.attrs: - raise ValueError("need units attribute to create Quantity from DataArray") - return cls( - data_array.values, - cast(Tuple[str], data_array.dims), - data_array.attrs["units"], - origin=origin, - extent=extent, - gt4py_backend=gt4py_backend, - ) - - def halo_spec(self, n_halo: int) -> QuantityHaloSpec: - return QuantityHaloSpec( - n_halo, - self.data.strides, - self.data.itemsize, - self.data.shape, - self.metadata.origin, - self.metadata.extent, - self.metadata.dims, - self.np, - self.metadata.dtype, - ) - - def __repr__(self): - return ( - f"Quantity(\n data=\n{self.data},\n dims={self.dims},\n" - f" units={self.units},\n origin={self.origin},\n" - f" extent={self.extent}\n)" - ) - - def sel(self, **kwargs: Union[slice, int]) -> np.ndarray: - """Convenience method to perform indexing on `view` using dimension names - without knowing dimension order. - - Args: - **kwargs: slice/index to retrieve for a given dimension name - - Returns: - view_selection: an ndarray-like selection of the given indices - on `self.view` - """ - return self.view[tuple(kwargs.get(dim, slice(None, None)) for dim in self.dims)] - - def _initialize_data(self, data, origin, gt4py_backend: str, dimensions: Tuple): - """Allocates an ndarray with optimal memory layout, and copies the data over.""" - storage = gt4py.storage.from_array( - data, - data.dtype, - backend=gt4py_backend, - aligned_index=origin, - dimensions=dimensions, - ) - return storage - - @property - def metadata(self) -> QuantityMetadata: - return self._metadata - - @property - def units(self) -> str: - """units of the quantity""" - return self.metadata.units - - @property - def gt4py_backend(self) -> Union[str, None]: - return self.metadata.gt4py_backend - - @property - def attrs(self) -> dict: - return dict(**self._attrs, units=self._metadata.units) - - @property - def dims(self) -> Tuple[str, ...]: - """names of each dimension""" - return self.metadata.dims - - @property - def values(self) -> np.ndarray: - warnings.warn( - "values exists only for backwards-compatibility with " - "DataArray and will be removed, use .view[:] instead", - DeprecationWarning, - ) - return_array = np.asarray(self.view[:]) - return_array.flags.writeable = False - return return_array - - @property - def view(self) -> BoundedArrayView: - """a view into the computational domain of the underlying data""" - return self._compute_domain_view - - @property - def data(self) -> Union[np.ndarray, cupy.ndarray]: - """the underlying array of data""" - return self._data - - @property - def origin(self) -> Tuple[int, ...]: - """the start of the computational domain""" - return self.metadata.origin - - @property - def extent(self) -> Tuple[int, ...]: - """the shape of the computational domain""" - return self.metadata.extent - - @property - def data_array(self) -> _xarray.DataArray: - return _xarray.DataArray(self.view[:], dims=self.dims, attrs=self.attrs) - - @property - def np(self) -> NumpyModule: - return self.metadata.np - - @property - def __array_interface__(self): - return self.data.__array_interface__ - - @property - def __cuda_array_interface__(self): - return self.data.__cuda_array_interface__ - - @property - def shape(self): - return self.data.shape - - def __descriptor__(self) -> Any: - """The descriptor is a property that dace uses. - This relies on `dace` capacity to read out data from the buffer protocol. - If the internal data given doesn't follow the protocol it will most likely - fail. - """ - if dace: - return dace.data.create_datadescriptor(self.data) - else: - raise ImportError( - "Attempt to use DaCe orchestrated backend but " - "DaCe module is not available." - ) - - def transpose( - self, - target_dims: Sequence[Union[str, Iterable[str]]], - allow_mismatch_float_precision: bool = False, - ) -> "Quantity": - """Change the dimension order of this Quantity. - - Args: - target_dims: a list of output dimensions. Instead of a single dimension - name, an iterable of dimensions can be used instead for any entries. - For example, you may want to use pace.util.X_DIMS to place an - x-dimension without knowing whether it is on cell centers or interfaces. - - Returns: - transposed: Quantity with the requested output dimension order - - Raises: - ValueError: if any of the target dimensions do not exist on this Quantity, - or if this Quantity contains multiple values from an iterable entry - - Examples: - Let's say we have a cell-centered variable: - - >>> import pace.util - >>> import numpy as np - >>> quantity = pace.util.Quantity( - ... data=np.zeros([2, 3, 4]), - ... dims=[pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM], - ... units="m", - ... ) - - If you know you are working with cell-centered variables, you can do: - - >>> from pace.util import X_DIM, Y_DIM, Z_DIM - >>> transposed_quantity = quantity.transpose([X_DIM, Y_DIM, Z_DIM]) - - To support re-ordering without checking whether quantities are on - cell centers or interfaces, the API supports giving a list of dimension - names for dimensions. For example, to re-order to X-Y-Z dimensions - regardless of the grid the variable is on, one could do: - - >>> from pace.util import X_DIMS, Y_DIMS, Z_DIMS - >>> transposed_quantity = quantity.transpose([X_DIMS, Y_DIMS, Z_DIMS]) - """ - target_dims = _collapse_dims(target_dims, self.dims) - transpose_order = [self.dims.index(dim) for dim in target_dims] - transposed = Quantity( - self.np.transpose(self.data, transpose_order), # type: ignore[attr-defined] - dims=transpose_sequence(self.dims, transpose_order), - units=self.units, - origin=transpose_sequence(self.origin, transpose_order), - extent=transpose_sequence(self.extent, transpose_order), - gt4py_backend=self.gt4py_backend, - allow_mismatch_float_precision=allow_mismatch_float_precision, - ) - transposed._attrs = self._attrs - return transposed - - -def transpose_sequence(sequence, order): - return sequence.__class__(sequence[i] for i in order) - - -def _collapse_dims(target_dims, dims): - return_list = [] - for target in target_dims: - if isinstance(target, str): - if target in dims: - return_list.append(target) - else: - raise ValueError( - f"requested dimension {target} is not defined in " - f"quantity dimensions {dims}" - ) - elif isinstance(target, Iterable): - matches = [d for d in target if d in dims] - if len(matches) > 1: - raise ValueError( - f"multiple matches for {target} found in quantity dimensions {dims}" - ) - elif len(matches) == 0: - raise ValueError( - f"no matches for {target} found in quantity dimensions {dims}" - ) - else: - return_list.append(matches[0]) - return return_list - - -def fill_index(index, length): - return tuple(index) + (slice(None, None, None),) * (length - len(index)) - - -def shift_slice(slice_in, shift, extent): - start = shift_index(slice_in.start, shift, extent) - stop = shift_index(slice_in.stop, shift, extent) - return slice(start, stop, slice_in.step) - - -def shift_index(current_value, shift, extent): - if current_value is None: - new_value = None - else: - new_value = current_value + shift - if new_value < 0: - new_value = extent + new_value - return new_value diff --git a/util/pace/util/restart_properties.yml b/util/pace/util/restart_properties.yml deleted file mode 100644 index f19c2ce41..000000000 --- a/util/pace/util/restart_properties.yml +++ /dev/null @@ -1,568 +0,0 @@ -accumulated_x_courant_number: - dims: - - z - - y - - x - restart_name: cx - units: '' -accumulated_x_mass_flux: - dims: - - z - - y - - x_interface - restart_name: mfx - units: unknown -accumulated_y_courant_number: - dims: - - z - - y - - x - restart_name: cy - units: unknown -accumulated_y_mass_flux: - dims: - - z - - y_interface - - x - restart_name: mfy - units: unknown -air_temperature: - dims: - - z - - y - - x - restart_name: T - units: degK -air_temperature_after_physics: - dims: - - z - - y - - x - restart_name: gt0 - units: K -air_temperature_at_2m: - dims: - - y - - x - restart_name: t2m - units: degK -area_of_grid_cell: - dims: - - y - - x - restart_name: area - units: m^2 -atmosphere_hybrid_a_coordinate: - dims: - - z_interface - restart_name: ak - units: Pa -atmosphere_hybrid_b_coordinate: - dims: - - z_interface - restart_name: bk - units: '' -canopy_water: - dims: - - y - - x - restart_name: canopy - units: unknown -clear_sky_downward_longwave_flux_at_surface: - dims: - - y - - x - fortran_subname: dnfx0 - restart_name: sfcflw - units: W/m^2 -clear_sky_downward_shortwave_flux_at_surface: - dims: - - y - - x - fortran_subname: dnfx0 - restart_name: sfcfsw - units: W/m^2 -clear_sky_upward_longwave_flux_at_surface: - dims: - - y - - x - fortran_subname: upfx0 - restart_name: sfcflw - units: W/m^2 -clear_sky_upward_longwave_flux_at_top_of_atmosphere: - dims: - - y - - x - fortran_subname: upfx0 - restart_name: topflw - units: W/m^2 -clear_sky_upward_shortwave_flux_at_surface: - dims: - - y - - x - fortran_subname: upfx0 - restart_name: sfcfsw - units: W/m^2 -clear_sky_upward_shortwave_flux_at_top_of_atmosphere: - dims: - - y - - x - fortran_subname: upfx0 - restart_name: topfsw - units: W/m^2 -convective_cloud_bottom_pressure: - dims: - - y - - x - restart_name: cvb - units: Pa -convective_cloud_fraction: - dims: - - y - - x - restart_name: cv - units: '' -convective_cloud_top_pressure: - dims: - - y - - x - restart_name: cvt - units: Pa -deep_soil_temperature: - dims: - - y - - x - restart_name: tg3 - units: degK -dissipation_estimate_from_heat_source: - dims: - - z - - y - - x - restart_name: diss_est - units: unknown -eastward_wind: - dims: - - z - - y - - x - restart_name: ua - units: m/s -eastward_wind_after_physics: - dims: - - z - - y - - x - restart_name: gu0 - units: m/s -eastward_wind_at_surface: - dims: - - y - - x - restart_name: u_srf - units: m/s -fh_parameter: - description: used in PBL scheme - dims: - - y - - x - restart_name: ffhh - units: unknown -fm_at_10m: - description: Ratio of sigma level 1 wind and 10m wind - dims: - - y - - x - restart_name: f10m - units: unknown -fm_parameter: - description: used in PBL scheme - dims: - - y - - x - restart_name: ffmm - units: unknown -fractional_coverage_with_strong_cosz_dependency: - dims: - - y - - x - restart_name: facsf - units: '' -fractional_coverage_with_weak_cosz_dependency: - dims: - - y - - x - restart_name: facwf - units: '' -friction_velocity: - dims: - - y - - x - restart_name: uustar - units: m/s -ice_fraction_over_open_water: - dims: - - y - - x - restart_name: fice - units: '' -interface_pressure: - dims: - - y - - z_interface - - x - restart_name: pe - units: Pa -interface_pressure_raised_to_power_of_kappa: - dims: - - z_interface - - y - - x - restart_name: pk - units: unknown -land_sea_mask: - description: sea=0, land=1, sea-ice=2 - dims: - - y - - x - restart_name: slmsk - units: '' -latent_heat_flux: - dims: - - y - - x - restart_name: dqsfci - units: W/m^2 -latitude: - dims: - - y - - x - restart_name: xlat - units: radians -layer_mean_pressure_raised_to_power_of_kappa: - dims: - - z - - y - - x - restart_name: pkz - units: unknown -liquid_soil_moisture: - dims: - - z_soil - - y - - x - restart_name: slc - units: unknown -logarithm_of_interface_pressure: - dims: - - y - - z_interface - - x - restart_name: peln - units: ln(Pa) -longitude: - dims: - - y - - x - restart_name: xlon - units: radians -maximum_fractional_coverage_of_green_vegetation: - dims: - - y - - x - restart_name: shdmax - units: '' -maximum_snow_albedo_in_fraction: - dims: - - y - - x - restart_name: snoalb - units: '' -mean_cos_zenith_angle: - dims: - - y - - x - restart_name: coszen - units: '' -mean_near_infrared_albedo_with_strong_cosz_dependency: - dims: - - y - - x - restart_name: alnsf - units: '' -mean_near_infrared_albedo_with_weak_cosz_dependency: - dims: - - y - - x - restart_name: alnwf - units: '' -mean_visible_albedo_with_strong_cosz_dependency: - dims: - - y - - x - restart_name: alvsf - units: '' -mean_visible_albedo_with_weak_cosz_dependency: - dims: - - y - - x - restart_name: alvwf - units: '' -minimum_fractional_coverage_of_green_vegetation: - dims: - - y - - x - restart_name: shdmin - units: '' -northward_wind: - dims: - - z - - y - - x - restart_name: va - units: m/s -northward_wind_after_physics: - dims: - - z - - y - - x - restart_name: gv0 - units: m/s -northward_wind_at_surface: - dims: - - y - - x - restart_name: v_srf - units: m/s -pressure_thickness_of_atmospheric_layer: - dims: - - z - - y - - x - restart_name: delp - units: Pa -sea_ice_thickness: - dims: - - y - - x - restart_name: hice - units: unknown -sensible_heat_flux: - dims: - - y - - x - restart_name: dtsfci - units: W/m^2 -snow_cover_in_fraction: - dims: - - y - - x - restart_name: sncovr - units: '' -snow_depth_water_equivalent: - dims: - - y - - x - restart_name: snwdph - units: mm -snow_rain_flag: - description: snow/rain flag for precipitation - dims: - - y - - x - restart_name: srflag - units: '' -soil_temperature: - dims: - - z_soil - - y - - x - restart_name: stc - units: degK -soil_type: - dims: - - y - - x - restart_name: stype - units: '' -specific_humidity_at_2m: - dims: - - y - - x - restart_name: q2m - units: kg/kg -surface_geopotential: - dims: - - y - - x - restart_name: phis - units: m^2 s^-2 -surface_pressure: - dims: - - y - - x - restart_name: ps - units: Pa -surface_roughness: - dims: - - y - - x - restart_name: zorl - units: cm -surface_slope_type: - description: used in land surface model - dims: - - y - - x - restart_name: slope - units: '' -surface_temperature: - description: surface skin temperature - dims: - - y - - x - restart_name: tsea - units: degK -surface_temperature_over_ice_fraction: - dims: - - y - - x - restart_name: tisfc - units: degK -total_condensate_mixing_ratio: - dims: - - z - - y - - x - restart_name: q_con - units: kg/kg -total_precipitation: - dims: - - y - - x - restart_name: tprcp - units: m -total_sky_downward_longwave_flux_at_surface: - dims: - - y - - x - fortran_subname: dnfxc - restart_name: sfcflw - units: W/m^2 -total_sky_downward_shortwave_flux_at_surface: - dims: - - y - - x - fortran_subname: dnfxc - restart_name: sfcfsw - units: W/m^2 -total_sky_downward_shortwave_flux_at_top_of_atmosphere: - dims: - - y - - x - fortran_subname: dnfxc - restart_name: topfsw - units: W/m^2 -total_sky_upward_longwave_flux_at_surface: - dims: - - y - - x - fortran_subname: upfxc - restart_name: sfcflw - units: W/m^2 -total_sky_upward_longwave_flux_at_top_of_atmosphere: - dims: - - y - - x - fortran_subname: upfxc - restart_name: topflw - units: W/m^2 -total_sky_upward_shortwave_flux_at_surface: - dims: - - y - - x - fortran_subname: upfxc - restart_name: sfcfsw - units: W/m^2 -total_sky_upward_shortwave_flux_at_top_of_atmosphere: - dims: - - y - - x - fortran_subname: upfxc - restart_name: topfsw - units: W/m^2 -total_soil_moisture: - dims: - - z_soil - - y - - x - restart_name: smc - units: unknown -vegetation_fraction: - dims: - - y - - x - restart_name: vfrac - units: '' -vegetation_type: - dims: - - y - - x - restart_name: vtype - units: '' -vertical_pressure_velocity: - dims: - - z - - y - - x - restart_name: omga - units: Pa/s -vertical_thickness_of_atmospheric_layer: - dims: - - z - - y - - x - restart_name: DZ - units: m -vertical_wind: - dims: - - z - - y - - x - restart_name: W - units: m/s -water_equivalent_of_accumulated_snow_depth: - description: weasd in Fortran code, over land and sea ice only - dims: - - y - - x - restart_name: sheleg - units: kg/m^2 -x_wind: - dims: - - z - - y_interface - - x - restart_name: u - units: m/s -x_wind_on_c_grid: - dims: - - z - - y - - x_interface - restart_name: uc - units: m/s -y_wind: - dims: - - z - - y - - x_interface - restart_name: v - units: m/s -y_wind_on_c_grid: - dims: - - z - - y_interface - - x - restart_name: vc - units: m/s diff --git a/util/pace/util/rotate.py b/util/pace/util/rotate.py deleted file mode 100644 index 27ab1f252..000000000 --- a/util/pace/util/rotate.py +++ /dev/null @@ -1,50 +0,0 @@ -from . import constants - - -def rotate_scalar_data(data, dims, numpy, n_clockwise_rotations): - n_clockwise_rotations = n_clockwise_rotations % 4 - if n_clockwise_rotations == 0: - pass - elif n_clockwise_rotations in (1, 3): - x_dim, y_dim = None, None - for i, dim in enumerate(dims): - if dim in constants.X_DIMS: - x_dim = i - elif dim in constants.Y_DIMS: - y_dim = i - if (x_dim is not None) and (y_dim is not None): - if n_clockwise_rotations == 1: - data = numpy.rot90(data, axes=(y_dim, x_dim)) - elif n_clockwise_rotations == 3: - data = numpy.rot90(data, axes=(x_dim, y_dim)) - elif x_dim is not None: - if n_clockwise_rotations == 1: - data = numpy.flip(data, axis=x_dim) - elif y_dim is not None: - if n_clockwise_rotations == 3: - data = numpy.flip(data, axis=y_dim) - elif n_clockwise_rotations == 2: - slice_list = [] - for dim in dims: - if dim in constants.HORIZONTAL_DIMS: - slice_list.append(slice(None, None, -1)) - else: - slice_list.append(slice(None, None)) - data = data[tuple(slice_list)] - return data - - -def rotate_vector_data(x_data, y_data, n_clockwise_rotations, dims, numpy): - x_data = rotate_scalar_data(x_data, dims, numpy, n_clockwise_rotations) - y_data = rotate_scalar_data(y_data, dims, numpy, n_clockwise_rotations) - data = [x_data, y_data] - n_clockwise_rotations = n_clockwise_rotations % 4 - if n_clockwise_rotations == 0: - pass - elif n_clockwise_rotations == 1: - data[0], data[1] = data[1], -data[0] - elif n_clockwise_rotations == 2: - data[0], data[1] = -data[0], -data[1] - elif n_clockwise_rotations == 3: - data[0], data[1] = -data[1], data[0] - return data diff --git a/util/pace/util/testing/__init__.py b/util/pace/util/testing/__init__.py deleted file mode 100644 index a1c927e97..000000000 --- a/util/pace/util/testing/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .comparison import compare_arr, compare_scalar, success, success_array -from .dummy_comm import ConcurrencyError, DummyComm -from .perturbation import perturb diff --git a/util/pace/util/testing/comparison.py b/util/pace/util/testing/comparison.py deleted file mode 100644 index 0ffe55edd..000000000 --- a/util/pace/util/testing/comparison.py +++ /dev/null @@ -1,68 +0,0 @@ -from typing import Union - -import numpy as np - - -def compare_arr(computed_data, ref_data): - """ - Smooth error near zero values. - Inputs are arrays. - """ - if ref_data.dtype in (np.float64, np.int64, np.float32, np.int32): - denom = np.abs(ref_data) + np.abs(computed_data) - compare = np.asarray(2.0 * np.abs(computed_data - ref_data) / denom) - compare[denom == 0] = 0.0 - return compare - elif ref_data.dtype in (np.bool,): - return np.logical_xor(computed_data, ref_data) - else: - raise TypeError(f"recieved data with unexpected dtype {ref_data.dtype}") - - -def compare_scalar(computed_data: np.float64, ref_data: np.float64) -> np.float64: - """Smooth error near zero values. Scalar versions.""" - err_as_array = compare_arr(np.atleast_1d(computed_data), np.atleast_1d(ref_data)) - return err_as_array[0] - - -def success_array( - computed_data: np.ndarray, - ref_data: np.ndarray, - eps: float, - ignore_near_zero_errors: Union[dict, bool], - near_zero: float, -): - success = np.logical_or( - np.logical_and(np.isnan(computed_data), np.isnan(ref_data)), - compare_arr(computed_data, ref_data) < eps, - ) - if isinstance(ignore_near_zero_errors, dict): - if ignore_near_zero_errors.keys(): - near_zero = ignore_near_zero_errors["near_zero"] - success = np.logical_or( - success, - np.logical_and( - np.abs(computed_data) < near_zero, - np.abs(ref_data) < near_zero, - ), - ) - elif ignore_near_zero_errors: - success = np.logical_or( - success, - np.logical_and( - np.abs(computed_data) < near_zero, np.abs(ref_data) < near_zero - ), - ) - return success - - -def success(computed_data, ref_data, eps, ignore_near_zero_errors, near_zero=0.0): - return np.all( - success_array( - np.asarray(computed_data), - np.asarray(ref_data), - eps, - ignore_near_zero_errors, - near_zero, - ) - ) diff --git a/util/pace/util/testing/dummy_comm.py b/util/pace/util/testing/dummy_comm.py deleted file mode 100644 index b82800e74..000000000 --- a/util/pace/util/testing/dummy_comm.py +++ /dev/null @@ -1,2 +0,0 @@ -from ..local_comm import ConcurrencyError # noqa -from ..local_comm import LocalComm as DummyComm # noqa diff --git a/util/pace/util/testing/perturbation.py b/util/pace/util/testing/perturbation.py deleted file mode 100644 index 25e423028..000000000 --- a/util/pace/util/testing/perturbation.py +++ /dev/null @@ -1,19 +0,0 @@ -from typing import Mapping - -import numpy as np - - -def perturb(input: Mapping[str, np.ndarray]): - """ - Adds roundoff-level noise to the input array in-place through multiplication. - - Will only make changes to float64 or float32 arrays. - """ - roundoff = 1e-16 - for data in input.values(): - if isinstance(data, np.ndarray) and data.dtype in (np.float64, np.float32): - not_fill_value = data < 1e30 - # multiply data by roundoff-level error - data[not_fill_value] *= 1.0 + np.random.uniform( - low=-roundoff, high=roundoff, size=data[not_fill_value].shape - ) diff --git a/util/pace/util/time.py b/util/pace/util/time.py deleted file mode 100644 index 54ce174cb..000000000 --- a/util/pace/util/time.py +++ /dev/null @@ -1,23 +0,0 @@ -import datetime - -import cftime -import numpy as np - - -# Calendar constant values copied from time_manager in FMS -THIRTY_DAY_MONTHS = 1 -JULIAN = 2 -GREGORIAN = 3 -NOLEAP = 4 -FMS_TO_CFTIME_TYPE = { - THIRTY_DAY_MONTHS: cftime.Datetime360Day, - JULIAN: cftime.DatetimeJulian, - GREGORIAN: cftime.DatetimeGregorian, # Not a valid calendar in FV3GFS - NOLEAP: cftime.DatetimeNoLeap, -} - - -def datetime64_to_datetime(dt64: np.datetime64) -> datetime.datetime: - utc_start = np.datetime64(0, "s") - timestamp = (dt64 - utc_start) / np.timedelta64(1, "s") - return datetime.datetime.utcfromtimestamp(timestamp) diff --git a/util/pace/util/types.py b/util/pace/util/types.py deleted file mode 100644 index 6c4ce5965..000000000 --- a/util/pace/util/types.py +++ /dev/null @@ -1,48 +0,0 @@ -import functools -from typing import Iterable, TypeVar - -import numpy as np -from typing_extensions import Protocol - - -Array = TypeVar("Array") - - -class Allocator(Protocol): - def __call__(self, shape: Iterable[int], dtype: type) -> Array: - pass - - -class NumpyModule(Protocol): - - empty: Allocator - zeros: Allocator - ones: Allocator - - @functools.wraps(np.rot90) - def rot90(self, *args, **kwargs): - ... - - @functools.wraps(np.sum) - def sum(self, *args, **kwargs): - ... - - @functools.wraps(np.log) - def log(self, *args, **kwargs): - ... - - @functools.wraps(np.sin) - def sin(self, *args, **kwargs): - ... - - @functools.wraps(np.asarray) - def asarray(self, *args, **kwargs): - ... - - -class AsyncRequest(Protocol): - """Define the result of an over-the-network capable communication API""" - - def wait(self): - """Block the current thread waiting for the request to be completed""" - ... diff --git a/util/pace/util/units.py b/util/pace/util/units.py deleted file mode 100644 index 73414715d..000000000 --- a/util/pace/util/units.py +++ /dev/null @@ -1,11 +0,0 @@ -def ensure_equal_units(units1: str, units2: str) -> None: - if not units_are_equal(units1, units2): - raise UnitsError(f"incompatible units {units1} and {units2}") - - -def units_are_equal(units1: str, units2: str) -> bool: - return units1.strip() == units2.strip() - - -class UnitsError(Exception): - pass diff --git a/util/pace/util/utils.py b/util/pace/util/utils.py deleted file mode 100644 index 9854609de..000000000 --- a/util/pace/util/utils.py +++ /dev/null @@ -1,113 +0,0 @@ -from enum import EnumMeta -from typing import Iterable, Sequence, Tuple, TypeVar, Union - -import numpy as np - -from . import constants -from ._optional_imports import cupy as cp -from .types import Allocator - - -# Run a deviceSynchronize() to check -# that the GPU is present and ready to run -if cp is not None: - try: - cp.cuda.runtime.deviceSynchronize() - GPU_AVAILABLE = True - except cp.cuda.runtime.CUDARuntimeError: - GPU_AVAILABLE = False -else: - GPU_AVAILABLE = False - -T = TypeVar("T") - - -class MetaEnumStr(EnumMeta): - def __contains__(cls, item) -> bool: - return item in cls.__members__.keys() - - -def list_by_dims( - dims: Sequence[str], horizontal_list: Sequence[T], non_horizontal_value: T -) -> Tuple[T, ...]: - """Take in a list of dimensions, a (y, x) set of values, and a value for any - non-horizontal dimensions. Return a list of length len(dims) with the value for - each dimension. - """ - return_list = [] - for dim in dims: - if dim in constants.Y_DIMS: - return_list.append(horizontal_list[0]) - elif dim in constants.X_DIMS: - return_list.append(horizontal_list[1]) - else: - return_list.append(non_horizontal_value) - return tuple(return_list) - - -def is_contiguous(array: np.ndarray) -> bool: - return array.flags["C_CONTIGUOUS"] or array.flags["F_CONTIGUOUS"] - - -def is_c_contiguous(array: np.ndarray) -> bool: - return array.flags["C_CONTIGUOUS"] - - -def ensure_contiguous(maybe_array: Union[np.ndarray, None]) -> None: - if maybe_array is not None and not is_contiguous(maybe_array): - raise ValueError("ndarray is not contiguous") - - -def safe_assign_array(to_array: np.ndarray, from_array: np.ndarray): - """Failproof assignment for array on different devices. - - The memory will be downloaded/uploaded from GPU if need be. - - Args: - to_array: destination ndarray - from_array: source ndarray - """ - try: - to_array[:] = from_array - except (ValueError, TypeError): - if cp and isinstance(to_array, cp.ndarray): - to_array[:] = cp.asarray(from_array) - elif cp and isinstance(from_array, cp.ndarray): - to_array[:] = cp.asnumpy(from_array) - else: - raise - - -def device_synchronize(): - """Synchronize all memory communication""" - if GPU_AVAILABLE: - cp.cuda.runtime.deviceSynchronize() - - -def safe_mpi_allocate( - allocator: Allocator, shape: Iterable[int], dtype: type -) -> np.ndarray: - """Make sure the allocation use an allocator that works with MPI - - For G2G transfer, MPICH requires the allocation to not be done - with managedmemory. Since we can't know what state `cupy` is in - with switch for the default pooled allocator. - - If allocator comes from cupy, it must be cupy.empty or cupy.zeros. - We raise a RuntimeError if a cupy array is allocated outside of - the safe code path. - - Though the allocation _might_ be safe, the MPI crash that result - from a managed memory allocation is non trivial and should be - tightly controlled. - """ - if cp and (allocator is cp.empty or allocator is cp.zeros): - original_allocator = cp.cuda.get_allocator() - cp.cuda.set_allocator(cp.get_default_memory_pool().malloc) - array = allocator(shape, dtype=dtype) # type: np.ndarray - cp.cuda.set_allocator(original_allocator) - else: - array = allocator(shape, dtype=dtype) - if __debug__ and cp and isinstance(array, cp.ndarray): - raise RuntimeError("cupy allocation might not be MPI-safe") - return array diff --git a/util/requirements.txt b/util/requirements.txt deleted file mode 100644 index 765e5ae43..000000000 --- a/util/requirements.txt +++ /dev/null @@ -1,19 +0,0 @@ -bump2version -wheel -flake8==3.8.4 -mypy==0.790 -tox -coverage -f90nml>=1.1.0 -appdirs>=1.4.0 -sphinx_rtd_theme -pytest-cov -pytest-subtests -gcsfs>=0.7.0 -google-cloud-storage -numcodecs>=0.7.2 #pin for gt4py, h5py and py3.6 to agree -h5py>=2.10.0 #pin for gt4py, h5py and py3.6 to agree -h5netcdf -dask>=2021.10.0 -numpy>=1.15. #pin for gt4py, h5py, cupy9.1 and py3.6 to agree -toolz diff --git a/util/setup.cfg b/util/setup.cfg deleted file mode 100644 index f98074dcc..000000000 --- a/util/setup.cfg +++ /dev/null @@ -1,21 +0,0 @@ -[bumpversion] -current_version = 0.10.0 -commit = True - -[bdist_wheel] -universal = 1 - -[flake8] -exclude = docs -ignore = E203,E501,W293,W503 -max-line-length = 88 - -[aliases] - -[bumpversion:file:pace/util/__init__.py] -search = __version__ = "{current_version}" -replace = __version__ = "{new_version}" - -[bumpversion:file:setup.py] -search = version="{current_version}" -replace = version="{new_version}" diff --git a/util/setup.py b/util/setup.py deleted file mode 100644 index f674b8d82..000000000 --- a/util/setup.py +++ /dev/null @@ -1,54 +0,0 @@ -from typing import List - -from setuptools import find_namespace_packages, setup - - -setup_requirements: List[str] = [] - -requirements = [ - "cftime>=1.2.1", - "numpy>=0.15.0", - "fsspec>=0.6.0", - "typing_extensions>=3.7.4", - "f90nml>=1.1.0", -] - -test_requirements: List[str] = [] - -with open("README.md") as readme_file: - readme = readme_file.read() - - -with open("HISTORY.md") as history_file: - history = history_file.read() - -setup( - author="Allen Institute of Artificial Intelligence", - author_email="jeremym@allenai.org", - python_requires=">=3.8", - classifiers=[ - "Development Status :: 2 - Pre-Alpha", - "Intended Audience :: Developers", - "License :: OSI Approved :: BSD License", - "Natural Language :: English", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", - ], - install_requires=requirements, - setup_requires=setup_requirements, - tests_require=test_requirements, - extras_require={ - "netcdf": ["xarray>=0.15.1", "scipy>=1.3.1"], - "zarr": ["zarr>=2.3.2", "xarray>=0.15.1", "scipy>=1.3.1"], - "dace": ["dace>=0.14"], - }, - name="pace-util", - license="BSD license", - long_description=readme + "\n\n" + history, - packages=find_namespace_packages(include=["pace.*"]), - include_package_data=True, - url="https://github.com/ai2cm/pace", - version="0.10.0", - zip_safe=False, -) diff --git a/util/tests/checkpointer/test_snapshot.py b/util/tests/checkpointer/test_snapshot.py deleted file mode 100644 index 5ed9a8945..000000000 --- a/util/tests/checkpointer/test_snapshot.py +++ /dev/null @@ -1,59 +0,0 @@ -import numpy as np -import pytest - -import pace.util -from pace.util._optional_imports import xarray as xr - - -requires_xarray = pytest.mark.skipif(xr is None, reason="xarray is not installed") - - -@requires_xarray -def test_snapshot_checkpointer_no_data(): - checkpointer = pace.util.SnapshotCheckpointer(rank=0) - xr.testing.assert_identical(checkpointer.dataset, xr.Dataset()) - - -@requires_xarray -def test_snapshot_checkpointer_one_snapshot(): - checkpointer = pace.util.SnapshotCheckpointer(rank=0) - val1 = np.random.randn(2, 3, 4) - checkpointer("savepoint_name", val1=val1) - xr.testing.assert_identical( - checkpointer.dataset, - xr.Dataset( - data_vars={ - "val1": xr.DataArray( - val1[None, :], - dims=["sp_val1", "val1_dim0", "val1_dim1", "val1_dim2"], - ), - "val1_savepoints": xr.DataArray(["savepoint_name"], dims=["sp_val1"]), - } - ), - ) - - -@requires_xarray -def test_snapshot_checkpointer_multiple_snapshots(): - checkpointer = pace.util.SnapshotCheckpointer(rank=0) - val1 = np.random.randn(2, 2, 3, 4) - val2 = np.random.randn(1, 3, 2, 4) - checkpointer("savepoint_name_1", val1=val1[0, :]) - checkpointer("savepoint_name_2", val1=val1[1, :], val2=val2[0, :]) - xr.testing.assert_identical( - checkpointer.dataset, - xr.Dataset( - data_vars={ - "val1": xr.DataArray( - val1, dims=["sp_val1", "val1_dim0", "val1_dim1", "val1_dim2"] - ), - "val2": xr.DataArray( - val2, dims=["sp_val2", "val2_dim0", "val2_dim1", "val2_dim2"] - ), - "val1_savepoints": xr.DataArray( - ["savepoint_name_1", "savepoint_name_2"], dims=["sp_val1"] - ), - "val2_savepoints": xr.DataArray(["savepoint_name_2"], dims=["sp_val2"]), - } - ), - ) diff --git a/util/tests/checkpointer/test_thresholds.py b/util/tests/checkpointer/test_thresholds.py deleted file mode 100644 index 498ad265e..000000000 --- a/util/tests/checkpointer/test_thresholds.py +++ /dev/null @@ -1,105 +0,0 @@ -import numpy as np -import pytest - -from pace.util.checkpointer import ( - InsufficientTrialsError, - Threshold, - ThresholdCalibrationCheckpointer, -) - - -def test_thresholds_no_trials(): - checkpointer = ThresholdCalibrationCheckpointer() - with pytest.raises(InsufficientTrialsError): - checkpointer.thresholds - - -def test_thresholds_one_empty_trial(): - checkpointer = ThresholdCalibrationCheckpointer() - with checkpointer.trial(): - pass - with pytest.raises(InsufficientTrialsError): - checkpointer.thresholds - - -def test_thresholds_two_empty_trials(): - checkpointer = ThresholdCalibrationCheckpointer() - for _ in range(2): - with checkpointer.trial(): - pass - assert checkpointer.thresholds.savepoints == {} - - -def test_thresholds_one_data_trial(): - checkpointer = ThresholdCalibrationCheckpointer() - with checkpointer.trial(): - data = np.asarray([0.0, 0.0, 0.0]) - checkpointer("savepoint_name", data=data) - with pytest.raises(InsufficientTrialsError): - checkpointer.thresholds - - -@pytest.mark.parametrize( - "factor, values, rel_threshold, abs_threshold", - [ - pytest.param(1.0, [0.0, 0.0], 0.0, 0.0, id="zero_threshold"), - pytest.param(1.0, [0.0, 1.0], 2.0, 1.0, id="nonzero_threshold"), - pytest.param(1.5, [0.0, 1.0], 3.0, 1.5, id="non_identity_factor"), - pytest.param(1.0, [4.0, 6.0], 0.4, 2.0, id="larger_mean"), - pytest.param(1.0, [-1.0, 1.0], 2.0, 2.0, id="varying_sign"), - pytest.param(1.0, [-5.0, 5.0, 10.0, 0.0], 3.0, 15.0, id="more_values"), - ], -) -def test_thresholds_sufficient_trials(factor, values, rel_threshold, abs_threshold): - checkpointer = ThresholdCalibrationCheckpointer(factor=factor) - for val in values: - with checkpointer.trial(): - data = np.asarray([val, 0.0, 0.0]) - checkpointer("savepoint_name", data=data) - assert checkpointer.thresholds.savepoints == { - "savepoint_name": [ - {"data": Threshold(relative=rel_threshold, absolute=abs_threshold)} - ] - } - - -def test_thresholds_more_variables(): - checkpointer = ThresholdCalibrationCheckpointer(factor=1.0) - with checkpointer.trial(): - data1 = np.asarray([0.0, 0.0, 0.0]) - data2 = np.asarray([0.0, 0.0, 0.0]) - checkpointer("savepoint_name", data1=data1, data2=data2) - with checkpointer.trial(): - data1 = np.asarray([0.0, 0.0, 0.0]) - data2 = np.asarray([1.0, 0.0, 0.0]) - checkpointer("savepoint_name", data1=data1, data2=data2) - assert checkpointer.thresholds.savepoints == { - "savepoint_name": [ - { - "data1": Threshold(relative=0.0, absolute=0.0), - "data2": Threshold(relative=2.0, absolute=1.0), - } - ] - } - - -def test_thresholds_two_calls(): - checkpointer = ThresholdCalibrationCheckpointer(factor=1.0) - with checkpointer.trial(): - data1 = np.asarray([0.0, 0.0, 0.0]) - data2 = np.asarray([0.0, 0.0, 0.0]) - checkpointer("savepoint_name", data=data1) - checkpointer("savepoint_name", data=data2) - with checkpointer.trial(): - data1 = np.asarray([0.0, 0.0, 0.0]) - data2 = np.asarray([1.0, 0.0, 0.0]) - checkpointer("savepoint_name", data=data1) - checkpointer("savepoint_name", data=data2) - assert checkpointer.thresholds.savepoints == { - "savepoint_name": [ - { - "data": Threshold(relative=0.0, absolute=0.0), - }, - {"data": Threshold(relative=2.0, absolute=1.0)}, - ] - } diff --git a/util/tests/checkpointer/test_validation.py b/util/tests/checkpointer/test_validation.py deleted file mode 100644 index 2ef06dc36..000000000 --- a/util/tests/checkpointer/test_validation.py +++ /dev/null @@ -1,289 +0,0 @@ -import os -import tempfile - -import numpy as np -import pytest - -from pace.util._optional_imports import xarray as xr -from pace.util.checkpointer import ( - SavepointThresholds, - Threshold, - ValidationCheckpointer, -) -from pace.util.checkpointer.validation import _clip_pace_array_to_target - - -requires_xarray = pytest.mark.skipif(xr is None, reason="xarray is not installed") - - -def get_dataset( - n_savepoints: int, n_vars: int, n_ranks: int, nx: int, ny: int, nz: int -): - data_vars = {} - for i in range(n_vars): - data_vars["data{}".format(i)] = xr.DataArray( - np.zeros((n_savepoints, n_ranks, nx, ny, nz)), - dims=[ - "savepoint", - "rank", - "dim_data{}_0".format(i), - "dim_data{}_1".format(i), - "dim_data{}_2".format(i), - ], - ) - return xr.Dataset(data_vars=data_vars) - - -@requires_xarray -def test_validation_validates_onevar_onecall(): - temp_dir = tempfile.TemporaryDirectory() - nx_compute = 12 - nz = 20 - n_halo = 3 - savepoint_name = "savepoint_name" - ds = get_dataset( - n_savepoints=1, n_vars=1, n_ranks=1, nx=nx_compute, ny=nx_compute, nz=nz - ) - ds["data0"].values[:] = 1.0 - ds.to_netcdf(os.path.join(temp_dir.name, savepoint_name + ".nc")) - - data = np.full( - (nx_compute + 2 * n_halo + 1, nx_compute + 2 * n_halo + 1, nz), fill_value=2.0 - ) - - checkpointer = ValidationCheckpointer( - temp_dir.name, - SavepointThresholds( - {savepoint_name: [{"data0": Threshold(relative=1.0, absolute=1.0)}]} - ), - rank=0, - ) - with checkpointer.trial(): - checkpointer(savepoint_name, data0=data) - - -@pytest.mark.parametrize( - "relative_threshold, absolute_threshold", - [ - pytest.param(0.99, 1.0, id="relative_failure"), - pytest.param(1.0, 0.99, id="absolute_failure"), - ], -) -@requires_xarray -def test_validation_asserts_onevar_onecall(relative_threshold, absolute_threshold): - temp_dir = tempfile.TemporaryDirectory() - nx_compute = 12 - nz = 20 - n_halo = 3 - savepoint_name = "savepoint_name" - ds = get_dataset( - n_savepoints=1, n_vars=1, n_ranks=1, nx=nx_compute, ny=nx_compute, nz=nz - ) - ds["data0"].values[:] = 1.0 - ds.to_netcdf(os.path.join(temp_dir.name, savepoint_name + ".nc")) - - data = np.full( - (nx_compute + 2 * n_halo + 1, nx_compute + 2 * n_halo + 1, nz), fill_value=2.0 - ) - - checkpointer = ValidationCheckpointer( - temp_dir.name, - SavepointThresholds( - { - savepoint_name: [ - { - "data0": Threshold( - relative=relative_threshold, - absolute=absolute_threshold, - ) - } - ] - } - ), - rank=0, - ) - with checkpointer.trial(): - with pytest.raises(AssertionError): - checkpointer(savepoint_name, data0=data) - - -@pytest.mark.parametrize( - "relative_threshold, absolute_threshold", - [ - pytest.param(0.99, 1.0, id="relative_threshold"), - pytest.param(1.0, 0.99, id="absolute_threshold"), - ], -) -@requires_xarray -def test_validation_passes_onevar_two_calls(relative_threshold, absolute_threshold): - temp_dir = tempfile.TemporaryDirectory() - nx_compute = 12 - nz = 20 - n_halo = 3 - savepoint_name = "savepoint_name" - ds = get_dataset( - n_savepoints=2, n_vars=1, n_ranks=1, nx=nx_compute, ny=nx_compute, nz=nz - ) - ds["data0"].values[:] = 2.0 - ds.to_netcdf(os.path.join(temp_dir.name, savepoint_name + ".nc")) - - data = np.full( - (nx_compute + 2 * n_halo + 1, nx_compute + 2 * n_halo + 1, nz), fill_value=2.0 - ) - - checkpointer = ValidationCheckpointer( - temp_dir.name, - SavepointThresholds( - { - savepoint_name: [ - { - "data0": Threshold( - relative=relative_threshold, - absolute=absolute_threshold, - ) - }, - { - "data0": Threshold( - relative=relative_threshold, - absolute=absolute_threshold, - ) - }, - ] - } - ), - rank=0, - ) - with checkpointer.trial(): - checkpointer(savepoint_name, data0=data) - checkpointer(savepoint_name, data0=data) - - -@pytest.mark.parametrize( - "relative_threshold, absolute_threshold", - [ - pytest.param(0.99, 1.0, id="relative_failure"), - pytest.param(1.0, 0.99, id="absolute_failure"), - ], -) -@requires_xarray -def test_validation_asserts_onevar_two_calls(relative_threshold, absolute_threshold): - temp_dir = tempfile.TemporaryDirectory() - nx_compute = 12 - nz = 20 - n_halo = 3 - savepoint_name = "savepoint_name" - ds = get_dataset( - n_savepoints=2, n_vars=1, n_ranks=1, nx=nx_compute, ny=nx_compute, nz=nz - ) - ds["data0"].values[0, :] = 2.0 - ds["data0"].values[1, :] = 1.0 - ds.to_netcdf(os.path.join(temp_dir.name, savepoint_name + ".nc")) - - data = np.full( - (nx_compute + 2 * n_halo + 1, nx_compute + 2 * n_halo + 1, nz), fill_value=2.0 - ) - - checkpointer = ValidationCheckpointer( - temp_dir.name, - SavepointThresholds( - { - savepoint_name: [ - { - "data0": Threshold( - relative=relative_threshold, - absolute=absolute_threshold, - ) - }, - { - "data0": Threshold( - relative=relative_threshold, - absolute=absolute_threshold, - ) - }, - ] - } - ), - rank=0, - ) - with checkpointer.trial(): - checkpointer(savepoint_name, data0=data) - with pytest.raises(AssertionError): - checkpointer(savepoint_name, data0=data) - - -@pytest.mark.parametrize( - "relative_threshold, absolute_threshold", - [ - pytest.param(0.99, 1.0, id="relative_failure"), - pytest.param(1.0, 0.99, id="absolute_failure"), - ], -) -@requires_xarray -def test_validation_asserts_twovar_onecall(relative_threshold, absolute_threshold): - temp_dir = tempfile.TemporaryDirectory() - nx_compute = 12 - nz = 20 - n_halo = 3 - savepoint_name = "savepoint_name" - ds = get_dataset( - n_savepoints=1, n_vars=2, n_ranks=1, nx=nx_compute, ny=nx_compute, nz=nz - ) - ds["data0"].values[:] = 1.0 - ds["data1"].values[:] = 1.0 - ds.to_netcdf(os.path.join(temp_dir.name, savepoint_name + ".nc")) - - data = np.full( - (nx_compute + 2 * n_halo + 1, nx_compute + 2 * n_halo + 1, nz), fill_value=2.0 - ) - - checkpointer = ValidationCheckpointer( - temp_dir.name, - SavepointThresholds( - { - savepoint_name: [ - { - "data0": Threshold( - relative=1.0, - absolute=1.0, - ), - "data1": Threshold( - relative=relative_threshold, - absolute=absolute_threshold, - ), - } - ] - } - ), - rank=0, - ) - with checkpointer.trial(): - with pytest.raises(AssertionError): - checkpointer(savepoint_name, data0=data, data1=data) - - -@pytest.mark.parametrize( - "array, target_shape, target_array", - [ - pytest.param( - np.asarray([1.0, 2.0, 3.0, 4.0, 5.0]), - (3,), - np.asarray([2.0, 3.0, 4.0]), - id="interface_dim", - ), - pytest.param( - np.asarray([1.0, 2.0, 3.0, 4.0, 5.0]), - (2,), - np.asarray([2.0, 3.0]), - id="centered_dim", - ), - pytest.param( - np.asarray([1.0, 2.0, 3.0, 4.0, 5.0]), - (5,), - np.asarray([1.0, 2.0, 3.0, 4.0, 5.0]), - id="all_points", - ), - ], -) -def test_clip_pace_array_to_target(array, target_shape, target_array): - clipped = _clip_pace_array_to_target(array, target_shape=target_shape) - np.testing.assert_array_equal(clipped, target_array) diff --git a/util/tests/conftest.py b/util/tests/conftest.py deleted file mode 100644 index 6bb91b9fb..000000000 --- a/util/tests/conftest.py +++ /dev/null @@ -1,81 +0,0 @@ -import numpy as np -import pytest - - -try: - import gt4py -except ModuleNotFoundError: - gt4py = None -try: - import cupy -except ModuleNotFoundError: - cupy = None - - -@pytest.fixture(params=["numpy", "cupy", "gt4py_numpy", "gt4py_cupy"]) -def backend(request): - if cupy is None and request.param.endswith("cupy"): - if request.config.getoption("--gpu-only"): - raise ModuleNotFoundError("cupy must be installed to run gpu tests") - else: - pytest.skip("cupy is not available for GPU backend") - elif gt4py is None and request.param.startswith("gt4py"): - pytest.skip("gt4py backend is not available") - elif request.config.getoption("--gpu-only") and not request.param.endswith("cupy"): - pytest.skip("running gpu tests only") - else: - return request.param - - -@pytest.fixture -def gt4py_backend(backend): - if backend in ("numpy", "gt4py_numpy"): - return "numpy" - elif backend in ("cupy", "gt4py_cupy"): - return "gt:gpu" - else: - return None - - -@pytest.fixture -def fast(pytestconfig): - return pytestconfig.getoption("--fast") - - -@pytest.fixture -def numpy(backend): - if backend == "numpy": - return np - elif backend == "cupy": - return cupy - elif backend == "gt4py_numpy": - # TODO: Deprecate these "backends". - return np - elif backend == "gt4py_cupy": - return cupy - else: - raise NotImplementedError() - - -def pytest_addoption(parser): - parser.addoption( - "--gpu-only", action="store_true", default=False, help="only run gpu tests" - ) - parser.addoption( - "--fast", - action="store_true", - default=False, - help="run a limited suite of tests which completes quickly", - ) - - -def pytest_configure(config): - config.addinivalue_line("markers", "cpu_only: mark test as not using a gpu") - - -def pytest_collection_modifyitems(config, items): - if config.getoption("--gpu-only"): - skip_cpu_only = pytest.mark.skip(reason="running gpu tests only") - for item in items: - if "cpu_only" in item.keywords: - item.add_marker(skip_cpu_only) diff --git a/util/tests/data/coupler.res b/util/tests/data/coupler.res deleted file mode 100644 index e61712029..000000000 --- a/util/tests/data/coupler.res +++ /dev/null @@ -1,3 +0,0 @@ - 2 (Calendar: no_calendar=0, thirty_day_months=1, julian=2, gregorian=3, noleap=4) - 2016 8 1 0 0 0 Model start time: year, month, day, hour, minute, second - 2016 8 3 0 0 0 Current model time: year, month, day, hour, minute, second diff --git a/util/tests/data/coupler_julian.res b/util/tests/data/coupler_julian.res deleted file mode 100644 index e61712029..000000000 --- a/util/tests/data/coupler_julian.res +++ /dev/null @@ -1,3 +0,0 @@ - 2 (Calendar: no_calendar=0, thirty_day_months=1, julian=2, gregorian=3, noleap=4) - 2016 8 1 0 0 0 Model start time: year, month, day, hour, minute, second - 2016 8 3 0 0 0 Current model time: year, month, day, hour, minute, second diff --git a/util/tests/data/coupler_noleap.res b/util/tests/data/coupler_noleap.res deleted file mode 100644 index 62168e04e..000000000 --- a/util/tests/data/coupler_noleap.res +++ /dev/null @@ -1,3 +0,0 @@ - 4 (Calendar: no_calendar=0, thirty_day_months=1, julian=2, gregorian=3, noleap=4) - 2016 8 1 0 0 0 Model start time: year, month, day, hour, minute, second - 2016 8 3 0 0 0 Current model time: year, month, day, hour, minute, second diff --git a/util/tests/data/coupler_thirty_day.res b/util/tests/data/coupler_thirty_day.res deleted file mode 100644 index fac354e6e..000000000 --- a/util/tests/data/coupler_thirty_day.res +++ /dev/null @@ -1,3 +0,0 @@ - 1 (Calendar: no_calendar=0, thirty_day_months=1, julian=2, gregorian=3, noleap=4) - 2016 8 1 0 0 0 Model start time: year, month, day, hour, minute, second - 2016 8 3 0 0 0 Current model time: year, month, day, hour, minute, second diff --git a/util/tests/mpi/mpi_comm.py b/util/tests/mpi/mpi_comm.py deleted file mode 100644 index c7eb36ccf..000000000 --- a/util/tests/mpi/mpi_comm.py +++ /dev/null @@ -1,9 +0,0 @@ -try: - from mpi4py import MPI -except ImportError: - MPI = None - -if MPI is not None and MPI.COMM_WORLD.Get_size() == 1: - # not run as a parallel test, disable MPI tests - MPI.Finalize() - MPI = None diff --git a/util/tests/mpi/test_mpi_halo_update.py b/util/tests/mpi/test_mpi_halo_update.py deleted file mode 100644 index 06f00fc6e..000000000 --- a/util/tests/mpi/test_mpi_halo_update.py +++ /dev/null @@ -1,420 +0,0 @@ -import copy - -import pytest -from mpi_comm import MPI - -import pace.util - - -@pytest.fixture -def dtype(numpy): - return numpy.float64 - - -@pytest.fixture -def layout(): - if MPI is not None: - size = MPI.COMM_WORLD.Get_size() - ranks_per_tile = size // 6 - ranks_per_edge = int(ranks_per_tile ** 0.5) - return (ranks_per_edge, ranks_per_edge) - else: - return (1, 1) - - -@pytest.fixture -def nz(): - return 70 - - -@pytest.fixture -def ny(n_points, layout): - ny_rank = max(12, n_points * 2 - 1) - return ny_rank * layout[0] - - -@pytest.fixture -def nx(n_points, layout): - nx_rank = max(12, n_points * 2 - 1) - return nx_rank * layout[1] - - -@pytest.fixture(params=[1, 3]) -def n_points(request): - return request.param - - -@pytest.fixture(params=["fewer", "same"]) -def n_points_update(request, n_points): - update = n_points + {"fewer": -1, "same": 0}[request.param] - if update > n_points: - pytest.skip("cannot update more points than exist in the halo") - elif update <= 0: - pytest.skip("cannot update fewer than 1 points") - else: - return update - - -@pytest.fixture( - params=[ - pytest.param((pace.util.Y_DIM, pace.util.X_DIM), id="center"), - pytest.param( - (pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM), id="center_3d" - ), - pytest.param( - (pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM), - id="center_3d_reverse", - ), - pytest.param( - (pace.util.X_DIM, pace.util.Z_DIM, pace.util.Y_DIM), - id="center_3d_shuffle", - ), - pytest.param( - (pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM), id="interface" - ), - pytest.param( - ( - pace.util.Z_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, - pace.util.X_INTERFACE_DIM, - ), - id="interface_3d", - ), - ] -) -def dims(request): - return request.param - - -@pytest.fixture -def units(): - return "m" - - -@pytest.fixture -def ranks_per_tile(layout): - return layout[0] * layout[1] - - -@pytest.fixture -def total_ranks(ranks_per_tile): - return 6 * ranks_per_tile - - -@pytest.fixture(params=[0, 1]) -def n_buffer(request): - return request.param - - -@pytest.fixture -def shape(nz, ny, nx, dims, n_points, n_buffer): - return_list = [] - length_dict = { - pace.util.X_DIM: 2 * n_points + nx + n_buffer, - pace.util.X_INTERFACE_DIM: 2 * n_points + nx + 1 + n_buffer, - pace.util.Y_DIM: 2 * n_points + ny + n_buffer, - pace.util.Y_INTERFACE_DIM: 2 * n_points + ny + 1 + n_buffer, - pace.util.Z_DIM: nz + n_buffer, - pace.util.Z_INTERFACE_DIM: nz + 1 + n_buffer, - } - for dim in dims: - return_list.append(length_dict[dim]) - return return_list - - -@pytest.fixture -def origin(n_points, dims): - return_list = [] - origin_dict = { - pace.util.X_DIM: n_points, - pace.util.X_INTERFACE_DIM: n_points, - pace.util.Y_DIM: n_points, - pace.util.Y_INTERFACE_DIM: n_points, - pace.util.Z_DIM: 0, - pace.util.Z_INTERFACE_DIM: 0, - } - for dim in dims: - return_list.append(origin_dict[dim]) - return return_list - - -@pytest.fixture -def extent(n_points, dims, nz, ny, nx): - return_list = [] - extent_dict = { - pace.util.X_DIM: nx, - pace.util.X_INTERFACE_DIM: nx + 1, - pace.util.Y_DIM: ny, - pace.util.Y_INTERFACE_DIM: ny + 1, - pace.util.Z_DIM: nz, - pace.util.Z_INTERFACE_DIM: nz + 1, - } - for dim in dims: - return_list.append(extent_dict[dim]) - return return_list - - -@pytest.fixture() -def communicator(cube_partitioner): - return pace.util.CubedSphereCommunicator( - comm=MPI.COMM_WORLD, - partitioner=cube_partitioner, - ) - - -@pytest.fixture(params=[0.1, 1.0]) -def edge_interior_ratio(request): - return request.param - - -@pytest.fixture -def tile_partitioner(layout, edge_interior_ratio: float): - return pace.util.TilePartitioner(layout, edge_interior_ratio=edge_interior_ratio) - - -@pytest.fixture -def cube_partitioner(tile_partitioner): - return pace.util.CubedSpherePartitioner(tile_partitioner) - - -@pytest.fixture -def updated_slice(ny, nx, dims, n_points, n_points_update): - n_points_remain = n_points - n_points_update - return_list = [] - length_dict = { - pace.util.X_DIM: slice(n_points_remain, n_points + nx + n_points_update), - pace.util.X_INTERFACE_DIM: slice( - n_points_remain, n_points + nx + 1 + n_points_update - ), - pace.util.Y_DIM: slice(n_points_remain, n_points + ny + n_points_update), - pace.util.Y_INTERFACE_DIM: slice( - n_points_remain, n_points + ny + 1 + n_points_update - ), - pace.util.Z_DIM: slice(None, None), - pace.util.Z_INTERFACE_DIM: slice(None, None), - } - for dim in dims: - return_list.append(length_dict[dim]) - return return_list - - -@pytest.fixture -def remaining_ones(nz, ny, nx, n_points, n_points_update): - width = n_points - n_points_update - return (2 * nx + 2 * ny + 4 * width) * width - - -@pytest.fixture -def boundary_dict(ranks_per_tile): - if ranks_per_tile == 1: - return {0: pace.util.EDGE_BOUNDARY_TYPES} - elif ranks_per_tile == 4: - return { - 0: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHWEST, pace.util.NORTHEAST, pace.util.SOUTHEAST), - 1: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHWEST, pace.util.NORTHEAST, pace.util.SOUTHWEST), - 2: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHEAST, pace.util.SOUTHWEST, pace.util.SOUTHEAST), - 3: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHWEST, pace.util.SOUTHWEST, pace.util.SOUTHEAST), - } - elif ranks_per_tile == 9: - return { - 0: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHWEST, pace.util.NORTHEAST, pace.util.SOUTHEAST), - 1: pace.util.BOUNDARY_TYPES, - 2: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHWEST, pace.util.NORTHEAST, pace.util.SOUTHWEST), - 3: pace.util.BOUNDARY_TYPES, - 4: pace.util.BOUNDARY_TYPES, - 5: pace.util.BOUNDARY_TYPES, - 6: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHEAST, pace.util.SOUTHWEST, pace.util.SOUTHEAST), - 7: pace.util.BOUNDARY_TYPES, - 8: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHWEST, pace.util.SOUTHWEST, pace.util.SOUTHEAST), - } - else: - raise NotImplementedError(ranks_per_tile) - - -@pytest.fixture -def depth_quantity( - dims, units, origin, extent, shape, numpy, dtype, n_points, n_buffer -): - """A quantity whose value indicates the distance from the computational - domain boundary.""" - data = numpy.zeros(shape, dtype=dtype) - data[:] = numpy.nan - for n_inside in range(max(n_points, max(extent) // 2), -1, -1): - for i, dim in enumerate(dims): - if (n_inside <= extent[i] // 2) and (dim in pace.util.HORIZONTAL_DIMS): - pos = [slice(None, None)] * len(dims) - pos[i] = origin[i] + n_inside - data[tuple(pos)] = n_inside - pos[i] = origin[i] + extent[i] - 1 - n_inside - data[tuple(pos)] = n_inside - for n_outside in range(1, n_points + 1 + n_buffer): - for i, dim in enumerate(dims): - if dim in pace.util.HORIZONTAL_DIMS: - pos = [slice(None, None)] * len(dims) - pos[i] = origin[i] - n_outside - data[tuple(pos)] = numpy.nan - pos[i] = origin[i] + extent[i] + n_outside - 1 - data[tuple(pos)] = numpy.nan - quantity = pace.util.Quantity( - data, - dims=dims, - units=units, - origin=origin, - extent=extent, - ) - return quantity - - -@pytest.mark.skipif( - MPI is None, reason="mpi4py is not available or pytest was not run in parallel" -) -def test_depth_halo_update( - depth_quantity, - communicator, - n_points_update, - n_points, - numpy, - subtests, - boundary_dict, - ranks_per_tile, -): - """test that written values have the correct orientation""" - y_dim, x_dim = get_horizontal_dims(depth_quantity.dims) - y_index = depth_quantity.dims.index(y_dim) - x_index = depth_quantity.dims.index(x_dim) - y_extent = depth_quantity.extent[y_index] - x_extent = depth_quantity.extent[x_index] - quantity = depth_quantity - if 0 < n_points_update <= n_points: - communicator.halo_update(quantity, n_points_update) - for dim, extent in ((y_dim, y_extent), (x_dim, x_extent)): - assert numpy.all(quantity.sel(**{dim: -1}) <= 1) - assert numpy.all(quantity.sel(**{dim: extent}) <= 1) - if n_points_update >= 2: - assert numpy.all(quantity.sel(**{dim: -2}) <= 2) - assert numpy.all(quantity.sel(**{dim: extent + 1}) <= 2) - if n_points_update >= 3: - assert numpy.all(quantity.sel(**{dim: -3}) <= 3) - assert numpy.all(quantity.sel(**{dim: extent + 2}) <= 3) - if n_points_update > 3: - raise NotImplementedError(n_points_update) - - -@pytest.fixture -def zeros_quantity(dims, units, origin, extent, shape, numpy, dtype): - """A list of quantities whose values are 0 in the computational domain and 1 - outside of it.""" - data = numpy.ones(shape, dtype=dtype) - quantity = pace.util.Quantity( - data, - dims=dims, - units=units, - origin=origin, - extent=extent, - ) - quantity.view[:] = 0.0 - return quantity - - -@pytest.mark.skipif( - MPI is None, reason="mpi4py is not available or pytest was not run in parallel" -) -def test_zeros_halo_update( - zeros_quantity, - communicator, - n_points_update, - n_points, - numpy, - subtests, - boundary_dict, - ranks_per_tile, -): - """test that zeros from adjacent domains get written over ones on local halo""" - quantity = zeros_quantity - if 0 < n_points_update <= n_points: - communicator.halo_update(quantity, n_points_update) - boundaries = boundary_dict[communicator.rank % ranks_per_tile] - for boundary in boundaries: - boundary_slice = pace.util._boundary_utils.get_boundary_slice( - quantity.dims, - quantity.origin, - quantity.extent, - quantity.data.shape, - boundary, - n_points_update, - interior=False, - ) - with subtests.test( - quantity=quantity, - rank=communicator.rank, - boundary=boundary, - boundary_slice=boundary_slice, - ): - numpy.testing.assert_array_equal( - quantity.data[tuple(boundary_slice)], 0.0 - ) - - -@pytest.mark.skipif( - MPI is None, reason="mpi4py is not available or pytest was not run in parallel" -) -def test_zeros_vector_halo_update( - zeros_quantity, - communicator, - n_points_update, - n_points, - numpy, - subtests, - boundary_dict, - ranks_per_tile, -): - """test that zeros from adjacent domains get written over ones on local halo""" - x_quantity = zeros_quantity - y_quantity = copy.deepcopy(x_quantity) - if 0 < n_points_update <= n_points: - communicator.vector_halo_update(y_quantity, x_quantity, n_points_update) - boundaries = boundary_dict[communicator.rank % ranks_per_tile] - for boundary in boundaries: - boundary_slice = pace.util._boundary_utils.get_boundary_slice( - x_quantity.dims, - x_quantity.origin, - x_quantity.extent, - x_quantity.data.shape, - boundary, - n_points_update, - interior=False, - ) - with subtests.test( - x_quantity=x_quantity, - rank=communicator.rank, - boundary=boundary, - boundary_slice=boundary_slice, - ): - for quantity in y_quantity, x_quantity: - numpy.testing.assert_array_equal( - quantity.data[tuple(boundary_slice)], 0.0 - ) - - -def get_horizontal_dims(dims): - for dim in pace.util.X_DIMS: - if dim in dims: - x_dim = dim - break - else: - raise ValueError(f"no x dimension in {dims}") - for dim in pace.util.Y_DIMS: - if dim in dims: - y_dim = dim - break - else: - raise ValueError(f"no y dimension in {dims}") - return y_dim, x_dim diff --git a/util/tests/mpi/test_mpi_mock.py b/util/tests/mpi/test_mpi_mock.py deleted file mode 100644 index e1efe760f..000000000 --- a/util/tests/mpi/test_mpi_mock.py +++ /dev/null @@ -1,310 +0,0 @@ -import numpy as np -import pytest -from mpi_comm import MPI - -import pace.util - - -worker_function_list = [] - -MAX_WORKER_ITERATIONS = 16 - - -def worker(rank_order=range): - def decorator(func): - func.rank_order = rank_order - worker_function_list.append(func) - return func - - return decorator - - -@worker() -def return_constant(comm): - return 1 - - -@worker() -def send_recv(comm, numpy): - rank = comm.Get_rank() - size = comm.Get_size() - data = numpy.asarray([rank], dtype=numpy.int) - - if rank < size - 1: - if isinstance(comm, pace.util.testing.DummyComm): - print(f"sending data from {rank} to {rank + 1}") - comm.Send(data, dest=rank + 1) - if rank > 0: - if isinstance(comm, pace.util.testing.DummyComm): - print(f"recieving data from {rank - 1} to {rank}") - comm.Recv(data, source=rank - 1) - return data - - -@worker() -def send_recv_big_data(comm, numpy): - rank = comm.Get_rank() - size = comm.Get_size() - data = numpy.ones([5, 3, 96], dtype=numpy.float64) * rank - - if rank < size - 1: - if isinstance(comm, pace.util.testing.DummyComm): - print(f"sending data from {rank} to {rank + 1}") - comm.Send(data, dest=rank + 1) - if rank > 0: - if isinstance(comm, pace.util.testing.DummyComm): - print(f"recieving data from {rank - 1} to {rank}") - comm.Recv(data, source=rank - 1) - return data - - -def data_send(data, to_rank): - new_array = data.copy() - return comm.Isend(new_array, dest=to_rank, tag=0) - - -@worker() -def send_recv_multiple_async_calls(comm, numpy): - rank = comm.Get_rank() - size = comm.Get_size() - shape = [50, 3, 48] - data = numpy.ones(shape, dtype=numpy.float64) * rank - recv_data = numpy.zeros([size] + shape, dtype=numpy.float64) - 1 - - req_list = [] - - for to_rank in range(size): - if to_rank != rank: - req_list.append(data_send(data, dest=to_rank)) - - for from_rank in range(size): - if from_rank != rank: - with pace.util.recv_buffer(numpy, recv_data[from_rank, :]) as recvbuf: - comm.Recv(recvbuf, source=from_rank, tag=0) - for req in req_list: - req.wait() - return recv_data - - -@worker() -def send_f_contiguous_buffer(comm, numpy): - rank = comm.Get_rank() - size = comm.Get_size() - numpy.random.seed(rank) - data = numpy.random.uniform(size=[2, 3]).T - - if rank < size - 1: - if isinstance(comm, pace.util.testing.DummyComm): - print(f"sending data from {rank} to {rank + 1}") - comm.Send(data, dest=rank + 1) - if rank > 0: - if isinstance(comm, pace.util.testing.DummyComm): - print(f"recieving data from {rank - 1} to {rank}") - comm.Recv(data, source=rank - 1) - return data - - -@worker() -def send_non_contiguous_buffer(comm, numpy): - rank = comm.Get_rank() - size = comm.Get_size() - numpy.random.seed(rank) - data = numpy.random.uniform(size=[2, 3, 4]).transpose(2, 0, 1) - recv_buffer = numpy.zeros([4, 2, 3]) - - if rank < size - 1: - if isinstance(comm, pace.util.testing.DummyComm): - print(f"sending data from {rank} to {rank + 1}") - comm.Send(data, dest=rank + 1) - if rank > 0: - pass # sends will raise exceptions, so we don't want to recv - return recv_buffer - - -@worker() -def send_subarray(comm, numpy): - rank = comm.Get_rank() - size = comm.Get_size() - numpy.random.seed(rank) - data = numpy.random.uniform(size=[4, 4, 4]) - recv_buffer = numpy.zeros([2, 2, 2]) - - if rank < size - 1: - if isinstance(comm, pace.util.testing.DummyComm): - print(f"sending data from {rank} to {rank + 1}") - comm.Send(data[1:-1, 1:-1, 1:-1], dest=rank + 1) - if rank > 0: - pass # sends will raise exceptions, so we don't want to recv - return recv_buffer - - -@worker() -def recv_to_subarray(comm, numpy): - rank = comm.Get_rank() - size = comm.Get_size() - numpy.random.seed(rank) - data = numpy.random.uniform(size=[2, 2, 2]) - recv_buffer = numpy.zeros([4, 4, 4]) - contiguous_recv_buffer = numpy.zeros([2, 2, 2]) - return_value = recv_buffer - - if rank < size - 1: - if isinstance(comm, pace.util.testing.DummyComm): - print(f"sending data from {rank} to {rank + 1}") - comm.Send(data, dest=rank + 1) - if rank > 0: - if isinstance(comm, pace.util.testing.DummyComm): - print(f"recieving data from {rank - 1} to {rank}") - try: - comm.Recv(recv_buffer[1:-1, 1:-1, 1:-1], source=rank - 1) - except Exception as err: - return_value = err - # must complete the MPI transaction for politeness to subsequent tests - comm.Recv(contiguous_recv_buffer, source=rank - 1) - return return_value - - -@worker() -def scatter(comm, numpy): - rank = comm.Get_rank() - size = comm.Get_size() - recvbuf = numpy.array([-1]) - if rank == 0: - data = numpy.arange(size)[:, None] - else: - data = None - comm.Scatter(data, recvbuf) - assert recvbuf[0] == rank - return recvbuf - - -@worker(rank_order=lambda total_ranks: range(total_ranks - 1, -1, -1)) -def gather(comm, numpy): - rank = comm.Get_rank() - size = comm.Get_size() - sendbuf = numpy.array([rank]) - if rank == 0: - recvbuf = numpy.ones([size], dtype=sendbuf.dtype)[:, None] * -1 - else: - recvbuf = None - comm.Gather(sendbuf, recvbuf) - if rank == 0: - assert numpy.all(recvbuf == numpy.arange(size)[:, None]) - return list(recvbuf) - else: - return recvbuf - - -@worker() -def isend_irecv(comm, numpy): - rank = comm.Get_rank() - size = comm.Get_size() - data = numpy.asarray([rank], dtype=numpy.int) - if rank < size - 1: - req = comm.Isend(data, dest=(rank + 1) % size) - req.wait() - if rank > 0: - req = comm.Irecv(data, source=(rank - 1) % size) - req.wait() - return data - - -@worker() -def asynchronous_and_synchronous_send_recv(comm, numpy): - rank = comm.Get_rank() - size = comm.Get_size() - data_async = numpy.asarray([rank], dtype=numpy.int) - data_sync = numpy.asarray([-rank], dtype=numpy.int) - if rank < size - 1: - req = comm.Isend(data_async, dest=(rank + 1) % size) - req.wait() - comm.Send(data_sync, dest=(rank + 1) % size) - if rank > 0: - comm.Recv(data_sync, source=(rank - 1) % size) - req = comm.Irecv(data_async, source=(rank - 1) % size) - req.wait() - return (data_async, data_sync) - - -@pytest.fixture(params=worker_function_list) -def worker_function(request): - return request.param - - -def gather_decorator(worker_function): - def wrapped(comm, numpy): - try: - result = worker_function(comm, numpy) - except Exception as err: - result = err - return comm.gather(result, root=0) - - return wrapped - - -@pytest.fixture -def total_ranks(): - return MPI.COMM_WORLD.Get_size() - - -@pytest.fixture -def dummy_list(total_ranks): - shared_buffer = {} - return_list = [] - for rank in range(total_ranks): - return_list.append( - pace.util.testing.DummyComm( - rank=rank, total_ranks=total_ranks, buffer_dict=shared_buffer - ) - ) - return return_list - - -@pytest.fixture -def comm(worker_function, total_ranks): - return MPI.COMM_WORLD - - -@pytest.fixture -def mpi_results(comm, worker_function, numpy): - return gather_decorator(worker_function)(comm, numpy) - - -@pytest.fixture -def dummy_results(worker_function, dummy_list, numpy): - print("Getting dummy results") - result_list = [None] * len(dummy_list) - done = False - iter_count = 0 - while not done: - iter_count += 1 - done = True - for i in worker_function.rank_order(len(dummy_list)): - comm = dummy_list[i] - try: - result_list[i] = worker_function(comm, numpy) - except pace.util.testing.ConcurrencyError as err: - if iter_count >= MAX_WORKER_ITERATIONS: - result_list[i] = err - else: - done = False - except Exception as err: - result_list[i] = err - return result_list - - -@pytest.mark.skipif( - MPI is None, reason="mpi4py is not available or pytest was not run in parallel" -) -def test_worker(comm, dummy_results, mpi_results, numpy): - comm.barrier() # synchronize the test "dots" across ranks - if comm.Get_rank() == 0: - assert len(dummy_results) == len(mpi_results) - for dummy, mpi in zip(dummy_results, mpi_results): - if isinstance(mpi, numpy.ndarray): - numpy.testing.assert_array_equal(np.asarray(dummy), np.asarray(mpi)) - elif isinstance(mpi, Exception): - assert type(dummy) == type(mpi) - assert dummy.args == mpi.args - else: - assert dummy == mpi diff --git a/util/tests/quantity/test_boundary.py b/util/tests/quantity/test_boundary.py deleted file mode 100644 index 9f818f343..000000000 --- a/util/tests/quantity/test_boundary.py +++ /dev/null @@ -1,257 +0,0 @@ -import numpy as np -import pytest - -import pace.util -from pace.util._boundary_utils import _shift_boundary_slice, get_boundary_slice - - -def boundary_data(quantity, boundary_type, n_points, interior=True): - boundary_slice = get_boundary_slice( - quantity.dims, - quantity.origin, - quantity.extent, - quantity.data.shape, - boundary_type, - n_points, - interior, - ) - return quantity.data[tuple(boundary_slice)] - - -@pytest.mark.cpu_only -def test_boundary_data_1_by_1_array_1_halo(): - quantity = pace.util.Quantity( - np.random.randn(3, 3), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ) - for side in ( - pace.util.WEST, - pace.util.EAST, - pace.util.NORTH, - pace.util.SOUTH, - ): - assert ( - boundary_data(quantity, side, n_points=1, interior=True) - == quantity.data[1, 1] - ) - - assert ( - boundary_data(quantity, pace.util.NORTH, n_points=1, interior=False) - == quantity.data[2, 1] - ) - assert ( - boundary_data(quantity, pace.util.SOUTH, n_points=1, interior=False) - == quantity.data[0, 1] - ) - assert ( - boundary_data(quantity, pace.util.WEST, n_points=1, interior=False) - == quantity.data[1, 0] - ) - assert ( - boundary_data(quantity, pace.util.EAST, n_points=1, interior=False) - == quantity.data[1, 2] - ) - - -def test_boundary_data_3d_array_1_halo_z_offset_origin(numpy): - quantity = pace.util.Quantity( - numpy.random.randn(2, 3, 3), - dims=[pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], - units="m", - origin=(1, 1, 1), - extent=(1, 1, 1), - ) - for side in ( - pace.util.WEST, - pace.util.EAST, - pace.util.NORTH, - pace.util.SOUTH, - ): - quantity.np.testing.assert_array_equal( - boundary_data(quantity, side, n_points=1, interior=True), - quantity.data[1, 1, 1], - ) - - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.NORTH, n_points=1, interior=False), - quantity.data[1, 2, 1], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.SOUTH, n_points=1, interior=False), - quantity.data[1, 0, 1], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.WEST, n_points=1, interior=False), - quantity.data[1, 1, 0], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.EAST, n_points=1, interior=False), - quantity.data[1, 1, 2], - ) - - -@pytest.mark.cpu_only -def test_boundary_data_2_by_2_array_2_halo(): - quantity = pace.util.Quantity( - np.random.randn(6, 6), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="m", - origin=(2, 2), - extent=(2, 2), - ) - for side in ( - pace.util.WEST, - pace.util.EAST, - pace.util.NORTH, - pace.util.SOUTH, - ): - np.testing.assert_array_equal( - boundary_data(quantity, side, n_points=2, interior=True), - quantity.data[2:4, 2:4], - ) - - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.NORTH, n_points=1, interior=True), - quantity.data[3:4, 2:4], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.NORTH, n_points=1, interior=False), - quantity.data[4:5, 2:4], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.NORTH, n_points=2, interior=False), - quantity.data[4:6, 2:4], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.SOUTH, n_points=1, interior=True), - quantity.data[2:3, 2:4], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.SOUTH, n_points=1, interior=False), - quantity.data[1:2, 2:4], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.SOUTH, n_points=2, interior=False), - quantity.data[0:2, 2:4], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.WEST, n_points=2, interior=False), - quantity.data[2:4, 0:2], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.WEST, n_points=1, interior=True), - quantity.data[2:4, 2:3], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.WEST, n_points=1, interior=False), - quantity.data[2:4, 1:2], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.EAST, n_points=1, interior=False), - quantity.data[2:4, 4:5], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.EAST, n_points=2, interior=False), - quantity.data[2:4, 4:6], - ) - quantity.np.testing.assert_array_equal( - boundary_data(quantity, pace.util.EAST, n_points=1, interior=True), - quantity.data[2:4, 3:4], - ) - - -@pytest.mark.parametrize( - "dim, origin, extent, boundary_type, slice_object, reference", - [ - pytest.param( - pace.util.X_DIM, - 1, - 3, - pace.util.WEST, - slice(None, None), - slice(1, 4), - id="none_is_changed", - ), - pytest.param( - pace.util.Y_DIM, - 1, - 3, - pace.util.WEST, - slice(None, None), - slice(1, 4), - id="perpendicular_none_is_changed", - ), - pytest.param( - pace.util.X_DIM, - 1, - 3, - pace.util.WEST, - slice(0, 1), - slice(1, 2), - id="shift_to_start", - ), - pytest.param( - pace.util.X_DIM, - 1, - 3, - pace.util.WEST, - slice(0, 2), - slice(1, 3), - id="shift_larger_to_start", - ), - pytest.param( - pace.util.X_DIM, - 1, - 3, - pace.util.EAST, - slice(0, 1), - slice(4, 5), - id="shift_to_end", - ), - pytest.param( - pace.util.X_INTERFACE_DIM, - 1, - 3, - pace.util.WEST, - slice(0, 1), - slice(1, 2), - id="shift_interface_to_start", - ), - pytest.param( - pace.util.X_INTERFACE_DIM, - 1, - 3, - pace.util.EAST, - slice(0, 1), - slice(4, 5), - id="shift_interface_to_end", - ), - pytest.param( - pace.util.Y_DIM, - 2, - 4, - pace.util.SOUTH, - slice(0, 1), - slice(2, 3), - id="shift_y_to_start", - ), - pytest.param( - pace.util.Y_DIM, - 2, - 4, - pace.util.NORTH, - slice(0, 1), - slice(6, 7), - id="shift_y_to_end", - ), - ], -) -@pytest.mark.cpu_only -def test_shift_boundary_slice( - dim, origin, extent, boundary_type, slice_object, reference -): - result = _shift_boundary_slice(dim, origin, extent, boundary_type, slice_object) - assert result == reference diff --git a/util/tests/quantity/test_corners.py b/util/tests/quantity/test_corners.py deleted file mode 100644 index 0b922b49e..000000000 --- a/util/tests/quantity/test_corners.py +++ /dev/null @@ -1,320 +0,0 @@ -import numpy as np -import pytest - -import pace.util - - -@pytest.fixture -def units(): - return "m" - - -@pytest.fixture -def dims(request): - return [pace.util.X_DIM, pace.util.Y_DIM] - - -@pytest.fixture -def shape(request): - return request.param - - -@pytest.fixture -def origin(request): - return request.param - - -@pytest.fixture -def extent(request): - return request.param - - -@pytest.fixture -def layout(request): - return request.param - - -@pytest.fixture -def quantity(shape, dims, units, origin, extent, numpy): - return pace.util.Quantity( - numpy.zeros(shape), dims=dims, units=units, origin=origin, extent=extent - ) - - -@pytest.fixture -def tile_partitioner(layout): - return pace.util.TilePartitioner(layout) - - -@pytest.fixture -def rank(request): - return request.param - - -@pytest.mark.parametrize( - "shape, origin, extent, n_halo", - [ - ((6, 6), (2, 2), (2, 2), 2), - ((6, 6), (2, 2), (2, 2), 1), - ((3, 3), (1, 1), (1, 1), 1), - ((6, 6), (3, 2), (2, 2), 1), - ], - indirect=["shape", "origin", "extent"], -) -@pytest.mark.parametrize("rank, layout", [(0, (1, 1))]) -@pytest.mark.parametrize("direction", ["x", "y"]) -def test_fill_scalar_corners_copies_from_halo( - quantity, direction, tile_partitioner, rank, n_halo -): - quantity.data[:] = 0 - # put nans in corners - quantity.view.southwest[-n_halo:0, -n_halo:0] = quantity.np.nan - quantity.view.southeast[0:n_halo, -n_halo:0] = quantity.np.nan - quantity.view.northwest[-n_halo:0, 0:n_halo] = quantity.np.nan - quantity.view.northeast[0:n_halo, 0:n_halo] = quantity.np.nan - quantity.view[:] = 2 - pace.util.fill_scalar_corners( - quantity=quantity, - direction=direction, - tile_partitioner=tile_partitioner, - rank=rank, - n_halo=n_halo, - ) - assert quantity.np.sum(quantity.np.isnan(quantity.data)) == 0 - assert quantity.np.all(quantity.view[:] == 2) # should be unchanged - quantity.np.testing.assert_array_equal( - quantity.view.southwest[-n_halo:0, -n_halo:0], 0 - ) - quantity.np.testing.assert_array_equal( - quantity.view.southeast[0:n_halo, -n_halo:0], 0 - ) - quantity.np.testing.assert_array_equal( - quantity.view.northwest[-n_halo:0, 0:n_halo], 0 - ) - quantity.np.testing.assert_array_equal( - quantity.view.northeast[0:n_halo, 0:n_halo], 0 - ) - - -@pytest.mark.parametrize( - "quantity_in, direction, layout, rank, n_halo, reference", - [ - pytest.param( - pace.util.Quantity( - np.array( - [ - [0, 1, 2, 3, 4, 5], - [6, 7, 8, 9, 10, 11], - [12, 13, 14, 15, 16, 17], - [18, 19, 20, 21, 22, 23], - [24, 25, 26, 27, 28, 29], - [30, 31, 32, 33, 34, 35], - ] - ).T, - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(2, 2), - extent=(2, 2), - ), - "x", - (1, 1), - 1, - 2, - np.array( - [ - [18, 12, 2, 3, 17, 23], - [19, 13, 8, 9, 16, 22], - [12, 13, 14, 15, 16, 17], - [18, 19, 20, 21, 22, 23], - [13, 19, 26, 27, 22, 16], - [12, 18, 32, 33, 23, 17], - ] - ).T, - id="all_corners_x", - ), - pytest.param( - pace.util.Quantity( - np.array( - [ - [0, 1, 2, 0, 3, 4, 5], - [6, 7, 8, 1, 9, 10, 11], - [12, 13, 14, 2, 15, 16, 17], - [0, 1, 2, 3, 4, 5, 6], - [18, 19, 20, 4, 21, 22, 23], - [24, 25, 26, 5, 27, 28, 29], - [30, 31, 32, 6, 33, 34, 35], - ] - ).T, - dims=[pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], - units="m", - origin=(2, 2), - extent=(3, 3), - ), - "x", - (1, 1), - 1, - 2, - np.array( - [ - [18, 0, 2, 0, 3, 6, 23], - [19, 1, 8, 1, 9, 5, 22], - [12, 13, 14, 2, 15, 16, 17], - [0, 1, 2, 3, 4, 5, 6], - [18, 19, 20, 4, 21, 22, 23], - [13, 1, 26, 5, 27, 5, 16], - [12, 0, 32, 6, 33, 6, 17], - ] - ).T, - id="all_corners_x_interfaces", - ), - pytest.param( - pace.util.Quantity( - np.array( - [ - [0, 1, 2, 3, 4, 5], - [6, 7, 8, 9, 10, 11], - [12, 13, 14, 15, 16, 17], - [0, 1, 2, 4, 5, 6], - [18, 19, 20, 21, 22, 23], - [24, 25, 26, 27, 28, 29], - [30, 31, 32, 33, 34, 35], - ] - ).T, - dims=[pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], - units="m", - origin=(2, 2), - extent=(2, 3), - ), - "x", - (1, 1), - 1, - 2, - np.array( - [ - [18, 0, 2, 3, 6, 23], - [19, 1, 8, 9, 5, 22], - [12, 13, 14, 15, 16, 17], - [0, 1, 2, 4, 5, 6], - [18, 19, 20, 21, 22, 23], - [13, 1, 26, 27, 5, 16], - [12, 0, 32, 33, 6, 17], - ] - ).T, - id="all_corners_x_one_iface_dim", - ), - pytest.param( - pace.util.Quantity( - np.array( - [ - [0, 1, 2, 0, 3, 4, 5], - [6, 7, 8, 1, 9, 10, 11], - [12, 13, 14, 2, 15, 16, 17], - [0, 1, 2, 3, 4, 5, 6], - [18, 19, 20, 4, 21, 22, 23], - [24, 25, 26, 5, 27, 28, 29], - [30, 31, 32, 6, 33, 34, 35], - ] - ).T, - dims=[pace.util.X_INTERFACE_DIM, pace.util.Y_INTERFACE_DIM], - units="m", - origin=(2, 2), - extent=(3, 3), - ), - "y", - (1, 1), - 1, - 2, - np.array( - [ - [3, 9, 2, 0, 3, 8, 2], - [0, 1, 8, 1, 9, 1, 0], - [12, 13, 14, 2, 15, 16, 17], - [0, 1, 2, 3, 4, 5, 6], - [18, 19, 20, 4, 21, 22, 23], - [6, 5, 26, 5, 27, 5, 6], - [33, 27, 32, 6, 33, 26, 32], - ] - ).T, - id="all_corners_y_interfaces", - ), - pytest.param( - pace.util.Quantity( - np.array( - [ - [0, 1, 2, 3, 4, 5], - [6, 7, 8, 9, 10, 11], - [12, 13, 14, 15, 16, 17], - [18, 19, 20, 21, 22, 23], - [24, 25, 26, 27, 28, 29], - [30, 31, 32, 33, 34, 35], - ] - ).T, - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(2, 2), - extent=(2, 2), - ), - "x", - (2, 2), - 2, - 2, - np.array( - [ - [0, 1, 2, 3, 4, 5], - [6, 7, 8, 9, 10, 11], - [12, 13, 14, 15, 16, 17], - [18, 19, 20, 21, 22, 23], - [13, 19, 26, 27, 28, 29], - [12, 18, 32, 33, 34, 35], - ] - ).T, - id="one_corner_x", - ), - pytest.param( - pace.util.Quantity( - np.array( - [ - [0, 1, 2, 3, 4, 5], - [6, 7, 8, 9, 10, 11], - [12, 13, 14, 15, 16, 17], - [18, 19, 20, 21, 22, 23], - [24, 25, 26, 27, 28, 29], - [30, 31, 32, 33, 34, 35], - ] - ).T, - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(2, 2), - extent=(2, 2), - ), - "y", - (1, 1), - 1, - 2, - np.array( - [ - [3, 9, 2, 3, 8, 2], - [2, 8, 8, 9, 9, 3], - [12, 13, 14, 15, 16, 17], - [18, 19, 20, 21, 22, 23], - [32, 26, 26, 27, 27, 33], - [33, 27, 32, 33, 26, 32], - ] - ).T, - id="all_corners_y", - ), - ], - indirect=["layout"], -) -@pytest.mark.cpu_only -def test_fill_corners( - quantity_in, direction, tile_partitioner, rank, n_halo, reference -): - pace.util.fill_scalar_corners( - quantity=quantity_in, - direction=direction, - tile_partitioner=tile_partitioner, - rank=rank, - n_halo=n_halo, - ) - quantity_in.np.testing.assert_array_equal(quantity_in.data, reference) diff --git a/util/tests/quantity/test_deepcopy.py b/util/tests/quantity/test_deepcopy.py deleted file mode 100644 index 502bd000f..000000000 --- a/util/tests/quantity/test_deepcopy.py +++ /dev/null @@ -1,63 +0,0 @@ -import copy -import dataclasses - -import numpy as np - -import pace.util - - -def test_deepcopy_copy_is_editable_by_view(): - nx, ny, nz = 12, 12, 15 - quantity = pace.util.Quantity( - np.zeros([nx, ny, nz]), - origin=(0, 0, 0), - extent=(nx, ny, nz), - dims=["x", "y", "z"], - units="", - ) - quantity_copy = copy.deepcopy(quantity) - # assertion below is only valid if we're overwriting the entire data through view - assert np.product(quantity_copy.view[:].shape) == np.product( - quantity_copy.data.shape - ) - quantity_copy.view[:] = 1.0 - np.testing.assert_array_equal(quantity.data, 0.0) - np.testing.assert_array_equal(quantity_copy.data, 1.0) - - -def test_deepcopy_copy_is_editable_by_data(): - nx, ny, nz = 12, 12, 15 - quantity = pace.util.Quantity( - np.zeros([nx, ny, nz]), - origin=(0, 0, 0), - extent=(nx, ny, nz), - dims=["x", "y", "z"], - units="", - ) - quantity_copy = copy.deepcopy(quantity) - quantity_copy.data[:] = 1.0 - np.testing.assert_array_equal(quantity.data, 0.0) - np.testing.assert_array_equal(quantity_copy.data, 1.0) - - -def test_deepcopy_of_dataclass_is_editable_by_data(): - nx, ny, nz = 12, 12, 15 - quantity = pace.util.Quantity( - np.zeros([nx, ny, nz]), - origin=(0, 0, 0), - extent=(nx, ny, nz), - dims=["x", "y", "z"], - units="", - ) - quantity_copy = copy.deepcopy(quantity) - quantity_copy.data[:] = 1.0 - - @dataclasses.dataclass - class MyClass: - quantity: pace.util.Quantity - - instance = MyClass(quantity) - instance_copy = copy.deepcopy(instance) - instance_copy.quantity.data[:] = 1.0 - np.testing.assert_array_equal(instance.quantity.data, 0.0) - np.testing.assert_array_equal(instance_copy.quantity.data, 1.0) diff --git a/util/tests/quantity/test_quantity.py b/util/tests/quantity/test_quantity.py deleted file mode 100644 index 051e244d0..000000000 --- a/util/tests/quantity/test_quantity.py +++ /dev/null @@ -1,280 +0,0 @@ -import numpy as np -import pytest - -import pace.util -import pace.util.quantity - - -try: - import xarray as xr -except ModuleNotFoundError: - xr = None - -requires_xarray = pytest.mark.skipif(xr is None, reason="xarray is not installed") - - -@pytest.fixture(params=["empty", "one", "five"]) -def extent_1d(request, backend, n_halo): - if request.param == "empty": - if "gt4py" in backend and n_halo == 0: - pytest.skip("gt4py does not support length-zero dimensions") - else: - return 0 - elif request.param == "one": - return 1 - elif request.param == "five": - return 5 - - -@pytest.fixture(params=[0, 1, 3]) -def n_halo(request): - return request.param - - -@pytest.fixture(params=[1, 2]) -def n_dims(request): - return request.param - - -@pytest.fixture -def extent(extent_1d, n_dims): - return (extent_1d,) * n_dims - - -@pytest.fixture -def dtype(numpy): - return numpy.float64 - - -@pytest.fixture -def units(): - return "m" - - -@pytest.fixture -def dims(n_dims): - return tuple(f"dimension_{dim}" for dim in range(n_dims)) - - -@pytest.fixture -def origin(n_halo, n_dims): - return (n_halo,) * n_dims - - -@pytest.fixture -def data(n_halo, extent_1d, n_dims, numpy, dtype): - shape = (n_halo * 2 + extent_1d,) * n_dims - return numpy.empty(shape, dtype=dtype) - - -@pytest.fixture -def quantity(data, origin, extent, dims, units): - return pace.util.Quantity( - data, origin=origin, extent=extent, dims=dims, units=units - ) - - -def test_smaller_data_raises(data, origin, extent, dims, units): - if len(data.shape) > 1: - try: - small_data = data[0] - except IndexError: - pass - else: - with pytest.raises(ValueError): - pace.util.Quantity( - small_data, origin=origin, extent=extent, dims=dims, units=units - ) - - -def test_smaller_dims_raises(data, origin, extent, dims, units): - with pytest.raises(ValueError): - pace.util.Quantity( - data, origin=origin, extent=extent, dims=dims[:-1], units=units - ) - - -def test_smaller_origin_raises(data, origin, extent, dims, units): - with pytest.raises(ValueError): - pace.util.Quantity( - data, origin=origin[:-1], extent=extent, dims=dims, units=units - ) - - -def test_smaller_extent_raises(data, origin, extent, dims, units): - with pytest.raises(ValueError): - pace.util.Quantity( - data, origin=origin, extent=extent[:-1], dims=dims, units=units - ) - - -def test_data_change_affects_quantity(data, quantity, numpy): - data[:] = 5.0 - numpy.testing.assert_array_equal(quantity.data, 5.0) - - -def test_quantity_units(quantity, units): - assert quantity.units == units - assert quantity.attrs["units"] == units - - -def test_quantity_dims(quantity, dims): - assert quantity.dims == dims - - -def test_quantity_origin(quantity, origin): - assert quantity.origin == origin - - -def test_quantity_extent(quantity, extent): - assert quantity.extent == extent - - -def test_compute_view_get_value(quantity, extent_1d, n_halo, n_dims): - quantity.data[:] = 0.0 - if extent_1d == 0 and n_halo == 0: - with pytest.raises(IndexError): - quantity.view[[0] * n_dims] - else: - value = quantity.view[[0] * n_dims] - assert value.shape == () - - -def test_compute_view_edit_start_halo(quantity, extent_1d, n_halo, n_dims): - quantity.data[:] = 0.0 - if extent_1d == 0 and n_halo == 0: - with pytest.raises(IndexError): - quantity.view[[-1] * n_dims] = 1 - else: - quantity.view[[-1] * n_dims] = 1 - assert quantity.np.sum(quantity.data) == 1.0 - assert quantity.data[(n_halo - 1,) * n_dims] == 1 - - -def test_compute_view_edit_end_halo(quantity, extent_1d, n_halo, n_dims): - quantity.data[:] = 0.0 - if n_halo == 0: - with pytest.raises(IndexError): - quantity.view[[extent_1d] * n_dims] = 1 - else: - quantity.view[(extent_1d,) * n_dims] = 1 - assert quantity.np.sum(quantity.data) == 1.0 - assert quantity.data[(n_halo + extent_1d,) * n_dims] == 1 - - -def test_compute_view_edit_start_of_domain(quantity, extent_1d, n_halo, n_dims): - if extent_1d == 0: - pytest.skip("cannot edit an empty domain") - quantity.data[:] = 0.0 - quantity.view[(0,) * n_dims] = 1 - assert quantity.data[(n_halo,) * n_dims] == 1 - assert quantity.np.sum(quantity.data) == 1.0 - - -def test_compute_view_edit_all_domain(quantity, n_halo, n_dims, extent_1d): - if extent_1d == 0: - pytest.skip("cannot edit an empty domain") - quantity.data[:] = 0.0 - quantity.view[:] = 1 - assert quantity.np.sum(quantity.data) == extent_1d ** n_dims - if n_dims > 1: - quantity.np.testing.assert_array_equal(quantity.data[:n_halo, :], 0.0) - quantity.np.testing.assert_array_equal( - quantity.data[n_halo + extent_1d :, :], 0.0 - ) - else: - quantity.np.testing.assert_array_equal(quantity.data[:n_halo], 0.0) - quantity.np.testing.assert_array_equal(quantity.data[n_halo + extent_1d :], 0.0) - - -@pytest.mark.parametrize( - "slice_in, shift, extent, slice_out", - [ - pytest.param(slice(0, 1), 0, 1, slice(0, 1), id="zero_shift"), - pytest.param(slice(None, None), 1, 1, slice(None, None), id="shift_none_slice"), - pytest.param( - slice(None, 5), - -1, - 5, - slice(None, 4), - id="shift_none_start", - ), - pytest.param( - slice(-3, None), - 0, - 5, - slice(2, None), - id="negative_start", - ), - pytest.param( - slice(-3, None), - 1, - 5, - slice(3, None), - id="shift_negative_start", - ), - pytest.param( - slice(None, -1), - 0, - 5, - slice(None, 4), - id="negative_end", - ), - pytest.param( - slice(0, -1), - 0, - 5, - slice(0, 4), - id="negative_end_with_none", - ), - pytest.param( - slice(2, -2), - 1, - 5, - slice(3, 4), - id="shift_negative_end", - ), - ], -) -def test_shift_slice(slice_in, shift, extent, slice_out): - result = pace.util.quantity.shift_slice(slice_in, shift, extent) - assert result == slice_out - - -@pytest.mark.parametrize( - "quantity", - [ - pace.util.Quantity( - np.array(5), - dims=[], - units="", - ), - pace.util.Quantity( - np.array([1, 2, 3]), - dims=["dimension"], - units="degK", - ), - pace.util.Quantity( - np.random.randn(3, 2, 4), - dims=["dim1", "dim_2", "dimension_3"], - units="m", - ), - pace.util.Quantity( - np.random.randn(8, 6, 6), - dims=["dim1", "dim_2", "dimension_3"], - units="km", - origin=(2, 2, 2), - extent=(4, 2, 2), - ), - ], -) -@requires_xarray -def test_to_data_array(quantity): - assert quantity.data_array.attrs == quantity.attrs - assert quantity.data_array.dims == quantity.dims - assert quantity.data_array.shape == quantity.extent - np.testing.assert_array_equal(quantity.data_array.values, quantity.view[:]) - if quantity.extent == quantity.data.shape: - assert ( - quantity.data_array.data.ctypes.data == quantity.data.ctypes.data - ), "data memory address is not equal" diff --git a/util/tests/quantity/test_storage.py b/util/tests/quantity/test_storage.py deleted file mode 100644 index a92e6a859..000000000 --- a/util/tests/quantity/test_storage.py +++ /dev/null @@ -1,139 +0,0 @@ -import numpy as np -import pytest - -import pace.util - - -try: - import gt4py -except ImportError: - gt4py = None -try: - import cupy as cp -except ImportError: - cp = None - - -@pytest.fixture -def extent_1d(): - return 5 - - -@pytest.fixture(params=[0, 3]) -def n_halo(request): - return request.param - - -@pytest.fixture(params=[3]) -def n_dims(request): - return request.param - - -@pytest.fixture -def extent(extent_1d, n_dims): - return (extent_1d,) * n_dims - - -@pytest.fixture -def dtype(numpy): - return numpy.float64 - - -@pytest.fixture -def units(): - return "m" - - -@pytest.fixture -def dims(n_dims): - return tuple(f"dimension_{dim}" for dim in range(n_dims)) - - -@pytest.fixture -def origin(n_halo, n_dims): - return (n_halo,) * n_dims - - -@pytest.fixture -def data(n_halo, extent_1d, n_dims, numpy, dtype): - shape = (n_halo * 2 + extent_1d,) * n_dims - return numpy.zeros(shape, dtype=dtype) - - -@pytest.fixture -def quantity(data, origin, extent, dims, units): - return pace.util.Quantity( - data, origin=origin, extent=extent, dims=dims, units=units - ) - - -def test_numpy(quantity, backend): - if "cupy" in backend: - assert quantity.np is cp - else: - assert quantity.np is np - - -@pytest.mark.skipif(gt4py is None, reason="requires gt4py") -def test_modifying_numpy_data_modifies_view(): - shape = (6, 6) - data = np.zeros(shape, dtype=float) - quantity = pace.util.Quantity( - data, - origin=(0, 0), - extent=shape, - dims=["dim1", "dim2"], - units="units", - gt4py_backend="numpy", - ) - assert np.all(quantity.data == 0) - quantity.data[0, 0] = 1 - quantity.data[2, 2] = 5 - quantity.data[4, 4] = 3 - assert quantity.view[0, 0] == 1 - assert quantity.view[2, 2] == 5 - assert quantity.view[4, 4] == 3 - assert quantity.data[0, 0] == 1 - assert quantity.data[2, 2] == 5 - assert quantity.data[4, 4] == 3 - - -@pytest.mark.parametrize("backend", ["gt4py_numpy", "gt4py_cupy"], indirect=True) -def test_data_exists(quantity, backend): - if "numpy" in backend: - assert isinstance(quantity.data, np.ndarray) - else: - assert isinstance(quantity.data, cp.ndarray) - - -@pytest.mark.parametrize("backend", ["numpy", "cupy"], indirect=True) -def test_accessing_data_does_not_break_view( - data, origin, extent, dims, units, gt4py_backend -): - quantity = pace.util.Quantity( - data, - origin=origin, - extent=extent, - dims=dims, - units=units, - gt4py_backend=gt4py_backend, - ) - quantity.data[origin] = -1.0 - assert quantity.data[origin] == quantity.view[tuple(0 for _ in origin)] - - -# run using cupy backend even though unused, to mark this as a "gpu" test -@pytest.mark.parametrize("backend", ["cupy"], indirect=True) -def test_numpy_data_becomes_cupy_with_gpu_backend( - data, origin, extent, dims, units, gt4py_backend -): - cpu_data = np.zeros(data.shape) - quantity = pace.util.Quantity( - cpu_data, - origin=origin, - extent=extent, - dims=dims, - units=units, - gt4py_backend=gt4py_backend, - ) - assert isinstance(quantity.data, cp.ndarray) diff --git a/util/tests/quantity/test_transpose.py b/util/tests/quantity/test_transpose.py deleted file mode 100644 index 164c7dee7..000000000 --- a/util/tests/quantity/test_transpose.py +++ /dev/null @@ -1,213 +0,0 @@ -import pytest - -import pace.util - - -@pytest.fixture -def initial_dims(request): - return request.param - - -@pytest.fixture -def initial_shape(request): - return request.param - - -@pytest.fixture -def initial_data(initial_shape, numpy): - return numpy.random.randn(*initial_shape) - - -@pytest.fixture -def quantity_data_input(initial_data, numpy, backend): - if "gt4py" in backend: - array = numpy.empty(initial_data.shape) - array[:] = initial_data - else: - array = initial_data - print(type(array)) - return array - - -@pytest.fixture -def initial_origin(request): - return request.param - - -@pytest.fixture -def initial_extent(request): - return request.param - - -@pytest.fixture -def transpose_order(request): - return request.param - - -@pytest.fixture -def target_dims(request): - return request.param - - -@pytest.fixture -def final_dims(initial_dims, transpose_order): - return tuple(initial_dims[index] for index in transpose_order) - - -@pytest.fixture -def final_origin(initial_origin, transpose_order): - return tuple(initial_origin[index] for index in transpose_order) - - -@pytest.fixture -def final_extent(initial_extent, transpose_order): - return tuple(initial_extent[index] for index in transpose_order) - - -@pytest.fixture -def final_data(initial_data, transpose_order, numpy): - return numpy.transpose(initial_data, transpose_order) - - -@pytest.fixture -def quantity(quantity_data_input, initial_dims, initial_origin, initial_extent): - return pace.util.Quantity( - quantity_data_input, - dims=initial_dims, - units="unit_string", - origin=initial_origin, - extent=initial_extent, - ) - - -def param_product(*param_lists): - return_list = [] - if len(param_lists) == 0: - return [[]] - else: - for item in param_lists[0]: - for later_items in param_product(*param_lists[1:]): - return_list.append([item] + later_items) - return return_list - - -@pytest.mark.parametrize( - ( - "initial_dims, initial_shape, initial_origin, " - "initial_extent, target_dims, transpose_order" - ), - [ - pytest.param( - (pace.util.X_DIM, pace.util.Y_DIM), - (6, 7), - (1, 2), - (2, 3), - (pace.util.X_DIM, pace.util.Y_DIM), - (0, 1), - id="2d_keep_order", - ), - pytest.param( - (pace.util.X_DIM, pace.util.Y_DIM), - (6, 7), - (1, 2), - (2, 3), - (pace.util.Y_DIM, pace.util.X_DIM), - (1, 0), - id="2d_transpose", - ), - pytest.param( - (pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM), - (6, 7, 8), - (1, 2, 3), - (2, 3, 4), - (pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM), - (0, 1, 2), - id="3d_keep_order", - ), - pytest.param( - (pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM), - (6, 7, 8), - (1, 2, 3), - (2, 3, 4), - (pace.util.X_DIMS, pace.util.Y_DIMS, pace.util.Z_DIMS), - (0, 1, 2), - id="3d_keep_order_list_dims", - ), - pytest.param( - (pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM), - (6, 7, 8), - (1, 2, 3), - (2, 3, 4), - (pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM), - (2, 1, 0), - id="3d_transpose", - ), - pytest.param( - (pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM), - (6, 7, 8), - (1, 2, 3), - (2, 3, 4), - (pace.util.Z_DIMS, pace.util.Y_DIMS, pace.util.X_DIMS), - (2, 1, 0), - id="3d_transpose_list_dims", - ), - ], - indirect=True, -) -@pytest.mark.parametrize("backend", ["gt4py_numpy", "gt4py_cupy"], indirect=True) -def test_transpose( - quantity, target_dims, final_data, final_dims, final_origin, final_extent, numpy -): - result = quantity.transpose(target_dims) - numpy.testing.assert_array_equal(result.data, final_data) - assert result.dims == final_dims - assert result.origin == final_origin - assert result.extent == final_extent - assert result.units == quantity.units - assert result.gt4py_backend == quantity.gt4py_backend - - -@pytest.mark.parametrize( - ( - "initial_dims, initial_shape, initial_origin, " - "initial_extent, target_dims, transpose_order" - ), - [ - pytest.param( - (pace.util.X_DIM,), (6,), (1,), (2,), (pace.util.Y_DIM,), (0,), id="1d" - ), - pytest.param( - (pace.util.X_DIM, pace.util.Y_INTERFACE_DIM), - (6, 7), - (1, 2), - (2, 3), - (pace.util.X_DIM, pace.util.Y_DIM), - (0, 1), - id="2d_switch_stagger", - ), - pytest.param( - (pace.util.X_DIM, pace.util.Y_DIM), - (6, 7), - (1, 2), - (2, 3), - (pace.util.Y_DIM, pace.util.X_INTERFACE_DIM), - (1, 0), - id="2d_transpose_switch_stagger", - ), - ], - indirect=True, -) -def test_transpose_invalid_cases( - quantity, target_dims, final_data, final_dims, final_origin, final_extent, numpy -): - with pytest.raises(ValueError): - quantity.transpose(target_dims) - - -def test_transpose_retains_attrs(numpy): - quantity = pace.util.Quantity( - numpy.random.randn(3, 4), dims=["x", "y"], units="unit_string" - ) - quantity._attrs = {"long_name": "500 mb height"} - transposed = quantity.transpose(["y", "x"]) - assert transposed.attrs == quantity.attrs diff --git a/util/tests/quantity/test_view.py b/util/tests/quantity/test_view.py deleted file mode 100644 index c571673c7..000000000 --- a/util/tests/quantity/test_view.py +++ /dev/null @@ -1,1224 +0,0 @@ -import numpy as np -import pytest - -import pace.util - - -@pytest.fixture -def quantity(request): - return pace.util.Quantity( - request.param[0], - dims=request.param[1], - units="units", - ) - - -# edge views were implemented but not enabled, since the API is not yet needed and -# might be subject to change - tests are included here as comments - - -# @pytest.mark.parametrize( -# "quantity, view_slice, reference", -# [ -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (0, 0), -# 4, -# id="3_by_3_center_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([1, 2, 3]), -# dims=[pace.util.X_DIM], -# units="m", -# origin=(1,), -# extent=(1,), -# ), -# (-1,), -# 1, -# id="3_1d_left_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (slice(0, 1), slice(None, None)), -# np.array([[4]]), -# id="3_by_3_center_value_as_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (-1, 0), -# 1, -# id="3_by_3_first_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (slice(-1, 0), slice(0, 1)), -# np.array([[1]]), -# id="3_by_3_first_value_as_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (slice(None, None), slice(None, None)), -# np.array([[4]]), -# id="3_by_3_default_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array( -# [ -# [0, 1, 2, 3, 4], -# [5, 6, 7, 8, 9], -# [10, 11, 12, 13, 14], -# [15, 16, 17, 18, 19], -# [20, 21, 22, 23, 24], -# ] -# ), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(2, 2), -# extent=(1, 1), -# ), -# (slice(None, None), slice(None, None)), -# np.array([[12]]), -# id="5_by_5_mostly_halo_default_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array( -# [ -# [0, 1, 2, 3, 4], -# [5, 6, 7, 8, 9], -# [10, 11, 12, 13, 14], -# [15, 16, 17, 18, 19], -# [20, 21, 22, 23, 24], -# ] -# ), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(2, 2), -# extent=(1, 1), -# ), -# (slice(-2, 0), slice(None, None)), -# np.array([[2], [7]]), -# id="5_by_5_larger_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array( -# [ -# [0, 1, 2, 3, 4], -# [5, 6, 7, 8, 9], -# [10, 11, 12, 13, 14], -# [15, 16, 17, 18, 19], -# [20, 21, 22, 23, 24], -# ] -# ), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(3, 2), -# extent=(1, 1), -# ), -# (slice(-3, 0), slice(None, None)), -# np.array([[2], [7], [12]]), -# id="5_by_5_shifted_right_larger_slice", -# ), -# ], -# ) -# def test_west(quantity, view_slice, reference): -# result = quantity.view.west[view_slice] -# quantity.np.testing.assert_array_equal(result, reference) -# # result should be a slice of the quantity memory, if it's a slice -# assert len(result.shape) == 0 or result.base is quantity.data -# transposed_quantity = pace.util.Quantity( -# quantity.data.T, -# dims=quantity.dims[::-1], -# units=quantity.units, -# origin=quantity.origin[::-1], -# extent=quantity.extent[::-1], -# ) -# transposed_result = transposed_quantity.view.west[view_slice[::-1]] -# if isinstance(reference, quantity.np.ndarray): -# quantity.np.testing.assert_array_equal(transposed_result, reference.T) -# else: -# quantity.np.testing.assert_array_equal(transposed_result, reference) - - -@pytest.mark.parametrize( - "quantity", - [ - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ) - ], -) -@pytest.mark.parametrize( - "view_name", - [ - # "east", - # "west", - # "north", - # "south", - "northeast", - "northwest", - "southeast", - "southwest", - "interior", - ], -) -def test_many_indices_raises(quantity, view_name): - view = getattr(quantity.view, view_name) - index = tuple([0] * (len(quantity.dims) + 1)) - with pytest.raises(IndexError): - view[index] - - -@pytest.mark.parametrize( - "quantity", - [ - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ) - ], -) -@pytest.mark.parametrize( - "view_name", - [ - # "east", - # "west", - # "north", - # "south", - "northeast", - "northwest", - "southeast", - "southwest", - "interior", - ], -) -def test_many_slices_raises(quantity, view_name): - view = getattr(quantity.view, view_name) - index = tuple([slice(0, 1)] * (len(quantity.dims) + 1)) - with pytest.raises(IndexError): - view[index] - - -# @pytest.mark.parametrize( -# "quantity, view_slice, reference", -# [ -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (-1, 0), -# 4, -# id="3_by_3_center_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([1, 2, 3]), -# dims=[pace.util.X_DIM], -# units="m", -# origin=(1,), -# extent=(1,), -# ), -# (0,), -# 3, -# id="3_1d_right_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (slice(-1, 0), slice(None, None)), -# np.array([[4]]), -# id="3_by_3_center_value_as_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (0, 0), -# 7, -# id="3_by_3_first_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (slice(0, 1), slice(0, 1)), -# np.array([[7]]), -# id="3_by_3_first_value_as_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (slice(None, None), slice(None, None)), -# np.array([[4]]), -# id="3_by_3_default_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array( -# [ -# [0, 1, 2, 3, 4], -# [5, 6, 7, 8, 9], -# [10, 11, 12, 13, 14], -# [15, 16, 17, 18, 19], -# [20, 21, 22, 23, 24], -# ] -# ), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(2, 2), -# extent=(1, 1), -# ), -# (slice(None, None), slice(None, None)), -# np.array([[12]]), -# id="5_by_5_mostly_halo_default_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array( -# [ -# [0, 1, 2, 3, 4], -# [5, 6, 7, 8, 9], -# [10, 11, 12, 13, 14], -# [15, 16, 17, 18, 19], -# [20, 21, 22, 23, 24], -# ] -# ), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(2, 2), -# extent=(1, 1), -# ), -# (slice(0, 2), slice(None, None)), -# np.array([[17], [22]]), -# id="5_by_5_larger_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array( -# [ -# [0, 1, 2, 3, 4], -# [5, 6, 7, 8, 9], -# [10, 11, 12, 13, 14], -# [15, 16, 17, 18, 19], -# [20, 21, 22, 23, 24], -# ] -# ), -# dims=[pace.util.X_DIM, pace.util.Y_DIM], -# units="m", -# origin=(1, 2), -# extent=(1, 1), -# ), -# (slice(0, 3), slice(None, None)), -# np.array([[12], [17], [22]]), -# id="5_by_5_shifted_left_larger_slice", -# ), -# ], -# ) -# def test_east(quantity, view_slice, reference): -# result = quantity.view.east[view_slice] -# quantity.np.testing.assert_array_equal(result, reference) -# # result should be a slice of the quantity memory, if it's a slice -# assert len(result.shape) == 0 or result.base is quantity.data -# transposed_quantity = pace.util.Quantity( -# quantity.data.T, -# dims=quantity.dims[::-1], -# units=quantity.units, -# origin=quantity.origin[::-1], -# extent=quantity.extent[::-1], -# ) -# transposed_result = transposed_quantity.view.east[view_slice[::-1]] -# if isinstance(reference, quantity.np.ndarray): -# quantity.np.testing.assert_array_equal(transposed_result, reference.T) -# else: -# quantity.np.testing.assert_array_equal(transposed_result, reference) - - -# @pytest.mark.parametrize( -# "quantity, view_slice, reference", -# [ -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (0, 0), -# 4, -# id="3_by_3_center_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([1, 2, 3]), -# dims=[pace.util.Y_DIM], -# units="m", -# origin=(1,), -# extent=(1,), -# ), -# (-1,), -# 1, -# id="3_1d_bottom_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([1, 2, 3]), -# dims=[pace.util.Y_INTERFACE_DIM], -# units="m", -# origin=(1,), -# extent=(1,), -# ), -# (-1,), -# 1, -# id="3_1d_bottom_interface_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (slice(0, 1), slice(None, None)), -# np.array([[4]]), -# id="3_by_3_center_value_as_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (-1, 0), -# 1, -# id="3_by_3_first_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (slice(-1, 0), slice(0, 1)), -# np.array([[1]]), -# id="3_by_3_first_value_as_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (slice(None, None), slice(None, None)), -# np.array([[4]]), -# id="3_by_3_default_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array( -# [ -# [0, 1, 2, 3, 4], -# [5, 6, 7, 8, 9], -# [10, 11, 12, 13, 14], -# [15, 16, 17, 18, 19], -# [20, 21, 22, 23, 24], -# ] -# ), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(2, 2), -# extent=(1, 1), -# ), -# (slice(None, None), slice(None, None)), -# np.array([[12]]), -# id="5_by_5_mostly_halo_default_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array( -# [ -# [0, 1, 2, 3, 4], -# [5, 6, 7, 8, 9], -# [10, 11, 12, 13, 14], -# [15, 16, 17, 18, 19], -# [20, 21, 22, 23, 24], -# ] -# ), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(2, 2), -# extent=(1, 1), -# ), -# (slice(-2, 0), slice(None, None)), -# np.array([[2], [7]]), -# id="5_by_5_larger_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array( -# [ -# [0, 1, 2, 3, 4], -# [5, 6, 7, 8, 9], -# [10, 11, 12, 13, 14], -# [15, 16, 17, 18, 19], -# [20, 21, 22, 23, 24], -# ] -# ), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(3, 2), -# extent=(1, 1), -# ), -# (slice(-3, 0), slice(None, None)), -# np.array([[2], [7], [12]]), -# id="5_by_5_shifted_larger_slice", -# ), -# ], -# ) -# def test_south(quantity, view_slice, reference): -# result = quantity.view.south[view_slice] -# quantity.np.testing.assert_array_equal(result, reference) -# # result should be a slice of the quantity memory, if it's a slice -# assert len(result.shape) == 0 or result.base is quantity.data -# transposed_quantity = pace.util.Quantity( -# quantity.data.T, -# dims=quantity.dims[::-1], -# units=quantity.units, -# origin=quantity.origin[::-1], -# extent=quantity.extent[::-1], -# ) -# transposed_result = transposed_quantity.view.south[view_slice[::-1]] -# if isinstance(reference, quantity.np.ndarray): -# quantity.np.testing.assert_array_equal(transposed_result, reference.T) -# else: -# quantity.np.testing.assert_array_equal(transposed_result, reference) - - -# @pytest.mark.parametrize( -# "quantity, view_slice, reference", -# [ -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (-1, 0), -# 4, -# id="3_by_3_center_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([1, 2, 3]), -# dims=[pace.util.Y_DIM], -# units="m", -# origin=(1,), -# extent=(1,), -# ), -# (0,), -# 3, -# id="3_1d_top_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([1, 2, 3]), -# dims=[pace.util.Y_INTERFACE_DIM], -# units="m", -# origin=(1,), -# extent=(1,), -# ), -# (0,), -# 3, -# id="3_1d_top_interface_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (slice(-1, 0), slice(None, None)), -# np.array([[4]]), -# id="3_by_3_center_value_as_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (0, 0), -# 7, -# id="3_by_3_first_value", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (slice(0, 1), slice(0, 1)), -# np.array([[7]]), -# id="3_by_3_first_value_as_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(1, 1), -# extent=(1, 1), -# ), -# (slice(None, None), slice(None, None)), -# np.array([[4]]), -# id="3_by_3_default_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array( -# [ -# [0, 1, 2, 3, 4], -# [5, 6, 7, 8, 9], -# [10, 11, 12, 13, 14], -# [15, 16, 17, 18, 19], -# [20, 21, 22, 23, 24], -# ] -# ), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(2, 2), -# extent=(1, 1), -# ), -# (slice(None, None), slice(None, None)), -# np.array([[12]]), -# id="5_by_5_mostly_halo_default_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array( -# [ -# [0, 1, 2, 3, 4], -# [5, 6, 7, 8, 9], -# [10, 11, 12, 13, 14], -# [15, 16, 17, 18, 19], -# [20, 21, 22, 23, 24], -# ] -# ), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(2, 2), -# extent=(1, 1), -# ), -# (slice(0, 2), slice(None, None)), -# np.array([[17], [22]]), -# id="5_by_5_larger_slice", -# ), -# pytest.param( -# pace.util.Quantity( -# np.array( -# [ -# [0, 1, 2, 3, 4], -# [5, 6, 7, 8, 9], -# [10, 11, 12, 13, 14], -# [15, 16, 17, 18, 19], -# [20, 21, 22, 23, 24], -# ] -# ), -# dims=[pace.util.Y_DIM, pace.util.X_DIM], -# units="m", -# origin=(1, 2), -# extent=(1, 1), -# ), -# (slice(0, 3), slice(None, None)), -# np.array([[12], [17], [22]]), -# id="5_by_5_shifted_larger_slice", -# ), -# ], -# ) -# def test_north(quantity, view_slice, reference): -# result = quantity.view.north[view_slice] -# quantity.np.testing.assert_array_equal(result, reference) -# # result should be a slice of the quantity memory, if it's a slice -# assert len(result.shape) == 0 or result.base is quantity.data -# transposed_quantity = pace.util.Quantity( -# quantity.data.T, -# dims=quantity.dims[::-1], -# units=quantity.units, -# origin=quantity.origin[::-1], -# extent=quantity.extent[::-1], -# ) -# transposed_result = transposed_quantity.view.north[view_slice[::-1]] -# if isinstance(reference, quantity.np.ndarray): -# quantity.np.testing.assert_array_equal(transposed_result, reference.T) -# else: -# quantity.np.testing.assert_array_equal(transposed_result, reference) - - -@pytest.mark.parametrize( - "quantity, view_slice, reference", - [ - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (0, 0), - 4, - id="3_by_3_center_value", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (-1, -1), - 0, - id="3_by_3_corner", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (slice(-1, 0), slice(-1, 0)), - np.array([[0]]), - id="3_by_3_corner_as_slice", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (-1, 0), - 1, - id="3_by_3_beside_corner", - ), - pytest.param( - pace.util.Quantity( - np.array( - [ - [0, 1, 2, 3, 4], - [5, 6, 7, 8, 9], - [10, 11, 12, 13, 14], - [15, 16, 17, 18, 19], - [20, 21, 22, 23, 24], - ] - ), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(2, 2), - extent=(1, 1), - ), - (slice(-2, 0), slice(-1, 2)), - np.array([[1, 2, 3], [6, 7, 8]]), - id="5_by_5_larger_slice", - ), - ], -) -def test_southwest(quantity, view_slice, reference): - result = quantity.view.southwest[view_slice] - quantity.np.testing.assert_array_equal(result, reference) - # result should be a slice of the quantity memory, if it's a slice - assert len(result.shape) == 0 or result.base is quantity.data - transposed_quantity = pace.util.Quantity( - quantity.data.T, - dims=quantity.dims[::-1], - units=quantity.units, - origin=quantity.origin[::-1], - extent=quantity.extent[::-1], - ) - transposed_result = transposed_quantity.view.southwest[view_slice[::-1]] - if isinstance(reference, quantity.np.ndarray): - quantity.np.testing.assert_array_equal(transposed_result, reference.T) - else: - quantity.np.testing.assert_array_equal(transposed_result, reference) - - -@pytest.mark.parametrize( - "quantity, view_slice, reference", - [ - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (-1, 0), - 4, - id="3_by_3_center_value", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (0, -1), - 6, - id="3_by_3_corner", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (slice(0, 1), slice(-1, 0)), - np.array([[6]]), - id="3_by_3_corner_as_slice", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (-1, -1), - 3, - id="3_by_3_beside_corner", - ), - pytest.param( - pace.util.Quantity( - np.array( - [ - [0, 1, 2, 3, 4], - [5, 6, 7, 8, 9], - [10, 11, 12, 13, 14], - [15, 16, 17, 18, 19], - [20, 21, 22, 23, 24], - ] - ), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(2, 2), - extent=(1, 1), - ), - (slice(-2, 0), slice(-1, 2)), - np.array([[6, 7, 8], [11, 12, 13]]), - id="5_by_5_larger_slice", - ), - ], -) -def test_southeast(quantity, view_slice, reference): - result = quantity.view.southeast[view_slice] - quantity.np.testing.assert_array_equal(result, reference) - # result should be a slice of the quantity memory, if it's a slice - assert len(result.shape) == 0 or result.base is quantity.data - transposed_quantity = pace.util.Quantity( - quantity.data.T, - dims=quantity.dims[::-1], - units=quantity.units, - origin=quantity.origin[::-1], - extent=quantity.extent[::-1], - ) - transposed_result = transposed_quantity.view.southeast[view_slice[::-1]] - if isinstance(reference, quantity.np.ndarray): - quantity.np.testing.assert_array_equal(transposed_result, reference.T) - else: - quantity.np.testing.assert_array_equal(transposed_result, reference) - - -@pytest.mark.parametrize( - "quantity, view_slice, reference", - [ - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (-1, 0), - 4, - id="3_by_3_center_value", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (0, -1), - 6, - id="3_by_3_corner", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (slice(0, 1), slice(-1, 0)), - np.array([[6]]), - id="3_by_3_corner_as_slice", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (-1, 0), - 4, - id="3_by_3_inside_corner", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (-1, -1), - 3, - id="3_by_3_beside_corner", - ), - pytest.param( - pace.util.Quantity( - np.array( - [ - [0, 1, 2, 3, 4], - [5, 6, 7, 8, 9], - [10, 11, 12, 13, 14], - [15, 16, 17, 18, 19], - [20, 21, 22, 23, 24], - ] - ), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="m", - origin=(2, 2), - extent=(1, 1), - ), - (slice(-2, 0), slice(-1, 2)), - np.array([[6, 7, 8], [11, 12, 13]]), - id="5_by_5_larger_slice", - ), - ], -) -def test_northwest(quantity, view_slice, reference): - result = quantity.view.northwest[view_slice] - quantity.np.testing.assert_array_equal(result, reference) - # result should be a slice of the quantity memory, if it's a slice - assert len(result.shape) == 0 or result.base is quantity.data - transposed_quantity = pace.util.Quantity( - quantity.data.T, - dims=quantity.dims[::-1], - units=quantity.units, - origin=quantity.origin[::-1], - extent=quantity.extent[::-1], - ) - transposed_result = transposed_quantity.view.northwest[view_slice[::-1]] - if isinstance(reference, quantity.np.ndarray): - quantity.np.testing.assert_array_equal(transposed_result, reference.T) - else: - quantity.np.testing.assert_array_equal(transposed_result, reference) - - -@pytest.mark.parametrize( - "quantity, view_slice, reference", - [ - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (-1, -1), - 4, - id="3_by_3_center_value", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (0, 0), - 8, - id="3_by_3_corner", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (slice(0, 1), slice(0, 1)), - np.array([[8]]), - id="3_by_3_corner_as_slice", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (-1, -1), - 4, - id="3_by_3_inside_corner", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (-1, 0), - 5, - id="3_by_3_beside_corner", - ), - pytest.param( - pace.util.Quantity( - np.array( - [ - [0, 1, 2, 3, 4], - [5, 6, 7, 8, 9], - [10, 11, 12, 13, 14], - [15, 16, 17, 18, 19], - [20, 21, 22, 23, 24], - ] - ), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(2, 2), - extent=(1, 1), - ), - (slice(-2, 0), slice(-1, 2)), - np.array([[7, 8, 9], [12, 13, 14]]), - id="5_by_5_larger_slice", - ), - ], -) -def test_northeast(quantity, view_slice, reference): - result = quantity.view.northeast[view_slice] - quantity.np.testing.assert_array_equal(result, reference) - # result should be a slice of the quantity memory, if it's a slice - assert len(result.shape) == 0 or result.base is quantity.data - transposed_quantity = pace.util.Quantity( - quantity.data.T, - dims=quantity.dims[::-1], - units=quantity.units, - origin=quantity.origin[::-1], - extent=quantity.extent[::-1], - ) - transposed_result = transposed_quantity.view.northeast[view_slice[::-1]] - if isinstance(reference, quantity.np.ndarray): - quantity.np.testing.assert_array_equal(transposed_result, reference.T) - else: - quantity.np.testing.assert_array_equal(transposed_result, reference) - - -@pytest.mark.parametrize( - "quantity, view_slice, reference", - [ - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (0, 0), - 4, - id="3_by_3_center_value", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (slice(0, 0), slice(0, 0)), - 4, - id="3_by_3_center_value_as_slice", - ), - pytest.param( - pace.util.Quantity( - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(1, 1), - ), - (slice(-1, 1), slice(-1, 1)), - np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]), - id="3_by_3_with_halo", - ), - pytest.param( - pace.util.Quantity( - np.array( - [ - [0, 1, 2, 3, 4], - [5, 6, 7, 8, 9], - [10, 11, 12, 13, 14], - [15, 16, 17, 18, 19], - [20, 21, 22, 23, 24], - ] - ), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(2, 2), - extent=(1, 1), - ), - (slice(-2, 0), slice(0, 1)), - np.array([[2, 3], [7, 8], [12, 13]]), - id="5_by_5_larger_slice", - ), - pytest.param( - pace.util.Quantity( - np.array( - [ - [0, 1, 2, 3, 4], - [5, 6, 7, 8, 9], - [10, 11, 12, 13, 14], - [15, 16, 17, 18, 19], - [20, 21, 22, 23, 24], - ] - ), - dims=[pace.util.X_DIM, pace.util.Y_DIM], - units="m", - origin=(1, 1), - extent=(3, 3), - ), - (0,), - np.array([6, 7, 8]), - id="5_by_5_one_index", - ), - ], -) -def test_interior(quantity, view_slice, reference): - result = quantity.view.interior[view_slice] - quantity.np.testing.assert_array_equal(result, reference) - # result should be a slice of the quantity memory, if it's a slice - assert len(result.shape) == 0 or result.base is quantity.data - transposed_quantity = pace.util.Quantity( - quantity.data.T, - dims=quantity.dims[::-1], - units=quantity.units, - origin=quantity.origin[::-1], - extent=quantity.extent[::-1], - ) - if len(view_slice) == len(quantity.dims): # skip if not - transposed_result = transposed_quantity.view.interior[view_slice[::-1]] - if isinstance(reference, quantity.np.ndarray): - quantity.np.testing.assert_array_equal(transposed_result, reference.T) - else: - quantity.np.testing.assert_array_equal(transposed_result, reference) diff --git a/util/tests/test__capture_stream.py b/util/tests/test__capture_stream.py deleted file mode 100644 index 6fec36d53..000000000 --- a/util/tests/test__capture_stream.py +++ /dev/null @@ -1,38 +0,0 @@ -import ctypes -import os -import sys - -import pytest - -from pace.util import capture_stream - - -def get_libc(): - if os.uname().sysname == "Linux": - return ctypes.cdll.LoadLibrary("libc.so.6") - else: - pytest.skip() - - -def printc(fd, text): - libc = get_libc() - b = bytes(text + "\n", "UTF-8") - libc.write(fd, b, len(b)) - - -def printpy(_, text): - print(text) - - -@pytest.mark.parametrize("print_", [printc, printpy]) -@pytest.mark.cpu_only -def test_capture_stream_python_print(capfdbinary, print_): - text = "hello world" - - # This test interacts in a confusing with pytests output capturing - # sys.stdout.fileno() is usually 1, but not here. - fd = sys.stdout.fileno() - with capture_stream(sys.stdout) as out: - print_(fd, text) - - assert out.getvalue().decode("UTF-8") == text + "\n" diff --git a/util/tests/test_buffer.py b/util/tests/test_buffer.py deleted file mode 100644 index edd768a10..000000000 --- a/util/tests/test_buffer.py +++ /dev/null @@ -1,192 +0,0 @@ -import pytest - -from pace.util.buffer import BUFFER_CACHE, Buffer, recv_buffer, send_buffer -from pace.util.utils import is_c_contiguous, is_contiguous - - -@pytest.fixture -def contiguous_array(numpy, backend): - if backend == "gt4py_cupy": - pytest.skip("gt4py gpu backend cannot produce contiguous arrays") - array = numpy.empty([3, 4, 5]) - array[:] = numpy.random.randn(3, 4, 5) - return array - - -@pytest.fixture -def non_contiguous_array(contiguous_array): - return contiguous_array.transpose(2, 0, 1) - - -@pytest.fixture(params=["empty", "zeros"]) -def allocator(request, numpy): - return getattr(numpy, request.param) - - -def test_is_contiguous(contiguous_array): - assert is_contiguous(contiguous_array) - - -def test_is_c_contiguous(contiguous_array): - assert is_c_contiguous(contiguous_array) - - -def test_not_is_contiguous(non_contiguous_array): - assert not is_contiguous(non_contiguous_array) - - -def test_not_is_c_contiguous(non_contiguous_array): - assert not is_c_contiguous(non_contiguous_array) - - -def test_sendbuf_uses_buffer(numpy, backend, allocator, non_contiguous_array): - with send_buffer(allocator, non_contiguous_array) as sendbuf: - assert sendbuf is not non_contiguous_array - assert sendbuf.data is not non_contiguous_array.data - numpy.testing.assert_array_equal(sendbuf, non_contiguous_array) - - -def test_recvbuf_uses_buffer(numpy, allocator, non_contiguous_array): - with recv_buffer(allocator, non_contiguous_array) as recvbuf: - assert recvbuf is not non_contiguous_array - assert recvbuf.data is not non_contiguous_array.data - recvbuf[:] = 0.0 - assert not numpy.all(non_contiguous_array == 0.0) - assert numpy.all(non_contiguous_array == 0.0) - - -def test_sendbuf_no_buffer(allocator, contiguous_array): - with send_buffer(allocator, contiguous_array) as sendbuf: - assert sendbuf is contiguous_array - - -def test_recvbuf_no_buffer(allocator, contiguous_array): - with recv_buffer(allocator, contiguous_array) as recvbuf: - assert recvbuf is contiguous_array - - -def test_buffer_cache_appends(allocator, backend): - """ - Test buffer with the same key are appended while not in use for potential reuse - """ - if backend == "gt4py_cupy": - pytest.skip("gt4py gpu backend cannot produce contiguous arrays") - BUFFER_CACHE.clear() - # Cache is cleared - no cache line - assert len(BUFFER_CACHE) == 0 - shape = (10, 10, 10) - # Pop two buffers with the same key - this creates a cache line for the key - first_buffer = Buffer.pop_from_cache(allocator, shape, float) - first_buffer.array.fill(42) - assert len(BUFFER_CACHE) == 1 - second_buffer = Buffer.pop_from_cache(allocator, shape, float) - second_buffer.array.fill(23) - assert first_buffer._key == second_buffer._key - assert (first_buffer.array != second_buffer.array).all() - assert len(BUFFER_CACHE) == 1 - assert len(BUFFER_CACHE[first_buffer._key]) == 0 - # Pushing back the buffers, the cache line should have two items - Buffer.push_to_cache(first_buffer) - Buffer.push_to_cache(second_buffer) - assert len(BUFFER_CACHE[first_buffer._key]) == 2 - - -def test_buffer_reuse(allocator, backend): - """Test we reuse the buffer when available instead of reallocating one""" - if backend == "gt4py_cupy": - pytest.skip("gt4py gpu backend cannot produce contiguous arrays") - BUFFER_CACHE.clear() - # Cache is cleared - no cache line - assert len(BUFFER_CACHE) == 0 - shape = (10, 10, 10) - # We popped a buffer from the cache. This created a cache line for key - # first_buffer._key. - # That cache line is an empty array for now (the element was popped) - first_buffer = Buffer.pop_from_cache(allocator, shape, float) - fill_scalar = 42 - first_buffer.array.fill(fill_scalar) - assert len(BUFFER_CACHE) == 1 - assert len(BUFFER_CACHE[first_buffer._key]) == 0 - # Pushing back - the cache line array as the first_buffer in it, if we - # re-pop it we should have the fill value (same buffer, no re-alloc) - Buffer.push_to_cache(first_buffer) - assert len(BUFFER_CACHE) == 1 - assert len(BUFFER_CACHE[first_buffer._key]) == 1 - repop_buffer = Buffer.pop_from_cache(allocator, shape, float) - assert len(BUFFER_CACHE[first_buffer._key]) == 0 - assert (repop_buffer.array == fill_scalar).all() - # Clean up - Buffer.push_to_cache(repop_buffer) - - -def test_cacheline_differentiation(allocator, backend): - """Test allocation with different keys creates different cache lines""" - if backend == "gt4py_cupy": - pytest.skip("gt4py gpu backend cannot produce contiguous arrays") - BUFFER_CACHE.clear() - # Cache is cleared - no cache line - assert len(BUFFER_CACHE) == 0 - shape = (10, 10, 10) - # Pop a float buffer - create a cache line for the triplet of parameters - first_buffer = Buffer.pop_from_cache(allocator, shape, float) - first_fill_scalar = 42 - first_buffer.array.fill(first_fill_scalar) - assert len(BUFFER_CACHE) == 1 - assert len(BUFFER_CACHE[first_buffer._key]) == 0 - # Pop an int buffer - create a second cache line for the triplet of parameters - second_buffer = Buffer.pop_from_cache(allocator, shape, int) - second_fill_scalar = 44 - second_buffer.array.fill(second_fill_scalar) - assert len(BUFFER_CACHE) == 2 - assert len(BUFFER_CACHE[second_buffer._key]) == 0 - # Check buffer are different - assert first_buffer._key != second_buffer._key - assert (first_buffer.array != second_buffer.array).all() - # Pushing back - the cache line get their buffer back - Buffer.push_to_cache(first_buffer) - Buffer.push_to_cache(second_buffer) - assert len(BUFFER_CACHE) == 2 - assert len(BUFFER_CACHE[first_buffer._key]) == 1 - assert len(BUFFER_CACHE[second_buffer._key]) == 1 - # We pop back the buffer and expect to get the previously fill'ed buffers - repop_first_buffer = Buffer.pop_from_cache(allocator, shape, float) - assert len(BUFFER_CACHE[repop_first_buffer._key]) == 0 - assert len(BUFFER_CACHE[second_buffer._key]) == 1 - repop_second_buffer = Buffer.pop_from_cache(allocator, shape, int) - assert len(BUFFER_CACHE[repop_first_buffer._key]) == 0 - assert len(BUFFER_CACHE[repop_second_buffer._key]) == 0 - assert (repop_first_buffer.array == first_fill_scalar).all() - assert (repop_second_buffer.array == second_fill_scalar).all() - # Clean up - Buffer.push_to_cache(repop_first_buffer) - Buffer.push_to_cache(repop_second_buffer) - - -@pytest.mark.parametrize( - "first_args, second_args", - [ - pytest.param(((10, 10, 10), float), ((10, 10, 10), int), id="different_dtype"), - pytest.param(((10, 10, 10), float), ((10, 10, 5), float), id="different_shape"), - ], -) -def test_new_args_gives_different_buffer(allocator, backend, first_args, second_args): - if backend == "gt4py_cupy": - pytest.skip("gt4py gpu backend cannot produce contiguous arrays") - BUFFER_CACHE.clear() - first_buffer = Buffer.pop_from_cache(allocator, *first_args) - Buffer.push_to_cache(first_buffer) - second_buffer = Buffer.pop_from_cache(allocator, *second_args) - assert not (first_buffer is second_buffer) - assert first_buffer._key != second_buffer._key - first_buffer.array[:] = 10.0 - second_buffer.array[:] = 1.0 - assert (first_buffer.array == 10.0).all() - assert (second_buffer.array == 1.0).all() - - -@pytest.mark.parametrize("allocator, backend", [["ones", "cupy"]], indirect=True) -def test_mpi_unsafe_allocator_exception(backend, allocator): - BUFFER_CACHE.clear() - print(allocator) - with pytest.raises(RuntimeError): - Buffer.pop_from_cache(allocator, shape=(10, 10, 10), dtype=float) diff --git a/util/tests/test_caching_comm.py b/util/tests/test_caching_comm.py deleted file mode 100644 index 1d93eadba..000000000 --- a/util/tests/test_caching_comm.py +++ /dev/null @@ -1,173 +0,0 @@ -import copy -import io -from typing import List - -import numpy as np - -import pace.util -from pace.util.caching_comm import CachingCommReader, CachingCommWriter - - -def test_halo_update_integration(): - shape = (18, 18) - dims = [pace.util.X_DIM, pace.util.Y_DIM] - origin = (3, 3) - extent = (12, 12) - n_ranks = 6 - partitioner = pace.util.CubedSpherePartitioner( - tile=pace.util.TilePartitioner(layout=(1, 1)) - ) - quantity_list = [ - pace.util.Quantity( - data=np.random.randn(*shape), - dims=dims, - units="", - origin=origin, - extent=extent, - ) - for _ in range(n_ranks) - ] - buffer_dict = {} - write_communicator_list: List[pace.util.CubedSphereCommunicator] = [] - for i in range(n_ranks): - write_communicator_list.append( - pace.util.CubedSphereCommunicator( - comm=pace.util.CachingCommWriter( - pace.util.LocalComm( - rank=i, total_ranks=n_ranks, buffer_dict=buffer_dict - ) - ), - partitioner=partitioner, - ) - ) - local_comm_quantities = copy.deepcopy(quantity_list) - perform_serial_halo_updates(write_communicator_list, local_comm_quantities) - - read_communicator_list: List[pace.util.CubedSphereCommunicator] = [] - for i in range(n_ranks): - file = io.BytesIO() - write_communicator_list[i].comm.dump(file) - file.seek(0) - read_communicator_list.append( - pace.util.CubedSphereCommunicator( - comm=pace.util.CachingCommReader.load(file), - partitioner=partitioner, - ) - ) - perform_serial_halo_updates(read_communicator_list, quantity_list) - for local_comm_quantity, read_quantity in zip(local_comm_quantities, quantity_list): - np.testing.assert_array_equal(local_comm_quantity.data, read_quantity.data) - - -def perform_serial_halo_updates( - communicator_list: List[pace.util.CubedSphereCommunicator], - quantity_list: List[pace.util.Quantity], -): - req_list = [] - for communicator, quantity in zip(communicator_list, quantity_list): - req_list.append(communicator.start_halo_update(quantity, n_points=3)) - for req in req_list: - req.wait() - - -def test_Recv_inserts_data(): - comm = pace.util.CachingCommWriter( - comm=pace.util.NullComm(rank=0, total_ranks=6, fill_value=0.0) - ) - shape = (12, 12) - recvbuf = np.random.randn(*shape) - assert len(comm._data.received_buffers) == 0 - comm.Recv(recvbuf, source=0) - assert len(comm._data.received_buffers) == 1 - assert comm._data.received_buffers[0].shape == shape - - -def test_Irecv_inserts_data(): - comm = pace.util.CachingCommWriter( - comm=pace.util.NullComm(rank=0, total_ranks=6, fill_value=0.0) - ) - shape = (12, 12) - recvbuf = np.random.randn(*shape) - assert len(comm._data.received_buffers) == 0 - req = comm.Irecv(recvbuf, source=0) - assert len(comm._data.received_buffers) == 0 - req.wait() - assert len(comm._data.received_buffers) == 1 - assert comm._data.received_buffers[0].shape == shape - - -def test_bcast_inserts_data(): - comm = pace.util.CachingCommWriter( - comm=pace.util.NullComm(rank=0, total_ranks=6, fill_value=0.0) - ) - shape = (12, 12) - recvbuf = np.random.randn(*shape) - assert len(comm._data.bcast_objects) == 0 - comm.bcast(recvbuf) - assert len(comm._data.bcast_objects) == 1 - assert comm._data.bcast_objects[0].shape == shape - np.testing.assert_array_equal(comm._data.bcast_objects[0], recvbuf) - assert comm._data.bcast_objects[0] is not recvbuf - - -def writer_to_reader(comm_writer: CachingCommWriter) -> CachingCommReader: - file = io.BytesIO() - comm_writer.dump(file) - file.seek(0) - return CachingCommReader.load(file) - - -def test_Scatter(): - np.random.seed(0) - array = np.random.uniform(size=(50,)) - send_array = np.empty([2] + list(array.shape)) - send_array[:] = array[None, :] - buffer_dict = {} - root_comm = pace.util.CachingCommWriter( - comm=pace.util.LocalComm(rank=0, total_ranks=2, buffer_dict=buffer_dict) - ) - worker_comm = pace.util.CachingCommWriter( - comm=pace.util.LocalComm(rank=1, total_ranks=2, buffer_dict=buffer_dict) - ) - recvbuf_root = np.zeros_like(array) - recvbuf_worker = np.zeros_like(array) - root_comm.Scatter(send_array, recvbuf=recvbuf_root, root=0) - worker_comm.Scatter(None, recvbuf=recvbuf_worker, root=0) - np.testing.assert_array_equal(recvbuf_root, recvbuf_worker) - - root_comm = writer_to_reader(root_comm) - worker_comm = writer_to_reader(worker_comm) - - recvbuf2_root = np.zeros_like(array) - recvbuf2_worker = np.zeros_like(array) - root_comm.Scatter(send_array, recvbuf=recvbuf2_root, root=0) - worker_comm.Scatter(None, recvbuf=recvbuf2_worker, root=0) - np.testing.assert_array_equal(recvbuf2_root, recvbuf_root) - np.testing.assert_array_equal(recvbuf2_worker, recvbuf_worker) - - -def test_Gather(): - np.random.seed(0) - array_root = np.random.uniform(size=(50,)) - array_worker = np.random.uniform(size=(50,)) - buffer_dict = {} - root_comm = pace.util.CachingCommWriter( - comm=pace.util.LocalComm(rank=0, total_ranks=2, buffer_dict=buffer_dict) - ) - worker_comm = pace.util.CachingCommWriter( - comm=pace.util.LocalComm(rank=1, total_ranks=2, buffer_dict=buffer_dict) - ) - recvbuf_root = np.empty([2] + list(array_root.shape)) - worker_comm.Gather(array_worker, recvbuf=None, root=0) - root_comm.Gather(array_root, recvbuf=recvbuf_root, root=0) - np.testing.assert_array_equal(recvbuf_root[0, :], array_root) - np.testing.assert_array_equal(recvbuf_root[1, :], array_worker) - - root_comm = writer_to_reader(root_comm) - worker_comm = writer_to_reader(worker_comm) - - recvbuf_root = np.empty([2] + list(array_root.shape)) - worker_comm.Gather(array_worker, recvbuf=None, root=0) - root_comm.Gather(array_root, recvbuf=recvbuf_root, root=0) - np.testing.assert_array_equal(recvbuf_root[0, :], array_root) - np.testing.assert_array_equal(recvbuf_root[1, :], array_worker) diff --git a/util/tests/test_cube_scatter_gather.py b/util/tests/test_cube_scatter_gather.py deleted file mode 100644 index 523cb0de1..000000000 --- a/util/tests/test_cube_scatter_gather.py +++ /dev/null @@ -1,299 +0,0 @@ -import copy -import datetime - -import pytest - -import pace.util - - -try: - import gt4py -except ImportError: - gt4py = None - - -@pytest.fixture(params=[(1, 1), (3, 3)]) -def layout(request): - return request.param - - -@pytest.fixture(params=[0, 1, 3]) -def n_rank_halo(request): - return request.param - - -@pytest.fixture(params=[0, 3]) -def n_tile_halo(request): - return request.param - - -@pytest.fixture(params=["x,y", "y,x", "xi,y", "x,y,z", "z,y,x", "y,z,x"]) -def dims(request, fast): - if request.param == "x,y": - return [pace.util.X_DIM, pace.util.Y_DIM] - elif request.param == "y,x": - if fast: - pytest.skip("running in fast mode") - else: - return [pace.util.Y_DIM, pace.util.X_DIM] - elif request.param == "xi,y": - return [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM] - elif request.param == "x,y,z": - return [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM] - elif request.param == "z,y,x": - if fast: - pytest.skip("running in fast mode") - else: - return [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM] - elif request.param == "y,z,x": - return [pace.util.Y_DIM, pace.util.Z_DIM, pace.util.X_DIM] - else: - raise NotImplementedError() - - -@pytest.fixture -def units(): - return "m/s" - - -@pytest.fixture -def time(): - return datetime.datetime(2000, 1, 1) - - -def assert_quantity_equals(result, reference): - assert result.dims == reference.dims - assert result.units == reference.units - assert result.extent == reference.extent - assert isinstance(result.data, type(reference.data)) - reference.np.testing.assert_array_equal(result.view[:], reference.view[:]) - - -@pytest.fixture() -def dim_lengths(layout): - return { - pace.util.X_DIM: 2 * layout[1], - pace.util.X_INTERFACE_DIM: 2 * layout[1] + 1, - pace.util.Y_DIM: 2 * layout[0], - pace.util.Y_INTERFACE_DIM: 2 * layout[0] + 1, - pace.util.Z_DIM: 3, - pace.util.Z_INTERFACE_DIM: 4, - } - - -@pytest.fixture() -def communicator_list(layout): - total_ranks = 6 * layout[0] * layout[1] - shared_buffer = {} - return_list = [] - for rank in range(total_ranks): - return_list.append( - pace.util.CubedSphereCommunicator( - pace.util.testing.DummyComm(rank, total_ranks, shared_buffer), - pace.util.CubedSpherePartitioner(pace.util.TilePartitioner(layout)), - timer=pace.util.Timer(), - ) - ) - return return_list - - -@pytest.fixture -def tile_extent(dims, dim_lengths): - return_list = [] - for dim in dims: - return_list.append(dim_lengths[dim]) - return tuple(return_list) - - -@pytest.fixture -def cube_quantity(dims, units, dim_lengths, tile_extent, n_tile_halo, numpy): - return get_cube_quantity(dims, units, dim_lengths, tile_extent, n_tile_halo, numpy) - - -@pytest.fixture -def scattered_quantities(cube_quantity, layout, n_rank_halo, numpy): - tile_ranks = layout[0] * layout[1] - return_list = [] - partitioner = pace.util.TilePartitioner(layout) - for i_tile in range(6): - for rank in range(tile_ranks): - # partitioner is tested in other tests, here we assume it works - subtile_slice = partitioner.subtile_slice( - rank=rank, - global_dims=cube_quantity.dims[1:], - global_extent=cube_quantity.extent[1:], - overlap=True, - ) - subtile_view = cube_quantity.view[(i_tile,) + subtile_slice] - subtile_quantity = get_quantity( - cube_quantity.dims[1:], - cube_quantity.units, - subtile_view.shape, - n_rank_halo, - numpy, - ) - subtile_quantity.view[:] = subtile_view - return_list.append(subtile_quantity) - return return_list - - -def get_cube_quantity(dims, units, dim_lengths, tile_extent, n_halo, numpy): - extent = [6] + [dim_lengths[dim] for dim in dims] - dims = [pace.util.TILE_DIM] + dims - quantity = get_quantity(dims, units, extent, n_halo, numpy) - quantity.view[:] = numpy.random.randn(*quantity.extent) - return quantity - - -def get_quantity(dims, units, extent, n_halo, numpy): - shape = list(copy.deepcopy(extent)) - origin = [0 for dim in dims] - for i, dim in enumerate(dims): - if dim in pace.util.HORIZONTAL_DIMS: - origin[i] += n_halo - shape[i] += 2 * n_halo - return pace.util.Quantity( - numpy.zeros(shape), - dims, - units, - origin=tuple(origin), - extent=tuple(extent), - ) - - -def test_cube_gather_state( - cube_quantity, scattered_quantities, communicator_list, time, backend -): - for communicator, rank_quantity in reversed( - list(zip(communicator_list, scattered_quantities)) - ): - state = {"time": time, "air_temperature": rank_quantity} - out = communicator.gather_state(send_state=state) - if communicator.rank == 0: - result_state = out - else: - assert out is None - assert result_state["time"] == time - result = result_state["air_temperature"] - assert_quantity_equals(result, cube_quantity) - - -def test_cube_gather_state_with_recv_state( - cube_quantity, scattered_quantities, communicator_list, time -): - recv_state = {"time": time, "air_temperature": copy.deepcopy(cube_quantity)} - recv_state["air_temperature"].data[:] = -1 - for communicator, rank_quantity in reversed( - list(zip(communicator_list, scattered_quantities)) - ): - state = {"time": time, "air_temperature": rank_quantity} - if communicator.rank == 0: - communicator.gather_state(send_state=state, recv_state=recv_state) - else: - communicator.gather_state(send_state=state) - assert recv_state["time"] == time - result = recv_state["air_temperature"] - assert_quantity_equals(result, cube_quantity) - - -def test_cube_gather_no_recv_quantity( - cube_quantity, scattered_quantities, communicator_list -): - for communicator, rank_quantity in reversed( - list(zip(communicator_list, scattered_quantities)) - ): - result = communicator.gather(send_quantity=rank_quantity) - if communicator.rank != 0: - assert result is None - assert_quantity_equals(result, cube_quantity) - - -def test_cube_scatter_no_recv_quantity( - cube_quantity, scattered_quantities, communicator_list -): - result_list = [] - for communicator in communicator_list: - if communicator.rank == 0: - result_list.append(communicator.scatter(send_quantity=cube_quantity)) - else: - result_list.append(communicator.scatter()) - for rank, (result, scattered) in enumerate(zip(result_list, scattered_quantities)): - assert_quantity_equals(result, scattered) - - -def test_cube_scatter_with_recv_quantity( - cube_quantity, scattered_quantities, communicator_list -): - recv_quantities = copy.deepcopy(scattered_quantities) - for q in recv_quantities: - q.data[:] = 0.0 - for recv, communicator in zip(recv_quantities, communicator_list): - if communicator.rank == 0: - result = communicator.scatter( - send_quantity=cube_quantity, recv_quantity=recv - ) - else: - result = communicator.scatter(recv_quantity=recv) - assert result is recv - for rank, (result, scattered) in enumerate( - zip(recv_quantities, scattered_quantities) - ): - assert_quantity_equals(result, scattered) - - -def test_cube_gather_with_recv_quantity( - cube_quantity, scattered_quantities, communicator_list -): - recv_quantity = copy.deepcopy(cube_quantity) - recv_quantity.data[:] = -1 - for communicator, rank_quantity in reversed( - list(zip(communicator_list, scattered_quantities)) - ): - if communicator.rank == 0: - result = communicator.gather( - send_quantity=rank_quantity, recv_quantity=recv_quantity - ) - else: - result = communicator.gather(send_quantity=rank_quantity) - assert result is None - assert_quantity_equals(recv_quantity, cube_quantity) - - -def test_cube_scatter_state( - cube_quantity, scattered_quantities, communicator_list, time -): - state = {"time": time, "air_temperature": cube_quantity} - result_list = [] - for communicator in communicator_list: - if communicator.rank == 0: - result_list.append(communicator.scatter_state(send_state=state)) - else: - result_list.append(communicator.scatter_state()) - for result_state, scattered in zip(result_list, scattered_quantities): - assert result_state["time"] == time - result = result_state["air_temperature"] - assert_quantity_equals(result, scattered) - - -def test_cube_scatter_state_with_recv_state( - cube_quantity, scattered_quantities, communicator_list, time -): - tile_state = {"time": time, "air_temperature": cube_quantity} - recv_quantities = copy.deepcopy(scattered_quantities) - for q in recv_quantities: - q.data[:] = 0.0 - for recv, communicator in zip(recv_quantities, communicator_list): - state = { - "time": time - datetime.timedelta(hours=1), - "air_temperature": recv, - } - if communicator.rank == 0: - result = communicator.scatter_state(send_state=tile_state, recv_state=state) - else: - result = communicator.scatter_state(recv_state=state) - assert result["time"] == time - assert result["air_temperature"] is recv - for rank, (result, scattered) in enumerate( - zip(recv_quantities, scattered_quantities) - ): - assert_quantity_equals(result, scattered) diff --git a/util/tests/test_decomposition.py b/util/tests/test_decomposition.py deleted file mode 100644 index 352b62a5c..000000000 --- a/util/tests/test_decomposition.py +++ /dev/null @@ -1,84 +0,0 @@ -import os -import unittest.mock -from typing import Tuple - -import pytest - -from pace.util.decomposition import ( - block_waiting_for_compilation, - build_cache_path, - check_cached_path_exists, - determine_rank_is_compiling, - unblock_waiting_tiles, -) -from pace.util.mpi import MPI -from pace.util.partitioner import CubedSpherePartitioner, TilePartitioner - - -@pytest.mark.parametrize( - "layout, rank, is_compiling", - [ - pytest.param((1, 1), 0, True, id="1x1 layout"), - pytest.param((1, 1), 2, False, id="1x1 layout"), - pytest.param((2, 2), 1, True, id="2x2 layout"), - pytest.param((2, 2), 5, False, id="2x2 layout"), - pytest.param((3, 3), 8, True, id="3x3 layout"), - pytest.param((3, 3), 25, False, id="3x3 layout"), - ], -) -def test_determine_rank_is_compiling( - layout: Tuple[int, int], rank: int, is_compiling: bool -): - partitioner = CubedSpherePartitioner(TilePartitioner(layout)) - assert determine_rank_is_compiling(rank, partitioner.total_ranks) == is_compiling - - -def test_check_cached_path_exists(): - with pytest.raises(RuntimeError): - check_cached_path_exists("notarealpath") - - -def test_check_cached_path_exists_working(): - path = os.getcwd() - check_cached_path_exists(path) - - -@pytest.mark.parametrize( - "use_minimal_caching, compiling_equivalent, rank, size, target_rank_str", - [ - pytest.param(True, 2, 6, 24, "_000002", id="find_equivalent"), - pytest.param(False, 2, 6, 24, "_000006", id="find_self"), - pytest.param(True, 1, 1, 1, "", id="find_nothing"), - pytest.param(False, 1, 1, 1, "", id="find_nothing again"), - ], -) -def test_build_cache_path( - use_minimal_caching: bool, - compiling_equivalent: int, - rank: int, - size: int, - target_rank_str: str, -): - compilation_config = unittest.mock.MagicMock( - use_minimal_caching=use_minimal_caching, - compiling_equivalent=compiling_equivalent, - rank=rank, - size=size, - ) - _, rank_str = build_cache_path(compilation_config) - assert rank_str == target_rank_str - - -@pytest.mark.skipif( - MPI is None or MPI.COMM_WORLD.Get_size() != 6, - reason="mpi4py is not available or pytest was not run in parallel", -) -def test_unblock_waiting_tiles(): - comm = MPI.COMM_WORLD - compilation_config = unittest.mock.MagicMock(compiling_equivalent=0) - rank = comm.Get_rank() - size = comm.Get_size() - if rank != 0: - block_waiting_for_compilation(comm, compilation_config) - if rank == 0: - unblock_waiting_tiles(comm) diff --git a/util/tests/test_dimension_sizer.py b/util/tests/test_dimension_sizer.py deleted file mode 100644 index 73f6f4c02..000000000 --- a/util/tests/test_dimension_sizer.py +++ /dev/null @@ -1,213 +0,0 @@ -from collections import namedtuple - -import pytest - -import pace.util - - -@pytest.fixture(params=[48, 96]) -def nx_tile(request): - return request.param - - -@pytest.fixture(params=[48, 96]) -def ny_tile(request, fast): - if fast and request.param == 96: - pytest.skip("running in fast mode") - return request.param - - -@pytest.fixture(params=[60, 80]) -def nz(request, fast): - if fast and request.param == 80: - pytest.skip("running in fast mode") - return request.param - - -@pytest.fixture -def nx(nx_tile, layout): - return nx_tile / layout[1] - - -@pytest.fixture -def ny(ny_tile, layout): - return ny_tile / layout[0] - - -@pytest.fixture(params=[(1, 1), (3, 3)]) -def layout(request): - return request.param - - -@pytest.fixture -def extra_dimension_lengths(): - return {} - - -@pytest.fixture -def namelist(nx_tile, ny_tile, nz, layout): - namelist = { - "fv_core_nml": { - "npx": nx_tile + 1, - "npy": ny_tile + 1, - "npz": nz, - "layout": layout, - } - } - return namelist - - -@pytest.fixture(params=["from_namelist", "from_tile_params"]) -def sizer(request, nx_tile, ny_tile, nz, layout, namelist, extra_dimension_lengths): - if request.param == "from_tile_params": - sizer = pace.util.SubtileGridSizer.from_tile_params( - nx_tile, - ny_tile, - nz, - pace.util.N_HALO_DEFAULT, - extra_dimension_lengths, - layout, - ) - elif request.param == "from_namelist": - sizer = pace.util.SubtileGridSizer.from_namelist(namelist) - else: - raise NotImplementedError() - return sizer - - -@pytest.fixture -def units(): - return "units_placeholder" - - -@pytest.fixture(params=[float, int]) -def dtype(request): - return request.param - - -DimCase = namedtuple("DimCase", ["dims", "origin", "extent", "shape"]) - - -@pytest.fixture( - params=[ - "x_only", - "x_interface_only", - "y_only", - "y_interface_only", - "z_only", - "z_interface_only", - "x_y", - "z_y_x", - ] -) -def dim_case(request, nx, ny, nz): - if request.param == "x_only": - return DimCase( - (pace.util.X_DIM,), - (pace.util.N_HALO_DEFAULT,), - (nx,), - (2 * pace.util.N_HALO_DEFAULT + nx + 1,), - ) - elif request.param == "x_interface_only": - return DimCase( - (pace.util.X_INTERFACE_DIM,), - (pace.util.N_HALO_DEFAULT,), - (nx + 1,), - (2 * pace.util.N_HALO_DEFAULT + nx + 1,), - ) - elif request.param == "y_only": - return DimCase( - (pace.util.Y_DIM,), - (pace.util.N_HALO_DEFAULT,), - (ny,), - (2 * pace.util.N_HALO_DEFAULT + ny + 1,), - ) - elif request.param == "y_interface_only": - return DimCase( - (pace.util.Y_INTERFACE_DIM,), - (pace.util.N_HALO_DEFAULT,), - (ny + 1,), - (2 * pace.util.N_HALO_DEFAULT + ny + 1,), - ) - elif request.param == "z_only": - return DimCase((pace.util.Z_DIM,), (0,), (nz,), (nz + 1,)) - elif request.param == "z_interface_only": - return DimCase((pace.util.Z_INTERFACE_DIM,), (0,), (nz + 1,), (nz + 1,)) - elif request.param == "x_y": - return DimCase( - ( - pace.util.X_DIM, - pace.util.Y_DIM, - ), - (pace.util.N_HALO_DEFAULT, pace.util.N_HALO_DEFAULT), - (nx, ny), - ( - 2 * pace.util.N_HALO_DEFAULT + nx + 1, - 2 * pace.util.N_HALO_DEFAULT + ny + 1, - ), - ) - elif request.param == "z_y_x": - return DimCase( - ( - pace.util.Z_DIM, - pace.util.Y_DIM, - pace.util.X_DIM, - ), - (0, pace.util.N_HALO_DEFAULT, pace.util.N_HALO_DEFAULT), - (nz, ny, nx), - ( - nz + 1, - 2 * pace.util.N_HALO_DEFAULT + ny + 1, - 2 * pace.util.N_HALO_DEFAULT + nx + 1, - ), - ) - - -@pytest.mark.cpu_only -def test_subtile_dimension_sizer_origin(sizer, dim_case): - result = sizer.get_origin(dim_case.dims) - assert result == dim_case.origin - - -@pytest.mark.cpu_only -def test_subtile_dimension_sizer_extent(sizer, dim_case): - result = sizer.get_extent(dim_case.dims) - assert result == dim_case.extent - - -@pytest.mark.cpu_only -def test_subtile_dimension_sizer_shape(sizer, dim_case): - result = sizer.get_shape(dim_case.dims) - assert result == dim_case.shape - - -def test_allocator_zeros(numpy, sizer, dim_case, units, dtype): - allocator = pace.util.QuantityFactory(sizer, numpy) - quantity = allocator.zeros(dim_case.dims, units, dtype=dtype) - assert quantity.units == units - assert quantity.dims == dim_case.dims - assert quantity.origin == dim_case.origin - assert quantity.extent == dim_case.extent - assert quantity.data.shape == dim_case.shape - assert numpy.all(quantity.data == 0) - - -def test_allocator_ones(numpy, sizer, dim_case, units, dtype): - allocator = pace.util.QuantityFactory(sizer, numpy) - quantity = allocator.ones(dim_case.dims, units, dtype=dtype) - assert quantity.units == units - assert quantity.dims == dim_case.dims - assert quantity.origin == dim_case.origin - assert quantity.extent == dim_case.extent - assert quantity.data.shape == dim_case.shape - assert numpy.all(quantity.data == 1) - - -def test_allocator_empty(numpy, sizer, dim_case, units, dtype): - allocator = pace.util.QuantityFactory(sizer, numpy) - quantity = allocator.empty(dim_case.dims, units, dtype=dtype) - assert quantity.units == units - assert quantity.dims == dim_case.dims - assert quantity.origin == dim_case.origin - assert quantity.extent == dim_case.extent - assert quantity.data.shape == dim_case.shape diff --git a/util/tests/test_g2g_communication.py b/util/tests/test_g2g_communication.py deleted file mode 100644 index 3bdf48a12..000000000 --- a/util/tests/test_g2g_communication.py +++ /dev/null @@ -1,167 +0,0 @@ -""" Test of the GPU to GPU communication strategy. - -Those test use halo_update but are separated from the entire -""" -import contextlib -import functools - -import numpy as np -import pytest - -import pace.util - - -try: - import cupy as cp -except ModuleNotFoundError: - cp = None - - -@pytest.fixture(params=[(1, 1), (3, 3)]) -def layout(request, fast): - if fast and request.param == (1, 1): - pytest.skip("running in fast mode") - else: - return request.param - - -@pytest.fixture -def ranks_per_tile(layout): - return layout[0] * layout[1] - - -@pytest.fixture -def total_ranks(ranks_per_tile): - return 6 * ranks_per_tile - - -@pytest.fixture -def tile_partitioner(layout): - return pace.util.TilePartitioner(layout) - - -@pytest.fixture -def cube_partitioner(tile_partitioner): - return pace.util.CubedSpherePartitioner(tile_partitioner) - - -@pytest.fixture -def cpu_communicators(cube_partitioner): - shared_buffer = {} - return_list = [] - for rank in range(cube_partitioner.total_ranks): - return_list.append( - pace.util.CubedSphereCommunicator( - comm=pace.util.testing.DummyComm( - rank=rank, total_ranks=total_ranks, buffer_dict=shared_buffer - ), - force_cpu=True, - partitioner=cube_partitioner, - timer=pace.util.Timer(), - ) - ) - return return_list - - -@pytest.fixture -def gpu_communicators(cube_partitioner): - shared_buffer = {} - return_list = [] - for rank in range(cube_partitioner.total_ranks): - return_list.append( - pace.util.CubedSphereCommunicator( - comm=pace.util.testing.DummyComm( - rank=rank, total_ranks=total_ranks, buffer_dict=shared_buffer - ), - partitioner=cube_partitioner, - force_cpu=False, - timer=pace.util.Timer(), - ) - ) - return return_list - - -# To record the calls to cp.ZEROS/np.ZEROS we use a global -# dict indexed on the functions -global N_ZEROS_CALLS -N_ZEROS_CALLS = {} - - -@contextlib.contextmanager -def module_count_calls_to_zeros(module): - global N_ZEROS_CALLS - N_ZEROS_CALLS[module.zeros] = 0 - - def count_calls(func): - """Count func call""" - - @functools.wraps(func) - def wrapped(*args, **kwargs): - global N_ZEROS_CALLS - N_ZEROS_CALLS[func] = N_ZEROS_CALLS[func] + 1 - return func(*args, **kwargs) - - return wrapped - - try: - original = module.zeros - module.zeros = count_calls(module.zeros) - yield - finally: - module.zeros = original - - -@pytest.mark.parametrize("backend", ["cupy", "gt4py_cupy"], indirect=True) -def test_halo_update_only_communicate_on_gpu(backend, gpu_communicators): - with module_count_calls_to_zeros(np), module_count_calls_to_zeros(cp): - shape = (10, 10, 79) - dims = (pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM) - data = cp.ones(shape, dtype=float) - quantity = pace.util.Quantity( - data, - dims=dims, - units="m", - origin=(3, 3, 1), - extent=(3, 3, 1), - ) - halo_updater_list = [] - for communicator in gpu_communicators: - halo_updater = communicator.start_halo_update(quantity, 3) - halo_updater_list.append(halo_updater) - for halo_updater in halo_updater_list: - halo_updater.wait() - - # We expect no np calls and several cp calls - global N_ZEROS_CALLS - print(f"Results {N_ZEROS_CALLS}") - assert N_ZEROS_CALLS[cp.zeros] > 0 - assert N_ZEROS_CALLS[np.zeros] == 0 - - -@pytest.mark.parametrize("backend", ["cupy", "gt4py_cupy"], indirect=True) -def test_halo_update_communicate_though_cpu(backend, cpu_communicators): - with module_count_calls_to_zeros(np), module_count_calls_to_zeros(cp): - shape = (10, 10, 79) - data = cp.ones(shape, dtype=float) - quantity = pace.util.Quantity( - data, - dims=( - pace.util.X_DIM, - pace.util.Y_DIM, - pace.util.Z_DIM, - ), - units="m", - origin=(3, 3, 0), - extent=(3, 3, 0), - ) - halo_updater_list = [] - for communicator in cpu_communicators: - halo_updater = communicator.start_halo_update(quantity, 3) - halo_updater_list.append(halo_updater) - for halo_updater in halo_updater_list: - halo_updater.wait() - - # We expect several np calls and several cp calls - global N_ZEROS_CALLS - assert N_ZEROS_CALLS[np.zeros] > 0 - assert N_ZEROS_CALLS[cp.zeros] == 0 diff --git a/util/tests/test_get_tile_number.py b/util/tests/test_get_tile_number.py deleted file mode 100644 index 5ba606aa9..000000000 --- a/util/tests/test_get_tile_number.py +++ /dev/null @@ -1,22 +0,0 @@ -import pytest - -from pace.util import get_tile_number - - -@pytest.mark.cpu_only -def test_get_tile_number_six_ranks(): - rank_list = list(range(6)) - for i_rank in rank_list: - tile = get_tile_number(i_rank, len(rank_list)) - assert tile == i_rank + 1 - - -@pytest.mark.cpu_only -def test_get_tile_number_twenty_four_ranks(): - rank_list = list(range(24)) - i_rank = 0 - for i_tile in [i + 1 for i in range(6)]: - for _ in range(4): - return_value = get_tile_number(i_rank, len(rank_list)) - assert return_value == i_tile - i_rank += 1 diff --git a/util/tests/test_halo_data_transformer.py b/util/tests/test_halo_data_transformer.py deleted file mode 100644 index 5f4947abd..000000000 --- a/util/tests/test_halo_data_transformer.py +++ /dev/null @@ -1,466 +0,0 @@ -import copy -from typing import Tuple - -import numpy as np -import pytest - -from pace.util import ( - EAST, - NORTH, - NORTHEAST, - NORTHWEST, - SOUTH, - SOUTHEAST, - SOUTHWEST, - WEST, - X_DIM, - X_INTERFACE_DIM, - Y_DIM, - Y_INTERFACE_DIM, - Z_DIM, - Z_INTERFACE_DIM, - Quantity, - _boundary_utils, -) -from pace.util.buffer import Buffer -from pace.util.halo_data_transformer import HaloDataTransformer, HaloExchangeSpec -from pace.util.quantity import QuantityHaloSpec -from pace.util.rotate import rotate_scalar_data, rotate_vector_data - - -@pytest.fixture -def nz(): - return 5 - - -@pytest.fixture -def ny(): - return 7 - - -@pytest.fixture -def nx(): - return 7 - - -@pytest.fixture -def units(): - return "m" - - -@pytest.fixture(params=[0, 1]) -def n_buffer(request): - return request.param - - -@pytest.fixture -def n_points(): - return 1 - - -@pytest.fixture -def dtype(numpy): - return numpy.float64 - - -@pytest.fixture(params=[1, 3]) -def n_halos(request): - return request.param - - -@pytest.fixture -def origin(n_halos, dims, n_buffer): - return_list = [] - origin_dict = { - X_DIM: n_halos + n_buffer, - X_INTERFACE_DIM: n_halos + n_buffer, - Y_DIM: n_halos + n_buffer, - Y_INTERFACE_DIM: n_halos + n_buffer, - Z_DIM: n_buffer, - Z_INTERFACE_DIM: n_buffer, - } - for dim in dims: - return_list.append(origin_dict[dim]) - return return_list - - -@pytest.fixture( - params=[ - pytest.param((Y_DIM, X_DIM), id="center"), - pytest.param((Z_DIM, Y_DIM, X_DIM), id="center_3d"), - pytest.param( - (X_DIM, Y_DIM, Z_DIM), - id="center_3d_reverse", - ), - pytest.param( - (X_DIM, Z_DIM, Y_DIM), - id="center_3d_shuffle", - ), - pytest.param((Y_INTERFACE_DIM, X_INTERFACE_DIM), id="interface"), - pytest.param( - ( - Z_INTERFACE_DIM, - Y_INTERFACE_DIM, - X_INTERFACE_DIM, - ), - id="interface_3d", - ), - ] -) -def dims(request, fast): - if fast and request.param in ( - (X_DIM, Y_DIM, Z_DIM), - ( - Z_INTERFACE_DIM, - Y_INTERFACE_DIM, - X_INTERFACE_DIM, - ), - ): - pytest.skip("running in fast mode") - return request.param - - -@pytest.fixture -def shape(nz, ny, nx, dims, n_halos, n_buffer): - return_list = [] - length_dict = { - X_DIM: 2 * n_halos + nx + n_buffer, - X_INTERFACE_DIM: 2 * n_halos + nx + 1 + n_buffer, - Y_DIM: 2 * n_halos + ny + n_buffer, - Y_INTERFACE_DIM: 2 * n_halos + ny + 1 + n_buffer, - Z_DIM: nz + n_buffer, - Z_INTERFACE_DIM: nz + 1 + n_buffer, - } - for dim in dims: - return_list.append(length_dict[dim]) - return return_list - - -@pytest.fixture -def extent(n_points, dims, nz, ny, nx): - return_list = [] - extent_dict = { - X_DIM: nx, - X_INTERFACE_DIM: nx + 1, - Y_DIM: ny, - Y_INTERFACE_DIM: ny + 1, - Z_DIM: nz, - Z_INTERFACE_DIM: nz + 1, - } - for dim in dims: - return_list.append(extent_dict[dim]) - return return_list - - -def _shape_length(shape: Tuple[int]) -> int: - """Compute linear size from slices""" - length = 1 - for s in shape: - length *= s - return length - - -@pytest.fixture -def quantity(dims, units, origin, extent, shape, dtype, gt4py_backend): - """A list of quantities whose values are 42.42 in the computational domain and 1 - outside of it.""" - sz = _shape_length(shape) - print(f"{shape} {sz}") - data = np.arange(0, sz, dtype=dtype).reshape(shape) - if "gtc" not in gt4py_backend: - # should also test code if gt4py_backend is unset - gt4py_backend = None - quantity = Quantity( - data, - dims=dims, - units=units, - origin=origin, - extent=extent, - gt4py_backend=gt4py_backend, - ) - return quantity - - -@pytest.fixture(params=[-0, -1, -2, -3]) -def rotation(request): - return request.param - - -def test_data_transformer_allocate(quantity, n_halos): - boundary_north = _boundary_utils.get_boundary_slice( - quantity.dims, - quantity.origin, - quantity.extent, - quantity.data.shape, - NORTH, - n_halos, - interior=False, - ) - boundary_southwest = _boundary_utils.get_boundary_slice( - quantity.dims, - quantity.origin, - quantity.extent, - quantity.data.shape, - SOUTHWEST, - n_halos, - interior=False, - ) - - specification = QuantityHaloSpec( - n_points=n_halos, - shape=quantity.data.shape, - strides=quantity.data.strides, - itemsize=quantity.data.itemsize, - origin=quantity.metadata.origin, - extent=quantity.metadata.extent, - dims=quantity.metadata.dims, - numpy_module=quantity.np, - dtype=quantity.metadata.dtype, - ) - - exchange_descriptors = [ - HaloExchangeSpec(specification, boundary_north, 0, boundary_north), - HaloExchangeSpec(specification, boundary_southwest, 0, boundary_southwest), - ] - - data_transformer = HaloDataTransformer.get(quantity.np, exchange_descriptors) - - assert len(data_transformer.get_pack_buffer().array.shape) == 1 - assert ( - data_transformer.get_pack_buffer().array.size - == quantity.data[boundary_north].size + quantity.data[boundary_southwest].size - ) - assert len(data_transformer.get_unpack_buffer().array.shape) == 1 - assert ( - data_transformer.get_unpack_buffer().array.size - == quantity.data[boundary_north].size + quantity.data[boundary_southwest].size - ) - # clean up - Buffer.push_to_cache(data_transformer._pack_buffer) - Buffer.push_to_cache(data_transformer._unpack_buffer) - - -def _get_boundaries(quantity, n_halos): - send_boundaries = {} - recv_boundaries = {} - for direction in [ - NORTH, - NORTHWEST, - WEST, - SOUTHWEST, - SOUTH, - SOUTHEAST, - EAST, - NORTHEAST, - ]: - send_boundaries[direction] = _boundary_utils.get_boundary_slice( - quantity.dims, - quantity.origin, - quantity.extent, - quantity.data.shape, - direction, - n_halos, - interior=True, - ) - recv_boundaries[direction] = _boundary_utils.get_boundary_slice( - quantity.dims, - quantity.origin, - quantity.extent, - quantity.data.shape, - direction, - n_halos, - interior=False, - ) - - return send_boundaries, recv_boundaries - - -def test_data_transformer_scalar_pack_unpack(quantity, rotation, n_halos): - target_quantity: Quantity = copy.deepcopy(quantity) - - send_boundaries, recv_boundaries = _get_boundaries(quantity, n_halos) - - NE_corner_boundaries = { - 0: (send_boundaries[NORTHEAST], recv_boundaries[SOUTHEAST]), - -1: (send_boundaries[NORTHEAST], recv_boundaries[SOUTHWEST]), - -2: (send_boundaries[NORTHEAST], recv_boundaries[NORTHWEST]), - -3: (send_boundaries[NORTHEAST], recv_boundaries[NORTHEAST]), - } - - N_edge_boundaries = { - 0: (send_boundaries[NORTH], recv_boundaries[SOUTH]), - -1: (send_boundaries[NORTH], recv_boundaries[WEST]), - -2: (send_boundaries[NORTH], recv_boundaries[NORTH]), - -3: (send_boundaries[NORTH], recv_boundaries[EAST]), - } - - specification = QuantityHaloSpec( - n_points=n_halos, - shape=quantity.data.shape, - strides=quantity.data.strides, - itemsize=quantity.data.itemsize, - origin=quantity.metadata.origin, - extent=quantity.metadata.extent, - dims=quantity.metadata.dims, - numpy_module=quantity.np, - dtype=quantity.metadata.dtype, - ) - - exchange_descriptors = [ - HaloExchangeSpec( - specification, - N_edge_boundaries[rotation][0], - rotation, - N_edge_boundaries[rotation][1], - ), - HaloExchangeSpec( - specification, - NE_corner_boundaries[rotation][0], - rotation, - NE_corner_boundaries[rotation][1], - ), - ] - - data_transformer = HaloDataTransformer.get(quantity.np, exchange_descriptors) - - data_transformer.async_pack([quantity, quantity]) - # Simulate data transfer - data_transformer.get_unpack_buffer().assign_from( - data_transformer.get_pack_buffer().array - ) - data_transformer.async_unpack([quantity, quantity]) - data_transformer.synchronize() - - # From the copy of the original quantity we rotate data - # according to the rotation & slice and insert them back - # this reproduces the multi-buffer strategy - rotated = rotate_scalar_data( - quantity.data[N_edge_boundaries[rotation][0]], - quantity.dims, - quantity.metadata.np, - -rotation, - ) - target_quantity.data[N_edge_boundaries[rotation][1]] = rotated - rotated = rotate_scalar_data( - quantity.data[NE_corner_boundaries[rotation][0]], - quantity.dims, - quantity.metadata.np, - -rotation, - ) - target_quantity.data[NE_corner_boundaries[rotation][1]] = rotated - - assert (target_quantity.data == quantity.data).all() - - -def test_data_transformer_vector_pack_unpack(quantity, rotation, n_halos): - targe_quanity_x = copy.deepcopy(quantity) - targe_quanity_y = copy.deepcopy(targe_quanity_x) - x_quantity = quantity - y_quantity = copy.deepcopy(x_quantity) - - send_boundaries, recv_boundaries = _get_boundaries(x_quantity, n_halos) - - NE_corner_boundaries = { - 0: (send_boundaries[NORTHEAST], recv_boundaries[SOUTHEAST]), - -1: (send_boundaries[NORTHEAST], recv_boundaries[SOUTHWEST]), - -2: (send_boundaries[NORTHEAST], recv_boundaries[NORTHWEST]), - -3: (send_boundaries[NORTHEAST], recv_boundaries[NORTHEAST]), - } - - N_edge_boundaries = { - 0: (send_boundaries[NORTH], recv_boundaries[SOUTH]), - -1: (send_boundaries[NORTH], recv_boundaries[WEST]), - -2: (send_boundaries[NORTH], recv_boundaries[NORTH]), - -3: (send_boundaries[NORTH], recv_boundaries[EAST]), - } - - specification_x = QuantityHaloSpec( - n_points=n_halos, - shape=x_quantity.data.shape, - strides=x_quantity.data.strides, - itemsize=x_quantity.data.itemsize, - origin=x_quantity.metadata.origin, - extent=x_quantity.metadata.extent, - dims=x_quantity.metadata.dims, - numpy_module=x_quantity.np, - dtype=x_quantity.metadata.dtype, - ) - specification_y = QuantityHaloSpec( - n_points=n_halos, - shape=y_quantity.data.shape, - strides=y_quantity.data.strides, - itemsize=y_quantity.data.itemsize, - origin=y_quantity.metadata.origin, - extent=y_quantity.metadata.extent, - dims=y_quantity.metadata.dims, - numpy_module=y_quantity.np, - dtype=y_quantity.metadata.dtype, - ) - - exchange_descriptors_x = [ - HaloExchangeSpec( - specification_x, - N_edge_boundaries[rotation][0], - rotation, - N_edge_boundaries[rotation][1], - ), - HaloExchangeSpec( - specification_x, - NE_corner_boundaries[rotation][0], - rotation, - NE_corner_boundaries[rotation][1], - ), - ] - exchange_descriptors_y = [ - HaloExchangeSpec( - specification_y, - N_edge_boundaries[rotation][0], - rotation, - N_edge_boundaries[rotation][1], - ), - HaloExchangeSpec( - specification_y, - NE_corner_boundaries[rotation][0], - rotation, - NE_corner_boundaries[rotation][1], - ), - ] - - data_transformer = HaloDataTransformer.get( - x_quantity.np, - exchange_descriptors_x, - exchange_descriptors_y, - ) - - data_transformer.async_pack([x_quantity, x_quantity], [y_quantity, y_quantity]) - # Simulate data transfer - data_transformer.get_unpack_buffer().assign_from( - data_transformer.get_pack_buffer().array - ) - data_transformer.async_unpack([x_quantity, x_quantity], [y_quantity, y_quantity]) - data_transformer.synchronize() - - # From the copy of the original quantity we rotate data - # according to the rotation & slice and insert them bak - # this reproduce the multi-buffer strategy - rotated_x, rotated_y = rotate_vector_data( - quantity.data[N_edge_boundaries[rotation][0]], - quantity.data[N_edge_boundaries[rotation][0]], - -rotation, - quantity.dims, - quantity.metadata.np, - ) - targe_quanity_x.data[N_edge_boundaries[rotation][1]] = rotated_x - targe_quanity_y.data[N_edge_boundaries[rotation][1]] = rotated_y - rotated_x, rotated_y = rotate_vector_data( - quantity.data[NE_corner_boundaries[rotation][0]], - quantity.data[NE_corner_boundaries[rotation][0]], - -rotation, - quantity.dims, - quantity.metadata.np, - ) - targe_quanity_x.data[NE_corner_boundaries[rotation][1]] = rotated_x - targe_quanity_y.data[NE_corner_boundaries[rotation][1]] = rotated_y - - assert (targe_quanity_x.data == x_quantity.data).all() - assert (targe_quanity_y.data == y_quantity.data).all() diff --git a/util/tests/test_halo_update.py b/util/tests/test_halo_update.py deleted file mode 100644 index 609a046c3..000000000 --- a/util/tests/test_halo_update.py +++ /dev/null @@ -1,917 +0,0 @@ -import copy -from typing import Any, Dict - -import pytest - -import pace.util -from pace.util.buffer import BUFFER_CACHE - - -@pytest.fixture -def dtype(numpy): - return numpy.float64 - - -@pytest.fixture(params=[(1, 1), (3, 3)]) -def layout(request, fast): - if fast and request.param == (1, 1): - pytest.skip("running in fast mode") - else: - return request.param - - -@pytest.fixture -def nx_rank(n_points): - return max(3, n_points * 2 - 1) - - -@pytest.fixture -def ny_rank(nx_rank): - return nx_rank - - -@pytest.fixture -def nz(): - return 2 - - -@pytest.fixture -def ny(ny_rank, layout): - return ny_rank * layout[0] - - -@pytest.fixture -def nx(nx_rank, layout): - return nx_rank * layout[1] - - -@pytest.fixture(params=[1, 3]) -def n_points(request, fast): - if fast and request.param == 1: - pytest.skip("running in fast mode") - return request.param - - -@pytest.fixture(params=["fewer", "more", "same"]) -def n_points_update(request, n_points, fast): - if fast and request.param == "same": - pytest.skip("running in fast mode") - return n_points + {"fewer": -1, "more": 1, "same": 0}[request.param] - - -@pytest.fixture( - params=[ - pytest.param((pace.util.Y_DIM, pace.util.X_DIM), id="center"), - pytest.param( - (pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM), id="center_3d" - ), - pytest.param( - (pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM), - id="center_3d_reverse", - ), - pytest.param( - (pace.util.X_DIM, pace.util.Z_DIM, pace.util.Y_DIM), - id="center_3d_shuffle", - ), - pytest.param( - (pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM), id="interface" - ), - pytest.param( - ( - pace.util.Z_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, - pace.util.X_INTERFACE_DIM, - ), - id="interface_3d", - ), - ] -) -def dims(request, fast): - if fast and request.param in ( - (pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM), - ( - pace.util.Z_INTERFACE_DIM, - pace.util.Y_INTERFACE_DIM, - pace.util.X_INTERFACE_DIM, - ), - ): - pytest.skip("running in fast mode") - return request.param - - -@pytest.fixture -def units(): - return "m" - - -@pytest.fixture -def ranks_per_tile(layout): - return layout[0] * layout[1] - - -@pytest.fixture -def total_ranks(ranks_per_tile): - return 6 * ranks_per_tile - - -@pytest.fixture -def single_tile_ranks(layout): - return layout[0] * layout[1] - - -@pytest.fixture(params=[0, 1]) -def n_buffer(request): - return request.param - - -@pytest.fixture -def shape(nz, ny, nx, dims, n_points, n_buffer): - return_list = [] - length_dict = { - pace.util.X_DIM: 2 * n_points + nx + n_buffer, - pace.util.X_INTERFACE_DIM: 2 * n_points + nx + 1 + n_buffer, - pace.util.Y_DIM: 2 * n_points + ny + n_buffer, - pace.util.Y_INTERFACE_DIM: 2 * n_points + ny + 1 + n_buffer, - pace.util.Z_DIM: nz + n_buffer, - pace.util.Z_INTERFACE_DIM: nz + 1 + n_buffer, - } - for dim in dims: - return_list.append(length_dict[dim]) - return return_list - - -@pytest.fixture -def origin(n_points, dims, n_buffer): - return_list = [] - origin_dict = { - pace.util.X_DIM: n_points + n_buffer, - pace.util.X_INTERFACE_DIM: n_points + n_buffer, - pace.util.Y_DIM: n_points + n_buffer, - pace.util.Y_INTERFACE_DIM: n_points + n_buffer, - pace.util.Z_DIM: n_buffer, - pace.util.Z_INTERFACE_DIM: n_buffer, - } - for dim in dims: - return_list.append(origin_dict[dim]) - return return_list - - -@pytest.fixture -def extent(n_points, dims, nz, ny, nx): - return_list = [] - extent_dict = { - pace.util.X_DIM: nx, - pace.util.X_INTERFACE_DIM: nx + 1, - pace.util.Y_DIM: ny, - pace.util.Y_INTERFACE_DIM: ny + 1, - pace.util.Z_DIM: nz, - pace.util.Z_INTERFACE_DIM: nz + 1, - } - for dim in dims: - return_list.append(extent_dict[dim]) - return return_list - - -@pytest.fixture -def communicator_list(cube_partitioner: pace.util.CubedSpherePartitioner): - total_ranks = cube_partitioner.total_ranks - shared_buffer: Dict[str, Any] = {} - return_list = [] - for rank in range(total_ranks): - return_list.append( - pace.util.CubedSphereCommunicator( - comm=pace.util.testing.DummyComm( - rank=rank, total_ranks=total_ranks, buffer_dict=shared_buffer - ), - partitioner=cube_partitioner, - timer=pace.util.Timer(), - ) - ) - return return_list - - -@pytest.fixture -def tile_communicator_list(tile_partitioner): - total_ranks = tile_partitioner.total_ranks - shared_buffer = {} - return_list = [] - for rank in range(total_ranks): - return_list.append( - pace.util.TileCommunicator( - comm=pace.util.testing.DummyComm( - rank=rank, total_ranks=total_ranks, buffer_dict=shared_buffer - ), - partitioner=tile_partitioner, - timer=pace.util.Timer(), - ) - ) - return return_list - - -@pytest.fixture -def tile_partitioner(layout): - return pace.util.TilePartitioner(layout) - - -@pytest.fixture -def cube_partitioner(tile_partitioner): - return pace.util.CubedSpherePartitioner(tile_partitioner) - - -@pytest.fixture -def updated_slice(ny, nx, dims, n_points, n_points_update): - n_points_remain = n_points - n_points_update - return_list = [] - length_dict = { - pace.util.X_DIM: slice(n_points_remain, n_points + nx + n_points_update), - pace.util.X_INTERFACE_DIM: slice( - n_points_remain, n_points + nx + 1 + n_points_update - ), - pace.util.Y_DIM: slice(n_points_remain, n_points + ny + n_points_update), - pace.util.Y_INTERFACE_DIM: slice( - n_points_remain, n_points + ny + 1 + n_points_update - ), - pace.util.Z_DIM: slice(None, None), - pace.util.Z_INTERFACE_DIM: slice(None, None), - } - for dim in dims: - return_list.append(length_dict[dim]) - return return_list - - -@pytest.fixture -def remaining_ones(nz, ny, nx, n_points, n_points_update): - width = n_points - n_points_update - return (2 * nx + 2 * ny + 4 * width) * width - - -@pytest.fixture -def boundary_dict(ranks_per_tile): - if ranks_per_tile == 1: - return {0: pace.util.EDGE_BOUNDARY_TYPES} - elif ranks_per_tile == 4: - return { - 0: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHWEST, pace.util.NORTHEAST, pace.util.SOUTHEAST), - 1: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHWEST, pace.util.NORTHEAST, pace.util.SOUTHWEST), - 2: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHEAST, pace.util.SOUTHWEST, pace.util.SOUTHEAST), - 3: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHWEST, pace.util.SOUTHWEST, pace.util.SOUTHEAST), - } - elif ranks_per_tile == 9: - return { - 0: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHWEST, pace.util.NORTHEAST, pace.util.SOUTHEAST), - 1: pace.util.BOUNDARY_TYPES, - 2: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHWEST, pace.util.NORTHEAST, pace.util.SOUTHWEST), - 3: pace.util.BOUNDARY_TYPES, - 4: pace.util.BOUNDARY_TYPES, - 5: pace.util.BOUNDARY_TYPES, - 6: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHEAST, pace.util.SOUTHWEST, pace.util.SOUTHEAST), - 7: pace.util.BOUNDARY_TYPES, - 8: pace.util.EDGE_BOUNDARY_TYPES - + (pace.util.NORTHWEST, pace.util.SOUTHWEST, pace.util.SOUTHEAST), - } - else: - raise NotImplementedError(ranks_per_tile) - - -@pytest.fixture -def depth_quantity_list( - total_ranks, dims, units, origin, extent, shape, numpy, dtype, n_points -): - """A list of quantities whose value indicates the distance from the computational - domain boundary.""" - return_list = [] - for rank in range(total_ranks): - data = numpy.empty(shape, dtype=dtype) - data[:] = numpy.nan - for n_inside in range(max(n_points, max(extent) // 2), -1, -1): - for i, dim in enumerate(dims): - if (n_inside <= extent[i] // 2) and (dim in pace.util.HORIZONTAL_DIMS): - pos = [slice(None, None)] * len(dims) - pos[i] = origin[i] + n_inside - data[tuple(pos)] = n_inside - pos[i] = origin[i] + extent[i] - 1 - n_inside - data[tuple(pos)] = n_inside - for n_outside in range(1, n_points + 1): - for i, dim in enumerate(dims): - if dim in pace.util.HORIZONTAL_DIMS: - pos = [slice(None, None)] * len(dims) - pos[i] = origin[i] - n_outside - data[tuple(pos)] = numpy.nan - pos[i] = origin[i] + extent[i] + n_outside - 1 - data[tuple(pos)] = numpy.nan - quantity = pace.util.Quantity( - data, - dims=dims, - units=units, - origin=origin, - extent=extent, - ) - return_list.append(quantity) - return return_list - - -@pytest.fixture -def tile_depth_quantity_list( - single_tile_ranks, dims, units, origin, extent, shape, numpy, dtype, n_points -): - """A list of quantities whose value indicates the distance from the computational - domain boundary for a single tile.""" - return_list = [] - for rank in range(single_tile_ranks): - data = numpy.empty(shape, dtype=dtype) - data[:] = numpy.nan - for n_inside in range(max(n_points, max(extent) // 2), -1, -1): - for i, dim in enumerate(dims): - if (n_inside <= extent[i] // 2) and (dim in pace.util.HORIZONTAL_DIMS): - pos = [slice(None, None)] * len(dims) - pos[i] = origin[i] + n_inside - data[tuple(pos)] = n_inside - pos[i] = origin[i] + extent[i] - 1 - n_inside - data[tuple(pos)] = n_inside - for n_outside in range(1, n_points + 1): - for i, dim in enumerate(dims): - if dim in pace.util.HORIZONTAL_DIMS: - pos = [slice(None, None)] * len(dims) - pos[i] = origin[i] - n_outside - data[tuple(pos)] = numpy.nan - pos[i] = origin[i] + extent[i] + n_outside - 1 - data[tuple(pos)] = numpy.nan - quantity = pace.util.Quantity( - data, - dims=dims, - units=units, - origin=origin, - extent=extent, - ) - return_list.append(quantity) - return return_list - - -@pytest.mark.parametrize( - "layout, n_points, n_points_update, dims", - [[(1, 1), 3, "same", [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM]]], - indirect=True, -) -def test_halo_update_timer( - zeros_quantity_list, - communicator_list, - n_points_update, - n_points, - numpy, - subtests, - boundary_dict, - ranks_per_tile, -): - """ - test that halo update produces nonzero timings for all expected labels - """ - halo_updater_list = [] - for communicator, quantity in zip(communicator_list, zeros_quantity_list): - halo_updater = communicator.start_halo_update(quantity, n_points_update) - halo_updater_list.append(halo_updater) - for halo_updater in halo_updater_list: - halo_updater.wait() - required_times_keys = ( - "pack", - "unpack", - "Isend", - "Irecv", - "wait", - "halo_exchange_global", - ) - for communicator in communicator_list: - with subtests.test(rank=communicator.rank): - assert isinstance(communicator.timer, pace.util.Timer) - times = communicator.timer.times - missing_keys = set(required_times_keys).difference(times.keys()) - assert len(missing_keys) == 0 - extra_keys = set(times.keys()).difference(required_times_keys) - assert len(extra_keys) == 0 - for key in required_times_keys: - assert times[key] > 0.0 - assert isinstance(times[key], float) - - -def test_depth_halo_update( - depth_quantity_list, - communicator_list, - n_points_update, - n_points, - numpy, - subtests, - boundary_dict, - ranks_per_tile, -): - """test that written values have the correct orientation""" - sample_quantity = depth_quantity_list[0] - y_dim, x_dim = get_horizontal_dims(sample_quantity.dims) - y_index = sample_quantity.dims.index(y_dim) - x_index = sample_quantity.dims.index(x_dim) - y_extent = sample_quantity.extent[y_index] - x_extent = sample_quantity.extent[x_index] - halo_updater_list = [] - if 0 < n_points_update <= n_points: - for communicator, quantity in zip(communicator_list, depth_quantity_list): - halo_updater = communicator.start_halo_update(quantity, n_points_update) - halo_updater_list.append(halo_updater) - for halo_updater in halo_updater_list: - halo_updater.wait() - for rank, quantity in enumerate(depth_quantity_list): - with subtests.test(rank=rank, quantity=quantity): - for dim, extent in ((y_dim, y_extent), (x_dim, x_extent)): - assert numpy.all(quantity.sel(**{dim: -1}) <= 1) - assert numpy.all(quantity.sel(**{dim: extent}) <= 1) - if n_points_update >= 2: - assert numpy.all(quantity.sel(**{dim: -2}) <= 2) - assert numpy.all(quantity.sel(**{dim: extent + 1}) <= 2) - if n_points_update >= 3: - assert numpy.all(quantity.sel(**{dim: -3}) <= 3) - assert numpy.all(quantity.sel(**{dim: extent + 2}) <= 3) - if n_points_update > 3: - raise NotImplementedError(n_points_update) - - -@pytest.mark.parametrize("layout", [(3, 3)], indirect=True) -def test_depth_tile_halo_update( - tile_depth_quantity_list, - tile_communicator_list, - n_points_update, - n_points, - numpy, - subtests, - boundary_dict, - ranks_per_tile, -): - """test that written values have the correct orientation on a tile""" - sample_quantity = tile_depth_quantity_list[0] - y_dim, x_dim = get_horizontal_dims(sample_quantity.dims) - y_index = sample_quantity.dims.index(y_dim) - x_index = sample_quantity.dims.index(x_dim) - y_extent = sample_quantity.extent[y_index] - x_extent = sample_quantity.extent[x_index] - halo_updater_list = [] - if 0 < n_points_update <= n_points: - for communicator, quantity in zip( - tile_communicator_list, tile_depth_quantity_list - ): - halo_updater = communicator.start_halo_update(quantity, n_points_update) - halo_updater_list.append(halo_updater) - for halo_updater in halo_updater_list: - halo_updater.wait() - for rank, quantity in enumerate(tile_depth_quantity_list): - with subtests.test(rank=rank, quantity=quantity): - for dim, extent in ((y_dim, y_extent), (x_dim, x_extent)): - assert numpy.all(quantity.sel(**{dim: -1}) <= 1) - assert numpy.all(quantity.sel(**{dim: extent}) <= 1) - if n_points_update >= 2: - assert numpy.all(quantity.sel(**{dim: -2}) <= 2) - assert numpy.all(quantity.sel(**{dim: extent + 1}) <= 2) - if n_points_update >= 3: - assert numpy.all(quantity.sel(**{dim: -3}) <= 3) - assert numpy.all(quantity.sel(**{dim: extent + 2}) <= 3) - if n_points_update > 3: - raise NotImplementedError(n_points_update) - - -@pytest.fixture -def zeros_quantity_list(total_ranks, dims, units, origin, extent, shape, numpy, dtype): - """A list of quantities whose values are 0 in the computational domain and 1 - outside of it.""" - return_list = [] - for rank in range(total_ranks): - data = numpy.ones(shape, dtype=dtype) - quantity = pace.util.Quantity( - data, - dims=dims, - units=units, - origin=origin, - extent=extent, - ) - quantity.view[:] = 0.0 - return_list.append(quantity) - return return_list - - -@pytest.fixture -def zeros_quantity_tile_list( - single_tile_ranks, dims, units, origin, extent, shape, numpy, dtype -): - """A list of quantities whose values are 0 in the computational domain and 1 - outside of it on a single tile.""" - return_list = [] - for rank in range(single_tile_ranks): - data = numpy.ones(shape, dtype=dtype) - quantity = pace.util.Quantity( - data, - dims=dims, - units=units, - origin=origin, - extent=extent, - ) - quantity.view[:] = 0.0 - return_list.append(quantity) - return return_list - - -@pytest.mark.parametrize( - "n_points, n_points_update, n_buffer", [(2, "more", 0)], indirect=True -) -def test_too_many_points_requested( - zeros_quantity_list, - communicator_list, - n_points_update, -): - """ - test that an exception is raised when trying to update more halo points than exist - """ - for communicator, quantity in zip(communicator_list, zeros_quantity_list): - with pytest.raises(pace.util.OutOfBoundsError): - communicator.start_halo_update(quantity, n_points_update) - - -@pytest.mark.parametrize( - "n_points, n_points_update, n_buffer", [(2, "more", 0)], indirect=True -) -@pytest.mark.parametrize("layout", [(3, 3)], indirect=True) -def test_too_many_points_requested_tile( - zeros_quantity_tile_list, - tile_communicator_list, - n_points_update, -): - """ - test that an exception is raised when trying to update more halo points than exist - on a tile - """ - for communicator, quantity in zip(tile_communicator_list, zeros_quantity_tile_list): - with pytest.raises(pace.util.OutOfBoundsError): - communicator.start_halo_update(quantity, n_points_update) - - -def test_zeros_halo_update( - zeros_quantity_list, - communicator_list, - n_points_update, - n_points, - numpy, - subtests, - boundary_dict, - ranks_per_tile, -): - """test that zeros from adjacent domains get written over ones on local halo""" - halo_updater_list = [] - if 0 < n_points_update <= n_points: - for communicator, quantity in zip(communicator_list, zeros_quantity_list): - halo_updater = communicator.start_halo_update(quantity, n_points_update) - halo_updater_list.append(halo_updater) - for halo_updater in halo_updater_list: - halo_updater.wait() - for rank, quantity in enumerate(zeros_quantity_list): - boundaries = boundary_dict[rank % ranks_per_tile] - for boundary in boundaries: - boundary_slice = pace.util._boundary_utils.get_boundary_slice( - quantity.dims, - quantity.origin, - quantity.extent, - quantity.data.shape, - boundary, - n_points_update, - interior=False, - ) - with subtests.test( - quantity=quantity, - rank=rank, - boundary=boundary, - boundary_slice=boundary_slice, - ): - numpy.testing.assert_array_equal( - quantity.data[tuple(boundary_slice)], 0.0 - ) - - -@pytest.mark.parametrize( - "layout, n_points, n_points_update, dims", - [ - [(1, 1), 3, "same", [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM]], - [(2, 2), 3, "same", [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM]], - ], - indirect=True, -) -def test_tile_halo_update_unsupported_layout( - zeros_quantity_tile_list, - tile_communicator_list, - n_points_update, -): - """test that correct exception is raised if layout is unsupported""" - # if you delete this test because this is now implemented, - # please add the appropriate layout cases to the main halo update test - for communicator, quantity in zip(tile_communicator_list, zeros_quantity_tile_list): - with pytest.raises(NotImplementedError): - communicator.start_halo_update(quantity, n_points_update) - with pytest.raises(NotImplementedError): - communicator.halo_update(quantity, n_points_update) - - -@pytest.mark.parametrize("layout", [(3, 3)], indirect=True) -def test_zeros_tile_halo_update( - zeros_quantity_tile_list, - tile_communicator_list, - n_points_update, - n_points, - numpy, - subtests, - boundary_dict, - ranks_per_tile, -): - """test that zeros from adjacent domains get written over ones on local halo - on a single tile""" - halo_updater_list = [] - if 0 < n_points_update <= n_points: - for communicator, quantity in zip( - tile_communicator_list, zeros_quantity_tile_list - ): - halo_updater = communicator.start_halo_update(quantity, n_points_update) - halo_updater_list.append(halo_updater) - for halo_updater in halo_updater_list: - halo_updater.wait() - for rank, quantity in enumerate(zeros_quantity_tile_list): - boundaries = boundary_dict[ - rank % ranks_per_tile - ] # Is the %ranks_per_tile necessary? - for boundary in boundaries: - boundary_slice = pace.util._boundary_utils.get_boundary_slice( - quantity.dims, - quantity.origin, - quantity.extent, - quantity.data.shape, - boundary, - n_points_update, - interior=False, - ) - with subtests.test( - quantity=quantity, - rank=rank, - boundary=boundary, - boundary_slice=boundary_slice, - ): - numpy.testing.assert_array_equal( - quantity.data[tuple(boundary_slice)], 0.0 - ) - - -def test_zeros_vector_halo_update( - zeros_quantity_list, - communicator_list, - n_points_update, - n_points, - numpy, - subtests, - boundary_dict, - ranks_per_tile, -): - """test that zeros from adjacent domains get written over ones on local halo""" - x_list = zeros_quantity_list - y_list = copy.deepcopy(x_list) - if 0 < n_points_update <= n_points: - halo_updater_list = [] - for communicator, y_quantity, x_quantity in zip( - communicator_list, y_list, x_list - ): - halo_updater_list.append( - communicator.start_vector_halo_update( - y_quantity, x_quantity, n_points_update - ) - ) - for halo_updater in halo_updater_list: - halo_updater.wait() - for rank, (y_quantity, x_quantity) in enumerate(zip(y_list, x_list)): - boundaries = boundary_dict[rank % ranks_per_tile] - for boundary in boundaries: - boundary_slice = pace.util._boundary_utils.get_boundary_slice( - x_quantity.dims, - x_quantity.origin, - x_quantity.extent, - x_quantity.data.shape, - boundary, - n_points_update, - interior=False, - ) - with subtests.test( - x_quantity=x_quantity, - rank=rank, - boundary=boundary, - boundary_slice=boundary_slice, - ): - for quantity in y_quantity, x_quantity: - numpy.testing.assert_array_equal( - quantity.data[tuple(boundary_slice)], 0.0 - ) - - -@pytest.mark.parametrize("layout", [(3, 3)], indirect=True) -def test_zeros_vector_tile_halo_update( - zeros_quantity_tile_list, - tile_communicator_list, - n_points_update, - n_points, - numpy, - subtests, - boundary_dict, - ranks_per_tile, -): - """test that zeros from adjacent domains get written over ones on local halo - on a single tile""" - x_list = zeros_quantity_tile_list - y_list = copy.deepcopy(x_list) - if 0 < n_points_update <= n_points: - halo_updater_list = [] - for communicator, y_quantity, x_quantity in zip( - tile_communicator_list, y_list, x_list - ): - halo_updater_list.append( - communicator.start_vector_halo_update( - y_quantity, x_quantity, n_points_update - ) - ) - for halo_updater in halo_updater_list: - halo_updater.wait() - for rank, (y_quantity, x_quantity) in enumerate(zip(y_list, x_list)): - boundaries = boundary_dict[rank % ranks_per_tile] - for boundary in boundaries: - boundary_slice = pace.util._boundary_utils.get_boundary_slice( - x_quantity.dims, - x_quantity.origin, - x_quantity.extent, - x_quantity.data.shape, - boundary, - n_points_update, - interior=False, - ) - with subtests.test( - x_quantity=x_quantity, - rank=rank, - boundary=boundary, - boundary_slice=boundary_slice, - ): - for quantity in y_quantity, x_quantity: - numpy.testing.assert_array_equal( - quantity.data[tuple(boundary_slice)], 0.0 - ) - - -@pytest.mark.parametrize( - "layout, n_points, n_points_update, dims", - [[(1, 1), 3, "same", [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM]]], - indirect=True, -) -def test_vector_halo_update_timer( - zeros_quantity_list, - communicator_list, - n_points_update, - n_points, - numpy, - subtests, - boundary_dict, - ranks_per_tile, -): - """ - test that halo update produces nonzero timings for all expected labels - """ - x_list = zeros_quantity_list - y_list = copy.deepcopy(x_list) - halo_updater_list = [] - for communicator, y_quantity, x_quantity in zip(communicator_list, y_list, x_list): - halo_updater_list.append( - communicator.start_vector_halo_update( - y_quantity, x_quantity, n_points_update - ) - ) - for halo_updater in halo_updater_list: - halo_updater.wait() - required_times_keys = ( - "pack", - "unpack", - "Isend", - "Irecv", - "wait", - "halo_exchange_global", - ) - for communicator in communicator_list: - with subtests.test(rank=communicator.rank): - assert isinstance(communicator.timer, pace.util.Timer) - times = communicator.timer.times - missing_keys = set(required_times_keys).difference(times.keys()) - assert len(missing_keys) == 0 - extra_keys = set(times.keys()).difference(required_times_keys) - assert len(extra_keys) == 0 - for key in required_times_keys: - assert times[key] > 0.0 - assert isinstance(times[key], float) - - -def get_horizontal_dims(dims): - for dim in pace.util.X_DIMS: - if dim in dims: - x_dim = dim - break - else: - raise ValueError(f"no x dimension in {dims}") - for dim in pace.util.Y_DIMS: - if dim in dims: - y_dim = dim - break - else: - raise ValueError(f"no y dimension in {dims}") - return y_dim, x_dim - - -@pytest.mark.parametrize( - "layout, n_points, n_points_update, n_buffer", - [((1, 1), 2, "more", 0)], - indirect=True, -) -def test_halo_updater_stability( - zeros_quantity_list, - communicator_list, - n_points_update, - n_points, - numpy, - subtests, - boundary_dict, - ranks_per_tile, -): - """ - Test that that halo_updater.start()/wait() is consistent through multiple execution. - Test the internal buffers are re-used properly and re-cached properly. - """ - BUFFER_CACHE.clear() - halo_updaters = [] - for communicator, quantity in zip(communicator_list, zeros_quantity_list): - specification = pace.util.QuantityHaloSpec( - n_points, - quantity.data.strides, - quantity.data.itemsize, - quantity.data.shape, - quantity.origin, - quantity.extent, - quantity.dims, - quantity.np, - quantity.metadata.dtype, - ) - halo_updater = pace.util.HaloUpdater.from_scalar_specifications( - comm=communicator, - numpy_like_module=quantity.np, - specifications=[specification], - boundaries=communicator.boundaries.values(), - tag=0, - ) - halo_updaters.append(halo_updater) - - # Caches must be created before we run (e.g. cache line != 0 - # and no caches in cache line since they are used) - assert len(BUFFER_CACHE) == 1 - assert len(next(iter(BUFFER_CACHE.values()))) == 0 - - # First run - for halo_updater in halo_updaters: - halo_updater.start([quantity]) - for halo_updater in halo_updaters: - halo_updater.wait() - - # Copy the exchanged buffer and trigger multiple runs - # The buffer should stay stable since we are exchanging the same information - exchanged_once_quantity = copy.deepcopy(quantity) - for halo_updater in halo_updaters: - halo_updater.start([quantity]) - for halo_updater in halo_updaters: - halo_updater.wait() - for halo_updater in halo_updaters: - halo_updater.start([quantity]) - for halo_updater in halo_updaters: - halo_updater.wait() - assert (quantity.data == exchanged_once_quantity.data).all() - - # All caches are still in use - assert len(BUFFER_CACHE) == 1 - assert len(next(iter(BUFFER_CACHE.values()))) == 0 - - # Manually call finalize on the transfomers - # This should recache all the buffers - # DSL-816 will refactor that behavior out - for halo_updater in halo_updaters: - for transformer in halo_updater._transformers.values(): - transformer.finalize() - - # With the layout constrained we will have - # 6 (ranks) * 4 (boundaries) * 2 (send&recv) buffers recached. - assert len(BUFFER_CACHE) == 1 - assert ( - len(next(iter(BUFFER_CACHE.values()))) - == len(communicator_list) * len(communicator.boundaries.values()) * 2 - ) diff --git a/util/tests/test_halo_update_ranks.py b/util/tests/test_halo_update_ranks.py deleted file mode 100644 index 427f952d5..000000000 --- a/util/tests/test_halo_update_ranks.py +++ /dev/null @@ -1,151 +0,0 @@ -import pytest - -import pace.util - - -@pytest.fixture -def dtype(numpy): - return numpy.float64 - - -@pytest.fixture(params=[(1, 1)]) -def layout(request): - return request.param - - -@pytest.fixture -def ranks_per_tile(layout): - return layout[0] * layout[1] - - -@pytest.fixture -def total_ranks(ranks_per_tile): - return 6 * ranks_per_tile - - -@pytest.fixture -def shape(nz, ny, nx, dims, n_points): - return_list = [] - length_dict = { - pace.util.X_DIM: 2 * n_points + nx, - pace.util.X_INTERFACE_DIM: 2 * n_points + nx + 1, - pace.util.Y_DIM: 2 * n_points + ny, - pace.util.Y_INTERFACE_DIM: 2 * n_points + ny + 1, - pace.util.Z_DIM: nz, - pace.util.Z_INTERFACE_DIM: nz + 1, - } - for dim in dims: - return_list.append(length_dict[dim]) - return return_list - - -@pytest.fixture -def origin(n_points, dims): - return_list = [] - origin_dict = { - pace.util.X_DIM: n_points, - pace.util.X_INTERFACE_DIM: n_points, - pace.util.Y_DIM: n_points, - pace.util.Y_INTERFACE_DIM: n_points, - pace.util.Z_DIM: 0, - pace.util.Z_INTERFACE_DIM: 0, - } - for dim in dims: - return_list.append(origin_dict[dim]) - return return_list - - -@pytest.fixture -def extent(n_points, dims, nz, ny, nx): - return_list = [] - extent_dict = { - pace.util.X_DIM: nx, - pace.util.X_INTERFACE_DIM: nx + 1, - pace.util.Y_DIM: ny, - pace.util.Y_INTERFACE_DIM: ny + 1, - pace.util.Z_DIM: nz, - pace.util.Z_INTERFACE_DIM: nz + 1, - } - for dim in dims: - return_list.append(extent_dict[dim]) - return return_list - - -@pytest.fixture -def tile_partitioner(layout): - return pace.util.TilePartitioner(layout) - - -@pytest.fixture -def cube_partitioner(tile_partitioner): - return pace.util.CubedSpherePartitioner(tile_partitioner) - - -@pytest.fixture() -def communicator_list(cube_partitioner, total_ranks): - shared_buffer = {} - return_list = [] - for rank in range(cube_partitioner.total_ranks): - return_list.append( - pace.util.CubedSphereCommunicator( - comm=pace.util.testing.DummyComm( - rank=rank, total_ranks=total_ranks, buffer_dict=shared_buffer - ), - partitioner=cube_partitioner, - timer=pace.util.Timer(), - ) - ) - return return_list - - -@pytest.fixture -def rank_quantity_list(total_ranks, numpy, dtype): - quantity_list = [] - for rank in range(total_ranks): - data = numpy.empty((3, 3), dtype=dtype) - data[:] = numpy.nan - data[1, 1] = rank - quantity = pace.util.Quantity( - data, - dims=(pace.util.Y_DIM, pace.util.X_DIM), - units="m", - origin=(1, 1), - extent=(1, 1), - ) - quantity_list.append(quantity) - return quantity_list - - -@pytest.mark.filterwarnings("ignore:invalid value encountered in remainder") -def test_correct_rank_layout(rank_quantity_list, communicator_list, subtests, numpy): - halo_updater_list = [] - for communicator, quantity in zip(communicator_list, rank_quantity_list): - halo_updater = communicator.start_halo_update(quantity, 1) - halo_updater_list.append(halo_updater) - for halo_updater in halo_updater_list: - halo_updater.wait() - for rank, quantity in enumerate(rank_quantity_list): - with subtests.test(rank=rank): - if rank % 2 == 0: - target_data = ( - numpy.array( - [ - [numpy.nan, rank - 1, numpy.nan], - [rank - 2, rank, rank + 1], - [numpy.nan, rank + 2, numpy.nan], - ] - ) - % 6 - ) - else: - target_data = ( - numpy.array( - [ - [numpy.nan, rank - 2, numpy.nan], - [rank - 1, rank, rank + 2], - [numpy.nan, rank + 1, numpy.nan], - ] - ) - % 6 - ) - numpy.testing.assert_array_equal(quantity.data, target_data) diff --git a/util/tests/test_legacy_restart.py b/util/tests/test_legacy_restart.py deleted file mode 100644 index 94d33a273..000000000 --- a/util/tests/test_legacy_restart.py +++ /dev/null @@ -1,405 +0,0 @@ -import os -import tempfile - -import cftime - - -try: - import xarray as xr -except ModuleNotFoundError: - xr = None -import numpy as np -import pytest - -import pace.util -import pace.util._legacy_restart -from pace.util.testing import DummyComm - - -requires_xarray = pytest.mark.skipif(xr is None, reason="xarray is not installed") - -TEST_DIRECTORY = os.path.dirname(os.path.realpath(__file__)) -DATA_DIRECTORY = os.path.join(TEST_DIRECTORY, "data") - - -@pytest.fixture(params=[(1, 1)]) -def layout(request): - return request.param - - -@requires_xarray -def get_c12_restart_state_list(layout, only_names, tracer_properties): - total_ranks = 6 * layout[0] * layout[1] - shared_buffer = {} - communicator_list = [] - for rank in range(total_ranks): - communicator = pace.util.CubedSphereCommunicator( - DummyComm(rank, total_ranks, shared_buffer), - pace.util.CubedSpherePartitioner(pace.util.TilePartitioner(layout)), - ) - communicator_list.append(communicator) - state_list = [] - for communicator in communicator_list: - state_list.append( - pace.util.open_restart( - os.path.join(DATA_DIRECTORY, "c12_restart"), - communicator, - only_names=only_names, - tracer_properties=tracer_properties, - ) - ) - return state_list - - -@pytest.mark.parametrize("layout", [(1, 1), (3, 3)]) -@pytest.mark.cpu_only -@requires_xarray -def test_open_c12_restart(layout): - tracer_properties = {} - only_names = None - c12_restart_state_list = get_c12_restart_state_list( - layout, only_names, tracer_properties - ) - # C12 has 12 gridcells along each tile side, we divide this across processors - ny = 12 / layout[0] - nx = 12 / layout[1] - for state in c12_restart_state_list: - assert "time" in state.keys() - assert len(state.keys()) == 63 - for name, value in state.items(): - if name == "time": - assert isinstance(value, cftime.DatetimeJulian) - else: - assert isinstance(value, pace.util.Quantity) - assert np.sum(np.isnan(value.view[:])) == 0 - for dim, extent in zip(value.dims, value.extent): - if dim == pace.util.X_DIM: - assert extent == nx - elif dim == pace.util.X_INTERFACE_DIM: - assert extent == nx + 1 - elif dim == pace.util.Y_DIM: - assert extent == ny - elif dim == pace.util.Y_INTERFACE_DIM: - assert extent == ny + 1 - - -@pytest.mark.parametrize( - "tracer_properties", - [ - { - "specific_humidity": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], - "units": "kg/kg", - "restart_name": "sphum", - }, - }, - { - "specific_humidity_by_another_name": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], - "units": "kg/kg", - "restart_name": "sphum", - }, - }, - { - "specific_humidity": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], - "units": "kg/kg", - "restart_name": "sphum", - }, - }, - { - "specific_humidity": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], - "units": "kg/kg", - "restart_name": "sphum", - }, - "snow_water_mixing_ratio": { - "dims": [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], - "units": "kg/kg", - "restart_name": "snowwat", - }, - }, - ], -) -@requires_xarray -@pytest.mark.cpu_only -def test_open_c12_restart_tracer_properties(layout, tracer_properties): - only_names = None - c12_restart_state_list = get_c12_restart_state_list( - layout, only_names, tracer_properties - ) - for state in c12_restart_state_list: - for name, properties in tracer_properties.items(): - assert name in state.keys() - assert state[name].dims == tuple(properties["dims"]) - assert state[name].attrs["units"] == properties["units"] - assert properties["restart_name"] not in state - - -@pytest.mark.parametrize("layout", [(1, 1), (3, 3)]) -@pytest.mark.cpu_only -@requires_xarray -def test_open_c12_restart_empty_to_state_without_crashing(layout): - total_ranks = 6 * layout[0] * layout[1] - ny = 12 / layout[0] - nx = 12 / layout[1] - shared_buffer = {} - communicator_list = [] - for rank in range(total_ranks): - communicator = pace.util.CubedSphereCommunicator( - DummyComm(rank, total_ranks, shared_buffer), - pace.util.CubedSpherePartitioner(pace.util.TilePartitioner(layout)), - ) - communicator_list.append(communicator) - state_list = [] - for communicator in communicator_list: - state_list.append({}) - pace.util.open_restart( - os.path.join(DATA_DIRECTORY, "c12_restart"), - communicator, - to_state=state_list[-1], - ) - for state in state_list: - assert "time" in state.keys() - assert len(state.keys()) == 63 - for name, value in state.items(): - if name == "time": - assert isinstance(value, cftime.DatetimeJulian) - else: - assert isinstance(value, pace.util.Quantity) - assert np.sum(np.isnan(value.view[:])) == 0 - for dim, extent in zip(value.dims, value.extent): - if dim == pace.util.X_DIM: - assert extent == nx - elif dim == pace.util.X_INTERFACE_DIM: - assert extent == nx + 1 - elif dim == pace.util.Y_DIM: - assert extent == ny - elif dim == pace.util.Y_INTERFACE_DIM: - assert extent == ny + 1 - - -@pytest.mark.parametrize("layout", [(1, 1), (3, 3)]) -@pytest.mark.cpu_only -@requires_xarray -def test_open_c12_restart_to_allocated_state_without_crashing(layout): - total_ranks = 6 * layout[0] * layout[1] - ny = 12 / layout[0] - nx = 12 / layout[1] - shared_buffer = {} - communicator_list = [] - for rank in range(total_ranks): - communicator = pace.util.CubedSphereCommunicator( - DummyComm(rank, total_ranks, shared_buffer), - pace.util.CubedSpherePartitioner(pace.util.TilePartitioner(layout)), - ) - communicator_list.append(communicator) - state_list = [] - for communicator in communicator_list: - state_list.append( - pace.util.open_restart( - os.path.join(DATA_DIRECTORY, "c12_restart"), communicator - ) - ) - for state in state_list: - for name, value in state.items(): - if name != "time": - value.view[:] = np.nan - for state, communicator in zip(state_list, communicator_list): - pace.util.open_restart( - os.path.join(DATA_DIRECTORY, "c12_restart"), communicator, to_state=state - ) - - for state in state_list: - assert "time" in state.keys() - assert len(state.keys()) == 63 - for name, value in state.items(): - if name == "time": - assert isinstance(value, cftime.DatetimeJulian) - else: - assert isinstance(value, pace.util.Quantity) - assert np.sum(np.isnan(value.view[:])) == 0 - for dim, extent in zip(value.dims, value.extent): - if dim == pace.util.X_DIM: - assert extent == nx - elif dim == pace.util.X_INTERFACE_DIM: - assert extent == nx + 1 - elif dim == pace.util.Y_DIM: - assert extent == ny - elif dim == pace.util.Y_INTERFACE_DIM: - assert extent == ny + 1 - - -@pytest.fixture( - params=[ - ("coupler_julian.res", cftime.DatetimeJulian), - ("coupler_thirty_day.res", cftime.Datetime360Day), - ("coupler_noleap.res", cftime.DatetimeNoLeap), - ], - ids=["julian", "thirty_day", "noleap"], -) -def coupler_res_file_and_time(request): - file, expected_date_type = request.param - return ( - os.path.join(DATA_DIRECTORY, file), - expected_date_type(2016, 8, 3), - ) - - -@pytest.mark.cpu_only -def test_get_current_date_from_coupler_res(coupler_res_file_and_time): - filename, current_time = coupler_res_file_and_time - with open(filename, "r") as f: - result = pace.util.io.get_current_date_from_coupler_res(f) - assert result == current_time - - -@pytest.fixture -def data_array(): - return xr.DataArray(np.random.randn(2, 3), dims=["x", "y"], attrs={"units": "m"}) - - -@pytest.fixture(params=["empty", "1_dim", "2_dims"]) -def new_dims(request): - if request.param == "empty": - return () - elif request.param == "1_dim": - return ("dim1",) - elif request.param == "2_dims": - return ("dim_2", "dim_1") - else: - raise NotImplementedError() - - -@pytest.fixture -def result_dims(data_array, new_dims): - kept_dims = len(data_array.dims) - len(new_dims) - return tuple(list(data_array.dims[:kept_dims]) + list(new_dims)) - - -@pytest.mark.cpu_only -@requires_xarray -def test_apply_dims(data_array, new_dims, result_dims): - result = pace.util._legacy_restart._apply_dims(data_array, new_dims) - np.testing.assert_array_equal(result.values, data_array.values) - assert result.dims == result_dims - assert result.attrs == data_array.attrs - - -@pytest.mark.parametrize( - "old_dict, key_mapping, new_dict", - [ - pytest.param( - {}, - {}, - {}, - id="empty_dict", - ), - pytest.param( - {"key1": 1, "key2": 2}, - {}, - {"key1": 1, "key2": 2}, - id="empty_map", - ), - pytest.param( - {"key1": 1, "key2": 2}, - {"key1": "key_1"}, - {"key_1": 1, "key2": 2}, - id="one_item_map", - ), - pytest.param( - {"key1": 1, "key2": 2}, - {"key3": "key_3"}, - {"key1": 1, "key2": 2}, - id="map_not_in_dict", - ), - pytest.param( - {"key1": 1, "key2": 2}, - {"key1": "key_1", "key2": "key_2"}, - {"key_1": 1, "key_2": 2}, - id="two_item_map", - ), - ], -) -@pytest.mark.cpu_only -def test_map_keys(old_dict, key_mapping, new_dict): - result = pace.util._legacy_restart.map_keys(old_dict, key_mapping) - assert result == new_dict - - -@pytest.mark.parametrize( - "rank, total_ranks, suffix", - [ - pytest.param( - 0, - 6, - ".tile1.nc", - id="first_tile", - ), - pytest.param( - 2, - 6, - ".tile3.nc", - id="third_tile", - ), - pytest.param( - 2, - 24, - ".tile1.nc.0002", - id="third_subtile", - ), - pytest.param( - 6, - 24, - ".tile2.nc.0002", - id="third_subtile_second_tile", - ), - ], -) -@pytest.mark.cpu_only -def test_get_rank_suffix(rank, total_ranks, suffix): - result = pace.util._legacy_restart.get_rank_suffix(rank, total_ranks) - assert result == suffix - - -@pytest.mark.parametrize("invalid_total_ranks", [5, 7, 9, 23]) -@pytest.mark.cpu_only -def test_get_rank_suffix_invalid_total_ranks(invalid_total_ranks): - with pytest.raises(ValueError): - # total_ranks should be multiple of 6 - pace.util._legacy_restart.get_rank_suffix(0, invalid_total_ranks) - - -@pytest.mark.cpu_only -@requires_xarray -def test_read_state_incorrectly_encoded_time(): - with tempfile.NamedTemporaryFile(mode="w", suffix=".nc") as file: - state_ds = xr.DataArray(0.0, name="time").to_dataset() - state_ds.to_netcdf(file.name) - with pytest.raises(ValueError, match="Time in stored state"): - pace.util.io.read_state(file.name) - - -@pytest.mark.cpu_only -@requires_xarray -def test_read_state_non_scalar_time(): - with tempfile.NamedTemporaryFile(mode="w", suffix=".nc") as file: - state_ds = xr.DataArray([0.0, 1.0], dims=["T"], name="time").to_dataset() - state_ds.to_netcdf(file.name) - with pytest.raises(ValueError, match="scalar time"): - pace.util.io.read_state(file.name) - - -@pytest.mark.parametrize( - "only_names", - [["time", "air_temperature"], ["air_temperature"]], - ids=lambda x: f"{x}", -) -@requires_xarray -def test_open_c12_restart_only_names(layout, only_names): - tracer_properties = {} - c12_restart_state_list = get_c12_restart_state_list( - layout, only_names, tracer_properties - ) - for state in c12_restart_state_list: - assert set(only_names) == set(state.keys()) diff --git a/util/tests/test_local_comm.py b/util/tests/test_local_comm.py deleted file mode 100644 index d84655079..000000000 --- a/util/tests/test_local_comm.py +++ /dev/null @@ -1,54 +0,0 @@ -import numpy -import pytest - -from pace.util import LocalComm - - -@pytest.fixture -def total_ranks(): - return 2 - - -@pytest.fixture -def tags(): - return [1, 2] - - -@pytest.fixture -def local_communicator_list(total_ranks): - shared_buffer = {} - return_list = [] - for rank in range(total_ranks): - return_list.append( - LocalComm(rank=rank, total_ranks=total_ranks, buffer_dict=shared_buffer) - ) - return return_list - - -def test_local_comm_simple(local_communicator_list): - for comm in local_communicator_list: - rank = comm.Get_rank() - size = comm.Get_size() - data = numpy.asarray([rank], dtype=numpy.int) - if rank % 2 == 0: - comm.Send(data, dest=(rank + 1) % size) - else: - comm.Recv(data, source=(rank - 1) % size) - assert data == (rank - 1) % size - - -@pytest.mark.parametrize("tags", [(0, 1, 2), (2, 1, 0), (2, 0, 1)]) -def test_local_comm_tags(local_communicator_list, tags): - for comm in local_communicator_list: - rank = comm.Get_rank() - size = comm.Get_size() - data = numpy.array([[rank], [rank + 1], [rank + 2]]) - if rank % 2 == 0: - for i in range(len(tags)): - comm.Isend(data[i], dest=(rank + 1) % size, tag=tags[i]) - else: - rec_buffer = numpy.array([[-1], [-1], [-1]]) - for i in range(len(tags)): - recv = comm.Irecv(rec_buffer[i], source=(rank - 1) % size, tag=i) - recv.wait() - assert (rec_buffer[list(tags)] == data - 1).all() diff --git a/util/tests/test_netcdf_monitor.py b/util/tests/test_netcdf_monitor.py deleted file mode 100644 index 31aca9837..000000000 --- a/util/tests/test_netcdf_monitor.py +++ /dev/null @@ -1,134 +0,0 @@ -import logging -from datetime import timedelta -from typing import List - -import cftime -import numpy as np -import pytest - -import pace.util -from pace.util._optional_imports import xarray as xr -from pace.util.testing import DummyComm - - -requires_xarray = pytest.mark.skipif(xr is None, reason="xarray is not installed") - -logger = logging.getLogger(__name__) - - -@pytest.mark.parametrize("layout", [(1, 1), (1, 2), (4, 4)]) -@pytest.mark.parametrize( - "nt, time_chunk_size", - [pytest.param(1, 1, id="single_time"), pytest.param(5, 2, id="chunked_time")], -) -@pytest.mark.parametrize( - "shape, ny_rank_add, nx_rank_add, dims", - [ - pytest.param((5, 4, 4), 0, 0, ("z", "y", "x"), id="cell_center"), - pytest.param( - (5, 4, 4), 1, 1, ("z", "y_interface", "x_interface"), id="cell_corner" - ), - pytest.param((5, 4, 4), 0, 1, ("z", "y", "x_interface"), id="cell_edge"), - ], -) -@requires_xarray -def test_monitor_store_multi_rank_state( - layout, nt, time_chunk_size, tmpdir, shape, ny_rank_add, nx_rank_add, dims, numpy -): - units = "m" - nz, ny, nx = shape - ny_rank = int(ny / layout[0] + ny_rank_add) - nx_rank = int(nx / layout[1] + nx_rank_add) - tile = pace.util.TilePartitioner(layout) - time = cftime.DatetimeJulian(2010, 6, 20, 6, 0, 0) - timestep = timedelta(hours=1) - total_ranks = 6 * layout[0] * layout[1] - partitioner = pace.util.CubedSpherePartitioner(tile) - shared_buffer = {} - monitor_list: List[pace.util.NetCDFMonitor] = [] - - for rank in range(total_ranks): - communicator = pace.util.CubedSphereCommunicator( - partitioner=partitioner, - comm=DummyComm( - rank=rank, total_ranks=total_ranks, buffer_dict=shared_buffer - ), - ) - # must eagerly initialize the tile object so that their ranks are - # created in ascending order - communicator.tile - monitor_list.append( - pace.util.NetCDFMonitor( - path=tmpdir, - communicator=communicator, - time_chunk_size=time_chunk_size, - ) - ) - - for rank in range(total_ranks - 1, -1, -1): - state = { - "var_const1": pace.util.Quantity( - numpy.ones([nz, ny_rank, nx_rank]), - dims=dims, - units=units, - ), - } - monitor_list[rank].store_constant(state) - - tile_gathered = [] - for i_t in range(nt): - for rank in range(total_ranks - 1, -1, -1): - state = { - "time": time + i_t * timestep, - "var1": pace.util.Quantity( - numpy.ones([nz, ny_rank, nx_rank]), - dims=dims, - units=units, - ), - } - monitor_list[rank].store(state) - tile_gathered.append( - monitor_list[rank]._communicator.tile.gather_state(state) - ) - - for rank in range(total_ranks - 1, -1, -1): - state = { - "var_const2": pace.util.Quantity( - numpy.ones([nz, ny_rank, nx_rank]), - dims=dims, - units=units, - ), - } - monitor_list[rank].store_constant(state) - - for monitor in monitor_list: - monitor.cleanup() - - ds = xr.open_mfdataset(str(tmpdir / "state_*_tile*.nc"), decode_times=True) - assert "var1" in ds - np.testing.assert_array_equal( - ds["var1"].shape, (nt, 6, nz, ny + ny_rank_add, nx + nx_rank_add) - ) - assert ds["var1"].dims == ("time", "tile") + dims - assert ds["var1"].attrs["units"] == units - assert ds["time"].shape == (nt,) - assert ds["time"].dims == ("time",) - assert ds["time"].values[0] == time - np.testing.assert_array_equal(ds["var1"].values, 1.0) - - ds_const = xr.open_dataset(str(tmpdir / "constants_var_const1.nc")) - assert "var_const1" in ds_const - np.testing.assert_array_equal( - ds_const["var_const1"].shape, (6, nz, ny + ny_rank_add, nx + nx_rank_add) - ) - assert ds_const["var_const1"].dims == ("tile",) + dims - assert ds_const["var_const1"].attrs["units"] == units - np.testing.assert_array_equal(ds_const["var_const1"].values, 1.0) - ds_const2 = xr.open_dataset(str(tmpdir / "constants_var_const2.nc")) - assert "var_const2" in ds_const2 - np.testing.assert_array_equal( - ds_const2["var_const2"].shape, (6, nz, ny + ny_rank_add, nx + nx_rank_add) - ) - assert ds_const2["var_const2"].dims == ("tile",) + dims - assert ds_const2["var_const2"].attrs["units"] == units - np.testing.assert_array_equal(ds_const2["var_const2"].values, 1.0) diff --git a/util/tests/test_nudging.py b/util/tests/test_nudging.py deleted file mode 100644 index 9e8a443fc..000000000 --- a/util/tests/test_nudging.py +++ /dev/null @@ -1,165 +0,0 @@ -import copy -from datetime import timedelta - -import pytest - -import pace.util - - -@pytest.fixture(params=["empty", "one_var", "two_vars"]) -def state(request, numpy): - if request.param == "empty": - return {} - elif request.param == "one_var": - return { - "var1": pace.util.Quantity( - numpy.ones([5]), - dims=["dim1"], - units="m", - ) - } - elif request.param == "two_vars": - return { - "var1": pace.util.Quantity( - numpy.ones([5]), - dims=["dim1"], - units="m", - ), - "var2": pace.util.Quantity( - numpy.ones([5]), - dims=["dim_2"], - units="m", - ), - } - else: - raise NotImplementedError() - - -@pytest.fixture(params=["equal", "plus_one", "extra_var"]) -def reference_difference(request): - return request.param - - -@pytest.fixture -def reference_state(reference_difference, state, numpy): - if reference_difference == "equal": - reference_state = copy.deepcopy(state) - elif reference_difference == "extra_var": - reference_state = copy.deepcopy(state) - reference_state["extra_var"] = pace.util.Quantity( - numpy.ones([5]), - dims=["dim1"], - units="m", - ) - elif reference_difference == "plus_one": - reference_state = copy.deepcopy(state) - for array in reference_state.values(): - array.data[:] += 1.0 - else: - raise NotImplementedError() - return reference_state - - -@pytest.fixture(params=[0.1, 0.5, 1.0]) -def multiple_of_timestep(request): - return request.param - - -@pytest.fixture -def nudging_timescales(state, timestep, multiple_of_timestep): - return_dict = {} - for name in state.keys(): - return_dict[name] = timedelta( - seconds=multiple_of_timestep * timestep.total_seconds() - ) - return return_dict - - -@pytest.fixture -def final_state(reference_difference, state, multiple_of_timestep): - if reference_difference in ("equal", "extra_var"): - final_state = copy.deepcopy(state) - elif reference_difference == "plus_one": - final_state = copy.deepcopy(state) - for name, array in final_state.items(): - array.data[:] += 1.0 / multiple_of_timestep - else: - raise NotImplementedError() - return final_state - - -@pytest.fixture -def nudging_tendencies(reference_difference, state, nudging_timescales): - if reference_difference in ("equal", "extra_var"): - tendencies = copy.deepcopy(state) - for array in tendencies.values(): - array.data[:] = 0.0 - array.metadata.units = array.units + " s^-1" - elif reference_difference == "plus_one": - tendencies = copy.deepcopy(state) - for name, array in tendencies.items(): - array.data[:] = 1.0 / nudging_timescales[name].total_seconds() - array.metadata.units = array.units + " s^-1" - else: - raise NotImplementedError() - return tendencies - - -@pytest.fixture(params=["one_second", "one_hour", "30_seconds"]) -def timestep(request): - if request.param == "one_second": - return timedelta(seconds=1) - if request.param == "one_hour": - return timedelta(hours=1) - if request.param == "30_seconds": - return timedelta(seconds=30) - else: - raise NotImplementedError - - -def test_apply_nudging_equals( - state, - reference_state, - nudging_timescales, - timestep, - final_state, - nudging_tendencies, - numpy, -): - result = pace.util.apply_nudging( - state, reference_state, nudging_timescales, timestep - ) - for name, tendency in nudging_tendencies.items(): - numpy.testing.assert_array_equal(result[name].data, tendency.data) - assert result[name].dims == tendency.dims - assert result[name].units == tendency.units - for name, reference_array in final_state.items(): - numpy.testing.assert_array_equal(state[name].data, reference_array.data) - assert state[name].dims == reference_array.dims - assert state[name].units == reference_array.units - - -def test_get_nudging_tendencies_equals( - state, reference_state, nudging_timescales, nudging_tendencies, numpy -): - result = pace.util.get_nudging_tendencies( - state, reference_state, nudging_timescales - ) - for name, tendency in nudging_tendencies.items(): - numpy.testing.assert_array_equal(result[name].data, tendency.data) - assert result[name].dims == tendency.dims - assert result[name].attrs["units"] == tendency.attrs["units"] - - -def test_get_nudging_tendencies_half_timescale( - state, reference_state, nudging_timescales, nudging_tendencies, numpy -): - for name, timescale in nudging_timescales.items(): - nudging_timescales[name] = timedelta(seconds=0.5 * timescale.total_seconds()) - result = pace.util.get_nudging_tendencies( - state, reference_state, nudging_timescales - ) - for name, tendency in nudging_tendencies.items(): - numpy.testing.assert_array_equal(result[name].data, 2.0 * tendency.data) - assert result[name].dims == tendency.dims - assert result[name].attrs["units"] == tendency.attrs["units"] diff --git a/util/tests/test_null_comm.py b/util/tests/test_null_comm.py deleted file mode 100644 index ef2c7f44a..000000000 --- a/util/tests/test_null_comm.py +++ /dev/null @@ -1,12 +0,0 @@ -import pace.util -from pace.util.null_comm import NullComm - - -def test_can_create_cube_communicator(): - rank = 2 - total_ranks = 24 - mpi_comm = NullComm(rank, total_ranks) - layout = (2, 2) - partitioner = pace.util.CubedSpherePartitioner(pace.util.TilePartitioner(layout)) - communicator = pace.util.CubedSphereCommunicator(mpi_comm, partitioner) - communicator.tile.partitioner diff --git a/util/tests/test_partitioner.py b/util/tests/test_partitioner.py deleted file mode 100644 index bebc3351f..000000000 --- a/util/tests/test_partitioner.py +++ /dev/null @@ -1,992 +0,0 @@ -import numpy as np -import pytest - -import pace.util -import pace.util.partitioner - - -rank_list = [] -total_rank_list = [] -tile_index_list = [] - -for ranks_per_tile in (1, 4): - total_ranks = 6 * ranks_per_tile - rank = 0 - for tile in range(6): - for subtile in range(ranks_per_tile): - rank_list.append(rank) - total_rank_list.append(total_ranks) - tile_index_list.append(tile) - rank += 1 - - -@pytest.mark.parametrize( - "rank, total_ranks, tile_index", zip(rank_list, total_rank_list, tile_index_list) -) -@pytest.mark.cpu_only -def test_get_tile_number(rank, total_ranks, tile_index): - tile = pace.util.get_tile_number(rank, total_ranks) - assert tile == tile_index + 1 - - -@pytest.mark.parametrize( - "rank, total_ranks, tile_index", zip(rank_list, total_rank_list, tile_index_list) -) -@pytest.mark.cpu_only -def test_get_tile_index(rank, total_ranks, tile_index): - tile = pace.util.get_tile_index(rank, total_ranks) - assert tile == tile_index - - -# initialize: rank, total_ranks, ny, nx, layout -# out: nx_rank, ny_rank, ranks_per_tile, subtile_index -# array_shape -> tile_extent -# array_dims -> subtile_slice - -rank_list = [] -layout_list = [] -subtile_index_list = [] - -for layout in ((1, 1), (1, 2), (2, 2), (2, 3)): - rank = 0 - for tile in range(6): - for y_subtile in range(layout[0]): - for x_subtile in range(layout[1]): - rank_list.append(rank) - layout_list.append(layout) - subtile_index_list.append((y_subtile, x_subtile)) - rank += 1 - - -@pytest.mark.parametrize( - "rank, layout, subtile_index", zip(rank_list, layout_list, subtile_index_list) -) -@pytest.mark.cpu_only -def test_subtile_index(rank, layout, subtile_index): - partitioner = pace.util.TilePartitioner(layout) - assert partitioner.subtile_index(rank) == subtile_index - - -@pytest.mark.parametrize( - "array_extent, array_dims, layout, tile_extent", - [ - ((16, 32), (pace.util.Y_DIM, pace.util.X_DIM), (1, 1), (16, 32)), - ((16, 32), (pace.util.Y_DIM, pace.util.X_INTERFACE_DIM), (1, 1), (16, 32)), - ((16, 32), (pace.util.Y_INTERFACE_DIM, pace.util.X_DIM), (1, 1), (16, 32)), - ( - (16, 32), - (pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM), - (1, 1), - (16, 32), - ), - ( - (8, 16, 32), - (pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM), - (1, 1), - (8, 16, 32), - ), - ((2, 2), (pace.util.Y_DIM, pace.util.X_DIM), (2, 2), (4, 4)), - ((3, 2), (pace.util.Y_INTERFACE_DIM, pace.util.X_DIM), (2, 2), (5, 4)), - ((2, 3), (pace.util.Y_DIM, pace.util.X_INTERFACE_DIM), (2, 2), (4, 5)), - ( - (4, 2, 3), - ( - pace.util.Z_INTERFACE_DIM, - pace.util.Y_DIM, - pace.util.X_INTERFACE_DIM, - ), - (2, 2), - (4, 4, 5), - ), - ], -) -@pytest.mark.cpu_only -def test_tile_extent_from_rank_metadata(array_extent, array_dims, layout, tile_extent): - result = pace.util.partitioner.tile_extent_from_rank_metadata( - array_dims, array_extent, layout - ) - assert result == tile_extent - - -@pytest.mark.parametrize( - ( - "array_dims, tile_extent, layout, rank, subtile_slice, " - "overlap, edge_interior_ratio" - ), - [ - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (8, 8), - (1, 1), - 0, - (slice(0, 8), slice(0, 8)), - False, - 1.0, - id="6_rank_centered", - ), - pytest.param( - [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (10, 8, 8), - (1, 1), - 0, - (slice(0, 10), slice(0, 8), slice(0, 8)), - False, - 1.0, - id="6_rank_centered_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (11, 8, 8), - (1, 1), - 0, - (slice(0, 11), slice(0, 8), slice(0, 8)), - False, - 1.0, - id="6_rank_centered_z_interface", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_DIM], - (9, 8), - (1, 1), - 0, - (slice(0, 9), slice(0, 8)), - True, - 1.0, - id="6_rank_y_interface", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_INTERFACE_DIM], - (8, 9), - (1, 1), - 0, - (slice(0, 8), slice(0, 9)), - True, - 1.0, - id="6_rank_x_interface", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM], - (9, 9), - (1, 1), - 0, - (slice(0, 9), slice(0, 9)), - False, - 1.0, - id="6_rank_both_interface", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (8, 8), - (2, 2), - 0, - (slice(0, 4), slice(0, 4)), - True, - 1.0, - id="24_rank_centered_left", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (8, 8), - (2, 2), - 3, - (slice(4, 8), slice(4, 8)), - False, - 1.0, - id="24_rank_centered_right", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM], - (9, 9), - (2, 2), - 0, - (slice(0, 4), slice(0, 4)), - False, - 1.0, - id="24_rank_interface_left_no_overlap", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM], - (9, 9), - (2, 2), - 3, - (slice(4, 9), slice(4, 9)), - False, - 1.0, - id="24_rank_interface_right_no_overlap", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM], - (9, 9), - (2, 2), - 0, - (slice(0, 5), slice(0, 5)), - True, - 1.0, - id="24_rank_interface_left_overlap", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM], - (9, 9), - (2, 2), - 3, - (slice(4, 9), slice(4, 9)), - True, - 1.0, - id="24_rank_interface_right_overlap", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (4, 4), - (1, 2), - 0, - (slice(0, 4), slice(0, 2)), - True, - 1.0, - id="12_rank_no_interface_right_overlap", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (4, 4), - (1, 2), - 1, - (slice(0, 4), slice(2, 4)), - True, - 1.0, - id="12_rank_no_interface_right_overlap", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (4, 4), - (1, 2), - 1, - (slice(0, 4), slice(2, 4)), - False, - 1.0, - id="12_rank_centered_right_no_overlap_rectangle_layout", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 4, 4), - (1, 3), - 0, - (slice(0, 5), slice(0, 4), slice(0, 1)), - False, - 0.5, - id="18_rank_left_no_overlap_rectangle_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 4, 4), - (1, 3), - 1, - (slice(0, 5), slice(0, 4), slice(1, 3)), - False, - 0.5, - id="18_rank_mid_no_overlap_rectangle_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 4, 4), - (1, 3), - 2, - (slice(0, 5), slice(0, 4), slice(3, 4)), - False, - 0.5, - id="18_rank_right_no_overlap_rectangle_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 4, 4), - (2, 3), - 0, - (slice(0, 5), slice(0, 2), slice(0, 1)), - False, - 0.5, - id="36_rank_botleft_right_no_overlap_rectangle_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 4, 4), - (2, 3), - 1, - (slice(0, 5), slice(0, 2), slice(1, 3)), - False, - 0.5, - id="36_rank_botmid_right_no_overlap_rectangle_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 4, 4), - (2, 3), - 2, - (slice(0, 5), slice(0, 2), slice(3, 4)), - False, - 0.5, - id="36_rank_botright_right_no_overlap_rectangle_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 4, 4), - (2, 3), - 3, - (slice(0, 5), slice(2, 4), slice(0, 1)), - False, - 0.5, - id="36_rank_topleft_no_overlap_rectangle_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 4, 4), - (2, 3), - 4, - (slice(0, 5), slice(2, 4), slice(1, 3)), - False, - 0.5, - id="36_rank_topmid_no_overlap_rectangle_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 4, 4), - (2, 3), - 5, - (slice(0, 5), slice(2, 4), slice(3, 4)), - False, - 0.5, - id="36_rank_topright_no_overlap_rectangle_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 8, 8), - (3, 3), - 0, - (slice(0, 5), slice(0, 2), slice(0, 2)), - False, - 0.5, - id="54_rank_botleft_no_overlap_square_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 8, 8), - (3, 3), - 1, - (slice(0, 5), slice(0, 2), slice(2, 6)), - False, - 0.5, - id="54_rank_botmid_no_overlap_square_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 8, 8), - (3, 3), - 4, - (slice(0, 5), slice(2, 6), slice(2, 6)), - False, - 0.5, - id="54_rank_midmid_no_overlap_square_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 8, 8), - (3, 3), - 5, - (slice(0, 5), slice(2, 6), slice(6, 8)), - False, - 0.5, - id="54_rank_midright_no_overlap_square_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 8, 8), - (3, 3), - 8, - (slice(0, 5), slice(6, 8), slice(6, 8)), - False, - 0.5, - id="54_rank_topright_no_overlap_square_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 8, 8), - (3, 3), - 0, - (slice(0, 5), slice(0, 1), slice(0, 1)), - False, - float(1.0 / 6), - id="54_rank_botleft_no_overlap_square_layout_sixth_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 8, 8), - (3, 3), - 1, - (slice(0, 5), slice(0, 1), slice(1, 7)), - False, - float(1.0 / 6), - id="54_rank_botmid_no_overlap_square_layout_sixth_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 8, 8), - (3, 3), - 4, - (slice(0, 5), slice(1, 7), slice(1, 7)), - False, - float(1.0 / 6), - id="54_rank_midmid_no_overlap_square_layout_sixth_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 8, 8), - (3, 3), - 5, - (slice(0, 5), slice(1, 7), slice(7, 8)), - False, - float(1.0 / 6), - id="54_rank_midright_no_overlap_square_layout_sixth_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 8, 8), - (3, 3), - 8, - (slice(0, 5), slice(7, 8), slice(7, 8)), - False, - float(1.0 / 6), - id="54_rank_topright_no_overlap_square_layout_half_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 16, 16), - (4, 4), - 0, - (slice(0, 5), slice(0, 2), slice(0, 2)), - False, - float(1.0 / 3), - id="96_rank_farbotfarleft_no_overlap_square_layout_third_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 16, 16), - (4, 4), - 1, - (slice(0, 5), slice(0, 2), slice(2, 8)), - False, - float(1.0 / 3), - id="96_rank_farbotcloseleft_no_overlap_square_layout_third_edge_tiles_3d", - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 16, 16), - (4, 4), - 6, - (slice(0, 5), slice(2, 8), slice(8, 14)), - False, - float(1.0 / 3), - id=( - "96_rank_closebotcloseright_right_no_overlap_" - "square_layout_third_edge_tiles_3d" - ), - ), - pytest.param( - [pace.util.Z_INTERFACE_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (5, 16, 16), - (4, 4), - 14, - (slice(0, 5), slice(14, 16), slice(8, 14)), - False, - float(1.0 / 3), - id="96_rank_fartopcloseright_no_overlap_square_layout_third_edge_tiles_3d", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM], - (13, 13), - (2, 4), - 1, - (slice(0, 7), slice(3, 7)), - True, - 1.0, - id="48_rank_botcloseleft_interface_right_overlap", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM], - (13, 13), - (2, 4), - 1, - (slice(0, 7), slice(2, 7)), - True, - 0.5, - id="48_rank_botcloseleft_interface_overlap_half_edge", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM], - (13, 13), - (2, 4), - 7, - (slice(6, 13), slice(10, 13)), - True, - 0.5, - id="48_rank_topfarright_interface_overlap_half_edge", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (12, 12), - (2, 4), - 0, - (slice(0, 6), slice(0, 2)), - True, - 0.5, - id="48_rank_botfarleft_overlap_half_edge", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_INTERFACE_DIM], - (12, 13), - (3, 4), - 0, - (slice(0, 3), slice(0, 2)), - False, - 0.5, - id="72_rank_botfarleft_x_interface_half_edge", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_INTERFACE_DIM], - (12, 13), - (3, 4), - 1, - (slice(0, 3), slice(2, 6)), - False, - 0.5, - id="72_rank_botcloseleft_x_interface_half_edge", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_INTERFACE_DIM], - (12, 13), - (3, 4), - 11, - (slice(9, 12), slice(10, 13)), - False, - 0.5, - id="72_rank_topfarright_x_interface_half_edge", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_DIM], - (13, 12), - (3, 4), - 0, - (slice(0, 3), slice(0, 2)), - False, - 0.5, - id="72_rank_botfarleft_y_interface_half_edge", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_DIM], - (13, 12), - (3, 4), - 1, - (slice(0, 3), slice(2, 6)), - False, - 0.5, - id="72_rank_botcloseleft_y_interface_half_edge", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_DIM], - (13, 12), - (3, 4), - 8, - (slice(9, 13), slice(0, 2)), - False, - 0.5, - id="72_rank_topfarleft_y_interface_half_edge", - ), - pytest.param( - [pace.util.Y_INTERFACE_DIM, pace.util.X_DIM], - (13, 12), - (3, 4), - 11, - (slice(9, 13), slice(10, 12)), - False, - 0.5, - id="72_rank_topfarright_y_interface_half_edge", - ), - ], -) -@pytest.mark.cpu_only -def test_subtile_slice( - array_dims, tile_extent, layout, rank, subtile_slice, overlap, edge_interior_ratio -): - partitioner = pace.util.TilePartitioner(layout, edge_interior_ratio) - result = partitioner.subtile_slice(rank, array_dims, tile_extent, overlap) - assert result == subtile_slice - - -@pytest.mark.parametrize( - ( - "array_dims, tile_extent, layout, rank, subtile_slice, " - "overlap, edge_interior_ratio" - ), - [ - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (16, 16), - (5, 5), - 0, - (slice(0, 2), slice(0, 2)), - False, - 1.0, - id="150_rank_yx_botfarleft", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (16, 16), - (5, 5), - 1, - (slice(0, 2), slice(2, 6)), - False, - 1.0, - id="150_rank_yx_botcloseleft", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (16, 16), - (5, 5), - 8, - (slice(2, 6), slice(10, 14)), - False, - 1.0, - id="150_rank_yx_closebotcloseright", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (16, 16), - (5, 5), - 14, - (slice(6, 10), slice(14, 16)), - False, - 1.0, - id="150_rank_yx_midfarright", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (16, 16), - (5, 5), - 24, - (slice(14, 16), slice(14, 16)), - False, - 1.0, - id="150_rank_yx_fartopfarright", - ), - pytest.param( - [pace.util.X_DIM, pace.util.Y_DIM], - (16, 16), - (5, 5), - 0, - (slice(0, 2), slice(0, 2)), - False, - 1.0, - id="150_rank_xy_botfarleft", - ), - pytest.param( - [pace.util.X_DIM, pace.util.Y_DIM], - (16, 16), - (5, 5), - 1, - (slice(2, 6), slice(0, 2)), - False, - 1.0, - id="150_rank_xy_botcloseleft", - ), - pytest.param( - [pace.util.X_DIM, pace.util.Y_DIM], - (16, 16), - (5, 5), - 8, - (slice(10, 14), slice(2, 6)), - False, - 1.0, - id="150_rank_xy_closebotcloseright", - ), - pytest.param( - [pace.util.X_DIM, pace.util.Y_DIM], - (16, 16), - (5, 5), - 14, - (slice(14, 16), slice(6, 10)), - False, - 1.0, - id="150_rank_xy_midfarright", - ), - pytest.param( - [pace.util.X_DIM, pace.util.Y_DIM], - (16, 16), - (5, 5), - 24, - (slice(14, 16), slice(14, 16)), - False, - 1.0, - id="150_rank_xy_fartopfarright", - ), - ], -) -@pytest.mark.cpu_only -def test_subtile_slice_even_grid_odd_layout( - array_dims, tile_extent, layout, rank, subtile_slice, overlap, edge_interior_ratio -): - partitioner = pace.util.TilePartitioner(layout, edge_interior_ratio) - result = partitioner.subtile_slice(rank, array_dims, tile_extent, overlap) - assert result == subtile_slice - - -@pytest.mark.parametrize( - ( - "array_dims, tile_extent, layout, rank, expected_error_string, " - "overlap, edge_interior_ratio" - ), - [ - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (13, 19), - (4, 4), - 24, - ( - "Cannot find valid decomposition for odd \\(13\\) gridpoints " - "along an even count \\(4\\) of ranks." - ), - False, - 0.5, - id="48_rank_odd_grid_even_layout_y", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (12, 19), - (4, 2), - 24, - ( - "Cannot find valid decomposition for odd \\(19\\) gridpoints " - "along an even count \\(2\\) of ranks." - ), - False, - 1.0, - id="48_rank_odd_grid_even_layout_x", - ), - ], -) -@pytest.mark.cpu_only -def test_subtile_slice_odd_grid_even_layout_no_interface( - array_dims, - tile_extent, - layout, - rank, - expected_error_string, - overlap, - edge_interior_ratio, -): - partitioner = pace.util.TilePartitioner(layout, edge_interior_ratio) - with pytest.raises(ValueError, match=expected_error_string): - partitioner.subtile_slice(rank, array_dims, tile_extent, overlap) - - -@pytest.mark.parametrize( - "array_dims, tile_extent, layout, edge_interior_ratio, rank_extent", - [ - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (12, 12), - (2, 3), - 1.0, - ((6, 4), (6, 4)), - id="36_rank_full_edge_tiles", - ), - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (12, 12), - (2, 3), - 0.5, - ((6, 6), (6, 3)), - id="36_rank_half_edge_tiles", - ), - pytest.param( - [pace.util.X_DIM, pace.util.Y_DIM], - (12, 12), - (3, 4), - 0.5, - ((4, 6), (2, 3)), - id="72_rank_half_edge_tiles", - ), - pytest.param( - [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM], - (13, 12), - (3, 4), - 0.5, - ((4, 6), (2, 3)), - id="72_rank_half_edge_tiles_x_interface", - ), - pytest.param( - [pace.util.X_DIM, pace.util.Y_INTERFACE_DIM], - (12, 13), - (3, 4), - 0.5, - ((4, 6), (2, 3)), - id="72_rank_half_edge_tiles_y_interface", - ), - pytest.param( - [pace.util.X_DIM, pace.util.Z_DIM, pace.util.Y_DIM], - (12, 5, 12), - (3, 4), - 0.5, - ((4, 5, 6), (2, 5, 3)), - id="72_rank_3d_half_edge_tiles", - ), - pytest.param( - [ - pace.util.TILE_DIM, - pace.util.X_DIM, - pace.util.Z_DIM, - pace.util.Y_DIM, - ], - (6, 12, 5, 12), - (3, 4), - 0.5, - ((6, 4, 5, 6), (6, 2, 5, 3)), - id="72_rank_3d_with_tile_dim_half_edge_tiles", - ), - ], -) -@pytest.mark.cpu_only -def test_subtile_extents_from_tile_metadata( - array_dims, tile_extent, layout, edge_interior_ratio, rank_extent -): - result = pace.util.partitioner._subtile_extents_from_tile_metadata( - array_dims, tile_extent, layout, edge_interior_ratio - ) - assert result == rank_extent - result = pace.util.partitioner._subtile_extents_from_tile_metadata( - dims=array_dims, - tile_extent=tile_extent, - layout=layout, - edge_interior_ratio=edge_interior_ratio, - ) - assert result == rank_extent - - -@pytest.mark.parametrize( - ( - "array_dims, tile_extent, layout, full_edge_interior_ratio, " - "half_edge_interior_ratio, expected_slice, expected_extent, " - "expected_error_string" - ), - [ - pytest.param( - [pace.util.Y_DIM, pace.util.X_DIM], - (12, 12), - (3, 4), - 1.0, - 0.5, - (slice(0, 3, None), slice(0, 2, None)), - (9, 8), - ( - "Only equal sized subdomains are supported, " - "was given an edge_interior_ratio of 0.5" - ), - id="72_rank_half_edge_tiles", - ), - ], -) -@pytest.mark.cpu_only -def test_tile_extent_from_metadata( - array_dims, - tile_extent, - layout, - full_edge_interior_ratio, - half_edge_interior_ratio, - expected_slice, - expected_extent, - expected_error_string, -): - partitioner = pace.util.TilePartitioner(layout, half_edge_interior_ratio) - subtile_slice = partitioner.subtile_slice(0, array_dims, tile_extent, False) - assert subtile_slice == expected_slice - slice_extent = ( - subtile_slice[0].stop - subtile_slice[0].start, - subtile_slice[1].stop - subtile_slice[1].start, - ) - rank_extent = pace.util.partitioner.tile_extent_from_rank_metadata( - array_dims, slice_extent, layout, full_edge_interior_ratio - ) - assert rank_extent == expected_extent - with pytest.raises(NotImplementedError, match=expected_error_string): - pace.util.partitioner.tile_extent_from_rank_metadata( - array_dims, slice_extent, layout, half_edge_interior_ratio - ) - - -@pytest.mark.parametrize( - ( - "array_dims, tile_extent, layout, edge_interior_ratio, rank, " - "tile_expected, cubedsphere_expected" - ), - [ - pytest.param( - [ - pace.util.TILE_DIM, - pace.util.X_DIM, - pace.util.Z_DIM, - pace.util.Y_DIM, - ], - (6, 12, 5, 12), - (3, 4), - 0.5, - 0, - (2, 5, 3), - (2, 5, 3), - id="72_rank_tile_x_z_y_half_edge_tiles", - ), - pytest.param( - [ - pace.util.TILE_DIM, - pace.util.Y_DIM, - pace.util.Z_DIM, - pace.util.X_DIM, - ], - (6, 12, 5, 12), - (3, 4), - 0.5, - 0, - (3, 5, 2), - (3, 5, 2), - id="72_rank_tile_y_z_x_half_edge_tiles", - ), - pytest.param( - [ - pace.util.Z_DIM, - pace.util.Y_DIM, - pace.util.TILE_DIM, - pace.util.X_DIM, - ], - (5, 12, 6, 12), - (3, 4), - 0.5, - 0, - (5, 3, 2), - (5, 3, 2), - id="72_rank_z_y_tile_x_half_edge_tiles", - ), - ], -) -def test_subtile_extent_with_tile_dimensions( - array_dims, - tile_extent, - layout, - edge_interior_ratio, - rank, - tile_expected, - cubedsphere_expected, -): - data_array = np.zeros((tile_extent)) - quantity = pace.util.Quantity(data_array, array_dims, "dimensionless", [0, 0, 0, 0]) - - tile_partitioner = pace.util.TilePartitioner(layout, edge_interior_ratio) - cubedsphere_partitioner = pace.util.CubedSpherePartitioner(tile_partitioner) - - tile_result = tile_partitioner.subtile_extent(quantity.metadata, rank) - assert tile_result == tile_expected - cubedsphere_result = cubedsphere_partitioner.subtile_extent(quantity.metadata, rank) - assert cubedsphere_result == cubedsphere_expected diff --git a/util/tests/test_partitioner_boundaries.py b/util/tests/test_partitioner_boundaries.py deleted file mode 100644 index e838a0142..000000000 --- a/util/tests/test_partitioner_boundaries.py +++ /dev/null @@ -1,765 +0,0 @@ -import pytest - -import pace.util -import pace.util.partitioner - - -# the test examples for the 2x2 cube here were recorded by manually inspecting -# a paper cube with printed ranks - - -@pytest.fixture -def partitioner_1_by_1(): - grid = pace.util.TilePartitioner((1, 1)) - return pace.util.CubedSpherePartitioner(grid) - - -@pytest.fixture -def partitioner_2_by_2(): - grid = pace.util.TilePartitioner((2, 2)) - return pace.util.CubedSpherePartitioner(grid) - - -@pytest.fixture -def tile_partitioner_3_by_3(): - return pace.util.TilePartitioner((3, 3)) - - -@pytest.fixture -def partitioner_3_by_3(): - grid = pace.util.TilePartitioner((3, 3)) - return pace.util.CubedSpherePartitioner(grid) - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 19, 1), # - (1, 0, 0), - (2, 18, 1), - (3, 2, 0), - (4, 1, 0), # - (5, 4, 0), - (6, 3, 0), - (7, 6, 0), - (8, 3, 1), # - (9, 8, 0), - (10, 2, 1), - (11, 10, 0), - (12, 9, 0), # - (13, 12, 0), - (14, 11, 0), - (15, 14, 0), - (16, 11, 1), # - (17, 16, 0), - (18, 10, 1), - (19, 18, 0), - (20, 17, 0), # - (21, 20, 0), - (22, 19, 0), - (23, 22, 0), - ], -) -@pytest.mark.cpu_only -def test_2_by_2_left_edge( - partitioner_2_by_2, from_rank, to_rank, n_clockwise_rotations -): - edge = partitioner_2_by_2.boundary(pace.util.WEST, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 2, 0), - (1, 0, 0), - (2, 1, 0), - (3, 5, 0), - (4, 3, 0), - (5, 4, 0), - (6, 8, 0), - (7, 6, 0), - (8, 7, 0), - ], -) -@pytest.mark.cpu_only -def test_single_3_by_3_left_edge( - tile_partitioner_3_by_3, from_rank, to_rank, n_clockwise_rotations -): - edge = tile_partitioner_3_by_3.boundary(pace.util.WEST, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [(0, 4, 1), (1, 0, 0), (2, 0, 1), (3, 2, 0), (4, 2, 1), (5, 4, 0)], -) -@pytest.mark.cpu_only -def test_1_by_1_left_edge( - partitioner_1_by_1, from_rank, to_rank, n_clockwise_rotations -): - edge = partitioner_1_by_1.boundary(pace.util.WEST, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "rank, layout, n_clockwise_rotations, new_rank", - [ - (12, (4, 4), 1, 15), - (14, (4, 4), 1, 7), - (0, (1, 1), 0, 0), - (0, (1, 1), 1, 0), - (2, (2, 2), 1, 3), - ], -) -@pytest.mark.cpu_only -def test_rotate_subtile_rank(rank, layout, n_clockwise_rotations, new_rank): - result = pace.util.partitioner.rotate_subtile_rank( - rank, layout, n_clockwise_rotations - ) - assert result == new_rank - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 2, 0), # - (1, 3, 0), - (2, 10, 3), - (3, 8, 3), - (4, 6, 0), # - (5, 7, 0), - (6, 8, 0), - (7, 9, 0), - (8, 10, 0), # - (9, 11, 0), - (10, 18, 3), - (11, 16, 3), - (12, 14, 0), # - (13, 15, 0), - (14, 16, 0), - (15, 17, 0), - (16, 18, 0), # - (17, 19, 0), - (18, 2, 3), - (19, 0, 3), - (20, 22, 0), # - (21, 23, 0), - (22, 0, 0), - (23, 1, 0), - ], -) -@pytest.mark.cpu_only -def test_2_by_2_top_edge(partitioner_2_by_2, from_rank, to_rank, n_clockwise_rotations): - edge = partitioner_2_by_2.boundary(pace.util.NORTH, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 3, 0), - (1, 4, 0), - (2, 5, 0), - (3, 6, 0), - (4, 7, 0), - (5, 8, 0), - (6, 0, 0), - (7, 1, 0), - (8, 2, 0), - ], -) -@pytest.mark.cpu_only -def test_single_3_by_3_top_edge( - tile_partitioner_3_by_3, from_rank, to_rank, n_clockwise_rotations -): - edge = tile_partitioner_3_by_3.boundary(pace.util.NORTH, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [(0, 2, 3), (1, 2, 0), (2, 4, 3), (3, 4, 0), (4, 0, 3), (5, 0, 0)], -) -@pytest.mark.cpu_only -def test_1_by_1_top_edge(partitioner_1_by_1, from_rank, to_rank, n_clockwise_rotations): - edge = partitioner_1_by_1.boundary(pace.util.NORTH, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 22, 0), # - (1, 23, 0), - (2, 0, 0), - (3, 1, 0), - (4, 23, 3), # - (5, 21, 3), - (6, 4, 0), - (7, 5, 0), - (8, 6, 0), # - (9, 7, 0), - (10, 8, 0), - (11, 9, 0), - (12, 7, 3), # - (13, 5, 3), - (14, 12, 0), - (15, 13, 0), - (16, 14, 0), # - (17, 15, 0), - (18, 16, 0), - (19, 17, 0), - (20, 15, 3), # - (21, 13, 3), - (22, 20, 0), - (23, 21, 0), - ], -) -@pytest.mark.cpu_only -def test_2_by_2_bottom_edge( - partitioner_2_by_2, from_rank, to_rank, n_clockwise_rotations -): - edge = partitioner_2_by_2.boundary(pace.util.SOUTH, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 6, 0), - (1, 7, 0), - (2, 8, 0), - (3, 0, 0), - (4, 1, 0), - (5, 2, 0), - (6, 3, 0), - (7, 4, 0), - (8, 5, 0), - ], -) -@pytest.mark.cpu_only -def test_single_3_by_3_bottom_edge( - tile_partitioner_3_by_3, from_rank, to_rank, n_clockwise_rotations -): - edge = tile_partitioner_3_by_3.boundary(pace.util.SOUTH, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [(0, 5, 0), (1, 5, 3), (2, 1, 0), (3, 1, 3), (4, 3, 0), (5, 3, 3)], -) -@pytest.mark.cpu_only -def test_1_by_1_bottom_edge( - partitioner_1_by_1, from_rank, to_rank, n_clockwise_rotations -): - edge = partitioner_1_by_1.boundary(pace.util.SOUTH, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 1, 0), # - (1, 4, 0), - (2, 3, 0), - (3, 6, 0), - (4, 5, 0), # - (5, 13, 1), - (6, 7, 0), - (7, 12, 1), - (8, 9, 0), # - (9, 12, 0), - (10, 11, 0), - (11, 14, 0), - (12, 13, 0), # - (13, 21, 1), - (14, 15, 0), - (15, 20, 1), - (16, 17, 0), # - (17, 20, 0), - (18, 19, 0), - (19, 22, 0), - (20, 21, 0), # - (21, 5, 1), - (22, 23, 0), - (23, 4, 1), - ], -) -@pytest.mark.cpu_only -def test_2_by_2_right_edge( - partitioner_2_by_2, from_rank, to_rank, n_clockwise_rotations -): - edge = partitioner_2_by_2.boundary(pace.util.EAST, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 1, 0), - (1, 2, 0), - (2, 0, 0), - (3, 4, 0), - (4, 5, 0), - (5, 3, 0), - (6, 7, 0), - (7, 8, 0), - (8, 6, 0), - ], -) -@pytest.mark.cpu_only -def test_single_3_by_3_right_edge( - tile_partitioner_3_by_3, from_rank, to_rank, n_clockwise_rotations -): - edge = tile_partitioner_3_by_3.boundary(pace.util.EAST, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [(0, 1, 0), (1, 3, 1), (2, 3, 0), (3, 5, 1), (4, 5, 0), (5, 1, 1)], -) -@pytest.mark.cpu_only -def test_1_by_1_right_edge( - partitioner_1_by_1, from_rank, to_rank, n_clockwise_rotations -): - edge = partitioner_1_by_1.boundary(pace.util.EAST, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize("from_rank", [0, 1, 2, 3, 4, 5]) -@pytest.mark.cpu_only -def test_1_by_1_top_left_corner(partitioner_1_by_1, from_rank): - corner = partitioner_1_by_1.boundary(pace.util.NORTHWEST, from_rank) - assert corner is None - - -@pytest.mark.parametrize("from_rank", [0, 1, 2, 3, 4, 5]) -@pytest.mark.cpu_only -def test_1_by_1_top_right_corner(partitioner_1_by_1, from_rank): - corner = partitioner_1_by_1.boundary(pace.util.NORTHEAST, from_rank) - assert corner is None - - -@pytest.mark.parametrize("from_rank", [0, 1, 2, 3, 4, 5]) -@pytest.mark.cpu_only -def test_1_by_1_bottom_left_corner(partitioner_1_by_1, from_rank): - corner = partitioner_1_by_1.boundary(pace.util.SOUTHWEST, from_rank) - assert corner is None - - -@pytest.mark.parametrize("from_rank", [0, 1, 2, 3, 4, 5]) -@pytest.mark.cpu_only -def test_1_by_1_bottom_right_corner(partitioner_1_by_1, from_rank): - corner = partitioner_1_by_1.boundary(pace.util.SOUTHEAST, from_rank) - assert corner is None - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 18, 1), # - (1, 2, 0), - (2, None, None), - (3, 10, 3), - (4, 3, 0), # - (5, 6, 0), - (6, None, None), - (7, 8, 0), - (8, 2, 1), # - (9, 10, 0), - (10, None, None), - (11, 18, 3), - (12, 11, 0), # - (13, 14, 0), - (14, None, None), - (15, 16, 0), - (16, 10, 1), # - (17, 18, 0), - (18, None, None), - (19, 2, 3), - (20, 19, 0), # - (21, 22, 0), - (22, None, None), - (23, 0, 0), - ], -) -@pytest.mark.cpu_only -def test_2_by_2_top_left_corner( - partitioner_2_by_2, from_rank, to_rank, n_clockwise_rotations -): - corner = partitioner_2_by_2.boundary(pace.util.NORTHWEST, from_rank) - if to_rank is None: - assert corner is None - else: - assert corner.from_rank == from_rank - assert corner.to_rank == to_rank - assert corner.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 5, 0), - (1, 3, 0), - (2, 4, 0), - (3, 8, 0), - (4, 6, 0), - (5, 7, 0), - (6, 2, 0), - (7, 0, 0), - (8, 1, 0), - ], -) -@pytest.mark.cpu_only -def test_single_3_by_3_top_left_corner( - tile_partitioner_3_by_3, from_rank, to_rank, n_clockwise_rotations -): - edge = tile_partitioner_3_by_3.boundary(pace.util.NORTHWEST, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "layout, boundary_type, from_rank, to_rank", - ( - ((1, 1), pace.util.WEST, 0, 0), - ((1, 1), pace.util.EAST, 0, 0), - ((1, 1), pace.util.NORTH, 0, 0), - ((1, 1), pace.util.SOUTH, 0, 0), - ((2, 2), pace.util.WEST, 0, 1), - ((2, 2), pace.util.EAST, 0, 1), - ((2, 2), pace.util.NORTH, 0, 2), - ((2, 2), pace.util.SOUTH, 0, 2), - ((2, 2), pace.util.WEST, 3, 2), - ((2, 2), pace.util.EAST, 3, 2), - ((2, 2), pace.util.NORTH, 3, 1), - ((2, 2), pace.util.SOUTH, 3, 1), - ), -) -@pytest.mark.cpu_only -def test_tile_boundary(layout, boundary_type, from_rank, to_rank): - tile = pace.util.TilePartitioner(layout) - boundary = tile.boundary(boundary_type, from_rank) - assert boundary.from_rank == from_rank - assert boundary.to_rank == to_rank - assert boundary.n_clockwise_rotations == 0 - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 3, 0), # - (1, 6, 0), - (2, 8, 3), - (3, None, None), - (4, 7, 0), # - (5, 12, 1), - (6, 9, 0), - (7, None, None), - (8, 11, 0), # - (9, 14, 0), - (10, 16, 3), - (11, None, None), - (12, 15, 0), # - (13, 20, 1), - (14, 17, 0), - (15, None, None), - (16, 19, 0), # - (17, 22, 0), - (18, 0, 3), - (19, None, None), - (20, 23, 0), # - (21, 4, 1), - (22, 1, 0), - (23, None, None), - ], -) -@pytest.mark.cpu_only -def test_2_by_2_top_right_corner( - partitioner_2_by_2, from_rank, to_rank, n_clockwise_rotations -): - corner = partitioner_2_by_2.boundary(pace.util.NORTHEAST, from_rank) - if to_rank is None: - assert corner is None - else: - assert corner.from_rank == from_rank - assert corner.to_rank == to_rank - assert corner.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 4, 0), - (1, 5, 0), - (2, 3, 0), - (3, 7, 0), - (4, 8, 0), - (5, 6, 0), - (6, 1, 0), - (7, 2, 0), - (8, 0, 0), - ], -) -@pytest.mark.cpu_only -def test_single_3_by_3_top_right_corner( - tile_partitioner_3_by_3, from_rank, to_rank, n_clockwise_rotations -): - edge = tile_partitioner_3_by_3.boundary(pace.util.NORTHEAST, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, None, None), # - (1, 22, 0), - (2, 19, 1), - (3, 0, 0), - (4, None, None), # - (5, 23, 3), - (6, 1, 0), - (7, 4, 0), - (8, None, None), # - (9, 6, 0), - (10, 3, 1), - (11, 8, 0), - (12, None, None), # - (13, 7, 3), - (14, 9, 0), - (15, 12, 0), - (16, None, None), # - (17, 14, 0), - (18, 11, 1), - (19, 16, 0), - (20, None, None), # - (21, 15, 3), - (22, 17, 0), - (23, 20, 0), - ], -) -@pytest.mark.cpu_only -def test_2_by_2_bottom_left_corner( - partitioner_2_by_2, from_rank, to_rank, n_clockwise_rotations -): - corner = partitioner_2_by_2.boundary(pace.util.SOUTHWEST, from_rank) - if to_rank is None: - assert corner is None - else: - assert corner.from_rank == from_rank - assert corner.to_rank == to_rank - assert corner.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 8, 0), - (1, 6, 0), - (2, 7, 0), - (3, 2, 0), - (4, 0, 0), - (5, 1, 0), - (6, 5, 0), - (7, 3, 0), - (8, 4, 0), - ], -) -@pytest.mark.cpu_only -def test_single_3_by_3_bottom_left_corner( - tile_partitioner_3_by_3, from_rank, to_rank, n_clockwise_rotations -): - edge = tile_partitioner_3_by_3.boundary(pace.util.SOUTHWEST, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 23, 0), # - (1, None, None), - (2, 1, 0), - (3, 4, 0), - (4, 21, 3), # - (5, None, None), - (6, 5, 0), - (7, 13, 1), - (8, 7, 0), # - (9, None, None), - (10, 9, 0), - (11, 12, 0), - (12, 5, 3), # - (13, None, None), - (14, 13, 0), - (15, 21, 1), - (16, 15, 0), # - (17, None, None), - (18, 17, 0), - (19, 20, 0), - (20, 13, 3), # - (21, None, None), - (22, 21, 0), - (23, 5, 1), - ], -) -@pytest.mark.cpu_only -def test_2_by_2_bottom_right_corner( - partitioner_2_by_2, from_rank, to_rank, n_clockwise_rotations -): - corner = partitioner_2_by_2.boundary(pace.util.SOUTHEAST, from_rank) - if to_rank is None: - assert corner is None - else: - assert corner.from_rank == from_rank - assert corner.to_rank == to_rank - assert corner.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize( - "from_rank, to_rank, n_clockwise_rotations", - [ - (0, 7, 0), - (1, 8, 0), - (2, 6, 0), - (3, 1, 0), - (4, 2, 0), - (5, 0, 0), - (6, 4, 0), - (7, 5, 0), - (8, 3, 0), - ], -) -@pytest.mark.cpu_only -def test_single_3_by_3_bottom_right_corner( - tile_partitioner_3_by_3, from_rank, to_rank, n_clockwise_rotations -): - edge = tile_partitioner_3_by_3.boundary(pace.util.SOUTHEAST, from_rank) - assert edge.from_rank == from_rank - assert edge.to_rank == to_rank - assert edge.n_clockwise_rotations == n_clockwise_rotations - - -def test_boundary_returns_correct_boundary_type(): - tile = pace.util.TilePartitioner((3, 3)) - partitioner = pace.util.CubedSpherePartitioner(tile) - for boundary_type in pace.util.BOUNDARY_TYPES: - boundary = partitioner.boundary(boundary_type, rank=4) # center face - assert boundary.boundary_type == boundary_type - - -# rank 42 is tile 4 (5), subrank 6, so top-left corner -# left is tile 2 top-left corner 1 rotations, up is tile 0 top-left corner 3 rotations -# rank 0 is tile 0 subrank 0 -# left is tile 4 top-right corner, 1 rotation -# bottom is tile 5 top-left corner, 0 rotations -@pytest.mark.parametrize( - "boundary_type, from_rank, to_rank, n_clockwise_rotations", - [ - (pace.util.WEST, 0, 4 * 9 + 8, 1), - (pace.util.SOUTH, 0, 5 * 9 + 6, 0), - (pace.util.WEST, 42, 2 * 9 + 6, 1), - (pace.util.NORTH, 42, 6, 3), - ], -) -@pytest.mark.cpu_only -def test_3_by_3_difficult_cases( - partitioner_3_by_3, boundary_type, from_rank, to_rank, n_clockwise_rotations -): - corner = partitioner_3_by_3.boundary(boundary_type, from_rank) - if to_rank is None: - assert corner is None - else: - assert corner.from_rank == from_rank - assert corner.to_rank == to_rank - assert corner.n_clockwise_rotations == n_clockwise_rotations - - -@pytest.mark.parametrize("layout", [(1, 1), (2, 2), (4, 4)]) -@pytest.mark.cpu_only -def test_edge_boundaries_pair(layout, subtests): - order = [pace.util.WEST, pace.util.NORTH, pace.util.EAST, pace.util.SOUTH] - tile = pace.util.TilePartitioner(layout) - partitioner = pace.util.CubedSpherePartitioner(tile) - for rank in range(partitioner.total_ranks): - for boundary_type in pace.util.EDGE_BOUNDARY_TYPES: - with subtests.test(rank=rank, boundary_type=boundary_type): - out_boundary = partitioner.boundary(boundary_type, rank) - in_boundary = partitioner.boundary( - rotate( - boundary_type, 2 - out_boundary.n_clockwise_rotations, order - ), - out_boundary.to_rank, - ) - assert out_boundary.to_rank == in_boundary.from_rank - assert in_boundary.to_rank == out_boundary.from_rank - assert ( - in_boundary.n_clockwise_rotations % 4 - == -out_boundary.n_clockwise_rotations % 4 - ) - - -@pytest.mark.parametrize("layout", [(1, 1), (2, 2), (4, 4)]) -@pytest.mark.cpu_only -def test_corner_boundaries_pair(layout, subtests): - order = [ - pace.util.NORTHWEST, - pace.util.NORTHEAST, - pace.util.SOUTHEAST, - pace.util.SOUTHWEST, - ] - tile = pace.util.TilePartitioner(layout) - partitioner = pace.util.CubedSpherePartitioner(tile) - for rank in range(partitioner.total_ranks): - for boundary_type in pace.util.CORNER_BOUNDARY_TYPES: - with subtests.test(rank=rank, boundary_type=boundary_type): - out_boundary = partitioner.boundary(boundary_type, rank) - if out_boundary is not None: - in_boundary = partitioner.boundary( - rotate( - boundary_type, 2 - out_boundary.n_clockwise_rotations, order - ), - out_boundary.to_rank, - ) - assert out_boundary.to_rank == in_boundary.from_rank - assert in_boundary.to_rank == out_boundary.from_rank - assert ( - in_boundary.n_clockwise_rotations % 4 - == -out_boundary.n_clockwise_rotations % 4 - ) - - -def rotate(boundary_type, n_clockwise_rotations, order): - target_index = (order.index(boundary_type) + n_clockwise_rotations) % len(order) - return order[target_index] diff --git a/util/tests/test_rotate.py b/util/tests/test_rotate.py deleted file mode 100644 index 7be38ff9c..000000000 --- a/util/tests/test_rotate.py +++ /dev/null @@ -1,178 +0,0 @@ -import numpy as np -import pytest - -import pace.util.rotate - - -@pytest.fixture -def start_data(request, numpy): - if isinstance(request.param, tuple): - return tuple(numpy.asarray(item) for item in request.param) - else: - return numpy.asarray(request.param) - - -@pytest.mark.parametrize( - "start_data, n_clockwise_rotations, dims, target_data", - [ - pytest.param( - np.array([1.0]), - 0, - [pace.util.Z_DIM], - np.array([1.0]), - id="1_value_no_rotation", - ), - pytest.param( - np.array([1.0]), - 1, - [pace.util.Z_DIM], - np.array([1.0]), - id="1_value_1_rotation", - ), - pytest.param( - np.array([1.0, 2.0]), - 1, - [pace.util.X_DIM], - np.array([2.0, 1.0]), - id="1d_x_one_rotation", - ), - pytest.param( - np.array([1.0, 2.0]), - 2, - [pace.util.X_DIM], - np.array([2.0, 1.0]), - id="1d_x_two_rotations", - ), - pytest.param( - np.array([1.0, 2.0]), - 1, - [pace.util.Y_DIM], - np.array([1.0, 2.0]), - id="1d_y_one_rotation", - ), - pytest.param( - np.array([1.0, 2.0]), - 2, - [pace.util.Y_DIM], - np.array([2.0, 1.0]), - id="1d_y_two_rotations", - ), - pytest.param( - np.zeros([2, 3]), - 0, - [pace.util.X_DIM, pace.util.Y_DIM], - np.zeros([2, 3]), - id="2d_no_rotation", - ), - pytest.param( - np.zeros([2, 3]), - 1, - [pace.util.X_DIM, pace.util.Y_DIM], - np.zeros([3, 2]), - id="2d_1_rotation", - ), - pytest.param( - np.zeros([2, 3]), - 2, - [pace.util.X_DIM, pace.util.Y_DIM], - np.zeros([2, 3]), - id="2d_2_rotations", - ), - pytest.param( - np.zeros([2, 3]), - 3, - [pace.util.X_DIM, pace.util.Y_DIM], - np.zeros([3, 2]), - id="2d_3_rotations", - ), - pytest.param( - np.arange(5)[:, None], - 1, - [pace.util.X_DIM, pace.util.Y_DIM], - np.arange(5)[None, ::-1], - id="2d_x_increasing_values", - ), - pytest.param( - np.arange(5)[:, None], - 2, - [pace.util.X_DIM, pace.util.Y_DIM], - np.arange(5)[::-1, None], - id="2d_x_increasing_values_double_rotate", - ), - pytest.param( - np.arange(5)[None, :], - 1, - [pace.util.X_DIM, pace.util.Y_DIM], - np.arange(5)[:, None], - id="2d_y_increasing_values", - ), - ], - indirect=["start_data"], -) -def test_rotate_scalar_data( - start_data, n_clockwise_rotations, dims, numpy, target_data -): - result = pace.util.rotate.rotate_scalar_data( - start_data, dims, numpy, n_clockwise_rotations - ) - numpy.testing.assert_array_equal(result, target_data) - - -@pytest.mark.parametrize( - "start_data, n_clockwise_rotations, dims, target_data", - [ - pytest.param( - (np.array([1.0]), np.array([1.0])), - 0, - [pace.util.Z_DIM], - (np.array([1.0]), np.array([1.0])), - id="scalar_no_rotation", - ), - pytest.param( - (np.array([1.0]), np.array([1.0])), - 1, - [pace.util.Z_DIM], - (np.array([1.0]), np.array([-1.0])), - id="scalar_1_rotation", - ), - pytest.param( - (np.array([1.0]), np.array([1.0])), - 2, - [pace.util.Z_DIM], - (np.array([-1.0]), np.array([-1.0])), - id="scalar_2_rotations", - ), - pytest.param( - (np.array([1.0]), np.array([1.0])), - 3, - [pace.util.Z_DIM], - (np.array([-1.0]), np.array([1.0])), - id="scalar_3_rotations", - ), - pytest.param( - (np.ones([3, 2]), np.ones([2, 3])), - 3, - [pace.util.Y_INTERFACE_DIM, pace.util.X_DIM], - (np.ones([3, 2]) * -1, np.ones([2, 3])), - id="2d_array_flat_values", - ), - pytest.param( - (np.arange(5)[:, None], np.arange(5)[None, :]), - 1, - [pace.util.X_DIM, pace.util.Y_DIM], - (np.arange(5)[:, None], np.arange(5)[None, ::-1] * -1), - id="2d_array_increasing_values", - ), - ], - indirect=["start_data"], -) -def test_rotate_vector_data( - start_data, n_clockwise_rotations, dims, numpy, target_data -): - x_data, y_data = start_data - x_target, y_target = target_data - x_result, y_result = pace.util.rotate.rotate_vector_data( - x_data, y_data, n_clockwise_rotations, dims, numpy - ) - numpy.testing.assert_array_equal(x_result, x_target) - numpy.testing.assert_array_equal(y_result, y_target) diff --git a/util/tests/test_sync_shared_boundary.py b/util/tests/test_sync_shared_boundary.py deleted file mode 100644 index b57435907..000000000 --- a/util/tests/test_sync_shared_boundary.py +++ /dev/null @@ -1,222 +0,0 @@ -import pytest - -import pace.util - - -@pytest.fixture -def dtype(numpy): - return numpy.float64 - - -@pytest.fixture -def units(): - return "m" - - -@pytest.fixture -def layout(request): - try: - return request.param - except AttributeError: - return (1, 1) - - -@pytest.fixture -def ranks_per_tile(layout): - return layout[0] * layout[1] - - -@pytest.fixture -def total_ranks(ranks_per_tile): - return 6 * ranks_per_tile - - -@pytest.fixture -def tile_partitioner(layout): - return pace.util.TilePartitioner(layout) - - -@pytest.fixture -def cube_partitioner(tile_partitioner): - return pace.util.CubedSpherePartitioner(tile_partitioner) - - -@pytest.fixture -def communicator_list(cube_partitioner, total_ranks): - shared_buffer = {} - return_list = [] - for rank in range(cube_partitioner.total_ranks): - return_list.append( - pace.util.CubedSphereCommunicator( - comm=pace.util.testing.DummyComm( - rank=rank, total_ranks=total_ranks, buffer_dict=shared_buffer - ), - partitioner=cube_partitioner, - timer=pace.util.Timer(), - ) - ) - return return_list - - -@pytest.fixture -def rank_quantity_list(total_ranks, numpy, dtype, units=units): - """ - Quantities whose values are equal to the rank - """ - quantity_list = [] - for rank in range(total_ranks): - x_data = numpy.empty((3, 2), dtype=dtype) - x_data[:] = rank - x_quantity = pace.util.Quantity( - x_data, - dims=(pace.util.Y_INTERFACE_DIM, pace.util.X_DIM), - units=units, - origin=(0, 0), - extent=(3, 2), - ) - y_data = numpy.empty((2, 3), dtype=dtype) - y_data[:] = rank - y_quantity = pace.util.Quantity( - y_data, - dims=(pace.util.Y_DIM, pace.util.X_INTERFACE_DIM), - units=units, - origin=(0, 0), - extent=(2, 3), - ) - quantity_list.append((x_quantity, y_quantity)) - return quantity_list - - -@pytest.fixture -def rank_target_list(total_ranks, numpy): - return_list = [] - for rank in range(total_ranks): - if rank % 2 == 0: - target_x = ( - numpy.array([[rank, rank], [rank, rank], [rank + 2, rank + 2]]) % 6 - ) - target_y = numpy.array([[rank, rank, rank + 1], [rank, rank, rank + 1]]) % 6 - else: - target_x = ( - numpy.array([[rank, rank], [rank, rank], [rank + 1, rank + 1]]) % 6 - ) - target_y = numpy.array([[rank, rank, rank + 2], [rank, rank, rank + 2]]) % 6 - return_list.append((target_x, target_y)) - return return_list - - -@pytest.mark.filterwarnings("ignore:invalid value encountered in remainder") -def test_correct_ranks_are_synchronized_with_no_halos( - rank_quantity_list, communicator_list, subtests, numpy, rank_target_list -): - req_list = [] - for communicator, (x_quantity, y_quantity) in zip( - communicator_list, rank_quantity_list - ): - req = communicator.start_synchronize_vector_interfaces(x_quantity, y_quantity) - req_list.append(req) - for req in req_list: - req.wait() - for (x_quantity, y_quantity), (target_x, target_y) in zip( - rank_quantity_list, rank_target_list - ): - numpy.testing.assert_array_equal(numpy.abs(x_quantity.data), target_x) - numpy.testing.assert_array_equal(numpy.abs(y_quantity.data), target_y) - - -@pytest.fixture -def counting_quantity_list(total_ranks, numpy, dtype, units=units): - """ - A list of quantities whose entries increase sequentially in memory, - with y values starting at 36 and x values starting at 0. - """ - quantity_list = [] - for rank in range(total_ranks): - x_data = numpy.array([[0, 1], [2, 3], [4, 5]]) + 6 * rank - x_quantity = pace.util.Quantity( - x_data, - dims=(pace.util.Y_INTERFACE_DIM, pace.util.X_DIM), - units=units, - origin=(0, 0), - extent=(3, 2), - ) - y_data = 6 * total_ranks + numpy.array([[0, 1, 2], [3, 4, 5]]) + 6 * rank - y_quantity = pace.util.Quantity( - y_data, - dims=(pace.util.Y_DIM, pace.util.X_INTERFACE_DIM), - units=units, - origin=(0, 0), - extent=(2, 3), - ) - quantity_list.append((x_quantity, y_quantity)) - return quantity_list - - -@pytest.mark.parametrize("layout", [(1, 1)], indirect=True) -def test_specific_edges_synced_correctly_on_first_rank( - counting_quantity_list, communicator_list, subtests, numpy, rank_target_list -): - """ - A test that a couple chosen edges send the correct data. - - Each example takes significant time to manually determine the correct answer, - so this is limited to the first rank. Please add more cases as needed. - """ - req_list = [] - for communicator, (x_quantity, y_quantity) in zip( - communicator_list, counting_quantity_list - ): - req = communicator.start_synchronize_vector_interfaces(x_quantity, y_quantity) - req_list.append(req) - for req in req_list: - req.wait() - first_rank_x, first_rank_y = counting_quantity_list[0] - numpy.testing.assert_array_equal( - first_rank_y.data, numpy.array([[36, 37, 42], [39, 40, 45]]) - ) - numpy.testing.assert_array_equal( - first_rank_x.data, numpy.array([[0, 1], [2, 3], [-3 - 36 - 12, -36 - 12]]) - ) - second_rank_x, second_rank_y = counting_quantity_list[1] - numpy.testing.assert_array_equal( - second_rank_y.data, numpy.array([[42, 43, -19], [45, 46, -18]]) - ) - numpy.testing.assert_array_equal( - second_rank_x.data, numpy.array([[6, 7], [8, 9], [12, 13]]) - ) - - -@pytest.mark.parametrize("layout", [(3, 3)], indirect=True) -def test_interior_edges_synced_correctly_on_first_tile( - counting_quantity_list, - communicator_list, - subtests, - numpy, - rank_target_list, - total_ranks, -): - """ - A test that a couple chosen edges send the correct data. - - Each example takes significant time to manually determine the correct answer, - so this is limited to the first rank. Please add more cases as needed. - """ - req_list = [] - for communicator, (x_quantity, y_quantity) in zip( - communicator_list, counting_quantity_list - ): - req = communicator.start_synchronize_vector_interfaces(x_quantity, y_quantity) - req_list.append(req) - for req in req_list: - req.wait() - _, first_rank_y = counting_quantity_list[0] - numpy.testing.assert_array_equal( - first_rank_y.data, total_ranks * 6 + numpy.array([[0, 1, 6], [3, 4, 9]]) - ) - fifth_rank_x, fifth_rank_y = counting_quantity_list[4] - numpy.testing.assert_array_equal( - fifth_rank_y.data, (total_ranks + 4) * 6 + numpy.array([[0, 1, 6], [3, 4, 9]]) - ) - numpy.testing.assert_array_equal( - fifth_rank_x.data, 4 * 6 + numpy.array([[0, 1], [2, 3], [18, 19]]) - ) diff --git a/util/tests/test_tile_scatter.py b/util/tests/test_tile_scatter.py deleted file mode 100644 index a9f57bbcb..000000000 --- a/util/tests/test_tile_scatter.py +++ /dev/null @@ -1,185 +0,0 @@ -import pytest - -import pace.util -from pace.util.testing import DummyComm - - -def rank_scatter_results(communicator_list, quantity): - for rank, tile_communicator in enumerate(communicator_list): - if rank == 0: - array = quantity - else: - array = None - yield (tile_communicator, tile_communicator.scatter(send_quantity=array)) - - -def get_tile_communicator_list(partitioner): - total_ranks = partitioner.total_ranks - shared_buffer = {} - tile_communicator_list = [] - for rank in range(total_ranks): - tile_communicator_list.append( - pace.util.TileCommunicator( - comm=DummyComm( - rank=rank, total_ranks=total_ranks, buffer_dict=shared_buffer - ), - partitioner=partitioner, - ) - ) - return tile_communicator_list - - -@pytest.mark.parametrize("layout", [(1, 1), (1, 2), (2, 1), (2, 2), (3, 3)]) -def test_interface_state_two_by_two_per_rank_scatter_tile(layout, numpy): - state = { - "pos_j": pace.util.Quantity( - numpy.empty([layout[0] + 1, layout[1] + 1]), - dims=[pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM], - units="dimensionless", - ), - "pos_i": pace.util.Quantity( - numpy.empty([layout[0] + 1, layout[1] + 1], dtype=numpy.int32), - dims=[pace.util.Y_INTERFACE_DIM, pace.util.X_INTERFACE_DIM], - units="dimensionless", - ), - } - - state["pos_j"].view[:, :] = numpy.arange(0, layout[0] + 1)[:, None] - state["pos_i"].view[:, :] = numpy.arange(0, layout[1] + 1)[None, :] - - partitioner = pace.util.TilePartitioner(layout) - tile_communicator_list = get_tile_communicator_list(partitioner) - for communicator, rank_array in rank_scatter_results( - tile_communicator_list, state["pos_j"] - ): - assert rank_array.extent == (2, 2) - j, i = partitioner.subtile_index(communicator.rank) - assert rank_array.view[0, 0] == j - assert rank_array.view[0, 1] == j - assert rank_array.view[1, 0] == j + 1 - assert rank_array.view[1, 1] == j + 1 - assert rank_array.data.dtype == state["pos_j"].data.dtype - - for communicator, rank_array in rank_scatter_results( - tile_communicator_list, state["pos_i"] - ): - assert rank_array.extent == (2, 2) - j, i = partitioner.subtile_index(communicator.rank) - assert rank_array.view[0, 0] == i - assert rank_array.view[1, 0] == i - assert rank_array.view[0, 1] == i + 1 - assert rank_array.view[1, 1] == i + 1 - assert rank_array.data.dtype == state["pos_i"].data.dtype - - -@pytest.mark.parametrize("layout", [(1, 1), (1, 2), (2, 1), (2, 2), (3, 3)]) -def test_centered_state_one_item_per_rank_scatter_tile(layout, numpy): - total_ranks = layout[0] * layout[1] - state = { - "rank": pace.util.Quantity( - numpy.empty([layout[0], layout[1]]), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="dimensionless", - ), - "rank_pos_j": pace.util.Quantity( - numpy.empty([layout[0], layout[1]]), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="dimensionless", - ), - "rank_pos_i": pace.util.Quantity( - numpy.empty([layout[0], layout[1]]), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="dimensionless", - ), - } - - partitioner = pace.util.TilePartitioner(layout) - for rank in range(total_ranks): - rank = numpy.asarray([rank]) - state["rank"].view[numpy.unravel_index(rank, state["rank"].extent)] = rank - j, i = partitioner.subtile_index(rank) - state["rank_pos_j"].view[ - numpy.unravel_index(rank, state["rank_pos_j"].extent) - ] = j - state["rank_pos_i"].view[ - numpy.unravel_index(rank, state["rank_pos_i"].extent) - ] = i - - partitioner = pace.util.TilePartitioner(layout) - tile_communicator_list = get_tile_communicator_list(partitioner) - for communicator, rank_array in rank_scatter_results( - tile_communicator_list, state["rank"] - ): - assert rank_array.extent == (1, 1) - assert rank_array.view[0, 0] == communicator.rank - assert rank_array.data.dtype == state["rank"].data.dtype - for communicator, rank_array in rank_scatter_results( - tile_communicator_list, state["rank_pos_j"] - ): - assert rank_array.extent == (1, 1) - assert rank_array.view[0, 0] == partitioner.subtile_index(communicator.rank)[0] - for communicator, rank_array in rank_scatter_results( - tile_communicator_list, state["rank_pos_i"] - ): - assert rank_array.extent == (1, 1) - assert rank_array.view[0, 0] == partitioner.subtile_index(communicator.rank)[1] - - -@pytest.mark.parametrize("layout", [(1, 1), (1, 2), (2, 1), (2, 2), (3, 3)]) -@pytest.mark.parametrize("n_halo", [0, 1, 3]) -def test_centered_state_one_item_per_rank_with_halo_scatter_tile(layout, n_halo, numpy): - extent = layout - total_ranks = layout[0] * layout[1] - state = { - "rank": pace.util.Quantity( - numpy.empty([layout[0] + 2 * n_halo, layout[1] + 2 * n_halo]), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="dimensionless", - origin=(n_halo, n_halo), - extent=extent, - ), - "rank_pos_j": pace.util.Quantity( - numpy.empty([layout[0] + 2 * n_halo, layout[1] + 2 * n_halo]), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="dimensionless", - origin=(n_halo, n_halo), - extent=extent, - ), - "rank_pos_i": pace.util.Quantity( - numpy.empty([layout[0] + 2 * n_halo, layout[1] + 2 * n_halo]), - dims=[pace.util.Y_DIM, pace.util.X_DIM], - units="dimensionless", - origin=(n_halo, n_halo), - extent=extent, - ), - } - - partitioner = pace.util.TilePartitioner(layout) - for rank in range(total_ranks): - rank = numpy.asarray([rank]) - state["rank"].view[numpy.unravel_index(rank, state["rank"].extent)] = rank - j, i = partitioner.subtile_index(rank) - state["rank_pos_j"].view[ - numpy.unravel_index(rank, state["rank_pos_j"].extent) - ] = j - state["rank_pos_i"].view[ - numpy.unravel_index(rank, state["rank_pos_i"].extent) - ] = i - - tile_communicator_list = get_tile_communicator_list(partitioner) - for communicator, rank_array in rank_scatter_results( - tile_communicator_list, state["rank"] - ): - assert rank_array.extent == (1, 1) - assert rank_array.data[0, 0] == communicator.rank - assert rank_array.data.dtype == state["rank"].data.dtype - for communicator, rank_array in rank_scatter_results( - tile_communicator_list, state["rank_pos_j"] - ): - assert rank_array.extent == (1, 1) - assert rank_array.view[0, 0] == partitioner.subtile_index(communicator.rank)[0] - for communicator, rank_array in rank_scatter_results( - tile_communicator_list, state["rank_pos_i"] - ): - assert rank_array.extent == (1, 1) - assert rank_array.view[0, 0] == partitioner.subtile_index(communicator.rank)[1] diff --git a/util/tests/test_tile_scatter_gather.py b/util/tests/test_tile_scatter_gather.py deleted file mode 100644 index 39780edde..000000000 --- a/util/tests/test_tile_scatter_gather.py +++ /dev/null @@ -1,360 +0,0 @@ -import copy -import datetime - -import pytest - -import pace.util - - -try: - import gt4py -except ImportError: - gt4py = None - - -@pytest.fixture(params=[(1, 1), (3, 3)]) -def layout(request): - return request.param - - -@pytest.fixture(params=[0, 1, 3]) -def n_rank_halo(request): - return request.param - - -@pytest.fixture(params=[0, 3]) -def n_tile_halo(request): - return request.param - - -@pytest.fixture(params=["x,y", "y,x", "xi,y", "x,y,z", "z,y,x", "y,z,x"]) -def dims(request, fast): - if request.param == "x,y": - return [pace.util.X_DIM, pace.util.Y_DIM] - elif request.param == "y,x": - if fast: - pytest.skip("running in fast mode") - else: - return [pace.util.Y_DIM, pace.util.X_DIM] - elif request.param == "xi,y": - return [pace.util.X_INTERFACE_DIM, pace.util.Y_DIM] - elif request.param == "x,y,z": - return [pace.util.X_DIM, pace.util.Y_DIM, pace.util.Z_DIM] - elif request.param == "z,y,x": - if fast: - pytest.skip("running in fast mode") - else: - return [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM] - elif request.param == "y,z,x": - return [pace.util.Y_DIM, pace.util.Z_DIM, pace.util.X_DIM] - else: - raise NotImplementedError() - - -@pytest.fixture -def units(): - return "m/s" - - -@pytest.fixture -def time(): - return datetime.datetime(2000, 1, 1) - - -@pytest.fixture() -def dim_lengths(layout): - return { - pace.util.X_DIM: 2 * layout[1], - pace.util.X_INTERFACE_DIM: 2 * layout[1] + 1, - pace.util.Y_DIM: 2 * layout[0], - pace.util.Y_INTERFACE_DIM: 2 * layout[0] + 1, - pace.util.Z_DIM: 3, - pace.util.Z_INTERFACE_DIM: 4, - } - - -@pytest.fixture() -def communicator_list(layout): - total_ranks = layout[0] * layout[1] - shared_buffer = {} - return_list = [] - for rank in range(total_ranks): - return_list.append( - pace.util.TileCommunicator( - pace.util.testing.DummyComm(rank, total_ranks, shared_buffer), - pace.util.TilePartitioner(layout), - ) - ) - return return_list - - -@pytest.fixture -def tile_extent(dims, dim_lengths): - return_list = [] - for dim in dims: - return_list.append(dim_lengths[dim]) - return tuple(return_list) - - -@pytest.fixture -def tile_quantity(dims, units, dim_lengths, tile_extent, n_tile_halo, numpy): - return get_tile_quantity(dims, units, dim_lengths, tile_extent, n_tile_halo, numpy) - - -@pytest.fixture -def scattered_quantities(tile_quantity, layout, n_rank_halo, numpy): - return_list = [] - total_ranks = layout[0] * layout[1] - partitioner = pace.util.TilePartitioner(layout) - for rank in range(total_ranks): - # partitioner is tested in other tests, here we assume it works - subtile_slice = partitioner.subtile_slice( - global_dims=tile_quantity.dims, - global_extent=tile_quantity.extent, - rank=rank, - overlap=True, - ) - subtile_view = tile_quantity.view[subtile_slice] - subtile_quantity = get_quantity( - tile_quantity.dims, - tile_quantity.units, - subtile_view.shape, - n_rank_halo, - numpy, - ) - subtile_quantity.view[:] = subtile_view - return_list.append(subtile_quantity) - return return_list - - -def get_tile_quantity(dims, units, dim_lengths, tile_extent, n_halo, numpy): - extent = [dim_lengths[dim] for dim in dims] - quantity = get_quantity(dims, units, extent, n_halo, numpy) - quantity.view[:] = numpy.random.randn(*quantity.extent) - return quantity - - -def get_quantity(dims, units, extent, n_halo, numpy): - shape = list(copy.deepcopy(extent)) - origin = [0 for dim in dims] - for i, dim in enumerate(dims): - if dim in pace.util.HORIZONTAL_DIMS: - origin[i] += n_halo - shape[i] += 2 * n_halo - return pace.util.Quantity( - numpy.zeros(shape), - dims, - units, - origin=tuple(origin), - extent=tuple(extent), - ) - - -def test_tile_gather_state( - tile_quantity, scattered_quantities, communicator_list, time, backend -): - for communicator, rank_quantity in reversed( - list(zip(communicator_list, scattered_quantities)) - ): - state = {"time": time, "air_temperature": rank_quantity} - out = communicator.gather_state(send_state=state) - if communicator.rank == 0: - result_state = out - else: - assert out is None - assert result_state["time"] == time - result = result_state["air_temperature"] - assert result.dims == tile_quantity.dims - assert result.units == tile_quantity.units - assert result.extent == tile_quantity.extent - assert isinstance(result.data, type(tile_quantity.data)) - tile_quantity.np.testing.assert_array_equal(result.view[:], tile_quantity.view[:]) - - -def test_tile_gather_state_with_recv_state( - tile_quantity, scattered_quantities, communicator_list, time -): - recv_state = {"time": time, "air_temperature": copy.deepcopy(tile_quantity)} - recv_state["air_temperature"].data[:] = -1 - for communicator, rank_quantity in reversed( - list(zip(communicator_list, scattered_quantities)) - ): - state = {"time": time, "air_temperature": rank_quantity} - if communicator.rank == 0: - communicator.gather_state(send_state=state, recv_state=recv_state) - else: - communicator.gather_state(send_state=state) - assert recv_state["time"] == time - result = recv_state["air_temperature"] - assert result.dims == tile_quantity.dims - assert result.units == tile_quantity.units - assert result.extent == tile_quantity.extent - tile_quantity.np.testing.assert_array_equal(result.view[:], tile_quantity.view[:]) - - -def test_tile_gather_no_recv_quantity( - tile_quantity, scattered_quantities, communicator_list -): - for communicator, rank_quantity in reversed( - list(zip(communicator_list, scattered_quantities)) - ): - result = communicator.gather(send_quantity=rank_quantity) - if communicator.rank != 0: - assert result is None - assert result.dims == tile_quantity.dims - assert result.units == tile_quantity.units - assert result.extent == tile_quantity.extent - tile_quantity.np.testing.assert_array_equal(result.view[:], tile_quantity.view[:]) - - -def test_tile_scatter_no_recv_quantity( - tile_quantity, scattered_quantities, communicator_list -): - result_list = [] - for communicator in communicator_list: - if communicator.rank == 0: - result_list.append(communicator.scatter(send_quantity=tile_quantity)) - else: - result_list.append(communicator.scatter()) - for rank, (result, scattered) in enumerate(zip(result_list, scattered_quantities)): - assert result.dims == scattered.dims - assert result.units == scattered.units - assert result.extent == scattered.extent - scattered.np.testing.assert_array_equal(result.view[:], scattered.view[:]) - - -def test_tile_scatter_with_recv_quantity( - tile_quantity, scattered_quantities, communicator_list -): - recv_quantities = copy.deepcopy(scattered_quantities) - for q in recv_quantities: - q.data[:] = 0.0 - for recv, communicator in zip(recv_quantities, communicator_list): - if communicator.rank == 0: - result = communicator.scatter( - send_quantity=tile_quantity, recv_quantity=recv - ) - else: - result = communicator.scatter(recv_quantity=recv) - assert result is recv - for rank, (result, scattered) in enumerate( - zip(recv_quantities, scattered_quantities) - ): - assert result.dims == scattered.dims - assert result.units == scattered.units - assert result.extent == scattered.extent - scattered.np.testing.assert_array_equal(result.view[:], scattered.view[:]) - - -def test_tile_gather_with_recv_quantity( - tile_quantity, scattered_quantities, communicator_list -): - recv_quantity = copy.deepcopy(tile_quantity) - recv_quantity.data[:] = -1 - for communicator, rank_quantity in reversed( - list(zip(communicator_list, scattered_quantities)) - ): - if communicator.rank == 0: - result = communicator.gather( - send_quantity=rank_quantity, recv_quantity=recv_quantity - ) - else: - result = communicator.gather(send_quantity=rank_quantity) - assert result is None - assert recv_quantity.dims == tile_quantity.dims - assert recv_quantity.units == tile_quantity.units - assert recv_quantity.extent == tile_quantity.extent - tile_quantity.np.testing.assert_array_equal( - recv_quantity.view[:], tile_quantity.view[:] - ) - - -def test_tile_scatter_state( - tile_quantity, scattered_quantities, communicator_list, time -): - state = {"time": time, "air_temperature": tile_quantity} - result_list = [] - for communicator in communicator_list: - if communicator.rank == 0: - result_list.append(communicator.scatter_state(send_state=state)) - else: - result_list.append(communicator.scatter_state()) - for result_state, scattered in zip(result_list, scattered_quantities): - assert result_state["time"] == time - result = result_state["air_temperature"] - assert result.dims == scattered.dims - assert result.units == scattered.units - assert result.extent == scattered.extent - scattered.np.testing.assert_array_equal(result.view[:], scattered.view[:]) - - -def test_tile_scatter_state_without_time( - tile_quantity, scattered_quantities, communicator_list -): - state = {"air_temperature": tile_quantity} - result_list = [] - for communicator in communicator_list: - if communicator.rank == 0: - result_list.append(communicator.scatter_state(send_state=state)) - else: - result_list.append(communicator.scatter_state()) - for result_state, scattered in zip(result_list, scattered_quantities): - assert "time" not in result_state - result = result_state["air_temperature"] - assert result.dims == scattered.dims - assert result.units == scattered.units - assert result.extent == scattered.extent - scattered.np.testing.assert_array_equal(result.view[:], scattered.view[:]) - - -def test_tile_scatter_state_with_recv_state( - tile_quantity, scattered_quantities, communicator_list, time -): - tile_state = {"time": time, "air_temperature": tile_quantity} - recv_quantities = copy.deepcopy(scattered_quantities) - for q in recv_quantities: - q.data[:] = 0.0 - for recv, communicator in zip(recv_quantities, communicator_list): - state = { - "time": time - datetime.timedelta(hours=1), - "air_temperature": recv, - } - if communicator.rank == 0: - result = communicator.scatter_state(send_state=tile_state, recv_state=state) - else: - result = communicator.scatter_state(recv_state=state) - assert result["time"] == time - assert result["air_temperature"] is recv - for rank, (result, scattered) in enumerate( - zip(recv_quantities, scattered_quantities) - ): - assert result.dims == scattered.dims - assert result.units == scattered.units - assert result.extent == scattered.extent - scattered.np.testing.assert_array_equal(result.view[:], scattered.view[:]) - - -def test_tile_scatter_state_with_recv_state_without_time( - tile_quantity, scattered_quantities, communicator_list -): - tile_state = {"air_temperature": tile_quantity} - recv_quantities = copy.deepcopy(scattered_quantities) - for q in recv_quantities: - q.data[:] = 0.0 - for recv, communicator in zip(recv_quantities, communicator_list): - state = { - "air_temperature": recv, - } - if communicator.rank == 0: - result = communicator.scatter_state(send_state=tile_state, recv_state=state) - else: - result = communicator.scatter_state(recv_state=state) - assert result["air_temperature"] is recv - assert "time" not in result - for rank, (result, scattered) in enumerate( - zip(recv_quantities, scattered_quantities) - ): - assert result.dims == scattered.dims - assert result.units == scattered.units - assert result.extent == scattered.extent - scattered.np.testing.assert_array_equal(result.view[:], scattered.view[:]) diff --git a/util/tests/test_timer.py b/util/tests/test_timer.py deleted file mode 100644 index 0065bcc16..000000000 --- a/util/tests/test_timer.py +++ /dev/null @@ -1,151 +0,0 @@ -import time - -import pytest - -from pace.util import NullTimer, Timer - - -@pytest.fixture -def timer(): - return Timer() - - -@pytest.fixture -def null_timer(): - return NullTimer() - - -def test_start_stop(timer): - timer.start("label") - timer.stop("label") - times = timer.times - assert "label" in times - assert len(times) == 1 - assert timer.hits["label"] == 1 - assert len(timer.hits) == 1 - - -def test_null_timer_cannot_be_enabled(null_timer): - with pytest.raises(NotImplementedError): - null_timer.enable() - - -def test_null_timer_is_disabled(null_timer): - assert not null_timer.enabled - - -def test_clock(timer): - with timer.clock("label"): - # small arbitrary computation task to time - time.sleep(0.1) - times = timer.times - assert "label" in times - assert len(times) == 1 - assert abs(times["label"] - 0.1) < 1e-2 - assert timer.hits["label"] == 1 - assert len(timer.hits) == 1 - - -def test_start_twice(timer): - """cannot call start twice consecutively with no stop""" - timer.start("label") - with pytest.raises(ValueError) as err: - timer.start("label") - assert "clock already started for 'label'" in str(err.value) - - -def test_clock_in_clock(timer): - """should not be able to create a given clock inside itself""" - with timer.clock("label"): - with pytest.raises(ValueError) as err: - with timer.clock("label"): - pass - assert "clock already started for 'label'" in str(err.value) - - -def test_consecutive_start_stops(timer): - """total time increases with consecutive clock blocks""" - timer.start("label") - time.sleep(0.01) - timer.stop("label") - previous_time = timer.times["label"] - for i in range(5): - timer.start("label") - time.sleep(0.01) - timer.stop("label") - assert timer.times["label"] >= previous_time + 0.01 - previous_time = timer.times["label"] - assert timer.hits["label"] == 6 - - -def test_consecutive_clocks(timer): - """total time increases with consecutive clock blocks""" - with timer.clock("label"): - time.sleep(0.01) - previous_time = timer.times["label"] - for i in range(5): - with timer.clock("label"): - time.sleep(0.01) - assert timer.times["label"] >= previous_time + 0.01 - previous_time = timer.times["label"] - assert timer.hits["label"] == 6 - - -@pytest.mark.parametrize( - "ops, result", - [ - ([], True), - (["enable"], True), - (["disable"], False), - (["disable", "enable"], True), - (["disable", "disable"], False), - ], -) -def test_enable_disable(timer, ops, result): - for op in ops: - getattr(timer, op)() - assert timer.enabled == result - - -def test_disabled_timer_does_not_add_key(timer): - timer.disable() - with timer.clock("label1"): - time.sleep(0.01) - assert len(timer.times) == 0 - with timer.clock("label2"): - time.sleep(0.01) - assert len(timer.times) == 0 - assert len(timer.hits) == 0 - - -def test_disabled_timer_does_not_add_time(timer): - with timer.clock("label"): - time.sleep(0.01) - initial_time = timer.times["label"] - timer.disable() - with timer.clock("label"): - time.sleep(0.01) - assert timer.times["label"] == initial_time - assert timer.hits["label"] == 1 - - -@pytest.fixture(params=["clean", "one_label", "two_labels"]) -def used_timer(request, timer): - if request.param == "clean": - return timer - elif request.param == "one_label": - with timer.clock("label1"): - time.sleep(0.01) - return timer - elif request.param == "two_labels": - with timer.clock("label1"): - time.sleep(0.01) - with timer.clock("label2"): - time.sleep(0.01) - return timer - - -def test_timer_reset(used_timer): - used_timer.reset() - assert len(used_timer.times) == 0 - assert len(used_timer.hits) == 0 diff --git a/util/tests/test_zarr_monitor.py b/util/tests/test_zarr_monitor.py deleted file mode 100644 index b02ae4542..000000000 --- a/util/tests/test_zarr_monitor.py +++ /dev/null @@ -1,519 +0,0 @@ -import tempfile - - -try: - import zarr -except ModuleNotFoundError: - zarr = None -import copy -import logging -from datetime import datetime, timedelta - -import cftime -import pytest - -import pace.util -from pace.util import X_DIMS, Y_DIMS -from pace.util._optional_imports import xarray as xr -from pace.util.monitor.zarr_monitor import array_chunks, get_calendar -from pace.util.testing import DummyComm - - -requires_zarr = pytest.mark.skipif(zarr is None, reason="zarr is not installed") -requires_xarray = pytest.mark.skipif(xr is None, reason="xarray is not installed") - -logger = logging.getLogger("test_zarr_monitor") - -# pace's Z_DIMS doesn't check the soil dimension -Z_DIMS = ("z", "z_interface", "z_soil") - - -@pytest.fixture(params=["one_step", "three_steps"]) -def n_times(request, fast): - if request.param == "one_step": - if fast: - pytest.skip("running in fast mode") - else: - return 1 - elif request.param == "three_steps": - return 3 - - -@pytest.fixture( - params=[ - cftime.DatetimeJulian, - cftime.Datetime360Day, - cftime.DatetimeNoLeap, - datetime, - ] -) -def start_time(request): - date_type = request.param - return date_type(2010, 1, 1) - - -@pytest.fixture -def time_step(): - return timedelta(hours=1) - - -@pytest.fixture -def ny(): - return 4 - - -@pytest.fixture -def nx(): - return 4 - - -@pytest.fixture -def nz(): - return 5 - - -@pytest.fixture -def layout(): - return (1, 1) - - -@pytest.fixture -def tile_partitioner(layout): - return pace.util.TilePartitioner(layout) - - -@pytest.fixture -def cube_partitioner(tile_partitioner): - return pace.util.CubedSpherePartitioner(tile_partitioner) - - -@pytest.fixture(params=["empty", "one_var_2d", "one_var_3d", "two_vars"]) -def base_state(request, nz, ny, nx, numpy): - if request.param == "empty": - return {} - elif request.param == "one_var_2d": - return { - "var1": pace.util.Quantity( - numpy.ones([ny, nx]), - dims=("y", "x"), - units="m", - ) - } - elif request.param == "one_var_3d": - return { - "var1": pace.util.Quantity( - numpy.ones([nz, ny, nx]), - dims=("z", "y", "x"), - units="m", - ) - } - elif request.param == "two_vars": - return { - "var1": pace.util.Quantity( - numpy.ones([ny, nx]), - dims=("y", "x"), - units="m", - ), - "var2": pace.util.Quantity( - numpy.ones([nz, ny, nx]), - dims=("z", "y", "x"), - units="degK", - ), - } - else: - raise NotImplementedError() - - -@pytest.fixture -def state_list(base_state, n_times, start_time, time_step, numpy): - state_list = [] - for i in range(n_times): - new_state = copy.deepcopy(base_state) - for name in set(new_state.keys()).difference(["time"]): - new_state[name].view[:] = numpy.random.randn(*new_state[name].extent) - state_list.append(new_state) - new_state["time"] = start_time + i * time_step - return state_list - - -@requires_zarr -@requires_xarray -def test_monitor_file_store(state_list, cube_partitioner, numpy, start_time): - with tempfile.TemporaryDirectory(suffix=".zarr") as tempdir: - monitor = pace.util.ZarrMonitor(tempdir, cube_partitioner) - for state in state_list: - monitor.store(state) - validate_store(state_list, tempdir, numpy, start_time) - validate_xarray_can_open(tempdir) - - -@requires_zarr -@requires_xarray -def validate_xarray_can_open(dirname): - # just checking there are no crashes, validate_group checks data - xr.open_zarr(dirname) - - -@requires_zarr -@requires_xarray -def validate_store(states, filename, numpy, start_time): - nt = len(states) - calendar = get_calendar(start_time) - - def assert_no_missing_names(store, state): - missing_names = set(states[0].keys()).difference(store.array_keys()) - assert len(missing_names) == 0, missing_names - - def validate_array_shape(name, array): - if name == "time": - assert array.shape == (nt,) - else: - assert array.shape == (nt, 6) + states[0][name].extent - - def validate_array_dimensions_and_attributes(name, array): - if name == "time": - target_attrs = { - "_ARRAY_DIMENSIONS": ["time"], - "units": "seconds since 2010-01-01 00:00:00", - "calendar": calendar, - } - else: - target_attrs = states[0][name].attrs - target_attrs["_ARRAY_DIMENSIONS"] = ["time", "tile"] + list( - states[0][name].dims - ) - assert dict(array.attrs) == target_attrs - - def validate_array_values(name, array): - if name == "time": - for i, s in enumerate(states): - value = cftime.num2date( - array[i], - units="seconds since 2010-01-01 00:00:00", - calendar=calendar, - ) - assert value == s["time"] - else: - for i, s in enumerate(states): - numpy.testing.assert_array_equal(array[i, 0, :], s[name].view[:]) - - store = zarr.open_group(filename, mode="r") - assert_no_missing_names( - store, states[0] - ) # states in test all have same names defined - for name, array in store.arrays(): - validate_array_shape(name, array) - validate_array_dimensions_and_attributes(name, array) - validate_array_values(name, array) - - -@pytest.mark.parametrize("layout", [(1, 1), (1, 2), (2, 2), (4, 4)]) -@pytest.mark.parametrize("nt", [1, 3]) -@pytest.mark.parametrize( - "shape, ny_rank_add, nx_rank_add, dims", - [ - ((5, 4, 4), 0, 0, ("z", "y", "x")), - ((5, 4, 4), 1, 1, ("z", "y_interface", "x_interface")), - ((5, 4, 4), 0, 1, ("z", "y", "x_interface")), - ], -) -@requires_zarr -@requires_xarray -def test_monitor_file_store_multi_rank_state( - layout, nt, tmpdir_factory, shape, ny_rank_add, nx_rank_add, dims, numpy -): - units = "m" - tmpdir = tmpdir_factory.mktemp("data.zarr") - nz, ny, nx = shape - ny_rank = int(ny / layout[0] + ny_rank_add) - nx_rank = int(nx / layout[1] + nx_rank_add) - grid = pace.util.TilePartitioner(layout) - time = cftime.DatetimeJulian(2010, 6, 20, 6, 0, 0) - timestep = timedelta(hours=1) - total_ranks = 6 * layout[0] * layout[1] - partitioner = pace.util.CubedSpherePartitioner(grid) - store = zarr.storage.DirectoryStore(tmpdir) - shared_buffer = {} - monitor_list = [] - for rank in range(total_ranks): - monitor_list.append( - pace.util.ZarrMonitor( - store, - partitioner, - "w", - mpi_comm=DummyComm( - rank=rank, total_ranks=total_ranks, buffer_dict=shared_buffer - ), - ) - ) - for i_t in range(nt): - for rank in range(total_ranks): - state = { - "time": time + i_t * timestep, - "var1": pace.util.Quantity( - numpy.ones([nz, ny_rank, nx_rank]), - dims=dims, - units=units, - ), - } - monitor_list[rank].store(state) - group = zarr.hierarchy.open_group(store=store, mode="r") - assert "var1" in group - assert group["var1"].shape == (nt, 6, nz, ny + ny_rank_add, nx + nx_rank_add) - numpy.testing.assert_array_equal(group["var1"], 1.0) - - -@pytest.mark.parametrize( - "layout, tile_array_shape, array_dims, target", - [ - pytest.param( - (1, 1), - (7, 6, 6), - [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (7, 6, 6), - id="single_chunk_tile_3d", - ), - pytest.param( - (1, 1), - (6, 6), - [pace.util.Y_DIM, pace.util.X_DIM], - (6, 6), - id="single_chunk_tile_2d", - ), - pytest.param((1, 1), (6,), [pace.util.Y_DIM], (6,), id="single_chunk_tile_1d"), - pytest.param( - (1, 1), - (7, 6, 6), - [ - pace.util.Z_DIM, - pace.util.Y_INTERFACE_DIM, - pace.util.X_INTERFACE_DIM, - ], - (7, 5, 5), - id="single_chunk_tile_3d_interfaces", - ), - pytest.param( - (2, 2), - (7, 6, 6), - [pace.util.Z_DIM, pace.util.Y_DIM, pace.util.X_DIM], - (7, 3, 3), - id="2_by_2_tile_3d", - ), - pytest.param( - (2, 2), - (6, 16, 6), - [pace.util.Y_DIM, pace.util.Z_DIM, pace.util.X_DIM], - (3, 16, 3), - id="2_by_2_tile_3d_odd_dim_order", - ), - pytest.param( - (2, 2), - (7, 7, 7), - [ - pace.util.Z_DIM, - pace.util.Y_INTERFACE_DIM, - pace.util.X_INTERFACE_DIM, - ], - (7, 3, 3), - id="2_by_2_tile_3d_interfaces", - ), - ], -) -@requires_zarr -@requires_xarray -def test_array_chunks(layout, tile_array_shape, array_dims, target): - result = array_chunks(layout, tile_array_shape, array_dims) - assert result == target - - -def _assert_no_nulls(dataset: "xr.Dataset"): - number_of_null = dataset["var"].isnull().sum().item() - total_size = dataset["var"].size - - assert ( - number_of_null == 0 - ), f"Number of nulls {number_of_null}. Size of data {total_size}" - - -@pytest.mark.parametrize("mask_and_scale", [True, False]) -@requires_zarr -@requires_xarray -def test_open_zarr_without_nans(cube_partitioner, numpy, backend, mask_and_scale): - - store = {} - - # initialize store - monitor = pace.util.ZarrMonitor(store, cube_partitioner) - zero_quantity = pace.util.Quantity( - numpy.zeros([10, 10]), dims=("y", "x"), units="m" - ) - monitor.store({"var": zero_quantity}) - - # open w/o dask using chunks=None - dataset = xr.open_zarr(store, chunks=None, mask_and_scale=mask_and_scale) - _assert_no_nulls(dataset.sel(tile=0)) - - -@requires_zarr -@requires_xarray -def test_values_preserved(cube_partitioner, numpy): - dims = ("y", "x") - units = "m" - - store = {} - - # initialize store - monitor = pace.util.ZarrMonitor(store, cube_partitioner) - quantity = pace.util.Quantity( - numpy.random.uniform(size=(10, 10)), dims=dims, units=units - ) - monitor.store({"var": quantity}) - - # open w/o dask using chunks=None - dataset = xr.open_zarr(store, chunks=None) - numpy.testing.assert_array_almost_equal( - dataset["var"][0, 0, :, :].values, quantity.data - ) - assert dataset["var"].shape[:2] == (1, 6) - assert dataset["var"].attrs["units"] == units - assert dataset["var"].dims[2:] == dims - - -@pytest.fixture -def state_list_with_inconsistent_calendars(base_state, numpy): - state_list = [] - state_times = [cftime.DatetimeNoLeap(2000, 1, 1), cftime.Datetime360Day(2000, 1, 2)] - for i in range(2): - new_state = copy.deepcopy(base_state) - for name in set(new_state.keys()).difference(["time"]): - new_state[name].view[:] = numpy.random.randn(*new_state[name].extent) - state_list.append(new_state) - new_state["time"] = state_times[i] - return state_list - - -@requires_zarr -@requires_xarray -def test_monitor_file_store_inconsistent_calendars( - state_list_with_inconsistent_calendars, cube_partitioner, numpy -): - with tempfile.TemporaryDirectory(suffix=".zarr") as tempdir: - monitor = pace.util.ZarrMonitor(tempdir, cube_partitioner) - initial_state, final_state = state_list_with_inconsistent_calendars - monitor.store(initial_state) - with pytest.raises(ValueError, match="Calendar type"): - monitor.store(final_state) - - -@pytest.fixture( - params=[ - ["x", "y"], - ["x", "y", "z"], - ["x_interface", "y", "z"], - ["x", "y_interface", "z"], - ["x", "y", "z_soil"], - ], -) -def diag(request, numpy): - dims = request.param - diag = pace.util.Quantity( - numpy.ones([size + 2 for size in range(len(dims))]), dims=dims, units="m" - ) - return diag - - -def _transpose(quantity, dims_2d, dims_3d): - if len(quantity.dims) == 2: - return quantity.transpose(dims_2d) - elif len(quantity.dims) == 3: - return quantity.transpose(dims_3d) - - -@pytest.fixture(scope="function") -def zarr_store(tmpdir_factory): - tmpdir = tmpdir_factory.mktemp("diags.zarr") - store = zarr.storage.DirectoryStore(tmpdir) - return store - - -@pytest.fixture(scope="function") -def zarr_monitor_single_rank(zarr_store, cube_partitioner): - return pace.util.ZarrMonitor(zarr_store, cube_partitioner) - - -@requires_zarr -@requires_xarray -def test_transposed_diags_write_across_ranks(diag, cube_partitioner, zarr_store): - - layout = (1, 1) - total_ranks = 6 * layout[0] * layout[1] - shared_buffer = {} - for rank in range(total_ranks): - monitor = pace.util.ZarrMonitor( - zarr_store, - cube_partitioner, - mpi_comm=DummyComm( - rank=rank, total_ranks=total_ranks, buffer_dict=shared_buffer - ), - ) - if rank % 2 == 0: - diag_to_store = _transpose( - diag, dims_2d=[Y_DIMS, X_DIMS], dims_3d=[Z_DIMS, Y_DIMS, X_DIMS] - ) - else: - diag_to_store = _transpose( - diag, dims_2d=[X_DIMS, Y_DIMS], dims_3d=[X_DIMS, Y_DIMS, Z_DIMS] - ) - # verify that we can store transposed diags across ranks - monitor.store({"a": diag_to_store}) - - -@requires_zarr -@requires_xarray -def test_transposed_diags_write_across_timesteps(diag, zarr_monitor_single_rank): - - # verify that we can store transposed diags across time - time_1 = cftime.DatetimeJulian(2010, 6, 20, 6, 0, 0) - diag_1 = _transpose( - diag, dims_2d=[Y_DIMS, X_DIMS], dims_3d=[Z_DIMS, Y_DIMS, X_DIMS] - ) - zarr_monitor_single_rank.store({"time": time_1, "a": diag_1}) - time_2 = cftime.DatetimeJulian(2010, 6, 20, 6, 15, 0) - diag_2 = _transpose( - diag, dims_2d=[X_DIMS, Y_DIMS], dims_3d=[X_DIMS, Y_DIMS, Z_DIMS] - ) - zarr_monitor_single_rank.store({"time": time_2, "a": diag_2}) - - -@requires_zarr -@requires_xarray -def test_diags_fail_different_dim_set(diag, numpy, zarr_monitor_single_rank): - time_1 = cftime.DatetimeJulian(2010, 6, 20, 6, 0, 0) - time_2 = cftime.DatetimeJulian(2010, 6, 20, 6, 15, 0) - zarr_monitor_single_rank.store({"time": time_1, "a": diag}) - new_dims = list(diag.dims) - new_dims[-1] = "some_other_dim" - diag_2 = pace.util.Quantity( - numpy.ones([size + 2 for size in range(len(diag.dims))]), - dims=new_dims, - units="m", - ) - with pytest.raises(ValueError) as excinfo: - zarr_monitor_single_rank.store({"time": time_2, "a": diag_2}) - assert "Attempting to append a quantity" in str(excinfo.value) - - -@requires_zarr -@requires_xarray -def test_diags_only_consistent_units_attrs_required(diag, zarr_monitor_single_rank): - - time_1 = cftime.DatetimeJulian(2010, 6, 20, 6, 0, 0) - time_2 = cftime.DatetimeJulian(2010, 6, 20, 6, 15, 0) - time_3 = cftime.DatetimeJulian(2010, 6, 20, 6, 30, 0) - zarr_monitor_single_rank.store({"time": time_1, "a": diag}) - diag_2 = copy.deepcopy(diag) - diag_2._attrs.update({"some_non_units_attrs": 9.0}) - zarr_monitor_single_rank.store({"time": time_2, "a": diag_2}) - diag_3 = pace.util.Quantity(data=diag.values, dims=diag.dims, units="not_m") - with pytest.raises(ValueError): - zarr_monitor_single_rank.store({"time": time_3, "a": diag_3}) diff --git a/util/tox.ini b/util/tox.ini deleted file mode 100644 index c4147ffa6..000000000 --- a/util/tox.ini +++ /dev/null @@ -1,55 +0,0 @@ -# tox (https://tox.readthedocs.io/) is a tool for running tests -# in multiple virtualenvs. This configuration file will run the -# test suite on all supported python versions. To use it, "pip install tox" -# and then run "tox" from this directory. - -[tox] -envlist = py3 - -[testenv:test_no_extras] -allowlist_externals=make -deps = - # other versions of pytest don't work with subtests - pytest - pytest-subtests - pytest-cov - dask # used for open_mfdataset in a test - netcdf4 - h5netcdf - -e external/gt4py - -c../constraints.txt -# only run a subset of tests (fast, no MPI tests) -# to check import infrastructure works with no extras -setenv = - PYTEST_ARGS = --fast -commands = - make test - - -[testenv:test] -allowlist_externals=make mpirun -deps = - # other versions of pytest don't work with subtests - pytest - pytest-subtests - pytest-cov - dask # used for open_mfdataset in a test - -e external/gt4py - netcdf4 - h5netcdf - mpi4py - -c../constraints.txt -extras = netcdf,zarr -commands = - make test test_mpi - -[testenv:lint] -allowlist_externals=make -skip_install = true -deps = - black - flake8 - mypy - -c../constraints.txt -commands = - make lint