diff --git a/.gitignore b/.gitignore deleted file mode 100644 index eceb295..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/Theano-*.tar.gz -/rel-*.tar.gz diff --git a/dead.package b/dead.package new file mode 100644 index 0000000..5204a84 --- /dev/null +++ b/dead.package @@ -0,0 +1 @@ +Orphaned for 6+ weeks diff --git a/python-theano-blas.patch b/python-theano-blas.patch deleted file mode 100644 index 7f55f04..0000000 --- a/python-theano-blas.patch +++ /dev/null @@ -1,231 +0,0 @@ ---- theano/link/c/cmodule.py.orig 2021-01-23 00:22:56.000000000 +0100 -+++ theano/link/c/cmodule.py 2021-06-10 18:32:24.905262642 +0200 -@@ -2611,227 +2611,7 @@ - str - - """ -- import numpy.distutils # noqa -- -- warn_record = [] -- try: -- if hasattr(numpy.distutils, "__config__") and numpy.distutils.__config__: -- # If the old private interface is available use it as it -- # don't print information to the user. -- blas_info = numpy.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 -- # isort: off -- 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']? -- [f"-l{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 '{new_path}' 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." -- ) -- -- 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']? -- [f"-l{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(f"install mkl with `conda install mkl-service`: {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 = [f'-L"{lib_path}"'] -- else: -- lib_path = blas_info.get("library_dirs", []) -- flags = [] -- if lib_path: -- flags = [f"-L{lib_path[0]}"] -- if "2018" in mkl.get_version_string(): -- thr = "mkl_gnu_thread" -- else: -- thr = "mkl_intel_thread" -- base_flags = list(flags) -- flags += [f"-l{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 + [ -- f"-l{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() -- theano.utils.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. -- [ -- f"-L{path_wrapper}{l}{path_wrapper}" -- for l in blas_info.get("library_dirs", []) -- ] -- + [f"-l{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"]) -+ return try_blas_flag(["-lflexiblas"]) - - - def add_blas_configvars(): diff --git a/python-theano-doc.patch b/python-theano-doc.patch deleted file mode 100644 index fa712c7..0000000 --- a/python-theano-doc.patch +++ /dev/null @@ -1,155 +0,0 @@ ---- doc/conf.py.orig 2020-11-23 15:59:25.572772033 -0700 -+++ doc/conf.py 2020-11-23 15:59:35.724796795 -0700 -@@ -136,7 +136,7 @@ if os.environ.get('READTHEDOCS') != 'Tru - html_theme = 'sphinx_rtd_theme' - - def setup(app): -- app.add_stylesheet("fix_rtd.css") -+ app.add_css_file("fix_rtd.css") - - # The name for this set of Sphinx documents. If None, it defaults to - # " v documentation". ---- doc/extending/extending_theano_gpu.txt.orig 2020-11-14 20:22:36.000000000 -0700 -+++ doc/extending/extending_theano_gpu.txt 2020-11-23 16:48:56.092972525 -0700 -@@ -264,14 +264,14 @@ CGpuKernelBase - Python File - ~~~~~~~~~~~ - --.. literalinclude:: ../../theano/gpuarray/tests/test_cgpukernelbase.py -+.. literalinclude:: ../../tests/gpuarray/test_cgpukernelbase.py - :language: python - :pyobject: GpuEye - - ``tstgpueye.c`` - ~~~~~~~~~~~~~~~ - --.. literalinclude:: ../../theano/gpuarray/tests/c_code/tstgpueye.c -+.. literalinclude:: ../../tests/gpuarray/c_code/tstgpueye.c - :language: C - - Wrapping Exisiting Libraries ---- doc/library/scan.txt.orig 2020-11-14 20:22:36.000000000 -0700 -+++ doc/library/scan.txt 2020-11-23 16:23:49.166254031 -0700 -@@ -682,4 +682,4 @@ reference - .. autofunction:: theano.foldl - .. autofunction:: theano.foldr - .. autofunction:: theano.scan --.. autofunction:: theano.scan_checkpoints -+.. autofunction:: theano.scan.checkpoints.scan_checkpoints ---- doc/library/sparse/sandbox.txt.orig 2020-11-14 20:22:36.000000000 -0700 -+++ doc/library/sparse/sandbox.txt 2020-11-23 16:25:00.134423267 -0700 -@@ -19,5 +19,3 @@ API - :members: - .. automodule:: theano.sparse.sandbox.sp2 - :members: --.. automodule:: theano.sparse.sandbox.truedot -- :members: ---- doc/library/tests.txt.orig 2020-11-14 20:22:36.000000000 -0700 -+++ doc/library/tests.txt 2020-11-23 16:33:08.245587256 -0700 -@@ -4,5 +4,5 @@ - :mod:`tests` -- Tests - ===================== - --.. automodule:: tests.breakpoint -+.. automodule:: theano.breakpoint - :members: ---- theano/gof/op.py.orig 2020-11-14 20:22:36.000000000 -0700 -+++ theano/gof/op.py 2020-11-23 15:59:35.726796800 -0700 -@@ -341,13 +341,13 @@ class CLinkerOp(CLinkerObject): - string is the name of a C variable pointing to that input. - The type of the variable depends on the declared type of - the input. There is a corresponding python variable that -- can be accessed by prepending "py_" to the name in the -+ can be accessed by prepending ```"py_"``` to the name in the - list. - outputs : list of strings - Each string is the name of a C variable where the Op should - store its output. The type depends on the declared type of - the output. There is a corresponding python variable that -- can be accessed by prepending "py_" to the name in the -+ can be accessed by prepending ```"py_"``` to the name in the - list. In some cases the outputs will be preallocated and - the value of the variable may be pre-filled. The value for - an unallocated output is type-dependent. -@@ -404,13 +404,13 @@ class CLinkerOp(CLinkerObject): - string is the name of a C variable pointing to that input. - The type of the variable depends on the declared type of - the input. There is a corresponding python variable that -- can be accessed by prepending "py_" to the name in the -+ can be accessed by prepending ```"py_"``` to the name in the - list. - outputs : list of strings - Each string is the name of a C variable correspoinding to - one of the outputs of the Op. The type depends on the - declared type of the output. There is a corresponding -- python variable that can be accessed by prepending "py_" to -+ python variable that can be accessed by prepending ```"py_"``` to - the name in the list. - sub : dict of strings - extra symbols defined in `CLinker` sub symbols (such as 'fail'). ---- theano/gof/opt.py.orig 2020-11-14 20:22:36.000000000 -0700 -+++ theano/gof/opt.py 2020-11-23 15:59:35.728796804 -0700 -@@ -102,9 +102,9 @@ class Optimizer: - - Add features to the fgraph that are required to apply the optimization. - For example: -- fgraph.attach_feature(History()) -- fgraph.attach_feature(MyFeature()) -- etc. -+ fgraph.attach_feature(History()) -+ fgraph.attach_feature(MyFeature()) -+ etc. - - """ - ---- theano/scan/__init__.py.orig 2020-11-14 20:22:36.000000000 -0700 -+++ theano/scan/__init__.py 2020-11-23 16:21:47.909964873 -0700 -@@ -25,9 +25,9 @@ of using ``scan`` over `for` loops in py - * it allows the number of iterations to be part of the symbolic graph - * it allows computing gradients through the for loop - * there exist a bunch of optimizations that help re-write your loop --such that less memory is used and that it runs faster -+ such that less memory is used and that it runs faster - * it ensures that data is not copied from host to gpu and gpu to --host at each step -+ host at each step - - The Scan Op should typically be used by calling any of the following - functions: ``scan()``, ``map()``, ``reduce()``, ``foldl()``, ---- theano/sparse/basic.py.orig 2020-11-14 20:22:36.000000000 -0700 -+++ theano/sparse/basic.py 2020-11-23 15:59:35.729796807 -0700 -@@ -4342,9 +4342,9 @@ class ConstructSparseFromList(gof.Op): - This create a sparse matrix with the same shape as `x`. Its - values are the rows of `values` moved. Pseudo-code:: - -- output = csc_matrix.zeros_like(x, dtype=values.dtype) -- for in_idx, out_idx in enumerate(ilist): -- output[out_idx] = values[in_idx] -+ output = csc_matrix.zeros_like(x, dtype=values.dtype) -+ for in_idx, out_idx in enumerate(ilist): -+ output[out_idx] = values[in_idx] - - """ - x_ = theano.tensor.as_tensor_variable(x) ---- theano/tensor/extra_ops.py.orig 2020-11-14 20:22:36.000000000 -0700 -+++ theano/tensor/extra_ops.py 2020-11-23 17:01:03.085630196 -0700 -@@ -1464,7 +1464,7 @@ def broadcast_shape(*arrays, **kwargs): - - Parameters - ---------- -- *arrays: `TensorVariable`s -+ *arrays: `TensorVariable` instances - The tensor variables, or their shapes (as tuples), - for which the broadcast shape is computed. - arrays_are_shapes: bool (Optional) ---- versioneer.py.orig 2020-11-14 20:22:36.000000000 -0700 -+++ versioneer.py 2020-11-23 15:59:35.730796809 -0700 -@@ -418,7 +418,7 @@ def run_command(commands, args, cwd=None - return stdout, p.returncode - - --LONG_VERSION_PY['git'] = ''' -+LONG_VERSION_PY['git'] = r''' - # This file helps to compute a version number in source trees obtained from - # git-archive tarball (such as those provided by githubs download-from-tag - # feature). Distribution tarballs (built by setup.py sdist) and build diff --git a/python-theano-git.patch b/python-theano-git.patch deleted file mode 100644 index 629f0d5..0000000 --- a/python-theano-git.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- doc/conf.py.orig 2020-12-24 06:22:22.569868065 -0700 -+++ doc/conf.py 2020-12-24 06:24:01.869469104 -0700 -@@ -221,11 +221,8 @@ def linkcode_resolve(domain, info): - filename = 'theano/%s#L%d-L%d' % find_source() - except Exception: - filename = info['module'].replace('.', '/') + '.py' -- import subprocess -- tag = subprocess.Popen(['git', 'rev-parse', 'HEAD'], -- stdout=subprocess.PIPE, -- universal_newlines=True).communicate()[0][:-1] -- return f"https://github.com/Theano/theano/blob/{tag}/{filename}" -+ tag = '@@tag@@' -+ return f"https://github.com/pymc-devs/Theano-PyMC/blob/{tag}/{filename}" - - # Options for LaTeX output - # ------------------------ diff --git a/python-theano-linecache.patch b/python-theano-linecache.patch deleted file mode 100644 index 90c3285..0000000 --- a/python-theano-linecache.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- theano/graph/utils.py.orig 2020-12-14 05:42:43.000000000 -0700 -+++ theano/graph/utils.py 2021-06-08 12:45:23.976560620 -0600 -@@ -42,7 +42,7 @@ def simple_extract_stack(f=None, limit=N - filename = co.co_filename - name = co.co_name - # linecache.checkcache(filename) -- line = linecache.getline(filename, lineno, f.f_globals) -+ line = linecache.getline(filename, lineno, f.f_globals) if lineno else None - if line: - line = line.strip() - else: diff --git a/python-theano-ppc64le.patch b/python-theano-ppc64le.patch deleted file mode 100644 index 3ef96ad..0000000 --- a/python-theano-ppc64le.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- tests/tensor/nnet/test_corr3d.py.orig 2020-12-14 05:42:43.000000000 -0700 -+++ tests/tensor/nnet/test_corr3d.py 2020-12-24 06:26:37.480889859 -0700 -@@ -35,7 +35,7 @@ class TestCorr3D(utt.InferShapeTester): - subsample=(1, 1, 1), - input=None, - filters=None, -- verify_grad=True, -+ verify_grad=False, - non_contiguous=False, - filter_dilation=(1, 1, 1), - ): ---- tests/tensor/test_nlinalg.py.orig 2020-12-14 05:42:43.000000000 -0700 -+++ tests/tensor/test_nlinalg.py 2020-12-24 06:26:37.481889855 -0700 -@@ -6,6 +6,7 @@ from numpy.testing import assert_array_a - - import theano - from tests import unittest_tools as utt -+from unittest import expectedFailure - from theano import config, function, tensor - from theano.tensor.basic import _allclose - from theano.tensor.nlinalg import ( -@@ -614,6 +615,7 @@ class TestTensorInv(utt.InferShapeTester - TensorInv, - ) - -+ @expectedFailure - def test_eval(self): - A = self.A - Ai = tensorinv(A) diff --git a/python-theano-printing.patch b/python-theano-printing.patch deleted file mode 100644 index 77c63aa..0000000 --- a/python-theano-printing.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- theano/printing.py.orig 2020-11-14 20:22:36.000000000 -0700 -+++ theano/printing.py 2020-11-23 16:00:21.019907292 -0700 -@@ -1358,7 +1358,7 @@ def hex_digest(x): - Returns a short, mostly hexadecimal hash of a numpy ndarray - """ - assert isinstance(x, np.ndarray) -- rval = hashlib.sha256(x.tostring()).hexdigest() -+ rval = hashlib.sha256(x.tobytes()).hexdigest() - # hex digest must be annotated with strides to avoid collisions - # because the buffer interface only exposes the raw data, not - # any info about the semantics of how that data should be arranged diff --git a/python-theano-pydotnode.patch b/python-theano-pydotnode.patch deleted file mode 100644 index 4f4eecc..0000000 --- a/python-theano-pydotnode.patch +++ /dev/null @@ -1,90 +0,0 @@ ---- theano/printing.py.orig 2021-01-23 00:22:56.000000000 +0100 -+++ theano/printing.py 2021-06-10 16:25:36.979803980 +0200 -@@ -20,7 +20,6 @@ - from theano.graph.basic import ( - Apply, - Constant, -- Node, - Variable, - graph_inputs, - io_toposort, -@@ -980,13 +979,13 @@ - use_color = color - - if use_color is None: -- nw_node = Node(aid, label=astr, shape=apply_shape) -+ nw_node = pd.Node(aid, label=astr, shape=apply_shape) - elif high_contrast: -- nw_node = Node( -+ nw_node = pd.Node( - aid, label=astr, style="filled", fillcolor=use_color, shape=apply_shape - ) - else: -- nw_node = Node(aid, label=astr, color=use_color, shape=apply_shape) -+ nw_node = pd.Node(aid, label=astr, color=use_color, shape=apply_shape) - g.add_node(nw_node) - if cond_highlight: - if node in middle: -@@ -1020,7 +1019,7 @@ - color = "cyan" - if high_contrast: - g.add_node( -- Node( -+ pd.Node( - varid, - style="filled", - fillcolor=color, -@@ -1029,7 +1028,7 @@ - ) - ) - else: -- g.add_node(Node(varid, color=color, label=varstr, shape=var_shape)) -+ g.add_node(pd.Node(varid, color=color, label=varstr, shape=var_shape)) - g.add_edge(pd.Edge(varid, aid, **param)) - elif var.name or not compact or var in outputs: - g.add_edge(pd.Edge(varid, aid, **param)) -@@ -1058,7 +1057,7 @@ - g.add_edge(pd.Edge(aid, varid, **param)) - if high_contrast: - g.add_node( -- Node( -+ pd.Node( - varid, - style="filled", - label=varstr, -@@ -1068,7 +1067,7 @@ - ) - else: - g.add_node( -- Node( -+ pd.Node( - varid, - color=colorCodes["Output"], - label=varstr, -@@ -1080,7 +1079,7 @@ - # grey mean that output var isn't used - if high_contrast: - g.add_node( -- Node( -+ pd.Node( - varid, - style="filled", - label=varstr, -@@ -1089,7 +1088,7 @@ - ) - ) - else: -- g.add_node(Node(varid, label=varstr, color="grey", shape=var_shape)) -+ g.add_node(pd.Node(varid, label=varstr, color="grey", shape=var_shape)) - elif var.name or not compact: - if not (not compact): - if label: -@@ -1099,7 +1098,7 @@ - label = label[: max_label_size - 3] + "..." - param["label"] = label - g.add_edge(pd.Edge(aid, varid, **param)) -- g.add_node(Node(varid, shape=var_shape, label=varstr)) -+ g.add_node(pd.Node(varid, shape=var_shape, label=varstr)) - # else: - # don't add egde here as it is already added from the inputs. - diff --git a/python-theano.rpmlintrc b/python-theano.rpmlintrc deleted file mode 100644 index be835c8..0000000 --- a/python-theano.rpmlintrc +++ /dev/null @@ -1,15 +0,0 @@ -# THIS FILE IS FOR WHITELISTING RPMLINT ERRORS AND WARNINGS IN TASKOTRON -# https://fedoraproject.org/wiki/Taskotron/Tasks/dist.rpmlint#Whitelisting_errors - -# The dictionary is missing some technical terms -addFilter(r'W: spelling-error .* (ndarray|numpy)') - -# This package really is a devel package -addFilter(r'^python3-theano\.noarch: E: devel-dependency') -addFilter(r'^python3-theano\.noarch: W: devel-file-in-non-devel-package') - -# The helper scripts have no man pages -addFilter(r'W: no-manual-page-for-binary theano-(cache|nose)') - -# Dangling font symlinks: the Requires ensures they will not dangle -addFilter(r'W: dangling-symlink .*fonts') diff --git a/python-theano.spec b/python-theano.spec deleted file mode 100644 index 7735276..0000000 --- a/python-theano.spec +++ /dev/null @@ -1,367 +0,0 @@ -%bcond_without check -%bcond_with doc - -%global pkgname theano -%global pypi_name Theano-PyMC - -Name: python-%{pkgname} -Version: 1.1.2 -Release: 9%{?dist} -Summary: Mathematical expressions involving multidimensional arrays - -License: BSD -URL: https://docs.pymc.io/PyMC3_and_Theano.html -Source0: %pypi_source Theano-PyMC -# This file was omitted from the release, but is available from aesara -Source1: scan_perform.pyx - -# Fix the blas interface; see https://github.com/Theano/Theano/issues/6518 -# If we fix the Fedora numpy package to specify flexiblas in its __config__.py -# file, we can discard this patch. -Patch0: %{name}-blas.patch -# Fix a call to a deprecated function in the printing code -Patch1: %{name}-printing.patch -# Workaround for linecache changes in python 3.10 -Patch2: %{name}-linecache.patch -# It's calling tt.Node instead of pydot.Node -Patch3: %{name}-pydotnode.patch - -BuildArch: noarch - -BuildRequires: gcc-c++ -BuildRequires: gcc-gfortran -BuildRequires: pkgconfig(flexiblas) - -BuildRequires: python3-devel -BuildRequires: python3-pygpu-devel -BuildRequires: %{py3_dist cython} -BuildRequires: %{py3_dist pip} -BuildRequires: %{py3_dist setuptools} -BuildRequires: %{py3_dist wheel} -%if %{with check} -BuildRequires: %{py3_dist pytest} -BuildRequires: %{py3_dist parameterized} -BuildRequires: %{py3_dist filelock} -BuildRequires: %{py3_dist numpy} -BuildRequires: %{py3_dist scipy} -BuildRequires: %{py3_dist pydot} -%endif - -%global _desc %{expand: -Theano is a Python library that allows you to define, optimize, and -evaluate mathematical expressions involving multi-dimensional arrays -efficiently. Theano features: -- tight integration with NumPy: Use numpy.ndarray in Theano-compiled - functions. -- transparent use of a GPU: Perform data-intensive calculations up to - 140x faster than with CPU (float32 only). -- efficient symbolic differentiation: Theano does your derivatives for - function with one or many inputs. -- speed and stability optimizations: Get the right answer for log(1+x) - even when x is really tiny. -- dynamic C code generation: Evaluate expressions faster. -- extensive unit-testing and self-verification: Detect and diagnose many - types of mistake.} - -%description %_desc - -%package -n python3-%{pkgname} -Summary: %{summary} -Requires: flexiblas-devel -Requires: gcc-c++ -Requires: gcc-gfortran -Recommends: python%{python3_version}dist(pygpu) -Suggests: python%{python3_version}dist(pydot) - -%description -n python3-%{pkgname} %_desc - -%package doc -Summary: Theano documentation -%if %{with doc} -Requires: font(fontawesome) -Requires: font(lato) -Requires: font(robotoslab) -%endif - -%description doc -User documentation for Theano. - -%prep -%autosetup -n %{pypi_name}-%{version} -p0 -cp -p %{SOURCE1} theano/scan - -# We don't need to use /usr/bin/env -for fil in $(grep -FRl /bin/env .); do - sed -ri.orig 's,( )?(/usr)?/bin/env[[:blank:]]*python.*,%{_bindir}/python3,' $fil - touch -r $fil.orig $fil - rm $fil.orig -done - -%build -# Regenerate from cython sources -cd theano/scan -cython -3 -o c_code/scan_perform.c scan_perform.pyx -cd - - -%pyproject_wheel - -# Build the documentation -# Latest tarball doesn't include the conf files required to build documentation -%if %{with doc} -export PYTHONPATH=$PWD -%{python3} doc/scripts/docgen.py --nopdf -#rst2html --no-datestamp README.rst README.html -# Remove build artifacts -rm -rf html/.buildinfo html/.doctrees -%endif - -%install -%pyproject_install - -# Restore executable permission on the scripts -chmod a+x $(find %{buildroot} -name \*.py -o -name \*.sh | xargs grep -l '^#!') - -# Do not ship the tests -rm -rf %{buildroot}%{python3_sitelib}/tests - -%if %{with check} -%check -%pytest - -%endif - -%files -n python3-%{pkgname} -%doc DESCRIPTION.txt HISTORY.txt NEWS.txt -%license doc/LICENSE.txt -%{_bindir}/theano-* -%{python3_sitelib}/Theano*.dist-info/ -%{python3_sitelib}/theano/ -%{python3_sitelib}/bin/ - -%files doc -%if %{with doc} -%doc html -%endif - -%changelog -* Sun Jul 23 2023 Python Maint - 1.1.2-9 -- Rebuilt for Python 3.12 - -* Fri Jul 21 2023 Fedora Release Engineering - 1.1.2-8 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild - -* Mon Jul 03 2023 Python Maint - 1.1.2-7 -- Rebuilt for Python 3.12 - -* Fri Jan 20 2023 Fedora Release Engineering - 1.1.2-6 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild - -* Sat Aug 6 2022 Jerry James - 1.1.2-5 -- Regenerate cython sources to fix FTBFS (rhbz#2113658) - -* Fri Jul 22 2022 Fedora Release Engineering - 1.1.2-5 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild - -* Tue Jun 14 2022 Python Maint - 1.1.2-4 -- Rebuilt for Python 3.11 - -* Fri Jan 21 2022 Fedora Release Engineering - 1.1.2-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild - -* Fri Jul 23 2021 Fedora Release Engineering - 1.1.2-2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild - -* Thu Jun 10 2021 Sergio Pascual - 1.1.2-1 -- New upstream source (1.1.2) -- Drop doc patches and other patches included upstream -- No cython files in tarball -- doc subpackage is empty - -* Tue Jun 8 2021 Jerry James - 1.0.13-4 -- Add -linecache patch to fix python 3.10 FTBFS (bz 1959774) - -* Fri Jun 04 2021 Python Maint - 1.0.13-4 -- Rebuilt for Python 3.10 - -* Wed Jan 27 2021 Fedora Release Engineering - 1.0.13-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - -* Mon Jan 11 2021 Jerry James - 1.0.13-2 -- Add -numpy-version patch to fix FTBFS (bz 1914890) - -* Thu Dec 24 2020 Jerry James - 1.0.13-1 -- Version 1.0.13 - -* Mon Nov 23 2020 Jerry James - 1.0.11-1 -- Version 1.0.11 -- Switch to the PyMC fork, now the official version -- Drop the -future-warning patch; it yields incorrect answers -- Test with pytest instead of nose - -* Fri Aug 7 2020 Jerry James - 1.0.5-1 -- Version 1.0.5 -- Drop upstreamed patches: -ceil-floor-trunc, -clip, -format, -gammaq, - -has-sorted-indices, -is, -iterable, -ordered-dict, -random, -sort, -sphinx3, - -traceback -- Add patches: -file-leak, -printing -- Build with flexiblas instead of with openblas directly - -* Wed Jul 29 2020 Fedora Release Engineering - 1.0.4-6.2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - -* Tue May 26 2020 Miro Hrončok - 1.0.4-6.1 -- Rebuilt for Python 3.9 - -* Tue Feb 4 2020 Jerry James - 1.0.4-6 -- Add -ordered-dict patch, thanks to Miro Hrončok (bz 1797982) - -* Thu Jan 30 2020 Fedora Release Engineering - 1.0.4-5.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild - -* Mon Nov 25 2019 Jerry James - 1.0.4-5 -- Drop epydoc BR since it has been retired -- Unbundle fonts from the documentation -- Ship an HTML form of the README -- Add -has-sorted-indices patch - -* Thu Oct 03 2019 Miro Hrončok - 1.0.4-4.1 -- Rebuilt for Python 3.8.0rc1 (#1748018) - -* Thu Aug 29 2019 Jerry James - 1.0.4-4 -- Add -iterable, -git, -format, -is, and -doc patches to fix warnings - -* Fri Aug 23 2019 Robert-André Mauchin - 1.0.4-3 -- Fix FTBFS with python-theano-sort patch (#1737011) - -* Mon Aug 19 2019 Miro Hrončok - 1.0.4-2.1 -- Rebuilt for Python 3.8 - -* Fri Aug 16 2019 Jerry James - 1.0.4-2 -- Add -future-warning, -gammaq, -ceil-floor-trunc, -traceback, -clip, and - -random patches to fix FTBFS (bz 1737011) - -* Fri Jul 26 2019 Fedora Release Engineering - 1.0.4-1.2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild - -* Sat Feb 02 2019 Fedora Release Engineering - 1.0.4-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild - -* Sat Jan 19 2019 Jerry James - 1.0.4-1 -- New upstream release - -* Thu Dec 27 2018 Igor Gnatenko - 1.0.3-2 -- Drop duplicated dependencies - -* Sat Oct 6 2018 Jerry James - 1.0.3-1 -- New upstream release -- Partially revert the previous commit; the gcc Requires is needed -- Build with openblas instead of atlas -- Send cython output to the correct directory -- Build with pygpu support - -* Sun Aug 12 2018 Igor Gnatenko - 1.0.2-2 -- Drop python2 subpackage - -* Sat Jul 14 2018 Fedora Release Engineering - 1.0.2-1.2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild - -* Tue Jun 19 2018 Miro Hrončok - 1.0.2-1.1 -- Rebuilt for Python 3.7 - -* Wed May 23 2018 Jerry James - 1.0.2-1 -- New upstream release - -* Fri Feb 09 2018 Fedora Release Engineering - 1.0.1-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - -* 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 - -* Thu Jul 27 2017 Fedora Release Engineering - 0.9.0-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild - -* Wed Mar 22 2017 Jerry James - 0.9.0-1 -- New upstream release - -* Sat Feb 11 2017 Fedora Release Engineering - 0.8.2-1.3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild - -* Mon Dec 19 2016 Miro Hrončok - 0.8.2-1.2 -- Rebuild for Python 3.6 - -* Tue Jul 19 2016 Fedora Release Engineering - 0.8.2-1.1 -- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages - -* Thu Apr 21 2016 Jerry James - 0.8.2-1 -- New upstream release - -* Fri Apr 15 2016 Jerry James - 0.8.1-2 -- Remove python2 dependency from the python3 subpackage (bz 1324232) -- Recommend pydot instead of requiring it - -* Sat Apr 2 2016 Jerry James - 0.8.1-1 -- New upstream release -- Fix the pydot dependencies - -* Wed Mar 23 2016 Jerry James - 0.8.0-1 -- New upstream release - -* Thu Feb 04 2016 Fedora Release Engineering - 0.7.1-0.2.a1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild - -* Mon Feb 1 2016 Jerry James - 0.7.1-0.1.a1 -- Comply with latest python packaging guidelines - -* Thu Nov 12 2015 Igor Gnatenko - 0.7.1-0.1.a1 -- Update to 0.7.1a1 - -* Tue Nov 10 2015 Fedora Release Engineering - 0.7.0-2.2 -- Rebuilt for https://fedoraproject.org/wiki/Changes/python3.5 - -* Wed Nov 4 2015 Toshio Kuratomi - 0.7.0-2.1 -- Fix python3 package requiring python2. - -* Thu Jun 18 2015 Fedora Release Engineering - 0.7.0-1.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild - -* Wed Apr 1 2015 Jerry James - 0.7.0-1 -- New upstream release -- Drop upstreamed -arm patch -- Regenerate cython files to fix build failure - -* Sat Feb 21 2015 Jerry James - 0.6.0-5 -- Add -arm patch to fix build failure on arm builders due to inverted test - -* Sat Feb 21 2015 Jerry James - 0.6.0-4 -- Drop workaround for fixed bug (bz 1075826) -- Use license macro - -* Sat Jun 07 2014 Fedora Release Engineering - 0.6.0-3.1 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild - -* Wed May 14 2014 Jerry James - 0.6.0-3 -- Rebuild for https://fedoraproject.org/wiki/Changes/Python_3.4 - -* Thu Mar 13 2014 Jerry James - 0.6.0-2 -- Add python3 subpackage -- Add another icon to the -missing tarball -- Update source icons -- Unbundle python-six -- Add workaround for bz 1075826 - -* Sat Dec 7 2013 Jerry James - 0.6.0-1 -- New upstream release -- Drop upstreamed -import patch - -* Mon Oct 21 2013 Jerry James - 0.6.0-0.1.rc3 -- Add the -import patch to fix an exception -- Add more files to the base package docs - -* Tue Aug 27 2013 Jerry James - 0.6.0-0.rc3 -- Initial RPM diff --git a/scan_perform.pyx b/scan_perform.pyx deleted file mode 100644 index 44177e0..0000000 --- a/scan_perform.pyx +++ /dev/null @@ -1,653 +0,0 @@ -# cython: language_level=3 -""" - This code implements the operations that scan has to carry on when called - as a stand alone function. - - IF anything this is the entire code that needs to be transported to C. - - Short description of how this code works: - Scan divides its inputs ( Op's inputs) into different classes of inputs - as follows: - i) sequences : inputs over which scan loops to get data. Nothing is - written into them ( they are readonly, loop over) - - ii) mit_mot : multiple input taps multiple output taps arguments. - These are inputs over which scan loops and gets data but into which - scan also writes data. The shorthand mit_mot describes how scan - deal with them at each step : at each step take several slices as - input and produce sevaral slices as outputs - - iii) mit_sot : multiple input taps single output tap arguments. - As before scan reads from these but also writes. At each step scan - uses several slices as input but produces only one as output - - iv) sit_sot : single input tap single output tap arguments. - At each step use only the previous slice as input, produce only one - slice as output - - v) nit_sot: no input tap single output tap arguments. - At each step don't use any previous values, only produce new onese - - vi) shared_outs: arguments corresponding to shared variables with - updates. - At each step use its value as input, and afterwards replace it with - a new value. - vii) other_args: arguments that are passed to every call of the - inner function as they are ( no slicing is perfomed) - - All these outputs are one after the other in the inputs list (named in - this code as args) in a given order ( namely the one described above - with little discrepencies depending if we are talking about the outputs - of the Scan op or the inputs of the Scan op Node, and if we are talking - about the inputs of the inner function of scan or of the scan op). - - Because of this, all we need to be able to separate and tell arguments - apart is how many of which we have as well as how many taps and which - ones (where applicable). All this information is desribed (more or less) - by describing the arguments of this function) -""" - - -__authors__ = "Razvan Pascanu" "PyMC Developers" -__copyright__ = "(c) 2011, Universite de Montreal" - - -import cython -import numpy - -cimport numpy - -import copy -import time - -from aesara.link.utils import raise_with_op - - -def get_version(): - return 0.298 - -@cython.boundscheck(False) -def perform( - unsigned int n_shared_outs, - unsigned int n_mit_mot_outs, - unsigned int n_seqs, - unsigned int n_mit_mot, - unsigned int n_mit_sot, - unsigned int n_sit_sot, - unsigned int n_nit_sot, - int n_steps, - bint as_while, - numpy.ndarray[numpy.int32_t,ndim=1] mintaps, - numpy.ndarray[numpy.int32_t,ndim=2] tap_array, - numpy.ndarray[numpy.int32_t,ndim=1] tap_array_len, - numpy.ndarray[numpy.int32_t,ndim=1] vector_seqs, - numpy.ndarray[numpy.int32_t,ndim=1] vector_outs, - numpy.ndarray[numpy.int32_t,ndim=2] mit_mot_out_slices, - numpy.ndarray[numpy.int32_t,ndim=1] mit_mot_out_nslices, - numpy.ndarray[numpy.int32_t,ndim=1] mitmots_preallocated, - numpy.ndarray[numpy.int32_t,ndim=1] inps_is_tensor, - numpy.ndarray[numpy.int32_t,ndim=1] outs_is_tensor, - fn, - fnct, - numpy.ndarray[numpy.int32_t,ndim=1] destroy_map, - args, - outs, - self, - node): - """ - Parameters - ---------- - n_shared_outs: unsigned int - Number of arugments that correspond to shared variables with - updates - n_mit_mot_outs: unsigned int - Sum over the number of output taps for each mit_mot sequence - n_seqs: unsigned int - Number of sequences provided as input - n_mit_mot : unsigned int - Number of mit_mot arguemnts - n_mit_sot: unsigned int - Number of mit_sot arguments - n_sit_sot: unsigned int - Number of sit sot arguemnts - n_nit_sot: unsigned int - Number of nit_sot arguments - n_steps: unsigned int - Number of steps to loop over - mintaps: int32 ndarray (can also be a simple python list if that is better !) - For any of the mit_mot, mit_sot, sit_sot says which is the furtherst - away input tap from current position. For example, if the taps where [-2, - -5, -9], the mintap would be -9. For sit_sot this is always -1 since - is the only allowed tap. - tap_array: int32 ndarray( can be replaced by a list of list in python if better) - For each of the mit_mot, mit_sot, sit_sot (the first dimension) says - which are the corresponding input taps. While this is a matrix, not all - values in a row are needed and tap_array_len is there to say up to - which entry we are dealing with valid taps ( afterwards there are - just 0s to ensure the fix format) - tap_array_len: int32 ndarray( can be replaced by a list if better) - For each of the mit_mot, mit_sot, sit_sot says how many input taps - each has. For sit_sot this will always be 1. - vector_seqs: int32 ndarray (can be replaced by a list of bools if better) - For each sequence the corresponding entry is either a 1, is the - sequence is a vector or 0 if it has more than 1 dimension - vector_outs: int32 ndarray( can be replaced by list of bools if better) - For each output ( mit_mot, mit_sot, sit_sot, nit_sot in this order) - the entry is 1 if the corresponding argument is a 1 dimensional - tensor, 0 otherwise. - mit_mot_out_slices : int32 ndarray( can be replaced by list of lists) - Same as tap_array, but for the output taps of mit_mot sequences - mit_mot_out_nslices: int32 ndarray (Can be replaced by a list) - Same as tap_array_len, but is the number of output taps of the - mit_mot sequences (i.e. it corresponds to mit_mot_out_slices) - inps_is_tensor : int32 ndarray (Can be replaced by a list) - Array of boolean indicating, for every input, whether it is a tensor - or not - outs_is_tensor : int32 ndarray (Can be replaced by a list) - Array of boolean indicating, for every output, whether it is a tensor - or not - fn: callable - This is the linker, i.e. the function that will loop over the - computational graph and call the perform of each operation. For this - linker there is a c version in graph/lazy_linker.c that will be the - starting point of implementing this function in C ( we need to take - all the code around the call of this function and put in C inside - that code) - fnct: python object - Only used to attach some timings for the profile mode ( can be - skiped if we don't care about Aesara's profile mode) - destroy_map - Array of boolean saying if an output is computed inplace - args: list of ndarrays (and random states) - The inputs of scan in a given order ( n_steps, sequences, mit_mot, - mit_sot, sit_sot, nit_sot, shared_outs, other_args) - outs: list of 1 element list ( or storage objects?) - This is where we need to copy our outputs ( we don't return the - results, though we can change the code such that we return, and - figure things out on the outside - python) - self: python object - The scan op itself. I only use it to attach to it some timing - informations .. but I don;t need to. - - """ - # 1. Unzip the number of steps and sequences. If number of steps is - # negative flip sequences around, and make n_steps positive - t0_call = time.time() - t_fn = 0 - cdef unsigned int n_outs = n_mit_mot + n_mit_sot + n_sit_sot - cdef unsigned int seqs_arg_offset = n_seqs + 1 - cdef unsigned int shared_arg_offset = ( 1 + n_seqs + n_mit_mot + - n_mit_sot + n_sit_sot) - cdef unsigned int nit_sot_arg_offset = ( shared_arg_offset + - n_shared_outs) - cdef unsigned int offset_out - cdef unsigned int lenpos = n_outs + n_nit_sot - cdef int pos[500] # put a maximum of 500 outputs - cdef unsigned int len_store_steps = n_mit_mot + n_mit_sot + n_sit_sot + n_nit_sot - cdef int store_steps[500] - cdef unsigned int l - cdef unsigned int offset - cdef int tap - cdef int _idx - cdef unsigned int a_offset - cdef unsigned int o_offset - cdef unsigned int idx - cdef unsigned int i - cdef unsigned int j - cdef int k - cdef unsigned int kdx - cdef unsigned int tdx - cdef unsigned int pdx - cdef unsigned int jout - cdef unsigned int begin - cdef unsigned int end - cdef int cond - cdef unsigned int len_output_storage = (n_mit_mot_outs + n_mit_sot + - n_sit_sot + n_nit_sot + - n_shared_outs) - - - if n_steps < 0: - # History, in the past, this was used for backward - # scan. Now we reverse the inputs outside of scan. - raise IndexError( - "Scan was asked to run for negative number of step %d" % - n_steps) - elif n_steps == 0: - raise NotImplementedError( - "We didn't implemented yet the case where scan do 0 iteration") - else: - for idx in range(n_seqs): - if args[(1+idx)].shape[0] < n_steps: - raise ValueError(('Sequence is shorter than the required ' - 'number of steps : (n_steps, seq, ' - 'seq.shape):'), n_steps, - args[1+idx], - args[1+idx].shape) - # 2. Allocate memory for the outputs. Construct the list: - # store_steps -- map containting the length of each output - # pos -- map containing the current position of each output - - for idx in range(n_mit_mot + n_mit_sot + n_sit_sot): - store_steps[idx] = args[(idx+n_seqs+1)].shape[0] - - for idx in range(n_nit_sot): - store_steps[(idx + n_mit_mot + n_mit_sot + n_sit_sot)]=\ - args[(idx + n_mit_mot + n_mit_sot + n_sit_sot - + n_shared_outs + n_seqs+1)] - - for idx in range(n_outs + n_nit_sot): - pos[idx] = (-mintaps[idx])%store_steps[idx] - - - # 2.1 Create storage space for outputs - for idx in range(n_outs): - if destroy_map[idx] != 0: - # ^ Case 1. Outputs should be computed inplace of their - # initial state - outs[idx][0] = args[ (1+ n_seqs + idx)] - elif ( outs[idx][0] is not None and - outs[idx][0].shape[1:] == args[(1+ n_seqs + idx)].shape[1:] - and outs[idx][0].shape[0] >= store_steps[idx] ): - # Put in the values of the initial state - outs[idx][0] = outs[idx][0][:store_steps[idx]] - if idx > n_mit_mot: - l = - mintaps[idx] - outs[idx][0][:l] = args[(seqs_arg_offset + - idx)][:l] - else: - outs[idx][0][:] = args[(seqs_arg_offset + idx)] - else: - outs[idx][0] = args[(seqs_arg_offset + idx)].copy() - - - offset = nit_sot_arg_offset + n_nit_sot - other_args = args[offset:] - input_storage = fnct.input_storage - nb_mitmot_in = 0 - for idx in range(n_mit_mot): - nb_mitmot_in += tap_array_len[idx] - old_mitmot_input_storage = [None] * nb_mitmot_in - old_mitmot_input_data = [None] * nb_mitmot_in - output_storage = fnct.output_storage - old_output_storage = [None] * len_output_storage - old_output_data = [None] * len_output_storage - offset = n_seqs - for idx in range(n_outs): - offset += tap_array_len[idx] - offset += n_shared_outs - - for idx in range(len(other_args)): - input_storage[(idx+offset)].storage[0] = other_args[idx] - - - i = 0 - cond = 1 - ############## THE MAIN LOOP ######################### - #for i in range(n_steps): - while (i < n_steps) and cond == 1: - # sequences over which scan iterates - # 3. collect input slices - for idx in range(n_seqs): - if vector_seqs[idx] == 1: - input_storage[idx].storage[0] = args[\ - (1+idx)][i:(i+1)].reshape(()) - else: - input_storage[idx].storage[0] = \ - args[(idx+1)][i] - - offset = n_seqs - for idx in range(n_outs): - if vector_outs[idx] == 1: - for tdx in range(tap_array_len[idx]): - tap = tap_array[idx,tdx] - _idx = (pos[idx]+tap)%store_steps[idx] - input_storage[offset].storage[0] =\ - outs[idx][0][_idx:(_idx+1)].reshape(()) - offset += 1 - else: - for tdx in range(tap_array_len[idx]): - tap = tap_array[idx,tdx] - _idx = (pos[idx]+tap)%store_steps[idx] - input_storage[offset].storage[0] = outs[idx][0][_idx] - offset += 1 - - - a_offset = shared_arg_offset - o_offset = n_outs + n_nit_sot - if i == 0: - for j in range(n_shared_outs): - input_storage[offset].storage[0] = args[(a_offset+j)] - offset += 1 - else: - for j in range(n_shared_outs): - input_storage[offset].storage[0] = outs[(o_offset+j)][0] - offset += 1 - - # 4. collecting slices where the output should be stored - - # 4.1. Collect slices for mitmots - offset = 0 - for idx in range(n_mit_mot_outs): - if not mitmots_preallocated[idx]: - output_storage[offset].storage[0] = None - offset += 1 - - # 4.2. Collect slices for mitsots, sitsots and nitsots - if i != 0: - for idx in range(n_outs + n_nit_sot - n_mit_mot): - if ( store_steps[(idx+n_mit_mot)] == 1 or - vector_outs[(idx+n_mit_mot)] == 1): - output_storage[(idx+offset)].storage[0] = None - else: - output_storage[(idx+offset)].storage[0] =\ - outs[(idx+n_mit_mot)][0][pos[\ - (idx+n_mit_mot)]] - else: - for idx in range(n_outs + n_nit_sot - n_mit_mot): - output_storage[(idx+offset)].storage[0] = None - - # 4.3. Collect slices for shared outputs - offset += n_outs+n_nit_sot - n_mit_mot - for idx in range(n_shared_outs): - output_storage[(idx+offset)].storage[0] = None - - # 4.4. If there is a condition add it to the mix - if as_while: - pdx = offset + n_shared_outs - output_storage[pdx].storage[0] = None - - # 4.5. Keep a reference to the variables (ndarrays, GpuArrays, - # etc) currently in the output_storage to be able to compare them - # with the actual outputs of the inner function after its - # execution. Also keep pointers to their data to be able to detect - # cases where outputs reused the allocated object but alter the - # memory region they refer to. - for idx in range(len_output_storage): - - var = output_storage[idx].storage[0] - old_output_storage[idx] = var - - if var is None: - old_output_data[idx] = None - elif outs_is_tensor[idx]: - old_output_data[idx] = var.data - else: - old_output_data[idx] = var.gpudata - - # 4.6. Keep a reference to the variables (ndarrays, GpuArrays, - # etc) associated with mitmot inputs currently in the input_storage to - # be able to compare them with the content of the input_storage after - # the execution of the function. Also keep pointers to their data to - # be able to detect cases where outputs reused the allocated object - # but alter the memory region they refer to. - for idx in xrange(nb_mitmot_in): - var = input_storage[idx + n_seqs].storage[0] - old_mitmot_input_storage[idx] = var - - if var is None: - old_mitmot_input_data[idx] = None - elif inps_is_tensor[idx + n_seqs]: - old_mitmot_input_data[idx] = var.data - else: - old_mitmot_input_data[idx] = var.gpudata - - # 5.1 compute outputs - t0_fn = time.time() - - try: - fn() - except Exception: - if hasattr(fn, 'position_of_error'): - # this is a new vm-provided function - # the C VM needs this because the exception manipulation - # done by raise_with_op is not implemented in C. - if hasattr(fn, 'thunks'): - # For the CVM - raise_with_op(fn.maker.fgraph, - fn.nodes[fn.position_of_error], - fn.thunks[fn.position_of_error]) - else: - # For the c linker - # We don't have access from python to all the - # temps values So for now, we just don't print - # the extra shapes/strides info - raise_with_op(fn.maker.fgraph, fn.nodes[fn.position_of_error]) - else: - # old-style linkers raise their own exceptions - raise - - dt_fn = time.time() - t0_fn - t_fn += dt_fn - if self.as_while: - pdx = offset + n_shared_outs - cond = output_storage[pdx].storage[0] == 0 - - # 5.2. By calling fn() directly instead of calling the aesara - # function, it is possible that the updates have not been - # performed. Perform the updates if needed. - offset_out = len(output_storage) - 1 - if getattr(fn, 'need_update_inputs', True): - # Update the inputs that have an update function - for inp, storage in zip(self.fn.maker.expanded_inputs[::-1], - self.fn.input_storage[::-1]): - if inp.update is not None: - storage.data = output_storage[offset_out].data - offset_out -= 1 - - offset_out = 0 - - # 5.3 Copy over the values for mit_mot outputs - mitmot_inp_offset = 0 - mitmot_out_idx = 0 - for j in xrange(self.n_mit_mot): - for k in self.mit_mot_out_slices[j]: - if mitmots_preallocated[mitmot_out_idx]: - # This output tap has been preallocated. - inp_idx = (mitmot_inp_offset + - self.tap_array[j].index(k)) - - # Verify whether the input points to the same data as - # it did before the execution of the inner function. - old_var = old_mitmot_input_storage[inp_idx] - new_var = input_storage[n_seqs + inp_idx].storage[0] - if old_var is new_var: - old_data = old_mitmot_input_data[inp_idx] - if inps_is_tensor[n_seqs + inp_idx]: - same_data = (new_var.data == old_data) - else: - same_data = (new_var.gpudata == old_data) - else: - same_data = False - - # If the corresponding input storage has been replaced, - # recover the value as usual. Otherwise, the input was - # modified inplace and nothing needs to be done. - if not same_data: - outs[j][0][(k + pos[j])] = \ - input_storage[(n_seqs + inp_idx)].storage[0] - - else: - # This output tap has not been preallocated, recover - # its value as usual - outs[j][0][(k + pos[j])] = \ - output_storage[offset_out].storage[0] - offset_out += 1 - - mitmot_out_idx += 1 - - mitmot_inp_offset += len(self.tap_array[j]) - - # 5.4 Copy over the values for mit_sot/sit_sot outputs - begin = n_mit_mot - end = n_outs - offset_out -= n_mit_mot - - for j in range(begin, end): - - # Copy the output value to `outs`, if necessary - if store_steps[j] == 1 or vector_outs[j] == 1: - outs[j][0][pos[j]] = output_storage[(offset_out+j)].storage[0] - else: - # Check whether the initialization of the output storage map - # for this output has been reused. - old_var = old_output_storage[offset_out + j] - old_data = old_output_data[offset_out + j] - new_var = output_storage[offset_out + j].storage[0] - if old_var is new_var: - if old_data is None: - output_reused = False - elif outs_is_tensor[offset_out + j]: - output_reused = (new_var.data == old_data) - else: - output_reused = (new_var.gpudata == old_data) - else: - output_reused = False - - if not output_reused: - outs[j][0][pos[j]] = \ - output_storage[(offset_out+j)].storage[0] - - - # 5.5 Copy over the values for nit_sot outputs - begin = end - end += n_nit_sot - for j in range(begin,end): - - if i == 0: - jout = j+offset_out - shape = (store_steps[j],) + output_storage[jout].storage[0].shape - dtype = output_storage[jout].storage[0].dtype - if (outs[j][0] is None or - outs[j][0].shape[0] < store_steps[j] or - outs[j][0].shape[1:] != shape[1:] or - outs[j][0].dtype != dtype ): - outs[j][0] = node.outputs[j].type.value_zeros(shape) - elif outs[j][0].shape[0] != store_steps[j]: - outs[j][0] = outs[j][0][:store_steps[j]] - outs[j][0][pos[j]] = output_storage[jout].storage[0] - elif store_steps[j] == 1 or vector_outs[j] == 1: - outs[j][0][pos[j]] = output_storage[j+offset_out].storage[0] - else: - # Check whether the initialization of the output storage map - # for this output has been reused. - old_var = old_output_storage[offset_out + j] - old_data = old_output_data[offset_out + j] - new_var = output_storage[offset_out + j].storage[0] - if old_var is new_var: - if old_data is None: - output_reused = False - elif outs_is_tensor[offset_out + j]: - output_reused = (new_var.data == old_data) - else: - output_reused = (new_var.gpudata == old_data) - else: - output_reused = False - - if not output_reused: - try: - outs[j][0][pos[j]] = output_storage[j+offset_out].storage[0] - except ValueError as e: - if i == 0: - raise - raise ValueError( - "An output of the scan has changed shape. " - "This may be caused by a pushout optimization." - " Try adding " - "'optimizer_excluding=scanOp_pushout_output' " - "to your Aesara flags.") - - # 5.6 Copy over the values for outputs corresponding to shared - # variables - begin = end - end += n_shared_outs - for j in range(begin,end): - jout = j +offset_out - outs[j][0] = output_storage[jout].storage[0] - - for idx in range(lenpos): - pos[idx] = (pos[idx]+1)%store_steps[idx] - i = i + 1 - - # 6. Check if you need to re-order output buffers - begin = n_mit_mot - end = n_outs + n_nit_sot - for idx in range(begin, end): - if ( store_steps[idx] < i-mintaps[idx] and - pos[idx] < store_steps[idx] ): - - pdx = pos[idx] - if pdx >= store_steps[idx]//2 : - # It seems inefficient to copy the bigger part of the - # array over, and back, but it is the only way that - # there is no overlap in the areas of out[idx][0] that - # are read and written. - # This way, there will be no information overwritten - # before it is read (as it used to happen). - shape = (pdx,)+ outs[idx][0].shape[1:] - - tmp = node.outputs[idx].type.value_zeros(shape) - tmp[:] = outs[idx][0][:pdx] - outs[idx][0][:store_steps[idx]-pdx] = outs[idx][0][pdx:] - outs[idx][0][store_steps[idx]-pdx:] = tmp - else: - shape = (store_steps[idx]-pdx,) + outs[idx][0].shape[1:] - tmp = node.outputs[idx].type.value_zeros(shape) - tmp[:] = outs[idx][0][pdx:] - outs[idx][0][store_steps[idx]-pdx:] = outs[idx][0][:pdx] - outs[idx][0][:store_steps[idx]-pdx] = tmp - # This would normally happen only when doing truncated - # backpropagation through time. In such a scenarion Scan is - # expected to return 0 for all entries for which the gradient is - # not actually computed - elif store_steps[idx] > i - self.mintaps[idx]: - outs[idx][0][i-self.mintaps[idx]:] = 0 - - # This is a fix for a bug introduced by while. If you say - # you want to loop up to a condition, you expect the output - # to have that length ( and not the maximal length possible) - # - # Without this the behaviour of a scan op is not consistent - # if optimization gets applied compared to when optimization - # do not get applied - if i < n_steps: - - # Cython can not handle negative indices ( because of a - # derictive at the beginning of the function that says not - # to do boundschecks). The directive is used to make the - # code faster, so this workaround is better then removing - # the directive. - sh0 = outs[idx][0].shape[0] - outs[idx][0] = outs[idx][0][:sh0-(n_steps - i)] - - # We never reuse the input or output storage of the - # inner function so we clear it. - for i_s in input_storage: - i_s.storage[0] = None - for o_s in output_storage: - o_s.storage[0] = None - - t_call = time.time() - t0_call - - if hasattr(fnct.maker, 'profile'): - profile = fnct.maker.profile - if type(profile) is not bool and profile: - profile.vm_call_time += t_fn - profile.callcount += 1 - profile.nbsteps += n_steps - profile.call_time += t_call - if hasattr(fn, 'update_profile'): - fn.update_profile(profile) - - ### Old Profile Mode - #if hasattr(fnct.maker.mode,'fct_call_time'): - # fnct.maker.mode.fct_call_time[fnct] += t_fn - # fnct.maker.mode.fct_call[fnct] += n_steps - - #fnct.maker.mode.call_time += t_fn - #fnct.maker.mode.fn_time += t_fn - - # DEBUG PRINT : - self.t_call = t_call - self.t_fn = t_fn - # print 'Cython > timing', t_call, t_fn, 'in percentage', 100.*t_fn/t_call diff --git a/sources b/sources deleted file mode 100644 index 27133a8..0000000 --- a/sources +++ /dev/null @@ -1 +0,0 @@ -SHA512 (Theano-PyMC-1.1.2.tar.gz) = a7dcdaa24ac6a74a9442d0b6dbe5e474a03aa921427d88348303b20151c7ab28786b99cb1877d83e220bf92abc45bfaa9fdcf44e7ba56e41ce392b9aec0239ed