Skip to content

Commit 09b880a

Browse files
zhanghang1989piiswrong
authored andcommitted
[MXNET-108] Adding BilinearResize2D and AdaptiveAvgPool2d operators (apache#9688)
* bilinear upsample from PYTorch * fix cpu backward * fix indent, add req * fix lint * fix lint * lint * handle req * add adaptive avg pooling operator * rename to bilinear resize * fix name * change assertion * rm unused var * refactor using mshadow tensor * rm devicetensor, only using mshadow * add docs * naming * merge * Revert "merge" This reverts commit a2a809a. * add unit test for BilinearResize2D and AdaptiveAvgPool2D * for test in python2, cast into float * mv function inside * link docs * address the comments * lint * add back private () * correct lint * decleare var * link params docs * fix bug * mv to contrib and upodate docs * contrib header * change include path for contrib * lint * register to contrib * lint * rename width, height, docs * rename param * Patch1 (#1) * two shapes input * docs * typo * lint * lint
1 parent cfaca3d commit 09b880a

File tree

9 files changed

+1339
-0
lines changed

9 files changed

+1339
-0
lines changed

docs/api/python/ndarray/contrib.md

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ In the rest of this document, we list routines provided by the `ndarray.contrib`
3434
.. autosummary::
3535
:nosignatures:
3636
37+
AdaptiveAvgPooling2D
38+
BilinearResize2D
3739
CTCLoss
3840
DeformableConvolution
3941
DeformablePSROIPooling

docs/api/python/symbol/contrib.md

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ In the rest of this document, we list routines provided by the `symbol.contrib`
3434
.. autosummary::
3535
:nosignatures:
3636
37+
AdaptiveAvgPooling2D
38+
BilinearResize2D
3739
CTCLoss
3840
DeformableConvolution
3941
DeformablePSROIPooling
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
/*!
20+
* Copyright (c) 2018 by Contributors
21+
* \file adaptive_avg_pooling-inl.h
22+
* \brief adaptive average pooling operator
23+
* \author Hang Zhang
24+
*/
25+
#ifndef MXNET_OPERATOR_CONTRIB_ADAPTIVE_AVG_POOLING_INL_H_
26+
#define MXNET_OPERATOR_CONTRIB_ADAPTIVE_AVG_POOLING_INL_H_
27+
28+
#include <dmlc/logging.h>
29+
#include <dmlc/parameter.h>
30+
#include <mxnet/operator.h>
31+
#include <mxnet/ndarray.h>
32+
#include <map>
33+
#include <vector>
34+
#include <string>
35+
#include <utility>
36+
/* contrib
37+
#include "../ndarray/ndarray_function.h"
38+
#include "./operator_common.h"
39+
#include "./mxnet_op.h"
40+
#include "./mshadow_op.h"
41+
*/
42+
#include "../../ndarray/ndarray_function.h"
43+
#include "../operator_common.h"
44+
#include "../mxnet_op.h"
45+
#include "../mshadow_op.h"
46+
47+
namespace mxnet {
48+
namespace op {
49+
50+
struct AdaptiveAvgPoolParam : public dmlc::Parameter<AdaptiveAvgPoolParam> {
51+
TShape output_size;
52+
DMLC_DECLARE_PARAMETER(AdaptiveAvgPoolParam) {
53+
DMLC_DECLARE_FIELD(output_size).set_default(TShape())
54+
.describe("int (output size) or a tuple of int for output (height, width).");
55+
}
56+
};
57+
58+
static inline bool IsWriting(const OpReqType ort) {
59+
return ort == kWriteTo || ort == kWriteInplace;
60+
}
61+
62+
template<typename xpu, typename DType, typename AccReal>
63+
void AdaptiveAvgPoolUpdateOutput(mshadow::Stream<cpu> *s,
64+
const std::vector<TBlob> &input,
65+
const std::vector<TBlob> &output);
66+
67+
template<typename xpu, typename DType, typename AccReal>
68+
void AdaptiveAvgPoolUpdateGradInput(mshadow::Stream<cpu> *s,
69+
const std::vector<TBlob> &input,
70+
const std::vector<TBlob> &output);
71+
72+
#if MXNET_USE_CUDA
73+
template<typename xpu, typename DType, typename AccReal>
74+
void AdaptiveAvgPoolUpdateOutput(mshadow::Stream<gpu> *s,
75+
const std::vector<TBlob> &input,
76+
const std::vector<TBlob> &output);
77+
78+
template<typename xpu, typename DType, typename AccReal>
79+
void AdaptiveAvgPoolUpdateGradInput(mshadow::Stream<gpu> *s,
80+
const std::vector<TBlob> &input,
81+
const std::vector<TBlob> &output);
82+
#endif // MXNET_USE_CUDA
83+
84+
template <typename xpu>
85+
inline void AdaptiveAvgPoolOpForward(const nnvm::NodeAttrs& attrs,
86+
const OpContext &ctx,
87+
const std::vector<TBlob> &inputs,
88+
const std::vector<OpReqType> &req,
89+
const std::vector<TBlob> &outputs) {
90+
CHECK_EQ(inputs.size(), 1U);
91+
CHECK_EQ(outputs.size(), 1U);
92+
mshadow::Stream<xpu> *s = ctx.get_stream<xpu>();
93+
MSHADOW_REAL_TYPE_SWITCH_EX(inputs[0].type_flag_, DType, AccReal, {
94+
AdaptiveAvgPoolUpdateOutput<xpu, DType, AccReal>(s, inputs, outputs);
95+
});
96+
}
97+
98+
99+
template <typename xpu>
100+
inline void AdaptiveAvgPoolOpBackward(const nnvm::NodeAttrs& attrs,
101+
const OpContext &ctx,
102+
const std::vector<TBlob> &inputs,
103+
const std::vector<OpReqType> &req,
104+
const std::vector<TBlob> &outputs) {
105+
CHECK_EQ(inputs.size(), 1U);
106+
CHECK_EQ(outputs.size(), 1U);
107+
mshadow::Stream<xpu> *s = ctx.get_stream<xpu>();
108+
if (IsWriting(req[0])) {
109+
// zero grad before backwarding
110+
MSHADOW_TYPE_SWITCH(inputs[0].type_flag_, DType, {
111+
Fill<false>(s, outputs[0], kWriteTo, 0);
112+
})
113+
}
114+
MSHADOW_REAL_TYPE_SWITCH_EX(inputs[0].type_flag_, DType, AccReal, {
115+
AdaptiveAvgPoolUpdateGradInput<xpu, DType, AccReal>(s, inputs, outputs);
116+
});
117+
}
118+
119+
120+
static bool AdaptiveAvgPoolOpInferShape(const nnvm::NodeAttrs& attrs,
121+
std::vector<TShape> *in_shape,
122+
std::vector<TShape> *out_shape) {
123+
using namespace mshadow;
124+
CHECK_EQ(in_shape->size(), 1U) << "Input:[data]";
125+
CHECK_EQ(out_shape->size(), 1U) << "Output:[data]";
126+
const AdaptiveAvgPoolParam& param = nnvm::get<AdaptiveAvgPoolParam>(attrs.parsed);
127+
TShape dshape(in_shape->at(0));
128+
if (dshape.ndim() == 0) return false;
129+
if (param.output_size.ndim() == 0) {
130+
dshape[2] = 1;
131+
dshape[3] = 1;
132+
} else if (param.output_size.ndim() == 1) {
133+
dshape[2] = param.output_size[0];
134+
dshape[3] = param.output_size[0];
135+
} else if (param.output_size.ndim() == 2) {
136+
dshape[2] = param.output_size[0];
137+
dshape[3] = param.output_size[1];
138+
} else {
139+
dshape[2] = 1;
140+
dshape[3] = 1;
141+
}
142+
out_shape->clear();
143+
out_shape->push_back(dshape);
144+
return true;
145+
}
146+
147+
static bool AdaptiveAvgPoolOpInferType(const nnvm::NodeAttrs& attrs,
148+
std::vector<int> *in_type,
149+
std::vector<int> *out_type) {
150+
using namespace mshadow;
151+
CHECK_EQ(in_type->size(), 1U);
152+
int dtype = (*in_type)[0];
153+
CHECK_NE(dtype, -1) << "First input must have specified type";
154+
// For float16 input type beta, gamma, mean, and average are stored in float32.
155+
// For other input types, these parameters have the same type as input
156+
// NOTE: This requirement is from cuDNN (v. 4 and 5)
157+
int dtype_param = 0;
158+
MSHADOW_REAL_TYPE_SWITCH_EX(dtype, DTypeX, AccRealX, {
159+
dtype_param = mshadow::DataType<AccRealX>::kFlag; });
160+
out_type->clear();
161+
out_type->push_back(dtype_param);
162+
return true;
163+
}
164+
165+
static inline bool AdaptiveAvgPoolOpStorageType(const nnvm::NodeAttrs &attrs,
166+
const int dev_mask,
167+
DispatchMode *dispatch_mode,
168+
std::vector<int> *in_attrs,
169+
std::vector<int> *out_attrs) {
170+
CHECK_EQ(in_attrs->size(), 1);
171+
CHECK_EQ(out_attrs->size(), 1);
172+
*dispatch_mode = DispatchMode::kFCompute;
173+
for (int& v : *in_attrs) {
174+
if (v == - 1) v = kDefaultStorage;
175+
}
176+
for (size_t i = 0; i < out_attrs->size(); i++) {
177+
(*out_attrs)[i] = kDefaultStorage;
178+
}
179+
return true;
180+
}
181+
182+
using namespace mshadow;
183+
template<typename xpu, int Dim, typename DType>
184+
MSHADOW_XINLINE int get_stride(Tensor<xpu, Dim, DType> tensor, int idx) {
185+
int stride = 1;
186+
for (int i = Dim-2; i >= idx; --i) {
187+
stride *= tensor.size(i+1);
188+
}
189+
return stride;
190+
}
191+
192+
} // namespace op
193+
} // namespace mxnet
194+
195+
#endif // MXNET_OPERATOR_CONTRIB_ADAPTIVE_AVG_POOLING_INL_H_

0 commit comments

Comments
 (0)