-
Notifications
You must be signed in to change notification settings - Fork 149
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
feat(optimizer): support external partition in virtual circuits #1187
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Benchmark
Benchmark suite | Current: 2758060 | Previous: 426a261 | Ratio |
---|---|---|---|
v0 PBS table generation |
53323126 ns/iter (± 3187870 ) |
61444122 ns/iter (± 639454 ) |
0.87 |
v0 PBS simulate dag table generation |
38013513 ns/iter (± 390494 ) |
38752536 ns/iter (± 1190408 ) |
0.98 |
v0 WoP-PBS table generation |
52478090 ns/iter (± 307768 ) |
54049522 ns/iter (± 3297729 ) |
0.97 |
This comment was automatically generated by workflow using github-action-benchmark.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, add an high-level concrete-python test
I think it could be great to have @rudy-6-4 review too |
arg("macro_glwe_dimension"), arg("macro_internal_dim"), | ||
arg("max_variance"), arg("variance")) | ||
.doc() = "Definition of an external partition."; | ||
|
||
// ------------------------------------------------------------------------------// | ||
// KEYSET INFO // |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about keygen using KeySetInfo instead of ProgramInfo? If it requires a lot of changes in the frontend, then we can think about having both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentionned at the end of our discussion, I thought it may incorrectly nudge the user into generating keysets from the virtual keyset info, which would yield a big keygen, while just a small subset would be needed for the circuit.
And thinking about it a bit more, I don't think it would work to use a superset of the necessary keyset on a circuit (nothing fancy, just that we index keys by number, and as such, we may incorrectly lookup keys).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sense yeah. I'm just thinking how can we showcase the feature then... We just need a way to construct a keyset from a program info using pregenerated keys. If we had a big keyset (with more keys than what the circuit needs), we could have a method that takes the program info and the big keyset, and extract necessary keys with their appropriate index.
We can also simulate all this with a keygen for now, so it's not really necessary, but it will make a better demo with something in this direction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@BourgerieQuentin WDYT ?
name, | ||
macroLog2PolynomialSize, | ||
macroGlweDimension, | ||
macroInternalDim, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if macroInternalDim have any use now or in the future !?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure how this is used, but it is needed to construct the external partition structure in the optimizer ...
@@ -46,6 +46,11 @@ impl std::fmt::Display for ExternalPartition { | |||
} | |||
} | |||
|
|||
pub struct PrePartitionDag { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If only for Viz could be in utils.
@@ -122,33 +207,55 @@ pub fn generate_virtual_parameters( | |||
&Some(p_cut), | |||
PartitionIndex(0), | |||
) | |||
.map_or(None, |v| Some(v.1)) | |||
.unwrap(); | |||
.unwrap() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could return a Result or Option CircuitKeys
def test_generic_restriction_with_external(helpers): | ||
""" | ||
Test that compiling a module works. | ||
""" | ||
|
||
dtype = tfhers.TFHERSIntegerType( | ||
False, | ||
bit_width=8, | ||
carry_width=3, | ||
msg_width=2, | ||
params=tfhers.CryptoParams( | ||
lwe_dimension=909, | ||
glwe_dimension=1, | ||
polynomial_size=4096, | ||
pbs_base_log=15, | ||
pbs_level=2, | ||
lwe_noise_distribution=0, | ||
glwe_noise_distribution=2.168404344971009e-19, | ||
encryption_key_choice=tfhers.EncryptionKeyChoice.BIG, | ||
), | ||
) | ||
config = helpers.configuration() | ||
options = config.to_compilation_options().get_optimizer_options() | ||
|
||
generic_keyset_info = KeysetInfo.generate_virtual( | ||
[ | ||
InternalPartitionDefinition(3, 10.0), | ||
InternalPartitionDefinition(5, 10.0) | ||
], | ||
[ | ||
dtype.external_partition_definition() | ||
], | ||
options | ||
) | ||
|
||
parameters = { | ||
"x": {"range": [0, 2**7], "status": "encrypted"}, | ||
"y": {"range": [0, 2**7], "status": "encrypted"}, | ||
} | ||
|
||
parameter_encryption_statuses = helpers.generate_encryption_statuses(parameters) | ||
|
||
def binary_tfhers(x, y, binary_op, tfhers_type): | ||
"""wrap binary op in tfhers conversion (2 tfhers inputs)""" | ||
x = tfhers.to_native(x) | ||
y = tfhers.to_native(y) | ||
return tfhers.from_native(binary_op(x, y), tfhers_type) | ||
|
||
compiler = fhe.Compiler( | ||
lambda x, y: binary_tfhers(x, y, lambda x, y: x + y, dtype), | ||
parameter_encryption_statuses, | ||
) | ||
|
||
inputset = [ | ||
tuple(tfhers.TFHERSInteger(dtype, arg) for arg in inpt) | ||
for inpt in helpers.generate_inputset(parameters) | ||
] | ||
|
||
circuit = compiler.compile(inputset, config, keyset_restriction=generic_keyset_info.get_restriction()) | ||
|
||
compiled_keyset_info = circuit._module.keys.specs.program_info.get_keyset_info() | ||
assert all([k in generic_keyset_info.secret_keys() for k in compiled_keyset_info.secret_keys()]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No description provided.