I’m currently using Concrete’s Modules with automatic module tracing, and it works like a charm. The only problem I face is that I would like to trace functions with numpy arrays as parameters using arrays of different dimensions, such that I can use the function with arrays of different dimensions. It seems to me that this is currently not supported, and the only solution I see is to pollute the Module with a function for each dimension I expect during runtime. Is there a more elegant way to achieve something like this?
Unfortunately not. The Compiler needs to know those dimensions as it impacts the computation that would be done.
The Compiler finds FHE parameters that fits your computation, so that it is efficient, and its results are accurate. So knowing the exact computation is necessary.
Thanks for your fast reply! I understand, but if it’s possible to create the same function with different names and different input shapes and trace them both, wouldn’t it be useful to abstract that such that it’s possible to trace the same function with inputs of different shape? I do that now, by monkey patching the function decorator an creating the module class dynamically, but it’s a hacky mess
If the function is the same, why don’t you just compile it multiple times with different inputs. You would get different circuits each working with a given shape. For example:
I tried that, but in my case I want to compile a function inside of a module in such a way.
It should look something like this:
from concrete import fhe
import numpy as np
@fhe.module()
class Example:
@fhe.function({"x": "encrypted", "y": "encrypted"})
def ex(x, y):
return fhe.refresh(x@y)
composition = fhe.Wired()
# Working Inputset
inputset = [tuple(np.random.randint(-2, 2, size=dims) for dims in ((5,5), (5, 5), (5, 5))) for _ in range(100)]
# Non working inputset
# inputset = [tuple(np.random.randint(-2, 2, size=dims) for dims in ((8,5), (5, 3), (3, 2))) for _ in range(100)]
with Example.wire_pipeline(inputset) as samples_iter:
# The inputset is iterated over
for s in samples_iter:
out = Example.ex(s[:2])
out = Example.ex(out, s[2])
MyExmaple = Example.compile()