45 if(indices !=
nullptr)
50 const int idx_channel = 0;
53 const int idx_depth = 3;
54 const int idx_batch = 4;
60 const int pool_stride_width =
static_cast<int>(pool3d_info.
stride.
width);
61 const int pool_stride_height =
static_cast<int>(pool3d_info.
stride.
height);
62 const int pool_stride_depth =
static_cast<int>(pool3d_info.
stride.
depth);
64 const int pad_left =
static_cast<int>(pool3d_info.
padding.
left);
65 const int pad_top =
static_cast<int>(pool3d_info.
padding.
top);
66 const int pad_front =
static_cast<int>(pool3d_info.
padding.
front);
68 const int pad_right =
static_cast<int>(pool3d_info.
padding.
right);
69 const int pad_bottom =
static_cast<int>(pool3d_info.
padding.
bottom);
70 const int pad_back =
static_cast<int>(pool3d_info.
padding.
back);
72 const int num_channels =
static_cast<int>(
src.shape()[idx_channel]);
73 const int num_batches =
static_cast<int>(
src.shape()[idx_batch]);
78 const int w_src =
static_cast<int>(
src.shape()[
idx_width]);
80 const int d_src =
static_cast<int>(
src.shape()[idx_depth]);
81 const int w_dst =
static_cast<int>(
dst.shape()[
idx_width]);
83 const int d_dst =
static_cast<int>(
dst.shape()[idx_depth]);
87 const int height_stride_src = num_channels * w_src;
88 const int depth_stride_src = height_stride_src * h_src;
89 const int batch_stride_src = depth_stride_src * d_src;
90 const int height_stride_dst = num_channels * w_dst;
91 const int depth_stride_dst = height_stride_dst * h_dst;
92 const int batch_stride_dst = depth_stride_dst * d_dst;
94 for(
int b = 0;
b < num_batches; ++
b)
96 const int batch_offset_dst =
b * batch_stride_dst;
97 const int batch_offset_src =
b * batch_stride_src;
98 for(
int c = 0; c < num_channels; ++c)
100 for(
int d = 0; d < d_dst; ++d)
102 const int depth_offset_dst = d * depth_stride_dst;
103 for(
int h = 0; h < h_dst; ++h)
105 const int height_offset_dst = h * height_stride_dst;
106 for(
int w = 0;
w < w_dst; ++
w)
108 int wstart =
w * pool_stride_width - pad_left;
109 int hstart = h * pool_stride_height - pad_top;
110 int dstart = d * pool_stride_depth - pad_front;
111 int wend = std::min(wstart + pool_size_width, w_src + pad_right);
112 int hend = std::min(hstart + pool_size_height, h_src + pad_bottom);
113 int dend = std::min(dstart + pool_size_depth, d_src + pad_back);
117 int pool_size = (dend - dstart) * (hend - hstart) * (wend - wstart);
120 wstart = std::max(wstart, 0);
121 hstart = std::max(hstart, 0);
122 dstart = std::max(dstart, 0);
123 wend = std::min(wend, w_src);
124 hend = std::min(hend, h_src);
125 dend = std::min(dend, d_src);
127 auto max_val = -std::numeric_limits<T>::infinity();
129 T avg_val =
static_cast<T
>(0.f);
130 T l2_val =
static_cast<T
>(0.f);
134 pool_size = (dend - dstart) * (hend - hstart) * (wend - wstart);
137 for(
int z = dstart; z < dend; ++z)
139 const int depth_offset_src = z * depth_stride_src;
140 for(
int y = hstart; y < hend; ++y)
142 const int height_offset_src = y * height_stride_src;
143 for(
int x = wstart; x < wend; ++x)
145 const auto val =
static_cast<T
>(
146 src[batch_offset_src + depth_offset_src + height_offset_src + x * num_channels + c]);
159 avg_val /= pool_size;
160 l2_val =
static_cast<T
>(std::sqrt(l2_val / pool_size));
162 int dst_index = batch_offset_dst + depth_offset_dst + height_offset_dst +
w * num_channels + c;
166 dst[dst_index] =
static_cast<T
>(max_val);
169 dst[dst_index] =
static_cast<T
>(avg_val);
172 dst[dst_index] =
static_cast<T
>(l2_val);
178 if(indices !=
nullptr)
180 (*indices)[dst_index] = max_index;
194 template <
typename T>
198 return pooling_3d_layer_internal<T>(
src, pool3d_info, indices);
205 SimpleTensor<float> dst_tmp = pooling_3d_layer_internal<float>(src_tmp, pool3d_info, indices);
206 return convert_to_asymmetric<int8_t>(dst_tmp, output_qinfo);
213 SimpleTensor<float> dst_tmp = pooling_3d_layer_internal<float>(src_tmp, pool3d_info, indices);
214 return convert_to_asymmetric<uint8_t>(dst_tmp, output_qinfo);