1 /**
2 * Copyright 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 "include/api/types.h"
18 #include <string.h>
19 #include <limits.h>
20 #include <numeric>
21 #include "include/api/status.h"
22 #include "include/api/dual_abi_helper.h"
23 #include "src/cxx_api/tensor/tensor_impl.h"
24 #include "src/common/log_adapter.h"
25 #include "include/version.h"
26
27 namespace mindspore {
28 class Buffer::Impl {
29 public:
Impl()30 Impl() : data_() {}
31 ~Impl() = default;
Impl(const void * data,size_t data_len)32 Impl(const void *data, size_t data_len) {
33 if (data != nullptr) {
34 (void)SetData(data, data_len);
35 } else {
36 ResizeData(data_len);
37 }
38 }
39
Data() const40 const void *Data() const { return data_.data(); }
MutableData()41 void *MutableData() { return data_.data(); }
DataSize() const42 size_t DataSize() const { return data_.size(); }
43
ResizeData(size_t data_len)44 bool ResizeData(size_t data_len) {
45 data_.resize(data_len);
46 return true;
47 }
48
SetData(const void * data,size_t data_len)49 bool SetData(const void *data, size_t data_len) {
50 ResizeData(data_len);
51 if (DataSize() != data_len) {
52 MS_LOG(ERROR) << "Set data failed, tensor current data size " << DataSize() << " not match data len " << data_len;
53 return false;
54 }
55
56 if (data == nullptr) {
57 return data_len == 0;
58 }
59
60 if (MutableData() == nullptr) {
61 MS_LOG(ERROR) << "Set data failed, data len " << data_len;
62 return false;
63 }
64
65 memcpy(MutableData(), data, data_len);
66
67 return true;
68 }
69
70 protected:
71 std::vector<uint8_t> data_;
72 };
73
MSTensor()74 MSTensor::MSTensor() : impl_(std::make_shared<Impl>()) {}
MSTensor(std::nullptr_t)75 MSTensor::MSTensor(std::nullptr_t) : impl_(nullptr) {}
MSTensor(const std::shared_ptr<Impl> & impl)76 MSTensor::MSTensor(const std::shared_ptr<Impl> &impl) : impl_(impl) {}
MSTensor(const std::vector<char> & name,enum DataType type,const std::vector<int64_t> & shape,const void * data,size_t data_len)77 MSTensor::MSTensor(const std::vector<char> &name, enum DataType type, const std::vector<int64_t> &shape,
78 const void *data, size_t data_len)
79 : impl_(Impl::CreateTensorImpl(CharToString(name), type, shape, data, data_len)) {}
80 MSTensor::~MSTensor() = default;
81
operator ==(std::nullptr_t) const82 bool MSTensor::operator==(std::nullptr_t) const { return impl_ == nullptr; }
83
operator !=(std::nullptr_t) const84 bool MSTensor::operator!=(std::nullptr_t) const { return impl_ != nullptr; }
85
operator ==(const MSTensor & tensor) const86 bool MSTensor::operator==(const MSTensor &tensor) const {
87 return impl_ == nullptr ? false : impl_->lite_tensor() == tensor.impl_->lite_tensor();
88 }
89
CreateTensor(const std::vector<char> & name,enum DataType type,const std::vector<int64_t> & shape,const void * data,size_t data_len)90 MSTensor *MSTensor::CreateTensor(const std::vector<char> &name, enum DataType type, const std::vector<int64_t> &shape,
91 const void *data, size_t data_len) noexcept {
92 if (data_len < 0 || data_len > MAX_MALLOC_SIZE) {
93 MS_LOG(ERROR) << "data_len is error.";
94 return nullptr;
95 }
96 if (data_len > 0 && data == nullptr) {
97 MS_LOG(ERROR) << "Mull data ptr of tensor.";
98 return nullptr;
99 }
100 auto impl = Impl::CreateTensorImpl(CharToString(name), type, shape, nullptr, data_len);
101 if (impl == nullptr) {
102 MS_LOG(ERROR) << "Allocate tensor impl failed.";
103 return nullptr;
104 }
105 impl->set_own_data(true);
106
107 auto ms_tensor = new (std::nothrow) MSTensor(impl);
108 if (ms_tensor == nullptr) {
109 MS_LOG(ERROR) << "Allocate tensor impl failed.";
110 return nullptr;
111 }
112
113 if (data != nullptr) {
114 if (ms_tensor->MutableData() == nullptr) {
115 MS_LOG(ERROR) << "Allocate data failed.";
116 delete ms_tensor;
117 return nullptr;
118 }
119 ::memcpy(ms_tensor->MutableData(), data, data_len);
120 }
121 return ms_tensor;
122 }
123
CreateRefTensor(const std::vector<char> & name,enum DataType type,const std::vector<int64_t> & shape,const void * data,size_t data_len)124 MSTensor *MSTensor::CreateRefTensor(const std::vector<char> &name, enum DataType type,
125 const std::vector<int64_t> &shape, const void *data, size_t data_len) noexcept {
126 auto impl = Impl::CreateTensorImpl(CharToString(name), type, shape, data, data_len);
127 if (impl == nullptr) {
128 MS_LOG(ERROR) << "Allocate tensor impl failed.";
129 return nullptr;
130 }
131 auto ms_tensor = new (std::nothrow) MSTensor(impl);
132 if (ms_tensor == nullptr) {
133 MS_LOG(ERROR) << "Allocate tensor impl failed.";
134 return nullptr;
135 }
136 return ms_tensor;
137 }
138
CreateDevTensor(const std::vector<char> & name,enum DataType type,const std::vector<int64_t> & shape,const void * data,size_t data_len)139 MSTensor *MSTensor::CreateDevTensor(const std::vector<char> &name, enum DataType type,
140 const std::vector<int64_t> &shape, const void *data, size_t data_len) noexcept {
141 MS_LOG(ERROR) << "Unsupported Feature.";
142 return nullptr;
143 }
144
CharStringsToTensor(const std::vector<char> & name,const std::vector<std::vector<char>> & inputs)145 MSTensor *MSTensor::CharStringsToTensor(const std::vector<char> &name, const std::vector<std::vector<char>> &inputs) {
146 #ifndef STRING_KERNEL_CLIP
147 auto impl = Impl::StringsToTensorImpl(CharToString(name), VectorCharToString(inputs));
148 if (impl == nullptr) {
149 MS_LOG(ERROR) << "Allocate tensor impl failed.";
150 return nullptr;
151 }
152 auto ms_tensor = new (std::nothrow) MSTensor(impl);
153 if (ms_tensor == nullptr) {
154 MS_LOG(ERROR) << "Allocate tensor impl failed.";
155 return nullptr;
156 }
157 return ms_tensor;
158 #else
159 MS_LOG(ERROR) << unsupport_string_tensor_log;
160 return nullptr;
161 #endif
162 }
163
TensorToStringChars(const MSTensor & tensor)164 std::vector<std::vector<char>> MSTensor::TensorToStringChars(const MSTensor &tensor) {
165 #ifndef STRING_KERNEL_CLIP
166 if (tensor.impl_ == nullptr) {
167 MS_LOG(ERROR) << "Invalid tensor.";
168 std::vector<std::vector<char>> empty;
169 return empty;
170 }
171 return VectorStringToChar(Impl::TensorImplToStrings(tensor.impl_));
172 #else
173 std::vector<std::vector<char>> empty;
174 MS_LOG(ERROR) << unsupport_string_tensor_log;
175 return empty;
176 #endif
177 }
178
Clone() const179 MSTensor *MSTensor::Clone() const {
180 if (impl_ == nullptr) {
181 MS_LOG(ERROR) << "Invalid tensor.";
182 return nullptr;
183 }
184 auto data_len = this->DataSize();
185 if (data_len <= 0 || data_len > MAX_MALLOC_SIZE) {
186 MS_LOG(ERROR) << "Illegal data size of tensor.";
187 return nullptr;
188 }
189 auto impl = Impl::CreateTensorImpl(this->Name(), this->DataType(), this->Shape(), nullptr, data_len);
190 if (impl == nullptr) {
191 MS_LOG(ERROR) << "Allocate tensor impl failed.";
192 return nullptr;
193 }
194 impl->set_own_data(true);
195
196 auto ms_tensor = new (std::nothrow) MSTensor(impl);
197 if (ms_tensor == nullptr) {
198 MS_LOG(ERROR) << "Allocate tensor impl failed.";
199 return nullptr;
200 }
201
202 if (impl_->Data() != nullptr) {
203 if (ms_tensor->MutableData() == nullptr) {
204 MS_LOG(ERROR) << "Allocate data failed.";
205 delete ms_tensor;
206 return nullptr;
207 }
208 ::memcpy(ms_tensor->MutableData(), impl_->MutableData(), data_len);
209 }
210 return ms_tensor;
211 }
212
CharName() const213 std::vector<char> MSTensor::CharName() const {
214 if (impl_ == nullptr) {
215 MS_LOG(ERROR) << "Invalid tensor implement.";
216 return std::vector<char>();
217 }
218 return StringToChar(impl_->Name());
219 }
220
ElementNum() const221 int64_t MSTensor::ElementNum() const {
222 if (impl_ == nullptr) {
223 MS_LOG(ERROR) << "Invalid tensor implement.";
224 return -1;
225 }
226 return impl_->ElementNum();
227 }
228
DataType() const229 enum DataType MSTensor::DataType() const {
230 if (impl_ == nullptr) {
231 MS_LOG(ERROR) << "Invalid tensor implement.";
232 return DataType::kTypeUnknown;
233 }
234 return impl_->DataType();
235 }
236
Shape() const237 const std::vector<int64_t> &MSTensor::Shape() const {
238 static std::vector<int64_t> empty;
239 if (impl_ == nullptr) {
240 MS_LOG(ERROR) << "Invalid tensor implement.";
241 return empty;
242 }
243 return impl_->Shape();
244 }
245
Data() const246 std::shared_ptr<const void> MSTensor::Data() const {
247 if (impl_ == nullptr) {
248 MS_LOG(ERROR) << "Invalid tensor implement.";
249 return nullptr;
250 }
251 return impl_->Data();
252 }
253
MutableData()254 void *MSTensor::MutableData() {
255 if (impl_ == nullptr) {
256 MS_LOG(ERROR) << "Invalid tensor implement.";
257 return nullptr;
258 }
259 return impl_->MutableData();
260 }
261
IsConst() const262 bool MSTensor::IsConst() const {
263 if (impl_ == nullptr) {
264 MS_LOG(ERROR) << "Invalid tensor implement.";
265 return false;
266 }
267 return impl_->IsConst();
268 }
269
DataSize() const270 size_t MSTensor::DataSize() const {
271 if (impl_ == nullptr) {
272 MS_LOG(ERROR) << "Invalid tensor implement.";
273 return 0;
274 }
275 return impl_->DataSize();
276 }
277
IsDevice() const278 bool MSTensor::IsDevice() const {
279 MS_LOG(ERROR) << "Unsupported feature.";
280 return false;
281 }
282
DestroyTensorPtr(MSTensor * tensor)283 void MSTensor::DestroyTensorPtr(MSTensor *tensor) noexcept {
284 if (tensor != nullptr) {
285 delete tensor;
286 }
287 }
288
SetShape(const std::vector<int64_t> & shape)289 void MSTensor::SetShape(const std::vector<int64_t> &shape) {
290 if (impl_ == nullptr) {
291 MS_LOG(ERROR) << "Invalid tensor implement.";
292 return;
293 }
294 impl_->SetShape(shape);
295 }
296
SetDataType(enum DataType data_type)297 void MSTensor::SetDataType(enum DataType data_type) {
298 if (impl_ == nullptr) {
299 MS_LOG(ERROR) << "Invalid tensor implement.";
300 return;
301 }
302 impl_->SetDataType(data_type);
303 }
304
SetTensorName(const std::string & name)305 void MSTensor::SetTensorName(const std::string &name) {
306 if (impl_ == nullptr) {
307 MS_LOG(ERROR) << "Invalid tensor implement.";
308 return;
309 }
310 impl_->SetName(name);
311 }
312
SetAllocator(std::shared_ptr<Allocator> allocator)313 void MSTensor::SetAllocator(std::shared_ptr<Allocator> allocator) {
314 if (impl_ == nullptr) {
315 MS_LOG(ERROR) << "Invalid tensor implement.";
316 return;
317 }
318 return impl_->SetAllocator(allocator);
319 }
320
allocator() const321 std::shared_ptr<Allocator> MSTensor::allocator() const {
322 if (impl_ == nullptr) {
323 MS_LOG(ERROR) << "Invalid tensor implement.";
324 return nullptr;
325 }
326 return impl_->allocator();
327 }
328
SetFormat(mindspore::Format format)329 void MSTensor::SetFormat(mindspore::Format format) {
330 if (impl_ == nullptr) {
331 MS_LOG(ERROR) << "Invalid tensor implement.";
332 return;
333 }
334 return impl_->SetFormat(format);
335 }
336
format() const337 mindspore::Format MSTensor::format() const {
338 if (impl_ == nullptr) {
339 MS_LOG(ERROR) << "Invalid tensor implement.";
340 return mindspore::Format::NHWC;
341 }
342 return impl_->format();
343 }
344
SetData(void * data)345 void MSTensor::SetData(void *data) {
346 if (impl_ == nullptr) {
347 MS_LOG(ERROR) << "Invalid tensor implement.";
348 return;
349 }
350 return impl_->SetData(data);
351 }
352
QuantParams() const353 std::vector<QuantParam> MSTensor::QuantParams() const {
354 if (impl_ == nullptr) {
355 MS_LOG(ERROR) << "Invalid tensor implement.";
356 return std::vector<QuantParam>{};
357 }
358 return impl_->QuantParams();
359 }
360
SetQuantParams(std::vector<QuantParam> quant_params)361 void MSTensor::SetQuantParams(std::vector<QuantParam> quant_params) {
362 if (impl_ == nullptr) {
363 MS_LOG(ERROR) << "Invalid tensor implement.";
364 return;
365 }
366 return impl_->SetQuantParams(quant_params);
367 }
368
Buffer()369 Buffer::Buffer() : impl_(std::make_shared<Impl>()) {}
Buffer(const void * data,size_t data_len)370 Buffer::Buffer(const void *data, size_t data_len) : impl_(std::make_shared<Impl>(data, data_len)) {}
371 Buffer::~Buffer() = default;
372
Clone() const373 Buffer Buffer::Clone() const {
374 Buffer ret;
375 if (impl_ == nullptr) {
376 MS_LOG(ERROR) << "impl is nullptr.";
377 return ret;
378 }
379 ret.impl_ = std::make_shared<Impl>(*impl_);
380 return ret;
381 }
382
Data() const383 const void *Buffer::Data() const {
384 if (impl_ == nullptr) {
385 MS_LOG(ERROR) << "impl is nullptr.";
386 return nullptr;
387 }
388 return impl_->Data();
389 }
390
MutableData()391 void *Buffer::MutableData() {
392 if (impl_ == nullptr) {
393 MS_LOG(ERROR) << "impl is nullptr.";
394 return nullptr;
395 }
396 return impl_->MutableData();
397 }
398
DataSize() const399 size_t Buffer::DataSize() const {
400 if (impl_ == nullptr) {
401 MS_LOG(ERROR) << "impl is nullptr.";
402 return 0;
403 }
404 return impl_->DataSize();
405 }
406
ResizeData(size_t data_len)407 bool Buffer::ResizeData(size_t data_len) {
408 if (impl_ == nullptr) {
409 MS_LOG(ERROR) << "impl is nullptr.";
410 return false;
411 }
412 return impl_->ResizeData(data_len);
413 }
414
SetData(const void * data,size_t data_len)415 bool Buffer::SetData(const void *data, size_t data_len) {
416 if (impl_ == nullptr) {
417 MS_LOG(ERROR) << "impl is nullptr.";
418 return false;
419 }
420 return impl_->SetData(data, data_len);
421 }
422
CharVersion()423 std::vector<char> CharVersion() { return StringToChar(lite::Version()); }
424 } // namespace mindspore
425