Skip to content

Commit

Permalink
[Runtime] Pipeline Executor Initial patch.
Browse files Browse the repository at this point in the history
This patch is one of serial patch for PR 7892 splitting.this is the initial part
of the pipeline executor, this patch include the cmake change and python and C++
interface for pipeline executor.
  • Loading branch information
huajsj committed Aug 10, 2021
1 parent 49756a5 commit 8d41893
Show file tree
Hide file tree
Showing 6 changed files with 442 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,12 @@ if(USE_PROFILER)
list(APPEND RUNTIME_SRCS ${RUNTIME_VM_PROFILER_SRCS})
endif(USE_PROFILER)

if(USE_PIPELINE_EXECUTOR)
message(STATUS "Build with Pipeline Executor support...")
file(GLOB RUNTIME_PIPELINE_SRCS src/runtime/pipeline/*.cc)
list(APPEND RUNTIME_SRCS ${RUNTIME_PIPELINE_SRCS})
endif(USE_PIPELINE_EXECUTOR)

# Module rules
include(cmake/modules/VTA.cmake)
include(cmake/modules/StandaloneCrt.cmake)
Expand Down
3 changes: 3 additions & 0 deletions cmake/config.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ set(USE_GRAPH_EXECUTOR ON)
# Whether enable tiny graph executor with CUDA Graph
set(USE_GRAPH_EXECUTOR_CUDA_GRAPH OFF)

# Whether enable subgraph runtime.
set(USE_PIPELINE_EXECUTOR ON)

# Whether to enable the profiler for the graph executor and vm
set(USE_PROFILER ON)

Expand Down
176 changes: 176 additions & 0 deletions python/tvm/contrib/pipeline_executor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# 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.
"""Pipeline executor that executes pipeline containing TVM PackedFunc."""
import json
import tvm._ffi
from tvm import relay
from tvm.contrib import graph_executor


def pipeline_executor_enabled():
"""check if pipeline executor enabled.
Return
------
enable: bool
return pipeline executor get enabled or not
"""
pipeline_enabled = False
try:
pipelinecreate = tvm._ffi.get_global_func("tvm.pipeline_executor.create")
assert pipelinecreate
pipeline_enabled = True
except ValueError:
print("pipeline executor not enabled!")

return pipeline_enabled


def build_pipeline(mod_n_configs):
"""build module list that can use for pipeline execution.
Parameters
----------
mod_n_configs: Dict[IRModule, Dict[str, Any]]
build configuration informaton, structure like following.
{IRModule: {"target":target,
"target_host":target_host,
"params":params,
"mod_name"mod_name,
"build":build}}
Returns
-------
ret: List[IRModule]
list of IRModule
string_config: Dict[int, Dict[str, any]]
pipeline configuration
"""
mods = {}
config_len = len(mod_n_configs)
string_config = [{} for _ in range(config_len)]
for _, (ir_mod, mod_config) in enumerate(mod_n_configs.items()):
# init lib_name and json_name params with empty
lib_name = ""
json_name = ""
params_name = ""
# Get module configuration
assert "pipeline" in mod_config and "mod_indx" in mod_config["pipeline"]
# Get module index in pipeline configuration
mconf = mod_config["pipeline"].copy()
# Get mod device config
dev = mod_config["dev"]
mod_indx = mconf["mod_indx"] - 1
target = mod_config["target"]
assert mod_indx < config_len
build_func = relay.build
# if there is a self defined build function then use it.
if "build" in mod_config and mod_config["build"]:
build_func = mod_config["build"]

# build IRModule
mod = build_func(
ir_mod,
target,
params=mod_config["params"],
target_host=mod_config["target_host"],
mod_name=mod_config["mod_name"],
)

mconf["lib_name"] = lib_name
mconf["json_name"] = json_name
mconf["params_name"] = params_name
mconf["dev"] = "{},{}".format(dev.device_type, dev.device_id)
# Create pipeline configuration
string_config[mod_indx] = mconf
# associate mod with device
mods[mod] = {"dev": dev}

# return IRModule list and pipeline configuration
return mods, string_config


def create(pipeline_mods, mod_config):
"""Create a pipeline runtime executor.
Parameters
----------
pipeline_mods : List[IRModule]
list of IRModule
mod_config : Dict[int, Dict[str, Any]]
modules and modules dependency configuration informaiton.
Returns
-------
submodule : PipelineModule
Runtime pipeline module.
"""

submodule = PipelineModule(pipeline_mods, mod_config)
return submodule


class PipelineModule(object):
"""Wrapper runtime module. This is a thin wrapper of the underlying TVM module.
you can also directly call set_input, run, and get_output of underlying module functions.
Parameters
----------
graph_module : List[GraphModule]
The internal tvm module that holds the actual graph functions.
pipeline_config : Dict[IRModule, Dict[str, Any]]
modules and modules dependency configuration informaiton.
"""

def graph_executor_create(self, pipeline_mods, mod_config):
"""Create a pipeline runtime executor.
Parameters
----------
pipeline_mods : List[IRModule]
list of IRModule
mod_config : Dict[int, Dict[str, Any]]
modules and modules dependency configuration informaiton.
Returns
-------
mods : GreaphModule
Runtime graph module.
"""

mods = []
for pipeline_mod in pipeline_mods:
mod = graph_executor.GraphModule(
pipeline_mod["default"](pipeline_mods[pipeline_mod]["dev"])
)
mods.append(mod.module)

return mods, json.dumps(mod_config)

def __init__(self, pipeline_mods, mod_config):
self.pipeline_mods = pipeline_mods
self.mod_config = mod_config
mods, config = self.graph_executor_create(pipeline_mods, mod_config)

pipelinecreate = tvm._ffi.get_global_func("tvm.pipeline_executor.create")
assert pipelinecreate
module = pipelinecreate(mods, config)

self.module_ = module
49 changes: 49 additions & 0 deletions src/runtime/pipeline/pipeline_executor.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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.
*/

/*!
* \file pipeline_executor.cc
*/
#include "pipeline_executor.h"

namespace tvm {
namespace runtime {

void SubGraphRuntime::Init(const Array<tvm::runtime::Module>& modules,
const std::string& pipeline_json) {
return;
}

PackedFunc SubGraphRuntime::GetFunction(const std::string& name,
const ObjectPtr<Object>& sptr_to_self) {
return PackedFunc();
}

Module PipelineRuntimeCreate(const Array<tvm::runtime::Module>& m,
const std::string& pipeline_json) {
auto exec = make_object<SubGraphRuntime>();
exec->Init(m, pipeline_json);
return Module(exec);
}

TVM_REGISTER_GLOBAL("tvm.pipeline_executor.create").set_body([](TVMArgs args, TVMRetValue* rv) {
*rv = PipelineRuntimeCreate(args[0], args[1]);
});
} // namespace runtime
} // namespace tvm
72 changes: 72 additions & 0 deletions src/runtime/pipeline/pipeline_executor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* 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.
*/

/*!
* \brief pipeline executor
* \file pipeline_executor.h
*/
#ifndef TVM_RUNTIME_PIPELINE_PIPELINE_EXECUTOR_H_
#define TVM_RUNTIME_PIPELINE_PIPELINE_EXECUTOR_H_
#include <tvm/runtime/registry.h>

#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

#include "../file_utils.h"
using namespace std;
namespace tvm {
namespace runtime {

/*!
* \brief pipeline runtime.
*
* This runtime can be acccesibly in various language via
* TVM runtime PackedFunc API.
*/
class TVM_DLL SubGraphRuntime : public ModuleNode {
public:
/*!
* \return The type key of the executor.
*/
const char* type_key() const final { return "SubGraphRuntime"; }
/*!
* \brief Initialize the graph executor with graph and context.
* \param graph_json The execution graph.
* \param module The module containing the compiled functions for the host
* processor.
* \param ctxs The context of the host and devices where graph nodes will be
* executed on.
* \param lookup_linked_param_func If given, a PackedFunc invoked to lookup linked parameters
* by storage_id. If not given, linked parameters are looked-up using an internal implementation,
* which is not compatible with RPCModules.
*/
void Init(const Array<tvm::runtime::Module>& modules, const std::string& pipeline_json);
/*!
* \brief Get member function to front-end
* \param name The name of the function.
* \param sptr_to_self The pointer to the module node.
* \return The corresponding member function.
*/
virtual PackedFunc GetFunction(const std::string& name, const ObjectPtr<Object>& sptr_to_self);
};
} // namespace runtime
} // namespace tvm
#endif // TVM_RUNTIME_PIPELINE_PIPELINE_EXECUTOR_H_
Loading

0 comments on commit 8d41893

Please sign in to comment.