30 #define GEN_PASS_DEF_CONVERTGPULAUNCHFUNCTOVULKANLAUNCHFUNC
31 #include "mlir/Conversion/Passes.h.inc"
47 class ConvertGpuLaunchFuncToVulkanLaunchFunc
48 :
public impl::ConvertGpuLaunchFuncToVulkanLaunchFuncBase<
49 ConvertGpuLaunchFuncToVulkanLaunchFunc> {
51 void runOnOperation()
override;
56 LogicalResult createBinaryShader(ModuleOp module,
57 std::vector<char> &binaryShader);
60 void convertGpuLaunchFunc(gpu::LaunchFuncOp launchOp);
63 bool isSupportedType(
Type type) {
64 if (
auto memRefType = dyn_cast_or_null<MemRefType>(type)) {
65 auto elementType = memRefType.getElementType();
66 return memRefType.hasRank() &&
67 (memRefType.getRank() >= 1 && memRefType.getRank() <= 3) &&
68 (elementType.isIntOrFloat());
75 LogicalResult declareVulkanLaunchFunc(
Location loc,
76 gpu::LaunchFuncOp launchOp);
81 static constexpr
unsigned kVulkanLaunchNumConfigOperands = 3;
86 void ConvertGpuLaunchFuncToVulkanLaunchFunc::runOnOperation() {
88 getOperation().walk([
this, &done](gpu::LaunchFuncOp op) {
90 op.emitError(
"should only contain one 'gpu::LaunchFuncOp' op");
91 return signalPassFailure();
94 convertGpuLaunchFunc(op);
99 llvm::make_early_inc_range(getOperation().getOps<gpu::GPUModuleOp>()))
102 for (
auto spirvModule :
103 llvm::make_early_inc_range(getOperation().getOps<spirv::ModuleOp>()))
107 LogicalResult ConvertGpuLaunchFuncToVulkanLaunchFunc::declareVulkanLaunchFunc(
108 Location loc, gpu::LaunchFuncOp launchOp) {
117 gpuLaunchTypes.begin() +
118 kVulkanLaunchNumConfigOperands);
119 vulkanLaunchTypes.append(gpuLaunchTypes.begin() +
120 gpu::LaunchOp::kNumConfigOperands,
121 gpuLaunchTypes.end());
126 llvm::drop_begin(vulkanLaunchTypes, kVulkanLaunchNumConfigOperands)) {
127 if (!isSupportedType(type))
128 return launchOp.emitError() << type <<
" is unsupported to run on Vulkan";
132 auto funcType = builder.getFunctionType(vulkanLaunchTypes, {});
133 builder.create<func::FuncOp>(loc,
kVulkanLaunch, funcType).setPrivate();
138 LogicalResult ConvertGpuLaunchFuncToVulkanLaunchFunc::createBinaryShader(
139 ModuleOp module, std::vector<char> &binaryShader) {
142 for (
auto spirvModule : module.getOps<spirv::ModuleOp>()) {
144 return spirvModule.emitError(
"should only contain one 'spirv.module' op");
150 binaryShader.resize(binary.size() *
sizeof(uint32_t));
151 std::memcpy(binaryShader.data(),
reinterpret_cast<char *
>(binary.data()),
152 binaryShader.size());
156 void ConvertGpuLaunchFuncToVulkanLaunchFunc::convertGpuLaunchFunc(
157 gpu::LaunchFuncOp launchOp) {
158 ModuleOp module = getOperation();
163 std::vector<char> binary;
164 if (failed(createBinaryShader(module, binary)))
165 return signalPassFailure();
168 if (failed(declareVulkanLaunchFunc(loc, launchOp)))
169 return signalPassFailure();
173 gpuLaunchOperands.begin(),
174 gpuLaunchOperands.begin() + kVulkanLaunchNumConfigOperands);
175 vulkanLaunchOperands.append(gpuLaunchOperands.begin() +
176 gpu::LaunchOp::kNumConfigOperands,
177 gpuLaunchOperands.end());
180 auto vulkanLaunchCallOp = builder.create<func::CallOp>(
182 vulkanLaunchOperands);
185 vulkanLaunchCallOp->setAttr(
187 builder.getStringAttr(StringRef(binary.data(), binary.size())));
191 launchOp.getKernelName());
195 for (
Type type : llvm::drop_begin(launchOp.getOperandTypes(),
196 gpu::LaunchOp::kNumConfigOperands)) {
200 elementTypes.push_back(cast<MemRefType>(type).getElementType());
203 builder.getTypeArrayAttr(elementTypes));
208 std::unique_ptr<mlir::OperationPass<mlir::ModuleOp>>
210 return std::make_unique<ConvertGpuLaunchFuncToVulkanLaunchFunc>();
static constexpr const char * kVulkanLaunch
static constexpr const char * kSPIRVElementTypesAttrName
static constexpr const char * kSPIRVEntryPointAttrName
static constexpr const char * kSPIRVBlobAttrName
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
This class helps build Operations.
static OpBuilder atBlockEnd(Block *block, Listener *listener=nullptr)
Create a builder and set the insertion point to after the last operation in the block but still insid...
This class provides an abstraction over the various different ranges of value types.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
LogicalResult serialize(ModuleOp module, SmallVectorImpl< uint32_t > &binary, const SerializationOptions &options={})
Serializes the given SPIR-V module and writes to binary.
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
std::unique_ptr< OperationPass< mlir::ModuleOp > > createConvertGpuLaunchFuncToVulkanLaunchFuncPass()