From 6f6a46070406e99365610c1009e9a962840b9d0c Mon Sep 17 00:00:00 2001 From: Samuel Date: Fri, 12 Apr 2024 13:09:04 +0200 Subject: [PATCH] [py2fgen]: support for Fortran granules (#402) feat: Enable GT4Py backend support and integrate Python diffusion module into ICON-DSL - Added GT4Py backend support for both CPU and GPU platforms. - Automated binding generation for embedding Python functions and GT4Py in Fortran. Co-authored-by: abishekg7 <56273301+abishekg7@users.noreply.github.com> --- .github/workflows/icon4py-qa.yml | 3 +- .gitignore | 5 + .../model/atmosphere/diffusion/diffusion.py | 11 +- .../atmosphere/diffusion/diffusion_states.py | 4 +- .../atmosphere/diffusion/diffusion_utils.py | 9 +- .../apply_diffusion_to_theta_and_exner.py | 2 +- .../stencils/apply_diffusion_to_vn.py | 2 +- ...ute_horizontal_gradients_for_turbulence.py | 2 +- .../apply_nabla2_and_nabla4_global_to_vn.py | 2 +- .../stencils/apply_nabla2_and_nabla4_to_vn.py | 2 +- .../apply_nabla2_to_vn_in_lateral_boundary.py | 2 +- .../diffusion/stencils/apply_nabla2_to_w.py | 2 +- ...pply_nabla2_to_w_in_upper_damping_layer.py | 2 +- ...te_diagnostic_quantities_for_turbulence.py | 2 +- .../calculate_diagnostics_for_turbulence.py | 2 +- ..._coefficients_for_grid_point_cold_pools.py | 2 +- ...ate_horizontal_gradients_for_turbulence.py | 2 +- ...ate_nabla2_and_smag_coefficients_for_vn.py | 2 +- .../stencils/calculate_nabla2_for_theta.py | 2 +- .../stencils/calculate_nabla2_for_w.py | 2 +- .../stencils/calculate_nabla2_for_z.py | 2 +- .../stencils/calculate_nabla2_of_theta.py | 2 +- .../diffusion/stencils/calculate_nabla4.py | 2 +- ...n_coefficient_for_grid_point_cold_pools.py | 2 +- ...d_for_grid_point_cold_pools_enhancement.py | 2 +- ...orary_fields_for_turbulence_diagnostics.py | 2 +- ...fusion_nabla_of_theta_over_steep_points.py | 2 +- .../stencils/update_theta_and_exner.py | 2 +- .../tests/diffusion_tests/test_diffusion.py | 2 +- .../diffusion_tests/test_diffusion_utils.py | 2 +- .../dycore/accumulate_prep_adv_fields.py | 2 +- ...lysis_increments_from_data_assimilation.py | 2 +- .../dycore/add_analysis_increments_to_vn.py | 2 +- ...tra_diffusion_for_w_con_approaching_cfl.py | 2 +- ..._extra_diffusion_for_wn_approaching_cfl.py | 2 +- ..._interpolated_horizontal_advection_of_w.py | 2 +- .../dycore/add_temporal_tendencies_to_vn.py | 2 +- ...vn_by_interpolating_between_time_levels.py | 2 +- ...l_wind_derivative_to_divergence_damping.py | 2 +- .../apply_2nd_order_divergence_damping.py | 2 +- .../apply_4th_order_divergence_damping.py | 2 +- ...o_horizontal_gradient_of_exner_pressure.py | 2 +- .../apply_rayleigh_damping_mechanism.py | 2 +- ...ed_2nd_and_4th_order_divergence_damping.py | 2 +- .../compute_advective_normal_wind_tendency.py | 2 +- ...ompute_advective_vertical_wind_tendency.py | 2 +- .../atmosphere/dycore/compute_airmass.py | 2 +- ...rox_of_2nd_vertical_derivative_of_exner.py | 2 +- .../model/atmosphere/dycore/compute_avg_vn.py | 2 +- .../compute_avg_vn_and_graddiv_vn_and_vt.py | 2 +- .../compute_contravariant_correction.py | 2 +- .../compute_contravariant_correction_of_w.py | 2 +- ...iant_correction_of_w_for_lower_boundary.py | 2 +- ...e_divergence_of_fluxes_of_rho_and_theta.py | 2 +- .../compute_dwdz_for_divergence_damping.py | 2 +- .../dycore/compute_exner_from_rhotheta.py | 2 +- ...compute_explicit_part_for_rho_and_exner.py | 2 +- ...rom_advection_and_vertical_wind_density.py | 2 +- ...d_speed_and_vertical_wind_times_density.py | 2 +- .../compute_first_vertical_derivative.py | 2 +- .../dycore/compute_graddiv2_of_vn.py | 2 +- ...e_horizontal_advection_of_rho_and_theta.py | 2 +- ...al_advection_term_for_vertical_velocity.py | 2 +- ..._of_exner_pressure_for_flat_coordinates.py | 2 +- ..._exner_pressure_for_nonflat_coordinates.py | 2 +- ..._of_extner_pressure_for_multiple_levels.py | 2 +- .../compute_horizontal_kinetic_energy.py | 2 +- .../compute_hydrostatic_correction_term.py | 2 +- .../atmosphere/dycore/compute_mass_flux.py | 2 +- ...nd_clip_contravariant_vertical_velocity.py | 2 +- .../compute_pertubation_of_rho_and_theta.py | 2 +- ...tubation_of_rho_and_theta_and_rho_at_ic.py | 2 +- ...ute_results_for_thermodynamic_variables.py | 2 +- ...tial_temperatures_and_pressure_gradient.py | 2 +- .../compute_solver_coefficients_matrix.py | 2 +- .../dycore/compute_tangential_wind.py | 2 +- .../dycore/compute_theta_and_exner.py | 2 +- ...tial_temperatures_and_pressure_gradient.py | 2 +- .../dycore/compute_vn_on_lateral_boundary.py | 2 +- .../dycore/copy_cell_kdim_field_to_vp.py | 2 +- ...correct_contravariant_vertical_velocity.py | 2 +- .../atmosphere/dycore/extrapolate_at_top.py | 2 +- .../extrapolate_temporally_exner_pressure.py | 2 +- .../fused_solve_nonhydro_stencil_39_40.py | 2 +- ...sed_velocity_advection_stencil_15_to_18.py | 2 +- ...sed_velocity_advection_stencil_19_to_20.py | 2 +- ...fused_velocity_advection_stencil_1_to_7.py | 2 +- ...used_velocity_advection_stencil_8_to_13.py | 2 +- ...used_velocity_advection_stencil_8_to_14.py | 2 +- ...tiant_vertical_verlocity_to_full_levels.py | 2 +- .../dycore/interpolate_to_cell_center.py | 2 +- .../dycore/interpolate_to_half_levels_vp.py | 2 +- .../dycore/interpolate_to_surface.py | 2 +- ..._and_vt_to_ie_and_compute_ekin_on_edges.py | 2 +- ...late_vn_to_ie_and_compute_ekin_on_edges.py | 2 +- .../atmosphere/dycore/interpolate_vt_to_ie.py | 2 +- ...lation_scalar_cells2verts_scalar_ri_dsl.py | 2 +- .../mo_math_divrot_rot_vertex_ri_dsl.py | 2 +- ...ath_gradients_grad_green_gauss_cell_dsl.py | 2 +- .../dycore/mo_solve_nonhydro_stencil_51.py | 2 +- .../dycore/nh_solve/solve_nonhydro.py | 2 +- .../dycore/nh_solve/solve_nonhydro_program.py | 2 +- .../dycore/set_cell_kdim_field_to_zero_vp.py | 2 +- .../dycore/set_cell_kdim_field_to_zero_wp.py | 2 +- ...tion_for_w_and_contravariant_correction.py | 2 +- .../set_theta_v_prime_ic_at_lower_boundary.py | 2 +- ...t_two_cell_kdim_fields_index_to_zero_vp.py | 2 +- .../set_two_cell_kdim_fields_to_zero_vp.py | 2 +- .../set_two_cell_kdim_fields_to_zero_wp.py | 2 +- .../set_two_edge_kdim_fields_to_zero_wp.py | 2 +- ...diagonal_matrix_for_w_back_substitution.py | 2 +- ..._tridiagonal_matrix_for_w_forward_sweep.py | 2 +- .../atmosphere/dycore/state_utils/utils.py | 2 +- .../dycore/update_densety_exener_wind.py | 2 +- .../update_dynamical_exner_time_increment.py | 2 +- .../dycore/update_mass_flux_weighted.py | 2 +- .../dycore/update_mass_volume_flux.py | 2 +- .../model/atmosphere/dycore/update_theta_v.py | 2 +- .../model/atmosphere/dycore/update_wind.py | 2 +- .../velocity/velocity_advection_program.py | 2 +- .../tests/dycore_tests/test_solve_nonhydro.py | 2 +- .../dycore/tests/dycore_tests/test_utils.py | 2 +- .../common/src/icon4py/model/common/config.py | 71 ++++ .../src/icon4py/model/common/grid/vertical.py | 7 +- .../mo_intp_rbf_rbf_vec_interpol_vertex.py | 2 +- .../icon4py/model/common/math/smagorinsky.py | 2 +- .../common/{model_backend.py => settings.py} | 16 +- .../model/common/states/prognostic_state.py | 2 +- .../model/common/test_utils/helpers.py | 4 +- tools/README.md | 66 +++- tools/pyproject.toml | 4 +- tools/src/icon4pytools/py2fgen/cffi.py | 116 ------ tools/src/icon4pytools/py2fgen/cli.py | 55 +-- tools/src/icon4pytools/py2fgen/generate.py | 13 +- tools/src/icon4pytools/py2fgen/parsing.py | 90 +++-- tools/src/icon4pytools/py2fgen/plugin.py | 182 +++++++++ tools/src/icon4pytools/py2fgen/template.py | 350 ++++++++++++++---- tools/src/icon4pytools/py2fgen/utils.py | 56 +-- .../py2fgen/wrappers/diffusion.py | 332 ++++++++--------- .../icon4pytools/py2fgen/wrappers/simple.py | 7 + .../fortran_samples/test_diffusion.f90 | 331 +++++++++++++++++ .../fortran_samples/test_multi_return.f90 | 155 ++++---- .../py2fgen/fortran_samples/test_square.f90 | 142 +++---- tools/tests/py2fgen/test_cffi.py | 80 +++- tools/tests/py2fgen/test_cli.py | 174 +++++++-- tools/tests/py2fgen/test_codegen.py | 284 ++++++++++++-- tools/tests/py2fgen/test_diffusion_wrapper.py | 219 +++++++++++ tools/tests/py2fgen/test_parsing.py | 43 ++- tools/tox.ini | 2 +- 149 files changed, 2234 insertions(+), 837 deletions(-) create mode 100644 model/common/src/icon4py/model/common/config.py rename model/common/src/icon4py/model/common/{model_backend.py => settings.py} (65%) delete mode 100644 tools/src/icon4pytools/py2fgen/cffi.py create mode 100644 tools/src/icon4pytools/py2fgen/plugin.py create mode 100644 tools/tests/py2fgen/fortran_samples/test_diffusion.f90 create mode 100644 tools/tests/py2fgen/test_diffusion_wrapper.py diff --git a/.github/workflows/icon4py-qa.yml b/.github/workflows/icon4py-qa.yml index e40d32042b..4dbcdd3541 100644 --- a/.github/workflows/icon4py-qa.yml +++ b/.github/workflows/icon4py-qa.yml @@ -29,8 +29,7 @@ jobs: **/base-requirements-dev.txt **/requirements.txt **/requirements-dev.txt - - name: Install icon4py-model packages - working-directory: model + - name: Install all icon4py namespace packages run: | python -m pip install --upgrade pip setuptools wheel python -m pip install -r ./requirements-dev.txt diff --git a/.gitignore b/.gitignore index 3c5a2f48dc..9cf32d256d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# nvidia +*.ncu-rep + + ### Custom #### _build _local @@ -7,6 +11,7 @@ tmp testdata simple_mesh*.nc /prof +.profile ### GT4Py #### .gt_cache/ diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion.py index 85c6b8c30a..ac9a332aaa 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion.py @@ -18,7 +18,6 @@ from enum import Enum from typing import Final, Optional -import numpy as np from gt4py.next import as_field from gt4py.next.common import Dimension from gt4py.next.ffront.fbuiltins import Field, int32 @@ -73,8 +72,7 @@ mo_intp_rbf_rbf_vec_interpol_vertex, ) from icon4py.model.common.states.prognostic_state import PrognosticState -from icon4py.model.common.model_backend import backend - +from icon4py.model.common.settings import xp """ Diffusion module ported from ICON mo_nh_diffusion.f90. @@ -257,9 +255,6 @@ def _validate(self): self.apply_to_temperature = False self.apply_to_horizontal_wind = False self.apply_to_vertical_wind = False - else: - self.apply_to_temperature = True - self.apply_to_horizontal_wind = True if self.shear_type not in ( TurbulenceShearForcingType.VERTICAL_OF_HORIZONTAL_WIND, @@ -474,7 +469,7 @@ def _allocate(*dims: Dimension): def _index_field(dim: Dimension, size=None): size = size if size else self.grid.size[dim] - return as_field((dim,), np.arange(size, dtype=int32)) + return as_field((dim,), xp.arange(size, dtype=int32)) self.diff_multfac_vn = _allocate(KDim) @@ -492,7 +487,7 @@ def _index_field(dim: Dimension, size=None): self.horizontal_cell_index = _index_field(CellDim) self.horizontal_edge_index = _index_field(EdgeDim) self.w_tmp = as_field( - (CellDim, KDim), np.zeros((self.grid.num_cells, self.grid.num_levels + 1), dtype=float) + (CellDim, KDim), xp.zeros((self.grid.num_cells, self.grid.num_levels + 1), dtype=float) ) def initial_run( diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion_states.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion_states.py index 96f3be04f9..87db9252fc 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion_states.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion_states.py @@ -88,11 +88,11 @@ class DiffusionInterpolationState: @functools.cached_property def geofac_n2s_c(self) -> Field[[CellDim], float]: - return as_field((CellDim,), data=self.geofac_n2s.asnumpy()[:, 0]) + return as_field((CellDim,), data=self.geofac_n2s.ndarray[:, 0]) @functools.cached_property def geofac_n2s_nbh(self) -> Field[[CECDim], float]: - geofac_nbh_ar = self.geofac_n2s.asnumpy()[:, 1:] + geofac_nbh_ar = self.geofac_n2s.ndarray[:, 1:] old_shape = geofac_nbh_ar.shape return as_field( (CECDim,), diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion_utils.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion_utils.py index 523b8e951c..94e23cc0aa 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion_utils.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/diffusion_utils.py @@ -12,7 +12,6 @@ # SPDX-License-Identifier: GPL-3.0-or-later from typing import Tuple -import numpy as np from gt4py.next import as_field from gt4py.next.common import Dimension, Field, GridType from gt4py.next.ffront.decorator import field_operator, program @@ -20,13 +19,13 @@ from icon4py.model.common.dimension import CellDim, EdgeDim, KDim, VertexDim from icon4py.model.common.math.smagorinsky import _en_smag_fac_for_zero_nshift -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend, xp # TODO(Magdalena): fix duplication: duplicated from test testutils/utils.py def zero_field(grid, *dims: Dimension, dtype=float): shapex = tuple(map(lambda x: grid.size[x], dims)) - return as_field(dims, np.zeros(shapex, dtype=dtype)) + return as_field(dims, xp.zeros(shapex, dtype=dtype)) @field_operator @@ -186,8 +185,8 @@ def init_nabla2_factor_in_upper_damping_zone( physcial_heights: vector of physical heights [m] of the height levels """ # TODO(Magdalena): fix with as_offset in gt4py - heights = physical_heights.asnumpy() - buffer = np.zeros(k_size) + heights = physical_heights.ndarray + buffer = xp.zeros(k_size) buffer[1 : nrdmax + 1] = ( 1.0 / 12.0 diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_diffusion_to_theta_and_exner.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_diffusion_to_theta_and_exner.py index 541f3a50ef..08bfcc8af1 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_diffusion_to_theta_and_exner.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_diffusion_to_theta_and_exner.py @@ -28,7 +28,7 @@ _update_theta_and_exner, ) from icon4py.model.common.dimension import CECDim, CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_diffusion_to_vn.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_diffusion_to_vn.py index 2eda98d777..591d1605d2 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_diffusion_to_vn.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_diffusion_to_vn.py @@ -25,7 +25,7 @@ ) from icon4py.model.atmosphere.diffusion.stencils.calculate_nabla4 import _calculate_nabla4 from icon4py.model.common.dimension import ECVDim, EdgeDim, KDim, VertexDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_diffusion_to_w_and_compute_horizontal_gradients_for_turbulence.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_diffusion_to_w_and_compute_horizontal_gradients_for_turbulence.py index d4160e460a..8dd62df576 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_diffusion_to_w_and_compute_horizontal_gradients_for_turbulence.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_diffusion_to_w_and_compute_horizontal_gradients_for_turbulence.py @@ -26,7 +26,7 @@ _calculate_nabla2_for_w, ) from icon4py.model.common.dimension import C2E2CODim, CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_and_nabla4_global_to_vn.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_and_nabla4_global_to_vn.py index 6da0a1fee8..e6e23155e0 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_and_nabla4_global_to_vn.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_and_nabla4_global_to_vn.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_and_nabla4_to_vn.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_and_nabla4_to_vn.py index 43c65ca23a..f3c76a6713 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_and_nabla4_to_vn.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_and_nabla4_to_vn.py @@ -15,7 +15,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, broadcast, int32, maximum from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_to_vn_in_lateral_boundary.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_to_vn_in_lateral_boundary.py index f8750138c5..c46da23269 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_to_vn_in_lateral_boundary.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_to_vn_in_lateral_boundary.py @@ -15,7 +15,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_to_w.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_to_w.py index 0503f3cbcc..1361c914d2 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_to_w.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_to_w.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import C2E2CO, C2E2CODim, CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_to_w_in_upper_damping_layer.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_to_w_in_upper_damping_layer.py index 1efa53ff05..9c2c854925 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_to_w_in_upper_damping_layer.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/apply_nabla2_to_w_in_upper_damping_layer.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, broadcast, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_diagnostic_quantities_for_turbulence.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_diagnostic_quantities_for_turbulence.py index 0aa4a4feb2..000764f073 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_diagnostic_quantities_for_turbulence.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_diagnostic_quantities_for_turbulence.py @@ -22,7 +22,7 @@ _temporary_fields_for_turbulence_diagnostics, ) from icon4py.model.common.dimension import CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_diagnostics_for_turbulence.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_diagnostics_for_turbulence.py index 4a0721e5d7..9dd4f5d307 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_diagnostics_for_turbulence.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_diagnostics_for_turbulence.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_enhanced_diffusion_coefficients_for_grid_point_cold_pools.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_enhanced_diffusion_coefficients_for_grid_point_cold_pools.py index 4aea5bf44e..afb3b45cd3 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_enhanced_diffusion_coefficients_for_grid_point_cold_pools.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_enhanced_diffusion_coefficients_for_grid_point_cold_pools.py @@ -22,7 +22,7 @@ _temporary_field_for_grid_point_cold_pools_enhancement, ) from icon4py.model.common.dimension import CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_horizontal_gradients_for_turbulence.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_horizontal_gradients_for_turbulence.py index 7e9bacab61..84965b3f61 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_horizontal_gradients_for_turbulence.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_horizontal_gradients_for_turbulence.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import C2E2CO, C2E2CODim, CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_and_smag_coefficients_for_vn.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_and_smag_coefficients_for_vn.py index 7435b98555..779027d81f 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_and_smag_coefficients_for_vn.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_and_smag_coefficients_for_vn.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, maximum, minimum, sqrt from icon4py.model.common.dimension import E2C2V, E2ECV, ECVDim, EdgeDim, KDim, VertexDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_for_theta.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_for_theta.py index 69b7b1779e..00e93d3b6d 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_for_theta.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_for_theta.py @@ -22,7 +22,7 @@ _calculate_nabla2_of_theta, ) from icon4py.model.common.dimension import CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_for_w.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_for_w.py index df71c48848..2c04213595 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_for_w.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_for_w.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import C2E2CO, C2E2CODim, CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_for_z.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_for_z.py index fbe32388e9..2dfdcc64bf 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_for_z.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_for_z.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import E2C, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_of_theta.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_of_theta.py index d6ecb4f742..6d1e007041 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_of_theta.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla2_of_theta.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import C2CE, C2E, C2EDim, CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla4.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla4.py index b1fcd4526c..23c75d63e6 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla4.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/calculate_nabla4.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import E2C2V, E2ECV, ECVDim, EdgeDim, KDim, VertexDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/enhance_diffusion_coefficient_for_grid_point_cold_pools.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/enhance_diffusion_coefficient_for_grid_point_cold_pools.py index cb1a98a555..39c0431e22 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/enhance_diffusion_coefficient_for_grid_point_cold_pools.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/enhance_diffusion_coefficient_for_grid_point_cold_pools.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32, max_over, maximum from icon4py.model.common.dimension import E2C, CellDim, E2CDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/temporary_field_for_grid_point_cold_pools_enhancement.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/temporary_field_for_grid_point_cold_pools_enhancement.py index 9208fdf09f..05b1dddcf9 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/temporary_field_for_grid_point_cold_pools_enhancement.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/temporary_field_for_grid_point_cold_pools_enhancement.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum, where from icon4py.model.common.dimension import C2E2C, C2E2CDim, CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/temporary_fields_for_turbulence_diagnostics.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/temporary_fields_for_turbulence_diagnostics.py index 941ca7ecdf..cbcaaad853 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/temporary_fields_for_turbulence_diagnostics.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/temporary_fields_for_turbulence_diagnostics.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import C2CE, C2E, C2EDim, CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/truly_horizontal_diffusion_nabla_of_theta_over_steep_points.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/truly_horizontal_diffusion_nabla_of_theta_over_steep_points.py index 8699498f4b..431758cf86 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/truly_horizontal_diffusion_nabla_of_theta_over_steep_points.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/truly_horizontal_diffusion_nabla_of_theta_over_steep_points.py @@ -17,7 +17,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, where from icon4py.model.common.dimension import C2CEC, C2E2C, CECDim, CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/update_theta_and_exner.py b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/update_theta_and_exner.py index 0d5e1933a1..85d608f0b0 100644 --- a/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/update_theta_and_exner.py +++ b/model/atmosphere/diffusion/src/icon4py/model/atmosphere/diffusion/stencils/update_theta_and_exner.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/diffusion/tests/diffusion_tests/test_diffusion.py b/model/atmosphere/diffusion/tests/diffusion_tests/test_diffusion.py index 4eb3d39efd..b4e0748473 100644 --- a/model/atmosphere/diffusion/tests/diffusion_tests/test_diffusion.py +++ b/model/atmosphere/diffusion/tests/diffusion_tests/test_diffusion.py @@ -18,7 +18,7 @@ from icon4py.model.atmosphere.diffusion.diffusion_utils import scale_k from icon4py.model.common.grid.horizontal import CellParams, EdgeParams from icon4py.model.common.grid.vertical import VerticalModelParams -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.test_utils.datatest_utils import GLOBAL_EXPERIMENT, REGIONAL_EXPERIMENT from icon4py.model.common.test_utils.helpers import dallclose from icon4py.model.common.test_utils.reference_funcs import enhanced_smagorinski_factor_numpy diff --git a/model/atmosphere/diffusion/tests/diffusion_tests/test_diffusion_utils.py b/model/atmosphere/diffusion/tests/diffusion_tests/test_diffusion_utils.py index 3d56479198..e060efd695 100644 --- a/model/atmosphere/diffusion/tests/diffusion_tests/test_diffusion_utils.py +++ b/model/atmosphere/diffusion/tests/diffusion_tests/test_diffusion_utils.py @@ -24,7 +24,7 @@ ) from icon4py.model.common.dimension import KDim, VertexDim from icon4py.model.common.grid.simple import SimpleGrid -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.test_utils.helpers import random_field, zero_field from .utils import construct_config, diff_multfac_vn_numpy, smag_limit_numpy diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/accumulate_prep_adv_fields.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/accumulate_prep_adv_fields.py index 1c6baa698d..d278725eb9 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/accumulate_prep_adv_fields.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/accumulate_prep_adv_fields.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_analysis_increments_from_data_assimilation.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_analysis_increments_from_data_assimilation.py index 7d7592fa90..e54837a65b 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_analysis_increments_from_data_assimilation.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_analysis_increments_from_data_assimilation.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_analysis_increments_to_vn.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_analysis_increments_to_vn.py index fcb381410f..1e10ba0fab 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_analysis_increments_to_vn.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_analysis_increments_to_vn.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_extra_diffusion_for_w_con_approaching_cfl.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_extra_diffusion_for_w_con_approaching_cfl.py index 6694c74bea..2e2e0875d1 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_extra_diffusion_for_w_con_approaching_cfl.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_extra_diffusion_for_w_con_approaching_cfl.py @@ -24,7 +24,7 @@ ) from icon4py.model.common.dimension import C2E2CO, C2E2CODim, CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_extra_diffusion_for_wn_approaching_cfl.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_extra_diffusion_for_wn_approaching_cfl.py index 38c1948d82..c86137e4ba 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_extra_diffusion_for_wn_approaching_cfl.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_extra_diffusion_for_wn_approaching_cfl.py @@ -38,7 +38,7 @@ Koff, VertexDim, ) -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_interpolated_horizontal_advection_of_w.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_interpolated_horizontal_advection_of_w.py index b35f23a745..c49474c7ce 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_interpolated_horizontal_advection_of_w.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_interpolated_horizontal_advection_of_w.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import C2CE, C2E, C2EDim, CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_temporal_tendencies_to_vn.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_temporal_tendencies_to_vn.py index fa07e89254..8e2b496de3 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_temporal_tendencies_to_vn.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_temporal_tendencies_to_vn.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_temporal_tendencies_to_vn_by_interpolating_between_time_levels.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_temporal_tendencies_to_vn_by_interpolating_between_time_levels.py index d1d1bf5b79..3d9949f2a8 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_temporal_tendencies_to_vn_by_interpolating_between_time_levels.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_temporal_tendencies_to_vn_by_interpolating_between_time_levels.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_vertical_wind_derivative_to_divergence_damping.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_vertical_wind_derivative_to_divergence_damping.py index 12668ac273..753903513c 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_vertical_wind_derivative_to_divergence_damping.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/add_vertical_wind_derivative_to_divergence_damping.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, broadcast, int32 from icon4py.model.common.dimension import E2C, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_2nd_order_divergence_damping.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_2nd_order_divergence_damping.py index c5343b5ef2..bdf3b23007 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_2nd_order_divergence_damping.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_2nd_order_divergence_damping.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_4th_order_divergence_damping.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_4th_order_divergence_damping.py index 5660973b79..ff6edabdee 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_4th_order_divergence_damping.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_4th_order_divergence_damping.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, broadcast, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_hydrostatic_correction_to_horizontal_gradient_of_exner_pressure.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_hydrostatic_correction_to_horizontal_gradient_of_exner_pressure.py index d8341df31e..f9e51a6ad1 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_hydrostatic_correction_to_horizontal_gradient_of_exner_pressure.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_hydrostatic_correction_to_horizontal_gradient_of_exner_pressure.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32, where from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_rayleigh_damping_mechanism.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_rayleigh_damping_mechanism.py index 2d83e534e4..30dbb06d0c 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_rayleigh_damping_mechanism.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_rayleigh_damping_mechanism.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, broadcast, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_weighted_2nd_and_4th_order_divergence_damping.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_weighted_2nd_and_4th_order_divergence_damping.py index 7fe36d9aee..6f4a2d1b35 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_weighted_2nd_and_4th_order_divergence_damping.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/apply_weighted_2nd_and_4th_order_divergence_damping.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, broadcast, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_advective_normal_wind_tendency.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_advective_normal_wind_tendency.py index 2d04c9ad98..f0d89744e2 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_advective_normal_wind_tendency.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_advective_normal_wind_tendency.py @@ -28,7 +28,7 @@ Koff, VertexDim, ) -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_advective_vertical_wind_tendency.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_advective_vertical_wind_tendency.py index 743cbbec0b..dc901a012d 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_advective_vertical_wind_tendency.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_advective_vertical_wind_tendency.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_airmass.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_airmass.py index c468bb88d7..fd42c8911a 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_airmass.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_airmass.py @@ -15,7 +15,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_approx_of_2nd_vertical_derivative_of_exner.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_approx_of_2nd_vertical_derivative_of_exner.py index 3dfa426a99..c5fbd1ee58 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_approx_of_2nd_vertical_derivative_of_exner.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_approx_of_2nd_vertical_derivative_of_exner.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_avg_vn.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_avg_vn.py index 44ebd75b8f..fbdadd4fd6 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_avg_vn.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_avg_vn.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32, neighbor_sum from icon4py.model.common.dimension import E2C2EO, E2C2EODim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_avg_vn_and_graddiv_vn_and_vt.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_avg_vn_and_graddiv_vn_and_vt.py index 67c8541b39..97db77ca8b 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_avg_vn_and_graddiv_vn_and_vt.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_avg_vn_and_graddiv_vn_and_vt.py @@ -18,7 +18,7 @@ from icon4py.model.atmosphere.dycore.compute_avg_vn import _compute_avg_vn from icon4py.model.atmosphere.dycore.compute_tangential_wind import _compute_tangential_wind from icon4py.model.common.dimension import E2C2EO, E2C2EDim, E2C2EODim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_contravariant_correction.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_contravariant_correction.py index 512f9e1755..9ac6fd8271 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_contravariant_correction.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_contravariant_correction.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_contravariant_correction_of_w.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_contravariant_correction_of_w.py index 2979307c73..5c9b2c58a6 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_contravariant_correction_of_w.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_contravariant_correction_of_w.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import C2CE, C2E, C2EDim, CEDim, CellDim, EdgeDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_contravariant_correction_of_w_for_lower_boundary.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_contravariant_correction_of_w_for_lower_boundary.py index 008984e19d..18fec6aba8 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_contravariant_correction_of_w_for_lower_boundary.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_contravariant_correction_of_w_for_lower_boundary.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import C2CE, C2E, C2EDim, CEDim, CellDim, EdgeDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_divergence_of_fluxes_of_rho_and_theta.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_divergence_of_fluxes_of_rho_and_theta.py index 8d82296c7a..ce1b0d60dd 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_divergence_of_fluxes_of_rho_and_theta.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_divergence_of_fluxes_of_rho_and_theta.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import C2CE, C2E, C2EDim, CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_dwdz_for_divergence_damping.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_dwdz_for_divergence_damping.py index be487494eb..906c044977 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_dwdz_for_divergence_damping.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_dwdz_for_divergence_damping.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_exner_from_rhotheta.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_exner_from_rhotheta.py index df3aa474f4..68470e7ac8 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_exner_from_rhotheta.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_exner_from_rhotheta.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, exp, int32, log from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_explicit_part_for_rho_and_exner.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_explicit_part_for_rho_and_exner.py index c170d1d899..63992e1995 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_explicit_part_for_rho_and_exner.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_explicit_part_for_rho_and_exner.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_explicit_vertical_wind_from_advection_and_vertical_wind_density.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_explicit_vertical_wind_from_advection_and_vertical_wind_density.py index 7398bacbda..0f00b88c74 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_explicit_vertical_wind_from_advection_and_vertical_wind_density.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_explicit_vertical_wind_from_advection_and_vertical_wind_density.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_explicit_vertical_wind_speed_and_vertical_wind_times_density.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_explicit_vertical_wind_speed_and_vertical_wind_times_density.py index 1f42c1f817..879643a31c 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_explicit_vertical_wind_speed_and_vertical_wind_times_density.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_explicit_vertical_wind_speed_and_vertical_wind_times_density.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_first_vertical_derivative.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_first_vertical_derivative.py index c3173c8444..75406eec02 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_first_vertical_derivative.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_first_vertical_derivative.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_graddiv2_of_vn.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_graddiv2_of_vn.py index 0995c3eeb3..d136ebd8b7 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_graddiv2_of_vn.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_graddiv2_of_vn.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import E2C2EO, E2C2EODim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_advection_of_rho_and_theta.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_advection_of_rho_and_theta.py index 6bb98fc047..65a2c2029e 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_advection_of_rho_and_theta.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_advection_of_rho_and_theta.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, where from icon4py.model.common.dimension import E2C, E2EC, CellDim, ECDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_advection_term_for_vertical_velocity.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_advection_term_for_vertical_velocity.py index d034dd8f78..36231bb463 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_advection_term_for_vertical_velocity.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_advection_term_for_vertical_velocity.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import E2C, E2V, CellDim, EdgeDim, KDim, VertexDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_gradient_of_exner_pressure_for_flat_coordinates.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_gradient_of_exner_pressure_for_flat_coordinates.py index 2ea32a5685..47659e2d13 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_gradient_of_exner_pressure_for_flat_coordinates.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_gradient_of_exner_pressure_for_flat_coordinates.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import E2C, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_gradient_of_exner_pressure_for_nonflat_coordinates.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_gradient_of_exner_pressure_for_nonflat_coordinates.py index 32f2837eb1..dc1a41750f 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_gradient_of_exner_pressure_for_nonflat_coordinates.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_gradient_of_exner_pressure_for_nonflat_coordinates.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import E2C, CellDim, E2CDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_gradient_of_extner_pressure_for_multiple_levels.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_gradient_of_extner_pressure_for_multiple_levels.py index eed15e1672..9ed0c65255 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_gradient_of_extner_pressure_for_multiple_levels.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_gradient_of_extner_pressure_for_multiple_levels.py @@ -17,7 +17,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import E2C, E2EC, CellDim, ECDim, EdgeDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_kinetic_energy.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_kinetic_energy.py index 1d15f87a23..478acd6d99 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_kinetic_energy.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_horizontal_kinetic_energy.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_hydrostatic_correction_term.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_hydrostatic_correction_term.py index abe05ee4e7..23789d7d2b 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_hydrostatic_correction_term.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_hydrostatic_correction_term.py @@ -17,7 +17,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import E2C, E2EC, CellDim, ECDim, EdgeDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_mass_flux.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_mass_flux.py index 0237074656..a097675a95 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_mass_flux.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_mass_flux.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_maximum_cfl_and_clip_contravariant_vertical_velocity.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_maximum_cfl_and_clip_contravariant_vertical_velocity.py index f08ffd62fc..31d21ae006 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_maximum_cfl_and_clip_contravariant_vertical_velocity.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_maximum_cfl_and_clip_contravariant_vertical_velocity.py @@ -23,7 +23,7 @@ ) from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_pertubation_of_rho_and_theta.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_pertubation_of_rho_and_theta.py index 8f650634dd..ba1602c8be 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_pertubation_of_rho_and_theta.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_pertubation_of_rho_and_theta.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_pertubation_of_rho_and_theta_and_rho_at_ic.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_pertubation_of_rho_and_theta_and_rho_at_ic.py index c36f261d75..93b46ce265 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_pertubation_of_rho_and_theta_and_rho_at_ic.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_pertubation_of_rho_and_theta_and_rho_at_ic.py @@ -19,7 +19,7 @@ _compute_pertubation_of_rho_and_theta, ) from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_results_for_thermodynamic_variables.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_results_for_thermodynamic_variables.py index 3ab0ae431b..31147db786 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_results_for_thermodynamic_variables.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_results_for_thermodynamic_variables.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_rho_virtual_potential_temperatures_and_pressure_gradient.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_rho_virtual_potential_temperatures_and_pressure_gradient.py index a44872ad7b..c9322ab14b 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_rho_virtual_potential_temperatures_and_pressure_gradient.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_rho_virtual_potential_temperatures_and_pressure_gradient.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_solver_coefficients_matrix.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_solver_coefficients_matrix.py index 009815fad9..987fc68579 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_solver_coefficients_matrix.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_solver_coefficients_matrix.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_tangential_wind.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_tangential_wind.py index 0d376c5796..03c67c522e 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_tangential_wind.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_tangential_wind.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import E2C2E, E2C2EDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_theta_and_exner.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_theta_and_exner.py index f55c48b776..da5df4473c 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_theta_and_exner.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_theta_and_exner.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, exp, int32, log, where from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_virtual_potential_temperatures_and_pressure_gradient.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_virtual_potential_temperatures_and_pressure_gradient.py index b4f6b9da42..5ff7adee0a 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_virtual_potential_temperatures_and_pressure_gradient.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_virtual_potential_temperatures_and_pressure_gradient.py @@ -19,7 +19,7 @@ _interpolate_to_half_levels_vp, ) from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_vn_on_lateral_boundary.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_vn_on_lateral_boundary.py index ea5f37dd4a..b798a36e04 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_vn_on_lateral_boundary.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/compute_vn_on_lateral_boundary.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/copy_cell_kdim_field_to_vp.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/copy_cell_kdim_field_to_vp.py index e82b324cec..8af01d5be1 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/copy_cell_kdim_field_to_vp.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/copy_cell_kdim_field_to_vp.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/correct_contravariant_vertical_velocity.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/correct_contravariant_vertical_velocity.py index cde2fc3242..38366f5093 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/correct_contravariant_vertical_velocity.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/correct_contravariant_vertical_velocity.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/extrapolate_at_top.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/extrapolate_at_top.py index e7da5e5081..8ce8b4818a 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/extrapolate_at_top.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/extrapolate_at_top.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import EdgeDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/extrapolate_temporally_exner_pressure.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/extrapolate_temporally_exner_pressure.py index 6d42ad17c1..881092e38c 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/extrapolate_temporally_exner_pressure.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/extrapolate_temporally_exner_pressure.py @@ -15,7 +15,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_solve_nonhydro_stencil_39_40.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_solve_nonhydro_stencil_39_40.py index efad6ee216..a55b426725 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_solve_nonhydro_stencil_39_40.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_solve_nonhydro_stencil_39_40.py @@ -21,7 +21,7 @@ _compute_contravariant_correction_of_w_for_lower_boundary, ) from icon4py.model.common.dimension import CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_15_to_18.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_15_to_18.py index 8eb521a2a2..deaa23b1b8 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_15_to_18.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_15_to_18.py @@ -27,7 +27,7 @@ _interpolate_contravatiant_vertical_verlocity_to_full_levels, ) from icon4py.model.common.dimension import C2E2CODim, CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_19_to_20.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_19_to_20.py index cfca1626f2..e7e450e37b 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_19_to_20.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_19_to_20.py @@ -33,7 +33,7 @@ V2EDim, VertexDim, ) -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_1_to_7.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_1_to_7.py index 9082d298f6..87303c38ed 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_1_to_7.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_1_to_7.py @@ -33,7 +33,7 @@ _mo_icon_interpolation_scalar_cells2verts_scalar_ri_dsl, ) from icon4py.model.common.dimension import CellDim, E2C2EDim, EdgeDim, KDim, V2CDim, VertexDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_8_to_13.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_8_to_13.py index 3167a6c8e9..bb8da96ad8 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_8_to_13.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_8_to_13.py @@ -26,7 +26,7 @@ _set_cell_kdim_field_to_zero_vp, ) from icon4py.model.common.dimension import CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_8_to_14.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_8_to_14.py index 695b77e57a..ea0074ed2f 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_8_to_14.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/fused_velocity_advection_stencil_8_to_14.py @@ -29,7 +29,7 @@ _set_cell_kdim_field_to_zero_vp, ) from icon4py.model.common.dimension import CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_contravatiant_vertical_verlocity_to_full_levels.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_contravatiant_vertical_verlocity_to_full_levels.py index a4d496998f..29a8527a4b 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_contravatiant_vertical_verlocity_to_full_levels.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_contravatiant_vertical_verlocity_to_full_levels.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_to_cell_center.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_to_cell_center.py index 17b1649386..1bf776d48b 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_to_cell_center.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_to_cell_center.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import C2CE, C2E, C2EDim, CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_to_half_levels_vp.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_to_half_levels_vp.py index 4c1332af94..350f006a0f 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_to_half_levels_vp.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_to_half_levels_vp.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_to_surface.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_to_surface.py index 5467242f68..8cfabb61ed 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_to_surface.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_to_surface.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_vn_and_vt_to_ie_and_compute_ekin_on_edges.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_vn_and_vt_to_ie_and_compute_ekin_on_edges.py index 895a7d9eb1..b33ed00b50 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_vn_and_vt_to_ie_and_compute_ekin_on_edges.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_vn_and_vt_to_ie_and_compute_ekin_on_edges.py @@ -20,7 +20,7 @@ ) from icon4py.model.atmosphere.dycore.interpolate_vt_to_ie import _interpolate_vt_to_ie from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_vn_to_ie_and_compute_ekin_on_edges.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_vn_to_ie_and_compute_ekin_on_edges.py index a1ff78abec..47af3271f7 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_vn_to_ie_and_compute_ekin_on_edges.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_vn_to_ie_and_compute_ekin_on_edges.py @@ -19,7 +19,7 @@ _compute_horizontal_kinetic_energy, ) from icon4py.model.common.dimension import EdgeDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_vt_to_ie.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_vt_to_ie.py index 84737c8f66..3a930515cc 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_vt_to_ie.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/interpolate_vt_to_ie.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import EdgeDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_icon_interpolation_scalar_cells2verts_scalar_ri_dsl.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_icon_interpolation_scalar_cells2verts_scalar_ri_dsl.py index daf11cef73..d49f92afb0 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_icon_interpolation_scalar_cells2verts_scalar_ri_dsl.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_icon_interpolation_scalar_cells2verts_scalar_ri_dsl.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import V2C, CellDim, KDim, V2CDim, VertexDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_math_divrot_rot_vertex_ri_dsl.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_math_divrot_rot_vertex_ri_dsl.py index 617ff9f29e..5ea61aa6ab 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_math_divrot_rot_vertex_ri_dsl.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_math_divrot_rot_vertex_ri_dsl.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import V2E, EdgeDim, KDim, V2EDim, VertexDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_math_gradients_grad_green_gauss_cell_dsl.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_math_gradients_grad_green_gauss_cell_dsl.py index 47724a039a..dafe3e5318 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_math_gradients_grad_green_gauss_cell_dsl.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_math_gradients_grad_green_gauss_cell_dsl.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32, neighbor_sum from icon4py.model.common.dimension import C2E2CO, C2E2CODim, CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_solve_nonhydro_stencil_51.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_solve_nonhydro_stencil_51.py index 6f921b7601..3b92096990 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_solve_nonhydro_stencil_51.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/mo_solve_nonhydro_stencil_51.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend @field_operator diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/nh_solve/solve_nonhydro.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/nh_solve/solve_nonhydro.py index db3787c9a5..4b802d3e85 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/nh_solve/solve_nonhydro.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/nh_solve/solve_nonhydro.py @@ -168,7 +168,7 @@ from icon4py.model.common.grid.vertical import VerticalModelParams from icon4py.model.common.math.smagorinsky import en_smag_fac_for_zero_nshift from icon4py.model.common.states.prognostic_state import PrognosticState -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend # flake8: noqa diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/nh_solve/solve_nonhydro_program.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/nh_solve/solve_nonhydro_program.py index c70244c11b..c51edccf87 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/nh_solve/solve_nonhydro_program.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/nh_solve/solve_nonhydro_program.py @@ -82,7 +82,7 @@ from icon4py.model.atmosphere.dycore.update_densety_exener_wind import _update_densety_exener_wind from icon4py.model.atmosphere.dycore.update_wind import _update_wind from icon4py.model.common.dimension import CEDim, CellDim, ECDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend # TODO: abishekg7 move this to tests diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_cell_kdim_field_to_zero_vp.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_cell_kdim_field_to_zero_vp.py index fca20c21e4..ab45b2e8ec 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_cell_kdim_field_to_zero_vp.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_cell_kdim_field_to_zero_vp.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, broadcast, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_cell_kdim_field_to_zero_wp.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_cell_kdim_field_to_zero_wp.py index 8837caa0da..fb053afad2 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_cell_kdim_field_to_zero_wp.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_cell_kdim_field_to_zero_wp.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, broadcast, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_lower_boundary_condition_for_w_and_contravariant_correction.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_lower_boundary_condition_for_w_and_contravariant_correction.py index 9c89fe5fcb..d4bf7addfc 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_lower_boundary_condition_for_w_and_contravariant_correction.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_lower_boundary_condition_for_w_and_contravariant_correction.py @@ -19,7 +19,7 @@ _set_cell_kdim_field_to_zero_wp, ) from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_theta_v_prime_ic_at_lower_boundary.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_theta_v_prime_ic_at_lower_boundary.py index 8eabaf9de6..89bd442968 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_theta_v_prime_ic_at_lower_boundary.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_theta_v_prime_ic_at_lower_boundary.py @@ -17,7 +17,7 @@ from icon4py.model.atmosphere.dycore.interpolate_to_surface import _interpolate_to_surface from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_cell_kdim_fields_index_to_zero_vp.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_cell_kdim_fields_index_to_zero_vp.py index dbdd114ba0..d4c8f0b658 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_cell_kdim_fields_index_to_zero_vp.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_cell_kdim_fields_index_to_zero_vp.py @@ -19,7 +19,7 @@ _set_cell_kdim_field_to_zero_vp, ) from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_cell_kdim_fields_to_zero_vp.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_cell_kdim_fields_to_zero_vp.py index 6942d1f006..a315f4bac2 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_cell_kdim_fields_to_zero_vp.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_cell_kdim_fields_to_zero_vp.py @@ -19,7 +19,7 @@ _set_cell_kdim_field_to_zero_vp, ) from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_cell_kdim_fields_to_zero_wp.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_cell_kdim_fields_to_zero_wp.py index 29b3635df6..990cc677d1 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_cell_kdim_fields_to_zero_wp.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_cell_kdim_fields_to_zero_wp.py @@ -19,7 +19,7 @@ _set_cell_kdim_field_to_zero_wp, ) from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_edge_kdim_fields_to_zero_wp.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_edge_kdim_fields_to_zero_wp.py index 888de75f9b..0094f5a259 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_edge_kdim_fields_to_zero_wp.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/set_two_edge_kdim_fields_to_zero_wp.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, broadcast, int32 from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/solve_tridiagonal_matrix_for_w_back_substitution.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/solve_tridiagonal_matrix_for_w_back_substitution.py index 04d5f40265..bae3536819 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/solve_tridiagonal_matrix_for_w_back_substitution.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/solve_tridiagonal_matrix_for_w_back_substitution.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/solve_tridiagonal_matrix_for_w_forward_sweep.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/solve_tridiagonal_matrix_for_w_forward_sweep.py index fe8e6e14f3..e43b221783 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/solve_tridiagonal_matrix_for_w_forward_sweep.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/solve_tridiagonal_matrix_for_w_forward_sweep.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/state_utils/utils.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/state_utils/utils.py index ee5acd308a..5aa3b973f5 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/state_utils/utils.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/state_utils/utils.py @@ -23,7 +23,7 @@ ) from icon4py.model.common.dimension import EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_densety_exener_wind.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_densety_exener_wind.py index 4579dd3df9..ab9c46d617 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_densety_exener_wind.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_densety_exener_wind.py @@ -17,7 +17,7 @@ from icon4py.model.atmosphere.dycore.update_wind import _update_wind from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_dynamical_exner_time_increment.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_dynamical_exner_time_increment.py index 0860757117..02d61d27ba 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_dynamical_exner_time_increment.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_dynamical_exner_time_increment.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_mass_flux_weighted.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_mass_flux_weighted.py index c8bcfc7df3..b5dee86658 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_mass_flux_weighted.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_mass_flux_weighted.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, astype, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import vpfloat, wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_mass_volume_flux.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_mass_volume_flux.py index 4090a78e97..4a67a0f867 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_mass_volume_flux.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_mass_volume_flux.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_theta_v.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_theta_v.py index f121943310..fe661422db 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_theta_v.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_theta_v.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32, where from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_wind.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_wind.py index fcd1508753..e3c64294fe 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_wind.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/update_wind.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32 from icon4py.model.common.dimension import CellDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/velocity/velocity_advection_program.py b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/velocity/velocity_advection_program.py index 862acfd611..386a365066 100644 --- a/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/velocity/velocity_advection_program.py +++ b/model/atmosphere/dycore/src/icon4py/model/atmosphere/dycore/velocity/velocity_advection_program.py @@ -42,7 +42,7 @@ _set_cell_kdim_field_to_zero_vp, ) from icon4py.model.common.dimension import CEDim, CellDim, EdgeDim, KDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend @field_operator diff --git a/model/atmosphere/dycore/tests/dycore_tests/test_solve_nonhydro.py b/model/atmosphere/dycore/tests/dycore_tests/test_solve_nonhydro.py index 4cc4454574..a73fca0ff6 100644 --- a/model/atmosphere/dycore/tests/dycore_tests/test_solve_nonhydro.py +++ b/model/atmosphere/dycore/tests/dycore_tests/test_solve_nonhydro.py @@ -39,7 +39,7 @@ ) from icon4py.model.common.grid.vertical import VerticalModelParams from icon4py.model.common.math.smagorinsky import en_smag_fac_for_zero_nshift -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.states.prognostic_state import PrognosticState from icon4py.model.common.test_utils.datatest_utils import ( GLOBAL_EXPERIMENT, diff --git a/model/atmosphere/dycore/tests/dycore_tests/test_utils.py b/model/atmosphere/dycore/tests/dycore_tests/test_utils.py index 276e3a0adf..b089faaed0 100644 --- a/model/atmosphere/dycore/tests/dycore_tests/test_utils.py +++ b/model/atmosphere/dycore/tests/dycore_tests/test_utils.py @@ -22,7 +22,7 @@ from icon4py.model.common import constants from icon4py.model.common.dimension import KDim from icon4py.model.common.grid.simple import SimpleGrid -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.test_utils.helpers import dallclose, random_field, zero_field diff --git a/model/common/src/icon4py/model/common/config.py b/model/common/src/icon4py/model/common/config.py new file mode 100644 index 0000000000..8c9f0eb95c --- /dev/null +++ b/model/common/src/icon4py/model/common/config.py @@ -0,0 +1,71 @@ +# ICON4Py - ICON inspired code in Python and GT4Py +# +# Copyright (c) 2022, ETH Zurich and MeteoSwiss +# All rights reserved. +# +# This file is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or any later +# version. See the LICENSE.txt file at the top-level directory of this +# distribution for a copy of the license or check . +# +# SPDX-License-Identifier: GPL-3.0-or-later + +# Assuming this code is in a module called icon4py_config.py +import dataclasses +import os +from enum import Enum +from functools import cached_property + +import numpy as np +from gt4py.next.program_processors.runners.gtfn import ( + run_gtfn_cached, + run_gtfn_gpu_cached, +) +from gt4py.next.program_processors.runners.roundtrip import backend as run_roundtrip + + +class Device(Enum): + CPU = "CPU" + GPU = "GPU" + + +class GT4PyBackend(Enum): + CPU = "run_gtfn_cached" + GPU = "run_gtfn_gpu_cached" + ROUNDTRIP = "run_roundtrip" + + +@dataclasses.dataclass +class Icon4PyConfig: + @cached_property + def icon4py_backend(self): + return os.environ.get("ICON4PY_BACKEND", "CPU") + + @cached_property + def array_ns(self): + if self.device == Device.GPU: + import cupy as cp # type: ignore[import-untyped] + + return cp + else: + return np + + @cached_property + def gt4py_runner(self): + backend_map = { + GT4PyBackend.CPU.name: run_gtfn_cached, + GT4PyBackend.GPU.name: run_gtfn_gpu_cached, + GT4PyBackend.ROUNDTRIP.name: run_roundtrip, + } + return backend_map[self.icon4py_backend] + + @cached_property + def device(self): + device_map = { + GT4PyBackend.CPU.name: Device.CPU, + GT4PyBackend.GPU.name: Device.GPU, + GT4PyBackend.ROUNDTRIP.name: Device.CPU, + } + device = device_map[self.icon4py_backend] + return device diff --git a/model/common/src/icon4py/model/common/grid/vertical.py b/model/common/src/icon4py/model/common/grid/vertical.py index f8434dd796..8609f282e0 100644 --- a/model/common/src/icon4py/model/common/grid/vertical.py +++ b/model/common/src/icon4py/model/common/grid/vertical.py @@ -19,6 +19,7 @@ from gt4py.next.ffront.fbuiltins import int32 from icon4py.model.common.dimension import KDim +from icon4py.model.common.settings import xp log = logging.getLogger(__name__) @@ -49,7 +50,7 @@ class VerticalModelParams: nflat_gradp: Final[int32] = None def __post_init__(self): - vct_a_array = self.vct_a.asnumpy() + vct_a_array = self.vct_a.ndarray object.__setattr__( self, "index_of_damping_layer", @@ -79,11 +80,11 @@ def _determine_kstart_moist( ) -> int32: n_levels = vct_a.shape[0] interface_height = 0.5 * (vct_a[: n_levels - 1 - nshift_total] + vct_a[1 + nshift_total :]) - return int32(np.min(np.where(interface_height < top_moist_threshold))) + return int32(xp.min(xp.where(interface_height < top_moist_threshold)[0]).item()) @classmethod def _determine_damping_height_index(cls, vct_a: np.ndarray, damping_height: float): - return int32(np.argmax(np.where(vct_a >= damping_height))) + return int32(xp.argmax(xp.where(vct_a >= damping_height)[0]).item()) @property def physical_heights(self) -> Field[[KDim], float]: diff --git a/model/common/src/icon4py/model/common/interpolation/stencils/mo_intp_rbf_rbf_vec_interpol_vertex.py b/model/common/src/icon4py/model/common/interpolation/stencils/mo_intp_rbf_rbf_vec_interpol_vertex.py index 979d96c70e..2d867d0a93 100644 --- a/model/common/src/icon4py/model/common/interpolation/stencils/mo_intp_rbf_rbf_vec_interpol_vertex.py +++ b/model/common/src/icon4py/model/common/interpolation/stencils/mo_intp_rbf_rbf_vec_interpol_vertex.py @@ -16,7 +16,7 @@ from gt4py.next.ffront.fbuiltins import Field, int32, neighbor_sum from icon4py.model.common.dimension import V2E, EdgeDim, KDim, V2EDim, VertexDim -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend from icon4py.model.common.type_alias import wpfloat diff --git a/model/common/src/icon4py/model/common/math/smagorinsky.py b/model/common/src/icon4py/model/common/math/smagorinsky.py index b82366302c..9e6765b1f2 100644 --- a/model/common/src/icon4py/model/common/math/smagorinsky.py +++ b/model/common/src/icon4py/model/common/math/smagorinsky.py @@ -15,7 +15,7 @@ from gt4py.next.ffront.fbuiltins import broadcast, maximum, minimum from icon4py.model.common.dimension import KDim, Koff -from icon4py.model.common.model_backend import backend +from icon4py.model.common.settings import backend @field_operator diff --git a/model/common/src/icon4py/model/common/model_backend.py b/model/common/src/icon4py/model/common/settings.py similarity index 65% rename from model/common/src/icon4py/model/common/model_backend.py rename to model/common/src/icon4py/model/common/settings.py index 3f2b518a9e..0f5d1a82c0 100644 --- a/model/common/src/icon4py/model/common/model_backend.py +++ b/model/common/src/icon4py/model/common/settings.py @@ -10,16 +10,10 @@ # distribution for a copy of the license or check . # # SPDX-License-Identifier: GPL-3.0-or-later -from gt4py.next.program_processors.runners.gtfn import ( - run_gtfn, - run_gtfn_cached, - run_gtfn_gpu, - run_gtfn_imperative, -) +from icon4py.model.common.config import Icon4PyConfig -cached_backend = run_gtfn_cached -compiled_backend = run_gtfn -imperative_backend = run_gtfn_imperative -gpu_backend = run_gtfn_gpu -backend = cached_backend +config = Icon4PyConfig() +backend = config.gt4py_runner +xp = config.array_ns +device = config.device diff --git a/model/common/src/icon4py/model/common/states/prognostic_state.py b/model/common/src/icon4py/model/common/states/prognostic_state.py index 9a0719faf5..a248211314 100644 --- a/model/common/src/icon4py/model/common/states/prognostic_state.py +++ b/model/common/src/icon4py/model/common/states/prognostic_state.py @@ -36,4 +36,4 @@ class PrognosticState: @property def w_1(self) -> Field[[CellDim], float]: - return as_field((CellDim,), self.w.asnumpy()[:, 0]) + return as_field((CellDim,), self.w.ndarray[:, 0]) diff --git a/model/common/src/icon4py/model/common/test_utils/helpers.py b/model/common/src/icon4py/model/common/test_utils/helpers.py index 25cf8357da..7de2eea602 100644 --- a/model/common/src/icon4py/model/common/test_utils/helpers.py +++ b/model/common/src/icon4py/model/common/test_utils/helpers.py @@ -117,7 +117,7 @@ def constant_field( def as_1D_sparse_field(field: gt_common.Field, target_dim: gt_common.Dimension) -> gt_common.Field: """Convert a 2D sparse field to a 1D flattened (Felix-style) sparse field.""" - buffer = field.asnumpy() + buffer = field.ndarray return numpy_to_1D_sparse_field(buffer, target_dim) @@ -131,7 +131,7 @@ def numpy_to_1D_sparse_field(field: np.ndarray, dim: gt_common.Dimension) -> gt_ def flatten_first_two_dims(*dims: gt_common.Dimension, field: gt_common.Field) -> gt_common.Field: """Convert a n-D sparse field to a (n-1)-D flattened (Felix-style) sparse field.""" - buffer = field.asnumpy() + buffer = field.ndarray old_shape = buffer.shape assert len(old_shape) >= 2 flattened_size = old_shape[0] * old_shape[1] diff --git a/tools/README.md b/tools/README.md index 9a311082eb..d6288ad2f7 100644 --- a/tools/README.md +++ b/tools/README.md @@ -314,7 +314,7 @@ OUTPUT_FILEPATH A path to the output Fortran source file to be generated. `py2fgen` is a command-line interface (CLI) tool designed to generate C and Fortran 90 (F90) wrappers, as well as a C library, for embedding a Python module into C and Fortran applications. This tool facilitates the embedding of Python code into Fortran programs by utilizing the [`CFFI`](https://cffi.readthedocs.io/en/latest/embedding) library. `CFFI` instantiates a Python interpreter to execute Python code which is "frozen" into the dynamic library generated by `CFFI`. -**Note:** `py2fgen` is currently in an **experimental** stage. Simple examples have been successfully tested within Fortran code, but it is not yet production-ready. Further testing with complex Python code is necessary. The performance implications of invoking a Python interpreter from within Fortran are also yet to be fully understood. +**Note:** `py2fgen` is currently in an **proof of concept** stage. Although embedding of more complex functions in Fortran such as the diffusion granule has been done in ICON, the performance implications of invoking a Python interpreter from within Fortran yet to be fully understood. ## Usage @@ -324,16 +324,26 @@ OUTPUT_FILEPATH A path to the output Fortran source file to be generated. py2fgen [OPTIONS] MODULE_IMPORT_PATH FUNCTION_NAME Arguments: - MODULE_IMPORT_PATH The Python module containing the function to embed. - FUNCTION_NAME The function within the module to embed. - + MODULE_IMPORT_PATH The Python module import path to the module where the functions to be embedded are defined. + FUNCTIONS A comma-separated list of functions to be embedded in the case of multiple, otherwise just the function name. + PLUGIN_NAME The name of the plugin used for creating the shared library and bindings. Options: - -b, --build-path PATH Specify the directory for generated code and compiled libraries. - -d, --debug-mode Enable debug mode to print additional runtime information. - -g, --gt4py-backend TYPE Set the gt4py backend to use (options: CPU, GPU, ROUNDTRIP). - --help Display the help message and exit. + -o, --output-path PATH Specify the directory for generated code and + compiled libraries. + -b, --backend [CPU|GPU|ROUNDTRIP] + Set the backend to use, thereby unpacking + Fortran pointers into NumPy or CuPy arrays + respectively. + -d, --debug-mode Enable debug mode to log additional Python + runtime information. + --help Show this message and exit. ``` +## Important Environment Variables + +When embedding granules it may be necessary to use an ICON grid file, as is the case in the diffusion granule wrapper. +The granule expects an `ICON_GRID_LOC` environment variable with the path to the folder holding the grid netcdf file. + ### Example To create a Fortran interface along with the dynamic library for a Python function named `square` within the module `example.functions`, execute: @@ -342,6 +352,12 @@ To create a Fortran interface along with the dynamic library for a Python functi py2fgen example.functions square ``` +It is also possible to generate bindings for more than one function at a time by using a comma-separated list of function names: + +```bash +py2fgen example.functions square,square2 +``` + `py2fgen` can accept two types of functions: - **Simple Function:** Any Python function can be exposed. @@ -368,15 +384,9 @@ Examples can be found under `tools/tests/py2fgen/fortran_samples`. ## Compilation -Compiling your Fortran driver code requires a Fortran compiler, such as `gfortran`. Follow these steps: +Compiling your Fortran driver code requires a Fortran compiler, such as `gfortran` or `nvfortran`. Follow these steps: -1. Compile (without linking) .f90 interface: - -```bash -gfortran -c _plugin.f90 -``` - -2. Compile the Fortran driver code along with the Fortran interface and dynamic library: +1. Compile and link the Fortran driver code along with the Fortran interface and dynamic library: ```bash gfortran -I. -Wl,-rpath=. -L. _plugin.f90 .f90 -l_plugin -o @@ -385,3 +395,27 @@ gfortran -I. -Wl,-rpath=. -L. _plugin.f90 .f90 -l Replace ``, ``, and `` with the appropriate names for your project. **Note:** When executing the compiled binary make sure that you have sourced a Python virtual environment where all required dependencies to run the embedded Python code are present. + +## Error handling + +All generated Python wrapper code is wrapped in a `try: ... except: ...` block, with the wrapper function returning an error code `1` if an Exception ocurred +and `0` otherwise. In case of an exception the error message is written to the `py2f_cffi.log` file, which is located in the same directory as the generated bindings. +This means that on the Fortran side we can handle errors gracefully as follows: + +```Fortran +integer(c_int) :: rc +real(c_double), dimension(:, :), allocatable :: input, result + +call square(input, result, rc) + +! handle the Python error here + if (rc /= 0) then + print *, "Python failed with exit code = ", rc + call exit(1) + end if +``` + +## Other requirements + +- Embedded Python functions must have type hints for all function parameters, as these are used to derive the corresponding C and Fortran types. +- Embedded Python functions are assumed to modify function parameters in-place. Explicitly returning anything is currently not supported. diff --git a/tools/pyproject.toml b/tools/pyproject.toml index 2f453c0b2c..8bb7d3df53 100644 --- a/tools/pyproject.toml +++ b/tools/pyproject.toml @@ -36,8 +36,8 @@ readme = 'README.md' requires-python = '>=3.10' [project.optional-dependencies] -all = ["icon4pytools[py2f]"] -py2f = ['cffi>=1.5'] +cupy11 = ['cupy-cuda11x'] +cupy12 = ['cupy-cuda12x'] [project.scripts] f2ser = 'icon4pytools.f2ser.cli:main' diff --git a/tools/src/icon4pytools/py2fgen/cffi.py b/tools/src/icon4pytools/py2fgen/cffi.py deleted file mode 100644 index cb364e31ad..0000000000 --- a/tools/src/icon4pytools/py2fgen/cffi.py +++ /dev/null @@ -1,116 +0,0 @@ -# ICON4Py - ICON inspired code in Python and GT4Py -# -# Copyright (c) 2022, ETH Zurich and MeteoSwiss -# All rights reserved. -# -# This file is free software: you can redistribute it and/or modify it under -# the terms of the GNU General Public License as published by the -# Free Software Foundation, either version 3 of the License, or any later -# version. See the LICENSE.txt file at the top-level directory of this -# distribution for a copy of the license or check . -# -# SPDX-License-Identifier: GPL-3.0-or-later -import logging -from pathlib import Path - -import cffi -import numpy as np -from cffi import FFI - -from icon4pytools.common.logger import setup_logger - - -ffi = FFI() - -logger = setup_logger(__name__) - - -def unpack(ptr, *sizes: int) -> np.ndarray: - """ - Unpacks an n-dimensional Fortran (column-major) array into a NumPy array (row-major). - - This function is particularly useful when interfacing with C code that returns arrays - in column-major order (Fortran order), but you want to work with the array in row-major - order (NumPy's default order). - - Args: - ptr: A C pointer to the field. - *sizes: Size arguments representing the length of each dimension of the array in - row-major order. The length of this argument must match the number of dimensions - of the array. - - Returns: - A NumPy array with shape specified by the sizes and dtype determined by the ctype - (C data type) of the pointer. - """ - length = np.prod(sizes) - c_type = ffi.getctype(ffi.typeof(ptr).item) - - # special casing different types - if c_type == "int": - dtype = np.int32 - else: - dtype = np.dtype(c_type) # type: ignore - - arr = np.frombuffer( # type: ignore - ffi.buffer(ptr, length * ffi.sizeof(c_type)), - dtype=dtype, - count=-1, - offset=0, - ).reshape(sizes) - return arr - - -def generate_and_compile_cffi_plugin( - plugin_name: str, c_header: str, python_wrapper: str, build_path: Path -) -> None: - """ - Create and compile a CFFI plugin. - - This function generates a C shared library and Fortran interface for Python functions - to be exposed in the {plugin_name} module. It creates a linkable C library named - 'lib{plugin_name}.so' in the specified build directory. - - Args: - plugin_name: Name of the plugin. - c_header: C header signatures for the Python functions. - python_wrapper: Python code wrapping the original function to be exposed. - build_path: Path to the build directory. - """ - try: - header_file_path = write_c_header(build_path, plugin_name, c_header) - compile_cffi_plugin( - builder=configure_cffi_builder(c_header, plugin_name, header_file_path), - python_wrapper=python_wrapper, - build_path=str(build_path), - plugin_name=plugin_name, - ) - except Exception as e: - logging.error(f"Error generating and compiling CFFI plugin: {e}") - raise - - -def write_c_header(build_path: Path, plugin_name: str, c_header: str) -> Path: - """Write the C header file to the specified path.""" - c_header_file = plugin_name + ".h" - header_file_path = build_path / c_header_file - with open(header_file_path, "w") as f: - f.write(c_header) - return header_file_path - - -def configure_cffi_builder(c_header: str, plugin_name: str, header_file_path: Path) -> cffi.FFI: - """Configure and returns a CFFI FFI builder instance.""" - builder = cffi.FFI() - builder.embedding_api(c_header) - builder.set_source(plugin_name, f'#include "{header_file_path.name}"') - return builder - - -def compile_cffi_plugin( - builder: cffi.FFI, python_wrapper: str, build_path: str, plugin_name: str -) -> None: - """Compile the CFFI plugin with the given configuration.""" - logger.info("Compiling CFFI dynamic library...") - builder.embedding_init_code(python_wrapper) - builder.compile(tmpdir=build_path, target=f"lib{plugin_name}.*", verbose=True) diff --git a/tools/src/icon4pytools/py2fgen/cli.py b/tools/src/icon4pytools/py2fgen/cli.py index 01e15520b4..99db23a5c8 100644 --- a/tools/src/icon4pytools/py2fgen/cli.py +++ b/tools/src/icon4pytools/py2fgen/cli.py @@ -10,20 +10,24 @@ # distribution for a copy of the license or check . # # SPDX-License-Identifier: GPL-3.0-or-later - import pathlib import click +from icon4py.model.common.config import GT4PyBackend from icon4pytools.icon4pygen.bindings.utils import write_string -from icon4pytools.py2fgen.cffi import generate_and_compile_cffi_plugin from icon4pytools.py2fgen.generate import ( generate_c_header, generate_f90_interface, generate_python_wrapper, ) from icon4pytools.py2fgen.parsing import parse -from icon4pytools.py2fgen.utils import Backend +from icon4pytools.py2fgen.plugin import generate_and_compile_cffi_plugin + + +def parse_comma_separated_list(ctx, param, value) -> list[str]: + # Splits the input string by commas and strips any leading/trailing whitespace from the strings + return [item.strip() for item in value.split(",")] @click.command("py2fgen") @@ -31,49 +35,48 @@ "module_import_path", type=str, ) -@click.argument("function_name", type=str) +@click.argument("functions", type=str, callback=parse_comma_separated_list) +@click.argument("plugin_name", type=str) @click.option( - "--build-path", - "-b", + "--output-path", + "-o", type=click.Path(dir_okay=True, resolve_path=True, path_type=pathlib.Path), default=".", help="Specify the directory for generated code and compiled libraries.", ) +@click.option( + "--backend", + "-b", + type=click.Choice([e.name for e in GT4PyBackend], case_sensitive=False), + default="CPU", + help="Set the backend to use, thereby unpacking Fortran pointers into NumPy or CuPy arrays respectively.", +) @click.option( "--debug-mode", "-d", is_flag=True, - help="Enable debug mode to print additional runtime information.", -) -@click.option( - "--gt4py-backend", - "-g", - type=click.Choice([e.name for e in Backend], case_sensitive=False), - default="ROUNDTRIP", - help="Set the gt4py backend to use.", + help="Enable debug mode to log additional Python runtime information.", ) def main( module_import_path: str, - function_name: str, - build_path: pathlib.Path, + functions: list[str], + plugin_name: str, + output_path: pathlib.Path, debug_mode: bool, - gt4py_backend: str, + backend: str, ) -> None: """Generate C and F90 wrappers and C library for embedding a Python module in C and Fortran.""" - backend = Backend[gt4py_backend] - build_path.mkdir(exist_ok=True, parents=True) + output_path.mkdir(exist_ok=True, parents=True) - plugin = parse(module_import_path, function_name) + plugin = parse(module_import_path, functions, plugin_name) c_header = generate_c_header(plugin) - python_wrapper = generate_python_wrapper(plugin, backend.value, debug_mode) + python_wrapper = generate_python_wrapper(plugin, backend, debug_mode) f90_interface = generate_f90_interface(plugin) - generate_and_compile_cffi_plugin(plugin.plugin_name, c_header, python_wrapper, build_path) - write_string(f90_interface, build_path, f"{plugin.plugin_name}.f90") - - if debug_mode: - write_string(python_wrapper, build_path, f"{plugin.plugin_name}.py") + generate_and_compile_cffi_plugin(plugin.plugin_name, c_header, python_wrapper, output_path) + write_string(f90_interface, output_path, f"{plugin.plugin_name}.f90") + write_string(python_wrapper, output_path, f"{plugin.plugin_name}.py") if __name__ == "__main__": diff --git a/tools/src/icon4pytools/py2fgen/generate.py b/tools/src/icon4pytools/py2fgen/generate.py index 143a4f8c9a..9812d8a3f8 100644 --- a/tools/src/icon4pytools/py2fgen/generate.py +++ b/tools/src/icon4pytools/py2fgen/generate.py @@ -20,6 +20,7 @@ from icon4pytools.py2fgen.template import ( CffiPlugin, CHeaderGenerator, + F90Interface, F90InterfaceGenerator, PythonWrapper, PythonWrapperGenerator, @@ -44,15 +45,13 @@ def generate_c_header(plugin: CffiPlugin) -> str: return codegen.format_source("cpp", generated_code, style="LLVM") -def generate_python_wrapper( - plugin: CffiPlugin, gt4py_backend: Optional[str], debug_mode: bool -) -> str: +def generate_python_wrapper(plugin: CffiPlugin, backend: Optional[str], debug_mode: bool) -> str: """ Generate Python wrapper code. Args: plugin: The CffiPlugin instance containing information for code generation. - gt4py_backend: Optional gt4py backend specification. + backend: Optional gt4py backend specification. debug_mode: Flag indicating if debug mode is enabled. Returns: @@ -62,9 +61,9 @@ def generate_python_wrapper( python_wrapper = PythonWrapper( module_name=plugin.module_name, plugin_name=plugin.plugin_name, - function=plugin.function, + functions=plugin.functions, imports=plugin.imports, - gt4py_backend=gt4py_backend, + backend=backend, debug_mode=debug_mode, ) @@ -80,5 +79,5 @@ def generate_f90_interface(plugin: CffiPlugin) -> str: plugin: The CffiPlugin instance containing information for code generation. """ logger.info("Generating Fortran interface...") - generated_code = F90InterfaceGenerator.apply(plugin) + generated_code = F90InterfaceGenerator.apply(F90Interface(cffi_plugin=plugin)) return format_fortran_code(generated_code) diff --git a/tools/src/icon4pytools/py2fgen/parsing.py b/tools/src/icon4pytools/py2fgen/parsing.py index eb22becc8d..1cc8ede610 100644 --- a/tools/src/icon4pytools/py2fgen/parsing.py +++ b/tools/src/icon4pytools/py2fgen/parsing.py @@ -27,7 +27,7 @@ from icon4pytools.py2fgen.utils import parse_type_spec -class ImportExtractor(ast.NodeVisitor): +class ImportStmtVisitor(ast.NodeVisitor): """AST Visitor to extract import statements.""" def __init__(self): @@ -48,8 +48,8 @@ def visit_ImportFrom(self, node): self.import_statements.append(import_statement) -class FuncDefVisitor(ast.NodeVisitor): - """AST Visitor to extract function definitions and type hints.""" +class TypeHintVisitor(ast.NodeVisitor): + """AST Visitor to extract function parameter type hints.""" def __init__(self): self.type_hints: dict[str, str] = {} @@ -59,20 +59,36 @@ def visit_FunctionDef(self, node): if arg.annotation: annotation = ast.unparse(arg.annotation) self.type_hints[arg.arg] = annotation + else: + raise TypeError( + f"Missing type hint for parameter '{arg.arg}' in function '{node.name}'" + ) -def parse(module_name: str, function_name: str) -> CffiPlugin: +def parse(module_name: str, functions: list[str], plugin_name: str) -> CffiPlugin: module = importlib.import_module(module_name) - parsed_function = _parse_function(module, function_name) parsed_imports = _extract_import_statements(module) + + parsed_functions: list[Func] = [] + for f in functions: + parsed_functions.append(_parse_function(module, f)) + return CffiPlugin( module_name=module_name, - plugin_name=f"{function_name}_plugin", - function=parsed_function, + plugin_name=plugin_name, + functions=parsed_functions, imports=parsed_imports, ) +def _extract_import_statements(module: ModuleType) -> list[str]: + src = inspect.getsource(module) + tree = ast.parse(src) + visitor = ImportStmtVisitor() + visitor.visit(tree) + return visitor.import_statements + + def _parse_function(module: ModuleType, function_name: str) -> Func: func = unwrap(getattr(module, function_name)) is_gt4py_program = isinstance(func, Program) @@ -87,6 +103,32 @@ def _parse_function(module: ModuleType, function_name: str) -> Func: return Func(name=function_name, args=params, is_gt4py_program=is_gt4py_program) +def _extract_type_hint_strings( + module: ModuleType, func: Callable, is_gt4py_program: bool, function_name: str +): + src = extract_function_signature( + inspect.getsource(module) if is_gt4py_program else inspect.getsource(func), function_name + ) + tree = ast.parse(src) + visitor = TypeHintVisitor() + visitor.visit(tree) + return visitor.type_hints + + +def extract_function_signature(code: str, function_name: str) -> str: + # This pattern attempts to match function definitions + pattern = rf"\bdef\s+{re.escape(function_name)}\s*\(([\s\S]*?)\)\s*:" + + match = re.search(pattern, code) + + if match: + # Constructing the full signature with empty return for ease of parsing by AST visitor + signature = match.group() + return signature.strip() + "\n return None" + else: + raise Exception(f"Could not parse function signature from the following code:\n {code}") + + def _get_gt4py_func_params(func: Program, type_hints: dict[str, str]) -> List[FuncParameter]: return [ FuncParameter( @@ -113,37 +155,3 @@ def _get_simple_func_params(func: Callable, type_hints: dict[str, str]) -> List[ ) for s, param in sig_params.items() ] - - -def _extract_type_hint_strings( - module: ModuleType, func: Callable, is_gt4py_program: bool, function_name: str -): - src = extract_function_signature( - inspect.getsource(module) if is_gt4py_program else inspect.getsource(func), function_name - ) - tree = ast.parse(src) - visitor = FuncDefVisitor() - visitor.visit(tree) - return visitor.type_hints - - -def extract_function_signature(code: str, function_name: str) -> str: - # This pattern attempts to match function definitions - pattern = rf"\bdef\s+{re.escape(function_name)}\s*\(([\s\S]*?)\)\s*:" - - match = re.search(pattern, code) - - if match: - # Constructing the full signature with empty return for ease of parsing by AST visitor - signature = match.group() - return signature.strip() + "\n return None" - else: - raise Exception(f"Could not parse function signature from the following code:\n {code}") - - -def _extract_import_statements(module: ModuleType) -> list[str]: - src = inspect.getsource(module) - tree = ast.parse(src) - visitor = ImportExtractor() - visitor.visit(tree) - return visitor.import_statements diff --git a/tools/src/icon4pytools/py2fgen/plugin.py b/tools/src/icon4pytools/py2fgen/plugin.py new file mode 100644 index 0000000000..8a85c90594 --- /dev/null +++ b/tools/src/icon4pytools/py2fgen/plugin.py @@ -0,0 +1,182 @@ +# ICON4Py - ICON inspired code in Python and GT4Py +# +# Copyright (c) 2022, ETH Zurich and MeteoSwiss +# All rights reserved. +# +# This file is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or any later +# version. See the LICENSE.txt file at the top-level directory of this +# distribution for a copy of the license or check . +# +# SPDX-License-Identifier: GPL-3.0-or-later +import logging +import typing +from pathlib import Path + +import cffi +import numpy as np +from cffi import FFI +from numpy.typing import NDArray + +from icon4pytools.common.logger import setup_logger + + +if typing.TYPE_CHECKING: + import cupy as cp # type: ignore + +ffi = FFI() # needed for unpack and unpack_gpu functions + +logger = setup_logger(__name__) + + +def unpack(ptr, *sizes: int) -> NDArray: + """ + Converts a C pointer into a NumPy array to directly manipulate memory allocated in Fortran. + This function is needed for operations requiring in-place modification of CPU data, enabling + changes made in Python to reflect immediately in the original Fortran memory space. + + Args: + ptr (CData): A CFFI pointer to the beginning of the data array in CPU memory. This pointer + should reference a contiguous block of memory whose total size matches the product + of the specified dimensions. + *sizes (int): Variable length argument list specifying the dimensions of the array. + These sizes determine the shape of the resulting NumPy array. + + Returns: + np.ndarray: A NumPy array that provides a direct view of the data pointed to by `ptr`. + This array shares the underlying data with the original Fortran code, allowing + modifications made through the array to affect the original data. + """ + length = np.prod(sizes) + c_type = ffi.getctype(ffi.typeof(ptr).item) + + # Map C data types to NumPy dtypes + dtype_map: dict[str, np.dtype] = { + "int": np.dtype(np.int32), + "double": np.dtype(np.float64), + } + dtype = dtype_map.get(c_type, np.dtype(c_type)) + + # Create a NumPy array from the buffer, specifying the Fortran order + arr = np.frombuffer(ffi.buffer(ptr, length * ffi.sizeof(c_type)), dtype=dtype).reshape( # type: ignore + sizes, order="F" + ) + return arr + + +def unpack_gpu(ptr, *sizes: int): + """ + Converts a C pointer into a CuPy array to directly manipulate memory allocated in Fortran. + This function is needed for operations that require in-place modification of GPU data, + enabling changes made in Python to reflect immediately in the original Fortran memory space. + + Args: + ptr (cffi.CData): A CFFI pointer to GPU memory allocated by OpenACC, representing + the starting address of the data. This pointer must correspond to + a contiguous block of memory whose total size matches the product + of the specified dimensions. + *sizes (int): Variable length argument list specifying the dimensions of the array. + These sizes determine the shape of the resulting CuPy array. + + Returns: + cp.ndarray: A CuPy array that provides a direct view of the data pointed to by `ptr`. + This array shares the underlying data with the original Fortran code, allowing + modifications made through the array to affect the original data. + """ + + if not sizes: + raise ValueError("Sizes must be provided to determine the array shape.") + + length = np.prod(sizes) + c_type = ffi.getctype(ffi.typeof(ptr).item) + + dtype_map = { + "int": cp.int32, + "double": cp.float64, + } + dtype = dtype_map.get(c_type, None) + if dtype is None: + raise ValueError(f"Unsupported C data type: {c_type}") + + itemsize = ffi.sizeof(c_type) + total_size = length * itemsize + + # cupy array from OpenACC device pointer + current_device = cp.cuda.Device() + ptr_val = int(ffi.cast("uintptr_t", ptr)) + mem = cp.cuda.UnownedMemory(ptr_val, total_size, owner=ptr, device_id=current_device.id) + memptr = cp.cuda.MemoryPointer(mem, 0) + arr = cp.ndarray(shape=sizes, dtype=dtype, memptr=memptr, order="F") + + return arr + + +def int_array_to_bool_array(int_array: NDArray) -> NDArray: + """ + Converts a NumPy array of integers to a boolean array. + In the input array, 0 represents False, and any non-zero value (1 or -1) represents True. + + Args: + int_array: A NumPy array of integers. + + Returns: + A NumPy array of booleans. + """ + bool_array = int_array != 0 + return bool_array + + +def generate_and_compile_cffi_plugin( + plugin_name: str, c_header: str, python_wrapper: str, build_path: Path +) -> None: + """ + Create and compile a CFFI plugin. + + This function generates a C shared library and Fortran interface for Python functions + to be exposed in the {plugin_name} module. It creates a linkable C library named + 'lib{plugin_name}.so' in the specified build directory. + + Args: + plugin_name: Name of the plugin. + c_header: C header signatures for the Python functions. + python_wrapper: Python code wrapping the original function to be exposed. + build_path: Path to the build directory. + """ + try: + header_file_path = write_c_header(build_path, plugin_name, c_header) + compile_cffi_plugin( + builder=configure_cffi_builder(c_header, plugin_name, header_file_path), + python_wrapper=python_wrapper, + build_path=str(build_path), + plugin_name=plugin_name, + ) + except Exception as e: + logging.error(f"Error generating and compiling CFFI plugin: {e}") + raise + + +def write_c_header(build_path: Path, plugin_name: str, c_header: str) -> Path: + """Write the C header file to the specified path.""" + c_header_file = plugin_name + ".h" + header_file_path = build_path / c_header_file + with open(header_file_path, "w") as f: + f.write(c_header) + return header_file_path + + +def configure_cffi_builder(c_header: str, plugin_name: str, header_file_path: Path) -> cffi.FFI: + """Configure and returns a CFFI FFI builder instance.""" + builder = cffi.FFI() + builder.embedding_api(c_header) + builder.set_source(plugin_name, f'#include "{header_file_path.name}"') + return builder + + +def compile_cffi_plugin( + builder: cffi.FFI, python_wrapper: str, build_path: str, plugin_name: str +) -> None: + """Compile the CFFI plugin with the given configuration.""" + logger.info("Compiling CFFI dynamic library...") + builder.embedding_init_code(python_wrapper) + builder.compile(tmpdir=build_path, target=f"lib{plugin_name}.*", verbose=True) diff --git a/tools/src/icon4pytools/py2fgen/template.py b/tools/src/icon4pytools/py2fgen/template.py index 81652efcb8..b2be3fbbda 100644 --- a/tools/src/icon4pytools/py2fgen/template.py +++ b/tools/src/icon4pytools/py2fgen/template.py @@ -11,19 +11,20 @@ # # SPDX-License-Identifier: GPL-3.0-or-later import inspect -from typing import Any, Optional, Sequence +from typing import Any, Sequence from gt4py.eve import Node, datamodels from gt4py.eve.codegen import JinjaTemplate as as_jinja, TemplatedGenerator from gt4py.next import Dimension from gt4py.next.type_system.type_specifications import ScalarKind +from icon4py.model.common.config import GT4PyBackend from icon4pytools.icon4pygen.bindings.codegen.type_conversion import ( BUILTIN_TO_CPP_TYPE, BUILTIN_TO_ISO_C_TYPE, ) -from icon4pytools.py2fgen.cffi import unpack -from icon4pytools.py2fgen.utils import build_array_size_args, flatten_and_get_unique_elts +from icon4pytools.py2fgen.plugin import int_array_to_bool_array, unpack, unpack_gpu +from icon4pytools.py2fgen.utils import flatten_and_get_unique_elts CFFI_DECORATOR = "@ffi.def_extern()" @@ -47,7 +48,12 @@ class FuncParameter(Node): def __post_init__(self): self.size_args = dims_to_size_strings(self.dimensions) self.is_array = True if len(self.dimensions) >= 1 else False - self.gtdims = [dimension.value + "Dim" for dimension in self.dimensions] + # We need some fields to have nlevp1 levels on the fortran wrapper side, which we make + # happen by using KHalfDim as a type hint. However, this is not yet supported on the icon4py + # side. So before generating the python wrapper code, we replace occurences of KHalfDim with KDim + self.gtdims = [ + dimension.value.replace("KHalf", "K") + "Dim" for dimension in self.dimensions + ] class Func(Node): @@ -66,14 +72,36 @@ class CffiPlugin(Node): module_name: str plugin_name: str imports: list[str] - function: Func + functions: list[Func] class PythonWrapper(CffiPlugin): - gt4py_backend: Optional[str] + backend: str debug_mode: bool cffi_decorator: str = CFFI_DECORATOR cffi_unpack: str = inspect.getsource(unpack) + cffi_unpack_gpu: str = inspect.getsource(unpack_gpu) + int_to_bool: str = inspect.getsource(int_array_to_bool_array) + gt4py_backend: str = datamodels.field(init=False) + is_gt4py_program_present: bool = datamodels.field(init=False) + + def __post_init__(self, *args: Any, **kwargs: Any) -> None: + self.gt4py_backend = GT4PyBackend[self.backend].value + self.is_gt4py_program_present = any(func.is_gt4py_program for func in self.functions) + + +def build_array_size_args() -> dict[str, str]: + array_size_args = {} + from icon4py.model.common import dimension + + for var_name, var in vars(dimension).items(): + if isinstance(var, Dimension): + dim_name = var_name.replace( + "Dim", "" + ) # Assumes we keep suffixing each Dimension with Dim in icon4py.common.dimension module + size_name = f"n_{dim_name}" + array_size_args[dim_name] = size_name + return array_size_args def to_c_type(scalar_type: ScalarKind) -> str: @@ -81,7 +109,7 @@ def to_c_type(scalar_type: ScalarKind) -> str: return BUILTIN_TO_CPP_TYPE[scalar_type] -def to_f_type(scalar_type: ScalarKind) -> str: +def to_iso_c_type(scalar_type: ScalarKind) -> str: """Convert a scalar type to its corresponding ISO C type.""" return BUILTIN_TO_ISO_C_TYPE[scalar_type] @@ -104,7 +132,7 @@ def render_c_pointer(param: FuncParameter) -> str: return "*" if len(param.dimensions) > 0 else "" -def render_fortran_array_dimensions(param: FuncParameter) -> str: +def render_fortran_array_dimensions(param: FuncParameter, assumed_size_array: bool) -> str: """ Render Fortran array dimensions for array types. @@ -114,9 +142,13 @@ def render_fortran_array_dimensions(param: FuncParameter) -> str: Returns: A string representing Fortran array dimensions. """ - if len(param.dimensions) > 0: + if len(param.dimensions) > 0 and assumed_size_array: + return "dimension(*)," + + if len(param.dimensions) > 0 and not assumed_size_array: dims = ",".join(":" for _ in param.dimensions) return f"dimension({dims})," + return "" @@ -162,77 +194,144 @@ def render_fortran_array_sizes(param: FuncParameter) -> str: class PythonWrapperGenerator(TemplatedGenerator): PythonWrapper = as_jinja( """\ -# necessary imports for generated code to work +# imports for generated wrapper code +import logging from {{ plugin_name }} import ffi import numpy as np -from gt4py.next.ffront.fbuiltins import int32 +{% if _this_node.backend == 'GPU' %}import cupy as cp {% endif %} +from numpy.typing import NDArray from gt4py.next.iterator.embedded import np_as_located_field -from gt4py.next.program_processors.runners.gtfn import run_gtfn, run_gtfn_gpu + +{% if _this_node.is_gt4py_program_present %} +# necessary imports when embedding a gt4py program directly +from gt4py.next.program_processors.runners.gtfn import run_gtfn_cached, run_gtfn_gpu_cached from gt4py.next.program_processors.runners.roundtrip import backend as run_roundtrip from icon4py.model.common.grid.simple import SimpleGrid -# all other imports from the module from which the function is being wrapped +# We need a grid to pass offset providers to the embedded gt4py program (granules load their own grid at runtime) +grid = SimpleGrid() +{% endif %} + +# logger setup +log_format = '%(asctime)s.%(msecs)03d - %(levelname)s - %(message)s' +logging.basicConfig(level=logging.{%- if _this_node.debug_mode -%}DEBUG{%- else -%}ERROR{%- endif -%}, + format=log_format, + datefmt='%Y-%m-%d %H:%M:%S') +{% if _this_node.backend == 'GPU' %}logging.info(cp.show_config()) {% endif %} + +# embedded module imports {% for stmt in imports -%} {{ stmt }} {% endfor %} -# We need a grid to pass offset providers -grid = SimpleGrid() - -from {{ module_name }} import {{ _this_node.function.name }} +# embedded function imports +{% for func in _this_node.functions -%} +from {{ module_name }} import {{ func.name }} +{% endfor %} +{% if _this_node.backend == 'GPU' %} +{{ cffi_unpack_gpu }} +{% else %} {{ cffi_unpack }} +{% endif %} + +{{ int_to_bool }} + +{% for func in _this_node.functions %} {{ cffi_decorator }} -def {{ _this_node.function.name }}_wrapper( -{%- for arg in _this_node.function.args -%} -{{ arg.name }}: {{ arg.py_type_hint }}{% if not loop.last or _this_node.function.global_size_args %}, {% endif %} +def {{ func.name }}_wrapper( +{%- for arg in func.args -%} +{{ arg.name }}: {{ arg.py_type_hint | replace("KHalfDim","KDim") }}{% if not loop.last or func.global_size_args %}, {% endif %} {%- endfor %} -{%- for arg in _this_node.function.global_size_args -%} +{%- for arg in func.global_size_args -%} {{ arg }}: int32{{ ", " if not loop.last else "" }} {%- endfor -%} ): + try: + {%- if _this_node.debug_mode %} + logging.info("Python Execution Context Start") + {% endif %} + + # Unpack pointers into Ndarrays + {% for arg in func.args %} + {% if arg.is_array %} + {%- if _this_node.debug_mode %} + msg = '{{ arg.name }} before unpacking: %s' % str({{ arg.name}}) + logging.debug(msg) + {% endif %} + {{ arg.name }} = unpack{%- if _this_node.backend == 'GPU' -%}_gpu{%- endif -%}({{ arg.name }}, {{ ", ".join(arg.size_args) }}) + + {%- if arg.d_type.name == "BOOL" %} + {{ arg.name }} = int_array_to_bool_array({{ arg.name }}) + {%- endif %} + + {%- if _this_node.debug_mode %} + msg = '{{ arg.name }} after unpacking: %s' % str({{ arg.name}}) + logging.debug(msg) + msg = 'shape of {{ arg.name }} after unpacking = %s' % str({{ arg.name}}.shape) + logging.debug(msg) + {% endif %} + {% endif %} + {% endfor %} + + # Allocate GT4Py Fields + {% for arg in func.args %} + {% if arg.is_array %} + {{ arg.name }} = np_as_located_field({{ ", ".join(arg.gtdims) }})({{ arg.name }}) + {%- if _this_node.debug_mode %} + msg = 'shape of {{ arg.name }} after allocating as field = %s' % str({{ arg.name}}.shape) + logging.debug(msg) + msg = '{{ arg.name }} after allocating as field: %s' % str({{ arg.name }}.ndarray) + logging.debug(msg) + {% endif %} + {% endif %} + {% endfor %} + + {{ func.name }} + {%- if func.is_gt4py_program -%}.with_backend({{ _this_node.gt4py_backend }}){%- endif -%}( + {%- for arg in func.args -%} + {{ arg.name }}{{ ", " if not loop.last or func.is_gt4py_program else "" }} + {%- endfor -%} + {%- if func.is_gt4py_program -%} + offset_provider=grid.offset_providers + {%- endif -%} + ) - # Unpack pointers into Ndarrays - {% for arg in _this_node.function.args %} - {% if arg.is_array %} - {{ arg.name }} = unpack({{ arg.name }}, {{ ", ".join(arg.size_args) }}) - {%- if _this_node.debug_mode %} - msg = 'shape of {{ arg.name }} = %s' % str({{ arg.name}}.shape) - print(msg) - {% endif %} - {% endif %} - {% endfor %} + {% if _this_node.debug_mode %} + # debug info + {% for arg in func.args %} + {% if arg.is_array %} + msg = 'shape of {{ arg.name }} after computation = %s' % str({{ arg.name}}.shape) + logging.debug(msg) + msg = '{{ arg.name }} after computation: %s' % str({{ arg.name }}.ndarray) + logging.debug(msg) + {% endif %} + {% endfor %} + {% endif %} + + {%- if _this_node.debug_mode %} + logging.info("Python Execution Context End") + {% endif %} + + except Exception as e: + logging.exception(f"A Python error occurred: {e}") + return 1 + + return 0 + + {% endfor %} - # Allocate GT4Py Fields - {% for arg in _this_node.function.args %} - {% if arg.is_array %} - {{ arg.name }} = np_as_located_field({{ ", ".join(arg.gtdims) }})({{ arg.name }}) - {%- if _this_node.debug_mode %} - print({{ arg.name }}) - print({{ arg.name }}.shape) - {% endif %} - {% endif %} - {% endfor %} - {{ _this_node.function.name }} - {%- if _this_node.function.is_gt4py_program -%}.with_backend({{ _this_node.gt4py_backend }}){%- endif -%}( - {%- for arg in _this_node.function.args -%} - {{ arg.name }}{{ ", " if not loop.last or _this_node.function.is_gt4py_program else "" }} - {%- endfor -%} - {%- if _this_node.function.is_gt4py_program -%} - offset_provider=grid.offset_providers - {%- endif -%} -) """ ) class CHeaderGenerator(TemplatedGenerator): - CffiPlugin = as_jinja("""extern void {{_this_node.function.name}}_wrapper({{function}});""") + CffiPlugin = as_jinja("""{{'\n'.join(functions)}}""") Func = as_jinja( - "{%- for arg in args -%}{{ arg }}{% if not loop.last or global_size_args|length > 0 %}, {% endif %}{% endfor -%}{%- for sarg in global_size_args -%} int {{ sarg }}{% if not loop.last %}, {% endif %}{% endfor -%}" + "extern int {{ name }}_wrapper({%- for arg in args -%}{{ arg }}{% if not loop.last or global_size_args|length > 0 %}, {% endif %}{% endfor -%}{%- for sarg in global_size_args -%} int {{ sarg }}{% if not loop.last %}, {% endif %}{% endfor -%});" ) def visit_FuncParameter(self, param: FuncParameter): @@ -243,38 +342,134 @@ def visit_FuncParameter(self, param: FuncParameter): FuncParameter = as_jinja("""{{rendered_type}}{{pointer}} {{name}}""") +class F90FunctionDeclaration(Func): + def __post_init__(self, *args: Any, **kwargs: Any) -> None: + super().__post_init__() # call Func __post_init__ + + +class DimensionPosition(Node): + variable: str + size_arg: str + index: int + + +class F90FunctionDefinition(Func): + dimension_size_declarations: Sequence[DimensionPosition] = datamodels.field(init=False) + + def __post_init__(self, *args: Any, **kwargs: Any) -> None: + super().__post_init__() # call Func __post_init__ + + dim_positions = [] + for arg in self.args: + for index, size_arg in enumerate(arg.size_args): + dim_positions.append( + DimensionPosition(variable=str(arg.name), size_arg=size_arg, index=index + 1) + ) # Use Fortran indexing + + self.dimension_size_declarations = dim_positions + + +class F90Interface(Node): + cffi_plugin: CffiPlugin + function_declaration: list[F90FunctionDeclaration] = datamodels.field(init=False) + function_definition: list[F90FunctionDefinition] = datamodels.field(init=False) + + def __post_init__(self, *args: Any, **kwargs: Any) -> None: + functions = self.cffi_plugin.functions + self.function_declaration = [ + F90FunctionDeclaration(name=f.name, args=f.args, is_gt4py_program=f.is_gt4py_program) + for f in functions + ] + self.function_definition = [ + F90FunctionDefinition(name=f.name, args=f.args, is_gt4py_program=f.is_gt4py_program) + for f in functions + ] + + class F90InterfaceGenerator(TemplatedGenerator): - CffiPlugin = as_jinja( + F90Interface = as_jinja( """\ - module {{ plugin_name }} - use, intrinsic:: iso_c_binding +module {{ _this_node.cffi_plugin.plugin_name }} + use, intrinsic :: iso_c_binding implicit none - public - interface - {{ function }} - end interface - end module - """ + {% for func in _this_node.cffi_plugin.functions %} + public :: {{ func.name }} + {% endfor %} + +interface + {{ '\n'.join(function_declaration) }} +end interface + +contains + {{ '\n'.join(function_definition) }} +end module +""" ) - def visit_Func(self, func: Func, **kwargs): + def visit_F90FunctionDeclaration(self, func: F90FunctionDeclaration, **kwargs): arg_names = ", &\n ".join(map(lambda x: x.name, func.args)) if func.global_size_args: arg_names += ",&\n" + ", &\n".join(func.global_size_args) + return self.generic_visit(func, assumed_size_array=True, param_names=arg_names) + + F90FunctionDeclaration = as_jinja( + """ +function {{name}}_wrapper({{param_names}}) bind(c, name="{{name}}_wrapper") result(rc) + import :: c_int, c_double, c_bool, c_ptr + {% for size_arg in global_size_args %} + integer(c_int), value :: {{ size_arg }} + {% endfor %} + integer(c_int) :: rc ! Stores the return code + {% for arg in args %} + {{ arg }} + {% endfor %} +end function {{name}}_wrapper + """ + ) - return self.generic_visit(func, param_names=arg_names) + def visit_F90FunctionDefinition(self, func: F90FunctionDefinition, **kwargs): + if len(func.args) < 1: + arg_names, param_names_with_size_args = "", "" + else: + arg_names = ", &\n ".join(map(lambda x: x.name, func.args)) + param_names_with_size_args = arg_names + ",&\n" + ", &\n".join(func.global_size_args) - Func = as_jinja( - """subroutine {{name}}_wrapper({{param_names}}) bind(c, name='{{name}}_wrapper') - use, intrinsic :: iso_c_binding - {% for size_arg in global_size_args -%} - integer(c_int), value, target :: {{ size_arg }} - {% endfor %} - {% for arg in args: %}\ - {{arg}}\ - {% endfor %}\ - end subroutine {{name}}_wrapper + return self.generic_visit( + func, + assumed_size_array=False, + param_names=arg_names, + param_names_with_size_args=param_names_with_size_args, + arrays=[arg for arg in func.args if arg.is_array], + ) + + # todo(samkellerhals): Consider using unique SIZE args + F90FunctionDefinition = as_jinja( + """ +subroutine {{name}}({{param_names}}, &\nrc) + use, intrinsic :: iso_c_binding + {% for size_arg in global_size_args %} + integer(c_int) :: {{ size_arg }} + {% endfor %} + {% for arg in args %} + {{ arg }} + {% endfor %} + integer(c_int) :: rc ! Stores the return code + + !$ACC host_data use_device( & + {%- for arr in arrays %} + !$ACC {{ arr.name }}{% if not loop.last %}, &{% else %} &{% endif %} + {%- endfor %} + !$ACC ) + + {% for d in _this_node.dimension_size_declarations %} + {{ d.size_arg }} = SIZE({{ d.variable }}, {{ d.index }}) + {% endfor %} + + rc = {{ name }}_wrapper({{ param_names_with_size_args }}) + + !$acc end host_data +end subroutine {{name}} """ ) @@ -282,12 +477,9 @@ def visit_FuncParameter(self, param: FuncParameter, **kwargs): return self.generic_visit( param, value=as_f90_value(param), - rendered_type=to_f_type(param.d_type), - dim=render_fortran_array_dimensions(param), + iso_c_type=to_iso_c_type(param.d_type), + dim=render_fortran_array_dimensions(param, kwargs["assumed_size_array"]), explicit_size=render_fortran_array_sizes(param), ) - FuncParameter = as_jinja( - """{{rendered_type}}, {{dim}} {{value}} target :: {{name}}{{ explicit_size }} - """ - ) + FuncParameter = as_jinja("""{{iso_c_type}}, {{dim}} {{value}} target :: {{name}}""") diff --git a/tools/src/icon4pytools/py2fgen/utils.py b/tools/src/icon4pytools/py2fgen/utils.py index 28923c776f..0313c04aa6 100644 --- a/tools/src/icon4pytools/py2fgen/utils.py +++ b/tools/src/icon4pytools/py2fgen/utils.py @@ -10,33 +10,14 @@ # distribution for a copy of the license or check . # # SPDX-License-Identifier: GPL-3.0-or-later - -from enum import Enum +import importlib +import os +from pathlib import Path from gt4py.next.common import Dimension from gt4py.next.type_system.type_specifications import FieldType, ScalarKind, ScalarType, TypeSpec -def build_array_size_args() -> dict[str, str]: - array_size_args = {} - from icon4py.model.common import dimension - - for var_name, var in vars(dimension).items(): - if isinstance(var, Dimension): - dim_name = var_name.replace( - "Dim", "" - ) # Assumes we keep suffixing each Dimension with Dim - size_name = f"n_{dim_name}" - array_size_args[dim_name] = size_name - return array_size_args - - -class Backend(Enum): - CPU = "run_gtfn" - GPU = "run_gtfn_gpu" - ROUNDTRIP = "run_roundtrip" - - def parse_type_spec(type_spec: TypeSpec) -> tuple[list[Dimension], ScalarKind]: if isinstance(type_spec, ScalarType): return [], type_spec.kind @@ -48,3 +29,34 @@ def parse_type_spec(type_spec: TypeSpec) -> tuple[list[Dimension], ScalarKind]: def flatten_and_get_unique_elts(list_of_lists: list[list[str]]) -> list[str]: return sorted(set(item for sublist in list_of_lists for item in sublist)) + + +def get_local_test_grid(): + test_folder = "testdata" + module_spec = importlib.util.find_spec("icon4pytools") + + if module_spec and module_spec.origin: + # following namespace package conventions the root is three levels down + repo_root = Path(module_spec.origin).parents[3] + return os.path.join(repo_root, test_folder) + else: + raise FileNotFoundError( + "The `icon4pytools` package could not be found. Ensure the package is installed " + "and accessible. Alternatively, set the 'ICON_GRID_LOC' environment variable " + "explicitly to specify the location." + ) + + +def get_icon_grid_loc(): + env_path = os.environ.get("ICON_GRID_LOC") + if env_path is not None: + return env_path + else: + return get_local_test_grid() + + +def get_grid_filename(): + env_path = os.environ.get("ICON_GRID_NAME") + if env_path is not None: + return env_path + return "grid.nc" diff --git a/tools/src/icon4pytools/py2fgen/wrappers/diffusion.py b/tools/src/icon4pytools/py2fgen/wrappers/diffusion.py index 8a8cb6ed71..855236c890 100644 --- a/tools/src/icon4pytools/py2fgen/wrappers/diffusion.py +++ b/tools/src/icon4pytools/py2fgen/wrappers/diffusion.py @@ -10,10 +10,7 @@ # distribution for a copy of the license or check . # # SPDX-License-Identifier: GPL-3.0-or-later -# flake8: noqa - -# We use gt4py type annotations and thus need to ignore this in MyPy -# mypy: disable-error-code="valid-type" +# type: ignore """ Wrapper module for diffusion granule. @@ -24,202 +21,189 @@ - passing of scalar types or fields of simple types """ -import numpy as np from gt4py.next.common import Field -from gt4py.next.ffront.fbuiltins import int32 +from gt4py.next.ffront.fbuiltins import float64, int32 from icon4py.model.atmosphere.diffusion.diffusion import ( Diffusion, DiffusionConfig, + DiffusionParams, + TurbulenceShearForcingType, +) +from icon4py.model.atmosphere.diffusion.diffusion_states import ( DiffusionDiagnosticState, DiffusionInterpolationState, DiffusionMetricState, - DiffusionParams, - DiffusionType, ) from icon4py.model.common.dimension import ( C2E2CDim, C2E2CODim, C2EDim, CECDim, + CEDim, CellDim, E2C2VDim, E2CDim, - E2VDim, ECVDim, EdgeDim, KDim, + KHalfDim, V2EDim, VertexDim, ) -from icon4py.model.common.grid.base import GridConfig -from icon4py.model.common.grid.horizontal import CellParams, EdgeParams, HorizontalGridSize -from icon4py.model.common.grid.icon import IconGrid -from icon4py.model.common.grid.vertical import VerticalGridSize, VerticalModelParams +from icon4py.model.common.grid.horizontal import CellParams, EdgeParams +from icon4py.model.common.grid.vertical import VerticalModelParams +from icon4py.model.common.settings import device from icon4py.model.common.states.prognostic_state import PrognosticState +from icon4py.model.common.test_utils.grid_utils import _load_from_gridfile +from icon4py.model.common.test_utils.helpers import as_1D_sparse_field, flatten_first_two_dims +from icon4pytools.common.logger import setup_logger +from icon4pytools.py2fgen.utils import get_grid_filename, get_icon_grid_loc -# TODO (magdalena) Revise interface architecture with Fortran granules: -# The module variable to match the Fortran interface: where only fields are passed. -# We should rather instantiate the object init and return it. -diffusion: Diffusion() -nproma = 50000 -field_sizes = {EdgeDim: nproma, CellDim: nproma, VertexDim: nproma} +logger = setup_logger(__name__) + +# global diffusion object +diffusion_granule: Diffusion = Diffusion() def diffusion_init( - nproma: int, - nlev: int, - n_shift_total: int, - nrdmax: float, - n_dyn_substeps: int, - nudge_max_coeff: float, - denom_diffu_v: float, - hdiff_smag_fac: float, - hdiff_order: int, - hdiff_efdt_ratio: float, - itype_sher: int, - itype_vn_diffu: int, - itype_t_diffu: int, - lhdiff_w: bool, - lhdiff_temp: bool, - l_limited_area: bool, - l_zdiffu_t: bool, - lsmag_3d: bool, - vct_a: Field[[KDim], float], - e_bln_c_s: Field[[CellDim, C2EDim], float], - geofac_div: Field[[CellDim, C2EDim], float], - geofac_n2s: Field[[CellDim, C2E2CODim], float], - geofac_grg_x: Field[[CellDim, C2E2CODim], float], - geofac_grg_y: Field[[CellDim, C2E2CODim], float], - nudgecoeff_e: Field[[EdgeDim], float], - zd_intcoef: Field[ - [CellDim, C2E2CDim, KDim], float - ], # special DSL field: zd_intcoef_dsl in mo_vertical_grid.f90 - zd_diffcoef: Field[ - [CellDim, KDim], float - ], # special DSL field mask instead of list: zd_diffcoef_dsl in mo_vertical_grid.f90 - wgtfac_c: Field[[CellDim, KDim], float], - theta_ref_mc: Field[[CellDim, KDim], float], - edges_vertex_idx: Field[[EdgeDim, E2VDim], int32], - edges_cell_idx: Field[[EdgeDim, E2CDim], int32], - edges_tangent_orientation: Field[[EdgeDim], float], - edges_primal_normal_vert_1: Field[[ECVDim], float], # shallow derived type in Fortran - edges_primal_normal_vert_2: Field[[ECVDim], float], # shallow derived type in Fortran - edges_dual_normal_vert_1: Field[[ECVDim], float], # shallow derived type in Fortran - edges_dual_normal_vert_2: Field[[ECVDim], float], # shallow derived type in Fortran - edges_inv_vert_vert_lengths: Field[[EdgeDim], float], - edges_inv_primal_edge_length: Field[[EdgeDim], float], - edges_inv_dual_edge_length: Field[[EdgeDim], float], - edges_area_edge: Field[[EdgeDim], float], - cells_neighbor_idx: Field[[CellDim, C2E2CDim], int32], - cells_edge_idx: Field[[CellDim, C2EDim], int32], - cells_area: Field[[CellDim], float], - # dsl specific additional args - mean_cell_area: float, + vct_a: Field[[KHalfDim], float64], + theta_ref_mc: Field[[CellDim, KDim], float64], + wgtfac_c: Field[[CellDim, KHalfDim], float64], + e_bln_c_s: Field[[CellDim, C2EDim], float64], + geofac_div: Field[[CellDim, C2EDim], float64], + geofac_grg_x: Field[[CellDim, C2E2CODim], float64], + geofac_grg_y: Field[[CellDim, C2E2CODim], float64], + geofac_n2s: Field[[CellDim, C2E2CODim], float64], + nudgecoeff_e: Field[[EdgeDim], float64], + rbf_coeff_1: Field[[VertexDim, V2EDim], float64], + rbf_coeff_2: Field[[VertexDim, V2EDim], float64], mask_hdiff: Field[[CellDim, KDim], bool], - zd_vertoffset: Field[ - [CECDim], int32 - ], # vertical offsets used in DSL for absolute indices zd_vertidx in mo_vertical_grid.f90 - rbf_coeff_1: Field[[VertexDim, V2EDim], float], # -> used in rbf_vec_interpol_vertex - rbf_coeff_2: Field[[VertexDim, V2EDim], float], # -> used in rbf_vec_interpol_vertex - verts_edge_idx: Field[[VertexDim, V2EDim], int32], # -> mo_intp_rbf_rbf_vec_interpol_vertex + zd_diffcoef: Field[[CellDim, KDim], float64], + zd_vertoffset: Field[[CellDim, C2E2CDim, KDim], int32], + zd_intcoef: Field[[CellDim, C2E2CDim, KDim], float64], + num_levels: int32, + mean_cell_area: float64, + ndyn_substeps: int32, + rayleigh_damping_height: float64, + nflatlev: int32, + nflat_gradp: int32, + diffusion_type: int32, + hdiff_w: bool, + hdiff_vn: bool, + zdiffu_t: bool, + type_t_diffu: int32, + type_vn_diffu: int32, + hdiff_efdt_ratio: float64, + smagorinski_scaling_factor: float64, + hdiff_temp: bool, + tangent_orientation: Field[[EdgeDim], float64], + inverse_primal_edge_lengths: Field[[EdgeDim], float64], + inv_dual_edge_length: Field[[EdgeDim], float64], + inv_vert_vert_length: Field[[EdgeDim], float64], + edge_areas: Field[[EdgeDim], float64], + f_e: Field[[EdgeDim], float64], + cell_areas: Field[[CellDim], float64], + primal_normal_vert_x: Field[[EdgeDim, E2C2VDim], float64], + primal_normal_vert_y: Field[[EdgeDim, E2C2VDim], float64], + dual_normal_vert_x: Field[[EdgeDim, E2C2VDim], float64], + dual_normal_vert_y: Field[[EdgeDim, E2C2VDim], float64], + primal_normal_cell_x: Field[[EdgeDim, E2CDim], float64], + primal_normal_cell_y: Field[[EdgeDim, E2CDim], float64], + dual_normal_cell_x: Field[[EdgeDim, E2CDim], float64], + dual_normal_cell_y: Field[[EdgeDim, E2CDim], float64], ): - """ - Instantiate and Initialize the diffusion object. - - should only accept simple fields as arguments for compatibility with the standalone - Fortran ICON Diffusion component (aka Diffusion granule) + logger.info(f"Using Device = {device}") - """ - if diffusion.initialized: - raise DuplicateInitializationException("Diffusion has already been already initialized") + # ICON grid + if device.name == "GPU": + on_gpu = True + else: + on_gpu = False - horizontal_size = HorizontalGridSize(num_cells=nproma, num_vertices=nproma, num_edges=nproma) - vertical_size = VerticalGridSize(num_lev=nlev) - mesh_config = GridConfig( - horizontal_config=horizontal_size, - vertical_config=vertical_size, - limited_area=l_limited_area, - n_shift_total=n_shift_total, + icon_grid = _load_from_gridfile( + file_path=get_icon_grid_loc(), + filename=get_grid_filename(), + num_levels=num_levels, + on_gpu=on_gpu, ) - # we need the start, end indices in order for the grid to be functional those are not passed - # to init in the Fortran diffusion granule since they are hidden away in the get_indices_[c,e,v] - # diffusion_run does take p_patch in order to pass it on to other subroutines (interpolation, get_indices... - c2e2c0 = np.column_stack( - ( - (np.asarray(cells_neighbor_idx)), - (np.asarray(range(np.asarray(cells_neighbor_idx).shape[0]))), - ) - ) - e2c2v = np.asarray(edges_vertex_idx) - e2v = e2c2v[:, 0:2] - connectivities = { - E2CDim: np.asarray(edges_cell_idx), - E2C2VDim: e2c2v, - E2VDim: e2v, - C2EDim: np.asarray(cells_edge_idx), - C2E2CDim: (np.asarray(cells_neighbor_idx)), - C2E2CODim: c2e2c0, - V2EDim: np.asarray(verts_edge_idx), - } - # TODO (Magdalena) we need start_index, end_index: those are not passed in the fortran granules, - # because they are used through get_indices only - grid = IconGrid().with_config(mesh_config).with_connectivities(connectivities) + # Edge geometry edge_params = EdgeParams( - tangent_orientation=edges_tangent_orientation, - inverse_primal_edge_lengths=edges_inv_primal_edge_length, - dual_normal_vert_x=edges_dual_normal_vert_1, - dual_normal_vert_y=edges_dual_normal_vert_2, - inverse_dual_edge_lengths=edges_inv_dual_edge_length, - inverse_vertex_vertex_lengths=edges_inv_vert_vert_lengths, - primal_normal_vert_x=edges_primal_normal_vert_1, - primal_normal_vert_y=edges_primal_normal_vert_2, - edge_areas=edges_area_edge, + tangent_orientation=tangent_orientation, + inverse_primal_edge_lengths=inverse_primal_edge_lengths, + inverse_dual_edge_lengths=inv_dual_edge_length, + inverse_vertex_vertex_lengths=inv_vert_vert_length, + primal_normal_vert_x=as_1D_sparse_field(primal_normal_vert_x, ECVDim), + primal_normal_vert_y=as_1D_sparse_field(primal_normal_vert_y, ECVDim), + dual_normal_vert_x=as_1D_sparse_field(dual_normal_vert_x, ECVDim), + dual_normal_vert_y=as_1D_sparse_field(dual_normal_vert_y, ECVDim), + primal_normal_cell_x=as_1D_sparse_field(primal_normal_cell_x, ECVDim), + primal_normal_cell_y=as_1D_sparse_field(primal_normal_cell_y, ECVDim), + dual_normal_cell_x=as_1D_sparse_field(dual_normal_cell_x, ECVDim), + dual_normal_cell_y=as_1D_sparse_field(dual_normal_cell_y, ECVDim), + edge_areas=edge_areas, + f_e=f_e, ) - cell_params = CellParams(area=cells_area, mean_cell_area=mean_cell_area) - config: DiffusionConfig = DiffusionConfig( - diffusion_type=DiffusionType(hdiff_order), - hdiff_w=lhdiff_w, - hdiff_temp=lhdiff_temp, - type_vn_diffu=itype_vn_diffu, - smag_3d=lsmag_3d, - type_t_diffu=itype_t_diffu, + + # cell geometry + cell_params = CellParams(area=cell_areas, mean_cell_area=mean_cell_area) + + # diffusion parameters + config = DiffusionConfig( + diffusion_type=diffusion_type, + hdiff_w=hdiff_w, + hdiff_vn=hdiff_vn, + zdiffu_t=zdiffu_t, + type_t_diffu=type_t_diffu, + type_vn_diffu=type_vn_diffu, hdiff_efdt_ratio=hdiff_efdt_ratio, - hdiff_w_efdt_ratio=hdiff_efdt_ratio, - smagorinski_scaling_factor=hdiff_smag_fac, - n_substeps=n_dyn_substeps, - zdiffu_t=l_zdiffu_t, - velocity_boundary_diffusion_denom=denom_diffu_v, - max_nudging_coeff=nudge_max_coeff, + smagorinski_scaling_factor=smagorinski_scaling_factor, + hdiff_temp=hdiff_temp, + n_substeps=ndyn_substeps, + thslp_zdiffu=0.02, + thhgtd_zdiffu=125.0, + velocity_boundary_diffusion_denom=150.0, + max_nudging_coeff=0.075, + shear_type=TurbulenceShearForcingType.VERTICAL_HORIZONTAL_OF_HORIZONTAL_VERTICAL_WIND, + ) + + diffusion_params = DiffusionParams(config) + + # vertical parameters + vertical_params = VerticalModelParams( + vct_a=vct_a, + rayleigh_damping_height=rayleigh_damping_height, + nflatlev=nflatlev, + nflat_gradp=nflat_gradp, ) - vertical_params = VerticalModelParams(vct_a=vct_a, rayleigh_damping_height=nrdmax) - derived_diffusion_params = DiffusionParams(config) + # metric state metric_state = DiffusionMetricState( + mask_hdiff=mask_hdiff, theta_ref_mc=theta_ref_mc, wgtfac_c=wgtfac_c, - mask_hdiff=mask_hdiff, - zd_vertoffset=zd_vertoffset, + zd_intcoef=flatten_first_two_dims(CECDim, KDim, field=zd_intcoef), + zd_vertoffset=flatten_first_two_dims(CECDim, KDim, field=zd_vertoffset), zd_diffcoef=zd_diffcoef, - zd_intcoef=zd_intcoef, ) + + # interpolation state interpolation_state = DiffusionInterpolationState( - e_bln_c_s, - rbf_coeff_1, - rbf_coeff_2, - geofac_div, - geofac_n2s, - geofac_grg_x, - geofac_grg_y, - nudgecoeff_e, + e_bln_c_s=as_1D_sparse_field(e_bln_c_s, CEDim), + rbf_coeff_1=rbf_coeff_1, + rbf_coeff_2=rbf_coeff_2, + geofac_div=as_1D_sparse_field(geofac_div, CEDim), + geofac_n2s=geofac_n2s, + geofac_grg_x=geofac_grg_x, + geofac_grg_y=geofac_grg_y, + nudgecoeff_e=nudgecoeff_e, ) - - diffusion.init( - grid=grid, + diffusion_granule.init( + grid=icon_grid, config=config, - params=derived_diffusion_params, + params=diffusion_params, vertical_params=vertical_params, metric_state=metric_state, interpolation_state=interpolation_state, @@ -229,37 +213,41 @@ def diffusion_init( def diffusion_run( - dtime: float, + w: Field[[CellDim, KHalfDim], float64], + vn: Field[[EdgeDim, KDim], float64], + exner: Field[[CellDim, KDim], float64], + theta_v: Field[[CellDim, KDim], float64], + rho: Field[[CellDim, KDim], float64], + hdef_ic: Field[[CellDim, KHalfDim], float64], + div_ic: Field[[CellDim, KHalfDim], float64], + dwdx: Field[[CellDim, KHalfDim], float64], + dwdy: Field[[CellDim, KHalfDim], float64], + dtime: float64, linit: bool, - vn: Field[[EdgeDim, KDim], float], - w: Field[[CellDim, KDim], float], - theta_v: Field[[CellDim, KDim], float], - exner: Field[[CellDim, KDim], float], - div_ic: Field[[CellDim, KDim], float], - hdef_ic: Field[[CellDim, KDim], float], - dwdx: Field[[CellDim, KDim], float], - dwdy: Field[[CellDim, KDim], float], - rho: Field[[CellDim, KDim], float], ): - diagnostic_state = DiffusionDiagnosticState(hdef_ic, div_ic, dwdx, dwdy) + # prognostic and diagnostic variables prognostic_state = PrognosticState( - rho=rho, w=w, vn=vn, exner=exner, theta_v=theta_v, + rho=rho, ) + + diagnostic_state = DiffusionDiagnosticState( + hdef_ic=hdef_ic, + div_ic=div_ic, + dwdx=dwdx, + dwdy=dwdy, + ) + if linit: - diffusion.initial_run( + diffusion_granule.initial_run( diagnostic_state, prognostic_state, dtime, ) else: - diffusion.run(diagnostic_state, prognostic_state, dtime) - - -class DuplicateInitializationException(Exception): - """Raised if the component is already initilalized.""" - - pass + diffusion_granule.run( + prognostic_state=prognostic_state, diagnostic_state=diagnostic_state, dtime=dtime + ) diff --git a/tools/src/icon4pytools/py2fgen/wrappers/simple.py b/tools/src/icon4pytools/py2fgen/wrappers/simple.py index 0b66da34b5..f7e072ff02 100644 --- a/tools/src/icon4pytools/py2fgen/wrappers/simple.py +++ b/tools/src/icon4pytools/py2fgen/wrappers/simple.py @@ -78,3 +78,10 @@ def multi_return( KDim: (vertical_start, vertical_end), }, ) + + +def square_error( + inp: Field[[CellDim, KDim], float64], + result: Field[[CellDim, KDim], float64], +): + raise Exception("Exception foo occurred") diff --git a/tools/tests/py2fgen/fortran_samples/test_diffusion.f90 b/tools/tests/py2fgen/fortran_samples/test_diffusion.f90 new file mode 100644 index 0000000000..460de43512 --- /dev/null +++ b/tools/tests/py2fgen/fortran_samples/test_diffusion.f90 @@ -0,0 +1,331 @@ +module random_utils +contains + subroutine fill_random_1d(array, low, high) + use, intrinsic :: iso_c_binding, only: c_double + implicit none + + real(c_double), intent(inout) :: array(:) + real(c_double), intent(in) :: low, high + integer :: i + real(c_double) :: rnd + + do i = 1, size(array) + call random_number(rnd) + array(i) = low + rnd*(high - low) + end do + end subroutine fill_random_1d + + subroutine fill_random_2d(array, low, high) + use, intrinsic :: iso_c_binding, only: c_double + implicit none + + real(c_double), intent(inout) :: array(:, :) + real(c_double), intent(in) :: low, high + integer :: i, j + real(c_double) :: rnd + + do i = 1, size(array, 1) + do j = 1, size(array, 2) + call random_number(rnd) + array(i, j) = low + rnd*(high - low) + end do + end do + end subroutine fill_random_2d + + subroutine fill_random_3d_int(array, low, high) + use, intrinsic :: iso_c_binding, only: c_int + implicit none + + integer(c_int), intent(inout) :: array(:, :, :) + integer(c_int), intent(in) :: low, high + integer :: i, j, k + real :: rnd ! real number between 0 and 1 + + do i = 1, size(array, 1) + do j = 1, size(array, 2) + do k = 1, size(array, 3) + call random_number(rnd) + array(i, j, k) = int(low + rnd * (high - low)) + end do + end do + end do + end subroutine fill_random_3d_int + + subroutine fill_random_3d(array, low, high) + use, intrinsic :: iso_c_binding, only: c_double + implicit none + + real(c_double), intent(inout) :: array(:, :, :) + real(c_double), intent(in) :: low, high + integer :: i, j, k + real :: rnd ! real number between 0 and 1 + + do i = 1, size(array, 1) + do j = 1, size(array, 2) + do k = 1, size(array, 3) + call random_number(rnd) + array(i, j, k) = low + rnd * (high - low) + end do + end do + end do + end subroutine fill_random_3d + + subroutine fill_random_2d_bool(array) + use, intrinsic :: iso_c_binding, only: c_int + implicit none + + logical(c_int), intent(inout) :: array(:, :) + integer :: i, j + real :: rnd ! real number between 0 and 1 + + do i = 1, size(array, 1) + do j = 1, size(array, 2) + call random_number(rnd) + if (rnd < 0.5) then + array(i, j) = .false. + else + array(i, j) = .true. + endif + end do + end do +end subroutine fill_random_2d_bool +end module random_utils + +program diffusion_simulation + use, intrinsic :: iso_c_binding + use random_utils, only: fill_random_1d, fill_random_2d, fill_random_2d_bool, fill_random_3d_int, fill_random_3d + use diffusion_plugin + implicit none + + integer(c_int) :: rc + + ! Constants and types + integer(c_int), parameter :: num_cells = 20480 + integer(c_int), parameter :: num_edges = 30720 + integer(c_int), parameter :: num_vertices = 10242 + integer(c_int), parameter :: num_levels = 60 + integer(c_int), parameter :: num_c2ec2o = 4 + integer(c_int), parameter :: num_v2e = 6 + integer(c_int), parameter :: num_c2e = 2 + integer(c_int), parameter :: num_e2c2v = 4 + integer(c_int), parameter :: num_c2e2c = 3 + integer(c_int), parameter :: num_e2c = 3 + real(c_double), parameter :: mean_cell_area = 24907282236.708576 + integer(c_int), parameter :: ndyn_substeps = 2 + real(c_double), parameter :: dtime = 2.0 + real(c_double), parameter :: rayleigh_damping_height = 50000 + integer(c_int), parameter :: nflatlev = 30 + integer(c_int), parameter :: nflat_gradp = 59 + integer(c_int), parameter :: diffusion_type = 5 ! Assuming DiffusionType.SMAGORINSKY_4TH_ORDER is represented by 5 + logical(c_int), parameter :: hdiff_w = .true. + logical(c_int), parameter :: hdiff_vn = .true. + logical(c_int), parameter :: zdiffu_t = .true. ! this runs stencil 15 which uses the boolean mask + integer(c_int), parameter :: type_t_diffu = 2 + integer(c_int), parameter :: type_vn_diffu = 1 + real(c_double), parameter :: hdiff_efdt_ratio = 24.0 + real(c_double), parameter :: smagorinski_scaling_factor = 0.025 + logical(c_int), parameter :: hdiff_temp = .true. + logical(c_int), parameter :: linit = .true. + + ! Declaring arrays for diffusion_init and diffusion_run + real(c_double), dimension(:), allocatable :: vct_a + real(c_double), dimension(:), allocatable :: nudgecoeff_e + real(c_double), dimension(:), allocatable :: tangent_orientation + real(c_double), dimension(:), allocatable :: inverse_primal_edge_lengths + real(c_double), dimension(:), allocatable :: inv_dual_edge_length + real(c_double), dimension(:), allocatable :: inv_vert_vert_length + real(c_double), dimension(:), allocatable :: edge_areas + real(c_double), dimension(:), allocatable :: f_e + real(c_double), dimension(:), allocatable :: cell_areas + + real(c_double), dimension(:, :), allocatable :: theta_ref_mc + real(c_double), dimension(:, :), allocatable :: wgtfac_c + real(c_double), dimension(:, :), allocatable :: e_bln_c_s + real(c_double), dimension(:, :), allocatable :: geofac_div + real(c_double), dimension(:, :), allocatable :: geofac_grg_x + real(c_double), dimension(:, :), allocatable :: geofac_grg_y + real(c_double), dimension(:, :), allocatable :: geofac_n2s + real(c_double), dimension(:, :), allocatable :: rbf_coeff_1 + real(c_double), dimension(:, :), allocatable :: rbf_coeff_2 + real(c_double), dimension(:, :), allocatable :: dwdx + real(c_double), dimension(:, :), allocatable :: dwdy + real(c_double), dimension(:, :), allocatable :: hdef_ic + real(c_double), dimension(:, :), allocatable :: div_ic + real(c_double), dimension(:, :), allocatable :: w + real(c_double), dimension(:, :), allocatable :: vn + real(c_double), dimension(:, :), allocatable :: exner + real(c_double), dimension(:, :), allocatable :: theta_v + real(c_double), dimension(:, :), allocatable :: rho + real(c_double), dimension(:, :), allocatable :: dual_normal_cell_x + real(c_double), dimension(:, :), allocatable :: dual_normal_cell_y + real(c_double), dimension(:, :), allocatable :: dual_normal_vert_x + real(c_double), dimension(:, :), allocatable :: dual_normal_vert_y + real(c_double), dimension(:, :), allocatable :: primal_normal_cell_x + real(c_double), dimension(:, :), allocatable :: primal_normal_cell_y + real(c_double), dimension(:, :), allocatable :: primal_normal_vert_x + real(c_double), dimension(:, :), allocatable :: primal_normal_vert_y + real(c_double), dimension(:, :), allocatable :: zd_diffcoef + logical(c_int), dimension(:, :), allocatable :: mask_hdiff + + integer(c_int), dimension(:, :, :), allocatable :: zd_vertoffset + real(c_double), dimension(:, :, :), allocatable :: zd_intcoef + + !$acc enter data create(vct_a, theta_ref_mc, wgtfac_c, e_bln_c_s, geofac_div, & + !$acc geofac_grg_x, geofac_grg_y, geofac_n2s, nudgecoeff_e, rbf_coeff_1, & + !$acc rbf_coeff_2, dwdx, dwdy, hdef_ic, div_ic, w, vn, exner, theta_v, rho, & + !$acc dual_normal_cell_x, dual_normal_cell_y, dual_normal_vert_x, & + !$acc dual_normal_vert_y, primal_normal_cell_x, primal_normal_cell_y, & + !$acc primal_normal_vert_x, primal_normal_vert_y, tangent_orientation, & + !$acc inverse_primal_edge_lengths, inv_dual_edge_length, inv_vert_vert_length, & + !$acc edge_areas, cell_areas, f_e, zd_diffcoef, zd_vertoffset, zd_intcoef, & + !$acc mask_hdiff) + + ! allocating arrays + allocate(zd_diffcoef(num_cells, num_levels)) + allocate(zd_vertoffset(num_cells, num_c2e2c, num_levels)) + allocate(zd_intcoef(num_cells, num_c2e2c, num_levels)) + allocate(mask_hdiff(num_cells, num_levels)) + allocate (vct_a(num_levels)) + allocate (theta_ref_mc(num_cells, num_levels)) + allocate (wgtfac_c(num_cells, num_levels + 1)) + allocate (e_bln_c_s(num_cells, num_c2e)) + allocate (geofac_div(num_cells, num_c2e)) + allocate (geofac_grg_x(num_cells, num_c2ec2o)) + allocate (geofac_grg_y(num_cells, num_c2ec2o)) + allocate (geofac_n2s(num_cells, num_c2ec2o)) + allocate (nudgecoeff_e(num_edges)) + allocate (rbf_coeff_1(num_vertices, num_v2e)) + allocate (rbf_coeff_2(num_vertices, num_v2e)) + allocate (dwdx(num_cells, num_levels)) + allocate (dwdy(num_cells, num_levels)) + allocate (hdef_ic(num_cells, num_levels + 1)) + allocate (div_ic(num_cells, num_levels + 1)) + allocate (w(num_cells, num_levels + 1)) + allocate (vn(num_edges, num_levels)) + allocate (exner(num_cells, num_levels)) + allocate (theta_v(num_cells, num_levels)) + allocate (rho(num_cells, num_levels)) + allocate (dual_normal_cell_x(num_edges, num_e2c)) + allocate (dual_normal_cell_y(num_edges, num_e2c)) + allocate (dual_normal_vert_x(num_edges, num_e2c2v)) + allocate (dual_normal_vert_y(num_edges, num_e2c2v)) + allocate (primal_normal_cell_x(num_edges, num_e2c)) + allocate (primal_normal_cell_y(num_edges, num_e2c)) + allocate (primal_normal_vert_x(num_edges, num_e2c)) + allocate (primal_normal_vert_y(num_edges, num_e2c)) + allocate (tangent_orientation(num_edges)) + allocate (inverse_primal_edge_lengths(num_edges)) + allocate (inv_dual_edge_length(num_edges)) + allocate (inv_vert_vert_length(num_edges)) + allocate (edge_areas(num_edges)) + allocate (f_e(num_edges)) + allocate (cell_areas(num_cells)) + + ! Fill arrays with random numbers + ! For 1D arrays + call fill_random_1d(vct_a, 0.0_c_double, 75000.0_c_double) ! needs to be above 50000 damping height restriction + call fill_random_1d(nudgecoeff_e, 0.0_c_double, 1.0_c_double) + call fill_random_1d(tangent_orientation, 0.0_c_double, 1.0_c_double) + call fill_random_1d(inverse_primal_edge_lengths, 0.0_c_double, 1.0_c_double) + call fill_random_1d(inv_dual_edge_length, 0.0_c_double, 1.0_c_double) + call fill_random_1d(inv_vert_vert_length, 0.0_c_double, 1.0_c_double) + call fill_random_1d(edge_areas, 0.0_c_double, 1.0_c_double) + call fill_random_1d(f_e, 0.0_c_double, 1.0_c_double) + call fill_random_1d(cell_areas, 0.0_c_double, 1.0_c_double) + + ! For 2D arrays + call fill_random_2d(theta_ref_mc, 0.0_c_double, 1.0_c_double) + call fill_random_2d(wgtfac_c, 0.0_c_double, 1.0_c_double) + call fill_random_2d(geofac_grg_x, 0.0_c_double, 1.0_c_double) + call fill_random_2d(geofac_grg_y, 0.0_c_double, 1.0_c_double) + call fill_random_2d(geofac_n2s, 0.0_c_double, 1.0_c_double) + call fill_random_2d(rbf_coeff_1, 0.0_c_double, 1.0_c_double) + call fill_random_2d(rbf_coeff_2, 0.0_c_double, 1.0_c_double) + call fill_random_2d(dwdx, 0.0_c_double, 1.0_c_double) + call fill_random_2d(dwdy, 0.0_c_double, 1.0_c_double) + call fill_random_2d(hdef_ic, 0.0_c_double, 1.0_c_double) + call fill_random_2d(div_ic, 0.0_c_double, 1.0_c_double) + call fill_random_2d(w, 0.0_c_double, 1.0_c_double) + call fill_random_2d(vn, 0.0_c_double, 1.0_c_double) + call fill_random_2d(exner, 0.0_c_double, 1.0_c_double) + call fill_random_2d(theta_v, 0.0_c_double, 1.0_c_double) + call fill_random_2d(rho, 0.0_c_double, 1.0_c_double) + call fill_random_2d(zd_diffcoef, 0.0_c_double, 1.0_c_double) + call fill_random_2d_bool(mask_hdiff) + + call fill_random_2d(e_bln_c_s, 0.0_c_double, 1.0_c_double) + call fill_random_2d(geofac_div, 0.0_c_double, 1.0_c_double) + call fill_random_2d(dual_normal_vert_x, 0.0_c_double, 1.0_c_double) + call fill_random_2d(dual_normal_vert_y, 0.0_c_double, 1.0_c_double) + call fill_random_2d(primal_normal_vert_x, 0.0_c_double, 1.0_c_double) + call fill_random_2d(primal_normal_vert_y, 0.0_c_double, 1.0_c_double) + call fill_random_2d(dual_normal_cell_x, 0.0_c_double, 1.0_c_double) + call fill_random_2d(dual_normal_cell_y, 0.0_c_double, 1.0_c_double) + call fill_random_2d(primal_normal_cell_x, 0.0_c_double, 1.0_c_double) + call fill_random_2d(primal_normal_cell_y, 0.0_c_double, 1.0_c_double) + + ! For 3D arrays + call fill_random_3d(zd_intcoef, 0.0_c_double, 1.0_c_double) + call fill_random_3d_int(zd_vertoffset, 0, 1) + + + !$acc data copyin(vct_a, theta_ref_mc, wgtfac_c, e_bln_c_s, geofac_div, & + !$acc geofac_grg_x, geofac_grg_y, geofac_n2s, nudgecoeff_e, rbf_coeff_1, & + !$acc rbf_coeff_2, dwdx, dwdy, hdef_ic, div_ic, w, vn, exner, theta_v, rho, & + !$acc dual_normal_cell_x, dual_normal_cell_y, dual_normal_vert_x, & + !$acc dual_normal_vert_y, primal_normal_cell_x, primal_normal_cell_y, & + !$acc primal_normal_vert_x, primal_normal_vert_y, tangent_orientation, & + !$acc inverse_primal_edge_lengths, inv_dual_edge_length, inv_vert_vert_length, & + !$acc edge_areas, cell_areas, f_e, zd_diffcoef, zd_vertoffset, zd_intcoef, & + !$acc mask_hdiff) + + ! Call diffusion_init + call diffusion_init(vct_a, theta_ref_mc, wgtfac_c, e_bln_c_s, geofac_div, & + geofac_grg_x, geofac_grg_y, geofac_n2s, nudgecoeff_e, rbf_coeff_1, & + rbf_coeff_2, mask_hdiff, zd_diffcoef, zd_vertoffset, zd_intcoef, & + num_levels, mean_cell_area, ndyn_substeps, rayleigh_damping_height, & + nflatlev, nflat_gradp, diffusion_type, & + hdiff_w, hdiff_vn, zdiffu_t, type_t_diffu, type_vn_diffu, & + hdiff_efdt_ratio, smagorinski_scaling_factor, hdiff_temp, & + tangent_orientation, inverse_primal_edge_lengths, inv_dual_edge_length, & + inv_vert_vert_length, edge_areas, f_e, cell_areas, primal_normal_vert_x, & + primal_normal_vert_y, dual_normal_vert_x, dual_normal_vert_y, & + primal_normal_cell_x, primal_normal_cell_y, dual_normal_cell_x, & + dual_normal_cell_y, rc) + + print *, "Python exit code = ", rc + if (rc /= 0) then + call exit(1) + end if + + ! Call diffusion_run + call diffusion_run(w, vn, exner, theta_v, rho, hdef_ic, div_ic, dwdx, dwdy, dtime, linit, rc) + + print *, "Python exit code = ", rc + if (rc /= 0) then + call exit(1) + end if + + !$acc update host(vct_a, theta_ref_mc, wgtfac_c, e_bln_c_s, geofac_div, & + !$acc geofac_grg_x, geofac_grg_y, geofac_n2s, nudgecoeff_e, rbf_coeff_1, & + !$acc rbf_coeff_2, dwdx, dwdy, hdef_ic, div_ic, w, vn, exner, theta_v, rho, & + !$acc dual_normal_cell_x, dual_normal_cell_y, dual_normal_vert_x, & + !$acc dual_normal_vert_y, primal_normal_cell_x, primal_normal_cell_y, & + !$acc primal_normal_vert_x, primal_normal_vert_y, tangent_orientation, & + !$acc inverse_primal_edge_lengths, inv_dual_edge_length, inv_vert_vert_length, & + !$acc edge_areas, cell_areas, f_e, zd_diffcoef, zd_vertoffset, zd_intcoef, & + !$acc mask_hdiff) + + print *, "passed: could run diffusion" + + !$acc end data + !$acc exit data delete(vct_a, theta_ref_mc, wgtfac_c, e_bln_c_s, geofac_div, & + !$acc geofac_grg_x, geofac_grg_y, geofac_n2s, nudgecoeff_e, rbf_coeff_1, & + !$acc rbf_coeff_2, dwdx, dwdy, hdef_ic, div_ic, w, vn, exner, theta_v, rho, & + !$acc dual_normal_cell_x, dual_normal_cell_y, dual_normal_vert_x, & + !$acc dual_normal_vert_y, primal_normal_cell_x, primal_normal_cell_y, & + !$acc primal_normal_vert_x, primal_normal_vert_y, tangent_orientation, & + !$acc inverse_primal_edge_lengths, inv_dual_edge_length, inv_vert_vert_length, & + !$acc edge_areas, cell_areas, f_e, zd_diffcoef, zd_vertoffset, zd_intcoef, & + !$acc mask_hdiff) +end program diffusion_simulation diff --git a/tools/tests/py2fgen/fortran_samples/test_multi_return.f90 b/tools/tests/py2fgen/fortran_samples/test_multi_return.f90 index c0b324dd4c..86c13b7495 100644 --- a/tools/tests/py2fgen/fortran_samples/test_multi_return.f90 +++ b/tools/tests/py2fgen/fortran_samples/test_multi_return.f90 @@ -1,83 +1,96 @@ program call_multi_return_cffi_plugin - use, intrinsic :: iso_c_binding - use multi_return_plugin - implicit none + use, intrinsic :: iso_c_binding + use multi_return_plugin + implicit none - integer(c_int) :: edim, kdim, i, j, horizontal_start, horizontal_end, vertical_start, vertical_end - logical :: computation_correct - character(len=100) :: str_buffer - real(c_double) :: r_nsubsteps - real(c_double), dimension(:,:), allocatable :: z_vn_avg, mass_fl_e, vn_traj, mass_flx_me + integer(c_int) :: edim, kdim, i, j, horizontal_start, horizontal_end, vertical_start, vertical_end, rc + logical :: computation_correct + character(len=100) :: str_buffer + real(c_double) :: r_nsubsteps + real(c_double), dimension(:, :), allocatable :: z_vn_avg, mass_fl_e, vn_traj, mass_flx_me - ! array dimensions - edim = 27 - kdim = 10 + ! array dimensions + edim = 27 + kdim = 10 - ! allocate arrays (allocate in column-major order) - allocate(z_vn_avg(kdim, edim)) - allocate(mass_fl_e(kdim, edim)) - allocate(vn_traj(kdim, edim)) - allocate(mass_flx_me(kdim, edim)) + !$ACC enter data create(z_vn_avg, mass_fl_e, vn_traj, mass_flx_me) - ! initialize arrays and variables - z_vn_avg = 1.0d0 - mass_fl_e = 2.0d0 - vn_traj = 3.0d0 - mass_flx_me = 4.0d0 - r_nsubsteps = 9.0d0 - horizontal_start = 0 - horizontal_end = edim - vertical_start = 0 - vertical_end = kdim + ! allocate arrays (allocate in column-major order) + allocate (z_vn_avg(edim, kdim)) + allocate (mass_fl_e(edim, kdim)) + allocate (vn_traj(edim, kdim)) + allocate (mass_flx_me(edim, kdim)) - ! print array shapes and values before computation - print *, "Arrays before computation:" - write(str_buffer, '("Shape of z_vn_avg = ", I2, ",", I2)') size(z_vn_avg, 1), size(z_vn_avg, 2) - print *, trim(str_buffer) - write(str_buffer, '("Shape of mass_fl_e = ", I2, ",", I2)') size(mass_fl_e, 1), size(mass_fl_e, 2) - print *, trim(str_buffer) - write(str_buffer, '("Shape of vn_traj = ", I2, ",", I2)') size(vn_traj, 1), size(vn_traj, 2) - print *, trim(str_buffer) - write(str_buffer, '("Shape of mass_flx_me = ", I2, ",", I2)') size(mass_flx_me, 1), size(mass_flx_me, 2) - print *, trim(str_buffer) - print * + ! initialize arrays and variables + z_vn_avg = 1.0d0 + mass_fl_e = 2.0d0 + vn_traj = 3.0d0 + mass_flx_me = 4.0d0 + r_nsubsteps = 9.0d0 + horizontal_start = 0 + horizontal_end = edim + vertical_start = 0 + vertical_end = kdim - ! call the cffi plugin - call multi_return_wrapper(z_vn_avg, mass_fl_e, vn_traj, mass_flx_me, r_nsubsteps, & - horizontal_start, horizontal_end, vertical_start, vertical_end, edim, kdim) + !$ACC data copyin(z_vn_avg, mass_fl_e, vn_traj, mass_flx_me, r_nsubsteps) - ! print array shapes and values before computation - print *, "Arrays after computation:" - write(str_buffer, '("Shape of z_vn_avg = ", I2, ",", I2)') size(z_vn_avg, 1), size(z_vn_avg, 2) - print *, trim(str_buffer) - write(str_buffer, '("Shape of mass_fl_e = ", I2, ",", I2)') size(mass_fl_e, 1), size(mass_fl_e, 2) - print *, trim(str_buffer) - write(str_buffer, '("Shape of vn_traj = ", I2, ",", I2)') size(vn_traj, 1), size(vn_traj, 2) - print *, trim(str_buffer) - write(str_buffer, '("Shape of mass_flx_me = ", I2, ",", I2)') size(mass_flx_me, 1), size(mass_flx_me, 2) - print *, trim(str_buffer) - print * + ! print array shapes and values before computation + print *, "Arrays before computation:" + write (str_buffer, '("Shape of z_vn_avg = ", I2, ",", I2)') size(z_vn_avg, 1), size(z_vn_avg, 2) + print *, trim(str_buffer) + write (str_buffer, '("Shape of mass_fl_e = ", I2, ",", I2)') size(mass_fl_e, 1), size(mass_fl_e, 2) + print *, trim(str_buffer) + write (str_buffer, '("Shape of vn_traj = ", I2, ",", I2)') size(vn_traj, 1), size(vn_traj, 2) + print *, trim(str_buffer) + write (str_buffer, '("Shape of mass_flx_me = ", I2, ",", I2)') size(mass_flx_me, 1), size(mass_flx_me, 2) + print *, trim(str_buffer) + print * - ! Assert vn_traj == 12 and mass_flx_me == 22 - computation_correct = .true. - do i = 1, edim - do j = 1, kdim - if (vn_traj(i, j) /= 12.0d0 .or. mass_flx_me(i, j) /= 22.0d0) then - computation_correct = .false. - exit - end if - end do - if (.not. computation_correct) exit - end do + ! call the cffi plugin + call multi_return(z_vn_avg, mass_fl_e, vn_traj, mass_flx_me, r_nsubsteps, & + horizontal_start, horizontal_end, vertical_start, vertical_end, rc) + print *, "Python exit code = ", rc + if (rc /= 0) then + call exit(1) + end if - ! deallocate arrays - deallocate(z_vn_avg, mass_fl_e, vn_traj, mass_flx_me) + !$ACC update host(z_vn_avg, mass_fl_e, vn_traj, mass_flx_me) - ! Check and print the result of the assertion - if (computation_correct) then - print *, "passed: vn_traj and mass_flx_me have expected values." - else - print *, "failed: vn_traj or mass_flx_me does not have the expected values." - stop 1 - end if + ! print array shapes and values before computation + print *, "Arrays after computation:" + write (str_buffer, '("Shape of z_vn_avg = ", I2, ",", I2)') size(z_vn_avg, 1), size(z_vn_avg, 2) + print *, trim(str_buffer) + write (str_buffer, '("Shape of mass_fl_e = ", I2, ",", I2)') size(mass_fl_e, 1), size(mass_fl_e, 2) + print *, trim(str_buffer) + write (str_buffer, '("Shape of vn_traj = ", I2, ",", I2)') size(vn_traj, 1), size(vn_traj, 2) + print *, trim(str_buffer) + write (str_buffer, '("Shape of mass_flx_me = ", I2, ",", I2)') size(mass_flx_me, 1), size(mass_flx_me, 2) + print *, trim(str_buffer) + print * + + ! Assert vn_traj == 12 and mass_flx_me == 22 + computation_correct = .true. + do i = 1, edim + do j = 1, kdim + if (vn_traj(i, j) /= 12.0d0 .or. mass_flx_me(i, j) /= 22.0d0) then + computation_correct = .false. + exit + end if + end do + if (.not. computation_correct) exit + end do + + !$ACC end data + !$ACC exit data delete(z_vn_avg, mass_fl_e, vn_traj, mass_flx_me) + + ! deallocate arrays + deallocate (z_vn_avg, mass_fl_e, vn_traj, mass_flx_me) + + ! Check and print the result of the assertion + if (computation_correct) then + print *, "passed: vn_traj and mass_flx_me have expected values." + else + print *, "failed: vn_traj or mass_flx_me does not have the expected values." + stop 1 + end if end program call_multi_return_cffi_plugin diff --git a/tools/tests/py2fgen/fortran_samples/test_square.f90 b/tools/tests/py2fgen/fortran_samples/test_square.f90 index faf3891262..24bebd0ea0 100644 --- a/tools/tests/py2fgen/fortran_samples/test_square.f90 +++ b/tools/tests/py2fgen/fortran_samples/test_square.f90 @@ -1,80 +1,90 @@ program call_square_wrapper_cffi_plugin - use, intrinsic :: iso_c_binding -#ifdef USE_SQUARE_FROM_FUNCTION - use square_from_function_plugin -#else - use square_plugin -#endif - implicit none - character(len=100) :: str_buffer - integer(c_int) :: cdim, kdim, i, j - logical :: computation_correct - real(c_double), dimension(:, :), allocatable :: input, result + use, intrinsic :: iso_c_binding + use square_plugin + implicit none + character(len=100) :: str_buffer + integer(c_int) :: cdim, kdim, i, j, rc + logical :: computation_correct + real(c_double), dimension(:, :), allocatable :: input, result + + ! array dimensions + cdim = 18 + kdim = 10 - ! array dimensions - cdim = 18 - kdim = 10 + !$ACC enter data create(input, result) - ! allocate arrays (allocate in column-major order) - allocate(input(kdim, cdim)) - allocate(result(kdim, cdim)) + ! allocate arrays (allocate in column-major order) + allocate (input(cdim, kdim)) + allocate (result(cdim, kdim)) - ! initialise arrays - input = 5.0d0 - result = 0.0d0 + ! initialise arrays + input = 5.0d0 + result = 0.0d0 - ! print array shapes and values before computation - print *, "Arrays before computation:" - write(str_buffer, '("Shape of input = ", I2, ",", I2)') size(input, 1), size(input, 2) - print *, trim(str_buffer) - write(str_buffer, '("Shape of result = ", I2, ",", I2)') size(result, 1), size(result, 2) - print *, trim(str_buffer) - print * - print *, "input = ", input - print * - print *, "result = ", result - print * + !$ACC data copyin(input, result) + + ! print array shapes and values before computation + print *, "Fortran Arrays before calling Python:" + write (str_buffer, '("Shape of input = ", I2, ",", I2)') size(input, 1), size(input, 2) + print *, trim(str_buffer) + write (str_buffer, '("Shape of result = ", I2, ",", I2)') size(result, 1), size(result, 2) + print *, trim(str_buffer) + print * + print *, "input = ", input + print * + print *, "result = ", result + print * - ! Call the appropriate cffi plugin #ifdef USE_SQUARE_FROM_FUNCTION - call square_from_function_wrapper(input, result, cdim, kdim) + call square_from_function(input, result, rc) +#elif USE_SQUARE_ERROR + call square_error(input, result, rc) #else - call square_wrapper(input, result, cdim, kdim) + call square(input, result, rc) #endif + if (rc /= 0) then + print *, "Python failed with exit code = ", rc + call exit(1) + end if + + !$ACC update host(input, result) + + ! print array shapes and values before computation + print *, "Fortran arrays after calling Python:" + write (str_buffer, '("Shape of input = ", I2, ",", I2)') size(input, 1), size(input, 2) + print *, trim(str_buffer) + write (str_buffer, '("Shape of result = ", I2, ",", I2)') size(result, 1), size(result, 2) + print *, trim(str_buffer) + print * + print *, "input = ", input + print * + print *, "result = ", result + print * - ! print array shapes and values before computation - print *, "Arrays after computation:" - write(str_buffer, '("Shape of input = ", I2, ",", I2)') size(input, 1), size(input, 2) - print *, trim(str_buffer) - write(str_buffer, '("Shape of result = ", I2, ",", I2)') size(result, 1), size(result, 2) - print *, trim(str_buffer) - print * - print *, "input = ", input - print * - print *, "result = ", result - print * + ! Assert each element of result is the square of the corresponding element in input + computation_correct = .true. + do i = 1, cdim + do j = 1, kdim + if (result(i, j) /= input(i, j)**2) then + print *, "Error: result(", i, ",", j, ") =", result(i, j), & + "is not the square of input(", i, ",", j, ") =", input(i, j) + computation_correct = .false. + exit + end if + end do + if (.not. computation_correct) exit + end do - ! Assert each element of result is the square of the corresponding element in input - computation_correct = .true. - do i = 1, cdim - do j = 1, kdim - if (result(i, j) /= input(i, j)**2) then - print *, "Error: result(", i, ",", j, ") =", result(i, j), & - "is not the square of input(", i, ",", j, ") =", input(i, j) - computation_correct = .false. - exit - endif - enddo - if (.not. computation_correct) exit - enddo + !$ACC end data + !$ACC exit data delete(input, result) - ! deallocate arrays - deallocate(input, result) + ! deallocate arrays + deallocate (input, result) - ! Check and print the result of the assertion - if (computation_correct) then - print *, "passed: result has expected values." - else - print *, "failed: result does not have the expected values." - end if + ! Check and print the result of the assertion + if (computation_correct) then + print *, "passed: result has expected values." + else + print *, "failed: result does not have the expected values." + end if end program call_square_wrapper_cffi_plugin diff --git a/tools/tests/py2fgen/test_cffi.py b/tools/tests/py2fgen/test_cffi.py index fdd16cba74..492c00cd66 100644 --- a/tools/tests/py2fgen/test_cffi.py +++ b/tools/tests/py2fgen/test_cffi.py @@ -10,12 +10,15 @@ # distribution for a copy of the license or check . # # SPDX-License-Identifier: GPL-3.0-or-later +import subprocess +import tempfile +from pathlib import Path import numpy as np import pytest from cffi import FFI -from icon4pytools.py2fgen.cffi import unpack +from icon4pytools.py2fgen.plugin import generate_and_compile_cffi_plugin, unpack @pytest.fixture @@ -26,11 +29,11 @@ def ffi(): @pytest.mark.parametrize( "data, expected_result", [ - ([1.0, 2.0, 3.0, 4.0], np.array([[1.0, 2.0], [3.0, 4.0]])), - ([1, 2, 3, 4], np.array([[1, 2], [3, 4]])), + ([1.0, 2.0, 3.0, 4.0], np.array([[1.0, 3.0], [2.0, 4.0]])), + ([1, 2, 3, 4], np.array([[1, 3], [2, 4]])), ], ) -def test_unpack(data, expected_result, ffi): +def test_unpack_column_major(data, expected_result, ffi): ptr = ffi.new("double[]", data) if isinstance(data[0], float) else ffi.new("int[]", data) rows, cols = expected_result.shape @@ -38,3 +41,72 @@ def test_unpack(data, expected_result, ffi): result = unpack(ptr, rows, cols) assert np.array_equal(result, expected_result) + + +def test_compile_and_run_cffi_plugin_from_C(): + plugin_name = "test_plugin" + c_header = "int test_function();" + c_source_code = f""" + #include + #include "{plugin_name}.h" + + int main() {{ + printf("%d\\n", test_function()); + return 0; + }} + """ + + python_wrapper = """ + from test_plugin import ffi + + @ffi.def_extern() + def test_function(): + return 42 + """ + + with tempfile.TemporaryDirectory() as tmpdirname: + build_path = Path(tmpdirname) + + try: + # Generate and compile the CFFI plugin, which creates lib{plugin_name}.so + generate_and_compile_cffi_plugin(plugin_name, c_header, python_wrapper, build_path) + compiled_library_path = build_path / f"lib{plugin_name}.so" + + # Verify the shared library was created + assert ( + compiled_library_path.exists() + ), f"Compiled library {compiled_library_path} does not exist." + assert compiled_library_path.stat().st_size > 0, "Compiled library is empty." + + # Write the main C program to a file + main_program_path = build_path / "main.c" + with open(main_program_path, "w") as main_program_file: + main_program_file.write(c_source_code) + + # Compile the main C program against the shared library + subprocess.run( + [ + "gcc", + "-o", + build_path / "test_program", + str(main_program_path), + "-L" + str(build_path), + "-l" + plugin_name, + "-Wl,-rpath=" + str(build_path), + ], + check=True, + ) + + # Execute the compiled program and capture its output + result = subprocess.run( + [build_path / "test_program"], stdout=subprocess.PIPE, check=True + ) + output = result.stdout.decode().strip() + + # Assert the output of test_function called within the C program + assert output == "42", f"Expected '42', got '{output}'" + + except Exception as e: + pytest.fail( + f"Unexpected error during plugin generation, compilation, or execution: {e}" + ) diff --git a/tools/tests/py2fgen/test_cli.py b/tools/tests/py2fgen/test_cli.py index d40d8c47a7..ce51e8eb30 100644 --- a/tools/tests/py2fgen/test_cli.py +++ b/tools/tests/py2fgen/test_cli.py @@ -29,83 +29,117 @@ def wrapper_module(): return "icon4pytools.py2fgen.wrappers.simple" +@pytest.fixture +def diffusion_module(): + return "icon4pytools.py2fgen.wrappers.diffusion_test_case" + + def run_test_case( cli, module: str, function: str, + plugin_name: str, backend: str, samples_path: Path, fortran_driver: str, + compiler: str = "gfortran", extra_compiler_flags: tuple[str, ...] = (), + expected_error_code: int = 0, ): with cli.isolated_filesystem(): - result = cli.invoke(main, [module, function, "--gt4py-backend", backend, "-d"]) + result = cli.invoke(main, [module, function, plugin_name, "-b", backend, "-d"]) assert result.exit_code == 0, "CLI execution failed" try: - compile_fortran_code(function, samples_path, fortran_driver, extra_compiler_flags) + compile_fortran_code( + plugin_name, samples_path, fortran_driver, compiler, extra_compiler_flags + ) except subprocess.CalledProcessError as e: pytest.fail(f"Compilation failed: {e}") try: - fortran_result = run_fortran_executable(function) - assert "passed" in fortran_result.stdout + fortran_result = run_fortran_executable(plugin_name) + if expected_error_code == 0: + assert "passed" in fortran_result.stdout + else: + assert "failed" in fortran_result.stdout except subprocess.CalledProcessError as e: pytest.fail(f"Execution of compiled Fortran code failed: {e}\nOutput:\n{e.stdout}") def compile_fortran_code( - function: str, samples_path: Path, fortran_driver: str, extra_compiler_flags: tuple[str, ...] + plugin_name: str, + samples_path: Path, + fortran_driver: str, + compiler: str, + extra_compiler_flags: tuple[str, ...], ): - subprocess.run(["gfortran", "-c", f"{function}_plugin.f90", "."], check=True) + command = [ + f"{compiler}", + "-cpp", + "-I.", + "-Wl,-rpath=.", + "-L.", + f"{plugin_name}.f90", + str(samples_path / f"{fortran_driver}.f90"), + f"-l{plugin_name}", + "-o", + plugin_name, + ] + [f for f in extra_compiler_flags] subprocess.run( - [ - "gfortran", - "-cpp", - "-I.", - "-Wl,-rpath=.", - "-L.", - f"{function}_plugin.f90", - str(samples_path / f"{fortran_driver}.f90"), - f"-l{function}_plugin", - "-o", - function, - ] - + [f for f in extra_compiler_flags], + command, check=True, ) -def run_fortran_executable(function: str): - return subprocess.run([f"./{function}"], capture_output=True, text=True, check=True) - - -@pytest.mark.parametrize("backend", ("CPU", "ROUNDTRIP")) -def test_py2fgen_compilation_and_execution_square( - cli_runner, backend, samples_path, wrapper_module +def run_fortran_executable(plugin_name: str): + try: + result = subprocess.run([f"./{plugin_name}"], capture_output=True, text=True, check=True) + except subprocess.CalledProcessError as e: + # If an error occurs, use the exception's `stdout` and `stderr`. + result = e + return result + + +@pytest.mark.parametrize( + "backend, extra_flags", + [ + ("CPU", ("-DUSE_SQUARE_FROM_FUNCTION",)), + ("ROUNDTRIP", ""), + ("CPU", ("-DUSE_SQUARE_FROM_FUNCTION",)), + ("ROUNDTRIP", ""), + ], +) +def test_py2fgen_compilation_and_execution_square_cpu( + cli_runner, backend, samples_path, wrapper_module, extra_flags ): + """Tests embedding Python functions, and GT4Py program directly. + Also tests embedding multiple functions in one shared library. + """ run_test_case( cli_runner, wrapper_module, - "square", + "square,square_from_function", + "square_plugin", backend, samples_path, "test_square", + extra_compiler_flags=extra_flags, ) -@pytest.mark.parametrize("backend", ("CPU", "ROUNDTRIP")) -def test_py2fgen_compilation_and_execution_square_from_function( - cli_runner, backend, samples_path, wrapper_module -): +def test_py2fgen_python_error_propagation_to_fortran(cli_runner, samples_path, wrapper_module): + """Tests that Exceptions triggered in Python propagate an error code (1) up to Fortran.""" run_test_case( cli_runner, wrapper_module, - "square_from_function", - backend, + "square_error", + "square_plugin", + "ROUNDTRIP", samples_path, "test_square", - ("-DUSE_SQUARE_FROM_FUNCTION",), + extra_compiler_flags=("-DUSE_SQUARE_ERROR",), + expected_error_code=1, ) @@ -113,11 +147,83 @@ def test_py2fgen_compilation_and_execution_square_from_function( def test_py2fgen_compilation_and_execution_multi_return( cli_runner, backend, samples_path, wrapper_module ): + """Tests embedding multi return gt4py program.""" run_test_case( cli_runner, wrapper_module, "multi_return", + "multi_return_plugin", backend, samples_path, "test_multi_return", ) + + +# todo: enable on CI +@pytest.mark.skip("Requires setting ICON_GRID_LOC environment variable.") +def test_py2fgen_compilation_and_execution_diffusion(cli_runner, samples_path): + run_test_case( + cli_runner, + "icon4pytools.py2fgen.wrappers.diffusion", + "diffusion_init,diffusion_run", + "diffusion_plugin", + "CPU", + samples_path, + "test_diffusion", + ) + + +# todo: enable on CI +@pytest.mark.skip("Requires setting various environment variables.") +@pytest.mark.parametrize( + "function_name, plugin_name, test_name, backend, extra_flags", + [ + ("square", "square_plugin", "test_square", "GPU", ("-acc", "-Minfo=acc")), + ("multi_return", "multi_return_plugin", "test_multi_return", "GPU", ("-acc", "-Minfo=acc")), + ], +) +def test_py2fgen_compilation_and_execution_gpu( + cli_runner, + function_name, + plugin_name, + test_name, + backend, + samples_path, + wrapper_module, + extra_flags, +): + run_test_case( + cli_runner, + wrapper_module, + function_name, + plugin_name, + backend, + samples_path, + test_name, + "/opt/nvidia/hpc_sdk/Linux_x86_64/2024/compilers/bin/nvfortran", # Ensure NVFORTRAN_COMPILER is set in your environment variables + extra_flags, + ) + + +# todo: enable on CI +# Need to compile using nvfortran, and set CUDACXX path to nvcc cuda compiler. Also need to set ICON_GRID_LOC for path to gridfile, and ICON4PY_BACKEND to determine device at runtime. +@pytest.mark.skip("Requires setting various environment variables.") +@pytest.mark.parametrize( + "backend, extra_flags", + [("GPU", ("-acc", "-Minfo=acc"))], +) +def test_py2fgen_compilation_and_execution_diffusion_gpu( + cli_runner, samples_path, backend, extra_flags +): + # todo: requires setting ICON_GRID_LOC + run_test_case( + cli_runner, + "icon4pytools.py2fgen.wrappers.diffusion", + "diffusion_init,diffusion_run", + "diffusion_plugin", + backend, + samples_path, + "test_diffusion", + "/opt/nvidia/hpc_sdk/Linux_x86_64/2024/compilers/bin/nvfortran", # todo: set nvfortran location in base.yml file. + extra_flags, + ) diff --git a/tools/tests/py2fgen/test_codegen.py b/tools/tests/py2fgen/test_codegen.py index 03bae08c30..1ff57f9410 100644 --- a/tools/tests/py2fgen/test_codegen.py +++ b/tools/tests/py2fgen/test_codegen.py @@ -16,10 +16,14 @@ from gt4py.next.type_system.type_specifications import ScalarKind from icon4py.model.common.dimension import CellDim, KDim +from icon4pytools.py2fgen.generate import ( + generate_c_header, + generate_f90_interface, + generate_python_wrapper, +) from icon4pytools.py2fgen.template import ( CffiPlugin, CHeaderGenerator, - F90InterfaceGenerator, Func, FuncParameter, as_f90_value, @@ -82,20 +86,20 @@ def test_as_target(param, expected): def test_cheader_generation_for_single_function(): plugin = CffiPlugin( - module_name="libtest", plugin_name="libtest_plugin", function=foo, imports=["import foo"] + module_name="libtest", plugin_name="libtest_plugin", functions=[foo], imports=["import foo"] ) header = CHeaderGenerator.apply(plugin) - assert header == "extern void foo_wrapper(int one, double* two, int n_Cell, int n_K);" + assert header == "extern int foo_wrapper(int one, double* two, int n_Cell, int n_K);" def test_cheader_for_pointer_args(): plugin = CffiPlugin( - module_name="libtest", plugin_name="libtest_plugin", function=bar, imports=["import bar"] + module_name="libtest", plugin_name="libtest_plugin", functions=[bar], imports=["import bar"] ) header = CHeaderGenerator.apply(plugin) - assert header == "extern void bar_wrapper(float* one, int two, int n_Cell, int n_K);" + assert header == "extern int bar_wrapper(float* one, int two, int n_Cell, int n_K);" def compare_ignore_whitespace(s1: str, s2: str): @@ -103,29 +107,263 @@ def compare_ignore_whitespace(s1: str, s2: str): return s1.translate(no_whitespace) == s2.translate(no_whitespace) -def test_fortran_interface(): - plugin = CffiPlugin( - module_name="libtest", plugin_name="libtest_plugin", function=foo, imports=["import foo"] +@pytest.fixture +def dummy_plugin(): + return CffiPlugin( + module_name="libtest", + plugin_name="libtest_plugin", + functions=[foo, bar], + imports=["import foo_module_x\nimport bar_module_y"], ) - interface = F90InterfaceGenerator.apply(plugin) + + +def test_fortran_interface(dummy_plugin): + interface = generate_f90_interface(dummy_plugin) expected = """ module libtest_plugin - use, intrinsic:: iso_c_binding - implicit none + use, intrinsic :: iso_c_binding + implicit none + + public :: foo + + public :: bar + + interface + + function foo_wrapper(one, & + two, & + n_Cell, & + n_K) bind(c, name="foo_wrapper") result(rc) + import :: c_int, c_double, c_bool, c_ptr + + integer(c_int), value :: n_Cell + + integer(c_int), value :: n_K + + integer(c_int) :: rc ! Stores the return code + + integer(c_int), value, target :: one + + real(c_double), dimension(*), target :: two + + end function foo_wrapper + + function bar_wrapper(one, & + two, & + n_Cell, & + n_K) bind(c, name="bar_wrapper") result(rc) + import :: c_int, c_double, c_bool, c_ptr + + integer(c_int), value :: n_Cell + + integer(c_int), value :: n_K + + integer(c_int) :: rc ! Stores the return code + + real(c_float), dimension(*), target :: one + + integer(c_int), value, target :: two + + end function bar_wrapper - public - interface - subroutine foo_wrapper(one, & + end interface + +contains + + subroutine foo(one, & + two, & + rc) + use, intrinsic :: iso_c_binding + + integer(c_int) :: n_Cell + + integer(c_int) :: n_K + + integer(c_int), value, target :: one + + real(c_double), dimension(:, :), target :: two + + integer(c_int) :: rc ! Stores the return code + + !$ACC host_data use_device( & + !$ACC two & + !$ACC ) + + n_Cell = SIZE(two, 1) + + n_K = SIZE(two, 2) + + rc = foo_wrapper(one, & two, & n_Cell, & - n_K) bind(c, name='foo_wrapper') - use, intrinsic :: iso_c_binding - integer(c_int), value, target :: n_Cell - integer(c_int), value, target :: n_K - integer(c_int), value, target :: one - real(c_double), dimension(:, :), target :: two(n_Cell, n_K) - end subroutine foo_wrapper - end interface - end module + n_K) + + !$acc end host_data + end subroutine foo + + subroutine bar(one, & + two, & + rc) + use, intrinsic :: iso_c_binding + + integer(c_int) :: n_Cell + + integer(c_int) :: n_K + + real(c_float), dimension(:, :), target :: one + + integer(c_int), value, target :: two + + integer(c_int) :: rc ! Stores the return code + + !$ACC host_data use_device( & + !$ACC one & + !$ACC ) + + n_Cell = SIZE(one, 1) + + n_K = SIZE(one, 2) + + rc = bar_wrapper(one, & + two, & + n_Cell, & + n_K) + + !$acc end host_data + end subroutine bar + +end module +""" + assert compare_ignore_whitespace(interface, expected) + + +def test_python_wrapper(dummy_plugin): + interface = generate_python_wrapper(dummy_plugin, "GPU", False) + expected = ''' +# imports for generated wrapper code +import logging +from libtest_plugin import ffi +import numpy as np +import cupy as cp +from numpy.typing import NDArray +from gt4py.next.iterator.embedded import np_as_located_field + +# logger setup +log_format = '%(asctime)s.%(msecs)03d - %(levelname)s - %(message)s' +logging.basicConfig(level=logging.ERROR, + format=log_format, + datefmt='%Y-%m-%d %H:%M:%S') +logging.info(cp.show_config()) + +# embedded module imports +import foo_module_x +import bar_module_y + +# embedded function imports +from libtest import foo +from libtest import bar + +def unpack_gpu(ptr, *sizes: int): + """ + Converts a C pointer into a CuPy array to directly manipulate memory allocated in Fortran. + This function is needed for operations that require in-place modification of GPU data, + enabling changes made in Python to reflect immediately in the original Fortran memory space. + + Args: + ptr (cffi.CData): A CFFI pointer to GPU memory allocated by OpenACC, representing + the starting address of the data. This pointer must correspond to + a contiguous block of memory whose total size matches the product + of the specified dimensions. + *sizes (int): Variable length argument list specifying the dimensions of the array. + These sizes determine the shape of the resulting CuPy array. + + Returns: + cp.ndarray: A CuPy array that provides a direct view of the data pointed to by `ptr`. + This array shares the underlying data with the original Fortran code, allowing + modifications made through the array to affect the original data. + """ + + if not sizes: + raise ValueError("Sizes must be provided to determine the array shape.") + + length = np.prod(sizes) + c_type = ffi.getctype(ffi.typeof(ptr).item) + + dtype_map = { + "int": cp.int32, + "double": cp.float64, + } + dtype = dtype_map.get(c_type, None) + if dtype is None: + raise ValueError(f"Unsupported C data type: {c_type}") + + itemsize = ffi.sizeof(c_type) + total_size = length * itemsize + + # cupy array from OpenACC device pointer + current_device = cp.cuda.Device() + ptr_val = int(ffi.cast("uintptr_t", ptr)) + mem = cp.cuda.UnownedMemory(ptr_val, total_size, owner=ptr, device_id=current_device.id) + memptr = cp.cuda.MemoryPointer(mem, 0) + arr = cp.ndarray(shape=sizes, dtype=dtype, memptr=memptr, order="F") + + return arr + +def int_array_to_bool_array(int_array: NDArray) -> NDArray: + """ + Converts a NumPy array of integers to a boolean array. + In the input array, 0 represents False, and any non-zero value (1 or -1) represents True. + + Args: + int_array: A NumPy array of integers. + + Returns: + A NumPy array of booleans. + """ + bool_array = int_array != 0 + return bool_array + +@ffi.def_extern() +def foo_wrapper(one: int32, two: Field[CellDim, KDim], float64], n_Cell: int32, n_K: int32): + try: + # Unpack pointers into Ndarrays + two = unpack_gpu(two, n_Cell, n_K) + + # Allocate GT4Py Fields + two = np_as_located_field(CellDim, KDim)(two) + + foo(one, two) + + except Exception as e: + logging.exception(f"A Python error occurred: {e}") + return 1 + + return 0 + +@ffi.def_extern() +def bar_wrapper(one: Field[CellDim, KDim], float64], two: int32, n_Cell: int32, n_K: int32): + try: + # Unpack pointers into Ndarrays + one = unpack_gpu(one, n_Cell, n_K) + + # Allocate GT4Py Fields + one = np_as_located_field(CellDim, KDim)(one) + + bar(one, two) + + except Exception as e: + logging.exception(f"A Python error occurred: {e}") + return 1 + + return 0 + ''' + assert compare_ignore_whitespace(interface, expected) + + +def test_c_header(dummy_plugin): + interface = generate_c_header(dummy_plugin) + expected = """ + extern int foo_wrapper(int one, double *two, int n_Cell, int n_K); + extern int bar_wrapper(float *one, int two, int n_Cell, int n_K); """ assert compare_ignore_whitespace(interface, expected) diff --git a/tools/tests/py2fgen/test_diffusion_wrapper.py b/tools/tests/py2fgen/test_diffusion_wrapper.py new file mode 100644 index 0000000000..cb49e594c1 --- /dev/null +++ b/tools/tests/py2fgen/test_diffusion_wrapper.py @@ -0,0 +1,219 @@ +# ICON4Py - ICON inspired code in Python and GT4Py +# +# Copyright (c) 2022, ETH Zurich and MeteoSwiss +# All rights reserved. +# +# This file is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or any later +# version. See the LICENSE.txt file at the top-level directory of this +# distribution for a copy of the license or check . +# +# SPDX-License-Identifier: GPL-3.0-or-later +# type: ignore +import pytest +from gt4py.next import as_field +from icon4py.model.atmosphere.diffusion.diffusion import DiffusionType +from icon4py.model.common.dimension import ( + C2E2CDim, + C2E2CODim, + C2EDim, + CellDim, + E2C2VDim, + E2CDim, + EdgeDim, + KDim, + V2EDim, + VertexDim, +) +from icon4py.model.common.settings import xp + +from icon4pytools.py2fgen.wrappers.diffusion import diffusion_init, diffusion_run + + +# todo(samkellerhals): turn on and off using a marker/option (required ICON_GRID_LOC) +@pytest.mark.skip +def test_diffusion_wrapper_py(): + # grid parameters + num_cells = 20480 + num_edges = 30720 + num_vertices = 10242 + num_levels = 60 + num_c2ec2o = 4 + num_v2e = 6 + num_c2e = 2 + num_e2c2v = 4 + num_c2e2c = 3 + num_e2c = 3 + mean_cell_area = 24907282236.708576 + + # other configuration parameters + ndyn_substeps = 2 + dtime = 2.0 + rayleigh_damping_height = 50000 + nflatlev = 30 + nflat_gradp = 59 + + # diffusion configuration + diffusion_type = DiffusionType.SMAGORINSKY_4TH_ORDER # 5 + hdiff_w = True + hdiff_vn = True + zdiffu_t = True # Setting this to true triggers running stencil 15 with the boolean masks. + type_t_diffu = 2 + type_vn_diffu = 1 + hdiff_efdt_ratio = 24.0 + smagorinski_scaling_factor = 0.025 + hdiff_temp = True + + # input data - numpy + rng = xp.random.default_rng() + + vct_a = rng.uniform( + low=0, high=75000, size=(num_levels,) + ) # has to be from 0 to 75000, must have larger values than rayleigh damping height + theta_ref_mc = rng.uniform(low=0, high=1, size=(num_cells, num_levels)) + wgtfac_c = rng.uniform(low=0, high=1, size=(num_cells, num_levels + 1)) + e_bln_c_s = rng.uniform(low=0, high=1, size=(num_cells, num_c2e)) + geofac_div = rng.uniform(low=0, high=1, size=(num_cells, num_c2e)) + geofac_grg_x = rng.uniform(low=0, high=1, size=(num_cells, num_c2ec2o)) + geofac_grg_y = rng.uniform(low=0, high=1, size=(num_cells, num_c2ec2o)) + geofac_n2s = rng.uniform(low=0, high=1, size=(num_cells, num_c2ec2o)) + nudgecoeff_e = xp.zeros((num_edges,)) + rbf_coeff_1 = rng.uniform(low=0, high=1, size=(num_vertices, num_v2e)) + rbf_coeff_2 = rng.uniform(low=0, high=1, size=(num_vertices, num_v2e)) + dwdx = xp.zeros((num_cells, num_levels)) + dwdy = xp.zeros((num_cells, num_levels)) + hdef_ic = xp.zeros((num_cells, num_levels + 1)) + div_ic = xp.zeros((num_cells, num_levels + 1)) + w = rng.uniform(low=0, high=1, size=(num_cells, num_levels + 1)) + vn = rng.uniform(low=0, high=1, size=(num_edges, num_levels)) + exner = rng.uniform(low=0, high=1, size=(num_cells, num_levels)) + theta_v = rng.uniform(low=0, high=1, size=(num_cells, num_levels)) + rho = rng.uniform(low=0, high=1, size=(num_cells, num_levels)) + dual_normal_cell_x = rng.uniform(low=0, high=1, size=(num_edges, num_e2c)) + dual_normal_cell_y = rng.uniform(low=0, high=1, size=(num_edges, num_e2c)) + dual_normal_vert_x = rng.uniform(low=0, high=1, size=(num_edges, num_e2c2v)) + dual_normal_vert_y = rng.uniform(low=0, high=1, size=(num_edges, num_e2c2v)) + primal_normal_cell_x = rng.uniform(low=0, high=1, size=(num_edges, num_e2c)) + primal_normal_cell_y = rng.uniform(low=0, high=1, size=(num_edges, num_e2c)) + primal_normal_vert_x = rng.uniform(low=0, high=1, size=(num_edges, num_e2c)) + primal_normal_vert_y = rng.uniform(low=0, high=1, size=(num_edges, num_e2c)) + tangent_orientation = rng.uniform(low=0, high=1, size=(num_edges)) + inverse_primal_edge_lengths = rng.uniform(low=0, high=1, size=(num_edges)) + inv_dual_edge_length = rng.uniform(low=0, high=1, size=(num_edges)) + inv_vert_vert_length = rng.uniform(low=0, high=1, size=(num_edges)) + edge_areas = rng.uniform(low=0, high=1, size=(num_edges)) + f_e = rng.uniform(low=0, high=1, size=(num_edges)) + cell_areas = rng.uniform(low=0, high=1, size=(num_cells)) + zd_diffcoef = rng.uniform(low=0, high=1, size=(num_cells, num_levels)) + zd_vertoffset = xp.round( + rng.uniform(low=0, high=1, size=(num_cells, num_c2e2c, num_levels)) + ).astype(xp.int32) + zd_intcoef = rng.uniform(low=0, high=1, size=(num_cells, num_c2e2c, num_levels)) + + # Create a boolean array based on a condition + mask_hdiff = rng.uniform(low=0, high=1, size=(num_cells, num_levels)) + mask_hdiff = mask_hdiff < 0.5 + + # input data - gt4py fields + theta_ref_mc = as_field((CellDim, KDim), theta_ref_mc) + wgtfac_c = as_field((CellDim, KDim), wgtfac_c) + vct_a = as_field((KDim,), vct_a) + e_bln_c_s = as_field((CellDim, C2EDim), e_bln_c_s) + geofac_div = as_field((CellDim, C2EDim), geofac_div) + geofac_grg_x = as_field((CellDim, C2E2CODim), geofac_grg_x) + geofac_grg_y = as_field((CellDim, C2E2CODim), geofac_grg_y) + geofac_n2s = as_field((CellDim, C2E2CODim), geofac_n2s) + nudgecoeff_e = as_field((EdgeDim,), nudgecoeff_e) + rbf_coeff_1 = as_field((VertexDim, V2EDim), rbf_coeff_1) + rbf_coeff_2 = as_field((VertexDim, V2EDim), rbf_coeff_2) + dwdx = as_field((CellDim, KDim), dwdx) + dwdy = as_field((CellDim, KDim), dwdy) + hdef_ic = as_field((CellDim, KDim), hdef_ic) + div_ic = as_field((CellDim, KDim), div_ic) + mask_hdiff = as_field((CellDim, KDim), mask_hdiff) + zd_diffcoef = as_field((CellDim, KDim), zd_diffcoef) + zd_vertoffset = as_field((CellDim, C2E2CDim, KDim), zd_vertoffset) + zd_intcoef = as_field((CellDim, C2E2CDim, KDim), zd_intcoef) + w = as_field((CellDim, KDim), w) + vn = as_field((EdgeDim, KDim), vn) + exner = as_field((CellDim, KDim), exner) + theta_v = as_field((CellDim, KDim), theta_v) + rho = as_field((CellDim, KDim), rho) + dual_normal_cell_x = as_field((EdgeDim, E2CDim), dual_normal_cell_x) + dual_normal_cell_y = as_field((EdgeDim, E2CDim), dual_normal_cell_y) + dual_normal_vert_x = as_field((EdgeDim, E2C2VDim), dual_normal_vert_x) + dual_normal_vert_y = as_field((EdgeDim, E2C2VDim), dual_normal_vert_y) + primal_normal_cell_x = as_field((EdgeDim, E2CDim), primal_normal_cell_x) + primal_normal_cell_y = as_field((EdgeDim, E2CDim), primal_normal_cell_y) + primal_normal_vert_x = as_field((EdgeDim, E2C2VDim), primal_normal_vert_x) + primal_normal_vert_y = as_field((EdgeDim, E2C2VDim), primal_normal_vert_y) + tangent_orientation = as_field((EdgeDim,), tangent_orientation) + inverse_primal_edge_lengths = as_field((EdgeDim,), inverse_primal_edge_lengths) + inv_dual_edge_length = as_field((EdgeDim,), inv_dual_edge_length) + inv_vert_vert_length = as_field((EdgeDim,), inv_vert_vert_length) + edge_areas = as_field((EdgeDim,), edge_areas) + f_e = as_field((EdgeDim,), f_e) + cell_areas = as_field((CellDim,), cell_areas) + + diffusion_init( + vct_a=vct_a, + theta_ref_mc=theta_ref_mc, + wgtfac_c=wgtfac_c, + e_bln_c_s=e_bln_c_s, + geofac_div=geofac_div, + geofac_grg_x=geofac_grg_x, + geofac_grg_y=geofac_grg_y, + geofac_n2s=geofac_n2s, + nudgecoeff_e=nudgecoeff_e, + rbf_coeff_1=rbf_coeff_1, + rbf_coeff_2=rbf_coeff_2, + num_levels=num_levels, + mean_cell_area=mean_cell_area, + ndyn_substeps=ndyn_substeps, + rayleigh_damping_height=rayleigh_damping_height, + nflatlev=nflatlev, + nflat_gradp=nflat_gradp, + diffusion_type=diffusion_type, + hdiff_w=hdiff_w, + hdiff_vn=hdiff_vn, + zdiffu_t=zdiffu_t, + type_t_diffu=type_t_diffu, + type_vn_diffu=type_vn_diffu, + hdiff_efdt_ratio=hdiff_efdt_ratio, + smagorinski_scaling_factor=smagorinski_scaling_factor, + hdiff_temp=hdiff_temp, + tangent_orientation=tangent_orientation, + inverse_primal_edge_lengths=inverse_primal_edge_lengths, + inv_dual_edge_length=inv_dual_edge_length, + inv_vert_vert_length=inv_vert_vert_length, + edge_areas=edge_areas, + f_e=f_e, + cell_areas=cell_areas, + primal_normal_vert_x=primal_normal_vert_x, + primal_normal_vert_y=primal_normal_vert_y, + dual_normal_vert_x=dual_normal_vert_x, + dual_normal_vert_y=dual_normal_vert_y, + primal_normal_cell_x=primal_normal_cell_x, + primal_normal_cell_y=primal_normal_cell_y, + dual_normal_cell_x=dual_normal_cell_x, + dual_normal_cell_y=dual_normal_cell_y, + mask_hdiff=mask_hdiff, + zd_diffcoef=zd_diffcoef, + zd_vertoffset=zd_vertoffset, + zd_intcoef=zd_intcoef, + ) + + diffusion_run( + w=w, + vn=vn, + exner=exner, + theta_v=theta_v, + rho=rho, + hdef_ic=hdef_ic, + div_ic=div_ic, + dwdx=dwdx, + dwdy=dwdy, + dtime=dtime, + linit=False, + ) diff --git a/tools/tests/py2fgen/test_parsing.py b/tools/tests/py2fgen/test_parsing.py index 3124d0bac0..71c59fa1f5 100644 --- a/tools/tests/py2fgen/test_parsing.py +++ b/tools/tests/py2fgen/test_parsing.py @@ -11,13 +11,48 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -from icon4pytools.py2fgen.parsing import parse +import ast + +import pytest + +from icon4pytools.py2fgen.parsing import ImportStmtVisitor, TypeHintVisitor, parse from icon4pytools.py2fgen.template import CffiPlugin +source = """ +import foo +import bar + +def test_function(x: Field[[EdgeDim, KDim], float64], y: int): + return x * y +""" + + def test_parse_functions_on_wrapper(): module_path = "icon4pytools.py2fgen.wrappers.diffusion" - function_name = "diffusion_init" - plugin = parse(module_path, function_name) + functions = ["diffusion_init", "diffusion_run"] + plugin = parse(module_path, functions, "diffusion_plugin") assert isinstance(plugin, CffiPlugin) - assert plugin.plugin_name == "diffusion_init_plugin" + + +def test_import_visitor(): + tree = ast.parse(source) + extractor = ImportStmtVisitor() + extractor.visit(tree) + expected_imports = ["import foo", "import bar"] + assert extractor.import_statements == expected_imports + + +def test_type_hint_visitor(): + tree = ast.parse(source) + visitor = TypeHintVisitor() + visitor.visit(tree) + expected_type_hints = {"x": "Field[[EdgeDim, KDim], float64]", "y": "int"} + assert visitor.type_hints == expected_type_hints + + +def test_function_missing_type_hints(): + tree = ast.parse(source.replace(": int", "")) + visitor = TypeHintVisitor() + with pytest.raises(TypeError): + visitor.visit(tree) diff --git a/tools/tox.ini b/tools/tox.ini index be68d08e88..0c8b7eb934 100644 --- a/tools/tox.ini +++ b/tools/tox.ini @@ -15,7 +15,7 @@ deps = -r {toxinidir}/requirements-dev.txt commands = -pytest -v -s -n auto -cache-clear --cov --cov-config=pyproject.toml --cov-reset --doctest-modules src/icon4pytools/ - pytest -vvv -l -s --full-trace -n auto --cov-config=pyproject.toml + pytest -vvv -s -n auto --cov-config=pyproject.toml commands_post = rm -rf tests/_reports/coverage_html -coverage html