diff --git a/compilers/concrete-compiler/compiler/lib/Bindings/Python/CompilerAPIModule.cpp b/compilers/concrete-compiler/compiler/lib/Bindings/Python/CompilerAPIModule.cpp index 4703495c4c..112bf2b91e 100644 --- a/compilers/concrete-compiler/compiler/lib/Bindings/Python/CompilerAPIModule.cpp +++ b/compilers/concrete-compiler/compiler/lib/Bindings/Python/CompilerAPIModule.cpp @@ -243,77 +243,6 @@ void mlir::concretelang::python::populateCompilerAPISubmodule( m.def("check_gpu_runtime_enabled", &checkGPURuntimeEnabled); m.def("check_cuda_device_available", &checkCudaDeviceAvailable); - pybind11::class_(m, "TfhersFheIntDescription") - .def(pybind11::init([](size_t width, bool is_signed, - size_t message_modulus, size_t carry_modulus, - size_t degree, size_t lwe_size, size_t n_cts, - size_t noise_level, bool ks_first) { - auto desc = TfhersFheIntDescription(); - desc.width = width; - desc.is_signed = is_signed; - desc.message_modulus = message_modulus; - desc.carry_modulus = carry_modulus; - desc.degree = degree; - desc.lwe_size = lwe_size; - desc.n_cts = n_cts; - desc.noise_level = noise_level; - desc.ks_first = ks_first; - return desc; - })) - .def_static("UNKNOWN_NOISE_LEVEL", - [] { return concrete_cpu_tfhers_unknown_noise_level(); }) - .def_property( - "width", [](TfhersFheIntDescription &desc) { return desc.width; }, - [](TfhersFheIntDescription &desc, size_t width) { - desc.width = width; - }) - .def_property( - "message_modulus", - [](TfhersFheIntDescription &desc) { return desc.message_modulus; }, - [](TfhersFheIntDescription &desc, size_t message_modulus) { - desc.message_modulus = message_modulus; - }) - .def_property( - "carry_modulus", - [](TfhersFheIntDescription &desc) { return desc.carry_modulus; }, - [](TfhersFheIntDescription &desc, size_t carry_modulus) { - desc.carry_modulus = carry_modulus; - }) - .def_property( - "degree", [](TfhersFheIntDescription &desc) { return desc.degree; }, - [](TfhersFheIntDescription &desc, size_t degree) { - desc.degree = degree; - }) - .def_property( - "lwe_size", - [](TfhersFheIntDescription &desc) { return desc.lwe_size; }, - [](TfhersFheIntDescription &desc, size_t lwe_size) { - desc.lwe_size = lwe_size; - }) - .def_property( - "n_cts", [](TfhersFheIntDescription &desc) { return desc.n_cts; }, - [](TfhersFheIntDescription &desc, size_t n_cts) { - desc.n_cts = n_cts; - }) - .def_property( - "noise_level", - [](TfhersFheIntDescription &desc) { return desc.noise_level; }, - [](TfhersFheIntDescription &desc, size_t noise_level) { - desc.noise_level = noise_level; - }) - .def_property( - "is_signed", - [](TfhersFheIntDescription &desc) { return desc.is_signed; }, - [](TfhersFheIntDescription &desc, bool is_signed) { - desc.is_signed = is_signed; - }) - .def_property( - "ks_first", - [](TfhersFheIntDescription &desc) { return desc.ks_first; }, - [](TfhersFheIntDescription &desc, bool ks_first) { - desc.ks_first = ks_first; - }); - pybind11::enum_(m, "Backend") .value("CPU", mlir::concretelang::Backend::CPU, "Circuit codegen targets cpu.") @@ -1993,6 +1922,109 @@ void mlir::concretelang::python::populateCompilerAPISubmodule( "Return the `circuit` ClientCircuit.", arg("circuit")) .doc() = "Client-side / Encryption program"; + // ------------------------------------------------------------------------------// + // TFHERS INTEGER DESCRIPTION // + // ------------------------------------------------------------------------------// + + pybind11::class_(m, "TfhersFheIntDescription") + .def(pybind11::init([](size_t width, bool is_signed, + size_t message_modulus, size_t carry_modulus, + size_t degree, size_t lwe_size, size_t n_cts, + size_t noise_level, bool ks_first) { + auto desc = TfhersFheIntDescription(); + desc.width = width; + desc.is_signed = is_signed; + desc.message_modulus = message_modulus; + desc.carry_modulus = carry_modulus; + desc.degree = degree; + desc.lwe_size = lwe_size; + desc.n_cts = n_cts; + desc.noise_level = noise_level; + desc.ks_first = ks_first; + return desc; + }), + arg("width"), arg("is_signed"), arg("lwe_size"), arg("n_cts"), + arg("degree"), arg("noise_level"), arg("message_modulus"), + arg("carry_modulus"), arg("ks_first")) + .def_static("get_unknown_noise_level", + [] { return concrete_cpu_tfhers_unknown_noise_level(); }) + .def_property( + "width", [](TfhersFheIntDescription &desc) { return desc.width; }, + [](TfhersFheIntDescription &desc, size_t width) { + desc.width = width; + }) + .def_property( + "message_modulus", + [](TfhersFheIntDescription &desc) { return desc.message_modulus; }, + [](TfhersFheIntDescription &desc, size_t message_modulus) { + desc.message_modulus = message_modulus; + }) + .def_property( + "carry_modulus", + [](TfhersFheIntDescription &desc) { return desc.carry_modulus; }, + [](TfhersFheIntDescription &desc, size_t carry_modulus) { + desc.carry_modulus = carry_modulus; + }) + .def_property( + "degree", [](TfhersFheIntDescription &desc) { return desc.degree; }, + [](TfhersFheIntDescription &desc, size_t degree) { + desc.degree = degree; + }) + .def_property( + "lwe_size", + [](TfhersFheIntDescription &desc) { return desc.lwe_size; }, + [](TfhersFheIntDescription &desc, size_t lwe_size) { + desc.lwe_size = lwe_size; + }) + .def_property( + "n_cts", [](TfhersFheIntDescription &desc) { return desc.n_cts; }, + [](TfhersFheIntDescription &desc, size_t n_cts) { + desc.n_cts = n_cts; + }) + .def_property( + "noise_level", + [](TfhersFheIntDescription &desc) { return desc.noise_level; }, + [](TfhersFheIntDescription &desc, size_t noise_level) { + desc.noise_level = noise_level; + }) + .def_property( + "is_signed", + [](TfhersFheIntDescription &desc) { return desc.is_signed; }, + [](TfhersFheIntDescription &desc, bool is_signed) { + desc.is_signed = is_signed; + }) + .def_property( + "ks_first", + [](TfhersFheIntDescription &desc) { return desc.ks_first; }, + [](TfhersFheIntDescription &desc, bool ks_first) { + desc.ks_first = ks_first; + }) + .def("__str__", + [](TfhersFheIntDescription &desc) { + std::ostringstream stringStream; + stringStream << "tfhers_int_description"; + return stringStream.str(); + }) + .doc() = "TFHE-rs integer description"; + m.def("import_tfhers_int", [](const pybind11::bytes &serialized_fheuint, TfhersFheIntDescription info, uint32_t encryptionKeyId, diff --git a/compilers/concrete-compiler/compiler/lib/Bindings/Python/concrete/compiler/__init__.py b/compilers/concrete-compiler/compiler/lib/Bindings/Python/concrete/compiler/__init__.py index ca8dd267e4..533dfb4804 100644 --- a/compilers/concrete-compiler/compiler/lib/Bindings/Python/concrete/compiler/__init__.py +++ b/compilers/concrete-compiler/compiler/lib/Bindings/Python/concrete/compiler/__init__.py @@ -18,6 +18,7 @@ ServerKeyset, Keyset, Compiler, + TfhersFheIntDescription, TransportValue, Value, ServerProgram, @@ -47,10 +48,7 @@ from .compilation_feedback import MoreCircuitCompilationFeedback from .compilation_context import CompilationContext -from .tfhers_int import ( - TfhersExporter, - TfhersFheIntDescription, -) +from .tfhers_int import TfhersExporter Parameter = Union[ LweSecretKeyParam, BootstrapKeyParam, KeyswitchKeyParam, PackingKeyswitchKeyParam diff --git a/compilers/concrete-compiler/compiler/lib/Bindings/Python/concrete/compiler/tfhers_int.py b/compilers/concrete-compiler/compiler/lib/Bindings/Python/concrete/compiler/tfhers_int.py index ced374b214..17b9e65139 100644 --- a/compilers/concrete-compiler/compiler/lib/Bindings/Python/concrete/compiler/tfhers_int.py +++ b/compilers/concrete-compiler/compiler/lib/Bindings/Python/concrete/compiler/tfhers_int.py @@ -7,179 +7,13 @@ from mlir._mlir_libs._concretelang._compiler import ( import_tfhers_int as _import_tfhers_int, export_tfhers_int as _export_tfhers_int, - TfhersFheIntDescription as _TfhersFheIntDescription, + TfhersFheIntDescription, TransportValue, ) -from .wrapper import WrapperCpp # pylint: enable=no-name-in-module,import-error -class TfhersFheIntDescription(WrapperCpp): - """A helper class to create `TfhersFheIntDescription`s.""" - - def __init__(self, desc: _TfhersFheIntDescription): - """ - Wrap the native C++ object. - - Args: - desc (_TfhersFheIntDescription): - object to wrap - - Raises: - TypeError: - if `desc` is not of type `_TfhersFheIntDescription` - """ - - if not isinstance(desc, _TfhersFheIntDescription): - raise TypeError( - f"desc must be of type _TfhersFheIntDescription, not {type(desc)}" - ) - - super().__init__(desc) - - @staticmethod - # pylint: disable=arguments-differ - def new( - width: int, - is_signed: bool, - message_modulus: int, - carry_modulus: int, - degree: int, - lwe_size: int, - n_cts: int, - noise_level: int, - ks_first: bool, - ) -> "TfhersFheIntDescription": - """Create a TfhersFheIntDescription. - - Args: - width (int): integer width - is_signed (bool): signed or unsigned - message_modulus (int): message modulus (not its log2) - carry_modulus (int): carry modulus (not its log2) - degree (int): degree - lwe_size (int): LWE size - n_cts (int): number of ciphertexts - noise_level (int): noise level - ks_first (bool): PBS order (keyswitch first, or bootstrap first) - - Returns: - TfhersFheIntDescription: TFHErs integer description - """ - return TfhersFheIntDescription( - _TfhersFheIntDescription( - width, - is_signed, - message_modulus, - carry_modulus, - degree, - lwe_size, - n_cts, - noise_level, - ks_first, - ) - ) - - @property - def width(self) -> int: - """Total integer bitwidth""" - return self.cpp().width - - @width.setter - def width(self, width: int): - self.cpp().width = width - - @property - def is_signed(self) -> bool: - """Is the integer signed""" - return self.cpp().is_signed - - @is_signed.setter - def is_signed(self, is_signed: bool): - self.cpp().is_signed = is_signed - - @property - def message_modulus(self) -> int: - """Modulus of the message part in each ciphertext""" - return self.cpp().message_modulus - - @message_modulus.setter - def message_modulus(self, message_modulus: int): - self.cpp().message_modulus = message_modulus - - @property - def carry_modulus(self) -> int: - """Modulus of the carry part in each ciphertext""" - return self.cpp().carry_modulus - - @carry_modulus.setter - def carry_modulus(self, carry_modulus: int): - self.cpp().carry_modulus = carry_modulus - - @property - def degree(self) -> int: - """Tracks the number of operations that have been done""" - return self.cpp().degree - - @degree.setter - def degree(self, degree: int): - self.cpp().degree = degree - - @property - def lwe_size(self) -> int: - """LWE size""" - return self.cpp().lwe_size - - @lwe_size.setter - def lwe_size(self, lwe_size: int): - self.cpp().lwe_size = lwe_size - - @property - def n_cts(self) -> int: - """Number of ciphertexts""" - return self.cpp().n_cts - - @n_cts.setter - def n_cts(self, n_cts: int): - self.cpp().n_cts = n_cts - - @property - def noise_level(self) -> int: - """Noise level""" - return self.cpp().noise_level - - @noise_level.setter - def noise_level(self, noise_level: int): - self.cpp().noise_level = noise_level - - @staticmethod - def get_unknown_noise_level() -> int: - """Get unknow noise level value. - - Returns: - int: unknown noise level value - """ - return _TfhersFheIntDescription.UNKNOWN_NOISE_LEVEL() - - @property - def ks_first(self) -> bool: - """Keyswitch placement relative to the bootsrap in a PBS""" - return self.cpp().ks_first - - @ks_first.setter - def ks_first(self, ks_first: bool): - self.cpp().ks_first = ks_first - - def __str__(self) -> str: - return ( - f"tfhers_int_description" - ) - - class TfhersExporter: """A helper class to import and export TFHErs big integers.""" @@ -203,7 +37,7 @@ def export_int(value: TransportValue, info: TfhersFheIntDescription) -> bytes: raise TypeError( f"info must be of type TfhersFheIntDescription, not {type(info)}" ) - return bytes(_export_tfhers_int(value, info.cpp())) + return bytes(_export_tfhers_int(value, info)) @staticmethod def import_int( @@ -240,4 +74,4 @@ def import_int( raise TypeError(f"variance must be of type float, not {type(variance)}") if not isinstance(shape, tuple): raise TypeError(f"shape must be of type tuple(int, ...), not {type(shape)}") - return _import_tfhers_int(buffer, info.cpp(), keyid, variance, shape) + return _import_tfhers_int(buffer, info, keyid, variance, shape) diff --git a/frontends/concrete-python/concrete/fhe/tfhers/bridge.py b/frontends/concrete-python/concrete/fhe/tfhers/bridge.py index f08416dd2b..bff25a89c8 100644 --- a/frontends/concrete-python/concrete/fhe/tfhers/bridge.py +++ b/frontends/concrete-python/concrete/fhe/tfhers/bridge.py @@ -121,7 +121,7 @@ def _description_from_type( # this should imply running a PBS on TFHErs side noise_level = TfhersFheIntDescription.get_unknown_noise_level() - return TfhersFheIntDescription.new( + return TfhersFheIntDescription( bit_width, signed, message_modulus,