Skip to content
Snippets Groups Projects
Commit 1fc2fcd2 authored by Olivier BICHLER's avatar Olivier BICHLER
Browse files

Fixed convolution implementation with dilation

parent b170ae76
No related branches found
No related tags found
2 merge requests!710.4.0,!59Continuous improvement of export_cpp
Pipeline #79072 failed
......@@ -40,24 +40,18 @@ void convolution_forward(
const Bias_T* __restrict biases,
const Rescaling_T& __restrict rescaling)
{
constexpr int DILATED_KERNEL_HEIGHT
= KERNEL_HEIGHT + (DILATION_Y - 1) * (KERNEL_HEIGHT - 1);
constexpr int DILATED_KERNEL_WIDTH
= KERNEL_WIDTH + (DILATION_X - 1) * (KERNEL_WIDTH - 1);
constexpr int OUTPUTS_HEIGHT_NOPAD
= (CHANNELS_HEIGHT - DILATION_Y * (KERNEL_HEIGHT - 1) - 1 + STRIDE_Y) / STRIDE_Y;
constexpr int OUTPUTS_WIDTH_NOPAD
= (CHANNELS_WIDTH - DILATION_X * (KERNEL_WIDTH - 1) - 1 + STRIDE_X) / STRIDE_X;
for (int oy = 0; oy < OUTPUTS_HEIGHT; ++oy) {
const int syMin = (PADDING_Y == 0) ? 0
: max(PADDING_Y - (oy * STRIDE_Y), 0);
const int syMin = (PADDING_Y == 0) ? 0
: max((PADDING_Y - (oy * STRIDE_Y) + DILATION_Y - 1) / DILATION_Y, 0);
const int syMax = (PADDING_Y == 0
&& OUTPUTS_HEIGHT == OUTPUTS_HEIGHT_NOPAD) ? DILATED_KERNEL_HEIGHT
: clamp(CHANNELS_HEIGHT + PADDING_Y - (oy * STRIDE_Y),
0, DILATED_KERNEL_HEIGHT);
&& OUTPUTS_HEIGHT == OUTPUTS_HEIGHT_NOPAD) ? KERNEL_HEIGHT
: clamp((CHANNELS_HEIGHT + PADDING_Y - (oy * STRIDE_Y)) / DILATION_Y,
0, KERNEL_HEIGHT);
const int iy = (oy * STRIDE_Y) - PADDING_Y;
#ifdef _OPENMP
......@@ -67,12 +61,12 @@ void convolution_forward(
for (int output = 0; output < NB_OUTPUTS; ++output) {
// moved to inner loop for collapsing -->
const int sxMin = (PADDING_X == 0) ? 0
: max(PADDING_X - (ox * STRIDE_X), 0);
: max((PADDING_X - (ox * STRIDE_X) + DILATION_X - 1) / DILATION_X, 0);
const int sxMax = (PADDING_X == 0
&& OUTPUTS_WIDTH == OUTPUTS_WIDTH_NOPAD)
? DILATED_KERNEL_WIDTH
: clamp(CHANNELS_WIDTH + PADDING_X - (ox * STRIDE_X),
0, DILATED_KERNEL_WIDTH);
? KERNEL_WIDTH
: clamp((CHANNELS_WIDTH + PADDING_X - (ox * STRIDE_X)) / DILATION_X,
0, KERNEL_WIDTH);
const int ix = (ox * STRIDE_X) - PADDING_X;
const int oPos = (ox + OUTPUTS_WIDTH * oy);
......@@ -90,13 +84,13 @@ void convolution_forward(
for (int sy = 0; sy < KERNEL_HEIGHT; ++sy) {
if ((PADDING_Y != 0
|| OUTPUTS_HEIGHT != OUTPUTS_HEIGHT_NOPAD)
&& ((sy*DILATION_Y < syMin) || (sy*DILATION_Y >= syMax)))
&& sy >= syMax - syMin)
{
continue;
}
const int iPos = ((sxMin + ix)
+ CHANNELS_WIDTH * (iy + syMin + sy * DILATION_Y));
const int iPos = ((sxMin * DILATION_X + ix)
+ CHANNELS_WIDTH * (iy + (syMin + sy) * DILATION_Y));
int iOffset = (INPUT_MEM_STRIDE / sizeof(Input_T)) * iPos;
// Wrapping cannot occur in the middle of a line, except if
......@@ -133,7 +127,7 @@ void convolution_forward(
for (int sx = 0; sx < KERNEL_WIDTH; ++sx) {
if ((PADDING_X != 0
|| OUTPUTS_WIDTH != OUTPUTS_WIDTH_NOPAD)
&& ((sx*DILATION_X < sxMin) || (sx*DILATION_X >= sxMax)))
&& sx >= sxMax - sxMin)
{
continue;
}
......
......@@ -603,6 +603,22 @@ class test_operator_export(unittest.TestCase):
self.unit_test_export(model, "Conv2D", [[1, 3, 12, 12]])
def test_conv2D_asym(self):
print("Conv2D_asym")
model = aidge_core.sequential([
aidge_core.Conv2D(in_channels=3, out_channels=3, kernel_dims=(2, 5), name="conv")
])
self.unit_test_export(model, "Conv2D_asym", [[1, 3, 22, 22]])
def test_conv2D_asym2(self):
print("Conv2D_asym2")
model = aidge_core.sequential([
aidge_core.Conv2D(in_channels=3, out_channels=3, kernel_dims=(2, 5), name="conv")
])
self.unit_test_export(model, "Conv2D_asym2", [[1, 3, 59, 22]])
def test_conv1D(self):
print("Conv1D")
model = aidge_core.sequential([
......@@ -821,7 +837,38 @@ class test_operator_export(unittest.TestCase):
])
initFiller(model)
self.unit_test_export(model, "Conv", [[1, 1, 9, 9]])
def test_PaddedConv(self):
print("PaddedConv")
model = aidge_core.sequential([
aidge_core.PaddedConv2D(3, 7, kernel_dims=[7, 7], name="InputNode", stride_dims=[2, 2], padding_dims=[3, 3, 3, 3])
])
initFiller(model)
self.unit_test_export(model, "PaddedConv", [[1, 3, 19, 19]])
def test_PaddedConv_asym(self):
print("PaddedConv_asym")
model = aidge_core.sequential([
aidge_core.PaddedConv2D(3, 7, kernel_dims=[3, 7], name="InputNode", stride_dims=[2, 1], padding_dims=[3, 1, 2, 3])
])
initFiller(model)
self.unit_test_export(model, "PaddedConv_asym", [[1, 3, 19, 19]])
def test_PaddedConv_dilated(self):
print("PaddedConv_dilated")
model = aidge_core.sequential([
aidge_core.PaddedConv2D(3, 7, kernel_dims=[7, 7], name="InputNode", stride_dims=[2, 2], padding_dims=[3, 3, 3, 3], dilation_dims=[2, 2])
])
initFiller(model)
self.unit_test_export(model, "PaddedConv_dilated", [[1, 3, 19, 19]])
def test_PaddedConv_dilated_asym(self):
print("PaddedConv_dilated_asym")
model = aidge_core.sequential([
aidge_core.PaddedConv2D(3, 7, kernel_dims=[7, 5], name="InputNode", stride_dims=[1, 2], padding_dims=[1, 3, 3, 0], dilation_dims=[1, 2])
])
initFiller(model)
self.unit_test_export(model, "PaddedConv_dilated_asym", [[1, 3, 19, 19]])
def test_Conv2(self):
print("Conv2")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment