Deploy server.zip using direct circuit?

I’ve been using a direct circuit because I wanted to use the full range of fhe.int16. But I would also like to compile and save the server.zip for deployment. Is there a proper way to use compile to get full range of a type? I’d be happy with some granularity setting (ie. full range of type in steps of x) or something. Its just that a large inputset didn’t seem like the correct/elegant way to achieve this. So thought I’d ask.

My current code summarized is:
@fhe.circuit({“s1”: “encrypted”, “s2”: “encrypted”})
def circuit(s1:fhe.int16, s2: fhe.int16):
return ((s1+s2)//2)

Followed by circuit.encrypt(a,b), etc.

Thank you again in advance.
Ron.

Hi,

Your direct circuit definition is correct and it’s producing this MLIR:

module {
  func.func @main(%arg0: !FHE.esint<16>, %arg1: !FHE.esint<16>) -> !FHE.esint<16> {
    %0 = "FHE.add_eint"(%arg0, %arg1) : (!FHE.esint<16>, !FHE.esint<16>) -> !FHE.esint<16>
    %c2_i17 = arith.constant 2 : i17
    %cst = arith.constant dense<"..."> : tensor<65536xi64>
    %1 = "FHE.apply_lookup_table"(%0, %cst) : (!FHE.esint<16>, tensor<65536xi64>) -> !FHE.esint<16>
    return %1 : !FHE.esint<16>
  }
}

from this code

from concrete import fhe

@fhe.circuit({"s1": "encrypted", "s2": "encrypted"})
def circuit(s1: fhe.int16, s2: fhe.int16):
    return (s1 + s2) // 2

print(circuit.mlir)

which means you can use the full range of int16 :slight_smile:

However, this code doesn’t behave well if there is an overflow! That’s why inputsets are useful as they can detect this overflow from your typical data and fail compilation early instead of unexpected failures later. So please be careful with direct circuits.

Let us know if you have any other questions!

As for deployment, you can follow the same procedure explained in How to Deploy section of our documentation. It’s the same for direct circuits!

Thank you so much for your answer. (and yes, I happen to know that in my specific application the odd overflow is no big deal…but thank you for pointing it out! I will be careful).

So, just to capture this in the thread for future readers…my core confusion was if I could call circuit.server.save() if I never explicitly called compile(), but used markup with direct circuit instead. And, I think you are saying that the answer is yes. (I’ll know for sure shortly when I try it :slight_smile:

All the best,
Ron.

Exactly, direct definition is just an alternative way to generate a circuit, it doesn’t add functionality or remove it from circuits.

Let us know if it worked like you expected :slight_smile: