Skip to content

Commit

Permalink
CMake maintenance (#4468)
Browse files Browse the repository at this point in the history
Description of changes:
- rewrite CMake logic for Python tests
   - checkpoint tests: convert the body of the list loop into a function `checkpoint_test()` and call it once for each combination of features (improves readability and separation of concerns)
   - tests called multiple times with a different number of MPI ranks no longer require creating a new copy of the original file, instead a different CTest name is used
   - Python tests that used to depend on CMake variable substitution are now configured with a class factory; the CMake variable is passed as a command-line argument to the test file and the corresponding test class is generated on-the-fly
- improve code coverage
   - checkpoint tests coverage data is no longer discarded at random, instead it is accumulated over all feature combinations
  • Loading branch information
kodiakhq[bot] authored Mar 16, 2022
2 parents a462268 + 84b7887 commit 240af62
Show file tree
Hide file tree
Showing 12 changed files with 673 additions and 533 deletions.
3 changes: 0 additions & 3 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,3 @@ ignore:
- "doc/tutorials"
- "samples"
- "maintainer"
fixes:
- "testsuite/python/save_checkpoint*::testsuite/python/save_checkpoint.py"
- "testsuite/python/test_checkpoint*::testsuite/python/test_checkpoint.py"
127 changes: 73 additions & 54 deletions testsuite/python/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
function(PYTHON_TEST)
cmake_parse_arguments(TEST "" "FILE;MAX_NUM_PROC;SUFFIX"
"DEPENDS;DEPENDENCIES;LABELS" ${ARGN})
"DEPENDS;DEPENDENCIES;LABELS;ARGUMENTS" ${ARGN})
get_filename_component(TEST_NAME ${TEST_FILE} NAME_WE)
set(TEST_FILE_CONFIGURED "${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}.py")
if(TEST_SUFFIX)
set(TEST_NAME "${TEST_NAME}_${TEST_SUFFIX}")
endif()
set(TEST_FILE_CONFIGURED "${CMAKE_CURRENT_BINARY_DIR}/${TEST_NAME}.py")
configure_file(${TEST_FILE} ${TEST_FILE_CONFIGURED})
configure_file(${TEST_FILE} ${TEST_FILE_CONFIGURED} COPYONLY)
foreach(dependency IN LISTS TEST_DEPENDENCIES)
configure_file(${dependency} ${CMAKE_CURRENT_BINARY_DIR}/${dependency})
configure_file(${dependency} ${CMAKE_CURRENT_BINARY_DIR}/${dependency}
COPYONLY)
endforeach(dependency)
set(TEST_FILE ${TEST_FILE_CONFIGURED})

Expand All @@ -29,11 +30,11 @@ function(PYTHON_TEST)
COMMAND
${MPIEXEC} ${MPIEXEC_OVERSUBSCRIBE} ${MPIEXEC_NUMPROC_FLAG}
${TEST_NUM_PROC} ${MPIEXEC_PREFLAGS} ${MPIEXEC_TMPDIR}
${CMAKE_BINARY_DIR}/pypresso ${PYPRESSO_OPTIONS} ${TEST_FILE}
${MPIEXEC_POSTFLAGS})
${CMAKE_BINARY_DIR}/pypresso ${PYPRESSO_OPTIONS}
${TEST_FILE_CONFIGURED} ${TEST_ARGUMENTS} ${MPIEXEC_POSTFLAGS})
else()
add_test(${TEST_NAME} ${CMAKE_BINARY_DIR}/pypresso ${PYPRESSO_OPTIONS}
${TEST_FILE})
${TEST_FILE_CONFIGURED} ${TEST_ARGUMENTS})
endif()
set_tests_properties(${TEST_NAME} PROPERTIES PROCESSORS ${TEST_NUM_PROC}
DEPENDS "${TEST_DEPENDS}")
Expand All @@ -42,49 +43,68 @@ function(PYTHON_TEST)
set_tests_properties(${TEST_NAME} PROPERTIES RESOURCE_LOCK GPU)
endif()

if(${TEST_MAX_NUM_PROC} EQUAL 1)
set_tests_properties(${TEST_NAME} PROPERTIES LABELS "${TEST_LABELS}")
elseif(${TEST_MAX_NUM_PROC} EQUAL 2)
set_tests_properties(${TEST_NAME} PROPERTIES LABELS
"${TEST_LABELS};parallel")
else()
set_tests_properties(
${TEST_NAME} PROPERTIES LABELS "${TEST_LABELS};parallel;parallel_odd")
if(${TEST_MAX_NUM_PROC} EQUAL 2)
list(APPEND TEST_LABELS "parallel")
endif()
if(${TEST_MAX_NUM_PROC} EQUAL 3)
list(APPEND TEST_LABELS "parallel_odd")
endif()
set_tests_properties(${TEST_NAME} PROPERTIES LABELS "${TEST_LABELS}")

