Send output of one function as input to another in concrete numpy

Hi,

Is there any provision to send the output of one function as input to another without decrypting?

An example for above question is: Say we want to find sum squares of first ‘n’ numbers how to do it in concrete numpy?

Hello,

We don’t support the feature of putting the result of a circuit as an input for another, but it’s something we have in our road-map and are working to deliver.

For the example, if you are using a recursive function to do the computation, just try to rewrite it as an iterative function, to compile a single function.

I also advise you to start using concrete-python instead of concrete-numpy as it’s now deprecated. You can read more here

so for the example that I have asked, to compute sum of squares for first n integers, ideal method is to first find n^2 using PBS, stores results in a list and then sum all elements of the list. How do we try to achieve this in concrete-python?

You can do this by initially creating a numpy array of zeros (n being the size), iterate over and put the result of the PBS at different indexes of the array, then do a sum at the end

Correct me if I am wrong but won’t doing sum at end require a different circuit.

The idea that I have in my is somehting like this:

@fhe.compiler({“x”:“encrypted”})
def square(x):
return x*x

@fhe.compiler({“x”:“encrypted”, “y”:“encrypted”})
def add(x):
return x+y

These two will be creating different circuits. That means output from one circuit is to be given as input to another. Am I doing something wrong over here?

What you want to have is something like this:

def square(x):
    return x * x

def add(x, y):
    return x + y

@fhe.compiler(...)
def to_compile(...):
    pass

using other python functions inside the to_compile function is allowed, so you could potentially combine the previous functions inside, but you don’t need to compile them separately, only the main function need to use the fhe.compiler decorator.

Okay, understood. One more question, does the current version of concrete support passing of encrypted list/tensor to the to_compile function, or just an encrypted integer is allowed?

There is support for encrypted tensors, so you could define your function using a numpy array

I tried using that but it gave me the following error

Expected argument 0 to be EncryptedScalar but it’s EncryptedTensor<uint3, shape=(8,)>

You might have done something that lead the compiler to think the input should be a scalar, and not a tensor, could you provide your python code?

(Moving this thread to Concrete Category)

def square(x):
  return x*x

def add(x, y):
  return x+y

@fhe.compiler({"n":"encrypted"})
def to_compile(n):
  ans = []
  for i in n:
    ans.append(square(i))
  
  res = 0
  for _ in ans:
    res = add(res, i)

  return res 

inputset = np.array(range(8))
circuit = to_compile.compile(inputset)

ip = np.array([1,2,3,4,5,6,7,1])
circuit.encrypt_run_decrypt(ip)

This is my code

the inputset is expected to be a list of inputs, so the compiler think individual elements of the array are inputs, thus scalar. Try to define it as inputset = [np.array(range(8)),]

This works. Thank you for the help.

One last question, there is a documentation available on the zama website for concrete library ( Extensions - Concrete (zama.ai)), but I wanted to know if there is a place where all the functions that have been implemented for concrete-python are available at one place, something similar to there-rs/older concrete-lib versions like this ( LWE in concrete::lwe - Rust (docs.rs))

You can check this one Compatibility - Concrete

1 Like

Is it not possible to return encrypted tensor from a function?

def square(x):
  return x*x

def add(x, y):
  return x+y

@fhe.compiler({"n":"encrypted"})
def to_compile(n):
  ans = []
  for i in n:
    ans.append(square(i))
  
  res = 0
  for _ in ans:
    res = add(res, i)

  return ans 

inputset = np.array(range(8))
circuit = to_compile.compile(inputset)

ip = np.array([1,2,3,4,5,6,7,1])
circuit.encrypt_run_decrypt(ip)

I am trying to return ans instead of res in to_compile function which gives me some error

You can return fhe.array(ans) :slight_smile: