in python/treelite/contrib/__init__.py [0:0]
def create_shared(toolchain, dirpath, nthread=None, verbose=False, options=None):
"""Create shared library.
Parameters
----------
toolchain : :py:class:`str <python:str>`
which toolchain to use. You may choose one of 'msvc', 'clang', and 'gcc'.
You may also specify a specific variation of clang or gcc (e.g. 'gcc-7')
dirpath : :py:class:`str <python:str>`
directory containing the header and source files previously generated
by :py:meth:`Model.compile`. The directory must contain recipe.json
which specifies build dependencies.
nthread : :py:class:`int <python:int>`, optional
number of threads to use in creating the shared library.
Defaults to the number of cores in the system.
verbose : :py:class:`bool <python:bool>`, optional
whether to produce extra messages
options : :py:class:`list <python:list>` of :py:class:`str <python:str>`, \
optional
Additional options to pass to toolchain
Returns
-------
libpath : :py:class:`str <python:str>`
absolute path of created shared library
Example
-------
The following command uses Visual C++ toolchain to generate
``./my/model/model.dll``:
.. code-block:: python
model.compile(dirpath='./my/model', params={}, verbose=True)
create_shared(toolchain='msvc', dirpath='./my/model', verbose=True)
Later, the shared library can be referred to by its directory name:
.. code-block:: python
predictor = Predictor(libpath='./my/model', verbose=True)
# looks for ./my/model/model.dll
Alternatively, one may specify the library down to its file name:
.. code-block:: python
predictor = Predictor(libpath='./my/model/model.dll', verbose=True)
"""
# pylint: disable=R0912
if nthread is not None and nthread <= 0:
raise TreeliteError('nthread must be positive integer')
dirpath = expand_windows_path(dirpath)
if not os.path.isdir(dirpath):
raise TreeliteError('Directory {} does not exist'.format(dirpath))
try:
with open(os.path.join(dirpath, 'recipe.json')) as f:
recipe = json.load(f)
except IOError:
raise TreeliteError('Failed to open recipe.json')
if 'sources' not in recipe or 'target' not in recipe:
raise TreeliteError('Malformed recipe.json')
if options is not None:
try:
_ = iter(options)
options = [str(x) for x in options]
except TypeError:
raise TreeliteError('options must be a list of string')
else:
options = []
# write warning for potentially long compile time
long_time_warning = False
for source in recipe['sources']:
if int(source['length']) > 10000:
long_time_warning = True
break
if long_time_warning:
log_info(__file__, lineno(),
'\033[1;31mWARNING: some of the source files are long. ' +\
'Expect long compilation time.\u001B[0m '+\
'You may want to adjust the parameter ' +\
'\x1B[33mparallel_comp\u001B[0m.\n')
tstart = time.time()
_toolchain_exist_check(toolchain)
if toolchain == 'msvc':
from .msvc import _create_shared
else:
from .gcc import _create_shared
libpath = \
_create_shared(dirpath, toolchain, recipe, nthread, options, verbose)
if verbose:
log_info(__file__, lineno(),
'Generated shared library in '+\
'{0:.2f} seconds'.format(time.time() - tstart))
return libpath