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 "tools/common/tensor_util.h"
18 #include "src/common/utils.h"
19 #include "tools/common/graph_util.h"
20 #include "abstract/utils.h"
21 #include "nnacl/op_base.h"
22
23 namespace mindspore::lite {
GetTensorQuantParam(const std::unique_ptr<TensorT> & tensor)24 std::unique_ptr<QuantParamT> GetTensorQuantParam(const std::unique_ptr<TensorT> &tensor) {
25 MS_ASSERT(tensor != nullptr);
26 auto &quantParams = tensor->quantParams;
27 if (!quantParams.empty()) {
28 return CopyQuantParamT(quantParams.front());
29 } else {
30 return nullptr;
31 }
32 }
CopyQuantParamT(const std::unique_ptr<schema::QuantParamT> & srcQuantParam)33 std::unique_ptr<schema::QuantParamT> CopyQuantParamT(const std::unique_ptr<schema::QuantParamT> &srcQuantParam) {
34 MS_ASSERT(srcQuantParam != nullptr);
35 std::unique_ptr<schema::QuantParamT> dstQuantParam = std::make_unique<schema::QuantParamT>();
36 dstQuantParam->inited = srcQuantParam->inited;
37 dstQuantParam->scale = srcQuantParam->scale;
38 dstQuantParam->zeroPoint = srcQuantParam->zeroPoint;
39 dstQuantParam->min = srcQuantParam->min;
40 dstQuantParam->max = srcQuantParam->max;
41 dstQuantParam->narrowRange = srcQuantParam->narrowRange;
42 dstQuantParam->numBits = srcQuantParam->numBits;
43 dstQuantParam->dstDtype = srcQuantParam->dstDtype;
44 dstQuantParam->multiplier = srcQuantParam->multiplier;
45 return dstQuantParam;
46 }
47
CreateTensorInfo(const void * data,size_t data_size,const std::vector<int64_t> & shape,TypeId data_type)48 tensor::TensorPtr CreateTensorInfo(const void *data, size_t data_size, const std::vector<int64_t> &shape,
49 TypeId data_type) {
50 if (data_type == kTypeUnknown) {
51 MS_LOG(ERROR) << "data type of tensor is unknown";
52 return nullptr;
53 }
54 tensor::TensorPtr tensor_info = nullptr;
55 if (shape.empty() && data_size == mindspore::abstract::TypeIdSize(data_type)) {
56 ShapeVector scalar_shape = {1};
57 tensor_info = std::make_shared<tensor::Tensor>(data_type, scalar_shape);
58 if (tensor_info == nullptr) {
59 MS_LOG(ERROR) << "new tensor init failed";
60 return nullptr;
61 }
62 tensor_info->set_shape({});
63 } else {
64 tensor_info = std::make_shared<tensor::Tensor>(data_type, shape);
65 }
66 if (tensor_info == nullptr) {
67 MS_LOG(ERROR) << "new tensor init failed";
68 return nullptr;
69 }
70 if (data_size == 0) {
71 return tensor_info;
72 }
73 if (data == nullptr) {
74 MS_LOG(ERROR) << "input tensor data is nullptr";
75 return nullptr;
76 }
77 auto ret = memcpy_s(tensor_info->data_c(), tensor_info->data().nbytes(), data, data_size);
78 if (ret != EOK) {
79 MS_LOG(ERROR) << "memcpy_s error : " << ret;
80 return nullptr;
81 }
82 return tensor_info;
83 }
84
CreateTensorAbstract(const std::vector<int64_t> & shape,TypeId data_type)85 AbstractBasePtr CreateTensorAbstract(const std::vector<int64_t> &shape, TypeId data_type) {
86 auto tensor_info = CreateTensorInfo(nullptr, 0, shape, data_type);
87 if (tensor_info == nullptr) {
88 MS_LOG(ERROR) << "Create tensor info failed";
89 return nullptr;
90 }
91 auto abstract = tensor_info->ToAbstract();
92 if (abstract == nullptr) {
93 MS_LOG(ERROR) << "Create tensor abstarct failed";
94 return nullptr;
95 }
96 return abstract;
97 }
98
SetParameterAbstractAndParam(const ParameterPtr & parameter,const void * data,size_t data_size,const std::vector<int64_t> & shape,TypeId data_type)99 int SetParameterAbstractAndParam(const ParameterPtr ¶meter, const void *data, size_t data_size,
100 const std::vector<int64_t> &shape, TypeId data_type) {
101 if (parameter == nullptr) {
102 MS_LOG(ERROR) << "Input parameter is nullptr";
103 return RET_INPUT_PARAM_INVALID;
104 }
105 auto tensor_info = CreateTensorInfo(data, data_size, shape, data_type);
106 if (tensor_info == nullptr) {
107 MS_LOG(ERROR) << "Create tensor info failed";
108 return RET_ERROR;
109 }
110 auto abstract = tensor_info->ToAbstract();
111 if (abstract == nullptr) {
112 MS_LOG(ERROR) << "Create tensor abstarct failed";
113 return RET_ERROR;
114 }
115 parameter->set_abstract(abstract);
116 return RET_OK;
117 }
118
SetTensorData(const tensor::TensorPtr & tensor_info,const void * data,size_t data_size)119 int SetTensorData(const tensor::TensorPtr &tensor_info, const void *data, size_t data_size) {
120 if (tensor_info == nullptr) {
121 MS_LOG(ERROR) << "tensor info is nullptr.";
122 return RET_ERROR;
123 }
124 if (data == nullptr) {
125 MS_LOG(ERROR) << "data is nullptr.";
126 return RET_ERROR;
127 }
128 auto ret = memcpy_s(tensor_info->data_c(), tensor_info->data().nbytes(), data, data_size);
129 if (ret != EOK) {
130 MS_LOG(ERROR) << "memcpy_s error : " << ret;
131 return RET_ERROR;
132 }
133 return RET_OK;
134 }
135
CreateTensorTFromTensorInfo(const tensor::TensorPtr & tensor_info,const std::string & tensor_name)136 std::unique_ptr<schema::TensorT> CreateTensorTFromTensorInfo(const tensor::TensorPtr &tensor_info,
137 const std::string &tensor_name) {
138 if (tensor_info == nullptr) {
139 MS_LOG(ERROR) << "Input tensor is nullptr";
140 return nullptr;
141 }
142 auto schema_tensor = std::make_unique<schema::TensorT>();
143 MS_CHECK_TRUE_MSG(schema_tensor != nullptr, nullptr, "schema_tensor is nullptr");
144 schema_tensor->name = tensor_name;
145 auto ret = UpdateTensorTFromTensorInfo(tensor_info, &schema_tensor);
146 if (ret != RET_OK) {
147 MS_LOG(ERROR) << "Init schema tensor failed";
148 return nullptr;
149 }
150 return schema_tensor;
151 }
152
UpdateTensorTFromTensorInfo(const tensor::TensorPtr & src_tensor,std::unique_ptr<schema::TensorT> * dst_tensor)153 int UpdateTensorTFromTensorInfo(const tensor::TensorPtr &src_tensor, std::unique_ptr<schema::TensorT> *dst_tensor) {
154 if (src_tensor == nullptr) {
155 MS_LOG(ERROR) << "Input tensor info is nullptr";
156 return RET_INPUT_PARAM_INVALID;
157 }
158 if (dst_tensor == nullptr || *dst_tensor == nullptr) {
159 MS_LOG(ERROR) << "Input schema tensor is nullptr";
160 return RET_INPUT_PARAM_INVALID;
161 }
162 auto &schema_tensor = *dst_tensor;
163 schema_tensor->format = schema::Format_NHWC;
164 schema_tensor->dataType = src_tensor->data_type();
165 auto &shape_vector = src_tensor->shape();
166 std::vector<int32_t> dims;
167 (void)std::transform(shape_vector.begin(), shape_vector.end(), std::back_inserter(dims),
168 [](const int64_t &value) { return static_cast<int32_t>(value); });
169 schema_tensor->dims = dims;
170 if (src_tensor->data().data() != nullptr) {
171 schema_tensor->data.resize(src_tensor->data().nbytes());
172 if (EOK != memcpy_s(schema_tensor->data.data(), schema_tensor->data.size(), src_tensor->data().data(),
173 src_tensor->data().nbytes())) {
174 MS_LOG(ERROR) << "memcpy_s failed.";
175 return RET_ERROR;
176 }
177 }
178 return RET_OK;
179 }
180
InitParameterFromTensorInfo(const ParameterPtr & param_node,const tensor::TensorPtr & tensor_info)181 int InitParameterFromTensorInfo(const ParameterPtr ¶m_node, const tensor::TensorPtr &tensor_info) {
182 if (tensor_info == nullptr) {
183 MS_LOG(ERROR) << "tensor info is nullptr.";
184 return RET_ERROR;
185 }
186 auto abstract_tensor = tensor_info->ToAbstract();
187 if (abstract_tensor == nullptr) {
188 MS_LOG(ERROR) << "Create abstract tensor failed.";
189 return RET_ERROR;
190 }
191 param_node->set_abstract(abstract_tensor);
192 param_node->set_default_param(tensor_info);
193 return RET_OK;
194 }
195
GetElementSize(const TensorT & tensor)196 size_t GetElementSize(const TensorT &tensor) { return GetElementSize(TypeId(tensor.dataType)); }
197
GetElementSize(const TypeId & dataType)198 size_t GetElementSize(const TypeId &dataType) {
199 switch (dataType) {
200 case kNumberTypeUInt8:
201 return sizeof(uint8_t);
202 case kNumberTypeInt32:
203 return sizeof(int32_t);
204 case kNumberTypeFloat:
205 return sizeof(float);
206 case kNumberTypeInt16:
207 return sizeof(int16_t);
208 case kNumberTypeInt8:
209 return sizeof(int8_t);
210 case kNumberTypeUInt32:
211 return sizeof(uint32_t);
212 default:
213 return sizeof(float);
214 }
215 }
216
GetShapeSize(const TensorT & tensor)217 size_t GetShapeSize(const TensorT &tensor) {
218 auto shape = tensor.dims;
219 size_t shapeSize = 1;
220 for (auto dim : shape) {
221 shapeSize *= dim;
222 }
223 return shapeSize;
224 }
225
CopyTensorDefT(const std::unique_ptr<TensorT> & oldTensor)226 std::unique_ptr<TensorT> CopyTensorDefT(const std::unique_ptr<TensorT> &oldTensor) {
227 auto newTensor = std::unique_ptr<TensorT>(new (std::nothrow) TensorT);
228 if (newTensor == nullptr) {
229 MS_LOG(ERROR) << "new TensorT failed";
230 return nullptr;
231 }
232 newTensor->dims = oldTensor->dims;
233 newTensor->format = oldTensor->format;
234 newTensor->dataType = oldTensor->dataType;
235 newTensor->refCount = oldTensor->refCount;
236 newTensor->nodeType = oldTensor->nodeType;
237 newTensor->data = oldTensor->data;
238 if (!oldTensor->quantParams.empty()) {
239 newTensor->quantParams.emplace_back(GetTensorQuantParam(oldTensor));
240 }
241 return newTensor;
242 }
243
GetRefCount(MetaGraphT * graphT,uint32_t tensorIdx)244 size_t GetRefCount(MetaGraphT *graphT, uint32_t tensorIdx) {
245 MS_ASSERT(graphT != nullptr);
246 MS_ASSERT(graphT->allTensors.size() > tensorIdx);
247 size_t refCount = 0;
248 for (auto &node : graphT->nodes) {
249 MS_ASSERT(node != nullptr);
250 if (IsContain(node->inputIndex, tensorIdx)) {
251 refCount++;
252 }
253 }
254 return refCount;
255 }
GetShapeSize(const std::vector<int32_t> & shape)256 size_t GetShapeSize(const std::vector<int32_t> &shape) {
257 size_t shapeSize = 1;
258 for (auto dim : shape) {
259 shapeSize *= dim;
260 }
261 return shapeSize;
262 }
263 } // namespace mindspore::lite
264