Skip to content
This repository was archived by the owner on Nov 16, 2023. It is now read-only.

Update clr helper function to search multiple folders for clr binaries. #72

Merged
merged 4 commits into from
Dec 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions src/python/nimbusml/internal/utils/entrypoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
from .data_stream import FileDataStream
from .dataframes import resolve_dataframe, resolve_csr_matrix, pd_concat, \
resolve_output
from .utils import try_set, set_clr_environment_vars, get_clr_path
from .utils import try_set, set_clr_environment_vars, get_clr_path, \
get_nimbusml_libs
from ..libs.pybridge import px_call


Expand Down Expand Up @@ -445,15 +446,11 @@ def remove_multi_level_index(c):
'graph = {%s} %s' %
(str(self), code), False, str)

# Set paths to ML.NET binaries (in nimbusml) and to .NET Core CLR binaries
nimbusml_path = os.path.abspath(os.path.join(
os.path.dirname(__file__), '..', 'libs'))
call_parameters['nimbusmlPath'] = try_set(nimbusml_path, True, str)
call_parameters['dotnetClrPath'] = try_set(nimbusml_path, True, str)
# dotnetcore2 package is available only for python 3.x
if six.PY3:
set_clr_environment_vars()
call_parameters['dotnetClrPath'] = try_set(get_clr_path(), True, str)
# Set paths to ML.NET libs (in nimbusml) and to .NET Core CLR libs
call_parameters['nimbusmlPath'] = try_set(get_nimbusml_libs(), True, str)
set_clr_environment_vars()
call_parameters['dotnetClrPath'] = try_set(get_clr_path(), True, str)

if random_state:
call_parameters['seed'] = try_set(random_state, False, int)
ret = self._try_call_bridge(
Expand Down
71 changes: 44 additions & 27 deletions src/python/nimbusml/internal/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,38 +283,55 @@ def set_clr_environment_vars():
Set system environment variables required by the .NET CLR.
Python 3.x only, as dotnetcore2 is not available for Python 2.x.
"""
from dotnetcore2 import runtime as clr_runtime
dependencies_path = None
try:
# try to resolve dependencies, for ex. libunwind
dependencies_path = clr_runtime.ensure_dependencies()
except:
if six.PY2:
pass
os.environ['DOTNET_SYSTEM_GLOBALIZATION_INVARIANT'] = 'true'
if dependencies_path is not None:
os.environ['LD_LIBRARY_PATH'] = dependencies_path
else:
from dotnetcore2 import runtime as clr_runtime
dependencies_path = None
try:
# try to resolve dependencies, specifically libunwind for Linux
dependencies_path = clr_runtime.ensure_dependencies()
except:
pass
# Without this, Linux versions would require the ICU package
os.environ['DOTNET_SYSTEM_GLOBALIZATION_INVARIANT'] = 'true'
# Will be None for Windows
if dependencies_path is not None:
os.environ['LD_LIBRARY_PATH'] = dependencies_path

def get_clr_path():
"""
Return path to .NET CLR binaries.
Python 3.x only, as dotnetcore2 is not available for Python 2.x.
Return path to .NET CLR libs.
Use dotnetcore2 package if Python 3.x, otherwise look for libs bundled with
NimbusML.
"""
from dotnetcore2 import runtime as clr_runtime
clr_version = pkg_resources.get_distribution('dotnetcore2').version
partial_path = os.path.join(clr_runtime._get_bin_folder(), 'shared', 'Microsoft.NETCore.App')
clr_path = os.path.join(partial_path, clr_version)
if not os.path.exists(clr_path):
# If folder name does not match published version, use the folder that
# exists
try:
version_folder = os.listdir(partial_path)[0]
except IndexError:
if six.PY2:
return get_nimbusml_libs()
else:
from dotnetcore2 import runtime as clr_runtime
libs_root = os.path.join(clr_runtime._get_bin_folder(), 'shared',
'Microsoft.NETCore.App')

# Search all libs folders to find which one contains the .NET CLR libs
libs_folders = os.listdir(libs_root)
if len(libs_folders) == 0:
raise ImportError("Trouble importing dotnetcore2: "
"{} had no version folder.".format(partial_path))
clr_path = os.path.join(partial_path, version_folder)
# Verify binaries are present
if not os.path.exists(os.path.join(clr_path, 'Microsoft.CSharp.dll')):
"{} had no libs folders.".format(libs_root))
clr_path = None
for folder in libs_folders:
if os.path.exists(os.path.join(libs_root, folder,
'Microsoft.CSharp.dll')):
clr_path = os.path.join(libs_root, folder)
break
if not clr_path:
raise ImportError(
"Trouble importing dotnetcore2: Microsoft.CSharp.dll was not "
"found in {}.".format(clr_path))
return clr_path
"found in {}.".format(libs_root))
return clr_path

def get_nimbusml_libs():
"""
Return path to NimbusML libs (the ML.NET binaries).
"""
return os.path.abspath(os.path.join(os.path.dirname(__file__), '..',
'libs'))