-
Notifications
You must be signed in to change notification settings - Fork 53
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ASM: suggest OpResult name for BGV/CKKS/Openfhe #1219
base: main
Are you sure you want to change the base?
Conversation
Unfortunately, I was not able to alter the function argument name, as I tried the following hack struct FuncOpHeirInterface
: public ::mlir::OpAsmOpInterface::ExternalModel<FuncOpHeirInterface,
func::FuncOp> {
void getAsmBlockArgumentNames(Operation *op, Region ®ion,
::mlir::OpAsmSetValueNameFn setNameFn) const {
for (auto &block : region) {
for (auto arg : block.getArguments()) {
setNameFn(arg, "test");
}
}
}
};
registry.addExtension(+[](MLIRContext *ctx, func::FuncDialect *dialect) {
func::FuncOp::attachInterface<FuncOpHeirInterface>(*ctx);
}); But it did not work as we will get Ignoring repeated interface registration, because func::FuncOp already registered the interface and the This is intended behavior, as https://mlir.llvm.org/docs/Interfaces/ has suggested
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks super nice!
Unfortunately, I was not able to alter the function argument name, as func::FuncOp is not in our control so its interface implementation is fixed.
I wonder if there's appetite upstream for changingfunc.func
's printer so that it respects some (new? existing?) name-defining interface on Types (if present for a given type) and uses that, rather than arg
? However, I could forsee this breaking a lot of tests, both upstream and in various downstream projects, since lots of them hardcoded %argN
names in.
12fc1a7
to
834e3d1
Compare
I get a hack for it. Just override the default implementation at the linker level. // hack here: another template specialization for FuncOp
// expect linker to pick this one
template <>
void ::mlir::detail::OpAsmOpInterfaceInterfaceTraits::
Model<mlir::func::FuncOp>::getAsmBlockArgumentNames(
mlir::detail::OpAsmOpInterfaceInterfaceTraits::Concept const *,
mlir::Operation *op, mlir::Region ®ion,
::mlir::OpAsmSetValueNameFn setNameFn) {
::mlir::heir::getAsmBlockArgumentNames(op, region, setNameFn);
} Refactored the code so much cleaner now. Should refactor our uses of Now we have much informative IR func.func @dot_product(%cc: !openfhe.crypto_context, %ct: !ct_L2_, %ct_0: !ct_L2_) -> !ct_L0_
...
func.func @dot_product__configure_crypto_context(%cc: !openfhe.crypto_context, %skey: !openfhe.private_key) -> !openfhe.crypto_context {
openfhe.gen_mulkey %cc, %skey : (!openfhe.crypto_context, !openfhe.private_key) -> ()
openfhe.gen_rotkey %cc, %skey {indices = array<i64: 1, 2, 4, 7>} : (!openfhe.crypto_context, !openfhe.private_key) -> ()
return %cc : !openfhe.crypto_context
} |
834e3d1
to
2e6e933
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactored the code so much cleaner now. Should refactor our uses of
OpAsmOpInterface
andOpAsmDialectInterface
so we can reuse thesuggestNameForType
(even reuse it inSelectVariableNames
).
Nice, that part LGTM!
// hack here: another template specialization for FuncOp | ||
// expect linker to pick this one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm really torn on this one - I love the IR it produces, but this is pretty hacky. At the very least, I'd say lets expand the comment here, maybe link it back to this PR or a new issue that explains why the other alternatives don't work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm OK with it, but I would be quick to remove it if it causes problems.
As long as no tests depend on the naming convention, it should be purely cosmetic.
2fa9baf
to
09754c7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have thought of ways to do this in upstream so we can avoid using the hack (should be a long-term upstreaming process though). Now the Op/Dialect themselves can control the implementation of the interface, but other people can not (similar to My first thinking is to allow user to override the Interface implementation (detailed as Another more reasonable way is that the default implementation of OpAsmOpInterface provides API for Or, since in our implementation it depends on the result type, maybe a default OpAsmInterface implementation could consult the Type with something interface like I wonder how the upstream would think about it, maybe I should open a thread on LLVM discourse. |
|
||
class BGV_Op<string mnemonic, list<Trait> traits = []> : | ||
Op<BGV_Dialect, mnemonic, traits> { | ||
Op<BGV_Dialect, mnemonic, traits # [OpAsmOpInterface]> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Op<BGV_Dialect, mnemonic, traits # [OpAsmOpInterface]> { | |
Op<BGV_Dialect, mnemonic, traits # [DeclareOpInterfaceMethods<OpAsmOpInterface, ["getAsmResultNames"]>]> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will define the methods for you, so you can remove the extra class declaration below. Cf. https://github.com/llvm/llvm-project/blob/1557eeda738d7dbe51d2f52fce28a1fd6f5844ce/mlir/include/mlir/Dialect/Mesh/IR/MeshOps.td#L85 for an upstream example
Same for the other td files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I put the getAsmResultNames
definition here because otherwise I have to instantiate it for each op in Ops.cpp
lib/Dialect/LWE/IR/LWEDialect.cpp
Outdated
.Case<NewLWEPublicKeyType>([&](Type) { return "pkey"; }) | ||
.Case<NewLWESecretKeyType>([&](Type) { return "skey"; }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.Case<NewLWEPublicKeyType>([&](Type) { return "pkey"; }) | |
.Case<NewLWESecretKeyType>([&](Type) { return "skey"; }) | |
.Case<NewLWEPublicKeyType>([&](Type) { return "pk"; }) | |
.Case<NewLWESecretKeyType>([&](Type) { return "sk"; }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same below
// hack here: another template specialization for FuncOp | ||
// expect linker to pick this one |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm OK with it, but I would be quick to remove it if it causes problems.
As long as no tests depend on the naming convention, it should be purely cosmetic.
09754c7
to
4bea464
Compare
This utilizes the
OpAsmOpInterface
'sgetAsmResultNames
, just similar to howgetAlias
works in #1131