Skip to content

Commit 75cb9ed

Browse files
authored
[MLIR][GPU-LLVM] Add GPU to LLVM-SPV address space mapping (#102621)
Implement mapping: - `global`: 1 - `workgroup`: 3 - `private`: 0 Add `addressSpaceToStorageClass`, mapping GPU address spaces to SPIR-V storage classes to be able to use SPIR-V's `storageClassToAddressSpace`, mapping SPIR-V storage classes to LLVM address spaces according to our mapping above *by definition*. --------- Signed-off-by: Victor Perez <[email protected]>
1 parent fc1b019 commit 75cb9ed

File tree

6 files changed

+82
-7
lines changed

6 files changed

+82
-7
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===- AttrToSPIRVConverter.h - GPU attributes conversion to SPIR-V - C++ -===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
#ifndef MLIR_CONVERSION_GPUCOMMON_ATTRTOSPIRVCONVERTER_H_
9+
#define MLIR_CONVERSION_GPUCOMMON_ATTRTOSPIRVCONVERTER_H_
10+
11+
#include <mlir/Dialect/GPU/IR/GPUDialect.h>
12+
#include <mlir/Dialect/SPIRV/IR/SPIRVEnums.h>
13+
14+
namespace mlir {
15+
spirv::StorageClass addressSpaceToStorageClass(gpu::AddressSpace addressSpace);
16+
} // namespace mlir
17+
18+
#endif // MLIR_CONVERSION_GPUCOMMON_ATTRTOSPIRVCONVERTER_H_

mlir/include/mlir/Conversion/GPUToLLVMSPV/GPUToLLVMSPVPass.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@ class DialectRegistry;
1616
class LLVMTypeConverter;
1717
class RewritePatternSet;
1818
class Pass;
19+
class TypeConverter;
1920

2021
#define GEN_PASS_DECL_CONVERTGPUOPSTOLLVMSPVOPS
2122
#include "mlir/Conversion/Passes.h.inc"
2223

2324
void populateGpuToLLVMSPVConversionPatterns(LLVMTypeConverter &converter,
2425
RewritePatternSet &patterns);
26+
27+
/// Populates memory space attribute conversion rules for lowering
28+
/// gpu.address_space to integer values.
29+
void populateGpuMemorySpaceAttributeConversions(TypeConverter &typeConverter);
2530
} // namespace mlir
2631

2732
#endif // MLIR_CONVERSION_GPUTOLLVMSPV_GPUTOLLVMSPVPASS_H_
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===- AttrToSPIRVConverter.cpp - GPU attributes conversion to SPIR-V - C++===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include <mlir/Conversion/GPUCommon/AttrToSPIRVConverter.h>
10+
11+
namespace mlir {
12+
spirv::StorageClass addressSpaceToStorageClass(gpu::AddressSpace addressSpace) {
13+
switch (addressSpace) {
14+
case gpu::AddressSpace::Global:
15+
return spirv::StorageClass::CrossWorkgroup;
16+
case gpu::AddressSpace::Workgroup:
17+
return spirv::StorageClass::Workgroup;
18+
case gpu::AddressSpace::Private:
19+
return spirv::StorageClass::Private;
20+
}
21+
llvm_unreachable("Unhandled storage class");
22+
}
23+
} // namespace mlir

mlir/lib/Conversion/GPUCommon/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ if (MLIR_ENABLE_ROCM_CONVERSIONS)
1515
endif()
1616

