diff --git a/mindspore/lite/src/executor.cc b/mindspore/lite/src/executor.cc index a1de30c098..904e67f26b 100644 --- a/mindspore/lite/src/executor.cc +++ b/mindspore/lite/src/executor.cc @@ -25,7 +25,7 @@ int Executor::CheckInputs(const std::vector &in_tensors) { MS_LOG(ERROR) << "Graph input tensor is nullptr"; return RET_ERROR; } - if (inTensor->data_c() == nullptr) { + if (inTensor->data_type() != kObjectTypeTensorType && inTensor->data_c() == nullptr) { MS_LOG(ERROR) << "Graph input tensor data is nullptr " << in_tensors; return RET_ERROR; } diff --git a/mindspore/lite/src/lite_session.cc b/mindspore/lite/src/lite_session.cc index 96c16b7c92..dca4d394ee 100644 --- a/mindspore/lite/src/lite_session.cc +++ b/mindspore/lite/src/lite_session.cc @@ -144,7 +144,7 @@ lite::Tensor *LiteSession::ConvertTensor(const schema::Tensor &src_tensor) { } lite::Tensor *dst_tensor = nullptr; if (TypeId(src_tensor.dataType()) == kObjectTypeTensorType) { - dst_tensor = new (std::nothrow) TensorList(shape, std::vector()); + dst_tensor = new (std::nothrow) TensorList(shape, std::vector(), src_category); } else { dst_tensor = new (std::nothrow) Tensor(TypeId(src_tensor.dataType()), shape, src_tensor.format(), src_category); } diff --git a/mindspore/lite/src/ops/tensorlist_fromtensor.cc b/mindspore/lite/src/ops/tensorlist_fromtensor.cc index 8a389ce3dd..441250de03 100644 --- a/mindspore/lite/src/ops/tensorlist_fromtensor.cc +++ b/mindspore/lite/src/ops/tensorlist_fromtensor.cc @@ -112,6 +112,9 @@ Registry TensorListFromTensorRegistry(schema::PrimitiveType_TensorListFromTensor #endif int TensorListFromTensor::InferShape(std::vector inputs_, std::vector outputs_) { + if (!infer_flag()) { + return RET_INFER_INVALID; + } auto input0 = inputs_[0]; MS_ASSERT(input0 != nullptr); std::vector input0_shape = input0->shape(); diff --git a/mindspore/lite/src/ops/tensorlist_getitem.cc b/mindspore/lite/src/ops/tensorlist_getitem.cc index 065c3e8e90..5e9f8627d2 100644 --- a/mindspore/lite/src/ops/tensorlist_getitem.cc +++ b/mindspore/lite/src/ops/tensorlist_getitem.cc @@ -117,6 +117,9 @@ int TensorListGetItem::MergeShape(const std::vector &tmp) { } int TensorListGetItem::InferShape(std::vector inputs_, std::vector outputs_) { + if (!infer_flag()) { + return RET_INFER_INVALID; + } auto input0 = reinterpret_cast(inputs_[0]); auto get_index = inputs_[1]; MS_ASSERT(get_index != nullptr); @@ -125,8 +128,8 @@ int TensorListGetItem::InferShape(std::vector inputs_, std::vect return RET_ERROR; } if (get_index->data_c() == nullptr) { - MS_LOG(ERROR) << "get_index->data_c() is nullptr"; - return RET_NULL_PTR; + MS_LOG(DEBUG) << "get_index->data_c() is nullptr"; + return RET_INFER_INVALID; } index_ = reinterpret_cast(get_index->data_c())[0]; if (index_ < 0 || index_ > (input0->ElementsNum() - 1)) { diff --git a/mindspore/lite/src/ops/tensorlist_stack.cc b/mindspore/lite/src/ops/tensorlist_stack.cc index 5e91be6ee1..05d46578b9 100644 --- a/mindspore/lite/src/ops/tensorlist_stack.cc +++ b/mindspore/lite/src/ops/tensorlist_stack.cc @@ -117,6 +117,9 @@ bool TensorListStack::IsFullyDefined(const std::vector &shape) const { } int TensorListStack::InferShape(std::vector inputs_, std::vector outputs_) { + if (!infer_flag()) { + return RET_INFER_INVALID; + } auto input0 = reinterpret_cast(inputs_.front()); MS_ASSERT(input0 != nullptr); if (input0->ElementsNum() == 0) { @@ -130,7 +133,7 @@ int TensorListStack::InferShape(std::vector inputs_, std::vector return RET_NULL_PTR; } auto ele_shape_ptr = reinterpret_cast(ele_shape->data_c()); - for (int i = 0; ele_shape->ElementsNum(); ++i) { + for (int i = 0; i < ele_shape->ElementsNum(); ++i) { output_shape_.push_back(ele_shape_ptr[i]); } diff --git a/mindspore/lite/src/runtime/kernel/arm/base/merge.cc b/mindspore/lite/src/runtime/kernel/arm/base/merge.cc index ad54decf62..a3b2c33f91 100644 --- a/mindspore/lite/src/runtime/kernel/arm/base/merge.cc +++ b/mindspore/lite/src/runtime/kernel/arm/base/merge.cc @@ -17,6 +17,7 @@ #include "src/runtime/kernel/arm/base/merge.h" #include "src/kernel_registry.h" #include "include/errorcode.h" +#include "src/tensorlist.h" using mindspore::lite::KernelRegistrar; using mindspore::lite::RET_ERROR; @@ -56,31 +57,72 @@ bool MergeCPUKernel::IsReady(const std::vector &scope_tensors) { std::all_of(this->in_tensors().begin() + in_tensors().size() / 2, this->in_tensors().end(), [&](lite::Tensor *kernel_in_tensor) { return kernel_in_tensor->IsConst() || kernel_in_tensor->IsGraphInput() || - kernel_in_tensor->ref_count() >= 1; + kernel_in_tensor->ref_count() >= 1 || + (kernel_in_tensor->data_type() == kObjectTypeTensorType); }); } int MergeCPUKernel::Init() { return RET_OK; } -int MergeCPUKernel::ReSize() { return RET_ERROR; } +int MergeCPUKernel::ReSize() { return RET_OK; } + +bool MergeCPUKernel::PartialInputReady(int num_begin, int num_end) { + MS_ASSERT(in_tensors_.size() == 2 * out_tensors_.size()); + bool result = (std::all_of(this->in_tensors().begin() + num_begin, this->in_tensors().begin() + num_end, + [&](lite::Tensor *kernel_in_tensor) { + return kernel_in_tensor->IsConst() || kernel_in_tensor->ref_count() >= 1 || + kernel_in_tensor->IsGraphInput() || + kernel_in_tensor->data_type() == kObjectTypeTensorType; + })) && + std::all_of(this->in_tensors_.begin() + num_begin, this->in_tensors_.begin() + num_end, + [&](lite::Tensor *in_tensor) { + if (in_tensor->data_type() != kObjectTypeTensorType) { + return in_tensor->data_c() != nullptr; + } else { + return true; + } + }); + return result; +} int MergeCPUKernel::Run() { MS_ASSERT(in_tensors_.size() == 2 * out_tensors_.size()); int in_tesnor_part_one = 0; - int in_tensor_part_two = out_tensors().size(); - if (in_tensors_[in_tesnor_part_one]->data_c() != nullptr) { + int in_tensor_part_two = in_tensors_.size() / 2; + int in_tensor_part_three = in_tensors_.size(); + if (PartialInputReady(in_tesnor_part_one, in_tensor_part_two)) { for (size_t i = 0; i < out_tensors().size(); i++) { auto out_data = out_tensors_[i]->data_c(); auto in_data = in_tensors_[i]->data_c(); + if (in_tensors_[i]->data_type() == kObjectTypeTensorType) { + auto in_tensor_list = reinterpret_cast(in_tensors_[i]); + auto out_tensor_list = reinterpret_cast(out_tensors_[i]); + if (std::any_of(in_tensor_list->tensors().begin(), in_tensor_list->tensors().end(), + [&](lite::Tensor *tensor) { return tensor->data_c() == nullptr; })) { + continue; + } + *out_tensor_list = *in_tensor_list; + continue; + } MS_ASSERT(in_data != nullptr); MS_ASSERT(out_data != nullptr); memcpy(out_data, in_data, in_tensors_[i]->Size()); } } - if (in_tensors_[in_tensor_part_two]->data_c() != nullptr) { + if (PartialInputReady(in_tensor_part_two, in_tensor_part_three)) { for (size_t i = 0; i < out_tensors().size(); i++) { auto out_data = out_tensors_[i]->data_c(); auto in_data = in_tensors_[i + in_tensor_part_two]->data_c(); + if (in_tensors_[i]->data_type() == kObjectTypeTensorType) { + auto in_tensor_list = reinterpret_cast(in_tensors_[i + in_tensor_part_two]); + auto out_tensor_list = reinterpret_cast(out_tensors_[i]); + if (std::any_of(in_tensor_list->tensors().begin(), in_tensor_list->tensors().end(), + [&](lite::Tensor *tensor) { return tensor->data_c() == nullptr; })) { + continue; + } + *out_tensor_list = *in_tensor_list; + continue; + } MS_ASSERT(in_data != nullptr); MS_ASSERT(out_data != nullptr); memcpy(out_data, in_data, in_tensors_[i]->Size()); diff --git a/mindspore/lite/src/runtime/kernel/arm/base/merge.h b/mindspore/lite/src/runtime/kernel/arm/base/merge.h index 726a3ae243..966d8a654e 100644 --- a/mindspore/lite/src/runtime/kernel/arm/base/merge.h +++ b/mindspore/lite/src/runtime/kernel/arm/base/merge.h @@ -39,6 +39,7 @@ class MergeCPUKernel : public LiteKernel { int Init() override; int ReSize() override; int Run() override; + bool PartialInputReady(int num_begin, int num_end); private: MergeParameter *merge_param_ = nullptr; diff --git a/mindspore/lite/src/runtime/kernel/arm/base/switch.cc b/mindspore/lite/src/runtime/kernel/arm/base/switch.cc index eb2c7933aa..e136f04f0e 100644 --- a/mindspore/lite/src/runtime/kernel/arm/base/switch.cc +++ b/mindspore/lite/src/runtime/kernel/arm/base/switch.cc @@ -17,6 +17,7 @@ #include "src/runtime/kernel/arm/base/switch.h" #include "src/kernel_registry.h" #include "include/errorcode.h" +#include "src/tensorlist.h" using mindspore::lite::KernelRegistrar; using mindspore::lite::RET_ERROR; @@ -28,8 +29,8 @@ int SwitchCPUKernel::PostProcess() { auto bool_tensor = in_tensors_.front(); MS_ASSERT(bool_tensor != nullptr); MS_ASSERT(bool_tensor->data_type() == kNumberTypeBool); - MS_ASSERT(bool_tensor->shape().size() == 1); - MS_ASSERT(bool_tensor->shape().front() == 1); + MS_ASSERT(bool_tensor->Size() == 1); + MS_ASSERT(bool_tensor->Size() == 1); auto active = static_cast(bool_tensor->data_c()); if (active == nullptr) { MS_LOG(ERROR) << "data of bool tensor is nullptr"; @@ -47,7 +48,7 @@ int SwitchCPUKernel::PostProcess() { int SwitchCPUKernel::Init() { return RET_OK; } -int SwitchCPUKernel::ReSize() { return RET_ERROR; } +int SwitchCPUKernel::ReSize() { return RET_OK; } // inputs: bool*1 data*n // output: true-data*n, false-data*n @@ -56,8 +57,8 @@ int SwitchCPUKernel::Run() { auto bool_tensor = in_tensors_.front(); MS_ASSERT(bool_tensor != nullptr); MS_ASSERT(bool_tensor->data_type() == kNumberTypeBool); - MS_ASSERT(bool_tensor->shape().size() == 1); - MS_ASSERT(bool_tensor->shape().front() == 1); + MS_ASSERT(bool_tensor->Size() == 1); + MS_ASSERT(bool_tensor->Size() == 1); auto active = static_cast(bool_tensor->data_c()); if (active == nullptr) { MS_LOG(ERROR) << "data of bool tensor is nullptr"; @@ -68,6 +69,14 @@ int SwitchCPUKernel::Run() { while (in_index < in_tensors_.size()) { auto in_tensor = in_tensors_.at(in_index++); auto out_tensor = out_tensors_.at(out_index++); + // copy for tensorlist + if (in_tensor->data_type() == kObjectTypeTensorType) { + auto in_tensor_list = reinterpret_cast(in_tensor); + auto out_tensor_list = reinterpret_cast(out_tensor); + *out_tensor_list = *in_tensor_list; + continue; + } + // copy for tensor MS_ASSERT(in_tensor != nullptr); MS_ASSERT(out_tensor != nullptr); auto input = in_tensor->data_c(); @@ -111,4 +120,5 @@ kernel::LiteKernel *CpuSwitchKernelCreator(const std::vector &in REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Switch, CpuSwitchKernelCreator) REG_KERNEL(kCPU, kNumberTypeBool, PrimitiveType_Switch, CpuSwitchKernelCreator) +REG_KERNEL(kCPU, kNumberTypeInt32, PrimitiveType_Switch, CpuSwitchKernelCreator) } // namespace mindspore::kernel diff --git a/mindspore/lite/src/runtime/kernel/arm/fp32/arithmetic_fp32.cc b/mindspore/lite/src/runtime/kernel/arm/fp32/arithmetic_fp32.cc index 6db337e0dd..cbab0cfb22 100644 --- a/mindspore/lite/src/runtime/kernel/arm/fp32/arithmetic_fp32.cc +++ b/mindspore/lite/src/runtime/kernel/arm/fp32/arithmetic_fp32.cc @@ -554,6 +554,7 @@ REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Mod, CpuArithmeticFp32KernelC REG_KERNEL(kCPU, kNumberTypeInt32, PrimitiveType_Mod, CpuArithmeticFp32KernelCreator) REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_LogicalAnd, CpuArithmeticFp32KernelCreator) REG_KERNEL(kCPU, kNumberTypeBool, PrimitiveType_LogicalAnd, CpuArithmeticFp32KernelCreator) +REG_KERNEL(kCPU, kNumberTypeInt32, PrimitiveType_LogicalAnd, CpuArithmeticFp32KernelCreator) REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_LogicalOr, CpuArithmeticFp32KernelCreator) REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Maximum, CpuArithmeticFp32KernelCreator) REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Minimum, CpuArithmeticFp32KernelCreator) diff --git a/mindspore/lite/src/runtime/kernel/arm/fp32/tensorlist_fromtensor_fp32.cc b/mindspore/lite/src/runtime/kernel/arm/fp32/tensorlist_fromtensor_fp32.cc index a2ffd8f78d..0c1f6ac174 100644 --- a/mindspore/lite/src/runtime/kernel/arm/fp32/tensorlist_fromtensor_fp32.cc +++ b/mindspore/lite/src/runtime/kernel/arm/fp32/tensorlist_fromtensor_fp32.cc @@ -59,9 +59,19 @@ int TensorListFromTensorCPUKernel::Init() { return IsCompatibleShape(); } -int TensorListFromTensorCPUKernel::ReSize() { return RET_OK; } +int TensorListFromTensorCPUKernel::ReSize() { + auto ret = this->Init(); + if (ret != RET_OK) { + MS_LOG(ERROR) << "Init kernel failed!"; + return ret; + } + return RET_OK; +} int TensorListFromTensorCPUKernel::Run() { + input0_ = in_tensors_[0]; // row tensor + input1_ = in_tensors_[1]; // element_shape tensor + output0_ = out_tensors_[0]; if (input0_->shape().size() == 0) { MS_LOG(ERROR) << "input0_->shape().size():" << input0_->shape().size() << " must be greater than 0"; } @@ -114,13 +124,6 @@ kernel::LiteKernel *CpuTensorListFromTensorFp32KernelCreator(const std::vectorInit(); - if (ret != RET_OK) { - MS_LOG(ERROR) << "Init kernel failed! name: " << op_parameter->name_ << ", type: " - << schema::EnumNamePrimitiveType(static_cast(op_parameter->type_)); - delete kernel; - return nullptr; - } return kernel; } diff --git a/mindspore/lite/src/runtime/kernel/arm/fp32/tensorlist_getitem_fp32.cc b/mindspore/lite/src/runtime/kernel/arm/fp32/tensorlist_getitem_fp32.cc index affa8f7545..7018bbed11 100644 --- a/mindspore/lite/src/runtime/kernel/arm/fp32/tensorlist_getitem_fp32.cc +++ b/mindspore/lite/src/runtime/kernel/arm/fp32/tensorlist_getitem_fp32.cc @@ -70,7 +70,14 @@ int TensorListGetItemCPUKernel::Run() { return RET_OK; } -int TensorListGetItemCPUKernel::ReSize() { return RET_OK; } +int TensorListGetItemCPUKernel::ReSize() { + auto ret = this->Init(); + if (ret != RET_OK) { + MS_LOG(ERROR) << "Init kernel failed!"; + return ret; + } + return RET_OK; +} kernel::LiteKernel *CpuTensorListGetItemFp32KernelCreator(const std::vector &inputs, const std::vector &outputs, @@ -93,15 +100,9 @@ kernel::LiteKernel *CpuTensorListGetItemFp32KernelCreator(const std::vectorInit(); - if (ret != RET_OK) { - MS_LOG(ERROR) << "Init kernel failed! name: " << op_parameter->name_ << ", type: " - << schema::EnumNamePrimitiveType(static_cast(op_parameter->type_)); - delete kernel; - return nullptr; - } return kernel; } REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_TensorListGetItem, CpuTensorListGetItemFp32KernelCreator) +REG_KERNEL(kCPU, kNumberTypeInt32, PrimitiveType_TensorListGetItem, CpuTensorListGetItemFp32KernelCreator) } // namespace mindspore::kernel diff --git a/mindspore/lite/src/runtime/kernel/arm/fp32/tensorlist_setitem_fp32.cc b/mindspore/lite/src/runtime/kernel/arm/fp32/tensorlist_setitem_fp32.cc index 7ce204a95d..74c325d301 100644 --- a/mindspore/lite/src/runtime/kernel/arm/fp32/tensorlist_setitem_fp32.cc +++ b/mindspore/lite/src/runtime/kernel/arm/fp32/tensorlist_setitem_fp32.cc @@ -116,4 +116,5 @@ kernel::LiteKernel *CpuTensorListSetItemFp32KernelCreator(const std::vector #include #include +#include #include "src/tensorlist.h" #include "src/ops/partial.h" #include "include/errorcode.h" @@ -59,7 +60,7 @@ int Scheduler::Schedule(std::vector *dst_kernels) { MS_LOG(ERROR) << "op infer shape failed."; return ret; } - ret = ScheduleSubGraphToKernels(kMainSubGraphIndex, dst_kernels); + ret = ScheduleSubGraphToKernels(kMainSubGraphIndex, dst_kernels, nullptr, nullptr); if (ret != RET_OK) { MS_LOG(ERROR) << "Schedule main subgraph to kernels failed."; return ret; @@ -115,6 +116,10 @@ int Scheduler::InferNodeShape(const lite::Model::Node *node, bool *infer_shape_i } primitive->set_infer_flag(!(*infer_shape_interrupt)); auto ret = primitive->InferShape(inputs, outputs); + if (ret == RET_INFER_INVALID) { + primitive->set_infer_flag(false); + *infer_shape_interrupt = true; + } if (ret == RET_OK) { for (auto &output : outputs) { if (output->ElementsNum() >= MAX_MALLOC_SIZE / static_cast(sizeof(int64_t))) { @@ -236,15 +241,15 @@ kernel::LiteKernel *Scheduler::SchedulePartialToKernel(const lite::Model::Node * auto partial_primitive = reinterpret_cast(primitive); auto sub_graph_index = partial_primitive->GetSubGraphIndex(); std::vector sub_kernels; - auto ret = ScheduleSubGraphToKernels(sub_graph_index, &sub_kernels); + std::vector in_tensors; + std::vector out_tensors; + auto ret = ScheduleSubGraphToKernels(sub_graph_index, &sub_kernels, &in_tensors, &out_tensors); if (ret != RET_OK) { MS_LOG(ERROR) << "Schedule partial failed, name: " << src_node->name_; return nullptr; } auto cur_sub_graph_type = mindspore::lite::Scheduler::GetKernelSubGraphType(sub_kernels.front()); - // for kernel::LiteKernelUtil::SubgraphInputTensors in CreateSubGraphKernel - FindAllInoutKernels(sub_kernels); - auto subgraph = CreateSubGraphKernel(sub_kernels, cur_sub_graph_type); + auto subgraph = CreateSubGraphKernel(sub_kernels, &in_tensors, &out_tensors, cur_sub_graph_type); subgraph->set_name("subgraph_" + src_node->name_); return subgraph; } @@ -266,7 +271,9 @@ kernel::LiteKernel *Scheduler::ScheduleNodeToKernel(const lite::Model::Node *src return kernel; } -int Scheduler::ScheduleSubGraphToKernels(size_t subgraph_index, std::vector *dst_kernels) { +int Scheduler::ScheduleSubGraphToKernels(size_t subgraph_index, std::vector *dst_kernels, + std::vector *in_tensors, + std::vector *out_tensors) { MS_ASSERT(src_model_ != nullptr); MS_ASSERT(!src_model_->sub_graphs_.empty()); MS_ASSERT(src_model_->sub_graphs_.size() > subgraph_index); @@ -292,6 +299,14 @@ int Scheduler::ScheduleSubGraphToKernels(size_t subgraph_index, std::vectorset_is_model_output(IsContain(graph_output_node_indexes_, size_t(node_index))); dst_kernels->emplace_back(kernel); } + if (in_tensors != nullptr) { + std::transform(subgraph->input_indices_.begin(), subgraph->input_indices_.end(), std::back_inserter(*in_tensors), + [&](const uint32_t index) { return this->src_tensors_.at(index); }); + } + if (out_tensors != nullptr) { + std::transform(subgraph->output_indices_.begin(), subgraph->output_indices_.end(), std::back_inserter(*out_tensors), + [&](const uint32_t index) { return this->src_tensors_.at(index); }); + } return RET_OK; } @@ -368,7 +383,7 @@ int Scheduler::ConstructSubGraphs(std::vector *kernels) { } auto cur_sub_graph_type = mindspore::lite::Scheduler::GetKernelSubGraphType(head_kernel); auto sub_kernels = FindAllSubGraphKernels(head_kernel, &is_kernel_finish); - auto subgraph = CreateSubGraphKernel(sub_kernels, cur_sub_graph_type); + auto subgraph = CreateSubGraphKernel(sub_kernels, nullptr, nullptr, cur_sub_graph_type); if (subgraph == nullptr) { MS_LOG(ERROR) << "Create SubGraphKernel failed"; return RET_ERROR; @@ -384,12 +399,14 @@ int Scheduler::ConstructSubGraphs(std::vector *kernels) { } return RET_OK; } + bool Scheduler::MergeOpIsReady(const kernel::LiteKernel *kernel, std::map is_kernel_finish) { std::map merge_in_tensors_map; for (auto merge_in_tensor : kernel->in_tensors()) { merge_in_tensors_map[merge_in_tensor] = false; - if (merge_in_tensor->category() == Tensor::CONST_TENSOR || merge_in_tensor->category() == Tensor::CONST_SCALAR) { + if (merge_in_tensor->category() == Tensor::CONST_TENSOR || merge_in_tensor->category() == Tensor::CONST_SCALAR || + merge_in_tensor->category() == Tensor::GRAPH_INPUT) { merge_in_tensors_map[merge_in_tensor] = true; } for (auto merge_in_kernel : kernel->in_kernels()) { @@ -408,12 +425,24 @@ bool Scheduler::MergeOpIsReady(const kernel::LiteKernel *kernel, } kernel::SubGraphKernel *Scheduler::CreateSubGraphKernel(const std::vector &kernels, + const std::vector *in_tensors, + const std::vector *out_tensors, kernel::SubGraphType type) { if (type == kernel::kApuSubGraph) { return nullptr; } - std::vector input_tensors = kernel::LiteKernelUtil::SubgraphInputTensors(kernels); - std::vector output_tensors = kernel::LiteKernelUtil::SubgraphOutputTensors(kernels); + std::vector input_tensors; + std::vector output_tensors; + if (in_tensors != nullptr) { + input_tensors = *in_tensors; + } else { + input_tensors = kernel::LiteKernelUtil::SubgraphInputTensors(kernels); + } + if (out_tensors != nullptr) { + output_tensors = *out_tensors; + } else { + output_tensors = kernel::LiteKernelUtil::SubgraphOutputTensors(kernels); + } std::vector input_kernels = kernel::LiteKernelUtil::SubgraphInputNodes(kernels); std::vector output_kernels = kernel::LiteKernelUtil::SubgraphOutputNodes(kernels); if (type == kernel::kGpuSubGraph) { @@ -468,7 +497,12 @@ TypeId Scheduler::GetFirstFp32Fp16OrInt8Type(const std::vector &in_ten } if (dtype == kObjectTypeTensorType) { auto tensor_list = reinterpret_cast(tensor); - return tensor_list->tensors_data_type(); + auto tensor_list_dtype = tensor_list->data_type(); + if (tensor_list_dtype == kNumberTypeFloat32 || tensor_list_dtype == kNumberTypeFloat16 || + tensor_list_dtype == kNumberTypeInt8 || tensor_list_dtype == kNumberTypeInt32 || + tensor_list_dtype == kNumberTypeBool) { + return tensor_list_dtype; + } } if (dtype == kNumberTypeFloat32 || dtype == kNumberTypeFloat16 || dtype == kNumberTypeInt8 || dtype == kNumberTypeInt32 || dtype == kNumberTypeBool) { diff --git a/mindspore/lite/src/scheduler.h b/mindspore/lite/src/scheduler.h index 3f9accf6b1..eff071ddd6 100644 --- a/mindspore/lite/src/scheduler.h +++ b/mindspore/lite/src/scheduler.h @@ -53,7 +53,8 @@ class Scheduler { // schedule a node to a kernel kernel::LiteKernel *ScheduleNodeToKernel(const lite::Model::Node *src_node); // schedule a Model::SubGraph into a vector of kernel and subgraph_kernel - int ScheduleSubGraphToKernels(size_t subgraph_index, std::vector *dst_kernels); + int ScheduleSubGraphToKernels(size_t subgraph_index, std::vector *dst_kernels, + std::vector *in_tensors, std::vector *out_tensors); // find in_kernels_ and out_kernels of kernel, sub_graph and nodes_ in sub_graph static void FindAllInoutKernels(const std::vector &kernels); @@ -63,6 +64,8 @@ class Scheduler { // create subgraph_kernel from a vector of kernel kernel::SubGraphKernel *CreateSubGraphKernel(const std::vector &kernels, + const std::vector *in_tensors, + const std::vector *out_tensors, kernel::SubGraphType type); bool MergeOpIsReady(const kernel::LiteKernel *kernel, std::map is_kernel_finish); diff --git a/mindspore/lite/src/tensor.h b/mindspore/lite/src/tensor.h index c146d04403..f945031e72 100644 --- a/mindspore/lite/src/tensor.h +++ b/mindspore/lite/src/tensor.h @@ -133,7 +133,7 @@ class Tensor : public mindspore::tensor::MSTensor { void set_quant_clusters(const std::vector &clusters); - bool IsConst() const { + virtual bool IsConst() const { return (this->category_ == CONST_TENSOR || this->category_ == CONST_SCALAR) && this->data_ != nullptr; } diff --git a/mindspore/lite/src/tensorlist.cc b/mindspore/lite/src/tensorlist.cc index 688016285b..85dc1dbdc5 100644 --- a/mindspore/lite/src/tensorlist.cc +++ b/mindspore/lite/src/tensorlist.cc @@ -24,8 +24,8 @@ namespace mindspore { namespace lite { -TensorList::TensorList(std::vector shape, std::vector element_shape) - : Tensor(kObjectTypeTensorType, shape), element_shape_(element_shape) {} +TensorList::TensorList(std::vector shape, std::vector element_shape, Category category) + : Tensor(kObjectTypeTensorType, shape, schema::Format::Format_NHWC, category), element_shape_(element_shape) {} TensorList::~TensorList() { if (!this->tensors_.empty()) { @@ -66,6 +66,9 @@ int TensorList::CopyTensorList(const TensorList &src, bool copy_data) { } int TensorList::CopyTensorData(const TensorList &src) { + if (src.tensors_.empty()) { + return RET_OK; + } for (int i = 0; i < this->ElementsNum(); ++i) { if (src.tensors_[i] == nullptr) { MS_LOG(ERROR) << "src tensors_[" << i << "] is nullptr!"; @@ -115,8 +118,14 @@ int TensorList::MallocTensorListData(TypeId dtype, const std::vector(allocator); + } // malloc data buf of each tensor in tensors_ for (int i = 0; i < this->ElementsNum(); ++i) { + if (tensors_.empty()) { + return RET_OK; + } auto tensor_ptr = this->tensors_[i]; if (tensor_ptr == nullptr) { MS_LOG(ERROR) << "tensors_[" << i << "] is nullptr!"; @@ -252,5 +261,8 @@ STATUS TensorList::Decode(const int *data) { } return RET_OK; } + +bool TensorList::IsConst() const { return this->category_ == CONST_TENSOR || this->category_ == CONST_SCALAR; } + } // namespace lite } // namespace mindspore diff --git a/mindspore/lite/src/tensorlist.h b/mindspore/lite/src/tensorlist.h index 580b78bcbd..1291c3c80d 100644 --- a/mindspore/lite/src/tensorlist.h +++ b/mindspore/lite/src/tensorlist.h @@ -60,7 +60,7 @@ class TensorList : public Tensor { public: TensorList() = default; - TensorList(std::vector shape, std::vector element_shape); + TensorList(std::vector shape, std::vector element_shape, Category category = VAR); ~TensorList() override; @@ -114,6 +114,8 @@ class TensorList : public Tensor { STATUS Decode(const int *data); + bool IsConst() const override; + protected: // The following functions must be masked. void set_data(void *data) override { return; } diff --git a/mindspore/lite/tools/converter/parser/tf/tf_util.cc b/mindspore/lite/tools/converter/parser/tf/tf_util.cc index 145b9f5f89..e95b040724 100644 --- a/mindspore/lite/tools/converter/parser/tf/tf_util.cc +++ b/mindspore/lite/tools/converter/parser/tf/tf_util.cc @@ -125,7 +125,7 @@ std::string TensorFlowUtils::GetFlattenNodeName(const std::string &input_name) { if (input_splits[2] == "0") { ret = input_splits[0]; } else { - ret = input_splits[0] + input_splits[2]; // multi output node + ret = input_splits[0] + ":" + input_splits[2]; // multi output node } } return ret;