masahi commented on a change in pull request #9108:
URL: https://github.com/apache/tvm/pull/9108#discussion_r717965514
##########
File path: python/tvm/contrib/pipeline_executor.py
##########
@@ -86,8 +87,43 @@ class PipelineModule(object):
Common interface for pipeline executor factory modules.
"""
- def __init__(self, module):
- self.module = module.module
+ def __init__(self, module=None):
+ self.module = module.module if module else None
+ self._get_num_outputs = None
+ # Get pack functions from pipeline executor.
+ self.load_functions()
+
+ def import_from_library(self, config_file_name):
+ """Create pipeline executor from files.
+
+ Parameters
+ ----------
+ config_file_name : str
+ The configuration file path, the configuration file contains the
+ disk path of the parameter file, library file and JSON file。
+ """
+ # Create empty PipelineExecutorFactoryModule.
+ pipeline_factory = PipelineExecutorFactoryModule()
+ # Load configuration file to initialize PipelineExecutorFactoryModule.
+ pipeline_factory.import_from_library(config_file_name)
+ self.module = pipeline_factory.module
+ # Get pack functions from pipeline executor.
+ self.load_functions()
+
+ def load_functions(self):
+ # Get functions from pipeline executor C++ modules
+ self._get_num_outputs = self.module["get_num_outputs"] if self.module
else None
+
+ def get_num_outputs(self):
+ """Get the number of outputs.
+ Returns
+ -------
+ count : int
+ The number of outputs.
+ """
+ if self._get_num_outputs:
+ return self._get_num_outputs()
+ return 0
Review comment:
I think it's better to assert that `_get_num_outputs` is None and not
return 0.
##########
File path: python/tvm/contrib/pipeline_executor.py
##########
@@ -501,17 +537,18 @@ class PipelineExecutorFactoryModule(object):
"""
- def __init__(self, pipeline_mods, mods_config):
- mods, config = self.graph_executor_create(pipeline_mods, mods_config)
- assert (
- pipeline_executor_enabled()
- ), "Pipeline executor is not enabled. Please \
- re-build TVM with USE_PIPELINE_EXECUTOR=ON"
- pipeline_create = tvm._ffi.get_global_func(
+ def __init__(self, pipeline_libs=None, mods_config=None):
+ self.pipeline_libs = pipeline_libs
+ self.mods_config = mods_config
+ self.pipeline_create = tvm._ffi.get_global_func(
"tvm.pipeline_executor.create", allow_missing=False
)
- assert pipeline_create
- self.module = pipeline_create(mods, config)
+ self.module = None
+ # Only create pipeline executor when pipeline_libs, mods_config and
+ # self.pipeline_create are not None.
+ if pipeline_libs and mods_config and self.pipeline_create:
Review comment:
Since you specify that `allow_missing=False`, `self.pipeline_create`
should always be non-None.
##########
File path: src/runtime/pipeline/pipeline_executor.h
##########
@@ -36,25 +43,83 @@ namespace runtime {
*
* This executor can be accessed by various language via TVM runtime
PackedFunc API.
*/
-class TVM_DLL PipelineRuntime : public ModuleNode {
+class TVM_DLL PipelineExecutor : public ModuleNode {
public:
/*!
* \Return the type key of the executor.
*/
- const char* type_key() const final { return "PipelineRuntime"; }
+ const char* type_key() const final { return "PipelineExecutor"; }
/*!
* \brief Initialize the pipeline executor with module array and json text.
* \param modules The module list used for building pipeline.
* \param pipeline_json The configuration of modules dependencies.
*/
- void Init(const Array<tvm::runtime::Module>& modules, const std::string&
pipeline_json);
+ void Init(const Array<Module>& modules, const std::string& pipeline_json);
/*!
* \brief Give frontends an access to packed functions.
* \param name The name of the function.
* \param sptr_to_self The pointer to the module node.
* \return The corresponding packed function.
*/
virtual PackedFunc GetFunction(const std::string& name, const
ObjectPtr<Object>& sptr_to_self);
+
+ /*!
+ * \brief Get the number of outputs.
+ *
+ * \return The number of outputs.
+ */
+ int NumOutputs() const { return output_number_; }
+
+ private:
+ /*!\brief The class used to execute pipeline logic*/
+ PipelineFunction pipeline_function_;
+ /*!\brief Dependency information of each graph runtime module of pipe line.*/
+ PipelineConfigure pipeline_configure_;
+ /*!\brief Module information that can get use to create graph runtime.*/
+ ModuleConfigure mod_configure_;
Review comment:
pipeline_config_ and mod_config_
"configure" is not a noun.
##########
File path: python/tvm/contrib/pipeline_executor.py
##########
@@ -533,11 +570,92 @@ def graph_executor_create(self, pipeline_mods,
mod_config):
The Modudle configuration.
"""
- mods = []
- for pipeline_mod in pipeline_mods:
- mod = graph_executor.GraphModule(
- pipeline_mod["default"](pipeline_mods[pipeline_mod]["dev"])
- )
- mods.append(mod.module)
+ # The module in pipeline_mods has a index information to identify the
modules order
+ # in pipe line, the pipe line executor follow such asend order to run
each module,
+ # but asend order of module is not guaranteed in pipeline_mod, here
need to pre-allocate
+ # module list then put module in correct place follow the index value.
+ mods = [None for _ in range(len(pipeline_mods))]
+ for lib_index in pipeline_mods:
+ pipeline_lib = pipeline_mods[lib_index]["lib"]
+ dev = pipeline_mods[lib_index]["dev"]
+ lib = graph_executor.GraphModule(pipeline_lib["default"](dev))
+ # Return a module list sorted by lib_index.
+ mods[lib_index - 1] = lib.module
return mods, json.dumps(mod_config)
+
+ def export_library(self, directory_path=None):
+ """Export pipeline runtime into disk.
+
+ Parameters
+ ----------
+ directory_path : str
+ The directory to which these files are exported.
+ """
+ if not self.pipeline_libs:
+ raise RuntimeError(f"The pipeline executor has not been
initialized.")
+
+ # If directory_path is not set, use the temporary path as the file
storage directory_path.
+ if not directory_path:
+ directory_path = tvm.contrib.utils.tempdir().temp_dir
+
+ # Create if the directory does not exist.
+ if not os.path.exists(directory_path):
+ os.makedirs(directory_path)
+ # Get the initial version of the configuration for export.
+ export_conf = self.mods_config.copy()
+ # Export library, JSON file and parameter file, and export the
corresponding
+ # relationship between the files and the pipeline modules.
+ for lib_index in self.pipeline_libs:
+ mconf = export_conf[lib_index - 1]
+ mconf["lib_name"] = "{}/lib{}.so".format(directory_path, lib_index)
+ mconf["json_name"] = "{}/json{}".format(directory_path, lib_index)
+ mconf["params_name"] = "{}/params{}".format(directory_path,
lib_index)
+ mconf["dev"] = "{},{}".format(
+ self.pipeline_libs[lib_index]["dev"].device_type,
+ self.pipeline_libs[lib_index]["dev"].device_id,
+ )
+
+ # Get graph, lib and parameters from GraphExecutorFactoryModule.
+ graph, lib, params = self.pipeline_libs[lib_index]["lib"]
+ # Export lib, graph and parameters to disk.
+ lib.export_library(mconf["lib_name"])
+ with open(mconf["json_name"], "w") as file_handle:
+ file_handle.write(graph)
+ with open(mconf["params_name"], "wb") as file_handle:
+ file_handle.write(relay.save_param_dict(params))
+
+ # Check whether the output is successful.
+ if not os.path.exists(mconf["json_name"]):
+ raise RuntimeError("File {} export
failure.".format(mconf["json_name"]))
+ if not os.path.exists(mconf["lib_name"]):
+ raise RuntimeError("File {} export
failure.".format(mconf["lib_name"]))
+ if not os.path.exists(mconf["params_name"]):
+ raise RuntimeError("File {} export
failure.".format(mconf["params_name"]))
Review comment:
I think these checks are unnecessary, since if the write fails Python
would raise exception. The same comment to L640 below.
##########
File path: python/tvm/contrib/pipeline_executor.py
##########
@@ -86,8 +87,43 @@ class PipelineModule(object):
Common interface for pipeline executor factory modules.
"""
- def __init__(self, module):
- self.module = module.module
+ def __init__(self, module=None):
+ self.module = module.module if module else None
+ self._get_num_outputs = None
+ # Get pack functions from pipeline executor.
Review comment:
packed functions
##########
File path: tests/python/relay/test_pipeline_executor.py
##########
@@ -231,9 +231,19 @@ def test_pipeline():
with tvm.transform.PassContext(opt_level=3):
pipeline_mod_factory = pipeline_executor.build(pipe_config)
+ # Export parameter configuration to file.
+ config_file_name = pipeline_mod_factory.export_library()
+
+ # The test is to create and initialized class PipelineModule using
build return.
Review comment:
A broken sentence.
##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#define TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#include <assert.h>
+#include <dlpack/dlpack.h>
+#include <dmlc/json.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+/*!
+ * \brief Store the corresponding dependencies between the input of other
modules
+ and the current outputs.
+ */
+struct OutputBindings {
+ /*! \brief All module interface binding with current output. */
+ std::unordered_map<int, std::string> bindings;
+ /*!
+ * \brief If there is one global binding in bindings, then current output is
+ * global interface.
+ * \return Whether this output interface is global output interface.
+ */
+ bool IsGlobalOutputNum() const {
+ int outputNum = 0;
+ for (auto binding : bindings) {
+ /* output is global output when value is 0.
+ */
+ outputNum += (binding.first == 0);
+ }
+ /* If this output is a global output then there is only one such output in
map.*/
+ assert(outputNum <= 1);
+ return outputNum == 1;
+ }
+ /*!
+ * \brief Create module interface map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ std::string inputName;
+ int mod_idx;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "mod_idx") {
+ reader->Read(&mod_idx);
+ }
+ if (key == "input_name") {
+ reader->Read(&inputName);
+ }
+ }
+ bindings[mod_idx] = inputName;
+ }
+ }
+};
+/*!
+ * \brief Binding information of the outputs by each module.
+ */
+struct OutputMap {
+ /*! \brief output and output binding map. */
+ std::unordered_map<int, OutputBindings> output_binding_map;
+ OutputMap& operator=(const OutputMap& output) {
+ output_binding_map = output.output_binding_map;
+ return *this;
+ }
+ /*! \brief Global output is the final outputs of pipeline, this function use
to
+ * get how many global outputs are in this Outputmap
+ * \return Number of global outputs.
+ */
+ size_t GetGlobalOutputNum(void) const {
+ size_t outputNum = 0;
+ for (auto bindings : output_binding_map) {
+ outputNum += bindings.second.IsGlobalOutputNum() ? 1 : 0;
+ }
+ return outputNum;
+ }
+
+ /*!
+ * \brief Create output and output binding map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ int output_idx;
+ OutputBindings binding;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "output_idx") {
+ reader->Read(&output_idx);
+ }
+ if (key == "dependent") {
+ reader->Read(&binding);
+ }
+ }
+ output_binding_map[output_idx] = binding;
+ }
+ }
+};
+/*!
+ * \brief Binding or dependency information of each module output interface.
+ */
+struct PipelineConfigure {
+ /*! */
+ std::unordered_map<int, OutputMap> config;
+ OutputMap& operator[](const int key) { return config[key]; }
+ /*!
+ * \brief Get total global outputs number.
+ * \return Global outputs number.
+ */
+ size_t GetGlobalOutputNum() const {
+ size_t output_num = 0;
+ for (auto mod_output : config) {
+ output_num += mod_output.second.GetGlobalOutputNum();
+ }
+ return output_num;
+ }
+};
+/*!
+ * \brief Informations used to initialize the graph executor module, these
+ information comming from export library function call.
Review comment:
come from
##########
File path: src/runtime/pipeline/pipeline_executor.cc
##########
@@ -21,31 +21,48 @@
* \file pipeline_executor.cc
*/
#include "pipeline_executor.h"
-
namespace tvm {
namespace runtime {
-
-void PipelineRuntime::Init(const Array<tvm::runtime::Module>& modules,
- const std::string& pipeline_json) {
- return;
-}
-
-/* GetFunction can not be pure abstract function, implement an empty function
for now.
+/*!
+ * \brief Give frontends an access to packed functions.
+ * \param name The name of the function.
+ * \param sptr_to_self The pointer to the module node.
+ * \return The corresponding packed function.
*/
-PackedFunc PipelineRuntime::GetFunction(const std::string& name,
- const ObjectPtr<Object>& sptr_to_self)
{
+PackedFunc PipelineExecutor::GetFunction(const std::string& name,
+ const ObjectPtr<Object>&
sptr_to_self) {
+ if (name == "get_num_outputs") {
+ return PackedFunc(
+ [sptr_to_self, this](TVMArgs args, TVMRetValue* rv) { *rv =
this->NumOutputs(); });
+ } else {
+ return PackedFunc();
+ }
return nullptr;
}
+/*!
+ * \brief Initialize the pipeline executor with module array and json text.
+ * \param modules The module list used for building pipeline.
+ * \param pipeline_json The configuration of modules dependencies.
+ */
+void PipelineExecutor::Init(const Array<Module>& modules, const std::string&
pipeline_json) {
+ // Use JSONReader to load pipe line configuration from file.
+ std::istringstream is(pipeline_json);
+ dmlc::JSONReader reader(&is);
+ this->Load(&reader);
+ // Initialize the pipeline function class used for pipeline thread pool
management
+ // and schedule etc. This function return output number of whole pipeline.
Review comment:
the number of outputs
##########
File path: src/runtime/pipeline/pipeline_executor.cc
##########
@@ -21,31 +21,48 @@
* \file pipeline_executor.cc
*/
#include "pipeline_executor.h"
-
namespace tvm {
namespace runtime {
-
-void PipelineRuntime::Init(const Array<tvm::runtime::Module>& modules,
- const std::string& pipeline_json) {
- return;
-}
-
-/* GetFunction can not be pure abstract function, implement an empty function
for now.
+/*!
+ * \brief Give frontends an access to packed functions.
+ * \param name The name of the function.
+ * \param sptr_to_self The pointer to the module node.
+ * \return The corresponding packed function.
*/
-PackedFunc PipelineRuntime::GetFunction(const std::string& name,
- const ObjectPtr<Object>& sptr_to_self)
{
+PackedFunc PipelineExecutor::GetFunction(const std::string& name,
+ const ObjectPtr<Object>&
sptr_to_self) {
+ if (name == "get_num_outputs") {
+ return PackedFunc(
+ [sptr_to_self, this](TVMArgs args, TVMRetValue* rv) { *rv =
this->NumOutputs(); });
+ } else {
+ return PackedFunc();
+ }
return nullptr;
}
+/*!
+ * \brief Initialize the pipeline executor with module array and json text.
+ * \param modules The module list used for building pipeline.
+ * \param pipeline_json The configuration of modules dependencies.
+ */
+void PipelineExecutor::Init(const Array<Module>& modules, const std::string&
pipeline_json) {
+ // Use JSONReader to load pipe line configuration from file.
Review comment:
pipeline
##########
File path: python/tvm/contrib/pipeline_executor.py
##########
@@ -533,11 +570,92 @@ def graph_executor_create(self, pipeline_mods,
mod_config):
The Modudle configuration.
"""
- mods = []
- for pipeline_mod in pipeline_mods:
- mod = graph_executor.GraphModule(
- pipeline_mod["default"](pipeline_mods[pipeline_mod]["dev"])
- )
- mods.append(mod.module)
+ # The module in pipeline_mods has a index information to identify the
modules order
+ # in pipe line, the pipe line executor follow such asend order to run
each module,
+ # but asend order of module is not guaranteed in pipeline_mod, here
need to pre-allocate
+ # module list then put module in correct place follow the index value.
Review comment:
This sentence is full of grammar errors, please fix all of them.
Even then, I don't understand what this sentence means. Please improve it.
##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#define TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#include <assert.h>
+#include <dlpack/dlpack.h>
+#include <dmlc/json.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+/*!
+ * \brief Store the corresponding dependencies between the input of other
modules
+ and the current outputs.
+ */
+struct OutputBindings {
+ /*! \brief All module interface binding with current output. */
+ std::unordered_map<int, std::string> bindings;
+ /*!
+ * \brief If there is one global binding in bindings, then current output is
+ * global interface.
+ * \return Whether this output interface is global output interface.
+ */
+ bool IsGlobalOutputNum() const {
+ int outputNum = 0;
+ for (auto binding : bindings) {
+ /* output is global output when value is 0.
+ */
+ outputNum += (binding.first == 0);
+ }
+ /* If this output is a global output then there is only one such output in
map.*/
+ assert(outputNum <= 1);
+ return outputNum == 1;
+ }
+ /*!
+ * \brief Create module interface map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ std::string inputName;
+ int mod_idx;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "mod_idx") {
+ reader->Read(&mod_idx);
+ }
+ if (key == "input_name") {
+ reader->Read(&inputName);
+ }
+ }
+ bindings[mod_idx] = inputName;
+ }
+ }
+};
+/*!
+ * \brief Binding information of the outputs by each module.
+ */
+struct OutputMap {
+ /*! \brief output and output binding map. */
+ std::unordered_map<int, OutputBindings> output_binding_map;
+ OutputMap& operator=(const OutputMap& output) {
+ output_binding_map = output.output_binding_map;
+ return *this;
+ }
+ /*! \brief Global output is the final outputs of pipeline, this function use
to
+ * get how many global outputs are in this Outputmap
+ * \return Number of global outputs.
+ */
+ size_t GetGlobalOutputNum(void) const {
+ size_t outputNum = 0;
+ for (auto bindings : output_binding_map) {
+ outputNum += bindings.second.IsGlobalOutputNum() ? 1 : 0;
+ }
+ return outputNum;
+ }
+
+ /*!
+ * \brief Create output and output binding map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ int output_idx;
+ OutputBindings binding;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "output_idx") {
+ reader->Read(&output_idx);
+ }
+ if (key == "dependent") {
+ reader->Read(&binding);
+ }
+ }
+ output_binding_map[output_idx] = binding;
+ }
+ }
+};
+/*!
+ * \brief Binding or dependency information of each module output interface.
+ */
+struct PipelineConfigure {
Review comment:
PipelineConfig
##########
File path: src/runtime/pipeline/pipeline_function.cc
##########
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 "pipeline_function.h"
+
+#include <utility>
+#include <vector>
+namespace tvm {
+namespace runtime {
+/*!
+ * \brief Initialize pipeline.
+ * \param modules List of graph runtime module.
+ * \param pipeline_conf Dependency relation of each graph runtime module.
+ * \param mod_configure Configure information that generate by export library
function call.
+ */
+size_t PipelineFunction::PipelineInit(Array<Module> modules, const
PipelineConfigure& pipeline_conf,
+ const ModuleConfigure& mod_configure) {
+ int outputNum = pipeline_conf.GetGlobalOutputNum();
+ std::vector<Module> graphRuntimes = PipelineCreateGraphruntime(modules,
mod_configure);
+ return outputNum;
+}
+/*!
+ * \brief There are two mode to create graph runtime list, first is to use
modules that
+ * are the module list already created by caller, when modules is empty these
information
+ * from mod_configure will get use to create graph runtime list.
Review comment:
I think it is better to separate the two cases in different function,
since the first one is much simpler. Actually we don't need a dedicated
function for the first case.
##########
File path: python/tvm/contrib/pipeline_executor.py
##########
@@ -86,8 +87,43 @@ class PipelineModule(object):
Common interface for pipeline executor factory modules.
"""
- def __init__(self, module):
- self.module = module.module
+ def __init__(self, module=None):
+ self.module = module.module if module else None
+ self._get_num_outputs = None
+ # Get pack functions from pipeline executor.
+ self.load_functions()
+
+ def import_from_library(self, config_file_name):
+ """Create pipeline executor from files.
+
+ Parameters
+ ----------
+ config_file_name : str
+ The configuration file path, the configuration file contains the
+ disk path of the parameter file, library file and JSON file。
+ """
+ # Create empty PipelineExecutorFactoryModule.
+ pipeline_factory = PipelineExecutorFactoryModule()
+ # Load configuration file to initialize PipelineExecutorFactoryModule.
+ pipeline_factory.import_from_library(config_file_name)
+ self.module = pipeline_factory.module
+ # Get pack functions from pipeline executor.
Review comment:
packed functions
##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#define TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#include <assert.h>
+#include <dlpack/dlpack.h>
+#include <dmlc/json.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+/*!
+ * \brief Store the corresponding dependencies between the input of other
modules
+ and the current outputs.
+ */
+struct OutputBindings {
+ /*! \brief All module interface binding with current output. */
+ std::unordered_map<int, std::string> bindings;
+ /*!
+ * \brief If there is one global binding in bindings, then current output is
+ * global interface.
+ * \return Whether this output interface is global output interface.
+ */
+ bool IsGlobalOutputNum() const {
+ int outputNum = 0;
+ for (auto binding : bindings) {
+ /* output is global output when value is 0.
+ */
+ outputNum += (binding.first == 0);
+ }
+ /* If this output is a global output then there is only one such output in
map.*/
+ assert(outputNum <= 1);
+ return outputNum == 1;
+ }
+ /*!
+ * \brief Create module interface map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ std::string inputName;
+ int mod_idx;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "mod_idx") {
+ reader->Read(&mod_idx);
+ }
+ if (key == "input_name") {
+ reader->Read(&inputName);
+ }
+ }
+ bindings[mod_idx] = inputName;
+ }
+ }
+};
+/*!
+ * \brief Binding information of the outputs by each module.
+ */
+struct OutputMap {
+ /*! \brief output and output binding map. */
+ std::unordered_map<int, OutputBindings> output_binding_map;
+ OutputMap& operator=(const OutputMap& output) {
+ output_binding_map = output.output_binding_map;
+ return *this;
+ }
+ /*! \brief Global output is the final outputs of pipeline, this function use
to
+ * get how many global outputs are in this Outputmap
+ * \return Number of global outputs.
+ */
+ size_t GetGlobalOutputNum(void) const {
+ size_t outputNum = 0;
+ for (auto bindings : output_binding_map) {
+ outputNum += bindings.second.IsGlobalOutputNum() ? 1 : 0;
+ }
+ return outputNum;
+ }
+
+ /*!
+ * \brief Create output and output binding map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ int output_idx;
+ OutputBindings binding;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "output_idx") {
+ reader->Read(&output_idx);
+ }
+ if (key == "dependent") {
+ reader->Read(&binding);
+ }
+ }
+ output_binding_map[output_idx] = binding;
+ }
+ }
+};
+/*!
+ * \brief Binding or dependency information of each module output interface.
+ */
+struct PipelineConfigure {
+ /*! */
+ std::unordered_map<int, OutputMap> config;
+ OutputMap& operator[](const int key) { return config[key]; }
+ /*!
+ * \brief Get total global outputs number.
+ * \return Global outputs number.
+ */
+ size_t GetGlobalOutputNum() const {
+ size_t output_num = 0;
+ for (auto mod_output : config) {
+ output_num += mod_output.second.GetGlobalOutputNum();
+ }
+ return output_num;
+ }
+};
+/*!
+ * \brief Informations used to initialize the graph executor module, these
+ information comming from export library function call.
+ */
+struct ModuleInformation {
+ std::unordered_map<std::string, std::string> info;
+ const std::string& operator[](const std::string& key) { return info[key]; }
+ ModuleInformation& operator=(const std::unordered_map<std::string,
std::string>& umap) {
+ info = umap;
+ return *this;
+ }
+};
+/*! Module information of each module. */
+typedef std::unordered_map<int, ModuleInformation> ModuleConfigure;
Review comment:
using ModuleConfig = std::unordered_map<int, ModuleInformation>
Document what is int
##########
File path: src/runtime/pipeline/pipeline_function.cc
##########
@@ -0,0 +1,105 @@
+/*
Review comment:
Please go through all variable names in this file and fix the style.
They should be in snake_case. There are many of them to fix.
##########
File path: src/runtime/pipeline/pipeline_function.cc
##########
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 "pipeline_function.h"
+
+#include <utility>
+#include <vector>
+namespace tvm {
+namespace runtime {
+/*!
+ * \brief Initialize pipeline.
+ * \param modules List of graph runtime module.
+ * \param pipeline_conf Dependency relation of each graph runtime module.
+ * \param mod_configure Configure information that generate by export library
function call.
+ */
+size_t PipelineFunction::PipelineInit(Array<Module> modules, const
PipelineConfigure& pipeline_conf,
+ const ModuleConfigure& mod_configure) {
+ int outputNum = pipeline_conf.GetGlobalOutputNum();
+ std::vector<Module> graphRuntimes = PipelineCreateGraphruntime(modules,
mod_configure);
+ return outputNum;
+}
+/*!
+ * \brief There are two mode to create graph runtime list, first is to use
modules that
+ * are the module list already created by caller, when modules is empty these
information
+ * from mod_configure will get use to create graph runtime list.
+ * \param modules List of graph runtime module.
+ * \param mod_configure Configure information that generate by export library
function call.
+ */
+std::vector<Module> PipelineFunction::PipelineCreateGraphruntime(
Review comment:
PipelineCreateGraphruntime -> PipelineCreateGraphRuntime
##########
File path: src/runtime/pipeline/pipeline_executor.h
##########
@@ -36,25 +43,83 @@ namespace runtime {
*
* This executor can be accessed by various language via TVM runtime
PackedFunc API.
*/
-class TVM_DLL PipelineRuntime : public ModuleNode {
+class TVM_DLL PipelineExecutor : public ModuleNode {
public:
/*!
* \Return the type key of the executor.
*/
- const char* type_key() const final { return "PipelineRuntime"; }
+ const char* type_key() const final { return "PipelineExecutor"; }
/*!
* \brief Initialize the pipeline executor with module array and json text.
* \param modules The module list used for building pipeline.
* \param pipeline_json The configuration of modules dependencies.
*/
- void Init(const Array<tvm::runtime::Module>& modules, const std::string&
pipeline_json);
+ void Init(const Array<Module>& modules, const std::string& pipeline_json);
/*!
* \brief Give frontends an access to packed functions.
* \param name The name of the function.
* \param sptr_to_self The pointer to the module node.
* \return The corresponding packed function.
*/
virtual PackedFunc GetFunction(const std::string& name, const
ObjectPtr<Object>& sptr_to_self);
+
+ /*!
+ * \brief Get the number of outputs.
+ *
+ * \return The number of outputs.
+ */
+ int NumOutputs() const { return output_number_; }
+
+ private:
+ /*!\brief The class used to execute pipeline logic*/
+ PipelineFunction pipeline_function_;
+ /*!\brief Dependency information of each graph runtime module of pipe line.*/
+ PipelineConfigure pipeline_configure_;
+ /*!\brief Module information that can get use to create graph runtime.*/
Review comment:
that can get use -> used
##########
File path: src/runtime/pipeline/pipeline_executor.h
##########
@@ -36,25 +43,83 @@ namespace runtime {
*
* This executor can be accessed by various language via TVM runtime
PackedFunc API.
*/
-class TVM_DLL PipelineRuntime : public ModuleNode {
+class TVM_DLL PipelineExecutor : public ModuleNode {
public:
/*!
* \Return the type key of the executor.
*/
- const char* type_key() const final { return "PipelineRuntime"; }
+ const char* type_key() const final { return "PipelineExecutor"; }
/*!
* \brief Initialize the pipeline executor with module array and json text.
* \param modules The module list used for building pipeline.
* \param pipeline_json The configuration of modules dependencies.
*/
- void Init(const Array<tvm::runtime::Module>& modules, const std::string&
pipeline_json);
+ void Init(const Array<Module>& modules, const std::string& pipeline_json);
/*!
* \brief Give frontends an access to packed functions.
* \param name The name of the function.
* \param sptr_to_self The pointer to the module node.
* \return The corresponding packed function.
*/
virtual PackedFunc GetFunction(const std::string& name, const
ObjectPtr<Object>& sptr_to_self);
+
+ /*!
+ * \brief Get the number of outputs.
+ *
+ * \return The number of outputs.
+ */
+ int NumOutputs() const { return output_number_; }
+
+ private:
+ /*!\brief The class used to execute pipeline logic*/
+ PipelineFunction pipeline_function_;
+ /*!\brief Dependency information of each graph runtime module of pipe line.*/
Review comment:
pipeline
##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#define TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#include <assert.h>
+#include <dlpack/dlpack.h>
+#include <dmlc/json.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+/*!
+ * \brief Store the corresponding dependencies between the input of other
modules
+ and the current outputs.
+ */
+struct OutputBindings {
+ /*! \brief All module interface binding with current output. */
+ std::unordered_map<int, std::string> bindings;
+ /*!
+ * \brief If there is one global binding in bindings, then current output is
+ * global interface.
+ * \return Whether this output interface is global output interface.
+ */
+ bool IsGlobalOutputNum() const {
Review comment:
The name IsGlobalOutputNum makes no sense.
##########
File path: src/runtime/pipeline/pipeline_executor.h
##########
@@ -36,25 +43,83 @@ namespace runtime {
*
* This executor can be accessed by various language via TVM runtime
PackedFunc API.
*/
-class TVM_DLL PipelineRuntime : public ModuleNode {
+class TVM_DLL PipelineExecutor : public ModuleNode {
public:
/*!
* \Return the type key of the executor.
*/
- const char* type_key() const final { return "PipelineRuntime"; }
+ const char* type_key() const final { return "PipelineExecutor"; }
/*!
* \brief Initialize the pipeline executor with module array and json text.
* \param modules The module list used for building pipeline.
* \param pipeline_json The configuration of modules dependencies.
*/
- void Init(const Array<tvm::runtime::Module>& modules, const std::string&
pipeline_json);
+ void Init(const Array<Module>& modules, const std::string& pipeline_json);
/*!
* \brief Give frontends an access to packed functions.
* \param name The name of the function.
* \param sptr_to_self The pointer to the module node.
* \return The corresponding packed function.
*/
virtual PackedFunc GetFunction(const std::string& name, const
ObjectPtr<Object>& sptr_to_self);
+
+ /*!
+ * \brief Get the number of outputs.
+ *
+ * \return The number of outputs.
+ */
+ int NumOutputs() const { return output_number_; }
+
+ private:
+ /*!\brief The class used to execute pipeline logic*/
+ PipelineFunction pipeline_function_;
+ /*!\brief Dependency information of each graph runtime module of pipe line.*/
+ PipelineConfigure pipeline_configure_;
+ /*!\brief Module information that can get use to create graph runtime.*/
+ ModuleConfigure mod_configure_;
+ /*!\birief How many outputs are in this pipeline executor.*/
+ size_t output_number_ = 0;
+ /*!\brief Json loader.*/
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ int mod_idx = 0;
+ std::string libName;
+ std::string jsonName;
+ std::string paramsName;
+ std::string dev;
+ OutputMap output;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "mod_idx") {
+ reader->Read(&mod_idx);
+ }
+ if (key == "lib_name") {
+ reader->Read(&libName);
+ }
+
+ if (key == "json_name") {
+ reader->Read(&jsonName);
+ }
+
+ if (key == "params_name") {
+ reader->Read(¶msName);
+ }
+
+ if (key == "dev") {
+ reader->Read(&dev);
+ }
+
+ if (key == "output") {
+ reader->Read(&output);
+ }
+ }
+ pipeline_configure_[mod_idx] = output;
+ mod_configure_[mod_idx] = {
Review comment:
Check that mod_idx is properly initialized.
##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#define TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#include <assert.h>
+#include <dlpack/dlpack.h>
+#include <dmlc/json.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+/*!
+ * \brief Store the corresponding dependencies between the input of other
modules
+ and the current outputs.
+ */
+struct OutputBindings {
+ /*! \brief All module interface binding with current output. */
+ std::unordered_map<int, std::string> bindings;
+ /*!
+ * \brief If there is one global binding in bindings, then current output is
+ * global interface.
+ * \return Whether this output interface is global output interface.
+ */
+ bool IsGlobalOutputNum() const {
+ int outputNum = 0;
Review comment:
style
##########
File path: src/runtime/pipeline/pipeline_executor.h
##########
@@ -36,25 +43,83 @@ namespace runtime {
*
* This executor can be accessed by various language via TVM runtime
PackedFunc API.
*/
-class TVM_DLL PipelineRuntime : public ModuleNode {
+class TVM_DLL PipelineExecutor : public ModuleNode {
public:
/*!
* \Return the type key of the executor.
*/
- const char* type_key() const final { return "PipelineRuntime"; }
+ const char* type_key() const final { return "PipelineExecutor"; }
/*!
* \brief Initialize the pipeline executor with module array and json text.
* \param modules The module list used for building pipeline.
* \param pipeline_json The configuration of modules dependencies.
*/
- void Init(const Array<tvm::runtime::Module>& modules, const std::string&
pipeline_json);
+ void Init(const Array<Module>& modules, const std::string& pipeline_json);
/*!
* \brief Give frontends an access to packed functions.
* \param name The name of the function.
* \param sptr_to_self The pointer to the module node.
* \return The corresponding packed function.
*/
virtual PackedFunc GetFunction(const std::string& name, const
ObjectPtr<Object>& sptr_to_self);
+
+ /*!
+ * \brief Get the number of outputs.
+ *
+ * \return The number of outputs.
+ */
+ int NumOutputs() const { return output_number_; }
+
+ private:
+ /*!\brief The class used to execute pipeline logic*/
+ PipelineFunction pipeline_function_;
+ /*!\brief Dependency information of each graph runtime module of pipe line.*/
+ PipelineConfigure pipeline_configure_;
+ /*!\brief Module information that can get use to create graph runtime.*/
+ ModuleConfigure mod_configure_;
+ /*!\birief How many outputs are in this pipeline executor.*/
+ size_t output_number_ = 0;
+ /*!\brief Json loader.*/
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ int mod_idx = 0;
+ std::string libName;
+ std::string jsonName;
+ std::string paramsName;
Review comment:
Variable names should be snake_case.
##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#define TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#include <assert.h>
+#include <dlpack/dlpack.h>
+#include <dmlc/json.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+/*!
+ * \brief Store the corresponding dependencies between the input of other
modules
+ and the current outputs.
+ */
+struct OutputBindings {
+ /*! \brief All module interface binding with current output. */
+ std::unordered_map<int, std::string> bindings;
Review comment:
"All module interface binding with current output" doesn't make much
sense.
Also what is `int` in the key
##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#define TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#include <assert.h>
+#include <dlpack/dlpack.h>
+#include <dmlc/json.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+/*!
+ * \brief Store the corresponding dependencies between the input of other
modules
+ and the current outputs.
+ */
+struct OutputBindings {
+ /*! \brief All module interface binding with current output. */
+ std::unordered_map<int, std::string> bindings;
+ /*!
+ * \brief If there is one global binding in bindings, then current output is
+ * global interface.
+ * \return Whether this output interface is global output interface.
+ */
+ bool IsGlobalOutputNum() const {
+ int outputNum = 0;
+ for (auto binding : bindings) {
+ /* output is global output when value is 0.
+ */
+ outputNum += (binding.first == 0);
+ }
+ /* If this output is a global output then there is only one such output in
map.*/
+ assert(outputNum <= 1);
+ return outputNum == 1;
+ }
+ /*!
+ * \brief Create module interface map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ std::string inputName;
+ int mod_idx;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "mod_idx") {
+ reader->Read(&mod_idx);
+ }
+ if (key == "input_name") {
+ reader->Read(&inputName);
+ }
+ }
+ bindings[mod_idx] = inputName;
+ }
+ }
+};
+/*!
+ * \brief Binding information of the outputs by each module.
+ */
+struct OutputMap {
+ /*! \brief output and output binding map. */
+ std::unordered_map<int, OutputBindings> output_binding_map;
+ OutputMap& operator=(const OutputMap& output) {
+ output_binding_map = output.output_binding_map;
+ return *this;
+ }
+ /*! \brief Global output is the final outputs of pipeline, this function use
to
+ * get how many global outputs are in this Outputmap
+ * \return Number of global outputs.
+ */
+ size_t GetGlobalOutputNum(void) const {
+ size_t outputNum = 0;
+ for (auto bindings : output_binding_map) {
+ outputNum += bindings.second.IsGlobalOutputNum() ? 1 : 0;
+ }
+ return outputNum;
+ }
+
+ /*!
+ * \brief Create output and output binding map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ int output_idx;
+ OutputBindings binding;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "output_idx") {
+ reader->Read(&output_idx);
+ }
+ if (key == "dependent") {
+ reader->Read(&binding);
+ }
+ }
+ output_binding_map[output_idx] = binding;
+ }
+ }
+};
+/*!
+ * \brief Binding or dependency information of each module output interface.
+ */
+struct PipelineConfigure {
+ /*! */
+ std::unordered_map<int, OutputMap> config;
Review comment:
what is int in the key
##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#define TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#include <assert.h>
+#include <dlpack/dlpack.h>
+#include <dmlc/json.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+/*!
+ * \brief Store the corresponding dependencies between the input of other
modules
+ and the current outputs.
+ */
+struct OutputBindings {
+ /*! \brief All module interface binding with current output. */
+ std::unordered_map<int, std::string> bindings;
+ /*!
+ * \brief If there is one global binding in bindings, then current output is
+ * global interface.
+ * \return Whether this output interface is global output interface.
+ */
+ bool IsGlobalOutputNum() const {
+ int outputNum = 0;
+ for (auto binding : bindings) {
+ /* output is global output when value is 0.
+ */
+ outputNum += (binding.first == 0);
+ }
+ /* If this output is a global output then there is only one such output in
map.*/
+ assert(outputNum <= 1);
+ return outputNum == 1;
+ }
+ /*!
+ * \brief Create module interface map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ std::string inputName;
+ int mod_idx;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "mod_idx") {
+ reader->Read(&mod_idx);
+ }
+ if (key == "input_name") {
+ reader->Read(&inputName);
+ }
+ }
+ bindings[mod_idx] = inputName;
+ }
+ }
+};
+/*!
+ * \brief Binding information of the outputs by each module.
+ */
+struct OutputMap {
+ /*! \brief output and output binding map. */
+ std::unordered_map<int, OutputBindings> output_binding_map;
+ OutputMap& operator=(const OutputMap& output) {
+ output_binding_map = output.output_binding_map;
+ return *this;
+ }
+ /*! \brief Global output is the final outputs of pipeline, this function use
to
+ * get how many global outputs are in this Outputmap
+ * \return Number of global outputs.
+ */
+ size_t GetGlobalOutputNum(void) const {
+ size_t outputNum = 0;
+ for (auto bindings : output_binding_map) {
+ outputNum += bindings.second.IsGlobalOutputNum() ? 1 : 0;
+ }
+ return outputNum;
+ }
+
+ /*!
+ * \brief Create output and output binding map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ int output_idx;
+ OutputBindings binding;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "output_idx") {
+ reader->Read(&output_idx);
+ }
+ if (key == "dependent") {
+ reader->Read(&binding);
+ }
+ }
+ output_binding_map[output_idx] = binding;
+ }
+ }
+};
+/*!
+ * \brief Binding or dependency information of each module output interface.
+ */
+struct PipelineConfigure {
+ /*! */
+ std::unordered_map<int, OutputMap> config;
+ OutputMap& operator[](const int key) { return config[key]; }
+ /*!
+ * \brief Get total global outputs number.
+ * \return Global outputs number.
+ */
+ size_t GetGlobalOutputNum() const {
+ size_t output_num = 0;
+ for (auto mod_output : config) {
+ output_num += mod_output.second.GetGlobalOutputNum();
+ }
+ return output_num;
+ }
+};
+/*!
+ * \brief Informations used to initialize the graph executor module, these
+ information comming from export library function call.
+ */
+struct ModuleInformation {
+ std::unordered_map<std::string, std::string> info;
Review comment:
what do two string represent
##########
File path: src/runtime/pipeline/pipeline_function.h
##########
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 TVM_RUNTIME_PIPELINE_PIPELINE_FUNCTION_H_
+#define TVM_RUNTIME_PIPELINE_PIPELINE_FUNCTION_H_
+#include <tvm/runtime/module.h>
+#include <tvm/runtime/packed_func.h>
+#include <tvm/runtime/registry.h>
+
+#include <fstream>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "pipeline_struct.h"
+namespace tvm {
+namespace runtime {
+/*!
+ * \brief The class that executes pipeline logic is used to initialize the
thread pool,
+ execute and schedule pipeline tasks, allocate and manage memory, etc.
+ */
+class PipelineFunction {
+ public:
+ /*!
+ * \brief There are two mode to create graph runtime list, first is to use
modules that
+ * are the module list already created by caller, when modules is empty
these information
+ * from mod_configure will get use to create graph runtime list.
+ * \param modules List of graph runtime module.
+ * \param mod_configure Configure information that generate by export
library function call.
+ */
+ std::vector<Module> PipelineCreateGraphruntime(Array<Module> modules,
+ const ModuleConfigure&
mod_configure);
+ /*!
+ * \brief Initialize pipeline.
+ * \param modules List of graph runtime module.
+ * \param pipeline_conf Dependency relation of each graph runtime module.
+ * \param mod_configure Configure information that generate by export
library function call.
+ */
Review comment:
Please make variable naming consistent. It's not good to have one name
called `conf` and another one `configure`.
##########
File path: tests/python/relay/test_pipeline_executor.py
##########
@@ -231,9 +231,19 @@ def test_pipeline():
with tvm.transform.PassContext(opt_level=3):
pipeline_mod_factory = pipeline_executor.build(pipe_config)
+ # Export parameter configuration to file.
+ config_file_name = pipeline_mod_factory.export_library()
+
+ # The test is to create and initialized class PipelineModule using
build return.
pipeline_module =
pipeline_executor.PipelineModule(pipeline_mod_factory)
assert pipeline_module
+ # The test is to initialized class PipelineModule using import
function.
Review comment:
A broken sentence, doesn't make sense.
##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#define TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#include <assert.h>
+#include <dlpack/dlpack.h>
+#include <dmlc/json.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+/*!
+ * \brief Store the corresponding dependencies between the input of other
modules
+ and the current outputs.
+ */
+struct OutputBindings {
+ /*! \brief All module interface binding with current output. */
+ std::unordered_map<int, std::string> bindings;
+ /*!
+ * \brief If there is one global binding in bindings, then current output is
+ * global interface.
+ * \return Whether this output interface is global output interface.
+ */
+ bool IsGlobalOutputNum() const {
+ int outputNum = 0;
+ for (auto binding : bindings) {
+ /* output is global output when value is 0.
+ */
+ outputNum += (binding.first == 0);
+ }
+ /* If this output is a global output then there is only one such output in
map.*/
+ assert(outputNum <= 1);
+ return outputNum == 1;
+ }
+ /*!
+ * \brief Create module interface map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ std::string inputName;
Review comment:
style
##########
File path: src/runtime/pipeline/pipeline_executor.h
##########
@@ -36,25 +43,83 @@ namespace runtime {
*
* This executor can be accessed by various language via TVM runtime
PackedFunc API.
*/
-class TVM_DLL PipelineRuntime : public ModuleNode {
+class TVM_DLL PipelineExecutor : public ModuleNode {
public:
/*!
* \Return the type key of the executor.
*/
- const char* type_key() const final { return "PipelineRuntime"; }
+ const char* type_key() const final { return "PipelineExecutor"; }
/*!
* \brief Initialize the pipeline executor with module array and json text.
* \param modules The module list used for building pipeline.
* \param pipeline_json The configuration of modules dependencies.
*/
- void Init(const Array<tvm::runtime::Module>& modules, const std::string&
pipeline_json);
+ void Init(const Array<Module>& modules, const std::string& pipeline_json);
/*!
* \brief Give frontends an access to packed functions.
* \param name The name of the function.
* \param sptr_to_self The pointer to the module node.
* \return The corresponding packed function.
*/
virtual PackedFunc GetFunction(const std::string& name, const
ObjectPtr<Object>& sptr_to_self);
+
+ /*!
+ * \brief Get the number of outputs.
+ *
+ * \return The number of outputs.
+ */
+ int NumOutputs() const { return output_number_; }
+
+ private:
+ /*!\brief The class used to execute pipeline logic*/
+ PipelineFunction pipeline_function_;
+ /*!\brief Dependency information of each graph runtime module of pipe line.*/
+ PipelineConfigure pipeline_configure_;
+ /*!\brief Module information that can get use to create graph runtime.*/
+ ModuleConfigure mod_configure_;
+ /*!\birief How many outputs are in this pipeline executor.*/
+ size_t output_number_ = 0;
Review comment:
num_outputs_
##########
File path: tests/python/relay/test_pipeline_executor.py
##########
@@ -231,9 +231,19 @@ def test_pipeline():
with tvm.transform.PassContext(opt_level=3):
pipeline_mod_factory = pipeline_executor.build(pipe_config)
+ # Export parameter configuration to file.
+ config_file_name = pipeline_mod_factory.export_library()
+
+ # The test is to create and initialized class PipelineModule using
build return.
pipeline_module =
pipeline_executor.PipelineModule(pipeline_mod_factory)
assert pipeline_module
+ # The test is to initialized class PipelineModule using import
function.
+ pipeline_module_test = pipeline_executor.PipelineModule()
+ pipeline_module_test.import_from_library(config_file_name)
+ # Check whether the number of outputs is two.
Review comment:
Remove this comment
##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#define TVM_RUNTIME_PIPELINE_PIPELINE_STRUCT_H_
+#include <assert.h>
+#include <dlpack/dlpack.h>
+#include <dmlc/json.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+/*!
+ * \brief Store the corresponding dependencies between the input of other
modules
+ and the current outputs.
+ */
+struct OutputBindings {
+ /*! \brief All module interface binding with current output. */
+ std::unordered_map<int, std::string> bindings;
+ /*!
+ * \brief If there is one global binding in bindings, then current output is
+ * global interface.
+ * \return Whether this output interface is global output interface.
+ */
+ bool IsGlobalOutputNum() const {
+ int outputNum = 0;
+ for (auto binding : bindings) {
+ /* output is global output when value is 0.
+ */
+ outputNum += (binding.first == 0);
+ }
+ /* If this output is a global output then there is only one such output in
map.*/
+ assert(outputNum <= 1);
+ return outputNum == 1;
+ }
+ /*!
+ * \brief Create module interface map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ std::string inputName;
+ int mod_idx;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "mod_idx") {
+ reader->Read(&mod_idx);
+ }
+ if (key == "input_name") {
+ reader->Read(&inputName);
+ }
+ }
+ bindings[mod_idx] = inputName;
+ }
+ }
+};
+/*!
+ * \brief Binding information of the outputs by each module.
+ */
+struct OutputMap {
+ /*! \brief output and output binding map. */
+ std::unordered_map<int, OutputBindings> output_binding_map;
+ OutputMap& operator=(const OutputMap& output) {
+ output_binding_map = output.output_binding_map;
+ return *this;
+ }
+ /*! \brief Global output is the final outputs of pipeline, this function use
to
+ * get how many global outputs are in this Outputmap
+ * \return Number of global outputs.
+ */
+ size_t GetGlobalOutputNum(void) const {
+ size_t outputNum = 0;
+ for (auto bindings : output_binding_map) {
+ outputNum += bindings.second.IsGlobalOutputNum() ? 1 : 0;
+ }
+ return outputNum;
+ }
+
+ /*!
+ * \brief Create output and output binding map from JSONReader.
+ * \param reader Json reader.
+ */
+ void Load(dmlc::JSONReader* reader) {
+ reader->BeginArray();
+ while (reader->NextArrayItem()) {
+ std::string key;
+ reader->BeginObject();
+ int output_idx;
+ OutputBindings binding;
+ while (reader->NextObjectItem(&key)) {
+ if (key == "output_idx") {
+ reader->Read(&output_idx);
+ }
+ if (key == "dependent") {
+ reader->Read(&binding);
+ }
+ }
+ output_binding_map[output_idx] = binding;
Review comment:
Make sure output_idx is initialized
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]