set(python_tests ${python_tests} ${TEST_FILE} PARENT_SCOPE)
set(python_tests ${python_tests} ${TEST_FILE_CONFIGURED} PARENT_SCOPE)
endfunction(PYTHON_TEST)

# Checkpointing tests: semicolon-separated list of mutually-compatible features.
# Separate features with hyphens, use a period to add an optional flag.
foreach(
TEST_COMBINATION
lb.cpu-p3m.cpu-lj-therm.lb;lb.gpu-p3m.elc-lj-therm.lb;lb.off-therm.npt-int.npt;lb.off-int.sd;lb.off-dp3m.cpu-therm.langevin-int.nvt;lb.off-therm.dpd-int.nvt;lb.off-scafacos-therm.bd-int.bd;lb.off-therm.sdm-int.sdm;lb.cpu-p3m.cpu-lj-therm.lb-mpi.1.core
)
if(${TEST_COMBINATION} MATCHES "mpi\\.1\\.core")
set(TEST_NPROCS 1)
else()
set(TEST_NPROCS 4)
endif()
if(${TEST_COMBINATION} MATCHES "\\.gpu")
set(TEST_LABELS "gpu")
else()
set(TEST_LABELS "")
function(CHECKPOINT_TEST)
cmake_parse_arguments(TEST "" "MODES;MAX_NUM_PROC;SUFFIX" "LABELS" ${ARGN})
if(NOT DEFINED TEST_MAX_NUM_PROC)
set(TEST_MAX_NUM_PROC 4)
endif()
if(${TEST_COMBINATION} MATCHES "lb\\.off")
set(TEST_BINARY_LIST "1")
if(TEST_SUFFIX)
set(TEST_ARGUMENTS "Test_suffix_${TEST_SUFFIX}__${TEST_MODES}")
set(TEST_SUFFIX "${TEST_MODES}_${TEST_SUFFIX}")
else()
set(TEST_BINARY_LIST "1;0")
set(TEST_ARGUMENTS "Test__${TEST_MODES}")
set(TEST_SUFFIX "${TEST_MODES}")
endif()
foreach(TEST_BINARY ${TEST_BINARY_LIST})
python_test(FILE save_checkpoint.py MAX_NUM_PROC ${TEST_NPROCS} LABELS
${TEST_LABELS} SUFFIX ${TEST_COMBINATION}_${TEST_BINARY})
python_test(
FILE test_checkpoint.py MAX_NUM_PROC ${TEST_NPROCS} LABELS ${TEST_LABELS}
SUFFIX ${TEST_COMBINATION}_${TEST_BINARY} DEPENDS
save_checkpoint_${TEST_COMBINATION}_${TEST_BINARY})
endforeach(TEST_BINARY)
endforeach(TEST_COMBINATION)
python_test(
FILE save_checkpoint.py MAX_NUM_PROC ${TEST_NPROCS} LABELS ${TEST_LABELS}
SUFFIX ${TEST_SUFFIX} ARGUMENTS ${TEST_ARGUMENTS} DEPENDENCIES
unittest_generator.py)
python_test(
FILE
test_checkpoint.py
MAX_NUM_PROC
${TEST_NPROCS}
LABELS
${TEST_LABELS}
SUFFIX
${TEST_SUFFIX}
ARGUMENTS
${TEST_ARGUMENTS}
DEPENDENCIES
unittest_generator.py
DEPENDS
save_checkpoint_${TEST_SUFFIX})
endfunction(CHECKPOINT_TEST)

