From 2f012fb59f29c0090c7a1fcb770f927de37bbe9e Mon Sep 17 00:00:00 2001 From: Jerry James Date: Dec 22 2017 21:34:33 +0000 Subject: New upstream release. Also: - Add -blas patch to fix compilation errors when using the blas interface. - Reenable the tests. - Pass nose flags to prevent memory exhaustion while running the tests. --- diff --git a/.gitignore b/.gitignore index 4175658..2a184b0 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /Theano-0.8.2.tar.gz /Theano-0.9.0.tar.gz /Theano-1.0.0.tar.gz +/Theano-1.0.1.tar.gz diff --git a/python-theano-blas.patch b/python-theano-blas.patch new file mode 100644 index 0000000..912ca8b --- /dev/null +++ b/python-theano-blas.patch @@ -0,0 +1,234 @@ +--- theano/configdefaults.py.orig 2017-12-07 05:52:45.000000000 -0700 ++++ theano/configdefaults.py 2017-12-22 09:01:13.520111578 -0700 +@@ -1263,211 +1263,13 @@ 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' +- flags += ['-l%s' % l for l in ["mkl_core", +- thr, +- "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 = [] ++ if os.path.isdir('/usr/lib64/atlas'): ++ flags += ['-L/usr/lib64/atlas'] ++ else: ++ flags += ['-L/usr/lib/atlas'] ++ flags += ['-lsatlas'] ++ return try_blas_flag(flags) + + + def try_blas_flag(flags): +--- theano/tensor/blas.py.orig 2017-12-07 05:52:45.000000000 -0700 ++++ theano/tensor/blas.py 2017-12-22 09:00:43.768246368 -0700 +@@ -2054,8 +2054,8 @@ class BatchedDot(Op): + + def c_support_code(self): + batch_gemm_defn = """ +- template +- bool batch_gemm(function gemm, int type_size, ++ template ++ bool batch_gemm(void (*gemm)(char*, char*, const int*, const int*, const int*, const dtype*, const dtype*, const int*, const dtype*, const int*, const dtype*, dtype*, const int*), int type_size, + PyArrayObject* xs, PyArrayObject* ys, PyArrayObject* zs) { + npy_intp *Nx = PyArray_DIMS(xs), *Sx = PyArray_STRIDES(xs); + npy_intp *Ny = PyArray_DIMS(ys), *Sy = PyArray_STRIDES(ys); diff --git a/python-theano.spec b/python-theano.spec index 51985ae..1018b33 100644 --- a/python-theano.spec +++ b/python-theano.spec @@ -3,13 +3,15 @@ #%%global rctag a1 Name: python-theano -Version: 1.0.0 +Version: 1.0.1 Release: 1%{?rctag:.%{rctag}}%{?dist} Summary: Mathematical expressions involving multidimensional arrays License: BSD URL: http://deeplearning.net/software/theano/ Source0: https://github.com/Theano/Theano/archive/rel-%{version}%{?rctag:%{rctag}}/%{pkgname}-%{version}%{?rctag:%{rctag}}.tar.gz +# Fix the blas interface; see https://github.com/Theano/Theano/issues/6518 +Patch0: %{name}-blas.patch BuildArch: noarch @@ -113,7 +115,7 @@ Summary: Theano documentation User documentation for Theano. %prep -%autosetup -n %{pkgname}-rel-%{version}%{?rctag:%{rctag}} -p1 +%autosetup -n %{pkgname}-rel-%{version}%{?rctag:%{rctag}} -p0 # Remove bundled python-six rm -f theano/compat/six.py @@ -183,8 +185,7 @@ popd chmod a+x $(find %{buildroot} -name \*.py -o -name \*.sh | xargs grep -l '^#!') %check -# https://github.com/Theano/Theano/issues/6518 -#PYTHONPATH=$PWD bin/theano-nose +PYTHONPATH=$PWD bin/theano-nose --processes=0 --process-restartworker %files -n python2-%{srcname} %doc DESCRIPTION.txt HISTORY.txt NEWS.txt README.rst @@ -201,6 +202,12 @@ chmod a+x $(find %{buildroot} -name \*.py -o -name \*.sh | xargs grep -l '^#!') %doc html %changelog +* Fri Dec 22 2017 Jerry James - 1.0.1-1 +- New upstream release +- Add -blas patch to fix compilation errors when using the blas interface +- Reenable the tests +- Pass nose flags to prevent memory exhaustion while running the tests + * Fri Nov 17 2017 Igor Gnatenko - 1.0.0-1 - Update to 1.0.0 diff --git a/sources b/sources index 6900f25..83ba660 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (Theano-1.0.0.tar.gz) = e202de64405d5ba8b279bbb5ae502226c70995508596708a62ca5633bbe0d7727427719c8f9a1505bed8e5f34d4e09f77a06a7e263dbe0e55767f66000e0e07f +SHA512 (Theano-1.0.1.tar.gz) = 94d56a99e30639f969560f9e7242cf9ef4f11af57b99f56406a5404d4d91f9ef8085489ead689472e0444804ce72a66494ed37b9d6fa84706d360a7d1151753d