Files
concrete/tests/execution/test_convolution.py
2022-04-08 12:09:44 +03:00

207 lines
4.8 KiB
Python

"""
Tests of execution of convolution operation.
"""
import numpy as np
import pytest
import concrete.numpy as cnp
@pytest.mark.parametrize(
"input_shape,weight_shape",
[
pytest.param(
(1, 1, 4, 4),
(1, 1, 2, 2),
),
pytest.param(
(4, 3, 4, 4),
(2, 3, 2, 2),
),
],
)
@pytest.mark.parametrize(
"strides",
[
(2, 2),
],
)
@pytest.mark.parametrize(
"dilations",
[
(1, 1),
],
)
@pytest.mark.parametrize(
"has_bias",
[
True,
False,
],
)
def test_conv2d(input_shape, weight_shape, strides, dilations, has_bias, helpers):
"""
Test conv2d.
"""
configuration = helpers.configuration()
weight = np.random.randint(0, 4, size=weight_shape)
if has_bias:
bias = np.random.randint(0, 4, size=(weight_shape[0],))
else:
bias = None
@cnp.compiler({"x": "encrypted"}, configuration=configuration)
def function(x):
return cnp.conv2d(x, weight, bias, strides=strides, dilations=dilations)
inputset = [np.random.randint(0, 4, size=input_shape) for i in range(100)]
circuit = function.compile(inputset)
sample = np.random.randint(0, 4, size=input_shape, dtype=np.uint8)
helpers.check_execution(circuit, function, sample)
@pytest.mark.parametrize(
"input_shape,weight_shape,bias_shape,pads,strides,dilations,auto_pad,"
"expected_error,expected_message",
[
pytest.param(
(1, 1, 4, 4),
(1, 1, 2, 2),
(1,),
(0, 0, 0, 0),
(1, 1),
(1, 1),
"VALID",
ValueError,
"Auto pad should be in {'NOTSET'} but it's 'VALID'",
),
pytest.param(
(1, 1, 4, 4),
(1, 1, 2, 2),
(1,),
(),
(1, 1),
(1, 1),
"NOTSET",
ValueError,
"Pads should be of form "
"(height_begin_pad, width_begin_pad, height_end_pad, width_end_pad) "
"but it's ()",
),
pytest.param(
(1, 1, 4, 4),
(1, 1, 2, 2),
(1,),
(0, 0, 0, 0),
(),
(1, 1),
"NOTSET",
ValueError,
"Strides should be of form (height_stride, width_stride) but it's ()",
),
pytest.param(
(1, 1, 4, 4),
(1, 1, 2, 2),
(1,),
(0, 0, 0, 0),
(1, 1),
(),
"NOTSET",
ValueError,
"Dilations should be of form (height_dilation, width_dilation) but it's ()",
),
pytest.param(
(),
(1, 1, 2, 2),
(1,),
(0, 0, 0, 0),
(1, 1),
(1, 1),
"NOTSET",
ValueError,
"Input should be of shape (N, C, H, W) but it's of shape ()",
),
pytest.param(
(1, 1, 4, 4),
(),
(1,),
(0, 0, 0, 0),
(1, 1),
(1, 1),
"NOTSET",
ValueError,
"Weight should be of shape (F, C, H, W) but it's of shape ()",
),
pytest.param(
(1, 1, 4, 4),
(1, 1, 2, 2),
(),
(0, 0, 0, 0),
(1, 1),
(1, 1),
"NOTSET",
ValueError,
"Bias should be of shape (F,) but it's of shape ()",
),
],
)
def test_bad_conv2d_tracing(
input_shape,
weight_shape,
bias_shape,
pads,
strides,
dilations,
auto_pad,
expected_error,
expected_message,
helpers,
):
"""
Test conv2d with bad parameters.
"""
configuration = helpers.configuration()
weight = np.random.randint(0, 4, size=weight_shape)
if bias_shape is not None:
bias = np.random.randint(0, 4, size=bias_shape)
else:
bias = None
@cnp.compiler({"x": "encrypted"}, configuration=configuration)
def function(x):
return cnp.conv2d(x, weight, bias, pads, strides, dilations, auto_pad)
inputset = [np.random.randint(0, 4, size=input_shape) for i in range(100)]
with pytest.raises(expected_error) as excinfo:
function.compile(inputset)
assert str(excinfo.value) == expected_message
def test_bad_conv2d_evaluation():
"""
Test conv2d evaluation with bad parameters.
"""
x = np.random.randint(0, 4, size=(1, 1, 4, 4))
with pytest.raises(ValueError) as excinfo:
cnp.conv2d(x, "abc")
assert str(excinfo.value) == "Weight should be of type np.ndarray for evaluation"
weight = np.random.randint(0, 4, size=(1, 1, 2, 2))
with pytest.raises(ValueError) as excinfo:
cnp.conv2d(x, weight, "abc")
assert str(excinfo.value) == "Bias should be of type np.ndarray for evaluation"