diff --git a/include/layers/conv2d.cuh b/include/layers/conv2d.cuh index e30321e..3ec73ca 100644 --- a/include/layers/conv2d.cuh +++ b/include/layers/conv2d.cuh @@ -25,6 +25,9 @@ class Conv2d { int outputSize; void forward(const float* d_input, float* d_output); + void setKernels(const std::vector& kernels_input); + + void host_conv(const float* input, float* output); private: // Inputs @@ -49,10 +52,6 @@ class Conv2d { void initializeKernels(); void toCuda(); - - void setKernels(const std::vector& kernels_input); - - void host_conv(const float* input, float* output); }; } // namespace Layers diff --git a/src/layers/conv2d.cu b/src/layers/conv2d.cu index c31bc4a..8277c20 100644 --- a/src/layers/conv2d.cu +++ b/src/layers/conv2d.cu @@ -1,4 +1,5 @@ #include +#include #include "activations.cuh" #include "conv2d.cuh" @@ -100,21 +101,25 @@ void Layers::Conv2d::host_conv(const float* input, float* output) { float sum = 0.0f; + // std::cout << "f: " << f << ", i: " << i << ", j: " << j << std::endl; + // Iterate over kernel and input matrix for (int k = 0; k < kernelSize; k++) { for (int l = 0; l < kernelSize; l++) { for (int c = 0; c < inputChannels; c++) { - - // For now stride = 1 int kernelIndex = k * (kernelSize * inputChannels * numFilters) + l * (inputChannels * numFilters) + c * (numFilters) + f; - int inputIndex = (i * stride + k) * (inputSize * inputChannels) + (j + stride + l) * (inputChannels) + c; + int inputIndex = (i * stride + k) * (inputSize * inputChannels) + (j * stride + l) * (inputChannels) + c; + + // std::cout << "kernelIndex: " << kernelIndex << ", kernel value: " << kernels[kernelIndex] << ", inputIndex: " << inputIndex << ", input value: " << input[inputIndex] << std::endl; sum += kernels[kernelIndex] * input[inputIndex]; } } } + // std::cout << "sum: " << sum << std::endl; + output[i * (outputSize * numFilters) + j * (numFilters) + f] = sum; } } diff --git a/test/layers/test_conv2d.cu b/test/layers/test_conv2d.cu index 9e620d2..e4b675a 100644 --- a/test/layers/test_conv2d.cu +++ b/test/layers/test_conv2d.cu @@ -5,11 +5,11 @@ #include "conv2d.cuh" -TEST(Conv2dTest, ValidPadding) { +TEST(Conv2dTest, SimpleExample) { - int inputSize = 3; + int inputSize = 4; int inputChannels = 1; - int kernelSize = 3; + int kernelSize = 2; int stride = 1; std::string padding = "VALID"; int numFilters = 1; @@ -28,8 +28,31 @@ TEST(Conv2dTest, ValidPadding) { int outputSize = (inputSize - kernelSize) / stride + 1; EXPECT_EQ(outputSize, conv2d.outputSize); - std::vector input(inputSize * inputSize * inputChannels); + std::vector input = { + 1.0f, 2.0f, 3.0f, 4.0f, + 5.0f, 6.0f, 7.0f, 8.0f, + 9.0f, 10.0f, 11.0f, 12.0f, + 13.0f, 14.0f, 15.0f, 16.0f + }; + std::vector kernels = { + 1.0f, 2.0f, 3.0f, 4.0f, + }; + + conv2d.setKernels(kernels); + + std::vector output(outputSize * outputSize * numFilters); - std::vector kernels(kernelSize * kernelSize * inputChannels * numFilters); + + conv2d.host_conv(input.data(), output.data()); + + std::vector expected = { + 44.0f, 54.0f, 64.0f, + 84.0f, 94.0f, 104.0f, + 124.0f, 134.0f, 144.0f + }; + + for (int i = 0; i < output.size(); ++i) { + EXPECT_FLOAT_EQ(expected[i], output[i]); + } }