Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
block_tensor_permute.hpp
Go to the documentation of this file.
1
7#pragma once
8
11
12#include <array>
13#include <cstddef>
14#include <tuple>
15#include <type_traits>
16#include <utility>
17
18namespace uni20
19{
20namespace detail
21{
22
23template <class Tensor, std::size_t... Axis> consteval auto is_side_preserving_permutation() -> bool
24{
25 using tensor_type = std::remove_cvref_t<Tensor>;
26 constexpr std::size_t order = tensor_type::order();
27 constexpr std::size_t domain_size = tensor_type::domain_type::size();
28 if constexpr (sizeof...(Axis) != order)
29 {
30 return false;
31 }
32 else
33 {
34 constexpr std::array<std::size_t, order> permutation{Axis...};
35 if (!is_valid_axis_permutation(permutation)) return false;
36 for (std::size_t output = 0; output < domain_size; ++output)
37 {
38 if (permutation[output] >= domain_size) return false;
39 }
40 for (std::size_t output = domain_size; output < order; ++output)
41 {
42 if (permutation[output] < domain_size) return false;
43 }
44 return true;
45 }
46}
47
48template <class Tensor, std::size_t... Axis>
49concept SidePreservingPermutation = BlockTensorView<Tensor> && is_side_preserving_permutation<Tensor, Axis...>();
50
51template <auto FactorPermutation, class Tensor, std::size_t... I>
52auto make_permuted_domain_impl(Tensor const& tensor, std::index_sequence<I...>)
53{
54 if constexpr (sizeof...(I) == 0)
55 {
56 static_cast<void>(tensor);
57 return Domain<>{};
58 }
59 else
60 {
61 auto const spaces = std::tuple_cat(tensor.domain().spaces(), tensor.codomain().spaces());
62 return domain_from_tuple(std::tuple{std::get<FactorPermutation[I]>(spaces)...});
63 }
64}
65
66template <auto FactorPermutation, class Tensor> auto make_permuted_domain(Tensor const& tensor)
67{
68 using tensor_type = std::remove_cvref_t<Tensor>;
69 return make_permuted_domain_impl<FactorPermutation>(tensor,
70 std::make_index_sequence<tensor_type::domain_type::size()>{});
71}
72
73template <auto FactorPermutation, class Tensor, std::size_t... I>
74auto make_permuted_codomain_impl(Tensor const& tensor, std::index_sequence<I...>)
75{
76 using tensor_type = std::remove_cvref_t<Tensor>;
77 constexpr std::size_t domain_size = tensor_type::domain_type::size();
78 if constexpr (sizeof...(I) == 0)
79 {
80 static_cast<void>(tensor);
81 return Codomain<>{};
82 }
83 else
84 {
85 auto const spaces = std::tuple_cat(tensor.domain().spaces(), tensor.codomain().spaces());
86 return codomain_from_tuple(std::tuple{std::get<FactorPermutation[domain_size + I]>(spaces)...});
87 }
88}
89
90template <auto FactorPermutation, class Tensor> auto make_permuted_codomain(Tensor const& tensor)
91{
92 using tensor_type = std::remove_cvref_t<Tensor>;
93 return make_permuted_codomain_impl<FactorPermutation>(tensor,
94 std::make_index_sequence<tensor_type::codomain_type::size()>{});
95}
96
97template <class SourceTensor, std::size_t... Axis>
98 requires SidePreservingPermutation<SourceTensor, Axis...>
99struct PermutationViewTraits
100{
101 using source_tensor_type = std::remove_const_t<SourceTensor>;
102 static constexpr std::array<std::size_t, source_tensor_type::order()> factor_permutation{Axis...};
103 using domain_type = decltype(make_permuted_domain<factor_permutation>(std::declval<source_tensor_type const&>()));
104 using codomain_type =
105 decltype(make_permuted_codomain<factor_permutation>(std::declval<source_tensor_type const&>()));
106 static constexpr auto key_permutation =
107 make_filtered_axis_permutation<source_tensor_type, factor_permutation, false>();
108 static constexpr auto dense_permutation =
109 make_filtered_axis_permutation<source_tensor_type, factor_permutation, true>();
110 using type = BlockTensorMappedView<SourceTensor, domain_type, codomain_type, key_permutation, dense_permutation>;
111};
112
113} // namespace detail
114
122template <class SourceTensor, std::size_t... Axis>
123 requires detail::SidePreservingPermutation<SourceTensor, Axis...>
124using BlockTensorPermutationView = typename detail::PermutationViewTraits<SourceTensor, Axis...>::type;
125
137template <std::size_t... Axis, class Tensor>
138 requires detail::SidePreservingPermutation<Tensor, Axis...>
140{
141 using traits = detail::PermutationViewTraits<Tensor, Axis...>;
142 using view_type = typename traits::type;
143 return view_type(tensor, detail::make_permuted_domain<traits::factor_permutation>(tensor),
144 detail::make_permuted_codomain<traits::factor_permutation>(tensor));
145}
146
148template <std::size_t... Axis, BorrowedBlockTensorView Tensor>
149 requires(!std::is_lvalue_reference_v<Tensor &&> && detail::SidePreservingPermutation<Tensor, Axis...>)
150auto permute(Tensor&& tensor)
151{
152 using traits = detail::PermutationViewTraits<Tensor, Axis...>;
153 using view_type = typename traits::type;
154 return view_type(tensor, detail::make_permuted_domain<traits::factor_permutation>(tensor),
155 detail::make_permuted_codomain<traits::factor_permutation>(tensor));
156}
157
158template <std::size_t... Axis, class Tensor>
159 requires(!std::is_lvalue_reference_v<Tensor &&> && detail::SidePreservingPermutation<Tensor, Axis...> &&
160 !BorrowedBlockTensorView<Tensor>)
161auto permute(Tensor&&) = delete;
162
163namespace detail
164{
165
166template <class Tensor, std::size_t... Axis>
167auto as_block_tensor_view_impl(Tensor& tensor, std::index_sequence<Axis...>) -> decltype(permute<Axis...>(tensor))
168{
169 return permute<Axis...>(tensor);
170}
171
172} // namespace detail
173
182template <class Tensor>
183 requires BlockTensorView<Tensor> && requires(Tensor& tensor) {
184 detail::as_block_tensor_view_impl(tensor, std::make_index_sequence<block_tensor_type_t<Tensor>::order()>{});
185 }
187{
188 return detail::as_block_tensor_view_impl(tensor, std::make_index_sequence<block_tensor_type_t<Tensor>::order()>{});
189}
190
191} // namespace uni20
Concepts and associated types for BlockTensor-level views.
Defines shared zero-copy BlockTensor axis-mapping machinery.
General-purpose owning tensor with immediate or deferred mdspan metadata.
Definition basic_tensor.hpp:109
Definition async/async.hpp:26
std::remove_cvref_t< Tensor > block_tensor_type_t
Cvref-stripped BlockTensor-level object type.
Definition block_tensor_concepts.hpp:22
typename detail::PermutationViewTraits< SourceTensor, Axis... >::type BlockTensorPermutationView
Zero-copy bosonic permutation of factors within each morphism side.
Definition block_tensor_permute.hpp:124
auto permute(Tensor &tensor) -> BlockTensorPermutationView< Tensor, Axis... >
Permute bosonic BlockTensor factors without moving numerical payload.
Definition block_tensor_permute.hpp:139
auto as_block_tensor_view(Tensor &tensor)
Materialize a borrowed identity view over an existing BlockTensor view.
Definition block_tensor_permute.hpp:186
Tensor(InputTensor const &) -> Tensor< tensor_element_t< InputTensor >, tensor_mdspec_t< InputTensor >::rank(), HostStorage, detail::materialized_layout_t< void, tensor_mdspec_t< InputTensor > >, DefaultAccessorFactory >
Deduce a runtime-extents host tensor that materializes a tensor view.