Client specification and Visualizing DAG

https://docs.zama.ai/concrete/how-to/deploy,‘Here’ is the client server setting in concrete
It mentions client specifications ,but how do I get hold of what are parameter settings in the part of client?
After we print a circuit ,any tool to visualize the dag corresponding to the circuit?

Hi @Laser_beam,

It’s not possible to get client parameters in a programmatic way officially, but you can use this unofficial and unstable trick to see the parameters if you want:

import json
client_parameters = json.loads(client.specs.client_parameters.serialize())
print(client_parameters)

Unfortunately, there is no way to visualize the DAG at the moment :slightly_smiling_face:

Let us know if you have any other questions!

1 Like

Thanks It works, but May I know how does concrete select the optimal parameters ?
Which parameters does the client has control to set up?
I found while going through docs “https://docs.zama.ai/concrete/how-to/configure” ,it says about parameter selection strategy,can you elaborate little theoretically and how do we actually set up using compile method? (it says “Set how cryptographic parameters are selected.”)

Thanks It works

You’re welcome!

May I know how does concrete select the optimal parameters ?

That’s a question for @Rudy_Sicard, but the answer is in https://github.com/zama-ai/concrete/tree/main/compilers/concrete-optimizer :wink:

It says about parameter selection strategy, can you elaborate little theoretically and how do we actually set up using compile method?

Sure! Theoretically, it’s an optimizer flag to change how it works. If fhe.ParameterSelectionStrategy.MONO is specified, only a single set of parameters would be selected for all encrypted values. This is not ideal because it means some operations will be more costly compared to what they can be (imagine you have 2-bit and 8-bit table lookups in your circuit, if MONO is used, all table lookups would be as costly as 8-bit table lookups). If fhe.ParameterSelectionStrategy.MULTI is specified, multiple parameters would be selected, to be as optimal as possible in terms of the execution time.

And for setting it up:

import time

import numpy as np
from concrete import fhe

configuration = fhe.Configuration(single_precision=False)

def f(x):
    return (x**2 + 1)**2

inputset = range(2**3)

for strategy in [fhe.ParameterSelectionStrategy.MONO, fhe.ParameterSelectionStrategy.MULTI]:
    name = str(strategy)

    print()
    print(name)
    print("-" * len(name))

    compiler = fhe.Compiler(f, {"x": "encrypted"})
    circuit = compiler.compile(inputset, configuration, parameter_selection_strategy=strategy)

    start = time.time()
    circuit.keys.generate()
    end = time.time()
    print(f"Key generation took {end - start:.3f}s")

    key_size = (
        circuit.size_of_secret_keys +
        circuit.size_of_bootstrap_keys +
        circuit.size_of_keyswitch_keys
    )
    print(f"Keys are {key_size / (1024 * 1024):.3f} mb")

    start = time.time()
    assert circuit.encrypt_run_decrypt(2) == 25
    end = time.time()
    print(f"Execution took {end - start:.3f}s")

When I run this code on my laptop, I see:

ParameterSelectionStrategy.MONO
-------------------------------
Key generation took 5.317s
Keys are 329.743 mb
Execution took 0.527s

ParameterSelectionStrategy.MULTI
--------------------------------
Key generation took 7.106s
Keys are 567.671 mb
Execution took 0.320s

So with multi parameters, it’s faster to execute but slower to generate keys and keys are larger, compared to mono parameters.

Feel free to use show_optimizer=True configuration option to see the parameters selected by the optimizer!

Let us know if this helps :slightly_smiling_face:

1 Like

Again thanks for the quick response
probably you missed this qn : Which parameters does the client has control to set up in client server setting?
I had one more confusion why is key generation dependent on the circuit? Do we not sample it internally through some generator from uniform distribution?
Are there any ways that I can access and print these vectors through python interface
std::vector secretKeys,
std::vector bootstrapKeys,
std::vector keyswitchKeys,
std::vector packingKeyswitchKeys, CSPRNG &&csprng)
I found this in keyset.cpp file

Which parameters does the client has control to set up in client server setting?

