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