• 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 "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 &parameter, 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 &param_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