Skip to content

Commit 61004b7

Browse files
authored
[MLIR][GPU] Add xevm-attach-target transform pass. (#147372)
Add xevm-attach-target transform pass and unit-tests. Co-authored-by: by Sang Ik Lee sang.ik.lee@intel.com. Co-authored-by: Artem Kroviakov artem.kroviakov@intel.com
1 parent 0c0aa56 commit 61004b7

File tree

5 files changed

+142
-4
lines changed

5 files changed

+142
-4
lines changed

mlir/include/mlir/Dialect/GPU/Transforms/Passes.td

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,4 +258,38 @@ def GpuSPIRVAttachTarget: Pass<"spirv-attach-target", ""> {
258258
];
259259
}
260260

261+
def GpuXeVMAttachTarget : Pass<"xevm-attach-target", ""> {
262+
let summary = "Attaches a XeVM target attribute to a GPU Module.";
263+
let description = [{
264+
This pass searches for all GPU Modules in the immediate regions and attaches
265+
a XeVM target if the module matches the name specified by the `module` argument.
266+
267+
Example:
268+
```
269+
// File: in.mlir:
270+
gpu.module @nvvm_module_1 {...}
271+
gpu.module @rocdl_module_2 {...}
272+
gpu.module @xevm_module_3 {...}
273+
// mlir-opt --xevm-attach-target="module=xevm.* chip=pvc" in.mlir
274+
gpu.module @nvvm_module_1 {...}
275+
gpu.module @rocdl_module_2 {...}
276+
gpu.module @xevm_module_3 [#xevm.target<chip = "pvc">] {...}
277+
```
278+
}];
279+
let options =
280+
[Option<"moduleMatcher", "module", "std::string",
281+
/*default=*/[{""}],
282+
"Regex used to identify the modules to attach the target to.">,
283+
Option<"triple", "triple", "std::string",
284+
/*default=*/"\"spirv64-unknown-unknown\"", "Target triple.">,
285+
Option<"chip", "chip", "std::string",
286+
/*default=*/"\"bmg\"", "Target chip.">,
287+
Option<"optLevel", "O", "unsigned",
288+
/*default=*/"2", "Optimization level.">,
289+
ListOption<"linkLibs", "l", "std::string",
290+
"Extra bitcode libraries paths to link to.">,
291+
Option<"cmdOptions", "cmd-options", "std::string",
292+
/*default=*/[{""}],
293+
"Command line options passed to downstream compiler">];
294+
}
261295
#endif // MLIR_DIALECT_GPU_PASSES

