Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions mlir/lib/Dialect/Transform/IR/TransformOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2571,6 +2571,11 @@ void transform::NamedSequenceOp::build(OpBuilder &builder,
TypeAttr::get(FunctionType::get(builder.getContext(),
rootType, resultTypes)));
state.attributes.append(attrs.begin(), attrs.end());
if (!argAttrs.empty()) {
SmallVector<Attribute> argAttrsVec(argAttrs.begin(), argAttrs.end());
state.getOrAddProperties<Properties>().arg_attrs =
ArrayAttr::get(builder.getContext(), argAttrsVec);
}
state.addRegion();

buildSequenceBody(builder, state, rootType,
Expand Down
1 change: 1 addition & 0 deletions mlir/unittests/Dialect/Transform/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_mlir_unittest(MLIRTransformDialectTests
TransformNamedSequenceCreate.cpp
BuildOnlyExtensionTest.cpp
Preload.cpp
)
Expand Down
45 changes: 45 additions & 0 deletions mlir/unittests/Dialect/Transform/TransformNamedSequenceCreate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "mlir/Dialect/Transform/IR/TransformDialect.h"
#include "mlir/Dialect/Transform/IR/TransformOps.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/MLIRContext.h"
#include "gtest/gtest.h"

using namespace mlir;
using namespace mlir::transform;

TEST(NamedSequenceOpTest, ArgAttrsAreHonoredByBuilder) {
MLIRContext ctx;
ctx.loadDialect<TransformDialect>();

OpBuilder builder(&ctx);
auto module = ModuleOp::create(UnknownLoc::get(&ctx));
builder.setInsertionPointToEnd(module.getBody());

Location loc = UnknownLoc::get(&ctx);

static constexpr StringLiteral kMainSequenceName = "__transform_main";

NamedSequenceOp seqOp = builder.create<NamedSequenceOp>(
loc,
/*sym_name=*/kMainSequenceName,
/*rootType=*/builder.getType<AnyOpType>(),
/*resultType=*/TypeRange{},
[](OpBuilder &b, Location nested, Value rootH) {
b.create<YieldOp>(nested, ValueRange());
},
/*args=*/ArrayRef<NamedAttribute>{},
/*attrArgs=*/
ArrayRef<DictionaryAttr>{
builder.getDictionaryAttr(ArrayRef<NamedAttribute>{
builder.getNamedAttr(TransformDialect::kArgConsumedAttrName,
builder.getUnitAttr())})});

// 检查 body argument 上有没有 transform.consumed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use English in comments.

Block &body = seqOp.getBody().front();
ASSERT_EQ(body.getNumArguments(), 1u);

StringAttr arg0Name = seqOp.getArgAttrsAttrName();
EXPECT_TRUE(arg0Name);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would hope we don't need a c++ unit-test here, can this move to an IR test?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this bug doesn't affect IR, because when parsing IR, this function NamedSequence::build does not invoked. It invokes versions that auto generated by TableGen.

However, for those user that writing an scheduler, they need to create an transform.named_sequence with C++

this build function addtion to versions auto genrated is to make this progress convinient.

So i am afraid to say sorry, I could not write an IR test for this case, because its only for c++

thanks for your attention.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you saying that outside of this unit-test, this method is dead code in the codebase?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked: this is dead-code...

I still don't think we're usually adding C++ unit-tests for covering every builders.
But also, builders are added when needed, I guess someone had a need downstream when they added this builder?

Copy link
Author

@colawithsauce colawithsauce Nov 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so. This builder have no usage out of this unittest. In my AI compiler project I use it to build my own schedule sequence. But it failed to work. And then with hours of struggling I find this bug and fix it at my downstream.

Since it is dead code, I have no idea this should be fix or removed instead?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't have an established pattern for testing this kind of code, I wonder if we should have a single file per dialect, maybe: TransformDialectODSHelperTests.cpp or something like that?

@jpienaar maybe?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think any of the builders are tested directly. We could test them by, e.g., having a test pass (per dialect) that simply calls the builders and FileCheck the IR generated by the pass.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I was thinking something similar to Mehdi here. Well in order

  1. Ideally builders (not automatically generated) are tested via existing passes upstream and there is use of them. No additional worked needed and builder obviously useful.
  2. Builder file say per dialect.

The pros and cons of builder unit test vs pass for me is, that unit test becomes its own binary (so extra linkage cost) but it doesn't bloat mlir-opt. Now, one could argue that mlir-opt is already a testing tool and so that doesn't actually matter. In which case Alex's suggestion is better.

I could see us doing a C++ unit test that looks like the Python lit tests (compile, run and check with lit). I am spoilt as I have a parallel build, but if we restrict it per dialect and only for those not covered in another way already, it's probably small set and not high cost while being very directed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add the trailing new line (and configure your code editor not to remove it).