Skip to content

[mlir][spirv] Add mgpu* wrappers for Vulkan runtime, migrate some tests #123114

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion mlir/include/mlir/Conversion/GPUCommon/GPUCommonPass.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ struct FunctionCallBuilder {
/// populate converter for gpu types.
void populateGpuToLLVMConversionPatterns(LLVMTypeConverter &converter,
RewritePatternSet &patterns,
bool kernelBarePtrCallConv = false);
bool kernelBarePtrCallConv = false,
bool typeCheckKernelArgs = false);

/// A function that maps a MemorySpace enum to a target-specific integer value.
using MemorySpaceMapping = std::function<unsigned(gpu::AddressSpace)>;
Expand Down
6 changes: 6 additions & 0 deletions mlir/include/mlir/Conversion/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,12 @@ def GpuToLLVMConversionPass : Pass<"gpu-to-llvm", "ModuleOp"> {
/*default=*/"false",
"Use bare pointers to pass memref arguments to kernels. "
"The kernel must use the same setting for this option."
>,
Option<"typeCheckKernelArgs", "type-check-kernel-args", "bool",
/*default=*/"false",
"Require all kernel arguments to be memrefs of rank 1 and with a "
"32-bit element size. This is a temporary option that will be "
"removed; TODO(https://github.com/llvm/llvm-project/issues/73457)."
>
];

Expand Down
39 changes: 33 additions & 6 deletions mlir/lib/Conversion/GPUCommon/GPUToLLVMConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -427,16 +427,19 @@ class LegalizeLaunchFuncOpPattern
: public ConvertOpToGpuRuntimeCallPattern<gpu::LaunchFuncOp> {
public:
LegalizeLaunchFuncOpPattern(const LLVMTypeConverter &typeConverter,
bool kernelBarePtrCallConv)
bool kernelBarePtrCallConv,
bool typeCheckKernelArgs)
: ConvertOpToGpuRuntimeCallPattern<gpu::LaunchFuncOp>(typeConverter),
kernelBarePtrCallConv(kernelBarePtrCallConv) {}
kernelBarePtrCallConv(kernelBarePtrCallConv),
typeCheckKernelArgs(typeCheckKernelArgs) {}

private:
LogicalResult
matchAndRewrite(gpu::LaunchFuncOp launchOp, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override;

bool kernelBarePtrCallConv;
bool typeCheckKernelArgs;
};

