11 #include "DataStructures/Tags/TempTensor.hpp"
16 #include "Utilities/GenerateInstantiations.hpp"
21 namespace TestHelpers::TensorExpressions {
51 template <
typename DataType,
typename RhsSymmetry,
52 typename RhsTensorIndexTypeList,
auto& TensorIndexA,
53 auto& TensorIndexB,
auto& TensorIndexC>
55 const size_t used_for_size = 5;
56 Tensor<DataType, RhsSymmetry, RhsTensorIndexTypeList> R_abc(used_for_size);
57 std::iota(R_abc.begin(), R_abc.end(), 0.0);
61 const std::int32_t rhs_symmetry_element_a = tmpl::at_c<RhsSymmetry, 0>::value;
62 const std::int32_t rhs_symmetry_element_b = tmpl::at_c<RhsSymmetry, 1>::value;
63 const std::int32_t rhs_symmetry_element_c = tmpl::at_c<RhsSymmetry, 2>::value;
64 using rhs_tensorindextype_a = tmpl::at_c<RhsTensorIndexTypeList, 0>;
65 using rhs_tensorindextype_b = tmpl::at_c<RhsTensorIndexTypeList, 1>;
66 using rhs_tensorindextype_c = tmpl::at_c<RhsTensorIndexTypeList, 2>;
71 using L_abc_type = Tensor<DataType, RhsSymmetry, RhsTensorIndexTypeList>;
72 const L_abc_type L_abc_returned =
73 ::TensorExpressions::evaluate<TensorIndexA, TensorIndexB, TensorIndexC>(
74 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
75 L_abc_type L_abc_filled{};
76 ::TensorExpressions::evaluate<TensorIndexA, TensorIndexB, TensorIndexC>(
78 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
81 using L_acb_symmetry =
82 Symmetry<rhs_symmetry_element_a, rhs_symmetry_element_c,
83 rhs_symmetry_element_b>;
84 using L_acb_tensorindextype_list =
85 tmpl::list<rhs_tensorindextype_a, rhs_tensorindextype_c,
86 rhs_tensorindextype_b>;
88 Tensor<DataType, L_acb_symmetry, L_acb_tensorindextype_list>;
89 const L_acb_type L_acb_returned =
90 ::TensorExpressions::evaluate<TensorIndexA, TensorIndexC, TensorIndexB>(
91 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
92 L_acb_type L_acb_filled{};
93 ::TensorExpressions::evaluate<TensorIndexA, TensorIndexC, TensorIndexB>(
95 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
98 using L_bac_symmetry =
99 Symmetry<rhs_symmetry_element_b, rhs_symmetry_element_a,
100 rhs_symmetry_element_c>;
101 using L_bac_tensorindextype_list =
102 tmpl::list<rhs_tensorindextype_b, rhs_tensorindextype_a,
103 rhs_tensorindextype_c>;
105 Tensor<DataType, L_bac_symmetry, L_bac_tensorindextype_list>;
106 const L_bac_type L_bac_returned =
107 ::TensorExpressions::evaluate<TensorIndexB, TensorIndexA, TensorIndexC>(
108 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
109 L_bac_type L_bac_filled{};
110 ::TensorExpressions::evaluate<TensorIndexB, TensorIndexA, TensorIndexC>(
112 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
115 using L_bca_symmetry =
116 Symmetry<rhs_symmetry_element_b, rhs_symmetry_element_c,
117 rhs_symmetry_element_a>;
118 using L_bca_tensorindextype_list =
119 tmpl::list<rhs_tensorindextype_b, rhs_tensorindextype_c,
120 rhs_tensorindextype_a>;
122 Tensor<DataType, L_bca_symmetry, L_bca_tensorindextype_list>;
123 const L_bca_type L_bca_returned =
124 ::TensorExpressions::evaluate<TensorIndexB, TensorIndexC, TensorIndexA>(
125 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
126 L_bca_type L_bca_filled{};
127 ::TensorExpressions::evaluate<TensorIndexB, TensorIndexC, TensorIndexA>(
129 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
132 using L_cab_symmetry =
133 Symmetry<rhs_symmetry_element_c, rhs_symmetry_element_a,
134 rhs_symmetry_element_b>;
135 using L_cab_tensorindextype_list =
136 tmpl::list<rhs_tensorindextype_c, rhs_tensorindextype_a,
137 rhs_tensorindextype_b>;
139 Tensor<DataType, L_cab_symmetry, L_cab_tensorindextype_list>;
140 const L_cab_type L_cab_returned =
141 ::TensorExpressions::evaluate<TensorIndexC, TensorIndexA, TensorIndexB>(
142 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
143 L_cab_type L_cab_filled{};
144 ::TensorExpressions::evaluate<TensorIndexC, TensorIndexA, TensorIndexB>(
146 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
149 using L_cba_symmetry =
150 Symmetry<rhs_symmetry_element_c, rhs_symmetry_element_b,
151 rhs_symmetry_element_a>;
152 using L_cba_tensorindextype_list =
153 tmpl::list<rhs_tensorindextype_c, rhs_tensorindextype_b,
154 rhs_tensorindextype_a>;
156 Tensor<DataType, L_cba_symmetry, L_cba_tensorindextype_list>;
157 const L_cba_type L_cba_returned =
158 ::TensorExpressions::evaluate<TensorIndexC, TensorIndexB, TensorIndexA>(
159 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
160 L_cba_type L_cba_filled{};
161 ::TensorExpressions::evaluate<TensorIndexC, TensorIndexB, TensorIndexA>(
163 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
165 const size_t dim_a = tmpl::at_c<RhsTensorIndexTypeList, 0>::dim;
166 const size_t dim_b = tmpl::at_c<RhsTensorIndexTypeList, 1>::dim;
167 const size_t dim_c = tmpl::at_c<RhsTensorIndexTypeList, 2>::dim;
169 for (
size_t i = 0; i < dim_a; ++i) {
170 for (
size_t j = 0; j < dim_b; ++j) {
171 for (
size_t k = 0; k < dim_c; ++k) {
173 CHECK(L_abc_returned.get(i, j, k) == R_abc.get(i, j, k));
174 CHECK(L_abc_filled.get(i, j, k) == R_abc.get(i, j, k));
176 CHECK(L_acb_returned.get(i, k, j) == R_abc.get(i, j, k));
177 CHECK(L_acb_filled.get(i, k, j) == R_abc.get(i, j, k));
179 CHECK(L_bac_returned.get(j, i, k) == R_abc.get(i, j, k));
180 CHECK(L_bac_filled.get(j, i, k) == R_abc.get(i, j, k));
182 CHECK(L_bca_returned.get(j, k, i) == R_abc.get(i, j, k));
183 CHECK(L_bca_filled.get(j, k, i) == R_abc.get(i, j, k));
185 CHECK(L_cab_returned.get(k, i, j) == R_abc.get(i, j, k));
186 CHECK(L_cab_filled.get(k, i, j) == R_abc.get(i, j, k));
188 CHECK(L_cba_returned.get(k, j, i) == R_abc.get(i, j, k));
189 CHECK(L_cba_filled.get(k, j, i) == R_abc.get(i, j, k));
195 if constexpr (not std::is_same_v<DataType, double>) {
197 Variables<tmpl::list<::Tags::TempTensor<1, L_abc_type>>> L_abc_var{
199 L_abc_type& L_abc_temp = get<::Tags::TempTensor<1, L_abc_type>>(L_abc_var);
200 ::TensorExpressions::evaluate<TensorIndexA, TensorIndexB, TensorIndexC>(
202 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
205 Variables<tmpl::list<::Tags::TempTensor<1, L_acb_type>>> L_acb_var{
207 L_acb_type& L_acb_temp = get<::Tags::TempTensor<1, L_acb_type>>(L_acb_var);
208 ::TensorExpressions::evaluate<TensorIndexA, TensorIndexC, TensorIndexB>(
210 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
213 Variables<tmpl::list<::Tags::TempTensor<1, L_bac_type>>> L_bac_var{
215 L_bac_type& L_bac_temp = get<::Tags::TempTensor<1, L_bac_type>>(L_bac_var);
216 ::TensorExpressions::evaluate<TensorIndexB, TensorIndexA, TensorIndexC>(
218 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
221 Variables<tmpl::list<::Tags::TempTensor<1, L_bca_type>>> L_bca_var{
223 L_bca_type& L_bca_temp = get<::Tags::TempTensor<1, L_bca_type>>(L_bca_var);
224 ::TensorExpressions::evaluate<TensorIndexB, TensorIndexC, TensorIndexA>(
226 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
229 Variables<tmpl::list<::Tags::TempTensor<1, L_cab_type>>> L_cab_var{
231 L_cab_type& L_cab_temp = get<::Tags::TempTensor<1, L_cab_type>>(L_cab_var);
232 ::TensorExpressions::evaluate<TensorIndexC, TensorIndexA, TensorIndexB>(
234 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
237 Variables<tmpl::list<::Tags::TempTensor<1, L_cba_type>>> L_cba_var{
239 L_cba_type& L_cba_temp = get<::Tags::TempTensor<1, L_cba_type>>(L_cba_var);
240 ::TensorExpressions::evaluate<TensorIndexC, TensorIndexB, TensorIndexA>(
242 R_abc(TensorIndexA, TensorIndexB, TensorIndexC));
244 for (
size_t i = 0; i < dim_a; ++i) {
245 for (
size_t j = 0; j < dim_b; ++j) {
246 for (
size_t k = 0; k < dim_c; ++k) {
248 CHECK(L_abc_temp.get(i, j, k) == R_abc.get(i, j, k));
250 CHECK(L_acb_temp.get(i, k, j) == R_abc.get(i, j, k));
252 CHECK(L_bac_temp.get(j, i, k) == R_abc.get(i, j, k));
254 CHECK(L_bca_temp.get(j, k, i) == R_abc.get(i, j, k));
256 CHECK(L_cab_temp.get(k, i, j) == R_abc.get(i, j, k));
258 CHECK(L_cba_temp.get(k, j, i) == R_abc.get(i, j, k));
308 template <
typename DataType,
309 template <
size_t, UpLo,
typename>
class TensorIndexTypeA,
310 template <
size_t, UpLo,
typename>
class TensorIndexTypeB,
311 template <
size_t, UpLo,
typename>
class TensorIndexTypeC,
312 UpLo ValenceA,
UpLo ValenceB,
UpLo ValenceC,
auto& TensorIndexA,
313 auto& TensorIndexB,
auto& TensorIndexC>
315 #define DIM_A(data) BOOST_PP_TUPLE_ELEM(0, data)
316 #define DIM_B(data) BOOST_PP_TUPLE_ELEM(1, data)
317 #define DIM_C(data) BOOST_PP_TUPLE_ELEM(2, data)
318 #define FRAME(data) BOOST_PP_TUPLE_ELEM(3, data)
320 #define CALL_TEST_EVALUATE_RANK_3_IMPL(_, data) \
321 test_evaluate_rank_3_impl< \
322 DataType, Symmetry<3, 2, 1>, \
323 index_list<TensorIndexTypeA<DIM_A(data), ValenceA, FRAME(data)>, \
324 TensorIndexTypeB<DIM_B(data), ValenceB, FRAME(data)>, \
325 TensorIndexTypeC<DIM_C(data), ValenceC, FRAME(data)>>, \
326 TensorIndexA, TensorIndexB, TensorIndexC>();
331 #undef CALL_TEST_EVALUATE_RANK_3_IMPL
340 template <
typename DataType,
341 template <
size_t, UpLo,
typename>
class TensorIndexTypeAB,
342 template <
size_t, UpLo,
typename>
class TensorIndexTypeC,
343 UpLo ValenceAB,
UpLo ValenceC,
auto& TensorIndexA,
auto& TensorIndexB,
346 #define DIM_AB(data) BOOST_PP_TUPLE_ELEM(0, data)
347 #define DIM_C(data) BOOST_PP_TUPLE_ELEM(1, data)
348 #define FRAME(data) BOOST_PP_TUPLE_ELEM(2, data)
350 #define CALL_TEST_EVALUATE_RANK_3_IMPL(_, data) \
351 test_evaluate_rank_3_impl< \
352 DataType, Symmetry<2, 2, 1>, \
353 index_list<TensorIndexTypeAB<DIM_AB(data), ValenceAB, FRAME(data)>, \
354 TensorIndexTypeAB<DIM_AB(data), ValenceAB, FRAME(data)>, \
355 TensorIndexTypeC<DIM_C(data), ValenceC, FRAME(data)>>, \
356 TensorIndexA, TensorIndexB, TensorIndexC>();
361 #undef CALL_TEST_EVALUATE_RANK_3_IMPL
369 template <
typename DataType,
370 template <
size_t, UpLo,
typename>
class TensorIndexTypeAC,
371 template <
size_t, UpLo,
typename>
class TensorIndexTypeB,
372 UpLo ValenceAC,
UpLo ValenceB,
auto& TensorIndexA,
auto& TensorIndexB,
375 #define DIM_AC(data) BOOST_PP_TUPLE_ELEM(0, data)
376 #define DIM_B(data) BOOST_PP_TUPLE_ELEM(1, data)
377 #define FRAME(data) BOOST_PP_TUPLE_ELEM(2, data)
379 #define CALL_TEST_EVALUATE_RANK_3_IMPL(_, data) \
380 test_evaluate_rank_3_impl< \
381 DataType, Symmetry<2, 1, 2>, \
382 index_list<TensorIndexTypeAC<DIM_AC(data), ValenceAC, FRAME(data)>, \
383 TensorIndexTypeB<DIM_B(data), ValenceB, FRAME(data)>, \
384 TensorIndexTypeAC<DIM_AC(data), ValenceAC, FRAME(data)>>, \
385 TensorIndexA, TensorIndexB, TensorIndexC>();
390 #undef CALL_TEST_EVALUATE_RANK_3_IMPL
399 typename DataType,
template <
size_t, UpLo,
typename>
class TensorIndexTypeA,
400 template <
size_t, UpLo,
typename>
class TensorIndexTypeBC,
UpLo ValenceA,
401 UpLo ValenceBC,
auto& TensorIndexA,
auto& TensorIndexB,
auto& TensorIndexC>
403 #define DIM_A(data) BOOST_PP_TUPLE_ELEM(0, data)
404 #define DIM_BC(data) BOOST_PP_TUPLE_ELEM(1, data)
405 #define FRAME(data) BOOST_PP_TUPLE_ELEM(2, data)
407 #define CALL_TEST_EVALUATE_RANK_3_IMPL(_, data) \
408 test_evaluate_rank_3_impl< \
409 DataType, Symmetry<2, 1, 1>, \
410 index_list<TensorIndexTypeA<DIM_A(data), ValenceA, FRAME(data)>, \
411 TensorIndexTypeBC<DIM_BC(data), ValenceBC, FRAME(data)>, \
412 TensorIndexTypeBC<DIM_BC(data), ValenceBC, FRAME(data)>>, \
413 TensorIndexA, TensorIndexB, TensorIndexC>();
418 #undef CALL_TEST_EVALUATE_RANK_3_IMPL
426 template <
typename DataType,
427 template <
size_t, UpLo,
typename>
class TensorIndexType,
UpLo Valence,
428 auto& TensorIndexA,
auto& TensorIndexB,
auto& TensorIndexC>
430 #define DIM(data) BOOST_PP_TUPLE_ELEM(0, data)
431 #define FRAME(data) BOOST_PP_TUPLE_ELEM(1, data)
433 #define CALL_TEST_EVALUATE_RANK_3_IMPL(_, data) \
434 test_evaluate_rank_3_impl< \
435 DataType, Symmetry<1, 1, 1>, \
436 index_list<TensorIndexType<DIM(data), Valence, FRAME(data)>, \
437 TensorIndexType<DIM(data), Valence, FRAME(data)>, \
438 TensorIndexType<DIM(data), Valence, FRAME(data)>>, \
439 TensorIndexA, TensorIndexB, TensorIndexC>();
444 #undef CALL_TEST_EVALUATE_RANK_3_IMPL