//===-- runtime/reduce.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // REDUCE() implementation #include "flang/Runtime/reduce.h" #include "reduction-templates.h" #include "terminator.h" #include "tools.h" #include "flang/Runtime/descriptor.h" namespace Fortran::runtime { template class ReduceAccumulator { public: using Operation = std::conditional_t, ReferenceReductionOperation>; RT_API_ATTRS ReduceAccumulator(const Descriptor &array, Operation operation, const T *identity, Terminator &terminator) : array_{array}, operation_{operation}, identity_{identity}, terminator_{terminator} {} RT_API_ATTRS void Reinitialize() { result_.reset(); } template RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) { const auto *operand{array_.Element(at)}; if (result_) { if constexpr (isByValue) { result_ = operation_(*result_, *operand); } else { result_ = operation_(&*result_, operand); } } else { result_ = *operand; } return true; } template RT_API_ATTRS void GetResult(A *to, int /*zeroBasedDim*/ = -1) { if (result_) { *to = *result_; } else if (identity_) { *to = *identity_; } else { terminator_.Crash("REDUCE() without IDENTITY= has no result"); } } private: const Descriptor &array_; common::optional result_; Operation operation_; const T *identity_{nullptr}; Terminator &terminator_; }; template class BufferedReduceAccumulator { public: RT_API_ATTRS BufferedReduceAccumulator(const Descriptor &array, OP operation, const T *identity, Terminator &terminator) : array_{array}, operation_{operation}, identity_{identity}, terminator_{terminator} {} RT_API_ATTRS void Reinitialize() { activeTemp_ = -1; } template RT_API_ATTRS bool AccumulateAt(const SubscriptValue at[]) { const auto *operand{array_.Element(at)}; if (activeTemp_ >= 0) { if constexpr (hasLength) { operation_(&*temp_[1 - activeTemp_], length_, &*temp_[activeTemp_], operand, length_, length_); } else { operation_(&*temp_[1 - activeTemp_], &*temp_[activeTemp_], operand); } activeTemp_ = 1 - activeTemp_; } else { activeTemp_ = 0; std::memcpy(&*temp_[activeTemp_], operand, elementBytes_); } return true; } template RT_API_ATTRS void GetResult(A *to, int /*zeroBasedDim*/ = -1) { if (activeTemp_ >= 0) { std::memcpy(to, &*temp_[activeTemp_], elementBytes_); } else if (identity_) { std::memcpy(to, identity_, elementBytes_); } else { terminator_.Crash("REDUCE() without IDENTITY= has no result"); } } private: const Descriptor &array_; OP operation_; const T *identity_{nullptr}; Terminator &terminator_; std::size_t elementBytes_{array_.ElementBytes()}; OwningPtr temp_[2]{SizedNew{terminator_}(elementBytes_), SizedNew{terminator_}(elementBytes_)}; int activeTemp_{-1}; std::size_t length_{elementBytes_ / sizeof(T)}; }; extern "C" { RT_EXT_API_GROUP_BEGIN std::int8_t RTDEF(ReduceInteger1Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int8_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } std::int8_t RTDEF(ReduceInteger1Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int8_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceInteger1DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int8_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceInteger1DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int8_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } std::int16_t RTDEF(ReduceInteger2Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int16_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } std::int16_t RTDEF(ReduceInteger2Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int16_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceInteger2DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int16_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceInteger2DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int16_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } std::int32_t RTDEF(ReduceInteger4Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int32_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } std::int32_t RTDEF(ReduceInteger4Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int32_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceInteger4DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int32_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceInteger4DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int32_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } std::int64_t RTDEF(ReduceInteger8Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int64_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } std::int64_t RTDEF(ReduceInteger8Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int64_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceInteger8DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int64_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceInteger8DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int64_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } #ifdef __SIZEOF_INT128__ common::int128_t RTDEF(ReduceInteger16Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const common::int128_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } common::int128_t RTDEF(ReduceInteger16Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const common::int128_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceInteger16DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const common::int128_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceInteger16DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const common::int128_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } #endif std::uint8_t RTDEF(ReduceUnsigned1Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint8_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } std::uint8_t RTDEF(ReduceUnsigned1Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint8_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceUnsigned1DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint8_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceUnsigned1DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint8_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } std::uint16_t RTDEF(ReduceUnsigned2Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint16_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } std::uint16_t RTDEF(ReduceUnsigned2Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint16_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceUnsigned2DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint16_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceUnsigned2DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint16_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } std::uint32_t RTDEF(ReduceUnsigned4Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint32_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } std::uint32_t RTDEF(ReduceUnsigned4Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint32_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceUnsigned4DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint32_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceUnsigned4DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint32_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } std::uint64_t RTDEF(ReduceUnsigned8Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint64_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } std::uint64_t RTDEF(ReduceUnsigned8Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint64_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceUnsigned8DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint64_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceUnsigned8DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::uint64_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } #ifdef __SIZEOF_INT128__ common::uint128_t RTDEF(ReduceUnsigned16Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const common::uint128_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } common::uint128_t RTDEF(ReduceUnsigned16Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const common::uint128_t *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceUnsigned16DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const common::uint128_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceUnsigned16DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const common::uint128_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } #endif // TODO: real/complex(2 & 3) float RTDEF(ReduceReal4Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const float *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{array, operation, identity, terminator}, "REDUCE"); } float RTDEF(ReduceReal4Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const float *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceReal4DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const float *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceReal4DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const float *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } double RTDEF(ReduceReal8Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const double *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{array, operation, identity, terminator}, "REDUCE"); } double RTDEF(ReduceReal8Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const double *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceReal8DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const double *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceReal8DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const double *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } #if HAS_FLOAT80 CppTypeFor RTDEF(ReduceReal10Ref)( const Descriptor &array, ReferenceReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator, false>{ array, operation, identity, terminator}, "REDUCE"); } CppTypeFor RTDEF(ReduceReal10Value)( const Descriptor &array, ValueReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator, true>{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceReal10DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator, false>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceReal10DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator, true>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } #endif #if HAS_LDBL128 || HAS_FLOAT128 CppFloat128Type RTDEF(ReduceReal16Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const CppFloat128Type *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } CppFloat128Type RTDEF(ReduceReal16Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const CppFloat128Type *identity, bool ordered) { Terminator terminator{source, line}; return GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(ReduceReal16DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const CppFloat128Type *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceReal16DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const CppFloat128Type *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } #endif void RTDEF(CppReduceComplex4Ref)(CppTypeFor &result, const Descriptor &array, ReferenceReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; result = GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator, false>{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(CppReduceComplex4Value)(CppTypeFor &result, const Descriptor &array, ValueReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; result = GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator, true>{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(CppReduceComplex4DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator, false>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(CppReduceComplex4DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator, true>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(CppReduceComplex8Ref)(CppTypeFor &result, const Descriptor &array, ReferenceReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; result = GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator, false>{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(CppReduceComplex8Value)(CppTypeFor &result, const Descriptor &array, ValueReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; result = GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator, true>{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(CppReduceComplex8DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator, false>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(CppReduceComplex8DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator, true>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } #if HAS_FLOAT80 void RTDEF(CppReduceComplex10Ref)(CppTypeFor &result, const Descriptor &array, ReferenceReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; result = GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator, false>{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(CppReduceComplex10Value)( CppTypeFor &result, const Descriptor &array, ValueReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; result = GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator, true>{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(CppReduceComplex10DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator, false>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(CppReduceComplex10DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator, true>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } #endif #if HAS_LDBL128 || HAS_FLOAT128 void RTDEF(CppReduceComplex16Ref)(CppTypeFor &result, const Descriptor &array, ReferenceReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; result = GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator, false>{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(CppReduceComplex16Value)( CppTypeFor &result, const Descriptor &array, ValueReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; result = GetTotalReduction(array, source, line, dim, mask, ReduceAccumulator, true>{ array, operation, identity, terminator}, "REDUCE"); } void RTDEF(CppReduceComplex16DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator, false>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(CppReduceComplex16DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation> operation, const char *source, int line, int dim, const Descriptor *mask, const CppTypeFor *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = ReduceAccumulator, true>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } #endif bool RTDEF(ReduceLogical1Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int8_t *identity, bool ordered) { return RTNAME(ReduceInteger1Ref)( array, operation, source, line, dim, mask, identity, ordered) != 0; } bool RTDEF(ReduceLogical1Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int8_t *identity, bool ordered) { return RTNAME(ReduceInteger1Value)( array, operation, source, line, dim, mask, identity, ordered) != 0; } void RTDEF(ReduceLogical1DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int8_t *identity, bool ordered) { RTNAME(ReduceInteger1DimRef) (result, array, operation, source, line, dim, mask, identity, ordered); } void RTDEF(ReduceLogical1DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int8_t *identity, bool ordered) { RTNAME(ReduceInteger1DimValue) (result, array, operation, source, line, dim, mask, identity, ordered); } bool RTDEF(ReduceLogical2Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int16_t *identity, bool ordered) { return RTNAME(ReduceInteger2Ref)( array, operation, source, line, dim, mask, identity, ordered) != 0; } bool RTDEF(ReduceLogical2Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int16_t *identity, bool ordered) { return RTNAME(ReduceInteger2Value)( array, operation, source, line, dim, mask, identity, ordered) != 0; } void RTDEF(ReduceLogical2DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int16_t *identity, bool ordered) { RTNAME(ReduceInteger2DimRef) (result, array, operation, source, line, dim, mask, identity, ordered); } void RTDEF(ReduceLogical2DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int16_t *identity, bool ordered) { RTNAME(ReduceInteger2DimValue) (result, array, operation, source, line, dim, mask, identity, ordered); } bool RTDEF(ReduceLogical4Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int32_t *identity, bool ordered) { return RTNAME(ReduceInteger4Ref)( array, operation, source, line, dim, mask, identity, ordered) != 0; } bool RTDEF(ReduceLogical4Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int32_t *identity, bool ordered) { return RTNAME(ReduceInteger4Value)( array, operation, source, line, dim, mask, identity, ordered) != 0; } void RTDEF(ReduceLogical4DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int32_t *identity, bool ordered) { RTNAME(ReduceInteger4DimRef) (result, array, operation, source, line, dim, mask, identity, ordered); } void RTDEF(ReduceLogical4DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int32_t *identity, bool ordered) { RTNAME(ReduceInteger4DimValue) (result, array, operation, source, line, dim, mask, identity, ordered); } bool RTDEF(ReduceLogical8Ref)(const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int64_t *identity, bool ordered) { return RTNAME(ReduceInteger8Ref)( array, operation, source, line, dim, mask, identity, ordered) != 0; } bool RTDEF(ReduceLogical8Value)(const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int64_t *identity, bool ordered) { return RTNAME(ReduceInteger8Value)( array, operation, source, line, dim, mask, identity, ordered) != 0; } void RTDEF(ReduceLogical8DimRef)(Descriptor &result, const Descriptor &array, ReferenceReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int64_t *identity, bool ordered) { RTNAME(ReduceInteger8DimRef) (result, array, operation, source, line, dim, mask, identity, ordered); } void RTDEF(ReduceLogical8DimValue)(Descriptor &result, const Descriptor &array, ValueReductionOperation operation, const char *source, int line, int dim, const Descriptor *mask, const std::int64_t *identity, bool ordered) { RTNAME(ReduceInteger8DimValue) (result, array, operation, source, line, dim, mask, identity, ordered); } void RTDEF(ReduceChar1)(char *result, const Descriptor &array, ReductionCharOperation operation, const char *source, int line, int dim, const Descriptor *mask, const char *identity, bool ordered) { Terminator terminator{source, line}; BufferedReduceAccumulator, /*hasLength=*/true> accumulator{array, operation, identity, terminator}; DoTotalReduction(array, dim, mask, accumulator, "REDUCE", terminator); accumulator.GetResult(result); } void RTDEF(ReduceCharacter1Dim)(Descriptor &result, const Descriptor &array, ReductionCharOperation operation, const char *source, int line, int dim, const Descriptor *mask, const char *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = BufferedReduceAccumulator, /*hasLength=*/true>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceChar2)(char16_t *result, const Descriptor &array, ReductionCharOperation operation, const char *source, int line, int dim, const Descriptor *mask, const char16_t *identity, bool ordered) { Terminator terminator{source, line}; BufferedReduceAccumulator, /*hasLength=*/true> accumulator{array, operation, identity, terminator}; DoTotalReduction( array, dim, mask, accumulator, "REDUCE", terminator); accumulator.GetResult(result); } void RTDEF(ReduceCharacter2Dim)(Descriptor &result, const Descriptor &array, ReductionCharOperation operation, const char *source, int line, int dim, const Descriptor *mask, const char16_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = BufferedReduceAccumulator, /*hasLength=*/true>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceChar4)(char32_t *result, const Descriptor &array, ReductionCharOperation operation, const char *source, int line, int dim, const Descriptor *mask, const char32_t *identity, bool ordered) { Terminator terminator{source, line}; BufferedReduceAccumulator, /*hasLength=*/true> accumulator{array, operation, identity, terminator}; DoTotalReduction( array, dim, mask, accumulator, "REDUCE", terminator); accumulator.GetResult(result); } void RTDEF(ReduceCharacter4Dim)(Descriptor &result, const Descriptor &array, ReductionCharOperation operation, const char *source, int line, int dim, const Descriptor *mask, const char32_t *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = BufferedReduceAccumulator, /*hasLength=*/true>; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } void RTDEF(ReduceDerivedType)(char *result, const Descriptor &array, ReductionDerivedTypeOperation operation, const char *source, int line, int dim, const Descriptor *mask, const char *identity, bool ordered) { Terminator terminator{source, line}; BufferedReduceAccumulator accumulator{array, operation, identity, terminator}; DoTotalReduction(array, dim, mask, accumulator, "REDUCE", terminator); accumulator.GetResult(result); } void RTDEF(ReduceDerivedTypeDim)(Descriptor &result, const Descriptor &array, ReductionDerivedTypeOperation operation, const char *source, int line, int dim, const Descriptor *mask, const char *identity, bool ordered) { Terminator terminator{source, line}; using Accumulator = BufferedReduceAccumulator; Accumulator accumulator{array, operation, identity, terminator}; PartialReduction(result, array, array.ElementBytes(), dim, mask, terminator, "REDUCE", accumulator); } RT_EXT_API_GROUP_END } // extern "C" } // namespace Fortran::runtime