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

Pass Attribute to debug function call #1422

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ZenithalHourlyRate
Copy link
Collaborator

@ZenithalHourlyRate ZenithalHourlyRate commented Feb 18, 2025

Fixes #1415

Because heir-translate does not have the func::FuncOp OpAsmOpInterface hack some %arg0 is present instead of %evaluator or %cc. Should be fixed later when I get OpAsmTypeInterface integrated upstream in MLIR (llvm/llvm-project#124700).

For Openfhe, the debug output is quite verbose because of LWE type. For printing op in generic form by AsmPrinter we can not have type alias. resolved now with post-processing in debug function

Example

Lattigo

<block argument> 
  [1 2 3 4 5 6 7 8]
  Noise: 22.30 Total: 96
<block argument> 
  [2 3 4 5 6 7 8 9]
  Noise: 22.49 Total: 96
%ct = lattigo.bgv.mul %arg0, %arg4, %arg5 
  [2 6 12 20 30 42 56 72]
  Noise: 49.79 Total: 96
%ct_0 = lattigo.bgv.relinearize %arg0, %ct 
  [2 6 12 20 30 42 56 72]
  Noise: 49.79 Total: 96

Openfhe

<block argument> 
  ( 1 2 3 4 5 6 7 8 ... )
  cv 2 Ql 4 logQ: 122.323 logqi: [ 31.0008 37 37 17.3219 ] budget 94.7219 noise: 26.6009
<block argument> 
  ( 2 3 4 5 6 7 8 9 ... )
  cv 2 Ql 4 logQ: 122.323 logqi: [ 31.0008 37 37 17.3219 ] budget 94.843 noise: 26.4798
%ct = openfhe.mul_no_relin %arg0, %arg2, %arg3 
  ( 2 6 12 20 30 42 56 72 ... )
  cv 3 Ql 3 logQ: 105.001 logqi: [ 31.0008 37 37 ] budget 52.7384 noise: 51.2625
%ct_0 = openfhe.relin %arg0, %ct 
  ( 2 6 12 20 30 42 56 72 ... )
  cv 2 Ql 3 logQ: 105.001 logqi: [ 31.0008 37 37 ] budget 52.7384 noise: 51.2625

const std::map<std::string, std::string>& debugAttrMap) {
#ifdef OP
auto op = debugAttrMap.at("op");
auto sepBlockArgument = op.find("of type");
Copy link
Collaborator

Choose a reason for hiding this comment

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

What kind of of attribute generates text like this? It looks like it's a printed block argument (block argument at index #0 of type...). Maybe there's an additional special case you can add to the map builder to avoid the string munging here and pass exactly what you want?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What kind of of attribute generates text like this?

    // Use AsmPrinter to print Value to print the defining op
    auto ciphertext = op->getOperand(op->getNumOperands() - 1);
    os << debugAttrMapName << R"(["op"] = ")" << ciphertext << "\"\n";

Here I called operator<<(raw_osstream&, Value) to print the Value, which will be either <block argument> of type (!type) at index or %0 = op %1..., so it is MLIR AsmPrinter's behavior.

Maybe there's an additional special case you can add to the map builder to avoid the string munging here and pass exactly what you want?

Well I do can process this in Emitter by copying buffer from raw_ostream, but then that is too reliant on MLIR's behavior. Once the upstream changed the text string it has to adapt to that.

Another point I want to make is that, we should provide full op information to the debug function and let end user decide whether they want to see the verbose type (so the change to the debug function is just a template here), instead of stripping it earlier.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah, so the complexity here is that you sometimes want to see the op name itself, and if it's not available then you want the type.

I feel like it may be simpler to just extract this info at map construction time...

 os << debugAttrMapName << R"(["is_block_arg"] = ")" << isa<BlockArgument>(ciphertext) << "\"\n";
 os << debugAttrMapName << R"(["value_type"] = ")" << ciphertext.getType() << "\"\n";
 os << debugAttrMapName << R"(["op_name"] = ")" << [get op name or default value] << "\"\n";
 os << debugAttrMapName << R"(["result_ssa_format"] = ")" << ciphertext << "\"\n";

You could still provide the raw string as a catch-all, but I feel that having string munging as the only mechanism to extract information you already know you want is rather brittle.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated to have more information at construction time.

Though instead of seeing detailed asm like op with operand name and result name.

%ct = openfhe.mul_no_relin %arg0, %arg2, %arg3 
   ...
%ct_0 = openfhe.relin %arg0, %ct 
   ...

we only get the op name for convenience now.

Input
  ...
Input
  ...
openfhe.mul_no_relin
  ...
openfhe.relin
  ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support passing attribute to debug function call
2 participants