From b163e601b6a4886523fb869b2055eb07be0799b9 Mon Sep 17 00:00:00 2001 From: tensor-tang Date: Tue, 24 Jul 2018 17:38:40 +0800 Subject: [PATCH] add gtest --- paddle/fluid/operators/math/im2col_test.cc | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/paddle/fluid/operators/math/im2col_test.cc b/paddle/fluid/operators/math/im2col_test.cc index 8e3f0f28682..87bfc1e95a2 100644 --- a/paddle/fluid/operators/math/im2col_test.cc +++ b/paddle/fluid/operators/math/im2col_test.cc @@ -160,8 +160,93 @@ void testIm2col() { delete context; } +void testIm2colCPU() { + paddle::framework::Tensor input; + paddle::framework::Tensor output; + int input_height = 3; + int input_width = 4; + int filter_size = 2; + int ic = 2; + std::vector stride({1, 1}); // stride_y, stride_x + std::vector padding({0, 0}); + std::vector dilation({1, 1}); // dilation_y, dilation_x + int output_height = + (input_height - filter_size + padding[0] * 2) / stride[0] + 1; + int output_width = + (input_width - filter_size + padding[1] * 2) / stride[1] + 1; + float* input_ptr = input.mutable_data({ic, input_height, input_width}, + paddle::platform::CPUPlace()); + for (int i = 0; i < input.numel(); ++i) { + input_ptr[i] = static_cast(i); + } + + paddle::platform::CPUPlace place; + paddle::platform::CPUDeviceContext context(place); + output.mutable_data( + {ic, filter_size, filter_size, output_height, output_width}, place); + paddle::operators::math::Im2ColFunctor< + paddle::operators::math::ColFormat::kCFO, + paddle::platform::CPUDeviceContext, float> + im2col; + im2col(context, input, dilation, stride, padding, &output); + auto ref_im2col = [&]( + const paddle::framework::Tensor& im, const std::vector& dilation, + const std::vector& stride, const std::vector& padding, + paddle::framework::Tensor* col) { + int im_channels = im.dims()[0]; + int im_height = im.dims()[1]; + int im_width = im.dims()[2]; + int filter_height = col->dims()[1]; + int filter_width = col->dims()[2]; + int output_height = col->dims()[3]; + int output_width = col->dims()[4]; + + int channels_col = im_channels * filter_height * filter_width; + + const float* im_data = im.data(); + float* col_data = col->data(); + for (int c = 0; c < channels_col; ++c) { + int w_offset = c % filter_width; + int h_offset = (c / filter_width) % filter_height; + int c_im = c / (filter_width * filter_height); + for (int h = 0; h < output_height; ++h) { + int im_row_idx = h * stride[0] - padding[0] + h_offset * dilation[0]; + for (int w = 0; w < output_width; ++w) { + int im_col_idx = w * stride[1] - padding[1] + w_offset * dilation[1]; + int col_idx = (c * output_height + h) * output_width + w; + int im_idx = (im_row_idx + c_im * im_height) * im_width + im_col_idx; + + col_data[col_idx] = (im_row_idx < 0 || im_row_idx >= im_height || + im_col_idx < 0 || im_col_idx >= im_width) + ? 0.f + : im_data[im_idx]; + } + } + } + }; + + paddle::framework::Tensor ref_output; + ref_output.mutable_data( + {ic, filter_size, filter_size, output_height, output_width}, place); + ref_im2col(input, dilation, stride, padding, &ref_output); + + float* out_cfo_ptr = output.data(); + for (int i = 0; i < ic * filter_size * filter_size; ++i) { + for (int j = 0; j < output_height * output_width; ++j) { + std::cout << out_cfo_ptr[i * output_height * output_width + j] << ","; + } + std::cout << std::endl; + } + + float* out_ref_ptr = ref_output.data(); + for (int i = 0; i < output.numel(); ++i) { + EXPECT_EQ(out_cfo_ptr[i], out_ref_ptr[i]); + } +} + TEST(math, im2col) { testIm2col(); + testIm2colCPU(); #ifdef PADDLE_WITH_CUDA testIm2col(); -- GitLab