Skip to content

Commit 57c5468

Browse files
committed
Implement support for compiling against MKL with new setup.py
1 parent de1ca53 commit 57c5468

File tree

3 files changed

+51
-165
lines changed

3 files changed

+51
-165
lines changed

numexpr/numexpr_config.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
# define USE_UNALIGNED_ACCESS 1
88
#endif
99

10-
#ifdef SCIPY_MKL_H
11-
#define USE_VML
12-
#endif
10+
// #ifdef SCIPY_MKL_H
11+
// #define USE_VML
12+
// #endif
1313

1414
#ifdef USE_VML
1515
/* The values below have been tuned for a Skylake processor (E3-1245 v5 @ 3.50GHz) */

setup.py

+39-118
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
fh.write("numpy_build_version = '%s'\n" % numpy.__version__)
4040
except ImportError:
4141
pass
42-
42+
4343
lib_dirs = []
4444
inc_dirs = [np.get_include(), op.join('framestream')]
4545
libs = [] # Pre-built libraries ONLY, like python36.so
@@ -59,16 +59,46 @@
5959
extra_cflags = []
6060
extra_link_args = []
6161

62-
numexpr_extension = Extension('numexpr.interpreter',
63-
include_dirs=inc_dirs,
64-
define_macros=def_macros,
65-
sources=sources,
66-
library_dirs=lib_dirs,
67-
libraries=libs,
68-
extra_compile_args=extra_cflags,
69-
extra_link_args=extra_link_args,)
62+
def parse_site_cfg():
63+
"""
64+
Parses `site.cfg`, if it exists, to determine the location of Intel oneAPI MKL.
65+
66+
To compile NumExpr with MKL (VML) support, typically you need to copy the
67+
provided `site.cfg.example` to `site.cfg` and then edit the paths in the
68+
configuration lines for `include_dirs` and `library_dirs` paths to point
69+
to the appropriate directories on your machine.
70+
"""
71+
import configparser
72+
site = configparser.ConfigParser()
73+
if not op.isfile('site.cfg'):
74+
return
75+
76+
site.read('site.cfg')
77+
78+
if 'mkl' in site.sections():
79+
inc_dirs.extend(
80+
site['mkl']['include_dirs'].split(os.pathsep))
81+
lib_dirs.extend(
82+
site['mkl']['library_dirs'].split(os.pathsep))
83+
libs.extend(
84+
site['mkl']['libraries'].split(os.pathsep))
85+
def_macros.append(('USE_VML', None))
86+
7087

7188
def setup_package():
89+
90+
parse_site_cfg()
91+
92+
numexpr_extension = Extension('numexpr.interpreter',
93+
include_dirs=inc_dirs,
94+
define_macros=def_macros,
95+
sources=sources,
96+
library_dirs=lib_dirs,
97+
libraries=libs,
98+
extra_compile_args=extra_cflags,
99+
extra_link_args=extra_link_args,)
100+
101+
72102
metadata = dict(
73103
name = 'numexpr',
74104
version = version,
@@ -111,115 +141,6 @@ def setup_package():
111141
],
112142

