Skip to content

Commit a806c0f

Browse files
committed
Homme(xx)/SL: Finish C++/Kokkos for ETM; modify vertical discretization.
The atmosphere semi-Lagrangian tracer transport method's enhanced trajectory method (ETM) is a stealth feature intended to make tracer transport time steps even longer and, in any case, more flexible. This PR completes the C++/Kokkos version of the ETM, in particular support for semi_lagrange_trajectory_nvelocity > 2. It also modifies the vertical discretization relative to the original ETM implementation, in light of issues at and around the tropopause when using the ETM in test v3 simulations. This new approach resolves the tropopause issue. Finally, this PR strengthens the homme_integration test suite as follows: * add a new planar tracer transport test with analytical solution at the end time, with space- and time-varying surface pressure; * add instances of this test to the homme_integration test suite; * add a cmake tool to check error output for the recently added sphere and new plane tracer transport tests when running this suite; * activate the Kokkos builds in the non-BFB part of homme_integration, turning on the parts of the unit tests that are meaningful in the non-BFB build and the recently added and new tracer transport tests.
1 parent 31de276 commit a806c0f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2007
-645
lines changed

components/eamxx/cime_config/namelist_defaults_eamxx.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,9 @@ be lost if SCREAM_HACK_XML is not enabled.
897897
<hypervis_subcycle_q hgrid=".*pg2">6</hypervis_subcycle_q>
898898
<transport_alg hgrid=".*pg2">12</transport_alg>
899899
<semi_lagrange_trajectory_nsubstep>0</semi_lagrange_trajectory_nsubstep>
900+
<semi_lagrange_trajectory_nvelocity>-1</semi_lagrange_trajectory_nvelocity>
901+
<semi_lagrange_halo>-1</semi_lagrange_halo>
902+
<semi_lagrange_diagnostics>0</semi_lagrange_diagnostics>
900903
<!-- Other settings that we'll trigger based on pg2 for convenience -->
901904
<se_ftype valid_values="0,2" hgrid=".*pg2">2</se_ftype>
902905
<mesh_file type="file">none</mesh_file>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
ATMCHANGE=$CIMEROOT/../components/eamxx/scripts/atmchange
22

33
$ATMCHANGE semi_lagrange_trajectory_nsubstep=2 -b
4+
$ATMCHANGE semi_lagrange_trajectory_nvelocity=3 -b

components/homme/cmake/HommeMacros.cmake

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,24 @@ MACRO(CREATE_CXX_VS_F90_TESTS_WITH_PROFILE TESTS_LIST testProfile)
829829
ENDFOREACH ()
830830
ENDMACRO(CREATE_CXX_VS_F90_TESTS_WITH_PROFILE)
831831

832+
function(check_transport_error_norms
833+
TEST_NAME TCEN_ERROR_ANCHOR TCEN_FILENAME TCEN_UPPER_BOUNDS)
834+
# Check prescribed-wind tracer transport test error-norm output, which is
835+
# available with some of these tests. This function encapsulates the setup
836+
# steps to add a check after a tracer transport test runs. See
837+
# TransportCheckErrorNorms.cmake.in for details.
838+
configure_file(
839+
${HOMME_SOURCE_DIR}/cmake/TransportCheckErrorNorms.cmake.in
840+
${HOMME_BINARY_DIR}/tests/${TEST_NAME}/check.cmake
841+
@ONLY)
842+
add_test(
843+
NAME "${TEST_NAME}_l2err"
844+
COMMAND ${CMAKE_COMMAND} -P check.cmake
845+
WORKING_DIRECTORY ${HOMME_BINARY_DIR}/tests/${TEST_NAME})
846+
set_tests_properties(
847+
"${TEST_NAME}_l2err" PROPERTIES DEPENDS "${TEST_NAME}")
848+
endfunction()
849+
832850
macro(testQuadPrec HOMME_QUAD_PREC)
833851

