Skip to content

Conversation

@ZenithalHourlyRate
Copy link
Collaborator

In CKKS, knowing the range of the plaintext inside each ciphertext is crucial for (worst-case) noise analysis (e.g. #1685), and further the selection of parameters.

Currently we have the following ways to know the range

  1. Plaintext backend: it can tell the range of all intermediate ciphertexts of one specific input
  2. Tools like Explore tools for annotating intermediate layers of ML models with range bounds #1700: it can tell the range of some ciphertext in ML model
  3. Assuming all ciphertexts are in range [-1, 1]: commonly used in paper, not practical.
  4. User annotates the range of the input and compiler does analysis on intermediate ciphertexts. This PR enables the analysis part; the annotation part needs further discussion (e.g. integration with python frontend and packing pipeline).

As an example, the current parameter generation process is modified to use the analysed range to select first-mod-bits when the user specifies the first-mod-bits to be 0; other usage will be explored in further noise model PRs.

Example

The dot_product_8f example is an inner product of [-1, 1] : <8xf32> with addition of 0.1 : f32, so maximal possible value is 8.1, and the analyse result is

Propagate CKKSRangeState to %22 = mgmt.modreduce %21 {mgmt.mgmt = #mgmt.mgmt<level = 0>} : tensor<8xf32>: CKKSRangeState(normal: 8.10, log2: 3.02)

Note that if we use plaintext backend, it will infer that the maximal value is 2.5, and select a smaller parameter; when the user changes the input, the selected parameter may not be valid.

Then the parameter selection process chose 51 as its first mod bits

First modulus bits not specified, using 51 bits.
Scheme Param:
logDefaultScale: 45
ringDim: 16384
level: 2
logqi: 51.00 45.00 45.00 

Limitation

For now only the dot_product example (and the cross_level example, which requires 12 extra bits) can work through the analysis; other example like hv_matmul does not have the range result due to complex IR structure.

@j2kun j2kun self-requested a review July 17, 2025 22:31
Copy link
Collaborator

Choose a reason for hiding this comment

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

This doesn't appear to be specific to CKKS, and so could we rename the file/structs involved to just be, perhaps, "RangeAnalysis"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Name changed to RangeAnalysis.

// For double input, default range is [-1, 1]
// This handles both secret input and plaintext func arg
propagateIfChanged(lattice,
lattice->join(CKKSRangeState({Log2Arithmetic::of(1)})));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would it be possible to make this configurable via a pass flag? I feel the -1, 1 default is a surprise and it should be at least made more visible by being configurable at the pass level.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added a input-range parameter to generate-param-ckks

@j2kun j2kun added the pull_ready Indicates whether a PR is ready to pull. The copybara worker will import for internal testing label Jul 26, 2025
@copybara-service copybara-service bot merged commit 0e5fd99 into google:main Jul 29, 2025
13 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.

2 participants