Clients cannot set parameters, parameters are set by the optimizer, which is done during compilation. In deployment, there is no compilation.

Why is key generation dependent on the circuit?

Because different circuits have different optimal parameters. If we used a single parameters everywhere, the worst case execution time would apply to all circuits.

Do we not sample it internally through some generator from uniform distribution?

I’m not sure how this is related to the question. Keys for different circuits can have different parameters, so the generated keys are not compatible.

Are there any ways that I can access and print these vectors through python interface?

No, those are low-level internal objects, which are not required to use the library. What is your use case exactly?

I was looking if I could have a granular view (similiar to that of rust)through an python interface of say how we are using lwe parmeters to generate the secret key;
choosing dimension of lwe mask; and so on…
1)By the way can we see pub unsafe features in concrete
2)pbs_base_log: DecompositionBaseLog,
pbs_level: DecompositionLevelCount,
ks_base_log: DecompositionBaseLog,
ks_level: DecompositionLevelCount; can you little elaborate on this parameters?
3) and also can you say how much has concrete architecture changed after this(https://homomorphicencryption.org/wp-content/uploads/2020/12/wahc20_demo_damien.pdf)

how we are using lwe parmeters to generate the secret key

There is no way to see that at the moment.

by the way can we see pub unsafe features in concrete

What do you mean by pub unsafe features?

can you little elaborate on this parameters

That’s a question for @Rudy_Sicard, he’ll be back next week!

and also can you say how much has concrete architecture changed after this

That’s another question for @Rudy_Sicard :slightly_smiling_face:

these are the unsafe features ,that we get set in tfhe rust : LweDimension,
glwe_dimension: GlweDimension,
polynomial_size: PolynomialSize,
lwe_modular_std_dev: StandardDev,
glwe_modular_std_dev: StandardDev,
pbs_base_log: DecompositionBaseLog,
pbs_level: DecompositionLevelCount,
ks_base_log: DecompositionBaseLog,
ks_level: DecompositionLevelCount,

@umutsahin Brother can you help me on how to print the client specs and model specifications in this case https://github.com/zama-ai/concrete-ml/blob/release/1.1.x/docs/advanced_examples/ClientServer.ipynb

Hello @Laser_beam,
In the notebook you mentioned (section “Client Machine”), you should be able to print the parameters using :

import json
client_parameters = json.loads(fhemodel_client.client.specs.client_parameters.serialize())
print(client_parameters)

Hope this helps !

1 Like

how does concrete select the optimal parameters ?

A module of the compiler (concrete-optimizer), smartly enumerate all crypto-parameters possibilites and take the solution that is consistant whit security and corectness constraint, and that minimize the execution cost.

1 Like

can you little elaborate on this parameters

Level and base are quantity used to create the bootstrapping key.
Bootstrapping key = many GGSW = many many GLev

You can follow the deep dive articles:

TFHE Deep Dive - Part I - Ciphertext types (for level and base parameters description)
TFHE Deep Dive - Part I - Ciphertext types (for level and base parameters description)
TFHE Deep Dive - Part IV - Programmable Bootstrapping for bootstrapping key definition

1 Like

@Rudy_Sicard If you can name those parameters which are invariant( meaning donot change ) with change of circuit?I had this doubt as I saw in boolean circuit evaluation we choose either default parameters or TFHE lib parameters

and please correct me I believe corresponding to the target p_error ,target security bits and max bit width of the circuit ,concrete chooses parameters from this enumerated list

Boolean circuit are very specifics, precision and norm2 are always the same (assuming gates with 2 operands).
On regular circuit, optimal crypto-parameters are differents with almost any circuit change (for instance if one clear value multiplier is modified). Also for the same circuit, if you target a different p_error, it also changes the crypto-parameters.

Note that the parameter being discrete, they are threshold effects before seeing a change.

The enumerated list on in v0_last_128 is a reference file for a specific kind of circuit, and specific p_error and security. The reference file only serves for internal tests.

Concrete Python and Concrete Compiler use online optimization tailored for a given circuit so it has access to all possible parameters and not only the ones in the references files.