176 lines
6.0 KiB
Python
176 lines
6.0 KiB
Python
# 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.
|
|
# pylint: disable=invalid-name, no-member
|
|
|
|
"""Executable object for TVM Runtime"""
|
|
|
|
from collections.abc import Callable
|
|
from typing import Any
|
|
|
|
from tvm_ffi import Function
|
|
|
|
import tvm
|
|
from tvm.support import utils as _utils
|
|
|
|
from . import Module
|
|
|
|
|
|
class Executable:
|
|
"""The executable object generated by `tvm.compile`."""
|
|
|
|
def __init__(self, mod: Module):
|
|
"""Initialize the Executable object."""
|
|
self.mod: Module = mod
|
|
self._jitted_mod: Module | None = None
|
|
|
|
def __getitem__(self, name: str) -> Function:
|
|
"""Get the Function from the jitted module."""
|
|
return self.jit().get_function(name, query_imports=True)
|
|
|
|
def __call__(self, *args, **kwargs) -> Any:
|
|
"""Call the executable."""
|
|
return self.jit().main(*args, **kwargs)
|
|
|
|
def jit(
|
|
self,
|
|
*,
|
|
fcompile: Callable[[str, list[str], dict[str, Any]], None] | None = None,
|
|
addons: list[str] | None = None,
|
|
force_recompile: bool = False,
|
|
**kwargs,
|
|
) -> Module:
|
|
"""Just-in-time compile and link the modules.
|
|
|
|
The Executable returned by tvm.compile may not be directly
|
|
runnable as they may contain CUDA source files and objects that
|
|
are yet to be compiled and linked.
|
|
This function helps to create a runtime.Module for these cases.
|
|
|
|
Parameters
|
|
----------
|
|
fcompile : function(target, file_list, kwargs), optional
|
|
The compilation function to use create the final library object during
|
|
|
|
addons : list of str, optional
|
|
Additional object files to link against.
|
|
|
|
force_recompile : bool, optional
|
|
If True, force a recompile of the module.
|
|
|
|
kwargs : dict, optional
|
|
Additional arguments passed to fcompile
|
|
|
|
Returns
|
|
-------
|
|
rt_mod: tvm.runtime.Module
|
|
A runnable runtime module that can be passed to VirtualMachine.
|
|
|
|
Examples
|
|
--------
|
|
.. code:: python
|
|
|
|
ex = tvm.compile(mod, target)
|
|
rt_mod = ex.jit()
|
|
|
|
"""
|
|
|
|
# If the module is already jitted and we don't want to force a recompile,
|
|
# return the cached module
|
|
if self._jitted_mod is not None and not force_recompile:
|
|
return self._jitted_mod
|
|
|
|
# TODO(tvm-team): Update runtime.Module interface
|
|
# to query these properties as bitmask.
|
|
def _not_runnable(x):
|
|
return x.kind in ("c", "static_library")
|
|
|
|
# pylint:disable = protected-access
|
|
not_runnable_list = self.mod._collect_from_import_tree(_not_runnable)
|
|
|
|
# everything is runnable, directly return mod.
|
|
if len(not_runnable_list) == 0:
|
|
return self.mod
|
|
|
|
# found source module, or other not runnable modules need to be export and load
|
|
# TODO(tvm-team): Support runnable but not exportable module.
|
|
# by collecting the link and allow export_library skip those modules.
|
|
workspace_dir = _utils.tempdir()
|
|
dso_path = workspace_dir.relpath("exported.so")
|
|
self.export_library(dso_path, fcompile=fcompile, addons=addons, **kwargs)
|
|
self._jitted_mod = tvm.runtime.load_module(dso_path)
|
|
return self._jitted_mod
|
|
|
|
def export_library(
|
|
self,
|
|
file_name,
|
|
*,
|
|
fcompile=None,
|
|
addons=None,
|
|
workspace_dir=None,
|
|
**kwargs,
|
|
):
|
|
"""
|
|
Export the module and all imported modules into a single device library.
|
|
|
|
This function only works on host LLVM modules, other runtime::Module
|
|
subclasses will work with this API but they must support implement
|
|
the save and load mechanisms of modules completely including saving
|
|
from streams and files. This will pack your non-shared library module
|
|
into a single shared library which can later be loaded by TVM.
|
|
|
|
Parameters
|
|
----------
|
|
file_name : str
|
|
The name of the shared library.
|
|
|
|
fcompile : function(target, file_list, kwargs), optional
|
|
The compilation function to use create the final library object during
|
|
export.
|
|
|
|
For example, when fcompile=_cc.create_shared, or when it is not supplied but
|
|
module is "llvm," this is used to link all produced artifacts
|
|
into a final dynamic library.
|
|
|
|
This behavior is controlled by the type of object exported.
|
|
If fcompile has attribute object_format, will compile host library
|
|
to that format. Otherwise, will use default format "o".
|
|
|
|
addons : list of str, optional
|
|
Additional object files to link against.
|
|
|
|
workspace_dir : str, optional
|
|
The path of the directory used to create the intermediate
|
|
artifacts when exporting the module.
|
|
If this is not provided a temporary dir will be created.
|
|
|
|
kwargs : dict, optional
|
|
Additional arguments passed to fcompile
|
|
|
|
Returns
|
|
-------
|
|
result of fcompile() : unknown, optional
|
|
If the compilation function returns an artifact it would be returned via
|
|
export_library, if any.
|
|
"""
|
|
return self.mod.export_library(
|
|
file_name,
|
|
fcompile=fcompile,
|
|
addons=addons,
|
|
workspace_dir=workspace_dir,
|
|
**kwargs,
|
|
)
|