/// A rewrite pattern to convert gpu.memcpy operations into a GPU runtime
Expand Down Expand Up @@ -563,8 +566,8 @@ void GpuToLLVMConversionPass::runOnOperation() {
populateFinalizeMemRefToLLVMConversionPatterns(converter, patterns);
populateAsyncStructuralTypeConversionsAndLegality(converter, patterns,
target);
populateGpuToLLVMConversionPatterns(converter, patterns,
kernelBarePtrCallConv);
populateGpuToLLVMConversionPatterns(
converter, patterns, kernelBarePtrCallConv, typeCheckKernelArgs);

if (failed(
applyPartialConversion(getOperation(), target, std::move(patterns))))
Expand Down Expand Up @@ -966,6 +969,28 @@ LogicalResult LegalizeLaunchFuncOpPattern::matchAndRewrite(
// stream must be created to pass to subsequent operations.
else if (launchOp.getAsyncToken())
stream = streamCreateCallBuilder.create(loc, rewriter, {}).getResult();

if (typeCheckKernelArgs) {
// The current non-bare-pointer ABI is a bad fit for `mgpuLaunchKernel`,
// which takes an untyped list of arguments. The type check here prevents
// accidentally violating the assumption made in vulkan-runtime-wrappers.cpp
// and creating a unchecked runtime ABI mismatch.
// TODO(https://github.com/llvm/llvm-project/issues/73457): Change the ABI
// here to remove the need for this type check.
for (Value arg : launchOp.getKernelOperands()) {
if (auto memrefTy = dyn_cast<MemRefType>(arg.getType())) {
if (memrefTy.getRank() != 1 ||
memrefTy.getElementTypeBitWidth() != 32) {
return rewriter.notifyMatchFailure(
launchOp, "Operand to launch op is not a rank-1 memref with "
"32-bit element type.");
}
} else {
return rewriter.notifyMatchFailure(
launchOp, "Operand to launch op is not a memref.");
}
}
}
// Lower the kernel operands to match kernel parameters.
// Note: If `useBarePtrCallConv` is set in the type converter's options,
// the value of `kernelBarePtrCallConv` will be ignored.
Expand Down Expand Up @@ -1737,7 +1762,8 @@ LogicalResult ConvertCreateBsrOpToGpuRuntimeCallPattern::matchAndRewrite(

void mlir::populateGpuToLLVMConversionPatterns(LLVMTypeConverter &converter,
RewritePatternSet &patterns,
bool kernelBarePtrCallConv) {
bool kernelBarePtrCallConv,
bool typeCheckKernelArgs) {
addOpaquePointerConversion<gpu::AsyncTokenType>(converter);
addOpaquePointerConversion<gpu::SparseDnTensorHandleType>(converter);
addOpaquePointerConversion<gpu::SparseSpMatHandleType>(converter);
Expand Down Expand Up @@ -1774,7 +1800,8 @@ void mlir::populateGpuToLLVMConversionPatterns(LLVMTypeConverter &converter,
ConvertSpGEMMCopyOpToGpuRuntimeCallPattern,
ConvertSpMatGetSizeOpToGpuRuntimeCallPattern,
ConvertSetCsrPointersOpToGpuRuntimeCallPattern>(converter);
patterns.add<LegalizeLaunchFuncOpPattern>(converter, kernelBarePtrCallConv);
patterns.add<LegalizeLaunchFuncOpPattern>(converter, kernelBarePtrCallConv,
typeCheckKernelArgs);
}

//===----------------------------------------------------------------------===//
Expand Down
22 changes: 21 additions & 1 deletion mlir/test/lib/Pass/TestVulkanRunnerPipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@
//===----------------------------------------------------------------------===//

#include "mlir/Conversion/ConvertToSPIRV/ConvertToSPIRVPass.h"
#include "mlir/Conversion/GPUCommon/GPUCommonPass.h"
#include "mlir/Conversion/GPUToSPIRV/GPUToSPIRVPass.h"
#include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
#include "mlir/Dialect/GPU/Transforms/Passes.h"
#include "mlir/Dialect/LLVMIR/Transforms/RequestCWrappers.h"
#include "mlir/Dialect/MemRef/Transforms/Passes.h"
#include "mlir/Dialect/SPIRV/IR/SPIRVOps.h"
#include "mlir/Dialect/SPIRV/Transforms/Passes.h"
Expand All @@ -29,6 +33,9 @@ struct VulkanRunnerPipelineOptions
Option<bool> spirvWebGPUPrepare{
*this, "spirv-webgpu-prepare",
llvm::cl::desc("Run MLIR transforms used when targetting WebGPU")};
Option<bool> toLlvm{*this, "to-llvm",
llvm::cl::desc("Run MLIR transforms to lower host code "
"to LLVM, intended for mlir-cpu-runner")};
};

void buildTestVulkanRunnerPipeline(OpPassManager &passManager,
Expand Down Expand Up @@ -56,6 +63,19 @@ void buildTestVulkanRunnerPipeline(OpPassManager &passManager,
spirvModulePM.addPass(spirv::createSPIRVWebGPUPreparePass());

passManager.addPass(createGpuModuleToBinaryPass());

if (options.toLlvm) {
passManager.addPass(createFinalizeMemRefToLLVMConversionPass());
passManager.nest<func::FuncOp>().addPass(
LLVM::createRequestCWrappersPass());
// vulkan-runtime-wrappers.cpp uses the non-bare-pointer calling convention,
// and the type check is needed to prevent accidental ABI mismatches.
GpuToLLVMConversionPassOptions opt;
opt.hostBarePtrCallConv = false;
opt.kernelBarePtrCallConv = false;
opt.typeCheckKernelArgs = true;
passManager.addPass(createGpuToLLVMConversionPass(opt));
}
}

} // namespace
Expand All @@ -65,7 +85,7 @@ void registerTestVulkanRunnerPipeline() {
PassPipelineRegistration<VulkanRunnerPipelineOptions>(
"test-vulkan-runner-pipeline",
"Runs a series of passes for lowering GPU-dialect MLIR to "
"SPIR-V-dialect MLIR intended for mlir-vulkan-runner.",
"SPIR-V-dialect MLIR intended for mlir-vulkan-runner or mlir-cpu-runner.",
buildTestVulkanRunnerPipeline);
}
} // namespace mlir::test
4 changes: 2 additions & 2 deletions mlir/test/mlir-vulkan-runner/addf.mlir
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: mlir-opt %s -test-vulkan-runner-pipeline \
// RUN: | mlir-vulkan-runner - --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils --entry-point-result=void | FileCheck %s
// RUN: mlir-opt %s -test-vulkan-runner-pipeline=to-llvm \
// RUN: | mlir-cpu-runner - --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils --entry-point-result=void | FileCheck %s

// CHECK: [3.3, 3.3, 3.3, 3.3, 3.3, 3.3, 3.3, 3.3]
module attributes {
Expand Down
4 changes: 2 additions & 2 deletions mlir/test/mlir-vulkan-runner/addf_if.mlir
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: mlir-opt %s -test-vulkan-runner-pipeline \
// RUN: | mlir-vulkan-runner - --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils --entry-point-result=void | FileCheck %s
// RUN: mlir-opt %s -test-vulkan-runner-pipeline=to-llvm \
// RUN: | mlir-cpu-runner - --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils --entry-point-result=void | FileCheck %s

// CHECK: [3.3, 3.3, 3.3, 3.3, 0, 0, 0, 0]
module attributes {
Expand Down
8 changes: 4 additions & 4 deletions mlir/test/mlir-vulkan-runner/addui_extended.mlir
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Make sure that addition with carry produces expected results
// with and without expansion to primitive add/cmp ops for WebGPU.

// RUN: mlir-opt %s -test-vulkan-runner-pipeline \
// RUN: | mlir-vulkan-runner - \
// RUN: mlir-opt %s -test-vulkan-runner-pipeline=to-llvm \
// RUN: | mlir-cpu-runner - \
// RUN: --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils \
// RUN: --entry-point-result=void | FileCheck %s

// RUN: mlir-opt %s -test-vulkan-runner-pipeline=spirv-webgpu-prepare \
// RUN: | mlir-vulkan-runner - \
// RUN: mlir-opt %s -test-vulkan-runner-pipeline="spirv-webgpu-prepare to-llvm" \
// RUN: | mlir-cpu-runner - \
// RUN: --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils \
// RUN: --entry-point-result=void | FileCheck %s

Expand Down
8 changes: 4 additions & 4 deletions mlir/test/mlir-vulkan-runner/smul_extended.mlir
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Make sure that signed extended multiplication produces expected results
// with and without expansion to primitive mul/add ops for WebGPU.

// RUN: mlir-opt %s -test-vulkan-runner-pipeline \
// RUN: | mlir-vulkan-runner - \
// RUN: mlir-opt %s -test-vulkan-runner-pipeline=to-llvm \
// RUN: | mlir-cpu-runner - \
// RUN: --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils \
// RUN: --entry-point-result=void | FileCheck %s

// RUN: mlir-opt %s -test-vulkan-runner-pipeline=spirv-webgpu-prepare \
// RUN: | mlir-vulkan-runner - \
// RUN: mlir-opt %s -test-vulkan-runner-pipeline="spirv-webgpu-prepare to-llvm" \
// RUN: | mlir-cpu-runner - \
// RUN: --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils \
// RUN: --entry-point-result=void | FileCheck %s

Expand Down
4 changes: 2 additions & 2 deletions mlir/test/mlir-vulkan-runner/time.mlir
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: mlir-opt %s -test-vulkan-runner-pipeline \
// RUN: | mlir-vulkan-runner - --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils --entry-point-result=void | FileCheck %s
// RUN: mlir-opt %s -test-vulkan-runner-pipeline=to-llvm \
// RUN: | mlir-cpu-runner - --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils --entry-point-result=void | FileCheck %s

// CHECK: Compute shader execution time
// CHECK: Command buffer submit time
Expand Down
8 changes: 4 additions & 4 deletions mlir/test/mlir-vulkan-runner/umul_extended.mlir
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
// Make sure that unsigned extended multiplication produces expected results
// with and without expansion to primitive mul/add ops for WebGPU.

// RUN: mlir-opt %s -test-vulkan-runner-pipeline \
// RUN: | mlir-vulkan-runner - \
// RUN: mlir-opt %s -test-vulkan-runner-pipeline=to-llvm \
// RUN: | mlir-cpu-runner - \
// RUN: --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils \
// RUN: --entry-point-result=void | FileCheck %s

// RUN: mlir-opt %s -test-vulkan-runner-pipeline=spirv-webgpu-prepare \
// RUN: | mlir-vulkan-runner - \
// RUN: mlir-opt %s -test-vulkan-runner-pipeline="spirv-webgpu-prepare to-llvm" \
// RUN: | mlir-cpu-runner - \
// RUN: --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils \
// RUN: --entry-point-result=void | FileCheck %s

Expand Down
4 changes: 2 additions & 2 deletions mlir/test/mlir-vulkan-runner/vector-deinterleave.mlir
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: mlir-opt %s -test-vulkan-runner-pipeline \
// RUN: | mlir-vulkan-runner - \
// RUN: mlir-opt %s -test-vulkan-runner-pipeline=to-llvm \
// RUN: | mlir-cpu-runner - \
// RUN: --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils \
// RUN: --entry-point-result=void | FileCheck %s

Expand Down
4 changes: 2 additions & 2 deletions mlir/test/mlir-vulkan-runner/vector-interleave.mlir
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: mlir-opt %s -test-vulkan-runner-pipeline \
// RUN: | mlir-vulkan-runner - \
// RUN: mlir-opt %s -test-vulkan-runner-pipeline=to-llvm \
// RUN: | mlir-cpu-runner - \
// RUN: --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils \
// RUN: --entry-point-result=void | FileCheck %s

Expand Down
4 changes: 2 additions & 2 deletions mlir/test/mlir-vulkan-runner/vector-shuffle.mlir
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: mlir-opt %s -test-vulkan-runner-pipeline \
// RUN: | mlir-vulkan-runner - \
// RUN: mlir-opt %s -test-vulkan-runner-pipeline=to-llvm \
// RUN: | mlir-cpu-runner - \
// RUN: --shared-libs=%vulkan-runtime-wrappers,%mlir_runner_utils \
// RUN: --entry-point-result=void | FileCheck %s

Expand Down
Loading
Loading