# Checkpoint tests run on 4 cores (can be overriden with MAX_NUM_PROC). The
# combination of modes to activate is stored in MODES. A mode consists of a
# feature with zero or more options; separate features with 2 underscores and
# options with 1 underscore (options can appear in any order). For example,
# "p3m_cpu__lb_cpu_ascii" generates modes P3M, P3M.CPU, LB, LB.CPU, LB.ASCII.
checkpoint_test(MODES therm_lb__p3m_cpu__lj__lb_cpu_ascii SUFFIX 1_core
MAX_NUM_PROC 1)
checkpoint_test(MODES therm_lb__p3m_cpu__lj__lb_cpu_ascii)
checkpoint_test(MODES therm_lb__elc_cpu__lj__lb_cpu_binary)
checkpoint_test(MODES therm_lb__elc_cpu__lj__lb_gpu_ascii LABELS gpu)
checkpoint_test(MODES therm_lb__p3m_gpu__lj__lb_gpu_binary LABELS gpu)
checkpoint_test(MODES therm_npt__int_npt)
checkpoint_test(MODES int_sd__lj)
checkpoint_test(MODES dp3m_cpu__therm_langevin__int_nvt)
checkpoint_test(MODES therm_dpd__int_nvt)
checkpoint_test(MODES scafacos__therm_bd__int_bd)
checkpoint_test(MODES therm_sdm__int_sdm)

python_test(FILE bond_breakage.py MAX_NUM_PROC 4)
python_test(FILE cellsystem.py MAX_NUM_PROC 4)
python_test(FILE tune_skin.py MAX_NUM_PROC 1)
Expand Down Expand Up @@ -135,9 +155,12 @@ python_test(FILE lb_stokes_sphere.py MAX_NUM_PROC 4 LABELS gpu long)
python_test(FILE lb_pressure_tensor.py MAX_NUM_PROC 1 LABELS gpu long)
python_test(FILE ek_fluctuations.py MAX_NUM_PROC 1 LABELS gpu)
python_test(FILE ek_charged_plate.py MAX_NUM_PROC 1 LABELS gpu)
python_test(FILE ek_eof_one_species.py MAX_NUM_PROC 1 LABELS gpu SUFFIX x)
python_test(FILE ek_eof_one_species.py MAX_NUM_PROC 1 LABELS gpu SUFFIX y)
python_test(FILE ek_eof_one_species.py MAX_NUM_PROC 1 LABELS gpu SUFFIX z)
python_test(FILE ek_eof_one_species.py MAX_NUM_PROC 1 LABELS gpu SUFFIX x
ARGUMENTS Test__axis_x DEPENDENCIES unittest_generator.py)
python_test(FILE ek_eof_one_species.py MAX_NUM_PROC 1 LABELS gpu SUFFIX y
ARGUMENTS Test__axis_y DEPENDENCIES unittest_generator.py)
python_test(FILE ek_eof_one_species.py MAX_NUM_PROC 1 LABELS gpu SUFFIX z
ARGUMENTS Test__axis_z DEPENDENCIES unittest_generator.py)
python_test(FILE exclusions.py MAX_NUM_PROC 2)
python_test(FILE langevin_thermostat.py MAX_NUM_PROC 1)
python_test(FILE langevin_thermostat_stats.py MAX_NUM_PROC 1 LABELS long)
Expand All @@ -146,8 +169,10 @@ python_test(FILE brownian_dynamics_stats.py MAX_NUM_PROC 1 LABELS long)
python_test(FILE lees_edwards.py MAX_NUM_PROC 4)
python_test(FILE nsquare.py MAX_NUM_PROC 4)
python_test(FILE virtual_sites_relative.py MAX_NUM_PROC 2)
python_test(FILE virtual_sites_tracers.py MAX_NUM_PROC 2)
python_test(FILE virtual_sites_tracers_gpu.py MAX_NUM_PROC 2 LABELS gpu)
python_test(FILE virtual_sites_tracers.py MAX_NUM_PROC 2 DEPENDENCIES
virtual_sites_tracers_common.py)
python_test(FILE virtual_sites_tracers_gpu.py MAX_NUM_PROC 2 LABELS gpu
DEPENDENCIES virtual_sites_tracers_common.py)
python_test(FILE regular_decomposition.py MAX_NUM_PROC 4)
python_test(FILE integrator_npt.py MAX_NUM_PROC 4)
python_test(FILE integrator_npt_stats.py MAX_NUM_PROC 4 LABELS long)
Expand Down Expand Up @@ -259,12 +284,6 @@ add_custom_target(
COMMAND
${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/unittest_decorators.py
${CMAKE_CURRENT_BINARY_DIR}
COMMAND
${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/virtual_sites_tracers_common.py
${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/ek_common.py
${CMAKE_CURRENT_BINARY_DIR}
COMMAND
${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/thermostats_common.py
${CMAKE_CURRENT_BINARY_DIR})
Expand Down
74 changes: 0 additions & 74 deletions testsuite/python/ek_common.py

This file was deleted.

Loading

0 comments on commit 240af62

Please sign in to comment.