Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@elynnwu
Copy link
Collaborator

@elynnwu elynnwu commented Dec 10, 2021

This PR is a prerequisite to moving namelist to driver. The goal for this PR is to 1) remove global config access, 2) share translate class infrastructure, 3) remove dependencies to fv3core in physics tests.

Changes:

  • Move grid, global_config, and corners from fv3core.utils to pace.util.testing and pace.util: global_config is removed from most places and can be deleted soon-ish
  • Move translate and parallel_translate to pace.util.testing: they are shared in dycore and physics
  • Move NamelistDefaults to pace.util.namelist
  • Add PhysicsConfig class: when namelist is moved to the driver, we should add a method to return physics config
  • Add filter in physics savepoint test to only check for physics tests: since the logic checks for every serialized savepoint, pytest also tries to run dycore tests (with no matching test in the physics folder). Adding this avoid checking all serialized savepoints, but future physics test needs to be included here.
  • Pass namelist and stencil_factory down to each savepoint class
  • Remove stencil_facotry from Grid class

elynnwu and others added 27 commits December 7, 2021 11:38
… into stencil externals rather than constants
backend=self.backend,
)

def python_grid(self):
Copy link
Collaborator Author

@elynnwu elynnwu Dec 11, 2021

Choose a reason for hiding this comment

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

All fv3core import in physics test have been removed except for Grid here. Should we make a new classmethod in GridData that makes the class with serialized data? Or should we retain Grid? We also need a new location for either of them.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Grid's main responsibility is to convert serialized data, which may or may not include some number of halos and may or may not be staggered, into standardized storages that all have 3 halos and a compute origin at (3, 3). For this reason, Grid should continue to be used in the test code, and should probably live with the translate infrastructure.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This makes sense, I had thought that we wanted to get rid of Grid all together. If the plan is to keep it alive within the translate infrastructure, I'll go ahead and reshuffle some things.

@elynnwu elynnwu marked this pull request as ready for review December 13, 2021 17:54
Comment on lines 109 to 125
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
Copy link
Collaborator

Choose a reason for hiding this comment

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

namelist_to_flatish_dict should probably go to util since it's used identically in the dycore. This can also live in pace.util.namelist.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Moved to pace.util.namelist

backend=self.backend,
)

def python_grid(self):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Grid's main responsibility is to convert serialized data, which may or may not include some number of halos and may or may not be staggered, into standardized storages that all have 3 halos and a compute origin at (3, 3). For this reason, Grid should continue to be used in the test code, and should probably live with the translate infrastructure.

def process_grid_savepoint(serializer, grid_savepoint, rank, *, backend: str):
grid = make_grid(grid_savepoint, serializer, rank, backend=backend)
fv3core._config.set_grid(grid)
def Grid(serializer, grid_savepoint, rank, layout, *, backend: str):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please use a lowercase name, since this isn't returning a class.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Changed to upper_grid

Comment on lines 276 to 278
grid_rank0 = Grid(
serializer, grid_savepoint, 0, physics_config.layout, backend=backend
)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This variable is unused, you should be able to delete it.

@mcgibbon
Copy link
Collaborator

I’m a little worried that if we duplicate the base translate classes and make small changes, these classes are very complex and may be hard to merge later. Would it be possible to put these in pace.util.testing in a way that both physics and dycore continue to use the same code?

@elynnwu elynnwu changed the title Remove fv3core from physics tests Remove global access in fv3core and physics tests Dec 15, 2021
Copy link
Contributor

@rheacangeo rheacangeo left a comment

Choose a reason for hiding this comment

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

Epic. As discussed, there are some known circular dependencies that come about from this. But we agree, this PR is large enough, and if everything works, we should merge this and make a new story to address those smaller cycles.


fv3core.set_backend(args.backend)
fv3core.set_rebuild(False)
fv3core.set_validate_args(False)
Copy link
Contributor

Choose a reason for hiding this comment

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

Is validate_args False when this script runs now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

great catch, changed to False

from datetime import datetime
from typing import Any, Dict, List, Tuple

import f90nml
Copy link
Contributor

Choose a reason for hiding this comment

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

please before merging make sure you run run_standalone (either login to daint, or do it through the performance test jenkins plan on your branch) so we know it still works.

# references it is updated or removed
grid = spec.make_grid_from_namelist(namelist, rank)

grid = spec.make_grid_from_namelist(dycore_config, rank, args.backend)
Copy link
Contributor

Choose a reason for hiding this comment

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

if this is only referenced by reading serialized input, this could be moved to inside the read_serialized_initial_state method

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

stencil_factory is needed for the baroclinic test case too, so can't be inside read_serialized_initial_state only

Comment on lines 20 to 25
# def test_set_backend():
# start_backend = fv3core.get_backend()
# new_backend = "new_backend"
# assert new_backend != start_backend
# fv3core.set_backend(new_backend)
# assert fv3core.get_backend() == new_backend
Copy link
Contributor

Choose a reason for hiding this comment

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

this can be deleted now?

