• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2020-2021 Huawei Technologies Co., Ltd
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/litert/delegate/npu/op/resize_npu.h"
18 #include <memory>
19 #include "src/litert/delegate/npu/npu_converter_utils.h"
20 #include "src/litert/delegate/npu/npu_manager.h"
21 
22 namespace mindspore::lite {
IsSupport(const schema::Primitive * primitive,const std::vector<mindspore::MSTensor> & in_tensors,const std::vector<mindspore::MSTensor> & out_tensors)23 int ResizeNPUOp::IsSupport(const schema::Primitive *primitive, const std::vector<mindspore::MSTensor> &in_tensors,
24                            const std::vector<mindspore::MSTensor> &out_tensors) {
25   auto resize_prim = primitive->value_as_Resize();
26   if (resize_prim == nullptr) {
27     MS_LOG(ERROR) << "Get null primitive value for op ." << name_;
28     return RET_ERROR;
29   }
30   resize_method_ = resize_prim->method();
31   if (resize_method_ != schema::ResizeMethod_LINEAR && resize_method_ != schema::ResizeMethod_NEAREST) {
32     MS_LOG(WARNING) << "Unsupported resize method type: " << resize_method_;
33     return RET_NOT_SUPPORT;
34   }
35   CHECK_LESS_RETURN(in_tensors.size(), 1);
36   CHECK_LESS_RETURN(out_tensors.size(), 1);
37   if (in_tensors[0].Shape()[NHWC_H] > out_tensors[0].Shape()[NHWC_H] ||
38       in_tensors[0].Shape()[NHWC_W] > out_tensors[0].Shape()[NHWC_W]) {
39     MS_LOG(WARNING) << "Npu resize does not support reduction.";
40     return RET_NOT_SUPPORT;
41   }
42   is_support_v2_ = NPUManager::CheckDDKVerGreatEqual("100.500.010.010");
43   is_support_scale_ = NPUManager::CheckDDKVerGreatEqual("100.320.012.043");
44   return RET_OK;
45 }
46 
Init(const schema::Primitive * primitive,const std::vector<mindspore::MSTensor> & in_tensors,const std::vector<mindspore::MSTensor> & out_tensors)47 int ResizeNPUOp::Init(const schema::Primitive *primitive, const std::vector<mindspore::MSTensor> &in_tensors,
48                       const std::vector<mindspore::MSTensor> &out_tensors) {
49   CHECK_LESS_RETURN(in_tensors.at(0).Shape().size(), DIMENSION_4D);
50   auto org_height = static_cast<float>(in_tensors.at(0).Shape().at(NHWC_H));
51   auto org_width = static_cast<float>(in_tensors.at(0).Shape().at(NHWC_W));
52   CHECK_LESS_RETURN(out_tensors.at(0).Shape().size(), DIMENSION_4D);
53   auto new_height = static_cast<int>(out_tensors.at(0).Shape().at(NHWC_H));
54   auto new_width = static_cast<int>(out_tensors.at(0).Shape().at(NHWC_W));
55 
56   ge::TensorPtr size_tensor = std::make_shared<hiai::Tensor>();
57   if (is_support_scale_) {
58     ge::TensorDesc size_tensor_desc(ge::Shape({NPU_SHAPE_SIZE}), ge::FORMAT_ND, ge::DT_FLOAT);
59     size_tensor->SetTensorDesc(size_tensor_desc);
60     std::vector<float> data_value = {1, 1, new_height / org_height, new_width / org_width};
61     size_tensor->SetData(reinterpret_cast<uint8_t *>(data_value.data()), NPU_SHAPE_SIZE * sizeof(float));
62   } else {
63     ge::TensorDesc size_tensor_desc(ge::Shape({DIMENSION_2D}), ge::FORMAT_ND, ge::DT_INT32);
64     size_tensor->SetTensorDesc(size_tensor_desc);
65     std::vector<int> data_value = {new_height, new_width};
66     size_tensor->SetData(reinterpret_cast<uint8_t *>(data_value.data()), DIMENSION_2D * sizeof(int));
67   }
68   out_size_ = new (std::nothrow) hiai::op::Const(name_ + "_size");
69   if (out_size_ == nullptr) {
70     MS_LOG(ERROR) << "create const NPU op failed for " << name_;
71     return RET_ERROR;
72   }
73   out_size_->set_attr_value(size_tensor);
74 
75   auto resize_prim = primitive->value_as_Resize();
76   if (resize_prim == nullptr) {
77     MS_LOG(ERROR) << "Get null primitive value for op ." << name_;
78     return RET_ERROR;
79   }
80   auto ret = SelectResizeOp(resize_prim);
81   if (ret != RET_OK) {
82     MS_LOG(ERROR) << "Select Resize op failed!";
83     return RET_ERROR;
84   }
85   return RET_OK;
86 }
87 
SelectResizeOp(const mindspore::schema::Resize * prim)88 int ResizeNPUOp::SelectResizeOp(const mindspore::schema::Resize *prim) {
89   if (resize_method_ == schema::ResizeMethod_LINEAR) {
90     auto resize_bilinear = new (std::nothrow) hiai::op::ResizeBilinearV2(name_);
91     if (resize_bilinear == nullptr) {
92       MS_LOG(ERROR) << " resize_ is nullptr.";
93       return RET_ERROR;
94     }
95     resize_bilinear->set_attr_align_corners(prim->coordinate_transform_mode() ==
96                                             schema::CoordinateTransformMode_ALIGN_CORNERS);
97     resize_bilinear->set_attr_half_pixel_centers(prim->coordinate_transform_mode() ==
98                                                  schema::CoordinateTransformMode_HALF_PIXEL);
99     resize_bilinear->set_input_size(*out_size_);
100     resize_ = resize_bilinear;
101   } else if (resize_method_ == schema::ResizeMethod_NEAREST) {
102     if (is_support_v2_) {
103       auto resize_nearest_v2 = new (std::nothrow) hiai::op::ResizeNearestNeighborV2(name_);
104       if (resize_nearest_v2 == nullptr) {
105         MS_LOG(ERROR) << " resize_ is nullptr.";
106         return RET_ERROR;
107       }
108       resize_nearest_v2->set_attr_align_corners(prim->coordinate_transform_mode() ==
109                                                 schema::CoordinateTransformMode_ALIGN_CORNERS);
110       resize_nearest_v2->set_input_size(*out_size_);
111       resize_ = resize_nearest_v2;
112     } else {
113       auto resize_nearest = new (std::nothrow) hiai::op::ResizeNearestNeighbor(name_);
114       if (resize_nearest == nullptr) {
115         MS_LOG(ERROR) << " resize_ is nullptr.";
116         return RET_ERROR;
117       }
118       resize_nearest->set_input_size(*out_size_);
119       resize_ = resize_nearest;
120     }
121   } else {
122     MS_LOG(WARNING) << "Unsupported resize method type:" << resize_method_;
123     return RET_ERROR;
124   }
125   return RET_OK;
126 }
127 
SetNPUInputs(const std::vector<mindspore::MSTensor> & in_tensors,const std::vector<mindspore::MSTensor> & out_tensors,const std::vector<ge::Operator * > & npu_inputs)128 int ResizeNPUOp::SetNPUInputs(const std::vector<mindspore::MSTensor> &in_tensors,
129                               const std::vector<mindspore::MSTensor> &out_tensors,
130                               const std::vector<ge::Operator *> &npu_inputs) {
131   CHECK_LESS_RETURN(npu_inputs.size(), 1);
132   if (resize_method_ == schema::ResizeMethod_LINEAR) {
133     auto resize_bilinear = reinterpret_cast<hiai::op::ResizeBilinearV2 *>(resize_);
134     resize_bilinear->set_input_x(*npu_inputs[0]);
135   } else if (resize_method_ == schema::ResizeMethod_NEAREST) {
136     if (is_support_v2_) {
137       auto resize_nearest_v2 = reinterpret_cast<hiai::op::ResizeNearestNeighborV2 *>(resize_);
138       resize_nearest_v2->set_input_x(*npu_inputs[0]);
139     } else {
140       auto resize_nearest = reinterpret_cast<hiai::op::ResizeNearestNeighbor *>(resize_);
141       resize_nearest->set_input_x(*npu_inputs[0]);
142     }
143   } else {
144     MS_LOG(WARNING) << "Unsupported resize method type:" << resize_method_;
145     return RET_ERROR;
146   }
147   return RET_OK;
148 }
149 
GetNPUOp()150 ge::Operator *ResizeNPUOp::GetNPUOp() { return this->resize_; }
151 
~ResizeNPUOp()152 ResizeNPUOp::~ResizeNPUOp() {
153   if (resize_ != nullptr) {
154     delete resize_;
155     resize_ = nullptr;
156   }
157   if (out_size_ != nullptr) {
158     delete out_size_;
159     out_size_ = nullptr;
160   }
161 }
162 }  // namespace mindspore::lite
163