diff --git a/include/ddc/kernels/splines.hpp b/include/ddc/kernels/splines.hpp index 51e550fad..ca4777461 100644 --- a/include/ddc/kernels/splines.hpp +++ b/include/ddc/kernels/splines.hpp @@ -20,6 +20,7 @@ #include "splines/spline_builder_2d.hpp" #include "splines/spline_evaluator.hpp" #include "splines/spline_evaluator_2d.hpp" +#include "splines/spline_traits.hpp" #include "splines/splines_linear_problem.hpp" #include "splines/splines_linear_problem_2x2_blocks.hpp" #include "splines/splines_linear_problem_3x3_blocks.hpp" diff --git a/include/ddc/kernels/splines/spline_traits.hpp b/include/ddc/kernels/splines/spline_traits.hpp new file mode 100644 index 000000000..6918e0120 --- /dev/null +++ b/include/ddc/kernels/splines/spline_traits.hpp @@ -0,0 +1,240 @@ +// Copyright (C) The DDC development team, see COPYRIGHT.md file +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include + +#include "spline_builder.hpp" +#include "spline_builder_2d.hpp" +#include "spline_evaluator.hpp" +#include "spline_evaluator_2d.hpp" + +namespace ddc { + +template +struct is_spline_builder : std::false_type +{ +}; + +template < + class ExecSpace, + class MemorySpace, + class BSplines, + class InterpolationDDim, + ddc::BoundCond BcLower, + ddc::BoundCond BcUpper, + SplineSolver Solver> +struct is_spline_builder> : std::true_type +{ +}; + +/** + * @brief A helper to check if T is a SplineBuilder + * @tparam T The type to be checked if is a SplineBuilder + */ +template +inline constexpr bool is_spline_builder_v = is_spline_builder::value; + +template +struct is_spline_builder2d : std::false_type +{ +}; + +template < + class ExecSpace, + class MemorySpace, + class BSpline1, + class BSpline2, + class DDimI1, + class DDimI2, + ddc::BoundCond BcLower1, + ddc::BoundCond BcUpper1, + ddc::BoundCond BcLower2, + ddc::BoundCond BcUpper2, + ddc::SplineSolver Solver> +struct is_spline_builder2d> : std::true_type +{ +}; + +/** + * @brief A helper to check if T is a SplineBuilder2D + * @tparam T The type to be checked if is a SplineBuilder2D + */ +template +inline constexpr bool is_spline_builder2d_v = is_spline_builder2d::value; + +template +struct is_spline_evaluator : std::false_type +{ +}; + +template < + class ExecSpace, + class MemorySpace, + class BSplines, + class EvaluationDDim, + class LowerExtrapolationRule, + class UpperExtrapolationRule> +struct is_spline_evaluator> : std::true_type +{ +}; + +/** + * @brief A helper to check if T is a SplineEvaluator + * @tparam T The type to be checked if is a SplineEvaluator + */ +template +inline constexpr bool is_spline_evaluator_v = is_spline_evaluator::value; + +template +struct is_spline_evaluator2d : std::false_type +{ +}; + +template < + class ExecSpace, + class MemorySpace, + class BSpline1, + class BSpline2, + class EvaluationDDim1, + class EvaluationDDim2, + class LowerExtrapolationRule1, + class UpperExtrapolationRule1, + class LowerExtrapolationRule2, + class UpperExtrapolationRule2> +struct is_spline_evaluator2d> : std::true_type +{ +}; + +/** + * @brief A helper to check if T is a SplineEvaluator2D + * @tparam T The type to be checked if is a SplineEvaluator2D + */ +template +inline constexpr bool is_spline_evaluator2d_v = is_spline_evaluator2d::value; + +template +struct is_evaluator_admissible : std::false_type +{ +}; + +template < + class ExecSpace, + class MemorySpace, + class BSplines, + class InterpolationDDim, + ddc::BoundCond BcLower, + ddc::BoundCond BcUpper, + SplineSolver Solver, + class LowerExtrapolationRule, + class UpperExtrapolationRule> +struct is_evaluator_admissible< + SplineBuilder< + ExecSpace, + MemorySpace, + BSplines, + InterpolationDDim, + BcLower, + BcUpper, + Solver>, + SplineEvaluator< + ExecSpace, + MemorySpace, + BSplines, + InterpolationDDim, + LowerExtrapolationRule, + UpperExtrapolationRule>> : std::true_type +{ +}; + +template < + class ExecSpace, + class MemorySpace, + class BSplines1, + class BSplines2, + class DDimI1, + class DDimI2, + ddc::BoundCond BcLower1, + ddc::BoundCond BcUpper1, + ddc::BoundCond BcLower2, + ddc::BoundCond BcUpper2, + SplineSolver Solver, + class LowerExtrapolationRule1, + class UpperExtrapolationRule1, + class LowerExtrapolationRule2, + class UpperExtrapolationRule2> +struct is_evaluator_admissible< + SplineBuilder2D< + ExecSpace, + MemorySpace, + BSplines1, + BSplines2, + DDimI1, + DDimI2, + BcLower1, + BcUpper1, + BcLower2, + BcUpper2, + Solver>, + SplineEvaluator2D< + ExecSpace, + MemorySpace, + BSplines1, + BSplines2, + DDimI1, + DDimI2, + LowerExtrapolationRule1, + UpperExtrapolationRule1, + LowerExtrapolationRule2, + UpperExtrapolationRule2>> : std::true_type +{ +}; + +/** + * @brief A helper to check if SplineEvaluator is admissible for SplineBuilder + * @tparam Builder The builder type to be checked if it is admissible for Evaluator + * @tparam Evaluator The evaluator type to be checked if it is admissible for Builder + */ +template +inline constexpr bool is_evaluator_admissible_v + = is_evaluator_admissible::value; + +} // namespace ddc diff --git a/tests/splines/CMakeLists.txt b/tests/splines/CMakeLists.txt index 3e1c99f83..519e4bbe6 100644 --- a/tests/splines/CMakeLists.txt +++ b/tests/splines/CMakeLists.txt @@ -16,6 +16,7 @@ add_executable( knots_as_interpolation_points.cpp splines_linear_problem.cpp spline_builder.cpp + spline_traits.cpp view.cpp ) target_compile_features(splines_tests PUBLIC cxx_std_17) diff --git a/tests/splines/spline_traits.cpp b/tests/splines/spline_traits.cpp new file mode 100644 index 000000000..0c009c5bf --- /dev/null +++ b/tests/splines/spline_traits.cpp @@ -0,0 +1,298 @@ +// Copyright (C) The DDC development team, see COPYRIGHT.md file +// +// SPDX-License-Identifier: MIT + +#include +#include +#include + +#include +#include + +#include + +#include + +#include "test_utils.hpp" + +inline namespace anonymous_namespace_workaround_spline_traits_cpp { + +struct DimX +{ + static constexpr bool PERIODIC = true; +}; + +struct DDimX : ddc::NonUniformPointSampling +{ +}; + +struct DimY +{ + static constexpr bool PERIODIC = true; +}; + +struct DDimY : ddc::NonUniformPointSampling +{ +}; + +template +struct BSplinesTraits; + +template +struct BSplinesTraits, + ExecSpace2, + std::integral_constant>> : public ::testing::Test +{ + using execution_space1 = ExecSpace1; + using execution_space2 = ExecSpace2; + using memory_space1 = typename ExecSpace1::memory_space; + using memory_space2 = typename ExecSpace2::memory_space; + static constexpr std::size_t m_spline_degree1 = D1; + static constexpr std::size_t m_spline_degree2 = D2; + + struct BSplinesX1 : ddc::UniformBSplines + { + }; + + struct BSplinesX2 : ddc::UniformBSplines + { + }; + + struct BSplinesY : ddc::UniformBSplines + { + }; + + using Builder1D_1 = ddc::SplineBuilder< + execution_space1, + memory_space1, + BSplinesX1, + DDimX, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::SplineSolver::LAPACK>; + + using Evaluator1D_1 = ddc::SplineEvaluator< + execution_space1, + memory_space1, + BSplinesX1, + DDimX, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule>; + + using Builder1D_2 = ddc::SplineBuilder< + execution_space2, + memory_space2, + BSplinesX2, + DDimX, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::SplineSolver::LAPACK>; + + using Evaluator1D_2 = ddc::SplineEvaluator< + execution_space2, + memory_space2, + BSplinesX2, + DDimX, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule>; + + using Builder2D_1 = ddc::SplineBuilder2D< + execution_space1, + memory_space1, + BSplinesX1, + BSplinesY, + DDimX, + DDimY, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::SplineSolver::LAPACK>; + + using Evaluator2D_1 = ddc::SplineEvaluator2D< + execution_space1, + memory_space1, + BSplinesX1, + BSplinesY, + DDimX, + DDimY, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule>; + + using Builder2D_2 = ddc::SplineBuilder2D< + execution_space2, + memory_space2, + BSplinesX2, + BSplinesY, + DDimX, + DDimY, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::BoundCond::PERIODIC, + ddc::SplineSolver::LAPACK>; + + using Evaluator2D_2 = ddc::SplineEvaluator2D< + execution_space2, + memory_space2, + BSplinesX2, + BSplinesY, + DDimX, + DDimY, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule, + ddc::PeriodicExtrapolationRule>; +}; + +#if defined(KOKKOS_ENABLE_SERIAL) +using execution_space_types = std:: + tuple; +#else +using execution_space_types + = std::tuple; +#endif + +using spline_degrees = std::integer_sequence; + +using TestTypes = tuple_to_types_t>; + +} // namespace anonymous_namespace_workaround_spline_traits_cpp + +TYPED_TEST_SUITE(BSplinesTraits, TestTypes, ); + +TYPED_TEST(BSplinesTraits, IsSplineBuilder) +{ + using Builder1D = typename TestFixture::Builder1D_1; + using Evaluator1D = typename TestFixture::Evaluator1D_1; + using Builder2D = typename TestFixture::Builder2D_1; + using Evaluator2D = typename TestFixture::Evaluator2D_1; + ASSERT_TRUE(ddc::is_spline_builder_v); + ASSERT_FALSE(ddc::is_spline_builder_v); + ASSERT_FALSE(ddc::is_spline_builder_v); + ASSERT_FALSE(ddc::is_spline_builder_v); +} + +TYPED_TEST(BSplinesTraits, IsSplineBuilder2D) +{ + using Builder1D = typename TestFixture::Builder1D_1; + using Evaluator1D = typename TestFixture::Evaluator1D_1; + using Builder2D = typename TestFixture::Builder2D_1; + using Evaluator2D = typename TestFixture::Evaluator2D_1; + ASSERT_FALSE(ddc::is_spline_builder2d_v); + ASSERT_TRUE(ddc::is_spline_builder2d_v); + ASSERT_FALSE(ddc::is_spline_builder2d_v); + ASSERT_FALSE(ddc::is_spline_builder2d_v); +} + +TYPED_TEST(BSplinesTraits, IsSplineEvaluator) +{ + using Builder1D = typename TestFixture::Builder1D_1; + using Evaluator1D = typename TestFixture::Evaluator1D_1; + using Builder2D = typename TestFixture::Builder2D_1; + using Evaluator2D = typename TestFixture::Evaluator2D_1; + ASSERT_FALSE(ddc::is_spline_evaluator_v); + ASSERT_FALSE(ddc::is_spline_evaluator_v); + ASSERT_TRUE(ddc::is_spline_evaluator_v); + ASSERT_FALSE(ddc::is_spline_evaluator_v); +} + +TYPED_TEST(BSplinesTraits, IsSplineEvaluator2D) +{ + using Builder1D = typename TestFixture::Builder1D_1; + using Evaluator1D = typename TestFixture::Evaluator1D_1; + using Builder2D = typename TestFixture::Builder2D_1; + using Evaluator2D = typename TestFixture::Evaluator2D_1; + ASSERT_FALSE(ddc::is_spline_evaluator2d_v); + ASSERT_FALSE(ddc::is_spline_evaluator2d_v); + ASSERT_FALSE(ddc::is_spline_evaluator2d_v); + ASSERT_TRUE(ddc::is_spline_evaluator2d_v); +} + +TYPED_TEST(BSplinesTraits, IsAdmissible1D) +{ + using Builder1D_1 = typename TestFixture::Builder1D_1; + using Evaluator1D_1 = typename TestFixture::Evaluator1D_1; + using Builder1D_2 = typename TestFixture::Builder1D_2; + using Evaluator1D_2 = typename TestFixture::Evaluator1D_2; + + // Builders are not compatible + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + + // Evaluators are not compatible + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + + // Compatible builder and evaluator pairs + ASSERT_TRUE((ddc::is_evaluator_admissible_v)); + ASSERT_TRUE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + + // Incompatible builder and evaluator pairs + using execution_space1 = typename TestFixture::execution_space1; + using execution_space2 = typename TestFixture::execution_space2; + std::size_t constexpr m_spline_degree1 = TestFixture::m_spline_degree1; + std::size_t constexpr m_spline_degree2 = TestFixture::m_spline_degree2; + + if ((!std::is_same_v) + || (m_spline_degree1 != m_spline_degree2)) { + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + } +} + +TYPED_TEST(BSplinesTraits, IsAdmissible2D) +{ + using Builder2D_1 = typename TestFixture::Builder2D_1; + using Evaluator2D_1 = typename TestFixture::Evaluator2D_1; + using Builder2D_2 = typename TestFixture::Builder2D_2; + using Evaluator2D_2 = typename TestFixture::Evaluator2D_2; + + // Builders are not compatible + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + + // Evaluators are not compatible + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + + // Compatible builder and evaluator pairs + ASSERT_TRUE((ddc::is_evaluator_admissible_v)); + ASSERT_TRUE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + + // Incompatible builder and evaluator pairs + using execution_space1 = typename TestFixture::execution_space1; + using execution_space2 = typename TestFixture::execution_space2; + std::size_t constexpr m_spline_degree1 = TestFixture::m_spline_degree1; + std::size_t constexpr m_spline_degree2 = TestFixture::m_spline_degree2; + + if ((!std::is_same_v) + || (m_spline_degree1 != m_spline_degree2)) { + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + ASSERT_FALSE((ddc::is_evaluator_admissible_v)); + } +}