masahi commented on a change in pull request #9108:
URL: https://github.com/apache/tvm/pull/9108#discussion_r719296414



##########
File path: python/tvm/contrib/pipeline_executor.py
##########
@@ -533,11 +570,82 @@ 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)
+        # Modules need to be stored in the list named 'mods' in index order.
+        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 the pipeline executor into disk files.
+
+        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 the 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
+
+        # If the directory does not exist, create the directory.
+        if not os.path.exists(directory_path):
+            os.makedirs(directory_path)
+        # Create a configuration copy for export.
+        export_conf = self.mods_config.copy()
+        # Export the library, JSON and parameter into files, then export these 
files path
+        # into a configuraton file.
+        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 the graph, lib and parameters from 
GraphExecutorFactoryModule.
+            graph, lib, params = self.pipeline_libs[lib_index]["lib"]
+            # Export the 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))
+
+        # Export the configuration file to disk.
+        conf_file_name = "{}/config".format(directory_path)
+        with open(conf_file_name, "w") as file_handle:
+            file_handle.write(json.dumps(export_conf))
+        if not os.path.exists(conf_file_name):
+            raise RuntimeError(f"File {conf_file_name} export failure.")
+
+        return conf_file_name
+
+    def import_from_library(self, configure_file_name):
+        """Load configuration file to create and initialize pipeline executor.
+
+        Parameters
+        ----------
+        configure_file_name : str
+            The configuration file path, the configuration file contains the
+            disk path of the parameter file, library file and JSON file。
+        """
+        if self.module:
+            raise RuntimeError(f"The pipeline executor has already been 
initialized.")
+
+        self.pipe_configure = ""
+        with open(configure_file_name, "r") as file_handle:
+            self.pipe_configure = file_handle.read()
+
+        self.module = self.pipeline_create([], self.pipe_configure)

Review comment:
       I said `configure` is not a verb.
   
   `config_file_name`
   `pipe_config`

##########
File path: src/runtime/pipeline/pipeline_function.h
##########
@@ -0,0 +1,60 @@
+/*
+ * 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 the pipeline logic is used to initialize the 
thread pool,
+    execute and schedule pipeline tasks, allocate and manage memory, etc.

Review comment:
       The beginning of this sentence is weird. Do you mean:
   "The class that executes the pipeline logic. It is used to initialize ..."?

##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,164 @@
+/*
+ * 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 All binding information of a output interface.
+ */
+struct OutputBindings {
+  /*!\brief Output interface binding information, 'int' is the index of the 
bond module.
+   * 'string' is the interface name of the bond module.
+   */
+  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 IsGlobalOutput() const {
+    int num_output = 0;
+    for (auto binding : bindings) {
+      /* output is global output when value is 0.
+       */
+      num_output += (binding.first == 0);
+    }
+    /* If this output is a global output then there is only one such output in 
map.*/
+    assert(num_output <= 1);
+    return num_output == 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 input_name;
+      int mod_idx;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "mod_idx") {
+          reader->Read(&mod_idx);
+        }
+        if (key == "input_name") {
+          reader->Read(&input_name);
+        }
+      }
+      bindings[mod_idx] = input_name;
+    }
+  }
+};
+/*!
+ * \brief The binding information of all outputs of a module.
+ */
+struct OutputMap {
+  /*! \brief Output binding map, 'int' is output interface index.*/
+  std::unordered_map<int, OutputBindings> output_binding_map;
+  OutputMap& operator=(const OutputMap& output) {
+    output_binding_map = output.output_binding_map;
+    return *this;
+  }
+
+  /*!\brief Check that OutMap is empty.
+   * \return True or False.
+   */
+  bool Empty() { return output_binding_map.empty(); }
+  /*! \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 num_output = 0;
+    for (auto bindings : output_binding_map) {
+      num_output += bindings.second.IsGlobalOutput() ? 1 : 0;
+    }
+    return num_output;
+  }
+
+  /*!
+   * \brief Create 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 = -1;
+      OutputBindings binding;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "output_idx") {
+          reader->Read(&output_idx);
+        }
+        if (key == "dependent") {
+          reader->Read(&binding);
+        }
+      }
+      assert(output_idx >= 0);

Review comment:
       ICHECK

##########
File path: python/tvm/contrib/pipeline_executor.py
##########
@@ -71,10 +72,10 @@ def build(pipe_configs):
 
         mconf["dev"] = "{},{}".format(dev.device_type, dev.device_id)
         # Create a pipeline configuration.
-        string_config[mod_idx] = mconf
-        mods[mod] = {"dev": dev}
+        string_config[mod_idx - 1] = mconf

Review comment:
       document why you subtract 1

##########
File path: src/runtime/pipeline/pipeline_executor.h
##########
@@ -36,25 +43,89 @@ 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 num_outputs_; }
+
+ private:
+  /*!\brief The class used to execute pipeline logic*/
+  PipelineFunction pipeline_function_;
+  /*!\brief The Dependency information of each graph runtime module of 
pipeline.*/
+  PipelineConfig pipeline_configure_;
+  /*!\brief The Module information that can get used to create graph runtime.*/
+  ModuleConfig mod_configure_;
+  /*!\birief How many outputs are in this pipeline executor.*/
+  size_t num_outputs_ = 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 lib_name;
+      std::string json_name;
+      std::string params_name;
+      std::string dev;
+      OutputMap output;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "mod_idx") {
+          reader->Read(&mod_idx);
+        }
+        if (key == "lib_name") {
+          reader->Read(&lib_name);
+        }
+
+        if (key == "json_name") {
+          reader->Read(&json_name);
+        }
+
+        if (key == "params_name") {
+          reader->Read(&params_name);
+        }
+
+        if (key == "dev") {
+          reader->Read(&dev);
+        }
+
+        if (key == "output") {
+          reader->Read(&output);
+        }
+      }
+      // Check if mod_idx is read successfully.
+      assert(mod_idx > 0);
+      // Check if the output is read successfully.
+      assert(!output.empty());
+      pipeline_configure_[mod_idx] = output;
+      // Check if lib, json and params are read successfully.
+      assert(!lib_name.empty() && !json_name.empty() && !params_name.empty());

