Skip to content

Commit 9839ae6

Browse files
authored
Merge branch 'main' into users/rampitec/08-05-_amdgpu_add_gfx1250_wmma_scale_16__f32_32x16x128_f4_instructions
2 parents b86e38e + 8676027 commit 9839ae6

File tree

17 files changed

+407
-32
lines changed

17 files changed

+407
-32
lines changed

flang-rt/include/flang-rt/runtime/descriptor.h

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ class DescriptorAddendum {
101101
explicit RT_API_ATTRS DescriptorAddendum(
102102
const typeInfo::DerivedType *dt = nullptr)
103103
: derivedType_{dt}, len_{0} {}
104+
RT_API_ATTRS DescriptorAddendum(const DescriptorAddendum &that) {
105+
*this = that;
106+
}
104107
RT_API_ATTRS DescriptorAddendum &operator=(const DescriptorAddendum &);
105108

106109
RT_API_ATTRS const typeInfo::DerivedType *derivedType() const {
@@ -181,6 +184,9 @@ class Descriptor {
181184
const SubscriptValue *extent = nullptr,
182185
ISO::CFI_attribute_t attribute = CFI_attribute_other);
183186

187+
RT_API_ATTRS void UncheckedScalarEstablish(
188+
const typeInfo::DerivedType &, void *);
189+
184190
// To create a descriptor for a derived type the caller
185191
// must provide non-null dt argument.
186192
// The addendum argument is only used for testing purposes,
@@ -433,7 +439,9 @@ class Descriptor {
433439
bool stridesAreContiguous{true};
434440
for (int j{0}; j < leadingDimensions; ++j) {
435441
const Dimension &dim{GetDimension(j)};
436-
stridesAreContiguous &= bytes == dim.ByteStride() || dim.Extent() == 1;
442+
if (bytes != dim.ByteStride() && dim.Extent() != 1) {
443+
stridesAreContiguous = false;
444+
}
437445
bytes *= dim.Extent();
438446
}
439447
// One and zero element arrays are contiguous even if the descriptor
@@ -448,28 +456,44 @@ class Descriptor {
448456

449457
// The result, if any, is a fixed stride value that can be used to
450458
// address all elements. It generalizes contiguity by also allowing
451-
// the case of an array with extent 1 on all but one dimension.
459+
// the case of an array with extent 1 on all dimensions but one.
460+
// Returns 0 for an empty array, a byte stride if one is well-defined
461+
// for the array, or nullopt otherwise.
452462
RT_API_ATTRS common::optional<SubscriptValue> FixedStride() const {
453-
auto rank{static_cast<std::size_t>(raw_.rank)};
454-
common::optional<SubscriptValue> stride;
455-
for (std::size_t j{0}; j < rank; ++j) {
456-
const Dimension &dim{GetDimension(j)};
457-
auto extent{dim.Extent()};
458-
if (extent == 0) {
459-
break; // empty array
460-
} else if (extent == 1) { // ok
461-
} else if (stride) {
462-
// Extent > 1 on multiple dimensions
463-
if (IsContiguous()) {
464-
return ElementBytes();
463+
int rank{raw_.rank};
464+
auto elementBytes{static_cast<SubscriptValue>(ElementBytes())};
465+
if (rank == 0) {
466+
return elementBytes;
467+
} else if (rank == 1) {
468+
const Dimension &dim{GetDimension(0)};
469+
return dim.Extent() == 0 ? 0 : dim.ByteStride();
470+
} else {
471+
common::optional<SubscriptValue> stride;
472+
auto bytes{elementBytes};
473+
for (int j{0}; j < rank; ++j) {
474+
const Dimension &dim{GetDimension(j)};
475+
auto extent{dim.Extent()};
476+
if (extent == 0) {
477+
return 0; // empty array
478+
} else if (extent == 1) { // ok
465479
} else {
466-
return common::nullopt;
480+
if (stride) { // Extent > 1 on multiple dimensions
481+
if (bytes != dim.ByteStride()) { // discontiguity
482+
while (++j < rank) {
483+
if (GetDimension(j).Extent() == 0) {
484+
return 0; // empty array
485+
}
486+
}
487+
return common::nullopt; // nonempty, discontiguous
488+
}
489+
} else {
490+
stride = dim.ByteStride();
491+
}
492+
bytes *= extent;
467493
}
468-
} else {
469-
stride = dim.ByteStride();
470494
}
495+
return stride.value_or(elementBytes /*for singleton*/);
471496
}
472-
return stride.value_or(0); // 0 for scalars and empty arrays
473497
}
474498

475499
// Establishes a pointer to a section or element.

flang-rt/include/flang-rt/runtime/io-stmt.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,14 +461,16 @@ class ListDirectedStatementState<Direction::Input>
461461
inNamelistSequence_ = inNamelistSequence;
462462
}
463463

464+
protected:
465+
bool inNamelistSequence_{false};
466+
464467
private:
465468
int remaining_{0}; // for "r*" repetition
466469
Fortran::common::optional<SavedPosition> repeatPosition_;
467470
bool eatComma_{false}; // consume comma after previously read item
468471
bool hitSlash_{false}; // once '/' is seen, nullify further items
469472
bool realPart_{false};
470473
bool imaginaryPart_{false};
471-
bool inNamelistSequence_{false};
472474
};
473475

474476
template <Direction DIR>
@@ -688,7 +690,8 @@ template <Direction DIR>
688690
class ChildListIoStatementState : public ChildIoStatementState<DIR>,
689691
public ListDirectedStatementState<DIR> {
690692
public:
691-
using ChildIoStatementState<DIR>::ChildIoStatementState;
693+
RT_API_ATTRS ChildListIoStatementState(
694+
ChildIo &, const char *sourceFile = nullptr, int sourceLine = 0);
692695
using ListDirectedStatementState<DIR>::GetNextDataEdit;
693696
RT_API_ATTRS int EndIoStatement();
694697
};

flang-rt/lib/runtime/derived.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,8 @@ RT_API_ATTRS int FinalizeTicket::Continue(WorkQueue &workQueue) {
360360
} else if (component_->genre() == typeInfo::Component::Genre::Data &&
361361
component_->derivedType() &&
362362
!component_->derivedType()->noFinalizationNeeded()) {
363+
// todo: calculate and use fixedStride_ here as in DestroyTicket to
364+
// avoid subscripts and repeated descriptor establishment.
363365
SubscriptValue extents[maxRank];
364366
GetComponentExtents(extents, *component_, instance_);
365367
Descriptor &compDesc{componentDescriptor_.descriptor()};
@@ -452,6 +454,24 @@ RT_API_ATTRS int DestroyTicket::Continue(WorkQueue &workQueue) {
452454
} else if (component_->genre() == typeInfo::Component::Genre::Data) {
453455
if (!componentDerived || componentDerived->noDestructionNeeded()) {
454456
SkipToNextComponent();
457+
} else if (fixedStride_) {
458+
// faster path, no need for subscripts, can reuse descriptor
459+
char *p{instance_.OffsetElement<char>(
460+
elementAt_ * *fixedStride_ + component_->offset())};
461+
Descriptor &compDesc{componentDescriptor_.descriptor()};
462+
const typeInfo::DerivedType &compType{*componentDerived};
463+
compDesc.UncheckedScalarEstablish(compType, p);
464+
for (std::size_t j{elementAt_}; j < elements_;
465+
++j, p += *fixedStride_) {
466+
compDesc.set_base_addr(p);
467+
++elementAt_;
468+
if (int status{workQueue.BeginDestroy(
469+
compDesc, compType, /*finalize=*/false)};
470+
status != StatOk) {
471+
return status;
472+
}
473+
}
474+
SkipToNextComponent();
455475
} else {
456476
SubscriptValue extents[maxRank];
457477
GetComponentExtents(extents, *component_, instance_);
@@ -461,8 +481,8 @@ RT_API_ATTRS int DestroyTicket::Continue(WorkQueue &workQueue) {
461481
instance_.ElementComponent<char>(subscripts_, component_->offset()),
462482
component_->rank(), extents);
463483
Advance();
464-
if (int status{workQueue.BeginDestroy(
465-
compDesc, *componentDerived, /*finalize=*/false)};
484+
if (int status{
485+
workQueue.BeginDestroy(compDesc, compType, /*finalize=*/false)};
466486
status != StatOk) {
467487
return status;
468488
}

flang-rt/lib/runtime/descriptor-io.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ static RT_API_ATTRS Fortran::common::optional<bool> DefinedFormattedIo(
110110
Fortran::common::optional<std::int64_t> startPos;
111111
if (edit.descriptor == DataEdit::DefinedDerivedType &&
112112
special.which() == typeInfo::SpecialBinding::Which::ReadFormatted) {
113-
// DT is an edit descriptor so everything that the child
113+
// DT is an edit descriptor, so everything that the child
114114
// I/O subroutine reads counts towards READ(SIZE=).
115115
startPos = io.InquirePos();
116116
}

flang-rt/lib/runtime/descriptor.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,15 @@ RT_API_ATTRS void Descriptor::Establish(const typeInfo::DerivedType &dt,
100100
new (Addendum()) DescriptorAddendum{&dt};
101101
}
102102

103+
RT_API_ATTRS void Descriptor::UncheckedScalarEstablish(
104+
const typeInfo::DerivedType &dt, void *p) {
105+
auto elementBytes{static_cast<std::size_t>(dt.sizeInBytes())};
106+
ISO::EstablishDescriptor(
107+
&raw_, p, CFI_attribute_other, CFI_type_struct, elementBytes, 0, nullptr);
108+
SetHasAddendum();
109+
new (Addendum()) DescriptorAddendum{&dt};
110+
}
111+
103112
RT_API_ATTRS OwningPtr<Descriptor> Descriptor::Create(TypeCode t,
104113
std::size_t elementBytes, void *p, int rank, const SubscriptValue *extent,
105114
ISO::CFI_attribute_t attribute, bool addendum,
@@ -231,6 +240,7 @@ RT_API_ATTRS bool Descriptor::EstablishPointerSection(const Descriptor &source,
231240
const SubscriptValue *stride) {
232241
*this = source;
233242
raw_.attribute = CFI_attribute_pointer;
243+
SetAllocIdx(source.GetAllocIdx());
234244
int newRank{raw_.rank};
235245
for (int j{0}; j < raw_.rank; ++j) {
236246
if (!stride || stride[j] == 0) {
@@ -242,14 +252,17 @@ RT_API_ATTRS bool Descriptor::EstablishPointerSection(const Descriptor &source,
242252
}
243253
}
244254
raw_.rank = newRank;
255+
if (CFI_section(&raw_, &source.raw_, lower, upper, stride) != CFI_SUCCESS) {
256+
return false;
257+
}
245258
if (const auto *sourceAddendum = source.Addendum()) {
246259
if (auto *addendum{Addendum()}) {
247260
*addendum = *sourceAddendum;
248261
} else {
249262
return false;
250263
}
251264
}
252-
return CFI_section(&raw_, &source.raw_, lower, upper, stride) == CFI_SUCCESS;
265+
return true;
253266
}
254267

255268
RT_API_ATTRS void Descriptor::ApplyMold(

flang-rt/lib/runtime/edit-input.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,9 @@ static RT_API_ATTRS ScannedRealInput ScanRealInput(
396396
}
397397
}
398398
} else if (first == radixPointChar || (first >= '0' && first <= '9') ||
399-
(bzMode && (first == ' ' || first == '\t')) || first == 'E' ||
400-
first == 'D' || first == 'Q') {
399+
(bzMode && (first == ' ' || first == '\t')) ||
400+
(remaining.has_value() &&
401+
(first == 'D' || first == 'E' || first == 'Q'))) {
401402
if (first == '0') {
402403
next = io.NextInField(remaining, edit);
403404
if (next && (*next == 'x' || *next == 'X')) { // 0X...
@@ -462,6 +463,14 @@ static RT_API_ATTRS ScannedRealInput ScanRealInput(
462463
// optional exponent letter and the exponent value.
463464
io.SkipSpaces(remaining);
464465
next = io.NextInField(remaining, edit);
466+
if (!next) {
467+
if (remaining.has_value()) {
468+
// bare exponent letter accepted in fixed-width field
469+
hasGoodExponent = true;
470+
} else {
471+
return {}; // error
472+
}
473+
}
465474
}
466475
}
467476
if (next &&

flang-rt/lib/runtime/io-stmt.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1078,6 +1078,22 @@ bool ChildFormattedIoStatementState<DIR, CHAR>::AdvanceRecord(int n) {
10781078
#endif
10791079
}
10801080

1081+
template <Direction DIR>
1082+
ChildListIoStatementState<DIR>::ChildListIoStatementState(
1083+
ChildIo &child, const char *sourceFile, int sourceLine)
1084+
: ChildIoStatementState<DIR>{child, sourceFile, sourceLine} {
1085+
#if !defined(RT_DEVICE_AVOID_RECURSION)
1086+
if constexpr (DIR == Direction::Input) {
1087+
if (auto *listInput{child.parent()
1088+
.get_if<ListDirectedStatementState<Direction::Input>>()}) {
1089+
this->inNamelistSequence_ = listInput->inNamelistSequence();
1090+
}
1091+
}
1092+
#else
1093+
this->ReportUnsupportedChildIo();
1094+
#endif
1095+
}
1096+
10811097
template <Direction DIR>
10821098
bool ChildUnformattedIoStatementState<DIR>::Receive(
10831099
char *data, std::size_t bytes, std::size_t elementBytes) {

flang-rt/lib/runtime/namelist.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -268,13 +268,21 @@ static RT_API_ATTRS void StorageSequenceExtension(
268268
? source.GetDimension(0).ByteStride()
269269
: static_cast<SubscriptValue>(source.ElementBytes())};
270270
stride != 0) {
271+
common::optional<DescriptorAddendum> savedAddendum;
272+
if (const DescriptorAddendum *addendum{desc.Addendum()}) {
273+
// Preserve a copy of the addendum, if any, before clobbering it
274+
savedAddendum.emplace(*addendum);
275+
}
271276
desc.raw().attribute = CFI_attribute_pointer;
272277
desc.raw().rank = 1;
273278
desc.GetDimension(0)
274279
.SetBounds(1,
275280
source.Elements() -
276281
((source.OffsetElement() - desc.OffsetElement()) / stride))
277282
.SetByteStride(stride);
283+
if (savedAddendum) {
284+
*desc.Addendum() = *savedAddendum;
285+
}
278286
}
279287
}
280288
}
@@ -570,12 +578,14 @@ bool IODEF(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
570578
addendum && addendum->derivedType()) {
571579
const NonTbpDefinedIoTable *table{group.nonTbpDefinedIo};
572580
listInput->ResetForNextNamelistItem(/*inNamelistSequence=*/true);
573-
if (!IONAME(InputDerivedType)(cookie, *useDescriptor, table)) {
581+
if (!IONAME(InputDerivedType)(cookie, *useDescriptor, table) &&
582+
handler.InError()) {
574583
return false;
575584
}
576585
} else {
577586
listInput->ResetForNextNamelistItem(useDescriptor->rank() > 0);
578-
if (!descr::DescriptorIO<Direction::Input>(io, *useDescriptor)) {
587+
if (!descr::DescriptorIO<Direction::Input>(io, *useDescriptor) &&
588+
handler.InError()) {
579589
return false;
580590
}
581591
}

flang-rt/unittests/Runtime/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ add_flangrt_unittest(RuntimeTests
1717
Complex.cpp
1818
CrashHandlerFixture.cpp
1919
Derived.cpp
20+
Descriptor.cpp
2021
ExternalIOTest.cpp
2122
Format.cpp
2223
InputExtensions.cpp

0 commit comments

Comments
 (0)