-
Notifications
You must be signed in to change notification settings - Fork 7
Add single precision option to the dycore (intermediate state) #970
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
dd41784 to
adcf8fb
Compare
577d435 to
f0d747e
Compare
f0d747e to
5daea04
Compare
|
cscs-ci run default |
egparedes
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks good in general although I have a few comments.
| def interface_physical_height(self) -> fa.KField[wpfloat]: | ||
| return gtx.astype(self._vct_a, wpfloat) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a question: is there are any particular reason why the conversion is done here instead of at initialization in the post_init method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really. When I changed this I think I just wanted to get it to run in single as soon as possible and did not always check for the cleanest way to do things.
You mean I should change lines 144-154 to the following?
def __post_init__(self, vct_a, vct_b):
object.__setattr__(
self,
"_vct_a",
gtx.astype(vct_a, wpfloat),
)
object.__setattr__(
self,
"_vct_b",
gtx.astype(vct_b, wpfloat),
)
I didn't work with dataclasses before and was not aware of __post_int__().
...ere/dycore/src/icon4py/model/atmosphere/dycore/stencils/vertically_implicit_dycore_solver.py
Show resolved
Hide resolved
model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/solve_nonhydro.py
Outdated
Show resolved
Hide resolved
model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/solve_nonhydro.py
Outdated
Show resolved
Hide resolved
model/atmosphere/dycore/tests/dycore/integration_tests/test_velocity_advection.py
Outdated
Show resolved
Hide resolved
model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/velocity_advection.py
Outdated
Show resolved
Hide resolved
model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/velocity_advection.py
Outdated
Show resolved
Hide resolved
| # Check if the --enable-mixed-precision option is set and set the environment variable accordingly | ||
| if config.getoption("--enable-mixed-precision"): | ||
| os.environ["FLOAT_PRECISION"] = "mixed" | ||
| config.addinivalue_line( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: is this marker needed only in a transition phase? Otherwise, why is actually needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that it might be a good idea to be able to have all tests skipped that nobody prepared for single precision. So I suggest using this marker until all tests have suitable tolerances defined for single precision operation.
| from icon4py.model.common.math import smagorinsky | ||
| from icon4py.model.common.model_options import setup_program | ||
| from icon4py.model.common.states import prognostic_state as prognostics | ||
| from icon4py.model.common.type_alias import vpfloat, wpfloat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, why do you import vpfloat, wpfloat explicitly instead of doing the usual way of importing the module type_alias type_alias as ta, and then when you need vpfloat or wpfloat, you just do ta.vpfloat or ta.wpfloat? I think this is the most common way of using vpfloat and wpfloat in icon4py.
Except for some cases in field_operator, for example, broadcast(wpfloat("0.0", (dims.CellDim,))) where you have to use vpfloat or wpfloat directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just saw that in many dycore stencils it was done this way (directly using wpfloat/vpfloat) and in other cases the other. So we already have some kind of inconsistency in the way these types are imported in the repo. I preferred to use the shorter version because I think it looks less cluttered (especially in cases like self.cfl_w_limit: vpfloat = vpfloat(0.65)) and I don't see a lot of descriptive value in the additional ta. (type_alias).
| fourth_order_divdamp_z: wpfloat | float = 32500.0, | ||
| fourth_order_divdamp_z2: wpfloat | float = 40000.0, | ||
| fourth_order_divdamp_z3: wpfloat | float = 60000.0, | ||
| fourth_order_divdamp_z4: wpfloat | float = 80000.0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could it be better with gtx.float64 | gtx.float32?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I first changed it to only using wpfloat which is what the instance variable type is, but because the default arguments are in float, and also because ruff doesn't like function calls like fourth_order_divdamp_z: wpfloat = wpfloat(32500.0) in default arguments, I thought that like this it would show that it can also take native python floats.
In my opinion gtx.float64 | gtx.float32 could almost be a bit misleading.
| dycore_utils._calculate_divdamp_fields( | ||
| self.interpolated_fourth_order_divdamp_factor, | ||
| gtx.int32(self._config.divdamp_order), | ||
| wpfloat(self._grid.global_properties.mean_cell_area), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would rather change instance variables in GlobalGridParams to wpfloat, because these grid properties and other physical constants should have working precision.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, that would be nicer. I don't know how these instances are constructed and where the casts to wpfloat would have to happen. Do you know how this can be done on dataclasses? (Assuming we don't change anything wherever these instances are constructed but just add casts to GlobalGridParams.)
| ) | ||
| from icon4py.model.atmosphere.dycore.stencils.update_wind import _update_wind | ||
| from icon4py.model.common import dimension as dims, field_type_aliases as fa | ||
| from icon4py.model.common.type_alias import vpfloat, wpfloat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you can directly import type_alias from icon4py.model.common import type_alias as ta. Similarly in other places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could, but as stated in my answer on about the same question in solve_nonhydro.py I think it looks less cluttered with a direct import.
| max_nudging_coefficient: float | None = None, # default is set in __init__ | ||
| nudging_decay_rate: float = 2.0, | ||
| thslp_zdiffu: wpfloat | float = 0.025, | ||
| thhgtd_zdiffu: wpfloat | float = 200.0, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly here, is it better with gtx.float64 | gtx.float32? It seems clearer in this way. So I know the initialization of diffusion granule accepts either single or double precision for these parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you think it is clearer? Wouldn't you anyway directly give the respective wpfloat to it (gtx.float64 or gtx.float32 depending on precision)?
Co-authored-by: Enrique González Paredes <enriqueg@cscs.ch>
…con4py into add_single_precision_dycore_part1
|
Mandatory Tests Please make sure you run these tests via comment before you merge!
Optional Tests To run benchmarks you can use:
To run tests and benchmarks with the DaCe backend you can use:
To run test levels ignored by the default test suite (mostly simple datatest for static fields computations) you can use:
For more detailed information please look at CI in the EXCLAIM universe. |
Adds the option to set wp/vpfloat to single via the env var
FLOAT_PRECISION(previous options were 'double' and 'mixed') to run (at least) the dycore in single precision.This PR was created to later reduce merge complexity of #886.
Changes
wpfloatorvpfloatfloatswere present (which are by default passed as gtx.float64 togtx.field_operators andgtx.programs) and add casts around float literalswpfloatorvpfloatand vice versa if found inconsistency with other operators (to hopefully make fixing mixed precision easier in the future)wpfloatandvpfloat(instead of ta.wpfloat -> more concise)DBL_EPSbyWP_EPSandVP_EPSsingle_precision_ready(running a test withFLOAT_PRECISION=singledeselects all tests without)test_velocity_advection.py::test_compute_advection_in_vertical_momentum_equationandtest_apply_diffusion_to_vn.pyto have first two pytests for CI--single-precisionfor CI--enable-mixed-precision(wpfloatorvpfloatare already set according toFLOAT_PRECISIONat import time of a pytest file)TODO
.test_single_precision(default.yml) test to CIcalculate_divdamp_fieldsa compiled program #888) in combination with single precision.