[Mlir-commits] [mlir] [MLIR][GPU-LLVM] Add in-pass signature update option for opencl kernels (PR #105664)
Petr Kurapov
llvmlistbot at llvm.org
Thu Aug 29 07:23:28 PDT 2024
https://github.com/kurapov-peter updated https://github.com/llvm/llvm-project/pull/105664
>From 2e8465cc42eb3cec6b4b94e5a01fc8bae0fb62c0 Mon Sep 17 00:00:00 2001
From: Petr Kurapov <petr.a.kurapov at intel.com>
Date: Mon, 19 Aug 2024 14:03:44 +0000
Subject: [PATCH 1/5] [MLIR][GPU-LLVM] Add in-pass signature update option for
opencl kernels
---
mlir/include/mlir/Conversion/Passes.td | 3 +
.../Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp | 59 +++++++++++++++++++
.../GPUToLLVMSPV/gpu-to-llvm-spv.mlir | 14 +++++
3 files changed, 76 insertions(+)
diff --git a/mlir/include/mlir/Conversion/Passes.td b/mlir/include/mlir/Conversion/Passes.td
index 7bde9e490e4f4e..05f07421b8f526 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -542,6 +542,9 @@ def ConvertGpuOpsToLLVMSPVOps : Pass<"convert-gpu-to-llvm-spv", "gpu::GPUModuleO
Option<"indexBitwidth", "index-bitwidth", "unsigned",
/*default=kDeriveIndexBitwidthFromDataLayout*/"0",
"Bitwidth of the index type, 0 to use size of machine word">,
+ Option<"forceOpenclAddressSpaces", "force-opencl-address-spaces",
+ "bool", /*default=*/"false",
+ "Force kernel argument pointers to have address space global.">,
];
}
diff --git a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
index ced4236402923a..25cf6560257978 100644
--- a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
+++ b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
@@ -306,6 +306,51 @@ struct GPUShuffleConversion final : ConvertOpToLLVMPattern<gpu::ShuffleOp> {
}
};
+class MemorySpaceToOpenCLMemorySpaceConverter : public TypeConverter {
+public:
+ explicit MemorySpaceToOpenCLMemorySpaceConverter() {
+ addConversion([](Type t) { return t; });
+ addConversion(
+ [this](BaseMemRefType memRefType) -> std::optional<Type> {
+ std::optional<gpu::AddressSpace> addrSpace =
+ memorySpaceMap(memRefType.getMemorySpace());
+ if (!addrSpace) {
+ LLVM_DEBUG(
+ llvm::dbgs()
+ << "cannot convert " << memRefType
+ << " due to being unable to find address space in the map\n");
+ return std::nullopt;
+ }
+ auto addrSpaceAttr =
+ gpu::AddressSpaceAttr::get(memRefType.getContext(), *addrSpace);
+ if (auto rankedType = dyn_cast<MemRefType>(memRefType)) {
+ return MemRefType::get(memRefType.getShape(),
+ memRefType.getElementType(),
+ rankedType.getLayout(), addrSpaceAttr);
+ }
+ return UnrankedMemRefType::get(memRefType.getElementType(),
+ addrSpaceAttr);
+ });
+ addConversion([this](FunctionType type) {
+ auto inputs = llvm::map_to_vector(
+ type.getInputs(), [this](Type ty) { return convertType(ty); });
+ auto results = llvm::map_to_vector(
+ type.getResults(), [this](Type ty) { return convertType(ty); });
+ return FunctionType::get(type.getContext(), inputs, results);
+ });
+ }
+
+private:
+ std::optional<gpu::AddressSpace> memorySpaceMap(Attribute memSpaceAttr) {
+ if (!memSpaceAttr)
+ return gpu::AddressSpace::Global;
+ auto gpuAddrSpace = dyn_cast<gpu::AddressSpaceAttr>(memSpaceAttr);
+ if (!gpuAddrSpace)
+ return std::nullopt;
+ return gpuAddrSpace.getValue();
+ }
+};
+
//===----------------------------------------------------------------------===//
// GPU To LLVM-SPV Pass.
//===----------------------------------------------------------------------===//
@@ -325,6 +370,20 @@ struct GPUToLLVMSPVConversionPass final
LLVMTypeConverter converter(context, options);
LLVMConversionTarget target(*context);
+ if (forceOpenclAddressSpaces) {
+ MemorySpaceToOpenCLMemorySpaceConverter converter;
+ AttrTypeReplacer replacer;
+ replacer.addReplacement([&converter](BaseMemRefType origType)
+ -> std::optional<BaseMemRefType> {
+ return converter.convertType<BaseMemRefType>(origType);
+ });
+
+ replacer.recursivelyReplaceElementsIn(getOperation(),
+ /*replaceAttrs=*/true,
+ /*replaceLocs=*/false,
+ /*replaceTypes=*/true);
+ }
+
target.addIllegalOp<gpu::BarrierOp, gpu::BlockDimOp, gpu::BlockIdOp,
gpu::GPUFuncOp, gpu::GlobalIdOp, gpu::GridDimOp,
gpu::ReturnOp, gpu::ShuffleOp, gpu::ThreadIdOp>();
diff --git a/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir b/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
index ec4f4a304d5073..d100f36ae42521 100644
--- a/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
+++ b/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
@@ -2,6 +2,8 @@
// RUN: | FileCheck --check-prefixes=CHECK-64,CHECK %s
// RUN: mlir-opt -pass-pipeline="builtin.module(gpu.module(convert-gpu-to-llvm-spv{index-bitwidth=32}))" -split-input-file -verify-diagnostics %s \
// RUN: | FileCheck --check-prefixes=CHECK-32,CHECK %s
+// RUN: mlir-opt -pass-pipeline="builtin.module(gpu.module(convert-gpu-to-llvm-spv{force-opencl-address-spaces}))" -split-input-file -verify-diagnostics %s \
+// RUN: | FileCheck --check-prefixes=OPENCL %s
gpu.module @builtins {
// CHECK-64: llvm.func spir_funccc @_Z14get_num_groupsj(i32) -> i64 attributes {
@@ -515,3 +517,15 @@ gpu.module @kernels {
gpu.return
}
}
+
+// -----
+
+gpu.module @kernels {
+// OPENCL-LABEL: llvm.func spir_funccc @no_address_spaces(
+// OPENCL-SAME: %{{[a-zA-Z_][a-zA-Z0-9_]*}}: !llvm.ptr<1>
+// OPENCL-SAME: %{{[a-zA-Z_][a-zA-Z0-9_]*}}: !llvm.ptr<1>
+// OPENCL-SAME: %{{[a-zA-Z_][a-zA-Z0-9_]*}}: !llvm.ptr<1>
+ gpu.func @no_address_spaces(%arg0: memref<f32>, %arg1: memref<f32, #gpu.address_space<global>>, %arg2: memref<f32>) {
+ gpu.return
+ }
+}
>From 9238460b818648defac1f0eaab5be0b2963af403 Mon Sep 17 00:00:00 2001
From: Petr Kurapov <petr.a.kurapov at intel.com>
Date: Thu, 22 Aug 2024 15:15:46 +0000
Subject: [PATCH 2/5] address review comment
---
mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
index 25cf6560257978..5fda6a83fd8213 100644
--- a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
+++ b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
@@ -306,9 +306,9 @@ struct GPUShuffleConversion final : ConvertOpToLLVMPattern<gpu::ShuffleOp> {
}
};
-class MemorySpaceToOpenCLMemorySpaceConverter : public TypeConverter {
+class MemorySpaceToOpenCLMemorySpaceConverter final : public TypeConverter {
public:
- explicit MemorySpaceToOpenCLMemorySpaceConverter() {
+ MemorySpaceToOpenCLMemorySpaceConverter() {
addConversion([](Type t) { return t; });
addConversion(
[this](BaseMemRefType memRefType) -> std::optional<Type> {
>From 7212344e18485804857b96047946ca392aa1cc19 Mon Sep 17 00:00:00 2001
From: Petr Kurapov <petr.kurapov at gmail.com>
Date: Mon, 26 Aug 2024 13:12:40 +0200
Subject: [PATCH 3/5] Update mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
Co-authored-by: Victor Perez <victor.perez at intel.com>
---
mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
index 5fda6a83fd8213..3db84678c2d48f 100644
--- a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
+++ b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
@@ -344,10 +344,7 @@ class MemorySpaceToOpenCLMemorySpaceConverter final : public TypeConverter {
std::optional<gpu::AddressSpace> memorySpaceMap(Attribute memSpaceAttr) {
if (!memSpaceAttr)
return gpu::AddressSpace::Global;
- auto gpuAddrSpace = dyn_cast<gpu::AddressSpaceAttr>(memSpaceAttr);
- if (!gpuAddrSpace)
- return std::nullopt;
- return gpuAddrSpace.getValue();
+ return std::nullopt;
}
};
>From 1961dffdb3e02ae4244eb2e0cd096cb64fc1b9a5 Mon Sep 17 00:00:00 2001
From: Petr Kurapov <petr.a.kurapov at intel.com>
Date: Mon, 26 Aug 2024 11:15:51 +0000
Subject: [PATCH 4/5] add debug type
---
mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
index 3db84678c2d48f..a9c6e76b506e61 100644
--- a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
+++ b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
@@ -34,6 +34,8 @@
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/FormatVariadic.h"
+#define DEBUG_TYPE "gpu-to-llvm-spv"
+
using namespace mlir;
namespace mlir {
>From 53baba218022fb2f0344bb6a9a5d2c9688ed5139 Mon Sep 17 00:00:00 2001
From: Petr Kurapov <petr.a.kurapov at intel.com>
Date: Thu, 29 Aug 2024 14:23:03 +0000
Subject: [PATCH 5/5] Add func & memeref to llvm conversion and test a more
complex caller/callee example
---
.../Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp | 48 ++++++++-----------
.../GPUToLLVMSPV/gpu-to-llvm-spv.mlir | 24 ++++++++++
2 files changed, 44 insertions(+), 28 deletions(-)
diff --git a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
index a9c6e76b506e61..6cbc8069c5bf68 100644
--- a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
+++ b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
@@ -9,12 +9,14 @@
#include "mlir/Conversion/GPUToLLVMSPV/GPUToLLVMSPVPass.h"
#include "../GPUCommon/GPUOpsLowering.h"
+#include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h"
#include "mlir/Conversion/GPUCommon/AttrToSPIRVConverter.h"
#include "mlir/Conversion/GPUCommon/GPUCommonPass.h"
#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
#include "mlir/Conversion/LLVMCommon/LoweringOptions.h"
#include "mlir/Conversion/LLVMCommon/Pattern.h"
#include "mlir/Conversion/LLVMCommon/TypeConverter.h"
+#include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
#include "mlir/Conversion/SPIRVCommon/AttrToLLVMConverter.h"
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
@@ -312,27 +314,22 @@ class MemorySpaceToOpenCLMemorySpaceConverter final : public TypeConverter {
public:
MemorySpaceToOpenCLMemorySpaceConverter() {
addConversion([](Type t) { return t; });
- addConversion(
- [this](BaseMemRefType memRefType) -> std::optional<Type> {
- std::optional<gpu::AddressSpace> addrSpace =
- memorySpaceMap(memRefType.getMemorySpace());
- if (!addrSpace) {
- LLVM_DEBUG(
- llvm::dbgs()
- << "cannot convert " << memRefType
- << " due to being unable to find address space in the map\n");
- return std::nullopt;
- }
- auto addrSpaceAttr =
- gpu::AddressSpaceAttr::get(memRefType.getContext(), *addrSpace);
- if (auto rankedType = dyn_cast<MemRefType>(memRefType)) {
- return MemRefType::get(memRefType.getShape(),
- memRefType.getElementType(),
- rankedType.getLayout(), addrSpaceAttr);
- }
- return UnrankedMemRefType::get(memRefType.getElementType(),
- addrSpaceAttr);
- });
+ addConversion([this](BaseMemRefType memRefType) -> std::optional<Type> {
+ // Attach global addr space attribute to memrefs with no addr space attr
+ Attribute memSpaceAttr = memRefType.getMemorySpace();
+ if (memSpaceAttr)
+ return std::nullopt;
+
+ auto addrSpaceAttr = gpu::AddressSpaceAttr::get(
+ memRefType.getContext(), gpu::AddressSpace::Global);
+ if (auto rankedType = dyn_cast<MemRefType>(memRefType)) {
+ return MemRefType::get(memRefType.getShape(),
+ memRefType.getElementType(),
+ rankedType.getLayout(), addrSpaceAttr);
+ }
+ return UnrankedMemRefType::get(memRefType.getElementType(),
+ addrSpaceAttr);
+ });
addConversion([this](FunctionType type) {
auto inputs = llvm::map_to_vector(
type.getInputs(), [this](Type ty) { return convertType(ty); });
@@ -341,13 +338,6 @@ class MemorySpaceToOpenCLMemorySpaceConverter final : public TypeConverter {
return FunctionType::get(type.getContext(), inputs, results);
});
}
-
-private:
- std::optional<gpu::AddressSpace> memorySpaceMap(Attribute memSpaceAttr) {
- if (!memSpaceAttr)
- return gpu::AddressSpace::Global;
- return std::nullopt;
- }
};
//===----------------------------------------------------------------------===//
@@ -388,6 +378,8 @@ struct GPUToLLVMSPVConversionPass final
gpu::ReturnOp, gpu::ShuffleOp, gpu::ThreadIdOp>();
populateGpuToLLVMSPVConversionPatterns(converter, patterns);
+ populateFuncToLLVMConversionPatterns(converter, patterns);
+ populateFinalizeMemRefToLLVMConversionPatterns(converter, patterns);
populateGpuMemorySpaceAttributeConversions(converter);
if (failed(applyPartialConversion(getOperation(), target,
diff --git a/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir b/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
index d100f36ae42521..481ae574a3fd4b 100644
--- a/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
+++ b/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
@@ -521,6 +521,7 @@ gpu.module @kernels {
// -----
gpu.module @kernels {
+// OPENCL: llvm.func spir_funccc @_Z12get_group_idj(i32)
// OPENCL-LABEL: llvm.func spir_funccc @no_address_spaces(
// OPENCL-SAME: %{{[a-zA-Z_][a-zA-Z0-9_]*}}: !llvm.ptr<1>
// OPENCL-SAME: %{{[a-zA-Z_][a-zA-Z0-9_]*}}: !llvm.ptr<1>
@@ -528,4 +529,27 @@ gpu.module @kernels {
gpu.func @no_address_spaces(%arg0: memref<f32>, %arg1: memref<f32, #gpu.address_space<global>>, %arg2: memref<f32>) {
gpu.return
}
+
+// OPENCL-LABEL: llvm.func spir_kernelcc @no_address_spaces_complex(
+// OPENCL-SAME: %{{[a-zA-Z_][a-zA-Z0-9_]*}}: !llvm.ptr<1>
+// OPENCL-SAME: %{{[a-zA-Z_][a-zA-Z0-9_]*}}: !llvm.ptr<1>
+// OPENCL: llvm.call @no_address_spaces_callee
+ gpu.func @no_address_spaces_complex(%arg0: memref<2x2xf32>, %arg1: memref<4xf32>) kernel {
+ func.call @no_address_spaces_callee(%arg0, %arg1) : (memref<2x2xf32>, memref<4xf32>) -> ()
+ gpu.return
+ }
+// OPENCL-LABEL: llvm.func @no_address_spaces_callee(
+// OPENCL-SAME: %{{[a-zA-Z_][a-zA-Z0-9_]*}}: !llvm.ptr<1>
+// OPENCL-SAME: %{{[a-zA-Z_][a-zA-Z0-9_]*}}: !llvm.ptr<1>
+// OPENCL: [[C0:%.*]] = llvm.mlir.constant(0 : i32) : i32
+// OPENCL: llvm.call spir_funccc @_Z12get_group_idj([[C0]]) {
+// OPENCL: [[LD:%.*]] = llvm.load
+// OPENCL: llvm.store [[LD]]
+ func.func @no_address_spaces_callee(%arg0: memref<2x2xf32>, %arg1: memref<4xf32>) {
+ %block_id = gpu.block_id x
+ %0 = memref.load %arg0[%block_id, %block_id] : memref<2x2xf32>
+ memref.store %0, %arg1[%block_id] : memref<4xf32>
+ func.return
+ }
+
}
More information about the Mlir-commits
mailing list