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