[flang][cuda] Allocate the dst descriptor in data transfer (#143437)

In a test like: 

```
integer, allocatable, device :: da(:)
allocate(a(200))
a = 2
da = a ! da is not allocated before data transfer is initiated. Allocate it with a
```

The reference compiler will allocate the data for the `da` descriptor so
the data transfer can be done properly.
This commit is contained in:
Valentin Clement (バレンタイン クレメン)
2025-06-10 09:43:30 -07:00
committed by GitHub
parent 8957e64a20
commit 9c54512c3e
2 changed files with 31 additions and 0 deletions

View File

@@ -105,6 +105,11 @@ void RTDECL(CUFDataTransferDescDesc)(Descriptor *dstDesc, Descriptor *srcDesc,
} else {
terminator.Crash("host to host copy not supported");
}
// Allocate dst descriptor if not allocated.
if (!dstDesc->IsAllocated()) {
dstDesc->ApplyMold(*srcDesc, dstDesc->rank());
dstDesc->Allocate(/*asyncObject=*/nullptr);
}
if ((srcDesc->rank() > 0) && (dstDesc->Elements() < srcDesc->Elements())) {
// Special case when rhs is bigger than lhs and both are contiguous arrays.
// In this case we do a simple ptr to ptr transfer with the size of lhs.

View File

@@ -70,3 +70,29 @@ TEST(MemoryCUFTest, CUFDataTransferDescDesc) {
EXPECT_EQ(*host->ZeroBasedIndexedElement<std::int32_t>(i), (std::int32_t)i);
}
}
TEST(MemoryCUFTest, CUFDataTransferDescDescDstNotAllocated) {
using Fortran::common::TypeCategory;
RTNAME(CUFRegisterAllocator)();
// INTEGER(4), DEVICE, ALLOCATABLE :: a(:)
auto dev{createAllocatable(TypeCategory::Integer, 4)};
dev->SetAllocIdx(kDeviceAllocatorPos);
EXPECT_EQ((int)kDeviceAllocatorPos, dev->GetAllocIdx());
EXPECT_FALSE(dev->IsAllocated());
// Create temp array to transfer to device.
auto x{MakeArray<TypeCategory::Integer, 4>(std::vector<int>{10},
std::vector<int32_t>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9})};
RTNAME(CUFDataTransferDescDesc)
(dev.get(), x.get(), kHostToDevice, __FILE__, __LINE__);
// Retrieve data from device.
auto host{MakeArray<TypeCategory::Integer, 4>(std::vector<int>{10},
std::vector<int32_t>{0, 0, 0, 0, 0, 0, 0, 0, 0, 0})};
RTNAME(CUFDataTransferDescDesc)
(host.get(), dev.get(), kDeviceToHost, __FILE__, __LINE__);
for (unsigned i = 0; i < 10; ++i) {
EXPECT_EQ(*host->ZeroBasedIndexedElement<std::int32_t>(i), (std::int32_t)i);
}
}