forked from OSchip/llvm-project
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
This commit is contained in:
parent
d6a91f6c56
commit
a103402288
|
@ -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<Descriptor> 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<Descriptor> 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<char>(orderSubscript),
|
||||
shapeElementBytes, terminator)};
|
||||
auto k{GetInt64(order->Element<char>(&orderSubscript), orderElementBytes,
|
||||
terminator)};
|
||||
RUNTIME_CHECK(
|
||||
terminator, k >= 1 && k <= resultRank && !((values >> k) & 1));
|
||||
values |= std::uint64_t{1} << k;
|
||||
|
@ -408,64 +409,33 @@ OwningPtr<Descriptor> 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<Descriptor> 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,
|
||||
|
|
|
@ -23,14 +23,13 @@
|
|||
|
||||
namespace Fortran::runtime {
|
||||
|
||||
// TODO: redo API, put under extern "C"
|
||||
OwningPtr<Descriptor> 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);
|
||||
|
|
|
@ -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<int>(sizeof orderData[0]),
|
||||
const_cast<void *>(reinterpret_cast<const void *>(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<std::int32_t>(ss));
|
||||
}
|
||||
|
||||
// TODO: test ORDER=
|
||||
|
||||
return testing::Complete();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue