Skip to content

Commit ceee71a

Browse files
authored
Add unpool2d op & Expose max_unpool2d API (#35056)
* add maxunppol2d op, test=develop * fix typo, test=develop * fix unpool unitest, test=develop * fix unpool code-example, test=develop * fix for unpool_op_unittest,test=develop * fix example code, test=develop * add noqa:F401, test=develop * fix converage, test=develop * fix unitest for unpool, test=develop * rename unpool2d to unpool, test=develop * rename unpool2d to unpool, test=develop
1 parent 234ce93 commit ceee71a

File tree

9 files changed

+511
-123
lines changed

9 files changed

+511
-123
lines changed

paddle/fluid/operators/math/unpooling.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class Unpool2dMaxFunctor<platform::CPUDeviceContext, T> {
3838
for (int c = 0; c < output_channels; ++c) {
3939
for (int i = 0; i < input_feasize; ++i) {
4040
int index = indices_data[i];
41+
4142
PADDLE_ENFORCE_LT(
4243
index, output_feasize,
4344
platform::errors::InvalidArgument(

paddle/fluid/operators/math/unpooling.cu

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -25,48 +25,27 @@ __global__ void KernelUnpool2dMax(const int nthreads, const T* input_data,
2525
const int channels, T* output_data,
2626
const int output_height,
2727
const int output_width) {
28-
int in_n_stride = input_height * input_width * channels;
29-
int in_c_stride = input_height * input_width;
30-
int out_n_stride = output_height * output_width * channels;
31-
int out_c_stride = output_height * output_width;
32-
int index = blockIdx.x * blockDim.x + threadIdx.x;
33-
int offset = blockDim.x * gridDim.x;
34-
for (int i = index; i < nthreads; i += offset) {
35-
int bidx = i / in_n_stride;
36-
int boffset = i % in_n_stride;
37-
int cidx = boffset / in_c_stride;
38-
int out_offset = bidx * out_n_stride + cidx * out_c_stride;
39-
int out_index = indices_data[i];
40-
PADDLE_ENFORCE(out_index < out_c_stride,
41-
"out_index < out_c_stride. Expected %ld < %ld, but got "
42-
"%ld >= %ld. Please check input value.",
43-
out_index, out_c_stride, out_index, out_c_stride);
44-
output_data[out_offset + out_index] = input_data[i];
28+
CUDA_KERNEL_LOOP(linearIndex, nthreads) {
29+
int c = (linearIndex / input_width / input_height) % channels;
30+
int n = linearIndex / input_width / input_height / channels;
31+
output_data += (n * channels + c) * output_height * output_width;
32+
int maxind = indices_data[linearIndex];
33+
output_data[maxind] = input_data[linearIndex];
4534
}
4635
}
36+
4737
template <typename T>
4838
__global__ void KernelUnpool2dMaxGrad(
4939
const int nthreads, const T* input_data, const int* indices_data,
5040
const int input_height, const int input_width, const int channels,
5141
const T* output_data, const T* output_grad, const int output_height,
5242
const int output_width, T* input_grad) {
53-
int in_n_stride = input_height * input_width * channels;
54-
int in_c_stride = input_height * input_width;
55-
int out_n_stride = output_height * output_width * channels;
56-
int out_c_stride = output_height * output_width;
57-
int index = blockIdx.x * blockDim.x + threadIdx.x;
58-
int offset = blockDim.x * gridDim.x;
59-
for (int i = index; i < nthreads; i += offset) {
60-
int bidx = i / in_n_stride;
61-
int boffset = i % in_n_stride;
62-
int cidx = boffset / in_c_stride;
63-
int out_offset = bidx * out_n_stride + cidx * out_c_stride;
64-
int out_index = indices_data[i];
65-
PADDLE_ENFORCE(out_index < out_c_stride,
66-
"out_index < out_c_stride. Expected %ld < %ld, but got "
67-
"%ld >= %ld. Please check input value.",
68-
out_index, out_c_stride, out_index, out_c_stride);
69-
input_grad[i] = output_grad[out_offset + out_index];
43+
CUDA_KERNEL_LOOP(linearIndex, nthreads) {
44+
int c = (linearIndex / input_width / input_height) % channels;
45+
int n = linearIndex / input_width / input_height / channels;
46+
output_grad += (n * channels + c) * output_height * output_width;
47+
int maxind = indices_data[linearIndex];
48+
input_grad[linearIndex] = output_grad[maxind];
7049
}
7150
}
7251
/*

paddle/fluid/operators/unpool_op.cc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,16 @@ class Unpool2dOpMaker : public framework::OpProtoAndCheckerMaker {
5454
"unpooling_type",
5555
"(string), unpooling type, can be \"max\" for max-unpooling ")
5656
.InEnum({"max"});
57+
AddAttr<std::vector<int>>("output_size",
58+
"(vector, optional). The shape of output.")
59+
.SetDefault({0, 0});
60+
AddAttr<std::string>(
61+
"data_format",
62+
"(string, default NCHW) Only used in "
63+
"An optional string from: \"NHWC\", \"NCHW\". "
64+
"Defaults to \"NHWC\". Specify the data format of the output data, "
65+
"the input will be transformed automatically. ")
66+
.SetDefault("NCHW");
5767
AddComment(R"DOC(
5868
Input shape is: $(N, C_{in}, H_{in}, W_{in})$, Output shape is:
5969
$(N, C_{out}, H_{out}, W_{out})$, where
@@ -93,6 +103,8 @@ class UnpoolOp : public framework::OperatorWithKernel {
93103
std::vector<int> ksize = ctx->Attrs().Get<std::vector<int>>("ksize");
94104
std::vector<int> strides = ctx->Attrs().Get<std::vector<int>>("strides");
95105
std::vector<int> paddings = ctx->Attrs().Get<std::vector<int>>("paddings");
106+
std::vector<int> output_size =
107+
ctx->Attrs().Get<std::vector<int>>("output_size");
96108
PADDLE_ENFORCE_EQ(in_x_dims.size() == 4, true,
97109
platform::errors::InvalidArgument(
98110
"Unpool Intput(X) must be of 4-dimensional, but "
@@ -111,8 +123,7 @@ class UnpoolOp : public framework::OperatorWithKernel {
111123
if (!ctx->IsRuntime() && in_x_dims[i + 2] <= 0) {
112124
output_shape.push_back(-1);
113125
} else {
114-
output_shape.push_back(UnpoolOutputSize(in_x_dims[i + 2], ksize[i],
115-
paddings[i], strides[i]));
126+
output_shape.push_back(output_size[i]);
116127
}
117128
}
118129
ctx->SetOutputDim("Out", framework::make_ddim(output_shape));

0 commit comments

Comments
 (0)