diff --git a/mindspore/lite/src/CMakeLists.txt b/mindspore/lite/src/CMakeLists.txt index b4c68eae56..61fb583395 100644 --- a/mindspore/lite/src/CMakeLists.txt +++ b/mindspore/lite/src/CMakeLists.txt @@ -56,6 +56,7 @@ set(LITE_SRC ${CMAKE_CURRENT_SOURCE_DIR}/lite_model.cc ${CMAKE_CURRENT_SOURCE_DIR}/kernel_registry.cc ${CMAKE_CURRENT_SOURCE_DIR}/lite_kernel.cc + ${CMAKE_CURRENT_SOURCE_DIR}/lite_kernel_util.cc ${CMAKE_CURRENT_SOURCE_DIR}/sub_graph_kernel.cc ${CMAKE_CURRENT_SOURCE_DIR}/sub_graph_split.cc ${CMAKE_CURRENT_SOURCE_DIR}/scheduler.cc diff --git a/mindspore/lite/src/lite_kernel.cc b/mindspore/lite/src/lite_kernel.cc index 3143174b3d..3697bd1749 100644 --- a/mindspore/lite/src/lite_kernel.cc +++ b/mindspore/lite/src/lite_kernel.cc @@ -16,7 +16,6 @@ #include "src/lite_kernel.h" #include -#include #include #include "src/tensor.h" #include "src/common/utils.h" @@ -224,170 +223,4 @@ void LiteKernel::FindInoutKernels(const std::vector &scope } } } - -std::vector LiteKernelUtil::SubgraphInputNodes(const std::vector &kernels) { - std::set input_nodes; - for (const auto &kernel : kernels) { - // if kernel has no pre-kernel, kernel is a graph input, it must be a subgraph input - if (kernel->in_kernels().empty() && !kernel->in_tensors().empty()) { - input_nodes.insert(kernel); - continue; - } - auto all_input_tensors = kernel->in_tensors(); - // remove all const tensor from input tensors - for (auto iter = all_input_tensors.begin(); iter != all_input_tensors.end();) { - if ((*iter)->IsConst()) { - iter = all_input_tensors.erase(iter); - } else { - iter++; - } - } - for (const auto &kernel_in_subgraph : kernels) { - // remove input tensors from kernel in subgraph - for (const auto *tensor : kernel_in_subgraph->out_tensors()) { - auto ret = std::find(all_input_tensors.begin(), all_input_tensors.end(), tensor); - if (ret != all_input_tensors.end()) { - all_input_tensors.erase(ret); - } - } - } - // if some input tensor is not from kernel in subgraph - if (!all_input_tensors.empty()) { - input_nodes.insert(kernel); - } - } - std::vector result; - result.insert(result.end(), input_nodes.begin(), input_nodes.end()); - return result; -} - -std::vector LiteKernelUtil::SubgraphOutputNodes( - const std::vector &kernels) { - std::set output_nodes; - // if kernel has no post-kernel, kernel is a graph output, it must be a subgraph output - for (const auto &kernel : kernels) { - if (kernel->is_model_output() || (kernel->out_kernels().empty() && !kernel->out_tensors().empty())) { - output_nodes.insert(kernel); - continue; - } - for (const auto &output : kernel->out_kernels()) { - auto out_kernel_in_graph = std::find(kernels.begin(), kernels.end(), output); - if (out_kernel_in_graph == kernels.end()) { - output_nodes.insert(kernel); - break; - } - } - } - std::vector result; - result.insert(result.end(), output_nodes.begin(), output_nodes.end()); - return result; -} - -std::vector LiteKernelUtil::SubgraphInputTensors(const std::vector &kernels) { - std::set input_tensors; - std::vector input_nodes = SubgraphInputNodes(kernels); - for (const auto &input_node : input_nodes) { - auto &in_node_in_kernels = input_node->in_kernels(); - auto &in_node_in_tensors = input_node->in_tensors(); - for (auto &in_node_in_tensor : in_node_in_tensors) { - if (in_node_in_tensor->IsGraphInput()) { - input_tensors.insert(in_node_in_tensor); - } - } - for (auto in_node_in_kernel : in_node_in_kernels) { - auto iter = std::find(kernels.begin(), kernels.end(), in_node_in_kernel); - if (iter != kernels.end()) { - continue; - } - auto &outer_in_kernel_out_tensors = in_node_in_kernel->out_tensors(); - for (auto in_node_in_tensor : in_node_in_tensors) { - auto outer_in_kernel_out_tensors_iter = - std::find(outer_in_kernel_out_tensors.begin(), outer_in_kernel_out_tensors.end(), in_node_in_tensor); - if (outer_in_kernel_out_tensors_iter != outer_in_kernel_out_tensors.end()) { - input_tensors.insert(in_node_in_tensor); - } - } - } - } - std::vector result; - result.insert(result.end(), input_tensors.begin(), input_tensors.end()); - return result; -} - -std::vector LiteKernelUtil::SubgraphOutputTensors(const std::vector &kernels) { - std::set output_tensors; - std::vector output_nodes = SubgraphOutputNodes(kernels); - for (const auto &output_kernel : output_nodes) { - auto &outer_out_kernels = output_kernel->out_kernels(); - auto &out_kernel_out_tensors = output_kernel->out_tensors(); - for (auto out_kernel_out_tensor : out_kernel_out_tensors) { - if (out_kernel_out_tensor->IsGraphOutput()) { - output_tensors.insert(out_kernel_out_tensor); - } - } - if (!outer_out_kernels.empty()) { - for (auto outer_out_kernel : outer_out_kernels) { - auto iter = std::find(kernels.begin(), kernels.end(), outer_out_kernel); - if (iter != kernels.end()) { - continue; - } - auto &outer_out_kernel_in_tensors = outer_out_kernel->in_tensors(); - for (auto out_kernel_out_tensor : out_kernel_out_tensors) { - auto outer_out_kernel_in_tensors_iter = - std::find(outer_out_kernel_in_tensors.begin(), outer_out_kernel_in_tensors.end(), out_kernel_out_tensor); - if (outer_out_kernel_in_tensors_iter != outer_out_kernel_in_tensors.end()) { - output_tensors.insert(out_kernel_out_tensor); - } - } - } - } - } - std::vector result; - result.insert(result.end(), output_tensors.begin(), output_tensors.end()); - return result; -} - -int LiteKernelUtil::TopologicalSortKernels(std::vector *kernels) { - auto old_kernels = *kernels; - kernels->clear(); - std::queue kernel_queue; - for (auto kernel : old_kernels) { - if (kernel->in_kernels().empty()) { - kernel_queue.push(kernel); - kernels->emplace_back(kernel); - } - } - while (!kernel_queue.empty()) { - auto cur_kernel = kernel_queue.front(); - kernel_queue.pop(); - MS_ASSERT(cur_kernel != nullptr); - auto next_kernels = cur_kernel->out_kernels(); - for (auto next_kernel : next_kernels) { - auto in_kernels = next_kernel->in_kernels(); - if (lite::IsContain(*kernels, const_cast(next_kernel))) { - MS_LOG(ERROR) << "TopologicalSortKernels failed, loop exist"; - return RET_ERROR; - } - if (std::all_of(in_kernels.begin(), in_kernels.end(), [&](const kernel::LiteKernel *in_kernel) { - return lite::IsContain(*kernels, const_cast(in_kernel)); - })) { - kernel_queue.push(next_kernel); - } - } - } - if (kernels->size() != old_kernels.size()) { - MS_LOG(ERROR) << "TopologicalSortKernels failed, kernels size before sort: " << old_kernels.size() - << ", kernels size after sort: " << kernels->size(); - return RET_ERROR; - } - return RET_OK; -} - -void LiteKernelUtil::InitTensorInitRefCount(const std::vector &kernels) { - for (auto *kernel : kernels) { - kernel->InitOutTensorInitRefCount(); - } -} - -int LiteKernelUtil::SetInput(LiteKernel &kernelMod, const std::vector &inputs) { return -1; } } // namespace mindspore::kernel diff --git a/mindspore/lite/src/lite_kernel.h b/mindspore/lite/src/lite_kernel.h index 4106c8f0ee..7a4747dd4d 100644 --- a/mindspore/lite/src/lite_kernel.h +++ b/mindspore/lite/src/lite_kernel.h @@ -222,23 +222,6 @@ typedef LiteKernel *(*KernelCreator)(const std::vector &inputs, const std::vector &outputs, OpParameter *parameter, const lite::InnerContext *ctx, const KernelKey &desc); -class LiteKernelUtil { - public: - static std::vector SubgraphInputNodes(const std::vector &kernels); - - static std::vector SubgraphOutputNodes(const std::vector &kernels); - - static std::vector SubgraphInputTensors(const std::vector &kernels); - - static std::vector SubgraphOutputTensors(const std::vector &kernels); - - static int TopologicalSortKernels(std::vector *kernels); - - static void InitTensorInitRefCount(const std::vector &kernels); - - static int SetInput(LiteKernel &kernelMod, const std::vector &inputs); -}; - template kernel::LiteKernel *LiteKernelCreator(const std::vector &inputs, const std::vector &outputs, OpParameter *parameter, diff --git a/mindspore/lite/src/lite_kernel_util.cc b/mindspore/lite/src/lite_kernel_util.cc new file mode 100644 index 0000000000..2d72fcdbb2 --- /dev/null +++ b/mindspore/lite/src/lite_kernel_util.cc @@ -0,0 +1,190 @@ +/** + * Copyright 2020 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. + */ + +#include "src/lite_kernel_util.h" +#include +#include + +namespace mindspore::kernel { +using mindspore::lite::RET_ERROR; +using mindspore::lite::RET_OK; +std::vector LiteKernelUtil::SubgraphInputNodes(const std::vector &kernels) { + std::set input_nodes; + for (const auto &kernel : kernels) { + // if kernel has no pre-kernel, kernel is a graph input, it must be a subgraph input + if (kernel->in_kernels().empty() && !kernel->in_tensors().empty()) { + input_nodes.insert(kernel); + continue; + } + auto all_input_tensors = kernel->in_tensors(); + // remove all const tensor from input tensors + for (auto iter = all_input_tensors.begin(); iter != all_input_tensors.end();) { + if ((*iter)->IsConst()) { + iter = all_input_tensors.erase(iter); + } else { + iter++; + } + } + for (const auto &kernel_in_subgraph : kernels) { + // remove input tensors from kernel in subgraph + for (const auto *tensor : kernel_in_subgraph->out_tensors()) { + auto ret = std::find(all_input_tensors.begin(), all_input_tensors.end(), tensor); + if (ret != all_input_tensors.end()) { + all_input_tensors.erase(ret); + } + } + } + // if some input tensor is not from kernel in subgraph + if (!all_input_tensors.empty()) { + input_nodes.insert(kernel); + } + } + std::vector result; + result.insert(result.end(), input_nodes.begin(), input_nodes.end()); + return result; +} + +std::vector LiteKernelUtil::SubgraphOutputNodes( + const std::vector &kernels) { + std::set output_nodes; + // if kernel has no post-kernel, kernel is a graph output, it must be a subgraph output + for (const auto &kernel : kernels) { + if (kernel->is_model_output() || (kernel->out_kernels().empty() && !kernel->out_tensors().empty())) { + output_nodes.insert(kernel); + continue; + } + for (const auto &output : kernel->out_kernels()) { + auto out_kernel_in_graph = std::find(kernels.begin(), kernels.end(), output); + if (out_kernel_in_graph == kernels.end()) { + output_nodes.insert(kernel); + break; + } + } + } + std::vector result; + result.insert(result.end(), output_nodes.begin(), output_nodes.end()); + return result; +} + +std::vector LiteKernelUtil::SubgraphInputTensors(const std::vector &kernels) { + std::set input_tensors; + std::vector input_nodes = SubgraphInputNodes(kernels); + for (const auto &input_node : input_nodes) { + auto &in_node_in_kernels = input_node->in_kernels(); + auto &in_node_in_tensors = input_node->in_tensors(); + for (auto &in_node_in_tensor : in_node_in_tensors) { + if (in_node_in_tensor->IsGraphInput()) { + input_tensors.insert(in_node_in_tensor); + } + } + for (auto in_node_in_kernel : in_node_in_kernels) { + auto iter = std::find(kernels.begin(), kernels.end(), in_node_in_kernel); + if (iter != kernels.end()) { + continue; + } + auto &outer_in_kernel_out_tensors = in_node_in_kernel->out_tensors(); + for (auto in_node_in_tensor : in_node_in_tensors) { + auto outer_in_kernel_out_tensors_iter = + std::find(outer_in_kernel_out_tensors.begin(), outer_in_kernel_out_tensors.end(), in_node_in_tensor); + if (outer_in_kernel_out_tensors_iter != outer_in_kernel_out_tensors.end()) { + input_tensors.insert(in_node_in_tensor); + } + } + } + } + std::vector result; + result.insert(result.end(), input_tensors.begin(), input_tensors.end()); + return result; +} + +std::vector LiteKernelUtil::SubgraphOutputTensors(const std::vector &kernels) { + std::set output_tensors; + std::vector output_nodes = SubgraphOutputNodes(kernels); + for (const auto &output_kernel : output_nodes) { + auto &outer_out_kernels = output_kernel->out_kernels(); + auto &out_kernel_out_tensors = output_kernel->out_tensors(); + for (auto out_kernel_out_tensor : out_kernel_out_tensors) { + if (out_kernel_out_tensor->IsGraphOutput()) { + output_tensors.insert(out_kernel_out_tensor); + } + } + if (!outer_out_kernels.empty()) { + for (auto outer_out_kernel : outer_out_kernels) { + auto iter = std::find(kernels.begin(), kernels.end(), outer_out_kernel); + if (iter != kernels.end()) { + continue; + } + auto &outer_out_kernel_in_tensors = outer_out_kernel->in_tensors(); + for (auto out_kernel_out_tensor : out_kernel_out_tensors) { + auto outer_out_kernel_in_tensors_iter = + std::find(outer_out_kernel_in_tensors.begin(), outer_out_kernel_in_tensors.end(), out_kernel_out_tensor); + if (outer_out_kernel_in_tensors_iter != outer_out_kernel_in_tensors.end()) { + output_tensors.insert(out_kernel_out_tensor); + } + } + } + } + } + std::vector result; + result.insert(result.end(), output_tensors.begin(), output_tensors.end()); + return result; +} + +int LiteKernelUtil::TopologicalSortKernels(std::vector *kernels) { + auto old_kernels = *kernels; + kernels->clear(); + std::queue kernel_queue; + for (auto kernel : old_kernels) { + if (kernel->in_kernels().empty()) { + kernel_queue.push(kernel); + kernels->emplace_back(kernel); + } + } + while (!kernel_queue.empty()) { + auto cur_kernel = kernel_queue.front(); + kernel_queue.pop(); + MS_ASSERT(cur_kernel != nullptr); + auto next_kernels = cur_kernel->out_kernels(); + for (auto next_kernel : next_kernels) { + auto in_kernels = next_kernel->in_kernels(); + if (lite::IsContain(*kernels, const_cast(next_kernel))) { + MS_LOG(ERROR) << "TopologicalSortKernels failed, loop exist"; + return RET_ERROR; + } + if (std::all_of(in_kernels.begin(), in_kernels.end(), [&](const kernel::LiteKernel *in_kernel) { + return lite::IsContain(*kernels, const_cast(in_kernel)); + })) { + kernel_queue.push(next_kernel); + } + } + } + if (kernels->size() != old_kernels.size()) { + MS_LOG(ERROR) << "TopologicalSortKernels failed, kernels size before sort: " << old_kernels.size() + << ", kernels size after sort: " << kernels->size(); + return RET_ERROR; + } + return RET_OK; +} + +void LiteKernelUtil::InitTensorInitRefCount(const std::vector &kernels) { + for (auto *kernel : kernels) { + kernel->InitOutTensorInitRefCount(); + } +} + +int LiteKernelUtil::SetInput(const LiteKernel &kernelMod, const std::vector &inputs) { return -1; } + +} // namespace mindspore::kernel diff --git a/mindspore/lite/src/lite_kernel_util.h b/mindspore/lite/src/lite_kernel_util.h new file mode 100644 index 0000000000..ff7380df23 --- /dev/null +++ b/mindspore/lite/src/lite_kernel_util.h @@ -0,0 +1,42 @@ +/** + * Copyright 2020 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_LITE_SRC_LITE_KERNEL_UTIL_H_ +#define MINDSPORE_LITE_SRC_LITE_KERNEL_UTIL_H_ +#include "src/lite_kernel.h" +#include +namespace mindspore::kernel { + +class LiteKernelUtil { + public: + static std::vector SubgraphInputNodes(const std::vector &kernels); + + static std::vector SubgraphOutputNodes(const std::vector &kernels); + + static std::vector SubgraphInputTensors(const std::vector &kernels); + + static std::vector SubgraphOutputTensors(const std::vector &kernels); + + static int TopologicalSortKernels(std::vector *kernels); + + static void InitTensorInitRefCount(const std::vector &kernels); + + static int SetInput(const LiteKernel &kernelMod, const std::vector &inputs); +}; + +} // namespace mindspore::kernel + +#endif // MINDSPORE_LITE_SRC_LITE_KERNEL_UTIL_H_ diff --git a/mindspore/lite/src/runtime/parallel_executor.cc b/mindspore/lite/src/runtime/parallel_executor.cc index 5acc704296..302ce7c8a3 100644 --- a/mindspore/lite/src/runtime/parallel_executor.cc +++ b/mindspore/lite/src/runtime/parallel_executor.cc @@ -17,6 +17,7 @@ #include #include "src/runtime/parallel_executor.h" #include "src/runtime/runtime_api.h" +#include "src/lite_kernel_util.h" namespace mindspore::lite { ParallelExecutor::~ParallelExecutor() { DestroyThreadPool(thread_pool_); } diff --git a/mindspore/lite/src/scheduler.cc b/mindspore/lite/src/scheduler.cc index 33eea31bd5..fd230d6cee 100644 --- a/mindspore/lite/src/scheduler.cc +++ b/mindspore/lite/src/scheduler.cc @@ -25,6 +25,7 @@ #include "src/common/graph_util.h" #include "src/common/utils.h" #include "src/kernel_registry.h" +#include "src/lite_kernel_util.h" #include "src/sub_graph_kernel.h" #include "src/ops/populate/populate_register.h" #include "src/common/version_manager.h" diff --git a/mindspore/lite/test/CMakeLists.txt b/mindspore/lite/test/CMakeLists.txt index f466970e3e..76b349e7f9 100644 --- a/mindspore/lite/test/CMakeLists.txt +++ b/mindspore/lite/test/CMakeLists.txt @@ -142,6 +142,7 @@ set(TEST_LITE_SRC ${LITE_DIR}/src/inner_context.cc ${LITE_DIR}/src/kernel_registry.cc ${LITE_DIR}/src/lite_kernel.cc + ${LITE_DIR}/src/lite_kernel_util.cc ${LITE_DIR}/src/lite_session.cc ${LITE_DIR}/src/dequant.cc ${LITE_DIR}/src/huffman_decode.cc diff --git a/mindspore/lite/test/ut/src/utils_test.cc b/mindspore/lite/test/ut/src/utils_test.cc index 6d7e8e352a..c7b862c87c 100644 --- a/mindspore/lite/test/ut/src/utils_test.cc +++ b/mindspore/lite/test/ut/src/utils_test.cc @@ -24,6 +24,7 @@ #include "include/errorcode.h" #include "src/common/log_adapter.h" #include "mindspore/lite/src/lite_kernel.h" +#include "mindspore/lite/src/lite_kernel_util.h" namespace mindspore { class UtilsTest : public mindspore::CommonTest { diff --git a/mindspore/lite/tools/converter/CMakeLists.txt b/mindspore/lite/tools/converter/CMakeLists.txt index 8d9fb8815f..130f7f07a2 100644 --- a/mindspore/lite/tools/converter/CMakeLists.txt +++ b/mindspore/lite/tools/converter/CMakeLists.txt @@ -108,6 +108,7 @@ set(LITE_SRC ${SRC_DIR}/tensorlist.cc ${SRC_DIR}/kernel_registry.cc ${SRC_DIR}/lite_kernel.cc + ${SRC_DIR}/lite_kernel_util.cc ${SRC_DIR}/scheduler.cc ${SRC_DIR}/sub_graph_kernel.cc ${SRC_DIR}/sub_graph_split.cc