-
Notifications
You must be signed in to change notification settings - Fork 0
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
Py2f parallel #457
base: main
Are you sure you want to change the base?
Py2f parallel #457
Changes from 116 commits
6deda18
5533ffa
90d66a4
a5fc37a
a4addc2
3d92f8a
abededa
2508d58
cb7d497
58a8d50
e08764f
6d4c5b9
d53386f
6576fa6
53be03b
a56b482
8e74d93
d6418d8
fdd89e9
1e75d55
378c583
9776040
474ed4d
d705d5f
6d44838
dad2137
0fa8bd0
d2f5ec3
f5293c8
6284fab
3292041
0d7e6ae
0fa868e
4412b17
9dd4ad0
306d204
eddd5b4
ec54515
8bcca18
a5241bf
03e4045
7e21089
09ef7d4
ded0d4f
a8aa65e
e92923c
e6b453f
ce7169a
378e19c
a7bf60b
47be422
a55c509
0b7afb5
74f9b87
bc8c6db
17fc611
ae733b1
b06ee35
53dda46
d0995e5
e133e75
835c1a3
4718d88
828f030
22563cf
41c7f17
32c0083
6c81409
18fab84
fbdcd07
bfe3b19
f105880
a4c28d3
2a1345d
c8660c5
dffdbc3
eb40203
c272075
6be6136
82515de
06d2a04
ffb27c6
9ea0689
7900cec
07751ec
92e08fc
8619487
aaa39eb
44cf44e
e14ac59
7ee29e7
e0aca5e
fac70b6
0e596fa
f3c49b9
0fd5f10
235dd36
e5c92f2
9eb2828
c5c868b
7c0c592
b3bc385
e4cb5df
29ac395
b090ebb
567f58d
382c82d
f300247
1f92f19
7f3c3d8
629f020
2785040
da1ab2c
6a40ff0
e6be7ba
e744c4d
e54e2ab
196ae94
14b187f
94f9c30
a375271
a0df554
057b79d
546247b
45b1d44
cdb51fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,10 +17,10 @@ | |
from dataclasses import InitVar, dataclass, field | ||
from enum import Enum | ||
from typing import Final, Optional | ||
|
||
from gt4py.next import as_field | ||
from gt4py.next.common import Dimension | ||
from gt4py.next.ffront.fbuiltins import Field, int32 | ||
from icon4py.model.common.decomposition.definitions import DecompositionInfo | ||
|
||
from icon4py.model.atmosphere.diffusion.diffusion_states import ( | ||
DiffusionDiagnosticState, | ||
|
@@ -297,7 +297,7 @@ def __post_init__(self, config): | |
object.__setattr__( | ||
self, | ||
"scaled_nudge_max_coeff", | ||
config.nudge_max_coeff * DEFAULT_PHYSICS_DYNAMICS_TIMESTEP_RATIO, | ||
config.nudge_max_coeff, | ||
) | ||
|
||
def _determine_smagorinski_factor(self, config: DiffusionConfig): | ||
|
@@ -370,6 +370,9 @@ def __init__(self, exchange: ExchangeRuntime = SingleNodeExchange()): | |
self.cell_params: Optional[CellParams] = None | ||
self._horizontal_start_index_w_diffusion: int32 = 0 | ||
|
||
def set_exchange(self, exchange): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you really need to set this and make it mutable? In general, we should discuss if there is a way that your granule interfacing works with having the distinction between the |
||
self._exchange = exchange | ||
|
||
def init( | ||
self, | ||
grid: IconGrid, | ||
|
@@ -547,9 +550,9 @@ def _sync_cell_fields(self, prognostic_state): | |
log.debug("communication of prognostic cell fields: theta, w, exner - start") | ||
self._exchange.exchange_and_wait( | ||
CellDim, | ||
prognostic_state.w, | ||
prognostic_state.theta_v, | ||
prognostic_state.exner, | ||
prognostic_state.w.ndarray[0 : self.grid.num_cells, :], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you try to get rid of this slices and it did not work. Do you know why or what did not work? We should try to figure this out and handle it differently it is very error prone like this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the explicit bounds are needed we could try to push it inside |
||
prognostic_state.theta_v.ndarray[0 : self.grid.num_cells, :], | ||
prognostic_state.exner.ndarray[0 : self.grid.num_cells, :], | ||
) | ||
log.debug("communication of prognostic cell fields: theta, w, exner - done") | ||
|
||
|
@@ -605,7 +608,21 @@ def _do_diffusion_step( | |
vertex_end_local = self.grid.get_end_index( | ||
VertexDim, HorizontalMarkerIndex.local(VertexDim) | ||
) | ||
|
||
vertex_end_halo = self.grid.get_end_index(VertexDim, HorizontalMarkerIndex.halo(VertexDim)) | ||
|
||
loc_rank = self._exchange.my_rank() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. either delete the log statements, or keep them but not commented out. You can switch it off globally. |
||
# log.debug("cell_start_interior for rank",loc_rank," is ..",cell_start_interior) | ||
# log.debug("cell_start_nudging for rank", loc_rank, " is ..", cell_start_nudging) | ||
# log.debug("cell_end_local for rank", loc_rank, " is ..", cell_end_local) | ||
# log.debug("cell_end_halo for rank", loc_rank, " is ..", cell_end_halo) | ||
# log.debug("edge_start_nudging_plus_one for rank", loc_rank, " is ..", edge_start_nudging_plus_one) | ||
# log.debug("edge_start_lb_plus4 for rank", loc_rank, " is ..", edge_start_lb_plus4) | ||
# log.debug("edge_end_local for rank", loc_rank, " is ..", edge_end_local) | ||
# log.debug("edge_end_local_minus2 for rank", loc_rank, " is ..", edge_end_local_minus2) | ||
# log.debug("edge_end_halo for rank", loc_rank, " is ..", edge_end_halo) | ||
# log.debug("vertex_start_lb_plus1 for rank", loc_rank, " is ..", vertex_start_lb_plus1) | ||
# log.debug("vertex_end_local for rank", loc_rank, " is ..", vertex_end_local) | ||
# log.debug("vertex_end_halo for rank", loc_rank, " is ..", vertex_end_halo) | ||
# dtime dependent: enh_smag_factor, | ||
scale_k(self.enh_smag_fac, dtime, self.diff_multfac_smag, offset_provider={}) | ||
|
||
|
@@ -624,10 +641,36 @@ def _do_diffusion_step( | |
) | ||
log.debug("rbf interpolation 1: end") | ||
|
||
# loc_ind_verts=self._exchange._decomposition_info.local_index(VertexDim,DecompositionInfo.EntryType.HALO) | ||
# log.debug("loc_ind_verts rank %s", loc_rank, " loc_ind_verts: %s",loc_ind_verts," shape: %s",loc_ind_verts.shape) | ||
# log.debug("after rbf rank %s", loc_rank, " u_vert max: %s min: %s", | ||
# xp.max(self.u_vert.ndarray[vertex_start_lb_plus1:vertex_end_local, 0:klevels]), | ||
# xp.min(self.u_vert.ndarray[vertex_start_lb_plus1:vertex_end_local, 0:klevels])) | ||
# 2. HALO EXCHANGE -- CALL sync_patch_array_mult u_vert and v_vert | ||
# log.debug("halo....after rbf rank %s", loc_rank, " u_vert max: %s min: %s", | ||
# self.u_vert.ndarray[loc_ind_verts, 0], | ||
# self.u_vert.ndarray[loc_ind_verts, 0]) | ||
log.debug("communication rbf extrapolation of vn - start") | ||
self._exchange.exchange_and_wait(VertexDim, self.u_vert, self.v_vert) | ||
log.debug( | ||
"size of u_vert %s v_vert %s", self.u_vert.ndarray.shape, self.v_vert.ndarray.shape | ||
) | ||
log.debug( | ||
"edge_start_lb_plus4 %s edge_end_local_minus2 %s", | ||
edge_start_lb_plus4, | ||
edge_end_local_minus2, | ||
) | ||
self._exchange.exchange_and_wait( | ||
VertexDim, | ||
self.u_vert.ndarray[0 : self.grid.num_vertices, :], | ||
self.v_vert.ndarray[0 : self.grid.num_vertices, :], | ||
) | ||
log.debug("communication rbf extrapolation of vn - end") | ||
# log.debug("after exchange rank %s", loc_rank, " u_vert max: %s min: %s", | ||
# xp.max(self.u_vert.ndarray[vertex_start_lb_plus1:vertex_end_local, 0:klevels]), | ||
# xp.min(self.u_vert.ndarray[vertex_start_lb_plus1:vertex_end_local, 0:klevels])) | ||
# log.debug("halo....after exchange rank %s", loc_rank, " u_vert max: %s min: %s", | ||
# self.u_vert.ndarray[loc_ind_verts, 0], | ||
# self.u_vert.ndarray[loc_ind_verts, 0]) | ||
|
||
log.debug("running stencil 01(calculate_nabla2_and_smag_coefficients_for_vn): start") | ||
calculate_nabla2_and_smag_coefficients_for_vn( | ||
|
@@ -682,10 +725,18 @@ def _do_diffusion_step( | |
|
||
# HALO EXCHANGE IF (discr_vn > 1) THEN CALL sync_patch_array | ||
# TODO (magdalena) move this up and do asynchronous exchange | ||
# loc_ind_edges=self._exchange._decomposition_info.local_index(EdgeDim,DecompositionInfo.EntryType.HALO) | ||
# log.debug("loc_ind_edges rank %s", loc_rank, " loc_ind_edges: %s",loc_ind_edges," shape: %s",loc_ind_edges.shape) | ||
# log.debug("halo..z_nabla2_e..before exchange rank %s", loc_rank, " z_nabla2_e: %s", | ||
# self.z_nabla2_e.ndarray[loc_ind_verts, 0]) | ||
if self.config.type_vn_diffu > 1: | ||
log.debug("communication rbf extrapolation of z_nable2_e - start") | ||
self._exchange.exchange_and_wait(EdgeDim, self.z_nabla2_e) | ||
self._exchange.exchange_and_wait( | ||
EdgeDim, self.z_nabla2_e.ndarray[0 : self.grid.num_edges, :] | ||
) | ||
log.debug("communication rbf extrapolation of z_nable2_e - end") | ||
# log.debug("halo..z_nabla2_e..after exchange rank %s", loc_rank, " z_nabla2_e: %s", | ||
# self.z_nabla2_e.ndarray[loc_ind_verts, 0]) | ||
|
||
log.debug("2nd rbf interpolation: start") | ||
mo_intp_rbf_rbf_vec_interpol_vertex( | ||
|
@@ -703,9 +754,19 @@ def _do_diffusion_step( | |
log.debug("2nd rbf interpolation: end") | ||
|
||
# 6. HALO EXCHANGE -- CALL sync_patch_array_mult (Vertex Fields) | ||
# log.debug("halo....after 2nd... rbf rank %s", loc_rank, " u_vert %s", | ||
# self.u_vert.ndarray[loc_ind_verts, 0], " v_vert:", | ||
# self.u_vert.ndarray[loc_ind_verts, 0]) | ||
log.debug("communication rbf extrapolation of z_nable2_e - start") | ||
self._exchange.exchange_and_wait(VertexDim, self.u_vert, self.v_vert) | ||
self._exchange.exchange_and_wait( | ||
VertexDim, | ||
self.u_vert.ndarray[0 : self.grid.num_vertices, :], | ||
self.v_vert.ndarray[0 : self.grid.num_vertices, :], | ||
) | ||
log.debug("communication rbf extrapolation of z_nable2_e - end") | ||
# log.debug("halo....after 2nd... after exchange rank %s", loc_rank, " u_vert %s", | ||
# self.u_vert.ndarray[loc_ind_verts, 0], " v_vert:", | ||
# self.u_vert.ndarray[loc_ind_verts, 0]) | ||
|
||
log.debug("running stencils 04 05 06 (apply_diffusion_to_vn): start") | ||
apply_diffusion_to_vn( | ||
|
@@ -734,7 +795,14 @@ def _do_diffusion_step( | |
) | ||
log.debug("running stencils 04 05 06 (apply_diffusion_to_vn): end") | ||
log.debug("communication of prognistic.vn : start") | ||
handle_edge_comm = self._exchange.exchange(EdgeDim, prognostic_state.vn) | ||
# log.debug("halo..vn..before exchange rank %s", loc_rank, " vn: %s", | ||
# prognostic_state.vn.ndarray[loc_ind_verts, 0]) | ||
handle_edge_comm = self._exchange.exchange( | ||
EdgeDim, prognostic_state.vn.ndarray[0 : self.grid.num_edges, :] | ||
) | ||
# handle_edge_comm = self._exchange.exchange_and_wait(EdgeDim, prognostic_state.vn.ndarray[0:self.grid.num_edges,:]) | ||
# log.debug("halo..vn..after exchange rank %s", loc_rank, " vn: %s", | ||
# prognostic_state.vn.ndarray[loc_ind_verts, 0]) | ||
|
||
log.debug( | ||
"running stencils 07 08 09 10 (apply_diffusion_to_w_and_compute_horizontal_gradients_for_turbulence): start" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,27 +21,29 @@ | |
from gt4py.next import Dimension, Field | ||
|
||
from icon4py.model.common.decomposition.definitions import SingleNodeExchange | ||
|
||
|
||
try: | ||
import ghex | ||
import mpi4py | ||
from ghex.context import make_context | ||
from ghex.unstructured import ( | ||
DomainDescriptor, | ||
HaloGenerator, | ||
make_communication_object, | ||
make_field_descriptor, | ||
make_pattern, | ||
) | ||
|
||
mpi4py.rc.initialize = False | ||
mpi4py.rc.finalize = True | ||
|
||
except ImportError: | ||
mpi4py = None | ||
ghex = None | ||
unstructured = None | ||
from icon4py.model.common.settings import device | ||
|
||
|
||
#try: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this removes ghex and mpi4py being optional dependencies, that is you can run icon4py even if you don't have those library installed. We should keep that feature imho. |
||
import ghex | ||
import mpi4py | ||
from ghex.context import make_context | ||
from ghex.unstructured import ( | ||
DomainDescriptor, | ||
HaloGenerator, | ||
make_communication_object, | ||
make_field_descriptor, | ||
make_pattern, | ||
) | ||
from ghex.util import Architecture | ||
|
||
mpi4py.rc.initialize = False | ||
mpi4py.rc.finalize = True | ||
|
||
# except ImportError: | ||
# mpi4py = None | ||
# ghex = None | ||
# unstructured = None | ||
|
||
from icon4py.model.common.decomposition import definitions | ||
from icon4py.model.common.dimension import CellDim, DimensionKind, EdgeDim, VertexDim | ||
|
@@ -51,6 +53,11 @@ | |
import mpi4py.MPI | ||
|
||
|
||
if device.name == "GPU": | ||
ghex_arch = Architecture.GPU | ||
else: | ||
ghex_arch = Architecture.CPU | ||
|
||
CommId = Union[int, "mpi4py.MPI.Comm", None] | ||
log = logging.getLogger(__name__) | ||
|
||
|
@@ -100,8 +107,10 @@ def filter(self, record: logging.LogRecord) -> bool: | |
|
||
|
||
@definitions.get_processor_properties.register(definitions.MultiNodeRun) | ||
def get_multinode_properties(s: definitions.MultiNodeRun) -> definitions.ProcessProperties: | ||
return _get_processor_properties(with_mpi=True) | ||
def get_multinode_properties( | ||
s: definitions.MultiNodeRun, comm_id: CommId = None | ||
) -> definitions.ProcessProperties: | ||
return _get_processor_properties(with_mpi=True, comm_id=comm_id) | ||
|
||
|
||
@dataclass(frozen=True) | ||
|
@@ -202,15 +211,16 @@ def exchange(self, dim: definitions.Dimension, *fields: Sequence[Field]): | |
domain_descriptor = self._domain_descriptors[dim] | ||
assert domain_descriptor is not None, f"domain descriptor for {dim.value} not found" | ||
applied_patterns = [ | ||
pattern(make_field_descriptor(domain_descriptor, f.asnumpy())) for f in fields | ||
pattern(make_field_descriptor(domain_descriptor, f, arch=ghex_arch)) for f in fields | ||
] | ||
handle = self._comm.exchange(applied_patterns) | ||
log.info(f"exchange for {len(fields)} fields of dimension ='{dim.value}' initiated.") | ||
log.debug(f"exchange for {len(fields)} fields of dimension ='{dim.value}' initiated.") | ||
return MultiNodeResult(handle, applied_patterns) | ||
|
||
def exchange_and_wait(self, dim: Dimension, *fields: tuple): | ||
res = self.exchange(dim, *fields) | ||
res.wait() | ||
log.debug(f"exchange for {len(fields)} fields of dimension ='{dim.value}' done.") | ||
|
||
|
||
@dataclass | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,13 @@ | |
EdgeDim = Dimension("Edge") | ||
CellDim = Dimension("Cell") | ||
VertexDim = Dimension("Vertex") | ||
SingletonDim = Dimension("Singleton") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what do you need those for? Could you move them it to py2fgen? Whatever has something to do with only the interfacing to fortran should go to |
||
SpecialADim = Dimension("SpecialA") | ||
SpecialBDim = Dimension("SpecialB") | ||
SpecialCDim = Dimension("SpecialC") | ||
CellIndexDim = Dimension("CellIndex") | ||
EdgeIndexDim = Dimension("EdgeIndex") | ||
VertexIndexDim = Dimension("VertexIndex") | ||
CEDim = Dimension("CE") | ||
CECDim = Dimension("CEC") | ||
ECDim = Dimension("EC") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -163,13 +163,6 @@ def end(cls, dim: Dimension) -> int: | |
return cls._end[dim] | ||
|
||
|
||
@dataclass(frozen=True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks for cleaning up... |
||
class HorizontalGridSize: | ||
num_vertices: int | ||
num_edges: int | ||
num_cells: int | ||
|
||
|
||
class EdgeParams: | ||
def __init__( | ||
self, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,6 @@ | |
# | ||
# SPDX-License-Identifier: GPL-3.0-or-later | ||
|
||
import numpy as np | ||
from gt4py.next import Dimension, NeighborTableOffsetProvider | ||
|
||
from icon4py.model.common.settings import xp | ||
|
@@ -23,7 +22,8 @@ def neighbortable_offset_provider_for_1d_sparse_fields( | |
neighbor_axis: Dimension, | ||
has_skip_values: bool, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what do you need the |
||
): | ||
table = xp.asarray(np.arange(old_shape[0] * old_shape[1]).reshape(old_shape)) | ||
|
||
table = xp.asarray(xp.arange(old_shape[0] * old_shape[1]).reshape(old_shape)) | ||
return NeighborTableOffsetProvider( | ||
table, | ||
origin_axis, | ||
|
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.
Can you add a comment here saying that ICON already scales this by 5, and that therefore it is the responsibility of the user to set
nudge_max_coeff
accordingly