!45751 [lite]optimize inferShape

Merge pull request !45751 from 徐安越/r1.8_1
This commit is contained in:
i-robot 2022-11-22 06:11:52 +00:00 committed by Gitee
commit 4b98342ca1
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
33 changed files with 540 additions and 486 deletions

View File

@ -41,7 +41,7 @@ int TensorListGetItemInferShape(const TensorC *const *inputs, size_t inputs_size
if (index < 0 || index > ((int)(input0->element_num_ - 1))) { if (index < 0 || index > ((int)(input0->element_num_ - 1))) {
return NNACL_ERR; return NNACL_ERR;
} }
TensorC *tensor_index = &input0->tensors_[index]; TensorC *tensor_index = input0->tensors_[index];
NNACL_CHECK_NULL_RETURN_ERR(tensor_index); NNACL_CHECK_NULL_RETURN_ERR(tensor_index);
if (tensor_index->data_type_ != kTypeUnknown) { if (tensor_index->data_type_ != kTypeUnknown) {
@ -49,7 +49,7 @@ int TensorListGetItemInferShape(const TensorC *const *inputs, size_t inputs_size
} else { } else {
output->data_type_ = input0->tensors_data_type_; output->data_type_ = input0->tensors_data_type_;
} }
output->format_ = input0->tensors_[index].format_; output->format_ = input0->tensors_[index]->format_;
if (!InferFlag(inputs, inputs_size)) { if (!InferFlag(inputs, inputs_size)) {
return NNACL_INFER_INVALID; 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)) { if (!TensorListIsFullyDefined(element_shape, element_shape_size)) {
for (size_t i = 0; i < input0->element_num_; ++i) { 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); NNACL_CHECK_NULL_RETURN_ERR(input);
if (input->data_type_ != kTypeUnknown) { if (input->data_type_ != kTypeUnknown) {
status = TensorListMergeShape(element_shape, &element_shape_size, input->shape_, input->shape_size_); status = TensorListMergeShape(element_shape, &element_shape_size, input->shape_, input->shape_size_);

View File

@ -90,7 +90,7 @@ int TensorListSetItemInferShape(const TensorC *const *inputs, size_t inputs_size
} else { } else {
output0->element_num_ = input0->element_num_; output0->element_num_ = input0->element_num_;
for (size_t i = 0; i < input0->element_num_; ++i) { 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) { if (src_ptr == NULL) {
free(out_shape.shape_); free(out_shape.shape_);
free(out_shape.shape_size_); free(out_shape.shape_size_);

View File

@ -72,7 +72,7 @@ int TensorListStackInferShape(const TensorC *const *inputs, size_t inputs_size,
} }
if (!TensorListIsFullyDefined(input0->element_shape_, input0->element_shape_size_)) { if (!TensorListIsFullyDefined(input0->element_shape_, input0->element_shape_size_)) {
for (size_t i = 0; i < input0->element_num_; ++i) { 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) { if (tensor_ele->data_type_ != kTypeUnknown) {
status = TensorListMergeShape(output_shape, &output_shape_size, tensor_ele->shape_, tensor_ele->shape_size_); status = TensorListMergeShape(output_shape, &output_shape_size, tensor_ele->shape_, tensor_ele->shape_size_);
if (status == NNACL_ERR) { if (status == NNACL_ERR) {

View File

@ -73,6 +73,12 @@ int SetShape(const TensorC *const *inputs, size_t inputs_size, TensorC **outputs
int b_shape[MAX_SHAPE_SIZE] = {0}; int b_shape[MAX_SHAPE_SIZE] = {0};
size_t b_shape_size = 0; size_t b_shape_size = 0;
ShapeSet(b_shape, &b_shape_size, input1->shape_, input1->shape_size_); 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}; int bias_shape[MAX_AXIS_SIZE] = {0};
size_t bias_shape_size = 0; size_t bias_shape_size = 0;
if (inputs_size == kInputSize2) { 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) { if (a_shape_size == COMM_SHAPE_SIZE && a_shape[THIRD_INPUT] == 1 && a_shape[FOURTH_INPUT] == 1) {
a_shape_size = 2; a_shape_size = 2;
SetShapeArray(input0, a_shape, a_shape_size);
} }
bool del_start = false; 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) { if (insert_ret != NNACL_OK) {
return NNACL_ERR; return NNACL_ERR;
} }
SetShapeArray(input0, a_shape, a_shape_size);
del_start = true; del_start = true;
} }
if (b_shape_size == 1) { if (b_shape_size == 1) {
ShapePush(b_shape, &b_shape_size, 1); ShapePush(b_shape, &b_shape_size, 1);
SetShapeArray(input1, b_shape, b_shape_size);
del_end = true; del_end = true;
} }
int ret = CheckMatmulInputShape(a_shape, a_shape_size, b_shape, b_shape_size, bias_shape, bias_shape_size, param); 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 *input1 = (TensorC *)inputs[1];
TensorC *output = outputs[0]; 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. TensorC *input = input1->data_ == NULL ? input1 : input0; // transfer the input which comes from the other node.
SetDataTypeFormat(output, input); SetDataTypeFormat(output, input);
if (parameter->quant_type_ == QuantType_QUANT_DYNAMIC || parameter->quant_type_ == QuantType_QUANT_WEIGHT) { if (parameter->quant_type_ == QuantType_QUANT_DYNAMIC || parameter->quant_type_ == QuantType_QUANT_WEIGHT) {

View File

@ -28,6 +28,8 @@ int ShapeFusionInferShape(const TensorC *const *inputs, size_t inputs_size, Tens
size_t input_len = in_tensor->shape_size_ + 1; size_t input_len = in_tensor->shape_size_ + 1;
for (size_t out_idx = 0; out_idx < outputs_size; out_idx++) { for (size_t out_idx = 0; out_idx < outputs_size; out_idx++) {
TensorC *out_tensor = outputs[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->data_type_ = kNumberTypeInt32;
out_tensor->format_ = in_tensor->format_; out_tensor->format_ = in_tensor->format_;
if (!InferFlag(inputs, inputs_size)) { 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]); out_tensor->shape_[0] = (int)(matrix_tensor->shape_[0]);
} }
int out_size = out_tensor->shape_size_ == 0 ? 1 : out_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); size_t matrix_data_size = input_len * out_size * sizeof(float);
float *matrix_data = (float *)(malloc(matrix_data_size)); float *matrix_data = (float *)(malloc(matrix_data_size));
NNACL_CHECK_NULL_RETURN_ERR(matrix_data); 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); free(matrix_data);
return NNACL_ERR; 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) { if (data == NULL) {
free(matrix_data); free(matrix_data);
return NNACL_ERR; 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]; data[i] += matrix_data[i * input_len + input_len - 1];
} }
outputs[out_idx]->data_ = (void *)data;
free(matrix_data); free(matrix_data);
} }
return NNACL_OK; return NNACL_OK;

View File

@ -20,13 +20,11 @@
typedef enum TensorCFormat { NCHW, NHWC, NC4HW4, NUM_OF_FORMAT } TensorCFormat; typedef enum TensorCFormat { NCHW, NHWC, NC4HW4, NUM_OF_FORMAT } TensorCFormat;
typedef struct TensorC { typedef struct TensorC {
bool is_ready_;
int data_type_; int data_type_;
int format_; int format_;
void *data_; void *data_;
size_t shape_size_; size_t shape_size_;
int shape_[MAX_SHAPE_SIZE]; int shape_[MAX_SHAPE_SIZE];
char *name_;
} TensorC; } TensorC;
#endif // MINDSPORE_NNACL_TENSOR_C_H_ #endif // MINDSPORE_NNACL_TENSOR_C_H_

View File

@ -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_

View File

@ -28,16 +28,21 @@ int MallocTensorListData(TensorListC *tensor_list, TypeIdC dtype, const vvector
return NNACL_ERR; return NNACL_ERR;
} }
tensor_list->tensors_data_type_ = dtype; tensor_list->tensors_data_type_ = dtype;
tensor_list->tensors_ = (TensorC *)malloc(tensor_list->element_num_ * sizeof(TensorC)); // free in infer_manager void *addr = malloc(tensor_list->element_num_ * sizeof(void *) +
if (tensor_list->tensors_ == NULL) { tensor_list->element_num_ * sizeof(TensorC)); // free in infer_manager
if (addr == NULL) {
free(tensor_list->tensors_);
return NNACL_NULL_PTR; 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) { for (size_t i = 0; i < tensor_list->element_num_; ++i) {
tensor_list->tensors_[i].format_ = Format_NHWC; TensorC *tensor = tensors + i;
tensor_list->tensors_[i].data_type_ = dtype; tensor_list->tensors_[i] = tensor;
ShapeSet(tensor_list->tensors_[i].shape_, &(tensor_list->tensors_[i].shape_size_), tensor_shape->shape_[i], tensor->format_ = Format_NHWC;
(size_t)tensor_shape->shape_size_[i]); tensor->data_type_ = dtype;
ShapeSet(tensor->shape_, &(tensor->shape_size_), tensor_shape->shape_[i], (size_t)tensor_shape->shape_size_[i]);
} }
return NNACL_OK; return NNACL_OK;
} }

View File

@ -14,38 +14,19 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef MINDSPORE_NNACL_TENSORLISTC_UTILS_H_ #ifndef MINDSPORE_NNACL_TENSORLIST_C_UTILS_H_
#define MINDSPORE_NNACL_TENSORLISTC_UTILS_H_ #define MINDSPORE_NNACL_TENSORLIST_C_UTILS_H_
#include <stddef.h> #include <stddef.h>
#include "nnacl/errorcode.h" #include "nnacl/errorcode.h"
#include "nnacl/op_base.h" #include "nnacl/op_base.h"
#include "nnacl/tensor_c.h" #include "nnacl/tensorlist_c.h"
#include "nnacl/infer/common_infer.h" #include "nnacl/infer/common_infer.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #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 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); 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); bool TensorListIsFullyDefined(const int *shape, size_t shape_size);
@ -55,4 +36,4 @@ bool InferFlagTensorList(TensorC *tensor_list);
} }
#endif #endif
#endif // MINDSPORE_NNACL_TENSORLISTC_UTILS_H_ #endif // MINDSPORE_NNACL_TENSORLIST_C_UTILS_H_

View File

@ -107,6 +107,7 @@ if(MSLITE_MINDDATA_IMPLEMENT STREQUAL "full")
include_directories("${MINDDATA_DIR}/kernels/image") include_directories("${MINDDATA_DIR}/kernels/image")
include_directories("${MINDDATA_DIR}/liteapi") include_directories("${MINDDATA_DIR}/liteapi")
include_directories("${TOP_DIR}") include_directories("${TOP_DIR}")
include_directories("${TOP_DIR}/mindspore/ccsrc/plugin/device/cpu/kernel")
set(MINDDATA_FULL_SRC set(MINDDATA_FULL_SRC
${TOP_DIR}/mindspore/lite/src/runtime/cxx_api/types.cc ${TOP_DIR}/mindspore/lite/src/runtime/cxx_api/types.cc

View File

@ -26,30 +26,7 @@
#endif #endif
namespace mindspore { namespace mindspore {
namespace lite { namespace lite {
int OutputTensor2TensorC(const std::vector<lite::Tensor *> &tensors, std::vector<TensorC *> *tensors_c, void FreeInTensorC(std::vector<TensorC *> *tensors_in, const std::shared_ptr<Allocator> &allocator) {
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) {
if (tensors_in == nullptr) { if (tensors_in == nullptr) {
return; return;
} }
@ -58,24 +35,46 @@ void FreeAllTensorC(std::vector<TensorC *> *tensors_in, std::shared_ptr<Allocato
continue; continue;
} }
if (i->data_type_ == kObjectTypeTensorType) { if (i->data_type_ == kObjectTypeTensorType) {
TensorListC *tensorListC = reinterpret_cast<TensorListC *>(i); auto *tensorListC = reinterpret_cast<TensorListC *>(i);
FreeTensorListC(tensorListC, allocator); if (tensorListC->tensors_ != nullptr) {
tensorListC = nullptr; if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
} else { allocator->Free(tensorListC->tensors_);
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) { } else {
allocator->Free(i); free(tensorListC->tensors_);
} else { }
free(i); tensorListC->tensors_ = nullptr;
} }
i = nullptr;
} }
} }
tensors_in->clear(); 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) { int Tensor2TensorC(const Tensor *src, TensorC *dst) {
MS_CHECK_TRUE_RET(src != nullptr && dst != nullptr, RET_ERROR); MS_CHECK_TRUE_RET(src != nullptr && dst != nullptr, RET_ERROR);
dst->is_ready_ = src->IsReady();
dst->format_ = static_cast<int>(src->format()); dst->format_ = static_cast<int>(src->format());
dst->data_ = src->data(); dst->data_ = src->data();
dst->data_type_ = src->data_type(); dst->data_type_ = src->data_type();
@ -90,7 +89,7 @@ int Tensor2TensorC(const Tensor *src, TensorC *dst) {
return RET_OK; 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); MS_CHECK_TRUE_RET(src != nullptr && dst != nullptr, RET_ERROR);
dst->set_format(static_cast<mindspore::Format>(src->format_)); 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 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) { if (src->data_ != nullptr) {
auto data = dst->MutableData(); auto data = dst->MutableData();
MS_CHECK_TRUE_RET(data != nullptr, RET_ERROR); MS_CHECK_TRUE_RET(data != nullptr, RET_ERROR);
memcpy(data, src->data_, dst->Size()); if (data == src->data_) { // tensor
dst->set_category(CONST_TENSOR); dst->set_own_data(true);
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) { dst->set_category(CONST_TENSOR);
allocator->Free(src->data_); return RET_OK;
} else {
free(src->data_);
} }
memcpy(data, src->data_, dst->Size()); // tensor_list
dst->set_category(CONST_TENSOR);
} }
return RET_OK; return RET_OK;
} }
int GenerateOutTensorC(const OpParameter *const parameter, const std::vector<lite::Tensor *> &outputs, 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); MS_CHECK_TRUE_RET(out_tensor_c != nullptr && parameter != nullptr, RET_ERROR);
if (parameter->type_ == mindspore::schema::PrimitiveType_TensorListFromTensor || if (parameter->type_ == mindspore::schema::PrimitiveType_TensorListFromTensor ||
parameter->type_ == mindspore::schema::PrimitiveType_TensorListReserve || parameter->type_ == mindspore::schema::PrimitiveType_TensorListReserve ||
parameter->type_ == mindspore::schema::PrimitiveType_TensorListSetItem) { parameter->type_ == mindspore::schema::PrimitiveType_TensorListSetItem) {
#ifndef CONTROLFLOW_TENSORLIST_CLIP
// TensorListC ->TensorC // TensorListC ->TensorC
MS_CHECK_TRUE_RET(!outputs.empty() && outputs.front()->data_type() == TypeId::kObjectTypeTensorType, RET_ERROR); MS_CHECK_TRUE_RET(!outputs.empty() && outputs.front()->data_type() == TypeId::kObjectTypeTensorType, RET_ERROR);
TensorListC *tensor_list_c = nullptr; auto output = static_cast<TensorList *>(outputs[0]);
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) { TensorListC *tensor_list_c = output->ConvertToTensorListC();
tensor_list_c = reinterpret_cast<TensorListC *>(allocator->Malloc(sizeof(TensorListC))); tensor_list_c->element_num_ = 0;
} 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));
out_tensor_c->push_back(reinterpret_cast<TensorC *const>(tensor_list_c)); out_tensor_c->push_back(reinterpret_cast<TensorC *const>(tensor_list_c));
return RET_OK; #else
return RET_NOT_SUPPORT;
#endif
} else { } 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, 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); MS_CHECK_TRUE_RET(in_tensor_c != nullptr, RET_ERROR);
int ret = RET_OK; int ret = RET_OK;
for (auto input : inputs) { for (auto input : inputs) {
if (input->data_type() == kObjectTypeTensorType) { if (input->data_type() == kObjectTypeTensorType) {
#ifndef CONTROLFLOW_TENSORLIST_CLIP
// Tensor ->TensorList -> TensorListC -> TensorC // Tensor ->TensorList -> TensorListC -> TensorC
auto *tensor_list = reinterpret_cast<TensorList *>(input); auto *tensor_list = reinterpret_cast<TensorList *>(input);
TensorListC *tensor_list_c = nullptr; TensorListC *tensor_list_c = tensor_list->ConvertToTensorListC();
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) { auto tensors = tensor_list->tensors();
tensor_list_c = reinterpret_cast<TensorListC *>(allocator->Malloc(sizeof(TensorListC))); if (!tensors.empty()) {
} 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) {
if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) { if (allocator != nullptr && !IS_RUNTIME_ALLOCATOR(allocator)) {
allocator->Free(tensor_list_c->tensors_); tensor_list_c->tensors_ = reinterpret_cast<TensorC **>(allocator->Malloc(tensors.size() * sizeof(void *)));
allocator->Free(tensor_list_c);
} else { } else {
free(tensor_list_c->tensors_); tensor_list_c->tensors_ = reinterpret_cast<TensorC **>(malloc(tensors.size() * sizeof(void *)));
free(tensor_list_c); }
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)); in_tensor_c->push_back(reinterpret_cast<TensorC *>(tensor_list_c));
#else
return RET_NOT_SUPPORT;
#endif
} else { } else {
// Tensor -> TensorC // Tensor -> TensorC
TensorC *tensor_c = nullptr; TensorC *tensor_c = input->ConvertToTensorC();
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;
}
in_tensor_c->emplace_back(tensor_c); 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_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(); src_tensor->DecRefCount();
} }
@ -445,10 +421,14 @@ void MoveTensorListTensorData(TensorList *dst_tensorlist, TensorList *src_tensor
auto &src_tensor = src_tensorlist->tensors()[i]; auto &src_tensor = src_tensorlist->tensors()[i];
auto &dst_tensor = dst_tensorlist->tensors()[i]; auto &dst_tensor = dst_tensorlist->tensors()[i];
dst_tensor->set_own_data(src_tensor->own_data());
if (src_tensor->data() != nullptr) { if (src_tensor->data() != nullptr) {
dst_tensor->set_data(src_tensor->MutableData()); /* using MutableData to sync GPU data */ 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()); 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()); 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) { int TensorListC2TensorList(const TensorListC *src, TensorList *dst) {
MS_CHECK_TRUE_RET(src != nullptr && dst != nullptr, RET_ERROR); MS_CHECK_TRUE_RET(src != nullptr && dst != nullptr, RET_ERROR);
dst->set_data_type(static_cast<TypeId>(src->data_type_)); dst->set_data_type(static_cast<TypeId>(src->data_type_));
dst->set_format(static_cast<mindspore::Format>(src->format_)); dst->set_format(static_cast<mindspore::Format>(src->format_));
dst->set_shape(std::vector<int>(1, src->element_num_)); dst->set_shape(std::vector<int>(1, src->element_num_));
dst->set_tensors_data_type(static_cast<TypeId>(src->tensors_data_type_));
// Set Tensors // Set Tensors
for (size_t i = 0; i < src->element_num_; i++) { 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) { if (ret != RET_OK) {
MS_LOG(ERROR) << "TensorC2Tensor failed"; MS_LOG(ERROR) << "TensorC2Tensor failed";
return ret; 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; return RET_OK;
} }
@ -562,7 +482,7 @@ TensorList *MallocTensorListDataAccordingToTensorListC(Tensor *tensor, TensorLis
auto tensor_shape = std::vector<std::vector<int>>( 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_num_, std::vector<int>(tensor_list_c->element_shape_,
tensor_list_c->element_shape_ + tensor_list_c->element_shape_size_)); 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; return tensor_list;
} }
@ -657,11 +577,6 @@ void FreeTensorListC(TensorListC *tensorlist_c, std::shared_ptr<Allocator> alloc
return; 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) { int TensorListC2TensorList(const TensorListC *src, TensorList *dst) {
MS_LOG(ERROR) << unsupport_controlflow_tensorlist_log; MS_LOG(ERROR) << unsupport_controlflow_tensorlist_log;
return RET_ERROR; return RET_ERROR;

View File

@ -29,18 +29,15 @@
namespace mindspore { namespace mindspore {
namespace lite { namespace lite {
int OutputTensor2TensorC(const std::vector<lite::Tensor *> &tensors, std::vector<TensorC *> *tensors_c, void FreeInTensorC(std::vector<TensorC *> *tensors_in, const std::shared_ptr<Allocator> &allocator = nullptr);
std::shared_ptr<Allocator> allocator = nullptr); void FreeOutTensorC(std::vector<TensorC *> *tensors_in, const std::shared_ptr<Allocator> &allocator = nullptr);
void FreeAllTensorC(std::vector<TensorC *> *tensors_in, std::shared_ptr<Allocator> allocator = nullptr);
int Tensor2TensorC(const Tensor *src, TensorC *dst); int Tensor2TensorC(const Tensor *src, TensorC *dst);
int TensorC2Tensor(const TensorC *src, Tensor *dst, std::shared_ptr<Allocator> allocator = nullptr); int TensorC2Tensor(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 TensorListC2TensorList(const TensorListC *src, TensorList *dst); int TensorListC2TensorList(const TensorListC *src, TensorList *dst);
int GenerateInTensorC(const std::vector<lite::Tensor *> &inputs, std::vector<TensorC *> *in_tensor_c, 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, 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 CheckTensorsInvalid(const std::vector<Tensor *> &tensors);
int CheckGraphInputShapes(const std::vector<Tensor *> &inputs, int CheckGraphInputShapes(const std::vector<Tensor *> &inputs,
const std::unordered_map<Tensor *, std::vector<int>> &input_shape_map); const std::unordered_map<Tensor *, std::vector<int>> &input_shape_map);

View File

@ -146,25 +146,25 @@ int KernelInferShape(const std::vector<lite::Tensor *> &inputs, const std::vecto
int ret = GenerateInTensorC(inputs, &in_tensors, allocator); int ret = GenerateInTensorC(inputs, &in_tensors, allocator);
if (ret != RET_OK) { if (ret != RET_OK) {
FreeAllTensorC(&in_tensors, allocator); FreeInTensorC(&in_tensors, allocator);
return RET_ERROR; return RET_ERROR;
} }
ret = GenerateOutTensorC(parameter, outputs, &out_tensors, allocator); ret = GenerateOutTensorC(parameter, outputs, &out_tensors);
if (ret != RET_OK) { if (ret != RET_OK) {
FreeAllTensorC(&in_tensors, allocator); FreeInTensorC(&in_tensors, allocator);
FreeAllTensorC(&out_tensors, allocator); FreeOutTensorC(&out_tensors, allocator);
return RET_ERROR; return RET_ERROR;
} }
auto infer_shape_func = GetInferFunc(parameter->type_); auto infer_shape_func = GetInferFunc(parameter->type_);
if (infer_shape_func == nullptr) { if (infer_shape_func == nullptr) {
MS_LOG(ERROR) << "Get infershape func failed! type:" << PrimitiveCurVersionTypeName(parameter->type_); MS_LOG(ERROR) << "Get infershape func failed! type:" << PrimitiveCurVersionTypeName(parameter->type_);
FreeAllTensorC(&in_tensors, allocator); FreeInTensorC(&in_tensors, allocator);
FreeAllTensorC(&out_tensors, allocator); FreeOutTensorC(&out_tensors, allocator);
return RET_ERROR; return RET_ERROR;
} }
ret = infer_shape_func(static_cast<TensorC **>(in_tensors.data()), in_tensors.size(), out_tensors.data(), ret = infer_shape_func(static_cast<TensorC **>(in_tensors.data()), in_tensors.size(), out_tensors.data(),
out_tensors.size(), parameter); out_tensors.size(), parameter);
FreeAllTensorC(&in_tensors, allocator); FreeInTensorC(&in_tensors, allocator);
for (size_t i = 0; i < out_tensors.size(); i++) { for (size_t i = 0; i < out_tensors.size(); i++) {
if (out_tensors.at(i) == nullptr) { if (out_tensors.at(i) == nullptr) {
continue; 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); auto tensor_list = MallocTensorListDataAccordingToTensorListC(outputs.at(i), tensor_list_c);
if (tensor_list == nullptr) { if (tensor_list == nullptr) {
MS_LOG(ERROR) << "get as tensorlist failed"; MS_LOG(ERROR) << "get as tensorlist failed";
FreeAllTensorC(&out_tensors, allocator); FreeOutTensorC(&out_tensors, allocator);
return RET_ERROR; return RET_ERROR;
} }
auto tensor_ret = TensorListC2TensorList(tensor_list_c, tensor_list); auto tensor_ret = TensorListC2TensorList(tensor_list_c, tensor_list);
if (tensor_ret != RET_OK) { if (tensor_ret != RET_OK) {
MS_LOG(ERROR) << "TensorCList2TensorList failed"; MS_LOG(ERROR) << "TensorCList2TensorList failed";
FreeAllTensorC(&out_tensors, allocator); FreeOutTensorC(&out_tensors, allocator);
return tensor_ret; return tensor_ret;
} }
} else { } else {
auto tensor_ret = TensorC2Tensor(out_tensors.at(i), outputs.at(i), allocator); if (out_tensors.at(i)->data_ != nullptr) {
if (tensor_ret != RET_OK) { outputs.at(i)->set_own_data(true);
MS_LOG(ERROR) << "TensorC2Tensor failed"; outputs.at(i)->set_category(CONST_TENSOR);
FreeAllTensorC(&out_tensors, allocator);
return tensor_ret;
} }
} }
@ -196,7 +194,7 @@ int KernelInferShape(const std::vector<lite::Tensor *> &inputs, const std::vecto
outputs.at(i)->set_shape({-1}); outputs.at(i)->set_shape({-1});
} }
} }
FreeAllTensorC(&out_tensors, allocator); FreeOutTensorC(&out_tensors, allocator);
return CheckInfershapeResult(ret, inputs, outputs, parameter); return CheckInfershapeResult(ret, inputs, outputs, parameter);
} }

View File

@ -215,7 +215,11 @@ int ReduceBaseCPUKernel::CopyInputToOutput() {
out_tensor->FreeData(); out_tensor->FreeData();
out_tensor->ResetRefCount(); out_tensor->ResetRefCount();
out_tensor->set_data(in_tensor->data()); 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; return RET_OK;
} }
} // namespace mindspore::kernel } // namespace mindspore::kernel

View File

@ -88,7 +88,11 @@ int ReshapeBaseCPUKernel::Run() {
out_tensor->FreeData(); out_tensor->FreeData();
out_tensor->ResetRefCount(); out_tensor->ResetRefCount();
out_tensor->set_data(in_tensor->data()); 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; return RET_OK;
} }

View File

@ -286,7 +286,11 @@ int StridedSliceCPUKernel::SoftCopyInputToOutput() {
output_tensor->FreeData(); output_tensor->FreeData();
output_tensor->ResetRefCount(); output_tensor->ResetRefCount();
output_tensor->set_data(input_tensor->data()); 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; return RET_OK;
} }

View File

@ -227,7 +227,11 @@ int TransposeBaseCPUKernel::CopyInputToOutput() {
out_tensor->FreeData(); out_tensor->FreeData();
out_tensor->ResetRefCount(); out_tensor->ResetRefCount();
out_tensor->set_data(in_tensor->data()); 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; return RET_OK;
} }

View File

@ -147,7 +147,7 @@ int ScatterNdUpdateCPUKernel::Run() {
auto in_tensor = in_tensors().front(); auto in_tensor = in_tensors().front();
auto out_tensor = out_tensors().front(); auto out_tensor = out_tensors().front();
if (in_tensor->allocator() == nullptr || in_tensor->allocator() != out_tensor->allocator() || 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()); memcpy(out_tensor->data(), in_tensor->data(), in_tensor->Size());
} else { } else {
out_tensor->FreeData(); out_tensor->FreeData();

View File

@ -1388,7 +1388,7 @@ void LiteSession::RuntimeAllocatorInitSubgraph() {
for (auto kernel : kernel_list) { for (auto kernel : kernel_list) {
/* malloc for output */ /* malloc for output */
for (auto tensor : kernel->out_tensors()) { for (auto tensor : kernel->out_tensors()) {
if (tensor->allocator() != default_allocator) { if (tensor->allocator() != default_allocator || tensor->IsConst()) {
continue; continue;
} }
tensor->set_allocator(runtime_allocator_); tensor->set_allocator(runtime_allocator_);

View File

@ -266,7 +266,7 @@ int MindrtExecutor::TransferGraphOutput() {
} }
if (src_tensor->allocator() != nullptr) { if (src_tensor->allocator() != nullptr) {
dst_tensor->set_data(src_tensor->data()); 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 { } else {
dst_tensor->set_data(src_tensor->data()); dst_tensor->set_data(src_tensor->data());
src_tensor->set_data(nullptr); src_tensor->set_data(nullptr);

View File

@ -114,11 +114,28 @@ class ShapeFusionPass {
[&](uint32_t idx) { return this->src_tensors_->at(idx); }); [&](uint32_t idx) { return this->src_tensors_->at(idx); });
#endif #endif
} }
void FreeOutputTensorDataOfFusedShape() {
#if !defined(RUNTIME_PASS_CLIP) void StoreStateAndReset() {
for (auto tensor : shape_fusion_outputs_) { #ifndef RUNTIME_PASS_CLIP
tensor->FreeData(); std::vector<lite::Tensor *> shape_fusion_outputs = shape_fusion_outputs_;
tensor->set_category(VAR); 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 #endif
} }
@ -141,6 +158,7 @@ class ShapeFusionPass {
private: private:
std::map<uint32_t, ShapeFusionMatrix> shape_fusion_matrices_; std::map<uint32_t, ShapeFusionMatrix> shape_fusion_matrices_;
std::vector<lite::Tensor *> shape_fusion_outputs_; std::vector<lite::Tensor *> shape_fusion_outputs_;
std::vector<void *> datas_;
#endif #endif
InnerContext *context_ = nullptr; InnerContext *context_ = nullptr;
LiteModel *lite_model_ = nullptr; LiteModel *lite_model_ = nullptr;

View File

@ -238,6 +238,10 @@ int Scheduler::InitKernels(std::vector<kernel::KernelExec *> &&dst_kernels) {
for (auto node : subgraph_nodes) { for (auto node : subgraph_nodes) {
for (auto *tensor : node->out_tensors()) { for (auto *tensor : node->out_tensors()) {
if (tensor->IsConst()) { 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(); MS_LOG(ERROR) << "Illegitimate kernel output tensor : " << tensor->tensor_name();
continue; continue;
} }
@ -460,8 +464,7 @@ int Scheduler::Schedule(std::vector<kernel::KernelExec *> *dst_kernels) {
return ret; return ret;
} }
} }
shape_fusion_pass_->FreeOutputTensorDataOfFusedShape(); shape_fusion_pass_->StoreStateAndReset();
ret = InitDelegateKernels(dst_kernels); ret = InitDelegateKernels(dst_kernels);
if (ret != RET_OK) { if (ret != RET_OK) {
MS_LOG(ERROR) << "Repalce delegate kernels failed."; 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."; MS_LOG(ERROR) << "InitKernels failed.";
return ret; return ret;
} }
shape_fusion_pass_->RestoreState();
if (IsPrintDebug()) { if (IsPrintDebug()) {
MS_LOG(DEBUG) << "schedule kernels success."; MS_LOG(DEBUG) << "schedule kernels success.";
for (auto subgraph : *dst_kernels) { for (auto subgraph : *dst_kernels) {

View File

@ -45,14 +45,24 @@ static const size_t max_malloc_size_ = GetMaxMallocSize();
#endif #endif
Tensor::Tensor(const TypeId data_type, std::vector<int> shape, const mindspore::Format &format, Category category) 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) { int Tensor::CopyTensorData(const Tensor &src_tensor, Tensor *dst_tensor) {
if (dst_tensor == nullptr) { if (dst_tensor == nullptr) {
MS_LOG(ERROR) << "dst_tensor is nullptr"; MS_LOG(ERROR) << "dst_tensor is nullptr";
return RET_PARAM_INVALID; 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"; MS_LOG(INFO) << "data of src tensor is nullptr";
return RET_OK; return RET_OK;
} }
@ -66,7 +76,7 @@ int Tensor::CopyTensorData(const Tensor &src_tensor, Tensor *dst_tensor) {
return RET_ERROR; return RET_ERROR;
} }
dst_tensor->ResetRefCount(); 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; return RET_OK;
} }
@ -76,10 +86,9 @@ Tensor *Tensor::CopyTensor(const Tensor &src_tensor, bool copy_data, AllocatorPt
MS_LOG(ERROR) << "New tensor failed"; MS_LOG(ERROR) << "New tensor failed";
return nullptr; return nullptr;
} }
result->data_type_ = src_tensor.data_type_; (void)memcpy(&result->tensor_c_, &src_tensor.tensor_c_, sizeof(TensorC));
result->shape_ = src_tensor.shape_; result->tensor_c_.data_ = nullptr;
result->category_ = src_tensor.category_; result->category_ = src_tensor.category_;
result->format_ = src_tensor.format_;
result->set_allocator(allocator); result->set_allocator(allocator);
result->set_tensor_name(src_tensor.tensor_name() + "_duplicate"); result->set_tensor_name(src_tensor.tensor_name() + "_duplicate");
if (copy_data) { if (copy_data) {
@ -101,20 +110,22 @@ Tensor *Tensor::CopyTensor(const Tensor &src_tensor, bool copy_data, AllocatorPt
Tensor::~Tensor() { Tensor::~Tensor() {
FreeData(); FreeData();
this->data_ = nullptr; this->tensor_c_.data_ = nullptr;
} }
bool Tensor::operator==(const Tensor &tensor) { 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 { int32_t Tensor::Batch() const {
// Only 2D or 4D tensors have valid batch. // Only 2D or 4D tensors have valid batch.
if (this->shape_.size() != 4 && this->shape_.size() != 2) { if (this->tensor_c_.shape_size_ != C4NUM && this->tensor_c_.shape_size_ != C2NUM) {
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->shape().size(); MS_LOG(ERROR) << "Unsupported tensor shape: " << this->tensor_c_.shape_size_;
return RET_ERROR; return RET_ERROR;
} }
switch (this->format_) { switch (this->tensor_c_.format_) {
case mindspore::NHWC: case mindspore::NHWC:
case mindspore::NHWC4: case mindspore::NHWC4:
case mindspore::NCHW: case mindspore::NCHW:
@ -124,56 +135,56 @@ int32_t Tensor::Batch() const {
case mindspore::KHWC: case mindspore::KHWC:
case mindspore::NC: case mindspore::NC:
case mindspore::NC4: case mindspore::NC4:
return this->shape_[0]; return this->tensor_c_.shape_[0];
case mindspore::HWCK: case mindspore::HWCK:
case mindspore::CHWK: case mindspore::CHWK:
if (this->shape_.size() != 4) { if (this->tensor_c_.shape_size_ != C4NUM) {
return RET_ERROR; return RET_ERROR;
} }
return this->shape_[3]; return this->tensor_c_.shape_[C3NUM];
case mindspore::HWKC: case mindspore::HWKC:
if (this->shape_.size() != 4) { if (this->tensor_c_.shape_size_ != C4NUM) {
return RET_ERROR; return RET_ERROR;
} }
return this->shape_[2]; return this->tensor_c_.shape_[C2NUM];
case mindspore::CKHW: case mindspore::CKHW:
return this->shape_[1]; return this->tensor_c_.shape_[1];
default: 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; return RET_ERROR;
} }
} }
int32_t Tensor::Channel() const { int32_t Tensor::Channel() const {
// Only 2D or 4D tensors have valid channel. // Only 2D or 4D tensors have valid channel.
if (this->shape_.size() != 4 && this->shape_.size() != 2) { if (this->tensor_c_.shape_size_ != C4NUM && this->tensor_c_.shape_size_ != C2NUM) {
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->shape().size(); MS_LOG(ERROR) << "Unsupported tensor shape: " << this->tensor_c_.shape_size_;
return RET_ERROR; return RET_ERROR;
} }
switch (this->format_) { switch (this->tensor_c_.format_) {
case mindspore::NCHW: case mindspore::NCHW:
case mindspore::KCHW: case mindspore::KCHW:
case mindspore::NC: case mindspore::NC:
case mindspore::NC4: case mindspore::NC4:
case mindspore::NC4HW4: case mindspore::NC4HW4:
case mindspore::NC8HW8: case mindspore::NC8HW8:
return this->shape_[1]; return this->tensor_c_.shape_[1];
case mindspore::HWCK: case mindspore::HWCK:
if (this->shape_.size() != 4) { if (this->tensor_c_.shape_size_ != C4NUM) {
return RET_ERROR; return RET_ERROR;
} }
return this->shape_[2]; return this->tensor_c_.shape_[C2NUM];
case mindspore::HWKC: case mindspore::HWKC:
case mindspore::NHWC: case mindspore::NHWC:
case mindspore::NHWC4: case mindspore::NHWC4:
case mindspore::KHWC: case mindspore::KHWC:
if (this->shape_.size() != 4) { if (this->tensor_c_.shape_size_ != C4NUM) {
return RET_ERROR; return RET_ERROR;
} }
return this->shape_[3]; return this->tensor_c_.shape_[C3NUM];
case mindspore::CKHW: case mindspore::CKHW:
case mindspore::CHWK: case mindspore::CHWK:
return this->shape_[0]; return this->tensor_c_.shape_[0];
default: default:
return RET_ERROR; return RET_ERROR;
} }
@ -181,79 +192,81 @@ int32_t Tensor::Channel() const {
int32_t Tensor::Height() const { int32_t Tensor::Height() const {
// Only 2D or 4D tensors have valid height. // Only 2D or 4D tensors have valid height.
if (this->shape_.size() != 4 && this->shape_.size() != 2) { if (this->tensor_c_.shape_size_ != C4NUM && this->tensor_c_.shape_size_ != C2NUM) {
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->shape().size(); MS_LOG(ERROR) << "Unsupported tensor shape: " << this->tensor_c_.shape_size_;
return RET_ERROR; return RET_ERROR;
} }
switch (this->format_) { switch (this->tensor_c_.format_) {
case mindspore::NCHW: case mindspore::NCHW:
case mindspore::KCHW: case mindspore::KCHW:
case mindspore::CKHW: case mindspore::CKHW:
case mindspore::NC4HW4: case mindspore::NC4HW4:
case mindspore::NC8HW8: case mindspore::NC8HW8:
if (this->shape_.size() != 4) { if (this->tensor_c_.shape_size_ != C4NUM) {
return RET_ERROR; return RET_ERROR;
} }
return this->shape_[2]; return this->tensor_c_.shape_[C2NUM];
case mindspore::NHWC: case mindspore::NHWC:
case mindspore::NHWC4: case mindspore::NHWC4:
case mindspore::KHWC: case mindspore::KHWC:
case mindspore::CHWK: case mindspore::CHWK:
return this->shape_[1]; return this->tensor_c_.shape_[1];
case mindspore::HWCK: case mindspore::HWCK:
case mindspore::HWKC: case mindspore::HWKC:
case mindspore::HW: case mindspore::HW:
case mindspore::HW4: case mindspore::HW4:
return this->shape_[0]; return this->tensor_c_.shape_[0];
default: 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; return RET_ERROR;
} }
} }
int32_t Tensor::Width() const { int32_t Tensor::Width() const {
// Only 2D or 4D tensors have valid width. // Only 2D or 4D tensors have valid width.
if (this->shape_.size() != 4 && this->shape_.size() != 2) { if (this->tensor_c_.shape_size_ != C4NUM && this->tensor_c_.shape_size_ != C2NUM) {
MS_LOG(ERROR) << "Unsupported tensor shape: " << this->shape().size(); MS_LOG(ERROR) << "Unsupported tensor shape: " << this->tensor_c_.shape_size_;
return RET_ERROR; return RET_ERROR;
} }
switch (this->format_) { switch (this->tensor_c_.format_) {
case mindspore::NCHW: case mindspore::NCHW:
case mindspore::KCHW: case mindspore::KCHW:
case mindspore::CKHW: case mindspore::CKHW:
case mindspore::NC4HW4: case mindspore::NC4HW4:
case mindspore::NC8HW8: case mindspore::NC8HW8:
if (this->shape_.size() != 4) { if (this->tensor_c_.shape_size_ != C4NUM) {
return RET_ERROR; return RET_ERROR;
} }
return this->shape_[3]; return this->tensor_c_.shape_[C3NUM];
case mindspore::KHWC: case mindspore::KHWC:
case mindspore::NHWC: case mindspore::NHWC:
case mindspore::NHWC4: case mindspore::NHWC4:
case mindspore::CHWK: case mindspore::CHWK:
if (this->shape_.size() != 4) { if (this->tensor_c_.shape_size_ != C4NUM) {
return RET_ERROR; return RET_ERROR;
} }
return this->shape_[2]; return this->tensor_c_.shape_[C2NUM];
case mindspore::HWCK: case mindspore::HWCK:
case mindspore::HWKC: case mindspore::HWKC:
case mindspore::HW: case mindspore::HW:
case mindspore::HW4: case mindspore::HW4:
return this->shape_[1]; return this->tensor_c_.shape_[1];
default: default:
return RET_ERROR; return RET_ERROR;
} }
} }
size_t Tensor::Size() const { 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) { if (element_size == 0) {
MS_LOG(INFO) << "Unexpected data type: " << data_type_; MS_LOG(INFO) << "Unexpected data type: " << tensor_c_.data_type_;
return 0; 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) { 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 0;
} }
return element_size * static_cast<size_t>(element_num); return element_size * static_cast<size_t>(element_num);
@ -263,16 +276,16 @@ int64_t Tensor::ElementsNum() const {
if (this->category_ == CONST_SCALAR) { if (this->category_ == CONST_SCALAR) {
return 1; return 1;
} }
if (format_ == mindspore::NC4HW4) { if (tensor_c_.format_ == mindspore::NC4HW4) {
return ElementsC4Num(); return ElementsC4Num();
} }
if (format_ == mindspore::NC8HW8) { if (tensor_c_.format_ == mindspore::NC8HW8) {
return ElementsC8Num(); return ElementsC8Num();
} }
int64_t num = 1; int64_t num = 1;
for (size_t i = 0; i < shape_.size(); ++i) { for (size_t i = 0; i < tensor_c_.shape_size_; ++i) {
CHECK_INT64_MUL_OVERFLOW(num, shape_[i]); CHECK_INT64_MUL_OVERFLOW(num, tensor_c_.shape_[i]);
num *= shape_[i]; num *= tensor_c_.shape_[i];
} }
return num; return num;
} }
@ -283,7 +296,7 @@ int64_t Tensor::ElementsC4Num() const {
} }
int64_t result = 1; int64_t result = 1;
constexpr int kC4Align = 4; constexpr int kC4Align = 4;
if (this->shape_.size() == 4) { if (this->tensor_c_.shape_size_ == C4NUM) {
CHECK_INT64_MUL_OVERFLOW(result, Batch()); CHECK_INT64_MUL_OVERFLOW(result, Batch());
result *= Batch(); result *= Batch();
CHECK_INT64_MUL_OVERFLOW(result, Height()); CHECK_INT64_MUL_OVERFLOW(result, Height());
@ -292,11 +305,11 @@ int64_t Tensor::ElementsC4Num() const {
result *= Width(); result *= Width();
CHECK_INT64_MUL_OVERFLOW(result, (Channel() + 3LL) / kC4Align * kC4Align); CHECK_INT64_MUL_OVERFLOW(result, (Channel() + 3LL) / kC4Align * kC4Align);
result *= (Channel() + 3LL) / kC4Align * kC4Align; result *= (Channel() + 3LL) / kC4Align * kC4Align;
} else if (this->shape_.size() == 2) { } else if (this->tensor_c_.shape_size_ == C2NUM) {
CHECK_INT64_MUL_OVERFLOW(result, this->shape_[0]); CHECK_INT64_MUL_OVERFLOW(result, this->tensor_c_.shape_[0]);
result *= this->shape_[0]; result *= this->tensor_c_.shape_[0];
CHECK_INT64_MUL_OVERFLOW(result, (this->shape_[1] + 3LL) / kC4Align * kC4Align); CHECK_INT64_MUL_OVERFLOW(result, (this->tensor_c_.shape_[1] + 3LL) / kC4Align * kC4Align);
result *= (this->shape_[1] + 3LL) / kC4Align * kC4Align; result *= (this->tensor_c_.shape_[1] + 3LL) / kC4Align * kC4Align;
} }
return result; return result;
} }
@ -307,7 +320,7 @@ int64_t Tensor::ElementsC8Num() const {
} }
int64_t result = 1; int64_t result = 1;
constexpr int kC8Align = 8; constexpr int kC8Align = 8;
if (this->shape_.size() == 4) { if (this->tensor_c_.shape_size_ == C4NUM) {
CHECK_INT64_MUL_OVERFLOW(result, Batch()); CHECK_INT64_MUL_OVERFLOW(result, Batch());
result *= Batch(); result *= Batch();
CHECK_INT64_MUL_OVERFLOW(result, Height()); CHECK_INT64_MUL_OVERFLOW(result, Height());
@ -316,19 +329,19 @@ int64_t Tensor::ElementsC8Num() const {
result *= Width(); result *= Width();
CHECK_INT64_MUL_OVERFLOW(result, (Channel() + 7LL) / kC8Align * kC8Align); CHECK_INT64_MUL_OVERFLOW(result, (Channel() + 7LL) / kC8Align * kC8Align);
result *= (Channel() + 7LL) / kC8Align * kC8Align; result *= (Channel() + 7LL) / kC8Align * kC8Align;
} else if (this->shape_.size() == 2) { } else if (this->tensor_c_.shape_size_ == C2NUM) {
CHECK_INT64_MUL_OVERFLOW(result, this->shape_[0]); CHECK_INT64_MUL_OVERFLOW(result, this->tensor_c_.shape_[0]);
result *= this->shape_[0]; result *= this->tensor_c_.shape_[0];
CHECK_INT64_MUL_OVERFLOW(result, (this->shape_[1] + 7LL) / kC8Align * kC8Align); CHECK_INT64_MUL_OVERFLOW(result, (this->tensor_c_.shape_[1] + 7LL) / kC8Align * kC8Align);
result *= (this->shape_[1] + 7LL) / kC8Align * kC8Align; result *= (this->tensor_c_.shape_[1] + 7LL) / kC8Align * kC8Align;
} }
return result; return result;
} }
int Tensor::DimensionSize(const size_t index) const { int Tensor::DimensionSize(const size_t index) const {
int dim_size = -1; int dim_size = -1;
if (index < shape_.size()) { if (index < tensor_c_.shape_size_) {
dim_size = shape_[index]; dim_size = tensor_c_.shape_[index];
} else { } else {
MS_LOG(ERROR) << "Dimension index is wrong: " << index; 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::string Tensor::ToString() const {
std::ostringstream oss; std::ostringstream oss;
oss << "Tensor name: " << this->tensor_name(); oss << "Tensor name: " << this->tensor_name();
oss << " schema::Format: " << EnumNameFormat(static_cast<schema::Format>(this->format_)); oss << " schema::Format: " << EnumNameFormat(static_cast<schema::Format>(this->tensor_c_.format_));
oss << " DataType: " << this->data_type_; oss << " DataType: " << this->tensor_c_.data_type_;
oss << " Category: " << this->category_; oss << " Category: " << this->category_;
oss << " Shape:"; oss << " Shape:";
for (auto &dim : this->shape()) { for (auto &dim : this->shape()) {
oss << " " << dim; oss << " " << dim;
} }
oss << std::endl << "Data:"; oss << std::endl << "Data:";
switch (this->data_type_) { auto data = tensor_c_.data_;
switch (this->tensor_c_.data_type_) {
case kNumberTypeFloat32: { case kNumberTypeFloat32: {
oss << DataToString<float>(data_, this->ElementsNum()); oss << DataToString<float>(data, this->ElementsNum());
} break; } break;
case kNumberTypeFloat16: { case kNumberTypeFloat16: {
oss << DataToString<int16_t>(data_, this->ElementsNum()); oss << DataToString<int16_t>(data, this->ElementsNum());
} break; } break;
case kNumberTypeInt32: { case kNumberTypeInt32: {
oss << DataToString<int32_t>(data_, this->ElementsNum()); oss << DataToString<int32_t>(data, this->ElementsNum());
} break; } break;
case kNumberTypeInt16: { case kNumberTypeInt16: {
oss << DataToString<int16_t>(data_, this->ElementsNum()); oss << DataToString<int16_t>(data, this->ElementsNum());
} break; } break;
case kNumberTypeInt8: { case kNumberTypeInt8: {
oss << DataToString<int8_t>(data_, this->ElementsNum()); oss << DataToString<int8_t>(data, this->ElementsNum());
} break; } break;
default: default:
oss << "Unsupported data type to print"; oss << "Unsupported data type to print";
@ -370,15 +384,15 @@ std::string Tensor::ToString() const {
} }
int Tensor::MallocData(const AllocatorPtr allocator) { int Tensor::MallocData(const AllocatorPtr allocator) {
if (this->data_ != nullptr) { if (this->tensor_c_.data_ != nullptr) {
return RET_OK; return RET_OK;
} }
if (allocator != nullptr) { if (allocator != nullptr) {
allocator_ = allocator; 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) { 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; return RET_ERROR;
} }
auto data_size = this->Size(); auto data_size = this->Size();
@ -391,12 +405,12 @@ int Tensor::MallocData(const AllocatorPtr allocator) {
return RET_ERROR; return RET_ERROR;
} }
if (allocator_ == nullptr) { if (allocator_ == nullptr) {
this->data_ = malloc(data_size); this->tensor_c_.data_ = malloc(data_size);
} else { } else {
this->data_ = allocator_->Malloc(data_size); this->tensor_c_.data_ = allocator_->Malloc(data_size);
allocator_->SetRefCount(this->data_, 1); 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; MS_LOG(ERROR) << "Malloc tensor data failed, size=" << data_size;
return RET_ERROR; return RET_ERROR;
} }
@ -408,43 +422,43 @@ void Tensor::FreeData() {
if (IS_RUNTIME_ALLOCATOR(allocator_)) { if (IS_RUNTIME_ALLOCATOR(allocator_)) {
return; return;
} }
if (this->data_ != nullptr && this->own_data_) { if (this->tensor_c_.data_ != nullptr && this->own_data_) {
if (this->allocator_ != nullptr) { if (this->allocator_ != nullptr) {
if (allocator_->DecRefCount(this->data_, 1) <= 0) { if (allocator_->DecRefCount(this->tensor_c_.data_, 1) <= 0) {
allocator_->Free(this->data_); // Due to existing various allocator, here do not set data to nullptr. 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) { if (!IS_STATIC_ALLOCATOR(allocator_) || allocator_->RefCount(this->tensor_c_.data_) != 0) {
this->data_ = nullptr; this->tensor_c_.data_ = nullptr;
} }
} else { } else {
free(this->data_); free(this->tensor_c_.data_);
this->data_ = nullptr; this->tensor_c_.data_ = nullptr;
} }
} else if (this->category_ == Category::VAR) { } 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) { if (this->init_ref_count_ == 1) {
this->data_ = nullptr; this->tensor_c_.data_ = nullptr;
} }
} }
} }
} }
void *Tensor::ReallocData() { void *Tensor::ReallocData() {
if (this->data_ != nullptr) { if (this->tensor_c_.data_ != nullptr) {
FreeData(); FreeData();
} }
return this->MutableData(); return this->MutableData();
} }
void *Tensor::MutableData() { void *Tensor::MutableData() {
if (this->data_ == nullptr) { if (this->tensor_c_.data_ == nullptr) {
auto ret = this->MallocData(); auto ret = this->MallocData();
if (ret != 0) { if (ret != 0) {
MS_LOG(WARNING) << "Malloc data failed"; MS_LOG(WARNING) << "Malloc data failed";
} }
} }
Prepare(); Prepare();
return this->data_; return this->tensor_c_.data_;
} }
void Tensor::DecRefCount() { void Tensor::DecRefCount() {

View File

@ -26,6 +26,7 @@
#include <atomic> #include <atomic>
#include "include/api/format.h" #include "include/api/format.h"
#include "include/lite_types.h" #include "include/lite_types.h"
#include "nnacl/tensor_c.h"
#include "src/runtime/inner_allocator.h" #include "src/runtime/inner_allocator.h"
#include "src/common/log_adapter.h" #include "src/common/log_adapter.h"
#include "src/common/utils.h" #include "src/common/utils.h"
@ -55,7 +56,7 @@ struct LiteQuantParam {
class Tensor { class Tensor {
public: 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, Tensor(TypeId data_type, std::vector<int> shape, const mindspore::Format &format = mindspore::NHWC,
Category category = VAR); Category category = VAR);
@ -85,13 +86,26 @@ class Tensor {
std::string tensor_name() const { return tensor_name_; } 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; int DimensionSize(size_t index) const;
@ -122,21 +136,21 @@ class Tensor {
void *ReallocData(); 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 // 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. // course, you can call FreeData before calling set_data to ensure the data can be freed by current tensor.
void set_data(void *data) { void set_data(void *data) {
if (this->data_ == data) { if (this->tensor_c_.data_ == data) {
return; return;
} }
if (allocator_ != nullptr) { if (allocator_ != nullptr) {
allocator_->IncRefCount(data, 1); 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; this->own_data_ = true;
} }
@ -144,9 +158,9 @@ class Tensor {
void set_category(Category category) { this->category_ = category; } 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 ref_count() const { return ref_count_; }
virtual int init_ref_count() const { return static_cast<int>(this->init_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); void set_quant_clusters(const std::vector<float> &clusters);
virtual bool IsConst() const { 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; } bool IsGraphInput() const { return this->category_ == GRAPH_INPUT; }
@ -187,12 +201,12 @@ class Tensor {
void Prepare() { void Prepare() {
if (allocator_ != nullptr) { if (allocator_ != nullptr) {
data_ = allocator_->Prepare(data_); tensor_c_.data_ = allocator_->Prepare(tensor_c_.data_);
} }
} }
bool IsReady() const { 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_; } bool own_data() const { return this->own_data_; }
@ -202,7 +216,7 @@ class Tensor {
template <typename T> template <typename T>
int Scale(float scale) { int Scale(float scale) {
T cast_scale = static_cast<T>(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) { if (data == nullptr) {
return RET_ERROR; return RET_ERROR;
} }
@ -220,6 +234,8 @@ class Tensor {
bool IsScale() const { return (std::fabs(this->scale_ - 1.0f) > 1.0e-05); } bool IsScale() const { return (std::fabs(this->scale_ - 1.0f) > 1.0e-05); }
TensorC *ConvertToTensorC() { return &tensor_c_; }
private: private:
template <typename T> template <typename T>
std::string DataToString(void *data, size_t data_number, size_t print_len = 40) const { std::string DataToString(void *data, size_t data_number, size_t print_len = 40) const {
@ -235,11 +251,8 @@ class Tensor {
} }
protected: protected:
TensorC tensor_c_;
std::string tensor_name_; std::string tensor_name_;
void *data_ = nullptr;
TypeId data_type_;
std::vector<int> shape_;
mindspore::Format format_;
Category category_; Category category_;
std::atomic_int ref_count_ = {0}; std::atomic_int ref_count_ = {0};
int init_ref_count_ = 0; int init_ref_count_ = 0;

View File

@ -23,9 +23,21 @@
namespace mindspore::lite { namespace mindspore::lite {
#ifndef CONTROLFLOW_TENSORLIST_CLIP #ifndef CONTROLFLOW_TENSORLIST_CLIP
namespace {
constexpr int kOffset = 2;
}
TensorList::TensorList(std::vector<int> shape, std::vector<int> element_shape, Category category) TensorList::TensorList(std::vector<int> shape, std::vector<int> element_shape, Category category)
: Tensor(kObjectTypeTensorType, std::move(shape), mindspore::NHWC, category), : Tensor(kObjectTypeTensorType, std::move(shape), mindspore::NHWC, category) {
element_shape_(std::move(element_shape)) {} 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() { TensorList::~TensorList() {
if (!this->tensors_.empty()) { 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(); << " must be equal to param2:tensor_shape.size():" << tensor_shape.size();
return RET_ERROR; return RET_ERROR;
} }
this->tensors_data_type_ = dtype; this->tensor_list_c_.tensors_data_type_ = dtype;
for (int i = 0; i < this->ElementsNum(); ++i) { for (int i = 0; i < this->ElementsNum(); ++i) {
auto tensor_ptr = new (std::nothrow) Tensor(dtype, tensor_shape[i]); auto tensor_ptr = new (std::nothrow) Tensor(dtype, tensor_shape[i]);
if (tensor_ptr == nullptr) { if (tensor_ptr == nullptr) {
@ -128,9 +140,9 @@ int TensorList::MallocData(const AllocatorPtr allocator) {
int TensorList::SetTensor(int index, const Tensor *src_tensor) { int TensorList::SetTensor(int index, const Tensor *src_tensor) {
MS_CHECK_TRUE_MSG(src_tensor != nullptr, RET_ERROR, "src tensor cannot null"); MS_CHECK_TRUE_MSG(src_tensor != nullptr, RET_ERROR, "src tensor cannot null");
// your can use this fun to modify tensor[index] value // 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() 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; return RET_ERROR;
} }
auto element_num = this->ElementsNum(); auto element_num = this->ElementsNum();
@ -157,9 +169,9 @@ int TensorList::CheckTensorListParam() {
MS_LOG(ERROR) << "CheckTensorListParam: tensors_[" << i << "] is nullptr"; MS_LOG(ERROR) << "CheckTensorListParam: tensors_[" << i << "] is nullptr";
return RET_ERROR; 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() 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; return RET_ERROR;
} }
} }
@ -176,14 +188,15 @@ Tensor *TensorList::GetTensor(int index) {
} }
bool TensorList::IsCompatibleShape(const std::vector<int> &shape) { 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; return true;
} }
if (shape.size() != this->element_shape_.size()) { if (shape.size() != this->tensor_list_c_.element_shape_size_) {
return false; return false;
} }
for (size_t i = 0; i < shape.size(); ++i) { 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; return false;
} }
} }
@ -193,7 +206,7 @@ bool TensorList::IsCompatibleShape(const std::vector<int> &shape) {
bool TensorList::IsCompatibleShape(const Tensor *src) { bool TensorList::IsCompatibleShape(const Tensor *src) {
MS_CHECK_TRUE_MSG(src != nullptr, false, "src tensor cannot null"); MS_CHECK_TRUE_MSG(src != nullptr, false, "src tensor cannot null");
// shape is store in Tensor. // 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; return false;
} }
if (src->data_type() != kNumberTypeInt && src->data_type() != kNumberTypeInt32) { if (src->data_type() != kNumberTypeInt && src->data_type() != kNumberTypeInt32) {
@ -201,8 +214,9 @@ bool TensorList::IsCompatibleShape(const Tensor *src) {
return false; return false;
} }
auto src_ptr = reinterpret_cast<int *>(src->data()); auto src_ptr = reinterpret_cast<int *>(src->data());
for (size_t i = 0; i < this->element_shape_.size(); ++i) { for (size_t i = 0; i < this->tensor_list_c_.element_shape_size_; ++i) {
if (this->element_shape_[i] >= 0 && src_ptr[i] >= 0 && this->element_shape_[i] != src_ptr[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; return false;
} }
} }
@ -214,8 +228,8 @@ STATUS TensorList::Decode(const int *data) {
MS_LOG(ERROR) << "data is nullptr"; MS_LOG(ERROR) << "data is nullptr";
return RET_ERROR; return RET_ERROR;
} }
tensors_data_type_ = TypeId(data[0]); tensor_list_c_.tensors_data_type_ = TypeId(data[0]);
if (tensors_data_type_ < kTypeUnknown || tensors_data_type_ > kMonadTypeEnd) { if (tensor_list_c_.tensors_data_type_ < kTypeUnknown || tensor_list_c_.tensors_data_type_ > kMonadTypeEnd) {
MS_LOG(ERROR) << "TypeId illegal."; MS_LOG(ERROR) << "TypeId illegal.";
return RET_ERROR; return RET_ERROR;
} }
@ -223,10 +237,15 @@ STATUS TensorList::Decode(const int *data) {
MS_LOG(ERROR) << "element shape size illegal."; MS_LOG(ERROR) << "element shape size illegal.";
return RET_ERROR; return RET_ERROR;
} }
for (int j = 0; j < data[1]; ++j) { if (data[1] < 0 || data[1] > MAX_SHAPE_SIZE) {
element_shape_.push_back(data[2 + j]); 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) { if (tensors_num < 0) {
MS_LOG(WARNING) << "not able to create tensors, need infer shape."; MS_LOG(WARNING) << "not able to create tensors, need infer shape.";
return RET_OK; return RET_OK;
@ -238,14 +257,14 @@ STATUS TensorList::Decode(const int *data) {
MS_LOG(WARNING) << "tensor name: " << this->tensor_name_; MS_LOG(WARNING) << "tensor name: " << this->tensor_name_;
} }
tensors_.reserve(tensors_num); 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++) { for (int i = 0; i < tensors_num; i++) {
int tensor_dims_size = data[tensor_index++]; int tensor_dims_size = data[tensor_index++];
std::vector<int> shape(tensor_dims_size); std::vector<int> shape(tensor_dims_size);
for (int j = 0; j < tensor_dims_size; j++) { for (int j = 0; j < tensor_dims_size; j++) {
shape[j] = data[tensor_index++]; 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) { if (tensor == nullptr) {
MS_LOG(ERROR) << "new Tensor failed"; MS_LOG(ERROR) << "new Tensor failed";
return RET_NULL_PTR; return RET_NULL_PTR;
@ -263,15 +282,13 @@ TensorList *TensorList::CopyTensorList(const TensorList &src, bool copy_data, Al
MS_LOG(ERROR) << "New tensor failed"; MS_LOG(ERROR) << "New tensor failed";
return nullptr; return nullptr;
} }
result->data_type_ = src.data_type_; (void)memcpy(&result->tensor_c_, &src.tensor_c_, sizeof(TensorC));
result->shape_ = src.shape_; 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->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_allocator(allocator);
result->set_tensor_name(src.tensor_name() + "_duplicate"); result->set_tensor_name(src.tensor_name() + "_duplicate");
auto src_tensor_dtype = src.tensors_data_type_;
std::vector<std::vector<int> > tensor_shape{}; std::vector<std::vector<int> > tensor_shape{};
std::transform(src.tensors_.begin(), src.tensors_.end(), std::back_inserter(tensor_shape), std::transform(src.tensors_.begin(), src.tensors_.end(), std::back_inserter(tensor_shape),
[](const Tensor *tensor_item) { return tensor_item->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()) { if (result->shape().empty()) {
return result; 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) { if (copy_data) {
for (size_t i = 1; i < src.tensors_.size(); ++i) { for (size_t i = 1; i < src.tensors_.size(); ++i) {
auto src_tensor = src.tensors_; auto src_tensor = src.tensors_;

View File

@ -20,6 +20,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "include/errorcode.h" #include "include/errorcode.h"
#include "nnacl/tensorlist_c.h"
#include "src/common/log_adapter.h" #include "src/common/log_adapter.h"
#include "schema/model_generated.h" #include "schema/model_generated.h"
#include "src/tensor.h" #include "src/tensor.h"
@ -57,7 +58,7 @@ namespace mindspore::lite {
*/ */
class TensorList : public Tensor { class TensorList : public Tensor {
public: 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); 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; 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); 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); 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_; } 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: protected:
// The following functions must be masked. // The following functions must be masked.
void *data() const override { return nullptr; } void *data() const override { return nullptr; }
void *MutableData() override { return nullptr; } void *MutableData() override { return nullptr; }
size_t Size() const override { return 0; } size_t Size() const override { return 0; }
TensorListC tensor_list_c_;
std::vector<Tensor *> tensors_{}; std::vector<Tensor *> tensors_{};
TypeId tensors_data_type_ = kTypeUnknown;
std::vector<int> element_shape_{};
int max_elements_num_ = -1;
}; };
#else #else

View File

@ -43,11 +43,12 @@ TEST_F(TensorlistFromtensorInferTest, TensorlistFromtensorInferTest0) {
inputs[1]->shape_[1] = 2; inputs[1]->shape_[1] = 2;
std::vector<TensorC *> outputs(1, NULL); std::vector<TensorC *> outputs(1, NULL);
outputs[0] = reinterpret_cast<TensorC *>(malloc(sizeof(TensorListC))); auto out = reinterpret_cast<TensorListC *>(malloc(sizeof(TensorListC)));
OpParameter *parameter = new OpParameter; out->tensors_ = nullptr;
outputs[0] = reinterpret_cast<TensorC *>(out);
auto *parameter = new OpParameter;
int ret = TensorListFromTensorInferShape((const TensorC **)inputs.data(), inputs.size(), outputs.data(), int ret = TensorListFromTensorInferShape((const TensorC **)inputs.data(), inputs.size(), outputs.data(),
outputs.size(), reinterpret_cast<OpParameter *>(parameter)); outputs.size(), reinterpret_cast<OpParameter *>(parameter));
TensorListC *out = reinterpret_cast<TensorListC *>(outputs[0]);
ASSERT_EQ(ret, NNACL_OK); ASSERT_EQ(ret, NNACL_OK);
ASSERT_EQ(out->element_num_, 4); ASSERT_EQ(out->element_num_, 4);
ASSERT_EQ(out->data_type_, kObjectTypeTensorType); ASSERT_EQ(out->data_type_, kObjectTypeTensorType);
@ -57,22 +58,16 @@ TEST_F(TensorlistFromtensorInferTest, TensorlistFromtensorInferTest0) {
ASSERT_EQ(out->tensors_data_type_, kNumberTypeInt32); ASSERT_EQ(out->tensors_data_type_, kNumberTypeInt32);
// ASSERT_EQ(outputs[0]->format_, Format_NHWC); // ASSERT_EQ(outputs[0]->format_, Format_NHWC);
for (size_t i = 0; i < out->element_num_; i++) { for (size_t i = 0; i < out->element_num_; i++) {
ASSERT_EQ(out->tensors_[i].shape_size_, 2); ASSERT_EQ(out->tensors_[i]->shape_size_, 2);
ASSERT_EQ(out->tensors_[i].shape_[0], 6); ASSERT_EQ(out->tensors_[i]->shape_[0], 6);
ASSERT_EQ(out->tensors_[i].shape_[1], 5); ASSERT_EQ(out->tensors_[i]->shape_[1], 5);
} }
delete parameter; delete parameter;
for (size_t i = 0; i < inputs_size; i++) { for (size_t i = 0; i < inputs_size; i++) {
delete inputs[i]; delete inputs[i];
} }
for (size_t i = 0; i < outputs.size(); i++) { lite::FreeOutTensorC(&outputs);
if (outputs[i]->data_type_ == kObjectTypeTensorType) { delete out;
TensorListC *tensorListC = reinterpret_cast<TensorListC *>(outputs[i]);
lite::FreeTensorListC(tensorListC);
} else {
delete outputs[i];
}
}
} }
} // namespace mindspore } // namespace mindspore

View File

@ -28,24 +28,25 @@ class TensorlistGetItemInferTest : public mindspore::CommonTest {
TEST_F(TensorlistGetItemInferTest, TensorlistGetItemInferTest0) { TEST_F(TensorlistGetItemInferTest, TensorlistGetItemInferTest0) {
size_t inputs_size = 3; size_t inputs_size = 3;
std::vector<TensorC *> inputs(inputs_size, NULL); 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->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_[0].shape_size_ = 2; input0->tensors_ = &in_tensors_c;
input0->tensors_[0].shape_[0] = 1; in_tensors_c[0].shape_size_ = 2;
input0->tensors_[0].shape_[1] = 2; in_tensors_c[0].shape_[0] = 1;
input0->tensors_[0].data_type_ = kNumberTypeInt32; in_tensors_c[0].shape_[1] = 2;
input0->tensors_[1].shape_size_ = 3; in_tensors_c[0].data_type_ = kNumberTypeInt32;
input0->tensors_[1].shape_[0] = 3; in_tensors_c[1].shape_size_ = 3;
input0->tensors_[1].shape_[1] = 4; in_tensors_c[1].shape_[0] = 3;
input0->tensors_[1].shape_[2] = 5; in_tensors_c[1].shape_[1] = 4;
input0->tensors_[1].data_type_ = kNumberTypeInt32; in_tensors_c[1].shape_[2] = 5;
input0->tensors_[2].shape_size_ = 4; in_tensors_c[1].data_type_ = kNumberTypeInt32;
input0->tensors_[2].shape_[0] = 6; in_tensors_c[2].shape_size_ = 4;
input0->tensors_[2].shape_[1] = 7; in_tensors_c[2].shape_[0] = 6;
input0->tensors_[2].shape_[2] = 8; in_tensors_c[2].shape_[1] = 7;
input0->tensors_[2].shape_[3] = 9; in_tensors_c[2].shape_[2] = 8;
input0->tensors_[2].data_type_ = kNumberTypeInt32; in_tensors_c[2].shape_[3] = 9;
in_tensors_c[2].data_type_ = kNumberTypeInt32;
// input0->tensors_[2]->format_ = Format_NHWC; // input0->tensors_[2]->format_ = Format_NHWC;
inputs[0] = reinterpret_cast<TensorC *>(input0); inputs[0] = reinterpret_cast<TensorC *>(input0);
inputs[0]->data_type_ = kObjectTypeTensorType; inputs[0]->data_type_ = kObjectTypeTensorType;
@ -60,7 +61,7 @@ TEST_F(TensorlistGetItemInferTest, TensorlistGetItemInferTest0) {
std::vector<TensorC *> outputs(1, NULL); std::vector<TensorC *> outputs(1, NULL);
outputs[0] = reinterpret_cast<TensorC *>(malloc(sizeof(TensorC))); 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(), int ret = TensorListGetItemInferShape((const TensorC **)inputs.data(), inputs.size(), outputs.data(), outputs.size(),
reinterpret_cast<OpParameter *>(parameter)); reinterpret_cast<OpParameter *>(parameter));
ASSERT_EQ(ret, NNACL_OK); ASSERT_EQ(ret, NNACL_OK);
@ -75,11 +76,10 @@ TEST_F(TensorlistGetItemInferTest, TensorlistGetItemInferTest0) {
delete parameter; delete parameter;
for (size_t i = 0; i < inputs_size; i++) { for (size_t i = 0; i < inputs_size; i++) {
if (inputs[i]->data_type_ == kObjectTypeTensorType) { if (inputs[i]->data_type_ == kObjectTypeTensorType) {
TensorListC *tensorListC = reinterpret_cast<TensorListC *>(inputs[i]); auto *tensorList_c = reinterpret_cast<TensorListC *>(inputs[i]);
lite::FreeTensorListC(tensorListC); free(*tensorList_c->tensors_);
} else {
free(inputs[i]);
} }
free(inputs[i]);
} }
for (size_t i = 0; i < outputs.size(); i++) { for (size_t i = 0; i < outputs.size(); i++) {
free(outputs[i]); free(outputs[i]);

View File

@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "common/common_test.h" #include "common/common_test.h"
#include "src/common/tensor_util.h"
#include "nnacl/infer/control/tensorlist_reserve_infer.h" #include "nnacl/infer/control/tensorlist_reserve_infer.h"
namespace mindspore { namespace mindspore {
@ -41,11 +42,12 @@ TEST_F(TensorlistReserveInferTest, TensorlistReserveInferTest0) {
inputs[1]->data_type_ = kNumberTypeInt32; inputs[1]->data_type_ = kNumberTypeInt32;
std::vector<TensorC *> outputs(1, NULL); std::vector<TensorC *> outputs(1, NULL);
outputs[0] = reinterpret_cast<TensorC *>(new TensorListC); auto out = reinterpret_cast<TensorListC *>(malloc(sizeof(TensorListC)));
OpParameter *parameter = new OpParameter; 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(), int ret = TensorListReserveInferShape((const TensorC **)inputs.data(), inputs.size(), outputs.data(), outputs.size(),
reinterpret_cast<OpParameter *>(parameter)); reinterpret_cast<OpParameter *>(parameter));
TensorListC *out = reinterpret_cast<TensorListC *>(outputs[0]);
ASSERT_EQ(ret, NNACL_OK); ASSERT_EQ(ret, NNACL_OK);
ASSERT_EQ(out->element_num_, 5); ASSERT_EQ(out->element_num_, 5);
ASSERT_EQ(out->data_type_, kObjectTypeTensorType); ASSERT_EQ(out->data_type_, kObjectTypeTensorType);
@ -56,15 +58,14 @@ TEST_F(TensorlistReserveInferTest, TensorlistReserveInferTest0) {
ASSERT_EQ(out->tensors_data_type_, kTypeUnknown); ASSERT_EQ(out->tensors_data_type_, kTypeUnknown);
// ASSERT_EQ(outputs[0]->format_, Format_NHWC); // ASSERT_EQ(outputs[0]->format_, Format_NHWC);
for (size_t i = 0; i < out->element_num_; i++) { 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; delete parameter;
for (size_t i = 0; i < inputs_size; i++) { for (size_t i = 0; i < inputs_size; i++) {
delete inputs[i]; delete inputs[i];
} }
for (size_t i = 0; i < outputs.size(); i++) { lite::FreeOutTensorC(&outputs);
delete outputs[i]; delete out;
}
} }
} // namespace mindspore } // namespace mindspore

View File

@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "common/common_test.h" #include "common/common_test.h"
#include "src/common/tensor_util.h"
#include "nnacl/infer/control/tensorlist_setitem_infer.h" #include "nnacl/infer/control/tensorlist_setitem_infer.h"
namespace mindspore { namespace mindspore {
@ -27,29 +28,30 @@ class TensorlistSetItemInferTest : public mindspore::CommonTest {
TEST_F(TensorlistSetItemInferTest, TensorlistSetItemInferTest0) { TEST_F(TensorlistSetItemInferTest, TensorlistSetItemInferTest0) {
size_t inputs_size = 3; size_t inputs_size = 3;
std::vector<TensorC *> inputs(inputs_size, NULL); std::vector<TensorC *> inputs(inputs_size, NULL);
TensorListC *input0 = new TensorListC; auto *input0 = new TensorListC;
input0->element_num_ = 3; 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_size_ = 2;
input0->element_shape_[0] = 2; input0->element_shape_[0] = 2;
input0->element_shape_[1] = 4; input0->element_shape_[1] = 4;
input0->tensors_data_type_ = kNumberTypeInt32; input0->tensors_data_type_ = kNumberTypeInt32;
input0->data_type_ = kObjectTypeTensorType; input0->data_type_ = kObjectTypeTensorType;
input0->tensors_[0].shape_size_ = 2; in_tensors_c[0].shape_size_ = 2;
input0->tensors_[0].shape_[0] = 2; in_tensors_c[0].shape_[0] = 2;
input0->tensors_[0].shape_[1] = 4; in_tensors_c[0].shape_[1] = 4;
input0->tensors_[0].data_type_ = kNumberTypeInt32; in_tensors_c[0].data_type_ = kNumberTypeInt32;
input0->tensors_[1].shape_size_ = 2; in_tensors_c[1].shape_size_ = 2;
input0->tensors_[1].shape_[0] = 2; in_tensors_c[1].shape_[0] = 2;
input0->tensors_[1].shape_[1] = 4; in_tensors_c[1].shape_[1] = 4;
input0->tensors_[1].data_type_ = kNumberTypeInt32; in_tensors_c[1].data_type_ = kNumberTypeInt32;
input0->tensors_[2].shape_size_ = 2; in_tensors_c[2].shape_size_ = 2;
input0->tensors_[2].shape_[0] = 2; in_tensors_c[2].shape_[0] = 2;
input0->tensors_[2].shape_[1] = 4; in_tensors_c[2].shape_[1] = 4;
input0->tensors_[2].data_type_ = kNumberTypeInt32; in_tensors_c[2].data_type_ = kNumberTypeInt32;
// input0->tensors_[2]->format_ = Format_NHWC; // input0->tensors_[2]->format_ = Format_NHWC;
inputs[0] = reinterpret_cast<TensorC *>(input0); inputs[0] = reinterpret_cast<TensorC *>(input0);
@ -69,11 +71,13 @@ TEST_F(TensorlistSetItemInferTest, TensorlistSetItemInferTest0) {
inputs[2]->data_ = inputs2_data.data(); inputs[2]->data_ = inputs2_data.data();
std::vector<TensorC *> outputs(1, NULL); std::vector<TensorC *> outputs(1, NULL);
outputs[0] = reinterpret_cast<TensorC *>(new TensorListC); auto out = reinterpret_cast<TensorListC *>(malloc(sizeof(TensorListC)));
OpParameter *parameter = new OpParameter; 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(), int ret = TensorListSetItemInferShape((const TensorC **)inputs.data(), inputs.size(), outputs.data(), outputs.size(),
reinterpret_cast<OpParameter *>(parameter)); 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(ret, NNACL_OK);
ASSERT_EQ(res->element_num_, 3); ASSERT_EQ(res->element_num_, 3);
ASSERT_EQ(res->element_shape_size_, 2); 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->element_shape_[1], 4);
ASSERT_EQ(res->tensors_data_type_, kNumberTypeInt32); ASSERT_EQ(res->tensors_data_type_, kNumberTypeInt32);
ASSERT_EQ(res->data_type_, kObjectTypeTensorType); ASSERT_EQ(res->data_type_, kObjectTypeTensorType);
ASSERT_EQ(res->tensors_[0].shape_size_, 2); ASSERT_EQ(res->tensors_[0]->shape_size_, 2);
ASSERT_EQ(res->tensors_[0].shape_[0], 2); ASSERT_EQ(res->tensors_[0]->shape_[0], 2);
ASSERT_EQ(res->tensors_[0].shape_[1], 4); ASSERT_EQ(res->tensors_[0]->shape_[1], 4);
ASSERT_EQ(res->tensors_[1].shape_size_, 2); ASSERT_EQ(res->tensors_[1]->shape_size_, 2);
ASSERT_EQ(res->tensors_[1].shape_[0], 2); ASSERT_EQ(res->tensors_[1]->shape_[0], 2);
ASSERT_EQ(res->tensors_[1].shape_[1], 4); ASSERT_EQ(res->tensors_[1]->shape_[1], 4);
ASSERT_EQ(res->tensors_[2].shape_size_, 2); ASSERT_EQ(res->tensors_[2]->shape_size_, 2);
ASSERT_EQ(res->tensors_[2].shape_[0], 5); ASSERT_EQ(res->tensors_[2]->shape_[0], 5);
ASSERT_EQ(res->tensors_[2].shape_[1], 6); ASSERT_EQ(res->tensors_[2]->shape_[1], 6);
// ASSERT_EQ(outputs[0]->format_, Format_NHWC); // ASSERT_EQ(outputs[0]->format_, Format_NHWC);
delete parameter; delete parameter;
for (size_t i = 0; i < inputs_size; i++) { 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]; delete inputs[i];
} }
for (size_t i = 0; i < outputs.size(); i++) { lite::FreeOutTensorC(&outputs);
delete outputs[i]; delete out;
}
} }
// retest mergeshape // retest mergeshape

View File

@ -27,28 +27,29 @@ class TensorlistStackInferTest : public mindspore::CommonTest {
TEST_F(TensorlistStackInferTest, TensorlistStackInferTest0) { TEST_F(TensorlistStackInferTest, TensorlistStackInferTest0) {
size_t inputs_size = 2; size_t inputs_size = 2;
std::vector<TensorC *> inputs(inputs_size, NULL); std::vector<TensorC *> inputs(inputs_size, NULL);
TensorListC *input0 = new TensorListC; auto *input0 = new TensorListC;
input0->element_num_ = 3; 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_size_ = 2;
input0->element_shape_[0] = 2; input0->element_shape_[0] = 2;
input0->element_shape_[1] = 4; input0->element_shape_[1] = 4;
input0->tensors_data_type_ = kNumberTypeInt32; input0->tensors_data_type_ = kNumberTypeInt32;
input0->tensors_[0].shape_size_ = 2; in_tensors_c[0].shape_size_ = 2;
input0->tensors_[0].shape_[0] = 2; in_tensors_c[0].shape_[0] = 2;
input0->tensors_[0].shape_[1] = 4; in_tensors_c[0].shape_[1] = 4;
input0->tensors_[0].data_type_ = kNumberTypeInt32; in_tensors_c[0].data_type_ = kNumberTypeInt32;
input0->tensors_[1].shape_size_ = 2; in_tensors_c[1].shape_size_ = 2;
input0->tensors_[1].shape_[0] = 2; in_tensors_c[1].shape_[0] = 2;
input0->tensors_[1].shape_[1] = 4; in_tensors_c[1].shape_[1] = 4;
input0->tensors_[1].data_type_ = kNumberTypeInt32; in_tensors_c[1].data_type_ = kNumberTypeInt32;
input0->tensors_[2].shape_size_ = 2; in_tensors_c[2].shape_size_ = 2;
input0->tensors_[2].shape_[0] = 2; in_tensors_c[2].shape_[0] = 2;
input0->tensors_[2].shape_[1] = 4; in_tensors_c[2].shape_[1] = 4;
input0->tensors_[2].data_type_ = kNumberTypeInt32; in_tensors_c[2].data_type_ = kNumberTypeInt32;
// input0->tensors_[2]->format_ = Format_NHWC; // input0->tensors_[2]->format_ = Format_NHWC;
inputs[0] = reinterpret_cast<TensorC *>(input0); inputs[0] = reinterpret_cast<TensorC *>(input0);
inputs[0]->data_type_ = kObjectTypeTensorType; inputs[0]->data_type_ = kObjectTypeTensorType;
@ -61,7 +62,7 @@ TEST_F(TensorlistStackInferTest, TensorlistStackInferTest0) {
std::vector<TensorC *> outputs(1, NULL); std::vector<TensorC *> outputs(1, NULL);
outputs[0] = new TensorC; 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(), int ret = TensorListStackInferShape((const TensorC **)inputs.data(), inputs.size(), outputs.data(), outputs.size(),
reinterpret_cast<OpParameter *>(parameter)); reinterpret_cast<OpParameter *>(parameter));
ASSERT_EQ(ret, NNACL_OK); ASSERT_EQ(ret, NNACL_OK);
@ -74,6 +75,10 @@ TEST_F(TensorlistStackInferTest, TensorlistStackInferTest0) {
delete parameter; delete parameter;
for (size_t i = 0; i < inputs_size; i++) { 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]; delete inputs[i];
} }
for (size_t i = 0; i < outputs.size(); i++) { for (size_t i = 0; i < outputs.size(); i++) {

View File

@ -193,8 +193,8 @@ void NNaclFp32Serializer::CodeArrayStruct(const std::string &name, TensorC *tens
int size = tensor.size(); int size = tensor.size();
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
std::string tensor_name = "tensor" + std::to_string(count++); 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_, CodeBaseStruct<false>("TensorC", name, tensor_name, tensorC[i].data_type_, tensorC[i].format_, tensor[i],
tensor[i], tensorC[i].shape_size_, ToString(tensorC[i].shape_)); tensorC[i].shape_size_, ToString(tensorC[i].shape_));
tensor_names.emplace_back(tensor_name); tensor_names.emplace_back(tensor_name);
} }
code << " TensorC" code << " TensorC"

View File

@ -175,6 +175,7 @@ getCommonFile() {
mindspore/lite/experimental/src/exec_env_utils.h mindspore/lite/experimental/src/exec_env_utils.h
mindspore/lite/src/expression/ops_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/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/ccsrc/plugin/device/cpu/kernel/nnacl/tensorlist_c_utils.h
mindspore/core/utils/log_adapter.h mindspore/core/utils/log_adapter.h
mindspore/core/ir/api_tensor_impl.h mindspore/core/ir/api_tensor_impl.h