vol2col_test.cc 7.7 KB
Newer Older
1
/* Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
C
chengduoZH 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. */

15
#include "paddle/phi/kernels/funcs/vol2col.h"
W
wanghuancoder 已提交
16

C
chengduoZH 已提交
17
#include <gtest/gtest.h>
18

19
#include "paddle/fluid/framework/tensor_util.h"
W
Wilber 已提交
20 21
#include "paddle/fluid/platform/device_context.h"
#include "paddle/fluid/platform/place.h"
C
chengduoZH 已提交
22

Q
QI JUN 已提交
23
template <typename DeviceContext, typename Place>
C
chengduoZH 已提交
24
void testVol2col() {
25 26 27 28
  phi::DenseTensor input;
  phi::DenseTensor input_tmp;
  phi::DenseTensor output;
  phi::DenseTensor output_tmp;
C
chengduoZH 已提交
29 30

  auto* place = new Place();
Q
QI JUN 已提交
31
  DeviceContext* context = new DeviceContext(*place);
C
chengduoZH 已提交
32 33 34 35 36 37
  /**
   * input = [[0, 1, 2,
   *          3, 4, 5]
   *          [6, 7, 8,
   *          9, 10, 11]]
   *
C
chengduoZH 已提交
38 39 40 41 42 43 44 45
   * output = [0, 1
   *           1, 2
   *           3, 4
   *           4, 5
   *           6, 7
   *           7, 8
   *           9, 10
   *           10, 11]
C
chengduoZH 已提交
46 47 48 49 50 51 52 53 54 55 56
   *
   * col2vol = [[0, 2, 2,
   *             3, 8, 5]
   *            [6, 14, 8,
   *             9, 20, 11]]
   *
   */
  int input_depth = 2;
  int input_height = 2;
  int input_width = 3;
  int filter_size = 2;
C
chengduoZH 已提交
57 58 59 60 61 62 63 64 65
  std::vector<int> strides({1, 1, 1});
  std::vector<int> paddings({0, 0, 0});
  std::vector<int> dilations({1, 1, 1});
  int output_depth =
      (input_depth - filter_size + 2 * paddings[0]) / strides[0] + 1;
  int output_height =
      (input_height - filter_size + 2 * paddings[1]) / strides[1] + 1;
  int output_width =
      (input_width - filter_size + 2 * paddings[2]) / strides[2] + 1;
C
chengduoZH 已提交
66 67 68 69 70 71 72 73 74 75 76

  // Vol2Col test
  float* input_ptr =
      input_tmp.mutable_data<float>({1, input_depth, input_height, input_width},
                                    paddle::platform::CPUPlace());
  float arr[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
  memcpy(input_ptr, arr, 12 * sizeof(float));

  if (paddle::platform::is_cpu_place(*place)) {
    input = input_tmp;
  } else {
F
fengjiayi 已提交
77
    paddle::framework::TensorCopySync(input_tmp, *place, &input);
C
chengduoZH 已提交
78
  }
79 80 81 82 83 84 85
  output.mutable_data<float>({1,
                              filter_size,
                              filter_size,
                              filter_size,
                              output_depth,
                              output_height,
                              output_width},
C
chengduoZH 已提交
86
                             *place);
C
chengduoZH 已提交
87

88
  phi::funcs::Vol2ColFunctor<DeviceContext, float> vol2col;
C
chengduoZH 已提交
89
  vol2col(*context, input, dilations, strides, paddings, &output);
C
chengduoZH 已提交
90

C
chengduoZH 已提交
91
  float vol_2_col[] = {0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11};
C
chengduoZH 已提交
92 93
  float* out_cfo_ptr;
  if (paddle::platform::is_cpu_place(*place)) {
C
chengduoZH 已提交
94
    out_cfo_ptr = output.data<float>();
C
chengduoZH 已提交
95
  } else {
96 97
    paddle::framework::TensorCopySync(
        output, paddle::platform::CPUPlace(), &output_tmp);
C
chengduoZH 已提交
98 99 100
    out_cfo_ptr = output_tmp.data<float>();
  }

C
chengduoZH 已提交
101 102 103
  for (int i = 0; i < 16; ++i) {
    EXPECT_EQ(out_cfo_ptr[i], vol_2_col[i]);
  }
C
chengduoZH 已提交
104 105

  // Col2Vol test
C
chengduoZH 已提交
106
  float col_2_vol[] = {0, 2, 2, 3, 8, 5, 6, 14, 8, 9, 20, 11};
C
chengduoZH 已提交
107 108 109 110
  memset(input_ptr, 0, 12 * sizeof(float));
  if (paddle::platform::is_cpu_place(*place)) {
    input = input_tmp;
  } else {
111
    paddle::framework::TensorCopySync(input_tmp, *place, &input);
C
chengduoZH 已提交
112 113
  }

114
  phi::funcs::Col2VolFunctor<DeviceContext, float> col2vol;
C
chengduoZH 已提交
115
  col2vol(*context, output, dilations, strides, paddings, &input);
C
chengduoZH 已提交
116

C
chengduoZH 已提交
117
  float* in_ptr;
C
chengduoZH 已提交
118
  if (paddle::platform::is_cpu_place(*place)) {
C
chengduoZH 已提交
119
    in_ptr = input.data<float>();
C
chengduoZH 已提交
120
  } else {
121 122
    paddle::framework::TensorCopySync(
        input, paddle::platform::CPUPlace(), &input_tmp);
C
chengduoZH 已提交
123
    in_ptr = input_tmp.data<float>();
C
chengduoZH 已提交
124 125
  }

C
chengduoZH 已提交
126
  for (int i = 0; i < 12; ++i) {
C
chengduoZH 已提交
127
    EXPECT_EQ(in_ptr[i], col_2_vol[i]);
C
chengduoZH 已提交
128
  }
129 130 131

  delete place;
  delete context;
C
chengduoZH 已提交
132 133
}

W
Wilber 已提交
134 135
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
template <>
L
Leo Chen 已提交
136
void testVol2col<phi::GPUContext, paddle::platform::CUDAPlace>() {
137 138 139 140
  phi::DenseTensor input;
  phi::DenseTensor input_tmp;
  phi::DenseTensor output;
  phi::DenseTensor output_tmp;
W
Wilber 已提交
141 142

  auto* place = new paddle::platform::CUDAPlace();
L
Leo Chen 已提交
143
  auto* context = new phi::GPUContext(*place);
W
Wilber 已提交
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
  context->SetAllocator(paddle::memory::allocation::AllocatorFacade::Instance()
                            .GetAllocator(*place, context->stream())
                            .get());
  context->PartialInitWithAllocator();

  /**
   * input = [[0, 1, 2,
   *          3, 4, 5]
   *          [6, 7, 8,
   *          9, 10, 11]]
   *
   * output = [0, 1
   *           1, 2
   *           3, 4
   *           4, 5
   *           6, 7
   *           7, 8
   *           9, 10
   *           10, 11]
   *
   * col2vol = [[0, 2, 2,
   *             3, 8, 5]
   *            [6, 14, 8,
   *             9, 20, 11]]
   *
   */
  int input_depth = 2;
  int input_height = 2;
  int input_width = 3;
  int filter_size = 2;
  std::vector<int> strides({1, 1, 1});
  std::vector<int> paddings({0, 0, 0});
  std::vector<int> dilations({1, 1, 1});
  int output_depth =
      (input_depth - filter_size + 2 * paddings[0]) / strides[0] + 1;
  int output_height =
      (input_height - filter_size + 2 * paddings[1]) / strides[1] + 1;
  int output_width =
      (input_width - filter_size + 2 * paddings[2]) / strides[2] + 1;

  // Vol2Col test
  float* input_ptr =
      input_tmp.mutable_data<float>({1, input_depth, input_height, input_width},
                                    paddle::platform::CPUPlace());
  float arr[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
  memcpy(input_ptr, arr, 12 * sizeof(float));

  if (paddle::platform::is_cpu_place(*place)) {
    input = input_tmp;
  } else {
    paddle::framework::TensorCopySync(input_tmp, *place, &input);
  }
196 197 198 199 200 201 202
  output.mutable_data<float>({1,
                              filter_size,
                              filter_size,
                              filter_size,
                              output_depth,
                              output_height,
                              output_width},
W
Wilber 已提交
203 204
                             *place);

205
  phi::funcs::Vol2ColFunctor<phi::GPUContext, float> vol2col;
W
Wilber 已提交
206 207 208 209 210 211 212
  vol2col(*context, input, dilations, strides, paddings, &output);

  float vol_2_col[] = {0, 1, 1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 10, 11};
  float* out_cfo_ptr;
  if (paddle::platform::is_cpu_place(*place)) {
    out_cfo_ptr = output.data<float>();
  } else {
213 214
    paddle::framework::TensorCopySync(
        output, paddle::platform::CPUPlace(), &output_tmp);
W
Wilber 已提交
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
    out_cfo_ptr = output_tmp.data<float>();
  }

  for (int i = 0; i < 16; ++i) {
    EXPECT_EQ(out_cfo_ptr[i], vol_2_col[i]);
  }

  // Col2Vol test
  float col_2_vol[] = {0, 2, 2, 3, 8, 5, 6, 14, 8, 9, 20, 11};
  memset(input_ptr, 0, 12 * sizeof(float));
  if (paddle::platform::is_cpu_place(*place)) {
    input = input_tmp;
  } else {
    paddle::framework::TensorCopySync(input_tmp, *place, &input);
  }

231
  phi::funcs::Col2VolFunctor<phi::GPUContext, float> col2vol;
W
Wilber 已提交
232 233 234 235 236 237
  col2vol(*context, output, dilations, strides, paddings, &input);

  float* in_ptr;
  if (paddle::platform::is_cpu_place(*place)) {
    in_ptr = input.data<float>();
  } else {
238 239
    paddle::framework::TensorCopySync(
        input, paddle::platform::CPUPlace(), &input_tmp);
W
Wilber 已提交
240 241 242 243 244 245 246 247 248 249 250 251
    in_ptr = input_tmp.data<float>();
  }

  for (int i = 0; i < 12; ++i) {
    EXPECT_EQ(in_ptr[i], col_2_vol[i]);
  }

  delete place;
  delete context;
}
#endif

C
chengduoZH 已提交
252
TEST(math, vol2col) {
L
Leo Chen 已提交
253
  testVol2col<phi::CPUContext, paddle::platform::CPUPlace>();
254
#if defined(PADDLE_WITH_CUDA) || defined(PADDLE_WITH_HIP)
L
Leo Chen 已提交
255
  testVol2col<phi::GPUContext, paddle::platform::CUDAPlace>();
C
chengduoZH 已提交
256
#endif  // PADDLE_WITH_CUDA
C
chengduoZH 已提交
257
}