Review comment:
       Replace assert with ICHECK, all of them

##########
File path: python/tvm/contrib/pipeline_executor.py
##########
@@ -533,11 +570,82 @@ 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)
+        # Modules need to be stored in the list named 'mods' in index order.
+        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

Review comment:
       document what subtract 1

##########
File path: python/tvm/contrib/pipeline_executor.py
##########
@@ -533,11 +570,82 @@ 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)
+        # Modules need to be stored in the list named 'mods' in index order.
+        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 the pipeline executor into disk files.
+
+        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 the 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
+
+        # If the directory does not exist, create the directory.
+        if not os.path.exists(directory_path):
+            os.makedirs(directory_path)
+        # Create a configuration copy for export.
+        export_conf = self.mods_config.copy()
+        # Export the library, JSON and parameter into files, then export these 
files path
+        # into a configuraton file.
+        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 the graph, lib and parameters from 
GraphExecutorFactoryModule.
+            graph, lib, params = self.pipeline_libs[lib_index]["lib"]
+            # Export the 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))
+
+        # Export the configuration file to disk.
+        conf_file_name = "{}/config".format(directory_path)
+        with open(conf_file_name, "w") as file_handle:
+            file_handle.write(json.dumps(export_conf))
+        if not os.path.exists(conf_file_name):
+            raise RuntimeError(f"File {conf_file_name} export failure.")

Review comment:
       remove this too.

##########
File path: src/runtime/pipeline/pipeline_function.cc
##########
@@ -0,0 +1,100 @@
+/*
+ * 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 the pipeline.
+ * \param modules The List of graph executor module.

Review comment:
       list

##########
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 pipeline 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 the number of output.

Review comment:
       returns

##########
File path: src/runtime/pipeline/pipeline_executor.h
##########
@@ -36,25 +43,89 @@ 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 num_outputs_; }
+
+ private:
+  /*!\brief The class used to execute pipeline logic*/
+  PipelineFunction pipeline_function_;
+  /*!\brief The Dependency information of each graph runtime module of 
pipeline.*/
+  PipelineConfig pipeline_configure_;
+  /*!\brief The Module information that can get used to create graph runtime.*/
+  ModuleConfig mod_configure_;
+  /*!\birief How many outputs are in this pipeline executor.*/

Review comment:
       `pipeline_config`
   `mod_config`

