forked from mindspore-Ecosystem/mindspore
!12468 [MSLITE][Develop] fix bug of npu kernel fusion
From: @yangruoqi713 Reviewed-by: @zhang_xue_tong,@zhanghaibo5 Signed-off-by: @zhang_xue_tong
This commit is contained in:
commit
cf8279267c
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
* Copyright 2020-2021 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.
|
||||
|
@ -197,7 +197,11 @@ int NPUFusionPass::ConcatFusion(kernel::LiteKernel *kernel) {
|
|||
}
|
||||
|
||||
int NPUFusionPass::FormatFusion(kernel::LiteKernel *kernel) {
|
||||
auto pre_kernel = kernel->in_kernels()[0];
|
||||
auto is_input_kernel = kernel->in_kernels().empty();
|
||||
kernel::LiteKernel *pre_kernel = nullptr;
|
||||
if (!is_input_kernel) {
|
||||
pre_kernel = kernel->in_kernels()[0];
|
||||
}
|
||||
auto in_tensor = kernel->in_tensors()[0];
|
||||
std::vector<kernel::LiteKernel *> pre_insert_kernels;
|
||||
for (const auto &trans_kernel : kernel->out_kernels()) {
|
||||
|
@ -225,7 +229,11 @@ int NPUFusionPass::FormatFusion(kernel::LiteKernel *kernel) {
|
|||
auto post_in_kernels = post_kernel->in_kernels();
|
||||
for (size_t i = 0; i < post_in_kernels.size(); i++) {
|
||||
if (post_in_kernels[i] == trans_kernel) {
|
||||
post_in_kernels[i] = pre_kernel;
|
||||
if (is_input_kernel) {
|
||||
post_in_kernels.erase(post_in_kernels.begin() + i);
|
||||
} else {
|
||||
post_in_kernels[i] = pre_kernel;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -234,16 +242,18 @@ int NPUFusionPass::FormatFusion(kernel::LiteKernel *kernel) {
|
|||
}
|
||||
RemoveAndFreeKernel(trans_kernel);
|
||||
}
|
||||
auto pre_out_kernels = pre_kernel->out_kernels();
|
||||
size_t index = 0;
|
||||
for (; index < pre_out_kernels.size(); index++) {
|
||||
if (pre_out_kernels[index] == kernel) {
|
||||
pre_out_kernels.erase(pre_out_kernels.begin() + index);
|
||||
break;
|
||||
if (!is_input_kernel) {
|
||||
auto pre_out_kernels = pre_kernel->out_kernels();
|
||||
size_t index = 0;
|
||||
for (; index < pre_out_kernels.size(); index++) {
|
||||
if (pre_out_kernels[index] == kernel) {
|
||||
pre_out_kernels.erase(pre_out_kernels.begin() + index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pre_out_kernels.insert(pre_out_kernels.begin() + index, pre_insert_kernels.begin(), pre_insert_kernels.end());
|
||||
pre_kernel->set_out_kernels(pre_out_kernels);
|
||||
}
|
||||
pre_out_kernels.insert(pre_out_kernels.begin() + index, pre_insert_kernels.begin(), pre_insert_kernels.end());
|
||||
pre_kernel->set_out_kernels(pre_out_kernels);
|
||||
RemoveAndFreeKernel(kernel);
|
||||
return RET_OK;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
* Copyright 2020-2021 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.
|
||||
|
@ -116,28 +116,30 @@ int NPUInsertTransformPass::InsertNode(kernel::LiteKernel *kernel, kernel::LiteK
|
|||
std::vector<int> nhwc_shape = in_tensor->shape();
|
||||
std::vector<int> nchw_shape = {nhwc_shape[0], nhwc_shape[3], nhwc_shape[1], nhwc_shape[2]};
|
||||
|
||||
auto nh2nc_name = kernel_name + "_nh2nc_" + std::to_string(total++);
|
||||
auto nh2nc_tensor = new (std::nothrow) Tensor(in_tensor->data_type(), nchw_shape, schema::Format_NHWC, Tensor::VAR);
|
||||
if (nh2nc_tensor == nullptr) {
|
||||
MS_LOG(ERROR) << "New nchw tensor failed when inserting nchw2nhwc kernel.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
nh2nc_tensor->set_tensor_name(nh2nc_name + "/output0");
|
||||
std::vector<Tensor *> nh2nc_tensors = {nh2nc_tensor};
|
||||
all_tensors_->push_back(nh2nc_tensors[0]);
|
||||
|
||||
auto nc2nh_name = kernel_name + "_nc2nh_" + std::to_string(total++);
|
||||
auto nc2nh_tensor = new (std::nothrow) Tensor(in_tensor->data_type(), nhwc_shape, schema::Format_NCHW, Tensor::VAR);
|
||||
if (nc2nh_tensor == nullptr) {
|
||||
MS_LOG(ERROR) << "New nhwc tensor failed when inserting nhwc2nchw kernel.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
nc2nh_tensor->set_tensor_name(nc2nh_name + "/output0");
|
||||
std::vector<Tensor *> nc2nh_tensors = {nc2nh_tensor};
|
||||
all_tensors_->push_back(nc2nh_tensors[0]);
|
||||
|
||||
auto nh2nc_name = kernel_name + "_nh2nc_" + std::to_string(total++);
|
||||
auto *nh2nc_kernel = NPUPassUtils::CreateNhwc2NchwKernel({in_tensor}, nh2nc_tensors, context_, nh2nc_name);
|
||||
trans_kernels->push_back(nh2nc_kernel);
|
||||
insert_primitive_.push_back(nh2nc_kernel->GetPrimitive());
|
||||
|
||||
auto nc2nh_name = kernel_name + "_nc2nh_" + std::to_string(total++);
|
||||
auto *nc2nh_kernel = NPUPassUtils::CreateNchw2NhwcKernel(nh2nc_tensors, nc2nh_tensors, context_, nc2nh_name);
|
||||
trans_kernels->push_back(nc2nh_kernel);
|
||||
insert_primitive_.push_back(nc2nh_kernel->GetPrimitive());
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
* Copyright 2020-2021 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.
|
||||
|
@ -191,7 +191,11 @@ void NPUPassUtils::UpdateNC2NHTransNodePostKernel(kernel::LiteKernel *kernel, ke
|
|||
|
||||
// For post_kernel after trans, kernel in in_kernels should be replaced with trans_kernel.
|
||||
auto post_in_kernels = post_kernel->in_kernels();
|
||||
std::replace(post_in_kernels.begin(), post_in_kernels.end(), kernel, trans_kernel);
|
||||
if (kernel == nullptr) {
|
||||
post_in_kernels.push_back(trans_kernel);
|
||||
} else {
|
||||
std::replace(post_in_kernels.begin(), post_in_kernels.end(), kernel, trans_kernel);
|
||||
}
|
||||
post_kernel->set_in_kernels(post_in_kernels);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
* Copyright 2020-2021 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.
|
||||
|
@ -39,11 +39,12 @@ int NPUTransformPass::InsertPreNodes(kernel::LiteKernel *kernel, std::vector<ker
|
|||
MS_LOG(ERROR) << "New nchw tensor failed when inserting pre nhwc2nchw kernel.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
auto name = kernel->name() + "_pre_trans" + "_Nhwc2Nchw_" + std::to_string(total++);
|
||||
tensor->set_tensor_name(name + "/output0");
|
||||
std::vector<Tensor *> pre_trans_out_tensors = {tensor};
|
||||
all_tensors_->push_back(pre_trans_out_tensors[0]);
|
||||
|
||||
// Create pre transform kernel: Nhwc2Nchw
|
||||
auto name = kernel->name() + "_pre_trans" + "_Nhwc2Nchw_" + std::to_string(total++);
|
||||
auto *trans_kernel =
|
||||
NPUPassUtils::CreateNhwc2NchwKernel({kernel->in_tensors()[0]}, pre_trans_out_tensors, context_, name);
|
||||
|
||||
|
@ -124,6 +125,11 @@ int NPUTransformPass::Run() {
|
|||
i++;
|
||||
continue;
|
||||
}
|
||||
if (kernel->Type() == schema::PrimitiveType_Resize &&
|
||||
kernel->in_tensors()[0]->Height() > kernel->out_tensors()[0]->Height()) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
// insert pre_kernels before kernel in vector
|
||||
// modify loop index add (pre_kernels.size() + 1) to the post_kernels insert location
|
||||
std::vector<kernel::LiteKernel *> pre_kernels;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/**
|
||||
* Copyright 2020 Huawei Technologies Co., Ltd
|
||||
* Copyright 2020-2021 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.
|
||||
|
@ -26,11 +26,15 @@ using mindspore::schema::PrimitiveType_Resize;
|
|||
namespace mindspore::kernel {
|
||||
int ResizeNPUKernel::IsSupport(const std::vector<lite::Tensor *> &inputs, const std::vector<lite::Tensor *> &outputs,
|
||||
OpParameter *opParameter) {
|
||||
if (resize_parameter_->method_ != schema::ResizeMethod_LINEAR ||
|
||||
resize_parameter_->method_ == schema::ResizeMethod_NEAREST) {
|
||||
if (resize_parameter_->method_ != schema::ResizeMethod_LINEAR &&
|
||||
resize_parameter_->method_ != schema::ResizeMethod_NEAREST) {
|
||||
MS_LOG(WARNING) << "Unsupported resize method type:" << resize_parameter_->method_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
if (inputs[0]->Height() > outputs[0]->Height() || inputs[0]->Width() > outputs[0]->Width()) {
|
||||
MS_LOG(WARNING) << "Npu resize does not support reduction.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
@ -55,7 +59,7 @@ int ResizeNPUKernel::SetNPUInputs(const std::vector<lite::Tensor *> &inputs, con
|
|||
op->set_input_size(*out_size);
|
||||
op->set_attr_half_pixel_centers(resize_parameter_->preserve_aspect_ratio_);
|
||||
op_ = op;
|
||||
} else {
|
||||
} else if (resize_parameter_->method_ == schema::ResizeMethod_NEAREST) {
|
||||
auto op = new (std::nothrow) hiai::op::ResizeNearestNeighborV2(name_);
|
||||
if (op == nullptr) {
|
||||
MS_LOG(ERROR) << " op is nullptr.";
|
||||
|
@ -66,6 +70,9 @@ int ResizeNPUKernel::SetNPUInputs(const std::vector<lite::Tensor *> &inputs, con
|
|||
op->set_input_x(*npu_inputs[0]);
|
||||
op->set_input_size(*out_size);
|
||||
op_ = op;
|
||||
} else {
|
||||
MS_LOG(WARNING) << "Unsupported resize method type:" << resize_parameter_->method_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue