Collecting the accumulator bit width - Concrete ML

Hello,

I wanted to know if there is a way to collect the value of the accumulator bit width. When it is reached, an error appears and the value of the accumulator is precised - so computed - but I wanted to know if it is possible to collect this value in a simpler way even if the RunTimeError due to accumulator bit width overtaking is not detected.

Thank you

Hello @Clo_Cant ,
You should be able to check the value in the traceback (as where this value is reached) !

For example, if you run this simple code :

from concrete import fhe

def add(x):
    return (x + 8) // 2

compiler = fhe.Compiler(add, {"x": "encrypted"})

inputset = [2**16-1, 0, 1, 7, 7]
circuit = compiler.compile(inputset)

You get the following traceback :

…
RuntimeError: Function you are trying to compile cannot be compiled
%0 = x # EncryptedScalar ∈ [0, 65535]
%1 = 8 # ClearScalar ∈ [8, 8]
%2 = add(%0, %1) # EncryptedScalar ∈ [8, 65543]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this 17-bit value is used as an input to a table lookup
/var/folders/p6/8g0g4d5s4y1bzz95sw3ch7qw0000gn/T/ipykernel_3523/2628929928.py:4
%3 = 2 # ClearScalar ∈ [2, 2]
%4 = floor_divide(%2, %3) # EncryptedScalar ∈ [4, 32771]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ but only up to 16-bit table lookups are supported
/var/folders/p6/8g0g4d5s4y1bzz95sw3ch7qw0000gn/T/ipykernel_3523/2628929928.py:4
return %4

which tells you that the add operation reaches a 17 bits value !

If you need this traceback as a proper text file, you can use the dump_artifacts_on_unexpected_failures configuration feature :

from concrete.fhe import Configuration

configuration = Configuration(dump_artifacts_on_unexpected_failures=True)
...
circuit = compiler.compile(inputset, configuration=configuration)

As this will write debug files in a .artifacts directory, in particular the traceback.txt file.

Let me know if that answers your request !

Thank you for the answer. I want to know if it is possible to catch it even though the accumulator is not overtaken ?

You mean when there’s no RuntimeError ? If so, you can access it after compilation through circuit.graph.maximum_integer_bit_width() !

2 Likes

Ok thank you, that is exactly what I needed!

1 Like