fix(frontend-python): raise proper error on encrypted multiplication on large bit-widths

This commit is contained in:
Umut
2023-05-09 14:10:08 +02:00
parent 0f726882c9
commit 03c5667600
2 changed files with 50 additions and 3 deletions

View File

@@ -1393,12 +1393,38 @@ class Context:
def mul(self, resulting_type: ConversionType, x: Conversion, y: Conversion) -> Conversion:
if x.is_clear and y.is_clear:
highlights = {
x.origin: "lhs is clear",
y.origin: "rhs is clear" if x.origin is not y.origin else "operand is clear",
self.converting: "but clear-clear multiplications are not supported",
x.origin: ["lhs is clear"],
y.origin: ["rhs is clear" if x.origin is not y.origin else "operand is clear"],
self.converting: ["but clear-clear multiplications are not supported"],
}
self.error(highlights)
if (x.is_encrypted and y.is_encrypted) and (
x.bit_width > MAXIMUM_TLU_BIT_WIDTH or y.bit_width > MAXIMUM_TLU_BIT_WIDTH
):
highlights = {
self.converting: [
f"but only up to {MAXIMUM_TLU_BIT_WIDTH}-bit "
f"encrypted multiplications are supported"
],
}
for operand in [x, y]:
if operand.bit_width > MAXIMUM_TLU_BIT_WIDTH:
highlights[operand.origin] = [
f"this {operand.bit_width}-bit value "
f"is used as an operand to an encrypted multiplication"
]
if operand.bit_width != operand.original_bit_width:
highlights[operand.origin].append(
"("
f"note that it's assigned {operand.bit_width}-bits "
f"during compilation because of its relation with other operations"
")"
)
self.error(highlights)
assert self.is_bit_width_compatible(resulting_type, x, y)
use_linalg = x.is_tensor or y.is_tensor

View File

@@ -637,6 +637,27 @@ Function you are trying to compile cannot be compiled
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this 5-bit value is used as the shift amount of a shift operation
%2 = left_shift(%0, %1) # EncryptedScalar<uint37> ∈ [104857600000, 104857600000]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ but only up to 4-bit shift operations on up to 16-bit operands are supported
return %2
""", # noqa: E501
),
pytest.param(
lambda x, y: x * y,
{"x": "encrypted", "y": "encrypted"},
[(100_000, 20)],
RuntimeError,
"""
Function you are trying to compile cannot be compiled
%0 = x # EncryptedScalar<uint17> ∈ [100000, 100000]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this 22-bit value is used as an operand to an encrypted multiplication
(note that it's assigned 22-bits during compilation because of its relation with other operations)
%1 = y # EncryptedScalar<uint5> ∈ [20, 20]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this 22-bit value is used as an operand to an encrypted multiplication
(note that it's assigned 22-bits during compilation because of its relation with other operations)
%2 = multiply(%0, %1) # EncryptedScalar<uint21> ∈ [2000000, 2000000]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ but only up to 16-bit encrypted multiplications are supported
return %2
""", # noqa: E501