Skip to content

Commit a103402

Browse files
committed
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
1 parent d6a91f6 commit a103402

File tree

3 files changed

+30
-51
lines changed

3 files changed

+30
-51
lines changed

flang/runtime/transformational.cpp

Lines changed: 13 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -350,9 +350,9 @@ void RTNAME(Pack)(Descriptor &result, const Descriptor &source,
350350
}
351351
}
352352

353-
} // extern "C" - TODO put Reshape under extern "C"
353+
// RESHAPE
354354
// F2018 16.9.163
355-
OwningPtr<Descriptor> RTNAME(Reshape)(const Descriptor &source,
355+
void RTNAME(Reshape)(Descriptor &result, const Descriptor &source,
356356
const Descriptor &shape, const Descriptor *pad, const Descriptor *order,
357357
const char *sourceFile, int line) {
358358
// Compute and check the rank of the result.
@@ -394,9 +394,10 @@ OwningPtr<Descriptor> RTNAME(Reshape)(const Descriptor &source,
394394
RUNTIME_CHECK(terminator, order->GetDimension(0).Extent() == resultRank);
395395
std::uint64_t values{0};
396396
SubscriptValue orderSubscript{order->GetDimension(0).LowerBound()};
397+
std::size_t orderElementBytes{order->ElementBytes()};
397398
for (SubscriptValue j{0}; j < resultRank; ++j, ++orderSubscript) {
398-
auto k{GetInt64(order->OffsetElement<char>(orderSubscript),
399-
shapeElementBytes, terminator)};
399+
auto k{GetInt64(order->Element<char>(&orderSubscript), orderElementBytes,
400+
terminator)};
400401
RUNTIME_CHECK(
401402
terminator, k >= 1 && k <= resultRank && !((values >> k) & 1));
402403
values |= std::uint64_t{1} << k;
@@ -408,64 +409,33 @@ OwningPtr<Descriptor> RTNAME(Reshape)(const Descriptor &source,
408409
}
409410
}
410411

411-
// Create and populate the result's descriptor.
412-
const DescriptorAddendum *sourceAddendum{source.Addendum()};
413-
const typeInfo::DerivedType *sourceDerivedType{
414-
sourceAddendum ? sourceAddendum->derivedType() : nullptr};
415-
OwningPtr<Descriptor> result;
416-
if (sourceDerivedType) {
417-
result = Descriptor::Create(*sourceDerivedType, nullptr, resultRank,
418-
resultExtent, CFI_attribute_allocatable);
419-
} else {
420-
result = Descriptor::Create(source.type(), elementBytes, nullptr,
421-
resultRank, resultExtent,
422-
CFI_attribute_allocatable); // TODO rearrange these arguments
423-
}
424-
DescriptorAddendum *resultAddendum{result->Addendum()};
425-
RUNTIME_CHECK(terminator, resultAddendum);
426-
resultAddendum->flags() |= DescriptorAddendum::DoNotFinalize;
427-
if (sourceDerivedType) {
428-
std::size_t lenParameters{sourceAddendum->LenParameters()};
429-
for (std::size_t j{0}; j < lenParameters; ++j) {
430-
resultAddendum->SetLenParameterValue(
431-
j, sourceAddendum->LenParameterValue(j));
432-
}
433-
}
434-
// Allocate storage for the result's data.
435-
for (int j{0}; j < resultRank; ++j) {
436-
result->GetDimension(j).SetBounds(1, resultExtent[j]);
437-
}
438-
int status{result->Allocate()};
439-
if (status != CFI_SUCCESS) {
440-
terminator.Crash("RESHAPE: Allocate failed (error %d)", status);
441-
}
412+
// Allocate result descriptor
413+
AllocateResult(
414+
result, source, resultRank, resultExtent, terminator, "RESHAPE");
442415

443416
// Populate the result's elements.
444417
SubscriptValue resultSubscript[maxRank];
445-
result->GetLowerBounds(resultSubscript);
418+
result.GetLowerBounds(resultSubscript);
446419
SubscriptValue sourceSubscript[maxRank];
447420
source.GetLowerBounds(sourceSubscript);
448421
std::size_t resultElement{0};
449422
std::size_t elementsFromSource{std::min(resultElements, sourceElements)};
450423
for (; resultElement < elementsFromSource; ++resultElement) {
451-
CopyElement(*result, resultSubscript, source, sourceSubscript, terminator);
424+
CopyElement(result, resultSubscript, source, sourceSubscript, terminator);
452425
source.IncrementSubscripts(sourceSubscript);
453-
result->IncrementSubscripts(resultSubscript, dimOrder);
426+
result.IncrementSubscripts(resultSubscript, dimOrder);
454427
}
455428
if (resultElement < resultElements) {
456429
// Remaining elements come from the optional PAD= argument.
457430
SubscriptValue padSubscript[maxRank];
458431
pad->GetLowerBounds(padSubscript);
459432
for (; resultElement < resultElements; ++resultElement) {
460-
CopyElement(*result, resultSubscript, *pad, padSubscript, terminator);
433+
CopyElement(result, resultSubscript, *pad, padSubscript, terminator);
461434
pad->IncrementSubscripts(padSubscript);
462-
result->IncrementSubscripts(resultSubscript, dimOrder);
435+
result.IncrementSubscripts(resultSubscript, dimOrder);
463436
}
464437
}
465-
466-
return result;
467438
}
468-
extern "C" { // TODO - remove when Reshape is under extern "C"
469439

470440
// SPREAD
471441
void RTNAME(Spread)(Descriptor &result, const Descriptor &source, int dim,

flang/runtime/transformational.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,13 @@
2323

2424
namespace Fortran::runtime {
2525

26-
// TODO: redo API, put under extern "C"
27-
OwningPtr<Descriptor> RTNAME(Reshape)(const Descriptor &source,
26+
extern "C" {
27+
28+
void RTNAME(Reshape)(Descriptor &result, const Descriptor &source,
2829
const Descriptor &shape, const Descriptor *pad = nullptr,
2930
const Descriptor *order = nullptr, const char *sourceFile = nullptr,
3031
int line = 0);
3132

32-
extern "C" {
33-
3433
void RTNAME(Cshift)(Descriptor &result, const Descriptor &source,
3534
const Descriptor &shift, int dim = 1, const char *sourceFile = nullptr,
3635
int line = 0);

flang/unittests/Evaluate/reshape.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,22 @@ int main() {
5353
MATCH(2, pad.GetDimension(0).Extent());
5454
MATCH(2, pad.GetDimension(1).Extent());
5555
MATCH(3, pad.GetDimension(2).Extent());
56+
StaticDescriptor<1> orderDescriptor;
57+
Descriptor &order{orderDescriptor.descriptor()};
58+
static const std::int32_t orderData[]{1, 2};
59+
static const SubscriptValue orderExtent[]{2};
60+
order.Establish(TypeCategory::Integer, static_cast<int>(sizeof orderData[0]),
61+
const_cast<void *>(reinterpret_cast<const void *>(orderData)), 1,
62+
orderExtent, CFI_attribute_pointer);
63+
orderDescriptor.Check();
64+
order.Check();
65+
MATCH(1, order.rank());
66+
MATCH(2, order.GetDimension(0).Extent());
5667

57-
auto result{
58-
RTNAME(Reshape)(*source, *shape, &pad, nullptr, __FILE__, __LINE__)};
68+
auto result{Descriptor::Create(TypeCategory::Integer, sizeof(std::int32_t),
69+
nullptr, 2, nullptr, CFI_attribute_allocatable)};
5970
TEST(result.get() != nullptr);
71+
RTNAME(Reshape)(*result, *source, *shape, &pad, &order, __FILE__, __LINE__);
6072
result->Check();
6173
MATCH(sizeof(std::int32_t), result->ElementBytes());
6274
MATCH(2, result->rank());
@@ -69,7 +81,5 @@ int main() {
6981
MATCH(j, *result->Element<std::int32_t>(ss));
7082
}
7183

72-
// TODO: test ORDER=
73-
7484
return testing::Complete();
7585
}

0 commit comments

Comments
 (0)