Skip to content

Commit e8fd165

Browse files
committed
Merge tag 'mi_250428' into update_MARBL_FeForcing
2 parents 80b70a2 + e9c44d0 commit e8fd165

17 files changed

Lines changed: 527 additions & 95 deletions

.github/workflows/general-ci-tests.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,10 @@ jobs:
133133
- uses: actions/checkout@v4
134134

135135
# Run black check
136-
- uses: psf/black@stable
136+
- uses: psf/black@24.1.0
137137
with:
138138
options: "--check --verbose"
139139
src: "./cime_config"
140140

141-
142141

143142

.gitmodules

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
path = MOM6
33
url = https://github.com/NCAR/MOM6.git
44
fxDONOTUSEurl = https://github.com/NCAR/MOM6.git
5-
fxtag = dev/ncar_250128
5+
fxtag = dev/ncar_250428
66
fxrequired = AlwaysRequired
77

88
[submodule "stochastic_physics"]
99
path = externals/stochastic_physics
1010
url = https://github.com/ESCOMP/stochastic_physics.git
1111
fxDONOTUSEurl = https://github.com/ESCOMP/stochastic_physics.git
12-
fxtag = ocn_skeb_240807
12+
fxtag = fcb_0.0.1
1313
fxrequired = AlwaysRequired
1414

1515
[submodule "MARBL"]

MOM6

Submodule MOM6 updated 32 files

