1 | //===------------------ TestVulkanRunnerPipeline.cpp --------------------===// |
---|---|
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 | // Implements a pipeline for use by Vulkan runner tests. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "mlir/Conversion/GPUCommon/GPUCommonPass.h" |
14 | #include "mlir/Conversion/GPUToSPIRV/GPUToSPIRVPass.h" |
15 | #include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h" |
16 | #include "mlir/Dialect/Func/IR/FuncOps.h" |
17 | #include "mlir/Dialect/GPU/IR/GPUDialect.h" |
18 | #include "mlir/Dialect/GPU/Transforms/Passes.h" |
19 | #include "mlir/Dialect/LLVMIR/Transforms/RequestCWrappers.h" |
20 | #include "mlir/Dialect/MemRef/Transforms/Passes.h" |
21 | #include "mlir/Dialect/SPIRV/IR/SPIRVOps.h" |
22 | #include "mlir/Dialect/SPIRV/Transforms/Passes.h" |
23 | #include "mlir/Pass/PassManager.h" |
24 | #include "mlir/Pass/PassOptions.h" |
25 | |
26 | using namespace mlir; |
27 | |
28 | // Defined in the test directory, no public header. |
29 | namespace mlir::test { |
30 | std::unique_ptr<Pass> createTestConvertToSPIRVPass(bool convertGPUModules, |
31 | bool nestInGPUModule); |
32 | } |
33 | |
34 | namespace { |
35 | |
36 | struct VulkanRunnerPipelineOptions |
37 | : PassPipelineOptions<VulkanRunnerPipelineOptions> { |
38 | Option<bool> spirvWebGPUPrepare{ |
39 | *this, "spirv-webgpu-prepare", |
40 | llvm::cl::desc("Run MLIR transforms used when targetting WebGPU")}; |
41 | }; |
42 | |
43 | void buildTestVulkanRunnerPipeline(OpPassManager &passManager, |
44 | const VulkanRunnerPipelineOptions &options) { |
45 | passManager.addPass(pass: createGpuKernelOutliningPass()); |
46 | passManager.addPass(memref::createFoldMemRefAliasOpsPass()); |
47 | |
48 | GpuSPIRVAttachTargetOptions attachTargetOptions{}; |
49 | attachTargetOptions.spirvVersion = "v1.0"; |
50 | attachTargetOptions.spirvCapabilities.push_back("Shader"); |
51 | attachTargetOptions.spirvExtensions.push_back( |
52 | "SPV_KHR_storage_buffer_storage_class"); |
53 | passManager.addPass(pass: createGpuSPIRVAttachTarget(attachTargetOptions)); |
54 | |
55 | passManager.addPass(pass: test::createTestConvertToSPIRVPass( |
56 | /*convertGPUModules=*/true, /*nestInGPUModule=*/true)); |
57 | |
58 | OpPassManager &spirvModulePM = |
59 | passManager.nest<gpu::GPUModuleOp>().nest<spirv::ModuleOp>(); |
60 | spirvModulePM.addPass(spirv::createSPIRVLowerABIAttributesPass()); |
61 | spirvModulePM.addPass(spirv::createSPIRVUpdateVCEPass()); |
62 | if (options.spirvWebGPUPrepare) |
63 | spirvModulePM.addPass(spirv::createSPIRVWebGPUPreparePass()); |
64 | |
65 | passManager.addPass(pass: createGpuModuleToBinaryPass()); |
66 | |
67 | passManager.addPass(pass: createFinalizeMemRefToLLVMConversionPass()); |
68 | passManager.nest<func::FuncOp>().addPass( |
69 | LLVM::createLLVMRequestCWrappersPass()); |
70 | // VulkanRuntimeWrappers.cpp requires these calling convention options. |
71 | GpuToLLVMConversionPassOptions opt; |
72 | opt.hostBarePtrCallConv = false; |
73 | opt.kernelBarePtrCallConv = true; |
74 | opt.kernelIntersperseSizeCallConv = true; |
75 | passManager.addPass(pass: createGpuToLLVMConversionPass(opt)); |
76 | } |
77 | |
78 | } // namespace |
79 | |
80 | namespace mlir::test { |
81 | void registerTestVulkanRunnerPipeline() { |
82 | PassPipelineRegistration<VulkanRunnerPipelineOptions>( |
83 | "test-vulkan-runner-pipeline", |
84 | "Runs a series of passes intended for Vulkan runner tests. Lowers GPU " |
85 | "dialect to LLVM dialect for the host and to serialized Vulkan SPIR-V " |
86 | "for the device.", |
87 | buildTestVulkanRunnerPipeline); |
88 | } |
89 | } // namespace mlir::test |
90 |