//===------------------ TestVulkanRunnerPipeline.cpp --------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Implements a pipeline for use by Vulkan runner tests. // //===----------------------------------------------------------------------===// #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" #include "mlir/Pass/PassManager.h" #include "mlir/Pass/PassOptions.h" using namespace mlir; // Defined in the test directory, no public header. namespace mlir::test { std::unique_ptr createTestConvertToSPIRVPass(bool convertGPUModules, bool nestInGPUModule); } namespace { struct VulkanRunnerPipelineOptions : PassPipelineOptions { Option spirvWebGPUPrepare{ *this, "spirv-webgpu-prepare", llvm::cl::desc("Run MLIR transforms used when targetting WebGPU")}; }; void buildTestVulkanRunnerPipeline(OpPassManager &passManager, const VulkanRunnerPipelineOptions &options) { passManager.addPass(createGpuKernelOutliningPass()); passManager.addPass(memref::createFoldMemRefAliasOpsPass()); GpuSPIRVAttachTargetOptions attachTargetOptions{}; attachTargetOptions.spirvVersion = "v1.0"; attachTargetOptions.spirvCapabilities.push_back("Shader"); attachTargetOptions.spirvExtensions.push_back( "SPV_KHR_storage_buffer_storage_class"); passManager.addPass(createGpuSPIRVAttachTarget(attachTargetOptions)); passManager.addPass(test::createTestConvertToSPIRVPass( /*convertGPUModules=*/true, /*nestInGPUModule=*/true)); OpPassManager &spirvModulePM = passManager.nest().nest(); spirvModulePM.addPass(spirv::createSPIRVLowerABIAttributesPass()); spirvModulePM.addPass(spirv::createSPIRVUpdateVCEPass()); if (options.spirvWebGPUPrepare) spirvModulePM.addPass(spirv::createSPIRVWebGPUPreparePass()); passManager.addPass(createGpuModuleToBinaryPass()); passManager.addPass(createFinalizeMemRefToLLVMConversionPass()); passManager.nest().addPass( LLVM::createLLVMRequestCWrappersPass()); // VulkanRuntimeWrappers.cpp requires these calling convention options. GpuToLLVMConversionPassOptions opt; opt.hostBarePtrCallConv = false; opt.kernelBarePtrCallConv = true; opt.kernelIntersperseSizeCallConv = true; passManager.addPass(createGpuToLLVMConversionPass(opt)); } } // namespace namespace mlir::test { void registerTestVulkanRunnerPipeline() { PassPipelineRegistration( "test-vulkan-runner-pipeline", "Runs a series of passes intended for Vulkan runner tests. Lowers GPU " "dialect to LLVM dialect for the host and to serialized Vulkan SPIR-V " "for the device.", buildTestVulkanRunnerPipeline); } } // namespace mlir::test