Skip to content

Commit e6ac016

Browse files
authored
[Codegen][Tuner] verifier for the default tuning spec (#19525)
This PR adds the unit attribute` iree_codegen.tuning_spec_with_default_entrypoint` to indicate the default tuning spec (typically or user-provided tuning spec but can work in the same manner) must contain one named sequence operation marked with `__kernel_config`, also add the corresponding verification in `verifyOperationAttribute` function. This PR is relevant to task in #19214: add [a discardable attr verifier](https://mlir.llvm.org/docs/DefiningDialects/#discardable-attribute-verification) for entry points iree_codegen.tuning_spec_entrypoint Context: Jakub proposed two approaches for verifying the default tuning specification: 1. Implement a dedicated pass for verification. 2. Add a new attribute and update the verifyOperationAttribute function accordingly. After careful consideration, we agreed on the second approach to avoid introducing an additional pass, ensuring a simple implementation. --------- Signed-off-by: Bangtian Liu <[email protected]>
1 parent 26b24f2 commit e6ac016

File tree

9 files changed

+54
-6
lines changed

9 files changed

+54
-6
lines changed

compiler/plugins/target/ROCM/builtins/tuning/iree_default_tuning_spec_gfx942.mlir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// TODO(https://github.com/iree-org/iree/issues/19214): Add missing
66
// configurations to this spec.
77

8-
module @iree_default_tuning_spec_gfx942 attributes { transform.with_named_sequence } {
8+
module @iree_default_tuning_spec_gfx942 attributes { transform.with_named_sequence, iree_codegen.tuning_spec_with_default_entrypoint } {
99

1010
transform.named_sequence @apply_op_config(%op: !transform.any_op {transform.readonly},
1111
%config: !transform.any_param {transform.readonly}) {

compiler/plugins/target/ROCM/test/default_tuning_specs_amdgpu.mlir

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919

2020
// Check that the default tuning spec gets materialized without linking.
2121

22-
// DEFAULT-LABEL: module @iree_default_tuning_spec_gfx942 attributes {transform.with_named_sequence}
22+
// DEFAULT-LABEL: module @iree_default_tuning_spec_gfx942
23+
// DEFAULT-SAME: iree_codegen.tuning_spec_with_default_entrypoint
24+
// DEFAULT-SAME: transform.with_named_sequence
2325
// DEFAULT-LABEL: transform.named_sequence @__kernel_config
2426
// DEFAULT-SAME: attributes {iree_codegen.tuning_spec_entrypoint}
2527

@@ -33,7 +35,9 @@
3335
// Check that both the user tuning spec and the default spec get linked and
3436
// materialized. The user spec should have precedence over the default one.
3537

36-
// BOTH-LABEL: module @iree_linked_tuning_spec attributes {transform.with_named_sequence}
38+
// BOTH-LABEL: module @iree_linked_tuning_spec
39+
// BOTH-SAME: iree_codegen.tuning_spec_with_default_entrypoint
40+
// BOTH-SAME: transform.with_named_sequence
3741
// BOTH-LABEL: module @mmt_tile_and_fuse_spec_0 attributes {transform.with_named_sequence}
3842
// BOTH-LABEL: transform.named_sequence @main
3943
// BOTH-SAME: attributes {iree_codegen.tuning_spec_entrypoint}

compiler/src/iree/compiler/Codegen/Common/LinkTuningSpecsPass.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ emitLinkedTuningSpec(ModuleOp module, ArrayRef<NamedSequenceOp> specsToLink) {
7272
Type anyOpType = builder.getType<transform::AnyOpType>();
7373
FunctionType specType =
7474
builder.getFunctionType(TypeRange{anyOpType}, TypeRange{anyOpType});
75+
// This code creates a named sequence operation that conforms to the
76+
// requirements for tuning specifications with a default entry point.
7577
auto newSpec = builder.create<NamedSequenceOp>(
7678
loc, kKernelConfigSpecName, TypeAttr::get(specType),
7779
/*sym_visibility=*/StringAttr{},
@@ -81,6 +83,7 @@ emitLinkedTuningSpec(ModuleOp module, ArrayRef<NamedSequenceOp> specsToLink) {
8183
0, hasConsumedSequences ? kArgConsumedAttrName : kArgReadOnlyAttrName,
8284
builder.getUnitAttr());
8385
newSpec->setAttr(kTuningSpecEntrypointAttrName, builder.getUnitAttr());
86+
module->setAttr(kTuningSpecDefaultEntrypointAttrName, builder.getUnitAttr());
8487

8588
Region &region = newSpec.getRegion();
8689
Block *body = builder.createBlock(&region, region.begin(),

compiler/src/iree/compiler/Codegen/Common/MaterializeTuningSpecsPass.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ struct MaterializeTuningSpecsPass final
234234
UnitAttr::get(ctx));
235235
for (auto [idx, spec] : llvm::enumerate(allSpecs)) {
236236
ModuleOp clonedSpec = spec.clone();
237+
// Drop the module-level attribute due to renamed entrypoints during
238+
// linking.
239+
if (clonedSpec->hasAttr(kTuningSpecDefaultEntrypointAttrName)) {
240+
clonedSpec->removeAttr(kTuningSpecDefaultEntrypointAttrName);
241+
}
237242
// Make sure there are no symbol name collisions.
238243
clonedSpec.setSymName(
239244
llvm::formatv("{}_{}", clonedSpec.getSymName().value(), idx).str());

compiler/src/iree/compiler/Codegen/Common/test/materialize_tuning_specs.mlir

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55

66
// Check that the final tuning spec is as expected when the user tuning spec is provided.
77

8-
// CHECK-LABEL: module @iree_linked_tuning_spec attributes {transform.with_named_sequence}
8+
// CHECK-LABEL: module @iree_linked_tuning_spec
9+
// CHECK-SAME: iree_codegen.tuning_spec_with_default_entrypoint
10+
// CHECK-SAME: transform.with_named_sequence
911
// CHECK-LABEL: module @user_spec_0 attributes {transform.with_named_sequence}
1012
// CHECK-LABEL: transform.named_sequence @hello
1113
// CHECK-SAME: attributes {iree_codegen.tuning_spec_entrypoint}

compiler/src/iree/compiler/Codegen/Common/test/verify_tuning_specs.mlir

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,18 @@ module @foo_module attributes { transform.with_named_sequence } {
5151
transform.named_sequence @foo(%arg0: !transform.any_op {transform.readonly})
5252
attributes { iree_codegen.tuning_spec_entrypoint } {}
5353
}
54+
55+
// -----
56+
57+
// expected-error @+1{{The tuning specification must include a named sequence with the symbol name '__kernel_config'}}
58+
module @iree_default_tuning_spec attributes { iree_codegen.tuning_spec_with_default_entrypoint } {
59+
}
60+
61+
// -----
62+
63+
// expected-error @+1{{The tuning specification must include a named sequence with the symbol name '__kernel_config'}}
64+
module @iree_default_tuning_spec attributes { iree_codegen.tuning_spec_with_default_entrypoint } {
65+
func.func @__kernel_config(%arg0: i32) -> () {
66+
return
67+
}
68+
}

compiler/src/iree/compiler/Codegen/Dialect/Codegen/IR/IREECodegenAttrs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ namespace mlir::iree_compiler {
4545
// Constant names.
4646
//===----------------------------------------------------------------------===//
4747
constexpr StringLiteral kConfigAttrName = "lowering_config";
48+
constexpr StringLiteral kTuningSpecDefaultEntrypointAttrName =
49+
"iree_codegen.tuning_spec_with_default_entrypoint";
4850
constexpr StringLiteral kTuningSpecEntrypointAttrName =
4951
"iree_codegen.tuning_spec_entrypoint";
5052
constexpr StringLiteral kSerializedTuningSpecAttrName =

compiler/src/iree/compiler/Codegen/Dialect/Codegen/IR/IREECodegenDialect.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ IREECodegenDialect::verifyOperationAttribute(Operation *op,
5151
NamedAttribute attribute) {
5252
StringRef symbol = attribute.getName().strref();
5353
Attribute attr = attribute.getValue();
54-
5554
// This function verifies the validity of a specific operation attribute.
55+
// - If the attribute's name matches `kTuningDefaultSpecAttrName`, make
56+
// sure it contains a single named sequence op with name `__kernel_config`.
5657
// - If the attribute's name matches `kTuningSpecEntrypointAttrName`
5758
// ("iree_codegen.tuning_spec_entrypoint"):
5859
// 1. The attribute value must be a UnitAttr.
@@ -63,6 +64,20 @@ IREECodegenDialect::verifyOperationAttribute(Operation *op,
6364
// b. It must have exactly one argument type, and the argument must be
6465
// of type `transform::AnyOpType`.
6566

67+
if (symbol == kTuningSpecDefaultEntrypointAttrName) {
68+
if (auto moduleOp = dyn_cast<ModuleOp>(op)) {
69+
if (!llvm::any_of(moduleOp.getOps<transform::NamedSequenceOp>(),
70+
[](transform::NamedSequenceOp op) {
71+
return op.getName() == kKernelConfigSpecName;
72+
})) {
73+
return moduleOp.emitError()
74+
<< "The tuning specification must include a named "
75+
"sequence with the symbol name '"
76+
<< kKernelConfigSpecName << "'.";
77+
}
78+
}
79+
}
80+
6681
if (symbol != kTuningSpecEntrypointAttrName)
6782
return success();
6883

docs/website/docs/reference/tuning.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ attempting the default one.
5050
### Example
5151

5252
```mlir
53-
module @my_spec attributes { transform.with_named_sequence } {
53+
module @my_spec attributes { transform.with_named_sequence, iree_codegen.tuning_spec_with_default_entrypoint } {
5454
transform.named_sequence @apply_op_config(%op: !transform.any_op {transform.readonly},
5555
%config: !transform.any_param {transform.readonly}) {
5656
transform.annotate %op "compilation_info" = %config : !transform.any_op, !transform.any_param
@@ -123,6 +123,8 @@ that conform to the following format:
123123
`!transform.any_op`.
124124
* All entry points in the final tuning specs must either read
125125
(`transform.readonly`) or consume (`transform.consumed`) the argument.
126+
* The `iree_codegen.tuning_spec_with_default_entrypoint` attribute ensures that
127+
the tuning spec includes a named sequence op with name `__kernel_config`.
126128

127129
The tuning spec above attempts to match `linalg.generic` ops that correspond to the
128130
matmul operation with the RHS operand transposed (a.k.a. mmt) of shape

0 commit comments

Comments
 (0)