Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
6d78659
Initialize GeosDycoreWrapper with bdt (timestep)
pchakraborty Jan 27, 2023
0a3e857
Use GEOS version of constants
pchakraborty Jan 27, 2023
0a8d705
1. Add qcld to the list of tracers beings advected
pchakraborty Jan 27, 2023
3b73d71
Accumulate diss_est
pchakraborty Jan 27, 2023
a68d160
Allow GEOS_WRAPPER to process device data
FlorianDeconinck Feb 24, 2023
33ba53f
Add clear to collector for 3rd party use. GEOS pass down timings to c…
FlorianDeconinck Feb 28, 2023
8968698
Merge branch 'geos/main' into opt_geos_wrapper_bridge
FlorianDeconinck Mar 1, 2023
2327cbe
Make kernel analysis run a copy stencil to compute local bandwith
FlorianDeconinck Mar 3, 2023
cb4ec5f
Move constant on a env var
FlorianDeconinck Mar 3, 2023
7348922
lint
FlorianDeconinck Mar 3, 2023
e234d16
lint
FlorianDeconinck Mar 3, 2023
131a2af
More linting
FlorianDeconinck Mar 3, 2023
dce3fb7
Merge branch 'opt_geos_wrapper_bridge' into debug/pchakrab/aquaplanet…
FlorianDeconinck Mar 3, 2023
8982542
Remove unused if leading to empty code block
FlorianDeconinck Mar 6, 2023
da2f902
Restrict dace to 0.14.1 due to a parsing bug
FlorianDeconinck Mar 6, 2023
f2799d8
Merge branch 'feature/dace_debug' into debug/pchakrab/aquaplanet/root…
FlorianDeconinck Mar 6, 2023
27fae1c
Add guard for bdt==0
FlorianDeconinck Mar 7, 2023
2f8ebac
Remove unused code
FlorianDeconinck Mar 7, 2023
5d9e0a0
Merge branch 'feature/dace_debug' into opt_geos_wrapper_bridge
FlorianDeconinck Mar 27, 2023
b8edbf2
Merge remote-tracking branch 'nasa/feature/kernel_bw_tool' into opt_g…
FlorianDeconinck Mar 27, 2023
f54b231
Merge branch 'opt_geos_wrapper_bridge' into debug/pchakrab/aquaplanet…
FlorianDeconinck Mar 27, 2023
81d00ce
Fix theroritical timings
FlorianDeconinck Mar 28, 2023
4891d56
Fixed a bug where pkz was being calculated twice, and the second calc…
pchakraborty Apr 7, 2023
fafbfc7
Downgrade DaCe to 0.14.0 pending array aliasing fix
FlorianDeconinck Apr 10, 2023
4fc5b4d
Set default cache path for orchestrated DaCe to respect GT_CACHE_* env
FlorianDeconinck Apr 10, 2023
2245027
Remove previous per stencil override of default_build_folder
FlorianDeconinck Apr 11, 2023
4f8fdc3
Revert "Set default cache path for orchestrated DaCe to respect GT_CA…
FlorianDeconinck Apr 11, 2023
47421a0
Revert "Remove previous per stencil override of default_build_folder"
FlorianDeconinck Apr 11, 2023
d51bc11
Read cache_root in default dace backend
FlorianDeconinck Apr 11, 2023
6bdd595
Document faulty behavior with GT_CACHE_DIR_NAME
FlorianDeconinck Apr 11, 2023
80cbb01
Fix bad requirements syntax
FlorianDeconinck Apr 13, 2023
40f2440
Check for the string value of CONST_VERSION directly instead of enum
pchakraborty Apr 14, 2023
cae25a9
Protect constant selection more rigorusly.
FlorianDeconinck Apr 20, 2023
915993e
Log constants selection
FlorianDeconinck Apr 20, 2023
c3e355c
Refactor NQ to constants.py
FlorianDeconinck Apr 20, 2023
08f6e68
Merge pull request #11 from GEOS-ESM/debug/pchakrab/aquaplanet/root-3…
FlorianDeconinck Apr 20, 2023
cde11e8
Replace all logger with pace_log
FlorianDeconinck May 2, 2023
9e6bbb6
Code guidelines clean up
FlorianDeconinck May 2, 2023
6695cec
Merge pull request #13 from GEOS-ESM/feature/logger
pchakraborty May 2, 2023
7e449cd
Devops/GitHub actions on (#15)
FlorianDeconinck Jun 21, 2023
d5d0ee5
Merge branch 'main' into up/feature/utest_on
FlorianDeconinck Aug 15, 2023
6f8bed5
Missed merge
FlorianDeconinck Aug 15, 2023
c4d5f41
Update HISTORY.md
FlorianDeconinck Aug 15, 2023
adbddf8
Restore zeroing dissipation and heat_source
FlorianDeconinck Aug 16, 2023
e8c669c
Restore test of grid decomposition
FlorianDeconinck Aug 16, 2023
d0e8be6
Adapt log_level in driver.run
FlorianDeconinck Aug 16, 2023
69429b4
Verbose the PACE_CONSTANTS
FlorianDeconinck Aug 16, 2023
1a7c642
Doc log level hierarchical nature
FlorianDeconinck Aug 16, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: "Lint"
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout Pace repository
uses: actions/checkout@v3.5.2
with:
submodules: 'recursive'
- name: Step Python 3.8.12
uses: actions/setup-python@v4.6.0
with:
python-version: '3.8.12'
- name: Install OpenMPI for gt4py
run: |
sudo apt-get install libopenmpi-dev
- name: Install Python packages
run: |
python -m pip install --upgrade pip
pip install -r requirements_dev.txt -r requirements_lint.txt
- name: Run lint via pre-commit
run: |
pre-commit run --all-files
27 changes: 27 additions & 0 deletions .github/workflows/main_unit_tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: "Main unit tests"
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]

