forked from mindspore-Ecosystem/mindspore
!45751 [lite]optimize inferShape
Merge pull request !45751 from 徐安越/r1.8_1
This commit is contained in:
commit
4b98342ca1
|
@ -41,7 +41,7 @@ int TensorListGetItemInferShape(const TensorC *const *inputs, size_t inputs_size
|
|||
if (index < 0 || index > ((int)(input0->element_num_ - 1))) {
|
||||
return NNACL_ERR;
|
||||
}
|
||||
TensorC *tensor_index = &input0->tensors_[index];
|
||||
TensorC *tensor_index = input0->tensors_[index];
|
||||
NNACL_CHECK_NULL_RETURN_ERR(tensor_index);
|
||||
|
||||
if (tensor_index->data_type_ != kTypeUnknown) {
|
||||
|
@ -49,7 +49,7 @@ int TensorListGetItemInferShape(const TensorC *const *inputs, size_t inputs_size
|
|||
} else {
|
||||
output->data_type_ = input0->tensors_data_type_;
|
||||
}
|
||||
output->format_ = input0->tensors_[index].format_;
|
||||
output->format_ = input0->tensors_[index]->format_;
|
||||
|
||||
if (!InferFlag(inputs, inputs_size)) {
|
||||
return NNACL_INFER_INVALID;
|
||||
|
@ -75,7 +75,7 @@ int TensorListGetItemInferShape(const TensorC *const *inputs, size_t inputs_size
|
|||
}
|
||||
if (!TensorListIsFullyDefined(element_shape, element_shape_size)) {
|
||||
for (size_t i = 0; i < input0->element_num_; ++i) {
|
||||
TensorC *input = &input0->tensors_[i];
|
||||
TensorC *input = input0->tensors_[i];
|
||||
NNACL_CHECK_NULL_RETURN_ERR(input);
|
||||
if (input->data_type_ != kTypeUnknown) {
|
||||
status = TensorListMergeShape(element_shape, &element_shape_size, input->shape_, input->shape_size_);
|
||||
|
|
|
@ -90,7 +90,7 @@ int TensorListSetItemInferShape(const TensorC *const *inputs, size_t inputs_size
|
|||
} else {
|
||||
output0->element_num_ = input0->element_num_;
|
||||
for (size_t i = 0; i < input0->element_num_; ++i) {
|
||||
TensorC *src_ptr = &input0->tensors_[i];
|
||||
TensorC *src_ptr = input0->tensors_[i];
|
||||
if (src_ptr == NULL) {
|
||||
free(out_shape.shape_);
|
||||
free(out_shape.shape_size_);
|
||||
|
|
|
@ -72,7 +72,7 @@ int TensorListStackInferShape(const TensorC *const *inputs, size_t inputs_size,
|
|||
}
|
||||
if (!TensorListIsFullyDefined(input0->element_shape_, input0->element_shape_size_)) {
|
||||
for (size_t i = 0; i < input0->element_num_; ++i) {
|
||||
TensorC *tensor_ele = &input0->tensors_[i];
|
||||
TensorC *tensor_ele = input0->tensors_[i];
|
||||
if (tensor_ele->data_type_ != kTypeUnknown) {
|
||||
status = TensorListMergeShape(output_shape, &output_shape_size, tensor_ele->shape_, tensor_ele->shape_size_);
|
||||
if (status == NNACL_ERR) {
|
||||
|
|
|
@ -73,6 +73,12 @@ int SetShape(const TensorC *const *inputs, size_t inputs_size, TensorC **outputs
|
|||
int b_shape[MAX_SHAPE_SIZE] = {0};
|
||||
size_t b_shape_size = 0;
|
||||
ShapeSet(b_shape, &b_shape_size, input1->shape_, input1->shape_size_);
|
||||
int *shape_align = a_shape_size > b_shape_size ? b_shape : a_shape;
|
||||
size_t *shape_size_align = a_shape_size > b_shape_size ? &b_shape_size : &a_shape_size;
|
||||
int diff = abs((int)a_shape_size - (int)b_shape_size);
|
||||
for (int i = 0; i < diff; ++i) {
|
||||
ShapeInsert(shape_align, shape_size_align, 0, 1);
|
||||
}
|
||||
int bias_shape[MAX_AXIS_SIZE] = {0};
|
||||
size_t bias_shape_size = 0;
|
||||
if (inputs_size == kInputSize2) {
|
||||
|
@ -83,7 +89,6 @@ int SetShape(const TensorC *const *inputs, size_t inputs_size, TensorC **outputs
|
|||
|
||||
if (a_shape_size == COMM_SHAPE_SIZE && a_shape[THIRD_INPUT] == 1 && a_shape[FOURTH_INPUT] == 1) {
|
||||
a_shape_size = 2;
|
||||
SetShapeArray(input0, a_shape, a_shape_size);
|
||||
}
|
||||
|
||||
bool del_start = false;
|
||||
|
@ -93,12 +98,10 @@ int SetShape(const TensorC *const *inputs, size_t inputs_size, TensorC **outputs
|
|||
if (insert_ret != NNACL_OK) {
|
||||
return NNACL_ERR;
|
||||
}
|
||||
SetShapeArray(input0, a_shape, a_shape_size);
|
||||
del_start = true;
|
||||
}
|
||||
if (b_shape_size == 1) {
|
||||
ShapePush(b_shape, &b_shape_size, 1);
|
||||
SetShapeArray(input1, b_shape, b_shape_size);
|
||||
del_end = true;
|
||||
}
|
||||
int ret = CheckMatmulInputShape(a_shape, a_shape_size, b_shape, b_shape_size, bias_shape, bias_shape_size, param);
|
||||
|
@ -138,11 +141,6 @@ int MatmulInferShape(const TensorC *const *inputs, size_t inputs_size, TensorC *
|
|||
TensorC *input1 = (TensorC *)inputs[1];
|
||||
TensorC *output = outputs[0];
|
||||
|
||||
int diff = abs((int)input0->shape_size_ - (int)input1->shape_size_);
|
||||
TensorC *in = input0->shape_size_ > input1->shape_size_ ? input1 : input0;
|
||||
for (int i = 0; i < diff; ++i) {
|
||||
ShapeInsert(in->shape_, &in->shape_size_, 0, 1);
|
||||
}
|
||||
TensorC *input = input1->data_ == NULL ? input1 : input0; // transfer the input which comes from the other node.
|
||||
SetDataTypeFormat(output, input);
|
||||
if (parameter->quant_type_ == QuantType_QUANT_DYNAMIC || parameter->quant_type_ == QuantType_QUANT_WEIGHT) {
|
||||
|
|
|
@ -28,6 +28,8 @@ int ShapeFusionInferShape(const TensorC *const *inputs, size_t inputs_size, Tens
|
|||
size_t input_len = in_tensor->shape_size_ + 1;
|
||||
for (size_t out_idx = 0; out_idx < outputs_size; out_idx++) {
|
||||
TensorC *out_tensor = outputs[out_idx];
|
||||
int origin_out_size = out_tensor->data_ == NULL ? 0 : (out_tensor->shape_size_ == 0 ? 1 : out_tensor->shape_[0]);
|
||||
MS_CHECK_TRUE_RET(origin_out_size >= 0, NNACL_INPUT_TENSOR_ERROR);
|
||||
out_tensor->data_type_ = kNumberTypeInt32;
|
||||
out_tensor->format_ = in_tensor->format_;
|
||||
if (!InferFlag(inputs, inputs_size)) {
|
||||
|
@ -44,6 +46,11 @@ int ShapeFusionInferShape(const TensorC *const *inputs, size_t inputs_size, Tens
|
|||
out_tensor->shape_[0] = (int)(matrix_tensor->shape_[0]);
|
||||
}
|
||||
int out_size = out_tensor->shape_size_ == 0 ? 1 : out_tensor->shape_[0];
|
||||
MS_CHECK_TRUE_RET(out_size >= 0, NNACL_INPUT_TENSOR_ERROR);
|
||||
if (out_size != origin_out_size && out_tensor->data_ != NULL) {
|
||||
free(out_tensor->data_);
|
||||
out_tensor->data_ = NULL;
|
||||
}
|
||||
size_t matrix_data_size = input_len * out_size * sizeof(float);
|
||||
float *matrix_data = (float *)(malloc(matrix_data_size));
|
||||
NNACL_CHECK_NULL_RETURN_ERR(matrix_data);
|
||||
|
@ -59,7 +66,10 @@ int ShapeFusionInferShape(const TensorC *const *inputs, size_t inputs_size, Tens
|
|||
free(matrix_data);
|
||||
return NNACL_ERR;
|
||||
}
|
||||
int *data = (int *)(malloc(out_size * sizeof(int)));
|
||||
if (out_tensor->data_ == NULL) {
|
||||
out_tensor->data_ = malloc(out_size * sizeof(int));
|
||||
}
|
||||
int *data = (int *)out_tensor->data_;
|
||||
if (data == NULL) {
|
||||
free(matrix_data);
|
||||
return NNACL_ERR;
|
||||
|
@ -71,7 +81,6 @@ int ShapeFusionInferShape(const TensorC *const *inputs, size_t inputs_size, Tens
|
|||
}
|
||||
data[i] += matrix_data[i * input_len + input_len - 1];
|
||||
}
|
||||
outputs[out_idx]->data_ = (void *)data;
|
||||
free(matrix_data);
|
||||
}
|
||||
return NNACL_OK;
|
||||
|
|
|
@ -20,13 +20,11 @@
|
|||
typedef enum TensorCFormat { NCHW, NHWC, NC4HW4, NUM_OF_FORMAT } TensorCFormat;
|
||||
|
||||
typedef struct TensorC {
|
||||
bool is_ready_;
|
||||
int data_type_;
|
||||
int format_;
|
||||
void *data_;
|
||||
size_t shape_size_;
|
||||
int shape_[MAX_SHAPE_SIZE];
|
||||
char *name_;
|
||||
} TensorC;
|
||||
|
||||
#endif // MINDSPORE_NNACL_TENSOR_C_H_
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* Copyright 2022 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.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_NNACL_TENSORLIST_C_H_
|
||||
#define MINDSPORE_NNACL_TENSORLIST_C_H_
|
||||
|
||||
#include "nnacl/tensor_c.h"
|
||||
|
||||
typedef struct vvector {
|
||||
int **shape_; // value of shapes
|
||||
int *shape_size_; // size of shape
|
||||
size_t size_; // number of shapes
|
||||
} vvector;
|
||||
|
||||
typedef struct TensorListC {
|
||||
int data_type_;
|
||||
int format_;
|
||||
int shape_value_;
|
||||
int tensors_data_type_; // element_data_type_, keep same as c++
|
||||
int max_elements_num_;
|
||||
TensorC **tensors_;
|
||||
size_t element_num_;
|
||||
size_t element_shape_size_;
|
||||
int element_shape_[MAX_SHAPE_SIZE];
|
||||
} TensorListC;
|
||||
|
||||
#endif // MINDSPORE_NNACL_TENSORLIST_C_H_
|
|
@ -28,16 +28,21 @@ int MallocTensorListData(TensorListC *tensor_list, TypeIdC dtype, const vvector
|
|||
return NNACL_ERR;
|
||||
}
|
||||
tensor_list->tensors_data_type_ = dtype;
|
||||
tensor_list->tensors_ = (TensorC *)malloc(tensor_list->element_num_ * sizeof(TensorC)); // free in infer_manager
|
||||
if (tensor_list->tensors_ == NULL) {
|
||||
void *addr = malloc(tensor_list->element_num_ * sizeof(void *) +
|
||||
tensor_list->element_num_ * sizeof(TensorC)); // free in infer_manager
|
||||
if (addr == NULL) {
|
||||
free(tensor_list->tensors_);
|
||||
return NNACL_NULL_PTR;
|
||||
}
|
||||
memset(tensor_list->tensors_, 0, tensor_list->element_num_ * sizeof(TensorC));
|
||||
memset(addr, 0, tensor_list->element_num_ * sizeof(void *) + tensor_list->element_num_ * sizeof(TensorC));
|
||||
tensor_list->tensors_ = (TensorC **)addr;
|
||||
TensorC *tensors = (TensorC *)(tensor_list->tensors_ + tensor_list->element_num_);
|
||||
for (size_t i = 0; i < tensor_list->element_num_; ++i) {
|
||||
tensor_list->tensors_[i].format_ = Format_NHWC;
|
||||
tensor_list->tensors_[i].data_type_ = dtype;
|
||||
ShapeSet(tensor_list->tensors_[i].shape_, &(tensor_list->tensors_[i].shape_size_), tensor_shape->shape_[i],
|
||||
(size_t)tensor_shape->shape_size_[i]);
|
||||
TensorC *tensor = tensors + i;
|
||||
tensor_list->tensors_[i] = tensor;
|
||||
tensor->format_ = Format_NHWC;
|
||||
tensor->data_type_ = dtype;
|
||||
ShapeSet(tensor->shape_, &(tensor->shape_size_), tensor_shape->shape_[i], (size_t)tensor_shape->shape_size_[i]);
|
||||
}
|
||||
return NNACL_OK;
|
||||
}
|
||||
|
|
|
@ -14,38 +14,19 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef MINDSPORE_NNACL_TENSORLISTC_UTILS_H_
|
||||
#define MINDSPORE_NNACL_TENSORLISTC_UTILS_H_
|
||||
#ifndef MINDSPORE_NNACL_TENSORLIST_C_UTILS_H_
|
||||
#define MINDSPORE_NNACL_TENSORLIST_C_UTILS_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include "nnacl/errorcode.h"
|
||||
#include "nnacl/op_base.h"
|
||||
#include "nnacl/tensor_c.h"
|
||||
#include "nnacl/tensorlist_c.h"
|
||||
#include "nnacl/infer/common_infer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct vvector {
|
||||
int **shape_; // value of shapes
|
||||
int *shape_size_; // size of shape
|
||||
size_t size_; // number of shapes
|
||||
} vvector;
|
||||
|
||||
typedef struct TensorListC {
|
||||
bool is_ready_;
|
||||
int data_type_;
|
||||
int format_;
|
||||
int shape_value_;
|
||||
int tensors_data_type_; // element_data_type_, keep same as c++
|
||||
int max_elements_num_;
|
||||
int element_shape_[8];
|
||||
size_t element_num_;
|
||||
size_t element_shape_size_;
|
||||
TensorC *tensors_;
|
||||
} TensorListC;
|
||||
|
||||
int MallocTensorListData(TensorListC *tensor_list, TypeIdC dtype, const vvector *tensor_shape);
|
||||
int TensorListMergeShape(int *element_shape, size_t *element_shape_size, const int *tmp, size_t tmp_size);
|
||||
bool TensorListIsFullyDefined(const int *shape, size_t shape_size);
|
||||
|
@ -55,4 +36,4 @@ bool InferFlagTensorList(TensorC *tensor_list);
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif // MINDSPORE_NNACL_TENSORLISTC_UTILS_H_
|
||||
#endif // MINDSPORE_NNACL_TENSORLIST_C_UTILS_H_
|
||||
|
|
|
@ -107,6 +107,7 @@ if(MSLITE_MINDDATA_IMPLEMENT STREQUAL "full")
|
|||
include_directories("${MINDDATA_DIR}/kernels/image")
|
||||
include_directories("${MINDDATA_DIR}/liteapi")
|
||||
include_directories("${TOP_DIR}")
|
||||
include_directories("${TOP_DIR}/mindspore/ccsrc/plugin/device/cpu/kernel")
|
||||
|
||||
set(MINDDATA_FULL_SRC
|
||||
${TOP_DIR}/mindspore/lite/src/runtime/cxx_api/types.cc
|
||||
|
|
|
@ -26,30 +26,7 @@
|
|||
#endif
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
int OutputTensor2TensorC(const std::vector<lite::Tensor *> &tensors, std::vector<TensorC *> *tensors_c,
|
||||
std::shared_ptr<Allocator> allocator) {
|
||||
MS_ASSERT(tensors_c != nullptr);
|
||||
for (size_t i = 0; i < tensors.size(); ++i) {
|
||||
TensorC *tensor_c = nullptr;
|
||||
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
|
||||
tensor_c = static_cast<TensorC *>(allocator->Malloc(sizeof(TensorC)));
|
||||
} else {
|
||||
tensor_c = static_cast<TensorC *>(malloc(sizeof(TensorC)));
|
||||
}
|
||||
if (tensor_c == nullptr) {
|
||||
MS_LOG(ERROR) << "malloc tensor fail!";
|
||||
return RET_ERROR;
|
||||
}
|
||||
tensor_c->data_type_ = kNumberTypeFloat32;
|
||||
tensor_c->format_ = tensors[i]->format();
|
||||
tensor_c->data_ = nullptr;
|
||||
tensor_c->shape_size_ = 0;
|
||||
tensors_c->push_back(tensor_c);
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void FreeAllTensorC(std::vector<TensorC *> *tensors_in, std::shared_ptr<Allocator> allocator) {
|
||||
void FreeInTensorC(std::vector<TensorC *> *tensors_in, const std::shared_ptr<Allocator> &allocator) {
|
||||
if (tensors_in == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
@ -58,24 +35,46 @@ void FreeAllTensorC(std::vector<TensorC *> *tensors_in, std::shared_ptr<Allocato
|
|||
continue;
|
||||
}
|
||||
if (i->data_type_ == kObjectTypeTensorType) {
|
||||
TensorListC *tensorListC = reinterpret_cast<TensorListC *>(i);
|
||||
FreeTensorListC(tensorListC, allocator);
|
||||
tensorListC = nullptr;
|
||||
} else {
|
||||
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
|
||||
allocator->Free(i);
|
||||
} else {
|
||||
free(i);
|
||||
auto *tensorListC = reinterpret_cast<TensorListC *>(i);
|
||||
if (tensorListC->tensors_ != nullptr) {
|
||||
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
|
||||
allocator->Free(tensorListC->tensors_);
|
||||
} else {
|
||||
free(tensorListC->tensors_);
|
||||
}
|
||||
tensorListC->tensors_ = nullptr;
|
||||
}
|
||||
i = nullptr;
|
||||
}
|
||||
}
|
||||
tensors_in->clear();
|
||||
}
|
||||
|
||||
void FreeOutTensorC(std::vector<TensorC *> *tensors_out, const std::shared_ptr<Allocator> &allocator) {
|
||||
if (tensors_out == nullptr) {
|
||||
return;
|
||||
}
|
||||
for (auto &i : *tensors_out) {
|
||||
if (i == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (i->data_type_ == kObjectTypeTensorType) {
|
||||
auto *tensorListC = reinterpret_cast<TensorListC *>(i);
|
||||
if (tensorListC->tensors_ != nullptr) {
|
||||
for (size_t j = 0; j < tensorListC->element_num_; ++j) {
|
||||
if (tensorListC->tensors_[j] != nullptr && tensorListC->tensors_[j]->data_ != nullptr) {
|
||||
free(tensorListC->tensors_[j]->data_);
|
||||
}
|
||||
}
|
||||
free((tensorListC->tensors_));
|
||||
tensorListC->tensors_ = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
tensors_out->clear();
|
||||
}
|
||||
|
||||
int Tensor2TensorC(const Tensor *src, TensorC *dst) {
|
||||
MS_CHECK_TRUE_RET(src != nullptr && dst != nullptr, RET_ERROR);
|
||||
dst->is_ready_ = src->IsReady();
|
||||
dst->format_ = static_cast<int>(src->format());
|
||||
dst->data_ = src->data();
|
||||
dst->data_type_ = src->data_type();
|
||||
|
@ -90,7 +89,7 @@ int Tensor2TensorC(const Tensor *src, TensorC *dst) {
|
|||
return RET_OK;
|
||||
}
|
||||
|
||||
int TensorC2Tensor(const TensorC *src, Tensor *dst, std::shared_ptr<Allocator> allocator) {
|
||||
int TensorC2Tensor(TensorC *src, Tensor *dst, std::shared_ptr<Allocator> allocator) {
|
||||
MS_CHECK_TRUE_RET(src != nullptr && dst != nullptr, RET_ERROR);
|
||||
dst->set_format(static_cast<mindspore::Format>(src->format_));
|
||||
dst->set_data_type(static_cast<TypeId>(src->data_type_)); // get data during the runtime period
|
||||
|
@ -98,95 +97,68 @@ int TensorC2Tensor(const TensorC *src, Tensor *dst, std::shared_ptr<Allocator> a
|
|||
if (src->data_ != nullptr) {
|
||||
auto data = dst->MutableData();
|
||||
MS_CHECK_TRUE_RET(data != nullptr, RET_ERROR);
|
||||
memcpy(data, src->data_, dst->Size());
|
||||
dst->set_category(CONST_TENSOR);
|
||||
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
|
||||
allocator->Free(src->data_);
|
||||
} else {
|
||||
free(src->data_);
|
||||
if (data == src->data_) { // tensor
|
||||
dst->set_own_data(true);
|
||||
dst->set_category(CONST_TENSOR);
|
||||
return RET_OK;
|
||||
}
|
||||
memcpy(data, src->data_, dst->Size()); // tensor_list
|
||||
dst->set_category(CONST_TENSOR);
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int GenerateOutTensorC(const OpParameter *const parameter, const std::vector<lite::Tensor *> &outputs,
|
||||
std::vector<TensorC *> *out_tensor_c, std::shared_ptr<Allocator> allocator) {
|
||||
std::vector<TensorC *> *out_tensor_c) {
|
||||
MS_CHECK_TRUE_RET(out_tensor_c != nullptr && parameter != nullptr, RET_ERROR);
|
||||
if (parameter->type_ == mindspore::schema::PrimitiveType_TensorListFromTensor ||
|
||||
parameter->type_ == mindspore::schema::PrimitiveType_TensorListReserve ||
|
||||
parameter->type_ == mindspore::schema::PrimitiveType_TensorListSetItem) {
|
||||
#ifndef CONTROLFLOW_TENSORLIST_CLIP
|
||||
// TensorListC ->TensorC
|
||||
MS_CHECK_TRUE_RET(!outputs.empty() && outputs.front()->data_type() == TypeId::kObjectTypeTensorType, RET_ERROR);
|
||||
TensorListC *tensor_list_c = nullptr;
|
||||
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
|
||||
tensor_list_c = reinterpret_cast<TensorListC *>(allocator->Malloc(sizeof(TensorListC)));
|
||||
} else {
|
||||
tensor_list_c = reinterpret_cast<TensorListC *>(malloc(sizeof(TensorListC)));
|
||||
}
|
||||
if (tensor_list_c == nullptr) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
memset(tensor_list_c, 0, sizeof(TensorListC));
|
||||
auto output = static_cast<TensorList *>(outputs[0]);
|
||||
TensorListC *tensor_list_c = output->ConvertToTensorListC();
|
||||
tensor_list_c->element_num_ = 0;
|
||||
out_tensor_c->push_back(reinterpret_cast<TensorC *const>(tensor_list_c));
|
||||
return RET_OK;
|
||||
#else
|
||||
return RET_NOT_SUPPORT;
|
||||
#endif
|
||||
} else {
|
||||
return OutputTensor2TensorC(outputs, out_tensor_c, allocator);
|
||||
(void)std::transform(outputs.begin(), outputs.end(), std::back_inserter(*out_tensor_c),
|
||||
[](lite::Tensor *output) { return output->ConvertToTensorC(); });
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int GenerateInTensorC(const std::vector<lite::Tensor *> &inputs, std::vector<TensorC *> *in_tensor_c,
|
||||
std::shared_ptr<Allocator> allocator) {
|
||||
const std::shared_ptr<Allocator> &allocator) {
|
||||
MS_CHECK_TRUE_RET(in_tensor_c != nullptr, RET_ERROR);
|
||||
int ret = RET_OK;
|
||||
for (auto input : inputs) {
|
||||
if (input->data_type() == kObjectTypeTensorType) {
|
||||
#ifndef CONTROLFLOW_TENSORLIST_CLIP
|
||||
// Tensor ->TensorList -> TensorListC -> TensorC
|
||||
auto *tensor_list = reinterpret_cast<TensorList *>(input);
|
||||
TensorListC *tensor_list_c = nullptr;
|
||||
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
|
||||
tensor_list_c = reinterpret_cast<TensorListC *>(allocator->Malloc(sizeof(TensorListC)));
|
||||
} else {
|
||||
tensor_list_c = reinterpret_cast<TensorListC *>(malloc(sizeof(TensorListC)));
|
||||
}
|
||||
if (tensor_list_c == nullptr) {
|
||||
ret = RET_NULL_PTR;
|
||||
break;
|
||||
}
|
||||
memset(tensor_list_c, 0, sizeof(TensorListC));
|
||||
ret = TensorList2TensorListC(tensor_list, tensor_list_c, allocator);
|
||||
if (ret != RET_OK) {
|
||||
TensorListC *tensor_list_c = tensor_list->ConvertToTensorListC();
|
||||
auto tensors = tensor_list->tensors();
|
||||
if (!tensors.empty()) {
|
||||
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
|
||||
allocator->Free(tensor_list_c->tensors_);
|
||||
allocator->Free(tensor_list_c);
|
||||
tensor_list_c->tensors_ = reinterpret_cast<TensorC **>(allocator->Malloc(tensors.size() * sizeof(void *)));
|
||||
} else {
|
||||
free(tensor_list_c->tensors_);
|
||||
free(tensor_list_c);
|
||||
tensor_list_c->tensors_ = reinterpret_cast<TensorC **>(malloc(tensors.size() * sizeof(void *)));
|
||||
}
|
||||
for (size_t i = 0; i < tensors.size(); ++i) {
|
||||
tensor_list_c->tensors_[i] = tensors[i]->ConvertToTensorC();
|
||||
}
|
||||
return NNACL_ERR;
|
||||
}
|
||||
in_tensor_c->push_back(reinterpret_cast<TensorC *>(tensor_list_c));
|
||||
#else
|
||||
return RET_NOT_SUPPORT;
|
||||
#endif
|
||||
} else {
|
||||
// Tensor -> TensorC
|
||||
TensorC *tensor_c = nullptr;
|
||||
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
|
||||
tensor_c = reinterpret_cast<TensorC *>(allocator->Malloc(sizeof(TensorC)));
|
||||
} else {
|
||||
tensor_c = reinterpret_cast<TensorC *>(malloc(sizeof(TensorC)));
|
||||
}
|
||||
if (tensor_c == nullptr) {
|
||||
ret = RET_NULL_PTR;
|
||||
break;
|
||||
}
|
||||
ret = Tensor2TensorC(input, tensor_c);
|
||||
if (ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "Tensor to TensorC failed.";
|
||||
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
|
||||
allocator->Free(tensor_c);
|
||||
} else {
|
||||
free(tensor_c);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
TensorC *tensor_c = input->ConvertToTensorC();
|
||||
in_tensor_c->emplace_back(tensor_c);
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +255,11 @@ void MoveCommonTensorData(Tensor *dst_tensor, Tensor *src_tensor) {
|
|||
dst_tensor->set_data(src_tensor->MutableData()); /* using MutableData to sync GPU data */
|
||||
}
|
||||
|
||||
dst_tensor->set_own_data(src_tensor->own_data());
|
||||
if (src_tensor->data() == dst_tensor->data() && src_tensor->IsConst()) {
|
||||
dst_tensor->set_own_data(false);
|
||||
} else {
|
||||
dst_tensor->set_own_data(src_tensor->own_data());
|
||||
}
|
||||
src_tensor->DecRefCount();
|
||||
}
|
||||
|
||||
|
@ -445,10 +421,14 @@ void MoveTensorListTensorData(TensorList *dst_tensorlist, TensorList *src_tensor
|
|||
auto &src_tensor = src_tensorlist->tensors()[i];
|
||||
auto &dst_tensor = dst_tensorlist->tensors()[i];
|
||||
|
||||
dst_tensor->set_own_data(src_tensor->own_data());
|
||||
if (src_tensor->data() != nullptr) {
|
||||
dst_tensor->set_data(src_tensor->MutableData()); /* using MutableData to sync GPU data */
|
||||
}
|
||||
if (src_tensor->data() == dst_tensor->data() && src_tensor->IsConst()) {
|
||||
dst_tensor->set_own_data(false);
|
||||
} else {
|
||||
dst_tensor->set_own_data(src_tensor->own_data());
|
||||
}
|
||||
dst_tensor->set_shape(src_tensor->shape());
|
||||
}
|
||||
|
||||
|
@ -467,80 +447,20 @@ void SetTensorListTensorData(TensorList *dst_tensor_list, TensorList *src_tensor
|
|||
dst_tensor_list->set_element_shape(src_tensor_list->element_shape());
|
||||
}
|
||||
|
||||
void FreeTensorListC(TensorListC *tensorlist_c, std::shared_ptr<Allocator> allocator) {
|
||||
MS_ASSERT(tensorlist_c != nullptr);
|
||||
if (tensorlist_c->tensors_ != nullptr) {
|
||||
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
|
||||
allocator->Free(tensorlist_c->tensors_);
|
||||
} else {
|
||||
free(tensorlist_c->tensors_);
|
||||
}
|
||||
tensorlist_c->tensors_ = nullptr;
|
||||
}
|
||||
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
|
||||
allocator->Free(tensorlist_c);
|
||||
} else {
|
||||
free(tensorlist_c);
|
||||
}
|
||||
}
|
||||
|
||||
int TensorList2TensorListC(TensorList *src, TensorListC *dst, std::shared_ptr<Allocator> allocator) {
|
||||
MS_CHECK_TRUE_RET(src != nullptr && dst != nullptr, RET_ERROR);
|
||||
dst->is_ready_ = src->IsReady();
|
||||
dst->data_type_ = static_cast<TypeIdC>(src->data_type());
|
||||
dst->format_ = static_cast<int>(src->format());
|
||||
dst->shape_value_ = src->shape().empty() ? 0 : src->shape().front();
|
||||
dst->element_num_ = src->shape().empty() ? 0 : src->tensors().size();
|
||||
|
||||
if ((dst->element_num_ != 0 && SIZE_MAX / dst->element_num_ < sizeof(TensorC)) ||
|
||||
dst->element_num_ * sizeof(TensorC) > MAX_MALLOC_SIZE) {
|
||||
MS_LOG(ERROR) << "data size error.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
|
||||
dst->tensors_ = reinterpret_cast<TensorC *>(allocator->Malloc(dst->element_num_ * sizeof(TensorC)));
|
||||
} else {
|
||||
dst->tensors_ = reinterpret_cast<TensorC *>(malloc(dst->element_num_ * sizeof(TensorC)));
|
||||
}
|
||||
if (dst->tensors_ == nullptr) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
memset(dst->tensors_, 0, dst->element_num_ * sizeof(TensorC));
|
||||
for (size_t i = 0; i < dst->element_num_; i++) {
|
||||
auto ret = Tensor2TensorC(src->tensors().at(i), &dst->tensors_[i]);
|
||||
if (ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "Tensor to TensorC failed.";
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
dst->tensors_data_type_ = src->tensors_data_type();
|
||||
dst->element_shape_size_ = src->element_shape().size();
|
||||
for (size_t i = 0; i < dst->element_shape_size_; i++) {
|
||||
dst->element_shape_[i] = src->element_shape().at(i);
|
||||
}
|
||||
dst->max_elements_num_ = src->max_elements_num();
|
||||
return NNACL_OK;
|
||||
}
|
||||
|
||||
int TensorListC2TensorList(const TensorListC *src, TensorList *dst) {
|
||||
MS_CHECK_TRUE_RET(src != nullptr && dst != nullptr, RET_ERROR);
|
||||
dst->set_data_type(static_cast<TypeId>(src->data_type_));
|
||||
dst->set_format(static_cast<mindspore::Format>(src->format_));
|
||||
dst->set_shape(std::vector<int>(1, src->element_num_));
|
||||
dst->set_tensors_data_type(static_cast<TypeId>(src->tensors_data_type_));
|
||||
|
||||
// Set Tensors
|
||||
for (size_t i = 0; i < src->element_num_; i++) {
|
||||
auto ret = TensorC2Tensor(&src->tensors_[i], dst->GetTensor(static_cast<int>(i)));
|
||||
auto ret = TensorC2Tensor(src->tensors_[i], dst->GetTensor(static_cast<int>(i)));
|
||||
if (ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "TensorC2Tensor failed";
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
dst->set_element_shape(std::vector<int>(src->element_shape_, src->element_shape_ + src->element_shape_size_));
|
||||
dst->set_max_elements_num(src->max_elements_num_);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
@ -562,7 +482,7 @@ TensorList *MallocTensorListDataAccordingToTensorListC(Tensor *tensor, TensorLis
|
|||
auto tensor_shape = std::vector<std::vector<int>>(
|
||||
tensor_list_c->element_num_, std::vector<int>(tensor_list_c->element_shape_,
|
||||
tensor_list_c->element_shape_ + tensor_list_c->element_shape_size_));
|
||||
tensor_list->MallocTensorListData(static_cast<TypeId>(tensor_list_c->data_type_), tensor_shape);
|
||||
tensor_list->MallocTensorListData(static_cast<TypeId>(tensor_list_c->tensors_data_type_), tensor_shape);
|
||||
return tensor_list;
|
||||
}
|
||||
|
||||
|
@ -657,11 +577,6 @@ void FreeTensorListC(TensorListC *tensorlist_c, std::shared_ptr<Allocator> alloc
|
|||
return;
|
||||
}
|
||||
|
||||
int TensorList2TensorListC(TensorList *src, TensorListC *dst, std::shared_ptr<Allocator> allocator) {
|
||||
MS_LOG(ERROR) << unsupport_controlflow_tensorlist_log;
|
||||
return NNACL_ERR;
|
||||
}
|
||||
|
||||
int TensorListC2TensorList(const TensorListC *src, TensorList *dst) {
|
||||
MS_LOG(ERROR) << unsupport_controlflow_tensorlist_log;
|
||||
return RET_ERROR;
|
||||
|
|
|
@ -29,18 +29,15 @@
|
|||
|
||||
namespace mindspore {
|
||||
namespace lite {
|
||||
int OutputTensor2TensorC(const std::vector<lite::Tensor *> &tensors, std::vector<TensorC *> *tensors_c,
|
||||
std::shared_ptr<Allocator> allocator = nullptr);
|
||||
void FreeAllTensorC(std::vector<TensorC *> *tensors_in, std::shared_ptr<Allocator> allocator = nullptr);
|
||||
void FreeInTensorC(std::vector<TensorC *> *tensors_in, const std::shared_ptr<Allocator> &allocator = nullptr);
|
||||
void FreeOutTensorC(std::vector<TensorC *> *tensors_in, const std::shared_ptr<Allocator> &allocator = nullptr);
|
||||
int Tensor2TensorC(const Tensor *src, TensorC *dst);
|
||||
int TensorC2Tensor(const TensorC *src, Tensor *dst, std::shared_ptr<Allocator> allocator = nullptr);
|
||||
void FreeTensorListC(TensorListC *tensorlist_c, std::shared_ptr<Allocator> allocator = nullptr);
|
||||
int TensorList2TensorListC(TensorList *src, TensorListC *dst, std::shared_ptr<Allocator> allocator = nullptr);
|
||||
int TensorC2Tensor(TensorC *src, Tensor *dst, std::shared_ptr<Allocator> allocator = nullptr);
|
||||
int TensorListC2TensorList(const TensorListC *src, TensorList *dst);
|
||||
int GenerateInTensorC(const std::vector<lite::Tensor *> &inputs, std::vector<TensorC *> *in_tensor_c,
|
||||
std::shared_ptr<Allocator> allocator = nullptr);
|
||||
const std::shared_ptr<Allocator> &allocator = nullptr);
|
||||
int GenerateOutTensorC(const OpParameter *const parameter, const std::vector<lite::Tensor *> &outputs,
|
||||
std::vector<TensorC *> *out_tensor_c, std::shared_ptr<Allocator> allocator = nullptr);
|
||||
std::vector<TensorC *> *out_tensor_c);
|
||||
int CheckTensorsInvalid(const std::vector<Tensor *> &tensors);
|
||||
int CheckGraphInputShapes(const std::vector<Tensor *> &inputs,
|
||||
const std::unordered_map<Tensor *, std::vector<int>> &input_shape_map);
|
||||
|
|
|
@ -146,25 +146,25 @@ int KernelInferShape(const std::vector<lite::Tensor *> &inputs, const std::vecto
|
|||
|
||||
int ret = GenerateInTensorC(inputs, &in_tensors, allocator);
|
||||
if (ret != RET_OK) {
|
||||
FreeAllTensorC(&in_tensors, allocator);
|
||||
FreeInTensorC(&in_tensors, allocator);
|
||||
return RET_ERROR;
|
||||
}
|
||||
ret = GenerateOutTensorC(parameter, outputs, &out_tensors, allocator);
|
||||
ret = GenerateOutTensorC(parameter, outputs, &out_tensors);
|
||||
if (ret != RET_OK) {
|
||||
FreeAllTensorC(&in_tensors, allocator);
|
||||
FreeAllTensorC(&out_tensors, allocator);
|
||||
FreeInTensorC(&in_tensors, allocator);
|
||||
FreeOutTensorC(&out_tensors, allocator);
|
||||
return RET_ERROR;
|
||||
}
|
||||
auto infer_shape_func = GetInferFunc(parameter->type_);
|
||||
if (infer_shape_func == nullptr) {
|
||||
MS_LOG(ERROR) << "Get infershape func failed! type:" << PrimitiveCurVersionTypeName(parameter->type_);
|
||||
FreeAllTensorC(&in_tensors, allocator);
|
||||
FreeAllTensorC(&out_tensors, allocator);
|
||||
FreeInTensorC(&in_tensors, allocator);
|
||||
FreeOutTensorC(&out_tensors, allocator);
|
||||
return RET_ERROR;
|
||||
}
|
||||
ret = infer_shape_func(static_cast<TensorC **>(in_tensors.data()), in_tensors.size(), out_tensors.data(),
|
||||
out_tensors.size(), parameter);
|
||||
FreeAllTensorC(&in_tensors, allocator);
|
||||
FreeInTensorC(&in_tensors, allocator);
|
||||
for (size_t i = 0; i < out_tensors.size(); i++) {
|
||||
if (out_tensors.at(i) == nullptr) {
|
||||
continue;
|
||||
|
@ -174,21 +174,19 @@ int KernelInferShape(const std::vector<lite::Tensor *> &inputs, const std::vecto
|
|||
auto tensor_list = MallocTensorListDataAccordingToTensorListC(outputs.at(i), tensor_list_c);
|
||||
if (tensor_list == nullptr) {
|
||||
MS_LOG(ERROR) << "get as tensorlist failed";
|
||||
FreeAllTensorC(&out_tensors, allocator);
|
||||
FreeOutTensorC(&out_tensors, allocator);
|
||||
return RET_ERROR;
|
||||
}
|
||||
auto tensor_ret = TensorListC2TensorList(tensor_list_c, tensor_list);
|
||||
if (tensor_ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "TensorCList2TensorList failed";
|
||||
FreeAllTensorC(&out_tensors, allocator);
|
||||
FreeOutTensorC(&out_tensors, allocator);
|
||||
return tensor_ret;
|
||||
}
|
||||
} else {
|
||||
auto tensor_ret = TensorC2Tensor(out_tensors.at(i), outputs.at(i), allocator);
|
||||
if (tensor_ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "TensorC2Tensor failed";
|
||||
FreeAllTensorC(&out_tensors, allocator);
|
||||
return tensor_ret;
|
||||
if (out_tensors.at(i)->data_ != nullptr) {
|
||||
outputs.at(i)->set_own_data(true);
|
||||
outputs.at(i)->set_category(CONST_TENSOR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,7 +194,7 @@ int KernelInferShape(const std::vector<lite::Tensor *> &inputs, const std::vecto
|
|||
outputs.at(i)->set_shape({-1});
|
||||
}
|
||||
}
|
||||
FreeAllTensorC(&out_tensors, allocator);
|
||||
FreeOutTensorC(&out_tensors, allocator);
|
||||
|
||||
return CheckInfershapeResult(ret, inputs, outputs, parameter);
|
||||
}
|
||||
|
|
|
@ -215,7 +215,11 @@ int ReduceBaseCPUKernel::CopyInputToOutput() {
|
|||
out_tensor->FreeData();
|
||||
out_tensor->ResetRefCount();
|
||||
out_tensor->set_data(in_tensor->data());
|
||||
out_tensor->set_own_data(in_tensor->own_data());
|
||||
if (in_tensor->IsConst()) {
|
||||
out_tensor->set_own_data(false);
|
||||
} else {
|
||||
out_tensor->set_own_data(in_tensor->own_data());
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
} // namespace mindspore::kernel
|
||||
|
|
|
@ -88,7 +88,11 @@ int ReshapeBaseCPUKernel::Run() {
|
|||
out_tensor->FreeData();
|
||||
out_tensor->ResetRefCount();
|
||||
out_tensor->set_data(in_tensor->data());
|
||||
out_tensor->set_own_data(in_tensor->own_data());
|
||||
if (in_tensor->IsConst()) {
|
||||
out_tensor->set_own_data(false);
|
||||
} else {
|
||||
out_tensor->set_own_data(in_tensor->own_data());
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -286,7 +286,11 @@ int StridedSliceCPUKernel::SoftCopyInputToOutput() {
|
|||
output_tensor->FreeData();
|
||||
output_tensor->ResetRefCount();
|
||||
output_tensor->set_data(input_tensor->data());
|
||||
output_tensor->set_own_data(input_tensor->own_data());
|
||||
if (input_tensor->IsConst()) {
|
||||
output_tensor->set_own_data(false);
|
||||
} else {
|
||||
output_tensor->set_own_data(input_tensor->own_data());
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -227,7 +227,11 @@ int TransposeBaseCPUKernel::CopyInputToOutput() {
|
|||
out_tensor->FreeData();
|
||||
out_tensor->ResetRefCount();
|
||||
out_tensor->set_data(in_tensor->data());
|
||||
out_tensor->set_own_data(in_tensor->own_data());
|
||||
if (in_tensor->IsConst()) {
|
||||
out_tensor->set_own_data(false);
|
||||
} else {
|
||||
out_tensor->set_own_data(in_tensor->own_data());
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ int ScatterNdUpdateCPUKernel::Run() {
|
|||
auto in_tensor = in_tensors().front();
|
||||
auto out_tensor = out_tensors().front();
|
||||
if (in_tensor->allocator() == nullptr || in_tensor->allocator() != out_tensor->allocator() ||
|
||||
in_tensor->own_data() == false || op_parameter_->is_train_session_) {
|
||||
in_tensor->own_data() == false || in_tensor->IsConst() || op_parameter_->is_train_session_) {
|
||||
memcpy(out_tensor->data(), in_tensor->data(), in_tensor->Size());
|
||||
} else {
|
||||
out_tensor->FreeData();
|
||||
|
|
|
@ -1388,7 +1388,7 @@ void LiteSession::RuntimeAllocatorInitSubgraph() {
|
|||
for (auto kernel : kernel_list) {
|
||||
/* malloc for output */
|
||||
for (auto tensor : kernel->out_tensors()) {
|
||||
if (tensor->allocator() != default_allocator) {
|
||||
if (tensor->allocator() != default_allocator || tensor->IsConst()) {
|
||||
continue;
|
||||
}
|
||||
tensor->set_allocator(runtime_allocator_);
|
||||
|
|
|
@ -266,7 +266,7 @@ int MindrtExecutor::TransferGraphOutput() {
|
|||
}
|
||||
if (src_tensor->allocator() != nullptr) {
|
||||
dst_tensor->set_data(src_tensor->data());
|
||||
dst_tensor->set_own_data(src_tensor->own_data());
|
||||
dst_tensor->set_own_data(src_tensor->IsConst() ? false : src_tensor->own_data());
|
||||
} else {
|
||||
dst_tensor->set_data(src_tensor->data());
|
||||
src_tensor->set_data(nullptr);
|
||||
|
|
|
@ -114,11 +114,28 @@ class ShapeFusionPass {
|
|||
[&](uint32_t idx) { return this->src_tensors_->at(idx); });
|
||||
#endif
|
||||
}
|
||||
void FreeOutputTensorDataOfFusedShape() {
|
||||
#if !defined(RUNTIME_PASS_CLIP)
|
||||
for (auto tensor : shape_fusion_outputs_) {
|
||||
tensor->FreeData();
|
||||
tensor->set_category(VAR);
|
||||
|
||||
void StoreStateAndReset() {
|
||||
#ifndef RUNTIME_PASS_CLIP
|
||||
std::vector<lite::Tensor *> shape_fusion_outputs = shape_fusion_outputs_;
|
||||
shape_fusion_outputs_.clear();
|
||||
for (auto output : shape_fusion_outputs) {
|
||||
if (output->IsConst()) {
|
||||
shape_fusion_outputs_.push_back(output);
|
||||
datas_.push_back(output->data());
|
||||
output->set_data(nullptr);
|
||||
output->set_category(VAR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void RestoreState() {
|
||||
#ifndef RUNTIME_PASS_CLIP
|
||||
size_t count = std::min(shape_fusion_outputs_.size(), datas_.size());
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
shape_fusion_outputs_[i]->set_data(datas_[i]);
|
||||
shape_fusion_outputs_[i]->set_category(CONST_TENSOR);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -141,6 +158,7 @@ class ShapeFusionPass {
|
|||
private:
|
||||
std::map<uint32_t, ShapeFusionMatrix> shape_fusion_matrices_;
|
||||
std::vector<lite::Tensor *> shape_fusion_outputs_;
|
||||
std::vector<void *> datas_;
|
||||
#endif
|
||||
InnerContext *context_ = nullptr;
|
||||
LiteModel *lite_model_ = nullptr;
|
||||
|
|
|
@ -238,6 +238,10 @@ int Scheduler::InitKernels(std::vector<kernel::KernelExec *> &&dst_kernels) {
|
|||
for (auto node : subgraph_nodes) {
|
||||
for (auto *tensor : node->out_tensors()) {
|
||||
if (tensor->IsConst()) {
|
||||
MS_CHECK_TRUE_MSG(node->op_parameter() != nullptr, RET_NULL_PTR, "node's op_parameter is invalid.");
|
||||
if (node->op_parameter()->type_ == PrimType::PrimType_Inner_ShapeFusion) {
|
||||
continue;
|
||||
}
|
||||
MS_LOG(ERROR) << "Illegitimate kernel output tensor : " << tensor->tensor_name();
|
||||
continue;
|
||||
}
|
||||
|
@ -460,8 +464,7 @@ int Scheduler::Schedule(std::vector<kernel::KernelExec *> *dst_kernels) {
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
shape_fusion_pass_->FreeOutputTensorDataOfFusedShape();
|
||||
|
||||
shape_fusion_pass_->StoreStateAndReset();
|
||||
ret = InitDelegateKernels(dst_kernels);
|
||||
if (ret != RET_OK) {
|
||||
MS_LOG(ERROR) << "Repalce delegate kernels failed.";
|
||||
|
@ -508,6 +511,7 @@ int Scheduler::Schedule(std::vector<kernel::KernelExec *> *dst_kernels) {
|
|||
MS_LOG(ERROR) << "InitKernels failed.";
|
||||
return ret;
|
||||
}
|
||||
shape_fusion_pass_->RestoreState();
|
||||
if (IsPrintDebug()) {
|
||||
MS_LOG(DEBUG) << "schedule kernels success.";
|
||||
for (auto subgraph : *dst_kernels) {
|
||||
|
|
|
@ -45,14 +45,24 @@ static const size_t max_malloc_size_ = GetMaxMallocSize();
|
|||
#endif
|
||||
|
||||
Tensor::Tensor(const TypeId data_type, std::vector<int> shape, const mindspore::Format &format, Category category)
|
||||
: data_type_(data_type), shape_(std::move(shape)), format_(format), category_(category) {}
|
||||
: category_(category) {
|
||||
tensor_c_ = {data_type, static_cast<int>(format), nullptr, shape.size()};
|
||||
if (shape.size() > MAX_SHAPE_SIZE) {
|
||||
tensor_c_.shape_size_ = 0;
|
||||
MS_LOG(WARNING) << "The shape-size has exceeded the limit 8, now is " << shape.size();
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < shape.size(); ++i) {
|
||||
tensor_c_.shape_[i] = shape[i];
|
||||
}
|
||||
}
|
||||
|
||||
int Tensor::CopyTensorData(const Tensor &src_tensor, Tensor *dst_tensor) {
|
||||
if (dst_tensor == nullptr) {
|
||||
MS_LOG(ERROR) << "dst_tensor is nullptr";
|
||||
return RET_PARAM_INVALID;
|
||||
}
|
||||
if (src_tensor.data_ == nullptr) {
|
||||
if (src_tensor.tensor_c_.data_ == nullptr) {
|
||||
MS_LOG(INFO) << "data of src tensor is nullptr";
|
||||
return RET_OK;
|
||||
}
|
||||
|
@ -66,7 +76,7 @@ int Tensor::CopyTensorData(const Tensor &src_tensor, Tensor *dst_tensor) {
|
|||
return RET_ERROR;
|
||||
}
|
||||
dst_tensor->ResetRefCount();
|
||||
memcpy(dst_tensor->data_, src_tensor.data_, data_size);
|
||||
(void)memcpy(dst_tensor->tensor_c_.data_, src_tensor.tensor_c_.data_, data_size);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
@ -76,10 +86,9 @@ Tensor *Tensor::CopyTensor(const Tensor &src_tensor, bool copy_data, AllocatorPt
|
|||
MS_LOG(ERROR) << "New tensor failed";
|
||||
return nullptr;
|
||||
}
|
||||
result->data_type_ = src_tensor.data_type_;
|
||||
result->shape_ = src_tensor.shape_;
|
||||
(void)memcpy(&result->tensor_c_, &src_tensor.tensor_c_, sizeof(TensorC));
|
||||
result->tensor_c_.data_ = nullptr;
|
||||
result->category_ = src_tensor.category_;
|
||||
result->format_ = src_tensor.format_;
|
||||
result->set_allocator(allocator);
|
||||
result->set_tensor_name(src_tensor.tensor_name() + "_duplicate");
|
||||
if (copy_data) {
|
||||
|
@ -101,20 +110,22 @@ Tensor *Tensor::CopyTensor(const Tensor &src_tensor, bool copy_data, AllocatorPt
|
|||
|
||||
Tensor::~Tensor() {
|
||||
FreeData();
|
||||
this->data_ = nullptr;
|
||||
this->tensor_c_.data_ = nullptr;
|
||||
}
|
||||
|
||||
bool Tensor::operator==(const Tensor &tensor) {
|
||||
return data_ == tensor.data_ && shape_ == tensor.shape_ && data_type_ == tensor.data_type_;
|
||||
return tensor_c_.data_ == tensor.tensor_c_.data_ && tensor_c_.shape_size_ == tensor.tensor_c_.shape_size_ &&
|
||||
tensor_c_.data_type_ == tensor.tensor_c_.data_type_ &&
|
||||
std::equal(tensor_c_.shape_, tensor_c_.shape_ + tensor_c_.shape_size_, tensor.tensor_c_.shape_);
|
||||
}
|
||||
|
||||
int32_t Tensor::Batch() const {
|
||||
// Only 2D or 4D tensors have valid batch.
|
||||
if (this->shape_.size() != 4 && this->shape_.size() != 2) {
|
||||
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->shape().size();
|
||||
if (this->tensor_c_.shape_size_ != C4NUM && this->tensor_c_.shape_size_ != C2NUM) {
|
||||
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->tensor_c_.shape_size_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
switch (this->format_) {
|
||||
switch (this->tensor_c_.format_) {
|
||||
case mindspore::NHWC:
|
||||
case mindspore::NHWC4:
|
||||
case mindspore::NCHW:
|
||||
|
@ -124,56 +135,56 @@ int32_t Tensor::Batch() const {
|
|||
case mindspore::KHWC:
|
||||
case mindspore::NC:
|
||||
case mindspore::NC4:
|
||||
return this->shape_[0];
|
||||
return this->tensor_c_.shape_[0];
|
||||
case mindspore::HWCK:
|
||||
case mindspore::CHWK:
|
||||
if (this->shape_.size() != 4) {
|
||||
if (this->tensor_c_.shape_size_ != C4NUM) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
return this->shape_[3];
|
||||
return this->tensor_c_.shape_[C3NUM];
|
||||
case mindspore::HWKC:
|
||||
if (this->shape_.size() != 4) {
|
||||
if (this->tensor_c_.shape_size_ != C4NUM) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
return this->shape_[2];
|
||||
return this->tensor_c_.shape_[C2NUM];
|
||||
case mindspore::CKHW:
|
||||
return this->shape_[1];
|
||||
return this->tensor_c_.shape_[1];
|
||||
default:
|
||||
MS_LOG(ERROR) << "Unsupported format: " << EnumNameFormat(static_cast<schema::Format>(this->format_));
|
||||
MS_LOG(ERROR) << "Unsupported format: " << EnumNameFormat(static_cast<schema::Format>(this->tensor_c_.format_));
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t Tensor::Channel() const {
|
||||
// Only 2D or 4D tensors have valid channel.
|
||||
if (this->shape_.size() != 4 && this->shape_.size() != 2) {
|
||||
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->shape().size();
|
||||
if (this->tensor_c_.shape_size_ != C4NUM && this->tensor_c_.shape_size_ != C2NUM) {
|
||||
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->tensor_c_.shape_size_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
switch (this->format_) {
|
||||
switch (this->tensor_c_.format_) {
|
||||
case mindspore::NCHW:
|
||||
case mindspore::KCHW:
|
||||
case mindspore::NC:
|
||||
case mindspore::NC4:
|
||||
case mindspore::NC4HW4:
|
||||
case mindspore::NC8HW8:
|
||||
return this->shape_[1];
|
||||
return this->tensor_c_.shape_[1];
|
||||
case mindspore::HWCK:
|
||||
if (this->shape_.size() != 4) {
|
||||
if (this->tensor_c_.shape_size_ != C4NUM) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
return this->shape_[2];
|
||||
return this->tensor_c_.shape_[C2NUM];
|
||||
case mindspore::HWKC:
|
||||
case mindspore::NHWC:
|
||||
case mindspore::NHWC4:
|
||||
case mindspore::KHWC:
|
||||
if (this->shape_.size() != 4) {
|
||||
if (this->tensor_c_.shape_size_ != C4NUM) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
return this->shape_[3];
|
||||
return this->tensor_c_.shape_[C3NUM];
|
||||
case mindspore::CKHW:
|
||||
case mindspore::CHWK:
|
||||
return this->shape_[0];
|
||||
return this->tensor_c_.shape_[0];
|
||||
default:
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
@ -181,79 +192,81 @@ int32_t Tensor::Channel() const {
|
|||
|
||||
int32_t Tensor::Height() const {
|
||||
// Only 2D or 4D tensors have valid height.
|
||||
if (this->shape_.size() != 4 && this->shape_.size() != 2) {
|
||||
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->shape().size();
|
||||
if (this->tensor_c_.shape_size_ != C4NUM && this->tensor_c_.shape_size_ != C2NUM) {
|
||||
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->tensor_c_.shape_size_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
switch (this->format_) {
|
||||
switch (this->tensor_c_.format_) {
|
||||
case mindspore::NCHW:
|
||||
case mindspore::KCHW:
|
||||
case mindspore::CKHW:
|
||||
case mindspore::NC4HW4:
|
||||
case mindspore::NC8HW8:
|
||||
if (this->shape_.size() != 4) {
|
||||
if (this->tensor_c_.shape_size_ != C4NUM) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
return this->shape_[2];
|
||||
return this->tensor_c_.shape_[C2NUM];
|
||||
case mindspore::NHWC:
|
||||
case mindspore::NHWC4:
|
||||
case mindspore::KHWC:
|
||||
case mindspore::CHWK:
|
||||
return this->shape_[1];
|
||||
return this->tensor_c_.shape_[1];
|
||||
case mindspore::HWCK:
|
||||
case mindspore::HWKC:
|
||||
case mindspore::HW:
|
||||
case mindspore::HW4:
|
||||
return this->shape_[0];
|
||||
return this->tensor_c_.shape_[0];
|
||||
default:
|
||||
MS_LOG(ERROR) << "Unsupported format: " << EnumNameFormat(static_cast<schema::Format>(this->format_));
|
||||
MS_LOG(ERROR) << "Unsupported format: " << EnumNameFormat(static_cast<schema::Format>(this->tensor_c_.format_));
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t Tensor::Width() const {
|
||||
// Only 2D or 4D tensors have valid width.
|
||||
if (this->shape_.size() != 4 && this->shape_.size() != 2) {
|
||||
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->shape().size();
|
||||
if (this->tensor_c_.shape_size_ != C4NUM && this->tensor_c_.shape_size_ != C2NUM) {
|
||||
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->tensor_c_.shape_size_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
switch (this->format_) {
|
||||
switch (this->tensor_c_.format_) {
|
||||
case mindspore::NCHW:
|
||||
case mindspore::KCHW:
|
||||
case mindspore::CKHW:
|
||||
case mindspore::NC4HW4:
|
||||
case mindspore::NC8HW8:
|
||||
if (this->shape_.size() != 4) {
|
||||
if (this->tensor_c_.shape_size_ != C4NUM) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
return this->shape_[3];
|
||||
return this->tensor_c_.shape_[C3NUM];
|
||||
case mindspore::KHWC:
|
||||
case mindspore::NHWC:
|
||||
case mindspore::NHWC4:
|
||||
case mindspore::CHWK:
|
||||
if (this->shape_.size() != 4) {
|
||||
if (this->tensor_c_.shape_size_ != C4NUM) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
return this->shape_[2];
|
||||
return this->tensor_c_.shape_[C2NUM];
|
||||
case mindspore::HWCK:
|
||||
case mindspore::HWKC:
|
||||
case mindspore::HW:
|
||||
case mindspore::HW4:
|
||||
return this->shape_[1];
|
||||
return this->tensor_c_.shape_[1];
|
||||
default:
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
size_t Tensor::Size() const {
|
||||
size_t element_size = DataTypeSize(this->data_type_);
|
||||
size_t element_size = DataTypeSize(static_cast<TypeId>(tensor_c_.data_type_));
|
||||
if (element_size == 0) {
|
||||
MS_LOG(INFO) << "Unexpected data type: " << data_type_;
|
||||
MS_LOG(INFO) << "Unexpected data type: " << tensor_c_.data_type_;
|
||||
return 0;
|
||||
}
|
||||
auto element_num = (format_ == mindspore::NC4HW4 || format_ == mindspore::NHWC4) ? ElementsC4Num() : ElementsNum();
|
||||
auto element_num =
|
||||
(tensor_c_.format_ == mindspore::NC4HW4 || tensor_c_.format_ == mindspore::NHWC4) ? ElementsC4Num() : ElementsNum();
|
||||
if (element_num <= 0) {
|
||||
MS_LOG(DEBUG) << "Element number of tensor should large than 0 : " << element_num << ", shape: " << shape_;
|
||||
std::vector<int> shape(tensor_c_.shape_, tensor_c_.shape_ + tensor_c_.shape_size_);
|
||||
MS_LOG(DEBUG) << "Element number of tensor should large than 0 : " << element_num << ", shape: " << shape;
|
||||
return 0;
|
||||
}
|
||||
return element_size * static_cast<size_t>(element_num);
|
||||
|
@ -263,16 +276,16 @@ int64_t Tensor::ElementsNum() const {
|
|||
if (this->category_ == CONST_SCALAR) {
|
||||
return 1;
|
||||
}
|
||||
if (format_ == mindspore::NC4HW4) {
|
||||
if (tensor_c_.format_ == mindspore::NC4HW4) {
|
||||
return ElementsC4Num();
|
||||
}
|
||||
if (format_ == mindspore::NC8HW8) {
|
||||
if (tensor_c_.format_ == mindspore::NC8HW8) {
|
||||
return ElementsC8Num();
|
||||
}
|
||||
int64_t num = 1;
|
||||
for (size_t i = 0; i < shape_.size(); ++i) {
|
||||
CHECK_INT64_MUL_OVERFLOW(num, shape_[i]);
|
||||
num *= shape_[i];
|
||||
for (size_t i = 0; i < tensor_c_.shape_size_; ++i) {
|
||||
CHECK_INT64_MUL_OVERFLOW(num, tensor_c_.shape_[i]);
|
||||
num *= tensor_c_.shape_[i];
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
@ -283,7 +296,7 @@ int64_t Tensor::ElementsC4Num() const {
|
|||
}
|
||||
int64_t result = 1;
|
||||
constexpr int kC4Align = 4;
|
||||
if (this->shape_.size() == 4) {
|
||||
if (this->tensor_c_.shape_size_ == C4NUM) {
|
||||
CHECK_INT64_MUL_OVERFLOW(result, Batch());
|
||||
result *= Batch();
|
||||
CHECK_INT64_MUL_OVERFLOW(result, Height());
|
||||
|
@ -292,11 +305,11 @@ int64_t Tensor::ElementsC4Num() const {
|
|||
result *= Width();
|
||||
CHECK_INT64_MUL_OVERFLOW(result, (Channel() + 3LL) / kC4Align * kC4Align);
|
||||
result *= (Channel() + 3LL) / kC4Align * kC4Align;
|
||||
} else if (this->shape_.size() == 2) {
|
||||
CHECK_INT64_MUL_OVERFLOW(result, this->shape_[0]);
|
||||
result *= this->shape_[0];
|
||||
CHECK_INT64_MUL_OVERFLOW(result, (this->shape_[1] + 3LL) / kC4Align * kC4Align);
|
||||
result *= (this->shape_[1] + 3LL) / kC4Align * kC4Align;
|
||||
} else if (this->tensor_c_.shape_size_ == C2NUM) {
|
||||
CHECK_INT64_MUL_OVERFLOW(result, this->tensor_c_.shape_[0]);
|
||||
result *= this->tensor_c_.shape_[0];
|
||||
CHECK_INT64_MUL_OVERFLOW(result, (this->tensor_c_.shape_[1] + 3LL) / kC4Align * kC4Align);
|
||||
result *= (this->tensor_c_.shape_[1] + 3LL) / kC4Align * kC4Align;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -307,7 +320,7 @@ int64_t Tensor::ElementsC8Num() const {
|
|||
}
|
||||
int64_t result = 1;
|
||||
constexpr int kC8Align = 8;
|
||||
if (this->shape_.size() == 4) {
|
||||
if (this->tensor_c_.shape_size_ == C4NUM) {
|
||||
CHECK_INT64_MUL_OVERFLOW(result, Batch());
|
||||
result *= Batch();
|
||||
CHECK_INT64_MUL_OVERFLOW(result, Height());
|
||||
|
@ -316,19 +329,19 @@ int64_t Tensor::ElementsC8Num() const {
|
|||
result *= Width();
|
||||
CHECK_INT64_MUL_OVERFLOW(result, (Channel() + 7LL) / kC8Align * kC8Align);
|
||||
result *= (Channel() + 7LL) / kC8Align * kC8Align;
|
||||
} else if (this->shape_.size() == 2) {
|
||||
CHECK_INT64_MUL_OVERFLOW(result, this->shape_[0]);
|
||||
result *= this->shape_[0];
|
||||
CHECK_INT64_MUL_OVERFLOW(result, (this->shape_[1] + 7LL) / kC8Align * kC8Align);
|
||||
result *= (this->shape_[1] + 7LL) / kC8Align * kC8Align;
|
||||
} else if (this->tensor_c_.shape_size_ == C2NUM) {
|
||||
CHECK_INT64_MUL_OVERFLOW(result, this->tensor_c_.shape_[0]);
|
||||
result *= this->tensor_c_.shape_[0];
|
||||
CHECK_INT64_MUL_OVERFLOW(result, (this->tensor_c_.shape_[1] + 7LL) / kC8Align * kC8Align);
|
||||
result *= (this->tensor_c_.shape_[1] + 7LL) / kC8Align * kC8Align;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int Tensor::DimensionSize(const size_t index) const {
|
||||
int dim_size = -1;
|
||||
if (index < shape_.size()) {
|
||||
dim_size = shape_[index];
|
||||
if (index < tensor_c_.shape_size_) {
|
||||
dim_size = tensor_c_.shape_[index];
|
||||
} else {
|
||||
MS_LOG(ERROR) << "Dimension index is wrong: " << index;
|
||||
}
|
||||
|
@ -338,29 +351,30 @@ int Tensor::DimensionSize(const size_t index) const {
|
|||
std::string Tensor::ToString() const {
|
||||
std::ostringstream oss;
|
||||
oss << "Tensor name: " << this->tensor_name();
|
||||
oss << " schema::Format: " << EnumNameFormat(static_cast<schema::Format>(this->format_));
|
||||
oss << " DataType: " << this->data_type_;
|
||||
oss << " schema::Format: " << EnumNameFormat(static_cast<schema::Format>(this->tensor_c_.format_));
|
||||
oss << " DataType: " << this->tensor_c_.data_type_;
|
||||
oss << " Category: " << this->category_;
|
||||
oss << " Shape:";
|
||||
for (auto &dim : this->shape()) {
|
||||
oss << " " << dim;
|
||||
}
|
||||
oss << std::endl << "Data:";
|
||||
switch (this->data_type_) {
|
||||
auto data = tensor_c_.data_;
|
||||
switch (this->tensor_c_.data_type_) {
|
||||
case kNumberTypeFloat32: {
|
||||
oss << DataToString<float>(data_, this->ElementsNum());
|
||||
oss << DataToString<float>(data, this->ElementsNum());
|
||||
} break;
|
||||
case kNumberTypeFloat16: {
|
||||
oss << DataToString<int16_t>(data_, this->ElementsNum());
|
||||
oss << DataToString<int16_t>(data, this->ElementsNum());
|
||||
} break;
|
||||
case kNumberTypeInt32: {
|
||||
oss << DataToString<int32_t>(data_, this->ElementsNum());
|
||||
oss << DataToString<int32_t>(data, this->ElementsNum());
|
||||
} break;
|
||||
case kNumberTypeInt16: {
|
||||
oss << DataToString<int16_t>(data_, this->ElementsNum());
|
||||
oss << DataToString<int16_t>(data, this->ElementsNum());
|
||||
} break;
|
||||
case kNumberTypeInt8: {
|
||||
oss << DataToString<int8_t>(data_, this->ElementsNum());
|
||||
oss << DataToString<int8_t>(data, this->ElementsNum());
|
||||
} break;
|
||||
default:
|
||||
oss << "Unsupported data type to print";
|
||||
|
@ -370,15 +384,15 @@ std::string Tensor::ToString() const {
|
|||
}
|
||||
|
||||
int Tensor::MallocData(const AllocatorPtr allocator) {
|
||||
if (this->data_ != nullptr) {
|
||||
if (this->tensor_c_.data_ != nullptr) {
|
||||
return RET_OK;
|
||||
}
|
||||
if (allocator != nullptr) {
|
||||
allocator_ = allocator;
|
||||
}
|
||||
size_t element_size = DataTypeSize(this->data_type_);
|
||||
size_t element_size = DataTypeSize(static_cast<TypeId>(this->tensor_c_.data_type_));
|
||||
if (element_size == 0) {
|
||||
MS_LOG(ERROR) << "Unexpected data type: " << data_type_;
|
||||
MS_LOG(ERROR) << "Unexpected data type: " << tensor_c_.data_type_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
auto data_size = this->Size();
|
||||
|
@ -391,12 +405,12 @@ int Tensor::MallocData(const AllocatorPtr allocator) {
|
|||
return RET_ERROR;
|
||||
}
|
||||
if (allocator_ == nullptr) {
|
||||
this->data_ = malloc(data_size);
|
||||
this->tensor_c_.data_ = malloc(data_size);
|
||||
} else {
|
||||
this->data_ = allocator_->Malloc(data_size);
|
||||
allocator_->SetRefCount(this->data_, 1);
|
||||
this->tensor_c_.data_ = allocator_->Malloc(data_size);
|
||||
allocator_->SetRefCount(this->tensor_c_.data_, 1);
|
||||
}
|
||||
if (this->data_ == nullptr) {
|
||||
if (this->tensor_c_.data_ == nullptr) {
|
||||
MS_LOG(ERROR) << "Malloc tensor data failed, size=" << data_size;
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
@ -408,43 +422,43 @@ void Tensor::FreeData() {
|
|||
if (IS_RUNTIME_ALLOCATOR(allocator_)) {
|
||||
return;
|
||||
}
|
||||
if (this->data_ != nullptr && this->own_data_) {
|
||||
if (this->tensor_c_.data_ != nullptr && this->own_data_) {
|
||||
if (this->allocator_ != nullptr) {
|
||||
if (allocator_->DecRefCount(this->data_, 1) <= 0) {
|
||||
allocator_->Free(this->data_); // Due to existing various allocator, here do not set data to nullptr.
|
||||
if (allocator_->DecRefCount(this->tensor_c_.data_, 1) <= 0) {
|
||||
allocator_->Free(this->tensor_c_.data_); // Due to existing various allocator, here do not set data to nullptr.
|
||||
}
|
||||
if (!IS_STATIC_ALLOCATOR(allocator_) || allocator_->RefCount(this->data_) != 0) {
|
||||
this->data_ = nullptr;
|
||||
if (!IS_STATIC_ALLOCATOR(allocator_) || allocator_->RefCount(this->tensor_c_.data_) != 0) {
|
||||
this->tensor_c_.data_ = nullptr;
|
||||
}
|
||||
} else {
|
||||
free(this->data_);
|
||||
this->data_ = nullptr;
|
||||
free(this->tensor_c_.data_);
|
||||
this->tensor_c_.data_ = nullptr;
|
||||
}
|
||||
} else if (this->category_ == Category::VAR) {
|
||||
if (!IS_STATIC_ALLOCATOR(allocator_) || allocator_->RefCount(this->data_) != 0) {
|
||||
if (!IS_STATIC_ALLOCATOR(allocator_) || allocator_->RefCount(this->tensor_c_.data_) != 0) {
|
||||
if (this->init_ref_count_ == 1) {
|
||||
this->data_ = nullptr;
|
||||
this->tensor_c_.data_ = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *Tensor::ReallocData() {
|
||||
if (this->data_ != nullptr) {
|
||||
if (this->tensor_c_.data_ != nullptr) {
|
||||
FreeData();
|
||||
}
|
||||
return this->MutableData();
|
||||
}
|
||||
|
||||
void *Tensor::MutableData() {
|
||||
if (this->data_ == nullptr) {
|
||||
if (this->tensor_c_.data_ == nullptr) {
|
||||
auto ret = this->MallocData();
|
||||
if (ret != 0) {
|
||||
MS_LOG(WARNING) << "Malloc data failed";
|
||||
}
|
||||
}
|
||||
Prepare();
|
||||
return this->data_;
|
||||
return this->tensor_c_.data_;
|
||||
}
|
||||
|
||||
void Tensor::DecRefCount() {
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <atomic>
|
||||
#include "include/api/format.h"
|
||||
#include "include/lite_types.h"
|
||||
#include "nnacl/tensor_c.h"
|
||||
#include "src/runtime/inner_allocator.h"
|
||||
#include "src/common/log_adapter.h"
|
||||
#include "src/common/utils.h"
|
||||
|
@ -55,7 +56,7 @@ struct LiteQuantParam {
|
|||
|
||||
class Tensor {
|
||||
public:
|
||||
Tensor() = default;
|
||||
Tensor() { tensor_c_ = {kTypeUnknown, DEFAULT_FORMAT, nullptr, 0}; }
|
||||
|
||||
Tensor(TypeId data_type, std::vector<int> shape, const mindspore::Format &format = mindspore::NHWC,
|
||||
Category category = VAR);
|
||||
|
@ -85,13 +86,26 @@ class Tensor {
|
|||
|
||||
std::string tensor_name() const { return tensor_name_; }
|
||||
|
||||
TypeId data_type() const { return data_type_; }
|
||||
TypeId data_type() const { return static_cast<TypeId>(tensor_c_.data_type_); }
|
||||
|
||||
void set_data_type(TypeId data_type) { data_type_ = data_type; }
|
||||
void set_data_type(TypeId data_type) { tensor_c_.data_type_ = data_type; }
|
||||
|
||||
std::vector<int> shape() const { return shape_; }
|
||||
std::vector<int> shape() const {
|
||||
return std::vector<int>(tensor_c_.shape_, tensor_c_.shape_ + tensor_c_.shape_size_);
|
||||
}
|
||||
|
||||
void set_shape(const std::vector<int> &shape) { shape_ = shape; }
|
||||
void set_shape(const std::vector<int> &shape) {
|
||||
if (shape.size() > MAX_SHAPE_SIZE) {
|
||||
FreeData();
|
||||
tensor_c_.shape_size_ = 0;
|
||||
MS_LOG(WARNING) << "The shape-size has exceeded the limit 8, now is " << shape.size();
|
||||
return;
|
||||
}
|
||||
tensor_c_.shape_size_ = shape.size();
|
||||
for (size_t i = 0; i < shape.size(); ++i) {
|
||||
tensor_c_.shape_[i] = shape[i];
|
||||
}
|
||||
}
|
||||
|
||||
int DimensionSize(size_t index) const;
|
||||
|
||||
|
@ -122,21 +136,21 @@ class Tensor {
|
|||
|
||||
void *ReallocData();
|
||||
|
||||
virtual void *data() { return data_; }
|
||||
virtual void *data() { return tensor_c_.data_; }
|
||||
|
||||
virtual void *data() const { return data_; }
|
||||
virtual void *data() const { return tensor_c_.data_; }
|
||||
|
||||
// note: in the case of that old_data is valid, set_data just releases the ownership of it but not frees it. Of
|
||||
// course, you can call FreeData before calling set_data to ensure the data can be freed by current tensor.
|
||||
void set_data(void *data) {
|
||||
if (this->data_ == data) {
|
||||
if (this->tensor_c_.data_ == data) {
|
||||
return;
|
||||
}
|
||||
if (allocator_ != nullptr) {
|
||||
allocator_->IncRefCount(data, 1);
|
||||
allocator_->DecRefCount(this->data_, 1);
|
||||
allocator_->DecRefCount(this->tensor_c_.data_, 1);
|
||||
}
|
||||
this->data_ = data;
|
||||
this->tensor_c_.data_ = data;
|
||||
this->own_data_ = true;
|
||||
}
|
||||
|
||||
|
@ -144,9 +158,9 @@ class Tensor {
|
|||
|
||||
void set_category(Category category) { this->category_ = category; }
|
||||
|
||||
void set_format(mindspore::Format format) { this->format_ = format; }
|
||||
void set_format(mindspore::Format format) { this->tensor_c_.format_ = format; }
|
||||
|
||||
mindspore::Format format() const { return this->format_; }
|
||||
mindspore::Format format() const { return static_cast<mindspore::Format>(this->tensor_c_.format_); }
|
||||
virtual int ref_count() const { return ref_count_; }
|
||||
|
||||
virtual int init_ref_count() const { return static_cast<int>(this->init_ref_count_); }
|
||||
|
@ -176,10 +190,10 @@ class Tensor {
|
|||
void set_quant_clusters(const std::vector<float> &clusters);
|
||||
|
||||
virtual bool IsConst() const {
|
||||
return (this->category_ == CONST_TENSOR || this->category_ == CONST_SCALAR) && this->data_ != nullptr;
|
||||
return (this->category_ == CONST_TENSOR || this->category_ == CONST_SCALAR) && this->tensor_c_.data_ != nullptr;
|
||||
}
|
||||
|
||||
bool IsScalar() const { return this->category_ == CONST_SCALAR && this->data_ != nullptr; }
|
||||
bool IsScalar() const { return this->category_ == CONST_SCALAR && this->tensor_c_.data_ != nullptr; }
|
||||
|
||||
bool IsGraphInput() const { return this->category_ == GRAPH_INPUT; }
|
||||
|
||||
|
@ -187,12 +201,12 @@ class Tensor {
|
|||
|
||||
void Prepare() {
|
||||
if (allocator_ != nullptr) {
|
||||
data_ = allocator_->Prepare(data_);
|
||||
tensor_c_.data_ = allocator_->Prepare(tensor_c_.data_);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsReady() const {
|
||||
return this->IsConst() || (this->IsGraphInput() && this->data_ != nullptr) || ref_count() >= 1;
|
||||
return this->IsConst() || (this->IsGraphInput() && this->tensor_c_.data_ != nullptr) || ref_count() >= 1;
|
||||
}
|
||||
|
||||
bool own_data() const { return this->own_data_; }
|
||||
|
@ -202,7 +216,7 @@ class Tensor {
|
|||
template <typename T>
|
||||
int Scale(float scale) {
|
||||
T cast_scale = static_cast<T>(scale);
|
||||
auto data = reinterpret_cast<T *>(data_);
|
||||
auto data = reinterpret_cast<T *>(tensor_c_.data_);
|
||||
if (data == nullptr) {
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
@ -220,6 +234,8 @@ class Tensor {
|
|||
|
||||
bool IsScale() const { return (std::fabs(this->scale_ - 1.0f) > 1.0e-05); }
|
||||
|
||||
TensorC *ConvertToTensorC() { return &tensor_c_; }
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
std::string DataToString(void *data, size_t data_number, size_t print_len = 40) const {
|
||||
|
@ -235,11 +251,8 @@ class Tensor {
|
|||
}
|
||||
|
||||
protected:
|
||||
TensorC tensor_c_;
|
||||
std::string tensor_name_;
|
||||
void *data_ = nullptr;
|
||||
TypeId data_type_;
|
||||
std::vector<int> shape_;
|
||||
mindspore::Format format_;
|
||||
Category category_;
|
||||
std::atomic_int ref_count_ = {0};
|
||||
int init_ref_count_ = 0;
|
||||
|
|
|
@ -23,9 +23,21 @@
|
|||
|
||||
namespace mindspore::lite {
|
||||
#ifndef CONTROLFLOW_TENSORLIST_CLIP
|
||||
namespace {
|
||||
constexpr int kOffset = 2;
|
||||
}
|
||||
TensorList::TensorList(std::vector<int> shape, std::vector<int> element_shape, Category category)
|
||||
: Tensor(kObjectTypeTensorType, std::move(shape), mindspore::NHWC, category),
|
||||
element_shape_(std::move(element_shape)) {}
|
||||
: Tensor(kObjectTypeTensorType, std::move(shape), mindspore::NHWC, category) {
|
||||
tensor_list_c_ = {kObjectTypeTensorType, Format_NHWC, 0, kTypeUnknown, -1, nullptr, 0, element_shape.size()};
|
||||
if (shape.size() > MAX_SHAPE_SIZE) {
|
||||
tensor_list_c_.element_shape_size_ = 0;
|
||||
MS_LOG(WARNING) << "The shape-size has exceeded the limit 8, now is " << element_shape.size();
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < element_shape.size(); ++i) {
|
||||
tensor_list_c_.element_shape_[i] = element_shape[i];
|
||||
}
|
||||
}
|
||||
|
||||
TensorList::~TensorList() {
|
||||
if (!this->tensors_.empty()) {
|
||||
|
@ -82,7 +94,7 @@ int TensorList::MallocTensorListData(TypeId dtype, const std::vector<std::vector
|
|||
<< " must be equal to param2:tensor_shape.size():" << tensor_shape.size();
|
||||
return RET_ERROR;
|
||||
}
|
||||
this->tensors_data_type_ = dtype;
|
||||
this->tensor_list_c_.tensors_data_type_ = dtype;
|
||||
for (int i = 0; i < this->ElementsNum(); ++i) {
|
||||
auto tensor_ptr = new (std::nothrow) Tensor(dtype, tensor_shape[i]);
|
||||
if (tensor_ptr == nullptr) {
|
||||
|
@ -128,9 +140,9 @@ int TensorList::MallocData(const AllocatorPtr allocator) {
|
|||
int TensorList::SetTensor(int index, const Tensor *src_tensor) {
|
||||
MS_CHECK_TRUE_MSG(src_tensor != nullptr, RET_ERROR, "src tensor cannot null");
|
||||
// your can use this fun to modify tensor[index] value
|
||||
if (src_tensor->data_type() != this->tensors_data_type_) {
|
||||
if (src_tensor->data_type() != this->tensor_list_c_.tensors_data_type_) {
|
||||
MS_LOG(ERROR) << "src_tensor->data_type():" << src_tensor->data_type()
|
||||
<< " must be equal to tensors_data_type_:" << this->tensors_data_type_;
|
||||
<< " must be equal to tensors_data_type_:" << this->tensor_list_c_.tensors_data_type_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
auto element_num = this->ElementsNum();
|
||||
|
@ -157,9 +169,9 @@ int TensorList::CheckTensorListParam() {
|
|||
MS_LOG(ERROR) << "CheckTensorListParam: tensors_[" << i << "] is nullptr";
|
||||
return RET_ERROR;
|
||||
}
|
||||
if (this->tensors_[i]->data_type() != this->tensors_data_type_) {
|
||||
if (this->tensors_[i]->data_type() != this->tensor_list_c_.tensors_data_type_) {
|
||||
MS_LOG(ERROR) << "CheckTensorListParam: tensors_[i] data_type:" << this->tensors_[i]->data_type()
|
||||
<< " is not equal to tensors_data_type_:" << this->tensors_data_type_;
|
||||
<< " is not equal to tensors_data_type_:" << this->tensor_list_c_.tensors_data_type_;
|
||||
return RET_ERROR;
|
||||
}
|
||||
}
|
||||
|
@ -176,14 +188,15 @@ Tensor *TensorList::GetTensor(int index) {
|
|||
}
|
||||
|
||||
bool TensorList::IsCompatibleShape(const std::vector<int> &shape) {
|
||||
if (this->tensors_.empty() && this->element_shape_.empty()) {
|
||||
if (this->tensors_.empty() && this->tensor_list_c_.element_shape_size_ == 0) {
|
||||
return true;
|
||||
}
|
||||
if (shape.size() != this->element_shape_.size()) {
|
||||
if (shape.size() != this->tensor_list_c_.element_shape_size_) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < shape.size(); ++i) {
|
||||
if (this->element_shape_[i] >= 0 && shape[i] >= 0 && this->element_shape_[i] != shape[i]) {
|
||||
if (this->tensor_list_c_.element_shape_[i] >= 0 && shape[i] >= 0 &&
|
||||
this->tensor_list_c_.element_shape_[i] != shape[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +206,7 @@ bool TensorList::IsCompatibleShape(const std::vector<int> &shape) {
|
|||
bool TensorList::IsCompatibleShape(const Tensor *src) {
|
||||
MS_CHECK_TRUE_MSG(src != nullptr, false, "src tensor cannot null");
|
||||
// shape is store in Tensor.
|
||||
if (static_cast<size_t>(src->ElementsNum()) != this->element_shape_.size()) {
|
||||
if (static_cast<size_t>(src->ElementsNum()) != this->tensor_list_c_.element_shape_size_) {
|
||||
return false;
|
||||
}
|
||||
if (src->data_type() != kNumberTypeInt && src->data_type() != kNumberTypeInt32) {
|
||||
|
@ -201,8 +214,9 @@ bool TensorList::IsCompatibleShape(const Tensor *src) {
|
|||
return false;
|
||||
}
|
||||
auto src_ptr = reinterpret_cast<int *>(src->data());
|
||||
for (size_t i = 0; i < this->element_shape_.size(); ++i) {
|
||||
if (this->element_shape_[i] >= 0 && src_ptr[i] >= 0 && this->element_shape_[i] != src_ptr[i]) {
|
||||
for (size_t i = 0; i < this->tensor_list_c_.element_shape_size_; ++i) {
|
||||
if (this->tensor_list_c_.element_shape_[i] >= 0 && src_ptr[i] >= 0 &&
|
||||
this->tensor_list_c_.element_shape_[i] != src_ptr[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -214,8 +228,8 @@ STATUS TensorList::Decode(const int *data) {
|
|||
MS_LOG(ERROR) << "data is nullptr";
|
||||
return RET_ERROR;
|
||||
}
|
||||
tensors_data_type_ = TypeId(data[0]);
|
||||
if (tensors_data_type_ < kTypeUnknown || tensors_data_type_ > kMonadTypeEnd) {
|
||||
tensor_list_c_.tensors_data_type_ = TypeId(data[0]);
|
||||
if (tensor_list_c_.tensors_data_type_ < kTypeUnknown || tensor_list_c_.tensors_data_type_ > kMonadTypeEnd) {
|
||||
MS_LOG(ERROR) << "TypeId illegal.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
@ -223,10 +237,15 @@ STATUS TensorList::Decode(const int *data) {
|
|||
MS_LOG(ERROR) << "element shape size illegal.";
|
||||
return RET_ERROR;
|
||||
}
|
||||
for (int j = 0; j < data[1]; ++j) {
|
||||
element_shape_.push_back(data[2 + j]);
|
||||
if (data[1] < 0 || data[1] > MAX_SHAPE_SIZE) {
|
||||
MS_LOG(WARNING) << "The shape-size must be in [0, 8], now is " << data[1];
|
||||
return RET_ERROR;
|
||||
}
|
||||
int tensors_num = data[2 + data[1]];
|
||||
tensor_list_c_.element_shape_size_ = data[1];
|
||||
for (int j = 0; j < data[1]; ++j) {
|
||||
tensor_list_c_.element_shape_[j] = data[kOffset + j];
|
||||
}
|
||||
int tensors_num = data[kOffset + data[1]];
|
||||
if (tensors_num < 0) {
|
||||
MS_LOG(WARNING) << "not able to create tensors, need infer shape.";
|
||||
return RET_OK;
|
||||
|
@ -238,14 +257,14 @@ STATUS TensorList::Decode(const int *data) {
|
|||
MS_LOG(WARNING) << "tensor name: " << this->tensor_name_;
|
||||
}
|
||||
tensors_.reserve(tensors_num);
|
||||
int tensor_index = 2 + data[1] + 1;
|
||||
int tensor_index = kOffset + data[1] + 1;
|
||||
for (int i = 0; i < tensors_num; i++) {
|
||||
int tensor_dims_size = data[tensor_index++];
|
||||
std::vector<int> shape(tensor_dims_size);
|
||||
for (int j = 0; j < tensor_dims_size; j++) {
|
||||
shape[j] = data[tensor_index++];
|
||||
}
|
||||
auto tensor = new (std::nothrow) Tensor(tensors_data_type_, shape);
|
||||
auto tensor = new (std::nothrow) Tensor(static_cast<TypeId>(tensor_list_c_.tensors_data_type_), shape);
|
||||
if (tensor == nullptr) {
|
||||
MS_LOG(ERROR) << "new Tensor failed";
|
||||
return RET_NULL_PTR;
|
||||
|
@ -263,15 +282,13 @@ TensorList *TensorList::CopyTensorList(const TensorList &src, bool copy_data, Al
|
|||
MS_LOG(ERROR) << "New tensor failed";
|
||||
return nullptr;
|
||||
}
|
||||
result->data_type_ = src.data_type_;
|
||||
result->shape_ = src.shape_;
|
||||
(void)memcpy(&result->tensor_c_, &src.tensor_c_, sizeof(TensorC));
|
||||
result->tensor_c_.data_ = nullptr;
|
||||
(void)memcpy(&result->tensor_list_c_, &src.tensor_list_c_, sizeof(TensorListC));
|
||||
result->tensor_list_c_.tensors_ = nullptr;
|
||||
result->category_ = src.category_;
|
||||
result->format_ = src.format_;
|
||||
result->tensors_data_type_ = src.tensors_data_type_;
|
||||
result->element_shape_ = src.element_shape_;
|
||||
result->set_allocator(allocator);
|
||||
result->set_tensor_name(src.tensor_name() + "_duplicate");
|
||||
auto src_tensor_dtype = src.tensors_data_type_;
|
||||
std::vector<std::vector<int> > tensor_shape{};
|
||||
std::transform(src.tensors_.begin(), src.tensors_.end(), std::back_inserter(tensor_shape),
|
||||
[](const Tensor *tensor_item) { return tensor_item->shape(); });
|
||||
|
@ -283,7 +300,7 @@ TensorList *TensorList::CopyTensorList(const TensorList &src, bool copy_data, Al
|
|||
if (result->shape().empty()) {
|
||||
return result;
|
||||
}
|
||||
result->MallocTensorListData(src_tensor_dtype, tensor_shape);
|
||||
result->MallocTensorListData(static_cast<TypeId>(src.tensor_list_c_.tensors_data_type_), tensor_shape);
|
||||
if (copy_data) {
|
||||
for (size_t i = 1; i < src.tensors_.size(); ++i) {
|
||||
auto src_tensor = src.tensors_;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <memory>
|
||||
#include <vector>
|
||||
#include "include/errorcode.h"
|
||||
#include "nnacl/tensorlist_c.h"
|
||||
#include "src/common/log_adapter.h"
|
||||
#include "schema/model_generated.h"
|
||||
#include "src/tensor.h"
|
||||
|
@ -57,7 +58,7 @@ namespace mindspore::lite {
|
|||
*/
|
||||
class TensorList : public Tensor {
|
||||
public:
|
||||
TensorList() = default;
|
||||
TensorList() { tensor_list_c_ = {kObjectTypeTensorType, DEFAULT_FORMAT, 0, kTypeUnknown, -1, nullptr, 0, 0}; }
|
||||
|
||||
TensorList(std::vector<int> shape, std::vector<int> element_shape, Category category = VAR);
|
||||
|
||||
|
@ -67,13 +68,27 @@ class TensorList : public Tensor {
|
|||
|
||||
TensorList &operator=(const TensorList &tl) = delete;
|
||||
|
||||
void set_element_shape(const std::vector<int> &shape) { element_shape_ = shape; }
|
||||
void set_element_shape(const std::vector<int> &shape) {
|
||||
if (shape.size() > MAX_SHAPE_SIZE) {
|
||||
FreeData();
|
||||
tensor_list_c_.element_shape_size_ = 0;
|
||||
MS_LOG(WARNING) << "The shape-size has exceeded the limit 8, now is " << shape.size();
|
||||
return;
|
||||
}
|
||||
tensor_list_c_.element_shape_size_ = shape.size();
|
||||
for (size_t i = 0; i < shape.size(); ++i) {
|
||||
tensor_list_c_.element_shape_[i] = shape[i];
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> &element_shape() { return element_shape_; }
|
||||
std::vector<int> element_shape() {
|
||||
return std::vector<int>(tensor_list_c_.element_shape_,
|
||||
tensor_list_c_.element_shape_ + tensor_list_c_.element_shape_size_);
|
||||
}
|
||||
|
||||
void set_max_elements_num(int ele_num) { max_elements_num_ = ele_num; }
|
||||
void set_max_elements_num(int ele_num) { tensor_list_c_.max_elements_num_ = ele_num; }
|
||||
|
||||
int max_elements_num() const { return max_elements_num_; }
|
||||
int max_elements_num() const { return tensor_list_c_.max_elements_num_; }
|
||||
|
||||
static TensorList *CopyTensorList(const TensorList &src, bool copy_data = false, AllocatorPtr allocator = nullptr);
|
||||
|
||||
|
@ -89,9 +104,9 @@ class TensorList : public Tensor {
|
|||
|
||||
Tensor *GetTensor(int index);
|
||||
|
||||
void set_tensors_data_type(TypeId type) { tensors_data_type_ = type; }
|
||||
void set_tensors_data_type(TypeId type) { tensor_list_c_.tensors_data_type_ = type; }
|
||||
|
||||
TypeId tensors_data_type() const { return tensors_data_type_; }
|
||||
TypeId tensors_data_type() const { return static_cast<TypeId>(tensor_list_c_.tensors_data_type_); }
|
||||
|
||||
std::vector<Tensor *> &tensors() { return tensors_; }
|
||||
|
||||
|
@ -173,15 +188,21 @@ class TensorList : public Tensor {
|
|||
}
|
||||
}
|
||||
|
||||
TensorListC *ConvertToTensorListC() {
|
||||
tensor_list_c_.format_ = tensor_c_.format_;
|
||||
tensor_list_c_.shape_value_ = tensor_c_.shape_size_ == 0 ? 0 : tensor_c_.shape_[0];
|
||||
tensor_list_c_.element_num_ = tensor_c_.shape_size_ == 0 ? 0 : tensors_.size();
|
||||
tensor_list_c_.tensors_ = nullptr;
|
||||
return &tensor_list_c_;
|
||||
}
|
||||
|
||||
protected:
|
||||
// The following functions must be masked.
|
||||
void *data() const override { return nullptr; }
|
||||
void *MutableData() override { return nullptr; }
|
||||
size_t Size() const override { return 0; }
|
||||
TensorListC tensor_list_c_;
|
||||
std::vector<Tensor *> tensors_{};
|
||||
TypeId tensors_data_type_ = kTypeUnknown;
|
||||
std::vector<int> element_shape_{};
|
||||
int max_elements_num_ = -1;
|
||||
};
|
||||
|
||||
#else
|
||||
|
|
|
@ -43,11 +43,12 @@ TEST_F(TensorlistFromtensorInferTest, TensorlistFromtensorInferTest0) {
|
|||
inputs[1]->shape_[1] = 2;
|
||||
|
||||
std::vector<TensorC *> outputs(1, NULL);
|
||||
outputs[0] = reinterpret_cast<TensorC *>(malloc(sizeof(TensorListC)));
|
||||
OpParameter *parameter = new OpParameter;
|
||||
auto out = reinterpret_cast<TensorListC *>(malloc(sizeof(TensorListC)));
|
||||
out->tensors_ = nullptr;
|
||||
outputs[0] = reinterpret_cast<TensorC *>(out);
|
||||
auto *parameter = new OpParameter;
|
||||
int ret = TensorListFromTensorInferShape((const TensorC **)inputs.data(), inputs.size(), outputs.data(),
|
||||
outputs.size(), reinterpret_cast<OpParameter *>(parameter));
|
||||
TensorListC *out = reinterpret_cast<TensorListC *>(outputs[0]);
|
||||
ASSERT_EQ(ret, NNACL_OK);
|
||||
ASSERT_EQ(out->element_num_, 4);
|
||||
ASSERT_EQ(out->data_type_, kObjectTypeTensorType);
|
||||
|
@ -57,22 +58,16 @@ TEST_F(TensorlistFromtensorInferTest, TensorlistFromtensorInferTest0) {
|
|||
ASSERT_EQ(out->tensors_data_type_, kNumberTypeInt32);
|
||||
// ASSERT_EQ(outputs[0]->format_, Format_NHWC);
|
||||
for (size_t i = 0; i < out->element_num_; i++) {
|
||||
ASSERT_EQ(out->tensors_[i].shape_size_, 2);
|
||||
ASSERT_EQ(out->tensors_[i].shape_[0], 6);
|
||||
ASSERT_EQ(out->tensors_[i].shape_[1], 5);
|
||||
ASSERT_EQ(out->tensors_[i]->shape_size_, 2);
|
||||
ASSERT_EQ(out->tensors_[i]->shape_[0], 6);
|
||||
ASSERT_EQ(out->tensors_[i]->shape_[1], 5);
|
||||
}
|
||||
delete parameter;
|
||||
for (size_t i = 0; i < inputs_size; i++) {
|
||||
delete inputs[i];
|
||||
}
|
||||
for (size_t i = 0; i < outputs.size(); i++) {
|
||||
if (outputs[i]->data_type_ == kObjectTypeTensorType) {
|
||||
TensorListC *tensorListC = reinterpret_cast<TensorListC *>(outputs[i]);
|
||||
lite::FreeTensorListC(tensorListC);
|
||||
} else {
|
||||
delete outputs[i];
|
||||
}
|
||||
}
|
||||
lite::FreeOutTensorC(&outputs);
|
||||
delete out;
|
||||
}
|
||||
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -28,24 +28,25 @@ class TensorlistGetItemInferTest : public mindspore::CommonTest {
|
|||
TEST_F(TensorlistGetItemInferTest, TensorlistGetItemInferTest0) {
|
||||
size_t inputs_size = 3;
|
||||
std::vector<TensorC *> inputs(inputs_size, NULL);
|
||||
TensorListC *input0 = reinterpret_cast<TensorListC *>(malloc(sizeof(TensorListC)));
|
||||
auto *input0 = reinterpret_cast<TensorListC *>(malloc(sizeof(TensorListC)));
|
||||
input0->element_num_ = 3;
|
||||
input0->tensors_ = reinterpret_cast<TensorC *>(malloc(input0->element_num_ * sizeof(TensorC)));
|
||||
input0->tensors_[0].shape_size_ = 2;
|
||||
input0->tensors_[0].shape_[0] = 1;
|
||||
input0->tensors_[0].shape_[1] = 2;
|
||||
input0->tensors_[0].data_type_ = kNumberTypeInt32;
|
||||
input0->tensors_[1].shape_size_ = 3;
|
||||
input0->tensors_[1].shape_[0] = 3;
|
||||
input0->tensors_[1].shape_[1] = 4;
|
||||
input0->tensors_[1].shape_[2] = 5;
|
||||
input0->tensors_[1].data_type_ = kNumberTypeInt32;
|
||||
input0->tensors_[2].shape_size_ = 4;
|
||||
input0->tensors_[2].shape_[0] = 6;
|
||||
input0->tensors_[2].shape_[1] = 7;
|
||||
input0->tensors_[2].shape_[2] = 8;
|
||||
input0->tensors_[2].shape_[3] = 9;
|
||||
input0->tensors_[2].data_type_ = kNumberTypeInt32;
|
||||
auto in_tensors_c = reinterpret_cast<TensorC *>(malloc(input0->element_num_ * sizeof(TensorC)));
|
||||
input0->tensors_ = &in_tensors_c;
|
||||
in_tensors_c[0].shape_size_ = 2;
|
||||
in_tensors_c[0].shape_[0] = 1;
|
||||
in_tensors_c[0].shape_[1] = 2;
|
||||
in_tensors_c[0].data_type_ = kNumberTypeInt32;
|
||||
in_tensors_c[1].shape_size_ = 3;
|
||||
in_tensors_c[1].shape_[0] = 3;
|
||||
in_tensors_c[1].shape_[1] = 4;
|
||||
in_tensors_c[1].shape_[2] = 5;
|
||||
in_tensors_c[1].data_type_ = kNumberTypeInt32;
|
||||
in_tensors_c[2].shape_size_ = 4;
|
||||
in_tensors_c[2].shape_[0] = 6;
|
||||
in_tensors_c[2].shape_[1] = 7;
|
||||
in_tensors_c[2].shape_[2] = 8;
|
||||
in_tensors_c[2].shape_[3] = 9;
|
||||
in_tensors_c[2].data_type_ = kNumberTypeInt32;
|
||||
// input0->tensors_[2]->format_ = Format_NHWC;
|
||||
inputs[0] = reinterpret_cast<TensorC *>(input0);
|
||||
inputs[0]->data_type_ = kObjectTypeTensorType;
|
||||
|
@ -60,7 +61,7 @@ TEST_F(TensorlistGetItemInferTest, TensorlistGetItemInferTest0) {
|
|||
|
||||
std::vector<TensorC *> outputs(1, NULL);
|
||||
outputs[0] = reinterpret_cast<TensorC *>(malloc(sizeof(TensorC)));
|
||||
OpParameter *parameter = new OpParameter;
|
||||
auto *parameter = new OpParameter;
|
||||
int ret = TensorListGetItemInferShape((const TensorC **)inputs.data(), inputs.size(), outputs.data(), outputs.size(),
|
||||
reinterpret_cast<OpParameter *>(parameter));
|
||||
ASSERT_EQ(ret, NNACL_OK);
|
||||
|
@ -75,11 +76,10 @@ TEST_F(TensorlistGetItemInferTest, TensorlistGetItemInferTest0) {
|
|||
delete parameter;
|
||||
for (size_t i = 0; i < inputs_size; i++) {
|
||||
if (inputs[i]->data_type_ == kObjectTypeTensorType) {
|
||||
TensorListC *tensorListC = reinterpret_cast<TensorListC *>(inputs[i]);
|
||||
lite::FreeTensorListC(tensorListC);
|
||||
} else {
|
||||
free(inputs[i]);
|
||||
auto *tensorList_c = reinterpret_cast<TensorListC *>(inputs[i]);
|
||||
free(*tensorList_c->tensors_);
|
||||
}
|
||||
free(inputs[i]);
|
||||
}
|
||||
for (size_t i = 0; i < outputs.size(); i++) {
|
||||
free(outputs[i]);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "common/common_test.h"
|
||||
#include "src/common/tensor_util.h"
|
||||
#include "nnacl/infer/control/tensorlist_reserve_infer.h"
|
||||
|
||||
namespace mindspore {
|
||||
|
@ -41,11 +42,12 @@ TEST_F(TensorlistReserveInferTest, TensorlistReserveInferTest0) {
|
|||
inputs[1]->data_type_ = kNumberTypeInt32;
|
||||
|
||||
std::vector<TensorC *> outputs(1, NULL);
|
||||
outputs[0] = reinterpret_cast<TensorC *>(new TensorListC);
|
||||
OpParameter *parameter = new OpParameter;
|
||||
auto out = reinterpret_cast<TensorListC *>(malloc(sizeof(TensorListC)));
|
||||
out->tensors_ = nullptr;
|
||||
outputs[0] = reinterpret_cast<TensorC *>(out);
|
||||
auto *parameter = new OpParameter;
|
||||
int ret = TensorListReserveInferShape((const TensorC **)inputs.data(), inputs.size(), outputs.data(), outputs.size(),
|
||||
reinterpret_cast<OpParameter *>(parameter));
|
||||
TensorListC *out = reinterpret_cast<TensorListC *>(outputs[0]);
|
||||
ASSERT_EQ(ret, NNACL_OK);
|
||||
ASSERT_EQ(out->element_num_, 5);
|
||||
ASSERT_EQ(out->data_type_, kObjectTypeTensorType);
|
||||
|
@ -56,15 +58,14 @@ TEST_F(TensorlistReserveInferTest, TensorlistReserveInferTest0) {
|
|||
ASSERT_EQ(out->tensors_data_type_, kTypeUnknown);
|
||||
// ASSERT_EQ(outputs[0]->format_, Format_NHWC);
|
||||
for (size_t i = 0; i < out->element_num_; i++) {
|
||||
ASSERT_EQ(out->tensors_[i].shape_size_, 0);
|
||||
ASSERT_EQ(out->tensors_[i]->shape_size_, 0);
|
||||
}
|
||||
delete parameter;
|
||||
for (size_t i = 0; i < inputs_size; i++) {
|
||||
delete inputs[i];
|
||||
}
|
||||
for (size_t i = 0; i < outputs.size(); i++) {
|
||||
delete outputs[i];
|
||||
}
|
||||
lite::FreeOutTensorC(&outputs);
|
||||
delete out;
|
||||
}
|
||||
|
||||
} // namespace mindspore
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
#include "common/common_test.h"
|
||||
#include "src/common/tensor_util.h"
|
||||
#include "nnacl/infer/control/tensorlist_setitem_infer.h"
|
||||
|
||||
namespace mindspore {
|
||||
|
@ -27,29 +28,30 @@ class TensorlistSetItemInferTest : public mindspore::CommonTest {
|
|||
TEST_F(TensorlistSetItemInferTest, TensorlistSetItemInferTest0) {
|
||||
size_t inputs_size = 3;
|
||||
std::vector<TensorC *> inputs(inputs_size, NULL);
|
||||
TensorListC *input0 = new TensorListC;
|
||||
auto *input0 = new TensorListC;
|
||||
input0->element_num_ = 3;
|
||||
input0->tensors_ = reinterpret_cast<TensorC *>(malloc(input0->element_num_ * sizeof(TensorC)));
|
||||
auto in_tensors_c = reinterpret_cast<TensorC *>(malloc(input0->element_num_ * sizeof(TensorC)));
|
||||
input0->tensors_ = &in_tensors_c;
|
||||
input0->element_shape_size_ = 2;
|
||||
input0->element_shape_[0] = 2;
|
||||
input0->element_shape_[1] = 4;
|
||||
input0->tensors_data_type_ = kNumberTypeInt32;
|
||||
input0->data_type_ = kObjectTypeTensorType;
|
||||
|
||||
input0->tensors_[0].shape_size_ = 2;
|
||||
input0->tensors_[0].shape_[0] = 2;
|
||||
input0->tensors_[0].shape_[1] = 4;
|
||||
input0->tensors_[0].data_type_ = kNumberTypeInt32;
|
||||
in_tensors_c[0].shape_size_ = 2;
|
||||
in_tensors_c[0].shape_[0] = 2;
|
||||
in_tensors_c[0].shape_[1] = 4;
|
||||
in_tensors_c[0].data_type_ = kNumberTypeInt32;
|
||||
|
||||
input0->tensors_[1].shape_size_ = 2;
|
||||
input0->tensors_[1].shape_[0] = 2;
|
||||
input0->tensors_[1].shape_[1] = 4;
|
||||
input0->tensors_[1].data_type_ = kNumberTypeInt32;
|
||||
in_tensors_c[1].shape_size_ = 2;
|
||||
in_tensors_c[1].shape_[0] = 2;
|
||||
in_tensors_c[1].shape_[1] = 4;
|
||||
in_tensors_c[1].data_type_ = kNumberTypeInt32;
|
||||
|
||||
input0->tensors_[2].shape_size_ = 2;
|
||||
input0->tensors_[2].shape_[0] = 2;
|
||||
input0->tensors_[2].shape_[1] = 4;
|
||||
input0->tensors_[2].data_type_ = kNumberTypeInt32;
|
||||
in_tensors_c[2].shape_size_ = 2;
|
||||
in_tensors_c[2].shape_[0] = 2;
|
||||
in_tensors_c[2].shape_[1] = 4;
|
||||
in_tensors_c[2].data_type_ = kNumberTypeInt32;
|
||||
// input0->tensors_[2]->format_ = Format_NHWC;
|
||||
inputs[0] = reinterpret_cast<TensorC *>(input0);
|
||||
|
||||
|
@ -69,11 +71,13 @@ TEST_F(TensorlistSetItemInferTest, TensorlistSetItemInferTest0) {
|
|||
inputs[2]->data_ = inputs2_data.data();
|
||||
|
||||
std::vector<TensorC *> outputs(1, NULL);
|
||||
outputs[0] = reinterpret_cast<TensorC *>(new TensorListC);
|
||||
OpParameter *parameter = new OpParameter;
|
||||
auto out = reinterpret_cast<TensorListC *>(malloc(sizeof(TensorListC)));
|
||||
out->tensors_ = nullptr;
|
||||
outputs[0] = reinterpret_cast<TensorC *>(out);
|
||||
auto *parameter = new OpParameter;
|
||||
int ret = TensorListSetItemInferShape((const TensorC **)inputs.data(), inputs.size(), outputs.data(), outputs.size(),
|
||||
reinterpret_cast<OpParameter *>(parameter));
|
||||
TensorListC *res = reinterpret_cast<TensorListC *>(outputs[0]);
|
||||
auto *res = reinterpret_cast<TensorListC *>(outputs[0]);
|
||||
ASSERT_EQ(ret, NNACL_OK);
|
||||
ASSERT_EQ(res->element_num_, 3);
|
||||
ASSERT_EQ(res->element_shape_size_, 2);
|
||||
|
@ -81,25 +85,28 @@ TEST_F(TensorlistSetItemInferTest, TensorlistSetItemInferTest0) {
|
|||
ASSERT_EQ(res->element_shape_[1], 4);
|
||||
ASSERT_EQ(res->tensors_data_type_, kNumberTypeInt32);
|
||||
ASSERT_EQ(res->data_type_, kObjectTypeTensorType);
|
||||
ASSERT_EQ(res->tensors_[0].shape_size_, 2);
|
||||
ASSERT_EQ(res->tensors_[0].shape_[0], 2);
|
||||
ASSERT_EQ(res->tensors_[0].shape_[1], 4);
|
||||
ASSERT_EQ(res->tensors_[1].shape_size_, 2);
|
||||
ASSERT_EQ(res->tensors_[1].shape_[0], 2);
|
||||
ASSERT_EQ(res->tensors_[1].shape_[1], 4);
|
||||
ASSERT_EQ(res->tensors_[2].shape_size_, 2);
|
||||
ASSERT_EQ(res->tensors_[2].shape_[0], 5);
|
||||
ASSERT_EQ(res->tensors_[2].shape_[1], 6);
|
||||
ASSERT_EQ(res->tensors_[0]->shape_size_, 2);
|
||||
ASSERT_EQ(res->tensors_[0]->shape_[0], 2);
|
||||
ASSERT_EQ(res->tensors_[0]->shape_[1], 4);
|
||||
ASSERT_EQ(res->tensors_[1]->shape_size_, 2);
|
||||
ASSERT_EQ(res->tensors_[1]->shape_[0], 2);
|
||||
ASSERT_EQ(res->tensors_[1]->shape_[1], 4);
|
||||
ASSERT_EQ(res->tensors_[2]->shape_size_, 2);
|
||||
ASSERT_EQ(res->tensors_[2]->shape_[0], 5);
|
||||
ASSERT_EQ(res->tensors_[2]->shape_[1], 6);
|
||||
|
||||
// ASSERT_EQ(outputs[0]->format_, Format_NHWC);
|
||||
|
||||
delete parameter;
|
||||
for (size_t i = 0; i < inputs_size; i++) {
|
||||
if (inputs[i]->data_type_ == kObjectTypeTensorType) {
|
||||
auto *tensorList_c = reinterpret_cast<TensorListC *>(inputs[i]);
|
||||
free(*tensorList_c->tensors_);
|
||||
}
|
||||
delete inputs[i];
|
||||
}
|
||||
for (size_t i = 0; i < outputs.size(); i++) {
|
||||
delete outputs[i];
|
||||
}
|
||||
lite::FreeOutTensorC(&outputs);
|
||||
delete out;
|
||||
}
|
||||
|
||||
// retest mergeshape
|
||||
|
|
|
@ -27,28 +27,29 @@ class TensorlistStackInferTest : public mindspore::CommonTest {
|
|||
TEST_F(TensorlistStackInferTest, TensorlistStackInferTest0) {
|
||||
size_t inputs_size = 2;
|
||||
std::vector<TensorC *> inputs(inputs_size, NULL);
|
||||
TensorListC *input0 = new TensorListC;
|
||||
auto *input0 = new TensorListC;
|
||||
input0->element_num_ = 3;
|
||||
input0->tensors_ = reinterpret_cast<TensorC *>(malloc(input0->element_num_ * sizeof(TensorC)));
|
||||
auto in_tensors_c = reinterpret_cast<TensorC *>(malloc(input0->element_num_ * sizeof(TensorC)));
|
||||
input0->tensors_ = &in_tensors_c;
|
||||
input0->element_shape_size_ = 2;
|
||||
input0->element_shape_[0] = 2;
|
||||
input0->element_shape_[1] = 4;
|
||||
input0->tensors_data_type_ = kNumberTypeInt32;
|
||||
|
||||
input0->tensors_[0].shape_size_ = 2;
|
||||
input0->tensors_[0].shape_[0] = 2;
|
||||
input0->tensors_[0].shape_[1] = 4;
|
||||
input0->tensors_[0].data_type_ = kNumberTypeInt32;
|
||||
in_tensors_c[0].shape_size_ = 2;
|
||||
in_tensors_c[0].shape_[0] = 2;
|
||||
in_tensors_c[0].shape_[1] = 4;
|
||||
in_tensors_c[0].data_type_ = kNumberTypeInt32;
|
||||
|
||||
input0->tensors_[1].shape_size_ = 2;
|
||||
input0->tensors_[1].shape_[0] = 2;
|
||||
input0->tensors_[1].shape_[1] = 4;
|
||||
input0->tensors_[1].data_type_ = kNumberTypeInt32;
|
||||
in_tensors_c[1].shape_size_ = 2;
|
||||
in_tensors_c[1].shape_[0] = 2;
|
||||
in_tensors_c[1].shape_[1] = 4;
|
||||
in_tensors_c[1].data_type_ = kNumberTypeInt32;
|
||||
|
||||
input0->tensors_[2].shape_size_ = 2;
|
||||
input0->tensors_[2].shape_[0] = 2;
|
||||
input0->tensors_[2].shape_[1] = 4;
|
||||
input0->tensors_[2].data_type_ = kNumberTypeInt32;
|
||||
in_tensors_c[2].shape_size_ = 2;
|
||||
in_tensors_c[2].shape_[0] = 2;
|
||||
in_tensors_c[2].shape_[1] = 4;
|
||||
in_tensors_c[2].data_type_ = kNumberTypeInt32;
|
||||
// input0->tensors_[2]->format_ = Format_NHWC;
|
||||
inputs[0] = reinterpret_cast<TensorC *>(input0);
|
||||
inputs[0]->data_type_ = kObjectTypeTensorType;
|
||||
|
@ -61,7 +62,7 @@ TEST_F(TensorlistStackInferTest, TensorlistStackInferTest0) {
|
|||
|
||||
std::vector<TensorC *> outputs(1, NULL);
|
||||
outputs[0] = new TensorC;
|
||||
OpParameter *parameter = new OpParameter;
|
||||
auto *parameter = new OpParameter;
|
||||
int ret = TensorListStackInferShape((const TensorC **)inputs.data(), inputs.size(), outputs.data(), outputs.size(),
|
||||
reinterpret_cast<OpParameter *>(parameter));
|
||||
ASSERT_EQ(ret, NNACL_OK);
|
||||
|
@ -74,6 +75,10 @@ TEST_F(TensorlistStackInferTest, TensorlistStackInferTest0) {
|
|||
|
||||
delete parameter;
|
||||
for (size_t i = 0; i < inputs_size; i++) {
|
||||
if (inputs[i]->data_type_ == kObjectTypeTensorType) {
|
||||
auto *tensorList_c = reinterpret_cast<TensorListC *>(inputs[i]);
|
||||
free(*tensorList_c->tensors_);
|
||||
}
|
||||
delete inputs[i];
|
||||
}
|
||||
for (size_t i = 0; i < outputs.size(); i++) {
|
||||
|
|
|
@ -193,8 +193,8 @@ void NNaclFp32Serializer::CodeArrayStruct(const std::string &name, TensorC *tens
|
|||
int size = tensor.size();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
std::string tensor_name = "tensor" + std::to_string(count++);
|
||||
CodeBaseStruct<false>("TensorC", name, tensor_name, tensorC[i].is_ready_, tensorC[i].data_type_, tensorC[i].format_,
|
||||
tensor[i], tensorC[i].shape_size_, ToString(tensorC[i].shape_));
|
||||
CodeBaseStruct<false>("TensorC", name, tensor_name, tensorC[i].data_type_, tensorC[i].format_, tensor[i],
|
||||
tensorC[i].shape_size_, ToString(tensorC[i].shape_));
|
||||
tensor_names.emplace_back(tensor_name);
|
||||
}
|
||||
code << " TensorC"
|
||||
|
|
|
@ -175,6 +175,7 @@ getCommonFile() {
|
|||
mindspore/lite/experimental/src/exec_env_utils.h
|
||||
mindspore/lite/src/expression/ops_utils.h
|
||||
mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/tensor_c_utils.h
|
||||
mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/tensorlist_c.h
|
||||
mindspore/ccsrc/plugin/device/cpu/kernel/nnacl/tensorlist_c_utils.h
|
||||
mindspore/core/utils/log_adapter.h
|
||||
mindspore/core/ir/api_tensor_impl.h
|
||||
|
|
Loading…
Reference in New Issue