• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From 464a6a0499d215d5c624041d6ce255b860a54a35 Mon Sep 17 00:00:00 2001
2From: j00575040 <jianghui58@huawei.com>
3Date: Tue, 9 Apr 2024 21:34:17 +0800
4Subject: [PATCH] fix argminmax int bug && support swish int8 && fix VAD asan
5 bug
6
7---
8 mindspore/lite/src/litert/kernel/cpu/BUILD.gn |  1 +
9 .../src/litert/kernel/cpu/base/custom_base.cc | 14 ++--
10 .../litert/kernel/cpu/int8/activation_int8.cc |  4 ++
11 .../litert/kernel/cpu/int8/argminmax_int8.cc  | 35 +++++-----
12 .../src/litert/kernel/cpu/int8/sigmoid_int8.h |  2 +-
13 .../src/litert/kernel/cpu/int8/swish_int8.cc  | 67 +++++++++++++++++++
14 .../src/litert/kernel/cpu/int8/swish_int8.h   | 38 +++++++++++
15 mindspore/lite/src/litert/scheduler.cc        |  9 ++-
16 8 files changed, 139 insertions(+), 31 deletions(-)
17 create mode 100644 mindspore/lite/src/litert/kernel/cpu/int8/swish_int8.cc
18 create mode 100644 mindspore/lite/src/litert/kernel/cpu/int8/swish_int8.h
19
20diff --git a/mindspore/lite/src/litert/kernel/cpu/BUILD.gn b/mindspore/lite/src/litert/kernel/cpu/BUILD.gn
21index 7b813314..297fc6f6 100644
22--- a/mindspore/lite/src/litert/kernel/cpu/BUILD.gn
23+++ b/mindspore/lite/src/litert/kernel/cpu/BUILD.gn
24@@ -245,6 +245,7 @@ int8_kernel_sources = [
25     "int8/split_int8.cc",
26     "int8/squeeze_int8.cc",
27     "int8/sub_int8.cc",
28+    "int8/swish_int8.cc",
29     "int8/tanh_int8.cc",
30     "int8/topk_int8.cc",
31     "int8/transpose_int8.cc",
32diff --git a/mindspore/lite/src/litert/kernel/cpu/base/custom_base.cc b/mindspore/lite/src/litert/kernel/cpu/base/custom_base.cc
33index 9921e063..0459c417 100644
34--- a/mindspore/lite/src/litert/kernel/cpu/base/custom_base.cc
35+++ b/mindspore/lite/src/litert/kernel/cpu/base/custom_base.cc
36@@ -28,19 +28,15 @@ using mindspore::lite::RET_OK;
37 using mindspore::schema::PrimitiveType_Custom;
38
39 namespace mindspore::kernel {
40-int CustomBaseCPUKernel::Prepare() {
41-  return RET_OK;
42-}
43+int CustomBaseCPUKernel::Prepare() { return RET_OK; }
44
45-int CustomBaseCPUKernel::ReSize() {
46-  return RET_OK;
47-}
48+int CustomBaseCPUKernel::ReSize() { return RET_OK; }
49
50-int CustomBaseCPUKernel::Run() {
51-  return RET_OK;
52-}
53+int CustomBaseCPUKernel::Run() { return RET_OK; }
54
55 REG_KERNEL(kCPU, kNumberTypeInt32, PrimType_Inner_ThirdPartyModel, LiteKernelCreator<CustomBaseCPUKernel>)
56 REG_KERNEL(kCPU, kNumberTypeFloat32, PrimType_Inner_ThirdPartyModel, LiteKernelCreator<CustomBaseCPUKernel>)
57+REG_KERNEL(kCPU, kNumberTypeInt8, PrimType_Inner_ThirdPartyModel, LiteKernelCreator<CustomBaseCPUKernel>)
58+REG_KERNEL(kCPU, kNumberTypeUInt8, PrimType_Inner_ThirdPartyModel, LiteKernelCreator<CustomBaseCPUKernel>)
59 REG_KERNEL(kCPU, kNumberTypeBool, PrimType_Inner_ThirdPartyModel, LiteKernelCreator<CustomBaseCPUKernel>)
60 }  // namespace mindspore::kernel
61diff --git a/mindspore/lite/src/litert/kernel/cpu/int8/activation_int8.cc b/mindspore/lite/src/litert/kernel/cpu/int8/activation_int8.cc
62index 9bc410e7..10b6cd5a 100644
63--- a/mindspore/lite/src/litert/kernel/cpu/int8/activation_int8.cc
64+++ b/mindspore/lite/src/litert/kernel/cpu/int8/activation_int8.cc
65@@ -16,6 +16,7 @@
66
67 #include "src/litert/kernel/cpu/int8/relux_int8.h"
68 #include "src/litert/kernel/cpu/int8/hswish_int8.h"
69+#include "src/litert/kernel/cpu/int8/swish_int8.h"
70 #include "src/litert/kernel/cpu/int8/sigmoid_int8.h"
71 #include "src/litert/kernel/cpu/int8/tanh_int8.h"
72 #include "src/litert/kernel/cpu/int8/leaky_relu_int8.h"
73@@ -50,6 +51,9 @@ kernel::LiteKernel *CpuActivationInt8KernelCreator(const std::vector<lite::Tenso
74     case schema::ActivationType_HSWISH:
75       kernel = new (std::nothrow) HswishInt8CPUKernel(parameter, inputs, outputs, ctx);
76       break;
77+    case schema::ActivationType_SWISH:
78+      kernel = new (std::nothrow) SwishInt8CPUKernel(parameter, inputs, outputs, ctx);
79+      break;
80     case schema::ActivationType_SIGMOID:
81       kernel = new (std::nothrow) SigmoidInt8CPUKernel(parameter, inputs, outputs, ctx);
82       break;
83diff --git a/mindspore/lite/src/litert/kernel/cpu/int8/argminmax_int8.cc b/mindspore/lite/src/litert/kernel/cpu/int8/argminmax_int8.cc
84index b5018909..7cb872d9 100644
85--- a/mindspore/lite/src/litert/kernel/cpu/int8/argminmax_int8.cc
86+++ b/mindspore/lite/src/litert/kernel/cpu/int8/argminmax_int8.cc
87@@ -47,12 +47,6 @@ int ArgMinMaxInt8CPUKernel::Prepare() {
88   CHECK_LESS_RETURN(out_tensors_.size(), C1NUM);
89   CHECK_NULL_RETURN(in_tensors_[0]);
90   CHECK_NULL_RETURN(out_tensors_[0]);
91-  if (in_tensors_[0]->data_type() != mindspore::kNumberTypeInt8 ||
92-      out_tensors_[0]->data_type() != mindspore::kNumberTypeInt8) {
93-    MS_LOG(ERROR) << "Datatype error, input0 data_type is " << in_tensors_[0]->data_type() << ", output data_type is "
94-                  << out_tensors_[0]->data_type();
95-    return RET_ERROR;
96-  }
97   in_quant_arg_ = reinterpret_cast<QuantArg *>(malloc(sizeof(QuantArg)));
98   if (in_quant_arg_ == nullptr) {
99     MS_LOG(ERROR) << "Malloc QuantArg for argmin or argmax int8 op failed!";
100@@ -64,18 +58,7 @@ int ArgMinMaxInt8CPUKernel::Prepare() {
101   in_quant_arg_->scale_ = in_quant_args.front().scale;
102   in_quant_arg_->zp_ = in_quant_args.front().zeroPoint;
103
104-  auto *out_tensor = out_tensors_.at(kOutputIndex);
105-  auto out_quant_args = out_tensor->quant_params();
106-  CHECK_LESS_RETURN(out_quant_args.size(), 1);
107-  out_quant_arg_ = reinterpret_cast<QuantArg *>(malloc(sizeof(QuantArg)));
108-  out_quant_arg_->scale_ = out_quant_args.front().scale;
109-  out_quant_arg_->zp_ = out_quant_args.front().zeroPoint;
110-  if (out_quant_arg_ == nullptr) {
111-    MS_LOG(ERROR) << "Malloc QuantArg for argmin or argmax int8 op failed!";
112-    return RET_ERROR;
113-  }
114-
115-  compute_param_ = reinterpret_cast<ArgMinMaxComputeParam *>(sizeof(ArgMinMaxComputeParam));
116+  compute_param_ = reinterpret_cast<ArgMinMaxComputeParam *>(malloc(sizeof(ArgMinMaxComputeParam)));
117   if (compute_param_ == nullptr) {
118     MS_LOG(ERROR) << "Malloc ArgMinMaxComputeParam for argmin or argmax int8 op failed!";
119     return RET_ERROR;
120@@ -87,6 +70,22 @@ int ArgMinMaxInt8CPUKernel::Prepare() {
121   compute_param_->out_value_ = param->out_value_;
122   compute_param_->keep_dims_ = param->keep_dims_;
123
124+  out_quant_arg_ = reinterpret_cast<QuantArg *>(malloc(sizeof(QuantArg)));
125+  if (out_quant_arg_ == nullptr) {
126+    MS_LOG(ERROR) << "Malloc QuantArg for argmin or argmax int8 op failed!";
127+    return RET_ERROR;
128+  }
129+  if (out_tensors_.size() == Num2 || compute_param_->out_value_) {
130+    auto *out_tensor = out_tensors_.at(kOutputIndex);
131+    auto out_quant_args = out_tensor->quant_params();
132+    CHECK_LESS_RETURN(out_quant_args.size(), 1);
133+    out_quant_arg_->scale_ = out_quant_args.front().scale;
134+    out_quant_arg_->zp_ = out_quant_args.front().zeroPoint;
135+  } else {  // set default quant value
136+    out_quant_arg_->scale_ = 1.0f;
137+    out_quant_arg_->zp_ = 0;
138+  }
139+
140   if (!InferShapeDone()) {
141     return RET_OK;
142   }
143diff --git a/mindspore/lite/src/litert/kernel/cpu/int8/sigmoid_int8.h b/mindspore/lite/src/litert/kernel/cpu/int8/sigmoid_int8.h
144index 1f383ae6..9080852f 100644
145--- a/mindspore/lite/src/litert/kernel/cpu/int8/sigmoid_int8.h
146+++ b/mindspore/lite/src/litert/kernel/cpu/int8/sigmoid_int8.h
147@@ -34,7 +34,7 @@ class SigmoidInt8CPUKernel : public LiteKernel {
148   int Run() override;
149   int DoActivation(int task_id);
150
151- private:
152+ protected:
153   int8_t table_list_[256]{0};
154 };
155 }  // namespace mindspore::kernel
156diff --git a/mindspore/lite/src/litert/kernel/cpu/int8/swish_int8.cc b/mindspore/lite/src/litert/kernel/cpu/int8/swish_int8.cc
157new file mode 100644
158index 00000000..501793af
159--- /dev/null
160+++ b/mindspore/lite/src/litert/kernel/cpu/int8/swish_int8.cc
161@@ -0,0 +1,67 @@
162+/**
163+ * Copyright 2024 Huawei Technologies Co., Ltd
164+ *
165+ * Licensed under the Apache License, Version 2.0 (the "License");
166+ * you may not use this file except in compliance with the License.
167+ * You may obtain a copy of the License at
168+ *
169+ * http://www.apache.org/licenses/LICENSE-2.0
170+ *
171+ * Unless required by applicable law or agreed to in writing, software
172+ * distributed under the License is distributed on an "AS IS" BASIS,
173+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
174+ * See the License for the specific language governing permissions and
175+ * limitations under the License.
176+ */
177+
178+#include "src/litert/kernel/cpu/int8/swish_int8.h"
179+#include <limits>
180+#include <algorithm>
181+#include "nnacl/int8/quantize.h"
182+#include "src/litert/kernel_registry.h"
183+#include "include/errorcode.h"
184+
185+using mindspore::kernel::KERNEL_ARCH;
186+using mindspore::lite::KernelRegistrar;
187+using mindspore::lite::RET_ERROR;
188+using mindspore::lite::RET_OK;
189+using mindspore::schema::ActivationType_SIGMOID;
190+
191+namespace mindspore::kernel {
192+//  Calculate the quantization results of 0-255 in advance
193+void CalculateSwishTableList(int8_t *table, const float input_scale, const int32_t input_zp, const float output_scale,
194+                             const int32_t output_zp) {
195+  int32_t min_value = std::numeric_limits<int8_t>::min();
196+  int32_t max_value = std::numeric_limits<int8_t>::max();
197+  for (int i = min_value; i < max_value; ++i) {
198+    const float real_input_value = input_scale * (i - input_zp);
199+    const float sigmoid_value = 1.0f / (1.0f + std::exp(-real_input_value));
200+    const int32_t quantized = (std::round(real_input_value * sigmoid_value / output_scale) + output_zp);
201+    int8_t out_value = static_cast<int8_t>(std::max(std::min(quantized, max_value), min_value));
202+    uint8_t index = static_cast<uint8_t>(i);
203+    table[index] = out_value;
204+  }
205+}
206+
207+int SwishInt8CPUKernel::Prepare() {
208+  CHECK_LESS_RETURN(in_tensors_.size(), C1NUM);
209+  CHECK_LESS_RETURN(out_tensors_.size(), C1NUM);
210+  CHECK_NULL_RETURN(in_tensors_[0]);
211+  CHECK_NULL_RETURN(out_tensors_[0]);
212+  if (in_tensors_[0]->data_type() != mindspore::kNumberTypeInt8 ||
213+      out_tensors_[0]->data_type() != mindspore::kNumberTypeInt8) {
214+    MS_LOG(ERROR) << "Datatype error, input0 data_type is " << in_tensors_[0]->data_type() << ", output data_type is "
215+                  << out_tensors_[0]->data_type();
216+    return RET_ERROR;
217+  }
218+  lite::Tensor *input = in_tensors_.at(0);
219+  lite::Tensor *output = out_tensors_.at(0);
220+  MS_CHECK_TRUE_RET(!input->quant_params().empty() && !output->quant_params().empty(), RET_ERROR);
221+  const float input_scale = input->quant_params().front().scale;
222+  const int32_t input_zp = input->quant_params().front().zeroPoint;
223+  const float output_scale = output->quant_params().front().scale;
224+  const int32_t output_zp = output->quant_params().front().zeroPoint;
225+  CalculateSwishTableList(table_list_, input_scale, input_zp, output_scale, output_zp);
226+  return RET_OK;
227+}
228+}  // namespace mindspore::kernel
229diff --git a/mindspore/lite/src/litert/kernel/cpu/int8/swish_int8.h b/mindspore/lite/src/litert/kernel/cpu/int8/swish_int8.h
230new file mode 100644
231index 00000000..7b8ef9ca
232--- /dev/null
233+++ b/mindspore/lite/src/litert/kernel/cpu/int8/swish_int8.h
234@@ -0,0 +1,38 @@
235+/**
236+ * Copyright 2024 Huawei Technologies Co., Ltd
237+ *
238+ * Licensed under the Apache License, Version 2.0 (the "License");
239+ * you may not use this file except in compliance with the License.
240+ * You may obtain a copy of the License at
241+ *
242+ * http://www.apache.org/licenses/LICENSE-2.0
243+ *
244+ * Unless required by applicable law or agreed to in writing, software
245+ * distributed under the License is distributed on an "AS IS" BASIS,
246+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
247+ * See the License for the specific language governing permissions and
248+ * limitations under the License.
249+ */
250+
251+#ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_CPU_INT8_SWISH_INT8_H_
252+#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_CPU_INT8_SWISH_INT8_H_
253+
254+#include <vector>
255+#include "src/litert/lite_kernel.h"
256+#include "src/litert/kernel/cpu/int8/sigmoid_int8.h"
257+#include "nnacl/int8/softmax_int8.h"
258+#include "nnacl/int8/quantize.h"
259+
260+namespace mindspore::kernel {
261+class SwishInt8CPUKernel : public SigmoidInt8CPUKernel {
262+ public:
263+  SwishInt8CPUKernel(OpParameter *parameter, const std::vector<lite::Tensor *> &inputs,
264+                     const std::vector<lite::Tensor *> &outputs, const lite::InnerContext *ctx)
265+      : SigmoidInt8CPUKernel(parameter, inputs, outputs, ctx) {}
266+  ~SwishInt8CPUKernel() override = default;
267+
268+  int Prepare() override;
269+};
270+}  // namespace mindspore::kernel
271+
272+#endif  // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_CPU_INT8_SWISH_INT8_H_
273diff --git a/mindspore/lite/src/litert/scheduler.cc b/mindspore/lite/src/litert/scheduler.cc
274index 199b4361..96efd972 100644
275--- a/mindspore/lite/src/litert/scheduler.cc
276+++ b/mindspore/lite/src/litert/scheduler.cc
277@@ -511,8 +511,8 @@ int Scheduler::ReplaceDelegateKernels(std::vector<kernel::KernelExec *> *dst_ker
278   if (context_->IsDeviceTypeEnabled(DT_NNRT)) {
279     auto delegate = static_cast<NNRTDelegate *>(delegate_.get());
280     delegate->ShallowCopyLiteGraph(this->src_model_->graph_);
281-    void *meta_graph = reinterpret_cast<void*>(const_cast<mindspore::schema::MetaGraph *>(
282-      mindspore::schema::GetMetaGraph(this->src_model_->buf)));
283+    void *meta_graph = reinterpret_cast<void *>(
284+      const_cast<mindspore::schema::MetaGraph *>(mindspore::schema::GetMetaGraph(this->src_model_->buf)));
285     delegate->SetMetaGraph(meta_graph);
286   }
287 #endif
288@@ -865,7 +865,9 @@ int Scheduler::InferSubGraphShape(size_t subgraph_index) {
289   infer_subgraph_index_.push_back(subgraph_index);
290   auto subgraph = src_model_->graph_.sub_graphs_.at(subgraph_index);
291   int subgraph_infershape_ret = RET_OK;
292-  for (auto node_index : subgraph->node_indices_) {
293+  auto node_indexes = subgraph->node_indices_;
294+  for (size_t i = 0; i < node_indexes.size(); ++i) {
295+    auto node_index = node_indexes[i];
296     auto node = src_model_->graph_.all_nodes_[node_index];
297     MS_ASSERT(node != nullptr);
298     auto *primitive = node->primitive_;
299@@ -877,6 +879,7 @@ int Scheduler::InferSubGraphShape(size_t subgraph_index) {
300       // convert shape to built-in shape
301       MS_CHECK_TRUE_RET(node->input_indices_.size() == 1, RET_ERROR);
302       shape_fusion_pass_->Run(node, subgraph_index);
303+      node_indexes = subgraph->node_indices_;
304     }
305     auto ret = InferNodeShape(node);
306     if (ret == RET_INFER_INVALID) {
307--
3082.31.1
309
310