Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up and clean up unit tests #310

Merged
merged 8 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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, ...)
jhp-lanl marked this conversation as resolved.
Show resolved Hide resolved

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)
jhp-lanl marked this conversation as resolved.
Show resolved Hide resolved

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));
jhp-lanl marked this conversation as resolved.
Show resolved Hide resolved
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
Loading