Skip to content

Commit

Permalink
merge develop
Browse files Browse the repository at this point in the history
  • Loading branch information
oelbert committed Sep 4, 2024
2 parents 6ab1dd5 + 7f84b32 commit 7bcce4b
Show file tree
Hide file tree
Showing 5 changed files with 366 additions and 241 deletions.
42 changes: 8 additions & 34 deletions ndsl/dsl/stencil.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from ndsl.dsl.typing import Float, Index3D, cast_to_index3d
from ndsl.initialization.sizer import GridSizer, SubtileGridSizer
from ndsl.quantity import Quantity
from ndsl.testing import comparison
from ndsl.testing.comparison import LegacyMetric


try:
Expand Down Expand Up @@ -68,40 +68,14 @@ def report_difference(args, kwargs, args_copy, kwargs_copy, function_name, gt_id


def report_diff(arg: np.ndarray, numpy_arg: np.ndarray, label) -> str:
metric_err = comparison.compare_arr(arg, numpy_arg)
nans_match = np.logical_and(np.isnan(arg), np.isnan(numpy_arg))
n_points = np.product(arg.shape)
failures_14 = n_points - np.sum(
np.logical_or(
nans_match,
metric_err < 1e-14,
)
)
failures_10 = n_points - np.sum(
np.logical_or(
nans_match,
metric_err < 1e-10,
)
metric = LegacyMetric(
reference_values=arg,
computed_values=numpy_arg,
eps=1e-13,
ignore_near_zero_errors=False,
near_zero=0,
)
failures_8 = n_points - np.sum(
np.logical_or(
nans_match,
metric_err < 1e-8,
)
)
greatest_error = np.max(metric_err[~np.isnan(metric_err)])
if greatest_error == 0.0 and failures_14 == 0:
report = ""
else:
report = f"\n {label}: "
report += f"max_err={greatest_error}"
if failures_14 > 0:
report += f" 1e-14 failures: {failures_14}"
if failures_10 > 0:
report += f" 1e-10 failures: {failures_10}"
if failures_8 > 0:
report += f" 1e-8 failures: {failures_8}"
return report
return metric.__repr__()


@dataclasses.dataclass
Expand Down
11 changes: 11 additions & 0 deletions ndsl/stencils/testing/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ def pytest_addoption(parser):
default="cubed-sphere",
help='Topology of the grid. "cubed-sphere" means a 6-faced grid, "doubly-periodic" means a 1 tile grid. Default to "cubed-sphere".',
)
parser.addoption(
"--multimodal_metric",
action="store_true",
default=False,
help="Use the multi-modal float metric. Default to False.",
)


def pytest_configure(config):
Expand Down Expand Up @@ -389,6 +395,11 @@ def failure_stride(pytestconfig):
return int(pytestconfig.getoption("failure_stride"))


@pytest.fixture()
def multimodal_metric(pytestconfig):
return bool(pytestconfig.getoption("multimodal_metric"))


@pytest.fixture()
def grid(pytestconfig):
return pytestconfig.getoption("grid")
Expand Down
47 changes: 26 additions & 21 deletions ndsl/stencils/testing/serialbox_to_netcdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,11 @@ def get_parser():
help="[Optional] Give the name of the data, will default to Generator_rankX",
)
parser.add_argument(
"-m", "--merge",
action='store_true',
"-m",
"--merge",
action="store_true",
default=False,
help="merges datastreams blocked into separate savepoints"
help="merges datastreams blocked into separate savepoints",
)
return parser

Expand Down Expand Up @@ -64,7 +65,12 @@ def get_serializer(data_path: str, rank: int, data_name: Optional[str] = None):
return serialbox.Serializer(serialbox.OpenModeKind.Read, data_path, name)


def main(data_path: str, output_path: str, merge_blocks: bool, data_name: Optional[str] = None):
def main(
data_path: str,
output_path: str,
merge_blocks: bool,
data_name: Optional[str] = None,
):
os.makedirs(output_path, exist_ok=True)
namelist_filename_in = os.path.join(data_path, "input.nml")

Expand All @@ -77,18 +83,20 @@ def main(data_path: str, output_path: str, merge_blocks: bool, data_name: Option
namelist = f90nml.read(namelist_filename_out)
if namelist["fv_core_nml"]["grid_type"] <= 3:
total_ranks = (
6 * namelist["fv_core_nml"]["layout"][0] * namelist["fv_core_nml"]["layout"][1]
6
* namelist["fv_core_nml"]["layout"][0]
* namelist["fv_core_nml"]["layout"][1]
)
else:
total_ranks = (
namelist["fv_core_nml"]["layout"][0] * namelist["fv_core_nml"]["layout"][1]
)
nx = int((namelist["fv_core_nml"]['npx'] - 1) / (
namelist["fv_core_nml"]['layout'][0]
))
ny = int((namelist["fv_core_nml"]['npy'] - 1) / (
namelist["fv_core_nml"]['layout'][1]
))
nx = int(
(namelist["fv_core_nml"]["npx"] - 1) / (namelist["fv_core_nml"]["layout"][0])
)
ny = int(
(namelist["fv_core_nml"]["npy"] - 1) / (namelist["fv_core_nml"]["layout"][1])
)

# all ranks have the same names, just look at first one
serializer_0 = get_serializer(data_path, rank=0, data_name=data_name)
Expand All @@ -113,22 +121,19 @@ def main(data_path: str, output_path: str, merge_blocks: bool, data_name: Option
rank_data[name].append(
read_serialized_data(serializer, savepoint, name)
)
if merge_blocks and len(rank_data[name] > 1):
nblocks = len(rank_data[name])
if merge_blocks and len(rank_data[name]) > 1:
full_data = np.array(rank_data[name])
if len(full_data.shape) > 1:
if (nx * ny == full_data.shape[0] * full_data.shape[1]):
if nx * ny == full_data.shape[0] * full_data.shape[1]:
# If we have an (i, x) array from each block reshape it
new_shape = (nx, ny) + full_data.shape[2:]
full_data = full_data.reshape(new_shape)
elif full_data.shape[1] == namelist["fv_core_nml"]['npz']:
# If it's a k-array from each block just take one
full_data = full_data[0]
else:
return IndexError(
"Shape mismatch in block merging: "
f"{full_data.shape[0]} by {full_data.shape[1]} "
f"is not compatible with {nx} by {ny}"
)
# We have one array for all blocks
# could be a k-array or something else, so we take one copy
# TODO: is there a decent check for this?
full_data = full_data[0]
elif len(full_data.shape) == 1:
# if it's a scalar from each block then just take one
full_data = full_data[0]
Expand Down
Loading

0 comments on commit 7bcce4b

Please sign in to comment.