mlir/lib/Dialect/GPU/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ add_mlir_dialect_library(MLIRGPUTransforms
4444
Transforms/ShuffleRewriter.cpp
4545
Transforms/SubgroupIdRewriter.cpp
4646
Transforms/SubgroupReduceLowering.cpp
47+
Transforms/XeVMAttachTarget.cpp
4748

4849
OBJECT
4950

@@ -78,6 +79,7 @@ add_mlir_dialect_library(MLIRGPUTransforms
7879
MLIRSupport
7980
MLIRTransformUtils
8081
MLIRVectorDialect
82+
MLIRXeVMDialect
8183
)
8284

8385
add_subdirectory(TransformOps)
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
//===-- XeVMAttachTarget.cpp - Attach an XeVM target ----------------------===//
2+
//
3+
// This file is licensed 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+
// This file implements the `GpuXeVMAttachTarget` pass, attaching `#xevm.target`
10+
// attributes to GPU modules.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "mlir/Dialect/GPU/Transforms/Passes.h"
15+
16+
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
17+
#include "mlir/Dialect/LLVMIR/XeVMDialect.h"
18+
#include "mlir/IR/Builders.h"
19+
#include "mlir/Pass/Pass.h"
20+
#include "llvm/Support/Regex.h"
21+
22+
namespace mlir {
23+
#define GEN_PASS_DEF_GPUXEVMATTACHTARGET
24+
#include "mlir/Dialect/GPU/Transforms/Passes.h.inc"
25+
} // namespace mlir
26+
27+
using namespace mlir;
28+
using namespace mlir::xevm;
29+
30+
namespace {
31+
struct XeVMAttachTarget
32+
: public mlir::impl::GpuXeVMAttachTargetBase<XeVMAttachTarget> {
33+
using Base::Base;
34+
35+
DictionaryAttr getFlags(OpBuilder &builder) const;
36+
37+
void runOnOperation() override;
38+
39+
void getDependentDialects(DialectRegistry &registry) const override {
40+
registry.insert<xevm::XeVMDialect>();
41+
}
42+
};
43+
} // namespace
44+
45+
DictionaryAttr XeVMAttachTarget::getFlags(OpBuilder &builder) const {
46+
SmallVector<NamedAttribute, 3> flags;
47+
// Tokenize and set the optional command line options.
48+
if (!cmdOptions.empty()) {
49+
std::pair<llvm::BumpPtrAllocator, SmallVector<const char *>> options =
50+
gpu::TargetOptions::tokenizeCmdOptions(cmdOptions);
51+
if (!options.second.empty()) {
52+
llvm::SmallVector<mlir::Attribute> xevmOptionAttrs;
53+
for (const char *opt : options.second) {
54+
xevmOptionAttrs.emplace_back(
55+
mlir::StringAttr::get(builder.getContext(), StringRef(opt)));
56+
}
57+
flags.push_back(builder.getNamedAttr(
58+
"cmd-options",
59+
mlir::ArrayAttr::get(builder.getContext(), xevmOptionAttrs)));
60+
}
61+
}
62+
63+
if (!flags.empty())
64+
return builder.getDictionaryAttr(flags);
65+
return nullptr;
66+
}
67+
68+
void XeVMAttachTarget::runOnOperation() {
69+
OpBuilder builder(&getContext());
70+
ArrayRef<std::string> libs(linkLibs);
71+
SmallVector<StringRef> filesToLink(libs);
72+
auto target = builder.getAttr<xevm::XeVMTargetAttr>(
73+
optLevel, triple, chip, getFlags(builder),
74+
filesToLink.empty() ? nullptr : builder.getStrArrayAttr(filesToLink));
75+
llvm::Regex matcher(moduleMatcher);
76+
for (Region &region : getOperation()->getRegions())
77+
for (Block &block : region.getBlocks())
78+
for (auto module : block.getOps<gpu::GPUModuleOp>()) {
79+
// Check if the name of the module matches.
80+
if (!moduleMatcher.empty() && !matcher.match(module.getName()))
81+
continue;
82+
// Create the target array.
83+
SmallVector<Attribute> targets;
84+
if (std::optional<ArrayAttr> attrs = module.getTargets())
85+
targets.append(attrs->getValue().begin(), attrs->getValue().end());
86+
targets.push_back(target);
87+
// Remove any duplicate targets.
88+
targets.erase(llvm::unique(targets), targets.end());
89+
// Update the target attribute array.
90+
module.setTargetsAttr(builder.getArrayAttr(targets));
91+
}
92+
}

mlir/test/Dialect/LLVMIR/attach-targets.mlir

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: mlir-opt %s --nvvm-attach-target='module=nvvm.* O=3 chip=sm_90' --rocdl-attach-target='module=rocdl.* O=3 chip=gfx90a' | FileCheck %s
2-
// RUN: mlir-opt %s --nvvm-attach-target='module=options.* O=1 chip=sm_70 fast=true ftz=true' --rocdl-attach-target='module=options.* l=file1.bc,file2.bc wave64=false finite-only=true' | FileCheck %s --check-prefix=CHECK_OPTS
1+
// RUN: mlir-opt %s --nvvm-attach-target='module=nvvm.* O=3 chip=sm_90' --rocdl-attach-target='module=rocdl.* O=3 chip=gfx90a' --xevm-attach-target='module=xevm.* O=3 chip=pvc' | FileCheck %s
2+
// RUN: mlir-opt %s --nvvm-attach-target='module=options.* O=1 chip=sm_70 fast=true ftz=true' --rocdl-attach-target='module=options.* l=file1.bc,file2.bc wave64=false finite-only=true' --xevm-attach-target='module=options.* O=1 chip=pvc' | FileCheck %s --check-prefix=CHECK_OPTS
33

44
module attributes {gpu.container_module} {
55
// Verify the target is appended.
@@ -18,12 +18,21 @@ gpu.module @nvvm_module_3 [#nvvm.target<O = 3, chip = "sm_90">] {
1818
// CHECK: @rocdl_module [#rocdl.target<O = 3, chip = "gfx90a">] {
1919
gpu.module @rocdl_module {
2020
}
21+
// Verify that other targets are not added as they fail to match the regex, but XeVM does get appended.
22+
// CHECK: @xevm_module [#xevm.target<O = 3, chip = "pvc">] {
23+
gpu.module @xevm_module {
24+
}
2125
// Check the options were added.
22-
// CHECK_OPTS: @options_module_1 [#nvvm.target<O = 1, chip = "sm_70", flags = {fast, ftz}>, #rocdl.target<flags = {finite_only, no_wave64}, link = ["file1.bc", "file2.bc"]>] {
26+
// CHECK_OPTS: @options_module_1 [#nvvm.target<O = 1, chip = "sm_70", flags = {fast, ftz}>,
27+
// CHECK_OPTS-SAME: #rocdl.target<flags = {finite_only, no_wave64}, link = ["file1.bc", "file2.bc"]>,
28+
// CHECK_OPTS-SAME: #xevm.target<O = 1, chip = "pvc">] {
2329
gpu.module @options_module_1 {
2430
}
2531
// Check the options were added and that the first target was preserved.
26-
// CHECK_OPTS: @options_module_2 [#nvvm.target<O = 3, chip = "sm_90">, #nvvm.target<O = 1, chip = "sm_70", flags = {fast, ftz}>, #rocdl.target<flags = {finite_only, no_wave64}, link = ["file1.bc", "file2.bc"]>] {
32+
// CHECK_OPTS: @options_module_2 [#nvvm.target<O = 3, chip = "sm_90">,
33+
// CHECK_OPTS-SAME: #nvvm.target<O = 1, chip = "sm_70", flags = {fast, ftz}>,
34+
// CHECK_OPTS-SAME: #rocdl.target<flags = {finite_only, no_wave64}, link = ["file1.bc", "file2.bc"]>,
35+
// CHECK_OPTS-SAME: #xevm.target<O = 1, chip = "pvc">] {
2736
gpu.module @options_module_2 [#nvvm.target<O = 3, chip = "sm_90">] {
2837
}
2938
}

mlir/test/lib/Dialect/GPU/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ set(LIBS
2929
MLIRTranslateLib
3030
MLIRVectorDialect
3131
MLIRVectorToLLVMPass
32+
MLIRXeVMDialect
3233
)
3334

3435
add_mlir_library(MLIRGPUTestPasses

0 commit comments

Comments
 (0)