113143
)
114-
115-
# def configuration():
116-
# from numpy.distutils.misc_util import Configuration, dict_append
117-
# from numpy.distutils.system_info import system_info
118-
119-
# config = Configuration('numexpr')
120-
121-
# #try to find configuration for MKL, either from environment or site.cfg
122-
# if op.exists('site.cfg'):
123-
# mkl_config_data = config.get_info('mkl')
124-
# # Some version of MKL needs to be linked with libgfortran.
125-
# # For this, use entries of DEFAULT section in site.cfg.
126-
# default_config = system_info()
127-
# dict_append(mkl_config_data,
128-
# libraries=default_config.get_libraries(),
129-
# library_dirs=default_config.get_lib_dirs())
130-
# else:
131-
# mkl_config_data = {}
132-
133-
# # setup information for C extension
134-
# if os.name == 'nt':
135-
# pthread_win = ['numexpr/win32/pthread.c']
136-
# else:
137-
# pthread_win = []
138-
# extension_config_data = {
139-
# 'sources': ['numexpr/interpreter.cpp',
140-
# 'numexpr/module.cpp',
141-
# 'numexpr/numexpr_object.cpp'] + pthread_win,
142-
# 'depends': ['numexpr/interp_body.cpp',
143-
# 'numexpr/complex_functions.hpp',
144-
# 'numexpr/interpreter.hpp',
145-
# 'numexpr/module.hpp',
146-
# 'numexpr/msvc_function_stubs.hpp',
147-
# 'numexpr/numexpr_config.hpp',
148-
# 'numexpr/numexpr_object.hpp'],
149-
# 'libraries': ['m'],
150-
# 'extra_compile_args': ['-funroll-all-loops', ],
151-
# }
152-
# dict_append(extension_config_data, **mkl_config_data)
153-
# if 'library_dirs' in mkl_config_data:
154-
# library_dirs = ':'.join(mkl_config_data['library_dirs'])
155-
# config.add_extension('interpreter', **extension_config_data)
156-
# config.set_options(quiet=True)
157-
158-
# config.make_config_py()
159-
# config.add_subpackage('tests', 'numexpr/tests')
160-
161-
# #version handling
162-
# config.get_version('numexpr/version.py')
163-
# return config
164-
165-
166-
# class cleaner(setuptools.command.clean):
167-
#
168-
# def run(self):
169-
# # Recursive deletion of build/ directory
170-
# path = localpath("build")
171-
# try:
172-
# shutil.rmtree(path)
173-
# except Exception:
174-
# debug("Failed to remove directory %s" % path)
175-
# else:
176-
# debug("Cleaned up %s" % path)
177-
#
178-
# # Now, the extension and other files
179-
# try:
180-
# import imp
181-
# except ImportError:
182-
# if os.name == 'posix':
183-
# paths = [localpath("numexpr/interpreter.so")]
184-
# else:
185-
# paths = [localpath("numexpr/interpreter.pyd")]
186-
# else:
187-
# paths = []
188-
# for suffix, _, _ in imp.get_suffixes():
189-
# if suffix == '.py':
190-
# continue
191-
# paths.append(localpath("numexpr", "interpreter" + suffix))
192-
# paths.append(localpath("numexpr/__config__.py"))
193-
# paths.append(localpath("numexpr/__config__.pyc"))
194-
# for path in paths:
195-
# try:
196-
# os.remove(path)
197-
# except Exception:
198-
# debug("Failed to clean up file %s" % path)
199-
# else:
200-
# debug("Cleaning up %s" % path)
201-
#
202-
# setuptools.clean.run(self)
203-
204-
# class build_ext(numpy_build_ext):
205-
# def build_extension(self, ext):
206-
# # at this point we know what the C compiler is.
207-
# if self.compiler.compiler_type == 'msvc' or self.compiler.compiler_type == 'intelemw':
208-
# ext.extra_compile_args = []
209-
# # also remove extra linker arguments msvc doesn't understand
210-
# ext.extra_link_args = []
211-
# # also remove gcc math library
212-
# ext.libraries.remove('m')
213-
# numpy_build_ext.build_extension(self, ext)
214-
215-
216-
# metadata['cmdclass'] = {
217-
# 'build_ext': build_ext,
218-
# # 'clean': cleaner,
219-
# 'build_py': build_py,
220-
# }
221-
# metadata['configuration'] = configuration
222-
223144
setup(**metadata)
224145

225146

site.cfg.example

+9-44
Original file line numberDiff line numberDiff line change
@@ -2,51 +2,16 @@
22
# file to "site.cfg" and edit the paths according to your installation of the
33
# Intel MKL.
44

