• 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/delegate/npu/op/resize_npu.h"
18 #include <memory>
19 #include "src/delegate/npu/npu_converter_utils.h"
20 
21 namespace mindspore {
22 constexpr int RESIZE_INPUT_SIZE = 2;
23 constexpr int SHAPE_SIZE = 2;
24 
IsSupport(const schema::Primitive * primitive,const std::vector<mindspore::MSTensor> & in_tensors,const std::vector<mindspore::MSTensor> & out_tensors)25 int ResizeNPUOp::IsSupport(const schema::Primitive *primitive, const std::vector<mindspore::MSTensor> &in_tensors,
26                            const std::vector<mindspore::MSTensor> &out_tensors) {
27   auto resize_prim = primitive->value_as_Resize();
28   if (resize_prim == nullptr) {
29     MS_LOG(ERROR) << "Get null primitive value for op ." << name_;
30     return RET_ERROR;
31   }
32   resize_method_ = resize_prim->method();
33   if (resize_method_ != schema::ResizeMethod_LINEAR && resize_method_ != schema::ResizeMethod_NEAREST) {
34     MS_LOG(WARNING) << "Unsupported resize method type: " << resize_method_;
35     return RET_NOT_SUPPORT;
36   }
37 
38   if (in_tensors[0].Shape()[NHWC_H] > out_tensors[0].Shape()[NHWC_H] ||
39       in_tensors[0].Shape()[NHWC_W] > out_tensors[0].Shape()[NHWC_W]) {
40     MS_LOG(WARNING) << "Npu resize does not support reduction.";
41     return RET_NOT_SUPPORT;
42   }
43   return RET_OK;
44 }
45 
Init(const schema::Primitive * primitive,const std::vector<mindspore::MSTensor> & in_tensors,const std::vector<mindspore::MSTensor> & out_tensors)46 int ResizeNPUOp::Init(const schema::Primitive *primitive, const std::vector<mindspore::MSTensor> &in_tensors,
47                       const std::vector<mindspore::MSTensor> &out_tensors) {
48   auto resize_prim = primitive->value_as_Resize();
49   if (resize_prim == nullptr) {
50     MS_LOG(ERROR) << "Get null primitive value for op ." << name_;
51     return RET_ERROR;
52   }
53   if (in_tensors.size() == 1) {
54     new_height_ = resize_prim->new_height();
55     new_width_ = resize_prim->new_width();
56   } else if (in_tensors.size() == RESIZE_INPUT_SIZE) {
57     auto out_size = in_tensors.at(1).Data();
58     if (out_size == nullptr) {
59       MS_LOG(ERROR) << "Out size is not assigned";
60       return RET_ERROR;
61     }
62     new_height_ = out_tensors.at(0).Shape().at(NHWC_H);
63     new_width_ = out_tensors.at(0).Shape().at(NHWC_W);
64   } else {
65     MS_LOG(ERROR) << "Get resize op new_height and new_width error.";
66     return RET_ERROR;
67   }
68 
69   ge::TensorDesc sizeTensorDesc(ge::Shape({SHAPE_SIZE}), ge::FORMAT_NCHW, ge::DT_INT32);
70   ge::TensorPtr sizeTensor = std::make_shared<hiai::Tensor>(sizeTensorDesc);
71   vector<int32_t> dataValue = {static_cast<int32_t>(new_height_), static_cast<int32_t>(new_width_)};
72   sizeTensor->SetData(reinterpret_cast<uint8_t *>(dataValue.data()), SHAPE_SIZE * sizeof(int32_t));
73   out_size_ = new (std::nothrow) hiai::op::Const(name_ + "_size");
74   if (out_size_ == nullptr) {
75     MS_LOG(ERROR) << "create const NPU op failed for " << name_;
76     return RET_ERROR;
77   }
78   out_size_->set_attr_value(sizeTensor);
79 
80   if (resize_method_ == schema::ResizeMethod_LINEAR) {
81     auto resize_bilinear = new (std::nothrow) hiai::op::ResizeBilinearV2(name_);
82     if (resize_bilinear == nullptr) {
83       MS_LOG(ERROR) << " resize_ is nullptr.";
84       return RET_ERROR;
85     }
86     resize_bilinear->set_attr_align_corners(resize_prim->coordinate_transform_mode() ==
87                                             schema::CoordinateTransformMode_ALIGN_CORNERS);
88     resize_bilinear->set_input_size(*out_size_);
89     resize_bilinear->set_attr_half_pixel_centers(resize_prim->preserve_aspect_ratio());
90     resize_ = resize_bilinear;
91   } else if (resize_method_ == schema::ResizeMethod_NEAREST) {
92     auto resize_nearest = new (std::nothrow) hiai::op::ResizeNearestNeighborV2(name_);
93     if (resize_nearest == nullptr) {
94       MS_LOG(ERROR) << " resize_ is nullptr.";
95       return RET_ERROR;
96     }
97     resize_nearest->set_attr_align_corners(resize_prim->coordinate_transform_mode() ==
98                                            schema::CoordinateTransformMode_ALIGN_CORNERS);
99     resize_nearest->set_input_size(*out_size_);
100     resize_ = resize_nearest;
101   } else {
102     MS_LOG(WARNING) << "Unsupported resize method type:" << resize_method_;
103     return RET_ERROR;
104   }
105   return RET_OK;
106 }
107 
SetNPUInputs(const std::vector<mindspore::MSTensor> & in_tensors,const std::vector<mindspore::MSTensor> & out_tensors,const std::vector<ge::Operator * > & npu_inputs)108 int ResizeNPUOp::SetNPUInputs(const std::vector<mindspore::MSTensor> &in_tensors,
109                               const std::vector<mindspore::MSTensor> &out_tensors,
110                               const std::vector<ge::Operator *> &npu_inputs) {
111   if (resize_method_ == schema::ResizeMethod_LINEAR) {
112     auto resize_bilinear = reinterpret_cast<hiai::op::ResizeBilinearV2 *>(resize_);
113     resize_bilinear->set_input_x(*npu_inputs[0]);
114   } else if (resize_method_ == schema::ResizeMethod_NEAREST) {
115     auto resize_nearest = reinterpret_cast<hiai::op::ResizeNearestNeighborV2 *>(resize_);
116     resize_nearest->set_input_x(*npu_inputs[0]);
117   } else {
118     MS_LOG(WARNING) << "Unsupported resize method type:" << resize_method_;
119     return RET_ERROR;
120   }
121   return RET_OK;
122 }
123 
GetNPUOp()124 ge::Operator *ResizeNPUOp::GetNPUOp() { return this->resize_; }
125 
~ResizeNPUOp()126 ResizeNPUOp::~ResizeNPUOp() {
127   if (resize_ != nullptr) {
128     delete resize_;
129     resize_ = nullptr;
130   }
131   if (out_size_ != nullptr) {
132     delete out_size_;
133     out_size_ = nullptr;
134   }
135 }
136 }  // namespace mindspore
137