Skip to content

Commit d3c09c4

Browse files
authored
[flang] Add special genre for allocatable and pointer device component (#157731)
Allocatable and pointer device components need a different allocator index to be set in their descriptor when it is establish. This PR adds two genre for the components `AllocatableDevice` and `PointerDevice` so the correct allocator index can be set accordingly.
1 parent 2a2296b commit d3c09c4

File tree

11 files changed

+97
-33
lines changed

11 files changed

+97
-33
lines changed

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,20 +171,21 @@ class Descriptor {
171171
void *p = nullptr, int rank = maxRank,
172172
const SubscriptValue *extent = nullptr,
173173
ISO::CFI_attribute_t attribute = CFI_attribute_other,
174-
bool addendum = false);
174+
bool addendum = false, int allocatorIdx = kDefaultAllocator);
175175
RT_API_ATTRS void Establish(TypeCategory, int kind, void *p = nullptr,
176176
int rank = maxRank, const SubscriptValue *extent = nullptr,
177177
ISO::CFI_attribute_t attribute = CFI_attribute_other,
178-
bool addendum = false);
178+
bool addendum = false, int allocatorIdx = kDefaultAllocator);
179179
RT_API_ATTRS void Establish(int characterKind, std::size_t characters,
180180
void *p = nullptr, int rank = maxRank,
181181
const SubscriptValue *extent = nullptr,
182182
ISO::CFI_attribute_t attribute = CFI_attribute_other,
183-
bool addendum = false);
183+
bool addendum = false, int allocatorIdx = kDefaultAllocator);
184184
RT_API_ATTRS void Establish(const typeInfo::DerivedType &dt,
185185
void *p = nullptr, int rank = maxRank,
186186
const SubscriptValue *extent = nullptr,
187-
ISO::CFI_attribute_t attribute = CFI_attribute_other);
187+
ISO::CFI_attribute_t attribute = CFI_attribute_other,
188+
int allocatorIdx = kDefaultAllocator);
188189

189190
RT_API_ATTRS void UncheckedScalarEstablish(
190191
const typeInfo::DerivedType &, void *);

flang-rt/include/flang-rt/runtime/type-info.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,9 @@ class Component {
5555
Data = 1,
5656
Pointer = 2,
5757
Allocatable = 3,
58-
Automatic = 4
58+
Automatic = 4,
59+
PointerDevice = 5,
60+
AllocatableDevice = 6
5961
};
6062

6163
RT_API_ATTRS const Descriptor &name() const { return name_.descriptor(); }