834852
TRY_COMPILE(COMPILE_RESULT_VAR
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# This utility checks output of the form
2+
# planar_conv> l2 linf
3+
# planar_conv> Q 1 3.7612654153016604E-03 9.8620728873592828E-03
4+
# planar_conv> Q 2 3.9526251584022527E-03 8.2639849437505641E-03
5+
# against caller-provided upper bounds on the l2 norms. Output of this sort
6+
# appears on stdout at the end of some tracer transport tests. 'planar_conv' can
7+
# be something else; it is caller-configurable. Example usage:
8+
# set(TCEN_ERROR_ANCHOR "planar_conv")
9+
# set(TCEN_FILENAME "out.txt")
10+
# set(TCEN_UPPER_BOUNDS "3.9e-3;4.1e-3")
11+
# configure_file(TransportCheckErrorNorms.cmake.in check.cmake @ONLY)
12+
# add_test(
13+
# NAME "${TEST_NAME}_l2err"
14+
# COMMAND ${CMAKE_COMMAND} -P check.cmake
15+
# WORKING_DIRECTORY ${HOMME_BINARY_DIR}/tests/${TEST_NAME})
16+
# set_tests_properties(
17+
# "${TEST_NAME}_l2err" PROPERTIES DEPENDS "${TEST_NAME}")
18+
# Function check_transport_error_norms in HommeMacros.cmake encapsulates the
19+
# above commands.
20+
21+
function(check_error_norms test_name filename upper_bounds)
22+
execute_process(COMMAND grep "${test_name}> Q" ${filename} OUTPUT_VARIABLE grep_stdout)
23+
separate_arguments(tokens NATIVE_COMMAND "${grep_stdout}")
24+
list(LENGTH upper_bounds nchk)
25+
math(EXPR nchk "${nchk} - 1")
26+
foreach(idx RANGE 0 ${nchk})
27+
math(EXPR tidx "3 + 5 * ${idx}")
28+
list(GET tokens ${tidx} e)
29+
list(GET upper_bounds ${idx} ub)
30+
if(e GREATER ub)
31+
message(FATAL_ERROR "${e} should be <= ${ub} but is not")
32+
endif()
33+
endforeach()
34+
endfunction()
35+
36+
check_error_norms(
37+
"@TCEN_ERROR_ANCHOR@"
38+
"@TCEN_FILENAME@"
39+
"@TCEN_UPPER_BOUNDS@")

components/homme/cmake/machineFiles/aurora-aot.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ SET(CMAKE_Fortran_COMPILER "mpifort" CACHE STRING "")
4444
SET(CMAKE_CXX_COMPILER "mpicxx" CACHE STRING "")
4545

4646
#AOT flags
47-
SET(SYCL_COMPILE_FLAGS "-std=c++17 -fsycl -fsycl-device-code-split=per_kernel -fno-sycl-id-queries-fit-in-int -fsycl-unnamed-lambda -Xclang -fsycl-allow-virtual-functions")
47+
#SET(SYCL_COMPILE_FLAGS "-std=c++17 -fsycl -fsycl-device-code-split=per_kernel -fno-sycl-id-queries-fit-in-int -fsycl-unnamed-lambda -Xclang -fsycl-allow-virtual-functions")
48+
SET(SYCL_COMPILE_FLAGS "-std=c++17 -fsycl -fsycl-device-code-split=per_kernel -fno-sycl-id-queries-fit-in-int -fsycl-unnamed-lambda")
4849
SET(SYCL_LINK_FLAGS "-Wl,--no-relax -flink-huge-device-code -fsycl-max-parallel-link-jobs=32 -fsycl -fsycl-device-code-split=per_kernel -fsycl-targets=intel_gpu_pvc")
4950

5051
SET(ADD_Fortran_FLAGS "-fc=ifx -fpscomp logicals -O3 -DNDEBUG -DCPRINTEL -g" CACHE STRING "")

components/homme/cmake/machineFiles/chrysalis.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ IF (${IFORT_RESULT} EQUAL 0)
5454
SET (ADD_Fortran_FLAGS "-traceback" CACHE STRING "")
5555
SET (ADD_C_FLAGS "-traceback" CACHE STRING "")
5656
SET (ADD_CXX_FLAGS "-traceback" CACHE STRING "")
57+
SET (BUILD_HOMME_THETA_KOKKOS TRUE CACHE BOOL "")
5758
ELSE()
5859
SET (MKLROOT $ENV{MKLROOT} CACHE FILEPATH "")
5960
SET (HOMME_FIND_BLASLAPACK TRUE CACHE BOOL "")

components/homme/src/preqx_kokkos/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ MACRO(PREQX_KOKKOS_SETUP)
9797
${SRC_SHARE_DIR}/cxx/prim_cxx_driver_base.F90
9898
${SRC_SHARE_DIR}/cxx/utilities/bfb_mod.F90
9999
${SRC_SHARE_DIR}/planar_mod.F90
100+
${TEST_SRC_DIR}/planar_transport.F90
100101
${SRC_SHARE_DIR}/geometry_mod.F90
101102
${SRC_SHARE_DIR}/planar_mesh_mod.F90
102103
)

