Skip to content

Commit

Permalink
MNT Update setup and travis to support OpenMP (scikit-learn#13053)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremiedbb authored and jnothman committed Feb 4, 2019
1 parent 1610094 commit 7307b56
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 3 deletions.
16 changes: 16 additions & 0 deletions build_tools/travis/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ then
# export CCACHE_LOGFILE=/tmp/ccache.log
# ~60M is used by .ccache when compiling from scratch at the time of writing
ccache --max-size 100M --show-stats
elif [ $TRAVIS_OS_NAME = "osx" ]
then
# install OpenMP not present by default on osx
brew install libomp

# enable OpenMP support for Apple-clang
export CC=/usr/bin/clang
export CXX=/usr/bin/clang++
export CPPFLAGS="$CPPFLAGS -Xpreprocessor -fopenmp"
export CFLAGS="$CFLAGS -I/usr/local/opt/libomp/include"
export CXXFLAGS="$CXXFLAGS -I/usr/local/opt/libomp/include"
export LDFLAGS="$LDFLAGS -L/usr/local/opt/libomp/lib -lomp"
export DYLD_LIBRARY_PATH=/usr/local/opt/libomp/lib

# avoid error due to multiple OpenMP libraries loaded simultaneously
export KMP_DUPLICATE_LIB_OK=TRUE
fi

make_conda() {
Expand Down
30 changes: 28 additions & 2 deletions doc/developers/advanced_installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ Scikit-learn requires:

Building Scikit-learn also requires

- Cython >=0.28.5
- Cython >=0.28.5
- OpenMP

Running tests requires

Expand Down Expand Up @@ -102,6 +103,31 @@ On Unix-like systems, you can simply type ``make`` in the top-level folder to
build in-place and launch all the tests. Have a look at the ``Makefile`` for
additional utilities.

Mac OSX
-------

The default C compiler, Apple-clang, on Mac OSX does not directly support
OpenMP. The first solution to build scikit-learn is to install another C
compiler such as gcc or llvm-clang. Another solution is to enable OpenMP
support on the default Apple-clang. In the following we present how to
configure this second option.

You first need to install the OpenMP library::

brew install libomp

Then you need to set the following environment variables::

export CC=clang
export CXX=clang++
export CPPFLAGS="$CPPFLAGS -Xpreprocessor -fopenmp"
export CFLAGS="$CFLAGS -I/usr/local/opt/libomp/include"
export CXXFLAGS="$CXXFLAGS -I/usr/local/opt/libomp/include"
export LDFLAGS="$LDFLAGS -L/usr/local/opt/libomp/lib -lomp"
export DYLD_LIBRARY_PATH=/usr/local/opt/libomp/lib

Finally you can build the package using the standard command.

Installing build dependencies
=============================

Expand All @@ -111,7 +137,7 @@ Linux
Installing from source requires you to have installed the scikit-learn runtime
dependencies, Python development headers and a working C/C++ compiler.
Under Debian-based operating systems, which include Ubuntu::

sudo apt-get install build-essential python3-dev python3-setuptools \
python3-numpy python3-scipy \
libatlas-dev libatlas3-base
Expand Down
52 changes: 51 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,57 @@ def run(self):
shutil.rmtree(os.path.join(dirpath, dirname))


cmdclass = {'clean': CleanCommand}
def get_openmp_flag(compiler):
if sys.platform == "win32" and ('icc' in compiler or 'icl' in compiler):
return ['/Qopenmp']
elif sys.platform == "win32":
return ['/openmp']
elif sys.platform == "darwin" and ('icc' in compiler or 'icl' in compiler):
return ['-openmp']
elif sys.platform == "darwin" and 'openmp' in os.getenv('CPPFLAGS', ''):
# -fopenmp can't be passed as compile flag when using Apple-clang.
# OpenMP support has to be enabled during preprocessing.
#
# For example, our macOS wheel build jobs use the following environment
# variables to build with Apple-clang and the brew installed "libomp":
#
# export CPPFLAGS="$CPPFLAGS -Xpreprocessor -fopenmp"
# export CFLAGS="$CFLAGS -I/usr/local/opt/libomp/include"
# export LDFLAGS="$LDFLAGS -L/usr/local/opt/libomp/lib -lomp"
# export DYLD_LIBRARY_PATH=/usr/local/opt/libomp/lib
return ['']
# Default flag for GCC and clang:
return ['-fopenmp']


OPENMP_EXTENSIONS = []


# custom build_ext command to set OpenMP compile flags depending on os and
# compiler
# build_ext has to be imported after setuptools
from numpy.distutils.command.build_ext import build_ext # noqa


class build_ext_subclass(build_ext):
def build_extensions(self):
if hasattr(self.compiler, 'compiler'):
compiler = self.compiler.compiler[0]
else:
compiler = self.compiler.__class__.__name__

openmp_flag = get_openmp_flag(compiler)

for e in self.extensions:
if e.name in OPENMP_EXTENSIONS:
e.extra_compile_args += openmp_flag
e.extra_link_args += openmp_flag

build_ext.build_extensions(self)


cmdclass = {'clean': CleanCommand, 'build_ext': build_ext_subclass}


# Optional wheelhouse-uploader features
# To automate release of binary packages for scikit-learn we need a tool
Expand Down

0 comments on commit 7307b56

Please sign in to comment.