1717
add_mlir_conversion_library(MLIRGPUToGPURuntimeTransforms
18+
AttrToSPIRVConverter.cpp
1819
GPUToLLVMConversion.cpp
1920
GPUOpsLowering.cpp
2021

mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include "mlir/Conversion/GPUToLLVMSPV/GPUToLLVMSPVPass.h"
1010

1111
#include "../GPUCommon/GPUOpsLowering.h"
12+
#include "mlir/Conversion/GPUCommon/AttrToSPIRVConverter.h"
13+
#include "mlir/Conversion/GPUCommon/GPUCommonPass.h"
1214
#include "mlir/Conversion/LLVMCommon/ConversionTarget.h"
1315
#include "mlir/Conversion/LLVMCommon/LoweringOptions.h"
1416
#include "mlir/Conversion/LLVMCommon/Pattern.h"
@@ -328,6 +330,7 @@ struct GPUToLLVMSPVConversionPass final
328330
gpu::ReturnOp, gpu::ShuffleOp, gpu::ThreadIdOp>();
329331

330332
populateGpuToLLVMSPVConversionPatterns(converter, patterns);
333+
populateGpuMemorySpaceAttributeConversions(converter);
331334

332335
if (failed(applyPartialConversion(getOperation(), target,
333336
std::move(patterns))))
@@ -341,6 +344,15 @@ struct GPUToLLVMSPVConversionPass final
341344
//===----------------------------------------------------------------------===//
342345

343346
namespace mlir {
347+
namespace {
348+
static unsigned
349+
gpuAddressSpaceToOCLAddressSpace(gpu::AddressSpace addressSpace) {
350+
constexpr spirv::ClientAPI clientAPI = spirv::ClientAPI::OpenCL;
351+
return storageClassToAddressSpace(clientAPI,
352+
addressSpaceToStorageClass(addressSpace));
353+
}
354+
} // namespace
355+
344356
void populateGpuToLLVMSPVConversionPatterns(LLVMTypeConverter &typeConverter,
345357
RewritePatternSet &patterns) {
346358
patterns.add<GPUBarrierConversion, GPUReturnOpLowering, GPUShuffleConversion,
@@ -349,12 +361,11 @@ void populateGpuToLLVMSPVConversionPatterns(LLVMTypeConverter &typeConverter,
349361
LaunchConfigOpConversion<gpu::BlockDimOp>,
350362
LaunchConfigOpConversion<gpu::ThreadIdOp>,
351363
LaunchConfigOpConversion<gpu::GlobalIdOp>>(typeConverter);
352-
constexpr spirv::ClientAPI clientAPI = spirv::ClientAPI::OpenCL;
353364
MLIRContext *context = &typeConverter.getContext();
354365
unsigned privateAddressSpace =
355-
storageClassToAddressSpace(clientAPI, spirv::StorageClass::Function);
366+
gpuAddressSpaceToOCLAddressSpace(gpu::AddressSpace::Private);
356367
unsigned localAddressSpace =
357-
storageClassToAddressSpace(clientAPI, spirv::StorageClass::Workgroup);
368+
gpuAddressSpaceToOCLAddressSpace(gpu::AddressSpace::Workgroup);
358369
OperationName llvmFuncOpName(LLVM::LLVMFuncOp::getOperationName(), context);
359370
StringAttr kernelBlockSizeAttributeName =
360371
LLVM::LLVMFuncOp::getReqdWorkGroupSizeAttrName(llvmFuncOpName);
@@ -366,4 +377,9 @@ void populateGpuToLLVMSPVConversionPatterns(LLVMTypeConverter &typeConverter,
366377
LLVM::CConv::SPIR_KERNEL, LLVM::CConv::SPIR_FUNC,
367378
/*encodeWorkgroupAttributionsAsArguments=*/true});
368379
}
380+
381+
void populateGpuMemorySpaceAttributeConversions(TypeConverter &typeConverter) {
382+
populateGpuMemorySpaceAttributeConversions(typeConverter,
383+
gpuAddressSpaceToOCLAddressSpace);
384+
}
369385
} // namespace mlir

mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ gpu.module @kernels {
444444
// CHECK: %[[VAL_17:.*]] = llvm.insertvalue %[[VAL_15]], %[[VAL_16]][0]
445445
// CHECK: llvm.insertvalue %[[VAL_15]], %[[VAL_17]][1]
446446
gpu.func @kernel_with_private_attributions()
447-
private(%arg2: memref<32xf32>, %arg3: memref<16xi16>)
447+
private(%arg2: memref<32xf32, #gpu.address_space<private>>, %arg3: memref<16xi16, #gpu.address_space<private>>)
448448
kernel {
449449
gpu.return
450450
}
@@ -471,7 +471,7 @@ gpu.module @kernels {
471471
// CHECK: %[[VAL_42:.*]] = llvm.insertvalue %[[VAL_30]], %[[VAL_41]][0]
472472
// CHECK: llvm.insertvalue %[[VAL_30]], %[[VAL_42]][1]
473473
gpu.func @kernel_with_workgoup_attributions()
474-
workgroup(%arg2: memref<32xf32, 3>, %arg3: memref<16xi16, 3>)
474+
workgroup(%arg2: memref<32xf32, #gpu.address_space<workgroup>>, %arg3: memref<16xi16, #gpu.address_space<workgroup>>)
475475
kernel {
476476
gpu.return
477477
}
@@ -491,8 +491,8 @@ gpu.module @kernels {
491491
// CHECK-64: %[[VAL_92:.*]] = llvm.alloca %[[VAL_91]] x i64 : (i64) -> !llvm.ptr
492492
// CHECK-32: %[[VAL_92:.*]] = llvm.alloca %[[VAL_91]] x i32 : (i64) -> !llvm.ptr
493493
gpu.func @kernel_with_both_attributions()
494-
workgroup(%arg4: memref<8xf32, 3>, %arg5: memref<16xindex, 3>)
495-
private(%arg6: memref<32xi32>, %arg7: memref<32xindex>)
494+
workgroup(%arg4: memref<8xf32, #gpu.address_space<workgroup>>, %arg5: memref<16xindex, #gpu.address_space<workgroup>>)
495+
private(%arg6: memref<32xi32, #gpu.address_space<private>>, %arg7: memref<32xindex, #gpu.address_space<private>>)
496496
kernel {
497497
gpu.return
498498
}
@@ -503,3 +503,15 @@ gpu.module @kernels {
503503
gpu.return
504504
}
505505
}
506+
507+
// -----
508+
509+
gpu.module @kernels {
510+
// CHECK-LABEL: llvm.func spir_funccc @address_spaces(
511+
// CHECK-SAME: {{.*}}: !llvm.ptr<1>
512+
// CHECK-SAME: {{.*}}: !llvm.ptr<3>
513+
// CHECK-SAME: {{.*}}: !llvm.ptr
514+
gpu.func @address_spaces(%arg0: memref<f32, #gpu.address_space<global>>, %arg1: memref<f32, #gpu.address_space<workgroup>>, %arg2: memref<f32, #gpu.address_space<private>>) {
515+
gpu.return
516+
}
517+
}

0 commit comments

Comments
 (0)