Skip to content

Add LWE to JaxiteWord conversion pass#2964

Merged
copybara-service[bot] merged 1 commit into
google:mainfrom
Zohaib58:feature/lwe-to-jaxiteword-pass
May 20, 2026
Merged

Add LWE to JaxiteWord conversion pass#2964
copybara-service[bot] merged 1 commit into
google:mainfrom
Zohaib58:feature/lwe-to-jaxiteword-pass

Conversation

@Zohaib58
Copy link
Copy Markdown
Contributor

@Zohaib58 Zohaib58 commented May 19, 2026

Adds the lwe-to-jaxiteword conversion pass, which lowers the lwe dialect (and related ckks / bgv ops handled by the pass) to the jaxiteword dialect for CROSS / JaxiteWord codegen.

This is a follow-up to #2946 (JaxiteWord dialect, emitter, and configure-crypto-context). That PR landed the target dialect and Python emission; this PR wires the LWE → JaxiteWord lowering so HEIR pipelines can reach CROSS backend ops from scheme-level IR.

Changes

  • New pass: lib/Dialect/LWE/Conversions/LWEToJaxiteWord/
  • Pass flag: --lwe-to-jaxiteword
  • Inserts jaxiteword.crypto_context and jaxiteword.eval_key on func.func when the function contains crypto ops
  • Lowers homomorphic ops (e.g. add/sub/mul/rotate/relin/mod-switch, encode/encrypt/decrypt/decode, plaintext variants) to jaxiteword ops
  • Register pass in heir-opt (tools/heir-opt.cpp, tools/BUILD)
  • Lit tests under tests/Dialect/LWE/Conversions/lwe_to_jaxiteword/:
  • smoke_test.mlir - encode + encrypt path runs without error
  • radd.mlir - lwe.radd lowers to jaxiteword.add with context/eval-key args

Notes

Intended to mirror patterns from existing LWE lowering passes (lwe-to-openfhe, lwe-to-polynomial).

@j2kun j2kun self-requested a review May 19, 2026 15:50
Copy link
Copy Markdown
Collaborator

@j2kun j2kun left a comment

Choose a reason for hiding this comment

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

Looks great! Only some minor nitpicks

Comment thread lib/Dialect/LWE/Conversions/LWEToJaxiteWord/BUILD Outdated
Comment thread tests/Dialect/LWE/Conversions/lwe_to_jaxiteword/radd.mlir Outdated
Comment thread tests/Dialect/LWE/Conversions/lwe_to_jaxiteword/smoke_test.mlir
Comment thread lib/Dialect/LWE/Conversions/LWEToJaxiteWord/LWEToJaxiteWord.cpp Outdated
Comment thread lib/Dialect/LWE/Conversions/LWEToJaxiteWord/LWEToJaxiteWord.cpp Outdated
}
if (dynamicShift) {
return rewriter.notifyMatchFailure(
op, "jaxiteword rotation requires static shift");
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This will end up being a bit of an obstacle for supporting looped linalg kernels. @JianmingTONG is this a strict limitation of CROSS?

No need to make any changes to this PR, I just want to know for tracking future work.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey Jeremy

Thank you for the comment and wish you a great memorial weekend!

IIUC, the computation in HE is preknown ahead of execution, which could be used to generate all rotation keys. And this dynamicShift seems telling that we need some rotation indice to be generated in the runtime. Might I get some insights on what cases would we need this runtime dynamity? And correct me if I miss understand it

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If we express a program using loops, then the SSA value representing the desired shift is statically inferrable, but dynamically dependent on the loop iteration in question. So even if we know all the rotation keys at compile time, the operation syntax may still need to express a non-attribute for the shift operand.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Aha got it!

It's the actual shift used at runtime that depends on which loop iteration is executing

I could confirm that is not the limitation of CROSS to support dynamic rotation, as it'll be the same API as OpenFHE

Comment thread lib/Dialect/LWE/Conversions/LWEToJaxiteWord/LWEToJaxiteWord.cpp Outdated
@Zohaib58 Zohaib58 requested a review from j2kun May 19, 2026 20:14
Copy link
Copy Markdown
Collaborator

@j2kun j2kun left a comment

Choose a reason for hiding this comment

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

LGTM! Please squash the commits (removing my co-authorship or replacing my email with jkun@google.com, I'm not sure why it doesn't recognize my account in the CLA...)

Register the pass in heir-opt and add lit tests with FileCheck coverage for
lowered jaxiteword operations.
@Zohaib58 Zohaib58 force-pushed the feature/lwe-to-jaxiteword-pass branch from 89a124c to cf2ccbf Compare May 19, 2026 21:04
@Zohaib58 Zohaib58 requested a review from j2kun May 19, 2026 21:09
Copy link
Copy Markdown
Collaborator

@j2kun j2kun left a comment

Choose a reason for hiding this comment

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

LGTM!

@j2kun j2kun added the pull_ready Indicates whether a PR is ready to pull. The copybara worker will import for internal testing label May 19, 2026
@copybara-service copybara-service Bot merged commit 74c1017 into google:main May 20, 2026
5 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pull_ready Indicates whether a PR is ready to pull. The copybara worker will import for internal testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants