From a1034022888cadca5f2a4700f60beda4f7053c08 Mon Sep 17 00:00:00 2001 From: Mark Leair Date: Thu, 24 Jun 2021 16:55:45 -0700 Subject: [PATCH] Change the flang reshape runtime routine interface to use a result argument instead of a result result object. Change the reshape flang unit test to use the new interface. Also, add an order argument to exercise the order subscript code in the rehsape runtime routine. Differential Revision: https://reviews.llvm.org/D104586 --- flang/runtime/transformational.cpp | 56 +++++++++--------------------------- flang/runtime/transformational.h | 7 ++--- flang/unittests/Evaluate/reshape.cpp | 18 +++++++++--- 3 files changed, 30 insertions(+), 51 deletions(-) diff --git a/flang/runtime/transformational.cpp b/flang/runtime/transformational.cpp index bf3618b..a6e4400 100644 --- a/flang/runtime/transformational.cpp +++ b/flang/runtime/transformational.cpp @@ -350,9 +350,9 @@ void RTNAME(Pack)(Descriptor &result, const Descriptor &source, } } -} // extern "C" - TODO put Reshape under extern "C" +// RESHAPE // F2018 16.9.163 -OwningPtr RTNAME(Reshape)(const Descriptor &source, +void RTNAME(Reshape)(Descriptor &result, const Descriptor &source, const Descriptor &shape, const Descriptor *pad, const Descriptor *order, const char *sourceFile, int line) { // Compute and check the rank of the result. @@ -394,9 +394,10 @@ OwningPtr RTNAME(Reshape)(const Descriptor &source, RUNTIME_CHECK(terminator, order->GetDimension(0).Extent() == resultRank); std::uint64_t values{0}; SubscriptValue orderSubscript{order->GetDimension(0).LowerBound()}; + std::size_t orderElementBytes{order->ElementBytes()}; for (SubscriptValue j{0}; j < resultRank; ++j, ++orderSubscript) { - auto k{GetInt64(order->OffsetElement(orderSubscript), - shapeElementBytes, terminator)}; + auto k{GetInt64(order->Element(&orderSubscript), orderElementBytes, + terminator)}; RUNTIME_CHECK( terminator, k >= 1 && k <= resultRank && !((values >> k) & 1)); values |= std::uint64_t{1} << k; @@ -408,64 +409,33 @@ OwningPtr RTNAME(Reshape)(const Descriptor &source, } } - // Create and populate the result's descriptor. - const DescriptorAddendum *sourceAddendum{source.Addendum()}; - const typeInfo::DerivedType *sourceDerivedType{ - sourceAddendum ? sourceAddendum->derivedType() : nullptr}; - OwningPtr result; - if (sourceDerivedType) { - result = Descriptor::Create(*sourceDerivedType, nullptr, resultRank, - resultExtent, CFI_attribute_allocatable); - } else { - result = Descriptor::Create(source.type(), elementBytes, nullptr, - resultRank, resultExtent, - CFI_attribute_allocatable); // TODO rearrange these arguments - } - DescriptorAddendum *resultAddendum{result->Addendum()}; - RUNTIME_CHECK(terminator, resultAddendum); - resultAddendum->flags() |= DescriptorAddendum::DoNotFinalize; - if (sourceDerivedType) { - std::size_t lenParameters{sourceAddendum->LenParameters()}; - for (std::size_t j{0}; j < lenParameters; ++j) { - resultAddendum->SetLenParameterValue( - j, sourceAddendum->LenParameterValue(j)); - } - } - // Allocate storage for the result's data. - for (int j{0}; j < resultRank; ++j) { - result->GetDimension(j).SetBounds(1, resultExtent[j]); - } - int status{result->Allocate()}; - if (status != CFI_SUCCESS) { - terminator.Crash("RESHAPE: Allocate failed (error %d)", status); - } + // Allocate result descriptor + AllocateResult( + result, source, resultRank, resultExtent, terminator, "RESHAPE"); // Populate the result's elements. SubscriptValue resultSubscript[maxRank]; - result->GetLowerBounds(resultSubscript); + result.GetLowerBounds(resultSubscript); SubscriptValue sourceSubscript[maxRank]; source.GetLowerBounds(sourceSubscript); std::size_t resultElement{0}; std::size_t elementsFromSource{std::min(resultElements, sourceElements)}; for (; resultElement < elementsFromSource; ++resultElement) { - CopyElement(*result, resultSubscript, source, sourceSubscript, terminator); + CopyElement(result, resultSubscript, source, sourceSubscript, terminator); source.IncrementSubscripts(sourceSubscript); - result->IncrementSubscripts(resultSubscript, dimOrder); + result.IncrementSubscripts(resultSubscript, dimOrder); } if (resultElement < resultElements) { // Remaining elements come from the optional PAD= argument. SubscriptValue padSubscript[maxRank]; pad->GetLowerBounds(padSubscript); for (; resultElement < resultElements; ++resultElement) { - CopyElement(*result, resultSubscript, *pad, padSubscript, terminator); + CopyElement(result, resultSubscript, *pad, padSubscript, terminator); pad->IncrementSubscripts(padSubscript); - result->IncrementSubscripts(resultSubscript, dimOrder); + result.IncrementSubscripts(resultSubscript, dimOrder); } } - - return result; } -extern "C" { // TODO - remove when Reshape is under extern "C" // SPREAD void RTNAME(Spread)(Descriptor &result, const Descriptor &source, int dim, diff --git a/flang/runtime/transformational.h b/flang/runtime/transformational.h index 97d5664..08f2d9a 100644 --- a/flang/runtime/transformational.h +++ b/flang/runtime/transformational.h @@ -23,14 +23,13 @@ namespace Fortran::runtime { -// TODO: redo API, put under extern "C" -OwningPtr RTNAME(Reshape)(const Descriptor &source, +extern "C" { + +void RTNAME(Reshape)(Descriptor &result, const Descriptor &source, const Descriptor &shape, const Descriptor *pad = nullptr, const Descriptor *order = nullptr, const char *sourceFile = nullptr, int line = 0); -extern "C" { - void RTNAME(Cshift)(Descriptor &result, const Descriptor &source, const Descriptor &shift, int dim = 1, const char *sourceFile = nullptr, int line = 0); diff --git a/flang/unittests/Evaluate/reshape.cpp b/flang/unittests/Evaluate/reshape.cpp index 719d220..b4c1eff 100644 --- a/flang/unittests/Evaluate/reshape.cpp +++ b/flang/unittests/Evaluate/reshape.cpp @@ -53,10 +53,22 @@ int main() { MATCH(2, pad.GetDimension(0).Extent()); MATCH(2, pad.GetDimension(1).Extent()); MATCH(3, pad.GetDimension(2).Extent()); + StaticDescriptor<1> orderDescriptor; + Descriptor &order{orderDescriptor.descriptor()}; + static const std::int32_t orderData[]{1, 2}; + static const SubscriptValue orderExtent[]{2}; + order.Establish(TypeCategory::Integer, static_cast(sizeof orderData[0]), + const_cast(reinterpret_cast(orderData)), 1, + orderExtent, CFI_attribute_pointer); + orderDescriptor.Check(); + order.Check(); + MATCH(1, order.rank()); + MATCH(2, order.GetDimension(0).Extent()); - auto result{ - RTNAME(Reshape)(*source, *shape, &pad, nullptr, __FILE__, __LINE__)}; + auto result{Descriptor::Create(TypeCategory::Integer, sizeof(std::int32_t), + nullptr, 2, nullptr, CFI_attribute_allocatable)}; TEST(result.get() != nullptr); + RTNAME(Reshape)(*result, *source, *shape, &pad, &order, __FILE__, __LINE__); result->Check(); MATCH(sizeof(std::int32_t), result->ElementBytes()); MATCH(2, result->rank()); @@ -69,7 +81,5 @@ int main() { MATCH(j, *result->Element(ss)); } - // TODO: test ORDER= - return testing::Complete(); } -- 2.7.4