Uni20
Asynchronous tensor and runtime library.
Loading...
Searching...
No Matches
environment.hpp
Go to the documentation of this file.
1
7#pragma once
8
19
20#include <algorithm>
21#include <array>
22#include <concepts>
23#include <cstddef>
24#include <numeric>
25#include <ranges>
26#include <stdexcept>
27#include <type_traits>
28#include <utility>
29#include <vector>
30
32{
33namespace detail
34{
35
36template <class Tensor, std::size_t Index>
37using environment_domain_space_t = typename block_tensor_domain_t<Tensor>::template space_type<Index>;
38
39template <class Tensor, std::size_t Index>
40using environment_codomain_space_t = typename block_tensor_codomain_t<Tensor>::template space_type<Index>;
41
42template <class Space>
43concept EnvironmentBondSpace =
44 BlockTensorSpace<Space> && BlockTensorSpaceTraits<std::remove_cvref_t<Space>>::has_block_coordinate &&
45 BlockTensorSpaceTraits<std::remove_cvref_t<Space>>::has_dense_axis;
46
47template <class Space>
48concept EnvironmentDiscreteSpace =
49 BlockTensorSpace<Space> && BlockTensorSpaceTraits<std::remove_cvref_t<Space>>::has_block_coordinate &&
50 !BlockTensorSpaceTraits<std::remove_cvref_t<Space>>::has_dense_axis;
51
52template <class Tensor>
53concept ImmediateHostBlockTensorView =
54 ImmediateBlockTensorView<Tensor> &&
55 HostAccessibleMdspan<immediate_tensor_mdspan_t<block_tensor_const_block_t<Tensor>>>;
56
57template <class Storage, class Value>
58using environment_storage_block_t = typename Storage::template storage_t<Value, 3, 2>::mutable_block_type;
59
60template <class Storage, class Value>
61concept EnvironmentStorageFor =
62 SparseBlockStorage<Storage> && !DiagonalBlockStorage<Storage> && LocalBlockStorageFor<Storage, Value, 3, 2> &&
63 !AsyncLocalBlockStorageFor<Storage, Value, 3, 2>;
64
65template <class Result>
66auto make_identity_environment_keys(BlockSpace const& bond,
67 std::size_t auxiliary_index) -> std::vector<typename Result::key_type>
68{
69 std::vector<typename Result::key_type> keys;
70 keys.reserve(bond.size());
71 for (std::size_t sector = 0; sector < bond.size(); ++sector)
72 keys.push_back(typename Result::key_type{{sector, auxiliary_index, sector}});
73 return keys;
74}
75
76template <class Result> void initialize_identity_environment(Result& result)
77{
78 using value_type = typename Result::value_type;
79 for (std::size_t ordinal = 0; ordinal < result.stored_block_count(); ++ordinal)
80 {
81 auto block = result.block_by_ordinal(ordinal);
82 ColumnMajorTensor<value_type, 2> identity(uninitialized, block.extent(0), block.extent(1));
83 auto identity_span = identity.mdspan();
84 for (index_type column = 0; column < identity.extent(1); ++column)
85 {
86 for (index_type row = 0; row < identity.extent(0); ++row)
87 identity_span[row, column] = row == column ? value_type{1} : value_type{};
88 }
89 uni20::copy(block, identity);
90 }
91}
92
93template <class Tensor>
94concept EnvironmentMatrixView =
95 BlockTensorView<Tensor> && (block_tensor_domain_t<Tensor>::size() == 2) &&
96 (block_tensor_codomain_t<Tensor>::size() == 1) && (block_tensor_type_t<Tensor>::key_coordinate_count() == 3) &&
97 (block_tensor_type_t<Tensor>::dense_block_order() == 2) &&
98 EnvironmentBondSpace<environment_domain_space_t<Tensor, 0>> &&
99 EnvironmentDiscreteSpace<environment_domain_space_t<Tensor, 1>> &&
100 EnvironmentBondSpace<environment_codomain_space_t<Tensor, 0>>;
101
102template <class Tensor>
103concept EnvironmentMpoView =
104 ImmediateHostBlockTensorView<Tensor> && (block_tensor_domain_t<Tensor>::size() == 2) &&
105 (block_tensor_codomain_t<Tensor>::size() == 2) && (block_tensor_type_t<Tensor>::key_coordinate_count() == 4) &&
106 (block_tensor_type_t<Tensor>::dense_block_order() == 0) &&
107 EnvironmentDiscreteSpace<environment_domain_space_t<Tensor, 0>> &&
108 EnvironmentDiscreteSpace<environment_domain_space_t<Tensor, 1>> &&
109 EnvironmentDiscreteSpace<environment_codomain_space_t<Tensor, 0>> &&
110 EnvironmentDiscreteSpace<environment_codomain_space_t<Tensor, 1>>;
111
112template <class Environment, class BraSite, class Mpo, class KetSite>
113concept CompatibleEnvironmentUpdateScalars =
114 std::same_as<block_tensor_value_t<Environment>, block_tensor_value_t<BraSite>> &&
115 std::same_as<block_tensor_value_t<Environment>, block_tensor_value_t<Mpo>> &&
116 std::same_as<block_tensor_value_t<Environment>, block_tensor_value_t<KetSite>>;
117
118template <class Environment, class BraSite, class Mpo, class KetSite>
119concept CompatibleLeftEnvironmentUpdateSpaces =
120 std::same_as<environment_domain_space_t<Environment, 0>, environment_domain_space_t<BraSite, 0>> &&
121 std::same_as<environment_domain_space_t<Environment, 1>, environment_domain_space_t<Mpo, 0>> &&
122 std::same_as<environment_codomain_space_t<Environment, 0>, environment_domain_space_t<KetSite, 0>> &&
123 std::same_as<environment_domain_space_t<BraSite, 1>, environment_codomain_space_t<Mpo, 1>> &&
124 std::same_as<environment_domain_space_t<KetSite, 1>, environment_domain_space_t<Mpo, 1>>;
125
126template <class Environment, class BraSite, class Mpo, class KetSite>
127concept CompatibleRightEnvironmentUpdateSpaces =
128 std::same_as<environment_domain_space_t<Environment, 0>, environment_codomain_space_t<BraSite, 0>> &&
129 std::same_as<environment_domain_space_t<Environment, 1>, environment_codomain_space_t<Mpo, 0>> &&
130 std::same_as<environment_codomain_space_t<Environment, 0>, environment_codomain_space_t<KetSite, 0>> &&
131 std::same_as<environment_domain_space_t<BraSite, 1>, environment_codomain_space_t<Mpo, 1>> &&
132 std::same_as<environment_domain_space_t<KetSite, 1>, environment_domain_space_t<Mpo, 1>>;
133
134enum class EnvironmentUpdateDirection
135{
136 left,
137 right,
138};
139
140struct EnvironmentUpdateTerm
141{
142 BlockKey<3> output_key;
143 std::size_t output_ordinal = 0;
144 std::size_t environment_ordinal;
145 std::size_t bra_site_ordinal;
146 std::size_t mpo_ordinal;
147 std::size_t ket_site_ordinal;
148};
149
150struct EnvironmentUpdatePlan
151{
152 std::vector<BlockKey<3>> output_keys;
153 std::vector<EnvironmentUpdateTerm> terms;
154 std::vector<std::size_t> group_offsets;
155};
156
157template <EnvironmentUpdateDirection Direction, EnvironmentMatrixView Environment, EnvironmentMatrixView BraSite,
158 EnvironmentMpoView Mpo, EnvironmentMatrixView KetSite>
159auto make_environment_update_plan(Environment const& environment, BraSite const& bra_site, Mpo const& mpo,
160 KetSite const& ket_site) -> EnvironmentUpdatePlan
161{
162 EnvironmentUpdatePlan result;
163 for (std::size_t environment_ordinal = 0; environment_ordinal < environment.stored_block_count();
164 ++environment_ordinal)
165 {
166 auto const& environment_key = environment.stored_keys()[environment_ordinal];
167 for (std::size_t mpo_ordinal = 0; mpo_ordinal < mpo.stored_block_count(); ++mpo_ordinal)
168 {
169 auto const& mpo_key = mpo.stored_keys()[mpo_ordinal];
170 constexpr std::size_t mpo_auxiliary = Direction == EnvironmentUpdateDirection::left ? 0 : 2;
171 if (environment_key.coordinate(1) != mpo_key.coordinate(mpo_auxiliary)) continue;
172
173 for (std::size_t bra_ordinal = 0; bra_ordinal < bra_site.stored_block_count(); ++bra_ordinal)
174 {
175 auto const& bra_key = bra_site.stored_keys()[bra_ordinal];
176 constexpr std::size_t site_bond = Direction == EnvironmentUpdateDirection::left ? 0 : 2;
177 if (environment_key.coordinate(0) != bra_key.coordinate(site_bond) ||
178 mpo_key.coordinate(3) != bra_key.coordinate(1))
179 continue;
180
181 for (std::size_t ket_ordinal = 0; ket_ordinal < ket_site.stored_block_count(); ++ket_ordinal)
182 {
183 auto const& ket_key = ket_site.stored_keys()[ket_ordinal];
184 if (environment_key.coordinate(2) != ket_key.coordinate(site_bond) ||
185 mpo_key.coordinate(1) != ket_key.coordinate(1))
186 continue;
187
188 BlockKey<3> const output_key =
189 Direction == EnvironmentUpdateDirection::left
190 ? BlockKey<3>{{bra_key.coordinate(2), mpo_key.coordinate(2), ket_key.coordinate(2)}}
191 : BlockKey<3>{{bra_key.coordinate(0), mpo_key.coordinate(0), ket_key.coordinate(0)}};
192 result.terms.push_back({.output_key = output_key,
193 .environment_ordinal = environment_ordinal,
194 .bra_site_ordinal = bra_ordinal,
195 .mpo_ordinal = mpo_ordinal,
196 .ket_site_ordinal = ket_ordinal});
197 }
198 }
199 }
200 }
201
202 std::ranges::stable_sort(result.terms, {}, &EnvironmentUpdateTerm::output_key);
203 for (auto& term : result.terms)
204 {
205 if (result.output_keys.empty() || result.output_keys.back() != term.output_key)
206 result.output_keys.push_back(term.output_key);
207 term.output_ordinal = result.output_keys.size() - 1;
208 }
209 result.group_offsets.assign(result.output_keys.size() + 1, 0);
210 for (auto const& term : result.terms)
211 ++result.group_offsets[term.output_ordinal + 1];
212 std::partial_sum(result.group_offsets.begin(), result.group_offsets.end(), result.group_offsets.begin());
213 return result;
214}
215
216template <class Function> void execute_environment_groups(SerialBlockExecution, std::size_t size, Function&& function)
217{
218 for (std::size_t index = 0; index < size; ++index)
219 function(index);
220}
221
222template <class Function>
223void execute_environment_groups(SchedulerBatchBlockExecution, std::size_t size, Function&& function)
224{
225 async::execute_batch(size, std::forward<Function>(function));
226}
227
228template <class LeafStorage, class Scalar, TensorView OutputBlock>
229[[nodiscard]] auto make_environment_intermediate(OutputBlock const& output_block, std::size_t rows, std::size_t columns)
230{
231 using intermediate_type = Tensor<Scalar, 2, LeafStorage, ColumnMajor>;
232 auto descriptor = mdspec_of(output_block);
233 if constexpr (requires {
234 descriptor.data_descriptor().buffer().resources();
235 intermediate_type(descriptor.data_descriptor().buffer().resources(), rows, columns);
236 })
237 {
238 return intermediate_type(descriptor.data_descriptor().buffer().resources(), rows, columns);
239 }
240 else
241 {
242 return intermediate_type(rows, columns);
243 }
244}
245
246template <EnvironmentUpdateDirection Direction, MutableBlockTensorView Output, EnvironmentMatrixView Environment,
247 EnvironmentMatrixView BraSite, EnvironmentMpoView Mpo, EnvironmentMatrixView KetSite>
248void execute_environment_update(Output& output, EnvironmentUpdatePlan const& plan, Environment const& environment,
249 BraSite const& bra_site, Mpo const& mpo, KetSite const& ket_site)
250{
251 using scalar_type = block_tensor_value_t<Output>;
252 using leaf_storage_policy = typename block_tensor_type_t<Output>::storage_policy::leaf_storage_policy;
253
254 execute_environment_groups(
255 typename std::remove_cvref_t<Output>::storage_policy::block_execution_policy{}, output.stored_block_count(),
256 [&](std::size_t output_ordinal) {
257 auto output_block = output.block_by_ordinal(output_ordinal);
258 std::size_t const first = plan.group_offsets[output_ordinal];
259 std::size_t const last = plan.group_offsets[output_ordinal + 1];
260 for (std::size_t index = first; index < last; ++index)
261 {
262 auto const& term = plan.terms[index];
263 auto const environment_block = environment.block_by_ordinal(term.environment_ordinal);
264 auto const bra_block = bra_site.block_by_ordinal(term.bra_site_ordinal);
265 auto const mpo_block = mpo.block_by_ordinal(term.mpo_ordinal);
266 auto const ket_block = ket_site.block_by_ordinal(term.ket_site_ordinal);
267 auto conjugated_bra = uni20::conj(bra_block);
268 scalar_type const coefficient = mpo_block[];
269 scalar_type const beta = index == first ? scalar_type{} : scalar_type{1};
270
271 if constexpr (Direction == EnvironmentUpdateDirection::left)
272 {
273 constexpr std::array<std::pair<std::size_t, std::size_t>, 1> first_axes{std::pair{1U, 0U}};
274 constexpr std::array<std::pair<std::size_t, std::size_t>, 1> second_axes{std::pair{0U, 0U}};
275 auto intermediate = make_environment_intermediate<leaf_storage_policy, scalar_type>(
276 output_block, static_cast<std::size_t>(environment_block.extent(0)),
277 static_cast<std::size_t>(ket_block.extent(1)));
278 linalg::contract(intermediate, scalar_type{1}, environment_block, ket_block, first_axes, scalar_type{});
279 linalg::contract(output_block, coefficient, conjugated_bra, intermediate, second_axes, beta);
280 }
281 else
282 {
283 constexpr std::array<std::pair<std::size_t, std::size_t>, 1> first_axes{std::pair{1U, 0U}};
284 constexpr std::array<std::pair<std::size_t, std::size_t>, 1> second_axes{std::pair{1U, 1U}};
285 auto intermediate = make_environment_intermediate<leaf_storage_policy, scalar_type>(
286 output_block, static_cast<std::size_t>(bra_block.extent(0)),
287 static_cast<std::size_t>(environment_block.extent(1)));
288 linalg::contract(intermediate, scalar_type{1}, conjugated_bra, environment_block, first_axes,
289 scalar_type{});
290 linalg::contract(output_block, coefficient, intermediate, ket_block, second_axes, beta);
291 }
292 }
293 });
294}
295
296template <EnvironmentUpdateDirection Direction, EnvironmentMatrixView Environment, EnvironmentMatrixView BraSite,
297 EnvironmentMpoView Mpo, EnvironmentMatrixView KetSite>
298void validate_environment_update(Environment const& environment, BraSite const& bra_site, Mpo const& mpo,
299 KetSite const& ket_site)
300{
301 if (environment.symmetry() != bra_site.symmetry() || environment.symmetry() != mpo.symmetry() ||
302 environment.symmetry() != ket_site.symmetry())
303 throw std::invalid_argument("MPO environment update operands require one symmetry");
304
305 bool compatible = false;
306 if constexpr (Direction == EnvironmentUpdateDirection::left)
307 {
308 compatible = environment.domain().template space<0>() == bra_site.domain().template space<0>() &&
309 environment.domain().template space<1>() == mpo.domain().template space<0>() &&
310 environment.codomain().template space<0>() == ket_site.domain().template space<0>() &&
311 bra_site.domain().template space<1>() == mpo.codomain().template space<1>() &&
312 ket_site.domain().template space<1>() == mpo.domain().template space<1>();
313 }
314 else
315 {
316 compatible = environment.domain().template space<0>() == bra_site.codomain().template space<0>() &&
317 environment.domain().template space<1>() == mpo.codomain().template space<0>() &&
318 environment.codomain().template space<0>() == ket_site.codomain().template space<0>() &&
319 bra_site.domain().template space<1>() == mpo.codomain().template space<1>() &&
320 ket_site.domain().template space<1>() == mpo.domain().template space<1>();
321 }
322 if (!compatible)
323 throw std::invalid_argument("MPO environment update has incompatible environment, site, or MPO spaces");
324}
325
326} // namespace detail
327
338template <typename Value, SparseBlockStorage Storage = SeparateSparseBlockStorage<>>
339 requires Scalar<Value> && detail::EnvironmentStorageFor<Storage, Value>
340[[nodiscard]] auto make_identity_mpo_environment(BlockSpace const& bond, LocalSpace const& auxiliary,
341 std::size_t auxiliary_index)
343{
344 if (bond.symmetry() != auxiliary.symmetry())
345 throw std::invalid_argument("identity MPO environment spaces require one symmetry");
346 if (auxiliary_index >= auxiliary.size())
347 throw std::invalid_argument("identity MPO environment auxiliary index is out of range");
348 if (!is_identity(auxiliary[auxiliary_index]))
349 throw std::invalid_argument("identity MPO environment requires an identity-charge auxiliary state");
350
352 auto keys = detail::make_identity_environment_keys<result_type>(bond, auxiliary_index);
353 result_type result(uninitialized, bond.symmetry(), Domain{bond, auxiliary}, Codomain{bond}, std::move(keys));
354 detail::initialize_identity_environment(result);
355 return result;
356}
357
367template <typename Value, SparseBlockStorage Storage = SeparateSparseBlockStorage<>, class Context>
368 requires Scalar<Value> && detail::EnvironmentStorageFor<Storage, Value> &&
369 requires(
370 BlockSpace const& bond, LocalSpace const& auxiliary,
371 std::vector<typename MpoEnvironment<Value, BlockSpace, LocalSpace, BlockSpace, Storage>::key_type>
372 keys,
373 Context& context) {
374 MpoEnvironment<Value, BlockSpace, LocalSpace, BlockSpace, Storage>(
375 uninitialized, bond.symmetry(), Domain{bond, auxiliary}, Codomain{bond}, std::move(keys), context);
376 }
377[[nodiscard]] auto
378make_identity_mpo_environment(BlockSpace const& bond, LocalSpace const& auxiliary, std::size_t auxiliary_index,
380{
381 if (bond.symmetry() != auxiliary.symmetry())
382 throw std::invalid_argument("identity MPO environment spaces require one symmetry");
383 if (auxiliary_index >= auxiliary.size())
384 throw std::invalid_argument("identity MPO environment auxiliary index is out of range");
385 if (!is_identity(auxiliary[auxiliary_index]))
386 throw std::invalid_argument("identity MPO environment requires an identity-charge auxiliary state");
387
389 auto keys = detail::make_identity_environment_keys<result_type>(bond, auxiliary_index);
390 result_type result(uninitialized, bond.symmetry(), Domain{bond, auxiliary}, Codomain{bond}, std::move(keys), context);
391 detail::initialize_identity_environment(result);
392 return result;
393}
394
403template <SparseBlockStorage OutputStorage = SeparateSparseBlockStorage<>, detail::EnvironmentMatrixView Environment,
404 detail::EnvironmentMatrixView BraSite, detail::EnvironmentMpoView Mpo, detail::EnvironmentMatrixView KetSite>
405 requires detail::CompatibleEnvironmentUpdateScalars<Environment, BraSite, Mpo, KetSite> &&
406 detail::CompatibleLeftEnvironmentUpdateSpaces<Environment, BraSite, Mpo, KetSite> &&
407 detail::EnvironmentStorageFor<OutputStorage, block_tensor_value_t<Environment>>
408[[nodiscard]] auto extend_left_environment(Environment const& environment, BraSite const& bra_site, Mpo const& mpo,
409 KetSite const& ket_site)
410{
411 using bra_bond_type = typename block_tensor_codomain_t<BraSite>::template space_type<0>;
412 using auxiliary_type = typename block_tensor_codomain_t<Mpo>::template space_type<0>;
413 using ket_bond_type = typename block_tensor_codomain_t<KetSite>::template space_type<0>;
416
417 detail::validate_environment_update<detail::EnvironmentUpdateDirection::left>(environment, bra_site, mpo, ket_site);
418 auto plan = detail::make_environment_update_plan<detail::EnvironmentUpdateDirection::left>(environment, bra_site, mpo,
419 ket_site);
420 auto result = [&] {
421 auto domain = Domain{bra_site.codomain().template space<0>(), mpo.codomain().template space<0>()};
422 auto codomain = Codomain{ket_site.codomain().template space<0>()};
423 if constexpr (requires {
424 result_type(environment.symmetry(), domain, codomain, plan.output_keys,
425 environment.allocation_context());
426 })
427 return result_type(environment.symmetry(), std::move(domain), std::move(codomain), std::move(plan.output_keys),
428 environment.allocation_context());
429 else
430 return result_type(environment.symmetry(), std::move(domain), std::move(codomain), std::move(plan.output_keys));
431 }();
432 detail::execute_environment_update<detail::EnvironmentUpdateDirection::left>(result, plan, environment, bra_site, mpo,
433 ket_site);
434 return result;
435}
436
441template <SparseBlockStorage OutputStorage = SeparateSparseBlockStorage<>, detail::EnvironmentMatrixView Environment,
442 detail::EnvironmentMatrixView Site, detail::EnvironmentMpoView Mpo>
443[[nodiscard]] auto extend_left_environment(Environment const& environment, Site const& site, Mpo const& mpo)
444{
445 return extend_left_environment<OutputStorage>(environment, site, mpo, site);
446}
447
456template <SparseBlockStorage OutputStorage = SeparateSparseBlockStorage<>, detail::EnvironmentMatrixView Environment,
457 detail::EnvironmentMatrixView BraSite, detail::EnvironmentMpoView Mpo, detail::EnvironmentMatrixView KetSite>
458 requires detail::CompatibleEnvironmentUpdateScalars<Environment, BraSite, Mpo, KetSite> &&
459 detail::CompatibleRightEnvironmentUpdateSpaces<Environment, BraSite, Mpo, KetSite> &&
460 detail::EnvironmentStorageFor<OutputStorage, block_tensor_value_t<Environment>>
461[[nodiscard]] auto extend_right_environment(Environment const& environment, BraSite const& bra_site, Mpo const& mpo,
462 KetSite const& ket_site)
463{
464 using bra_bond_type = typename block_tensor_domain_t<BraSite>::template space_type<0>;
465 using auxiliary_type = typename block_tensor_domain_t<Mpo>::template space_type<0>;
466 using ket_bond_type = typename block_tensor_domain_t<KetSite>::template space_type<0>;
469
470 detail::validate_environment_update<detail::EnvironmentUpdateDirection::right>(environment, bra_site, mpo, ket_site);
471 auto plan = detail::make_environment_update_plan<detail::EnvironmentUpdateDirection::right>(environment, bra_site,
472 mpo, ket_site);
473 auto result = [&] {
474 auto domain = Domain{bra_site.domain().template space<0>(), mpo.domain().template space<0>()};
475 auto codomain = Codomain{ket_site.domain().template space<0>()};
476 if constexpr (requires {
477 result_type(environment.symmetry(), domain, codomain, plan.output_keys,
478 environment.allocation_context());
479 })
480 return result_type(environment.symmetry(), std::move(domain), std::move(codomain), std::move(plan.output_keys),
481 environment.allocation_context());
482 else
483 return result_type(environment.symmetry(), std::move(domain), std::move(codomain), std::move(plan.output_keys));
484 }();
485 detail::execute_environment_update<detail::EnvironmentUpdateDirection::right>(result, plan, environment, bra_site,
486 mpo, ket_site);
487 return result;
488}
489
494template <SparseBlockStorage OutputStorage = SeparateSparseBlockStorage<>, detail::EnvironmentMatrixView Environment,
495 detail::EnvironmentMatrixView Site, detail::EnvironmentMpoView Mpo>
496[[nodiscard]] auto extend_right_environment(Environment const& environment, Site const& site, Mpo const& mpo)
497{
498 return extend_right_environment<OutputStorage>(environment, site, mpo, site);
499}
500
501} // namespace uni20::tensor_network
Concepts and associated types for BlockTensor-level views.
Classifies tensor spaces for block-key and dense-block storage.
Immutable coalesced tensor space represented as unique symmetry blocks.
Definition block_space.hpp:38
Fixed-order tensor whose blocks obey a bosonic abelian selection rule.
Definition block_tensor.hpp:161
Ordered codomain spaces of a tensor morphism.
Definition morphism_boundary.hpp:78
Ordered domain spaces of a tensor morphism.
Definition morphism_boundary.hpp:24
Ordered local-state space whose quantum numbers may repeat.
Definition local_space.hpp:28
Concept for numeric scalar types (integer, real, or complex).
Definition scalar_concepts.hpp:81
Read-only lazy conjugation views for tensor-level objects.
Coroutine scheduler for AsyncTask.
Named backend-neutral function objects for elementwise transforms.
uni20::complex< T > conj(detail::standard_complex< T > x)
Returns the complex conjugate for complex-valued scalars.
Definition math.hpp:70
Fixed-output pairwise Tensor contraction front end.
std::pair< int, int > size(std::FILE *stream)
Return the terminal size associated with a C stream.
Definition terminal.cpp:504
void execute_batch(std::size_t size, Function &&function)
Execute a synchronous lightweight batch on the global scheduler.
Definition debug_scheduler.hpp:245
void contract(BackendSelector selector, async::Async< OutputTensor > &output, Alpha &&alpha, async::Async< LhsTensor > const &lhs, async::Async< RhsTensor > const &rhs, ContractionAxes< LhsRank, RhsRank, ContractedRank > axes, Beta &&beta)
Schedule a fixed-output pairwise contraction through an explicit selector.
Definition linalg/async/contract.hpp:84
typename optional_traits< T >::value_type value_type
Definition data_table.hpp:42
Definition right_first_rabc.hpp:34
auto extend_right_environment(Environment const &environment, BraSite const &bra_site, Mpo const &mpo, KetSite const &ket_site)
Extend a right MPO environment across distinct bra and ket MPS sites.
Definition environment.hpp:461
auto extend_left_environment(Environment const &environment, BraSite const &bra_site, Mpo const &mpo, KetSite const &ket_site)
Extend a left MPO environment across distinct bra and ket MPS sites.
Definition environment.hpp:408
auto make_identity_mpo_environment(BlockSpace const &bond, LocalSpace const &auxiliary, std::size_t auxiliary_index) -> MpoEnvironment< Value, BlockSpace, LocalSpace, BlockSpace, Storage >
Construct an identity MPO environment at one scalar auxiliary state.
Definition environment.hpp:340
constexpr uninitialized_t uninitialized
Explicit allocation tag for overwrite outputs and scratch space.
Definition common/initialization.hpp:22
typename block_tensor_type_t< Tensor >::domain_type block_tensor_domain_t
Ordered domain type exposed by a BlockTensor-level object.
Definition block_tensor_concepts.hpp:31
typename block_tensor_type_t< Tensor >::value_type block_tensor_value_t
Scalar value type exposed by a BlockTensor-level object.
Definition block_tensor_concepts.hpp:25
constexpr decltype(auto) mdspec_of(Tensor &tensor) noexcept(noexcept(tensor.mdspec()))
Return a tensor's immediate or descriptor-backed multidimensional metadata.
Definition tensor/concepts.hpp:50
void copy(BackendSelector selector, async::Async< OutputTensor > &output, async::Async< InputTensor > const &input)
Schedule a Tensor copy through an explicit backend selector.
Definition linalg/async/copy.hpp:174
std::ptrdiff_t index_type
Definition types.hpp:19
mpreal beta(mpreal const &a, mpreal const &x)
Real Beta function; positive rational/integer pairs retain exact values.
Definition mpreal_special.hpp:164
typename block_tensor_type_t< Tensor >::codomain_type block_tensor_codomain_t
Ordered codomain type exposed by a BlockTensor-level object.
Definition block_tensor_concepts.hpp:34
auto is_identity(QNum const &q) -> bool
Return whether a quantum number is the identity irrep.
Definition qnum.hpp:250
Defines canonical BlockTensor types for matrix-product networks.
Trait to extract the scalar type from a type T.
Definition scalar_traits.hpp:93
Backend-dispatched elementwise overwrite and update operations.
General-purpose owning tensors with runtime extents.