From b0bf9eb9c16f8dcdc11d22972855998d86e5c6d2 Mon Sep 17 00:00:00 2001 From: Chris White Date: Mon, 4 May 2026 17:07:19 -0700 Subject: [PATCH 1/3] type alias mfem::future::tuple to smith::tuple and fix ambigious compiler errors --- .../functional/domain_integral_kernels.hpp | 4 +- .../tests/tuple_arithmetic_unit_tests.cpp | 18 + src/smith/numerics/functional/tuple.hpp | 797 +++--------------- .../tuple_tensor_dual_functions.hpp | 29 +- 4 files changed, 140 insertions(+), 708 deletions(-) diff --git a/src/smith/numerics/functional/domain_integral_kernels.hpp b/src/smith/numerics/functional/domain_integral_kernels.hpp index 3b2121dfaa..c94d2df106 100644 --- a/src/smith/numerics/functional/domain_integral_kernels.hpp +++ b/src/smith/numerics/functional/domain_integral_kernels.hpp @@ -100,8 +100,8 @@ template >::type...>; - return get_gradient(apply_qf(qf, double{}, smith::tuple, tensor>{}, qpt_data, - make_dual_wrt(qf_arguments{}))); + return get_gradient(apply_qf(qf, double{}, smith::tuple, tensor>{}, + qpt_data, make_dual_wrt(qf_arguments{}))); }; template diff --git a/src/smith/numerics/functional/tests/tuple_arithmetic_unit_tests.cpp b/src/smith/numerics/functional/tests/tuple_arithmetic_unit_tests.cpp index 2fc7f91ec3..c3521c181d 100644 --- a/src/smith/numerics/functional/tests/tuple_arithmetic_unit_tests.cpp +++ b/src/smith/numerics/functional/tests/tuple_arithmetic_unit_tests.cpp @@ -28,6 +28,24 @@ TEST(TupleArithmeticUnitTests, StructuredBinding) EXPECT_NEAR(c, 2.0f, 1.0e-10); } +TEST(TupleArithmeticUnitTests, TenElementTuple) +{ + smith::tuple x{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + EXPECT_EQ(smith::get<9>(x), 9); + smith::get<9>(x) = 42; + EXPECT_EQ(smith::get<9>(x), 42); +} + +TEST(TupleArithmeticUnitTests, ElevenElementTuple) +{ + smith::tuple x{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + + EXPECT_EQ(smith::get<10>(x), 10); + smith::get<10>(x) = 42; + EXPECT_EQ(smith::get<10>(x), 42); +} + TEST(TupleArithmeticUnitTests, Add) { smith::tuple a{0.0, make_tensor<3>([](int) { return 3.0; }), diff --git a/src/smith/numerics/functional/tuple.hpp b/src/smith/numerics/functional/tuple.hpp index 48af5ec04b..ae11103cda 100644 --- a/src/smith/numerics/functional/tuple.hpp +++ b/src/smith/numerics/functional/tuple.hpp @@ -7,202 +7,21 @@ /** * @file tuple.hpp * - * @brief Implements a std::tuple-like object that works in CUDA kernels + * @brief Smith tuple compatibility layer over mfem::future::tuple */ #pragma once -#include +#include "mfem/fem/dfem/tuple.hpp" #include "smith/infrastructure/accelerator.hpp" -namespace smith { - -/** - * @tparam T the types stored in the tuple - * @brief This is a class that mimics most of std::tuple's interface, - * except that it is usable in CUDA kernels and admits some arithmetic operator overloads. - * - * see https://en.cppreference.com/w/cpp/utility/tuple for more information about std::tuple - */ -template -struct tuple {}; - -/** - * @brief Type that mimics std::tuple - * - * @tparam T0 The first type stored in the tuple - */ -template -struct tuple { - T0 v0; ///< The first member of the tuple -}; - -/** - * @brief Type that mimics std::tuple - * - * @tparam T0 The first type stored in the tuple - * @tparam T1 The second type stored in the tuple - */ -template -struct tuple { - T0 v0; ///< The first member of the tuple - T1 v1; ///< The second member of the tuple -}; - -/** - * @brief Type that mimics std::tuple - * - * @tparam T0 The first type stored in the tuple - * @tparam T1 The second type stored in the tuple - * @tparam T2 The third type stored in the tuple - */ -template -struct tuple { - T0 v0; ///< The first member of the tuple - T1 v1; ///< The second member of the tuple - T2 v2; ///< The third member of the tuple -}; - -/** - * @brief Type that mimics std::tuple - * - * @tparam T0 The first type stored in the tuple - * @tparam T1 The second type stored in the tuple - * @tparam T2 The third type stored in the tuple - * @tparam T3 The fourth type stored in the tuple - */ -template -struct tuple { - T0 v0; ///< The first member of the tuple - T1 v1; ///< The second member of the tuple - T2 v2; ///< The third member of the tuple - T3 v3; ///< The fourth member of the tuple -}; - -/** - * @brief Type that mimics std::tuple - * - * @tparam T0 The first type stored in the tuple - * @tparam T1 The second type stored in the tuple - * @tparam T2 The third type stored in the tuple - * @tparam T3 The fourth type stored in the tuple - * @tparam T4 The fifth type stored in the tuple - */ -template -struct tuple { - T0 v0; ///< The first member of the tuple - T1 v1; ///< The second member of the tuple - T2 v2; ///< The third member of the tuple - T3 v3; ///< The fourth member of the tuple - T4 v4; ///< The fifth member of the tuple -}; - -/** - * @brief Type that mimics std::tuple - * - * @tparam T0 The first type stored in the tuple - * @tparam T1 The second type stored in the tuple - * @tparam T2 The third type stored in the tuple - * @tparam T3 The fourth type stored in the tuple - * @tparam T4 The fifth type stored in the tuple - * @tparam T5 The sixth type stored in the tuple - */ -template -struct tuple { - T0 v0; ///< The first member of the tuple - T1 v1; ///< The second member of the tuple - T2 v2; ///< The third member of the tuple - T3 v3; ///< The fourth member of the tuple - T4 v4; ///< The fifth member of the tuple - T5 v5; ///< The sixth member of the tuple -}; +namespace mfem::future { /** - * @brief Type that mimics std::tuple + * @brief Smith compatibility extension for the MFEM tuple implementation. * - * @tparam T0 The first type stored in the tuple - * @tparam T1 The second type stored in the tuple - * @tparam T2 The third type stored in the tuple - * @tparam T3 The fourth type stored in the tuple - * @tparam T4 The fifth type stored in the tuple - * @tparam T5 The sixth type stored in the tuple - * @tparam T6 The seventh type stored in the tuple - */ -template -struct tuple { - T0 v0; ///< The first member of the tuple - T1 v1; ///< The second member of the tuple - T2 v2; ///< The third member of the tuple - T3 v3; ///< The fourth member of the tuple - T4 v4; ///< The fifth member of the tuple - T5 v5; ///< The sixth member of the tuple - T6 v6; ///< The seventh member of the tuple -}; - -/** - * @brief Type that mimics std::tuple - * - * @tparam T0 The first type stored in the tuple - * @tparam T1 The second type stored in the tuple - * @tparam T2 The third type stored in the tuple - * @tparam T3 The fourth type stored in the tuple - * @tparam T4 The fifth type stored in the tuple - * @tparam T5 The sixth type stored in the tuple - * @tparam T6 The seventh type stored in the tuple - * @tparam T7 The eighth type stored in the tuple - */ -template -struct tuple { - T0 v0; ///< The first member of the tuple - T1 v1; ///< The second member of the tuple - T2 v2; ///< The third member of the tuple - T3 v3; ///< The fourth member of the tuple - T4 v4; ///< The fifth member of the tuple - T5 v5; ///< The sixth member of the tuple - T6 v6; ///< The seventh member of the tuple - T7 v7; ///< The eighth member of the tuple -}; - -/** - * @brief Type that mimics std::tuple - * - * @tparam T0 The first type stored in the tuple - * @tparam T1 The second type stored in the tuple - * @tparam T2 The third type stored in the tuple - * @tparam T3 The fourth type stored in the tuple - * @tparam T4 The fifth type stored in the tuple - * @tparam T5 The sixth type stored in the tuple - * @tparam T6 The seventh type stored in the tuple - * @tparam T7 The eighth type stored in the tuple - * @tparam T8 The ninth type stored in the tuple - */ -template -struct tuple { - T0 v0; ///< The first member of the tuple - T1 v1; ///< The second member of the tuple - T2 v2; ///< The third member of the tuple - T3 v3; ///< The fourth member of the tuple - T4 v4; ///< The fifth member of the tuple - T5 v5; ///< The sixth member of the tuple - T6 v6; ///< The seventh member of the tuple - T7 v7; ///< The eighth member of the tuple - T8 v8; ///< The ninth member of the tuple -}; - -/** - * @brief Type that mimics std::tuple - * - * @tparam T0 The first type stored in the tuple - * @tparam T1 The second type stored in the tuple - * @tparam T2 The third type stored in the tuple - * @tparam T3 The fourth type stored in the tuple - * @tparam T4 The fifth type stored in the tuple - * @tparam T5 The sixth type stored in the tuple - * @tparam T6 The seventh type stored in the tuple - * @tparam T7 The eighth type stored in the tuple - * @tparam T8 The ninth type stored in the tuple - * @tparam T9 The tenth type stored in the tuple + * MFEM's tuple copy currently stores up to nine elements, while Smith's + * historical tuple API supports ten and eleven elements. */ template @@ -220,19 +39,7 @@ struct tuple { }; /** - * @brief Type that mimics std::tuple - * - * @tparam T0 The first type stored in the tuple - * @tparam T1 The second type stored in the tuple - * @tparam T2 The third type stored in the tuple - * @tparam T3 The fourth type stored in the tuple - * @tparam T4 The fifth type stored in the tuple - * @tparam T5 The sixth type stored in the tuple - * @tparam T6 The seventh type stored in the tuple - * @tparam T7 The eighth type stored in the tuple - * @tparam T8 The ninth type stored in the tuple - * @tparam T9 The tenth type stored in the tuple - * @tparam T10 The eleventh type stored in the tuple + * @brief Smith compatibility extension for the MFEM tuple implementation. */ template @@ -250,83 +57,12 @@ struct tuple { T10 v10; ///< The eleventh member of the tuple }; -/** - * @brief Class template argument deduction rule for tuples - * @tparam T The variadic template parameter for tuple types - */ -template -tuple(T...) -> tuple; - -/** - * @brief helper function for combining a list of values into a tuple - * @tparam T types of the values to be tuple-d - * @param args the actual values to be put into a tuple - */ -template -SMITH_HOST_DEVICE tuple make_tuple(const T&... args) -{ - return tuple{args...}; -} - -template -struct tuple_size {}; - -template -struct tuple_size> : std::integral_constant {}; - -/** - * @tparam i the tuple index to access - * @tparam T the types stored in the tuple - * @brief return a reference to the ith tuple entry - */ -template -SMITH_HOST_DEVICE constexpr auto& get(tuple& values) -{ - static_assert(i < sizeof...(T), ""); - if constexpr (i == 0) { - return values.v0; - } - if constexpr (i == 1) { - return values.v1; - } - if constexpr (i == 2) { - return values.v2; - } - if constexpr (i == 3) { - return values.v3; - } - if constexpr (i == 4) { - return values.v4; - } - if constexpr (i == 5) { - return values.v5; - } - if constexpr (i == 6) { - return values.v6; - } - if constexpr (i == 7) { - return values.v7; - } - if constexpr (i == 8) { - return values.v8; - } - if constexpr (i == 9) { - return values.v9; - } - if constexpr (i == 10) { - return values.v10; - } -} +namespace detail { -/** - * @tparam i the tuple index to access - * @tparam T the types stored in the tuple - * @brief return a copy of the ith tuple entry - */ -template -SMITH_HOST_DEVICE constexpr const auto& get(const tuple& values) +/// @brief Return element @p i from a 10- or 11-element tuple. +template +MFEM_HOST_DEVICE constexpr auto& tuple_get_extended(Tuple& values) { - static_assert(i < sizeof...(T), ""); if constexpr (i == 0) { return values.v0; } @@ -360,22 +96,13 @@ SMITH_HOST_DEVICE constexpr const auto& get(const tuple& values) if constexpr (i == 10) { return values.v10; } + MFEM_UNREACHABLE(); } -/** - * @brief a function intended to be used for extracting the ith type from a tuple. - * - * @note type(my_tuple) returns a value, whereas get(my_tuple) returns a reference - * - * @tparam i the index of the tuple to query - * @tparam T the types stored in the tuple - * @param values the tuple of values - * @return a copy of the ith entry of the input - */ -template -SMITH_HOST_DEVICE constexpr auto type(const tuple& values) +/// @brief Return const element @p i from a 10- or 11-element tuple. +template +MFEM_HOST_DEVICE constexpr const auto& tuple_get_extended(const Tuple& values) { - static_assert(i < sizeof...(T), ""); if constexpr (i == 0) { return values.v0; } @@ -409,448 +136,134 @@ SMITH_HOST_DEVICE constexpr auto type(const tuple& values) if constexpr (i == 10) { return values.v10; } + MFEM_UNREACHABLE(); } -/** - * @brief A helper function for the + operator of tuples - * - * @tparam S the types stored in the tuple x - * @tparam T the types stored in the tuple y - * @tparam i The integer sequence to i - * @param x tuple of values - * @param y tuple of values - * @return the returned tuple sum - */ -template -SMITH_HOST_DEVICE constexpr auto plus_helper(const tuple& x, const tuple& y, - std::integer_sequence) -{ - return tuple{get(x) + get(y)...}; -} - -/** - * @tparam S the types stored in the tuple x - * @tparam T the types stored in the tuple y - * @param x a tuple of values - * @param y a tuple of values - * @brief return a tuple of values defined by elementwise sum of x and y - */ -template -SMITH_HOST_DEVICE constexpr auto operator+(const tuple& x, const tuple& y) -{ - static_assert(sizeof...(S) == sizeof...(T)); - return plus_helper(x, y, std::make_integer_sequence(sizeof...(S))>()); -} - -/** - * @brief A helper function for the += operator of tuples - * - * @tparam T the types stored in the tuples x and y - * @tparam i integer sequence used to index the tuples - * @param x tuple of values to be incremented - * @param y tuple of increment values - */ -template -SMITH_HOST_DEVICE constexpr void plus_equals_helper(tuple& x, const tuple& y, - std::integer_sequence) -{ - ((get(x) += get(y)), ...); -} - -/** - * @tparam T the types stored in the tuples x and y - * @param x a tuple of values - * @param y a tuple of values - * @brief add values contained in y, to the tuple x - */ -template -SMITH_HOST_DEVICE constexpr auto operator+=(tuple& x, const tuple& y) -{ - return plus_equals_helper(x, y, std::make_integer_sequence(sizeof...(T))>()); -} - -/** - * @brief A helper function for the -= operator of tuples - * - * @tparam T the types stored in the tuples x and y - * @tparam i integer sequence used to index the tuples - * @param x tuple of values to be subracted from - * @param y tuple of values to subtract from x - */ -template -SMITH_HOST_DEVICE constexpr void minus_equals_helper(tuple& x, const tuple& y, - std::integer_sequence) -{ - ((get(x) -= get(y)), ...); -} - -/** - * @tparam T the types stored in the tuples x and y - * @param x a tuple of values - * @param y a tuple of values - * @brief add values contained in y, to the tuple x - */ -template -SMITH_HOST_DEVICE constexpr auto operator-=(tuple& x, const tuple& y) -{ - return minus_equals_helper(x, y, std::make_integer_sequence(sizeof...(T))>()); -} - -/** - * @brief A helper function for the - operator of tuples - * - * @tparam S the types stored in the tuple x - * @tparam T the types stored in the tuple y - * @tparam i The integer sequence to i - * @param x tuple of values - * @param y tuple of values - * @return the returned tuple difference - */ -template -SMITH_HOST_DEVICE constexpr auto minus_helper(const tuple& x, const tuple& y, - std::integer_sequence) -{ - return tuple{get(x) - get(y)...}; -} - -/** - * @tparam S the types stored in the tuple x - * @tparam T the types stored in the tuple y - * @param x a tuple of values - * @param y a tuple of values - * @brief return a tuple of values defined by elementwise difference of x and y - */ -template -SMITH_HOST_DEVICE constexpr auto operator-(const tuple& x, const tuple& y) -{ - static_assert(sizeof...(S) == sizeof...(T)); - return minus_helper(x, y, std::make_integer_sequence(sizeof...(S))>()); -} - -/** - * @brief A helper function for the - operator of tuples - * - * @tparam T the types stored in the tuple y - * @tparam i The integer sequence to i - * @param x tuple of values - * @return the returned tuple difference - */ -template -SMITH_HOST_DEVICE constexpr auto unary_minus_helper(const tuple& x, std::integer_sequence) -{ - return tuple{-get(x)...}; -} +} // namespace detail -/** - * @tparam T the types stored in the tuple y - * @param x a tuple of values - * @brief return a tuple of values defined by applying the unary minus operator to each element of x - */ -template -SMITH_HOST_DEVICE constexpr auto operator-(const tuple& x) +/// @brief Return mutable element @p i from a 10-element tuple. +template +MFEM_HOST_DEVICE constexpr auto& get(tuple& values) { - return unary_minus_helper(x, std::make_integer_sequence(sizeof...(T))>()); + static_assert(i < 10); + return detail::tuple_get_extended(values); } -/** - * @brief A helper function for the / operator of tuples - * - * @tparam S the types stored in the tuple x - * @tparam T the types stored in the tuple y - * @tparam i The integer sequence to i - * @param x tuple of values - * @param y tuple of values - * @return the returned tuple ratio - */ -template -SMITH_HOST_DEVICE constexpr auto div_helper(const tuple& x, const tuple& y, - std::integer_sequence) +/// @brief Return mutable element @p i from an 11-element tuple. +template +MFEM_HOST_DEVICE constexpr auto& get(tuple& values) { - return tuple{get(x) / get(y)...}; + static_assert(i < 11); + return detail::tuple_get_extended(values); } -/** - * @tparam S the types stored in the tuple x - * @tparam T the types stored in the tuple y - * @param x a tuple of values - * @param y a tuple of values - * @brief return a tuple of values defined by elementwise division of x by y - */ -template -SMITH_HOST_DEVICE constexpr auto operator/(const tuple& x, const tuple& y) +/// @brief Return const element @p i from a 10-element tuple. +template +MFEM_HOST_DEVICE constexpr const auto& get(const tuple& values) { - static_assert(sizeof...(S) == sizeof...(T)); - return div_helper(x, y, std::make_integer_sequence(sizeof...(S))>()); + static_assert(i < 10); + return detail::tuple_get_extended(values); } -/** - * @brief A helper function for the / operator of tuples - * - * @tparam T the types stored in the tuple y - * @tparam i The integer sequence to i - * @param x tuple of values - * @param a the constant numerator - * @return the returned tuple ratio - */ -template -SMITH_HOST_DEVICE constexpr auto div_helper(const double a, const tuple& x, std::integer_sequence) +/// @brief Return const element @p i from an 11-element tuple. +template +MFEM_HOST_DEVICE constexpr const auto& get(const tuple& values) { - return tuple{a / get(x)...}; + static_assert(i < 11); + return detail::tuple_get_extended(values); } /** - * @brief A helper function for the / operator of tuples + * @brief a function intended to be used for extracting the ith type from a tuple. * - * @tparam T the types stored in the tuple y - * @tparam i The integer sequence to i - * @param x tuple of values - * @param a the constant denomenator - * @return the returned tuple ratio - */ -template -SMITH_HOST_DEVICE constexpr auto div_helper(const tuple& x, const double a, std::integer_sequence) -{ - return tuple{get(x) / a...}; -} - -/** - * @tparam T the types stored in the tuple x - * @param a the numerator - * @param x a tuple of denominator values - * @brief return a tuple of values defined by division of a by the elements of x - */ -template -SMITH_HOST_DEVICE constexpr auto operator/(const double a, const tuple& x) -{ - return div_helper(a, x, std::make_integer_sequence(sizeof...(T))>()); -} - -/** - * @tparam T the types stored in the tuple y - * @param x a tuple of numerator values - * @param a a denominator - * @brief return a tuple of values defined by elementwise division of x by a - */ -template -SMITH_HOST_DEVICE constexpr auto operator/(const tuple& x, const double a) -{ - return div_helper(x, a, std::make_integer_sequence(sizeof...(T))>()); -} - -/** - * @brief A helper function for the * operator of tuples + * @note type(my_tuple) returns a value, whereas get(my_tuple) returns a reference * - * @tparam S the types stored in the tuple x - * @tparam T the types stored in the tuple y - * @tparam i The integer sequence to i - * @param x tuple of values - * @param y tuple of values - * @return the returned tuple product - */ -template -SMITH_HOST_DEVICE constexpr auto mult_helper(const tuple& x, const tuple& y, - std::integer_sequence) -{ - return tuple{get(x) * get(y)...}; -} - -/** - * @tparam S the types stored in the tuple x - * @tparam T the types stored in the tuple y - * @param x a tuple of values - * @param y a tuple of values - * @brief return a tuple of values defined by elementwise multiplication of x and y + * @tparam i the index of the tuple to query + * @tparam T0 The first type stored in the tuple + * @tparam T1 The second type stored in the tuple + * @tparam T2 The third type stored in the tuple + * @tparam T3 The fourth type stored in the tuple + * @tparam T4 The fifth type stored in the tuple + * @tparam T5 The sixth type stored in the tuple + * @tparam T6 The seventh type stored in the tuple + * @tparam T7 The eighth type stored in the tuple + * @tparam T8 The ninth type stored in the tuple + * @tparam T9 The tenth type stored in the tuple + * @param values the tuple of values + * @return a copy of the ith entry of the input */ -template -SMITH_HOST_DEVICE constexpr auto operator*(const tuple& x, const tuple& y) +template +MFEM_HOST_DEVICE constexpr auto type(const tuple& values) { - static_assert(sizeof...(S) == sizeof...(T)); - return mult_helper(x, y, std::make_integer_sequence(sizeof...(S))>()); + static_assert(i < 10); + return detail::tuple_get_extended(values); } /** - * @brief A helper function for the * operator of tuples + * @brief a function intended to be used for extracting the ith type from a tuple. * - * @tparam T the types stored in the tuple y - * @tparam i The integer sequence to i - * @param x tuple of values - * @param a a constant multiplier - * @return the returned tuple product - */ -template -SMITH_HOST_DEVICE constexpr auto mult_helper(const double a, const tuple& x, std::integer_sequence) -{ - return tuple{a * get(x)...}; -} - -/** - * @brief A helper function for the * operator of tuples + * @note type(my_tuple) returns a value, whereas get(my_tuple) returns a reference * - * @tparam T the types stored in the tuple y - * @tparam i The integer sequence to i - * @param x tuple of values - * @param a a constant multiplier - * @return the returned tuple product - */ -template -SMITH_HOST_DEVICE constexpr auto mult_helper(const tuple& x, const double a, std::integer_sequence) -{ - return tuple{get(x) * a...}; -} - -/** - * @tparam T the types stored in the tuple - * @param a a scaling factor - * @param x the tuple object - * @brief multiply each component of x by the value a on the left + * @tparam i the index of the tuple to query + * @tparam T0 The first type stored in the tuple + * @tparam T1 The second type stored in the tuple + * @tparam T2 The third type stored in the tuple + * @tparam T3 The fourth type stored in the tuple + * @tparam T4 The fifth type stored in the tuple + * @tparam T5 The sixth type stored in the tuple + * @tparam T6 The seventh type stored in the tuple + * @tparam T7 The eighth type stored in the tuple + * @tparam T8 The ninth type stored in the tuple + * @tparam T9 The tenth type stored in the tuple + * @tparam T10 The eleventh type stored in the tuple + * @param values the tuple of values + * @return a copy of the ith entry of the input */ -template -SMITH_HOST_DEVICE constexpr auto operator*(const double a, const tuple& x) +template +MFEM_HOST_DEVICE constexpr auto type(const tuple& values) { - return mult_helper(a, x, std::make_integer_sequence(sizeof...(T))>()); + static_assert(i < 11); + return detail::tuple_get_extended(values); } -/** - * @tparam T the types stored in the tuple - * @param x the tuple object - * @param a a scaling factor - * @brief multiply each component of x by the value a on the right - */ -template -SMITH_HOST_DEVICE constexpr auto operator*(const tuple& x, const double a) -{ - return mult_helper(x, a, std::make_integer_sequence(sizeof...(T))>()); -} +} // namespace mfem::future -/** - * @tparam T the types stored in the tuple - * @tparam i a list of indices used to acces each element of the tuple - * @param out the ostream to write the output to - * @param A the tuple of values - * @brief helper used to implement printing a tuple of values - */ -template -auto& print_helper(std::ostream& out, const smith::tuple& A, std::integer_sequence) -{ - out << "tuple{"; - (..., (out << (i == 0 ? "" : ", ") << smith::get(A))); - out << "}"; - return out; -} +namespace smith { -/** - * @tparam T the types stored in the tuple - * @param out the ostream to write the output to - * @param A the tuple of values - * @brief print a tuple of values - */ +/// @brief Expose MFEM tuple in the Smith namespace. template -auto& operator<<(std::ostream& out, const smith::tuple& A) -{ - return print_helper(out, A, std::make_integer_sequence()); -} - -/** - * @brief A helper to apply a lambda to a tuple - * - * @tparam lambda The functor type - * @tparam T The tuple types - * @tparam i The integer sequence to i - * @param f The functor to apply to the tuple - * @param args The input tuple - * @return The functor output - */ -template -SMITH_HOST_DEVICE auto apply_helper(lambda f, tuple& args, std::integer_sequence) -{ - return f(get(args)...); -} - -/** - * @tparam lambda a callable type - * @tparam T the types of arguments to be passed in to f - * @param f the callable object - * @param args a tuple of arguments - * @brief a way of passing an n-tuple to a function that expects n separate arguments - * - * e.g. foo(bar, baz) is equivalent to apply(foo, smith::tuple(bar,baz)); - */ -template -SMITH_HOST_DEVICE auto apply(lambda f, tuple& args) -{ - return apply_helper(f, std::move(args), std::make_integer_sequence(sizeof...(T))>()); -} - -/** - * @overload - */ -template -SMITH_HOST_DEVICE auto apply_helper(lambda f, const tuple& args, std::integer_sequence) -{ - return f(get(args)...); -} - -/** - * @tparam lambda a callable type - * @tparam T the types of arguments to be passed in to f - * @param f the callable object - * @param args a tuple of arguments - * @brief a way of passing an n-tuple to a function that expects n separate arguments - * - * e.g. foo(bar, baz) is equivalent to apply(foo, smith::tuple(bar,baz)); - */ -template -SMITH_HOST_DEVICE auto apply(lambda f, const tuple& args) -{ - return apply_helper(f, std::move(args), std::make_integer_sequence(sizeof...(T))>()); -} +using tuple = mfem::future::tuple; + +/// @brief Expose MFEM tuple application in the Smith namespace. +using mfem::future::apply; +/// @brief Expose MFEM tuple element access in the Smith namespace. +using mfem::future::get; +/// @brief Expose MFEM tuple construction in the Smith namespace. +using mfem::future::make_tuple; +/// @brief Expose MFEM tuple type selection in the Smith namespace. +using mfem::future::type; + +/// @brief Alias for the MFEM tuple size trait. +template +using tuple_size = mfem::future::tuple_size; -/** - * @brief a struct used to determine the type at index I of a tuple - * - * @note see: https://en.cppreference.com/w/cpp/utility/tuple/tuple_element - * - * @tparam I the index of the desired type - * @tparam T a tuple of different types - */ +/// @brief Alias for the MFEM tuple element trait. template -struct tuple_element; - -// recursive case -/// @overload -template -struct tuple_element> : tuple_element> {}; +using tuple_element = mfem::future::tuple_element; -// base case -/// @overload -template -struct tuple_element<0, tuple> { - using type = Head; ///< the type at the specified index -}; - -/** - * @brief Trait for checking if a type is a @p smith::tuple - */ +/// @brief Alias for the MFEM tuple detection trait. template -struct is_tuple : std::false_type {}; +using is_tuple = mfem::future::is_tuple; -/// @overload -template -struct is_tuple> : std::true_type {}; - -/** - * @brief Trait for checking if a type if a @p smith::tuple containing only @p smith::tuple - */ +/// @brief Alias for the MFEM nested tuple detection trait. template -struct is_tuple_of_tuples : std::false_type {}; - -/** - * @brief Trait for checking if a type if a @p smith::tuple containing only @p smith::tuple - */ -template -struct is_tuple_of_tuples> { - static constexpr bool value = (is_tuple::value && ...); ///< true/false result of type check -}; +using is_tuple_of_tuples = mfem::future::is_tuple_of_tuples; } // namespace smith diff --git a/src/smith/numerics/functional/tuple_tensor_dual_functions.hpp b/src/smith/numerics/functional/tuple_tensor_dual_functions.hpp index ad2efb46a4..0bb3c5671d 100644 --- a/src/smith/numerics/functional/tuple_tensor_dual_functions.hpp +++ b/src/smith/numerics/functional/tuple_tensor_dual_functions.hpp @@ -276,6 +276,18 @@ constexpr auto make_dual_wrt(const smith::tuple& args) return make_dual_helper(args, std::make_integer_sequence(sizeof...(T))>{}); } +/** + * @brief Retrieves the value components of a set of (possibly dual) numbers + * @param[in] tuple_of_values The tuple of numbers to retrieve values from + * @pre The tuple must contain only scalars or tensors of @p dual numbers or doubles + */ +template +SMITH_HOST_DEVICE auto get_value(const smith::tuple& tuple_of_values) +{ + return smith::apply([](const auto&... each_value) { return smith::tuple{get_value(each_value)...}; }, + tuple_of_values); +} + /** * @brief Extracts all of the values from a tensor of dual numbers * @@ -288,25 +300,13 @@ constexpr auto make_dual_wrt(const smith::tuple& args) template SMITH_HOST_DEVICE auto get_value(const tensor, n>& input) { - tensor{})), n> output{}; + tensor{})), n> output{}; for (int i = 0; i < n; i++) { output[i] = get_value(input[i]); } return output; } -/** - * @brief Retrieves the value components of a set of (possibly dual) numbers - * @param[in] tuple_of_values The tuple of numbers to retrieve values from - * @pre The tuple must contain only scalars or tensors of @p dual numbers or doubles - */ -template -SMITH_HOST_DEVICE auto get_value(const smith::tuple& tuple_of_values) -{ - return smith::apply([](const auto&... each_value) { return smith::tuple{get_value(each_value)...}; }, - tuple_of_values); -} - /** * @brief Retrieves the gradient components of a set of dual numbers * @param[in] arg The set of numbers to retrieve gradients from @@ -332,7 +332,8 @@ SMITH_HOST_DEVICE auto get_gradient(const tensor>, n...> template SMITH_HOST_DEVICE auto get_gradient(smith::tuple tuple_of_values) { - return smith::apply([](auto... each_value) { return smith::tuple{get_gradient(each_value)...}; }, tuple_of_values); + return smith::apply([](auto... each_value) { return smith::tuple{get_gradient(each_value)...}; }, + tuple_of_values); } /** From e11f0180d631e44c85070a06e63aaa025c4f206b Mon Sep 17 00:00:00 2001 From: Chris White Date: Tue, 5 May 2026 22:41:19 -0700 Subject: [PATCH 2/3] style --- src/smith/numerics/functional/domain_integral_kernels.hpp | 4 ++-- src/smith/numerics/functional/tuple_tensor_dual_functions.hpp | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/smith/numerics/functional/domain_integral_kernels.hpp b/src/smith/numerics/functional/domain_integral_kernels.hpp index c94d2df106..3b2121dfaa 100644 --- a/src/smith/numerics/functional/domain_integral_kernels.hpp +++ b/src/smith/numerics/functional/domain_integral_kernels.hpp @@ -100,8 +100,8 @@ template >::type...>; - return get_gradient(apply_qf(qf, double{}, smith::tuple, tensor>{}, - qpt_data, make_dual_wrt(qf_arguments{}))); + return get_gradient(apply_qf(qf, double{}, smith::tuple, tensor>{}, qpt_data, + make_dual_wrt(qf_arguments{}))); }; template diff --git a/src/smith/numerics/functional/tuple_tensor_dual_functions.hpp b/src/smith/numerics/functional/tuple_tensor_dual_functions.hpp index 0bb3c5671d..0b80bf3977 100644 --- a/src/smith/numerics/functional/tuple_tensor_dual_functions.hpp +++ b/src/smith/numerics/functional/tuple_tensor_dual_functions.hpp @@ -332,8 +332,7 @@ SMITH_HOST_DEVICE auto get_gradient(const tensor>, n...> template SMITH_HOST_DEVICE auto get_gradient(smith::tuple tuple_of_values) { - return smith::apply([](auto... each_value) { return smith::tuple{get_gradient(each_value)...}; }, - tuple_of_values); + return smith::apply([](auto... each_value) { return smith::tuple{get_gradient(each_value)...}; }, tuple_of_values); } /** From 485826f5b60fffc51690e92bef5556547509f2be Mon Sep 17 00:00:00 2001 From: Chris White Date: Wed, 6 May 2026 00:16:59 -0700 Subject: [PATCH 3/3] fix mfem include --- src/smith/numerics/functional/tuple.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/smith/numerics/functional/tuple.hpp b/src/smith/numerics/functional/tuple.hpp index ae11103cda..9331b8ef07 100644 --- a/src/smith/numerics/functional/tuple.hpp +++ b/src/smith/numerics/functional/tuple.hpp @@ -11,7 +11,7 @@ */ #pragma once -#include "mfem/fem/dfem/tuple.hpp" +#include "mfem.hpp" #include "smith/infrastructure/accelerator.hpp"