8#include <similie/misc/specialization.hpp>
10#include "character.hpp"
11#if defined BUILD_YOUNG_TABLEAU
12#include "young_tableau_tensor.hpp"
22struct SubindicesDomain;
24template <
template <
class...>
class T,
class... SubIndex>
25struct SubindicesDomain<T<SubIndex...>>
27 using type = ddc::DiscreteDomain<SubIndex...>;
29 static constexpr type run()
31 return ddc::DiscreteDomain<SubIndex...>(
32 ddc::DiscreteElement<SubIndex...>(ddc::DiscreteElement<SubIndex>(0)...),
33 ddc::DiscreteVector<SubIndex...>(
34 ddc::DiscreteVector<SubIndex>(SubIndex::size())...));
46 return detail::SubindicesDomain<T>::run();
52template <
class ProdDDims,
class Indices1,
class Indices2>
53struct CheckTensorsCompatibility;
55template <
class... ProdDDim,
class... Index1,
class... Index2>
56struct CheckTensorsCompatibility<
57 ddc::detail::TypeSeq<ProdDDim...>,
58 ddc::detail::TypeSeq<Index1...>,
59 ddc::detail::TypeSeq<Index2...>>
61 KOKKOS_FUNCTION
static constexpr void run()
63 static_assert(std::is_same_v<
64 ddc::type_seq_remove_t<
66 ddc::cartesian_prod_t<natural_domain_t<Index1>...>>>,
68 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>>,
69 ddc::type_seq_remove_t<
71 ddc::cartesian_prod_t<natural_domain_t<Index2>...>>>,
73 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>>>);
75 ddc::type_seq_remove_t<
77 ddc::cartesian_prod_t<natural_domain_t<Index1>...>>,
79 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>,
80 ddc::type_seq_remove_t<
82 ddc::cartesian_prod_t<natural_domain_t<Index2>...>>,
84 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>>);
90template <
class ProdDDims,
class Indices1,
class Indices2>
93 return detail::CheckTensorsCompatibility<ProdDDims, Indices1, Indices2>::run();
103 class HeadDDim1TypeSeq,
104 class ContractDDimTypeSeq,
105 class TailDDim2TypeSeq>
106struct TensorProdAnyAnyAny;
113 class... ContractDDim,
115struct TensorProdAnyAnyAny<
116 ddc::detail::TypeSeq<ProdDDim...>,
117 ddc::detail::TypeSeq<Index1...>,
118 ddc::detail::TypeSeq<Index2...>,
119 ddc::detail::TypeSeq<HeadDDim1...>,
120 ddc::detail::TypeSeq<ContractDDim...>,
121 ddc::detail::TypeSeq<TailDDim2...>>
123 template <
class ElementType,
class LayoutStr
idedPolicy,
class MemorySpace>
124 KOKKOS_FUNCTION
static Tensor<
126 ddc::DiscreteDomain<ProdDDim...>,
129 run(
Tensor<ElementType, ddc::DiscreteDomain<ProdDDim...>, LayoutStridedPolicy, MemorySpace>
131 Tensor<ElementType, ddc::DiscreteDomain<Index1...>, LayoutStridedPolicy, MemorySpace>
133 Tensor<ElementType, ddc::DiscreteDomain<Index2...>, LayoutStridedPolicy, MemorySpace>
137 ddc::DiscreteDomain<ContractDDim...> contract_dom = contract_accessor.
natural_domain();
139 ddc::annotated_for_each(
140 prod_tensor.domain(),
141 [&](ddc::DiscreteElement<ProdDDim...> mem_elem) {
142 auto elem = prod_tensor.canonical_natural_element(mem_elem);
143 prod_tensor.mem(mem_elem) = ddc::annotated_transform_reduce(
146 ddc::reducer::sum<ElementType>(),
147 [&](ddc::DiscreteElement<ContractDDim...> contract_elem) {
148 return tensor1.get(tensor1.access_element(
149 ddc::DiscreteElement<HeadDDim1..., ContractDDim...>(
150 ddc::select<HeadDDim1...>(elem),
151 contract_accessor.access_element(
153 * tensor2.get(tensor2.access_element(
154 ddc::DiscreteElement<ContractDDim..., TailDDim2...>(
156 ddc::select<TailDDim2...>(elem))));
170 class LayoutStridedPolicy,
173 ((!TensorNatIndex<ProdDDim> || ...) || (!TensorNatIndex<Index2> || ...)
174 || (!TensorNatIndex<Index1> || ...))
175#if defined BUILD_YOUNG_TABLEAU
176 && (!misc::Specialization<ProdDDim, TensorYoungTableauIndex> && ...)
177 && (!misc::Specialization<Index1, TensorYoungTableauIndex> && ...)
178 && (!misc::Specialization<Index2, TensorYoungTableauIndex> && ...)
181Tensor<ElementType, ddc::DiscreteDomain<ProdDDim...>, LayoutStridedPolicy, MemorySpace>
182 KOKKOS_FUNCTION tensor_prod(
184 ddc::DiscreteDomain<ProdDDim...>,
186 MemorySpace> prod_tensor,
188 ddc::DiscreteDomain<Index1...>,
190 MemorySpace> tensor1,
192 ddc::DiscreteDomain<Index2...>,
194 MemorySpace> tensor2)
197 ddc::detail::TypeSeq<ProdDDim...>,
198 ddc::detail::TypeSeq<Index1...>,
199 ddc::detail::TypeSeq<Index2...>>();
201 detail::TensorProdAnyAnyAny<
205 ddc::type_seq_remove_t<
207 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>,
209 ddc::cartesian_prod_t<natural_domain_t<Index2>...>>>>,
210 ddc::type_seq_remove_t<
212 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<Index1>...>>>,
214 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>>,
215 ddc::type_seq_remove_t<
217 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>,
219 ddc::cartesian_prod_t<natural_domain_t<Index1>...>>>>>::
226#if defined BUILD_YOUNG_TABLEAU
230template <
class Index1,
class HeadDDim1TypeSeq,
class ContractDDimTypeSeq,
class TailDDim2TypeSeq>
231struct TensorProdNatYoungNat;
233template <
class Index1,
class... HeadDDim1,
class... ContractDDim,
class... TailDDim2>
234struct TensorProdNatYoungNat<
236 ddc::detail::TypeSeq<HeadDDim1...>,
237 ddc::detail::TypeSeq<ContractDDim...>,
238 ddc::detail::TypeSeq<TailDDim2...>>
240 template <
class ElementType,
class LayoutStr
idedPolicy,
class MemorySpace>
243 ddc::DiscreteDomain<HeadDDim1..., TailDDim2...>,
246 run(Tensor<ElementType,
247 ddc::DiscreteDomain<HeadDDim1..., TailDDim2...>,
248 Kokkos::layout_right,
249 Kokkos::DefaultHostExecutionSpace::memory_space> prod_tensor,
250 Tensor<ElementType, ddc::DiscreteDomain<Index1>, LayoutStridedPolicy, MemorySpace> tensor1,
252 ddc::DiscreteDomain<ContractDDim..., TailDDim2...>,
254 MemorySpace> tensor2)
260 ddc::Chunk uncompressed_tensor1_alloc(
261 Index1::subindices_domain(),
262 ddc::HostAllocator<double>());
263 tensor::Tensor uncompressed_tensor1(uncompressed_tensor1_alloc);
265 tensor::uncompress(uncompressed_tensor1, tensor1);
267 return tensor_prod(prod_tensor, uncompressed_tensor1, tensor2);
274 TensorNatIndex... ProdDDim,
275 misc::Specialization<TensorYoungTableauIndex> Index1,
276 TensorNatIndex... DDim2,
278 class LayoutStridedPolicy,
281 ddc::DiscreteDomain<ProdDDim...>,
282 Kokkos::layout_right,
283 Kokkos::DefaultHostExecutionSpace::memory_space>
286 ddc::DiscreteDomain<ProdDDim...>,
287 Kokkos::layout_right,
288 Kokkos::DefaultHostExecutionSpace::memory_space> prod_tensor,
289 Tensor<ElementType, ddc::DiscreteDomain<Index1>, LayoutStridedPolicy, MemorySpace> tensor1,
290 Tensor<ElementType, ddc::DiscreteDomain<DDim2...>, LayoutStridedPolicy, MemorySpace>
300 return detail::TensorProdNatYoungNat<
302 ddc::type_seq_remove_t<
303 ddc::detail::TypeSeq<ProdDDim...>,
304 ddc::detail::TypeSeq<DDim2...>>,
305 ddc::type_seq_remove_t<
306 ddc::to_type_seq_t<typename Index1::subindices_domain_t>,
307 ddc::detail::TypeSeq<ProdDDim...>>,
308 ddc::type_seq_remove_t<
309 ddc::detail::TypeSeq<ProdDDim...>,
310 ddc::to_type_seq_t<typename Index1::subindices_domain_t>>>::
311 run(prod_tensor, tensor1, tensor2);
320 class HeadDDim1TypeSeq,
321 class ContractDDimTypeSeq,
322 class TailDDim2TypeSeq>
323struct TensorProdNatYoungYoung;
325template <
class Index1,
class Index2,
class... HeadDDim1,
class... ContractDDim,
class... TailDDim2>
326struct TensorProdNatYoungYoung<
329 ddc::detail::TypeSeq<HeadDDim1...>,
330 ddc::detail::TypeSeq<ContractDDim...>,
331 ddc::detail::TypeSeq<TailDDim2...>>
333 template <
class ElementType,
class LayoutStr
idedPolicy,
class MemorySpace>
336 ddc::DiscreteDomain<HeadDDim1..., TailDDim2...>,
339 run(Tensor<ElementType,
340 ddc::DiscreteDomain<HeadDDim1..., TailDDim2...>,
341 Kokkos::layout_right,
342 Kokkos::DefaultHostExecutionSpace::memory_space> prod_tensor,
343 Tensor<ElementType, ddc::DiscreteDomain<Index1>, LayoutStridedPolicy, MemorySpace> tensor1,
344 Tensor<ElementType, ddc::DiscreteDomain<Index2>, LayoutStridedPolicy, MemorySpace> tensor2)
350 ddc::Chunk uncompressed_tensor1_alloc(
351 Index1::subindices_domain(),
352 ddc::HostAllocator<double>());
353 tensor::Tensor uncompressed_tensor1(uncompressed_tensor1_alloc);
355 ddc::Chunk uncompressed_tensor2_alloc(
356 Index2::subindices_domain(),
357 ddc::HostAllocator<double>());
358 tensor::Tensor uncompressed_tensor2(uncompressed_tensor2_alloc);
360 tensor::uncompress(uncompressed_tensor1, tensor1);
361 tensor::uncompress(uncompressed_tensor2, tensor2);
363 return tensor_prod(prod_tensor, uncompressed_tensor1, uncompressed_tensor2);
370 TensorNatIndex... ProdDDim,
371 misc::Specialization<TensorYoungTableauIndex> Index1,
372 misc::Specialization<TensorYoungTableauIndex> Index2,
374 class LayoutStridedPolicy,
377 ddc::DiscreteDomain<ProdDDim...>,
378 Kokkos::layout_right,
379 Kokkos::DefaultHostExecutionSpace::memory_space>
382 ddc::DiscreteDomain<ProdDDim...>,
383 Kokkos::layout_right,
384 Kokkos::DefaultHostExecutionSpace::memory_space> prod_tensor,
385 Tensor<ElementType, ddc::DiscreteDomain<Index1>, LayoutStridedPolicy, MemorySpace> tensor1,
386 Tensor<ElementType, ddc::DiscreteDomain<Index2>, LayoutStridedPolicy, MemorySpace> tensor2)
389 ddc::detail::TypeSeq<ProdDDim...>,
390 ddc::detail::TypeSeq<Index1>,
391 ddc::detail::TypeSeq<Index2>>();
393 detail::TensorProdNatYoungYoung<
394 uncharacterize_t<Index1>,
395 uncharacterize_t<Index2>,
396 ddc::type_seq_remove_t<
398 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>,
400 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<Index2>>>>>,
401 ddc::type_seq_remove_t<
403 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<Index1>>>>,
405 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>>,
406 ddc::type_seq_remove_t<
408 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>,
410 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<Index1>>>>>>::
425 class HeadDDim1TypeSeq,
426 class ContractDDimTypeSeq,
427 class TailDDim2TypeSeq>
428struct TensorProdYoungAnyAny;
435 class... ContractDDim,
437struct TensorProdYoungAnyAny<
438 ddc::detail::TypeSeq<ProdDDim...>,
439 ddc::detail::TypeSeq<Index1...>,
440 ddc::detail::TypeSeq<Index2...>,
441 ddc::detail::TypeSeq<HeadDDim1...>,
442 ddc::detail::TypeSeq<ContractDDim...>,
443 ddc::detail::TypeSeq<TailDDim2...>>
445 template <
class ElementType,
class LayoutStr
idedPolicy,
class MemorySpace>
446 static Tensor<ElementType, ddc::DiscreteDomain<ProdDDim...>, LayoutStridedPolicy, MemorySpace>
447 run(Tensor<ElementType,
448 ddc::DiscreteDomain<ProdDDim...>,
449 Kokkos::layout_right,
450 Kokkos::DefaultHostExecutionSpace::memory_space> prod_tensor,
451 Tensor<ElementType, ddc::DiscreteDomain<Index1...>, LayoutStridedPolicy, MemorySpace>
453 Tensor<ElementType, ddc::DiscreteDomain<Index2...>, LayoutStridedPolicy, MemorySpace>
460 ddc::Chunk uncompressed_prod_alloc(
461 ddc::DiscreteDomain(ProdDDim::subindices_domain()...),
462 ddc::HostAllocator<double>());
463 tensor::Tensor uncompressed_prod(uncompressed_prod_alloc);
465 tensor::TensorAccessor<ContractDDim...> contract_accessor;
466 ddc::DiscreteDomain<ContractDDim...> contract_dom = contract_accessor.natural_domain();
469 uncompressed_prod.domain(),
470 [&](ddc::cartesian_prod_t<
471 typename ProdDDim::subindices_domain_t...>::discrete_element_type elem) {
472 uncompressed_prod(elem) = ddc::transform_reduce(
475 ddc::reducer::sum<ElementType>(),
476 [&](ddc::DiscreteElement<ContractDDim...> contract_elem) {
477 return tensor1.get(tensor1.access_element(
478 ddc::DiscreteElement<HeadDDim1..., ContractDDim...>(
479 ddc::select<HeadDDim1...>(elem),
480 contract_accessor.access_element(
482 * tensor2.get(tensor2.access_element(
483 ddc::DiscreteElement<ContractDDim..., TailDDim2...>(
485 ddc::select<TailDDim2...>(elem))));
488 tensor::compress(prod_tensor, uncompressed_prod);
496 misc::Specialization<TensorYoungTableauIndex> ProdDDim,
500 class LayoutStridedPolicy,
503 ddc::DiscreteDomain<ProdDDim>,
504 Kokkos::layout_right,
505 Kokkos::DefaultHostExecutionSpace::memory_space>
508 ddc::DiscreteDomain<ProdDDim>,
509 Kokkos::layout_right,
510 Kokkos::DefaultHostExecutionSpace::memory_space> prod_tensor,
511 Tensor<ElementType, ddc::DiscreteDomain<Index1...>, LayoutStridedPolicy, MemorySpace>
513 Tensor<ElementType, ddc::DiscreteDomain<Index2...>, LayoutStridedPolicy, MemorySpace>
517 ddc::detail::TypeSeq<ProdDDim>,
518 ddc::detail::TypeSeq<Index1...>,
519 ddc::detail::TypeSeq<Index2...>>();
521 detail::TensorProdYoungAnyAny<
522 uncharacterize_t<ddc::detail::TypeSeq<ProdDDim>>,
525 ddc::type_seq_remove_t<
527 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<ProdDDim>>>>,
529 ddc::cartesian_prod_t<natural_domain_t<Index2>...>>>>,
530 ddc::type_seq_remove_t<
532 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<Index1>...>>>,
534 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<ProdDDim>>>>>,
535 ddc::type_seq_remove_t<
537 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<ProdDDim>>>>,
539 ddc::cartesian_prod_t<natural_domain_t<Index1>...>>>>>::
static constexpr natural_domain_t natural_domain()
sil::tensor::Tensor< double, ddc::DiscreteDomain< TailTensorIndex... >, Kokkos::layout_right, Kokkos::DefaultHostExecutionSpace::memory_space > tensor_prod(sil::tensor::Tensor< double, ddc::DiscreteDomain< TailTensorIndex... >, Kokkos::layout_right, Kokkos::DefaultHostExecutionSpace::memory_space > prod, sil::tensor::Tensor< double, ddc::DiscreteDomain< HeadTensorIndex >, Kokkos::layout_right, Kokkos::DefaultHostExecutionSpace::memory_space > dense, Csr< N, HeadTensorIndex, TailTensorIndex... > csr)
constexpr void check_tensors_compatibility()
Tensor(ddc::Chunk< ElementType, SupportType, Allocator >) -> Tensor< ElementType, SupportType, Kokkos::layout_right, typename Allocator::memory_space >
constexpr uncharacterize_tensor_t< TensorType > uncharacterize_tensor(TensorType tensor)
constexpr bool are_different_characters_v
detail::SubindicesDomain< T >::type subindices_domain_t
detail::Uncharacterize< Index >::type uncharacterize_t
The top-level namespace of SimiLie.