Skip to content

Commit

Permalink
Merge pull request #310 from lanl/jmm/fastertests
Browse files Browse the repository at this point in the history
Speed up and clean up unit tests
  • Loading branch information
Yurlungur authored Oct 12, 2023
2 parents 4fb2409 + bd4bc24 commit 70d370b
Show file tree
Hide file tree
Showing 19 changed files with 1,675 additions and 1,504 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
- [[PR177]](https://github.com/lanl/singularity-eos/pull/177) added EOSPAC vector functions

### Changed (changing behavior/API/variables/...)
- [[PR310]](https://github.com/lanl/singularity-eos/pull/310) Speed up and clean up tests
- [[PR295]](https://github.com/lanl/singularity-eos/pull/295) Add fast logs to singularity-eos
- [[PR246]](https://github.com/lanl/singularity-eos/pull/246) Update CMake with upstream changes
- [[PR223]](https://github.com/lanl/singularity-eos/pull/223) Update ports-of-call and add portable error handling
Expand Down
21 changes: 14 additions & 7 deletions doc/sphinx/src/contributing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,9 @@ test in the ``CMakeLists.txt`` file,

.. code-block:: cmake
add_executable(eos_unit_tests
add_executable(eos_analytic_unit_tests
catch2_define.cpp
eos_unit_test_helpers.hpp
test_eos_unit.cpp
test_eos_gruneisen.cpp
test_eos_vinet.cpp
test_my_new_eos.cpp
Expand All @@ -245,15 +244,23 @@ test in the ``CMakeLists.txt`` file,
in order for the test to be compiled. If your EOS requires any special
dependencies, be sure to block off the test using ``#IFDEF`` blocks.

**Important:** this is a subtlety that highlights the importance of unit tests!
Since our library is header only, the unit tests are often the only place where
a specific EOS may be instantiated when ``singularity-eos`` is compiled. Unit
tests _must_ make use of the ``EOS`` type, i.e.
.. note::

Note that there are three executables, ``eos_analytic_unit_tests``,
``eos_infrastructure_tests`` and ``eos_tabulated_unit_tests``. Pick
the executable that most closely matches what your model is.

**Important:** Since our library is header only, the unit
tests are often the only place where a specific EOS may be
instantiated when ``singularity-eos`` is compiled. Therefore to
exercise all code paths, it is best to create an ``EOS`` type
instantiated as

.. code-block:: c++

#include <singularity-eos/eos/eos.hpp>
EOS my_eos = my_new_eos(parameter1, parameter2, ...)
using EOS = singularity::Variant<MyNewEOS>;``.
EOS my_eos = MyNewEOS(parameter1, parameter2, ...)

in order to properly test the functionality of a new EOS. Simply using the
new class as the type such as
Expand Down
41 changes: 32 additions & 9 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,58 @@
# ------------------------------------------------------------------------------

add_executable(
eos_unit_tests
eos_analytic_unit_tests
catch2_define.cpp
eos_unit_test_helpers.hpp
test_eos_unit.cpp
test_eos_ideal.cpp
test_eos_gruneisen.cpp
test_eos_sap_polynomial.cpp
test_eos_vinet.cpp
test_eos_noble_abel.cpp
test_eos_stiff.cpp
)

add_executable(
eos_infrastructure_tests
catch2_define.cpp
eos_unit_test_helpers.hpp
test_eos_modifiers.cpp
test_eos_vector.cpp
test_math_utils.cpp
)

add_executable(
eos_tabulated_unit_tests
catch2_define.cpp
eos_unit_test_helpers.hpp
test_eos_vinet.cpp
test_eos_helmholtz.cpp
test_eos_tabulated.cpp
test_eos_stellar_collapse.cpp
)

if(SINGULARITY_TEST_HELMHOLTZ)
configure_file(${PROJECT_SOURCE_DIR}/data/helmholtz/helm_table.dat ${CMAKE_BINARY_DIR}/data/helmholtz/helm_table.dat COPYONLY)
target_compile_definitions(eos_unit_tests PRIVATE SINGULARITY_TEST_HELMHOLTZ SINGULARITY_USE_HELMHOLTZ)
target_compile_definitions(eos_tabulated_unit_tests PRIVATE SINGULARITY_TEST_HELMHOLTZ SINGULARITY_USE_HELMHOLTZ)
endif()

if(SINGULARITY_TEST_SESAME)
target_compile_definitions(eos_unit_tests PRIVATE SINGULARITY_TEST_SESAME)
target_compile_definitions(eos_tabulated_unit_tests PRIVATE SINGULARITY_TEST_SESAME)
endif()
if(SINGULARITY_TEST_STELLAR_COLLAPSE)
target_compile_definitions(eos_unit_tests
target_compile_definitions(eos_tabulated_unit_tests
PRIVATE SINGULARITY_TEST_STELLAR_COLLAPSE)
endif()

target_link_libraries(eos_unit_tests PRIVATE Catch2::Catch2
singularity-eos::singularity-eos)
target_link_libraries(eos_analytic_unit_tests PRIVATE Catch2::Catch2
singularity-eos::singularity-eos)
target_link_libraries(eos_infrastructure_tests PRIVATE Catch2::Catch2
singularity-eos::singularity-eos)
target_link_libraries(eos_tabulated_unit_tests PRIVATE Catch2::Catch2
singularity-eos::singularity-eos)
include(Catch)
catch_discover_tests(eos_unit_tests PROPERTIES TIMEOUT 60)
catch_discover_tests(eos_analytic_unit_tests PROPERTIES TIMEOUT 60)
catch_discover_tests(eos_infrastructure_tests PROPERTIES TIMEOUT 60)
catch_discover_tests(eos_tabulated_unit_tests PROPERTIES TIMEOUT 60)

if(SINGULARITY_USE_EOSPAC AND SINGULARITY_TEST_SESAME)
add_executable(compare_to_eospac compare_to_eospac.cpp)
Expand Down
1 change: 1 addition & 0 deletions test/catch2_define.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#ifndef CATCH_CONFIG_RUNNER
#define CATCH_CONFIG_RUNNER
#define CATCH_CONFIG_FAST_COMPILE
#include "catch2/catch.hpp"
#endif

Expand Down
83 changes: 57 additions & 26 deletions test/eos_unit_test_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
#ifndef _SINGULARITY_EOS_TEST_TEST_HELPERS_
#define _SINGULARITY_EOS_TEST_TEST_HELPERS_

#ifndef CATCH_CONFIG_RUNNER
#ifndef CATCH_CONFIG_FAST_COMPILE
#define CATCH_CONFIG_FAST_COMPILE
#include "catch2/catch.hpp"
#endif
#include <cmath>
Expand Down Expand Up @@ -49,8 +50,7 @@ inline std::string demangle(const char *name) { return name; }
#endif

#include <ports-of-call/portability.hpp>

using singularity::EOS;
#include <singularity-eos/eos/eos.hpp>

PORTABLE_INLINE_FUNCTION bool isClose(Real a, Real b, Real eps = 5e-2) {
return fabs(b - a) / (fabs(a + b) + 1e-20) <= eps;
Expand All @@ -71,34 +71,65 @@ inline void array_compare(int num, X &&x, Y &&y, Z &&z, ZT &&ztrue, XN xname, YN
}
}

inline void compare_two_eoss(const EOS &test_e, const EOS &ref_e) {
template <typename E1, typename E2>
inline void compare_two_eoss(const E1 &&test_e, const E2 &&ref_e) {
// compare all individual member functions with 1 as inputs,
// this function is meant to catch mis-implementations of
// modifiers that can be initialized in such a way as to
// be equivalent of an unmodified eos. Best used with analytic
// eoss.
REQUIRE(isClose(test_e.TemperatureFromDensityInternalEnergy(1, 1),
ref_e.TemperatureFromDensityInternalEnergy(1, 1), 1.e-15));
REQUIRE(isClose(test_e.InternalEnergyFromDensityTemperature(1, 1),
ref_e.InternalEnergyFromDensityTemperature(1, 1), 1.e-15));
REQUIRE(isClose(test_e.PressureFromDensityInternalEnergy(1, 1),
ref_e.PressureFromDensityInternalEnergy(1, 1), 1.e-15));
REQUIRE(isClose(test_e.SpecificHeatFromDensityInternalEnergy(1, 1),
ref_e.SpecificHeatFromDensityInternalEnergy(1, 1), 1.e-15));
REQUIRE(isClose(test_e.BulkModulusFromDensityInternalEnergy(1, 1),
ref_e.BulkModulusFromDensityInternalEnergy(1, 1), 1.e-15));
REQUIRE(isClose(test_e.GruneisenParamFromDensityInternalEnergy(1, 1),
ref_e.GruneisenParamFromDensityInternalEnergy(1, 1), 1.e-15));
REQUIRE(isClose(test_e.PressureFromDensityTemperature(1, 1),
ref_e.PressureFromDensityTemperature(1, 1), 1.e-15));
REQUIRE(isClose(test_e.SpecificHeatFromDensityTemperature(1, 1),
ref_e.SpecificHeatFromDensityTemperature(1, 1), 1.e-15));
REQUIRE(isClose(test_e.BulkModulusFromDensityTemperature(1, 1),
ref_e.BulkModulusFromDensityTemperature(1, 1), 1.e-15));
REQUIRE(isClose(test_e.GruneisenParamFromDensityTemperature(1, 1),
ref_e.GruneisenParamFromDensityTemperature(1, 1), 1.e-15));
REQUIRE(isClose(test_e.MinimumDensity(), ref_e.MinimumDensity(), 1.e-15));
REQUIRE(isClose(test_e.MinimumTemperature(), ref_e.MinimumTemperature(), 1.e-15));
INFO("reference T: " << ref_e.TemperatureFromDensityInternalEnergy(1, 1) << " test T: "
<< test_e.TemperatureFromDensityInternalEnergy(1, 1));
CHECK(isClose(test_e.TemperatureFromDensityInternalEnergy(1, 1),
ref_e.TemperatureFromDensityInternalEnergy(1, 1), 1.e-15));
INFO("reference sie: " << ref_e.InternalEnergyFromDensityTemperature(1, 1)
<< " test sie: "
<< test_e.InternalEnergyFromDensityTemperature(1, 1));
CHECK(isClose(test_e.InternalEnergyFromDensityTemperature(1, 1),
ref_e.InternalEnergyFromDensityTemperature(1, 1), 1.e-15));
INFO("reference P: " << ref_e.PressureFromDensityInternalEnergy(1, 1)
<< " test P: " << test_e.PressureFromDensityInternalEnergy(1, 1));
CHECK(isClose(test_e.PressureFromDensityInternalEnergy(1, 1),
ref_e.PressureFromDensityInternalEnergy(1, 1), 1.e-15));
INFO("reference Cv: " << ref_e.SpecificHeatFromDensityInternalEnergy(1, 1)
<< " test Cv: "
<< test_e.SpecificHeatFromDensityInternalEnergy(1, 1));
CHECK(isClose(test_e.SpecificHeatFromDensityInternalEnergy(1, 1),
ref_e.SpecificHeatFromDensityInternalEnergy(1, 1), 1.e-15));
INFO("reference bmod: " << ref_e.BulkModulusFromDensityInternalEnergy(1, 1)
<< " test bmod: "
<< test_e.BulkModulusFromDensityInternalEnergy(1, 1));
CHECK(isClose(test_e.BulkModulusFromDensityInternalEnergy(1, 1),
ref_e.BulkModulusFromDensityInternalEnergy(1, 1), 1.e-15));
INFO("reference Grun. Param.: "
<< ref_e.GruneisenParamFromDensityInternalEnergy(1, 1)
<< " test Grun. Param.: " << test_e.GruneisenParamFromDensityInternalEnergy(1, 1));
CHECK(isClose(test_e.GruneisenParamFromDensityInternalEnergy(1, 1),
ref_e.GruneisenParamFromDensityInternalEnergy(1, 1), 1.e-15));
INFO("reference P: " << ref_e.PressureFromDensityTemperature(1, 1)
<< " test P: " << test_e.PressureFromDensityTemperature(1, 1));
CHECK(isClose(test_e.PressureFromDensityTemperature(1, 1),
ref_e.PressureFromDensityTemperature(1, 1), 1.e-15));
INFO("reference Cv: " << ref_e.SpecificHeatFromDensityTemperature(1, 1) << " test Cv: "
<< test_e.SpecificHeatFromDensityTemperature(1, 1));
CHECK(isClose(test_e.SpecificHeatFromDensityTemperature(1, 1),
ref_e.SpecificHeatFromDensityTemperature(1, 1), 1.e-15));
INFO("reference bmod: " << ref_e.BulkModulusFromDensityTemperature(1, 1)
<< " test bmod: "
<< test_e.BulkModulusFromDensityTemperature(1, 1));
CHECK(isClose(test_e.BulkModulusFromDensityTemperature(1, 1),
ref_e.BulkModulusFromDensityTemperature(1, 1), 1.e-15));
INFO("reference Grun. Param.: " << ref_e.GruneisenParamFromDensityTemperature(1, 1)
<< " test Grun. Param.: "
<< test_e.GruneisenParamFromDensityTemperature(1, 1));
CHECK(isClose(test_e.GruneisenParamFromDensityTemperature(1, 1),
ref_e.GruneisenParamFromDensityTemperature(1, 1), 1.e-15));
INFO("reference rho min.: " << ref_e.MinimumDensity()
<< " test rho min.: " << test_e.MinimumDensity());
CHECK(isClose(test_e.MinimumDensity(), ref_e.MinimumDensity(), 1.e-15));
INFO("reference T min.: " << ref_e.MinimumTemperature()
<< " test T min.: " << test_e.MinimumTemperature());
CHECK(isClose(test_e.MinimumTemperature(), ref_e.MinimumTemperature(), 1.e-15));
return;
}

Expand Down
10 changes: 4 additions & 6 deletions test/profile_eos.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
#include <spiner/interpolation.hpp>

#include <singularity-eos/eos/eos.hpp>
#include <singularity-eos/eos/eos_builder.hpp>
#include <type_traits>

using namespace singularity;
Expand Down Expand Up @@ -67,6 +66,7 @@ inline double get_duration(Function function) {
TODO(JMM): Only profiles Pressure call
and does not accept lambdas.
*/
template <typename EOS>
inline void get_timing(int ncycles, const ivec &ncells_1d, const double rho_min,
const double rho_max, const double T_min, const double T_max,
const std::string &name, EOS &eos_h) {
Expand Down Expand Up @@ -220,11 +220,9 @@ int main(int argc, char *argv[]) {
<< "Please note that timings are for 1 node and 1 GPU respectively.\n"
<< "Beginning profiling..." << std::endl;

EOSBuilder::EOSType type = EOSBuilder::EOSType::IdealGas;
EOSBuilder::params_t params;
params["Cv"].emplace<Real>(1e7 * 0.716); // specific heat in ergs/(g K)
params["gm1"].emplace<Real>(0.4); // gamma - 1
EOS eos = EOSBuilder::buildEOS(type, params);
constexpr Real Cv = 1e7 * 0.716; // specific heat in ergs/(g K)
constexpr Real gm1 = 0.4; // gamma - 1
auto eos = singularity::IdealGas(gm1, Cv);
get_timing(ncycles, ncells_1d, RHO_MIN, RHO_MAX, T_MIN, T_MAX, "IdealGas", eos);

std::cout << "Done." << std::endl;
Expand Down
5 changes: 3 additions & 2 deletions test/test_eos_gruneisen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,17 @@
#include <cstdio>
#include <cstdlib>
#include <limits>
#ifndef CATCH_CONFIG_RUNNER
#ifndef CATCH_CONFIG_FAST_COMPILE
#define CATCH_CONFIG_FAST_COMPILE
#include "catch2/catch.hpp"
#endif

#include <singularity-eos/base/constants.hpp>
#include <singularity-eos/eos/eos.hpp>
#include <test/eos_unit_test_helpers.hpp>

using singularity::EOS;
using singularity::Gruneisen;
using EOS = singularity::Variant<Gruneisen>;

PORTABLE_INLINE_FUNCTION Real QuadFormulaMinus(Real a, Real b, Real c) {
return (-b - std::sqrt(b * b - 4 * a * c)) / (2 * a);
Expand Down
3 changes: 2 additions & 1 deletion test/test_eos_helmholtz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
#include <limits>
#include <string>

#ifndef CATCH_CONFIG_RUNNER
#ifndef CATCH_CONFIG_FAST_COMPILE
#define CATCH_CONFIG_FAST_COMPILE
#include "catch2/catch.hpp"
#endif

Expand Down
Loading

0 comments on commit 70d370b

Please sign in to comment.