From: @ling_qiao_min Reviewed-by: @zhang_xue_tong,@HilbertDavid Signed-off-by: @zhang_xue_tongtags/v1.1.0
| @@ -40,6 +40,8 @@ int HSigmoid(const float *src, int length, float *dst); | |||
| int Swish(const float *src, int length, float *dst); | |||
| int HSwish(const float *src, int length, float *dst); | |||
| int HardTanh(const float *src, int length, float *dst, float min_val, float max_val); | |||
| float TanhOpt(float src); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| @@ -0,0 +1,30 @@ | |||
| /** | |||
| * Copyright 2020 Huawei Technologies Co., Ltd | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #include "nnacl/int8/tanh_int8.h" | |||
| #ifdef ENABLE_NEON | |||
| #include <arm_neon.h> | |||
| #endif | |||
| void TanhInt8(const int8_t *input_ptr, int8_t *output_ptr, int size, TanhQuantParameter *quant) { | |||
| for (int i = 0; i < size; ++i) { | |||
| float fp32_src = (input_ptr[i] - quant->in_zp_) * quant->in_scale_; | |||
| float fp32_dst = TanhOpt(fp32_src); | |||
| int32_t int32_dst = (int32_t)round(fp32_dst * 1.0 / quant->out_scale_ + quant->out_zp_); | |||
| output_ptr[i] = (int8_t)MSMAX(MSMIN(int32_dst, 127), -128); | |||
| } | |||
| return; | |||
| } | |||
| @@ -0,0 +1,43 @@ | |||
| /** | |||
| * Copyright 2020 Huawei Technologies Co., Ltd | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #ifndef MINDSPORE_LITE_NNACL_INT8_TANH_INT8_H_ | |||
| #define MINDSPORE_LITE_NNACL_INT8_TANH_INT8_H_ | |||
| #include "nnacl/op_base.h" | |||
| #include "nnacl/quantization/quantize.h" | |||
| #include "nnacl/quantization/fixed_point.h" | |||
| #include "nnacl/int8/quant_dtype_cast_int8.h" | |||
| #include "nnacl/fp32/activation.h" | |||
| typedef struct TanhQuantParameter { | |||
| int32_t in_zp_; | |||
| int32_t out_zp_; | |||
| double in_scale_; | |||
| double out_scale_; | |||
| } TanhQuantParameter; | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| void TanhInt8(const int8_t *input_ptr, int8_t *output_ptr, int size, TanhQuantParameter *quant); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| #endif // MINDSPORE_LITE_NNACL_INT8_TANH_INT8_H_ | |||
| @@ -124,7 +124,7 @@ int Transpose::InferShape(std::vector<Tensor *> inputs_, std::vector<Tensor *> o | |||
| if (!GetInferFlag()) { | |||
| return RET_OK; | |||
| } | |||
| MS_ASSERT(inputs_.size() == kSingleNum); | |||
| MS_ASSERT(inputs_.size() == kDoubleNum); | |||
| MS_ASSERT(outputs_.size() == kSingleNum); | |||
| int conjugate = GetConjugate(); | |||
| @@ -116,7 +116,7 @@ int TransposeFp32Run(void *cdata, int task_id) { | |||
| } | |||
| int TransposeCPUKernel::Run() { | |||
| MS_ASSERT(in_tensors_.size() == 1); | |||
| MS_ASSERT(in_tensors_.size() == 2); | |||
| MS_ASSERT(out_tensors_.size() == 1); | |||
| auto &in_tensor = in_tensors_.front(); | |||
| auto &out_tensor = out_tensors_.front(); | |||
| @@ -17,6 +17,7 @@ | |||
| #include "src/runtime/kernel/arm/int8/relux_int8.h" | |||
| #include "src/runtime/kernel/arm/int8/hswish_int8.h" | |||
| #include "src/runtime/kernel/arm/int8/sigmoid_int8.h" | |||
| #include "src/runtime/kernel/arm/int8/tanh_int8.h" | |||
| #include "src/runtime/kernel/arm/int8/leaky_relu_int8.h" | |||
| #include "schema/model_generated.h" | |||
| #include "src/kernel_registry.h" | |||
| @@ -57,6 +58,9 @@ kernel::LiteKernel *CpuActivationInt8KernelCreator(const std::vector<lite::Tenso | |||
| case schema::ActivationType_LEAKY_RELU: | |||
| kernel = new (std::nothrow) LeakyReluInt8CPUKernel(parameter, inputs, outputs, ctx, primitive); | |||
| break; | |||
| case schema::ActivationType_TANH: | |||
| kernel = new (std::nothrow) TanhInt8CPUKernel(parameter, inputs, outputs, ctx, primitive); | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| @@ -162,7 +162,7 @@ kernel::LiteKernel *CpuFullConnectionInt8KernelCreator(const std::vector<lite::T | |||
| const kernel::KernelKey &desc, | |||
| const mindspore::lite::PrimitiveC *primitive) { | |||
| MS_ASSERT(opParameter != nullptr); | |||
| MS_ASSERT(desc.type == schema::PrimitiveType_Concat); | |||
| MS_ASSERT(desc.type == schema::PrimitiveType_FullConnection); | |||
| auto kernel = new (std::nothrow) FullconnectionInt8CPUKernel(opParameter, inputs, outputs, ctx, primitive); | |||
| if (!kernel) { | |||
| MS_LOG(ERROR) << "kernel is nullptr."; | |||
| @@ -0,0 +1,77 @@ | |||
| /** | |||
| * Copyright 2020 Huawei Technologies Co., Ltd | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #include "src/runtime/kernel/arm/int8/tanh_int8.h" | |||
| #include "src/runtime/runtime_api.h" | |||
| using mindspore::lite::RET_ERROR; | |||
| using mindspore::lite::RET_OK; | |||
| namespace mindspore::kernel { | |||
| int TanhInt8CPUKernel::Init() { | |||
| lite::Tensor *input = in_tensors_.at(0); | |||
| lite::Tensor *output = out_tensors_.at(0); | |||
| tanh_quant_.in_scale_ = input->GetQuantParams().front().scale; | |||
| tanh_quant_.in_zp_ = input->GetQuantParams().front().zeroPoint; | |||
| tanh_quant_.out_scale_ = output->GetQuantParams().front().scale; | |||
| tanh_quant_.out_zp_ = output->GetQuantParams().front().zeroPoint; | |||
| if (!InferShapeDone()) { | |||
| return RET_OK; | |||
| } | |||
| return ReSize(); | |||
| } | |||
| int TanhInt8CPUKernel::ReSize() { | |||
| element_size_ = in_tensors_.at(0)->ElementsNum(); | |||
| thread_count_ = MSMIN(element_size_, op_parameter_->thread_num_); | |||
| thread_stride_ = UP_DIV(element_size_, thread_count_); | |||
| return RET_OK; | |||
| } | |||
| int TanhInt8CPUKernel::DoActivation(int task_id) { | |||
| int current_size = element_size_ - task_id * thread_stride_; | |||
| current_size = MSMIN(thread_stride_, current_size); | |||
| if (current_size <= 0) { | |||
| return RET_OK; | |||
| } | |||
| int8_t *cur_input = in_ptr_ + task_id * thread_stride_; | |||
| int8_t *cur_output = out_ptr_ + task_id * thread_stride_; | |||
| TanhInt8(cur_input, cur_output, current_size, &tanh_quant_); | |||
| return RET_OK; | |||
| } | |||
| int TanhInt8Run(void *cdata, int task_id) { | |||
| auto activation_kernel = reinterpret_cast<TanhInt8CPUKernel *>(cdata); | |||
| auto error_code = activation_kernel->DoActivation(task_id); | |||
| if (error_code != RET_OK) { | |||
| MS_LOG(ERROR) << "TanhInt8Run error task_id[" << task_id << "] error_code[" << error_code << "]"; | |||
| return RET_ERROR; | |||
| } | |||
| return RET_OK; | |||
| } | |||
| int TanhInt8CPUKernel::Run() { | |||
| in_ptr_ = reinterpret_cast<int8_t *>(in_tensors_.at(0)->data_c()); | |||
| out_ptr_ = reinterpret_cast<int8_t *>(out_tensors_.at(0)->data_c()); | |||
| ParallelLaunch(this->context_->thread_pool_, TanhInt8Run, this, thread_count_); | |||
| return RET_OK; | |||
| } | |||
| } // namespace mindspore::kernel | |||
| @@ -0,0 +1,54 @@ | |||
| /** | |||
| * Copyright 2020 Huawei Technologies Co., Ltd | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| #ifndef MINDSPORE_LITE_SRC_BACKEND_ARM_INT8_TANH_INT8_H_ | |||
| #define MINDSPORE_LITE_SRC_BACKEND_ARM_INT8_TANH_INT8_H_ | |||
| #include <vector> | |||
| #include <limits> | |||
| #include <algorithm> | |||
| #include "src/lite_kernel.h" | |||
| #include "nnacl/int8/tanh_int8.h" | |||
| #include "nnacl/quantization/quantize.h" | |||
| #include "include/errorcode.h" | |||
| namespace mindspore::kernel { | |||
| class TanhInt8CPUKernel : public LiteKernel { | |||
| public: | |||
| TanhInt8CPUKernel(OpParameter *parameter, const std::vector<lite::Tensor *> &inputs, | |||
| const std::vector<lite::Tensor *> &outputs, const lite::InnerContext *ctx, | |||
| const mindspore::lite::PrimitiveC *primitive) | |||
| : LiteKernel(parameter, inputs, outputs, ctx, primitive) {} | |||
| ~TanhInt8CPUKernel() override = default; | |||
| int Init() override; | |||
| int ReSize() override; | |||
| int Run() override; | |||
| public: | |||
| int DoActivation(int task_id); | |||
| private: | |||
| int8_t *in_ptr_; | |||
| int8_t *out_ptr_; | |||
| int element_size_; | |||
| int thread_count_; | |||
| int thread_stride_; | |||
| TanhQuantParameter tanh_quant_; | |||
| }; | |||
| } // namespace mindspore::kernel | |||
| #endif // MINDSPORE_LITE_SRC_BACKEND_ARM_INT8_TANH_INT8_H_ | |||