DUNE-ACFEM (unstable)
einsum.hh
63 template<class LeftTensor, class LeftIndices, class RightTensor, class RightIndices, bool IdenticalOperands = Expressions::AreRuntimeEqual<LeftTensor, RightTensor>::value>
78 using Operation = EinsumOperation<Seq<LPos...>, Seq<RPos...>, SubSequence<Seq<LDims...>, LPos...> >;
100 inline constexpr std::size_t EinsumRank = EinsumOperationTraits<LDims, LPos, RDims, RPos>::rank_;
105 template<class LeftTensor, class LeftIndices, class RightTensor, class RightIndices, bool IdenticalOperands>
107 : public TensorBase<FloatingPointClosure<typename FieldPromotion<LeftTensor, RightTensor>::Type>,
111 , public Expressions::Storage<EinsumFunctor<LeftTensor, LeftIndices, RightTensor, RightIndices >,
144 using Signature = EinsumSignature<LeftTensor, LeftIndexPositions, RightTensor, RightIndexPositions>;
146 using FunctorType = OperationTraits<EinsumOperation<LeftIndexPositions, RightIndexPositions, LeftDefectSignature> >;
177 std::enable_if_t<std::is_constructible<LeftType, LeftArg>::value && std::is_constructible<RightType, RightArg>::value, int> = 0>
207 : accu_(accu), left_(left), right_(right), leftIndices_(toArray<std::size_t>(leftIndices)), rightIndices_(toArray<std::size_t>(rightIndices))
214 if (!LeftTensorType::isZero(DefectIndices{}, LeftIndexPositions{}) && !RightTensorType::isZero(DefectIndices{}, RightIndexPositions{})) {
217 auto val = tensorValue(left_, insertAt(leftIndices_, PermuteSequence<DefectIndices, LeftPermutation>{}, LeftSortedPos{}));
221 tensorValue(left_, insertAt(leftIndices_, PermuteSequence<DefectIndices, LeftPermutation>{}, LeftSortedPos{}))
223 tensorValue(left_, insertAt(rightIndices_, PermuteSequence<DefectIndices, RightPermutation>{}, RightSortedPos{}));
227 tensorValue(left_, insertAt(leftIndices_, PermuteSequence<DefectIndices, LeftPermutation>{}, LeftSortedPos{}))
229 tensorValue(right_, insertAt(rightIndices_, PermuteSequence<DefectIndices, RightPermutation>{}, RightSortedPos{}));
255 forLoop<multiDim(DefectSignature{})>(GCCBugCompensator1(accu, operand(0_c), operand(1_c), leftIndices, rightIndices));
260 if (!LeftTensorType::isZero(DefectIndices{}, LeftIndexPositions{}) && !RightTensorType::isZero(DefectIndices{}, RightIndexPositions{})) {
263 auto val = tensorValue(operand(0_c), insertAt(leftIndices, PermuteSequence<DefectIndices, LeftPermutation>{}, LeftSortedPos{}));
267 tensorValue(operand(0_c), insertAt(leftIndices, PermuteSequence<DefectIndices, LeftPermutation>{}, LeftSortedPos{}))
269 tensorValue(operand(0_c), insertAt(rightIndices, PermuteSequence<DefectIndices, RightPermutation>{}, RightSortedPos{}));
273 tensorValue(operand(0_c), insertAt(leftIndices, PermuteSequence<DefectIndices, LeftPermutation>{}, LeftSortedPos{}))
275 tensorValue(operand(1_c), insertAt(rightIndices, PermuteSequence<DefectIndices, RightPermutation>{}, RightSortedPos{}));
296 using LeftArg = InsertAt<LeftIndexArg, PermuteSequence<DefectIndices, LeftPermutation>, LeftSortedPos>;
297 using RightArg = InsertAt<RightIndexArg, PermuteSequence<DefectIndices, RightPermutation>, RightSortedPos>;
333 using LeftArg = InsertAt<LeftIndexArg, PermuteSequence<DefectIndices, LeftPermutation>, LeftSortedPos>;
334 using RightArg = InsertAt<RightIndexArg, PermuteSequence<DefectIndices, RightPermutation>, RightSortedPos>;
397 using LeftArg = InsertAt<LeftIndexArg, PermuteSequence<DefectIndices, LeftPermutation>, LeftSortedPos>;
398 using RightArg = InsertAt<RightIndexArg, PermuteSequence<DefectIndices, RightPermutation>, RightSortedPos>;
421 forLoop<multiDim(DefectSignature{})>(GCCBugCompensator2<LeftIndexArg, RightIndexArg>(accu, operand(0_c), operand(1_c)));
425 using LeftArg = InsertAt<LeftIndexArg, PermuteSequence<DefectIndices, LeftPermutation>, LeftSortedPos>;
426 using RightArg = InsertAt<RightIndexArg, PermuteSequence<DefectIndices, RightPermutation>, RightSortedPos>;
463 forLoop<multiDim(DefectSignature{})>(GCCBugCompensator2<LeftIndexArg, RightIndexArg>(accu, operand(0_c), operand(1_c)));
468 using LeftArg = InsertAt<LeftIndexArg, PermuteSequence<DefectIndices, LeftPermutation>, LeftSortedPos>;
469 using RightArg = InsertAt<RightIndexArg, PermuteSequence<DefectIndices, RightPermutation>, RightSortedPos>;
492 return (... && (LeftTensorType::isZero(InsertAt<PermuteSequence<MultiIndex<N, DefectSignature>, LeftPermutation>, LeftInd, LeftInj>{}, LeftPos{})
494 RightTensorType::isZero(InsertAt<PermuteSequence<MultiIndex<N, DefectSignature>, RightPermutation>, RightInd, RightInj>{}, RightPos{})));
512 TransformSequence<RealPos, Seq<>, IndexFunctor, AcceptInputInRangeFunctor<std::size_t, 0, leftRank_> >;
522 TransformSequence<RealPos, Seq<>, IndexFunctor, AcceptInputInRangeFunctor<std::size_t, leftRank_, leftRank_ + rightRank_> >;
523 using RightPos = TransformSequence<SequenceSlice<RealPos, RightPosInd>, Seq<>, OffsetFunctor<-(ssize_t)leftRank_> >;
539 if constexpr (ExpressionTraits<LeftTensorType>::isZero || ExpressionTraits<RightTensorType>::isZero) {
550 std::string pfxL = std::is_reference<TL>::value ? (RefersConst<TL>::value ? "cref" : "ref") : "";
551 std::string pfxR = std::is_reference<TR>::value ? (RefersConst<TR>::value ? "cref" : "ref") : "";
563 return finalize(EinsumFunctor<T1, Seq1, T2, Seq2>{}, std::forward<T1>(t1), std::forward<T2>(t2));
583 constexpr auto operate(Expressions::DontOptimize, OperationTraits<EinsumOperation<Seq0, Seq1, Dims> >, T0&& t0, T1&& t1)
600 struct FieldTraits<ACFem::Tensor::EinsteinSummation<LeftTensor, LeftIndices, RightTensor, RightIndices> >
601 : FieldTraits<ACFem::FloatingPointClosure<typename ACFem::FieldPromotion<LeftTensor, RightTensor>::Type> >
Contraction of two tensor over a selection set of indices.
Definition: einsum.hh:117
auto constexpr operator()(Seq< Indices... >) const
Constant access from index-sequence.
Definition: einsum.hh:383
OptimizeTag< 0 > DontOptimize
Bottom level is overloaded to do nothing.
Definition: optimizationbase.hh:74
std::string operationName(F &&f, const std::string &arg)
Verbose print of an operation, helper function to produce noise.
Definition: operationtraits.hh:601
typename FloatingPointClosureHelper< T >::Type FloatingPointClosure
Template alias.
Definition: fieldpromotion.hh:74
BoolConstant< ExpressionTraits< T >::isTypedValue > IsTypedValue
Compile-time true if T is a "typed value", e.g. a std::integral_constant.
Definition: expressiontraits.hh:90
constexpr auto addLoop(F &&f, T &&init, IndexConstant< N >=IndexConstant< N >{})
Version with just a plain number as argument.
Definition: foreach.hh:110
typename GetHeadPartHelper< Cnt, Seq >::Type HeadPart
Extract Cnt many consecutive elements from the front of Seq.
Definition: access.hh:217
constexpr std::size_t size()
Gives the number of elements in tuple-likes and std::integer_sequence.
Definition: size.hh:73
IndexConstant< CommonHeadHelper< 0UL, Seq1, Seq2 >::value > CommonHead
Compute the number of identical indices at the head of the sequence.
Definition: filter.hh:173
MakeSequence< std::size_t, N, Offset, Stride, Repeat > MakeIndexSequence
Make a sequence of std::size_t elements.
Definition: generators.hh:34
MultiplyOffsetFunctor< 1, Offset > OffsetFunctor
Offset functor.
Definition: transform.hh:335
typename SequenceCatHelper2< S... >::Type SequenceCat
Concatenate the given sequences, in order, to <S0, S1, ... >.
Definition: transform.hh:220
typename InsertAtHelper< Sequence< typename Input::value_type >, Input, Inject, Pos, AssumeSorted >::Type InsertAt
Insert Inject into the sequence Input at the position specified by Pos.
Definition: insertat.hh:87
auto insertAt(SrcTuple &&src, DataTuple &&data, BoolConstant< AssumeSorted >=BoolConstant< AssumeSorted >{})
Insert the elements of data at positions given by pos into src in turn.
Definition: subtuple.hh:106
auto forwardSubTuple(const TupleLike &t, IndexSequence< I... >=IndexSequence< I... >{})
Like subTuble() but forward the arguments, possibly in order to be expanded as parameters to another ...
Definition: subtuple.hh:162
constexpr auto operate(OptimizeNext< EinsumTag >, F &&f, T0 &&t0, T1 &&t1)
Definition: einsum.hh:327
constexpr decltype(auto) einsum(T1 &&t1, T2 &&t2)
Greedy tensor contraction for proper tensors, summing over all matching dimensions.
Definition: einsum.hh:571
typename EinsumOperationTraits< LDims, LPos, RDims, RPos >::Signature EinsumSignature
Compute the signature of the einsum tensor.
Definition: einsum.hh:84
typename EinsumOperationTraits< LDims, LPos, RDims, RPos >::Functor EinsumFunctor
Generate an einsum-functor.
Definition: einsum.hh:91
decltype(isIntegralPack(std::declval< T >()...)) IsIntegralPack
Decide whether the given parameter pack contains only integral types.
Definition: compare.hh:377
std::decay_t< decltype(permute(Sequence{}, Perm{}))> PermuteSequence
Apply the given permutation to the positions of the given sequence.
Definition: permutation.hh:137
Sequence< typename Seq::value_type, Get< Indices, Seq >::value... > SubSequence
Create a subsequence containing all values designated by the positions given by Indices.
Definition: sequenceslice.hh:16
std::decay_t< decltype(multiIndex< I >(DimSeq{}))> MultiIndex
Generate the multi-index corresponding to the flattened index I where the multiindex varies between t...
Definition: multiindex.hh:68
static std::size_t constexpr multiDim(IndexSequence< Dimensions... >, IndexSequence< IndexPositions... >=IndexSequence< IndexPositions... >{})
Compute the "dimension" corresponding to the given signature, i.e.
Definition: multiindex.hh:171
