Commit 40486b6c authored by Nikita Titov's avatar Nikita Titov Committed by Tsukasa OMOTO
Browse files

[python] added OpenMP options for python-package installation (#1975)

* added OpenMP options for python-package installation

* fixed grammar typo
parent 5530f286
......@@ -43,7 +43,17 @@ Build from Sources
For **Linux** and **macOS** users, installation from sources requires installed `CMake`_.
For **macOS** users, you can perform installation either with **Apple Clang** or **gcc**. In case you prefer **Apple Clang**, you should install **OpenMP** (details for installation can be found in `Installation Guide <https://github.com/Microsoft/LightGBM/blob/master/docs/Installation-Guide.rst#apple-clang>`__) first and **CMake** version 3.12 or higher is required. In case you prefer **gcc**, you need to install it (details for installation can be found in `Installation Guide <https://github.com/Microsoft/LightGBM/blob/master/docs/Installation-Guide.rst#gcc>`__) and specify compilers by running ``export CXX=g++-7 CC=gcc-7`` (replace "7" with version of **gcc** installed on your machine) first.
For **macOS** users, you can perform installation either with **Apple Clang** or **gcc**.
- In case you prefer **Apple Clang**, you should install **OpenMP** (details for installation can be found in `Installation Guide <https://github.com/Microsoft/LightGBM/blob/master/docs/Installation-Guide.rst#apple-clang>`__) first and **CMake** version 3.12 or higher is required.
In some cases **OpenMP** cannot be found which causes installation failures. So, if you encounter errors during the installation process, try to pass paths to **CMake** via ``pip`` options, like
.. code:: sh
pip install lightgbm --install-option="--openmp-include-dir=/usr/local/opt/libomp/include/" --install-option="--openmp-library=/usr/local/opt/libomp/lib/libomp.dylib"
- In case you prefer **gcc**, you need to install it (details for installation can be found in `Installation Guide <https://github.com/Microsoft/LightGBM/blob/master/docs/Installation-Guide.rst#gcc>`__) and specify compilers by running ``export CXX=g++-7 CC=gcc-7`` (replace "7" with version of **gcc** installed on your machine) first.
For **Windows** users, **Visual Studio** (or `VS Build Tools <https://visualstudio.microsoft.com/downloads/>`_) is needed. If you get any errors during installation, you may need to install `CMake`_ (version 3.8 or higher).
......@@ -129,6 +139,8 @@ Install from GitHub
All remarks from `Build from Sources section <#build-from-sources>`__ are actual in this case.
For **macOS** users who compile with **Apple Clang**, to pass **OpenMP** paths to **CMake** use the following syntax: ``python setup.py install --openmp-include-dir=/usr/local/opt/libomp/include/ --openmp-library=/usr/local/opt/libomp/lib/libomp.dylib``.
For **Windows** users, if you get any errors during installation and there is the warning ``WARNING:LightGBM:Compilation with MSBuild from existing solution file failed.`` in the log, you should install `CMake`_ (version 3.8 or higher).
.. code:: sh
......
......@@ -90,7 +90,8 @@ def silent_call(cmd, raise_error=False, error_msg=''):
def compile_cpp(use_mingw=False, use_gpu=False, use_mpi=False, nomp=False,
use_hdfs=False, boost_root=None, boost_dir=None,
boost_include_dir=None, boost_librarydir=None,
opencl_include_dir=None, opencl_library=None):
opencl_include_dir=None, opencl_library=None,
openmp_include_dir=None, openmp_library=None):
if os.path.exists(os.path.join(CURRENT_DIR, "build_cpp")):
shutil.rmtree(os.path.join(CURRENT_DIR, "build_cpp"))
......@@ -118,19 +119,6 @@ def compile_cpp(use_mingw=False, use_gpu=False, use_mpi=False, nomp=False,
cmake_cmd.append("-DUSE_MPI=ON")
if nomp:
cmake_cmd.append("-DUSE_OPENMP=OFF")
if system() == 'Darwin' and not nomp:
cc = os.environ.get('CC')
cxx = os.environ.get('CXX')
if not (cc and cc.startswith('gcc') and cxx and cxx.startswith('g++')):
# Apple Clang
# https://github.com/Homebrew/homebrew-core/pull/20589
cmake_cmd.extend([
'-DOpenMP_C_FLAGS=-Xpreprocessor -fopenmp -I/usr/local/opt/libomp/include',
'-DOpenMP_C_LIB_NAMES=omp',
'-DOpenMP_CXX_FLAGS=-Xpreprocessor -fopenmp -I/usr/local/opt/libomp/include',
'-DOpenMP_CXX_LIB_NAMES=omp',
'-DOpenMP_omp_LIBRARY=/usr/local/opt/libomp/lib/libomp.dylib'
])
if use_hdfs:
cmake_cmd.append("-DUSE_HDFS=ON")
......@@ -177,9 +165,41 @@ def compile_cpp(use_mingw=False, use_gpu=False, use_mpi=False, nomp=False,
error_msg='Please install CMake first')
else: # Linux, Darwin (macOS), etc.
logger.info("Starting to compile with CMake.")
silent_call(cmake_cmd, raise_error=True, error_msg='Please install CMake and all required dependencies first')
silent_call(["make", "_lightgbm", "-j4"], raise_error=True,
error_msg='An error has occurred while building lightgbm library file')
# Apple Clang with OpenMP
if system() == 'Darwin' and not nomp and not (os.environ.get('CC', '').startswith('gcc')
and os.environ.get('CXX', '').startswith('g++')):
def get_cmake_opts(openmp_include_dir, openmp_library):
if openmp_include_dir and openmp_library:
return ['-DOpenMP_C_FLAGS=-Xpreprocessor -fopenmp -I{0}'.format(openmp_include_dir),
'-DOpenMP_C_LIB_NAMES=omp',
'-DOpenMP_CXX_FLAGS=-Xpreprocessor -fopenmp -I{0}'.format(openmp_include_dir),
'-DOpenMP_CXX_LIB_NAMES=omp',
'-DOpenMP_omp_LIBRARY={0}'.format(openmp_library)]
else:
return []
status = silent_call(cmake_cmd + get_cmake_opts(openmp_include_dir, openmp_library))
status += silent_call(["make", "_lightgbm", "-j4"])
if status != 0:
logger.warning("Compilation failed.")
logger.info("Starting to compile with Homebrew OpenMP paths guesses.")
clear_path(os.path.join(CURRENT_DIR, "build_cpp"))
status = silent_call(cmake_cmd + get_cmake_opts('/usr/local/opt/libomp/include',
'/usr/local/opt/libomp/lib/libomp.dylib'))
status += silent_call(["make", "_lightgbm", "-j4"])
if status != 0:
logger.warning("Compilation failed.")
logger.info("Starting to compile with MacPorts OpenMP paths guesses.")
clear_path(os.path.join(CURRENT_DIR, "build_cpp"))
silent_call(cmake_cmd + get_cmake_opts('/opt/local/include/libomp',
'/opt/local/lib/libomp/libomp.dylib'),
raise_error=True, error_msg='Please install CMake and all required dependencies first')
silent_call(["make", "_lightgbm", "-j4"], raise_error=True,
error_msg='An error has occurred while building lightgbm library file')
else:
silent_call(cmake_cmd, raise_error=True, error_msg='Please install CMake and all required dependencies first')
silent_call(["make", "_lightgbm", "-j4"], raise_error=True,
error_msg='An error has occurred while building lightgbm library file')
os.chdir(CURRENT_DIR)
......@@ -208,7 +228,9 @@ class CustomInstall(install):
('boost-include-dir=', None, 'Directory containing Boost headers'),
('boost-librarydir=', None, 'Preferred Boost library directory'),
('opencl-include-dir=', None, 'OpenCL include directory'),
('opencl-library=', None, 'Path to OpenCL library')
('opencl-library=', None, 'Path to OpenCL library'),
('openmp-include-dir=', None, 'OpenMP include directory'),
('openmp-library=', None, 'Path to OpenMP library')
]
def initialize_options(self):
......@@ -221,6 +243,8 @@ class CustomInstall(install):
self.boost_librarydir = None
self.opencl_include_dir = None
self.opencl_library = None
self.openmp_include_dir = None
self.openmp_library = None
self.mpi = 0
self.hdfs = 0
self.precompile = 0
......@@ -233,7 +257,8 @@ class CustomInstall(install):
compile_cpp(use_mingw=self.mingw, use_gpu=self.gpu, use_mpi=self.mpi, nomp=self.nomp,
use_hdfs=self.hdfs, boost_root=self.boost_root, boost_dir=self.boost_dir,
boost_include_dir=self.boost_include_dir, boost_librarydir=self.boost_librarydir,
opencl_include_dir=self.opencl_include_dir, opencl_library=self.opencl_library)
opencl_include_dir=self.opencl_include_dir, opencl_library=self.opencl_library,
openmp_include_dir=self.openmp_include_dir, openmp_library=self.openmp_library)
install.run(self)
if os.path.isfile(LOG_PATH):
os.remove(LOG_PATH)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment