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::device_for_each(prod_tensor.domain(), [&](ddc::DiscreteElement<ProdDDim...> mem_elem) {
140 auto elem = prod_tensor.canonical_natural_element(mem_elem);
141 prod_tensor.mem(mem_elem) = ddc::device_transform_reduce(
144 ddc::reducer::sum<ElementType>(),
145 [&](ddc::DiscreteElement<ContractDDim...> contract_elem) {
146 return tensor1.get(tensor1.access_element(
147 ddc::DiscreteElement<HeadDDim1..., ContractDDim...>(
148 ddc::select<HeadDDim1...>(elem),
149 contract_accessor.access_element(contract_elem))))
150 * tensor2.get(tensor2.access_element(
151 ddc::DiscreteElement<ContractDDim..., TailDDim2...>(
153 ddc::select<TailDDim2...>(elem))));
167 class LayoutStridedPolicy,
170 ((!TensorNatIndex<ProdDDim> || ...) || (!TensorNatIndex<Index2> || ...)
171 || (!TensorNatIndex<Index1> || ...))
172#if defined BUILD_YOUNG_TABLEAU
173 && (!misc::Specialization<ProdDDim, TensorYoungTableauIndex> && ...)
174 && (!misc::Specialization<Index1, TensorYoungTableauIndex> && ...)
175 && (!misc::Specialization<Index2, TensorYoungTableauIndex> && ...)
178Tensor<ElementType, ddc::DiscreteDomain<ProdDDim...>, LayoutStridedPolicy, MemorySpace>
179 KOKKOS_FUNCTION tensor_prod(
181 ddc::DiscreteDomain<ProdDDim...>,
183 MemorySpace> prod_tensor,
185 ddc::DiscreteDomain<Index1...>,
187 MemorySpace> tensor1,
189 ddc::DiscreteDomain<Index2...>,
191 MemorySpace> tensor2)
194 ddc::detail::TypeSeq<ProdDDim...>,
195 ddc::detail::TypeSeq<Index1...>,
196 ddc::detail::TypeSeq<Index2...>>();
198 detail::TensorProdAnyAnyAny<
202 ddc::type_seq_remove_t<
204 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>,
206 ddc::cartesian_prod_t<natural_domain_t<Index2>...>>>>,
207 ddc::type_seq_remove_t<
209 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<Index1>...>>>,
211 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>>,
212 ddc::type_seq_remove_t<
214 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>,
216 ddc::cartesian_prod_t<natural_domain_t<Index1>...>>>>>::
223#if defined BUILD_YOUNG_TABLEAU
227template <
class Index1,
class HeadDDim1TypeSeq,
class ContractDDimTypeSeq,
class TailDDim2TypeSeq>
228struct TensorProdNatYoungNat;
230template <
class Index1,
class... HeadDDim1,
class... ContractDDim,
class... TailDDim2>
231struct TensorProdNatYoungNat<
233 ddc::detail::TypeSeq<HeadDDim1...>,
234 ddc::detail::TypeSeq<ContractDDim...>,
235 ddc::detail::TypeSeq<TailDDim2...>>
237 template <
class ElementType,
class LayoutStr
idedPolicy,
class MemorySpace>
240 ddc::DiscreteDomain<HeadDDim1..., TailDDim2...>,
243 run(Tensor<ElementType,
244 ddc::DiscreteDomain<HeadDDim1..., TailDDim2...>,
245 Kokkos::layout_right,
246 Kokkos::DefaultHostExecutionSpace::memory_space> prod_tensor,
247 Tensor<ElementType, ddc::DiscreteDomain<Index1>, LayoutStridedPolicy, MemorySpace> tensor1,
249 ddc::DiscreteDomain<ContractDDim..., TailDDim2...>,
251 MemorySpace> tensor2)
257 ddc::Chunk uncompressed_tensor1_alloc(
258 Index1::subindices_domain(),
259 ddc::HostAllocator<double>());
260 tensor::Tensor uncompressed_tensor1(uncompressed_tensor1_alloc);
262 tensor::uncompress(uncompressed_tensor1, tensor1);
264 return tensor_prod(prod_tensor, uncompressed_tensor1, tensor2);
271 TensorNatIndex... ProdDDim,
272 misc::Specialization<TensorYoungTableauIndex> Index1,
273 TensorNatIndex... DDim2,
275 class LayoutStridedPolicy,
278 ddc::DiscreteDomain<ProdDDim...>,
279 Kokkos::layout_right,
280 Kokkos::DefaultHostExecutionSpace::memory_space>
283 ddc::DiscreteDomain<ProdDDim...>,
284 Kokkos::layout_right,
285 Kokkos::DefaultHostExecutionSpace::memory_space> prod_tensor,
286 Tensor<ElementType, ddc::DiscreteDomain<Index1>, LayoutStridedPolicy, MemorySpace> tensor1,
287 Tensor<ElementType, ddc::DiscreteDomain<DDim2...>, LayoutStridedPolicy, MemorySpace>
297 return detail::TensorProdNatYoungNat<
299 ddc::type_seq_remove_t<
300 ddc::detail::TypeSeq<ProdDDim...>,
301 ddc::detail::TypeSeq<DDim2...>>,
302 ddc::type_seq_remove_t<
303 ddc::to_type_seq_t<typename Index1::subindices_domain_t>,
304 ddc::detail::TypeSeq<ProdDDim...>>,
305 ddc::type_seq_remove_t<
306 ddc::detail::TypeSeq<ProdDDim...>,
307 ddc::to_type_seq_t<typename Index1::subindices_domain_t>>>::
308 run(prod_tensor, tensor1, tensor2);
317 class HeadDDim1TypeSeq,
318 class ContractDDimTypeSeq,
319 class TailDDim2TypeSeq>
320struct TensorProdNatYoungYoung;
322template <
class Index1,
class Index2,
class... HeadDDim1,
class... ContractDDim,
class... TailDDim2>
323struct TensorProdNatYoungYoung<
326 ddc::detail::TypeSeq<HeadDDim1...>,
327 ddc::detail::TypeSeq<ContractDDim...>,
328 ddc::detail::TypeSeq<TailDDim2...>>
330 template <
class ElementType,
class LayoutStr
idedPolicy,
class MemorySpace>
333 ddc::DiscreteDomain<HeadDDim1..., TailDDim2...>,
336 run(Tensor<ElementType,
337 ddc::DiscreteDomain<HeadDDim1..., TailDDim2...>,
338 Kokkos::layout_right,
339 Kokkos::DefaultHostExecutionSpace::memory_space> prod_tensor,
340 Tensor<ElementType, ddc::DiscreteDomain<Index1>, LayoutStridedPolicy, MemorySpace> tensor1,
341 Tensor<ElementType, ddc::DiscreteDomain<Index2>, LayoutStridedPolicy, MemorySpace> tensor2)
347 ddc::Chunk uncompressed_tensor1_alloc(
348 Index1::subindices_domain(),
349 ddc::HostAllocator<double>());
350 tensor::Tensor uncompressed_tensor1(uncompressed_tensor1_alloc);
352 ddc::Chunk uncompressed_tensor2_alloc(
353 Index2::subindices_domain(),
354 ddc::HostAllocator<double>());
355 tensor::Tensor uncompressed_tensor2(uncompressed_tensor2_alloc);
357 tensor::uncompress(uncompressed_tensor1, tensor1);
358 tensor::uncompress(uncompressed_tensor2, tensor2);
360 return tensor_prod(prod_tensor, uncompressed_tensor1, uncompressed_tensor2);
367 TensorNatIndex... ProdDDim,
368 misc::Specialization<TensorYoungTableauIndex> Index1,
369 misc::Specialization<TensorYoungTableauIndex> Index2,
371 class LayoutStridedPolicy,
374 ddc::DiscreteDomain<ProdDDim...>,
375 Kokkos::layout_right,
376 Kokkos::DefaultHostExecutionSpace::memory_space>
379 ddc::DiscreteDomain<ProdDDim...>,
380 Kokkos::layout_right,
381 Kokkos::DefaultHostExecutionSpace::memory_space> prod_tensor,
382 Tensor<ElementType, ddc::DiscreteDomain<Index1>, LayoutStridedPolicy, MemorySpace> tensor1,
383 Tensor<ElementType, ddc::DiscreteDomain<Index2>, LayoutStridedPolicy, MemorySpace> tensor2)
386 ddc::detail::TypeSeq<ProdDDim...>,
387 ddc::detail::TypeSeq<Index1>,
388 ddc::detail::TypeSeq<Index2>>();
390 detail::TensorProdNatYoungYoung<
391 uncharacterize_t<Index1>,
392 uncharacterize_t<Index2>,
393 ddc::type_seq_remove_t<
395 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>,
397 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<Index2>>>>>,
398 ddc::type_seq_remove_t<
400 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<Index1>>>>,
402 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>>,
403 ddc::type_seq_remove_t<
405 ddc::cartesian_prod_t<natural_domain_t<ProdDDim>...>>>,
407 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<Index1>>>>>>::
422 class HeadDDim1TypeSeq,
423 class ContractDDimTypeSeq,
424 class TailDDim2TypeSeq>
425struct TensorProdYoungAnyAny;
432 class... ContractDDim,
434struct TensorProdYoungAnyAny<
435 ddc::detail::TypeSeq<ProdDDim...>,
436 ddc::detail::TypeSeq<Index1...>,
437 ddc::detail::TypeSeq<Index2...>,
438 ddc::detail::TypeSeq<HeadDDim1...>,
439 ddc::detail::TypeSeq<ContractDDim...>,
440 ddc::detail::TypeSeq<TailDDim2...>>
442 template <
class ElementType,
class LayoutStr
idedPolicy,
class MemorySpace>
443 static Tensor<ElementType, ddc::DiscreteDomain<ProdDDim...>, LayoutStridedPolicy, MemorySpace>
444 run(Tensor<ElementType,
445 ddc::DiscreteDomain<ProdDDim...>,
446 Kokkos::layout_right,
447 Kokkos::DefaultHostExecutionSpace::memory_space> prod_tensor,
448 Tensor<ElementType, ddc::DiscreteDomain<Index1...>, LayoutStridedPolicy, MemorySpace>
450 Tensor<ElementType, ddc::DiscreteDomain<Index2...>, LayoutStridedPolicy, MemorySpace>
457 ddc::Chunk uncompressed_prod_alloc(
458 ddc::DiscreteDomain(ProdDDim::subindices_domain()...),
459 ddc::HostAllocator<double>());
460 tensor::Tensor uncompressed_prod(uncompressed_prod_alloc);
462 tensor::TensorAccessor<ContractDDim...> contract_accessor;
463 ddc::DiscreteDomain<ContractDDim...> contract_dom = contract_accessor.natural_domain();
466 uncompressed_prod.domain(),
467 [&](ddc::cartesian_prod_t<
468 typename ProdDDim::subindices_domain_t...>::discrete_element_type elem) {
469 uncompressed_prod(elem) = ddc::transform_reduce(
472 ddc::reducer::sum<ElementType>(),
473 [&](ddc::DiscreteElement<ContractDDim...> contract_elem) {
474 return tensor1.get(tensor1.access_element(
475 ddc::DiscreteElement<HeadDDim1..., ContractDDim...>(
476 ddc::select<HeadDDim1...>(elem),
477 contract_accessor.access_element(
479 * tensor2.get(tensor2.access_element(
480 ddc::DiscreteElement<ContractDDim..., TailDDim2...>(
482 ddc::select<TailDDim2...>(elem))));
485 tensor::compress(prod_tensor, uncompressed_prod);
493 misc::Specialization<TensorYoungTableauIndex> ProdDDim,
497 class LayoutStridedPolicy,
500 ddc::DiscreteDomain<ProdDDim>,
501 Kokkos::layout_right,
502 Kokkos::DefaultHostExecutionSpace::memory_space>
505 ddc::DiscreteDomain<ProdDDim>,
506 Kokkos::layout_right,
507 Kokkos::DefaultHostExecutionSpace::memory_space> prod_tensor,
508 Tensor<ElementType, ddc::DiscreteDomain<Index1...>, LayoutStridedPolicy, MemorySpace>
510 Tensor<ElementType, ddc::DiscreteDomain<Index2...>, LayoutStridedPolicy, MemorySpace>
514 ddc::detail::TypeSeq<ProdDDim>,
515 ddc::detail::TypeSeq<Index1...>,
516 ddc::detail::TypeSeq<Index2...>>();
518 detail::TensorProdYoungAnyAny<
519 uncharacterize_t<ddc::detail::TypeSeq<ProdDDim>>,
522 ddc::type_seq_remove_t<
524 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<ProdDDim>>>>,
526 ddc::cartesian_prod_t<natural_domain_t<Index2>...>>>>,
527 ddc::type_seq_remove_t<
529 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<Index1>...>>>,
531 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<ProdDDim>>>>>,
532 ddc::type_seq_remove_t<
534 ddc::to_type_seq_t<ddc::cartesian_prod_t<natural_domain_t<ProdDDim>>>>,
536 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.