CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
191 lines
8.6 KiB
C++
191 lines
8.6 KiB
C++
//===- GPUToXeVMPipeline.cpp - Lowering pipeline to XeVM/LLVM -------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements a pass for testing the lowering to XeVM as a generally
|
|
// usable sink pass. If XeGPU ops are used, it expects the MLIR code to have
|
|
// XeGPU ops already embedded in gpu code.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Conversion/AffineToStandard/AffineToStandard.h"
|
|
#include "mlir/Conversion/GPUCommon/GPUCommonPass.h"
|
|
#include "mlir/Conversion/MathToXeVM/MathToXeVM.h"
|
|
#include "mlir/Conversion/Passes.h"
|
|
#include "mlir/Conversion/SCFToControlFlow/SCFToControlFlow.h"
|
|
#include "mlir/Conversion/VectorToSCF/VectorToSCF.h"
|
|
#include "mlir/Conversion/XeGPUToXeVM/XeGPUToXeVM.h"
|
|
#include "mlir/Conversion/XeVMToLLVM/XeVMToLLVM.h"
|
|
#include "mlir/Dialect/Arith/Transforms/Passes.h"
|
|
#include "mlir/Dialect/Func/IR/FuncOps.h"
|
|
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
|
|
#include "mlir/Dialect/GPU/Pipelines/Passes.h"
|
|
#include "mlir/Dialect/GPU/Transforms/Passes.h"
|
|
#include "mlir/Dialect/LLVMIR/Transforms/RequestCWrappers.h"
|
|
#include "mlir/Dialect/Math/Transforms/Passes.h"
|
|
#include "mlir/Dialect/MemRef/Transforms/Passes.h"
|
|
#include "mlir/Dialect/XeGPU/Transforms/Passes.h"
|
|
#include "mlir/Pass/PassManager.h"
|
|
#include "mlir/Pass/PassOptions.h"
|
|
#include "mlir/Target/LLVM/XeVM/Target.h"
|
|
#include "mlir/Transforms/Passes.h"
|
|
|
|
using namespace mlir;
|
|
|
|
namespace {
|
|
//===----------------------------------------------------------------------===//
|
|
// Pre-GPU common pipeline for both Host and GPU.
|
|
//===----------------------------------------------------------------------===//
|
|
void buildPreGPUCommonPassPipeline(
|
|
OpPassManager &pm, const mlir::gpu::GPUToXeVMPipelineOptions &options) {
|
|
// builtin.module scope passes.
|
|
pm.addPass(createCSEPass());
|
|
pm.addPass(createConvertVectorToSCFPass());
|
|
{
|
|
GpuXeVMAttachTargetOptions xevmTargetOptions;
|
|
xevmTargetOptions.moduleMatcher = options.xevmModuleMatcher;
|
|
xevmTargetOptions.triple = options.zebinTriple;
|
|
xevmTargetOptions.chip = options.zebinChip;
|
|
xevmTargetOptions.optLevel = options.optLevel;
|
|
xevmTargetOptions.cmdOptions = options.cmdOptions;
|
|
pm.addPass(createGpuXeVMAttachTarget(xevmTargetOptions));
|
|
}
|
|
pm.addPass(createLowerAffinePass());
|
|
pm.addNestedPass<func::FuncOp>(createGpuAsyncRegionPass());
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// GPUModule-specific stuff.
|
|
//===----------------------------------------------------------------------===//
|
|
void buildGPUPassPipeline(OpPassManager &pm,
|
|
const mlir::gpu::GPUToXeVMPipelineOptions &options) {
|
|
xegpu::XeGPUPropagateLayoutOptions laneLayoutOptions;
|
|
laneLayoutOptions.indexBitWidth = options.use64bitIndex ? 64 : 32;
|
|
laneLayoutOptions.layoutKind = "lane";
|
|
pm.addNestedPass<ModuleOp>(createCSEPass());
|
|
if (options.xegpuOpLevel == "workgroup") {
|
|
xegpu::XeGPUPropagateLayoutOptions sgLayoutOptions;
|
|
sgLayoutOptions.layoutKind = "subgroup";
|
|
pm.addNestedPass<gpu::GPUModuleOp>(
|
|
xegpu::createXeGPUPropagateLayout(sgLayoutOptions));
|
|
pm.addNestedPass<gpu::GPUModuleOp>(xegpu::createXeGPUWgToSgDistribute());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createLowerAffinePass());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
|
|
xegpu::XeGPUPropagateLayoutOptions instDataOptions;
|
|
instDataOptions.layoutKind = "inst";
|
|
pm.addNestedPass<gpu::GPUModuleOp>(
|
|
xegpu::createXeGPUPropagateLayout(instDataOptions));
|
|
pm.addNestedPass<gpu::GPUModuleOp>(xegpu::createXeGPUBlocking());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
|
|
}
|
|
if (options.xegpuOpLevel == "subgroup" ||
|
|
options.xegpuOpLevel == "workgroup") {
|
|
pm.addNestedPass<gpu::GPUModuleOp>(
|
|
xegpu::createXeGPUPropagateLayout(laneLayoutOptions));
|
|
pm.addNestedPass<gpu::GPUModuleOp>(xegpu::createXeGPUPeepHoleOptimizer());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(
|
|
xegpu::createXeGPUPropagateLayout(laneLayoutOptions));
|
|
pm.addNestedPass<gpu::GPUModuleOp>(xegpu::createXeGPUSgToLaneDistribute());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createCanonicalizerPass());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createLoopInvariantCodeMotionPass());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(xegpu::createXeGPUVectorLinearize());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createCanonicalizerPass());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
|
|
}
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createConvertMathToXeVM());
|
|
ConvertXeGPUToXeVMPassOptions xegpuToXeVMOptions;
|
|
xegpuToXeVMOptions.use64bitIndex = options.use64bitIndex;
|
|
pm.addNestedPass<gpu::GPUModuleOp>(
|
|
createConvertXeGPUToXeVMPass(xegpuToXeVMOptions));
|
|
{
|
|
ConvertGpuOpsToLLVMSPVOpsOptions gpuToLLVMSPVOptions;
|
|
gpuToLLVMSPVOptions.use64bitIndex = options.use64bitIndex;
|
|
pm.addNestedPass<gpu::GPUModuleOp>(
|
|
createConvertGpuOpsToLLVMSPVOps(gpuToLLVMSPVOptions));
|
|
}
|
|
// Legalize math/arith ops on floating-point types that the XeVM target
|
|
// cannot handle natively (e.g. bf16) by wrapping them with extf/truncf
|
|
// around a supported type (defaulting to f32).
|
|
{
|
|
math::MathExtendToSupportedTypesOptions mathExtendOptions;
|
|
mathExtendOptions.extraTypeStrs.assign(options.mathExtendExtraTypes.begin(),
|
|
options.mathExtendExtraTypes.end());
|
|
mathExtendOptions.targetTypeStr = options.supportedTargetTypes;
|
|
pm.addNestedPass<gpu::GPUModuleOp>(
|
|
math::createMathExtendToSupportedTypes(mathExtendOptions));
|
|
}
|
|
{
|
|
arith::ArithEmulateUnsupportedFloatsOptions arithEmulateOptions;
|
|
arithEmulateOptions.sourceTypeStrs.assign(
|
|
options.unsupportedSourceTypes.begin(),
|
|
options.unsupportedSourceTypes.end());
|
|
arithEmulateOptions.targetTypeStr = options.supportedTargetTypes;
|
|
pm.addNestedPass<gpu::GPUModuleOp>(
|
|
arith::createArithEmulateUnsupportedFloats(arithEmulateOptions));
|
|
}
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createReconcileUnrealizedCastsPass());
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Post-GPU pipeline for both Host and GPU.
|
|
//===----------------------------------------------------------------------===//
|
|
void buildPostGPUCommonPassPipeline(
|
|
OpPassManager &pm, const mlir::gpu::GPUToXeVMPipelineOptions &options) {
|
|
// builtin.module scope passes.
|
|
pm.addPass(createSCFToControlFlowPass());
|
|
pm.addPass(memref::createExpandStridedMetadataPass());
|
|
{
|
|
GpuToLLVMConversionPassOptions gpuToLLVMOptions;
|
|
gpuToLLVMOptions.hostBarePtrCallConv = options.hostBarePtrCallConv;
|
|
gpuToLLVMOptions.kernelBarePtrCallConv = options.kernelBarePtrCallConv;
|
|
pm.addPass(createGpuToLLVMConversionPass(gpuToLLVMOptions));
|
|
}
|
|
pm.addPass(createLowerAffinePass());
|
|
pm.addPass(createConvertVectorToLLVMPass());
|
|
pm.addPass(createConvertToLLVMPass());
|
|
pm.addPass(createReconcileUnrealizedCastsPass());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createCanonicalizerPass());
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createCSEPass());
|
|
// XeVM-to-LLVM must be the last pass before gpu-module-to-binary.
|
|
pm.addNestedPass<gpu::GPUModuleOp>(createConvertXeVMToLLVMPass());
|
|
// gpu-module-to-binary
|
|
{
|
|
GpuModuleToBinaryPassOptions gpuToModuleBinOptions;
|
|
gpuToModuleBinOptions.compilationTarget = options.binaryFormat;
|
|
gpuToModuleBinOptions.cmdOptions = options.cmdOptions;
|
|
pm.addPass(createGpuModuleToBinaryPass(gpuToModuleBinOptions));
|
|
}
|
|
}
|
|
} // namespace
|
|
|
|
void mlir::gpu::buildLowerToXeVMPassPipeline(
|
|
OpPassManager &pm, const GPUToXeVMPipelineOptions &options) {
|
|
// Pre-GPU common pipelines.
|
|
buildPreGPUCommonPassPipeline(pm, options);
|
|
|
|
// GPUModule-specific stuff.
|
|
buildGPUPassPipeline(pm, options);
|
|
|
|
// Post-GPU pipeline for both Host and GPU.
|
|
buildPostGPUCommonPassPipeline(pm, options);
|
|
}
|
|
|
|
void mlir::gpu::registerGPUToXeVMPipeline() {
|
|
PassPipelineRegistration<GPUToXeVMPipelineOptions>(
|
|
"gpu-lower-to-xevm-pipeline",
|
|
"The default GPU to XeVM lowering pipeline. It starts by lowering GPU "
|
|
"code to the "
|
|
"specified compilation target (default is fatbin) then lowers the host "
|
|
"code.",
|
|
buildLowerToXeVMPassPipeline);
|
|
}
|