Skip to content
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

[Calyx] constant op #7770

Merged
merged 3 commits into from
Nov 6, 2024
Merged

[Calyx] constant op #7770

merged 3 commits into from
Nov 6, 2024

Conversation

jiahanxie353
Copy link
Contributor

This patch tries to support Calyx constant op whose type is always unsigned integer; and the values and user-intended types are only specified via attributes

@jiahanxie353
Copy link
Contributor Author

jiahanxie353 commented Nov 4, 2024

Hi @rachitnigam @andrewb1999 @cgyurgyik , I'm trying to support the feature we discussed in here.

When I'm running example:

module {
  func.func @main() -> i32 {
    %0 = calyx.constant {value=4.2 : f32} : i32
    return %0 : i32
  }
}

it tells me:

calyx-const.mlir:4:42: error: expected attribute value
    %0 = calyx.constant {value=4.2 : f32} : i32
                                                                    ^

so then I changed to:

%0 = "calyx.constant"() <{value=4.2 : f32}> : () -> i32

it again complains:

calyx-const.mlir:4:10: error: 'calyx.constant' op requires string attribute 'sym_name'
    %0 = "calyx.constant"() <{value=4.2 : f32}> : () -> i32
             ^
calyx-const.mlir:4:10: note: see current operation: %0 = "calyx.constant"() <{value = 4.200000e+00 : f32}> : () -> i3

and then I changed to:

%0 = "calyx.constant"() {sym_name="cst_0", value=4.2 : f32} : () -> i32

it complains:

calyx-const.mlir:4:10: error: 'calyx.constant' op symbol's parent must have the SymbolTable trait
    %0 = "calyx.constant"() {sym_name="cst_0", value=4.2 : f32} : () -> i32
              ^
calyx-const.mlir:4:10: note: see current operation: %0 = "calyx.constant"() <{value = 4.200000e+00 : f32}> {sym_name = "cst_0"} : () -> i32

Any idea how to fix it?

@andrewb1999
Copy link
Contributor

andrewb1999 commented Nov 4, 2024

I think your assembly format is wrong. I also think you shouldn't use { } for this since that's usually reserved for regions and generic op printing. Maybe an assembly format like this?

let assemblyFormat = "$sym_name ` ` `<` $value `>` `:` qualified(type($out))";

Also we need to remove the FirstAttrDerivedResultType property from the operation because the output type no longer necessarily matches the attribute type.

@jiahanxie353
Copy link
Contributor Author

I think your assembly format is wrong. I also think you shouldn't use { } for this since that's usually reserved for regions and generic op printing. Maybe an assembly format like this?

let assemblyFormat = "$sym_name ` ` `<` $value `>` `:` qualified(type($out))";

Also we need to remove the FirstAttrDerivedResultType property from the operation because the output type no longer necessarily matches the attribute type.

I see, thanks!

Is attr-dict a required field in assemblyFormat?

error: 'attr-dict' directive not found in custom assembly format
$sym_name ` ` `<` $value `>` `:` qualified(type($out))
^
Included from /scratch/jiahan/circt/include/circt/Dialect/Calyx/Calyx.td:95:

My td file has:

  let arguments = (ins SymbolNameAttr:$sym_name, TypedAttrInterface:$value);

  let results = (outs AnySignlessInteger:$out);

  let builders = [
    OpBuilder <(ins "StringRef":$sym_name, "TypedAttr":$attr)>,
  ];

  let hasFolder = 1;
  let assemblyFormat = "$sym_name ` ` `<` $value `>` `:` qualified(type($out))";
  let hasVerifier = 1;

any obvious mistake?

@andrewb1999
Copy link
Contributor

Yeah my bad I forgot to add that to the format. Go ahead and add it right before the ':'

@jiahanxie353
Copy link
Contributor Author

Yeah my bad I forgot to add that to the format. Go ahead and add it right before the ':'

No worries and thanks!

Now I have:

def ConstantOp: CalyxPrimitive<"constant",
    [ConstantLike, DeclareOpInterfaceMethods<OpAsmOpInterface, ["getAsmResultNames"]>
    ]> {
  let arguments = (ins SymbolNameAttr:$sym_name, TypedAttrInterface:$value);

  let results = (outs AnySignlessInteger:$out);

  let builders = [
    OpBuilder <(ins "StringRef":$sym_name, "TypedAttr":$attr)>,
  ];

  let hasFolder = 1;
  let assemblyFormat = "$sym_name ` ` `<` $value `>` attr-dict `:` qualified(type($out))";
  let hasVerifier = 1;
}


but it complains:

calyx-const.mlir:3:10: error: 'calyx.constant' op symbol's parent must have the SymbolTable trait
    %0 = calyx.constant @cst <4.2 : f32> : i32
              ^
calyx-const.mlir:3:10: note: see current operation: %0 = "calyx.constant"() <{sym_name = "cst", value = 4.200000e+00 : f32}> : () -> i32

I mean my example is:

module {
  func.func @main() -> i32 {
    %0 = calyx.constant @cst <4.2 : f32> : i32
    return %0 : i32
  }
}

and calyx.constant's parent is funcOp, which obviously has the SymbolTable trait. This is very confusing (and TableGen is confusing for me in general...

@andrewb1999
Copy link
Contributor

Can you push what you have currently so I can take a closer look?

@jiahanxie353
Copy link
Contributor Author

Can you push what you have currently so I can take a closer look?

Sure, just pushed, thank you!

@andrewb1999
Copy link
Contributor

As can be seen here the func op does not have the SymbolTable trait (in contrast to the Calyx ComponentOp as can be seen here. This is in contrast to the Symbol trait which just says an operation defines a symbol. The SymbolTable trait defines the ability for an op to have children that define a symbol. It seems FuncOp does not have this trait to prevent people from defining functions inside of another function.

I think you can simply switch to testing with a calyx.component instead of func.func.

@jiahanxie353
Copy link
Contributor Author

As can be seen here the func op does not have the SymbolTable trait

Indeed, I always assumed that it does...

The SymbolTable trait defines the ability for an op to have children that define a symbol. It seems FuncOp does not have this trait to prevent people from defining functions inside of another function.

I see, makes sense. Thanks!

I think you can simply switch to testing with a calyx.component instead of func.func.

Sounds good!

@rachitnigam rachitnigam added the Calyx The Calyx dialect label Nov 5, 2024
…ttribute,

while the type is always unsigned integer.
Make the corresponding change for addf operator so that they also take integer inputs and produce integer results;
make the corresponding change for function argument passing to convert floating point args to integer.
Finally make the corresponding change for the test code.
Copy link
Member

@cgyurgyik cgyurgyik left a comment

Choose a reason for hiding this comment

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

Seems good to me. Let's let @andrewb1999 take a second look.

Copy link
Contributor

@andrewb1999 andrewb1999 left a comment

Choose a reason for hiding this comment

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

LGTM! Go ahead and merge once CI passes.

@jiahanxie353 jiahanxie353 merged commit 9a34bbb into llvm:main Nov 6, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Calyx The Calyx dialect
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants