1 /**
2 * Copyright 2020 Huawei Technologies Co., Ltd
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "src/runtime/kernel/arm/int8/depth_to_space_int8.h"
17 #include <cfloat>
18 #include <cmath>
19 #include "schema/model_generated.h"
20 #include "src/kernel_registry.h"
21
22 using mindspore::lite::KernelRegistrar;
23 using mindspore::lite::RET_ERROR;
24 using mindspore::lite::RET_FORMAT_ERR;
25 using mindspore::lite::RET_OK;
26 using mindspore::lite::RET_PARAM_INVALID;
27 using mindspore::schema::PrimitiveType_DepthToSpace;
28
29 namespace mindspore::kernel {
~DepthToSpaceInt8CPUKernel()30 DepthToSpaceInt8CPUKernel::~DepthToSpaceInt8CPUKernel() {
31 if (in_quant_arg_ != nullptr) {
32 free(in_quant_arg_);
33 in_quant_arg_ = nullptr;
34 }
35 if (out_quant_arg_ != nullptr) {
36 free(out_quant_arg_);
37 out_quant_arg_ = nullptr;
38 }
39 }
40
Init()41 int DepthToSpaceInt8CPUKernel::Init() {
42 CHECK_LESS_RETURN(in_tensors_.size(), 1);
43 CHECK_LESS_RETURN(out_tensors_.size(), 1);
44 param_->data_type_size_ = sizeof(int8_t);
45
46 in_quant_arg_ = reinterpret_cast<QuantArg *>(malloc(sizeof(QuantArg)));
47 if (in_quant_arg_ == nullptr) {
48 MS_LOG(ERROR) << "Malloc QuantArg for DepthToSpace int8 op failed!";
49 return RET_ERROR;
50 }
51 auto *input_tensor = in_tensors_.at(kInputIndex);
52 auto in_quant_args = input_tensor->quant_params();
53 CHECK_LESS_RETURN(in_quant_args.size(), 1);
54 in_quant_arg_->scale_ = in_quant_args.front().scale;
55 in_quant_arg_->zp_ = in_quant_args.front().zeroPoint;
56
57 out_quant_arg_ = reinterpret_cast<QuantArg *>(malloc(sizeof(QuantArg)));
58 if (out_quant_arg_ == nullptr) {
59 MS_LOG(ERROR) << "Malloc QuantArg for DepthToSpace int8 op failed!";
60 return RET_ERROR;
61 }
62 auto *out_tensor = out_tensors_.at(kOutputIndex);
63 auto out_quant_args = out_tensor->quant_params();
64 CHECK_LESS_RETURN(out_quant_args.size(), 1);
65 out_quant_arg_->scale_ = out_quant_args.front().scale;
66 out_quant_arg_->zp_ = out_quant_args.front().zeroPoint;
67 if (!InferShapeDone()) {
68 return RET_OK;
69 }
70 return ReSize();
71 }
72
Run()73 int DepthToSpaceInt8CPUKernel::Run() {
74 auto input = in_tensors_[0];
75 auto output = out_tensors_[0];
76 const int8_t *input_data = reinterpret_cast<const int8_t *>(input->data());
77 CHECK_NULL_RETURN(input_data);
78 int8_t *output_data = reinterpret_cast<int8_t *>(output->data());
79 CHECK_NULL_RETURN(output_data);
80 auto in_shape = input->shape();
81 if (std::abs(in_quant_arg_->scale_ - out_quant_arg_->scale_) < FLT_EPSILON &&
82 in_quant_arg_->zp_ == out_quant_arg_->zp_) {
83 DepthToSpaceForNHWC(input_data, output_data, in_shape.data(), param_);
84 } else {
85 DepthToSpaceForNHWCInt8(input_data, output_data, in_shape.data(), param_, in_quant_arg_, out_quant_arg_);
86 }
87 return RET_OK;
88 }
89
90 REG_KERNEL(kCPU, kNumberTypeInt8, PrimitiveType_DepthToSpace, LiteKernelCreator<DepthToSpaceInt8CPUKernel>)
91 } // namespace mindspore::kernel
92