|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517 |
- /**
- * Copyright 2019 Huawei Technologies Co., Ltd
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- #include "include/tensor.h"
- #include "common/mslog.h"
- #include "src/op_common.h"
- #include "include/errorcode.h"
- #include "securec/include/securec.h"
- #include "common/common.h"
- #include "src/runtime/allocator.h"
-
- namespace mindspore {
- namespace predict {
- Tensor *Tensor::CopyFromTensorDef(const TensorDef &tensorDef) {
- std::vector<int64_t> dims;
-
- if (tensorDef.dims() == nullptr) {
- MS_LOGD("tensorDef->dims is nullptr");
- } else {
- MS_ASSERT(tensorDef.dims()->data() != nullptr);
- for (uint32_t j = 0; j < tensorDef.dims()->size(); j++) {
- dims.push_back(tensorDef.dims()->data()[j]);
- }
- }
- auto tensor =
- std::unique_ptr<Tensor>(new (std::nothrow) Tensor(tensorDef.dataType(), dims, tensorDef.format(), nullptr));
- if (tensor == nullptr) {
- MS_LOGE("new Tensor failed");
- return nullptr;
- }
-
- if (tensorDef.refCount() == MSConst_WEIGHT_REFCOUNT && tensorDef.data() != nullptr && tensorDef.data()->size() > 0) {
- if (dims.size() < 1) {
- tensor->SetDims({1});
- }
- auto ret = tensor->MallocData();
- if (ret != RET_OK) {
- MS_LOGE("malloc data fail,datasize %zu", tensor->GetDataSize());
- return nullptr;
- }
- auto tensorData = tensorDef.data()->data();
- ret = memcpy_sp(tensor->GetData(), tensor->GetDataSize(), tensorData, tensorDef.data()->size());
- if (ret != RET_OK) {
- MS_LOGE("copy data fail,dst size %zu, src size %u", tensor->GetDataSize(), tensorDef.data()->size());
- return nullptr;
- }
- }
- tensor->refCount = tensorDef.refCount();
- return tensor.release();
- }
-
- Tensor::Tensor(const Tensor &tensor, bool copyData) {
- format = tensor.format;
- dlTensor.data = nullptr;
- dlTensor.ctx.device_type = tensor.dlTensor.ctx.device_type;
- dlTensor.ctx.device_id = tensor.dlTensor.ctx.device_id;
- dlTensor.strides = nullptr;
- dlTensor.byte_offset = tensor.dlTensor.byte_offset;
- dlTensor.dtype.code = tensor.dlTensor.dtype.code;
- dlTensor.dtype.bits = tensor.dlTensor.dtype.bits;
- dlTensor.dtype.lanes = tensor.dlTensor.dtype.lanes;
-
- dlTensor.ndim = tensor.dlTensor.ndim;
- if (dlTensor.ndim > 0) {
- dlTensor.shape = new (std::nothrow) int64_t[dlTensor.ndim];
- if (dlTensor.shape != nullptr) {
- for (int i = 0; i < dlTensor.ndim; i++) {
- dlTensor.shape[i] = tensor.dlTensor.shape[i];
- }
- } else {
- MS_LOGW("new shape fail,ndim %d", dlTensor.ndim);
- }
- } else {
- dlTensor.shape = nullptr;
- }
- if (copyData) {
- allocator = tensor.allocator;
- refCount = tensor.refCount;
- auto ret = MallocData();
- if (ret != RET_OK) {
- return;
- }
- size_t datasize = GetDataSize();
- ret = memcpy_sp(dlTensor.data, datasize, tensor.dlTensor.data, datasize);
- if (ret != RET_OK) {
- return;
- }
- }
- }
-
- Tensor::Tensor(DataType dt, const std::vector<int64_t> &dims, Format format, void *data) {
- this->format = format;
- dlTensor.data = data;
- dlTensor.ctx.device_type = DLDeviceType::kDLCPU;
- dlTensor.ctx.device_id = 0;
- dlTensor.strides = nullptr;
- dlTensor.byte_offset = 0;
-
- dlTensor.ndim = static_cast<int>(dims.size());
- if (dlTensor.ndim > 0) {
- dlTensor.shape = new (std::nothrow) int64_t[dlTensor.ndim];
- if (dlTensor.shape != nullptr) {
- for (int i = 0; i < dlTensor.ndim; i++) {
- dlTensor.shape[i] = dims[i];
- }
- } else {
- MS_LOGW("new shape fail,ndim %d", dlTensor.ndim);
- }
- } else {
- dlTensor.shape = nullptr;
- }
-
- SetDataType(dt);
- }
-
- Tensor::~Tensor() { FreeTensor(); }
-
- DLDataType Tensor::GetTensorDtype() const { return dlTensor.dtype; }
-
- void *Tensor::GetData() const { return dlTensor.data; }
-
- void Tensor::SetData(void *data) { dlTensor.data = data; }
-
- DataType Tensor::GetDataType() const {
- DataType dataType = DataType_DT_UNDEFINED;
- switch (dlTensor.dtype.code) {
- case kDLFloat:
- if (dlTensor.dtype.bits == 32) {
- dataType = DataType_DT_FLOAT;
- } else if (dlTensor.dtype.bits == 16) {
- dataType = DataType_DT_FLOAT16;
- }
- break;
- case kDLInt:
- if (dlTensor.dtype.bits == 32) {
- dataType = DataType_DT_INT32;
- } else if (dlTensor.dtype.bits == 8) {
- dataType = DataType_DT_INT8;
- }
- break;
- case kDLUInt:
- if (dlTensor.dtype.bits == 32) {
- dataType = DataType_DT_UINT32;
- } else if (dlTensor.dtype.bits == 8) {
- dataType = DataType_DT_UINT8;
- }
- break;
- default:
- break;
- }
- return dataType;
- }
-
- void Tensor::SetDataType(DataType dt) {
- switch (dt) {
- case DataType_DT_FLOAT:
- dlTensor.dtype.code = kDLFloat;
- dlTensor.dtype.bits = 32;
- dlTensor.dtype.lanes = 1;
- break;
- case DataType_DT_FLOAT16:
- dlTensor.dtype.code = kDLFloat;
- dlTensor.dtype.bits = 16;
- dlTensor.dtype.lanes = 1;
- break;
- case DataType_DT_INT8:
- dlTensor.dtype.code = kDLInt;
- dlTensor.dtype.bits = 8;
- dlTensor.dtype.lanes = 1;
- break;
- case DataType_DT_UINT8:
- dlTensor.dtype.code = kDLUInt;
- dlTensor.dtype.bits = 8;
- dlTensor.dtype.lanes = 1;
- break;
- case DataType_DT_INT32:
- dlTensor.dtype.code = kDLInt;
- dlTensor.dtype.bits = 32;
- dlTensor.dtype.lanes = 1;
- break;
- case DataType_DT_UINT32:
- dlTensor.dtype.code = kDLUInt;
- dlTensor.dtype.bits = 32;
- dlTensor.dtype.lanes = 1;
- break;
- default:
- MS_LOGW(" DataType %d is not implemented.", dt);
- MS_LOGW(" DataType DT_FLOAT is used.");
- dlTensor.dtype.code = kDLFloat;
- dlTensor.dtype.bits = 32;
- dlTensor.dtype.lanes = 1;
- return;
- }
- }
-
- int Tensor::GetNDim() const { return dlTensor.ndim; }
-
- std::vector<int64_t> Tensor::GetDims() const {
- std::vector<int64_t> dims;
- for (int i = 0; i < dlTensor.ndim; i++) {
- dims.push_back(dlTensor.shape[i]);
- }
- return dims;
- }
-
- size_t Tensor::GetElementSize() const {
- const int tile = 4;
- if (format == Format_NC4HW4) {
- size_t size = 1;
- for (int i = 0; i < dlTensor.ndim; i++) {
- auto var = static_cast<size_t>(dlTensor.shape[i]);
- if (i == 1) {
- var = UP_DIV(var, tile) * tile;
- }
- size *= var;
- }
- return size;
- } else {
- size_t size = 1;
- for (int i = 0; i < dlTensor.ndim; i++) {
- size *= static_cast<size_t>(dlTensor.shape[i]);
- }
-
- return size;
- }
- }
-
- size_t Tensor::GetDataSize() const {
- size_t size = GetElementSize();
-
- const int BYTES = 8;
- const int GAP = 7;
- size *= (dlTensor.dtype.bits * dlTensor.dtype.lanes + GAP) / BYTES;
- return size;
- }
-
- int Tensor::MallocData(std::shared_ptr<Allocator> allocator, int refCount) {
- if (dlTensor.data != nullptr) {
- this->refCount += refCount;
- return RET_OK;
- }
- this->refCount = refCount;
-
- size_t size = GetDataSize();
- if (allocator) {
- this->allocator = allocator;
- dlTensor.data = allocator->Malloc(size);
- } else {
- if (size > MAX_MALLOC_SIZE) {
- return RET_ERROR;
- }
- dlTensor.data = malloc(size);
- }
- if (dlTensor.data == nullptr) {
- return RET_ERROR;
- }
- return RET_OK;
- }
-
- void Tensor::ForceFreeData() {
- if (allocator) {
- allocator->Free(dlTensor.data);
- } else {
- free(dlTensor.data);
- }
- dlTensor.data = nullptr;
- }
-
- void Tensor::FreeData() {
- --refCount;
- if (refCount <= 0) {
- ForceFreeData();
- }
- }
-
- bool Tensor::CompareShape(const Tensor &dst) {
- if (dlTensor.ndim != dst.dlTensor.ndim || dlTensor.shape == nullptr || dst.dlTensor.shape == nullptr) {
- MS_LOGE("param error, one.ndim: %d, other.ndim: %d, one shape %p,other shape %p", dlTensor.ndim, dst.dlTensor.ndim,
- dlTensor.shape, dst.dlTensor.shape);
- return false;
- }
-
- for (int i = 0; i < dlTensor.ndim; i++) {
- if (dlTensor.shape[i] != dst.dlTensor.shape[i]) {
- MS_LOGE("one.shape[%d]: %ld, other.shape[%d]: %ld", i, dlTensor.shape[i], i, dst.dlTensor.shape[i]);
- return false;
- }
- }
- return true;
- }
-
- bool Tensor::CompareShape(const std::vector<int64_t> &other) {
- if (dlTensor.ndim != other.size() || dlTensor.shape == nullptr) {
- return false;
- }
-
- for (int i = 0; i < dlTensor.ndim; i++) {
- if (dlTensor.shape[i] != other[i]) {
- return false;
- }
- }
- return true;
- }
-
- int64_t Tensor::Height() const {
- if (dlTensor.shape == nullptr) {
- MS_LOGE("shape is null");
- }
- if (dlTensor.ndim != DIM_DEFAULT_SIZE) {
- MS_LOGE("Tensor should be 4 dimensional.");
- return -1;
- }
- switch (this->format) {
- case Format_NCHW:
- case Format_NC4HW4:
- return dlTensor.shape[NCHW_H];
- case Format_NHWC:
- return dlTensor.shape[NHWC_H];
- default:
- MS_LOGE("Unsupported format: %d", this->format);
- return -1;
- }
- }
-
- int64_t Tensor::Width() const {
- if (dlTensor.shape == nullptr) {
- MS_LOGE("shape is null");
- }
- if (dlTensor.ndim != DIM_DEFAULT_SIZE) {
- MS_LOGE("Tensor should be 4 dimensional.");
- return -1;
- }
- switch (this->format) {
- case Format_NCHW:
- case Format_NC4HW4:
- return dlTensor.shape[NCHW_W];
- case Format_NHWC:
- return dlTensor.shape[NHWC_W];
- default:
- MS_LOGE("Unsupported format: %d", this->format);
- return -1;
- }
- }
-
- int64_t Tensor::Channel() const {
- if (dlTensor.shape == nullptr) {
- MS_LOGE("shape is null");
- }
- if (dlTensor.ndim != DIM_DEFAULT_SIZE) {
- MS_LOGE("Tensor should be 4 dimensional.");
- return -1;
- }
- switch (this->format) {
- case Format_NCHW:
- case Format_NC4HW4:
- return dlTensor.shape[NCHW_C];
- case Format_NHWC:
- return dlTensor.shape[NHWC_C];
- default:
- MS_LOGE("Unsupported format: %d", this->format);
- return -1;
- }
- }
-
- int64_t Tensor::Batch() const {
- if (dlTensor.shape == nullptr) {
- MS_LOGE("shape is null");
- }
- if (dlTensor.ndim != DIM_DEFAULT_SIZE) {
- MS_LOGE("Tensor should be 4 dimensional.");
- return -1;
- }
- switch (this->format) {
- case Format_NCHW:
- case Format_NC4HW4:
- case Format_NHWC:
- return dlTensor.shape[NCHW_N];
- default:
- MS_LOGE("Unsupported format: %d", this->format);
- return -1;
- }
- }
-
- int64_t Tensor::Stride(int index) const {
- if (dlTensor.strides) {
- return dlTensor.strides[index];
- }
- if (dlTensor.shape == nullptr) {
- MS_LOGE("shape is null");
- return -1;
- }
- int64_t stride = 1;
- for (int i = index + 1; i < dlTensor.ndim; i++) {
- stride *= dlTensor.shape[i];
- }
- return stride;
- }
-
- void Tensor::SetStride() {
- if (dlTensor.strides == nullptr) {
- if (dlTensor.ndim < 1) {
- MS_LOGE("dims of dlTensor is empty.");
- return;
- }
- dlTensor.strides = new (std::nothrow) int64_t[dlTensor.ndim - 1];
- if (dlTensor.strides == nullptr) {
- MS_LOGW("new stride fail, ndim %d.", dlTensor.ndim);
- return;
- }
- }
-
- for (int idx = 0; idx < dlTensor.ndim - 1; idx++) {
- int64_t stride = 1;
- if (dlTensor.ndim <= idx + 1) {
- MS_LOGE("out of for loop upper limit.");
- return;
- }
- for (int i = idx + 1; i < dlTensor.ndim; i++) {
- stride *= dlTensor.shape[i];
- }
- dlTensor.strides[idx] = stride;
- }
- }
- void Tensor::SetScale(bool isScale) { this->isScale = isScale; }
-
- void Tensor::SetStride(int index, int64_t stride) {
- if (index >= dlTensor.ndim) {
- return;
- }
-
- if (dlTensor.strides == nullptr) {
- SetStride();
- }
-
- dlTensor.strides[index] = stride;
- return;
- }
-
- void Tensor::SetDims(const std::vector<int64_t> &dims) {
- if (dlTensor.shape != nullptr) {
- delete[] dlTensor.shape;
- }
- dlTensor.ndim = static_cast<int>(dims.size());
- if (dlTensor.ndim > 0) {
- dlTensor.shape = new (std::nothrow) int64_t[dlTensor.ndim];
- if (dlTensor.shape != nullptr) {
- for (int i = 0; i < dlTensor.ndim; i++) {
- dlTensor.shape[i] = dims[i];
- }
- } else {
- MS_LOGW("new shape fail,ndim %d", dlTensor.ndim);
- }
- } else {
- dlTensor.shape = nullptr;
- }
- }
-
- void Tensor::FreeTensor() {
- if (dlTensor.shape != nullptr) {
- delete[] dlTensor.shape;
- dlTensor.shape = nullptr;
- }
-
- if (dlTensor.strides != nullptr) {
- delete[] dlTensor.strides;
- dlTensor.strides = nullptr;
- }
-
- dlTensor.ndim = 0;
-
- if (allocator != nullptr) {
- allocator->Free(dlTensor.data);
- } else {
- free(dlTensor.data);
- }
- dlTensor.data = nullptr;
- }
-
- size_t Tensor::GetNC4HW4ElementSize(bool isNhwc) {
- int alignIndex = 1;
- if (isNhwc) {
- alignIndex = 3;
- }
-
- size_t size = 1;
- for (int i = 0; i < dlTensor.ndim; i++) {
- auto var = static_cast<size_t>(dlTensor.shape[i]);
- if (i == alignIndex) {
- var = ALIGN_UP4(var);
- }
- size *= var;
- }
- return size;
- }
-
- size_t Tensor::GetNC4HW4DataSize(bool isNhwc) {
- size_t size = GetNC4HW4ElementSize(isNhwc);
- const int BYTES = 8;
- const int GAP = 7;
- size *= (dlTensor.dtype.bits * dlTensor.dtype.lanes + GAP) / BYTES;
- return size;
- }
- } // namespace predict
- } // namespace mindspore
|