-
Notifications
You must be signed in to change notification settings - Fork 51
Open
Description
As an example, try this simple single operation from the MLIR Toy Tutorial:
#ifndef TOY_OPS
#define TOY_OPS
include "mlir/IR/OpBase.td"
def Toy_Dialect : Dialect {
let name = "toy";
let cppNamespace = "::mlir::toy";
}
class Toy_Op<string mnemonic, list<Trait> traits = []> :
Op<Toy_Dialect, mnemonic, traits>;
def TransposeOp : Toy_Op<"transpose"> {
let summary = "transpose operation";
let arguments = (ins F64Tensor:$input);
let results = (outs F64Tensor);
// Allow building a TransposeOp from the input operand.
let builders = [
OpBuilder<(ins "Value":$input)>
];
}
#endif // TOY_OPS
Use the macro:
mod melior_gen {
melior::dialect! {
name: "toy",
files: ["src/dialect/toy.td"]
}
}
This results in the following builder (I cleaned up the code a bit to be more readable):
pub(crate) mod mre {
/// Autogenerated dialect module from a `.td` file.
mod melior_gen {
pub mod toy {
use melior::ir::operation::OperationLike;
use melior::ir::operation::OperationMutLike;
pub struct TransposeOperation<'c> {
operation: ::melior::ir::operation::Operation<'c>,
}
impl<'c> TransposeOperation<'c> {
/// Returns a name.
pub fn name() -> &'static str {
"toy.transpose"
}
/// Returns a generic operation.
pub fn as_operation(&self) -> &::melior::ir::operation::Operation<'c> {
&self.operation
}
/// Creates a builder.
pub fn builder(
context: &'c ::melior::Context,
location: ::melior::ir::Location<'c>,
) -> TransposeOperationBuilder<'c, ::melior::dialect::ods::__private::Unset> {
TransposeOperationBuilder::new(context, location)
}
pub fn input(&self) -> Result<::melior::ir::Value<'c, '_>, ::melior::Error> {
self.operation.operand(0)
}
}
///A builder for a [`transpose`](TransposeOperation) operation.
pub struct TransposeOperationBuilder<'c, O0> {
builder: ::melior::ir::operation::OperationBuilder<'c>,
context: &'c ::melior::Context,
_state: ::std::marker::PhantomData<(O0)>,
}
impl<'c,> TransposeOperationBuilder<'c, ::melior::dialect::ods::__private::Unset> {
pub fn new(context: &'c ::melior::Context, location: ::melior::ir::Location<'c>) -> Self {
Self {
context,
builder: ::melior::ir::operation::OperationBuilder::new(
"toy.transpose",
location,
),
_state: Default::default(),
}
}
}
impl<'c> TransposeOperationBuilder<'c, ::melior::dialect::ods::__private::Unset> {
pub fn input(self, input: ::melior::ir::Value<'c, '_>) -> TransposeOperationBuilder<
'c,
::melior::dialect::ods::__private::Set,
> {
TransposeOperationBuilder {
context: self.context,
builder: self.builder.add_operands(&[input]),
_state: Default::default(),
}
}
}
impl<'c> TransposeOperationBuilder<'c, ::melior::dialect::ods::__private::Set> {
pub fn build(self) -> TransposeOperation<'c> {
self.builder
.build()
.expect("valid operation")
.try_into()
.expect("should be a valid TransposeOperation")
}
}
#[allow(clippy::too_many_arguments)]
///Creates a [`transpose`](TransposeOperation) operation.
pub fn transpose<'c>(
context: &'c ::melior::Context,
input: ::melior::ir::Value<'c, '_>,
location: ::melior::ir::Location<'c>,
) -> TransposeOperation<'c> {
TransposeOperation::builder(context, location).input(input).build()
}
}
}
}
- At no point is the operation configured to have one result of the
F64Tensor
type. Transpose operations created from this module will always have zero results, which is incorrect. As far as I can see this applies to every operation generated with the macro currently – they're all resultless. The workaround is to write all this code yourself, but that defeats the purpose of the macro. - As a secondary, smaller issue – I'd expect the builder to validate that the
input
argument provided conforms to the definition in TableGen, i.e. that it is actually of theF64Tensor
type. - I also think that currently the
builder
field in the TableGen definition is completely ignored, I couldn't get any behaviour difference by changing or removing it. - It is really confusing to use this macro, because there is zero documentation on what it does. I would really appreciate at least a shortlist of parts of the MLIR ODS framework that are actually supported. For example, the
hasVerifier
field has no effect – it would be nice to read this in the doc instead of having to figure it out by experimentation and reading the generated code (no one likes reading generated code, right).
Metadata
Metadata
Assignees
Labels
No labels