cime_config/MARBL_scripts/MARBL_diags_to_diag_table.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def __init__(self, vert_grid):
6767
new_file_freq_units = "days" if self._nstep_output else None
6868
suffix_dict = {
6969
'$OCN_DIAG_MODE == "spinup"': "h.bgc.native_annual%4yr",
70-
"$TEST == True": "h.bgc.native%4yr-%2mo",
70+
"$TEST == True": "h.bgc.native%4yr-%2mo-%2dy",
7171
"else": "h.bgc.native%4yr-%2mo",
7272
}
7373
output_freq_units_dict = {
@@ -83,7 +83,7 @@ def __init__(self, vert_grid):
8383
if vert_grid in ["interpolated", "both"]:
8484
suffix_dict = {
8585
'$OCN_DIAG_MODE == "spinup"': "h.bgc.z_annual%4yr",
86-
"$TEST == True": "h.bgc.z%4yr-%2mo",
86+
"$TEST == True": "h.bgc.z%4yr-%2mo-%2dy",
8787
f"{self._nstep_output} == True": "h.bgc.z_nstep%4yr-%2mo-%2dy",
8888
"else": "h.bgc.z%4yr-%2mo",
8989
}

cime_config/config_archive.xml

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,27 @@
1111
h.bgc.*[._optional instance number].nc -->
1212
<hist_file_extension>h\.bgc\..*?.?[_\d+]+.nc$</hist_file_extension>
1313
<!-- match filenames of the form
14-
ic.(date string)[._optional instance number].nc[.optional tile number] -->
15-
<hist_file_extension>ic.[-\d+]+(\._\d*)?\.nc(\.\d*)?$</hist_file_extension>
16-
<hist_file_ext_regex>\w+\.\w+(\._\d*)?</hist_file_ext_regex>
14+
ic.(date string[_optional id for splitting date over many files)[._optional instance number].nc[.optional tile number] -->
15+
<hist_file_extension>ic.[-\d(_\d)?+]+(\._\d*)?\.nc(\.\d*)?$</hist_file_extension>
16+
<hist_file_ext_regex>\w+\.\w+(\.\w+)?(\._\d*)?</hist_file_ext_regex>
1717
<rpointer>
18-
<rpointer_file>rpointer.ocn$NINST_STRING</rpointer_file>
18+
<rpointer_file>rpointer.ocn$NINST_STRING.$DATENAME</rpointer_file>
1919
<rpointer_content>$CASE.mom6$NINST_STRING.r.$DATENAME.nc</rpointer_content>
2020
</rpointer>
21+
<test_file_names>
22+
<tfile disposition="copy">rpointer.ocn.1976-01-01-00000</tfile>
23+
<tfile disposition="copy">casename.mom6.r.1976-01-01-00000.nc</tfile>
24+
<tfile disposition="copy">casename.mom6.r.1976-01-01-00000_1.nc</tfile>
25+
<tfile disposition="move">casename.mom6.h.bgc.native.1976-01-01.nc</tfile>
26+
<tfile disposition="move">casename.mom6.h.bgc.z.1976-01-01.nc</tfile>
27+
<tfile disposition="move">casename.mom6.h.native.1976-01-01-00000.nc</tfile>
28+
<tfile disposition="move">casename.mom6.h.ocean_geometry.nc</tfile>
29+
<tfile disposition="move">casename.mom6.h.rho2.1976-01-01-00000.nc</tfile>
30+
<tfile disposition="move">casename.mom6.h.sfc.1976-01-01-00000.nc</tfile>
31+
<tfile disposition="move">casename.mom6.h.static.nc</tfile>
32+
<tfile disposition="move">casename.mom6.h.z.1976-01-01-00000.nc</tfile>
33+
<tfile disposition="move">casename.mom6.ic.1976-01-01-00000.nc</tfile>
34+
<tfile disposition="move">casename.mom6.ic.1976-01-01-00000_1.nc</tfile>
35+
</test_file_names>
2136
</comp_archive_spec>
2237
</components>

cime_config/config_compsets.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,4 +110,14 @@
110110
<lname>1850_DATM%JRA-1p5-2023_SLND_CICE_MOM6%MARBL-ABIO_DROF%JRA-1p5-2023_SGLC_SWAV</lname>
111111
</compset>
112112

113+
<compset>
114+
<alias>GW1850MARBL_JRA</alias>
115+
<lname>1850_DATM%JRA-1p5-2023_SLND_CICE_MOM6%MARBL-BIO_DROF%JRA-1p5-2023_SGLC_WW3</lname>
116+
</compset>
117+
118+
<compset>
119+
<alias>GW1850ABIOMARBL_JRA</alias>
120+
<lname>1850_DATM%JRA-1p5-2023_SLND_CICE_MOM6%MARBL-ABIO_DROF%JRA-1p5-2023_SGLC_WW3</lname>
121+
</compset>
122+
113123
</compsets>

cime_config/config_pes.xml

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@
171171
<rootpe_rof>0</rootpe_rof>
172172
<rootpe_cpl>0</rootpe_cpl>
173173
<rootpe_ice>128</rootpe_ice>
174-
<rootpe_ocn>2560</rootpe_ocn>
174+
<rootpe_ocn>256</rootpe_ocn>
175175
<rootpe_lnd>0</rootpe_lnd>
176176
<rootpe_wav>0</rootpe_wav>
177177
<rootpe_glc>0</rootpe_glc>
@@ -186,7 +186,7 @@
186186
<ntasks_ice>128</ntasks_ice>
187187
<ntasks_ocn>896</ntasks_ocn>
188188
<ntasks_lnd>1</ntasks_lnd>
189-
<ntasks_wav>256</ntasks_wav>
189+
<ntasks_wav>128</ntasks_wav>
190190
<ntasks_glc>1</ntasks_glc>
191191
</ntasks>
192192
<nthrds>
@@ -204,7 +204,40 @@
204204
<rootpe_rof>0</rootpe_rof>
205205
<rootpe_cpl>0</rootpe_cpl>
206206
<rootpe_ice>0</rootpe_ice>
207-
<rootpe_ocn>384</rootpe_ocn>
207+
<rootpe_ocn>256</rootpe_ocn>
208+
<rootpe_lnd>0</rootpe_lnd>
209+
<rootpe_wav>128</rootpe_wav>
210+
<rootpe_glc>0</rootpe_glc>
211+
</rootpe>
212+
</pes>
213+
<pes pesize="any" compset="_DATM.+_CICE.*_MOM6%[^_]*MARBL-BIO.+_WW3">
214+
<comment>none</comment>
215+
<ntasks>
216+
<ntasks_atm>128</ntasks_atm>
217+
<ntasks_rof>128</ntasks_rof>
218+
<ntasks_cpl>128</ntasks_cpl>
219+
<ntasks_ice>128</ntasks_ice>
220+
<ntasks_ocn>2560</ntasks_ocn>
221+
<ntasks_lnd>1</ntasks_lnd>
222+
<ntasks_wav>128</ntasks_wav>
223+
<ntasks_glc>1</ntasks_glc>
224+
</ntasks>
225+
<nthrds>
226+
<nthrds_atm>1</nthrds_atm>
227+
<nthrds_lnd>1</nthrds_lnd>
228+
<nthrds_rof>1</nthrds_rof>
229+
<nthrds_ice>1</nthrds_ice>
230+
<nthrds_ocn>1</nthrds_ocn>
231+
<nthrds_glc>1</nthrds_glc>
232+
<nthrds_wav>1</nthrds_wav>
233+
<nthrds_cpl>1</nthrds_cpl>
234+
</nthrds>
235+
<rootpe>
236+
<rootpe_atm>0</rootpe_atm>
237+
<rootpe_rof>0</rootpe_rof>
238+
<rootpe_cpl>0</rootpe_cpl>
239+
<rootpe_ice>0</rootpe_ice>
240+
<rootpe_ocn>256</rootpe_ocn>
208241
<rootpe_lnd>0</rootpe_lnd>
209242
<rootpe_wav>128</rootpe_wav>
210243
<rootpe_glc>0</rootpe_glc>

cime_config/tools/lbe.py

Lines changed: 98 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,19 @@ def gen_auto_mask_table(
8383
Output directory to write the mask table.
8484
"""
8585

86-
ds_topog = xr.open_dataset(topo_file_path)
87-
ny, nx = ds_topog.mask.shape
88-
8986
ibuf = 2
9087
jbuf = 2
9188
num_masked_blocks = 0
9289

93-
mask = np.zeros((ny + 2 * jbuf, nx + 2 * ibuf))
94-
95-
mask[jbuf : ny + jbuf, ibuf : nx + ibuf] = ds_topog.mask.data
90+
ds_topog = xr.open_dataset(topo_file_path)
91+
if "mask" in ds_topog:
92+
ny, nx = ds_topog.mask.shape
93+
mask = np.zeros((ny + 2 * jbuf, nx + 2 * ibuf))
94+
mask[jbuf : ny + jbuf, ibuf : nx + ibuf] = ds_topog.mask.data
95+
elif "wet" in ds_topog:
96+
ny, nx = ds_topog.wet.shape
97+
mask = np.zeros((ny + 2 * jbuf, nx + 2 * ibuf))
98+
mask[jbuf : ny + jbuf, ibuf : nx + ibuf] = ds_topog.wet.data
9699

97100
# fill in buffer cells
98101
if reentrant_x:
@@ -123,37 +126,98 @@ def gen_auto_mask_table(
123126
# ratio of ocean cells to total number of cells
124127
glob_ocn_frac = mask[jbuf : ny + jbuf, ibuf : nx + ibuf].sum() / (ny * nx)
125128

129+
pfrac = 0.01
130+
max_feasible_p = 0
131+
target_io_pes = args.tiopes
132+
found_feasible_layout = False
133+
126134
# Iteratively check for all possible division counts starting from the upper bound of npes/glob_ocn_frac,
127-
# which is over-optimistic for realistic domains, but may be satisfied with idealized domains.
128-
for p in range(int(np.ceil(npes / glob_ocn_frac)), npes, -1):
129-
130-
# compute the layout for the current division count, p
131-
idiv, jdiv = MOM_define_layout(nx, ny, p)
132-
133-
# don't bother checking this p if the aspect ratio is extreme
134-
r_p = (nx / idiv) / (ny / jdiv)
135-
if r_p * r_extreme < 1.0 or r_extreme < r_p:
136-
continue
137-
138-
# Get the number of masked_blocks for this particular division count
139-
mask_table = determine_land_blocks(mask, nx, ny, idiv, jdiv, ibuf, jbuf)
140-
141-
# If we can eliminate enough blocks to reach the target npes, adopt
142-
# this p (and the associated layout) and terminate the iteration.
143-
num_masked_blocks = len(mask_table)
144-
if p - num_masked_blocks <= npes:
145-
print("Found the optimum layout for auto-masking. Terminating iteration...")
146-
print(f"\t new ndivs: {p}, num_masked_blocks: {p-npes}")
135+
# which is over-optimistic for realistic domains, but may be satisfied with idealized domains. The first encountered
136+
# feasible division count is stored in max_feasible_p. If the target_io_pes is not achievable with this layout,
137+
# the iteration continues until max_feasible_p * (1 - pfrac) is reached or the target_io_pes is satisfiable.
138+
# If not, the target_io_pes is decremented and the iteration is re-done from max_feasible_p to max_feasible_p * (1 - pfrac).
139+
140+
for i in range(target_io_pes, 0, -1):
141+
142+
if found_feasible_layout:
147143
break
148144

145+
if max_feasible_p == 0: # first iteration
146+
p_up = int(np.ceil(npes / glob_ocn_frac))
147+
else:
148+
p_up = max_feasible_p
149+
150+
for p in range(p_up, npes, -1):
151+
152+
# compute the layout for the current division count, p
153+
idiv, jdiv = MOM_define_layout(nx, ny, p)
154+
155+
# don't bother checking this p if the aspect ratio is extreme
156+
ar = (nx / idiv) / (ny / jdiv)
157+
if ar * r_extreme < 1.0 or r_extreme < ar:
158+
continue
159+
160+
# Get the number of masked_blocks for this particular division count
161+
mask_table = determine_land_blocks(mask, nx, ny, idiv, jdiv, ibuf, jbuf)
162+
163+
# If we can eliminate enough blocks to reach the target npes, adopt
164+
# this p (and the associated layout) and terminate the iteration.
165+
num_masked_blocks = len(mask_table)
166+
167+
if p - num_masked_blocks <= npes:
168+
print(
169+
f"ndivs: {p}, masked_blocks: {num_masked_blocks}",
170+
" idiv: ",
171+
idiv,
172+
"jdiv",
173+
jdiv,
174+
)
175+
176+
if max_feasible_p == 0:
177+
print("^^^^^^^^^^^^^^^ first feasible layout ^^^^^^^^^^^^^^^")
178+
max_feasible_p = p
179+
if (idiv * jdiv) % i == 0:
180+
idiv_io, jdiv_io = determine_io_layout(idiv, jdiv, i)
181+
# if the io layout ratio is extreme, skip this layout
182+
ar = (idiv / idiv_io) / (jdiv / jdiv_io)
183+
if ar * r_extreme < 1.0 or r_extreme < ar:
184+
continue
185+
print(f"IO layout: {idiv_io} x {jdiv_io}")
186+
print(
187+
"Found the optimum layout for auto-masking. Terminating iteration."
188+
)
189+
found_feasible_layout = True
190+
break
191+
192+
if p <= max_feasible_p * (1 - pfrac):
193+
break
194+
149195
if num_masked_blocks == 0:
150196
raise RuntimeError(
151197
"Couldn't auto-eliminate any land blocks. Try to increase the number"
152198
)
153199

154200
# Call determine_land_blocks once again, this time to retrieve and write out the mask_table.
155201
mask_table = determine_land_blocks(mask, nx, ny, idiv, jdiv, ibuf, jbuf)
156-
write_auto_mask_file(mask_table, idiv, jdiv, npes, output_dir)
202+
203+
204+
def determine_io_layout(idiv, jdiv, nio):
205+
"""Determines the optimal I/O layout given the number of partitions in x and y direction and the number of I/O PEs."""
206+
min_ratio_diff = float("inf")
207+
best_idiv_io, best_jdiv_io = 1, nio
208+
209+
for f in range(1, nio + 1):
210+
if nio % f == 0:
211+
idiv_io, jdiv_io = f, nio // f
212+
213+
if idiv % idiv_io == 0 and jdiv % jdiv_io == 0:
214+
ratio_diff = abs((idiv_io / jdiv_io) - (idiv / jdiv))
215+
216+
if ratio_diff < min_ratio_diff:
217+
min_ratio_diff = ratio_diff
218+
best_idiv_io, best_jdiv_io = idiv_io, jdiv_io
219+
220+
return best_idiv_io, best_jdiv_io
157221

158222

159223
def write_auto_mask_file(
@@ -209,6 +273,13 @@ def write_auto_mask_file(
209273
required=True,
210274
help="Number of MOM6 PEs (NTASKS_OCN)",
211275
)
276+
parser.add_argument(
277+
"--tiopes",
278+
default=1,
279+
type=int,
280+
required=False,
281+
help="Number of target I/O PEs (NTASKS_IO) (default: 1)",
282+
)
212283
parser.add_argument(
213284
"-rx",
214285
default=False,

0 commit comments

Comments
 (0)