components/homme/src/share/compose/compose_hommexx.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ using View = typename TracerArrays<ko::MachineTraits>::View<DataType>;
2424
void set_views (const SetView<HommexxReal***>& spheremp,
2525
const SetView<HommexxReal****>& dp, const SetView5& dp3d,
2626
const SetView<HommexxReal******>& qdp, const SetView5& q,
27-
const SetView5& dep_points, const SetView5& vnode,
28-
const SetView5& vdep, const Int ndim) {
27+
const SetView5& dep_points, const SetView5& vnode, const Int ndim,
28+
const SetView5& vdep, const Int vdep_ndim) {
2929
static_assert(std::is_same<Real, HommexxReal>::value,
3030
"Hommexx and Compose real types must be the same.");
3131
#ifdef COMPOSE_PORT
@@ -42,23 +42,22 @@ void set_views (const SetView<HommexxReal***>& spheremp,
4242
if (vnode.data())
4343
ta.vnode = View<Real****>(vnode.data(), nel, vnode.extent_int(1), np2, ndim);
4444
if (vdep.data())
45-
ta.vdep = View<Real****>(vdep.data(), nel, vdep .extent_int(1), np2, ndim);
45+
ta.vdep = View<Real****>(vdep.data(), nel, vdep .extent_int(1), np2, vdep_ndim);
4646
#else
4747
slmm_throw_if(true, "Running a Hommexx code path with the non-Hommexx build"
4848
" is not supported.\n");
4949
#endif
5050
}
5151

52-
void set_hvcoord (const HommexxReal etai_beg, const HommexxReal etai_end,
53-
const HommexxReal* etam) {
52+
void set_hvcoord (const HommexxReal* etai, const HommexxReal* etam) {
5453
auto& cm = *get_isl_mpi_singleton();
55-
islmpi::set_hvcoord(cm, etai_beg, etai_end, etam);
54+
islmpi::set_hvcoord(cm, etai, etam);
5655
}
5756

58-
void calc_v_departure (const int step, const HommexxReal dtsub) {
57+
void interp_v_update (const int step, const HommexxReal dtsub) {
5958
auto& cm = *get_isl_mpi_singleton();
60-
islmpi::calc_v_departure<>(cm, 0, cm.nelemd - 1, step, dtsub,
61-
nullptr, nullptr, nullptr);
59+
islmpi::interp_v_update<>(cm, 0, cm.nelemd - 1, step, dtsub,
60+
nullptr, nullptr, nullptr);
6261
}
6362

6463
void advect (const int np1, const int n0_qdp, const int np1_qdp) {

components/homme/src/share/compose/compose_hommexx.hpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@ typedef SetView<HommexxReal*****> SetView5;
1616
void set_views(const SetView<HommexxReal***>& spheremp,
1717
const SetView<HommexxReal****>& dp, const SetView5& dp3d,
1818
const SetView<HommexxReal******>& qdp, const SetView5& q,
19-
const SetView5& dep_points, const SetView5& vnode,
20-
const SetView5& vdep, const int trajectory_ndim);
19+
const SetView5& dep_points, const SetView5& vnode, const int ndim,
20+
const SetView5& vdep, const int vdep_ndim);
2121

22-
void set_hvcoord(const HommexxReal etai_beg, const HommexxReal etai_end,
23-
const HommexxReal* etam);
24-
void calc_v_departure(const int step, const HommexxReal dtsub);
22+
void set_hvcoord(const HommexxReal* etai, const HommexxReal* etam);
23+
void interp_v_update(const int step, const HommexxReal dtsub);
2524

2625
void advect(const int np1, const int n0_qdp, const int np1_qdp);
2726

components/homme/src/share/compose/compose_slmm.cpp

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -124,41 +124,47 @@ void finalize_init_phase (IslMpi<MT>& cm, typename IslMpi<MT>::Advecter& advecte
124124
}
125125

126126
template <typename MT>
127-
void set_hvcoord (IslMpi<MT>& cm, const Real etai_beg, const Real etai_end,
128-
const Real* etam) {
127+
void set_hvcoord (IslMpi<MT>& cm, const Real* etai, const Real* etam) {
129128
if (cm.etam.size() > 0) return;
130129
#if defined COMPOSE_HORIZ_OPENMP
131130
# pragma omp barrier
132131
# pragma omp master
133132
#endif
134133
{
135134
slmm_assert(cm.nlev > 0);
136-
cm.etai_beg = etai_beg;
137-
cm.etai_end = etai_end;
135+
cm.etai_beg = etai[0];
136+
cm.etai_end = etai[cm.nlev];
137+
cm.etai = typename IslMpi<MT>::template ArrayD<Real*>("etai", cm.nlev+1);
138138
cm.etam = typename IslMpi<MT>::template ArrayD<Real*>("etam", cm.nlev);
139-
const auto h = ko::create_mirror_view(cm.etam);
139+
const auto hi = ko::create_mirror_view(cm.etai);
140+
const auto hm = ko::create_mirror_view(cm.etam);
141+
for (int k = 0; k <= cm.nlev; ++k) {
142+
hi(k) = etai[k];
143+
slmm_assert(k == 0 or hi(k) > hi(k-1));
144+
slmm_assert(hi(k) >= 0 && hi(k) <= 1);
145+
}
140146
for (int k = 0; k < cm.nlev; ++k) {
141-
h(k) = etam[k];
142-
slmm_assert(k == 0 || h(k) > h(k-1));
143-
slmm_assert(h(k) > 0 && h(k) < 1);
147+
hm(k) = etam[k];
148+
slmm_assert(k == 0 or hm(k) > hm(k-1));
149+
slmm_assert(hm(k) > 0 && hm(k) < 1);
144150
}
145-
ko::deep_copy(cm.etam, h);
151+
ko::deep_copy(cm.etai, hi);
152+
ko::deep_copy(cm.etam, hm);
146153
}
147154
#if defined COMPOSE_HORIZ_OPENMP
148155
# pragma omp barrier
149156
#endif
150157
}
151158

152159
template void set_hvcoord(
153-
IslMpi<ko::MachineTraits>& cm, const Real etai_beg, const Real etai_end,
154-
const Real* etam);
160+
IslMpi<ko::MachineTraits>& cm, const Real* etai, const Real* etam);
155161

156162
// Set pointers to HOMME data arrays.
157163
template <typename MT>
158164
void set_elem_data (IslMpi<MT>& cm, const Int ie, Real* qdp, const Int n0_qdp,
159165
const Real* dp, Real* q, const Int nelem_in_patch) {
160166
slmm_assert(ie < cm.ed_h.size());
161-
slmm_assert(cm.halo > 1 || cm.ed_h(ie).nbrs.size() == nelem_in_patch);
167+
slmm_assert(cm.halo > 1 or cm.ed_h(ie).nbrs.size() == nelem_in_patch);
162168
auto& e = cm.ed_h(ie);
163169
#if defined COMPOSE_PORT
164170
cm.tracer_arrays->pqdp.set_ie_ptr(ie, qdp);
@@ -395,15 +401,14 @@ void slmm_check_ref2sphere (homme::Int ie, homme::Cartesian3D* p) {
395401
amb::dev_fin_threads();
396402
}
397403

398-
void slmm_set_hvcoord (const homme::Real etai_beg, const homme::Real etai_end,
399-
const homme::Real* etam) {
404+
void slmm_set_hvcoord (const homme::Real* etai, const homme::Real* etam) {
400405
amb::dev_init_threads();
401406
slmm_assert(homme::g_csl_mpi);
402-
homme::islmpi::set_hvcoord(*homme::g_csl_mpi, etai_beg, etai_end, etam);
407+
homme::islmpi::set_hvcoord(*homme::g_csl_mpi, etai, etam);
403408
amb::dev_fin_threads();
404409
}
405410

406-
void slmm_calc_v_departure (
411+
void slmm_interp_v_update (
407412
homme::Int nets, homme::Int nete, homme::Int step, homme::Real dtsub,
408413
homme::Real* dep_points, homme::Int dep_points_ndim, homme::Real* vnode,
409414
homme::Real* vdep, homme::Int* info)
@@ -419,8 +424,8 @@ void slmm_calc_v_departure (
419424
homme::sl_traj_h2d(*cm.tracer_arrays, dep_points, vnode, vdep,
420425
cm.dep_points_ndim);
421426
}
422-
homme::islmpi::calc_v_departure(cm, nets - 1, nete - 1, step - 1,
423-
dtsub, dep_points, vnode, vdep);
427+
homme::islmpi::interp_v_update(cm, nets - 1, nete - 1, step - 1,
428+
dtsub, dep_points, vnode, vdep);
424429
*info = 0;
425430
{
426431
slmm::Timer timer("d2h");

0 commit comments

Comments
 (0)