From 5e0d8311e0fad6599b7cbd56d1c47a3f791ecbf6 Mon Sep 17 00:00:00 2001 From: mzy <929449726@qq.com> Date: Mon, 17 Nov 2025 07:23:58 +0000 Subject: [PATCH] add ft78, ft04 range --- .../src/litert/kernel/dsp/ft04/range.cc | 117 +++++ .../src/litert/kernel/dsp/ft04/range.h | 48 ++ .../src/litert/kernel/dsp/ft78/range.cc | 136 +++++ .../src/litert/kernel/dsp/ft78/range.h | 58 ++ .../ut/src/runtime/kernel/dsp/range_tests.cc | 495 ++++++++++++++++++ 5 files changed, 854 insertions(+) create mode 100644 mindspore-lite/src/litert/kernel/dsp/ft04/range.cc create mode 100644 mindspore-lite/src/litert/kernel/dsp/ft04/range.h create mode 100644 mindspore-lite/src/litert/kernel/dsp/ft78/range.cc create mode 100644 mindspore-lite/src/litert/kernel/dsp/ft78/range.h create mode 100644 mindspore-lite/test/ut/src/runtime/kernel/dsp/range_tests.cc diff --git a/mindspore-lite/src/litert/kernel/dsp/ft04/range.cc b/mindspore-lite/src/litert/kernel/dsp/ft04/range.cc new file mode 100644 index 000000000..b33bf1534 --- /dev/null +++ b/mindspore-lite/src/litert/kernel/dsp/ft04/range.cc @@ -0,0 +1,117 @@ +/** + * Copyright 2025 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/litert/kernel/dsp/ft04/range.h" +#include +#include +#include +#include +#include "src/litert/kernel/cpu/nnacl_c/range_parameter.h" +#include "src/litert/kernel_registry.h" + +using mindspore::kernel::KERNEL_ARCH::kDSP; +using mindspore::lite::KernelRegistrar; +using mindspore::lite::RET_ERROR; +using mindspore::lite::RET_OK; +using mindspore::schema::PrimitiveType_Range; + +namespace mindspore::kernel { +int RangeDSPKernel::CheckSpecs() { + if (out_tensors_.size() != 1) { + MS_LOG(WARNING) << "out size: " << out_tensors_.size(); + return RET_ERROR; + } + return RET_OK; +} + +int RangeDSPKernel::Prepare() { + auto range_param = reinterpret_cast(this->op_parameter_); + start_int_ = range_param->start_; + delta_int_ = range_param->delta_; + start_ = static_cast(range_param->start_); + delta_ = static_cast(range_param->delta_); + return RET_OK; +} + +int RangeDSPKernel::RangeRunFp32() { + kernel_name_ = "fp_range_s"; + core_mask_ = 0xf; + return dsp_runtime_->RunKernel(kernel_name_, kernel_args_, core_mask_); +} + +int RangeDSPKernel::RangeRunFp16() { + kernel_name_ = "hp_range_s"; + core_mask_ = 0xf; + return dsp_runtime_->RunKernel(kernel_name_, kernel_args_, core_mask_); +} + +int RangeDSPKernel::RangeRunInt16() { + kernel_name_ = "i16_range_s"; + core_mask_ = 0xf; + return dsp_runtime_->RunKernel(kernel_name_, kernel_args_, core_mask_); +} + +int RangeDSPKernel::RangeRunInt32() { + kernel_name_ = "i32_range_s"; + core_mask_ = 0xf; + return dsp_runtime_->RunKernel(kernel_name_, kernel_args_, core_mask_); +} + +int RangeDSPKernel::Run() { + int ret = -1; + uint64_t length = out_tensors_[0]->ElementsNum(); + auto allocator = dsp_runtime_->GetAllocator(); + uint64_t out_device_ptr = allocator->GetDeviceMemPtr(out_tensors_[0]->data()); + auto data_type = out_tensors_[0]->data_type(); + + if (data_type == kNumberTypeFloat32) { + uint64_t start_hex = 0; + memcpy(&start_hex, &start_, sizeof(float)); + uint64_t delta_hex = 0; + memcpy(&delta_hex, &delta_, sizeof(float)); + SetKernelArg({out_device_ptr, start_hex, delta_hex, static_cast(length)}); + ret = RangeRunFp32(); + } else if (data_type == kNumberTypeFloat16) { + uint64_t start_hex = 0; + memcpy(&start_hex, &start_, sizeof(float)); + uint64_t delta_hex = 0; + memcpy(&delta_hex, &delta_, sizeof(float)); + SetKernelArg({out_device_ptr, start_hex, delta_hex, static_cast(length)}); + ret = RangeRunFp16(); + } else if (data_type == kNumberTypeInt16) { + SetKernelArg({out_device_ptr, static_cast(start_int_), static_cast(delta_int_), + static_cast(length)}); + ret = RangeRunInt16(); + } else if (data_type == kNumberTypeInt32) { + SetKernelArg({out_device_ptr, static_cast(start_int_), static_cast(delta_int_), + static_cast(length)}); + ret = RangeRunInt32(); + } else { + MS_LOG(ERROR) << "unsupported data type: " << static_cast(data_type); + } + + if (ret != RET_OK) { + MS_LOG(ERROR) << this->name() << " Run failed! "; + return RET_ERROR; + } + return RET_OK; +} + +REG_KERNEL(kDSP, kNumberTypeFloat32, PrimitiveType_Range, DSPKernelCreator) +REG_KERNEL(kDSP, kNumberTypeFloat16, PrimitiveType_Range, DSPKernelCreator) +REG_KERNEL(kDSP, kNumberTypeInt16, PrimitiveType_Range, DSPKernelCreator) +REG_KERNEL(kDSP, kNumberTypeInt32, PrimitiveType_Range, DSPKernelCreator) +} // namespace mindspore::kernel diff --git a/mindspore-lite/src/litert/kernel/dsp/ft04/range.h b/mindspore-lite/src/litert/kernel/dsp/ft04/range.h new file mode 100644 index 000000000..3397af76a --- /dev/null +++ b/mindspore-lite/src/litert/kernel/dsp/ft04/range.h @@ -0,0 +1,48 @@ +/** + * Copyright 2025 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_RUNTIME_KERNEL_DSP_KERNEL_RANGE_H_ +#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_DSP_KERNEL_RANGE_H_ + +#include +#include +#include "src/litert/kernel/dsp/dsp_kernel.h" + +namespace mindspore::kernel { +class RangeDSPKernel : public DSPKernel { + public: + using DSPKernel::DSPKernel; + + ~RangeDSPKernel() override = default; + int Prepare() override; + int CheckSpecs() override; + int Run() override; + + int RangeRunFp32(); + int RangeRunFp16(); + int RangeRunInt16(); + int RangeRunInt32(); + + private: + std::string kernel_name_; + uint64_t core_mask_; + float start_; + float delta_; + int start_int_; + int delta_int_; +}; +} // namespace mindspore::kernel +#endif diff --git a/mindspore-lite/src/litert/kernel/dsp/ft78/range.cc b/mindspore-lite/src/litert/kernel/dsp/ft78/range.cc new file mode 100644 index 000000000..de54713e6 --- /dev/null +++ b/mindspore-lite/src/litert/kernel/dsp/ft78/range.cc @@ -0,0 +1,136 @@ +/** + * Copyright 2025 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/litert/kernel/dsp/ft78/range.h" +#include +#include +#include +#include +#include +#include "src/litert/kernel/cpu/nnacl_c/range_parameter.h" +#include "src/litert/kernel_registry.h" + +using mindspore::kernel::KERNEL_ARCH::kDSP; +using mindspore::lite::KernelRegistrar; +using mindspore::lite::RET_ERROR; +using mindspore::lite::RET_OK; +using mindspore::schema::PrimitiveType_Range; + +namespace mindspore::kernel { +int RangeDSPKernel::CheckSpecs() { + if (out_tensors_.size() != 1) { + MS_LOG(WARNING) << "out size: " << out_tensors_.size(); + return RET_ERROR; + } + return RET_OK; +} + +int RangeDSPKernel::Prepare() { + auto range_param = reinterpret_cast(this->op_parameter_); + start_i32_ = static_cast(range_param->start_); + delta_i32_ = static_cast(range_param->delta_); + start_i16_ = static_cast(range_param->start_); + delta_i16_ = static_cast(range_param->delta_); + start_i8_ = static_cast(range_param->start_); + delta_i8_ = static_cast(range_param->delta_); + start_ = static_cast(range_param->start_); + delta_ = static_cast(range_param->delta_); + start_double_ = static_cast(range_param->start_); + delta_double_ = static_cast(range_param->delta_); + return RET_OK; +} + +int RangeDSPKernel::RangeRunFp32() { + kernel_name_ = "fp_range_s"; + core_mask_ = 0xff; + return dsp_runtime_->RunKernel(kernel_name_, kernel_args_, core_mask_); +} + +int RangeDSPKernel::RangeRunFp64() { + kernel_name_ = "dp_range_s"; + core_mask_ = 0xff; + return dsp_runtime_->RunKernel(kernel_name_, kernel_args_, core_mask_); +} + +int RangeDSPKernel::RangeRunInt8() { + kernel_name_ = "i8_range_s"; + core_mask_ = 0xff; + return dsp_runtime_->RunKernel(kernel_name_, kernel_args_, core_mask_); +} + +int RangeDSPKernel::RangeRunInt16() { + kernel_name_ = "i16_range_s"; + core_mask_ = 0xff; + return dsp_runtime_->RunKernel(kernel_name_, kernel_args_, core_mask_); +} + +int RangeDSPKernel::RangeRunInt32() { + kernel_name_ = "i32_range_s"; + core_mask_ = 0xff; + return dsp_runtime_->RunKernel(kernel_name_, kernel_args_, core_mask_); +} + +int RangeDSPKernel::Run() { + int ret = RET_ERROR; + uint64_t length = out_tensors_[0]->ElementsNum(); + auto allocator = dsp_runtime_->GetAllocator(); + uint64_t out_device_ptr = allocator->GetDeviceMemPtr(out_tensors_[0]->data()); + auto data_type = out_tensors_[0]->data_type(); + + if (data_type == kNumberTypeFloat32) { + uint64_t start_hex = 0; + uint64_t delta_hex = 0; + memcpy(&start_hex, &start_, sizeof(float)); + memcpy(&delta_hex, &delta_, sizeof(float)); + SetKernelArg({out_device_ptr, start_hex, delta_hex, static_cast(length)}); + ret = RangeRunFp32(); + } else if (data_type == kNumberTypeFloat64) { + uint64_t start_hex = 0; + uint64_t delta_hex = 0; + memcpy(&start_hex, &start_double_, sizeof(double)); + memcpy(&delta_hex, &delta_double_, sizeof(double)); + SetKernelArg({out_device_ptr, start_hex, delta_hex, static_cast(length)}); + ret = RangeRunFp64(); + } else if (data_type == kNumberTypeInt8) { + SetKernelArg({out_device_ptr, static_cast(static_cast(start_i8_)), + static_cast(static_cast(delta_i8_)), static_cast(length)}); + ret = RangeRunInt8(); + } else if (data_type == kNumberTypeInt16) { + SetKernelArg({out_device_ptr, static_cast(static_cast(start_i16_)), + static_cast(static_cast(delta_i16_)), static_cast(length)}); + ret = RangeRunInt16(); + } else if (data_type == kNumberTypeInt32) { + SetKernelArg({out_device_ptr, static_cast(static_cast(start_i32_)), + static_cast(static_cast(delta_i32_)), static_cast(length)}); + ret = RangeRunInt32(); + } else { + MS_LOG(ERROR) << "unsupported data type: " << static_cast(data_type); + return RET_ERROR; + } + + if (ret != RET_OK) { + MS_LOG(ERROR) << this->name() << " Run failed! "; + return RET_ERROR; + } + return RET_OK; +} + +REG_KERNEL(kDSP, kNumberTypeFloat32, PrimitiveType_Range, DSPKernelCreator) +REG_KERNEL(kDSP, kNumberTypeFloat64, PrimitiveType_Range, DSPKernelCreator) +REG_KERNEL(kDSP, kNumberTypeInt8, PrimitiveType_Range, DSPKernelCreator) +REG_KERNEL(kDSP, kNumberTypeInt16, PrimitiveType_Range, DSPKernelCreator) +REG_KERNEL(kDSP, kNumberTypeInt32, PrimitiveType_Range, DSPKernelCreator) +} // namespace mindspore::kernel diff --git a/mindspore-lite/src/litert/kernel/dsp/ft78/range.h b/mindspore-lite/src/litert/kernel/dsp/ft78/range.h new file mode 100644 index 000000000..9e14a5c63 --- /dev/null +++ b/mindspore-lite/src/litert/kernel/dsp/ft78/range.h @@ -0,0 +1,58 @@ +/** + * Copyright 2025 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_RUNTIME_KERNEL_DSP_FT78_RANGE_H_ +#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_DSP_FT78_RANGE_H_ + +#include +#include +#include "src/litert/kernel/dsp/dsp_kernel.h" + +namespace mindspore::kernel { +class RangeDSPKernel : public DSPKernel { + public: + RangeDSPKernel(OpParameter *parameter, const std::vector &inputs, + const std::vector &outputs, const lite::InnerContext *ctx) + : DSPKernel(parameter, inputs, outputs, ctx) {} + ~RangeDSPKernel() override = default; + + int CheckSpecs() override; + int Prepare() override; + int Run() override; + + private: + int RangeRunFp32(); + int RangeRunFp64(); + int RangeRunInt8(); + int RangeRunInt16(); + int RangeRunInt32(); + + std::string kernel_name_; + uint64_t core_mask_ = 0; + float start_ = 0.f; + float delta_ = 0.f; + double start_double_ = 0.0; + double delta_double_ = 0.0; + int32_t start_i32_ = 0; + int32_t delta_i32_ = 0; + int16_t start_i16_ = 0; + int16_t delta_i16_ = 0; + int8_t start_i8_ = 0; + int8_t delta_i8_ = 0; +}; +} // namespace mindspore::kernel + +#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_DSP_FT78_RANGE_H_ diff --git a/mindspore-lite/test/ut/src/runtime/kernel/dsp/range_tests.cc b/mindspore-lite/test/ut/src/runtime/kernel/dsp/range_tests.cc new file mode 100644 index 000000000..a0dd8d6f2 --- /dev/null +++ b/mindspore-lite/test/ut/src/runtime/kernel/dsp/range_tests.cc @@ -0,0 +1,495 @@ +/** + * Copyright 2025 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 +#include +#include +#include +#include +#include +#include +#include "ut/src/runtime/kernel/dsp/dsp_test.h" +#include "include/api/context.h" +#include "include/api/data_type.h" +#include "nnacl_c/range_parameter.h" +#include "schema/inner/model_generated.h" +#include "src/litert/kernel/dsp/dsp_subgraph.h" +#include "src/litert/kernel_registry.h" + +namespace mindspore::lite::dsp::test { + +namespace { +typedef int16_t float16; +static inline float fp16_to_fp32(float16 h) { + uint32_t sign = (h & 0x8000) << 16; + uint32_t exp = (h & 0x7C00) >> 10; + uint32_t frac = (h & 0x03FF); + uint32_t f_exp, f_frac; + if (exp == 0) { + if (frac == 0) { + f_exp = 0; + f_frac = 0; + } else { + int shift = 0; + while ((frac & 0x0200) == 0) { + frac <<= 1; + ++shift; + } + frac &= 0x03FF; + f_exp = 127 - 15 - shift; + f_frac = frac << 13; + } + } else if (exp == 0x1F) { + f_exp = 255; + f_frac = frac << 13; + } else { + f_exp = exp - 15 + 127; + f_frac = frac << 13; + } + uint32_t f_bits = sign | (f_exp << 23) | f_frac; + float result; + std::memcpy(&result, &f_bits, sizeof(result)); + return result; +} +} // namespace + +class TestDSP_Range : public DSPCommonTest {}; + +#ifdef SUPPORT_FT04 +TEST_F(TestDSP_Range, Range_FT04_Fp32) { + InitDSPRuntime(); + std::vector inputs; + std::vector outputs; + + std::vector output_shape = {100}; + int num = output_shape[0]; + + auto param = reinterpret_cast(malloc(sizeof(RangeParameter))); + ASSERT_NE(param, nullptr); + std::memset(param, 0, sizeof(RangeParameter)); + param->start_ = 0; + param->limit_ = 100; + param->delta_ = 1; + param->dtype_ = static_cast(kNumberTypeFloat32); + + auto output = new lite::Tensor(kNumberTypeFloat32, output_shape, mindspore::NHWC, lite::Category::CONST_TENSOR); + output->MallocData(allocator_); + outputs.push_back(output); + std::fill_n(reinterpret_cast(output->MutableData()), num, 0.f); + + auto ctx = new lite::InnerContext; + ASSERT_EQ(lite::RET_OK, ctx->Init()); + + kernel::KernelKey key = {kernel::KERNEL_ARCH::kDSP, kNumberTypeFloat32, NHWC, schema::PrimitiveType_Range}; + auto creator = KernelRegistry::GetInstance()->GetCreator(key); + auto kernel = creator(inputs, outputs, reinterpret_cast(param), ctx, key); + ASSERT_NE(kernel, nullptr); + + ASSERT_EQ(kernel->Prepare(), lite::RET_OK); + ASSERT_EQ(kernel->Run(), lite::RET_OK); + + std::vector correct(num); + for (int i = 0; i < num; ++i) { + correct[i] = static_cast(i); + } + ASSERT_EQ(0, CompareOutputData(reinterpret_cast(outputs[0]->MutableData()), correct.data(), num)); + + UninitDSPRuntime(); + delete ctx; + for (auto t : outputs) { + delete t; + } + delete kernel; +} + +TEST_F(TestDSP_Range, Range_FT04_Int32) { + InitDSPRuntime(); + std::vector inputs; + std::vector outputs; + + std::vector output_shape = {100}; + int num = output_shape[0]; + + auto param = reinterpret_cast(malloc(sizeof(RangeParameter))); + ASSERT_NE(param, nullptr); + std::memset(param, 0, sizeof(RangeParameter)); + param->start_ = 0; + param->limit_ = 100; + param->delta_ = 1; + param->dtype_ = static_cast(kNumberTypeInt32); + + auto output = new lite::Tensor(kNumberTypeInt32, output_shape, mindspore::NHWC, lite::Category::CONST_TENSOR); + output->MallocData(allocator_); + outputs.push_back(output); + std::fill_n(reinterpret_cast(output->MutableData()), num, 0); + + auto ctx = new lite::InnerContext; + ASSERT_EQ(lite::RET_OK, ctx->Init()); + + kernel::KernelKey key = {kernel::KERNEL_ARCH::kDSP, kNumberTypeInt32, NHWC, schema::PrimitiveType_Range}; + auto creator = KernelRegistry::GetInstance()->GetCreator(key); + auto kernel = creator(inputs, outputs, reinterpret_cast(param), ctx, key); + ASSERT_NE(kernel, nullptr); + + ASSERT_EQ(kernel->Prepare(), lite::RET_OK); + ASSERT_EQ(kernel->Run(), lite::RET_OK); + + std::vector correct(num); + for (int i = 0; i < num; ++i) { + correct[i] = i; + } + ASSERT_EQ(0, CompareOutputData(reinterpret_cast(outputs[0]->MutableData()), correct.data(), num)); + + UninitDSPRuntime(); + delete ctx; + for (auto t : outputs) { + delete t; + } + delete kernel; +} + +TEST_F(TestDSP_Range, Range_FT04_Int16) { + InitDSPRuntime(); + std::vector inputs; + std::vector outputs; + + std::vector output_shape = {50}; + int num = output_shape[0]; + + auto param = reinterpret_cast(malloc(sizeof(RangeParameter))); + ASSERT_NE(param, nullptr); + std::memset(param, 0, sizeof(RangeParameter)); + param->start_ = 0; + param->limit_ = 100; + param->delta_ = 2; + param->dtype_ = static_cast(kNumberTypeInt16); + + auto output = new lite::Tensor(kNumberTypeInt16, output_shape, mindspore::NHWC, lite::Category::CONST_TENSOR); + output->MallocData(allocator_); + outputs.push_back(output); + std::fill_n(reinterpret_cast(output->MutableData()), num, static_cast(0)); + + auto ctx = new lite::InnerContext; + ASSERT_EQ(lite::RET_OK, ctx->Init()); + + kernel::KernelKey key = {kernel::KERNEL_ARCH::kDSP, kNumberTypeInt16, NHWC, schema::PrimitiveType_Range}; + auto creator = KernelRegistry::GetInstance()->GetCreator(key); + auto kernel = creator(inputs, outputs, reinterpret_cast(param), ctx, key); + ASSERT_NE(kernel, nullptr); + + ASSERT_EQ(kernel->Prepare(), lite::RET_OK); + ASSERT_EQ(kernel->Run(), lite::RET_OK); + + std::vector correct(num); + for (int i = 0; i < num; ++i) { + correct[i] = static_cast(i * 2); + } + ASSERT_EQ(0, CompareOutputData(reinterpret_cast(outputs[0]->MutableData()), correct.data(), num)); + + UninitDSPRuntime(); + delete ctx; + for (auto t : outputs) { + delete t; + } + delete kernel; +} + +TEST_F(TestDSP_Range, Range_FT04_Fp16) { + InitDSPRuntime(); + std::vector inputs; + std::vector outputs; + + std::vector output_shape = {1024}; + int num = output_shape[0]; + + auto param = reinterpret_cast(malloc(sizeof(RangeParameter))); + ASSERT_NE(param, nullptr); + std::memset(param, 0, sizeof(RangeParameter)); + param->start_ = 0; + param->limit_ = 100; + param->delta_ = 1; + param->dtype_ = static_cast(kNumberTypeFloat16); + + auto output = new lite::Tensor(kNumberTypeFloat16, output_shape, mindspore::NHWC, lite::Category::CONST_TENSOR); + output->MallocData(allocator_); + outputs.push_back(output); + std::memset(output->MutableData(), 0, static_cast(num) * sizeof(uint16_t)); + + auto ctx = new lite::InnerContext; + ASSERT_EQ(lite::RET_OK, ctx->Init()); + + kernel::KernelKey key = {kernel::KERNEL_ARCH::kDSP, kNumberTypeFloat16, NHWC, schema::PrimitiveType_Range}; + auto creator = KernelRegistry::GetInstance()->GetCreator(key); + auto kernel = creator(inputs, outputs, reinterpret_cast(param), ctx, key); + ASSERT_NE(kernel, nullptr); + + ASSERT_EQ(kernel->Prepare(), lite::RET_OK); + ASSERT_EQ(kernel->Run(), lite::RET_OK); + + std::vector correct(num); + for (int i = 0; i < num; ++i) { + correct[i] = static_cast(i); + } + auto out_fp16 = reinterpret_cast(outputs[0]->MutableData()); + std::vector actual(num); + for (int i = 0; i < num; ++i) { + actual[i] = fp16_to_fp32(out_fp16[i]); + } + ASSERT_EQ(0, CompareOutputData(actual.data(), correct.data(), num, 1e-4)); + + UninitDSPRuntime(); + delete ctx; + for (auto t : outputs) { + delete t; + } + delete kernel; +} +#endif + +#ifdef SUPPORT_FT78 +TEST_F(TestDSP_Range, Range_FT78_Fp32) { + InitDSPRuntime(); + std::vector inputs; + std::vector outputs; + + std::vector output_shape = {100}; + int num = output_shape[0]; + + auto param = reinterpret_cast(malloc(sizeof(RangeParameter))); + ASSERT_NE(param, nullptr); + std::memset(param, 0, sizeof(RangeParameter)); + param->start_ = 0; + param->limit_ = 100; + param->delta_ = 1; + param->dtype_ = static_cast(kNumberTypeFloat32); + + auto output = new lite::Tensor(kNumberTypeFloat32, output_shape, mindspore::NHWC, lite::Category::CONST_TENSOR); + output->MallocData(allocator_); + outputs.push_back(output); + std::fill_n(reinterpret_cast(output->MutableData()), num, 0.f); + + auto ctx = new lite::InnerContext; + ASSERT_EQ(lite::RET_OK, ctx->Init()); + + kernel::KernelKey key = {kernel::KERNEL_ARCH::kDSP, kNumberTypeFloat32, NHWC, schema::PrimitiveType_Range}; + auto creator = KernelRegistry::GetInstance()->GetCreator(key); + auto kernel = creator(inputs, outputs, reinterpret_cast(param), ctx, key); + ASSERT_NE(kernel, nullptr); + + ASSERT_EQ(kernel->Prepare(), lite::RET_OK); + ASSERT_EQ(kernel->Run(), lite::RET_OK); + + std::vector correct(num); + for (int i = 0; i < num; ++i) { + correct[i] = static_cast(i); + } + ASSERT_EQ(0, CompareOutputData(reinterpret_cast(outputs[0]->MutableData()), correct.data(), num)); + + UninitDSPRuntime(); + delete ctx; + for (auto t : outputs) { + delete t; + } + delete kernel; +} + +TEST_F(TestDSP_Range, Range_FT78_Fp64) { + InitDSPRuntime(); + std::vector inputs; + std::vector outputs; + + std::vector output_shape = {64}; + int num = output_shape[0]; + + auto param = reinterpret_cast(malloc(sizeof(RangeParameter))); + ASSERT_NE(param, nullptr); + std::memset(param, 0, sizeof(RangeParameter)); + param->start_ = -32; + param->limit_ = 32; + param->delta_ = 1; + param->dtype_ = static_cast(kNumberTypeFloat64); + + auto output = new lite::Tensor(kNumberTypeFloat64, output_shape, mindspore::NHWC, lite::Category::CONST_TENSOR); + output->MallocData(allocator_); + outputs.push_back(output); + std::fill_n(reinterpret_cast(output->MutableData()), num, 0.0); + + auto ctx = new lite::InnerContext; + ASSERT_EQ(lite::RET_OK, ctx->Init()); + + kernel::KernelKey key = {kernel::KERNEL_ARCH::kDSP, kNumberTypeFloat64, NHWC, schema::PrimitiveType_Range}; + auto creator = KernelRegistry::GetInstance()->GetCreator(key); + auto kernel = creator(inputs, outputs, reinterpret_cast(param), ctx, key); + ASSERT_NE(kernel, nullptr); + + ASSERT_EQ(kernel->Prepare(), lite::RET_OK); + ASSERT_EQ(kernel->Run(), lite::RET_OK); + + std::vector correct(num); + for (int i = 0; i < num; ++i) { + correct[i] = static_cast(i - 32); + } + ASSERT_EQ(0, CompareOutputData(reinterpret_cast(outputs[0]->MutableData()), correct.data(), num, 1e-6)); + + UninitDSPRuntime(); + delete ctx; + for (auto t : outputs) { + delete t; + } + delete kernel; +} + +TEST_F(TestDSP_Range, Range_FT78_Int32) { + InitDSPRuntime(); + std::vector inputs; + std::vector outputs; + + std::vector output_shape = {100}; + int num = output_shape[0]; + + auto param = reinterpret_cast(malloc(sizeof(RangeParameter))); + ASSERT_NE(param, nullptr); + std::memset(param, 0, sizeof(RangeParameter)); + param->start_ = 0; + param->limit_ = 100; + param->delta_ = 1; + param->dtype_ = static_cast(kNumberTypeInt32); + + auto output = new lite::Tensor(kNumberTypeInt32, output_shape, mindspore::NHWC, lite::Category::CONST_TENSOR); + output->MallocData(allocator_); + outputs.push_back(output); + std::fill_n(reinterpret_cast(output->MutableData()), num, 0); + + auto ctx = new lite::InnerContext; + ASSERT_EQ(lite::RET_OK, ctx->Init()); + + kernel::KernelKey key = {kernel::KERNEL_ARCH::kDSP, kNumberTypeInt32, NHWC, schema::PrimitiveType_Range}; + auto creator = KernelRegistry::GetInstance()->GetCreator(key); + auto kernel = creator(inputs, outputs, reinterpret_cast(param), ctx, key); + ASSERT_NE(kernel, nullptr); + + ASSERT_EQ(kernel->Prepare(), lite::RET_OK); + ASSERT_EQ(kernel->Run(), lite::RET_OK); + + std::vector correct(num); + for (int i = 0; i < num; ++i) { + correct[i] = i; + } + ASSERT_EQ(0, CompareOutputData(reinterpret_cast(outputs[0]->MutableData()), correct.data(), num)); + + UninitDSPRuntime(); + delete ctx; + for (auto t : outputs) { + delete t; + } + delete kernel; +} + +TEST_F(TestDSP_Range, Range_FT78_Int16) { + InitDSPRuntime(); + std::vector inputs; + std::vector outputs; + + std::vector output_shape = {50}; + int num = output_shape[0]; + + auto param = reinterpret_cast(malloc(sizeof(RangeParameter))); + ASSERT_NE(param, nullptr); + std::memset(param, 0, sizeof(RangeParameter)); + param->start_ = -3; + param->limit_ = 97; + param->delta_ = 2; + param->dtype_ = static_cast(kNumberTypeInt16); + + auto output = new lite::Tensor(kNumberTypeInt16, output_shape, mindspore::NHWC, lite::Category::CONST_TENSOR); + output->MallocData(allocator_); + outputs.push_back(output); + std::fill_n(reinterpret_cast(output->MutableData()), num, static_cast(0)); + + auto ctx = new lite::InnerContext; + ASSERT_EQ(lite::RET_OK, ctx->Init()); + + kernel::KernelKey key = {kernel::KERNEL_ARCH::kDSP, kNumberTypeInt16, NHWC, schema::PrimitiveType_Range}; + auto creator = KernelRegistry::GetInstance()->GetCreator(key); + auto kernel = creator(inputs, outputs, reinterpret_cast(param), ctx, key); + ASSERT_NE(kernel, nullptr); + + ASSERT_EQ(kernel->Prepare(), lite::RET_OK); + ASSERT_EQ(kernel->Run(), lite::RET_OK); + + std::vector correct(num); + int16_t value = -3; + for (int i = 0; i < num; ++i) { + correct[i] = value; + value = static_cast(value + 2); + } + ASSERT_EQ(0, CompareOutputData(reinterpret_cast(outputs[0]->MutableData()), correct.data(), num)); + + UninitDSPRuntime(); + delete ctx; + for (auto t : outputs) { + delete t; + } + delete kernel; +} + +TEST_F(TestDSP_Range, Range_FT78_Int8) { + InitDSPRuntime(); + std::vector inputs; + std::vector outputs; + + std::vector output_shape = {40}; + int num = output_shape[0]; + + auto param = reinterpret_cast(malloc(sizeof(RangeParameter))); + ASSERT_NE(param, nullptr); + std::memset(param, 0, sizeof(RangeParameter)); + param->start_ = -20; + param->limit_ = 20; + param->delta_ = 1; + param->dtype_ = static_cast(kNumberTypeInt8); + + auto output = new lite::Tensor(kNumberTypeInt8, output_shape, mindspore::NHWC, lite::Category::CONST_TENSOR); + output->MallocData(allocator_); + outputs.push_back(output); + std::fill_n(reinterpret_cast(output->MutableData()), num, static_cast(0)); + + auto ctx = new lite::InnerContext; + ASSERT_EQ(lite::RET_OK, ctx->Init()); + + kernel::KernelKey key = {kernel::KERNEL_ARCH::kDSP, kNumberTypeInt8, NHWC, schema::PrimitiveType_Range}; + auto creator = KernelRegistry::GetInstance()->GetCreator(key); + auto kernel = creator(inputs, outputs, reinterpret_cast(param), ctx, key); + ASSERT_NE(kernel, nullptr); + + ASSERT_EQ(kernel->Prepare(), lite::RET_OK); + ASSERT_EQ(kernel->Run(), lite::RET_OK); + + std::vector correct(num); + for (int i = 0; i < num; ++i) { + correct[i] = static_cast(i - 20); + } + ASSERT_EQ(0, CompareOutputData(reinterpret_cast(outputs[0]->MutableData()), correct.data(), num)); + + UninitDSPRuntime(); + delete ctx; + for (auto t : outputs) { + delete t; + } + delete kernel; +} +#endif + +} // namespace mindspore::lite::dsp::test -- Gitee