| @@ -25,7 +25,7 @@ int Executor::CheckInputs(const std::vector<Tensor *> &in_tensors) { | |||||
| MS_LOG(ERROR) << "Graph input tensor is nullptr"; | MS_LOG(ERROR) << "Graph input tensor is nullptr"; | ||||
| return RET_ERROR; | 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; | MS_LOG(ERROR) << "Graph input tensor data is nullptr " << in_tensors; | ||||
| return RET_ERROR; | return RET_ERROR; | ||||
| } | } | ||||
| @@ -144,7 +144,7 @@ lite::Tensor *LiteSession::ConvertTensor(const schema::Tensor &src_tensor) { | |||||
| } | } | ||||
| lite::Tensor *dst_tensor = nullptr; | lite::Tensor *dst_tensor = nullptr; | ||||
| if (TypeId(src_tensor.dataType()) == kObjectTypeTensorType) { | if (TypeId(src_tensor.dataType()) == kObjectTypeTensorType) { | ||||
| dst_tensor = new (std::nothrow) TensorList(shape, std::vector<int>()); | |||||
| dst_tensor = new (std::nothrow) TensorList(shape, std::vector<int>(), src_category); | |||||
| } else { | } else { | ||||
| dst_tensor = new (std::nothrow) Tensor(TypeId(src_tensor.dataType()), shape, src_tensor.format(), src_category); | dst_tensor = new (std::nothrow) Tensor(TypeId(src_tensor.dataType()), shape, src_tensor.format(), src_category); | ||||
| } | } | ||||
| @@ -112,6 +112,9 @@ Registry TensorListFromTensorRegistry(schema::PrimitiveType_TensorListFromTensor | |||||
| #endif | #endif | ||||
| int TensorListFromTensor::InferShape(std::vector<lite::Tensor *> inputs_, std::vector<lite::Tensor *> outputs_) { | int TensorListFromTensor::InferShape(std::vector<lite::Tensor *> inputs_, std::vector<lite::Tensor *> outputs_) { | ||||
| if (!infer_flag()) { | |||||
| return RET_INFER_INVALID; | |||||
| } | |||||
| auto input0 = inputs_[0]; | auto input0 = inputs_[0]; | ||||
| MS_ASSERT(input0 != nullptr); | MS_ASSERT(input0 != nullptr); | ||||
| std::vector<int> input0_shape = input0->shape(); | std::vector<int> input0_shape = input0->shape(); | ||||
| @@ -117,6 +117,9 @@ int TensorListGetItem::MergeShape(const std::vector<int> &tmp) { | |||||
| } | } | ||||
| int TensorListGetItem::InferShape(std::vector<lite::Tensor *> inputs_, std::vector<lite::Tensor *> outputs_) { | int TensorListGetItem::InferShape(std::vector<lite::Tensor *> inputs_, std::vector<lite::Tensor *> outputs_) { | ||||
| if (!infer_flag()) { | |||||
| return RET_INFER_INVALID; | |||||
| } | |||||
| auto input0 = reinterpret_cast<TensorList *>(inputs_[0]); | auto input0 = reinterpret_cast<TensorList *>(inputs_[0]); | ||||
| auto get_index = inputs_[1]; | auto get_index = inputs_[1]; | ||||
| MS_ASSERT(get_index != nullptr); | MS_ASSERT(get_index != nullptr); | ||||
| @@ -125,8 +128,8 @@ int TensorListGetItem::InferShape(std::vector<lite::Tensor *> inputs_, std::vect | |||||
| return RET_ERROR; | return RET_ERROR; | ||||
| } | } | ||||
| if (get_index->data_c() == nullptr) { | 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<int *>(get_index->data_c())[0]; | index_ = reinterpret_cast<int *>(get_index->data_c())[0]; | ||||
| if (index_ < 0 || index_ > (input0->ElementsNum() - 1)) { | if (index_ < 0 || index_ > (input0->ElementsNum() - 1)) { | ||||
| @@ -117,6 +117,9 @@ bool TensorListStack::IsFullyDefined(const std::vector<int> &shape) const { | |||||
| } | } | ||||
| int TensorListStack::InferShape(std::vector<lite::Tensor *> inputs_, std::vector<lite::Tensor *> outputs_) { | int TensorListStack::InferShape(std::vector<lite::Tensor *> inputs_, std::vector<lite::Tensor *> outputs_) { | ||||
| if (!infer_flag()) { | |||||
| return RET_INFER_INVALID; | |||||
| } | |||||
| auto input0 = reinterpret_cast<TensorList *>(inputs_.front()); | auto input0 = reinterpret_cast<TensorList *>(inputs_.front()); | ||||
| MS_ASSERT(input0 != nullptr); | MS_ASSERT(input0 != nullptr); | ||||
| if (input0->ElementsNum() == 0) { | if (input0->ElementsNum() == 0) { | ||||
| @@ -130,7 +133,7 @@ int TensorListStack::InferShape(std::vector<lite::Tensor *> inputs_, std::vector | |||||
| return RET_NULL_PTR; | return RET_NULL_PTR; | ||||
| } | } | ||||
| auto ele_shape_ptr = reinterpret_cast<int *>(ele_shape->data_c()); | auto ele_shape_ptr = reinterpret_cast<int *>(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]); | output_shape_.push_back(ele_shape_ptr[i]); | ||||
| } | } | ||||
| @@ -17,6 +17,7 @@ | |||||
| #include "src/runtime/kernel/arm/base/merge.h" | #include "src/runtime/kernel/arm/base/merge.h" | ||||
| #include "src/kernel_registry.h" | #include "src/kernel_registry.h" | ||||
| #include "include/errorcode.h" | #include "include/errorcode.h" | ||||
| #include "src/tensorlist.h" | |||||
| using mindspore::lite::KernelRegistrar; | using mindspore::lite::KernelRegistrar; | ||||
| using mindspore::lite::RET_ERROR; | using mindspore::lite::RET_ERROR; | ||||
| @@ -56,31 +57,72 @@ bool MergeCPUKernel::IsReady(const std::vector<lite::Tensor *> &scope_tensors) { | |||||
| std::all_of(this->in_tensors().begin() + in_tensors().size() / 2, this->in_tensors().end(), | std::all_of(this->in_tensors().begin() + in_tensors().size() / 2, this->in_tensors().end(), | ||||
| [&](lite::Tensor *kernel_in_tensor) { | [&](lite::Tensor *kernel_in_tensor) { | ||||
| return kernel_in_tensor->IsConst() || kernel_in_tensor->IsGraphInput() || | 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::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() { | int MergeCPUKernel::Run() { | ||||
| MS_ASSERT(in_tensors_.size() == 2 * out_tensors_.size()); | MS_ASSERT(in_tensors_.size() == 2 * out_tensors_.size()); | ||||
| int in_tesnor_part_one = 0; | 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++) { | for (size_t i = 0; i < out_tensors().size(); i++) { | ||||
| auto out_data = out_tensors_[i]->data_c(); | auto out_data = out_tensors_[i]->data_c(); | ||||
| auto in_data = in_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<lite::TensorList *>(in_tensors_[i]); | |||||
| auto out_tensor_list = reinterpret_cast<lite::TensorList *>(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(in_data != nullptr); | ||||
| MS_ASSERT(out_data != nullptr); | MS_ASSERT(out_data != nullptr); | ||||
| memcpy(out_data, in_data, in_tensors_[i]->Size()); | 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++) { | for (size_t i = 0; i < out_tensors().size(); i++) { | ||||
| auto out_data = out_tensors_[i]->data_c(); | auto out_data = out_tensors_[i]->data_c(); | ||||
| auto in_data = in_tensors_[i + in_tensor_part_two]->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<lite::TensorList *>(in_tensors_[i + in_tensor_part_two]); | |||||
| auto out_tensor_list = reinterpret_cast<lite::TensorList *>(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(in_data != nullptr); | ||||
| MS_ASSERT(out_data != nullptr); | MS_ASSERT(out_data != nullptr); | ||||
| memcpy(out_data, in_data, in_tensors_[i]->Size()); | memcpy(out_data, in_data, in_tensors_[i]->Size()); | ||||
| @@ -39,6 +39,7 @@ class MergeCPUKernel : public LiteKernel { | |||||
| int Init() override; | int Init() override; | ||||
| int ReSize() override; | int ReSize() override; | ||||
| int Run() override; | int Run() override; | ||||
| bool PartialInputReady(int num_begin, int num_end); | |||||
| private: | private: | ||||
| MergeParameter *merge_param_ = nullptr; | MergeParameter *merge_param_ = nullptr; | ||||
| @@ -17,6 +17,7 @@ | |||||
| #include "src/runtime/kernel/arm/base/switch.h" | #include "src/runtime/kernel/arm/base/switch.h" | ||||
| #include "src/kernel_registry.h" | #include "src/kernel_registry.h" | ||||
| #include "include/errorcode.h" | #include "include/errorcode.h" | ||||
| #include "src/tensorlist.h" | |||||
| using mindspore::lite::KernelRegistrar; | using mindspore::lite::KernelRegistrar; | ||||
| using mindspore::lite::RET_ERROR; | using mindspore::lite::RET_ERROR; | ||||
| @@ -28,8 +29,8 @@ int SwitchCPUKernel::PostProcess() { | |||||
| auto bool_tensor = in_tensors_.front(); | auto bool_tensor = in_tensors_.front(); | ||||
| MS_ASSERT(bool_tensor != nullptr); | MS_ASSERT(bool_tensor != nullptr); | ||||
| MS_ASSERT(bool_tensor->data_type() == kNumberTypeBool); | 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 *>(bool_tensor->data_c()); | auto active = static_cast<bool *>(bool_tensor->data_c()); | ||||
| if (active == nullptr) { | if (active == nullptr) { | ||||
| MS_LOG(ERROR) << "data of bool tensor is 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::Init() { return RET_OK; } | ||||
| int SwitchCPUKernel::ReSize() { return RET_ERROR; } | |||||
| int SwitchCPUKernel::ReSize() { return RET_OK; } | |||||
| // inputs: bool*1 data*n | // inputs: bool*1 data*n | ||||
| // output: true-data*n, false-data*n | // output: true-data*n, false-data*n | ||||
| @@ -56,8 +57,8 @@ int SwitchCPUKernel::Run() { | |||||
| auto bool_tensor = in_tensors_.front(); | auto bool_tensor = in_tensors_.front(); | ||||
| MS_ASSERT(bool_tensor != nullptr); | MS_ASSERT(bool_tensor != nullptr); | ||||
| MS_ASSERT(bool_tensor->data_type() == kNumberTypeBool); | 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 *>(bool_tensor->data_c()); | auto active = static_cast<bool *>(bool_tensor->data_c()); | ||||
| if (active == nullptr) { | if (active == nullptr) { | ||||
| MS_LOG(ERROR) << "data of bool tensor is nullptr"; | MS_LOG(ERROR) << "data of bool tensor is nullptr"; | ||||
| @@ -68,6 +69,14 @@ int SwitchCPUKernel::Run() { | |||||
| while (in_index < in_tensors_.size()) { | while (in_index < in_tensors_.size()) { | ||||
| auto in_tensor = in_tensors_.at(in_index++); | auto in_tensor = in_tensors_.at(in_index++); | ||||
| auto out_tensor = out_tensors_.at(out_index++); | auto out_tensor = out_tensors_.at(out_index++); | ||||
| // copy for tensorlist | |||||
| if (in_tensor->data_type() == kObjectTypeTensorType) { | |||||
| auto in_tensor_list = reinterpret_cast<lite::TensorList *>(in_tensor); | |||||
| auto out_tensor_list = reinterpret_cast<lite::TensorList *>(out_tensor); | |||||
| *out_tensor_list = *in_tensor_list; | |||||
| continue; | |||||
| } | |||||
| // copy for tensor | |||||
| MS_ASSERT(in_tensor != nullptr); | MS_ASSERT(in_tensor != nullptr); | ||||
| MS_ASSERT(out_tensor != nullptr); | MS_ASSERT(out_tensor != nullptr); | ||||
| auto input = in_tensor->data_c(); | auto input = in_tensor->data_c(); | ||||
| @@ -111,4 +120,5 @@ kernel::LiteKernel *CpuSwitchKernelCreator(const std::vector<lite::Tensor *> &in | |||||
| REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Switch, CpuSwitchKernelCreator) | REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Switch, CpuSwitchKernelCreator) | ||||
| REG_KERNEL(kCPU, kNumberTypeBool, PrimitiveType_Switch, CpuSwitchKernelCreator) | REG_KERNEL(kCPU, kNumberTypeBool, PrimitiveType_Switch, CpuSwitchKernelCreator) | ||||
| REG_KERNEL(kCPU, kNumberTypeInt32, PrimitiveType_Switch, CpuSwitchKernelCreator) | |||||
| } // namespace mindspore::kernel | } // namespace mindspore::kernel | ||||
| @@ -554,6 +554,7 @@ REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Mod, CpuArithmeticFp32KernelC | |||||
| REG_KERNEL(kCPU, kNumberTypeInt32, PrimitiveType_Mod, CpuArithmeticFp32KernelCreator) | REG_KERNEL(kCPU, kNumberTypeInt32, PrimitiveType_Mod, CpuArithmeticFp32KernelCreator) | ||||
| REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_LogicalAnd, CpuArithmeticFp32KernelCreator) | REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_LogicalAnd, CpuArithmeticFp32KernelCreator) | ||||
| REG_KERNEL(kCPU, kNumberTypeBool, 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_LogicalOr, CpuArithmeticFp32KernelCreator) | ||||
| REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Maximum, CpuArithmeticFp32KernelCreator) | REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Maximum, CpuArithmeticFp32KernelCreator) | ||||
| REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Minimum, CpuArithmeticFp32KernelCreator) | REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_Minimum, CpuArithmeticFp32KernelCreator) | ||||
| @@ -59,9 +59,19 @@ int TensorListFromTensorCPUKernel::Init() { | |||||
| return IsCompatibleShape(); | 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() { | 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) { | if (input0_->shape().size() == 0) { | ||||
| MS_LOG(ERROR) << "input0_->shape().size():" << input0_->shape().size() << " must be greater than 0"; | MS_LOG(ERROR) << "input0_->shape().size():" << input0_->shape().size() << " must be greater than 0"; | ||||
| } | } | ||||
| @@ -114,13 +124,6 @@ kernel::LiteKernel *CpuTensorListFromTensorFp32KernelCreator(const std::vector<l | |||||
| free(op_parameter); | free(op_parameter); | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| auto ret = kernel->Init(); | |||||
| if (ret != RET_OK) { | |||||
| MS_LOG(ERROR) << "Init kernel failed! name: " << op_parameter->name_ << ", type: " | |||||
| << schema::EnumNamePrimitiveType(static_cast<schema::PrimitiveType>(op_parameter->type_)); | |||||
| delete kernel; | |||||
| return nullptr; | |||||
| } | |||||
| return kernel; | return kernel; | ||||
| } | } | ||||
| @@ -70,7 +70,14 @@ int TensorListGetItemCPUKernel::Run() { | |||||
| return RET_OK; | 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<lite::Tensor *> &inputs, | kernel::LiteKernel *CpuTensorListGetItemFp32KernelCreator(const std::vector<lite::Tensor *> &inputs, | ||||
| const std::vector<lite::Tensor *> &outputs, | const std::vector<lite::Tensor *> &outputs, | ||||
| @@ -93,15 +100,9 @@ kernel::LiteKernel *CpuTensorListGetItemFp32KernelCreator(const std::vector<lite | |||||
| free(op_parameter); | free(op_parameter); | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| auto ret = kernel->Init(); | |||||
| if (ret != RET_OK) { | |||||
| MS_LOG(ERROR) << "Init kernel failed! name: " << op_parameter->name_ << ", type: " | |||||
| << schema::EnumNamePrimitiveType(static_cast<schema::PrimitiveType>(op_parameter->type_)); | |||||
| delete kernel; | |||||
| return nullptr; | |||||
| } | |||||
| return kernel; | return kernel; | ||||
| } | } | ||||
| REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_TensorListGetItem, CpuTensorListGetItemFp32KernelCreator) | REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_TensorListGetItem, CpuTensorListGetItemFp32KernelCreator) | ||||
| REG_KERNEL(kCPU, kNumberTypeInt32, PrimitiveType_TensorListGetItem, CpuTensorListGetItemFp32KernelCreator) | |||||
| } // namespace mindspore::kernel | } // namespace mindspore::kernel | ||||
| @@ -116,4 +116,5 @@ kernel::LiteKernel *CpuTensorListSetItemFp32KernelCreator(const std::vector<lite | |||||
| } | } | ||||
| REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_TensorListSetItem, CpuTensorListSetItemFp32KernelCreator) | REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_TensorListSetItem, CpuTensorListSetItemFp32KernelCreator) | ||||
| REG_KERNEL(kCPU, kNumberTypeInt32, PrimitiveType_TensorListSetItem, CpuTensorListSetItemFp32KernelCreator) | |||||
| } // namespace mindspore::kernel | } // namespace mindspore::kernel | ||||
| @@ -198,4 +198,5 @@ kernel::LiteKernel *CpuTensorListStackFp32KernelCreator(const std::vector<lite:: | |||||
| } | } | ||||
| REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_TensorListStack, CpuTensorListStackFp32KernelCreator) | REG_KERNEL(kCPU, kNumberTypeFloat32, PrimitiveType_TensorListStack, CpuTensorListStackFp32KernelCreator) | ||||
| REG_KERNEL(kCPU, kNumberTypeInt32, PrimitiveType_TensorListStack, CpuTensorListStackFp32KernelCreator) | |||||
| } // namespace mindspore::kernel | } // namespace mindspore::kernel | ||||
| @@ -19,6 +19,7 @@ | |||||
| #include <queue> | #include <queue> | ||||
| #include <string> | #include <string> | ||||
| #include <vector> | #include <vector> | ||||
| #include <algorithm> | |||||
| #include "src/tensorlist.h" | #include "src/tensorlist.h" | ||||
| #include "src/ops/partial.h" | #include "src/ops/partial.h" | ||||
| #include "include/errorcode.h" | #include "include/errorcode.h" | ||||
| @@ -59,7 +60,7 @@ int Scheduler::Schedule(std::vector<kernel::LiteKernel *> *dst_kernels) { | |||||
| MS_LOG(ERROR) << "op infer shape failed."; | MS_LOG(ERROR) << "op infer shape failed."; | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| ret = ScheduleSubGraphToKernels(kMainSubGraphIndex, dst_kernels); | |||||
| ret = ScheduleSubGraphToKernels(kMainSubGraphIndex, dst_kernels, nullptr, nullptr); | |||||
| if (ret != RET_OK) { | if (ret != RET_OK) { | ||||
| MS_LOG(ERROR) << "Schedule main subgraph to kernels failed."; | MS_LOG(ERROR) << "Schedule main subgraph to kernels failed."; | ||||
| return ret; | 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)); | primitive->set_infer_flag(!(*infer_shape_interrupt)); | ||||
| auto ret = primitive->InferShape(inputs, outputs); | auto ret = primitive->InferShape(inputs, outputs); | ||||
| if (ret == RET_INFER_INVALID) { | |||||
| primitive->set_infer_flag(false); | |||||
| *infer_shape_interrupt = true; | |||||
| } | |||||
| if (ret == RET_OK) { | if (ret == RET_OK) { | ||||
| for (auto &output : outputs) { | for (auto &output : outputs) { | ||||
| if (output->ElementsNum() >= MAX_MALLOC_SIZE / static_cast<int>(sizeof(int64_t))) { | if (output->ElementsNum() >= MAX_MALLOC_SIZE / static_cast<int>(sizeof(int64_t))) { | ||||
| @@ -236,15 +241,15 @@ kernel::LiteKernel *Scheduler::SchedulePartialToKernel(const lite::Model::Node * | |||||
| auto partial_primitive = reinterpret_cast<lite::Partial *>(primitive); | auto partial_primitive = reinterpret_cast<lite::Partial *>(primitive); | ||||
| auto sub_graph_index = partial_primitive->GetSubGraphIndex(); | auto sub_graph_index = partial_primitive->GetSubGraphIndex(); | ||||
| std::vector<kernel::LiteKernel *> sub_kernels; | std::vector<kernel::LiteKernel *> sub_kernels; | ||||
| auto ret = ScheduleSubGraphToKernels(sub_graph_index, &sub_kernels); | |||||
| std::vector<lite::Tensor *> in_tensors; | |||||
| std::vector<lite::Tensor *> out_tensors; | |||||
| auto ret = ScheduleSubGraphToKernels(sub_graph_index, &sub_kernels, &in_tensors, &out_tensors); | |||||
| if (ret != RET_OK) { | if (ret != RET_OK) { | ||||
| MS_LOG(ERROR) << "Schedule partial failed, name: " << src_node->name_; | MS_LOG(ERROR) << "Schedule partial failed, name: " << src_node->name_; | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| auto cur_sub_graph_type = mindspore::lite::Scheduler::GetKernelSubGraphType(sub_kernels.front()); | 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_); | subgraph->set_name("subgraph_" + src_node->name_); | ||||
| return subgraph; | return subgraph; | ||||
| } | } | ||||
| @@ -266,7 +271,9 @@ kernel::LiteKernel *Scheduler::ScheduleNodeToKernel(const lite::Model::Node *src | |||||
| return kernel; | return kernel; | ||||
| } | } | ||||
| int Scheduler::ScheduleSubGraphToKernels(size_t subgraph_index, std::vector<kernel::LiteKernel *> *dst_kernels) { | |||||
| int Scheduler::ScheduleSubGraphToKernels(size_t subgraph_index, std::vector<kernel::LiteKernel *> *dst_kernels, | |||||
| std::vector<lite::Tensor *> *in_tensors, | |||||
| std::vector<lite::Tensor *> *out_tensors) { | |||||
| MS_ASSERT(src_model_ != nullptr); | MS_ASSERT(src_model_ != nullptr); | ||||
| MS_ASSERT(!src_model_->sub_graphs_.empty()); | MS_ASSERT(!src_model_->sub_graphs_.empty()); | ||||
| MS_ASSERT(src_model_->sub_graphs_.size() > subgraph_index); | MS_ASSERT(src_model_->sub_graphs_.size() > subgraph_index); | ||||
| @@ -292,6 +299,14 @@ int Scheduler::ScheduleSubGraphToKernels(size_t subgraph_index, std::vector<kern | |||||
| kernel->set_is_model_output(IsContain(graph_output_node_indexes_, size_t(node_index))); | kernel->set_is_model_output(IsContain(graph_output_node_indexes_, size_t(node_index))); | ||||
| dst_kernels->emplace_back(kernel); | 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; | return RET_OK; | ||||
| } | } | ||||
| @@ -368,7 +383,7 @@ int Scheduler::ConstructSubGraphs(std::vector<kernel::LiteKernel *> *kernels) { | |||||
| } | } | ||||
| auto cur_sub_graph_type = mindspore::lite::Scheduler::GetKernelSubGraphType(head_kernel); | auto cur_sub_graph_type = mindspore::lite::Scheduler::GetKernelSubGraphType(head_kernel); | ||||
| auto sub_kernels = FindAllSubGraphKernels(head_kernel, &is_kernel_finish); | 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) { | if (subgraph == nullptr) { | ||||
| MS_LOG(ERROR) << "Create SubGraphKernel failed"; | MS_LOG(ERROR) << "Create SubGraphKernel failed"; | ||||
| return RET_ERROR; | return RET_ERROR; | ||||
| @@ -384,12 +399,14 @@ int Scheduler::ConstructSubGraphs(std::vector<kernel::LiteKernel *> *kernels) { | |||||
| } | } | ||||
| return RET_OK; | return RET_OK; | ||||
| } | } | ||||
| bool Scheduler::MergeOpIsReady(const kernel::LiteKernel *kernel, | bool Scheduler::MergeOpIsReady(const kernel::LiteKernel *kernel, | ||||
| std::map<const kernel::LiteKernel *, bool> is_kernel_finish) { | std::map<const kernel::LiteKernel *, bool> is_kernel_finish) { | ||||
| std::map<const lite::Tensor *, bool> merge_in_tensors_map; | std::map<const lite::Tensor *, bool> merge_in_tensors_map; | ||||
| for (auto merge_in_tensor : kernel->in_tensors()) { | for (auto merge_in_tensor : kernel->in_tensors()) { | ||||
| merge_in_tensors_map[merge_in_tensor] = false; | 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; | merge_in_tensors_map[merge_in_tensor] = true; | ||||
| } | } | ||||
| for (auto merge_in_kernel : kernel->in_kernels()) { | 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<kernel::LiteKernel *> &kernels, | kernel::SubGraphKernel *Scheduler::CreateSubGraphKernel(const std::vector<kernel::LiteKernel *> &kernels, | ||||
| const std::vector<lite::Tensor *> *in_tensors, | |||||
| const std::vector<lite::Tensor *> *out_tensors, | |||||
| kernel::SubGraphType type) { | kernel::SubGraphType type) { | ||||
| if (type == kernel::kApuSubGraph) { | if (type == kernel::kApuSubGraph) { | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| std::vector<Tensor *> input_tensors = kernel::LiteKernelUtil::SubgraphInputTensors(kernels); | |||||
| std::vector<Tensor *> output_tensors = kernel::LiteKernelUtil::SubgraphOutputTensors(kernels); | |||||
| std::vector<Tensor *> input_tensors; | |||||
| std::vector<Tensor *> 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<kernel::LiteKernel *> input_kernels = kernel::LiteKernelUtil::SubgraphInputNodes(kernels); | std::vector<kernel::LiteKernel *> input_kernels = kernel::LiteKernelUtil::SubgraphInputNodes(kernels); | ||||
| std::vector<kernel::LiteKernel *> output_kernels = kernel::LiteKernelUtil::SubgraphOutputNodes(kernels); | std::vector<kernel::LiteKernel *> output_kernels = kernel::LiteKernelUtil::SubgraphOutputNodes(kernels); | ||||
| if (type == kernel::kGpuSubGraph) { | if (type == kernel::kGpuSubGraph) { | ||||
| @@ -468,7 +497,12 @@ TypeId Scheduler::GetFirstFp32Fp16OrInt8Type(const std::vector<Tensor *> &in_ten | |||||
| } | } | ||||
| if (dtype == kObjectTypeTensorType) { | if (dtype == kObjectTypeTensorType) { | ||||
| auto tensor_list = reinterpret_cast<TensorList *>(tensor); | auto tensor_list = reinterpret_cast<TensorList *>(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 || | if (dtype == kNumberTypeFloat32 || dtype == kNumberTypeFloat16 || dtype == kNumberTypeInt8 || | ||||
| dtype == kNumberTypeInt32 || dtype == kNumberTypeBool) { | dtype == kNumberTypeInt32 || dtype == kNumberTypeBool) { | ||||
| @@ -53,7 +53,8 @@ class Scheduler { | |||||
| // schedule a node to a kernel | // schedule a node to a kernel | ||||
| kernel::LiteKernel *ScheduleNodeToKernel(const lite::Model::Node *src_node); | kernel::LiteKernel *ScheduleNodeToKernel(const lite::Model::Node *src_node); | ||||
| // schedule a Model::SubGraph into a vector of kernel and subgraph_kernel | // schedule a Model::SubGraph into a vector of kernel and subgraph_kernel | ||||
| int ScheduleSubGraphToKernels(size_t subgraph_index, std::vector<kernel::LiteKernel *> *dst_kernels); | |||||
| int ScheduleSubGraphToKernels(size_t subgraph_index, std::vector<kernel::LiteKernel *> *dst_kernels, | |||||
| std::vector<lite::Tensor *> *in_tensors, std::vector<lite::Tensor *> *out_tensors); | |||||
| // find in_kernels_ and out_kernels of kernel, sub_graph and nodes_ in sub_graph | // find in_kernels_ and out_kernels of kernel, sub_graph and nodes_ in sub_graph | ||||
| static void FindAllInoutKernels(const std::vector<kernel::LiteKernel *> &kernels); | static void FindAllInoutKernels(const std::vector<kernel::LiteKernel *> &kernels); | ||||
| @@ -63,6 +64,8 @@ class Scheduler { | |||||
| // create subgraph_kernel from a vector of kernel | // create subgraph_kernel from a vector of kernel | ||||
| kernel::SubGraphKernel *CreateSubGraphKernel(const std::vector<kernel::LiteKernel *> &kernels, | kernel::SubGraphKernel *CreateSubGraphKernel(const std::vector<kernel::LiteKernel *> &kernels, | ||||
| const std::vector<lite::Tensor *> *in_tensors, | |||||
| const std::vector<lite::Tensor *> *out_tensors, | |||||
| kernel::SubGraphType type); | kernel::SubGraphType type); | ||||
| bool MergeOpIsReady(const kernel::LiteKernel *kernel, std::map<const kernel::LiteKernel *, bool> is_kernel_finish); | bool MergeOpIsReady(const kernel::LiteKernel *kernel, std::map<const kernel::LiteKernel *, bool> is_kernel_finish); | ||||
| @@ -133,7 +133,7 @@ class Tensor : public mindspore::tensor::MSTensor { | |||||
| void set_quant_clusters(const std::vector<float> &clusters); | void set_quant_clusters(const std::vector<float> &clusters); | ||||
| 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->data_ != nullptr; | ||||
| } | } | ||||
| @@ -24,8 +24,8 @@ | |||||
| namespace mindspore { | namespace mindspore { | ||||
| namespace lite { | namespace lite { | ||||
| TensorList::TensorList(std::vector<int> shape, std::vector<int> element_shape) | |||||
| : Tensor(kObjectTypeTensorType, shape), element_shape_(element_shape) {} | |||||
| TensorList::TensorList(std::vector<int> shape, std::vector<int> element_shape, Category category) | |||||
| : Tensor(kObjectTypeTensorType, shape, schema::Format::Format_NHWC, category), element_shape_(element_shape) {} | |||||
| TensorList::~TensorList() { | TensorList::~TensorList() { | ||||
| if (!this->tensors_.empty()) { | if (!this->tensors_.empty()) { | ||||
| @@ -66,6 +66,9 @@ int TensorList::CopyTensorList(const TensorList &src, bool copy_data) { | |||||
| } | } | ||||
| int TensorList::CopyTensorData(const TensorList &src) { | int TensorList::CopyTensorData(const TensorList &src) { | ||||
| if (src.tensors_.empty()) { | |||||
| return RET_OK; | |||||
| } | |||||
| for (int i = 0; i < this->ElementsNum(); ++i) { | for (int i = 0; i < this->ElementsNum(); ++i) { | ||||
| if (src.tensors_[i] == nullptr) { | if (src.tensors_[i] == nullptr) { | ||||
| MS_LOG(ERROR) << "src tensors_[" << i << "] is nullptr!"; | MS_LOG(ERROR) << "src tensors_[" << i << "] is nullptr!"; | ||||
| @@ -115,8 +118,14 @@ int TensorList::MallocTensorListData(TypeId dtype, const std::vector<std::vector | |||||
| } | } | ||||
| int TensorList::MallocData(const mindspore::lite::Allocator *allocator) { | int TensorList::MallocData(const mindspore::lite::Allocator *allocator) { | ||||
| if (allocator != nullptr) { | |||||
| allocator_ = const_cast<mindspore::lite::Allocator *>(allocator); | |||||
| } | |||||
| // malloc data buf of each tensor in tensors_ | // malloc data buf of each tensor in tensors_ | ||||
| for (int i = 0; i < this->ElementsNum(); ++i) { | for (int i = 0; i < this->ElementsNum(); ++i) { | ||||
| if (tensors_.empty()) { | |||||
| return RET_OK; | |||||
| } | |||||
| auto tensor_ptr = this->tensors_[i]; | auto tensor_ptr = this->tensors_[i]; | ||||
| if (tensor_ptr == nullptr) { | if (tensor_ptr == nullptr) { | ||||
| MS_LOG(ERROR) << "tensors_[" << i << "] is nullptr!"; | MS_LOG(ERROR) << "tensors_[" << i << "] is nullptr!"; | ||||
| @@ -252,5 +261,8 @@ STATUS TensorList::Decode(const int *data) { | |||||
| } | } | ||||
| return RET_OK; | return RET_OK; | ||||
| } | } | ||||
| bool TensorList::IsConst() const { return this->category_ == CONST_TENSOR || this->category_ == CONST_SCALAR; } | |||||
| } // namespace lite | } // namespace lite | ||||
| } // namespace mindspore | } // namespace mindspore | ||||
| @@ -60,7 +60,7 @@ class TensorList : public Tensor { | |||||
| public: | public: | ||||
| TensorList() = default; | TensorList() = default; | ||||
| TensorList(std::vector<int> shape, std::vector<int> element_shape); | |||||
| TensorList(std::vector<int> shape, std::vector<int> element_shape, Category category = VAR); | |||||
| ~TensorList() override; | ~TensorList() override; | ||||
| @@ -114,6 +114,8 @@ class TensorList : public Tensor { | |||||
| STATUS Decode(const int *data); | STATUS Decode(const int *data); | ||||
| bool IsConst() const override; | |||||
| protected: | protected: | ||||
| // The following functions must be masked. | // The following functions must be masked. | ||||
| void set_data(void *data) override { return; } | void set_data(void *data) override { return; } | ||||
| @@ -125,7 +125,7 @@ std::string TensorFlowUtils::GetFlattenNodeName(const std::string &input_name) { | |||||
| if (input_splits[2] == "0") { | if (input_splits[2] == "0") { | ||||
| ret = input_splits[0]; | ret = input_splits[0]; | ||||
| } else { | } else { | ||||
| ret = input_splits[0] + input_splits[2]; // multi output node | |||||
| ret = input_splits[0] + ":" + input_splits[2]; // multi output node | |||||
| } | } | ||||
| } | } | ||||
| return ret; | return ret; | ||||