domain_compute: Index3D,
):
grid = fv3core.utils.grid.GridIndexing(
grid = pace.stencils.testing.grid.GridIndexing(
Copy link
Contributor

Choose a reason for hiding this comment

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

is GridIndexing in pace.dsl or pace.stencils.testing.grid?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It is pace.dsl, updated here and elsewhere

Copy link
Collaborator

@mcgibbon mcgibbon left a comment

Choose a reason for hiding this comment

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

Very nice seeing the test code make direct use of namelist and stencil_factory instead of relying on Grid for everything.

You can leave refactoring pace.stencils.testing.grid for a follow-on PR, but please make a Jira task. It's not great having every stencil file import from testing, since the idea of putting things there is to indicate the stencil code shouldn't be importing from it.

Very few comments for how much you've updated. Great job!

import time

import click
import f90nml
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't know how to evaluate changes to example scripts like this that aren't in CI. We should consider CI-testing all our examples. For now I'll trust you've run this and it works.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, we should add a plan for this. This script was actually broken for a while and we didn't notice.



def set_up_namelist(data_directory: str) -> None:
def set_up_namelist(data_directory: str) -> DynamicalCoreConfig:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you update this function's name and docstring now that it's returning a config and not a namelist? You could name it dycore_config_from_namelist.

Comment on lines 273 to 276
turbulent_kinetic_energy.metadata.gt4py_backend = backend
cloud_fraction.metadata.gt4py_backend = backend
u_tendency.metadata.gt4py_backend = backend
v_tendency.metadata.gt4py_backend = backend
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can pass the gt4py_backend argument when calling Quantity.from_data_array above, instead of overriding it here.

Comment on lines 273 to 276
n_sponge: int = NamelistDefaults.n_sponge

@classmethod
def from_f90nml(cls, namelist: f90nml.Namelist):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Return value type hints for constructors are particularly important/helpful, because they provide type hinting in the place where they're used. For example, this will make mypy check for any typos in attribute accesses on DynamicalCoreConfig in our untested runfiles.

Suggested change
n_sponge: int = NamelistDefaults.n_sponge
@classmethod
def from_f90nml(cls, namelist: f90nml.Namelist):
n_sponge: int = NamelistDefaults.n_sponge
@classmethod
def from_f90nml(cls, namelist: f90nml.Namelist) -> "DynamicalCoreConfig":

with unittest.mock.patch("pace.util.global_config.get_backend", new=error_func):
with unittest.mock.patch(
"fv3core.utils.global_config.is_gpu_backend", new=error_func
"pace.util.global_config.is_gpu_backend", new=error_func
Copy link
Collaborator

Choose a reason for hiding this comment

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

Make sure there's a Jira task to delete pace.util.global_config, if we're no longer using it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's being used in two spots in the main tests. Once we get rid of those, we can delete global_config

def process_grid_savepoint(serializer, grid_savepoint, rank, *, backend: str):
grid = make_grid(grid_savepoint, serializer, rank, backend=backend)
fv3core._config.set_grid(grid)
def upper_grid(serializer, grid_savepoint, rank, layout, *, backend: str):
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is an "upper" grid? Is there a reason for this function when you can directly call make_grid?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It was originally going to be a pytest fixture, but you're right we can just call make_grid directly. Changing this.

@@ -1,2 +0,0 @@
from . import translate_physics
from .translate_physics import TranslatePhysicsFortranData2Py
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why were these removed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Since we no longer need to carry separate translate class infrastructure, we don't need this in physics anymore. If we decide to add TranslatePhysics, it will go here.

Comment on lines 115 to 116
def upper_grid(serializer, grid_savepoint, rank, layout, *, backend: str):
grid = make_grid(grid_savepoint, serializer, rank, layout, backend=backend)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you call make_grid directly?

I'm a little confused by this network of functions (grid_data, grid_indexing, physics_config, etc.). Instead of calling grid_data(grid), should you directly use grid.grid_data in whatever function is calling these?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

They were supposed to be pytest fixtures, but it's easier to make them instead. I forgot to clean up, deleting all these now.

stencil_config = pace.dsl.stencil.StencilConfig(
backend=args.backend,
rebuild=False,
validate_args=True,
Copy link
Contributor

Choose a reason for hiding this comment

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

change to False please

Copy link
Contributor

@rheacangeo rheacangeo left a comment

Choose a reason for hiding this comment

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

Wahoo! I think the Grid object served us well, but good to finalize the shift away from it by untangling the objects we were grabbing from it as an interim step. Lots going on here and this will make many things possible!

Copy link
Collaborator

@mcgibbon mcgibbon left a comment

Choose a reason for hiding this comment

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

Make sure there are the 2 Jira tasks for removing global_config and for moving utilities out of pace.stencils.testing.grid, otherwise looks good to me!

@elynnwu elynnwu merged commit 309408b into main Dec 20, 2021
@elynnwu elynnwu deleted the feature/remove-fv3core-from-physics-test branch December 20, 2021 18:33
twicki pushed a commit to twicki/pace that referenced this pull request Aug 22, 2025
* pace-physics -> pySHiELD

* Removed pySHiELD locally

* Added pySHiELD as submodule

* Updating branch to current versions of NDSL and pyFV3

* Updating pyFV3 and pySHiELD for changes to their setup.py files

* Updated constraints.txt to match new pySHiELD submodule

* Removed local references in constraints.txt

* Update pySHiELD

* lint

* Remove unused mypy

* Bad driver `setup,py`

* Regenerate `constraints.txt`

* Remove local constraints

* Lint

---------

Co-authored-by: Florian Deconinck <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants