Differential D77339 Diff 255803 mlir/lib/Conversion/GPUToVulkan/ConvertGPULaunchFuncToVulkanLaunchFunc.cpp
Changeset View
Changeset View
Standalone View
Standalone View
mlir/lib/Conversion/GPUToVulkan/ConvertGPULaunchFuncToVulkanLaunchFunc.cpp
Show All 32 Lines | |||||
namespace { | namespace { | ||||
/// A pass to convert gpu launch op to vulkan launch call op, by creating a | /// A pass to convert gpu launch op to vulkan launch call op, by creating a | ||||
/// SPIR-V binary shader from `spirv::ModuleOp` using `spirv::serialize` | /// SPIR-V binary shader from `spirv::ModuleOp` using `spirv::serialize` | ||||
/// function and attaching binary data and entry point name as an attributes to | /// function and attaching binary data and entry point name as an attributes to | ||||
/// created vulkan launch call op. | /// created vulkan launch call op. | ||||
class ConvertGpuLaunchFuncToVulkanLaunchFunc | class ConvertGpuLaunchFuncToVulkanLaunchFunc | ||||
: public ModulePass<ConvertGpuLaunchFuncToVulkanLaunchFunc> { | : public OperationPass<ConvertGpuLaunchFuncToVulkanLaunchFunc, ModuleOp> { | ||||
public: | public: | ||||
/// Include the generated pass utilities. | /// Include the generated pass utilities. | ||||
#define GEN_PASS_ConvertGpuLaunchFuncToVulkanLaunchFunc | #define GEN_PASS_ConvertGpuLaunchFuncToVulkanLaunchFunc | ||||
#include "mlir/Conversion/Passes.h.inc" | #include "mlir/Conversion/Passes.h.inc" | ||||
void runOnModule() override; | void runOnOperation() override; | ||||
private: | private: | ||||
/// Creates a SPIR-V binary shader from the given `module` using | /// Creates a SPIR-V binary shader from the given `module` using | ||||
/// `spirv::serialize` function. | /// `spirv::serialize` function. | ||||
LogicalResult createBinaryShader(ModuleOp module, | LogicalResult createBinaryShader(ModuleOp module, | ||||
std::vector<char> &binaryShader); | std::vector<char> &binaryShader); | ||||
/// Converts the given `launchOp` to vulkan launch call. | /// Converts the given `launchOp` to vulkan launch call. | ||||
void convertGpuLaunchFunc(gpu::LaunchFuncOp launchOp); | void convertGpuLaunchFunc(gpu::LaunchFuncOp launchOp); | ||||
/// Checks where the given type is supported by Vulkan runtime. | /// Checks where the given type is supported by Vulkan runtime. | ||||
bool isSupportedType(Type type) { | bool isSupportedType(Type type) { | ||||
// TODO(denis0x0D): Handle other types. | // TODO(denis0x0D): Handle other types. | ||||
if (auto memRefType = type.dyn_cast_or_null<MemRefType>()) | if (auto memRefType = type.dyn_cast_or_null<MemRefType>()) | ||||
return memRefType.hasRank() && | return memRefType.hasRank() && | ||||
(memRefType.getRank() >= 1 && memRefType.getRank() <= 3); | (memRefType.getRank() >= 1 && memRefType.getRank() <= 3); | ||||
return false; | return false; | ||||
} | } | ||||
/// Declares the vulkan launch function. Returns an error if the any type of | /// Declares the vulkan launch function. Returns an error if the any type of | ||||
/// operand is unsupported by Vulkan runtime. | /// operand is unsupported by Vulkan runtime. | ||||
LogicalResult declareVulkanLaunchFunc(Location loc, | LogicalResult declareVulkanLaunchFunc(Location loc, | ||||
gpu::LaunchFuncOp launchOp); | gpu::LaunchFuncOp launchOp); | ||||
}; | }; | ||||
} // anonymous namespace | } // anonymous namespace | ||||
void ConvertGpuLaunchFuncToVulkanLaunchFunc::runOnModule() { | void ConvertGpuLaunchFuncToVulkanLaunchFunc::runOnOperation() { | ||||
bool done = false; | bool done = false; | ||||
getModule().walk([this, &done](gpu::LaunchFuncOp op) { | getOperation().walk([this, &done](gpu::LaunchFuncOp op) { | ||||
if (done) { | if (done) { | ||||
op.emitError("should only contain one 'gpu::LaunchFuncOp' op"); | op.emitError("should only contain one 'gpu::LaunchFuncOp' op"); | ||||
return signalPassFailure(); | return signalPassFailure(); | ||||
} | } | ||||
done = true; | done = true; | ||||
convertGpuLaunchFunc(op); | convertGpuLaunchFunc(op); | ||||
}); | }); | ||||
// Erase `gpu::GPUModuleOp` and `spirv::Module` operations. | // Erase `gpu::GPUModuleOp` and `spirv::Module` operations. | ||||
for (auto gpuModule : | for (auto gpuModule : | ||||
llvm::make_early_inc_range(getModule().getOps<gpu::GPUModuleOp>())) | llvm::make_early_inc_range(getOperation().getOps<gpu::GPUModuleOp>())) | ||||
gpuModule.erase(); | gpuModule.erase(); | ||||
for (auto spirvModule : | for (auto spirvModule : | ||||
llvm::make_early_inc_range(getModule().getOps<spirv::ModuleOp>())) | llvm::make_early_inc_range(getOperation().getOps<spirv::ModuleOp>())) | ||||
spirvModule.erase(); | spirvModule.erase(); | ||||
} | } | ||||
LogicalResult ConvertGpuLaunchFuncToVulkanLaunchFunc::declareVulkanLaunchFunc( | LogicalResult ConvertGpuLaunchFuncToVulkanLaunchFunc::declareVulkanLaunchFunc( | ||||
Location loc, gpu::LaunchFuncOp launchOp) { | Location loc, gpu::LaunchFuncOp launchOp) { | ||||
OpBuilder builder(getModule().getBody()->getTerminator()); | OpBuilder builder(getOperation().getBody()->getTerminator()); | ||||
// TODO: Workgroup size is written into the kernel. So to properly modelling | // TODO: Workgroup size is written into the kernel. So to properly modelling | ||||
// vulkan launch, we cannot have the local workgroup size configuration here. | // vulkan launch, we cannot have the local workgroup size configuration here. | ||||
SmallVector<Type, 8> vulkanLaunchTypes{launchOp.getOperandTypes()}; | SmallVector<Type, 8> vulkanLaunchTypes{launchOp.getOperandTypes()}; | ||||
// Check that all operands have supported types except those for the launch | // Check that all operands have supported types except those for the launch | ||||
// configuration. | // configuration. | ||||
for (auto type : | for (auto type : | ||||
llvm::drop_begin(vulkanLaunchTypes, gpu::LaunchOp::kNumConfigOperands)) { | llvm::drop_begin(vulkanLaunchTypes, gpu::LaunchOp::kNumConfigOperands)) { | ||||
Show All 25 Lines | LogicalResult ConvertGpuLaunchFuncToVulkanLaunchFunc::createBinaryShader( | ||||
binaryShader.resize(binary.size() * sizeof(uint32_t)); | binaryShader.resize(binary.size() * sizeof(uint32_t)); | ||||
std::memcpy(binaryShader.data(), reinterpret_cast<char *>(binary.data()), | std::memcpy(binaryShader.data(), reinterpret_cast<char *>(binary.data()), | ||||
binaryShader.size()); | binaryShader.size()); | ||||
return success(); | return success(); | ||||
} | } | ||||
void ConvertGpuLaunchFuncToVulkanLaunchFunc::convertGpuLaunchFunc( | void ConvertGpuLaunchFuncToVulkanLaunchFunc::convertGpuLaunchFunc( | ||||
gpu::LaunchFuncOp launchOp) { | gpu::LaunchFuncOp launchOp) { | ||||
ModuleOp module = getModule(); | ModuleOp module = getOperation(); | ||||
OpBuilder builder(launchOp); | OpBuilder builder(launchOp); | ||||
Location loc = launchOp.getLoc(); | Location loc = launchOp.getLoc(); | ||||
// Serialize `spirv::Module` into binary form. | // Serialize `spirv::Module` into binary form. | ||||
std::vector<char> binary; | std::vector<char> binary; | ||||
if (failed(createBinaryShader(module, binary))) | if (failed(createBinaryShader(module, binary))) | ||||
return signalPassFailure(); | return signalPassFailure(); | ||||
Show All 26 Lines |