pytensor 2.36.0__cp314-cp314-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pytensor/__init__.py +176 -0
- pytensor/_version.py +21 -0
- pytensor/bin/__init__.py +0 -0
- pytensor/bin/pytensor_cache.py +112 -0
- pytensor/breakpoint.py +161 -0
- pytensor/compile/__init__.py +63 -0
- pytensor/compile/builders.py +882 -0
- pytensor/compile/compiledir.py +260 -0
- pytensor/compile/compilelock.py +87 -0
- pytensor/compile/debugmode.py +2323 -0
- pytensor/compile/function/__init__.py +348 -0
- pytensor/compile/function/pfunc.py +688 -0
- pytensor/compile/function/types.py +1973 -0
- pytensor/compile/io.py +251 -0
- pytensor/compile/mode.py +590 -0
- pytensor/compile/monitormode.py +111 -0
- pytensor/compile/nanguardmode.py +260 -0
- pytensor/compile/ops.py +341 -0
- pytensor/compile/profiling.py +1630 -0
- pytensor/compile/sharedvalue.py +224 -0
- pytensor/configdefaults.py +1313 -0
- pytensor/configparser.py +619 -0
- pytensor/d3viz/__init__.py +1 -0
- pytensor/d3viz/css/d3-context-menu.css +29 -0
- pytensor/d3viz/css/d3viz.css +98 -0
- pytensor/d3viz/d3viz.py +130 -0
- pytensor/d3viz/formatting.py +368 -0
- pytensor/d3viz/html/template.html +101 -0
- pytensor/d3viz/js/d3-context-menu.js +42 -0
- pytensor/d3viz/js/d3.v3.min.js +5 -0
- pytensor/d3viz/js/d3viz.js +969 -0
- pytensor/d3viz/js/dagre-d3.min.js +2 -0
- pytensor/d3viz/js/graphlib-dot.min.js +4 -0
- pytensor/gradient.py +2522 -0
- pytensor/graph/__init__.py +19 -0
- pytensor/graph/basic.py +1281 -0
- pytensor/graph/destroyhandler.py +804 -0
- pytensor/graph/features.py +883 -0
- pytensor/graph/fg.py +926 -0
- pytensor/graph/null_type.py +42 -0
- pytensor/graph/op.py +821 -0
- pytensor/graph/replace.py +323 -0
- pytensor/graph/rewriting/__init__.py +4 -0
- pytensor/graph/rewriting/basic.py +3035 -0
- pytensor/graph/rewriting/db.py +547 -0
- pytensor/graph/rewriting/kanren.py +99 -0
- pytensor/graph/rewriting/unify.py +497 -0
- pytensor/graph/rewriting/utils.py +229 -0
- pytensor/graph/traversal.py +773 -0
- pytensor/graph/type.py +270 -0
- pytensor/graph/utils.py +374 -0
- pytensor/ifelse.py +810 -0
- pytensor/ipython.py +215 -0
- pytensor/link/__init__.py +1 -0
- pytensor/link/basic.py +745 -0
- pytensor/link/c/__init__.py +0 -0
- pytensor/link/c/basic.py +2010 -0
- pytensor/link/c/c_code/lazylinker_c.c +1018 -0
- pytensor/link/c/c_code/pytensor_mod_helper.h +25 -0
- pytensor/link/c/cmodule.py +3015 -0
- pytensor/link/c/cutils.py +116 -0
- pytensor/link/c/cvm.py +29 -0
- pytensor/link/c/exceptions.py +12 -0
- pytensor/link/c/interface.py +632 -0
- pytensor/link/c/lazylinker_c.py +147 -0
- pytensor/link/c/op.py +649 -0
- pytensor/link/c/params_type.py +885 -0
- pytensor/link/c/type.py +787 -0
- pytensor/link/jax/__init__.py +1 -0
- pytensor/link/jax/dispatch/__init__.py +24 -0
- pytensor/link/jax/dispatch/basic.py +150 -0
- pytensor/link/jax/dispatch/blas.py +14 -0
- pytensor/link/jax/dispatch/blockwise.py +21 -0
- pytensor/link/jax/dispatch/einsum.py +20 -0
- pytensor/link/jax/dispatch/elemwise.py +115 -0
- pytensor/link/jax/dispatch/extra_ops.py +143 -0
- pytensor/link/jax/dispatch/math.py +60 -0
- pytensor/link/jax/dispatch/nlinalg.py +82 -0
- pytensor/link/jax/dispatch/pad.py +53 -0
- pytensor/link/jax/dispatch/random.py +454 -0
- pytensor/link/jax/dispatch/scalar.py +343 -0
- pytensor/link/jax/dispatch/scan.py +251 -0
- pytensor/link/jax/dispatch/shape.py +106 -0
- pytensor/link/jax/dispatch/signal/__init__.py +1 -0
- pytensor/link/jax/dispatch/signal/conv.py +24 -0
- pytensor/link/jax/dispatch/slinalg.py +191 -0
- pytensor/link/jax/dispatch/sort.py +24 -0
- pytensor/link/jax/dispatch/sparse.py +38 -0
- pytensor/link/jax/dispatch/subtensor.py +101 -0
- pytensor/link/jax/dispatch/tensor_basic.py +203 -0
- pytensor/link/jax/linker.py +142 -0
- pytensor/link/jax/ops.py +538 -0
- pytensor/link/mlx/__init__.py +1 -0
- pytensor/link/mlx/dispatch/__init__.py +17 -0
- pytensor/link/mlx/dispatch/basic.py +101 -0
- pytensor/link/mlx/dispatch/blockwise.py +42 -0
- pytensor/link/mlx/dispatch/core.py +324 -0
- pytensor/link/mlx/dispatch/elemwise.py +457 -0
- pytensor/link/mlx/dispatch/extra_ops.py +35 -0
- pytensor/link/mlx/dispatch/math.py +72 -0
- pytensor/link/mlx/dispatch/nlinalg.py +69 -0
- pytensor/link/mlx/dispatch/shape.py +42 -0
- pytensor/link/mlx/dispatch/signal/__init__.py +0 -0
- pytensor/link/mlx/dispatch/signal/conv.py +33 -0
- pytensor/link/mlx/dispatch/slinalg.py +84 -0
- pytensor/link/mlx/dispatch/sort.py +38 -0
- pytensor/link/mlx/dispatch/subtensor.py +105 -0
- pytensor/link/mlx/linker.py +77 -0
- pytensor/link/numba/__init__.py +1 -0
- pytensor/link/numba/cache.py +129 -0
- pytensor/link/numba/dispatch/__init__.py +23 -0
- pytensor/link/numba/dispatch/basic.py +571 -0
- pytensor/link/numba/dispatch/blockwise.py +115 -0
- pytensor/link/numba/dispatch/compile_ops.py +148 -0
- pytensor/link/numba/dispatch/cython_support.py +214 -0
- pytensor/link/numba/dispatch/elemwise.py +746 -0
- pytensor/link/numba/dispatch/extra_ops.py +351 -0
- pytensor/link/numba/dispatch/linalg/_LAPACK.py +557 -0
- pytensor/link/numba/dispatch/linalg/__init__.py +0 -0
- pytensor/link/numba/dispatch/linalg/decomposition/__init__.py +0 -0
- pytensor/link/numba/dispatch/linalg/decomposition/cholesky.py +76 -0
- pytensor/link/numba/dispatch/linalg/decomposition/lu.py +198 -0
- pytensor/link/numba/dispatch/linalg/decomposition/lu_factor.py +89 -0
- pytensor/link/numba/dispatch/linalg/decomposition/qr.py +980 -0
- pytensor/link/numba/dispatch/linalg/solve/__init__.py +0 -0
- pytensor/link/numba/dispatch/linalg/solve/cholesky.py +88 -0
- pytensor/link/numba/dispatch/linalg/solve/general.py +147 -0
- pytensor/link/numba/dispatch/linalg/solve/lu_solve.py +150 -0
- pytensor/link/numba/dispatch/linalg/solve/norm.py +55 -0
- pytensor/link/numba/dispatch/linalg/solve/posdef.py +224 -0
- pytensor/link/numba/dispatch/linalg/solve/symmetric.py +229 -0
- pytensor/link/numba/dispatch/linalg/solve/triangular.py +117 -0
- pytensor/link/numba/dispatch/linalg/solve/tridiagonal.py +446 -0
- pytensor/link/numba/dispatch/linalg/solve/utils.py +11 -0
- pytensor/link/numba/dispatch/linalg/utils.py +118 -0
- pytensor/link/numba/dispatch/nlinalg.py +179 -0
- pytensor/link/numba/dispatch/random.py +484 -0
- pytensor/link/numba/dispatch/scalar.py +414 -0
- pytensor/link/numba/dispatch/scan.py +466 -0
- pytensor/link/numba/dispatch/shape.py +78 -0
- pytensor/link/numba/dispatch/signal/__init__.py +1 -0
- pytensor/link/numba/dispatch/signal/conv.py +71 -0
- pytensor/link/numba/dispatch/slinalg.py +503 -0
- pytensor/link/numba/dispatch/sort.py +65 -0
- pytensor/link/numba/dispatch/sparse.py +206 -0
- pytensor/link/numba/dispatch/subtensor.py +655 -0
- pytensor/link/numba/dispatch/tensor_basic.py +254 -0
- pytensor/link/numba/dispatch/typed_list.py +236 -0
- pytensor/link/numba/dispatch/vectorize_codegen.py +574 -0
- pytensor/link/numba/linker.py +32 -0
- pytensor/link/pytorch/dispatch/__init__.py +16 -0
- pytensor/link/pytorch/dispatch/basic.py +242 -0
- pytensor/link/pytorch/dispatch/blas.py +14 -0
- pytensor/link/pytorch/dispatch/blockwise.py +32 -0
- pytensor/link/pytorch/dispatch/elemwise.py +212 -0
- pytensor/link/pytorch/dispatch/extra_ops.py +53 -0
- pytensor/link/pytorch/dispatch/math.py +12 -0
- pytensor/link/pytorch/dispatch/nlinalg.py +87 -0
- pytensor/link/pytorch/dispatch/scalar.py +105 -0
- pytensor/link/pytorch/dispatch/shape.py +58 -0
- pytensor/link/pytorch/dispatch/slinalg.py +23 -0
- pytensor/link/pytorch/dispatch/sort.py +25 -0
- pytensor/link/pytorch/dispatch/subtensor.py +148 -0
- pytensor/link/pytorch/linker.py +103 -0
- pytensor/link/utils.py +840 -0
- pytensor/link/vm.py +1335 -0
- pytensor/misc/__init__.py +0 -0
- pytensor/misc/check_blas.py +301 -0
- pytensor/misc/check_blas_many.sh +21 -0
- pytensor/misc/check_duplicate_key.py +71 -0
- pytensor/misc/elemwise_openmp_speedup.py +77 -0
- pytensor/misc/elemwise_time_test.py +76 -0
- pytensor/misc/frozendict.py +44 -0
- pytensor/misc/may_share_memory.py +38 -0
- pytensor/misc/ordered_set.py +44 -0
- pytensor/misc/pkl_utils.py +64 -0
- pytensor/npy_2_compat.py +22 -0
- pytensor/printing.py +1899 -0
- pytensor/py.typed +0 -0
- pytensor/raise_op.py +200 -0
- pytensor/scalar/__init__.py +2 -0
- pytensor/scalar/basic.py +4508 -0
- pytensor/scalar/c_code/Faddeeva.cc +2517 -0
- pytensor/scalar/c_code/Faddeeva.hh +62 -0
- pytensor/scalar/c_code/gamma.c +391 -0
- pytensor/scalar/c_code/incbet.c +313 -0
- pytensor/scalar/loop.py +339 -0
- pytensor/scalar/math.py +1902 -0
- pytensor/scalar/sharedvar.py +61 -0
- pytensor/scan/__init__.py +57 -0
- pytensor/scan/basic.py +1277 -0
- pytensor/scan/checkpoints.py +191 -0
- pytensor/scan/op.py +3513 -0
- pytensor/scan/rewriting.py +2701 -0
- pytensor/scan/scan_perform.c +35073 -0
- pytensor/scan/scan_perform.cp314-win_amd64.pyd +0 -0
- pytensor/scan/scan_perform.pyx +602 -0
- pytensor/scan/scan_perform_ext.py +17 -0
- pytensor/scan/utils.py +1147 -0
- pytensor/scan/views.py +260 -0
- pytensor/sparse/__init__.py +35 -0
- pytensor/sparse/basic.py +1946 -0
- pytensor/sparse/linalg.py +93 -0
- pytensor/sparse/math.py +2087 -0
- pytensor/sparse/rewriting.py +2070 -0
- pytensor/sparse/sharedvar.py +30 -0
- pytensor/sparse/type.py +253 -0
- pytensor/sparse/utils.py +20 -0
- pytensor/sparse/variable.py +479 -0
- pytensor/tensor/__init__.py +161 -0
- pytensor/tensor/_linalg/__init__.py +2 -0
- pytensor/tensor/_linalg/solve/__init__.py +2 -0
- pytensor/tensor/_linalg/solve/rewriting.py +285 -0
- pytensor/tensor/_linalg/solve/tridiagonal.py +227 -0
- pytensor/tensor/basic.py +4652 -0
- pytensor/tensor/blas.py +1798 -0
- pytensor/tensor/blas_c.py +673 -0
- pytensor/tensor/blas_headers.py +1207 -0
- pytensor/tensor/blockwise.py +604 -0
- pytensor/tensor/c_code/alt_blas_common.h +21 -0
- pytensor/tensor/c_code/alt_blas_template.c +369 -0
- pytensor/tensor/c_code/dimshuffle.c +86 -0
- pytensor/tensor/conv/__init__.py +10 -0
- pytensor/tensor/conv/abstract_conv.py +3720 -0
- pytensor/tensor/einsum.py +800 -0
- pytensor/tensor/elemwise.py +1719 -0
- pytensor/tensor/elemwise_cgen.py +761 -0
- pytensor/tensor/exceptions.py +16 -0
- pytensor/tensor/extra_ops.py +2034 -0
- pytensor/tensor/fft.py +222 -0
- pytensor/tensor/fourier.py +183 -0
- pytensor/tensor/functional.py +131 -0
- pytensor/tensor/interpolate.py +200 -0
- pytensor/tensor/linalg.py +2 -0
- pytensor/tensor/math.py +4318 -0
- pytensor/tensor/nlinalg.py +1198 -0
- pytensor/tensor/optimize.py +1053 -0
- pytensor/tensor/pad.py +693 -0
- pytensor/tensor/random/__init__.py +6 -0
- pytensor/tensor/random/basic.py +2173 -0
- pytensor/tensor/random/op.py +509 -0
- pytensor/tensor/random/rewriting/__init__.py +11 -0
- pytensor/tensor/random/rewriting/basic.py +358 -0
- pytensor/tensor/random/rewriting/jax.py +196 -0
- pytensor/tensor/random/rewriting/numba.py +90 -0
- pytensor/tensor/random/type.py +128 -0
- pytensor/tensor/random/utils.py +402 -0
- pytensor/tensor/random/var.py +37 -0
- pytensor/tensor/rewriting/__init__.py +17 -0
- pytensor/tensor/rewriting/basic.py +1407 -0
- pytensor/tensor/rewriting/blas.py +925 -0
- pytensor/tensor/rewriting/blas_c.py +72 -0
- pytensor/tensor/rewriting/blockwise.py +311 -0
- pytensor/tensor/rewriting/einsum.py +53 -0
- pytensor/tensor/rewriting/elemwise.py +1311 -0
- pytensor/tensor/rewriting/extra_ops.py +130 -0
- pytensor/tensor/rewriting/jax.py +150 -0
- pytensor/tensor/rewriting/linalg.py +1019 -0
- pytensor/tensor/rewriting/math.py +3863 -0
- pytensor/tensor/rewriting/numba.py +108 -0
- pytensor/tensor/rewriting/ofg.py +73 -0
- pytensor/tensor/rewriting/shape.py +1296 -0
- pytensor/tensor/rewriting/special.py +175 -0
- pytensor/tensor/rewriting/subtensor.py +1880 -0
- pytensor/tensor/rewriting/subtensor_lift.py +919 -0
- pytensor/tensor/rewriting/uncanonicalize.py +252 -0
- pytensor/tensor/shape.py +1024 -0
- pytensor/tensor/sharedvar.py +136 -0
- pytensor/tensor/signal/__init__.py +4 -0
- pytensor/tensor/signal/conv.py +348 -0
- pytensor/tensor/slinalg.py +2161 -0
- pytensor/tensor/sort.py +234 -0
- pytensor/tensor/special.py +822 -0
- pytensor/tensor/subtensor.py +3175 -0
- pytensor/tensor/type.py +1416 -0
- pytensor/tensor/type_other.py +143 -0
- pytensor/tensor/utils.py +287 -0
- pytensor/tensor/var.py +11 -0
- pytensor/tensor/variable.py +1146 -0
- pytensor/tensor/xlogx.py +66 -0
- pytensor/typed_list/__init__.py +3 -0
- pytensor/typed_list/basic.py +659 -0
- pytensor/typed_list/rewriting.py +26 -0
- pytensor/typed_list/type.py +142 -0
- pytensor/updates.py +60 -0
- pytensor/utils.py +340 -0
- pytensor/xtensor/__init__.py +14 -0
- pytensor/xtensor/basic.py +100 -0
- pytensor/xtensor/indexing.py +219 -0
- pytensor/xtensor/linalg.py +108 -0
- pytensor/xtensor/math.py +632 -0
- pytensor/xtensor/random.py +292 -0
- pytensor/xtensor/reduction.py +125 -0
- pytensor/xtensor/rewriting/__init__.py +6 -0
- pytensor/xtensor/rewriting/basic.py +62 -0
- pytensor/xtensor/rewriting/indexing.py +212 -0
- pytensor/xtensor/rewriting/math.py +47 -0
- pytensor/xtensor/rewriting/reduction.py +72 -0
- pytensor/xtensor/rewriting/shape.py +198 -0
- pytensor/xtensor/rewriting/utils.py +63 -0
- pytensor/xtensor/rewriting/vectorization.py +101 -0
- pytensor/xtensor/shape.py +694 -0
- pytensor/xtensor/type.py +1041 -0
- pytensor/xtensor/vectorization.py +278 -0
- pytensor-2.36.0.dist-info/METADATA +205 -0
- pytensor-2.36.0.dist-info/RECORD +310 -0
- pytensor-2.36.0.dist-info/WHEEL +5 -0
- pytensor-2.36.0.dist-info/entry_points.txt +2 -0
- pytensor-2.36.0.dist-info/licenses/LICENSE.txt +44 -0
- pytensor-2.36.0.dist-info/top_level.txt +1 -0
pytensor/__init__.py
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""
|
|
2
|
+
PyTensor is an optimizing compiler in Python, built to evaluate
|
|
3
|
+
complicated expressions (especially matrix-valued ones) as quickly as
|
|
4
|
+
possible. PyTensor compiles expression graphs (see :doc:`graph` ) that
|
|
5
|
+
are built by Python code. The expressions in these graphs are called
|
|
6
|
+
`Apply` nodes and the variables in these graphs are called `Variable`
|
|
7
|
+
nodes.
|
|
8
|
+
|
|
9
|
+
You compile a graph by calling `function`, which takes a graph, and
|
|
10
|
+
returns a callable object. One of pytensor's most important features is
|
|
11
|
+
that `function` can transform your graph before compiling it. It can
|
|
12
|
+
replace simple expressions with faster or more numerically stable
|
|
13
|
+
implementations.
|
|
14
|
+
|
|
15
|
+
To learn more, check out:
|
|
16
|
+
|
|
17
|
+
- Op List (:doc:`oplist`)
|
|
18
|
+
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
__docformat__ = "restructuredtext en"
|
|
22
|
+
|
|
23
|
+
# Set a default logger. It is important to do this before importing some other
|
|
24
|
+
# pytensor code, since this code may want to log some messages.
|
|
25
|
+
import logging
|
|
26
|
+
import sys
|
|
27
|
+
import warnings
|
|
28
|
+
from functools import singledispatch
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
from typing import Any, NoReturn, Optional
|
|
31
|
+
|
|
32
|
+
from pytensor import _version
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
__version__: str = _version.get_versions()["version"]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
pytensor_logger = logging.getLogger("pytensor")
|
|
39
|
+
logging_default_handler = logging.StreamHandler()
|
|
40
|
+
logging_default_formatter = logging.Formatter(
|
|
41
|
+
fmt="%(levelname)s (%(name)s): %(message)s"
|
|
42
|
+
)
|
|
43
|
+
logging_default_handler.setFormatter(logging_default_formatter)
|
|
44
|
+
pytensor_logger.setLevel(logging.WARNING)
|
|
45
|
+
|
|
46
|
+
if not pytensor_logger.hasHandlers():
|
|
47
|
+
pytensor_logger.addHandler(logging_default_handler)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# Disable default log handler added to pytensor_logger when the module
|
|
51
|
+
# is imported.
|
|
52
|
+
def disable_log_handler(logger=pytensor_logger, handler=logging_default_handler):
|
|
53
|
+
if logger.hasHandlers():
|
|
54
|
+
logger.removeHandler(handler)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# Raise a meaningful warning/error if the pytensor directory is in the Python
|
|
58
|
+
# path.
|
|
59
|
+
rpath = Path(__file__).parent.resolve()
|
|
60
|
+
if any(rpath == Path(p).resolve() for p in sys.path):
|
|
61
|
+
raise RuntimeError("You have the pytensor directory in your Python path.")
|
|
62
|
+
|
|
63
|
+
from pytensor.configdefaults import config
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# This is the api version for ops that generate C code. External ops
|
|
67
|
+
# might need manual changes if this number goes up. An undefined
|
|
68
|
+
# __api_version__ can be understood to mean api version 0.
|
|
69
|
+
#
|
|
70
|
+
# This number is not tied to the release version and should change
|
|
71
|
+
# very rarely.
|
|
72
|
+
__api_version__ = 1
|
|
73
|
+
|
|
74
|
+
# isort: off
|
|
75
|
+
from pytensor.graph.basic import Variable
|
|
76
|
+
from pytensor.graph.replace import clone_replace, graph_replace
|
|
77
|
+
|
|
78
|
+
# isort: on
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def as_symbolic(x: Any, name: str | None = None, **kwargs) -> Variable:
|
|
82
|
+
"""Convert `x` into an equivalent PyTensor `Variable`.
|
|
83
|
+
|
|
84
|
+
Parameters
|
|
85
|
+
----------
|
|
86
|
+
x
|
|
87
|
+
The object to be converted into a ``Variable`` type. A
|
|
88
|
+
``numpy.ndarray`` argument will not be copied, but a list of numbers
|
|
89
|
+
will be copied to make an ``numpy.ndarray``.
|
|
90
|
+
name
|
|
91
|
+
If a new ``Variable`` instance is created, it will be named with this
|
|
92
|
+
string.
|
|
93
|
+
kwargs
|
|
94
|
+
Options passed to the appropriate sub-dispatch functions. For example,
|
|
95
|
+
`ndim` and `dtype` can be passed when `x` is an `numpy.ndarray` or
|
|
96
|
+
`Number` type.
|
|
97
|
+
|
|
98
|
+
Raises
|
|
99
|
+
------
|
|
100
|
+
TypeError
|
|
101
|
+
If `x` cannot be converted to a `Variable`.
|
|
102
|
+
|
|
103
|
+
"""
|
|
104
|
+
if isinstance(x, Variable):
|
|
105
|
+
return x
|
|
106
|
+
|
|
107
|
+
res = _as_symbolic(x, **kwargs)
|
|
108
|
+
res.name = name
|
|
109
|
+
return res
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@singledispatch
|
|
113
|
+
def _as_symbolic(x: Any, **kwargs) -> Variable:
|
|
114
|
+
from pytensor.tensor import as_tensor_variable
|
|
115
|
+
|
|
116
|
+
return as_tensor_variable(x, **kwargs)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
# isort: off
|
|
120
|
+
from pytensor import scalar, tensor
|
|
121
|
+
from pytensor.compile import (
|
|
122
|
+
In,
|
|
123
|
+
Mode,
|
|
124
|
+
Out,
|
|
125
|
+
ProfileStats,
|
|
126
|
+
predefined_linkers,
|
|
127
|
+
predefined_modes,
|
|
128
|
+
predefined_optimizers,
|
|
129
|
+
shared,
|
|
130
|
+
)
|
|
131
|
+
from pytensor.compile.function import function, function_dump
|
|
132
|
+
from pytensor.compile.function.types import FunctionMaker
|
|
133
|
+
from pytensor.gradient import Lop, Rop, grad, subgraph_grad
|
|
134
|
+
from pytensor.printing import debugprint as dprint
|
|
135
|
+
from pytensor.printing import pp, pprint
|
|
136
|
+
from pytensor.updates import OrderedUpdates
|
|
137
|
+
|
|
138
|
+
# isort: on
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def get_underlying_scalar_constant(v):
|
|
142
|
+
"""Return the constant scalar (i.e. 0-D) value underlying variable `v`.
|
|
143
|
+
|
|
144
|
+
If `v` is the output of dim-shuffles, fills, allocs, cast, etc.
|
|
145
|
+
this function digs through them.
|
|
146
|
+
|
|
147
|
+
If ``pytensor.sparse`` is also there, we will look over CSM `Op`.
|
|
148
|
+
|
|
149
|
+
If `v` is not some view of constant data, then raise a
|
|
150
|
+
`NotScalarConstantError`.
|
|
151
|
+
"""
|
|
152
|
+
warnings.warn(
|
|
153
|
+
"get_underlying_scalar_constant is deprecated. Use tensor.get_underlying_scalar_constant_value instead.",
|
|
154
|
+
FutureWarning,
|
|
155
|
+
)
|
|
156
|
+
from pytensor.tensor.basic import get_underlying_scalar_constant_value
|
|
157
|
+
|
|
158
|
+
return get_underlying_scalar_constant_value(v)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
# isort: off
|
|
162
|
+
import pytensor.tensor.random.var
|
|
163
|
+
import pytensor.sparse
|
|
164
|
+
from pytensor.ifelse import ifelse
|
|
165
|
+
from pytensor.scan import checkpoints
|
|
166
|
+
from pytensor.scan.basic import scan
|
|
167
|
+
from pytensor.scan.views import foldl, foldr, map, reduce
|
|
168
|
+
from pytensor.compile.builders import OpFromGraph
|
|
169
|
+
from pytensor.link.jax.ops import wrap_jax
|
|
170
|
+
# isort: on
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
# Some config variables are registered by submodules. Only after all those
|
|
174
|
+
# imports were executed, we can warn about remaining flags provided by the user
|
|
175
|
+
# through PYTENSOR_FLAGS.
|
|
176
|
+
config.warn_unused_flags()
|
pytensor/_version.py
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
# This file was generated by 'versioneer.py' (0.29) from
|
|
3
|
+
# revision-control system data, or from the parent directory name of an
|
|
4
|
+
# unpacked source archive. Distribution tarballs contain a pre-generated copy
|
|
5
|
+
# of this file.
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
|
|
9
|
+
version_json = '''
|
|
10
|
+
{
|
|
11
|
+
"date": "2025-12-15T22:58:11+0100",
|
|
12
|
+
"dirty": false,
|
|
13
|
+
"error": null,
|
|
14
|
+
"full-revisionid": "6319fac84ebc71ad079c5986c6c302a52e254198",
|
|
15
|
+
"version": "2.36.0"
|
|
16
|
+
}
|
|
17
|
+
''' # END VERSION_JSON
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def get_versions():
|
|
21
|
+
return json.loads(version_json)
|
pytensor/bin/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import shutil
|
|
4
|
+
import sys
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
if sys.platform == "win32":
|
|
9
|
+
config_for_pytensor_cache_script = "cxx=,device=cpu"
|
|
10
|
+
pytensor_flags = (
|
|
11
|
+
os.environ["PYTENSOR_FLAGS"] if "PYTENSOR_FLAGS" in os.environ else ""
|
|
12
|
+
)
|
|
13
|
+
if pytensor_flags:
|
|
14
|
+
pytensor_flags += ","
|
|
15
|
+
pytensor_flags += config_for_pytensor_cache_script
|
|
16
|
+
os.environ["PYTENSOR_FLAGS"] = pytensor_flags
|
|
17
|
+
|
|
18
|
+
import pytensor
|
|
19
|
+
import pytensor.compile.compiledir
|
|
20
|
+
from pytensor import config
|
|
21
|
+
from pytensor.link.c.basic import get_module_cache
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
_logger = logging.getLogger("pytensor.bin.pytensor-cache")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def print_help(exit_status):
|
|
28
|
+
if exit_status:
|
|
29
|
+
print(f'command "{" ".join(sys.argv)}" not recognized')
|
|
30
|
+
print('Type "pytensor-cache" to print the cache location')
|
|
31
|
+
print('Type "pytensor-cache help" to print this help')
|
|
32
|
+
print('Type "pytensor-cache clear" to erase the cache')
|
|
33
|
+
print('Type "pytensor-cache list" to print the cache content')
|
|
34
|
+
print('Type "pytensor-cache unlock" to unlock the cache directory')
|
|
35
|
+
print('Type "pytensor-cache cleanup" to delete keys in the old format/code version')
|
|
36
|
+
print('Type "pytensor-cache purge" to force deletion of the cache directory')
|
|
37
|
+
print(
|
|
38
|
+
'Type "pytensor-cache basecompiledir" '
|
|
39
|
+
"to print the parent of the cache directory"
|
|
40
|
+
)
|
|
41
|
+
print(
|
|
42
|
+
'Type "pytensor-cache basecompiledir list" '
|
|
43
|
+
"to print the content of the base compile dir"
|
|
44
|
+
)
|
|
45
|
+
print(
|
|
46
|
+
'Type "pytensor-cache basecompiledir purge" '
|
|
47
|
+
"to remove everything in the base compile dir, "
|
|
48
|
+
"that is, erase ALL cache directories"
|
|
49
|
+
)
|
|
50
|
+
sys.exit(exit_status)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def main():
|
|
54
|
+
if len(sys.argv) == 1:
|
|
55
|
+
print(config.compiledir)
|
|
56
|
+
elif len(sys.argv) == 2:
|
|
57
|
+
if sys.argv[1] == "help":
|
|
58
|
+
print_help(exit_status=0)
|
|
59
|
+
if sys.argv[1] == "clear":
|
|
60
|
+
# We skip the refresh on module cache creation because the refresh will
|
|
61
|
+
# be done when calling clear afterwards.
|
|
62
|
+
cache = get_module_cache(init_args=dict(do_refresh=False))
|
|
63
|
+
cache.clear(
|
|
64
|
+
unversioned_min_age=-1, clear_base_files=True, delete_if_problem=True
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Print a warning if some cached modules were not removed, so that the
|
|
68
|
+
# user knows he should manually delete them, or call
|
|
69
|
+
# pytensor-cache purge, # to properly clear the cache.
|
|
70
|
+
items = list(Path(cache.dirname).glob("tmp*"))
|
|
71
|
+
if items:
|
|
72
|
+
_logger.warning(
|
|
73
|
+
"There remain elements in the cache dir that you may "
|
|
74
|
+
f"need to erase manually. The cache dir is:\n {config.compiledir}\n"
|
|
75
|
+
'You can also call "pytensor-cache purge" to '
|
|
76
|
+
"remove everything from that directory."
|
|
77
|
+
)
|
|
78
|
+
_logger.debug(f"Remaining elements ({len(items)}): {items}")
|
|
79
|
+
numba_cache_dir: Path = config.base_compiledir / "numba"
|
|
80
|
+
shutil.rmtree(numba_cache_dir, ignore_errors=True)
|
|
81
|
+
|
|
82
|
+
elif sys.argv[1] == "list":
|
|
83
|
+
pytensor.compile.compiledir.print_compiledir_content()
|
|
84
|
+
elif sys.argv[1] == "cleanup":
|
|
85
|
+
pytensor.compile.compiledir.cleanup()
|
|
86
|
+
cache = get_module_cache(init_args=dict(do_refresh=False))
|
|
87
|
+
cache.clear_old()
|
|
88
|
+
elif sys.argv[1] == "unlock":
|
|
89
|
+
pytensor.compile.compilelock.force_unlock(config.compiledir)
|
|
90
|
+
print("Lock successfully removed!")
|
|
91
|
+
elif sys.argv[1] == "purge":
|
|
92
|
+
pytensor.compile.compiledir.compiledir_purge()
|
|
93
|
+
numba_cache_dir: Path = config.base_compiledir / "numba"
|
|
94
|
+
shutil.rmtree(numba_cache_dir, ignore_errors=True)
|
|
95
|
+
elif sys.argv[1] == "basecompiledir":
|
|
96
|
+
# Simply print the base_compiledir
|
|
97
|
+
print(pytensor.config.base_compiledir)
|
|
98
|
+
else:
|
|
99
|
+
print_help(exit_status=1)
|
|
100
|
+
elif len(sys.argv) == 3 and sys.argv[1] == "basecompiledir":
|
|
101
|
+
if sys.argv[2] == "list":
|
|
102
|
+
pytensor.compile.compiledir.basecompiledir_ls()
|
|
103
|
+
elif sys.argv[2] == "purge":
|
|
104
|
+
pytensor.compile.compiledir.basecompiledir_purge()
|
|
105
|
+
else:
|
|
106
|
+
print_help(exit_status=1)
|
|
107
|
+
else:
|
|
108
|
+
print_help(exit_status=1)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
if __name__ == "__main__":
|
|
112
|
+
main()
|
pytensor/breakpoint.py
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pytensor.gradient import DisconnectedType
|
|
4
|
+
from pytensor.graph.basic import Apply, Variable
|
|
5
|
+
from pytensor.graph.op import Op
|
|
6
|
+
from pytensor.tensor.basic import as_tensor_variable
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class PdbBreakpoint(Op):
|
|
10
|
+
"""
|
|
11
|
+
This is an identity-like op with the side effect of enforcing a
|
|
12
|
+
conditional breakpoint, inside an PyTensor function, based on a symbolic
|
|
13
|
+
scalar condition. It automatically detects available debuggers and uses
|
|
14
|
+
the first available in the following order: `pudb`, `ipdb`, or `pdb`.
|
|
15
|
+
|
|
16
|
+
:type name: String
|
|
17
|
+
:param name: name of the conditional breakpoint. To be printed when the
|
|
18
|
+
breakpoint is activated.
|
|
19
|
+
|
|
20
|
+
:note: WARNING. At least one of the outputs of the op must be used
|
|
21
|
+
otherwise the op will be removed from the PyTensor graph
|
|
22
|
+
due to its outputs being unused
|
|
23
|
+
|
|
24
|
+
:note: WARNING. Employing the function inside an PyTensor graph can prevent
|
|
25
|
+
PyTensor from applying certain optimizations to improve
|
|
26
|
+
performance, reduce memory consumption and/or reduce
|
|
27
|
+
numerical instability.
|
|
28
|
+
|
|
29
|
+
Detailed explanation:
|
|
30
|
+
As of 2014-12-01 the PdbBreakpoint op is not known by any
|
|
31
|
+
optimization. Setting a PdbBreakpoint op in the middle of a
|
|
32
|
+
pattern that is usually optimized out will block the optimization.
|
|
33
|
+
|
|
34
|
+
Example:
|
|
35
|
+
|
|
36
|
+
.. code-block:: python
|
|
37
|
+
|
|
38
|
+
import pytensor
|
|
39
|
+
import pytensor.tensor as pt
|
|
40
|
+
from pytensor.breakpoint import PdbBreakpoint
|
|
41
|
+
|
|
42
|
+
input = pt.fvector()
|
|
43
|
+
target = pt.fvector()
|
|
44
|
+
|
|
45
|
+
# Mean squared error between input and target
|
|
46
|
+
mse = (input - target) ** 2
|
|
47
|
+
|
|
48
|
+
# Conditional breakpoint to be activated if the total MSE is higher
|
|
49
|
+
# than 100. The breakpoint will monitor the inputs, targets as well
|
|
50
|
+
# as the individual error values
|
|
51
|
+
breakpointOp = PdbBreakpoint("MSE too high")
|
|
52
|
+
condition = pt.gt(mse.sum(), 100)
|
|
53
|
+
mse, monitored_input, monitored_target = breakpointOp(condition, mse,
|
|
54
|
+
input, target)
|
|
55
|
+
|
|
56
|
+
# Compile the pytensor function
|
|
57
|
+
fct = pytensor.function([input, target], mse)
|
|
58
|
+
|
|
59
|
+
# Use the function
|
|
60
|
+
print fct([10, 0], [10, 5]) # Will NOT activate the breakpoint
|
|
61
|
+
print fct([0, 0], [10, 5]) # Will activate the breakpoint
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
__props__ = ("name",)
|
|
67
|
+
|
|
68
|
+
def __init__(self, name):
|
|
69
|
+
self.name = name
|
|
70
|
+
|
|
71
|
+
def make_node(self, condition, *monitored_vars):
|
|
72
|
+
# Ensure that condition is an PyTensor tensor
|
|
73
|
+
if not isinstance(condition, Variable):
|
|
74
|
+
condition = as_tensor_variable(condition)
|
|
75
|
+
|
|
76
|
+
# Validate that the condition is a scalar (else it is not obvious how
|
|
77
|
+
# is should be evaluated)
|
|
78
|
+
assert condition.ndim == 0
|
|
79
|
+
|
|
80
|
+
# Because the user might be tempted to instantiate PdbBreakpoint only
|
|
81
|
+
# once and apply it many times on different number of inputs, we must
|
|
82
|
+
# create a new instance of the op here, define the instance attributes
|
|
83
|
+
# (view_map and var_types) in that instance and then apply it on the
|
|
84
|
+
# inputs.
|
|
85
|
+
new_op = PdbBreakpoint(name=self.name)
|
|
86
|
+
new_op.view_map = {}
|
|
87
|
+
new_op.inp_types = []
|
|
88
|
+
for i in range(len(monitored_vars)):
|
|
89
|
+
# Every output i is a view of the input i+1 because of the input
|
|
90
|
+
# condition.
|
|
91
|
+
new_op.view_map[i] = [i + 1]
|
|
92
|
+
new_op.inp_types.append(monitored_vars[i].type)
|
|
93
|
+
|
|
94
|
+
# Build the Apply node
|
|
95
|
+
inputs = [condition, *monitored_vars]
|
|
96
|
+
outputs = [inp.type() for inp in monitored_vars]
|
|
97
|
+
return Apply(op=new_op, inputs=inputs, outputs=outputs)
|
|
98
|
+
|
|
99
|
+
def perform(self, node, inputs, output_storage):
|
|
100
|
+
condition = inputs[0]
|
|
101
|
+
|
|
102
|
+
if condition:
|
|
103
|
+
try:
|
|
104
|
+
monitored = [np.asarray(inp) for inp in inputs[1:]]
|
|
105
|
+
except Exception:
|
|
106
|
+
raise ValueError(
|
|
107
|
+
"Some of the inputs to the PdbBreakpoint op "
|
|
108
|
+
f"'{self.name}' could not be casted to NumPy arrays"
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
print("\n") # noqa: T201
|
|
112
|
+
print("-------------------------------------------------") # noqa: T201
|
|
113
|
+
print(f"Conditional breakpoint '{self.name}' activated\n") # noqa: T201
|
|
114
|
+
print("The monitored variables are stored, in order,") # noqa: T201
|
|
115
|
+
print("in the list variable 'monitored' as NumPy arrays.\n") # noqa: T201
|
|
116
|
+
print("Their contents can be altered and, when execution") # noqa: T201
|
|
117
|
+
print("resumes, the updated values will be used.") # noqa: T201
|
|
118
|
+
print("-------------------------------------------------") # noqa: T201
|
|
119
|
+
|
|
120
|
+
try:
|
|
121
|
+
import pudb
|
|
122
|
+
|
|
123
|
+
pudb.set_trace()
|
|
124
|
+
except ImportError:
|
|
125
|
+
try:
|
|
126
|
+
import ipdb
|
|
127
|
+
|
|
128
|
+
ipdb.set_trace()
|
|
129
|
+
except ImportError:
|
|
130
|
+
import pdb
|
|
131
|
+
|
|
132
|
+
pdb.set_trace()
|
|
133
|
+
|
|
134
|
+
# Take the new values in monitored, cast them back to their
|
|
135
|
+
# original type and store them in the output_storage
|
|
136
|
+
for i in range(len(output_storage)):
|
|
137
|
+
output_storage[i][0] = self.inp_types[i].filter(monitored[i])
|
|
138
|
+
|
|
139
|
+
else:
|
|
140
|
+
# Simply return views on the monitored variables
|
|
141
|
+
for i in range(len(output_storage)):
|
|
142
|
+
output_storage[i][0] = inputs[i + 1]
|
|
143
|
+
|
|
144
|
+
def grad(self, inputs, output_gradients):
|
|
145
|
+
return [DisconnectedType()(), *output_gradients]
|
|
146
|
+
|
|
147
|
+
def infer_shape(self, fgraph, inputs, input_shapes):
|
|
148
|
+
# Return the shape of every input but the condition (first input)
|
|
149
|
+
return input_shapes[1:]
|
|
150
|
+
|
|
151
|
+
def connection_pattern(self, node):
|
|
152
|
+
nb_inp = len(node.inputs)
|
|
153
|
+
nb_out = nb_inp - 1
|
|
154
|
+
|
|
155
|
+
# First input is connected to no output and every other input n is
|
|
156
|
+
# connected to input n-1
|
|
157
|
+
connections = [
|
|
158
|
+
[out_idx == inp_idx - 1 for out_idx in range(nb_out)]
|
|
159
|
+
for inp_idx in range(nb_inp)
|
|
160
|
+
]
|
|
161
|
+
return connections
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from pytensor.compile.function.pfunc import pfunc, rebuild_collect_shared
|
|
2
|
+
from pytensor.compile.function.types import (
|
|
3
|
+
AliasedMemoryError,
|
|
4
|
+
Function,
|
|
5
|
+
FunctionMaker,
|
|
6
|
+
Supervisor,
|
|
7
|
+
UnusedInputError,
|
|
8
|
+
alias_root,
|
|
9
|
+
convert_function_input,
|
|
10
|
+
fgraph_updated_vars,
|
|
11
|
+
get_info_on_inputs,
|
|
12
|
+
infer_reuse_pattern,
|
|
13
|
+
insert_deepcopy,
|
|
14
|
+
orig_function,
|
|
15
|
+
std_fgraph,
|
|
16
|
+
view_tree_set,
|
|
17
|
+
)
|
|
18
|
+
from pytensor.compile.io import In, Out, SymbolicInput, SymbolicOutput
|
|
19
|
+
from pytensor.compile.mode import (
|
|
20
|
+
CVM,
|
|
21
|
+
FAST_COMPILE,
|
|
22
|
+
JAX,
|
|
23
|
+
NUMBA,
|
|
24
|
+
OPT_FAST_COMPILE,
|
|
25
|
+
OPT_FAST_RUN,
|
|
26
|
+
OPT_FAST_RUN_STABLE,
|
|
27
|
+
OPT_MERGE,
|
|
28
|
+
OPT_NONE,
|
|
29
|
+
OPT_O2,
|
|
30
|
+
OPT_O3,
|
|
31
|
+
OPT_STABILIZE,
|
|
32
|
+
OPT_UNSAFE,
|
|
33
|
+
PYTORCH,
|
|
34
|
+
AddDestroyHandler,
|
|
35
|
+
AddFeatureOptimizer,
|
|
36
|
+
C,
|
|
37
|
+
Mode,
|
|
38
|
+
PrintCurrentFunctionGraph,
|
|
39
|
+
get_default_mode,
|
|
40
|
+
get_mode,
|
|
41
|
+
local_useless,
|
|
42
|
+
optdb,
|
|
43
|
+
predefined_linkers,
|
|
44
|
+
predefined_modes,
|
|
45
|
+
predefined_optimizers,
|
|
46
|
+
register_linker,
|
|
47
|
+
register_mode,
|
|
48
|
+
register_optimizer,
|
|
49
|
+
)
|
|
50
|
+
from pytensor.compile.monitormode import MonitorMode
|
|
51
|
+
from pytensor.compile.ops import (
|
|
52
|
+
DeepCopyOp,
|
|
53
|
+
FromFunctionOp,
|
|
54
|
+
ViewOp,
|
|
55
|
+
as_op,
|
|
56
|
+
deep_copy_op,
|
|
57
|
+
register_deep_copy_op_c_code,
|
|
58
|
+
register_view_op_c_code,
|
|
59
|
+
view_op,
|
|
60
|
+
wrap_py,
|
|
61
|
+
)
|
|
62
|
+
from pytensor.compile.profiling import ProfileStats
|
|
63
|
+
from pytensor.compile.sharedvalue import SharedVariable, shared, shared_constructor
|