Skip to content

Commit 2de58d7

Browse files
authored
Improve CI/CD workflows (#5252)
Description of changes: - modernize CI/CD workflow shell scripts - improve test performance - add missing feature guards - adjust tolerances in flaky tests - adjust warmup in benchmarks with large particle numbers
1 parent d491f94 commit 2de58d7

16 files changed

+123
-92
lines changed

.codecov.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,4 @@ ignore:
5353
- "src/walberla_bridge/**/generated_kernels/*"
5454
- "src/walberla_bridge/myintrin.h"
5555
- "src/walberla_bridge/philox_rand.h"
56+
- "build/_deps/**"

maintainer/CI/build_cmake.sh

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ set_default_value with_stokesian_dynamics false
134134
set_default_value test_timeout 500
135135
set_default_value hide_gpu false
136136

137+
# accumulate CMake params in a Bash array to preserve whitespace characters
138+
declare -a cmake_param_list
139+
137140
if [ "${make_check_unit_tests}" = true ] || [ "${make_check_python}" = true ] || [ "${make_check_tutorials}" = true ] || [ "${make_check_samples}" = true ] || [ "${make_check_benchmarks}" = true ]; then
138141
run_checks=true
139142
else
@@ -144,44 +147,43 @@ if [ "${with_coverage}" = true ]; then
144147
build_type="Coverage"
145148
fi
146149

147-
if [ "${with_fast_math}" = true ]; then
148-
cmake_param_protected="-DCMAKE_CXX_FLAGS=-ffast-math"
149-
fi
150+
cmake_param_list+=(
151+
${cmake_params}
152+
-D CMAKE_BUILD_TYPE=${build_type}
153+
-D CMAKE_INSTALL_PREFIX=/tmp/espresso-unit-tests
154+
-D ESPRESSO_INSIDE_DOCKER:BOOL=ON
155+
-D ESPRESSO_WARNINGS_ARE_ERRORS:BOOL=ON
156+
-D ESPRESSO_CTEST_ARGS:STRING="-j${check_procs}"
157+
-D ESPRESSO_TEST_TIMEOUT:STRING=${test_timeout}
158+
-D ESPRESSO_BUILD_BENCHMARKS:BOOL=${make_check_benchmarks}
159+
-D ESPRESSO_BUILD_WITH_CCACHE:BOOL=${with_ccache}
160+
-D ESPRESSO_BUILD_WITH_CALIPER:BOOL=${with_caliper}
161+
-D ESPRESSO_BUILD_WITH_FPE:BOOL=${with_fpe}
162+
-D ESPRESSO_BUILD_WITH_SHARED_MEMORY_PARALLELISM:BOOL=${with_shared_memory_parallelism}
163+
-D ESPRESSO_BUILD_WITH_HDF5:BOOL=${with_hdf5}
164+
-D ESPRESSO_BUILD_WITH_FFTW:BOOL=${with_fftw}
165+
-D ESPRESSO_BUILD_WITH_GSL:BOOL=${with_gsl}
166+
-D ESPRESSO_BUILD_WITH_SCAFACOS:BOOL=${with_scafacos}
167+
-D ESPRESSO_BUILD_WITH_NLOPT:BOOL=${with_nlopt}
168+
-D ESPRESSO_BUILD_WITH_STOKESIAN_DYNAMICS:BOOL=${with_stokesian_dynamics}
169+
-D ESPRESSO_BUILD_WITH_WALBERLA:BOOL=${with_walberla}
170+
-D ESPRESSO_BUILD_WITH_WALBERLA_AVX:BOOL=${with_walberla_avx}
171+
-D ESPRESSO_BUILD_WITH_COVERAGE:BOOL=${with_coverage}
172+
-D ESPRESSO_BUILD_WITH_COVERAGE_PYTHON:BOOL=${with_coverage_python}
173+
-D ESPRESSO_BUILD_WITH_ASAN:BOOL=${with_asan}
174+
-D ESPRESSO_BUILD_WITH_UBSAN:BOOL=${with_ubsan}
175+
-D ESPRESSO_BUILD_WITH_CLANG_TIDY:BOOL=${with_static_analysis}
176+
-D ESPRESSO_BUILD_WITH_CUDA:BOOL=${with_cuda}
177+
)
150178

151-
cmake_params="-D CMAKE_BUILD_TYPE=${build_type} -D ESPRESSO_WARNINGS_ARE_ERRORS=ON ${cmake_params}"
152-
cmake_params="${cmake_params} -D CMAKE_INSTALL_PREFIX=/tmp/espresso-unit-tests -D ESPRESSO_INSIDE_DOCKER=ON"
153-
cmake_params="${cmake_params} -D ESPRESSO_CTEST_ARGS:STRING=-j${check_procs} -D ESPRESSO_TEST_TIMEOUT=${test_timeout}"
154-
155-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_BENCHMARKS=${make_check_benchmarks}"
156-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_CCACHE=${with_ccache}"
157-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_CALIPER=${with_caliper}"
158-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_FPE=${with_fpe}"
159-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_SHARED_MEMORY_PARALLELISM=${with_shared_memory_parallelism}"
160-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_HDF5=${with_hdf5}"
161-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_FFTW=${with_fftw}"
162-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_GSL=${with_gsl}"
163-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_SCAFACOS=${with_scafacos}"
164-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_NLOPT=${with_nlopt}"
165-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_STOKESIAN_DYNAMICS=${with_stokesian_dynamics}"
166-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_WALBERLA=${with_walberla}"
167-
168-
if [ "${with_walberla}" = true ]; then
169-
if [ "${with_walberla_avx}" = true ]; then
170-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_WALBERLA_AVX=ON"
171-
fi
179+
if [ "${with_fast_math}" = true ]; then
180+
cmake_param_list+=(-D CMAKE_CXX_FLAGS=-ffast-math)
172181
fi
173182

174-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_COVERAGE=${with_coverage}"
175-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_COVERAGE_PYTHON=${with_coverage_python}"
176-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_ASAN=${with_asan}"
177-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_UBSAN=${with_ubsan}"
178-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_CLANG_TIDY=${with_static_analysis}"
179-
cmake_params="${cmake_params} -D ESPRESSO_BUILD_WITH_CUDA=${with_cuda}"
180-
181183
if [ "${with_cuda}" = true ]; then
182-
cmake_params="${cmake_params} -D CUDAToolkit_ROOT=/usr/lib/cuda"
184+
cmake_param_list+=(-D CUDAToolkit_ROOT=/usr/lib/cuda)
183185
if [ "${CUDACXX}" = "" ] && [ "${CXX}" != "" ]; then
184-
cmake_params="${cmake_params} -D CMAKE_CUDA_FLAGS='--compiler-bindir=$(which "${CXX}")'"
186+
cmake_param_list+=(-D CMAKE_CUDA_HOST_COMPILER="${CXX}")
185187
fi
186188
fi
187189

@@ -201,6 +203,7 @@ echo ""
201203

202204
builddir="${srcdir}/build"
203205

206+
echo "variables:"
204207
outp srcdir builddir \
205208
make_check_unit_tests make_check_python make_check_tutorials make_check_samples make_check_benchmarks \
206209
cmake_params \
@@ -254,11 +257,21 @@ else
254257
fi
255258
fi
256259

257-
if [ -z "${cmake_param_protected}" ]; then
258-
cmake -G Ninja "${srcdir}" ${cmake_params} || exit 1
259-
else
260-
cmake -G Ninja "${srcdir}" ${cmake_params} "${cmake_param_protected}" || exit 1
261-
fi
260+
# print cmake command, one parameter per line (line length is limited to 1024 chars on macOS)
261+
echo "cmake -G Ninja \\"
262+
for arg in "${cmake_param_list[@]}"; do
263+
if [[ "${arg}" = *" "* ]]; then
264+
echo -n " \"${arg}\""
265+
else
266+
echo -n " ${arg}"
267+
fi
268+
if [ ! "${arg}" = "-D" ]; then
269+
echo " \\"
270+
fi
271+
done
272+
echo " ${srcdir}"
273+
274+
cmake -G Ninja "${srcdir}" "${cmake_param_list[@]}" || exit 1
262275
end "CONFIGURE"
263276

264277
# BUILD
@@ -353,6 +366,7 @@ fi
353366
if [ "${with_coverage}" = true ] || [ "${with_coverage_python}" = true ]; then
354367
start "COVERAGE"
355368
cd "${builddir}"
369+
rm -f _deps/highfive-src/.github/workflows/coverage.yml
356370

357371
# import codecov key
358372
gpg --import "${CODECOV_PUBLIC_KEY}"
@@ -372,6 +386,7 @@ if [ "${with_coverage}" = true ] || [ "${with_coverage_python}" = true ]; then
372386
echo "Running lcov and gcov..."
373387
codecov_opts="${codecov_opts} --gcov"
374388
"${srcdir}/maintainer/CI/run_lcov.sh" coverage.info
389+
rm coverage.info
375390
fi
376391
if [ "${with_coverage_python}" = true ]; then
377392
echo "Running python3-coverage..."

maintainer/benchmarks/CMakeLists.txt

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ python_benchmark(FILE lj.py ARGUMENTS
109109
python_benchmark(FILE lj.py ARGUMENTS
110110
"--particles_per_core=10000;--volume_fraction=0.02")
111111
python_benchmark(FILE mc_acid_base_reservoir.py ARGUMENTS
112-
"--particles_per_core=500;--mode=benchmark")
112+
"--particles_per_core=500")
113113
python_benchmark(
114114
FILE lj.py ARGUMENTS
115115
"--particles_per_core=1000;--volume_fraction=0.10;--bonds" RUN_WITH_MPI FALSE)
@@ -129,15 +129,19 @@ python_benchmark(
129129
python_benchmark(FILE ferrofluid.py ARGUMENTS "--particles_per_core=400")
130130
python_benchmark(FILE mc_acid_base_reservoir.py ARGUMENTS
131131
"--particles_per_core=500" RUN_WITH_MPI FALSE)
132-
python_benchmark(FILE lb.py ARGUMENTS "--box_l=32;--single_precision")
133-
python_benchmark(FILE lb.py ARGUMENTS "--box_l=32")
134-
python_benchmark(FILE lb.py ARGUMENTS "--box_l=64;--single_precision")
135-
python_benchmark(FILE lb.py ARGUMENTS "--box_l=64")
136-
python_benchmark(FILE lb.py ARGUMENTS "--box_l=128;--single_precision")
137-
python_benchmark(FILE lb.py ARGUMENTS "--box_l=128")
132+
python_benchmark(FILE lb.py ARGUMENTS
133+
"--box_l=32;--particles_per_core=0;--single_precision")
134+
python_benchmark(FILE lb.py ARGUMENTS "--box_l=32;--particles_per_core=0")
135+
python_benchmark(FILE lb.py ARGUMENTS
136+
"--box_l=64;--particles_per_core=0;--single_precision")
137+
python_benchmark(FILE lb.py ARGUMENTS "--box_l=64;--particles_per_core=0")
138+
python_benchmark(FILE lb.py ARGUMENTS
139+
"--box_l=128;--particles_per_core=0;--single_precision")
140+
python_benchmark(FILE lb.py ARGUMENTS "--box_l=128;--particles_per_core=0")
138141
if(NOT ESPRESSO_BUILD_WITH_WALBERLA_USE_AVX)
139-
python_benchmark(FILE lb.py ARGUMENTS "--box_l=196;--single_precision")
140-
python_benchmark(FILE lb.py ARGUMENTS "--box_l=196")
142+
python_benchmark(FILE lb.py ARGUMENTS
143+
"--box_l=196;--particles_per_core=0;--single_precision")
144+
python_benchmark(FILE lb.py ARGUMENTS "--box_l=196;--particles_per_core=0")
141145
endif()
142146

143147
add_custom_target(

maintainer/benchmarks/ferrofluid.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
parser.add_argument("--volume_fraction", metavar="FRAC", action="store",
3232
type=float, default=0.1, required=False,
3333
help="Fraction of the simulation box volume occupied by "
34-
"particles (range: [0.01-0.74], default: 0.50)")
34+
"particles (range: [0.01-0.74], default: 0.10)")
3535
parser.add_argument("--dipole_moment", metavar="FRAC", action="store",
3636
type=float, default=2**0.5, required=False,
3737
help="Magnitude of the dipole moment (same for all particles)")
@@ -55,7 +55,7 @@
5555
assert measurement_steps >= 100, \
5656
f"{measurement_steps} steps per tick are too short"
5757

58-
required_features = ["LENNARD_JONES"]
58+
required_features = ["LENNARD_JONES", "DP3M"]
5959
espressomd.assert_features(required_features)
6060

6161
# System
@@ -110,8 +110,8 @@
110110
system.thermostat.set_langevin(kT=1.0, gamma=1.0, seed=42)
111111

112112
# tuning and equilibration
113-
min_skin = 0.2
114-
max_skin = 1.0
113+
min_skin = 0.1
114+
max_skin = 0.6
115115
dp3m_params = {'prefactor': 1, 'accuracy': 1e-4}
116116
print("Equilibration")
117117
system.integrator.run(min(5 * measurement_steps, 60000))

maintainer/benchmarks/lb.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,12 @@
9898
lb_grid = box_l
9999
measurement_steps = 80
100100
else:
101+
mpi_factor = min(2., float(np.amax(system.cell_system.node_grid)))
101102
# volume of N spheres with radius r: N * (4/3*pi*r^3)
102103
box_l = (n_part * 4. / 3. * np.pi * (lj_sig / 2.)**3
103104
/ args.volume_fraction)**(1. / 3.)
104105
lb_grid = (n_part * args.lb_sites_per_particle)**(1. / 3.)
105-
lb_grid = int(2. * round(lb_grid / 2.))
106+
lb_grid = int(mpi_factor * np.ceil(lb_grid / mpi_factor))
106107
agrid = box_l / lb_grid
107108
measurement_steps = max(50, int(120**3 / lb_grid**3))
108109
measurement_steps = 40

maintainer/benchmarks/lj.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,16 @@
115115
# warmup
116116
benchmarks.minimize(system, n_part / 2.)
117117

118-
system.integrator.set_symplectic_euler()
118+
system.integrator.set_vv()
119119
system.thermostat.set_langevin(kT=1.0, gamma=1.0, seed=42)
120120

121121
# tuning and equilibration
122122
min_skin = 0.2
123123
max_skin = 1.0
124124
print("Equilibration")
125+
system.time_step = system.time_step / 10.
126+
system.integrator.run(100)
127+
system.time_step = system.time_step * 10.
125128
system.integrator.run(min(5 * measurement_steps, 60000))
126129
print("Tune skin: {:.3f}".format(system.cell_system.tune_skin(
127130
min_skin=min_skin, max_skin=max_skin, tol=0.025, int_steps=200)))

maintainer/benchmarks/p3m.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@
137137
"tune_limits": [12, 160], "gpu": args.gpu}
138138
p3m = espressomd.electrostatics.P3M(**p3m_params)
139139
print("Quick equilibration")
140+
system.time_step = system.time_step / 10.
141+
system.integrator.run(100)
142+
system.time_step = system.time_step * 10.
140143
system.integrator.run(min(3 * measurement_steps, 1000))
141144
print("Tune skin: {:.3f}".format(system.cell_system.tune_skin(
142145
min_skin=min_skin, max_skin=max_skin, tol=0.05, int_steps=100,

testsuite/python/CMakeLists.txt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,9 @@ function(python_test)
110110
if(${TEST_GPU_SLOTS} GREATER 0 AND ESPRESSO_BUILD_WITH_CUDA)
111111
set_property(TEST ${TEST_NAME} PROPERTY RESOURCE_GROUPS
112112
"gpus:${TEST_GPU_SLOTS}")
113-
endif()
114-
115-
if(${TEST_GPU_SLOTS} GREATER 0)
116113
list(APPEND TEST_LABELS "gpu")
117114
endif()
118-
if(${TEST_NUM_PROC} EQUAL 2)
115+
if(${TEST_NUM_PROC} GREATER_EQUAL 2)
119116
list(APPEND TEST_LABELS "parallel")
120117
endif()
121118
if(${TEST_NUM_PROC} EQUAL 3)
@@ -262,7 +259,7 @@ python_test(FILE tabulated.py MAX_NUM_PROC 2)
262259
python_test(FILE particle_slice.py MAX_NUM_PROC 4)
263260
python_test(FILE rigid_bond.py MAX_NUM_PROC 4)
264261
python_test(FILE rotation_per_particle.py MAX_NUM_PROC 4)
265-
python_test(FILE rotational_inertia.py MAX_NUM_PROC 4)
262+
python_test(FILE rotational_inertia.py MAX_NUM_PROC 2)
266263
python_test(FILE rotational-diffusion-aniso.py MAX_NUM_PROC 1 LABELS long)
267264
python_test(FILE rotational_dynamics.py MAX_NUM_PROC 1)
268265
python_test(FILE script_interface.py MAX_NUM_PROC 4)
@@ -346,7 +343,7 @@ python_test(FILE lb_electrohydrodynamics.py MAX_NUM_PROC 4 GPU_SLOTS 1)
346343
python_test(FILE cluster_analysis.py MAX_NUM_PROC 4)
347344
python_test(FILE pair_criteria.py MAX_NUM_PROC 4)
348345
python_test(FILE drude.py MAX_NUM_PROC 2)
349-
python_test(FILE thermostats_anisotropic.py MAX_NUM_PROC 4)
346+
python_test(FILE thermostats_anisotropic.py MAX_NUM_PROC 2)
350347
python_test(FILE thermalized_bond.py MAX_NUM_PROC 4)
351348
python_test(FILE thole.py MAX_NUM_PROC 4)
352349
python_test(FILE lb_slice.py MAX_NUM_PROC 2 GPU_SLOTS 1)

testsuite/python/coulomb_cloud_wall_duplicated.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ def test_p3m(self):
8282
self.compare("p3m", energy=True)
8383

8484
@utx.skipIfMissingGPU()
85+
@utx.skipIfMissingFeatures("P3M")
8586
def test_p3m_gpu(self):
8687
p3m = espressomd.electrostatics.P3M(
8788
**self.p3m_params, tune=False, gpu=True)

testsuite/python/icc_electrodes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import numpy as np
2626

2727

28-
@utx.skipIfMissingFeatures(["ELECTROSTATICS", "EXTERNAL_FORCES"])
28+
@utx.skipIfMissingFeatures(["ELECTROSTATICS", "P3M", "EXTERNAL_FORCES"])
2929
class Test(ut.TestCase):
3030

3131
def test_electrodes(self):

0 commit comments

Comments
 (0)