Skip to content

Commit b163e60

Browse files
committed
add gtest
1 parent aae994f commit b163e60

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

paddle/fluid/operators/math/im2col_test.cc

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,93 @@ void testIm2col() {
160160
delete context;
161161
}
162162

163+
void testIm2colCPU() {
164+
paddle::framework::Tensor input;
165+
paddle::framework::Tensor output;
166+
int input_height = 3;
167+
int input_width = 4;
168+
int filter_size = 2;
169+
int ic = 2;
170+
std::vector<int> stride({1, 1}); // stride_y, stride_x
171+
std::vector<int> padding({0, 0});
172+
std::vector<int> dilation({1, 1}); // dilation_y, dilation_x
173+
int output_height =
174+
(input_height - filter_size + padding[0] * 2) / stride[0] + 1;
175+
int output_width =
176+
(input_width - filter_size + padding[1] * 2) / stride[1] + 1;
177+
float* input_ptr = input.mutable_data<float>({ic, input_height, input_width},
178+
paddle::platform::CPUPlace());
179+
for (int i = 0; i < input.numel(); ++i) {
180+
input_ptr[i] = static_cast<float>(i);
181+
}
182+
183+
paddle::platform::CPUPlace place;
184+
paddle::platform::CPUDeviceContext context(place);
185+
output.mutable_data<float>(
186+
{ic, filter_size, filter_size, output_height, output_width}, place);
187+
paddle::operators::math::Im2ColFunctor<
188+
paddle::operators::math::ColFormat::kCFO,
189+
paddle::platform::CPUDeviceContext, float>
190+
im2col;
191+
im2col(context, input, dilation, stride, padding, &output);
192+
auto ref_im2col = [&](
193+
const paddle::framework::Tensor& im, const std::vector<int>& dilation,
194+
const std::vector<int>& stride, const std::vector<int>& padding,
195+
paddle::framework::Tensor* col) {
196+
int im_channels = im.dims()[0];
197+
int im_height = im.dims()[1];
198+
int im_width = im.dims()[2];
199+
int filter_height = col->dims()[1];
200+
int filter_width = col->dims()[2];
201+
int output_height = col->dims()[3];
202+
int output_width = col->dims()[4];
203+
204+
int channels_col = im_channels * filter_height * filter_width;
205+
206+
const float* im_data = im.data<float>();
207+
float* col_data = col->data<float>();
208+
for (int c = 0; c < channels_col; ++c) {
209+
int w_offset = c % filter_width;
210+
int h_offset = (c / filter_width) % filter_height;
211+
int c_im = c / (filter_width * filter_height);
212+
for (int h = 0; h < output_height; ++h) {
213+
int im_row_idx = h * stride[0] - padding[0] + h_offset * dilation[0];
214+
for (int w = 0; w < output_width; ++w) {
215+
int im_col_idx = w * stride[1] - padding[1] + w_offset * dilation[1];
216+
int col_idx = (c * output_height + h) * output_width + w;
217+
int im_idx = (im_row_idx + c_im * im_height) * im_width + im_col_idx;
218+
219+
col_data[col_idx] = (im_row_idx < 0 || im_row_idx >= im_height ||
220+
im_col_idx < 0 || im_col_idx >= im_width)
221+
? 0.f
222+
: im_data[im_idx];
223+
}
224+
}
225+
}
226+
};
227+
228+
paddle::framework::Tensor ref_output;
229+
ref_output.mutable_data<float>(
230+
{ic, filter_size, filter_size, output_height, output_width}, place);
231+
ref_im2col(input, dilation, stride, padding, &ref_output);
232+
233+
float* out_cfo_ptr = output.data<float>();
234+
for (int i = 0; i < ic * filter_size * filter_size; ++i) {
235+
for (int j = 0; j < output_height * output_width; ++j) {
236+
std::cout << out_cfo_ptr[i * output_height * output_width + j] << ",";
237+
}
238+
std::cout << std::endl;
239+
}
240+
241+
float* out_ref_ptr = ref_output.data<float>();
242+
for (int i = 0; i < output.numel(); ++i) {
243+
EXPECT_EQ(out_cfo_ptr[i], out_ref_ptr[i]);
244+
}
245+
}
246+
163247
TEST(math, im2col) {
164248
testIm2col<paddle::platform::CPUDeviceContext, paddle::platform::CPUPlace>();
249+
testIm2colCPU();
165250
#ifdef PADDLE_WITH_CUDA
166251
testIm2col<paddle::platform::CUDADeviceContext,
167252
paddle::platform::CUDAPlace>();

0 commit comments

Comments
 (0)