5-
# Note: some versions of MKL need to be linked to gfortran if compiled with
6-
# GNU C compiler. Uncomment next line if you get an error like "undefined
7-
# symbol: _gfortran_malloc"
8-
#
9-
# Note2: Some Fedora users reported that they had to install a
10-
# compatible version of the gfortran lib. See:
11-
# http://code.google.com/p/numexpr/issues/detail?id=15
12-
# for more info.
13-
[DEFAULT]
14-
#libraries = gfortran
5+
# Example for Intel(R) MKL 2018 on Linux
6+
# [mkl]
7+
# library_dirs = /opt/intel/compilers_and_libraries_2018/linux/mkl/lib/intel64
8+
# include_dirs = /opt/intel/compilers_and_libraries_2018/linux/mkl/include
9+
# libraries = mkl_rt
1510

16-
#[mkl]
17-
# Example for the MKL included in Intel C 11.0 compiler
18-
# (you may need a recent NumPy version for being able to search libraries
19-
# in different directories at a time)
20-
#library_dirs = /opt/intel/Compiler/11.0/074/mkl/lib/em64t/:/opt/intel/Compiler/11.0/074/lib/intel64
21-
#include_dirs = /opt/intel/Compiler/11.0/074/mkl/include/
22-
#libraries = mkl_solver_ilp64, mkl_intel_ilp64, mkl_intel_thread, mkl_core, iomp5
2311

24-
# This seems to work for MKL 11 with processors with AVX (Sandy Bridge and above) for Linux
25-
#library_dirs = /opt/intel/composerxe/mkl/lib/intel64:/opt/intel/composer_xe_2013.3.163/compiler/lib/intel64
26-
#include_dirs = /opt/intel/composerxe/mkl/include/
27-
#libraries = mkl_intel_lp64, mkl_gf_lp64, mkl_intel_thread, mkl_core, mkl_blas95_lp64, mkl_lapack95_lp64, mkl_avx, mkl_vml_avx, mkl_rt, iomp5
28-
29-
## Example for using MKL 10.0
30-
#library_dirs = /opt/intel/mkl/10.0.2.018/lib/em64t
31-
#include_dirs = /opt/intel/mkl/10.0.2.018/include
32-
33-
# Example for using MKL 10.2 for Windows 64-bit
34-
#include_dirs = \Program Files\Intel\MKL\10.2.5.035\include
35-
#library_dirs = \Program Files\Intel\MKL\10.2.5.035\em64t\lib
36-
#libraries = mkl_solver_ilp64, mkl_core, mkl_intel_thread, mkl_intel_ilp64, libiomp5md
37-
# The next works too, but for LP64 arithmetic
38-
#libraries = mkl_core, mkl_intel_thread, mkl_intel_lp64, libiomp5md
39-
40-
# Example with Intel compiler version 14.0.2 and MKL v11.1.2 on intel64 architecture
41-
#libraries = mkl_intel_lp64, mkl_gf_lp64, mkl_intel_thread, mkl_core, mkl_def, mkl_vml_avx, mkl_rt, iomp5
42-
# For details, see https://github.com/pydata/numexpr/issues/148
43-
44-
# Example for MKL2018 on Windows x64
45-
# https://software.intel.com/en-us/articles/building-numpyscipy-with-intel-mkl-and-intel-fortran-on-windows
12+
# Example for Intel(R) oneAPI MKL on Windows x64
4613
# Please note that the valid os.pathsep is ';' on Windows and ':' on Linux
47-
# and that numpy.distutils.system_info only accepts the first instance of library_dirs
48-
# Last make sure you do `python setup.py install` instead of using pip.
4914
[mkl]
50-
library_dirs=/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/intel64;/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/compiler/lib/intel64
51-
include_dirs=/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/include
52-
libraries = mkl_intel_lp64, mkl_intel_thread, mkl_core, libiomp5md
15+
include_dirs=C:/Program Files (x86)/Intel/oneAPI/mkl/latest/include
16+
library_dirs=C:/Program Files (x86)/Intel/oneAPI/mkl/latest/lib/intel64
17+
libraries=mkl_rt

0 commit comments

Comments
 (0)