提交 bd9972f4 编写于 作者: M mindspore-ci-bot 提交者: Gitee

!4274 add quantize resize bilinear and nearest neighbor

Merge pull request !4274 from zhaozhenlong/lite/op/int8/resize
......@@ -44,8 +44,10 @@ int Pad::InferShape(std::vector<tensor::Tensor *> inputs, std::vector<tensor::Te
}
auto input_shape = input->shape();
std::vector<int> output_shape;
MS_ASSERT(input->shape().size() <= kInputRank);
for (size_t i = 0; i < input_shape.size(); i++) {
auto shape = input_shape[i] + (*paddings)[2 * i] + (*paddings)[2 * i + 1];
auto paddings_index = i + kInputRank - input_shape.size();
auto shape = input_shape[i] + (*paddings)[2 * paddings_index] + (*paddings)[2 * paddings_index + 1];
output_shape.push_back(shape);
}
......
......@@ -30,6 +30,8 @@ int Resize::InferShape(std::vector<tensor::Tensor *> inputs_, std::vector<tensor
if (input == nullptr) {
return RET_NULL_PTR;
}
MS_ASSERT(input->shape().size() == kInputRank);
auto output = outputs_.front();
if (output == nullptr) {
return RET_NULL_PTR;
......
......@@ -57,7 +57,7 @@
#include "src/runtime/kernel/arm/nnacl/unique.h"
#include "src/runtime/kernel/arm/nnacl/scale.h"
#include "src/runtime/kernel/arm/nnacl/fp32/gatherNd.h"
#include "src/runtime/kernel/arm/nnacl/resize.h"
#include "src/runtime/kernel/arm/nnacl/resize_parameter.h"
#include "src/runtime/kernel/arm/nnacl/scatter_nd.h"
#include "src/runtime/kernel/arm/nnacl/batch_to_space.h"
#include "src/runtime/kernel/arm/nnacl/fp32/crop.h"
......@@ -1023,7 +1023,7 @@ OpParameter *PopulateResizeParameter(const lite::Primitive *primitive) {
}
resize_param->op_parameter_.type_ = primitive->Type();
auto param = primitive->Value()->value_as_Resize();
resize_param->method_ = param->method();
resize_param->method_ = static_cast<int>(param->method());
resize_param->new_height_ = param->newHeight();
resize_param->new_width_ = param->newWidth();
resize_param->align_corners_ = param->alignCorners();
......
/**
* 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 <vector>
#include "schema/model_generated.h"
#include "src/kernel_registry.h"
#include "include/errorcode.h"
#include "src/runtime/kernel/arm/base/resize_base.h"
#include "src/runtime/kernel/arm/fp32/resize.h"
#include "src/runtime/kernel/arm/int8/resize_int8.h"
using mindspore::lite::KernelRegistrar;
using mindspore::lite::RET_ERROR;
using mindspore::lite::RET_INVALID_OP_ATTR;
using mindspore::lite::RET_NULL_PTR;
using mindspore::lite::RET_OK;
namespace mindspore::kernel {
namespace {
constexpr int kInputNum = 1;
constexpr int kOutputNum = 1;
constexpr int kRank = 4;
} // namespace
int ResizeBaseCPUKernel::CheckParameters() {
auto parameter = reinterpret_cast<ResizeParameter *>(opParameter);
if (parameter == nullptr) {
MS_LOG(ERROR) << "cast ResizeParameter failed.";
return RET_NULL_PTR;
}
method_ = parameter->method_;
if (method_ != schema::ResizeMethod_BILINEAR && method_ != schema::ResizeMethod_NEAREST_NEIGHBOR) {
MS_LOG(ERROR) << "Resize method should be bilinear or nearest_neighbor, but got " << method_;
return RET_INVALID_OP_ATTR;
}
new_height_ = parameter->new_height_;
if (new_height_ < 1) {
MS_LOG(ERROR) << "Resize new_height should >= 1, but got " << new_height_;
return RET_INVALID_OP_ATTR;
}
new_width_ = parameter->new_width_;
if (new_width_ < 1) {
MS_LOG(ERROR) << "Resize new_width should >= 1, but got " << new_width_;
return RET_INVALID_OP_ATTR;
}
align_corners_ = parameter->align_corners_;
preserve_aspect_ratio = parameter->preserve_aspect_ratio_;
if (preserve_aspect_ratio) {
MS_LOG(ERROR) << "Resize currently not support preserve_aspect_ratio true";
return RET_ERROR;
}
return RET_OK;
}
int ResizeBaseCPUKernel::CheckInputsOuputs() {
if (inputs_.size() != kInputNum) {
MS_LOG(ERROR) << "Resize input num should be " << kInputNum << ", but got " << inputs_.size();
return RET_ERROR;
}
auto input = inputs_.at(0);
if (input == nullptr) {
return RET_NULL_PTR;
}
if (outputs_.size() != kOutputNum) {
MS_LOG(ERROR) << "Resize output num should be " << kOutputNum << ", but got " << outputs_.size();
return RET_ERROR;
}
auto output = outputs_.at(0);
if (output == nullptr) {
return RET_NULL_PTR;
}
return RET_OK;
}
int ResizeBaseCPUKernel::Init() {
auto ret = CheckParameters();
if (ret != RET_OK) {
return ret;
}
ret = CheckInputsOuputs();
if (ret != RET_OK) {
return ret;
}
auto input = inputs_.at(0);
auto input_shape = input->shape();
if (input_shape.size() != kRank) {
MS_LOG(ERROR) << "Resize op support input rank 4, got " << input_shape.size();
return RET_ERROR;
}
return RET_OK;
}
kernel::LiteKernel *CpuResizeFp32KernelCreator(const std::vector<lite::tensor::Tensor *> &inputs,
const std::vector<lite::tensor::Tensor *> &outputs,
OpParameter *opParameter, const lite::Context *ctx,
const kernel::KernelKey &desc, const lite::Primitive *primitive) {
if (opParameter == nullptr) {
MS_LOG(ERROR) << "Input opParameter is nullptr!";
return nullptr;
}
MS_ASSERT(desc.type == schema::PrimitiveType_Resize);
auto *kernel = new (std::nothrow) ResizeCPUKernel(opParameter, inputs, outputs, ctx, primitive);
if (kernel == nullptr) {
MS_LOG(ERROR) << "new ResizeCPUKernel fail!";
return nullptr;
}
auto ret = kernel->Init();
if (ret != RET_OK) {
delete kernel;
MS_LOG(ERROR) << "Init kernel failed, name: " << opParameter->name_ << ", type: "
<< schema::EnumNamePrimitiveType(static_cast<schema::PrimitiveType>(opParameter->type_));
return nullptr;
}
return kernel;
}
kernel::LiteKernel *CpuResizeInt8KernelCreator(const std::vector<lite::tensor::Tensor *> &inputs,
const std::vector<lite::tensor::Tensor *> &outputs,
OpParameter *opParameter, const lite::Context *ctx,
const kernel::KernelKey &desc, const lite::Primitive *primitive) {
if (opParameter == nullptr) {
MS_LOG(ERROR) << "Input opParameter is nullptr!";
return nullptr;
}
MS_ASSERT(desc.type == schema::PrimitiveType_Resize);
auto *kernel = new (std::nothrow) ResizeInt8CPUKernel(opParameter, inputs, outputs, ctx, primitive);
if (kernel == nullptr) {
MS_LOG(ERROR) << "new ResizeCPUKernel fail!";
return nullptr;
}
auto ret = kernel->Init();
if (ret != RET_OK) {
delete kernel;
MS_LOG(ERROR) << "Init kernel failed, name: " << opParameter->name_ << ", type: "
<< schema::EnumNamePrimitiveType(static_cast<schema::PrimitiveType>(opParameter->type_));
return nullptr;
}
return kernel;
}
REG_KERNEL(kCPU, kNumberTypeInt8, PrimitiveType_Resize, CpuResizeInt8KernelCreator)
REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Resize, CpuResizeFp32KernelCreator)
} // namespace mindspore::kernel
/**
* 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_RUNTIME_KERNEL_ARM_BASE_RESIZE_BASE_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_BASE_RESIZE_BASE_H_
#include <vector>
#include "src/lite_kernel.h"
#include "nnacl/resize_parameter.h"
using mindspore::schema::PrimitiveType_Resize;
using mindspore::schema::ResizeMethod;
namespace mindspore::kernel {
class ResizeBaseCPUKernel : public LiteKernel {
public:
ResizeBaseCPUKernel(OpParameter *parameter, const std::vector<lite::tensor::Tensor *> &inputs,
const std::vector<lite::tensor::Tensor *> &outputs, const lite::Context *ctx,
const lite::Primitive *primitive)
: LiteKernel(parameter, inputs, outputs, ctx, primitive), context_(ctx) {}
~ResizeBaseCPUKernel() = default;
int Init() override;
int ReSize() override { return 0; };
protected:
const lite::Context *context_;
int method_;
int64_t new_height_;
int64_t new_width_;
bool align_corners_;
bool preserve_aspect_ratio;
private:
int CheckParameters();
int CheckInputsOuputs();
};
} // namespace mindspore::kernel
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_BASE_RESIZE_BASE_H_
......@@ -15,136 +15,33 @@
*/
#include "src/runtime/kernel/arm/fp32/resize.h"
#include <vector>
#include "schema/model_generated.h"
#include "src/kernel_registry.h"
#include "src/runtime/kernel/arm/nnacl/resize.h"
#include "src/runtime/kernel/arm/nnacl/pack.h"
#include "nnacl/fp32/resize.h"
#include "include/errorcode.h"
#include "src/runtime/runtime_api.h"
using mindspore::kernel::KERNEL_ARCH::kCPU;
using mindspore::lite::KernelRegistrar;
using mindspore::lite::RET_ERROR;
using mindspore::lite::RET_INVALID_OP_ATTR;
using mindspore::lite::RET_NULL_PTR;
using mindspore::lite::RET_OK;
namespace mindspore::kernel {
namespace {
constexpr int kInputNum = 1;
constexpr int kOutputNum = 1;
constexpr int kRank = 4;
} // namespace
int ResizeCPUKernel::CheckParameters() {
auto parameter = reinterpret_cast<ResizeParameter *>(opParameter);
if (parameter == nullptr) {
MS_LOG(ERROR) << "cast ResizeParameter failed.";
return RET_NULL_PTR;
}
method_ = parameter->method_;
if (method_ != schema::ResizeMethod_BILINEAR && method_ != schema::ResizeMethod_NEAREST_NEIGHBOR) {
MS_LOG(ERROR) << "Resize method should be bilinear or nearest_neighbor, but got " << method_;
return RET_INVALID_OP_ATTR;
}
new_height_ = parameter->new_height_;
if (new_height_ < 1) {
MS_LOG(ERROR) << "Resize new_height should >= 1, but got " << new_height_;
return RET_INVALID_OP_ATTR;
}
new_width_ = parameter->new_width_;
if (new_width_ < 1) {
MS_LOG(ERROR) << "Resize new_width should >= 1, but got " << new_width_;
return RET_INVALID_OP_ATTR;
}
align_corners_ = parameter->align_corners_;
preserve_aspect_ratio = parameter->preserve_aspect_ratio_;
if (preserve_aspect_ratio) {
MS_LOG(ERROR) << "Resize currently not support preserve_aspect_ratio true";
return RET_ERROR;
}
return RET_OK;
}
int ResizeCPUKernel::CheckInputsOuputs() {
if (inputs_.size() != kInputNum) {
MS_LOG(ERROR) << "Resize input num should be " << kInputNum << ", but got " << inputs_.size();
return RET_ERROR;
}
auto input = inputs_.at(0);
if (input == nullptr) {
return RET_NULL_PTR;
}
if (outputs_.size() != kOutputNum) {
MS_LOG(ERROR) << "Resize output num should be " << kOutputNum << ", but got " << outputs_.size();
return RET_ERROR;
}
auto output = outputs_.at(0);
if (output == nullptr) {
return RET_NULL_PTR;
}
return RET_OK;
}
int ResizeCPUKernel::Init() {
if (context_->infer_shape_interrupt_ && !context_->running_) {
SetNeedReInit();
return RET_OK;
}
auto ret = CheckParameters();
if (ret != RET_OK) {
return ret;
}
ret = CheckInputsOuputs();
auto ret = ResizeBaseCPUKernel::Init();
if (ret != RET_OK) {
return ret;
}
auto output = outputs_.at(0);
auto input = inputs_.at(0);
auto input_shape = input->shape();
if (input_shape.size() != kRank) {
return RET_ERROR;
}
schema::Format execute_format;
size_t exec_input_size;
switch (method_) {
case schema::ResizeMethod_BILINEAR: {
execute_format = schema::Format_NC4HW4;
output->SetFormat(schema::Format_NC4HW4);
exec_input_size = input->ElementsC4Num();
break;
}
case schema::ResizeMethod_NEAREST_NEIGHBOR: {
execute_format = schema::Format_NHWC;
output->SetFormat(schema::Format_NHWC);
exec_input_size = input->ElementsNum();
break;
}
default: {
MS_LOG(ERROR) << "Resize unknown method " << method_;
return RET_ERROR;
}
}
auto input_format = input->GetFormat();
if (input_format != execute_format) {
auto input_type = input->data_type();
layout_convertor_ = LayoutTransform(input_type, input_format, execute_format);
exec_input_data_ = reinterpret_cast<float *>(malloc(exec_input_size * sizeof(float)));
if (exec_input_data_ == nullptr) {
return RET_NULL_PTR;
}
if (!InferShapeDone()) {
return RET_OK;
}
return RET_OK;
return ReSize();
}
int ResizeImpl(int task_id, LiteParallelGroupEnv *penv, void *cdata) {
auto resize = reinterpret_cast<ResizeCPUKernel *>(cdata);
auto error_code = resize->RunImpl(task_id);
if (error_code != NNACL_OK) {
if (error_code != RET_OK) {
MS_LOG(ERROR) << "Resize Run error task_id[" << task_id << "] error_code[" << error_code << "]";
return RET_ERROR;
}
......@@ -162,47 +59,30 @@ int ResizeCPUKernel::RunImpl(int task_id) {
return RET_NULL_PTR;
}
auto input_shape = input->shape();
if (input_shape.size() != kRank) {
return RET_ERROR;
}
if (context_ == nullptr) {
return RET_NULL_PTR;
}
int ret = 0;
switch (method_) {
case schema::ResizeMethod_BILINEAR: {
if (layout_convertor_ != nullptr) {
layout_convertor_(input_data, exec_input_data_, input->Batch(), input->Height() * input->Width(),
input->Channel());
ret = ResizeBilinear(exec_input_data_, output_data, inputs_[0]->shape().data(), outputs_[0]->shape().data(),
case static_cast<int>(schema::ResizeMethod_BILINEAR): {
ret = ResizeBilinear(input_data, output_data, input_shape.data(), outputs_[0]->shape().data(),
align_corners_, task_id, context_->thread_num_);
} else {
ret = ResizeBilinear(input_data, output_data, inputs_[0]->shape().data(), outputs_[0]->shape().data(),
align_corners_, task_id, context_->thread_num_);
}
break;
}
case schema::ResizeMethod_NEAREST_NEIGHBOR: {
case static_cast<int>(schema::ResizeMethod_NEAREST_NEIGHBOR): {
if (align_corners_) {
MS_LOG(ERROR) << "ResizeNearestNeighbor not support align_corners.";
return RET_ERROR;
}
if (layout_convertor_ != nullptr) {
layout_convertor_(input_data, exec_input_data_, input->Batch(), input->Height() * input->Width(),
input->Channel());
ret = ResizeNearestNeighbor(exec_input_data_, output_data, input_shape.data(), outputs_[0]->shape().data(),
task_id, context_->thread_num_);
} else {
ret = ResizeNearestNeighbor(input_data, output_data, input_shape.data(), outputs_[0]->shape().data(), task_id,
ret = ResizeNearestNeighbor(input_data, output_data, input_shape.data(), outputs_[0]->shape().data(), task_id,
context_->thread_num_);
}
break;
}
case schema::ResizeMethod_UNKNOW:
default: {
MS_LOG(ERROR) << "Resize unknown method " << method_;
ret = NNACL_ERR;
ret = RET_ERROR;
}
}
return ret;
......@@ -221,31 +101,4 @@ int ResizeCPUKernel::Run() {
}
return RET_OK;
}
kernel::LiteKernel *CpuResizeFp32KernelCreator(const std::vector<lite::tensor::Tensor *> &inputs,
const std::vector<lite::tensor::Tensor *> &outputs,
OpParameter *opParameter, const lite::Context *ctx,
const kernel::KernelKey &desc, const lite::Primitive *primitive) {
if (opParameter == nullptr) {
MS_LOG(ERROR) << "Input opParameter is nullptr!";
return nullptr;
}
MS_ASSERT(desc.type == schema::PrimitiveType_Resize);
auto *kernel = new (std::nothrow) ResizeCPUKernel(opParameter, inputs, outputs, ctx, primitive);
if (kernel == nullptr) {
MS_LOG(ERROR) << "new ResizeCPUKernel fail!";
return nullptr;
}
auto ret = kernel->Init();
if (ret != RET_OK) {
delete kernel;
MS_LOG(ERROR) << "Init kernel failed, name: " << opParameter->name_ << ", type: "
<< schema::EnumNamePrimitiveType(static_cast<schema::PrimitiveType>(opParameter->type_));
return nullptr;
}
return kernel;
}
REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Resize, CpuResizeFp32KernelCreator)
} // namespace mindspore::kernel
......@@ -18,47 +18,25 @@
#include <vector>
#include "src/lite_kernel.h"
#include "src/runtime/kernel/arm/nnacl/resize.h"
#include "src/runtime/kernel/arm/base/layout_transform.h"
#include "src/runtime/kernel/arm/base/resize_base.h"
using mindspore::schema::PrimitiveType_Resize;
using mindspore::schema::ResizeMethod;
namespace mindspore::kernel {
class ResizeCPUKernel : public LiteKernel {
class ResizeCPUKernel : public ResizeBaseCPUKernel {
public:
ResizeCPUKernel(OpParameter *parameter, const std::vector<lite::tensor::Tensor *> &inputs,
const std::vector<lite::tensor::Tensor *> &outputs, const lite::Context *ctx,
const lite::Primitive *primitive)
: LiteKernel(parameter, inputs, outputs, ctx, primitive), context_(ctx) {}
: ResizeBaseCPUKernel(parameter, inputs, outputs, ctx, primitive) {}
~ResizeCPUKernel() {
if (exec_input_data_ != nullptr) {
free(exec_input_data_);
exec_input_data_ = nullptr;
}
}
~ResizeCPUKernel() = default;
int Init() override;
int ReSize() override { return 0; };
int Run() override;
int RunImpl(int task_id);
protected:
const lite::Context *context_;
private:
int CheckParameters();
int CheckInputsOuputs();
private:
ResizeMethod method_;
int64_t new_height_;
int64_t new_width_;
bool align_corners_;
bool preserve_aspect_ratio;
LayoutConvertor layout_convertor_ = nullptr;
float *exec_input_data_ = nullptr;
};
} // namespace mindspore::kernel
......
/**
* 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 <vector>
#include "schema/model_generated.h"
#include "src/kernel_registry.h"
#include "nnacl/int8/resize.h"
#include "include/errorcode.h"
#include "src/runtime/kernel/arm/int8/resize_int8.h"
#include "src/runtime/runtime_api.h"
using mindspore::kernel::KERNEL_ARCH::kCPU;
using mindspore::lite::KernelRegistrar;
using mindspore::lite::RET_ERROR;
using mindspore::lite::RET_INVALID_OP_ATTR;
using mindspore::lite::RET_NULL_PTR;
using mindspore::lite::RET_OK;
namespace mindspore::kernel {
namespace {
constexpr int kInputNum = 1;
constexpr int kOutputNum = 1;
constexpr size_t kRank = 4;
} // namespace
int ResizeInt8CPUKernel::Init() {
auto ret = ResizeBaseCPUKernel::Init();
if (ret != RET_OK) {
return ret;
}
quant_in_ = new (std::nothrow) QuantArg;
MS_ASSERT(quant_in_);
quant_out_ = new (std::nothrow) QuantArg;
MS_ASSERT(quant_out_);
auto input = inputs_.at(0);
quant_in_->zp_ = input->GetQuantParams().front().zeroPoint;
quant_in_->scale_ = input->GetQuantParams().front().scale;
auto output = outputs_.at(0);
quant_out_->zp_ = output->GetQuantParams().front().zeroPoint;
quant_out_->scale_ = output->GetQuantParams().front().scale;
multiplier_ = new (std::nothrow) QuantMulArg;
MS_ASSERT(multiplier_);
QuantizeRoundParameter(quant_in_->scale_ / quant_out_->scale_, &multiplier_->multiplier_, &multiplier_->left_shift_,
&multiplier_->right_shift_);
if (!InferShapeDone()) {
return RET_OK;
}
return ReSize();
}
int ResizeInt8Impl(int task_id, LiteParallelGroupEnv *penv, void *cdata) {
auto resize = reinterpret_cast<ResizeInt8CPUKernel *>(cdata);
auto error_code = resize->RunImpl(task_id);
if (error_code != RET_OK) {
MS_LOG(ERROR) << "Resize Run error task_id[" << task_id << "] error_code[" << error_code << "]";
return RET_ERROR;
}
return RET_OK;
}
int ResizeInt8CPUKernel::RunImpl(int task_id) {
auto input = inputs_.at(0);
auto input_data = reinterpret_cast<const int8_t *>(input->Data());
if (input_data == nullptr) {
return RET_NULL_PTR;
}
auto output_data = reinterpret_cast<int8_t *>(outputs_.at(0)->Data());
if (output_data == nullptr) {
return RET_NULL_PTR;
}
auto input_shape = input->shape();
if (context_ == nullptr) {
return RET_NULL_PTR;
}
int ret = 0;
switch (method_) {
case static_cast<int>(schema::ResizeMethod_BILINEAR): {
ret = ResizeBilinearInt8(input_data, output_data, input_shape.data(), outputs_[0]->shape().data(), align_corners_,
quant_in_, quant_out_, multiplier_, task_id, context_->thread_num_);
break;
}
case static_cast<int>(schema::ResizeMethod_NEAREST_NEIGHBOR): {
bool same_zp = quant_in_->zp_ == quant_out_->zp_;
bool same_scale = abs(quant_out_->scale_ - quant_in_->scale_) < 1e-6;
if (same_zp && same_scale) {
ret = ResizeNearestNeighborInt8Simple(input_data, output_data, input_shape.data(), outputs_[0]->shape().data(),
align_corners_, task_id, context_->thread_num_);
} else {
ret =
ResizeNearestNeighborInt8(input_data, output_data, input_shape.data(), outputs_[0]->shape().data(),
align_corners_, multiplier_, quant_in_, quant_out_, task_id, context_->thread_num_);
}
break;
}
case schema::ResizeMethod_UNKNOW:
default: {
MS_LOG(ERROR) << "Resize unknown method " << method_;
ret = RET_ERROR;
}
}
return ret;
}
int ResizeInt8CPUKernel::Run() {
auto ret = Prepare();
if (ret != RET_OK) {
MS_LOG(ERROR) << "Prepare failed.";
return RET_ERROR;
}
int error_code = LiteBackendParallelLaunch(ResizeInt8Impl, this, context_->thread_num_);
if (error_code != RET_OK) {
MS_LOG(ERROR) << "Resize run error, error_code[" << error_code << "]";
return RET_ERROR;
}
return RET_OK;
}
} // namespace mindspore::kernel
/**
* 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_RUNTIME_KERNEL_ARM_INT8_RESIZE_INT8_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_INT8_RESIZE_INT8_H_
#include <vector>
#include "src/lite_kernel.h"
#include "src/runtime/kernel/arm/base/resize_base.h"
#include "nnacl/quantization/quantize.h"
using mindspore::schema::PrimitiveType_Resize;
using mindspore::schema::ResizeMethod;
namespace mindspore::kernel {
class ResizeInt8CPUKernel : public ResizeBaseCPUKernel {
public:
ResizeInt8CPUKernel(OpParameter *parameter, const std::vector<lite::tensor::Tensor *> &inputs,
const std::vector<lite::tensor::Tensor *> &outputs, const lite::Context *ctx,
const lite::Primitive *primitive)
: ResizeBaseCPUKernel(parameter, inputs, outputs, ctx, primitive) {}
~ResizeInt8CPUKernel() {
delete quant_out_;
quant_out_ = nullptr;
delete quant_in_;
quant_in_ = nullptr;
delete multiplier_;
multiplier_ = nullptr;
}
int Init() override;
int ReSize() override { return 0; };
int Run() override;
int RunImpl(int task_id);
private:
QuantArg *quant_in_;
QuantArg *quant_out_;
QuantMulArg *multiplier_;
};
} // namespace mindspore::kernel
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_INT8_RESIZE_INT8_H_
......@@ -14,20 +14,20 @@
* limitations under the License.
*/
#include <math.h>
#include "nnacl/resize.h"
#include "nnacl/fp32/resize.h"
#include "nnacl/common_func.h"
#include "nnacl/errorcode.h"
int ResizeBilinear(const float *input_data, float *output_data, const int *input_shape, const int *output_shape,
bool align_corners, int tid, int thread_num) {
if (input_data == nullptr || output_data == nullptr || input_shape == nullptr || output_shape == nullptr) {
return NNACL_NULL_PTR;
}
// nhwc (memory layout is nc4hw4)
int n = input_shape[0];
int in_n = input_shape[0];
int in_h = input_shape[1];
int in_w = input_shape[2];
int channel = input_shape[3];
int c4 = UP_DIV(channel, C4NUM);
int in_c = input_shape[3];
int new_height = output_shape[1];
int new_width = output_shape[2];
......@@ -40,67 +40,61 @@ int ResizeBilinear(const float *input_data, float *output_data, const int *input
width_scale = (float)(in_w - 1) / (new_width - 1);
}
int o[5]; // n c4 h w 4
for (o[0] = 0; o[0] < n; o[0]++) {
for (o[1] = tid; o[1] < c4; o[1] += thread_num) {
for (o[2] = 0; o[2] < new_height; o[2]++) {
float actual_y = (float)(o[2]) * height_scale;
int y_left = (int)(floor(actual_y));
int y_right = y_left + 1 < in_h ? (y_left + 1) : (in_h - 1);
float y_right_weight = actual_y - (float)(y_left);
float y_left_weight = 1.0 - y_right_weight;
for (o[3] = 0; o[3] < new_width; o[3]++) {
float actual_x = (float)(o[3]) * width_scale;
int x_left = (int)(floor(actual_x));
int x_right = x_left + 1 < in_w ? (x_left + 1) : (in_w - 1);
float x_right_weight = actual_x - (float)(x_left);
float x_left_weight = 1.0 - x_right_weight;
auto input_base_offset = (((o[0] * c4 + o[1]) * in_h + y_left) * in_w + x_left) * C4NUM;
auto output_base_offset = (((o[0] * c4 + o[1]) * new_height + o[2]) * new_width + o[3]) * C4NUM;
int in_offset_1_0 = (y_right - y_left) * in_w * C4NUM;
int in_offset_0_1 = (x_right - x_left) * C4NUM;
int n, h, w, c;
for (n = 0; n < in_n; n++) {
for (h = tid; h < new_height; h += thread_num) {
float actual_y = (float)h * height_scale;
int y_bottom = (int)(floor(actual_y));
int y_top = y_bottom + 1 < in_h ? (y_bottom + 1) : (in_h - 1);
float y_top_weight = actual_y - (float)(y_bottom);
float y_bottom_weight = 1.0f - y_top_weight;
for (w = 0; w < new_width; w++) {
float actual_x = (float)(w)*width_scale;
int x_left = (int)(floor(actual_x));
int x_right = x_left + 1 < in_w ? (x_left + 1) : (in_w - 1);
float x_right_weight = actual_x - (float)(x_left);
float x_left_weight = 1.0f - x_right_weight;
c = 0;
#ifdef ENABLE_NEON
float32x4_t x_l_weight = vdupq_n_f32(x_left_weight);
float32x4_t x_r_weight = vdupq_n_f32(x_right_weight);
float32x4_t y_l_weight = vdupq_n_f32(y_left_weight);
float32x4_t y_r_weight = vdupq_n_f32(y_right_weight);
for (; c <= in_c - 4; c += 4) {
float32x4_t bottom_left = vld1q_f32(input_data + offset(input_shape, n, y_bottom, x_left, c));
float32x4_t bottom_right = vld1q_f32(input_data + offset(input_shape, n, y_bottom, x_right, c));
float32x4_t top_left = vld1q_f32(input_data + offset(input_shape, n, y_top, x_left, c));
float32x4_t top_right = vld1q_f32(input_data + offset(input_shape, n, y_top, x_right, c));
float32x4_t input_yl_xl = vld1q_f32(input_data + input_base_offset);
float32x4_t input_yr_xl = vld1q_f32(input_data + input_base_offset + in_offset_1_0);
float32x4_t input_yl_xr = vld1q_f32(input_data + input_base_offset + in_offset_0_1);
float32x4_t input_yr_xr = vld1q_f32(input_data + input_base_offset + in_offset_0_1 + in_offset_1_0);
float32x4_t y_top_w = vdupq_n_f32(y_top_weight);
float32x4_t y_bottom_w = vdupq_n_f32(y_bottom_weight);
float32x4_t x_left_w = vdupq_n_f32(x_left_weight);
float32x4_t x_right_w = vdupq_n_f32(x_right_weight);
float32x4_t interp_value = vdupq_n_f32(0.0);
float32x4_t interp_value_tmp = vmulq_f32(input_yl_xl, y_l_weight);
interp_value_tmp = vmulq_f32(interp_value_tmp, x_l_weight);
interp_value = vaddq_f32(interp_value, interp_value_tmp);
float32x4_t tmp = vmulq_f32(bottom_left, y_bottom_w);
tmp = vmulq_f32(tmp, x_left_w);
interp_value = vaddq_f32(interp_value, tmp);
interp_value_tmp = vmulq_f32(input_yr_xl, y_r_weight);
interp_value_tmp = vmulq_f32(interp_value_tmp, x_l_weight);
interp_value = vaddq_f32(interp_value, interp_value_tmp);
tmp = vmulq_f32(bottom_right, y_bottom_w);
tmp = vmulq_f32(tmp, x_right_w);
interp_value = vaddq_f32(interp_value, tmp);
interp_value_tmp = vmulq_f32(input_yl_xr, y_l_weight);
interp_value_tmp = vmulq_f32(interp_value_tmp, x_r_weight);
interp_value = vaddq_f32(interp_value, interp_value_tmp);
tmp = vmulq_f32(top_left, y_top_w);
tmp = vmulq_f32(tmp, x_left_w);
interp_value = vaddq_f32(interp_value, tmp);
interp_value_tmp = vmulq_f32(input_yr_xr, y_r_weight);
interp_value_tmp = vmulq_f32(interp_value_tmp, x_r_weight);
interp_value = vaddq_f32(interp_value, interp_value_tmp);
vst1q_f32(output_base_offset + output_data, interp_value);
#else
// 4 continuous data in a group;
for (o[4] = 0; o[4] < C4NUM; o[4]++) {
auto in_offset = input_base_offset + o[4];
auto output_offset = output_base_offset + o[4];
float interp_value =
input_data[in_offset] * y_left_weight * x_left_weight +
input_data[in_offset + in_offset_1_0] * y_right_weight * x_left_weight +
input_data[in_offset + in_offset_0_1] * y_left_weight * x_right_weight +
input_data[in_offset + in_offset_0_1 + in_offset_1_0] * y_right_weight * x_right_weight;
output_data[output_offset] = interp_value;
}
tmp = vmulq_f32(top_right, y_top_w);
tmp = vmulq_f32(tmp, x_right_w);
interp_value = vaddq_f32(interp_value, tmp);
vst1q_f32(output_data + offset(output_shape, n, h, w, c), interp_value);
}
#endif
for (; c < in_c; c++) {
auto bottom_left = input_data[offset(input_shape, n, y_bottom, x_left, c)];
auto bottom_right = input_data[offset(input_shape, n, y_bottom, x_right, c)];
auto top_left = input_data[offset(input_shape, n, y_top, x_left, c)];
auto top_right = input_data[offset(input_shape, n, y_top, x_right, c)];
float interp_value = bottom_left * y_bottom_weight * x_left_weight +
bottom_right * y_bottom_weight * x_right_weight +
top_left * y_top_weight * x_left_weight + top_right * y_top_weight * x_right_weight;
output_data[offset(output_shape, n, h, w, c)] = interp_value;
}
}
}
......@@ -118,10 +112,10 @@ int ResizeNearestNeighbor(const float *input_data, float *output_data, const int
for (batch = 0; batch < output_shape[0]; batch++) {
for (y = tid; y < output_shape[1]; y += thread_num) {
int actual_y = (int)(floor((float)(y) * height_scale));
int actual_y = (int)(floor((float)(y)*height_scale));
int input_y = actual_y < input_shape[1] ? actual_y : input_shape[1] - 1;
for (x = 0; x < output_shape[2]; x++) {
int actual_x = (int)(floor((float)(x) * width_scale));
int actual_x = (int)(floor((float)(x)*width_scale));
int input_x = actual_x < input_shape[2] ? actual_x : input_shape[2] - 1;
int in_offset = offset(input_shape, batch, input_y, input_x, 0);
int out_offset = offset(output_shape, batch, y, x, 0);
......@@ -132,4 +126,3 @@ int ResizeNearestNeighbor(const float *input_data, float *output_data, const int
return NNACL_OK;
}
......@@ -13,8 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_NNACL_RESIZE_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_NNACL_RESIZE_H_
#ifndef MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_NNACL_FP32_RESIZE_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_NNACL_FP32_RESIZE_H_
#ifdef ENABLE_NEON
#include <arm_neon.h>
......@@ -22,18 +22,6 @@
#include <memory.h>
#include "nnacl/op_base.h"
#include "schema/ops_generated.h"
#include "nnacl/errorcode.h"
using mindspore::schema::ResizeMethod;
typedef struct ResizeParameter {
OpParameter op_parameter_;
ResizeMethod method_;
int64_t new_height_;
int64_t new_width_;
bool align_corners_;
bool preserve_aspect_ratio_;
} ResizeParameter;
int ResizeBilinear(const float *input_data, float *output_data, const int *input_shape, const int *output_shape,
bool align_corners, int tid, int thread_num);
......@@ -41,5 +29,5 @@ int ResizeBilinear(const float *input_data, float *output_data, const int *input
int ResizeNearestNeighbor(const float *input_data, float *output_data, const int *input_shape, const int *output_shape,
int tid, int thread_num);
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_NNACL_RESIZE_H_
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_NNACL_FP32_RESIZE_H_
/**
* 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 <math.h>
#include "nnacl/int8/resize.h"
#include "nnacl/common_func.h"
#include "nnacl/quantization/fixed_point.h"
#include "nnacl/errorcode.h"
int ResizeBilinearInt8(const int8_t *input_data, int8_t *output_data, const int *input_shape, const int *output_shape,
const bool align_corners, QuantArg *quant_in, QuantArg *quant_out, const QuantMulArg *mul_arg,
int tid, int thread_num) {
if (input_data == nullptr || output_data == nullptr || input_shape == nullptr || output_shape == nullptr) {
return NNACL_NULL_PTR;
}
int32_t in_n = input_shape[0];
int32_t in_h = input_shape[1];
int32_t in_w = input_shape[2];
int32_t in_c = input_shape[3];
int32_t new_height = output_shape[1];
int32_t new_width = output_shape[2];
int32_t height_scale, width_scale;
ComputeScale(in_h, new_height, align_corners, &height_scale);
ComputeScale(in_w, new_width, align_corners, &width_scale);
int n, h, w, c;
for (n = 0; n < in_n; n++) {
for (h = tid; h < new_height; h += thread_num) {
// float actual_y = (float)h * height_scale;
int base_offset = 20;
int scaled_actual_y;
int bottom, top;
int scaled_bottom_weight, scaled_top_weight;
ComputeInterpolationArgs(h, height_scale, in_h, &scaled_actual_y, &bottom, &scaled_bottom_weight, &top,
&scaled_top_weight);
for (w = 0; w < new_width; w++) {
int scaled_actual_x;
int left, right;
int scaled_left_weight, scaled_right_weight;
ComputeInterpolationArgs(w, width_scale, in_w, &scaled_actual_x, &left, &scaled_left_weight, &right,
&scaled_right_weight);
for (c = 0; c < in_c; c++) {
const int64_t bottom_left_value =
(int64_t)(input_data[offset(input_shape, n, bottom, left, c)] - quant_in->zp_) * scaled_bottom_weight *
scaled_left_weight;
const int64_t bottom_right_value =
(int64_t)(input_data[offset(input_shape, n, bottom, right, c)] - quant_in->zp_) * scaled_bottom_weight *
scaled_right_weight;
const int64_t top_left_value = (int64_t)(input_data[offset(input_shape, n, top, left, c)] - quant_in->zp_) *
scaled_top_weight * scaled_left_weight;
const int64_t top_right_value = (int64_t)(input_data[offset(input_shape, n, top, right, c)] - quant_in->zp_) *
scaled_top_weight * scaled_right_weight;
const int64_t scaled_interp_value = bottom_left_value + bottom_right_value + top_left_value + top_right_value;
int32_t interp_value;
if (scaled_interp_value >= 0) {
interp_value = (scaled_interp_value + (1 << 19)) / (1 << 20);
} else {
interp_value = (scaled_interp_value - (1 << 19)) / (1 << 20);
}
const int out_interp_value =
MultiplyByQuantizedMultiplier(interp_value, mul_arg->multiplier_, mul_arg->left_shift_ + base_offset,
mul_arg->right_shift_ - base_offset) +
quant_out->zp_;
int8_t out_value;
out_value = out_interp_value > INT8_MAX ? INT8_MAX : out_interp_value;
out_value = out_value < INT8_MIN ? INT8_MIN : out_value;
output_data[offset(output_shape, n, h, w, c)] = out_value;
}
}
}
}
return NNACL_OK;
}
int ResizeNearestNeighborInt8Simple(const int8_t *input_data, int8_t *output_data, const int *input_shape,
const int *output_shape, const bool align_corners, int tid, int thread_num) {
int batch, y, x, c;
c = output_shape[3];
int in_h, in_w, new_height, new_width;
in_h = input_shape[1];
in_w = input_shape[2];
new_height = output_shape[1];
new_width = output_shape[2];
for (batch = 0; batch < output_shape[0]; batch++) {
for (y = tid; y < output_shape[1]; y += thread_num) {
int input_y;
ComputeNearestNeighborInt(y, in_h, new_height, align_corners, &input_y);
for (x = 0; x < output_shape[2]; x++) {
int input_x;
ComputeNearestNeighborInt(x, in_w, new_width, align_corners, &input_x);
int in_offset = offset(input_shape, batch, input_y, input_x, 0);
int out_offset = offset(output_shape, batch, y, x, 0);
memcpy(output_data + out_offset, input_data + in_offset, c * sizeof(int8_t));
}
}
}
return NNACL_OK;
}
void ComputeScale(const int32_t in_value, const int32_t out_value, const bool align_corners, int32_t *scale) {
*scale = (in_value * (1 << 10) + out_value / 2) / out_value;
if (align_corners && out_value > 1) {
*scale = ((in_value - 1) * (1 << 10) + (out_value - 1) / 2) / (out_value - 1);
}
}
void ComputeInterpolationArgs(const int32_t pos, const int32_t scale, const int32_t size, int32_t *scaled_pos,
int32_t *low, int32_t *scaled_low_weight, int32_t *high, int32_t *scaled_high_weight) {
*scaled_pos = pos * scale;
int scale_back = *scaled_pos / (1 << 10);
*low = scale_back > 0 ? scale_back : 0;
*scaled_low_weight = (1 << 10) - (*scaled_pos - (1 << 10) * (*low));
*high = scale_back + 1 < size ? scale_back + 1 : size - 1;
*scaled_high_weight = *scaled_pos - (1 << 10) * (*low);
}
void ComputeNearestNeighborInt(const int32_t pos, const int in_size, const int32_t new_size, const bool align_corners,
int32_t *nearest) {
*nearest = (in_size * pos) / new_size;
if (align_corners) {
*nearest = ((in_size - 1) * pos + (new_size - 1) / 2) / (new_size - 1);
}
*nearest = *nearest < in_size ? *nearest : in_size - 1;
}
int ResizeNearestNeighborInt8(const int8_t *input_data, int8_t *output_data, const int *input_shape,
const int *output_shape, const bool align_corners, const QuantMulArg *multiplier,
QuantArg *quant_in, QuantArg *quant_out, int tid, int thread_num) {
int base_offset = 20;
int32_t batch, y, x, c;
int32_t in_h, in_w, new_height, new_width;
in_h = input_shape[1];
in_w = input_shape[2];
new_height = output_shape[1];
new_width = output_shape[2];
for (batch = 0; batch < output_shape[0]; batch++) {
for (y = tid; y < output_shape[1]; y += thread_num) {
int input_y;
ComputeNearestNeighborInt(y, in_h, new_height, align_corners, &input_y);
for (x = 0; x < output_shape[2]; x++) {
int input_x;
ComputeNearestNeighborInt(x, in_w, new_width, align_corners, &input_x);
for (c = 0; c < output_shape[3]; c++) {
int in_offset = offset(input_shape, batch, input_y, input_x, c);
int out_offset = offset(output_shape, batch, y, x, c);
int32_t out_value = MultiplyByQuantizedMultiplier(
input_data[in_offset] - quant_in->zp_, multiplier->multiplier_,
multiplier->left_shift_ + base_offset, multiplier->right_shift_ - base_offset) +
quant_out->zp_;
out_value = out_value > INT8_MAX ? INT8_MAX : out_value;
out_value = out_value < INT8_MIN ? INT8_MIN : out_value;
output_data[out_offset] = (int8_t)out_value;
}
}
}
}
return NNACL_OK;
}
/**
* 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_RUNTIME_KERNEL_ARM_NNACL_INT8_RESIZE_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_NNACL_INT8_RESIZE_H_
#ifdef ENABLE_NEON
#include <arm_neon.h>
#endif
#include <memory.h>
#include "nnacl/op_base.h"
#include "nnacl/quantization/quantize.h"
#include "nnacl/resize_parameter.h"
int ResizeBilinearInt8(const int8_t *input_data, int8_t *output_data, const int *input_shape, const int *output_shape,
const bool align_corners, QuantArg *quant_in, QuantArg *quant_out, const QuantMulArg *mul_arg,
int tid, int thread_num);
int ResizeNearestNeighborInt8Simple(const int8_t *input_data, int8_t *output_data, const int *input_shape,
const int *output_shape, const bool align_corners, int tid, int thread_num);
int ResizeNearestNeighborInt8(const int8_t *input_data, int8_t *output_data, const int *input_shape,
const int *output_shape, const bool align_corners, const QuantMulArg *multiplier,
QuantArg *quant_in, QuantArg *quant_out, int tid, int thread_num);
void ComputeScale(const int32_t in_value, const int32_t out_value, const bool align_corners, int32_t *scale);
void ComputeInterpolationArgs(const int32_t pos, const int32_t scale, const int32_t size, int32_t *scaled_pos,
int32_t *low, int32_t *scaled_low_weight, int32_t *high, int32_t *scaled_high_weight);
void ComputeNearestNeighborInt(const int32_t pos, const int in_size, const int32_t new_size, const bool align_corners,
int32_t *nearest);
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_NNACL_INT8_RESIZE_H_
......@@ -167,6 +167,12 @@ typedef struct ReshapeQuantArg {
int output_activation_max_;
} ReshapeQuantArg;
typedef struct QuantMulArg {
int32_t multiplier_;
int left_shift_;
int right_shift_;
} QuantMulArg;
void QuantizeMultiplier(double double_multiplier, int32_t *quantized_multiplier, int *shift);
inline void QuantizeMultiplierSmallerThanOne(double double_multiplier, int32_t *quantized_multiplier,
......
/**
* 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_RUNTIME_KERNEL_ARM_NNACL_RESIZE_PARAMETER_H_
#define MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_NNACL_RESIZE_PARAMETER_H_
#include "src/runtime/kernel/arm/nnacl/op_base.h"
typedef struct ResizeParameter {
OpParameter op_parameter_;
int method_;
int64_t new_height_;
int64_t new_width_;
bool align_corners_;
bool preserve_aspect_ratio_;
} ResizeParameter;
#endif // MINDSPORE_LITE_SRC_RUNTIME_KERNEL_ARM_NNACL_RESIZE_PARAMETER_H_
......@@ -56,6 +56,19 @@ class Common : public testing::Test {
}
}
void CompareOutputInt8(int8_t *output_data, int8_t *correct_data, int size, float err_percent) {
int bias_count = 0;
for (size_t i = 0; i < size; i++) {
int8_t diff = abs(output_data[i] - correct_data[i]);
ASSERT_LE(diff, 1);
if (diff == 1) {
bias_count++;
}
}
float bias_percent = static_cast<float>(bias_count) / size;
ASSERT_LE(bias_percent, err_percent);
}
void ReadFile(const char *file, size_t *size, char **buf) {
ASSERT_NE(nullptr, file);
ASSERT_NE(nullptr, size);
......
/**
* 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 <memory>
#include "utils/log_adapter.h"
#include "common/common_test.h"
#include "mindspore/lite/src/runtime/kernel/arm/nnacl/fp32/reduce.h"
namespace mindspore {
class TestReduceFp32 : public mindspore::Common {
public:
TestReduceFp32() = default;
int tid = 0;
int thread_num = 1;
float err_tol = 1e-5;
};
TEST_F(TestReduceFp32, Mean) {
/* 2 4 4 3 NHWC */
float in[96] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0};
float correct[24] = {18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0,
66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0};
int input_shape[4] = {2, 4, 4, 3};
// int output_shape[4] = {2, 1, 4, 3};
float out[24] = {0};
int outer_size = 2;
int inner_size = 12;
int axis_size = 4;
(void)ReduceMean(outer_size, inner_size, axis_size, in, input_shape, out, tid, thread_num);
int output_size = 24;
CompareOutputData(out, correct, output_size, err_tol);
}
TEST_F(TestReduceFp32, Mean2Thread) {
/* 2*4*4*3 NHWC */
float in[96] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0};
float correct[24] = {18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0,
66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0};
int input_shape[4] = {2, 4, 4, 3};
// int output_shape[4] = {2, 1, 4, 3};
float out[24] = {0};
int outer_size = 2;
int inner_size = 12;
int axis_size = 4;
thread_num = 2;
tid = 0;
(void)ReduceMean(outer_size, inner_size, axis_size, in, input_shape, out, tid, thread_num);
tid = 1;
(void)ReduceMean(outer_size, inner_size, axis_size, in, input_shape, out, tid, thread_num);
int output_size = 24;
CompareOutputData(out, correct, output_size, err_tol);
}
TEST_F(TestReduceFp32, MeanAllAxis) {
/* 2*4*4*3 NHWC */
float in[96] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0};
float correct[1] = {47.5};
float out[1] = {0};
int input_shape[4] = {2, 4, 4, 3};
int outer_size = 1;
int inner_size = 48;
int axis_size = 2;
float *src = in;
float dst1[48] = {0};
MS_ASSERT(dst != nullptr);
(void)ReduceMean(outer_size, inner_size, axis_size, src, input_shape, dst1, tid, thread_num);
input_shape[0] = 1; // 1 4 4 3
outer_size = 1;
inner_size = 12;
axis_size = 4;
src = dst1;
float dst2[12] = {0};
(void)ReduceMean(outer_size, inner_size, axis_size, src, input_shape, dst2, tid, thread_num);
input_shape[1] = 1; // 1 1 4 3
outer_size = 1;
inner_size = 3;
axis_size = 4;
src = dst2;
float dst3[3] = {0};
(void)ReduceMean(outer_size, inner_size, axis_size, src, input_shape, dst3, tid, thread_num);
input_shape[2] = 1; // 1 1 1 3
outer_size = 1;
inner_size = 1;
axis_size = 3;
src = dst3;
(void)ReduceMean(outer_size, inner_size, axis_size, src, input_shape, out, tid, thread_num);
int output_size = 1;
CompareOutputData(out, correct, output_size, err_tol);
}
TEST_F(TestReduceFp32, Sum) {
/* 2*4*4*3 NHWC */
float in[96] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0};
float correct[24] = {72.0, 76.0, 80.0, 84.0, 88.0, 92.0, 96.0, 100.0, 104.0, 108.0, 112.0, 116.0,
264.0, 268.0, 272.0, 276.0, 280.0, 284.0, 288.0, 292.0, 296.0, 300.0, 304.0, 308.0};
int input_shape[4] = {2, 4, 4, 3};
// int output_shape[4] = {2, 1, 4, 3};
float out[24] = {0};
int outer_size = 2;
int inner_size = 12;
int axis_size = 4;
(void)ReduceSum(outer_size, inner_size, axis_size, in, input_shape, out, tid, thread_num);
int output_size = 24;
CompareOutputData(out, correct, output_size, err_tol);
}
TEST_F(TestReduceFp32, Sum2Thread) {
/* 2*4*4*3 NHWC */
float in[96] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0};
float correct[24] = {72.0, 76.0, 80.0, 84.0, 88.0, 92.0, 96.0, 100.0, 104.0, 108.0, 112.0, 116.0,
264.0, 268.0, 272.0, 276.0, 280.0, 284.0, 288.0, 292.0, 296.0, 300.0, 304.0, 308.0};
int input_shape[4] = {2, 4, 4, 3};
// int output_shape[4] = {2, 1, 4, 3};
float out[24] = {0};
int outer_size = 2;
int inner_size = 12;
int axis_size = 4;
thread_num = 2;
tid = 0;
(void)ReduceSum(outer_size, inner_size, axis_size, in, input_shape, out, tid, thread_num);
tid = 1;
(void)ReduceSum(outer_size, inner_size, axis_size, in, input_shape, out, tid, thread_num);
int output_size = 24;
CompareOutputData(out, correct, output_size, err_tol);
}
TEST_F(TestReduceFp32, SumAllAxis) {
/* 2*4*4*3 NHWC */
float in[96] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0};
float correct[1] = {4560};
float out[1] = {0};
int input_shape[4] = {2, 4, 4, 3};
int outer_size = 1;
int inner_size = 48;
int axis_size = 2;
float *src = in;
float dst1[48] = {0};
MS_ASSERT(dst != nullptr);
(void)ReduceSum(outer_size, inner_size, axis_size, src, input_shape, dst1, tid, thread_num);
input_shape[0] = 1; // 1 4 4 3
outer_size = 1;
inner_size = 12;
axis_size = 4;
src = dst1;
float dst2[12] = {0};
(void)ReduceSum(outer_size, inner_size, axis_size, src, input_shape, dst2, tid, thread_num);
input_shape[1] = 1; // 1 1 4 3
outer_size = 1;
inner_size = 3;
axis_size = 4;
src = dst2;
float dst3[3] = {0};
(void)ReduceSum(outer_size, inner_size, axis_size, src, input_shape, dst3, tid, thread_num);
input_shape[2] = 1; // 1 1 1 3
outer_size = 1;
inner_size = 1;
axis_size = 3;
src = dst3;
(void)ReduceSum(outer_size, inner_size, axis_size, src, input_shape, out, tid, thread_num);
int output_size = 1;
CompareOutputData(out, correct, output_size, err_tol);
}
TEST_F(TestReduceFp32, Max) {
/* 2*4*4*3 NHWC */
float in[96] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0};
float correct[24] = {36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0};
int input_shape[4] = {2, 4, 4, 3};
// int output_shape[4] = {2, 1, 4, 3};
float out[24] = {0};
int outer_size = 2;
int inner_size = 12;
int axis_size = 4;
(void)ReduceMax(outer_size, inner_size, axis_size, in, input_shape, out, tid, thread_num);
int output_size = 24;
CompareOutputData(out, correct, output_size, err_tol);
}
TEST_F(TestReduceFp32, Min) {
/* 2*4*4*3 NHWC */
float in[96] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0};
float correct[24] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0,
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0};
int input_shape[4] = {2, 4, 4, 3};
// int output_shape[4] = {2, 1, 4, 3};
float out[24] = {0};
int outer_size = 2;
int inner_size = 12;
int axis_size = 4;
(void)ReduceMin(outer_size, inner_size, axis_size, in, input_shape, out, tid, thread_num);
int output_size = 24;
CompareOutputData(out, correct, output_size, err_tol);
}
TEST_F(TestReduceFp32, Prod) {
/* 2*4*4*3 NHWC */
float in[96] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0};
float correct[24] = {0.0, 12025.0, 27664.0, 47385.0, 71680.0, 101065.0, 136080.0, 177289.0,
225280.0, 280665.0, 344080.0, 416185.0, 17418240.0, 18546744.0, 19728400.0, 20964824.0,
22257664.0, 23608584.0, 25019280.0, 26491464.0, 28026880.0, 29627288.0, 31294480.0, 33030264.0};
int input_shape[4] = {2, 4, 4, 3};
// int output_shape[4] = {2, 1, 4, 3};
float out[24] = {0};
int outer_size = 2;
int inner_size = 12;
int axis_size = 4;
(void)ReduceProd(outer_size, inner_size, axis_size, in, input_shape, out, tid, thread_num);
int output_size = 24;
CompareOutputData(out, correct, output_size, err_tol);
}
TEST_F(TestReduceFp32, SumSquare) {
/* 2*4*4*3 NHWC */
float in[96] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0,
16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0,
32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0,
48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0,
64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0,
80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0};
float correct[24] = {2016.0, 2164.0, 2320.0, 2484.0, 2656.0, 2836.0, 3024.0, 3220.0,
3424.0, 3636.0, 3856.0, 4084.0, 18144.0, 18676.0, 19216.0, 19764.0,
20320.0, 20884.0, 21456.0, 22036.0, 22624.0, 23220.0, 23824.0, 24436.0};
int input_shape[4] = {2, 4, 4, 3};
// int output_shape[4] = {2, 1, 4, 3};
float out[24] = {0};
int outer_size = 2;
int inner_size = 12;
int axis_size = 4;
(void)ReduceSumSquare(outer_size, inner_size, axis_size, in, input_shape, out, tid, thread_num);
int output_size = 24;
CompareOutputData(out, correct, output_size, err_tol);
}
} // namespace mindspore
/**
* 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 <iostream>
#include <vector>
#include "common/common_test.h"
#include "mindspore/lite/src/runtime/kernel/arm/nnacl/fp32/resize.h"
namespace mindspore {
class TestResizeBilinearFp32 : public mindspore::Common {
public:
TestResizeBilinearFp32() = default;
public:
int tid = 0;
int thread_num = 1;
float err_tol = 1e-5;
};
// 1*1 -> 1*1
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest1) {
std::vector<float> input = {1.0};
std::vector<int> input_shape = {1, 1, 1, 1};
std::vector<int> output_shape = {1, 1, 1, 1};
std::vector<float> expect = {1.0};
bool align_corners = false;
auto output_size = 1;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 1*1
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest2) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 1, 1, 1};
std::vector<float> expect = {0.0};
bool align_corners = false;
int output_size = 1;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 1*2
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest3) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 1, 2, 1};
std::vector<float> expect = {0.0, 1.0};
bool align_corners = false;
auto output_size = 2;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 2*1
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest4) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 2, 1, 1};
std::vector<float> expect = {0.0, 2.0};
bool align_corners = false;
auto output_size = 2;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 2*2
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest5) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 2, 2, 1};
std::vector<float> expect = {0.0, 1.0, 2.0, 3.0};
bool align_corners = false;
auto output_size = 4;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 1*4
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest6) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 1, 4, 1};
std::vector<float> expect = {0.0, 0.5, 1.0, 1.0};
bool align_corners = false;
auto output_size = 4;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 4*1
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest7) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 4, 1, 1};
std::vector<float> expect = {0.0, 1.0, 2.0, 2.0};
bool align_corners = false;
auto output_size = 4;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 2*4
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest8) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 2, 4, 1};
std::vector<float> expect = {0.0, 0.5, 1.0, 1.0, 2.0, 2.5, 3.0, 3.0};
bool align_corners = false;
auto output_size = 8;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 4*2
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest9) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 4, 2, 1};
std::vector<float> expect = {0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 2.0, 3.0};
bool align_corners = false;
auto output_size = 8;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 3*3
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest10) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 3, 3, 1};
std::vector<float> expect = {0.0, 0.6666667, 1.0, 1.3333334, 2.0, 2.3333335, 2.0, 2.6666667, 3.0};
bool align_corners = false;
auto output_size = 9;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 4*4
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest11) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 4, 4, 1};
std::vector<float> expect = {0.0, 0.5, 1.0, 1.0, 1.0, 1.5, 2.0, 2.0, 2.0, 2.5, 3.0, 3.0, 2.0, 2.5, 3.0, 3.0};
bool align_corners = false;
auto output_size = 16;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2*2*5 -> 2*4*4*5
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest12) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0,
28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0};
std::vector<int> input_shape = {2, 2, 2, 5};
std::vector<int> output_shape = {2, 4, 4, 5};
std::vector<float> expect = {
0.0, 1.0, 2.0, 3.0, 4.0, 2.5, 3.5, 4.5, 5.5, 6.5, 5.0, 6.0, 7.0, 8.0, 9.0, 5.0, 6.0, 7.0,
8.0, 9.0, 5.0, 6.0, 7.0, 8.0, 9.0, 7.5, 8.5, 9.5, 10.5, 11.5, 10.0, 11.0, 12.0, 13.0, 14.0, 10.0,
11.0, 12.0, 13.0, 14.0, 10.0, 11.0, 12.0, 13.0, 14.0, 12.5, 13.5, 14.5, 15.5, 16.5, 15.0, 16.0, 17.0, 18.0,
19.0, 15.0, 16.0, 17.0, 18.0, 19.0, 10.0, 11.0, 12.0, 13.0, 14.0, 12.5, 13.5, 14.5, 15.5, 16.5, 15.0, 16.0,
17.0, 18.0, 19.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 22.5, 23.5, 24.5, 25.5, 26.5,
25.0, 26.0, 27.0, 28.0, 29.0, 25.0, 26.0, 27.0, 28.0, 29.0, 25.0, 26.0, 27.0, 28.0, 29.0, 27.5, 28.5, 29.5,
30.5, 31.5, 30.0, 31.0, 32.0, 33.0, 34.0, 30.0, 31.0, 32.0, 33.0, 34.0, 30.0, 31.0, 32.0, 33.0, 34.0, 32.5,
33.5, 34.5, 35.5, 36.5, 35.0, 36.0, 37.0, 38.0, 39.0, 35.0, 36.0, 37.0, 38.0, 39.0, 30.0, 31.0, 32.0, 33.0,
34.0, 32.5, 33.5, 34.5, 35.5, 36.5, 35.0, 36.0, 37.0, 38.0, 39.0, 35.0, 36.0, 37.0, 38.0, 39.0};
bool align_corners = false;
auto output_size = 160;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2*2*5 -> 2*4*4*5 align corners
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest13) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0,
28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0};
std::vector<int> input_shape = {2, 2, 2, 5};
std::vector<int> output_shape = {2, 4, 4, 5};
std::vector<float> expect = {
0.0, 1.0, 2.0, 3.0, 4.0, 1.6666667, 2.6666667, 3.6666667, 4.666667, 5.666667,
3.3333335, 4.3333335, 5.3333335, 6.3333335, 7.3333335, 5.0, 6.0, 7.0, 8.0, 9.0,
3.3333335, 4.3333335, 5.3333335, 6.3333335, 7.3333335, 5.0, 6.0, 7.0, 8.0, 9.0,
6.666667, 7.666667, 8.666667, 9.666667, 10.666667, 8.333334, 9.333334, 10.333334, 11.333334, 12.333334,
6.666667, 7.666667, 8.666667, 9.666667, 10.666667, 8.333334, 9.333334, 10.333334, 11.333334, 12.333334,
10.0, 11.0, 12.0, 13.0, 14.0, 11.666667, 12.666667, 13.666667, 14.666667, 15.666667,
10.0, 11.0, 12.0, 13.0, 14.0, 11.666667, 12.666667, 13.666667, 14.666667, 15.666667,
13.333334, 14.333334, 15.333334, 16.333334, 17.333334, 15.0, 16.0, 17.0, 18.0, 19.0,
20.0, 21.0, 22.0, 23.0, 24.0, 21.666666, 22.666666, 23.666666, 24.666666, 25.666666,
23.333334, 24.333334, 25.333334, 26.333334, 27.333334, 25.0, 26.0, 27.0, 28.0, 29.0,
23.333334, 24.333334, 25.333334, 26.333334, 27.333334, 25.0, 26.0, 27.0, 28.0, 29.0,
26.666666, 27.666666, 28.666666, 29.666666, 30.666666, 28.333334, 29.333334, 30.333334, 31.333334, 32.333332,
26.666668, 27.666668, 28.666668, 29.666668, 30.666668, 28.333332, 29.333334, 30.333334, 31.333334, 32.333336,
30.0, 31.0, 32.0, 33.0, 34.0, 31.666668, 32.666668, 33.666668, 34.666668, 35.666668,
30.0, 31.0, 32.0, 33.0, 34.0, 31.666666, 32.666668, 33.666668, 34.666668, 35.666668,
33.333332, 34.333332, 35.333332, 36.333332, 37.333332, 35.0, 36.0, 37.0, 38.0, 39.0};
bool align_corners = true;
auto output_size = 160;
std::vector<float> output(output_size, 0.0);
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2*2*5 -> 2*4*4*5 thread_num 2
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest14) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0,
28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0};
std::vector<int> input_shape = {2, 2, 2, 5};
std::vector<int> output_shape = {2, 4, 4, 5};
std::vector<float> expect = {
0.0, 1.0, 2.0, 3.0, 4.0, 2.5, 3.5, 4.5, 5.5, 6.5, 5.0, 6.0, 7.0, 8.0, 9.0, 5.0, 6.0, 7.0,
8.0, 9.0, 5.0, 6.0, 7.0, 8.0, 9.0, 7.5, 8.5, 9.5, 10.5, 11.5, 10.0, 11.0, 12.0, 13.0, 14.0, 10.0,
11.0, 12.0, 13.0, 14.0, 10.0, 11.0, 12.0, 13.0, 14.0, 12.5, 13.5, 14.5, 15.5, 16.5, 15.0, 16.0, 17.0, 18.0,
19.0, 15.0, 16.0, 17.0, 18.0, 19.0, 10.0, 11.0, 12.0, 13.0, 14.0, 12.5, 13.5, 14.5, 15.5, 16.5, 15.0, 16.0,
17.0, 18.0, 19.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 22.5, 23.5, 24.5, 25.5, 26.5,
25.0, 26.0, 27.0, 28.0, 29.0, 25.0, 26.0, 27.0, 28.0, 29.0, 25.0, 26.0, 27.0, 28.0, 29.0, 27.5, 28.5, 29.5,
30.5, 31.5, 30.0, 31.0, 32.0, 33.0, 34.0, 30.0, 31.0, 32.0, 33.0, 34.0, 30.0, 31.0, 32.0, 33.0, 34.0, 32.5,
33.5, 34.5, 35.5, 36.5, 35.0, 36.0, 37.0, 38.0, 39.0, 35.0, 36.0, 37.0, 38.0, 39.0, 30.0, 31.0, 32.0, 33.0,
34.0, 32.5, 33.5, 34.5, 35.5, 36.5, 35.0, 36.0, 37.0, 38.0, 39.0, 35.0, 36.0, 37.0, 38.0, 39.0};
bool align_corners = false;
auto output_size = 160;
std::vector<float> output(output_size, 0.0);
thread_num = 2;
tid = 0;
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
tid = 1;
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2*2*5 -> 2*4*4*5 thread_num 4
TEST_F(TestResizeBilinearFp32, ResizeBilinearTest15) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0,
28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0};
std::vector<int> input_shape = {2, 2, 2, 5};
std::vector<int> output_shape = {2, 4, 4, 5};
std::vector<float> expect = {
0.0, 1.0, 2.0, 3.0, 4.0, 2.5, 3.5, 4.5, 5.5, 6.5, 5.0, 6.0, 7.0, 8.0, 9.0, 5.0, 6.0, 7.0,
8.0, 9.0, 5.0, 6.0, 7.0, 8.0, 9.0, 7.5, 8.5, 9.5, 10.5, 11.5, 10.0, 11.0, 12.0, 13.0, 14.0, 10.0,
11.0, 12.0, 13.0, 14.0, 10.0, 11.0, 12.0, 13.0, 14.0, 12.5, 13.5, 14.5, 15.5, 16.5, 15.0, 16.0, 17.0, 18.0,
19.0, 15.0, 16.0, 17.0, 18.0, 19.0, 10.0, 11.0, 12.0, 13.0, 14.0, 12.5, 13.5, 14.5, 15.5, 16.5, 15.0, 16.0,
17.0, 18.0, 19.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 22.5, 23.5, 24.5, 25.5, 26.5,
25.0, 26.0, 27.0, 28.0, 29.0, 25.0, 26.0, 27.0, 28.0, 29.0, 25.0, 26.0, 27.0, 28.0, 29.0, 27.5, 28.5, 29.5,
30.5, 31.5, 30.0, 31.0, 32.0, 33.0, 34.0, 30.0, 31.0, 32.0, 33.0, 34.0, 30.0, 31.0, 32.0, 33.0, 34.0, 32.5,
33.5, 34.5, 35.5, 36.5, 35.0, 36.0, 37.0, 38.0, 39.0, 35.0, 36.0, 37.0, 38.0, 39.0, 30.0, 31.0, 32.0, 33.0,
34.0, 32.5, 33.5, 34.5, 35.5, 36.5, 35.0, 36.0, 37.0, 38.0, 39.0, 35.0, 36.0, 37.0, 38.0, 39.0};
bool align_corners = false;
auto output_size = 160;
std::vector<float> output(output_size, 0.0);
thread_num = 4;
tid = 0;
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
tid = 1;
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
tid = 2;
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
tid = 3;
ResizeBilinear(input.data(), output.data(), input_shape.data(), output_shape.data(), align_corners, tid,
thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
} // namespace mindspore
/**
* 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 <vector>
#include "common/common_test.h"
#include "mindspore/lite/src/runtime/kernel/arm/nnacl/fp32/resize.h"
namespace mindspore {
class TestResizeNearestNeighborFp32 : public mindspore::Common {
public:
TestResizeNearestNeighborFp32() = default;
public:
int tid = 0;
int thread_num = 1;
float err_tol = 1e-5;
};
// 1*1 -> 1*1
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest1) {
std::vector<float> input = {1.0};
std::vector<int> input_shape = {1, 1, 1, 1};
std::vector<int> output_shape = {1, 1, 1, 1};
std::vector<float> expect = {1.0};
size_t output_size = 1;
std::vector<float> output(output_size, 0.0);
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 1*1
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest2) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 1, 1, 1};
std::vector<float> expect = {0.0};
size_t output_size = 1;
std::vector<float> output(output_size, 0.0);
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 1*2
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest3) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 1, 2, 1};
std::vector<float> expect = {0.0, 1.0};
size_t output_size = 2;
std::vector<float> output(output_size, 0.0);
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 2*1
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest4) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 2, 1, 1};
std::vector<float> expect = {0.0, 2.0};
size_t output_size = 2;
std::vector<float> output(output_size, 0.0);
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 2*2
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest5) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 2, 2, 1};
std::vector<float> expect = {0.0, 1.0, 2.0, 3.0};
size_t output_size = 4;
std::vector<float> output(output_size, 0.0);
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 1*4
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest6) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 1, 4, 1};
std::vector<float> expect = {0.0, 0.0, 1.0, 1.0};
size_t output_size = 4;
std::vector<float> output(output_size, 0.0);
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 4*1
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest7) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 4, 1, 1};
std::vector<float> expect = {0.0, 0.0, 2.0, 2.0};
size_t output_size = 4;
std::vector<float> output(output_size, 0.0);
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 2*4
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest8) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 2, 4, 1};
std::vector<float> expect = {0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0};
size_t output_size = 8;
std::vector<float> output(output_size, 0.0);
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 4*2
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest9) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 4, 2, 1};
std::vector<float> expect = {0.0, 1.0, 0.0, 1.0, 2.0, 3.0, 2.0, 3.0};
size_t output_size = 8;
std::vector<float> output(output_size, 0.0);
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 3*3
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest10) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 3, 3, 1};
std::vector<float> expect = {0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 2.0, 2.0, 3.0};
size_t output_size = 9;
std::vector<float> output(output_size, 0.0);
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2 -> 4*4
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest11) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0};
std::vector<int> input_shape = {1, 2, 2, 1};
std::vector<int> output_shape = {1, 4, 4, 1};
std::vector<float> expect = {0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0, 2.0, 2.0, 3.0, 3.0};
size_t output_size = 16;
std::vector<float> output(output_size, 0.0);
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2*2*5 -> 2*4*4*5
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest12) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0,
28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0};
std::vector<int> input_shape = {2, 2, 2, 5};
std::vector<int> output_shape = {2, 4, 4, 5};
std::vector<float> expect = {
0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 5.0, 6.0, 7.0,
8.0, 9.0, 0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 5.0,
6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0,
19.0, 15.0, 16.0, 17.0, 18.0, 19.0, 10.0, 11.0, 12.0, 13.0, 14.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
17.0, 18.0, 19.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 20.0, 21.0, 22.0, 23.0, 24.0,
25.0, 26.0, 27.0, 28.0, 29.0, 25.0, 26.0, 27.0, 28.0, 29.0, 20.0, 21.0, 22.0, 23.0, 24.0, 20.0, 21.0, 22.0,
23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 30.0,
31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 35.0, 36.0, 37.0, 38.0, 39.0, 30.0, 31.0, 32.0, 33.0,
34.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 35.0, 36.0, 37.0, 38.0, 39.0};
size_t output_size = 160;
std::vector<float> output(output_size, 0.0);
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2*2*5 -> 2*4*4*5 thread_num 2
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest13) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0,
28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0};
std::vector<int> input_shape = {2, 2, 2, 5};
std::vector<int> output_shape = {2, 4, 4, 5};
std::vector<float> expect = {
0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 5.0, 6.0, 7.0,
8.0, 9.0, 0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 5.0,
6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0,
19.0, 15.0, 16.0, 17.0, 18.0, 19.0, 10.0, 11.0, 12.0, 13.0, 14.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
17.0, 18.0, 19.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 20.0, 21.0, 22.0, 23.0, 24.0,
25.0, 26.0, 27.0, 28.0, 29.0, 25.0, 26.0, 27.0, 28.0, 29.0, 20.0, 21.0, 22.0, 23.0, 24.0, 20.0, 21.0, 22.0,
23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 30.0,
31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 35.0, 36.0, 37.0, 38.0, 39.0, 30.0, 31.0, 32.0, 33.0,
34.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 35.0, 36.0, 37.0, 38.0, 39.0};
size_t output_size = 160;
std::vector<float> output(output_size, 0.0);
thread_num = 2;
tid = 0;
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
tid = 1;
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
// 2*2*2*5 -> 2*4*4*5 thread_num 4
TEST_F(TestResizeNearestNeighborFp32, ResizeNearestNeighborTest14) {
std::vector<float> input = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0,
14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0,
28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0};
std::vector<int> input_shape = {2, 2, 2, 5};
std::vector<int> output_shape = {2, 4, 4, 5};
std::vector<float> expect = {
0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 5.0, 6.0, 7.0,
8.0, 9.0, 0.0, 1.0, 2.0, 3.0, 4.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 5.0,
6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0,
19.0, 15.0, 16.0, 17.0, 18.0, 19.0, 10.0, 11.0, 12.0, 13.0, 14.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
17.0, 18.0, 19.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 20.0, 21.0, 22.0, 23.0, 24.0,
25.0, 26.0, 27.0, 28.0, 29.0, 25.0, 26.0, 27.0, 28.0, 29.0, 20.0, 21.0, 22.0, 23.0, 24.0, 20.0, 21.0, 22.0,
23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 30.0,
31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 35.0, 36.0, 37.0, 38.0, 39.0, 30.0, 31.0, 32.0, 33.0,
34.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 35.0, 36.0, 37.0, 38.0, 39.0};
size_t output_size = 160;
std::vector<float> output(output_size, 0.0);
thread_num = 4;
tid = 0;
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
tid = 1;
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
tid = 2;
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
tid = 3;
ResizeNearestNeighbor(input.data(), output.data(), input_shape.data(), output_shape.data(), tid, thread_num);
CompareOutputData(output.data(), expect.data(), output_size, err_tol);
}
} // namespace mindspore
/**
* 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 <iostream>
#include "include/context.h"
#include "src/ir/tensor.h"
#include "common/common_test.h"
#include "src/common/file_utils.h"
#include "mindspore/lite/src/kernel_registry.h"
#include "src/runtime/kernel/arm/nnacl/int8/resize.h"
#include "src/runtime/kernel/arm/int8/resize_int8.h"
namespace mindspore {
using mindspore::lite::tensor::QuantArg;
using mindspore::lite::tensor::Tensor;
class TestResizeBilinearInt8 : public mindspore::Common {
public:
TestResizeBilinearInt8() = default;
void TearDown() override;
void Prepare(const std::vector<int> &in_shape, const std::vector<int> &out_shape, int8_t *input_data,
int8_t *output_data, const QuantArg quant_in, const QuantArg quant_out, const bool align_corners,
const int thread_num);
std::vector<lite::tensor::Tensor *> inputs;
std::vector<lite::tensor::Tensor *> outputs;
ResizeParameter param_ = {};
lite::tensor::Tensor in_tensor;
lite::tensor::Tensor out_tensor;
kernel::KernelKey desc_ = {kernel::KERNEL_ARCH::kCPU, kNumberTypeInt8, schema::PrimitiveType_Resize};
kernel::KernelCreator creator_ = nullptr;
lite::Context ctx_ = lite::Context();
kernel::LiteKernel *kernel_ = nullptr;
float err_percent_ = 0.2f;
};
void TestResizeBilinearInt8::TearDown() {
in_tensor.SetData(nullptr);
out_tensor.SetData(nullptr);
}
void TestResizeBilinearInt8::Prepare(const std::vector<int> &in_shape, const std::vector<int> &out_shape,
int8_t *input_data, int8_t *output_data, const mindspore::QuantArg quant_in,
const mindspore::QuantArg quant_out, const bool align_corners,
const int thread_num) {
in_tensor.set_data_type(kNumberTypeInt8);
in_tensor.set_shape(in_shape);
in_tensor.SetData(input_data);
in_tensor.AddQuantParam(quant_in);
out_tensor.set_data_type(kNumberTypeInt8);
out_tensor.set_shape(out_shape);
out_tensor.SetData(output_data);
out_tensor.AddQuantParam(quant_out);
inputs.push_back(&in_tensor);
outputs.push_back(&out_tensor);
param_.method_ = static_cast<int>(schema::ResizeMethod_BILINEAR);
param_.new_width_ = out_shape[2];
param_.new_height_ = out_shape[1];
param_.align_corners_ = align_corners;
creator_ = lite::KernelRegistry::GetInstance()->GetCreator(desc_);
ctx_.thread_num_ = thread_num;
kernel_ = creator_(inputs, outputs, reinterpret_cast<OpParameter *>(&param_), &ctx_, desc_, nullptr);
}
TEST_F(TestResizeBilinearInt8, Bilinear0) {
int8_t input_data[] = {0, 1, 2, 3};
int8_t output_data[16] = {0};
std::vector<int> in_shape = {1, 2, 2, 1};
std::vector<int> out_shape = {1, 4, 4, 1};
const lite::tensor::QuantArg quant_in = {0.005f, 2};
const lite::tensor::QuantArg quant_out = {0.008f, 5};
bool align_corners = false;
int thread_num = 1;
int8_t expect[16] = {4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 5, 5, 6, 6};
Prepare(in_shape, out_shape, input_data, output_data, quant_in, quant_out, align_corners, thread_num);
kernel_->Init();
kernel_->Run();
CompareOutputInt8(output_data, expect, 16, err_percent_);
}
// 2*2*2*5 -> 2*4*4*5
TEST_F(TestResizeBilinearInt8, Bilinear1) {
std::vector<int> in_shape = {2, 2, 2, 5};
std::vector<int> out_shape = {2, 4, 4, 5};
int8_t input_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
int8_t output_data[160] = {0};
const lite::tensor::QuantArg quant_in = {0.005f, 2};
const lite::tensor::QuantArg quant_out = {0.008f, 5};
int thread_num = 1;
bool align_corners = false;
int8_t expect[160] = {4, 4, 5, 6, 6, 5, 6, 7, 7, 8, 7, 8, 8, 9, 9, 7, 8, 8, 9, 9, 7, 8, 8,
9, 9, 8, 9, 10, 10, 11, 10, 11, 11, 12, 13, 10, 11, 11, 12, 13, 10, 11, 11, 12, 13, 12,
12, 13, 13, 14, 13, 14, 14, 15, 16, 13, 14, 14, 15, 16, 10, 11, 11, 12, 13, 12, 12, 13, 13,
14, 13, 14, 14, 15, 16, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 18, 18, 19, 20, 20, 19, 20,
21, 21, 22, 19, 20, 21, 21, 22, 19, 20, 21, 21, 22, 21, 22, 22, 23, 23, 23, 23, 24, 24, 25,
23, 23, 24, 24, 25, 23, 23, 24, 24, 25, 24, 25, 25, 26, 27, 26, 26, 27, 28, 28, 26, 26, 27,
28, 28, 23, 23, 24, 24, 25, 24, 25, 25, 26, 27, 26, 26, 27, 28, 28, 26, 26, 27, 28, 28};
Prepare(in_shape, out_shape, input_data, output_data, quant_in, quant_out, align_corners, thread_num);
kernel_->Init();
kernel_->Run();
CompareOutputInt8(output_data, expect, 160, err_percent_);
}
// 2*2*2*5 -> 2*4*4*5 thread num 2, align corners
TEST_F(TestResizeBilinearInt8, Bilinear2) {
std::vector<int> in_shape = {2, 2, 2, 5};
std::vector<int> out_shape = {2, 4, 4, 5};
int8_t input_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
int8_t output_data[160] = {0};
const lite::tensor::QuantArg quant_in = {0.005f, 2};
const lite::tensor::QuantArg quant_out = {0.008f, 5};
int thread_num = 2;
bool align_corners = true;
int8_t expect[160] = {4, 4, 5, 6, 6, 5, 5, 6, 7, 7, 6, 6, 7, 8, 8, 7, 8, 8, 9, 9, 6, 6, 7,
8, 8, 7, 8, 8, 9, 9, 8, 9, 9, 10, 10, 9, 10, 10, 11, 11, 8, 9, 9, 10, 10, 9,
10, 10, 11, 11, 10, 11, 11, 12, 13, 11, 12, 12, 13, 14, 10, 11, 11, 12, 13, 11, 12, 12, 13,
14, 12, 13, 13, 14, 15, 13, 14, 14, 15, 16, 16, 17, 18, 18, 19, 17, 18, 19, 19, 20, 18, 19,
20, 20, 21, 19, 20, 21, 21, 22, 18, 19, 20, 20, 21, 19, 20, 21, 21, 22, 20, 21, 22, 22, 23,
21, 22, 23, 23, 24, 20, 21, 22, 22, 23, 21, 22, 23, 23, 24, 23, 23, 24, 24, 25, 24, 24, 25,
25, 26, 23, 23, 24, 24, 25, 24, 24, 25, 25, 26, 25, 25, 26, 26, 27, 26, 26, 27, 28, 28};
Prepare(in_shape, out_shape, input_data, output_data, quant_in, quant_out, align_corners, thread_num);
kernel_->Init();
kernel_->Run();
CompareOutputInt8(output_data, expect, 160, err_percent_);
}
} // namespace mindspore
/**
* 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 <iostream>
#include "include/context.h"
#include "src/ir/tensor.h"
#include "common/common_test.h"
#include "mindspore/lite/src/kernel_registry.h"
#include "src/runtime/kernel/arm/nnacl/int8/resize.h"
namespace mindspore {
using mindspore::lite::tensor::QuantArg;
using mindspore::lite::tensor::Tensor;
class TestResizeNearestNeighborInt8 : public mindspore::Common {
public:
TestResizeNearestNeighborInt8() = default;
void Prepare(const std::vector<int> &in_shape, const std::vector<int> &out_shape, int8_t *input_data,
int8_t *output_data, const QuantArg quant_in, const QuantArg quant_out, const bool align_corners,
const int thread_num);
void TearDown() override;
std::vector<lite::tensor::Tensor *> inputs;
std::vector<lite::tensor::Tensor *> outputs;
ResizeParameter param_ = {};
lite::tensor::Tensor in_tensor;
lite::tensor::Tensor out_tensor;
kernel::KernelKey desc_ = {kernel::KERNEL_ARCH::kCPU, kNumberTypeInt8, schema::PrimitiveType_Resize};
kernel::KernelCreator creator_ = nullptr;
lite::Context ctx_ = lite::Context();
kernel::LiteKernel *kernel_ = nullptr;
float err_percent_ = 0.05f;
};
void TestResizeNearestNeighborInt8::Prepare(const std::vector<int> &in_shape, const std::vector<int> &out_shape,
int8_t *input_data, int8_t *output_data, const QuantArg quant_in,
const QuantArg quant_out, const bool align_corners, const int thread_num) {
in_tensor.set_data_type(kNumberTypeInt8);
in_tensor.set_shape(in_shape);
in_tensor.SetData(input_data);
in_tensor.AddQuantParam(quant_in);
out_tensor.set_data_type(kNumberTypeInt8);
out_tensor.set_shape(out_shape);
out_tensor.SetData(output_data);
out_tensor.AddQuantParam(quant_out);
inputs.push_back(&in_tensor);
outputs.push_back(&out_tensor);
param_.method_ = static_cast<int>(schema::ResizeMethod_NEAREST_NEIGHBOR);
param_.new_width_ = out_shape[2];
param_.new_height_ = out_shape[1];
param_.align_corners_ = align_corners;
creator_ = lite::KernelRegistry::GetInstance()->GetCreator(desc_);
ctx_.thread_num_ = thread_num;
kernel_ = creator_(inputs, outputs, reinterpret_cast<OpParameter *>(&param_), &ctx_, desc_, nullptr);
}
void TestResizeNearestNeighborInt8::TearDown() {
in_tensor.SetData(nullptr);
out_tensor.SetData(nullptr);
}
// 2*2*1 -> 4*4*1
TEST_F(TestResizeNearestNeighborInt8, NearestNeighbor0) {
std::vector<int> in_shape = {1, 2, 2, 1};
std::vector<int> out_shape = {1, 4, 4, 1};
QuantArg quant_in = {0.00390625, 2};
QuantArg quant_out = {0.015625, 5};
int8_t input_data[] = {0, 1, 2, 3};
const int out_element_num = 16;
int8_t output_data[out_element_num] = {0};
int thread_num = 1;
int8_t expect[16] = {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5};
err_percent_ = 0.25f;
Prepare(in_shape, out_shape, input_data, output_data, quant_in, quant_out, false, thread_num);
kernel_->Init();
kernel_->Run();
CompareOutputInt8(output_data, expect, 16, err_percent_);
}
// 2*2*2*5 -> 2*4*4*5
TEST_F(TestResizeNearestNeighborInt8, NearestNeighbor1) {
std::vector<int> in_shape = {2, 2, 2, 5};
std::vector<int> out_shape = {2, 4, 4, 5};
QuantArg quant_in = {0.00390625, 2};
QuantArg quant_out = {0.015625, 5};
int8_t input_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
const int out_element_num = 160;
int8_t output_data[out_element_num] = {0};
int thread_num = 1;
int8_t expect[160] = {5, 5, 5, 5, 6, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 6, 6, 6, 7, 7, 5, 5, 5,
5, 6, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 7,
7, 8, 8, 8, 8, 9, 9, 9, 9, 8, 9, 9, 9, 9, 7, 7, 8, 8, 8, 7, 7, 8, 8,
8, 8, 9, 9, 9, 9, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 10, 10, 10, 10, 11, 11, 11,
11, 12, 12, 11, 11, 11, 12, 12, 10, 10, 10, 10, 11, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12,
11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 13, 14, 14,
14, 14, 12, 12, 13, 13, 13, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 13, 14, 14, 14, 14};
Prepare(in_shape, out_shape, input_data, output_data, quant_in, quant_out, false, thread_num);
kernel_->Init();
kernel_->Run();
CompareOutputInt8(output_data, expect, out_element_num, err_percent_);
}
// 2*2*2*5 -> 2*4*4*5 thread num 2 align_corners
TEST_F(TestResizeNearestNeighborInt8, NearestNeighbor2) {
std::vector<int> in_shape = {2, 2, 2, 5};
std::vector<int> out_shape = {2, 4, 4, 5};
QuantArg quant_in = {0.00390625, 2};
QuantArg quant_out = {0.015625, 5};
int8_t input_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
const int out_element_num = 160;
int8_t output_data[out_element_num] = {0};
int thread_num = 2;
int8_t expect[160] = {
5, 5, 5, 5, 6, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 6, 6, 6, 7, 7, 5, 5, 5, 5, 6, 5, 5,
5, 5, 6, 6, 6, 6, 7, 7, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 7, 7, 8, 8, 8, 8, 9, 9, 9,
9, 8, 9, 9, 9, 9, 7, 7, 8, 8, 8, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 8, 9, 9, 9, 9, 10,
10, 10, 10, 11, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 11, 11, 11, 12, 12, 10, 10, 10, 10, 11, 10, 10, 10,
10, 11, 11, 11, 11, 12, 12, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14,
13, 14, 14, 14, 14, 12, 12, 13, 13, 13, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 13, 14, 14, 14, 14,
};
Prepare(in_shape, out_shape, input_data, output_data, quant_in, quant_out, true, thread_num);
kernel_->Init();
kernel_->Run();
CompareOutputInt8(output_data, expect, out_element_num, err_percent_);
}
// 2*2*2*5 -> 2*4*4*5 thread num 2, same quant args
TEST_F(TestResizeNearestNeighborInt8, NearestNeighbor3) {
std::vector<int> in_shape = {2, 2, 2, 5};
std::vector<int> out_shape = {2, 4, 4, 5};
QuantArg quant_in = {0.00390625, 2};
QuantArg quant_out = {0.00390625, 2};
int8_t input_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
const int out_element_num = 160;
int8_t output_data[out_element_num] = {0};
int thread_num = 2;
int8_t expect[160] = {0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9, 0, 1, 2,
3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 20, 21, 22, 23, 24, 25, 26,
27, 28, 29, 25, 26, 27, 28, 29, 20, 21, 22, 23, 24, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 35, 36, 37,
38, 39, 30, 31, 32, 33, 34, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 35, 36, 37, 38, 39};
Prepare(in_shape, out_shape, input_data, output_data, quant_in, quant_out, false, thread_num);
kernel_->Init();
kernel_->Run();
CompareOutputInt8(output_data, expect, out_element_num, err_percent_);
}
// 2*2*2*5 -> 2*4*4*5 thread num 2 align_corners, same quant args
TEST_F(TestResizeNearestNeighborInt8, NearestNeighbor4) {
std::vector<int> in_shape = {2, 2, 2, 5};
std::vector<int> out_shape = {2, 4, 4, 5};
QuantArg quant_in = {0.00390625, 2};
QuantArg quant_out = {0.00390625, 2};
int8_t input_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
const int out_element_num = 160;
int8_t output_data[out_element_num] = {0};
int thread_num = 2;
int8_t expect[160] = {
0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 0, 1,
2, 3, 4, 5, 6, 7, 8, 9, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 25, 26, 27, 28, 29, 20, 21, 22, 23, 24, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
35, 36, 37, 38, 39, 30, 31, 32, 33, 34, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 35, 36, 37, 38, 39,
};
Prepare(in_shape, out_shape, input_data, output_data, quant_in, quant_out, true, thread_num);
kernel_->Init();
kernel_->Run();
CompareOutputInt8(output_data, expect, out_element_num, err_percent_);
}
} // namespace mindspore
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册