Skip to content
This repository was archived by the owner on Nov 17, 2023. It is now read-only.

Commit dc3648b

Browse files
TaoLvszha
authored andcommitted
[MXNET-33] Enhance mkldnn pooling to support full convention (#11047)
* fix mkldnn pooling to support full convention * backward with full convention * fix * add pooling test for full convention * add function for computing padding size * fix unit test * only support max-pooling * fix pooling bwd * address review comment
1 parent ac57ce3 commit dc3648b

3 files changed

Lines changed: 66 additions & 21 deletions

File tree

src/operator/nn/mkldnn/mkldnn_pooling-inl.h

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,20 +113,12 @@ inline bool SupportMKLDNNPooling(const PoolingParam &param,
113113
if (!ret)
114114
return false;
115115

116-
if (param.pooling_convention == pool_enum::kValid)
116+
if (param.pooling_convention == pool_enum::kValid) {
117117
return true;
118-
else
119-
return false;
120-
121-
// need to support pooling convention full
122-
// https://issues.apache.org/jira/browse/MXNET-33
123-
#if 0
124-
if (((dshape[2] + 2 * param.pad[0] - param.kernel[0]) % param.stride[0] == 0) &&
125-
((dshape[3] + 2 * param.pad[1] - param.kernel[1]) % param.stride[1] == 0))
126-
return true;
127-
else
128-
return false;
129-
#endif
118+
} else {
119+
// currently, only max-pooling is supported for full convention
120+
return param.pool_type == pool_enum::kMaxPooling;
121+
}
130122
}
131123

132124
inline bool MKLDNNRequireWorkspace(const PoolingParam &param) {

src/operator/nn/mkldnn/mkldnn_pooling.cc

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,14 @@ mkldnn::algorithm GetMKLDNNPoolAlgo(const PoolingParam &param) {
134134
}
135135
}
136136

137+
static inline int GetPaddingSizeFull(int x, int padl, int padr, int k, int s) {
138+
if ((x + padl + padr - k) % s != 0) {
139+
return (padr + s - ((x + padl + padr - k) % s));
140+
} else {
141+
return padr;
142+
}
143+
}
144+
137145
mkldnn::pooling_forward::primitive_desc GetPoolingFwdPdesc(
138146
const PoolingParam &param, const bool is_train, const memory::desc &data_md,
139147
const memory::desc &out_md) {
@@ -154,11 +162,17 @@ mkldnn::pooling_forward::primitive_desc GetPoolingFwdPdesc(
154162
int pad_l_ = param.pad[1], pad_r_ = param.pad[1];
155163
int stride_h_ = param.stride[0], stride_w_ = param.stride[1];
156164

165+
if (param.pooling_convention == pool_enum::kFull) {
166+
pad_b_ = GetPaddingSizeFull(data_md.data.dims[2], pad_t_, pad_b_, kernel_h_, stride_h_);
167+
pad_r_ = GetPaddingSizeFull(data_md.data.dims[3], pad_l_, pad_r_, kernel_w_, stride_w_);
168+
}
169+
157170
const mkldnn::engine engine = CpuEngine::Get()->get_engine();
158171
if (param.global_pool) {
159172
pad_t_ = pad_b_ = pad_l_ = pad_r_ = 0;
160173
stride_h_ = stride_w_ = 1;
161174
}
175+
162176
if (pad_t_ != 0 || pad_l_ != 0) {
163177
CHECK(param.pool_type == pool_enum::kAvgPooling ||
164178
param.pool_type == pool_enum::kMaxPooling)
@@ -167,7 +181,6 @@ mkldnn::pooling_forward::primitive_desc GetPoolingFwdPdesc(
167181
CHECK_LT(pad_t_, kernel_h_);
168182
}
169183

170-
171184
const mkldnn::algorithm alg = GetMKLDNNPoolAlgo(param);
172185
mkldnn::prop_kind kind = mkldnn::prop_kind::forward_scoring;
173186
if (is_train && alg != algorithm::pooling_avg) {
@@ -227,17 +240,22 @@ MKLDNNPoolingFwd &GetPoolingFwd(const PoolingParam &param,
227240
int pad_l_ = param.pad[1], pad_r_ = param.pad[1];
228241
int stride_h_ = param.stride[0], stride_w_ = param.stride[1];
229242

243+
if (param.pooling_convention == pool_enum::kFull) {
244+
pad_b_ = GetPaddingSizeFull(data_md.data.dims[2], pad_t_, pad_b_, kernel_h_, stride_h_);
245+
pad_r_ = GetPaddingSizeFull(data_md.data.dims[3], pad_l_, pad_r_, kernel_w_, stride_w_);
246+
}
247+
230248
if (param.global_pool) {
231-
pad_t_ = pad_b_ = pad_l_ = pad_r_ = 0;
232-
stride_h_ = stride_w_ = 1;
249+
pad_t_ = pad_b_ = pad_l_ = pad_r_ = 0;
250+
stride_h_ = stride_w_ = 1;
233251
}
234252

235253
if (pad_t_ != 0 || pad_l_ != 0) {
236-
CHECK(param.pool_type == pool_enum::kAvgPooling ||
237-
param.pool_type == pool_enum::kMaxPooling)
238-
<< "Padding implemented only for average and max pooling.";
239-
CHECK_LT(pad_l_, kernel_w_);
240-
CHECK_LT(pad_t_, kernel_h_);
254+
CHECK(param.pool_type == pool_enum::kAvgPooling ||
255+
param.pool_type == pool_enum::kMaxPooling)
256+
<< "Padding implemented only for average and max pooling.";
257+
CHECK_LT(pad_l_, kernel_w_);
258+
CHECK_LT(pad_t_, kernel_h_);
241259
}
242260

243261
const mkldnn::algorithm alg = GetMKLDNNPoolAlgo(param);
@@ -353,6 +371,12 @@ MKLDNNPoolingBwd &GetPoolingBwd(const PoolingParam &param,
353371
int pad_t_ = param.pad[0], pad_b_ = param.pad[0];
354372
int pad_l_ = param.pad[1], pad_r_ = param.pad[1];
355373
int stride_h_ = param.stride[0], stride_w_ = param.stride[1];
374+
375+
if (param.pooling_convention == pool_enum::kFull) {
376+
pad_b_ = GetPaddingSizeFull(data_md.data.dims[2], pad_t_, pad_b_, kernel_h_, stride_h_);
377+
pad_r_ = GetPaddingSizeFull(data_md.data.dims[3], pad_l_, pad_r_, kernel_w_, stride_w_);
378+
}
379+
356380
if (param.global_pool) {
357381
pad_t_ = pad_b_ = pad_l_ = pad_r_ = 0;
358382
stride_h_ = stride_w_ = 1;

tests/python/gpu/test_operator_gpu.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,35 @@ def test_3d_pooling(pool_type, p_value=2, count_include_pad=True):
996996
test_3d_pooling('lp', p_value=3)
997997

998998

999+
@with_seed()
1000+
def test_pooling_full_2d():
1001+
def test_pooling_full_2d_type(pool_type):
1002+
data = (2, 2, 10, 10)
1003+
kernel = (4, 5)
1004+
pad = (1, 2)
1005+
stride = (3, 4)
1006+
1007+
convention = 'full'
1008+
ctx_list = []
1009+
sym_list = []
1010+
1011+
# o_h = ceil((10 + 1 + 1 - 4) / 3) + 1 = 4
1012+
# o_w = ceil((10 + 2 + 2 - 5) / 4) + 1 = 4
1013+
ctx_list.append({'ctx': mx.cpu(0), 'pool_data': data, 'type_dict': {'pool_data': np.float32}})
1014+
sym_list.append(mx.sym.Pooling(kernel=kernel, pad=pad, stride=stride, pool_type=pool_type,
1015+
pooling_convention=convention, global_pool=False, name='pool'))
1016+
1017+
ctx_list.append({'ctx': mx.gpu(0), 'pool_data': data, 'type_dict': {'pool_data': np.float32}})
1018+
sym_list.append(mx.sym.Pooling(kernel=kernel, pad=pad, stride=stride, pool_type=pool_type,
1019+
pooling_convention=convention, global_pool=False, name='pool'))
1020+
1021+
check_consistency(sym_list, ctx_list)
1022+
1023+
test_pooling_full_2d_type('max')
1024+
test_pooling_full_2d_type('avg')
1025+
test_pooling_full_2d_type('sum')
1026+
1027+
9991028
@with_seed()
10001029
def test_global_pooling():
10011030
def test_1d_pooling(pool_type, p_value=2):

0 commit comments

Comments
 (0)