[flang-commits] [flang] fdf3377 - [flang] Implement runtime for IALL & IANY
peter klausler via flang-commits
flang-commits at lists.llvm.org
Wed Jun 16 14:54:46 PDT 2021
Author: peter klausler
Date: 2021-06-16T14:54:36-07:00
New Revision: fdf33771feeb23ecab25b61d37f5ad575a641a10
URL: https://github.com/llvm/llvm-project/commit/fdf33771feeb23ecab25b61d37f5ad575a641a10
DIFF: https://github.com/llvm/llvm-project/commit/fdf33771feeb23ecab25b61d37f5ad575a641a10.diff
LOG: [flang] Implement runtime for IALL & IANY
We had IPARITY (xor-reduction) but I missed IALL (and)
and IANY (or).
Differential Revision: https://reviews.llvm.org/D104339
Added:
Modified:
flang/runtime/reduction.cpp
flang/runtime/reduction.h
flang/unittests/RuntimeGTest/Reduction.cpp
Removed:
################################################################################
diff --git a/flang/runtime/reduction.cpp b/flang/runtime/reduction.cpp
index 73fcfa831c2e..f5f6abff9b28 100644
--- a/flang/runtime/reduction.cpp
+++ b/flang/runtime/reduction.cpp
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-// Implements ALL, ANY, COUNT, IPARITY, & PARITY for all required operand
-// types and shapes.
+// Implements ALL, ANY, COUNT, IALL, IANY, IPARITY, & PARITY for all required
+// operand types and shapes.
//
// DOT_PRODUCT, FINDLOC, MATMUL, SUM, and PRODUCT are in their own eponymous
// source files.
@@ -21,7 +21,41 @@
namespace Fortran::runtime {
-// IPARITY()
+// IALL, IANY, IPARITY
+
+template <typename INTERMEDIATE> class IntegerAndAccumulator {
+public:
+ explicit IntegerAndAccumulator(const Descriptor &array) : array_{array} {}
+ void Reinitialize() { and_ = ~INTERMEDIATE{0}; }
+ template <typename A> void GetResult(A *p, int /*zeroBasedDim*/ = -1) const {
+ *p = static_cast<A>(and_);
+ }
+ template <typename A> bool AccumulateAt(const SubscriptValue at[]) {
+ and_ &= *array_.Element<A>(at);
+ return true;
+ }
+
+private:
+ const Descriptor &array_;
+ INTERMEDIATE and_{~INTERMEDIATE{0}};
+};
+
+template <typename INTERMEDIATE> class IntegerOrAccumulator {
+public:
+ explicit IntegerOrAccumulator(const Descriptor &array) : array_{array} {}
+ void Reinitialize() { or_ = 0; }
+ template <typename A> void GetResult(A *p, int /*zeroBasedDim*/ = -1) const {
+ *p = static_cast<A>(or_);
+ }
+ template <typename A> bool AccumulateAt(const SubscriptValue at[]) {
+ or_ |= *array_.Element<A>(at);
+ return true;
+ }
+
+private:
+ const Descriptor &array_;
+ INTERMEDIATE or_{0};
+};
template <typename INTERMEDIATE> class IntegerXorAccumulator {
public:
@@ -41,6 +75,82 @@ template <typename INTERMEDIATE> class IntegerXorAccumulator {
};
extern "C" {
+CppTypeFor<TypeCategory::Integer, 1> RTNAME(IAll1)(const Descriptor &x,
+ const char *source, int line, int dim, const Descriptor *mask) {
+ return GetTotalReduction<TypeCategory::Integer, 1>(x, source, line, dim, mask,
+ IntegerAndAccumulator<CppTypeFor<TypeCategory::Integer, 4>>{x}, "IALL");
+}
+CppTypeFor<TypeCategory::Integer, 2> RTNAME(IAll2)(const Descriptor &x,
+ const char *source, int line, int dim, const Descriptor *mask) {
+ return GetTotalReduction<TypeCategory::Integer, 2>(x, source, line, dim, mask,
+ IntegerAndAccumulator<CppTypeFor<TypeCategory::Integer, 4>>{x}, "IALL");
+}
+CppTypeFor<TypeCategory::Integer, 4> RTNAME(IAll4)(const Descriptor &x,
+ const char *source, int line, int dim, const Descriptor *mask) {
+ return GetTotalReduction<TypeCategory::Integer, 4>(x, source, line, dim, mask,
+ IntegerAndAccumulator<CppTypeFor<TypeCategory::Integer, 4>>{x}, "IALL");
+}
+CppTypeFor<TypeCategory::Integer, 8> RTNAME(IAll8)(const Descriptor &x,
+ const char *source, int line, int dim, const Descriptor *mask) {
+ return GetTotalReduction<TypeCategory::Integer, 8>(x, source, line, dim, mask,
+ IntegerAndAccumulator<CppTypeFor<TypeCategory::Integer, 8>>{x}, "IALL");
+}
+#ifdef __SIZEOF_INT128__
+CppTypeFor<TypeCategory::Integer, 16> RTNAME(IAll16)(const Descriptor &x,
+ const char *source, int line, int dim, const Descriptor *mask) {
+ return GetTotalReduction<TypeCategory::Integer, 16>(x, source, line, dim,
+ mask, IntegerAndAccumulator<CppTypeFor<TypeCategory::Integer, 16>>{x},
+ "IALL");
+}
+#endif
+void RTNAME(IAllDim)(Descriptor &result, const Descriptor &x, int dim,
+ const char *source, int line, const Descriptor *mask) {
+ Terminator terminator{source, line};
+ auto catKind{x.type().GetCategoryAndKind()};
+ RUNTIME_CHECK(terminator,
+ catKind.has_value() && catKind->first == TypeCategory::Integer);
+ PartialIntegerReduction<IntegerAndAccumulator>(
+ result, x, dim, catKind->second, mask, "IALL", terminator);
+}
+
+CppTypeFor<TypeCategory::Integer, 1> RTNAME(IAny1)(const Descriptor &x,
+ const char *source, int line, int dim, const Descriptor *mask) {
+ return GetTotalReduction<TypeCategory::Integer, 1>(x, source, line, dim, mask,
+ IntegerOrAccumulator<CppTypeFor<TypeCategory::Integer, 4>>{x}, "IANY");
+}
+CppTypeFor<TypeCategory::Integer, 2> RTNAME(IAny2)(const Descriptor &x,
+ const char *source, int line, int dim, const Descriptor *mask) {
+ return GetTotalReduction<TypeCategory::Integer, 2>(x, source, line, dim, mask,
+ IntegerOrAccumulator<CppTypeFor<TypeCategory::Integer, 4>>{x}, "IANY");
+}
+CppTypeFor<TypeCategory::Integer, 4> RTNAME(IAny4)(const Descriptor &x,
+ const char *source, int line, int dim, const Descriptor *mask) {
+ return GetTotalReduction<TypeCategory::Integer, 4>(x, source, line, dim, mask,
+ IntegerOrAccumulator<CppTypeFor<TypeCategory::Integer, 4>>{x}, "IANY");
+}
+CppTypeFor<TypeCategory::Integer, 8> RTNAME(IAny8)(const Descriptor &x,
+ const char *source, int line, int dim, const Descriptor *mask) {
+ return GetTotalReduction<TypeCategory::Integer, 8>(x, source, line, dim, mask,
+ IntegerOrAccumulator<CppTypeFor<TypeCategory::Integer, 8>>{x}, "IANY");
+}
+#ifdef __SIZEOF_INT128__
+CppTypeFor<TypeCategory::Integer, 16> RTNAME(IAny16)(const Descriptor &x,
+ const char *source, int line, int dim, const Descriptor *mask) {
+ return GetTotalReduction<TypeCategory::Integer, 16>(x, source, line, dim,
+ mask, IntegerOrAccumulator<CppTypeFor<TypeCategory::Integer, 16>>{x},
+ "IANY");
+}
+#endif
+void RTNAME(IAnyDim)(Descriptor &result, const Descriptor &x, int dim,
+ const char *source, int line, const Descriptor *mask) {
+ Terminator terminator{source, line};
+ auto catKind{x.type().GetCategoryAndKind()};
+ RUNTIME_CHECK(terminator,
+ catKind.has_value() && catKind->first == TypeCategory::Integer);
+ PartialIntegerReduction<IntegerOrAccumulator>(
+ result, x, dim, catKind->second, mask, "IANY", terminator);
+}
+
CppTypeFor<TypeCategory::Integer, 1> RTNAME(IParity1)(const Descriptor &x,
const char *source, int line, int dim, const Descriptor *mask) {
return GetTotalReduction<TypeCategory::Integer, 1>(x, source, line, dim, mask,
diff --git a/flang/runtime/reduction.h b/flang/runtime/reduction.h
index 379fcb85cd1c..a52a921b6109 100644
--- a/flang/runtime/reduction.h
+++ b/flang/runtime/reduction.h
@@ -141,7 +141,37 @@ void RTNAME(CppProductComplex16)(std::complex<long double> &,
void RTNAME(ProductDim)(Descriptor &result, const Descriptor &array, int dim,
const char *source, int line, const Descriptor *mask = nullptr);
-// IPARITY()
+// IALL, IANY, IPARITY
+std::int8_t RTNAME(IAll1)(const Descriptor &, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr);
+std::int16_t RTNAME(IAll2)(const Descriptor &, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr);
+std::int32_t RTNAME(IAll4)(const Descriptor &, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr);
+std::int64_t RTNAME(IAll8)(const Descriptor &, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr);
+#ifdef __SIZEOF_INT128__
+common::int128_t RTNAME(IAll16)(const Descriptor &, const char *source,
+ int line, int dim = 0, const Descriptor *mask = nullptr);
+#endif
+void RTNAME(IAllDim)(Descriptor &result, const Descriptor &array, int dim,
+ const char *source, int line, const Descriptor *mask = nullptr);
+
+std::int8_t RTNAME(IAny1)(const Descriptor &, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr);
+std::int16_t RTNAME(IAny2)(const Descriptor &, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr);
+std::int32_t RTNAME(IAny4)(const Descriptor &, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr);
+std::int64_t RTNAME(IAny8)(const Descriptor &, const char *source, int line,
+ int dim = 0, const Descriptor *mask = nullptr);
+#ifdef __SIZEOF_INT128__
+common::int128_t RTNAME(IAny16)(const Descriptor &, const char *source,
+ int line, int dim = 0, const Descriptor *mask = nullptr);
+#endif
+void RTNAME(IAnyDim)(Descriptor &result, const Descriptor &array, int dim,
+ const char *source, int line, const Descriptor *mask = nullptr);
+
std::int8_t RTNAME(IParity1)(const Descriptor &, const char *source, int line,
int dim = 0, const Descriptor *mask = nullptr);
std::int16_t RTNAME(IParity2)(const Descriptor &, const char *source, int line,
diff --git a/flang/unittests/RuntimeGTest/Reduction.cpp b/flang/unittests/RuntimeGTest/Reduction.cpp
index 4c01cf468bcb..617131c6f227 100644
--- a/flang/unittests/RuntimeGTest/Reduction.cpp
+++ b/flang/unittests/RuntimeGTest/Reduction.cpp
@@ -21,11 +21,17 @@
using namespace Fortran::runtime;
using Fortran::common::TypeCategory;
-TEST(Reductions, SumInt4) {
+TEST(Reductions, Int4Ops) {
auto array{MakeArray<TypeCategory::Integer, 4>(
std::vector<int>{2, 3}, std::vector<std::int32_t>{1, 2, 3, 4, 5, 6})};
std::int32_t sum{RTNAME(SumInteger4)(*array, __FILE__, __LINE__)};
EXPECT_EQ(sum, 21) << sum;
+ std::int32_t all{RTNAME(IAll4)(*array, __FILE__, __LINE__)};
+ EXPECT_EQ(all, 0) << all;
+ std::int32_t any{RTNAME(IAny4)(*array, __FILE__, __LINE__)};
+ EXPECT_EQ(any, 7) << any;
+ std::int32_t eor{RTNAME(IParity4)(*array, __FILE__, __LINE__)};
+ EXPECT_EQ(eor, 7) << eor;
}
TEST(Reductions, DimMaskProductInt4) {
More information about the flang-commits
mailing list