Skip to content

Commit

Permalink
Add unit tests to CMake (#295)
Browse files Browse the repository at this point in the history
* Add option to build tests and register with ctest

* Copy test inputs and fix paths in tests

* Add setup test for basis conversion

* Refactor cmake setup for unit tests

* Fix include variable ordering for generated header

* Add MPI tests

* Update CI to use ctest

* Adjust MPI flags for CI

* Add option for additional flags

* Add test options to compile.sh and update readme
  • Loading branch information
ckendrick authored Aug 29, 2024
1 parent 57fcbf2 commit b229933
Show file tree
Hide file tree
Showing 13 changed files with 191 additions and 151 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ jobs:
run: |
mkdir ${GITHUB_WORKSPACE}/build
cd ${GITHUB_WORKSPACE}/build
cmake .. -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} -DCMAKE_BUILD_TYPE=Debug -DUSE_MFEM=${USE_MFEM} -DMFEM_USE_GSLIB=${MFEM_USE_GSLIB}
make
cmake .. -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} -DCMAKE_BUILD_TYPE=Optimized -DUSE_MFEM=${USE_MFEM} -DMFEM_USE_GSLIB=${MFEM_USE_GSLIB}
make
cmake .. -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} -DCMAKE_BUILD_TYPE=Debug -DUSE_MFEM=${USE_MFEM} -DMFEM_USE_GSLIB=${MFEM_USE_GSLIB} -DENABLE_TESTS=ON -DMPIEXEC_PREFLAGS="--oversubscribe" -DMPIEXEC_MAX_NUMPROCS=4
make -j 4
cmake .. -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} -DCMAKE_BUILD_TYPE=Optimized -DUSE_MFEM=${USE_MFEM} -DMFEM_USE_GSLIB=${MFEM_USE_GSLIB} -DENABLE_TESTS=ON -DMPIEXEC_PREFLAGS="--oversubscribe" -DMPIEXEC_MAX_NUMPROCS=4
make -j 4
- name: Build baseline libROM
if: ${{ github.event.label.name == 'LGTM' || contains(github.event.pull_request.labels.*.name, 'LGTM') }}
run: |
Expand Down
36 changes: 1 addition & 35 deletions .github/workflows/run_tests/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,41 +4,7 @@ runs:
- name: Run unit tests
run: |
cd ${GITHUB_WORKSPACE}/build
./tests/test_Vector
./tests/test_Matrix
mpirun -n 3 --oversubscribe ./tests/test_Matrix
./tests/smoke_static
./tests/test_DEIM
./tests/test_GNAT
./tests/test_QDEIM
./tests/test_S_OPT
mpirun -n 4 --oversubscribe tests/test_S_OPT
./tests/test_IncrementalSVD
./tests/test_DMD
mpirun -n 3 --oversubscribe tests/test_DMD
./tests/test_GreedyCustomSampler
mpirun -n 3 --oversubscribe tests/test_GreedyCustomSampler
./tests/test_RandomizedSVD
mpirun -n 3 --oversubscribe tests/test_RandomizedSVD
./tests/test_StaticSVD
mpirun -n 3 --oversubscribe tests/test_StaticSVD
./tests/test_IncrementalSVDBrand
mpirun -n 3 --oversubscribe tests/test_IncrementalSVDBrand
./tests/test_HDFDatabase
mpirun -n 3 --oversubscribe tests/test_HDFDatabase
./tests/test_QR
mpirun -n 3 --oversubscribe tests/test_QR
./tests/test_NNLS
mpirun -n 3 --oversubscribe tests/test_NNLS
shell: bash
- name: Basis dataset update test
run: |
cd ${GITHUB_WORKSPACE}/build/tests
cp ${GITHUB_WORKSPACE}/unit_tests/baselines/basis_conversion/* ./
cp ${GITHUB_WORKSPACE}/scripts/data/update_basis_format.py ./
python3 update_basis_format.py test_basis.000000
python3 update_basis_format.py test_basis_snapshot.000000
./test_basis_conversion
ctest --output-on-failure
shell: bash

- name: Run regression tests
Expand Down
105 changes: 24 additions & 81 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,18 @@ option(MFEM_USE_GSLIB "Build libROM with MFEM using GSLIB" OFF)
option(BUILD_STATIC "Build libROM as a static library" OFF)
option(ENABLE_EXAMPLES "Build examples and regression tests" ON)
option(ENABLE_DOCS "Build docs using Doxygen" OFF)
option(ENABLE_TESTS "Build unit tests. Requires googletest to be installed" OFF)
set(LIBROM_FLAGS "" CACHE STRING "Additional compiler flags used to compile libROM")

## Set a bunch of variables to generate a configure header
# Enable assertion checking if debug symbols generated
if((CMAKE_BUILD_TYPE STREQUAL "Debug") OR
(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
set(DEBUG_CHECK_ASSERTIONS "1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
set(LIBROM_FLAGS "${LIBROM_FLAGS} -Wall")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS_INIT} ${LIBROM_FLAGS}" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_INIT} ${LIBROM_FLAGS}" CACHE STRING "" FORCE)

if (CMAKE_HOST_APPLE)
# Fix linker flags for OSX to use classic linker on XCode 15.0+:
Expand Down Expand Up @@ -86,27 +89,9 @@ set(stdc_header_list "${stdc_header_list};stddef.h;stdio.h;stdlib.h;string.h")
set(stdc_header_list "${stdc_header_list};tgmath.h;time.h;wchar.h;wctype.h")
check_include_files("${stdc_header_list}" CAROM_STDC_HEADERS)

# Define variables for use in generating a configure file
if(GTEST_FOUND)
set(CAROM_HAS_GTEST 1)
endif(GTEST_FOUND)

if(BLAS_FOUND)
set(CAROM_HAVE_BLAS 1)
endif(BLAS_FOUND)

if(LAPACK_FOUND)
set(CAROM_HAVE_LAPACK 1)
endif(LAPACK_FOUND)

if(HDF5_FOUND)
set(CAROM_HAVE_HDF5 1)
endif(HDF5_FOUND)

# List minimum version requirements for dependencies where possible to make
# packaging easier later.
find_package(HDF5 1.8.0 REQUIRED)

find_package(BLAS 3.4.0 REQUIRED)
find_package(LAPACK 3.4.0 REQUIRED)

Expand All @@ -115,7 +100,14 @@ find_package(MPI 1.2 REQUIRED)

find_package(ZLIB 1.2.3 REQUIRED)

find_package(GTest 1.6.0)
if (ENABLE_TESTS)
find_package(GTest 1.6.0 REQUIRED)
endif()

# Define variables for use in generating a configure file
set(CAROM_HAVE_BLAS ${BLAS_FOUND})
set(CAROM_HAVE_LAPACK ${LAPACK_FOUND})
set(CAROM_HAVE_HDF5 ${HDF5_FOUND})

if (USE_MFEM)
find_library(MFEM mfem "${CMAKE_SOURCE_DIR}/dependencies/mfem" "${MFEM_DIR}/lib")
Expand Down Expand Up @@ -226,37 +218,16 @@ if (ENABLE_EXAMPLES)
target_compile_features(${name} PRIVATE cxx_std_11)
endforeach(name) # IN LISTS misc_exmaple_names

set(unit_test_names
smoke_test
test_include
uneven_dist
weak_scaling
random_test
smoke_static
load_samples)

if (USE_MFEM)
set(regression_test_names
basisComparator
checkError
computeSpeedup
solutionComparator
fileComparator)
endif()

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/tests)

foreach(name IN LISTS unit_test_names)
add_executable(${name} unit_tests/${name}.cpp)
target_link_libraries(${name}
PRIVATE ROM ${MPI_C_LINK_FLAGS} ${MPI_C_LIBRARIES} MPI::MPI_C ${MPI_FORTRAN_LINK_FLAGS} ${MPI_FORTRAN_LIBRARIES} MPI::MPI_Fortran)
target_include_directories(${name}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
${MPI_C_INCLUDE_DIRS})
target_compile_features(${name} PRIVATE cxx_std_11)
endforeach(name) # IN LISTS unit_test_names

if (USE_MFEM)
set(regression_test_names
basisComparator
checkError
computeSpeedup
solutionComparator
fileComparator)

foreach(name IN LISTS regression_test_names)
add_executable(${name} regression_tests/${name}.cpp)
target_link_libraries(${name}
Expand All @@ -269,37 +240,10 @@ if (ENABLE_EXAMPLES)
endif()
endif(ENABLE_EXAMPLES)


if(GTEST_FOUND)
set(unit_test_stems
Vector
Matrix
HDFDatabase
DEIM
DMD
GNAT
QDEIM
QR
S_OPT
StaticSVD
RandomizedSVD
IncrementalSVD
IncrementalSVDBrand
GreedyCustomSampler
NNLS
basis_conversion
PCHIPInterpolator)
foreach(stem IN LISTS unit_test_stems)
add_executable(test_${stem} unit_tests/test_${stem}.cpp)
target_link_libraries(test_${stem} PRIVATE ROM
${MPI_C_LINK_FLAGS} ${MPI_C_LIBRARIES} MPI::MPI_C ${MPI_FORTRAN_LINK_FLAGS} ${MPI_FORTRAN_LIBRARIES} MPI::MPI_Fortran GTest::GTest)
target_include_directories(test_${stem}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
${MPI_C_INCLUDE_DIRS})
target_compile_features(test_${stem} PRIVATE cxx_std_11)
target_compile_definitions(test_${stem} PRIVATE CAROM_HAS_GTEST)
endforeach(stem) # IN LISTS unit_test_stems
endif(GTEST_FOUND)
if (ENABLE_TESTS)
enable_testing()
add_subdirectory(unit_tests tests)
endif()

# NOTE([email protected], [email protected]): This code snippet
# builds the Doxygen documentation, but outputs said documentation to
Expand All @@ -324,5 +268,4 @@ if(${ENABLE_DOCS})
${CMAKE_CURRENT_SOURCE_DIR}/rom.tag
${CMAKE_CURRENT_BINARY_DIR}/docs/html/rom.tag)
add_dependencies(doxygen_tagfile documentation)

endif()
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ Compilation options:

- -a: Compile a special build for the LLNL codebase: Ardra
- -d: Compile in debug mode.
- -f: Specify additional compiler flags
- -m: Compile with MFEM (required to run the libROM examples)
- -g: Compile MFEM with GSLib (requires -m)
- -r: Compile unit tests (requires Googletest)
- -s: Compile and use a local SCALAPACK
- -t: Use your own cmake/toolchain
- -u: Update all of libROM's dependencies.

Expand Down Expand Up @@ -92,7 +96,9 @@ Docker container [`librom_env`](https://ghcr.io/llnl/librom/librom_env) provides

# libROM CI

libROM leverages GitHub Actions for CI. The CI currently applies only to commits to pull requests. Unit tests run for all PR commits. Upon the addition of the `LGTM` label, both the unit tests and regression tests run. While the `LGTM` label is still present, all subsequent commits run both unit tests and regression tests.
libROM leverages GitHub Actions for CI. The CI currently applies only to commits to pull requests. Unit tests run for all PR commits. Upon the addition of the `LGTM` label, both the unit tests and regression tests run. While the `LGTM` label is still present, all subsequent commits run both unit tests and regression tests.

To compile and run unit tests locally, build using the `-r` option to `compile.sh` or with `-DENABLE_TESTS=ON`. Building the unit tests will require Googletest to be installed. Unit tests can be run using `ctest` from the root build directory.

# License

Expand Down
18 changes: 15 additions & 3 deletions scripts/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ UPDATE_LIBS=false
INSTALL_SCALAPACK=false
MFEM_USE_GSLIB="Off"
MFEM_USE_LAPACK="Off"
ENABLE_TESTS="Off"
LIBROM_FLAGS=""

cleanup_dependencies() {
pushd .
Expand All @@ -46,7 +48,7 @@ cleanup_dependencies() {


# Get options
while getopts "ah:dh:gh:lh:mh:t:uh:sh" o;
while getopts "ah:dh:gh:lh:mh:t:uh:sh:rh:f:" o;
do
case "${o}" in
a)
Expand All @@ -73,6 +75,12 @@ do
s)
INSTALL_SCALAPACK=true
;;
r)
ENABLE_TESTS="On"
;;
f)
LIBROM_FLAGS=${OPTARG}
;;
*)
echo "Unknown option."
exit 1
Expand Down Expand Up @@ -152,7 +160,9 @@ if [ "$(uname)" == "Darwin" ]; then
cmake ${REPO_PREFIX} \
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DUSE_MFEM=${USE_MFEM} \
-DMFEM_USE_GSLIB=${MFEM_USE_GSLIB}
-DMFEM_USE_GSLIB=${MFEM_USE_GSLIB} \
-DENABLE_TESTS=${ENABLE_TESTS} \
-DLIBROM_FLAGS="${LIBROM_FLAGS}"
check_result $? librom-config
make
check_result $? librom-build
Expand All @@ -166,7 +176,9 @@ elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
-DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_FILE} \
-DCMAKE_BUILD_TYPE=${BUILD_TYPE} \
-DUSE_MFEM=${USE_MFEM} \
-DMFEM_USE_GSLIB=${MFEM_USE_GSLIB}
-DMFEM_USE_GSLIB=${MFEM_USE_GSLIB} \
-DENABLE_TESTS=${ENABLE_TESTS} \
-DLIBROM_FLAGS="${LIBROM_FLAGS}"
check_result $? librom-config
make -j8
check_result $? librom-build
Expand Down
103 changes: 103 additions & 0 deletions unit_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
###############################################################################
#
# Copyright (c) 2013-2024, Lawrence Livermore National Security, LLC
# and other libROM project developers. See the top-level COPYRIGHT
# file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
#
###############################################################################

set(ROM_TEST_RANKS 3 CACHE STRING "Number of MPI ranks to use for parallel tests")

set(unit_test_names
smoke_test
test_include
uneven_dist
weak_scaling
random_test
smoke_static
load_samples)

foreach(name IN LISTS unit_test_names)
add_executable(${name} ${name}.cpp)
target_link_libraries(${name} PRIVATE
ROM ${MPI_C_LINK_FLAGS} ${MPI_C_LIBRARIES} MPI::MPI_C
${MPI_FORTRAN_LINK_FLAGS} ${MPI_FORTRAN_LIBRARIES}
MPI::MPI_Fortran)
target_include_directories(${name} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR} ${MPI_C_INCLUDE_DIRS})
target_compile_features(${name} PRIVATE cxx_std_11)
endforeach(name)

set(unit_test_stems
Vector
Matrix
HDFDatabase
DEIM
DMD
GNAT
QDEIM
QR
S_OPT
StaticSVD
RandomizedSVD
IncrementalSVD
IncrementalSVDBrand
GreedyCustomSampler
NNLS
basis_conversion
PCHIPInterpolator)

foreach(stem IN LISTS unit_test_stems)
add_executable(test_${stem} test_${stem}.cpp)
target_link_libraries(test_${stem} PRIVATE
ROM ${MPI_C_LINK_FLAGS} ${MPI_C_LIBRARIES} MPI::MPI_C
${MPI_FORTRAN_LINK_FLAGS} ${MPI_FORTRAN_LIBRARIES}
MPI::MPI_Fortran GTest::GTest)
target_include_directories(test_${stem} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR} ${MPI_C_INCLUDE_DIRS})
target_compile_features(test_${stem} PRIVATE cxx_std_11)
target_compile_definitions(test_${stem} PRIVATE CAROM_HAS_GTEST)

add_test(NAME test_${stem} COMMAND test_${stem})
endforeach(stem)

# Add parallel tests
set(parallel_tests
Matrix
S_OPT
DMD
GreedyCustomSampler
RandomizedSVD
StaticSVD
IncrementalSVDBrand
HDFDatabase
QR
NNLS)
set(MPI_TEST_CMD "${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${ROM_TEST_RANKS} ${MPIEXEC_PREFLAGS}")
foreach(test IN LISTS parallel_tests)
add_test(NAME test_${test}_mpi COMMAND sh -c "${MPI_TEST_CMD} ./test_${test}")
set_tests_properties(test_${test}_mpi PROPERTIES
TIMEOUT 300
PROCESSORS ${ROM_TEST_RANKS}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
endforeach()

# Copy testing inputs and scripts to build/tests/
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/baselines/basis_conversion/
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/baselines/basis_conversion/")
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/s_opt_data/
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/s_opt_data/")

# Create test to setup inputs for basis_conversion test
file(COPY ${CMAKE_SOURCE_DIR}/scripts/data/update_basis_format.py
DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/")
add_test(NAME basis_conversion_setup
COMMAND sh -c "cp baselines/basis_conversion/test_basis.000000 . &&
cp baselines/basis_conversion/test_basis_snapshot.000000 . &&
python3 update_basis_format.py test_basis.000000 &&
python3 update_basis_format.py test_basis_snapshot.000000"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
set_tests_properties(basis_conversion_setup PROPERTIES FIXTURES_SETUP basis_setup)
set_tests_properties(test_basis_conversion PROPERTIES FIXTURES_REQUIRED basis_setup)
Loading

0 comments on commit b229933

Please sign in to comment.