[flang-commits] [flang] [flang][cuda] Make sure allocator id is set for pointer allocate (PR #129950)
Valentin Clement バレンタイン クレメン via flang-commits
flang-commits at lists.llvm.org
Wed Mar 5 14:39:10 PST 2025
https://github.com/clementval created https://github.com/llvm/llvm-project/pull/129950
None
>From 991ceb3fe161263c5b22066a4d9e9c316aeb32fe Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Wed, 5 Mar 2025 14:37:05 -0800
Subject: [PATCH 1/2] [flang][cuda] Make sure allocator id is set for pointer
allocate
---
flang/include/flang/Lower/Cuda.h | 19 ++++++++++++++++++-
flang/lib/Lower/Allocatable.cpp | 13 ++++++++-----
flang/lib/Lower/ConvertVariable.cpp | 19 ++-----------------
3 files changed, 28 insertions(+), 23 deletions(-)
diff --git a/flang/include/flang/Lower/Cuda.h b/flang/include/flang/Lower/Cuda.h
index e446b505ee6e4..d97045383d195 100644
--- a/flang/include/flang/Lower/Cuda.h
+++ b/flang/include/flang/Lower/Cuda.h
@@ -25,7 +25,7 @@ namespace Fortran::lower {
// for it.
// If the insertion point is inside an OpenACC region op, it is considered
// device context.
-static bool isCudaDeviceContext(fir::FirOpBuilder &builder) {
+static bool inline isCudaDeviceContext(fir::FirOpBuilder &builder) {
if (builder.getRegion().getParentOfType<cuf::KernelOp>())
return true;
if (builder.getRegion()
@@ -41,6 +41,23 @@ static bool isCudaDeviceContext(fir::FirOpBuilder &builder) {
}
return false;
}
+
+static inline unsigned getAllocatorIdx(const Fortran::semantics::Symbol &sym) {
+ std::optional<Fortran::common::CUDADataAttr> cudaAttr =
+ Fortran::semantics::GetCUDADataAttr(&sym.GetUltimate());
+ if (cudaAttr) {
+ if (*cudaAttr == Fortran::common::CUDADataAttr::Pinned)
+ return kPinnedAllocatorPos;
+ if (*cudaAttr == Fortran::common::CUDADataAttr::Device)
+ return kDeviceAllocatorPos;
+ if (*cudaAttr == Fortran::common::CUDADataAttr::Managed)
+ return kManagedAllocatorPos;
+ if (*cudaAttr == Fortran::common::CUDADataAttr::Unified)
+ return kUnifiedAllocatorPos;
+ }
+ return kDefaultAllocator;
+}
+
} // end namespace Fortran::lower
#endif // FORTRAN_LOWER_CUDA_H
diff --git a/flang/lib/Lower/Allocatable.cpp b/flang/lib/Lower/Allocatable.cpp
index dc135543fafc7..2006fa605aa22 100644
--- a/flang/lib/Lower/Allocatable.cpp
+++ b/flang/lib/Lower/Allocatable.cpp
@@ -475,6 +475,7 @@ class AllocateStmtHelper {
!alloc.type.IsPolymorphic() &&
!alloc.hasCoarraySpec() && !useAllocateRuntime &&
!box.isPointer();
+ unsigned allocatorIdx = Fortran::lower::getAllocatorIdx(alloc.getSymbol());
if (inlineAllocation &&
((isCudaSymbol && isCudaDeviceContext) || !isCudaSymbol)) {
@@ -488,7 +489,7 @@ class AllocateStmtHelper {
// Generate a sequence of runtime calls.
errorManager.genStatCheck(builder, loc);
- genAllocateObjectInit(box);
+ genAllocateObjectInit(box, allocatorIdx);
if (alloc.hasCoarraySpec())
TODO(loc, "coarray: allocation of a coarray object");
if (alloc.type.IsPolymorphic())
@@ -549,14 +550,15 @@ class AllocateStmtHelper {
TODO(loc, "derived type length parameters in allocate");
}
- void genAllocateObjectInit(const fir::MutableBoxValue &box) {
+ void genAllocateObjectInit(const fir::MutableBoxValue &box, unsigned allocatorIdx) {
if (box.isPointer()) {
// For pointers, the descriptor may still be uninitialized (see Fortran
// 2018 19.5.2.2). The allocation runtime needs to be given a descriptor
// with initialized rank, types and attributes. Initialize the descriptor
// here to ensure these constraints are fulfilled.
mlir::Value nullPointer = fir::factory::createUnallocatedBox(
- builder, loc, box.getBoxTy(), box.nonDeferredLenParams());
+ builder, loc, box.getBoxTy(), box.nonDeferredLenParams(),
+ /*typeSourceBox=*/{}, allocatorIdx);
builder.create<fir::StoreOp>(loc, nullPointer, box.getAddr());
} else {
assert(box.isAllocatable() && "must be an allocatable");
@@ -612,11 +614,12 @@ class AllocateStmtHelper {
void genSourceMoldAllocation(const Allocation &alloc,
const fir::MutableBoxValue &box, bool isSource) {
+ unsigned allocatorIdx = Fortran::lower::getAllocatorIdx(alloc.getSymbol());
fir::ExtendedValue exv = isSource ? sourceExv : moldExv;
- ;
+
// Generate a sequence of runtime calls.
errorManager.genStatCheck(builder, loc);
- genAllocateObjectInit(box);
+ genAllocateObjectInit(box, allocatorIdx);
if (alloc.hasCoarraySpec())
TODO(loc, "coarray: allocation of a coarray object");
// Set length of the allocate object if it has. Otherwise, get the length
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 3cf2988a8b48c..8a7be19f8040b 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -19,6 +19,7 @@
#include "flang/Lower/ConvertExpr.h"
#include "flang/Lower/ConvertExprToHLFIR.h"
#include "flang/Lower/ConvertProcedureDesignator.h"
+#include "flang/Lower/Cuda.h"
#include "flang/Lower/Mangler.h"
#include "flang/Lower/PFTBuilder.h"
#include "flang/Lower/StatementContext.h"
@@ -1985,22 +1986,6 @@ static void genBoxDeclare(Fortran::lower::AbstractConverter &converter,
replace);
}
-static unsigned getAllocatorIdx(const Fortran::semantics::Symbol &sym) {
- std::optional<Fortran::common::CUDADataAttr> cudaAttr =
- Fortran::semantics::GetCUDADataAttr(&sym.GetUltimate());
- if (cudaAttr) {
- if (*cudaAttr == Fortran::common::CUDADataAttr::Pinned)
- return kPinnedAllocatorPos;
- if (*cudaAttr == Fortran::common::CUDADataAttr::Device)
- return kDeviceAllocatorPos;
- if (*cudaAttr == Fortran::common::CUDADataAttr::Managed)
- return kManagedAllocatorPos;
- if (*cudaAttr == Fortran::common::CUDADataAttr::Unified)
- return kUnifiedAllocatorPos;
- }
- return kDefaultAllocator;
-}
-
/// Lower specification expressions and attributes of variable \p var and
/// add it to the symbol map. For a global or an alias, the address must be
/// pre-computed and provided in \p preAlloc. A dummy argument for the current
@@ -2091,7 +2076,7 @@ void Fortran::lower::mapSymbolAttributes(
converter, loc, var, boxAlloc, nonDeferredLenParams,
/*alwaysUseBox=*/
converter.getLoweringOptions().getLowerToHighLevelFIR(),
- getAllocatorIdx(var.getSymbol()));
+ Fortran::lower::getAllocatorIdx(var.getSymbol()));
genAllocatableOrPointerDeclare(converter, symMap, var.getSymbol(), box,
replace);
return;
>From 497a471271b0af0dc1df3a0cf2d68e664886ffe1 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Wed, 5 Mar 2025 14:38:24 -0800
Subject: [PATCH 2/2] Add test
---
flang/test/Lower/CUDA/cuda-pointer.cuf | 11 +++++++++++
1 file changed, 11 insertions(+)
create mode 100644 flang/test/Lower/CUDA/cuda-pointer.cuf
diff --git a/flang/test/Lower/CUDA/cuda-pointer.cuf b/flang/test/Lower/CUDA/cuda-pointer.cuf
new file mode 100644
index 0000000000000..2a9dbe54c2922
--- /dev/null
+++ b/flang/test/Lower/CUDA/cuda-pointer.cuf
@@ -0,0 +1,11 @@
+! RUN: bbc -emit-hlfir -fcuda %s -o - | FileCheck %s
+
+! Test lowering of CUDA pointers.
+
+subroutine allocate_pointer
+ real, device, pointer :: pr(:)
+ allocate(pr(10))
+end
+
+! CHECK-LABEL: func.func @_QPallocate_pointer()
+! CHECK-COUNT-2: fir.embox %{{.*}} {allocator_idx = 2 : i32} : (!fir.ptr<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
More information about the flang-commits
mailing list