forked from mindspore-Ecosystem/mindspore
!45751 [lite]optimize inferShape
Merge pull request !45751 from 徐安越/r1.8_1
This commit is contained in:
commit
4b98342ca1
|
@ -41,7 +41,7 @@ int TensorListGetItemInferShape(const TensorC *const *inputs, size_t inputs_size
|
||||||
if (index < 0 || index > ((int)(input0->element_num_ - 1))) {
|
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_);
|
||||||
|
|
|
@ -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_);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
/**
|
||||||
|
* Copyright 2022 Huawei Technologies Co., Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MINDSPORE_NNACL_TENSORLIST_C_H_
|
||||||
|
#define MINDSPORE_NNACL_TENSORLIST_C_H_
|
||||||
|
|
||||||
|
#include "nnacl/tensor_c.h"
|
||||||
|
|
||||||
|
typedef struct vvector {
|
||||||
|
int **shape_; // value of shapes
|
||||||
|
int *shape_size_; // size of shape
|
||||||
|
size_t size_; // number of shapes
|
||||||
|
} vvector;
|
||||||
|
|
||||||
|
typedef struct TensorListC {
|
||||||
|
int data_type_;
|
||||||
|
int format_;
|
||||||
|
int shape_value_;
|
||||||
|
int tensors_data_type_; // element_data_type_, keep same as c++
|
||||||
|
int max_elements_num_;
|
||||||
|
TensorC **tensors_;
|
||||||
|
size_t element_num_;
|
||||||
|
size_t element_shape_size_;
|
||||||
|
int element_shape_[MAX_SHAPE_SIZE];
|
||||||
|
} TensorListC;
|
||||||
|
|
||||||
|
#endif // MINDSPORE_NNACL_TENSORLIST_C_H_
|
|
@ -28,16 +28,21 @@ int MallocTensorListData(TensorListC *tensor_list, TypeIdC dtype, const vvector
|
||||||
return NNACL_ERR;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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_);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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_;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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++) {
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue