forked from alibaba/MNN
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResizeExecution.cpp
More file actions
114 lines (94 loc) · 3.82 KB
/
Copy pathResizeExecution.cpp
File metadata and controls
114 lines (94 loc) · 3.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//
// ResizeExecution.cpp
// MNN
//
// Created by MNN on 2019/02/28.
// Copyright © 2018, Alibaba Group Holding Limited
//
#include "execution/ResizeExecution.hpp"
#include "Macro.h"
#include "TensorUtils.hpp"
#include "core/OpenCLRunningUtils.hpp"
namespace MNN {
namespace OpenCL {
ResizeExecution::ResizeExecution(const std::vector<Tensor *> &inputs, const MNN::Op *op, Backend *backend)
: Execution(backend) {
#ifdef LOG_VERBOSE
MNN_PRINT("Start ResizeExecution init !\n");
#endif
mOpenCLBackend = static_cast<OpenCLBackend *>(backend);
const auto *scaleParams = op->main_as_Resize();
mXScale = scaleParams->xScale();
mYScale = scaleParams->yScale();
mAreadySetArg = false;
#ifdef LOG_VERBOSE
MNN_PRINT("end ResizeExecution init !\n");
#endif
}
ErrorCode ResizeExecution::onResize(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) {
#ifdef LOG_VERBOSE
MNN_PRINT("Start ResizeExecution onResize !\n");
#endif
auto runtime = mOpenCLBackend->getOpenCLRuntime();
if (mKernel.get() == nullptr) {
mKernel = runtime->buildKernel("interp", "interp", {});
mMaxWorkGroupSize = static_cast<uint32_t>(runtime->getMaxWorkGroupSize(mKernel));
}
#ifdef LOG_VERBOSE
MNN_PRINT("end ResizeExecution onResize !\n");
#endif
return NO_ERROR;
}
ErrorCode ResizeExecution::onExecute(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) {
#ifdef LOG_VERBOSE
MNN_PRINT("Start ResizeExecution onExecute !\n");
#endif
Tensor *input = inputs[0];
Tensor *output = outputs[0];
std::vector<int> inputShape = tensorShapeFormat(input);
std::vector<int> outputShape = tensorShapeFormat(output);
const float x_scaling_ = 1.0 / mXScale;
const float y_scaling_ = 1.0 / mYScale;
const int batch = outputShape.at(0);
const int height = outputShape.at(1);
const int width = outputShape.at(2);
const int channels = outputShape.at(3);
const int channelBlocks = UP_DIV(channels, 4);
const int inputHeight = input->height();
const int inputWidth = input->width();
const std::vector<uint32_t> gws = {static_cast<uint32_t>(channelBlocks), static_cast<uint32_t>(width),
static_cast<uint32_t>(height * batch)};
auto runtime = mOpenCLBackend->getOpenCLRuntime();
if (!mAreadySetArg) {
uint32_t idx = 0;
mKernel.setArg(idx++, gws[0]);
mKernel.setArg(idx++, gws[1]);
mKernel.setArg(idx++, gws[2]);
mKernel.setArg(idx++, openCLImage(input));
mKernel.setArg(idx++, openCLImage(output));
mKernel.setArg(idx++, y_scaling_);
mKernel.setArg(idx++, x_scaling_);
mKernel.setArg(idx++, static_cast<int32_t>(inputHeight));
mKernel.setArg(idx++, static_cast<int32_t>(inputWidth));
mKernel.setArg(idx++, static_cast<int32_t>(height));
mAreadySetArg = true;
}
const std::vector<uint32_t> lws = localWS3DDefault(gws, mMaxWorkGroupSize, mOpenCLBackend->getOpenCLRuntime());
std::vector<uint32_t> roundUpGroupWorkSize(lws.size());
for (size_t i = 0; i < lws.size(); ++i) {
if (lws[i] != 0) {
roundUpGroupWorkSize[i] = ROUND_UP(gws[i], std::max((uint32_t)1, lws[i]));
}
}
auto error = runtime->commandQueue().enqueueNDRangeKernel(
mKernel, cl::NullRange, cl::NDRange(roundUpGroupWorkSize[0], roundUpGroupWorkSize[1], roundUpGroupWorkSize[2]),
cl::NDRange(lws[0], lws[1], lws[2]), nullptr, nullptr);
MNN_CHECK_CL_SUCCESS(error);
#ifdef LOG_VERBOSE
MNN_PRINT("end ResizeExecution onExecute !\n");
#endif
return NO_ERROR;
}
OpenCLCreatorRegister<TypedCreator<ResizeExecution>> __resize_op(OpType_Resize);
} // namespace OpenCL
} // namespace MNN