jobs:
main_unit_tests:
runs-on: ubuntu-latest
steps:
- name: Checkout Pace repository
uses: actions/checkout@v3.5.2
with:
submodules: 'recursive'
- name: Step Python 3.8.12
uses: actions/setup-python@v4.6.0
with:
python-version: '3.8.12'
- name: Install OpenMPI for gt4py
run: |
sudo apt-get install libopenmpi-dev
- name: Install Python packages
run: |
python -m pip install --upgrade pip
pip install -r requirements_dev.txt
- name: Run all main tests
run: |
pytest -x tests/main
Comment thread
bensonr marked this conversation as resolved.
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Pace is an implementation of the FV3GFS / SHiELD atmospheric model developed by
Full Sphinx documentation can be found at [https://ai2cm.github.io/pace/](https://ai2cm.github.io/pace/).

**WARNING** This repo is under active development - supported features and procedures can change rapidly and without notice.

## Quickstart - bare metal

### Build
Expand All @@ -27,10 +28,13 @@ export BOOST_ROOT=BOOST/ROOT/boost_1_79_0
```

When cloning Pace you will need to update the repository's submodules as well:

```shell
git clone --recursive https://github.com/ai2cm/pace.git
```

or if you have already cloned the repository:

```
git submodule update --init --recursive
```
Expand All @@ -43,6 +47,7 @@ source venv_name/bin/activate
```

Inside of your pace `venv` or conda environment pip install the Python requirements, GT4Py, and Pace:

```shell
pip3 install -r requirements_dev.txt -c constraints.txt
```
Expand All @@ -52,6 +57,7 @@ Shell scripts to install Pace on specific machines such as Gaea can be found in
### Run

With the environment activated, you can run an example baroclinic test case with the following command:

```shell
mpirun -n 6 python3 -m pace.driver.run driver/examples/configs/baroclinic_c12.yaml

Expand All @@ -61,20 +67,33 @@ mpirun -n 6 --oversubscribe python3 -m pace.driver.run driver/examples/configs/b

After the run completes, you will see an output direcotry `output.zarr`. An example to visualize the output is provided in `driver/examples/plot_output.py`. See the [driver example](driver/examples/README.md) section for more details.

### Environment variable configuration

- `PACE_CONSTANTS`: Pace is bundled with various constants (see _util/pace/util/constants.py_).
Comment thread
FlorianDeconinck marked this conversation as resolved.
- `FV3DYCORE` NOAA's FV3 dynamical core constants (original port)
- `GFS` Constant as defined in NOAA GFS
- `GEOS` Constant as defined in GEOS v13
- `PACE_FLOAT_PRECISION`: default precision of the field & scalars in the numerics. Default to 64.
- `PACE_LOGLEVEL`: logging level to display (DEBUG, INFO, WARNING, ERROR, CRITICAL). Default to INFO.

## Quickstart - Docker

### Build

While it is possible to install and build pace bare-metal, we can ensure all system libraries are installed with the correct versions by using a Docker container to test and develop pace.

First, you will need to update the git submodules so that any dependencies are cloned and at the correct version:

```shell
git submodule update --init --recursive
```

Then build the `pace` docker image at the top level.

```shell
make build
```

### Run

```shell
Expand All @@ -94,7 +113,6 @@ This git repository is laid out as a mono-repo, containing multiple independent

![Graph of interdependencies of Pace modules, generated from dependences.dot](./dependencies.svg)


## ML emulation

An example of integration of an ML model replacing the microphysics parametrization is available on the `feature/microphysics-emulator` branch.
Expand Down
54 changes: 7 additions & 47 deletions driver/pace/driver/run.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,15 @@
import dataclasses
import gc
import logging
from typing import Optional

import click
import yaml

from pace.util.mpi import MPI
from pace.util import pace_log, AVAILABLE_LOG_LEVELS

from .driver import Driver, DriverConfig


logger = logging.getLogger(__name__)


log_levels = {
"info": logging.INFO,
"debug": logging.DEBUG,
"warning": logging.WARNING,
"error": logging.ERROR,
"critical": logging.CRITICAL,
}


def configure_logging(log_rank: Optional[int], log_level: str):
"""
Configure logging for the driver.

Args:
log_rank: rank to log from, or 'all' to log to all ranks,
forced to 'all' if running without MPI
log_level: log level to use
"""
level = log_levels[log_level.lower()]
if MPI is None:
logging.basicConfig(
level=level,
format="%(asctime)s [%(levelname)s] %(name)s:%(message)s",
handlers=[logging.StreamHandler()],
datefmt="%Y-%m-%d %H:%M:%S",
)
else:
if log_rank is None or int(log_rank) == MPI.COMM_WORLD.Get_rank():
logging.basicConfig(
level=level,
format=(
f"%(asctime)s [%(levelname)s] (rank {MPI.COMM_WORLD.Get_rank()}) "
"%(name)s:%(message)s"
),
handlers=[logging.StreamHandler()],
datefmt="%Y-%m-%d %H:%M:%S",
)


@click.command()
@click.argument(
"CONFIG_PATH",
Expand All @@ -75,12 +32,15 @@ def command_line(config_path: str, log_rank: Optional[int], log_level: str):

CONFIG_PATH is the path to a DriverConfig yaml file.
"""
configure_logging(log_rank=log_rank, log_level=log_level)
logger.info("loading DriverConfig from yaml")
level = AVAILABLE_LOG_LEVELS[log_level.lower()]
pace_log.setLevel(level)
pace_log.info("loading DriverConfig from yaml")
with open(config_path, "r") as f:
config = yaml.safe_load(f)
driver_config = DriverConfig.from_dict(config)
logging.info(f"DriverConfig loaded: {yaml.dump(dataclasses.asdict(driver_config))}")
pace_log.info(
f"DriverConfig loaded: {yaml.dump(dataclasses.asdict(driver_config))}"
)
main(driver_config=driver_config)


Expand Down
2 changes: 1 addition & 1 deletion dsl/pace/dsl/dace/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def __init__(self, config: DaceConfig, label: str):

@classmethod
def log(cls, prefix: str, message: str):
pace_log.info(f"{prefix} {message}")
pace_log.debug(f"{prefix} {message}")

@classmethod
def default_prefix(cls, config: DaceConfig) -> str:
Expand Down
8 changes: 4 additions & 4 deletions fv3core/pace/fv3core/initialization/geos_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,12 @@ def __init__(
self._allocate_output_dir()

pace_log.info(
"GEOS-Wrapper with: \n"
"Pace GEOS wrapper initialized: \n"
f" dt : {self.dycore_state.bdt}\n"
f" bridge : {self._fortran_mem_space} > {self._pace_mem_space}\n"
f" backend: {backend}\n"
f" orchestration: {self._is_orchestrated}\n"
f" sizer : {sizer.nx}x{sizer.ny}x{sizer.nz} (halo: {sizer.n_halo})"
)

def _critical_path(self):
Expand Down Expand Up @@ -173,7 +176,6 @@ def __call__(
cyd: np.ndarray,
diss_estd: np.ndarray,
) -> Tuple[Dict[str, np.ndarray], Dict[str, List[float]]]:

with self.perf_collector.timestep_timer.clock("numpy-to-dycore"):
self.dycore_state = self._put_fortran_data_in_dycore(
u,
Expand Down Expand Up @@ -246,7 +248,6 @@ def _put_fortran_data_in_dycore(
cyd: np.ndarray,
diss_estd: np.ndarray,
) -> fv3core.DycoreState:

isc = self._grid_indexing.isc
jsc = self._grid_indexing.jsc
iec = self._grid_indexing.iec + 1
Expand Down Expand Up @@ -315,7 +316,6 @@ def _put_fortran_data_in_dycore(
return state

def _prep_outputs_for_geos(self) -> Dict[str, np.ndarray]:

output_dict = self.output_dict
isc = self._grid_indexing.isc
jsc = self._grid_indexing.jsc
Expand Down
6 changes: 3 additions & 3 deletions fv3core/pace/fv3core/stencils/d_sw.py
Original file line number Diff line number Diff line change
Expand Up @@ -932,7 +932,7 @@ def make_quantity():
)
)

if (self._d_con > 1.e-5) or (self._do_stochastic_ke_backscatter):
if (self._d_con > 1.0e-5) or (self._do_stochastic_ke_backscatter):
self._accumulate_heat_source_and_dissipation_estimate_stencil = (
stencil_factory.from_dims_halo(
func=accumulate_heat_source_and_dissipation_estimate,
Expand Down Expand Up @@ -1254,11 +1254,11 @@ def __call__(
self._column_namelist["d_con"],
)

if (self._d_con > 1.e-5) or (self._do_stochastic_ke_backscatter):
if (self._d_con > 1.0e-5) or (self._do_stochastic_ke_backscatter):
self._accumulate_heat_source_and_dissipation_estimate_stencil(
self._tmp_heat_s, heat_source, self._tmp_diss_e, diss_est
)

self._update_u_and_v_stencil(
self._tmp_ut,
self._tmp_vt,
Expand Down
3 changes: 1 addition & 2 deletions fv3core/pace/fv3core/stencils/fv_dynamics.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import pace.dsl.gt4py_utils as utils
import pace.fv3core.stencils.moist_cv as moist_cv
import pace.util
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 StencilFactory
Expand All @@ -21,7 +20,7 @@
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
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
Expand Down
60 changes: 33 additions & 27 deletions tests/main/fv3core/test_init_from_geos.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@


def test_geos_wrapper():

namelist_dict = {
"stencil_config": {
"compilation_config": {
Expand Down Expand Up @@ -82,7 +81,12 @@ def test_geos_wrapper():
comm = NullComm(rank=0, total_ranks=6, fill_value=0.0)
backend = "numpy"

wrapper = fv3core.GeosDycoreWrapper(namelist, comm, backend)
wrapper = fv3core.GeosDycoreWrapper(
namelist=namelist,
comm=comm,
backend=backend,
bdt=namelist_dict["dt_atmos"],

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Realizing now that we're passing this in twice, once via the namelist and once directly here. Probably outside the scope of this PR to reduce that duplication, but in principle we could add a bit to the wrapper's __init__ that grabs the timestep from the namelist?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. The wrapper could actually be broken a bit more. I am thinking there's "re-usable" parts for any model integration then things that are GEOS. We need more thinking and clean up here

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once I confirm things with one of the NOAA-GFDL github domain managers tomorrow that we are good on the github action front, I'll merge this in.

)
nhalo = 3
shape_centered = (
namelist["nx_tile"] + 2 * nhalo,
Expand Down Expand Up @@ -191,31 +195,33 @@ def test_geos_wrapper():
)
diss_estd = np.ones(shape_centered)

output_dict = wrapper(
u,
v,
w,
delz,
pt,
delp,
q,
ps,
pe,
pk,
peln,
pkz,
phis,
q_con,
omga,
ua,
va,
uc,
vc,
mfxd,
mfyd,
cxd,
cyd,
diss_estd,
timings = {}
output_dict, timings = wrapper(
timings=timings,
u=u,
v=v,
w=w,
delz=delz,
pt=pt,
delp=delp,
q=q,
ps=ps,
pe=pe,
pk=pk,
peln=peln,
pkz=pkz,
phis=phis,
q_con=q_con,
omga=omga,
ua=ua,
va=va,
uc=uc,
vc=vc,
mfxd=mfxd,
mfyd=mfyd,
cxd=cxd,
cyd=cyd,
diss_estd=diss_estd,
)

assert isinstance(output_dict["u"], np.ndarray)
1 change: 1 addition & 0 deletions util/HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ latest
------

- Added f32 support to halo exchange data transformation
- Use one single logger, from logging.py

v0.10.0
-------
Expand Down
2 changes: 1 addition & 1 deletion util/pace/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
from .initialization import GridSizer, QuantityFactory, SubtileGridSizer
from .io import read_state, write_state
from .local_comm import LocalComm
from .logging import pace_log
from .logging import pace_log, AVAILABLE_LOG_LEVELS
from .monitor import Monitor, NetCDFMonitor, ZarrMonitor
from .mpi import MPIComm
from .namelist import Namelist, NamelistDefaults
Expand Down
Loading