flang-rt/lib/runtime/assign.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,8 @@ RT_API_ATTRS int DerivedAssignTicket<IS_COMPONENTWISE>::Continue(
648648
}
649649
}
650650
break;
651-
case typeInfo::Component::Genre::Pointer: {
651+
case typeInfo::Component::Genre::Pointer:
652+
case typeInfo::Component::Genre::PointerDevice: {
652653
std::size_t componentByteSize{
653654
this->component_->SizeInBytes(this->instance_)};
654655
if (IS_COMPONENTWISE && toIsContiguous_ && fromIsContiguous_) {
@@ -680,6 +681,7 @@ RT_API_ATTRS int DerivedAssignTicket<IS_COMPONENTWISE>::Continue(
680681
}
681682
} break;
682683
case typeInfo::Component::Genre::Allocatable:
684+
case typeInfo::Component::Genre::AllocatableDevice:
683685
case typeInfo::Component::Genre::Automatic: {
684686
auto *toDesc{reinterpret_cast<Descriptor *>(
685687
this->instance_.template Element<char>(this->subscripts_) +

flang-rt/lib/runtime/copy.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,8 @@ RT_API_ATTRS void CopyElement(const Descriptor &to, const SubscriptValue toAt[],
168168
std::size_t nComponents{componentDesc.Elements()};
169169
for (std::size_t j{0}; j < nComponents; ++j, ++component) {
170170
if (component->genre() == typeInfo::Component::Genre::Allocatable ||
171+
component->genre() ==
172+
typeInfo::Component::Genre::AllocatableDevice ||
171173
component->genre() == typeInfo::Component::Genre::Automatic) {
172174
Descriptor &toDesc{
173175
*reinterpret_cast<Descriptor *>(toPtr + component->offset())};

flang-rt/lib/runtime/derived.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ RT_API_ATTRS int InitializeTicket::Continue(WorkQueue &workQueue) {
6363
char *rawInstance{instance_.OffsetElement<char>()};
6464
for (; !Componentwise::IsComplete(); SkipToNextComponent()) {
6565
char *rawComponent{rawInstance + component_->offset()};
66-
if (component_->genre() == typeInfo::Component::Genre::Allocatable) {
66+
if (component_->genre() == typeInfo::Component::Genre::Allocatable ||
67+
component_->genre() == typeInfo::Component::Genre::AllocatableDevice) {
6768
Descriptor &allocDesc{*reinterpret_cast<Descriptor *>(rawComponent)};
6869
component_->EstablishDescriptor(
6970
allocDesc, instance_, workQueue.terminator());
@@ -72,7 +73,8 @@ RT_API_ATTRS int InitializeTicket::Continue(WorkQueue &workQueue) {
7273
// non-allocatable non-automatic components
7374
std::size_t bytes{component_->SizeInBytes(instance_)};
7475
runtime::memcpy(rawComponent, init, bytes);
75-
} else if (component_->genre() == typeInfo::Component::Genre::Pointer) {
76+
} else if (component_->genre() == typeInfo::Component::Genre::Pointer ||
77+
component_->genre() == typeInfo::Component::Genre::PointerDevice) {
7678
// Data pointers without explicit initialization are established
7779
// so that they are valid right-hand side targets of pointer
7880
// assignment statements.
@@ -143,7 +145,8 @@ RT_API_ATTRS int InitializeClone(const Descriptor &clone,
143145

144146
RT_API_ATTRS int InitializeCloneTicket::Continue(WorkQueue &workQueue) {
145147
while (!IsComplete()) {
146-
if (component_->genre() == typeInfo::Component::Genre::Allocatable) {
148+
if (component_->genre() == typeInfo::Component::Genre::Allocatable ||
149+
component_->genre() == typeInfo::Component::Genre::AllocatableDevice) {
147150
Descriptor &origDesc{*instance_.ElementComponent<Descriptor>(
148151
subscripts_, component_->offset())};
149152
if (origDesc.IsAllocated()) {
@@ -320,7 +323,9 @@ RT_API_ATTRS int FinalizeTicket::Begin(WorkQueue &workQueue) {
320323

321324
RT_API_ATTRS int FinalizeTicket::Continue(WorkQueue &workQueue) {
322325
while (!IsComplete()) {
323-
if (component_->genre() == typeInfo::Component::Genre::Allocatable &&
326+
if ((component_->genre() == typeInfo::Component::Genre::Allocatable ||
327+
component_->genre() ==
328+
typeInfo::Component::Genre::AllocatableDevice) &&
324329
component_->category() == TypeCategory::Derived) {
325330
// Component may be polymorphic or unlimited polymorphic. Need to use the
326331
// dynamic type to check whether finalization is needed.
@@ -342,6 +347,7 @@ RT_API_ATTRS int FinalizeTicket::Continue(WorkQueue &workQueue) {
342347
}
343348
}
344349
} else if (component_->genre() == typeInfo::Component::Genre::Allocatable ||
350+
component_->genre() == typeInfo::Component::Genre::AllocatableDevice ||
345351
component_->genre() == typeInfo::Component::Genre::Automatic) {
346352
if (const typeInfo::DerivedType *compType{component_->derivedType()};
347353
compType && !compType->noFinalizationNeeded()) {
@@ -424,7 +430,8 @@ RT_API_ATTRS int DestroyTicket::Continue(WorkQueue &workQueue) {
424430
// Contrary to finalization, the order of deallocation does not matter.
425431
while (!IsComplete()) {
426432
const auto *componentDerived{component_->derivedType()};
427-
if (component_->genre() == typeInfo::Component::Genre::Allocatable) {
433+
if (component_->genre() == typeInfo::Component::Genre::Allocatable ||
434+
component_->genre() == typeInfo::Component::Genre::AllocatableDevice) {
428435
if (fixedStride_ &&
429436
(!componentDerived || componentDerived->noDestructionNeeded())) {
430437
// common fast path, just deallocate in every element

flang-rt/lib/runtime/descriptor.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ RT_API_ATTRS Descriptor &Descriptor::operator=(const Descriptor &that) {
3333

3434
RT_API_ATTRS void Descriptor::Establish(TypeCode t, std::size_t elementBytes,
3535
void *p, int rank, const SubscriptValue *extent,
36-
ISO::CFI_attribute_t attribute, bool addendum) {
36+
ISO::CFI_attribute_t attribute, bool addendum, int allocatorIdx) {
3737
Terminator terminator{__FILE__, __LINE__};
3838
int cfiStatus{ISO::VerifyEstablishParameters(&raw_, p, attribute, t.raw(),
3939
elementBytes, rank, extent, /*external=*/false)};
@@ -60,6 +60,7 @@ RT_API_ATTRS void Descriptor::Establish(TypeCode t, std::size_t elementBytes,
6060
if (a) {
6161
new (a) DescriptorAddendum{};
6262
}
63+
SetAllocIdx(allocatorIdx);
6364
}
6465

6566
RT_API_ATTRS std::size_t Descriptor::BytesFor(TypeCategory category, int kind) {
@@ -71,21 +72,22 @@ RT_API_ATTRS std::size_t Descriptor::BytesFor(TypeCategory category, int kind) {
7172

7273
RT_API_ATTRS void Descriptor::Establish(TypeCategory c, int kind, void *p,
7374
int rank, const SubscriptValue *extent, ISO::CFI_attribute_t attribute,
74-
bool addendum) {
75+
bool addendum, int allocatorIdx) {
7576
Establish(TypeCode(c, kind), BytesFor(c, kind), p, rank, extent, attribute,
76-
addendum);
77+
addendum, allocatorIdx);
7778
}
7879

7980
RT_API_ATTRS void Descriptor::Establish(int characterKind,
8081
std::size_t characters, void *p, int rank, const SubscriptValue *extent,
81-
ISO::CFI_attribute_t attribute, bool addendum) {
82+
ISO::CFI_attribute_t attribute, bool addendum, int allocatorIdx) {
8283
Establish(TypeCode{TypeCategory::Character, characterKind},
83-
characterKind * characters, p, rank, extent, attribute, addendum);
84+
characterKind * characters, p, rank, extent, attribute, addendum,
85+
allocatorIdx);
8486
}
8587

8688
RT_API_ATTRS void Descriptor::Establish(const typeInfo::DerivedType &dt,
8789
void *p, int rank, const SubscriptValue *extent,
88-
ISO::CFI_attribute_t attribute) {
90+
ISO::CFI_attribute_t attribute, int allocatorIdx) {
8991
auto elementBytes{static_cast<std::size_t>(dt.sizeInBytes())};
9092
ISO::EstablishDescriptor(
9193
&raw_, p, attribute, CFI_type_struct, elementBytes, rank, extent);
@@ -99,6 +101,7 @@ RT_API_ATTRS void Descriptor::Establish(const typeInfo::DerivedType &dt,
99101
}
100102
SetHasAddendum();
101103
new (Addendum()) DescriptorAddendum{&dt};
104+
SetAllocIdx(allocatorIdx);
102105
}
103106

104107
RT_API_ATTRS void Descriptor::UncheckedScalarEstablish(

flang-rt/lib/runtime/type-info.cpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,16 @@ RT_API_ATTRS std::size_t Component::SizeInBytes(
9595
RT_API_ATTRS void Component::EstablishDescriptor(Descriptor &descriptor,
9696
const Descriptor &container, Terminator &terminator) const {
9797
ISO::CFI_attribute_t attribute{static_cast<ISO::CFI_attribute_t>(
98-
genre_ == Genre::Allocatable ? CFI_attribute_allocatable
99-
: genre_ == Genre::Pointer ? CFI_attribute_pointer
100-
: CFI_attribute_other)};
98+
genre_ == Genre::Allocatable || genre_ == Genre::AllocatableDevice
99+
? CFI_attribute_allocatable
100+
: genre_ == Genre::Pointer || genre_ == Genre::PointerDevice
101+
? CFI_attribute_pointer
102+
: CFI_attribute_other)};
101103
TypeCategory cat{category()};
104+
unsigned allocatorIdx{
105+
genre_ == Genre::AllocatableDevice || genre_ == Genre::PointerDevice
106+
? kDeviceAllocatorPos
107+
: kDefaultAllocator};
102108
if (cat == TypeCategory::Character) {
103109
std::size_t lengthInChars{0};
104110
if (auto length{characterLen_.GetValue(&container)}) {
@@ -107,19 +113,22 @@ RT_API_ATTRS void Component::EstablishDescriptor(Descriptor &descriptor,
107113
RUNTIME_CHECK(
108114
terminator, characterLen_.genre() == Value::Genre::Deferred);
109115
}
110-
descriptor.Establish(
111-
kind_, lengthInChars, nullptr, rank_, nullptr, attribute);
116+
descriptor.Establish(kind_, lengthInChars, nullptr, rank_, nullptr,
117+
attribute, false, allocatorIdx);
112118
} else if (cat == TypeCategory::Derived) {
113119
if (const DerivedType * type{derivedType()}) {
114-
descriptor.Establish(*type, nullptr, rank_, nullptr, attribute);
120+
descriptor.Establish(
121+
*type, nullptr, rank_, nullptr, attribute, allocatorIdx);
115122
} else { // unlimited polymorphic
116123
descriptor.Establish(TypeCode{TypeCategory::Derived, 0}, 0, nullptr,
117-
rank_, nullptr, attribute, true);
124+
rank_, nullptr, attribute, true, allocatorIdx);
118125
}
119126
} else {
120-
descriptor.Establish(cat, kind_, nullptr, rank_, nullptr, attribute);
127+
descriptor.Establish(
128+
cat, kind_, nullptr, rank_, nullptr, attribute, false, allocatorIdx);
121129
}
122-
if (rank_ && genre_ != Genre::Allocatable && genre_ != Genre::Pointer) {
130+
if (rank_ && genre_ != Genre::Allocatable && genre_ != Genre::Pointer &&
131+
genre_ != Genre::AllocatableDevice && genre_ != Genre::PointerDevice) {
123132
const typeInfo::Value *boundValues{bounds()};
124133
RUNTIME_CHECK(terminator, boundValues != nullptr);
125134
auto byteStride{static_cast<SubscriptValue>(descriptor.ElementBytes())};
@@ -267,13 +276,17 @@ FILE *Component::Dump(FILE *f) const {
267276
std::fputs(" name: ", f);
268277
DumpScalarCharacter(f, name(), "Component::name");
269278
if (genre_ == Genre::Data) {
270-
std::fputs(" Data ", f);
279+
std::fputs(" Data ", f);
271280
} else if (genre_ == Genre::Pointer) {
272-
std::fputs(" Pointer ", f);
281+
std::fputs(" Pointer ", f);
282+
} else if (genre_ == Genre::PointerDevice) {
283+
std::fputs(" PointerDevice ", f);
273284
} else if (genre_ == Genre::Allocatable) {
274-
std::fputs(" Allocatable", f);
285+
std::fputs(" Allocatable. ", f);
286+
} else if (genre_ == Genre::AllocatableDevice) {
287+
std::fputs(" AllocatableDevice", f);
275288
} else if (genre_ == Genre::Automatic) {
276-
std::fputs(" Automatic ", f);
289+
std::fputs(" Automatic ", f);
277290
} else {
278291
std::fprintf(f, " (bad genre 0x%x)", static_cast<int>(genre_));
279292
}

flang/include/flang/Semantics/tools.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,14 @@ inline bool HasCUDAAttr(const Symbol &sym) {
225225

226226
bool HasCUDAComponent(const Symbol &sym);
227227

228+
inline bool IsCUDADevice(const Symbol &sym) {
229+
if (const auto *details{sym.GetUltimate().detailsIf<ObjectEntityDetails>()}) {
230+
return details->cudaDataAttr() &&
231+
*details->cudaDataAttr() == common::CUDADataAttr::Device;
232+
}
233+
return false;
234+
}
235+
228236
inline bool IsCUDAShared(const Symbol &sym) {
229237
if (const auto *details{sym.GetUltimate().detailsIf<ObjectEntityDetails>()}) {
230238
if (details->cudaDataAttr() &&

flang/lib/Semantics/runtime-type-info.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,8 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
771771
auto &foldingContext{context_.foldingContext()};
772772
auto typeAndShape{evaluate::characteristics::TypeAndShape::Characterize(
773773
symbol, foldingContext)};
774+
bool isDevice{object.cudaDataAttr() &&
775+
*object.cudaDataAttr() == common::CUDADataAttr::Device};
774776
CHECK(typeAndShape.has_value());
775777
auto dyType{typeAndShape->type()};
776778
int rank{typeAndShape->Rank()};
@@ -883,9 +885,19 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
883885
// Default component initialization
884886
bool hasDataInit{false};
885887
if (IsAllocatable(symbol)) {
886-
AddValue(values, componentSchema_, "genre"s, GetEnumValue("allocatable"));
888+
if (isDevice) {
889+
AddValue(values, componentSchema_, "genre"s,
890+
GetEnumValue("allocatabledevice"));
891+
} else {
892+
AddValue(values, componentSchema_, "genre"s, GetEnumValue("allocatable"));
893+
}
887894
} else if (IsPointer(symbol)) {
888-
AddValue(values, componentSchema_, "genre"s, GetEnumValue("pointer"));
895+
if (isDevice) {
896+
AddValue(
897+
values, componentSchema_, "genre"s, GetEnumValue("pointerdevice"));
898+
} else {
899+
AddValue(values, componentSchema_, "genre"s, GetEnumValue("pointer"));
900+
}
889901
hasDataInit = InitializeDataPointer(
890902
values, symbol, object, scope, dtScope, distinctName);
891903
} else if (IsAutomatic(symbol)) {

flang/module/__fortran_type_info.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
end type
7676

7777
enum, bind(c) ! Component::Genre
78-
enumerator :: Data = 1, Pointer = 2, Allocatable = 3, Automatic = 4
78+
enumerator :: Data = 1, Pointer = 2, Allocatable = 3, Automatic = 4, PointerDevice = 5, AllocatableDevice = 6
7979
end enum
8080

8181
enum, bind(c) ! common::TypeCategory

0 commit comments

Comments
 (0)