|
|
6acf609 |
--- theano/configdefaults.py.orig 2019-01-15 14:13:57.000000000 -0700
|
|
|
6acf609 |
+++ theano/configdefaults.py 2019-08-23 08:49:26.259908947 -0600
|
|
|
062ec9e |
@@ -1274,221 +1274,8 @@ sure you have the right version you *wil
|
|
|
2f012fb |
|
|
|
2f012fb |
|
|
|
2f012fb |
def default_blas_ldflags():
|
|
|
2f012fb |
- global numpy
|
|
|
2f012fb |
- warn_record = []
|
|
|
2f012fb |
- try:
|
|
|
2f012fb |
- if (hasattr(np.distutils, '__config__') and
|
|
|
2f012fb |
- np.distutils.__config__):
|
|
|
2f012fb |
- # If the old private interface is available use it as it
|
|
|
2f012fb |
- # don't print information to the user.
|
|
|
2f012fb |
- blas_info = np.distutils.__config__.blas_opt_info
|
|
|
2f012fb |
- else:
|
|
|
2f012fb |
- # We do this import only here, as in some setup, if we
|
|
|
2f012fb |
- # just import theano and exit, with the import at global
|
|
|
2f012fb |
- # scope, we get this error at exit: "Exception TypeError:
|
|
|
2f012fb |
- # "'NoneType' object is not callable" in
|
|
|
2f012fb |
- # Popen.__del__ of <subprocess.Popen object at 0x21359d0>>
|
|
|
2f012fb |
- # ignored"
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- # This happen with Python 2.7.3 |EPD 7.3-1 and numpy 1.8.1
|
|
|
2f012fb |
- import numpy.distutils.system_info # noqa
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- # We need to catch warnings as in some cases NumPy print
|
|
|
2f012fb |
- # stuff that we don't want the user to see.
|
|
|
2f012fb |
- # I'm not able to remove all printed stuff
|
|
|
2f012fb |
- with warnings.catch_warnings(record=True):
|
|
|
2f012fb |
- numpy.distutils.system_info.system_info.verbosity = 0
|
|
|
2f012fb |
- blas_info = numpy.distutils.system_info.get_info("blas_opt")
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- # If we are in a EPD installation, mkl is available
|
|
|
2f012fb |
- if "EPD" in sys.version:
|
|
|
2f012fb |
- use_unix_epd = True
|
|
|
2f012fb |
- if sys.platform == 'win32':
|
|
|
2f012fb |
- return ' '.join(
|
|
|
2f012fb |
- ['-L"%s"' % os.path.join(sys.prefix, "Scripts")] +
|
|
|
2f012fb |
- # Why on Windows, the library used are not the
|
|
|
2f012fb |
- # same as what is in
|
|
|
2f012fb |
- # blas_info['libraries']?
|
|
|
2f012fb |
- ['-l%s' % l for l in ["mk2_core", "mk2_intel_thread",
|
|
|
2f012fb |
- "mk2_rt"]])
|
|
|
2f012fb |
- elif sys.platform == 'darwin':
|
|
|
2f012fb |
- # The env variable is needed to link with mkl
|
|
|
2f012fb |
- new_path = os.path.join(sys.prefix, "lib")
|
|
|
2f012fb |
- v = os.getenv("DYLD_FALLBACK_LIBRARY_PATH", None)
|
|
|
2f012fb |
- if v is not None:
|
|
|
2f012fb |
- # Explicit version could be replaced by a symbolic
|
|
|
2f012fb |
- # link called 'Current' created by EPD installer
|
|
|
2f012fb |
- # This will resolve symbolic links
|
|
|
2f012fb |
- v = os.path.realpath(v)
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- # The python __import__ don't seam to take into account
|
|
|
2f012fb |
- # the new env variable "DYLD_FALLBACK_LIBRARY_PATH"
|
|
|
2f012fb |
- # when we set with os.environ['...'] = X or os.putenv()
|
|
|
2f012fb |
- # So we warn the user and tell him what todo.
|
|
|
2f012fb |
- if v is None or new_path not in v.split(":"):
|
|
|
2f012fb |
- _logger.warning(
|
|
|
2f012fb |
- "The environment variable "
|
|
|
2f012fb |
- "'DYLD_FALLBACK_LIBRARY_PATH' does not contain "
|
|
|
2f012fb |
- "the '%s' path in its value. This will make "
|
|
|
2f012fb |
- "Theano use a slow version of BLAS. Update "
|
|
|
2f012fb |
- "'DYLD_FALLBACK_LIBRARY_PATH' to contain the "
|
|
|
2f012fb |
- "said value, this will disable this warning."
|
|
|
2f012fb |
- % new_path)
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- use_unix_epd = False
|
|
|
2f012fb |
- if use_unix_epd:
|
|
|
2f012fb |
- return ' '.join(
|
|
|
2f012fb |
- ['-L%s' % os.path.join(sys.prefix, "lib")] +
|
|
|
2f012fb |
- ['-l%s' % l for l in blas_info['libraries']])
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- # Canopy
|
|
|
2f012fb |
- if "Canopy" in sys.prefix:
|
|
|
2f012fb |
- subsub = 'lib'
|
|
|
2f012fb |
- if sys.platform == 'win32':
|
|
|
2f012fb |
- subsub = 'Scripts'
|
|
|
2f012fb |
- lib_path = os.path.join(sys.base_prefix, subsub)
|
|
|
2f012fb |
- if not os.path.exists(lib_path):
|
|
|
2f012fb |
- # Old logic to find the path. I don't think we still
|
|
|
2f012fb |
- # need it, but I don't have the time to test all
|
|
|
2f012fb |
- # installation configuration. So I keep this as a fall
|
|
|
2f012fb |
- # back in case the current expectation don't work.
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- # This old logic don't work when multiple version of
|
|
|
2f012fb |
- # Canopy is installed.
|
|
|
2f012fb |
- p = os.path.join(sys.base_prefix, "..", "..", "appdata")
|
|
|
2f012fb |
- assert os.path.exists(p), "Canopy changed the location of MKL"
|
|
|
2f012fb |
- lib_paths = os.listdir(p)
|
|
|
2f012fb |
- # Try to remove subdir that can't contain MKL
|
|
|
2f012fb |
- for sub in lib_paths:
|
|
|
2f012fb |
- if not os.path.exists(os.path.join(p, sub, subsub)):
|
|
|
2f012fb |
- lib_paths.remove(sub)
|
|
|
2f012fb |
- assert len(lib_paths) == 1, (
|
|
|
2f012fb |
- "Unexpected case when looking for Canopy MKL libraries",
|
|
|
2f012fb |
- p, lib_paths, [os.listdir(os.path.join(p, sub))
|
|
|
2f012fb |
- for sub in lib_paths])
|
|
|
2f012fb |
- lib_path = os.path.join(p, lib_paths[0], subsub)
|
|
|
2f012fb |
- assert os.path.exists(lib_path), "Canopy changed the location of MKL"
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- if sys.platform == "linux2" or sys.platform == "darwin":
|
|
|
2f012fb |
- return ' '.join(
|
|
|
2f012fb |
- ['-L%s' % lib_path] +
|
|
|
2f012fb |
- ['-l%s' % l for l in blas_info['libraries']])
|
|
|
2f012fb |
- elif sys.platform == 'win32':
|
|
|
2f012fb |
- return ' '.join(
|
|
|
2f012fb |
- ['-L"%s"' % lib_path] +
|
|
|
2f012fb |
- # Why on Windows, the library used are not the
|
|
|
2f012fb |
- # same as what is in blas_info['libraries']?
|
|
|
2f012fb |
- ['-l%s' % l for l in ["mk2_core", "mk2_intel_thread",
|
|
|
2f012fb |
- "mk2_rt"]])
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- # MKL
|
|
|
2f012fb |
- # If mkl can be imported then use it. On conda:
|
|
|
2f012fb |
- # "conda install mkl-service" installs the Python wrapper and
|
|
|
2f012fb |
- # the low-level C libraries as well as optimised version of
|
|
|
2f012fb |
- # numpy and scipy.
|
|
|
2f012fb |
- try:
|
|
|
2f012fb |
- import mkl # noqa
|
|
|
2f012fb |
- except ImportError as e:
|
|
|
2f012fb |
- if any([m for m in ('conda', 'Continuum') if m in sys.version]):
|
|
|
2f012fb |
- warn_record.append(('install mkl with `conda install mkl-service`: %s', e))
|
|
|
2f012fb |
- else:
|
|
|
2f012fb |
- # This branch is executed if no exception was raised
|
|
|
2f012fb |
- if sys.platform == "win32":
|
|
|
2f012fb |
- lib_path = os.path.join(sys.prefix, 'Library', 'bin')
|
|
|
2f012fb |
- flags = ['-L"%s"' % lib_path]
|
|
|
2f012fb |
- else:
|
|
|
2f012fb |
- lib_path = blas_info.get('library_dirs', [])
|
|
|
2f012fb |
- flags = []
|
|
|
2f012fb |
- if lib_path:
|
|
|
2f012fb |
- flags = ['-L%s' % lib_path[0]]
|
|
|
2f012fb |
- if '2018' in mkl.get_version_string():
|
|
|
2f012fb |
- thr = 'mkl_gnu_thread'
|
|
|
2f012fb |
- else:
|
|
|
2f012fb |
- thr = 'mkl_intel_thread'
|
|
|
5ef9abd |
- base_flags = list(flags)
|
|
|
2f012fb |
- flags += ['-l%s' % l for l in ["mkl_core",
|
|
|
2f012fb |
- thr,
|
|
|
2f012fb |
- "mkl_rt"]]
|
|
|
2f012fb |
- res = try_blas_flag(flags)
|
|
|
5ef9abd |
-
|
|
|
5ef9abd |
- if not res and sys.platform == "win32" and thr == "mkl_gnu_thread":
|
|
|
5ef9abd |
- # Check if it would work for intel OpenMP on windows
|
|
|
5ef9abd |
- flags = base_flags + ['-l%s' % l for l in ["mkl_core",
|
|
|
5ef9abd |
- 'mkl_intel_thread',
|
|
|
5ef9abd |
- "mkl_rt"]]
|
|
|
5ef9abd |
- res = try_blas_flag(flags)
|
|
|
5ef9abd |
-
|
|
|
2f012fb |
- if res:
|
|
|
2f012fb |
- check_mkl_openmp()
|
|
|
2f012fb |
- return res
|
|
|
5ef9abd |
-
|
|
|
2f012fb |
- flags.extend(['-Wl,-rpath,' + l for l in
|
|
|
2f012fb |
- blas_info.get('library_dirs', [])])
|
|
|
2f012fb |
- res = try_blas_flag(flags)
|
|
|
2f012fb |
- if res:
|
|
|
2f012fb |
- check_mkl_openmp()
|
|
|
2f012fb |
- maybe_add_to_os_environ_pathlist('PATH', lib_path[0])
|
|
|
2f012fb |
- return res
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- # to support path that includes spaces, we need to wrap it with double quotes on Windows
|
|
|
2f012fb |
- path_wrapper = "\"" if os.name == 'nt' else ""
|
|
|
2f012fb |
- ret = (
|
|
|
2f012fb |
- # TODO: the Gemm op below should separate the
|
|
|
2f012fb |
- # -L and -l arguments into the two callbacks
|
|
|
2f012fb |
- # that CLinker uses for that stuff. for now,
|
|
|
2f012fb |
- # we just pass the whole ldflags as the -l
|
|
|
2f012fb |
- # options part.
|
|
|
2f012fb |
- ['-L%s%s%s' % (path_wrapper, l, path_wrapper) for l in blas_info.get('library_dirs', [])] +
|
|
|
2f012fb |
- ['-l%s' % l for l in blas_info.get('libraries', [])] +
|
|
|
2f012fb |
- blas_info.get('extra_link_args', []))
|
|
|
2f012fb |
- # For some very strange reason, we need to specify -lm twice
|
|
|
2f012fb |
- # to get mkl to link correctly. I have no idea why.
|
|
|
2f012fb |
- if any('mkl' in fl for fl in ret):
|
|
|
2f012fb |
- ret.extend(['-lm', '-lm'])
|
|
|
2f012fb |
- res = try_blas_flag(ret)
|
|
|
2f012fb |
- if res:
|
|
|
2f012fb |
- if 'mkl' in res:
|
|
|
2f012fb |
- check_mkl_openmp()
|
|
|
2f012fb |
- return res
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- # If we are using conda and can't reuse numpy blas, then doing
|
|
|
2f012fb |
- # the fallback and test -lblas could give slow computation, so
|
|
|
2f012fb |
- # warn about this.
|
|
|
2f012fb |
- for warn in warn_record:
|
|
|
2f012fb |
- _logger.warning(*warn)
|
|
|
2f012fb |
- del warn_record
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- # Some environment don't have the lib dir in LD_LIBRARY_PATH.
|
|
|
2f012fb |
- # So add it.
|
|
|
2f012fb |
- ret.extend(['-Wl,-rpath,' + l for l in
|
|
|
2f012fb |
- blas_info.get('library_dirs', [])])
|
|
|
2f012fb |
- res = try_blas_flag(ret)
|
|
|
2f012fb |
- if res:
|
|
|
2f012fb |
- if 'mkl' in res:
|
|
|
2f012fb |
- check_mkl_openmp()
|
|
|
2f012fb |
- return res
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- # Add sys.prefix/lib to the runtime search path. On
|
|
|
2f012fb |
- # non-system installations of Python that use the
|
|
|
2f012fb |
- # system linker, this is generally necessary.
|
|
|
2f012fb |
- if sys.platform in ("linux", "darwin"):
|
|
|
2f012fb |
- lib_path = os.path.join(sys.prefix, 'lib')
|
|
|
2f012fb |
- ret.append('-Wl,-rpath,' + lib_path)
|
|
|
2f012fb |
- res = try_blas_flag(ret)
|
|
|
2f012fb |
- if res:
|
|
|
2f012fb |
- if 'mkl' in res:
|
|
|
2f012fb |
- check_mkl_openmp()
|
|
|
2f012fb |
- return res
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- except KeyError:
|
|
|
2f012fb |
- pass
|
|
|
2f012fb |
-
|
|
|
2f012fb |
- # Even if we could not detect what was used for numpy, or if these
|
|
|
2f012fb |
- # libraries are not found, most Linux systems have a libblas.so
|
|
|
2f012fb |
- # readily available. We try to see if that's the case, rather
|
|
|
2f012fb |
- # than disable blas. To test it correctly, we must load a program.
|
|
|
2f012fb |
- # Otherwise, there could be problem in the LD_LIBRARY_PATH.
|
|
|
2f012fb |
- return try_blas_flag(['-lblas'])
|
|
|
062ec9e |
+ flags = ['-lopenblaso']
|
|
|
2f012fb |
+ return try_blas_flag(flags)
|
|
|
2f012fb |
|
|
|
2f012fb |
|
|
|
2f012fb |
def try_blas_flag(flags):
|