##########
File path: src/runtime/pipeline/pipeline_function.cc
##########
@@ -0,0 +1,100 @@
+/*
+ * 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 the pipeline.
+ * \param modules The List of graph executor module.
+ * \param pipeline_conf The Dependency information of each graph executor 
module.
+ * \param mod_config The config information that generate by the export 
library function call.

Review comment:
       generated by?

##########
File path: src/runtime/pipeline/pipeline_function.cc
##########
@@ -0,0 +1,100 @@
+/*
+ * 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 the pipeline.
+ * \param modules The List of graph executor module.
+ * \param pipeline_conf The Dependency information of each graph executor 
module.
+ * \param mod_config The config information that generate by the export 
library function call.
+ */
+size_t PipelineFunction::PipelineInit(Array<Module> modules, const 
PipelineConfig& pipeline_config,
+                                      const ModuleConfig& mod_config) {
+  int num_output = pipeline_config.GetGlobalOutputNum();
+  // If 'modules' is not empty just return in vector container
+  if (!modules.empty()) {
+    for (auto mod : modules) {
+      graph_executors_.push_back(mod);
+    }
+  } else {
+    // If 'modules' is empty, need to build the graph exectuor from mod_config.
+    graph_executors_ = PipelineCreateGraphExecutors(mod_config);
+  }
+  return num_output;
+}
+/*!
+ * \brief Use the mod_config information to create a graph runtime list.
+ * \param mod_configure The config information that generate by export library 
function call.

Review comment:
       `mod_config`

##########
File path: src/runtime/pipeline/pipeline_function.cc
##########
@@ -0,0 +1,100 @@
+/*
+ * 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 the pipeline.
+ * \param modules The List of graph executor module.
+ * \param pipeline_conf The Dependency information of each graph executor 
module.
+ * \param mod_config The config information that generate by the export 
library function call.
+ */
+size_t PipelineFunction::PipelineInit(Array<Module> modules, const 
PipelineConfig& pipeline_config,
+                                      const ModuleConfig& mod_config) {
+  int num_output = pipeline_config.GetGlobalOutputNum();
+  // If 'modules' is not empty just return in vector container
+  if (!modules.empty()) {
+    for (auto mod : modules) {
+      graph_executors_.push_back(mod);
+    }
+  } else {
+    // If 'modules' is empty, need to build the graph exectuor from mod_config.
+    graph_executors_ = PipelineCreateGraphExecutors(mod_config);
+  }
+  return num_output;
+}
+/*!
+ * \brief Use the mod_config information to create a graph runtime list.
+ * \param mod_configure The config information that generate by export library 
function call.
+ */
+std::vector<Module> PipelineFunction::PipelineCreateGraphExecutors(const 
ModuleConfig& mod_config) {
+  const PackedFunc* graph_executor_create = 
Registry::Get("tvm.graph_executor.create");
+  std::vector<Module> ret;
+  ret.resize(mod_config.size());
+  for (auto config : mod_config) {
+    // Load library.
+    auto lib = Module::LoadFromFile(config.second["lib_name"].c_str());
+
+    // Read json.
+    std::ifstream ifJson(config.second["json_name"].c_str());
+    if (ifJson.fail()) {
+      throw std::runtime_error("json file not found!");
+    }
+    const std::string json((std::istreambuf_iterator<char>(ifJson)),
+                           std::istreambuf_iterator<char>());
+
+    // Create graph executor.
+    std::istringstream istr(config.second["dev"]);
+    std::string str;
+    int device_type = 1, device_id = 0;
+    while (getline(istr, str, ';')) {
+      std::istringstream istr_dev(str);
+      std::string str_temp;
+      if (getline(istr_dev, str_temp)) {
+        device_type = stoi(str_temp);
+      }
+      if (getline(istr_dev, str_temp)) {
+        device_id = stoi(str_temp);
+      }
+    }
+    Module graph_module = (*graph_executor_create)(json, lib, device_type, 
device_id);
+
+    // Load parameters.
+    TVMByteArray params_arr;
+    std::ifstream if_param(config.second["params"].c_str());
+    if (if_param.fail()) {
+      throw std::runtime_error("params file not found!");
+    }
+    const std::string params((std::istreambuf_iterator<char>(if_param)),
+                             std::istreambuf_iterator<char>());
+    params_arr.data = params.c_str();
+    params_arr.size = params.length();
+    auto load_params = graph_module.GetFunction("load_params");
+    load_params(params_arr);
+
+    // Put a graph executor module into the vector.
+    ret[config.first - 1] = graph_module;

Review comment:
       why subtract -1

##########
File path: src/runtime/pipeline/pipeline_function.cc
##########
@@ -0,0 +1,100 @@
+/*
+ * 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 the pipeline.
+ * \param modules The List of graph executor module.
+ * \param pipeline_conf The Dependency information of each graph executor 
module.
+ * \param mod_config The config information that generate by the export 
library function call.
+ */
+size_t PipelineFunction::PipelineInit(Array<Module> modules, const 
PipelineConfig& pipeline_config,
+                                      const ModuleConfig& mod_config) {
+  int num_output = pipeline_config.GetGlobalOutputNum();
+  // If 'modules' is not empty just return in vector container
+  if (!modules.empty()) {
+    for (auto mod : modules) {
+      graph_executors_.push_back(mod);
+    }
+  } else {
+    // If 'modules' is empty, need to build the graph exectuor from mod_config.
+    graph_executors_ = PipelineCreateGraphExecutors(mod_config);
+  }
+  return num_output;
+}
+/*!
+ * \brief Use the mod_config information to create a graph runtime list.
+ * \param mod_configure The config information that generate by export library 
function call.
+ */
+std::vector<Module> PipelineFunction::PipelineCreateGraphExecutors(const 
ModuleConfig& mod_config) {
+  const PackedFunc* graph_executor_create = 
Registry::Get("tvm.graph_executor.create");
+  std::vector<Module> ret;
+  ret.resize(mod_config.size());
+  for (auto config : mod_config) {
+    // Load library.
+    auto lib = Module::LoadFromFile(config.second["lib_name"].c_str());
+
+    // Read json.
+    std::ifstream ifJson(config.second["json_name"].c_str());
+    if (ifJson.fail()) {
+      throw std::runtime_error("json file not found!");

Review comment:
       Replace with `LOG(FATAL)`.

##########
File path: src/runtime/pipeline/pipeline_function.h
##########
@@ -0,0 +1,60 @@
+/*
+ * 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 the pipeline logic is used to initialize the 
thread pool,
+    execute and schedule pipeline tasks, allocate and manage memory, etc.
+ */
+class PipelineFunction {
+ public:
+  /*!
+   * \brief Use the information of mod_config to create graph executor list.
+   * \param mod_config The Configuration information that generate by the 
library export library
+   *  function call.
+   */
+  std::vector<Module> PipelineCreateGraphExecutors(const ModuleConfig& 
mod_config);
+  /*!
+   * \brief Initialize the pipeline.
+   * \param modules The List of graph executor module.
+   * \param pipeline_config The Dependency information of each graph executor 
module.

Review comment:
       list
   
   dependency

##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,164 @@
+/*
+ * 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 All binding information of a output interface.
+ */
+struct OutputBindings {
+  /*!\brief Output interface binding information, 'int' is the index of the 
bond module.
+   * 'string' is the interface name of the bond module.

Review comment:
       what is "bond module".

##########
File path: src/runtime/pipeline/pipeline_function.h
##########
@@ -0,0 +1,60 @@
+/*
+ * 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 the pipeline logic is used to initialize the 
thread pool,
+    execute and schedule pipeline tasks, allocate and manage memory, etc.
+ */
+class PipelineFunction {
+ public:
+  /*!
+   * \brief Use the information of mod_config to create graph executor list.
+   * \param mod_config The Configuration information that generate by the 
library export library

Review comment:
       configuration
   
   that generate by -> generated by

##########
File path: src/runtime/pipeline/pipeline_function.cc
##########
@@ -0,0 +1,100 @@
+/*
+ * 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 the pipeline.
+ * \param modules The List of graph executor module.
+ * \param pipeline_conf The Dependency information of each graph executor 
module.
+ * \param mod_config The config information that generate by the export 
library function call.
+ */
+size_t PipelineFunction::PipelineInit(Array<Module> modules, const 
PipelineConfig& pipeline_config,
+                                      const ModuleConfig& mod_config) {
+  int num_output = pipeline_config.GetGlobalOutputNum();
+  // If 'modules' is not empty just return in vector container
+  if (!modules.empty()) {
+    for (auto mod : modules) {
+      graph_executors_.push_back(mod);
+    }
+  } else {
+    // If 'modules' is empty, need to build the graph exectuor from mod_config.
+    graph_executors_ = PipelineCreateGraphExecutors(mod_config);
+  }
+  return num_output;
+}
+/*!
+ * \brief Use the mod_config information to create a graph runtime list.
+ * \param mod_configure The config information that generate by export library 
function call.
+ */
+std::vector<Module> PipelineFunction::PipelineCreateGraphExecutors(const 
ModuleConfig& mod_config) {
+  const PackedFunc* graph_executor_create = 
Registry::Get("tvm.graph_executor.create");
+  std::vector<Module> ret;
+  ret.resize(mod_config.size());
+  for (auto config : mod_config) {
+    // Load library.
+    auto lib = Module::LoadFromFile(config.second["lib_name"].c_str());
+
+    // Read json.
+    std::ifstream ifJson(config.second["json_name"].c_str());
+    if (ifJson.fail()) {
+      throw std::runtime_error("json file not found!");
+    }
+    const std::string json((std::istreambuf_iterator<char>(ifJson)),
+                           std::istreambuf_iterator<char>());
+
+    // Create graph executor.
+    std::istringstream istr(config.second["dev"]);
+    std::string str;
+    int device_type = 1, device_id = 0;
+    while (getline(istr, str, ';')) {
+      std::istringstream istr_dev(str);
+      std::string str_temp;
+      if (getline(istr_dev, str_temp)) {
+        device_type = stoi(str_temp);
+      }
+      if (getline(istr_dev, str_temp)) {
+        device_id = stoi(str_temp);
+      }
+    }
+    Module graph_module = (*graph_executor_create)(json, lib, device_type, 
device_id);
+
+    // Load parameters.
+    TVMByteArray params_arr;
+    std::ifstream if_param(config.second["params"].c_str());
+    if (if_param.fail()) {
+      throw std::runtime_error("params file not found!");

Review comment:
       replace with `LOG(FATAL)`

##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,164 @@
+/*
+ * 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 All binding information of a output interface.
+ */
+struct OutputBindings {
+  /*!\brief Output interface binding information, 'int' is the index of the 
bond module.
+   * 'string' is the interface name of the bond module.
+   */
+  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 IsGlobalOutput() const {
+    int num_output = 0;
+    for (auto binding : bindings) {
+      /* output is global output when value is 0.
+       */
+      num_output += (binding.first == 0);
+    }
+    /* If this output is a global output then there is only one such output in 
map.*/
+    assert(num_output <= 1);
+    return num_output == 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 input_name;
+      int mod_idx;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "mod_idx") {
+          reader->Read(&mod_idx);
+        }
+        if (key == "input_name") {
+          reader->Read(&input_name);
+        }
+      }
+      bindings[mod_idx] = input_name;

Review comment:
       check mod_idx is initialized

##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,164 @@
+/*
+ * 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 All binding information of a output interface.
+ */
+struct OutputBindings {
+  /*!\brief Output interface binding information, 'int' is the index of the 
bond module.
+   * 'string' is the interface name of the bond module.
+   */
+  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 IsGlobalOutput() const {
+    int num_output = 0;
+    for (auto binding : bindings) {
+      /* output is global output when value is 0.
+       */
+      num_output += (binding.first == 0);
+    }
+    /* If this output is a global output then there is only one such output in 
map.*/
+    assert(num_output <= 1);

Review comment:
       ICHECK

##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,164 @@
+/*
+ * 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 All binding information of a output interface.
+ */
+struct OutputBindings {
+  /*!\brief Output interface binding information, 'int' is the index of the 
bond module.
+   * 'string' is the interface name of the bond module.
+   */
+  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 IsGlobalOutput() const {
+    int num_output = 0;
+    for (auto binding : bindings) {
+      /* output is global output when value is 0.
+       */
+      num_output += (binding.first == 0);
+    }
+    /* If this output is a global output then there is only one such output in 
map.*/
+    assert(num_output <= 1);
+    return num_output == 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 input_name;
+      int mod_idx;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "mod_idx") {
+          reader->Read(&mod_idx);
+        }
+        if (key == "input_name") {
+          reader->Read(&input_name);
+        }
+      }
+      bindings[mod_idx] = input_name;
+    }
+  }
+};
+/*!
+ * \brief The binding information of all outputs of a module.
+ */
+struct OutputMap {
+  /*! \brief Output binding map, 'int' is output interface index.*/
+  std::unordered_map<int, OutputBindings> output_binding_map;
+  OutputMap& operator=(const OutputMap& output) {
+    output_binding_map = output.output_binding_map;
+    return *this;
+  }
+
+  /*!\brief Check that OutMap is empty.
+   * \return True or False.

Review comment:
       Remove silly comment like this. It is obvious.

##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,164 @@
+/*
+ * 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 All binding information of a output interface.
+ */
+struct OutputBindings {
+  /*!\brief Output interface binding information, 'int' is the index of the 
bond module.
+   * 'string' is the interface name of the bond module.
+   */
+  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 IsGlobalOutput() const {
+    int num_output = 0;
+    for (auto binding : bindings) {
+      /* output is global output when value is 0.
+       */
+      num_output += (binding.first == 0);
+    }
+    /* If this output is a global output then there is only one such output in 
map.*/
+    assert(num_output <= 1);
+    return num_output == 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 input_name;
+      int mod_idx;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "mod_idx") {
+          reader->Read(&mod_idx);
+        }
+        if (key == "input_name") {
+          reader->Read(&input_name);
+        }
+      }
+      bindings[mod_idx] = input_name;
+    }
+  }
+};
+/*!
+ * \brief The binding information of all outputs of a module.
+ */
+struct OutputMap {
+  /*! \brief Output binding map, 'int' is output interface index.*/
+  std::unordered_map<int, OutputBindings> output_binding_map;
+  OutputMap& operator=(const OutputMap& output) {
+    output_binding_map = output.output_binding_map;
+    return *this;
+  }
+
+  /*!\brief Check that OutMap is empty.
+   * \return True or False.
+   */
+  bool Empty() { return output_binding_map.empty(); }
+  /*! \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 num_output = 0;
+    for (auto bindings : output_binding_map) {
+      num_output += bindings.second.IsGlobalOutput() ? 1 : 0;
+    }
+    return num_output;
+  }
+
+  /*!
+   * \brief Create 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 = -1;
+      OutputBindings binding;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "output_idx") {
+          reader->Read(&output_idx);
+        }
+        if (key == "dependent") {
+          reader->Read(&binding);
+        }
+      }
+      assert(output_idx >= 0);
+      output_binding_map[output_idx] = binding;
+    }
+  }
+};
+/*!
+ * \brief Binding or dependency information of each module output interface.
+ */
+struct PipelineConfig {
+  /*!\brief The module index is the key, this variable record all module 
pipeline configuration

Review comment:
       The key is the module index
   
   records

##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,164 @@
+/*
+ * 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 All binding information of a output interface.
+ */
+struct OutputBindings {
+  /*!\brief Output interface binding information, 'int' is the index of the 
bond module.
+   * 'string' is the interface name of the bond module.
+   */
+  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 IsGlobalOutput() const {
+    int num_output = 0;
+    for (auto binding : bindings) {
+      /* output is global output when value is 0.
+       */
+      num_output += (binding.first == 0);
+    }
+    /* If this output is a global output then there is only one such output in 
map.*/
+    assert(num_output <= 1);
+    return num_output == 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 input_name;
+      int mod_idx;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "mod_idx") {
+          reader->Read(&mod_idx);
+        }
+        if (key == "input_name") {
+          reader->Read(&input_name);
+        }
+      }
+      bindings[mod_idx] = input_name;
+    }
+  }
+};
+/*!
+ * \brief The binding information of all outputs of a module.
+ */
+struct OutputMap {
+  /*! \brief Output binding map, 'int' is output interface index.*/
+  std::unordered_map<int, OutputBindings> output_binding_map;
+  OutputMap& operator=(const OutputMap& output) {
+    output_binding_map = output.output_binding_map;
+    return *this;
+  }
+
+  /*!\brief Check that OutMap is empty.
+   * \return True or False.
+   */
+  bool Empty() { return output_binding_map.empty(); }
+  /*! \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 num_output = 0;
+    for (auto bindings : output_binding_map) {
+      num_output += bindings.second.IsGlobalOutput() ? 1 : 0;
+    }
+    return num_output;
+  }
+
+  /*!
+   * \brief Create 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 = -1;
+      OutputBindings binding;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "output_idx") {
+          reader->Read(&output_idx);
+        }
+        if (key == "dependent") {
+          reader->Read(&binding);
+        }
+      }
+      assert(output_idx >= 0);
+      output_binding_map[output_idx] = binding;
+    }
+  }
+};
+/*!
+ * \brief Binding or dependency information of each module output interface.
+ */
+struct PipelineConfig {
+  /*!\brief The module index is the key, this variable record all module 
pipeline configuration
+   * information.
+   */
+  std::unordered_map<int, OutputMap> config;
+  OutputMap& operator[](const int key) { return config[key]; }

Review comment:
       remove const
   
   You should check that the key actually exists in the map before accessing.

##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,164 @@
+/*
+ * 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 All binding information of a output interface.
+ */
+struct OutputBindings {
+  /*!\brief Output interface binding information, 'int' is the index of the 
bond module.
+   * 'string' is the interface name of the bond module.
+   */
+  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 IsGlobalOutput() const {
+    int num_output = 0;
+    for (auto binding : bindings) {
+      /* output is global output when value is 0.
+       */
+      num_output += (binding.first == 0);
+    }
+    /* If this output is a global output then there is only one such output in 
map.*/
+    assert(num_output <= 1);
+    return num_output == 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 input_name;
+      int mod_idx;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "mod_idx") {
+          reader->Read(&mod_idx);
+        }
+        if (key == "input_name") {
+          reader->Read(&input_name);
+        }
+      }
+      bindings[mod_idx] = input_name;
+    }
+  }
+};
+/*!
+ * \brief The binding information of all outputs of a module.
+ */
+struct OutputMap {
+  /*! \brief Output binding map, 'int' is output interface index.*/
+  std::unordered_map<int, OutputBindings> output_binding_map;
+  OutputMap& operator=(const OutputMap& output) {
+    output_binding_map = output.output_binding_map;
+    return *this;
+  }
+
+  /*!\brief Check that OutMap is empty.
+   * \return True or False.
+   */
+  bool Empty() { return output_binding_map.empty(); }
+  /*! \brief Global output is the final outputs of pipeline, this function use 
to

Review comment:
       is used to

##########
File path: src/runtime/pipeline/pipeline_function.h
##########
@@ -0,0 +1,60 @@
+/*
+ * 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 the pipeline logic is used to initialize the 
thread pool,
+    execute and schedule pipeline tasks, allocate and manage memory, etc.
+ */
+class PipelineFunction {
+ public:
+  /*!
+   * \brief Use the information of mod_config to create graph executor list.
+   * \param mod_config The Configuration information that generate by the 
library export library
+   *  function call.
+   */
+  std::vector<Module> PipelineCreateGraphExecutors(const ModuleConfig& 
mod_config);
+  /*!
+   * \brief Initialize the pipeline.
+   * \param modules The List of graph executor module.
+   * \param pipeline_config The Dependency information of each graph executor 
module.
+   * \param mod_config The config information that generate by the export 
library function call.

Review comment:
       generated by

##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,164 @@
+/*
+ * 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 All binding information of a output interface.
+ */
+struct OutputBindings {
+  /*!\brief Output interface binding information, 'int' is the index of the 
bond module.
+   * 'string' is the interface name of the bond module.
+   */
+  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 IsGlobalOutput() const {
+    int num_output = 0;
+    for (auto binding : bindings) {
+      /* output is global output when value is 0.
+       */
+      num_output += (binding.first == 0);
+    }
+    /* If this output is a global output then there is only one such output in 
map.*/
+    assert(num_output <= 1);
+    return num_output == 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 input_name;
+      int mod_idx;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "mod_idx") {
+          reader->Read(&mod_idx);
+        }
+        if (key == "input_name") {
+          reader->Read(&input_name);
+        }
+      }
+      bindings[mod_idx] = input_name;
+    }
+  }
+};
+/*!
+ * \brief The binding information of all outputs of a module.
+ */
+struct OutputMap {
+  /*! \brief Output binding map, 'int' is output interface index.*/
+  std::unordered_map<int, OutputBindings> output_binding_map;
+  OutputMap& operator=(const OutputMap& output) {
+    output_binding_map = output.output_binding_map;
+    return *this;
+  }
+
+  /*!\brief Check that OutMap is empty.
+   * \return True or False.
+   */
+  bool Empty() { return output_binding_map.empty(); }
+  /*! \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 num_output = 0;
+    for (auto bindings : output_binding_map) {
+      num_output += bindings.second.IsGlobalOutput() ? 1 : 0;
+    }
+    return num_output;
+  }
+
+  /*!
+   * \brief Create 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 = -1;
+      OutputBindings binding;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "output_idx") {
+          reader->Read(&output_idx);
+        }
+        if (key == "dependent") {
+          reader->Read(&binding);
+        }
+      }
+      assert(output_idx >= 0);
+      output_binding_map[output_idx] = binding;
+    }
+  }
+};
+/*!
+ * \brief Binding or dependency information of each module output interface.
+ */
+struct PipelineConfig {
+  /*!\brief The module index is the key, this variable record all module 
pipeline configuration
+   * information.
+   */
+  std::unordered_map<int, OutputMap> config;
+  OutputMap& operator[](const int key) { return config[key]; }
+  /*!
+   * \brief Get the total global outputs number.
+   * \return The global outputs number.

Review comment:
       What is global outputs number

##########
File path: src/runtime/pipeline/pipeline_struct.h
##########
@@ -0,0 +1,164 @@
+/*
+ * 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 All binding information of a output interface.
+ */
+struct OutputBindings {
+  /*!\brief Output interface binding information, 'int' is the index of the 
bond module.
+   * 'string' is the interface name of the bond module.
+   */
+  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 IsGlobalOutput() const {
+    int num_output = 0;
+    for (auto binding : bindings) {
+      /* output is global output when value is 0.
+       */
+      num_output += (binding.first == 0);
+    }
+    /* If this output is a global output then there is only one such output in 
map.*/
+    assert(num_output <= 1);
+    return num_output == 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 input_name;
+      int mod_idx;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "mod_idx") {
+          reader->Read(&mod_idx);
+        }
+        if (key == "input_name") {
+          reader->Read(&input_name);
+        }
+      }
+      bindings[mod_idx] = input_name;
+    }
+  }
+};
+/*!
+ * \brief The binding information of all outputs of a module.
+ */
+struct OutputMap {
+  /*! \brief Output binding map, 'int' is output interface index.*/
+  std::unordered_map<int, OutputBindings> output_binding_map;
+  OutputMap& operator=(const OutputMap& output) {
+    output_binding_map = output.output_binding_map;
+    return *this;
+  }
+
+  /*!\brief Check that OutMap is empty.
+   * \return True or False.
+   */
+  bool Empty() { return output_binding_map.empty(); }
+  /*! \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 num_output = 0;
+    for (auto bindings : output_binding_map) {
+      num_output += bindings.second.IsGlobalOutput() ? 1 : 0;
+    }
+    return num_output;
+  }
+
+  /*!
+   * \brief Create 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 = -1;
+      OutputBindings binding;
+      while (reader->NextObjectItem(&key)) {
+        if (key == "output_idx") {
+          reader->Read(&output_idx);
+        }
+        if (key == "dependent") {
+          reader->Read(&binding);
+        }
+      }
+      assert(output_idx >= 0);
+      output_binding_map[output_idx] = binding;
+    }
+  }
+};
+/*!
+ * \brief Binding or dependency information of each module output interface.
+ */
+struct PipelineConfig {
+  /*!\brief The module index is the key, this variable record all module 
pipeline configuration
+   * information.
+   */
+  std::unordered_map<int, OutputMap> config;
+  OutputMap& operator[](const int key) { return config[key]; }
+  /*!
+   * \brief Get the total global outputs number.
+   * \return The global outputs number.
+   */
+  size_t GetGlobalOutputNum() const {
+    size_t num_output = 0;
+    for (auto mod_output : config) {
+      num_output += mod_output.second.GetGlobalOutputNum();
+    }
+    return num_output;
+  }
+};
+/*!
+ * \brief The informations used to initialize the graph executor module, the 
information
+ *  come from the export library function call.
+ */
+struct ModuleInformation {
+  /*\brief The first string is the information type such as "lib_name",the 
second string is
+   * the information detail such as "/src/lib1.so" for "lib_name".

Review comment:
       I don't think this is a good way to use maps. If the set of keys is 
fixed, use variables such as `lib_name`, rather than making everything string.




-- 
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]


Reply via email to