[flang-commits] [flang] 1dbc9b5 - Fix runtime internal error with certain intrinsics that can take a scalar
Mark Leair via flang-commits
flang-commits at lists.llvm.org
Thu Jul 29 13:10:02 PDT 2021
Author: Mark Leair
Date: 2021-07-29T13:08:41-07:00
New Revision: 1dbc9b534b2a4903af0f98bde72b8f6da797bc19
URL: https://github.com/llvm/llvm-project/commit/1dbc9b534b2a4903af0f98bde72b8f6da797bc19
DIFF: https://github.com/llvm/llvm-project/commit/1dbc9b534b2a4903af0f98bde72b8f6da797bc19.diff
LOG: Fix runtime internal error with certain intrinsics that can take a scalar
result descriptor (e.g., maxloc, minloc, maxval, minval, all, any, count,
parity, findloc, etc.)
Also add a scalar case for these intrinsic unit tests.
Differential Revision: https://reviews.llvm.org/D106820
Added:
Modified:
flang/runtime/reduction-templates.h
flang/runtime/reduction.cpp
flang/unittests/RuntimeGTest/Reduction.cpp
Removed:
################################################################################
diff --git a/flang/runtime/reduction-templates.h b/flang/runtime/reduction-templates.h
index 3f77ac0dfb300..ff9841a9e4756 100644
--- a/flang/runtime/reduction-templates.h
+++ b/flang/runtime/reduction-templates.h
@@ -197,7 +197,7 @@ inline void PartialReduction(Descriptor &result, const Descriptor &x, int dim,
result, x, dim, terminator, intrinsic, TypeCode{CAT, KIND});
SubscriptValue at[maxRank];
result.GetLowerBounds(at);
- INTERNAL_CHECK(at[0] == 1);
+ INTERNAL_CHECK(result.rank() == 0 || at[0] == 1);
using CppType = CppTypeFor<CAT, KIND>;
if (mask) {
CheckConformability(x, *mask, terminator, intrinsic, "ARRAY", "MASK");
diff --git a/flang/runtime/reduction.cpp b/flang/runtime/reduction.cpp
index f5f6abff9b28e..66fe9efa56222 100644
--- a/flang/runtime/reduction.cpp
+++ b/flang/runtime/reduction.cpp
@@ -267,7 +267,7 @@ template <LogicalReduction REDUCTION> struct LogicalReduceHelper {
result, x, dim, terminator, intrinsic, x.type());
SubscriptValue at[maxRank];
result.GetLowerBounds(at);
- INTERNAL_CHECK(at[0] == 1);
+ INTERNAL_CHECK(result.rank() == 0 || at[0] == 1);
using CppType = CppTypeFor<TypeCategory::Logical, KIND>;
for (auto n{result.Elements()}; n-- > 0; result.IncrementSubscripts(at)) {
*result.Element<CppType>(at) =
@@ -315,7 +315,7 @@ template <int KIND> struct CountDimension {
TypeCode{TypeCategory::Integer, KIND});
SubscriptValue at[maxRank];
result.GetLowerBounds(at);
- INTERNAL_CHECK(at[0] == 1);
+ INTERNAL_CHECK(result.rank() == 0 || at[0] == 1);
using CppType = CppTypeFor<TypeCategory::Integer, KIND>;
for (auto n{result.Elements()}; n-- > 0; result.IncrementSubscripts(at)) {
*result.Element<CppType>(at) =
diff --git a/flang/unittests/RuntimeGTest/Reduction.cpp b/flang/unittests/RuntimeGTest/Reduction.cpp
index 617131c6f2273..1750b914f0f88 100644
--- a/flang/unittests/RuntimeGTest/Reduction.cpp
+++ b/flang/unittests/RuntimeGTest/Reduction.cpp
@@ -146,6 +146,34 @@ TEST(Reductions, DoubleMaxMinNorm2) {
EXPECT_EQ(*loc.ZeroBasedIndexedElement<std::int16_t>(10), 2); // 22
EXPECT_EQ(*loc.ZeroBasedIndexedElement<std::int16_t>(11), 2); // 22
loc.Destroy();
+ // Test scalar result for MaxlocDim, MinlocDim, MaxvalDim, MinvalDim.
+ // A scalar result occurs when you have a rank 1 array and dim == 1.
+ std::vector<int> shape1{24};
+ auto array1{MakeArray<TypeCategory::Real, 8>(shape1, rawData)};
+ StaticDescriptor<0, true> statDesc0;
+ Descriptor &scalarResult{statDesc0.descriptor()};
+ RTNAME(MaxlocDim)
+ (scalarResult, *array1, /*KIND=*/2, /*DIM=*/1, __FILE__, __LINE__,
+ /*MASK=*/nullptr, /*BACK=*/false);
+ EXPECT_EQ(scalarResult.rank(), 0);
+ EXPECT_EQ(*scalarResult.ZeroBasedIndexedElement<std::int16_t>(0), 23);
+ scalarResult.Destroy();
+ RTNAME(MinlocDim)
+ (scalarResult, *array1, /*KIND=*/2, /*DIM=*/1, __FILE__, __LINE__,
+ /*MASK=*/nullptr, /*BACK=*/true);
+ EXPECT_EQ(scalarResult.rank(), 0);
+ EXPECT_EQ(*scalarResult.ZeroBasedIndexedElement<std::int16_t>(0), 22);
+ scalarResult.Destroy();
+ RTNAME(MaxvalDim)
+ (scalarResult, *array1, /*DIM=*/1, __FILE__, __LINE__, /*MASK=*/nullptr);
+ EXPECT_EQ(scalarResult.rank(), 0);
+ EXPECT_EQ(*scalarResult.ZeroBasedIndexedElement<double>(0), 22.0);
+ scalarResult.Destroy();
+ RTNAME(MinvalDim)
+ (scalarResult, *array1, /*DIM=*/1, __FILE__, __LINE__, /*MASK=*/nullptr);
+ EXPECT_EQ(scalarResult.rank(), 0);
+ EXPECT_EQ(*scalarResult.ZeroBasedIndexedElement<double>(0), -21.0);
+ scalarResult.Destroy();
}
TEST(Reductions, Character) {
@@ -269,6 +297,17 @@ TEST(Reductions, Logical) {
EXPECT_EQ(*res.ZeroBasedIndexedElement<std::int32_t>(0), 0);
EXPECT_EQ(*res.ZeroBasedIndexedElement<std::int32_t>(1), 0);
res.Destroy();
+ // Test scalar result for AllDim.
+ // A scalar result occurs when you have a rank 1 array.
+ std::vector<int> shape1{4};
+ auto array1{MakeArray<TypeCategory::Logical, 4>(
+ shape1, std::vector<std::int32_t>{false, false, true, true})};
+ StaticDescriptor<0, true> statDesc0;
+ Descriptor &scalarResult{statDesc0.descriptor()};
+ RTNAME(AllDim)(scalarResult, *array1, /*DIM=*/1, __FILE__, __LINE__);
+ EXPECT_EQ(scalarResult.rank(), 0);
+ EXPECT_EQ(*scalarResult.ZeroBasedIndexedElement<std::int64_t>(0), 0);
+ scalarResult.Destroy();
RTNAME(AnyDim)(res, *array, /*DIM=*/1, __FILE__, __LINE__);
EXPECT_EQ(res.rank(), 1);
EXPECT_EQ(res.type().raw(), (TypeCode{TypeCategory::Logical, 4}.raw()));
@@ -285,6 +324,12 @@ TEST(Reductions, Logical) {
EXPECT_EQ(*res.ZeroBasedIndexedElement<std::int32_t>(0), 1);
EXPECT_EQ(*res.ZeroBasedIndexedElement<std::int32_t>(1), 1);
res.Destroy();
+ // Test scalar result for AnyDim.
+ // A scalar result occurs when you have a rank 1 array.
+ RTNAME(AnyDim)(scalarResult, *array1, /*DIM=*/1, __FILE__, __LINE__);
+ EXPECT_EQ(scalarResult.rank(), 0);
+ EXPECT_EQ(*scalarResult.ZeroBasedIndexedElement<std::int64_t>(0), 1);
+ scalarResult.Destroy();
RTNAME(ParityDim)(res, *array, /*DIM=*/1, __FILE__, __LINE__);
EXPECT_EQ(res.rank(), 1);
EXPECT_EQ(res.type().raw(), (TypeCode{TypeCategory::Logical, 4}.raw()));
@@ -301,6 +346,12 @@ TEST(Reductions, Logical) {
EXPECT_EQ(*res.ZeroBasedIndexedElement<std::int32_t>(0), 1);
EXPECT_EQ(*res.ZeroBasedIndexedElement<std::int32_t>(1), 1);
res.Destroy();
+ // Test scalar result for ParityDim.
+ // A scalar result occurs when you have a rank 1 array.
+ RTNAME(ParityDim)(scalarResult, *array1, /*DIM=*/1, __FILE__, __LINE__);
+ EXPECT_EQ(scalarResult.rank(), 0);
+ EXPECT_EQ(*scalarResult.ZeroBasedIndexedElement<std::int32_t>(0), 0);
+ scalarResult.Destroy();
RTNAME(CountDim)(res, *array, /*DIM=*/1, /*KIND=*/4, __FILE__, __LINE__);
EXPECT_EQ(res.rank(), 1);
EXPECT_EQ(res.type().raw(), (TypeCode{TypeCategory::Integer, 4}.raw()));
@@ -317,6 +368,13 @@ TEST(Reductions, Logical) {
EXPECT_EQ(*res.ZeroBasedIndexedElement<std::int64_t>(0), 1);
EXPECT_EQ(*res.ZeroBasedIndexedElement<std::int64_t>(1), 1);
res.Destroy();
+ // Test scalar result for CountDim.
+ // A scalar result occurs when you have a rank 1 array and dim == 1.
+ RTNAME(CountDim)
+ (scalarResult, *array1, /*DIM=*/1, /*KIND=*/8, __FILE__, __LINE__);
+ EXPECT_EQ(scalarResult.rank(), 0);
+ EXPECT_EQ(*scalarResult.ZeroBasedIndexedElement<std::int64_t>(0), 2);
+ scalarResult.Destroy();
bool boolValue{false};
Descriptor &target{statDesc[1].descriptor()};
target.Establish(TypeCategory::Logical, 1, static_cast<void *>(&boolValue), 0,
@@ -436,6 +494,21 @@ TEST(Reductions, FindlocNumeric) {
EXPECT_EQ(*res.ZeroBasedIndexedElement<SubscriptValue>(0), 2);
EXPECT_EQ(*res.ZeroBasedIndexedElement<SubscriptValue>(1), 0);
res.Destroy();
+ // Test scalar result for FindlocDim.
+ // A scalar result occurs when you have a rank 1 array, value, and dim == 1.
+ std::vector<int> shape1{6};
+ auto realArray1{MakeArray<TypeCategory::Real, 8>(shape1,
+ std::vector<double>{0.0, -0.0, 1.0, 3.14,
+ std::numeric_limits<double>::quiet_NaN(),
+ std::numeric_limits<double>::infinity()})};
+ StaticDescriptor<0, true> statDesc0;
+ Descriptor &scalarResult{statDesc0.descriptor()};
+ RTNAME(FindlocDim)
+ (scalarResult, *realArray1, target, 8, /*DIM=*/1, __FILE__, __LINE__, nullptr,
+ /*BACK=*/false);
+ EXPECT_EQ(scalarResult.rank(), 0);
+ EXPECT_EQ(*scalarResult.ZeroBasedIndexedElement<SubscriptValue>(0), 3);
+ scalarResult.Destroy();
}
TEST(Reductions, DotProduct) {
More information about the flang-commits
mailing list