pytensor 3.0.3__tar.gz → 3.0.5__tar.gz
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-3.0.3/pytensor.egg-info → pytensor-3.0.5}/PKG-INFO +1 -1
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/_version.py +3 -3
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/__init__.py +4 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/core.py +8 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/diagonal.py +7 -2
- pytensor-3.0.5/pytensor/assumptions/permutation.py +80 -0
- pytensor-3.0.5/pytensor/assumptions/selection.py +133 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/specify.py +8 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/subtensor.py +14 -3
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/triangular.py +20 -9
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/debug/profiling.py +2 -1
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/executor.py +17 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/basic.py +19 -24
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/fg.py +7 -2
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/traversal.py +3 -1
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/ifelse.py +9 -20
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/blockwise.py +6 -1
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/elemwise.py +147 -24
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/constructors.py +17 -5
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/random.py +24 -14
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/shape.py +2 -2
- pytensor-3.0.5/pytensor/link/numba/dispatch/signal/conv.py +125 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/sparse/math.py +5 -3
- pytensor-3.0.5/pytensor/link/numba/dispatch/vectorize_codegen.py +1100 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scalar/basic.py +1 -2
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/rewriting/merge.py +0 -3
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/rewriting/push_out.py +0 -3
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/sparse/math.py +48 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/sparse/rewriting.py +17 -22
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/elemwise.py +11 -3
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/products.py +22 -26
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/optimize.py +3 -2
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/random/rewriting/basic.py +9 -10
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/random/rewriting/numba.py +3 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/assumptions.py +1 -1
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/basic.py +50 -60
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/blas_c.py +10 -12
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/elemwise.py +226 -64
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/extra_ops.py +0 -12
- pytensor-3.0.5/pytensor/tensor/rewriting/indexed_elemwise.py +774 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/linalg/products.py +137 -2
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/linalg/summary.py +11 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/math.py +61 -1
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/numba.py +32 -1
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/shape.py +52 -30
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/subtensor.py +104 -106
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/subtensor_lift.py +86 -102
- pytensor-3.0.5/pytensor/tensor/rewriting/uncanonicalize.py +230 -0
- {pytensor-3.0.3 → pytensor-3.0.5/pytensor.egg-info}/PKG-INFO +1 -1
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor.egg-info/SOURCES.txt +3 -0
- pytensor-3.0.3/pytensor/link/numba/dispatch/signal/conv.py +0 -71
- pytensor-3.0.3/pytensor/link/numba/dispatch/vectorize_codegen.py +0 -585
- pytensor-3.0.3/pytensor/tensor/rewriting/uncanonicalize.py +0 -234
- {pytensor-3.0.3 → pytensor-3.0.5}/LICENSE.txt +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/MANIFEST.in +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/README.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/.templates/PLACEHOLDER +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/.templates/layout.html +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/.templates/nb-badges.html +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/.templates/rendered_citation.html +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/LICENSE.txt +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/README.md +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/_drafts/benchmark_mlx_v_jax_corrected.ipynb +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/_thumbnails/autodiff/vector_jacobian_product.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/acknowledgement.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/bcast.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/bcast.svg +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/blog.md +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/conf.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/core_development_guide.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/css.inc +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/dev_start_guide.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/environment.yml +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/apply.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/apply.svg +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/apply2.svg +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/creating_a_c_op.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/creating_a_numba_jax_op.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/creating_an_op.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/ctype.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/extending_faq.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/extending_pytensor_solution_1.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/graph_rewriting.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/graphstructures.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/index.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/inplace.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/op.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/other_ops.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/pics/symbolic_graph_opt.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/pipeline.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/scan.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/tips.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/type.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/unittest.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/extending/using_params.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/faq.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/gallery/applications/normalizing_flows_in_pytensor.ipynb +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/gallery/autodiff/vector_jacobian_product.ipynb +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/gallery/introduction/pytensor_intro.ipynb +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/gallery/optimize/root.ipynb +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/gallery/page_footer.md +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/gallery/rewrites/graph_rewrites.ipynb +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/gallery/scan/scan_tutorial.ipynb +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/generate_dtype_tensor_table.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/glossary.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/images/Elman_srnn.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/images/PyTensor.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/images/PyTensor_RGB.svg +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/images/PyTensor_logo.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/images/binder.svg +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/images/blocksparse.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/images/colab.svg +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/images/github.svg +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/images/lstm.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/images/lstm_memorycell.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/images/talk2010.gif +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/images/talk2010.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/index.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/install.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/internal/how_to_release.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/internal/index.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/internal/metadocumentation.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/introduction.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/compile/debugmode.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/compile/function.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/compile/index.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/compile/io.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/compile/mode.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/compile/nanguardmode.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/compile/opfromgraph.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/compile/ops.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/compile/profilemode.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/compile/shared.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/config.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/mlp.html +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/mlp.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/mlp2.html +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/mlp2.pdf +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/mlp2.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/ofg.html +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/examples/ofg2.html +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/index.ipynb +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/index.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/index_files/index_10_0.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/index_files/index_11_0.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/index_files/index_24_0.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/d3viz/index_files/index_25_0.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/graph/features.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/graph/fgraph.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/graph/graph.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/graph/index.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/graph/op.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/graph/replace.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/graph/type.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/graph/utils.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/index.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/misc/pkl_utils.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/printing.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/scalar/index.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/scan.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/sparse/index.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/sparse/sandbox.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/basic.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/basic_opt.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/bcast.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/bcast.svg +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/elemwise.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/extra_ops.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/fft.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/functional.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/index.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/io.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/linalg.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/math_opt.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/nlinalg.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/optimize.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/plot_fft.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/random.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/slinalg.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/tensor/utils.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/typed_list.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/xtensor/index.md +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/xtensor/linalg.md +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/xtensor/math.md +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/xtensor/module_functions.md +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/xtensor/random.md +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/xtensor/signal.md +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/library/xtensor/type.md +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/links.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/optimizations.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/pylintrc +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/robots.txt +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/troubleshooting.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/adding.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/adding_solution_1.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/aliasing.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/apply.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/apply.svg +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/bcast.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/broadcasting.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/conditions.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/debug_faq.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/dlogistic.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/examples.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/faq_tutorial.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/gradients.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/index.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/loading_and_saving.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/logistic.gp +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/logistic.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/loop.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/loop_solution_1.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/modes.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/modes_solution_1.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/multi_cores.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/nan_tutorial.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/pics/d3viz.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/printing_drawing.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/prng.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/profiling.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/profiling_example.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/profiling_example_out.prof +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/shape_info.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/sparse.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/tutorial/symbolic_graphs.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/doc/user_guide.rst +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pyproject.toml +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/_sparse_lazy.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/alloc.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/blockwise.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/dimshuffle.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/dot.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/elemwise.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/orthogonal.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/positive_definite.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/reshape.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/shape.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/assumptions/symmetric.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/bin/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/bin/pytensor_cache.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/breakpoint.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/aliasing.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/builders.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/compiledir.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/compilelock.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/debug/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/debug/debugmode.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/debug/dump.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/debug/monitormode.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/debug/nanguardmode.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/io.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/maker.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/mode.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/ops.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/rebuild.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/compile/sharedvalue.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/configdefaults.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/configparser.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/d3viz/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/d3viz/css/d3viz.css +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/d3viz/d3viz.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/d3viz/formatting.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/d3viz/html/template.html +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/d3viz/js/d3viz.js +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/gradient.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/destroyhandler.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/features.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/null_type.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/op.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/replace.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/rewriting/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/rewriting/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/rewriting/db.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/rewriting/kanren.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/rewriting/unify.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/rewriting/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/type.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/graph/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/ipython.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/cmodule.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/cutils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/cvm.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/exceptions.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/interface.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/lazylinker_c.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/op.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/params_type.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/c/type.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/blas.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/blockwise.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/einsum.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/elemwise.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/linalg/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/linalg/constructors.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/linalg/decomposition.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/linalg/inverse.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/linalg/products.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/linalg/solvers.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/linalg/summary.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/math.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/pad.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/random.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/scalar.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/scan.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/shape.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/signal/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/signal/conv.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/sort.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/sparse.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/subtensor.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/linker.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/jax/ops.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/blas.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/blockwise.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/einsum.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/elemwise.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/extra_ops.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/linalg/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/linalg/decomposition.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/linalg/inverse.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/linalg/products.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/linalg/solvers.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/linalg/summary.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/math.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/pad.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/scalar.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/shape.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/signal/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/signal/conv.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/sort.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/subtensor.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/dispatch/tensor_basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/mlx/linker.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/cache.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/compile_ops.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/cython_support.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/_LAPACK.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/decomposition/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/decomposition/cholesky.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/decomposition/dispatch.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/decomposition/eigen.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/decomposition/lu.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/decomposition/lu_factor.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/decomposition/qr.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/decomposition/qz.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/decomposition/schur.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/decomposition/svd.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/inverse.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/products.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/solvers/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/solvers/cholesky.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/solvers/dispatch.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/solvers/general.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/solvers/hermitian.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/solvers/linear_control.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/solvers/lu_solve.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/solvers/posdef.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/solvers/symmetric.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/solvers/triangular.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/solvers/tridiagonal.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/solvers/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/summary.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/linalg/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/scalar.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/scan.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/signal/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/sort.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/sparse/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/sparse/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/sparse/variable.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/string_codegen.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/subtensor.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/dispatch/typed_list.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/numba/linker.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/blas.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/blockwise.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/elemwise.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/extra_ops.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/linalg/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/linalg/decomposition.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/linalg/inverse.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/linalg/products.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/linalg/summary.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/math.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/scalar.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/shape.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/sort.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/dispatch/subtensor.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/pytorch/linker.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/link/vm.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/misc/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/misc/check_blas.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/misc/check_blas_many.sh +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/misc/check_duplicate_key.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/misc/elemwise_time_test.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/misc/frozendict.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/misc/may_share_memory.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/misc/ordered_set.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/misc/pkl_utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/npy_2_compat.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/printing.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/py.typed +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/raise_op.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scalar/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scalar/c_code/gamma.c +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scalar/c_code/incbet.c +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scalar/loop.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scalar/math.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scalar/sharedvar.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/checkpoints.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/op.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/rewriting/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/rewriting/db.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/rewriting/inplace.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/rewriting/io.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/rewriting/trace.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/rewriting/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/scan_perform.pyx +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/scan_perform_ext.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/scan/views.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/sparse/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/sparse/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/sparse/linalg.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/sparse/sharedvar.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/sparse/type.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/sparse/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/sparse/variable.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/blas.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/blas_c.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/blas_headers.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/blockwise.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/c_code/dimshuffle.c +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/einsum.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/elemwise_cgen.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/exceptions.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/extra_ops.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/fft.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/fourier.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/functional.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/interpolate.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/_lazy.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/constructors.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/decomposition/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/decomposition/cholesky.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/decomposition/eigen.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/decomposition/lu.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/decomposition/qr.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/decomposition/schur.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/decomposition/svd.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/dtype_utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/inverse.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/solvers/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/solvers/core.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/solvers/general.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/solvers/linear_control.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/solvers/lstsq.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/solvers/psd.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/solvers/triangular.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/solvers/tridiagonal.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/linalg/summary.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/math.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/nlinalg.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/pad.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/random/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/random/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/random/op.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/random/rewriting/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/random/rewriting/jax.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/random/type.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/random/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/random/variable.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/reshape.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/blas.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/blockwise.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/einsum.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/jax.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/linalg/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/linalg/decomposition.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/linalg/inverse.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/linalg/solvers.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/linalg/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/ofg.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/optimize.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/reshape.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/rewriting/special.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/shape.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/sharedvar.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/signal/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/signal/conv.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/slinalg.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/sort.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/special.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/subtensor.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/symbolic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/type.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/type_other.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/var.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/variable.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/tensor/xlogx.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/typed_list/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/typed_list/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/typed_list/rewriting.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/typed_list/type.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/indexing.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/linalg.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/math.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/random/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/random/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/random/type.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/random/variable.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/reduction.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/rewriting/__init__.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/rewriting/basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/rewriting/indexing.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/rewriting/math.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/rewriting/reduction.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/rewriting/shape.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/rewriting/utils.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/rewriting/vectorization.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/shape.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/signal.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/type.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor/xtensor/vectorization.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor.egg-info/dependency_links.txt +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor.egg-info/entry_points.txt +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor.egg-info/requires.txt +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/pytensor.egg-info/top_level.txt +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/scripts/mypy-failing.txt +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/scripts/slowest_tests/update-slowest-times-issue.sh +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/setup.cfg +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/setup.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/tests/link/c/c_code/test_cenum.h +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/tests/link/c/c_code/test_quadratic_function.c +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/tests/test_basic.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/tests/test_breakpoint.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/tests/test_config.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/tests/test_gradient.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/tests/test_ifelse.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/tests/test_printing.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/tests/test_raise_op.py +0 -0
- {pytensor-3.0.3 → pytensor-3.0.5}/tests/test_rop.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2026-
|
|
11
|
+
"date": "2026-06-11T03:57:58+0200",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "3.0.
|
|
14
|
+
"full-revisionid": "3411b300d7a120e7fb58b5ad5495391ddd74e189",
|
|
15
|
+
"version": "3.0.5"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -6,8 +6,10 @@ import pytensor.assumptions.blockwise
|
|
|
6
6
|
import pytensor.assumptions.diagonal
|
|
7
7
|
import pytensor.assumptions.dimshuffle
|
|
8
8
|
import pytensor.assumptions.orthogonal
|
|
9
|
+
import pytensor.assumptions.permutation
|
|
9
10
|
import pytensor.assumptions.positive_definite
|
|
10
11
|
import pytensor.assumptions.reshape
|
|
12
|
+
import pytensor.assumptions.selection
|
|
11
13
|
import pytensor.assumptions.shape
|
|
12
14
|
import pytensor.assumptions.subtensor
|
|
13
15
|
import pytensor.assumptions.symmetric
|
|
@@ -18,7 +20,9 @@ from pytensor.assumptions.core import (
|
|
|
18
20
|
IMPLIES,
|
|
19
21
|
LOWER_TRIANGULAR,
|
|
20
22
|
ORTHOGONAL,
|
|
23
|
+
PERMUTATION,
|
|
21
24
|
POSITIVE_DEFINITE,
|
|
25
|
+
SELECTION,
|
|
22
26
|
SYMMETRIC,
|
|
23
27
|
UPPER_TRIANGULAR,
|
|
24
28
|
AssumptionFeature,
|
|
@@ -101,6 +101,8 @@ UPPER_TRIANGULAR = AssumptionKey("upper_triangular", short_name="triu")
|
|
|
101
101
|
SYMMETRIC = AssumptionKey("symmetric", short_name="sym")
|
|
102
102
|
POSITIVE_DEFINITE = AssumptionKey("positive_definite", short_name="pd")
|
|
103
103
|
ORTHOGONAL = AssumptionKey("orthogonal", short_name="orth")
|
|
104
|
+
SELECTION = AssumptionKey("selection", short_name="sel")
|
|
105
|
+
PERMUTATION = AssumptionKey("permutation", short_name="perm")
|
|
104
106
|
|
|
105
107
|
ALL_KEYS = (
|
|
106
108
|
DIAGONAL,
|
|
@@ -109,11 +111,14 @@ ALL_KEYS = (
|
|
|
109
111
|
SYMMETRIC,
|
|
110
112
|
POSITIVE_DEFINITE,
|
|
111
113
|
ORTHOGONAL,
|
|
114
|
+
SELECTION,
|
|
115
|
+
PERMUTATION,
|
|
112
116
|
)
|
|
113
117
|
|
|
114
118
|
# Implications about structural properties derivably from other structural properties
|
|
115
119
|
register_implies(DIAGONAL, LOWER_TRIANGULAR, UPPER_TRIANGULAR, SYMMETRIC)
|
|
116
120
|
register_implies(POSITIVE_DEFINITE, SYMMETRIC)
|
|
121
|
+
register_implies(PERMUTATION, SELECTION, ORTHOGONAL)
|
|
117
122
|
|
|
118
123
|
|
|
119
124
|
def register_assumption(
|
|
@@ -211,6 +216,9 @@ class AssumptionFeature(Feature):
|
|
|
211
216
|
else:
|
|
212
217
|
self.cache[(new_var, key)] = FactState.join(old_state, new_state)
|
|
213
218
|
self._var_to_keys.setdefault(new_var, set()).add(key)
|
|
219
|
+
# new_var gained a fact whose implications were cached UNKNOWN before it was
|
|
220
|
+
# known; flag it so the next get() sweep re-derives those stale entries.
|
|
221
|
+
self._stale_vars.add(new_var)
|
|
214
222
|
|
|
215
223
|
self._stale_vars.update(node.outputs)
|
|
216
224
|
|
|
@@ -49,8 +49,13 @@ def _diagonal_from_constant(var: TensorConstant) -> FactState:
|
|
|
49
49
|
if m != n:
|
|
50
50
|
result = FactState.FALSE
|
|
51
51
|
else:
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
# Off-diagonal has a nonzero iff there are more nonzeros in ``data``
|
|
53
|
+
# than on its diagonal.
|
|
54
|
+
diag = np.diagonal(data, axis1=-2, axis2=-1)
|
|
55
|
+
if np.count_nonzero(data) == np.count_nonzero(diag):
|
|
56
|
+
result = FactState.TRUE
|
|
57
|
+
else:
|
|
58
|
+
result = FactState.FALSE
|
|
54
59
|
|
|
55
60
|
var.tag.is_diagonal = result
|
|
56
61
|
return result
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pytensor.assumptions.alloc import eye_identity_rule
|
|
4
|
+
from pytensor.assumptions.core import (
|
|
5
|
+
PERMUTATION,
|
|
6
|
+
FactState,
|
|
7
|
+
all_inputs_have_key,
|
|
8
|
+
propagate_first,
|
|
9
|
+
register_assumption,
|
|
10
|
+
register_constant_inference,
|
|
11
|
+
)
|
|
12
|
+
from pytensor.assumptions.dimshuffle import left_expand_dims_propagates_matrix_property
|
|
13
|
+
from pytensor.assumptions.subtensor import subtensor_propagates_matrix_property
|
|
14
|
+
from pytensor.tensor.basic import Eye
|
|
15
|
+
from pytensor.tensor.elemwise import DimShuffle
|
|
16
|
+
from pytensor.tensor.linalg.constructors import BlockDiagonal
|
|
17
|
+
from pytensor.tensor.linalg.inverse import MatrixInverse, MatrixPinv
|
|
18
|
+
from pytensor.tensor.linalg.products import KroneckerProduct
|
|
19
|
+
from pytensor.tensor.math import Dot
|
|
20
|
+
from pytensor.tensor.subtensor import Subtensor
|
|
21
|
+
from pytensor.tensor.variable import TensorConstant
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# A PERMUTATION matrix is a square 0/1 matrix with exactly one 1 in every row and every
|
|
25
|
+
# column -- a reordering of the identity's columns. It is a square SELECTION and is
|
|
26
|
+
# ORTHOGONAL; unlike a general selection it is closed under transpose and inverse
|
|
27
|
+
# (P.T = P^{-1} is again a permutation).
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _permutation_from_constant(var: TensorConstant) -> FactState:
|
|
31
|
+
"""Recognize a constant PERMUTATION matrix from its data, caching the scan on
|
|
32
|
+
``var.tag.is_permutation``."""
|
|
33
|
+
cached: FactState | None = getattr(var.tag, "is_permutation", None)
|
|
34
|
+
if cached is not None:
|
|
35
|
+
return cached
|
|
36
|
+
|
|
37
|
+
data = np.asarray(var.data)
|
|
38
|
+
if data.ndim < 2 or data.shape[-1] != data.shape[-2]:
|
|
39
|
+
result = FactState.FALSE
|
|
40
|
+
else:
|
|
41
|
+
with np.errstate(invalid="ignore"):
|
|
42
|
+
if not (data.sum(axis=-2) == 1).all():
|
|
43
|
+
is_permutation = False
|
|
44
|
+
elif not (data.sum(axis=-1) == 1).all():
|
|
45
|
+
is_permutation = False
|
|
46
|
+
elif data.dtype.kind in "ub":
|
|
47
|
+
is_permutation = True
|
|
48
|
+
elif data.dtype.kind == "i":
|
|
49
|
+
is_permutation = data.min(initial=0) >= 0
|
|
50
|
+
else:
|
|
51
|
+
n = data.shape[-1]
|
|
52
|
+
is_permutation = np.count_nonzero(data) == (data.size // n if n else 0)
|
|
53
|
+
result = FactState.TRUE if is_permutation else FactState.FALSE
|
|
54
|
+
|
|
55
|
+
var.tag.is_permutation = result
|
|
56
|
+
return result
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
register_constant_inference(PERMUTATION, _permutation_from_constant)
|
|
60
|
+
|
|
61
|
+
# eye(n, m, k) is a permutation iff it is the square identity -- the same condition that
|
|
62
|
+
# makes it orthogonal.
|
|
63
|
+
register_assumption(PERMUTATION, Eye)(eye_identity_rule)
|
|
64
|
+
# The symmetric group is closed under matmul and inversion.
|
|
65
|
+
register_assumption(PERMUTATION, Dot)(all_inputs_have_key)
|
|
66
|
+
register_assumption(PERMUTATION, MatrixInverse)(propagate_first)
|
|
67
|
+
register_assumption(PERMUTATION, MatrixPinv)(propagate_first)
|
|
68
|
+
register_assumption(PERMUTATION, BlockDiagonal)(all_inputs_have_key)
|
|
69
|
+
register_assumption(PERMUTATION, KroneckerProduct)(all_inputs_have_key)
|
|
70
|
+
register_assumption(PERMUTATION, Subtensor)(subtensor_propagates_matrix_property)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@register_assumption(PERMUTATION, DimShuffle)
|
|
74
|
+
def _dimshuffle(key, op, feature, fgraph, node, input_states):
|
|
75
|
+
"""Permutation survives matrix transpose (P.T = P^{-1}) and batch left-expand-dims."""
|
|
76
|
+
if input_states[0] is not FactState.TRUE:
|
|
77
|
+
return [FactState.UNKNOWN]
|
|
78
|
+
if op.is_matrix_transpose or left_expand_dims_propagates_matrix_property(op):
|
|
79
|
+
return [FactState.TRUE]
|
|
80
|
+
return [FactState.UNKNOWN]
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from pytensor.assumptions.core import (
|
|
4
|
+
SELECTION,
|
|
5
|
+
FactState,
|
|
6
|
+
all_inputs_have_key,
|
|
7
|
+
register_assumption,
|
|
8
|
+
register_constant_inference,
|
|
9
|
+
true_if,
|
|
10
|
+
)
|
|
11
|
+
from pytensor.assumptions.subtensor import subtensor_propagates_matrix_property
|
|
12
|
+
from pytensor.graph.basic import Variable
|
|
13
|
+
from pytensor.tensor.basic import Eye
|
|
14
|
+
from pytensor.tensor.linalg.constructors import BlockDiagonal
|
|
15
|
+
from pytensor.tensor.linalg.products import KroneckerProduct
|
|
16
|
+
from pytensor.tensor.subtensor import AdvancedSubtensor, Subtensor
|
|
17
|
+
from pytensor.tensor.variable import TensorConstant
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _selection_from_constant(var: TensorConstant) -> FactState:
|
|
21
|
+
"""Recognize a constant SELECTION matrix from its data, caching the O(n*k) scan on
|
|
22
|
+
``var.tag.is_selection``."""
|
|
23
|
+
cached: FactState | None = getattr(var.tag, "is_selection", None)
|
|
24
|
+
if cached is not None:
|
|
25
|
+
return cached
|
|
26
|
+
|
|
27
|
+
data = np.asarray(var.data)
|
|
28
|
+
if data.ndim < 2:
|
|
29
|
+
result = FactState.FALSE
|
|
30
|
+
else:
|
|
31
|
+
with np.errstate(invalid="ignore"):
|
|
32
|
+
if not (data.sum(axis=-2) == 1).all():
|
|
33
|
+
is_selection = False
|
|
34
|
+
elif data.dtype.kind in "ub":
|
|
35
|
+
is_selection = True
|
|
36
|
+
elif data.dtype.kind == "i":
|
|
37
|
+
is_selection = data.min(initial=0) >= 0
|
|
38
|
+
else:
|
|
39
|
+
n_rows = data.shape[-2]
|
|
40
|
+
is_selection = np.count_nonzero(data) == (
|
|
41
|
+
data.size // n_rows if n_rows else 0
|
|
42
|
+
)
|
|
43
|
+
result = FactState.TRUE if is_selection else FactState.FALSE
|
|
44
|
+
|
|
45
|
+
var.tag.is_selection = result
|
|
46
|
+
return result
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
register_constant_inference(SELECTION, _selection_from_constant)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def column_selection_index(op, node) -> Variable | None:
|
|
53
|
+
"""Return the 1-D integer index of an ``x[..., idx]`` advanced subtensor, or ``None``.
|
|
54
|
+
|
|
55
|
+
Matches every axis but the last a full slice, the last an integer vector. Selecting
|
|
56
|
+
columns preserves selection for any ``idx``; selecting rows does not, so only this
|
|
57
|
+
pattern is recognized.
|
|
58
|
+
"""
|
|
59
|
+
x = node.inputs[0]
|
|
60
|
+
ndim = x.type.ndim
|
|
61
|
+
idx_list = op.idx_list
|
|
62
|
+
if ndim < 2 or len(idx_list) != ndim:
|
|
63
|
+
return None
|
|
64
|
+
|
|
65
|
+
full = slice(None, None, None)
|
|
66
|
+
if any(entry != full for entry in idx_list[:-1]):
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
last = idx_list[-1]
|
|
70
|
+
if not isinstance(last, int) or isinstance(last, bool):
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
index_var: Variable = node.inputs[1:][last]
|
|
74
|
+
if index_var.type.ndim != 1 or not index_var.type.dtype.startswith(("int", "uint")):
|
|
75
|
+
return None
|
|
76
|
+
return index_var
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@register_assumption(SELECTION, Eye)
|
|
80
|
+
def _eye(key, op, feature, fgraph, node, input_states):
|
|
81
|
+
"""``eye(n, m, k)`` is a selection iff ``k == 0`` (main diagonal) and ``n >= m``
|
|
82
|
+
(no trailing zero columns)."""
|
|
83
|
+
n, m, k = node.inputs
|
|
84
|
+
if not isinstance(k, TensorConstant):
|
|
85
|
+
return [FactState.UNKNOWN]
|
|
86
|
+
if k.data.item() != 0:
|
|
87
|
+
return [FactState.FALSE]
|
|
88
|
+
if n is m:
|
|
89
|
+
return [FactState.TRUE]
|
|
90
|
+
if isinstance(n, TensorConstant) and isinstance(m, TensorConstant):
|
|
91
|
+
return true_if(n.data.item() >= m.data.item(), else_false=True)
|
|
92
|
+
rows, cols = node.outputs[0].type.shape[-2:]
|
|
93
|
+
if rows is not None and cols is not None:
|
|
94
|
+
return true_if(rows >= cols, else_false=True)
|
|
95
|
+
return [FactState.UNKNOWN]
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
register_assumption(SELECTION, BlockDiagonal)(all_inputs_have_key)
|
|
99
|
+
register_assumption(SELECTION, KroneckerProduct)(all_inputs_have_key)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@register_assumption(SELECTION, AdvancedSubtensor)
|
|
103
|
+
def _advanced_subtensor(key, op, feature, fgraph, node, input_states):
|
|
104
|
+
if (
|
|
105
|
+
input_states[0] is FactState.TRUE
|
|
106
|
+
and column_selection_index(op, node) is not None
|
|
107
|
+
):
|
|
108
|
+
return [FactState.TRUE]
|
|
109
|
+
return [FactState.UNKNOWN]
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@register_assumption(SELECTION, Subtensor)
|
|
113
|
+
def _subtensor(key, op, feature, fgraph, node, input_states):
|
|
114
|
+
# Batch-axis indexing (trailing two axes untouched) keeps every per-matrix property.
|
|
115
|
+
states = subtensor_propagates_matrix_property(
|
|
116
|
+
key, op, feature, fgraph, node, input_states
|
|
117
|
+
)
|
|
118
|
+
if states[0] is FactState.TRUE:
|
|
119
|
+
return states
|
|
120
|
+
|
|
121
|
+
# A column slice keeps a subset of the one-hot columns -- still a selection.
|
|
122
|
+
if input_states[0] is FactState.TRUE:
|
|
123
|
+
x = node.inputs[0]
|
|
124
|
+
idx_list = op.idx_list
|
|
125
|
+
full = slice(None, None, None)
|
|
126
|
+
if (
|
|
127
|
+
2 <= x.type.ndim == len(idx_list)
|
|
128
|
+
and all(entry == full for entry in idx_list[:-1])
|
|
129
|
+
and isinstance(idx_list[-1], slice)
|
|
130
|
+
):
|
|
131
|
+
return [FactState.TRUE]
|
|
132
|
+
|
|
133
|
+
return [FactState.UNKNOWN]
|
|
@@ -67,6 +67,8 @@ def assume(
|
|
|
67
67
|
symmetric: bool | None = None,
|
|
68
68
|
positive_definite: bool | None = None,
|
|
69
69
|
orthogonal: bool | None = None,
|
|
70
|
+
selection: bool | None = None,
|
|
71
|
+
permutation: bool | None = None,
|
|
70
72
|
):
|
|
71
73
|
"""Attach structural assumptions to a symbolic tensor.
|
|
72
74
|
|
|
@@ -90,6 +92,10 @@ def assume(
|
|
|
90
92
|
Assert that *x* is (or is not) positive-definite.
|
|
91
93
|
orthogonal : bool, optional
|
|
92
94
|
Assert that *x* is (or is not) orthogonal.
|
|
95
|
+
selection : bool, optional
|
|
96
|
+
Assert that *x* is (or is not) a selection matrix
|
|
97
|
+
permutation : bool, optional
|
|
98
|
+
Assert that *x* is (or is not) a permutation matrix
|
|
93
99
|
|
|
94
100
|
Returns
|
|
95
101
|
-------
|
|
@@ -113,6 +119,8 @@ def assume(
|
|
|
113
119
|
"symmetric": symmetric,
|
|
114
120
|
"positive_definite": positive_definite,
|
|
115
121
|
"orthogonal": orthogonal,
|
|
122
|
+
"selection": selection,
|
|
123
|
+
"permutation": permutation,
|
|
116
124
|
}
|
|
117
125
|
assumptions = {
|
|
118
126
|
name: FactState.TRUE if value else FactState.FALSE
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
from pytensor.assumptions.core import (
|
|
2
2
|
ALL_KEYS,
|
|
3
|
-
|
|
3
|
+
DIAGONAL,
|
|
4
|
+
LOWER_TRIANGULAR,
|
|
5
|
+
POSITIVE_DEFINITE,
|
|
6
|
+
SYMMETRIC,
|
|
7
|
+
UPPER_TRIANGULAR,
|
|
4
8
|
FactState,
|
|
5
9
|
register_assumption,
|
|
6
10
|
true_if,
|
|
@@ -46,7 +50,7 @@ def incsubtensor_propagates_matrix_property(
|
|
|
46
50
|
- ``set`` over a partial batch region: every output slice comes from ``base``
|
|
47
51
|
or ``value``, so both must carry the property.
|
|
48
52
|
- ``inc``: the written region becomes ``base + value``; the property must be
|
|
49
|
-
closed under addition
|
|
53
|
+
closed under addition (diagonal, triangular, symmetric, positive-definite).
|
|
50
54
|
|
|
51
55
|
An index that reaches into the core axes is left to the per-key rules (e.g.
|
|
52
56
|
the diagonal-position write handled by ``indexes_diagonal``).
|
|
@@ -66,7 +70,14 @@ def incsubtensor_propagates_matrix_property(
|
|
|
66
70
|
return [value_state]
|
|
67
71
|
return true_if(base_state is FactState.TRUE and value_state is FactState.TRUE)
|
|
68
72
|
|
|
69
|
-
|
|
73
|
+
# Closed under addition
|
|
74
|
+
if key not in (
|
|
75
|
+
DIAGONAL,
|
|
76
|
+
LOWER_TRIANGULAR,
|
|
77
|
+
UPPER_TRIANGULAR,
|
|
78
|
+
SYMMETRIC,
|
|
79
|
+
POSITIVE_DEFINITE,
|
|
80
|
+
):
|
|
70
81
|
return [FactState.UNKNOWN]
|
|
71
82
|
return true_if(base_state is FactState.TRUE and value_state is FactState.TRUE)
|
|
72
83
|
|
|
@@ -136,21 +136,32 @@ def _lu_upper(key, op, feature, fgraph, node, input_states):
|
|
|
136
136
|
return states
|
|
137
137
|
|
|
138
138
|
|
|
139
|
-
|
|
140
|
-
|
|
139
|
+
@register_assumption(LOWER_TRIANGULAR, DimShuffle)
|
|
140
|
+
def _lower_dimshuffle(key, op, feature, fgraph, node, input_states):
|
|
141
|
+
"""Mirror lower-triangularity through left-expand-dims and matrix transpose.
|
|
141
142
|
|
|
142
|
-
|
|
143
|
-
|
|
143
|
+
Left-expand-dims preserves the matrix exactly and transpose swaps the two
|
|
144
|
+
triangles, swapping their fact states.
|
|
144
145
|
"""
|
|
145
|
-
if
|
|
146
|
-
return [
|
|
146
|
+
if op.is_matrix_transpose:
|
|
147
|
+
return [feature.get(node.inputs[0], UPPER_TRIANGULAR)]
|
|
147
148
|
if left_expand_dims_propagates_matrix_property(op):
|
|
148
|
-
return [
|
|
149
|
+
return [input_states[0]]
|
|
149
150
|
return [FactState.UNKNOWN]
|
|
150
151
|
|
|
151
152
|
|
|
152
|
-
register_assumption(
|
|
153
|
-
|
|
153
|
+
@register_assumption(UPPER_TRIANGULAR, DimShuffle)
|
|
154
|
+
def _upper_dimshuffle(key, op, feature, fgraph, node, input_states):
|
|
155
|
+
"""Mirror upper-triangularity through left-expand-dims and matrix transpose.
|
|
156
|
+
|
|
157
|
+
Left-expand-dims preserves the matrix exactly and transpose swaps the two
|
|
158
|
+
triangles, swapping their fact states.
|
|
159
|
+
"""
|
|
160
|
+
if op.is_matrix_transpose:
|
|
161
|
+
return [feature.get(node.inputs[0], LOWER_TRIANGULAR)]
|
|
162
|
+
if left_expand_dims_propagates_matrix_property(op):
|
|
163
|
+
return [input_states[0]]
|
|
164
|
+
return [FactState.UNKNOWN]
|
|
154
165
|
|
|
155
166
|
|
|
156
167
|
@register_assumption(LOWER_TRIANGULAR, Elemwise)
|
|
@@ -15,6 +15,7 @@ import operator
|
|
|
15
15
|
import sys
|
|
16
16
|
import time
|
|
17
17
|
from collections import Counter, defaultdict
|
|
18
|
+
from collections.abc import Callable
|
|
18
19
|
from contextlib import contextmanager
|
|
19
20
|
from pathlib import Path
|
|
20
21
|
from typing import Any
|
|
@@ -172,7 +173,7 @@ def print_global_stats():
|
|
|
172
173
|
print("=" * 50, file=f)
|
|
173
174
|
|
|
174
175
|
|
|
175
|
-
_profiler_printers = []
|
|
176
|
+
_profiler_printers: list[Callable] = []
|
|
176
177
|
|
|
177
178
|
|
|
178
179
|
def register_profiler_printer(fct):
|
|
@@ -395,6 +395,23 @@ class Function:
|
|
|
395
395
|
)
|
|
396
396
|
fg_cpy.update_mapping = maker.fgraph.update_mapping
|
|
397
397
|
|
|
398
|
+
# Warn if any shared variable with a deleted update is being
|
|
399
|
+
# destroyed (mutated inplace) by a node in the copied graph.
|
|
400
|
+
# In that case the shared variable storage will still be mutated
|
|
401
|
+
# even though the update is not applied.
|
|
402
|
+
if delete_updates and hasattr(maker.fgraph, "destroyers"):
|
|
403
|
+
for in_idx in maker.fgraph.update_mapping.values():
|
|
404
|
+
input_var = maker.fgraph.inputs[in_idx]
|
|
405
|
+
for destroyer in maker.fgraph.destroyers(input_var):
|
|
406
|
+
if destroyer in memo:
|
|
407
|
+
warnings.warn(
|
|
408
|
+
f"Shared variable '{input_var.name}' will still be mutated "
|
|
409
|
+
"even though its update is being deleted, because an "
|
|
410
|
+
"operation in the graph modifies it inplace.",
|
|
411
|
+
UserWarning,
|
|
412
|
+
stacklevel=2,
|
|
413
|
+
)
|
|
414
|
+
|
|
398
415
|
# Re initialize Outs and swap update and variable in Ins
|
|
399
416
|
# By doing this, we can pass FunctionMaker.check_unused_inputs()
|
|
400
417
|
if delete_updates:
|
|
@@ -820,40 +820,35 @@ def _make_frozen_output_reduce(out: Variable):
|
|
|
820
820
|
class FrozenApply(Apply):
|
|
821
821
|
"""An immutable, globally-interned Apply node for frozen graphs.
|
|
822
822
|
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
the cached instance.
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
823
|
+
``inputs`` and ``outputs`` are tuples, so mutating them raises ``TypeError``.
|
|
824
|
+
|
|
825
|
+
Instances are interned on ``(op, inputs, output_types)``: constructing one
|
|
826
|
+
with a matching key returns the cached instance. Constant inputs are keyed
|
|
827
|
+
by ``signature()`` (so equal-valued Constants share a node). Other inputs
|
|
828
|
+
are already globally interned, so identity is enough; the key stores their
|
|
829
|
+
``id()`` rather than the variables themselves, keeping strong references out
|
|
830
|
+
of the cache so chains of ``FrozenApply`` nodes collect in a single GC pass.
|
|
831
|
+
|
|
832
|
+
``output_types`` is in the key because frozen graphs root on
|
|
833
|
+
``NominalVariable`` inputs (index and type only). Nominalizing truncates the
|
|
834
|
+
root inputs, discarding the values and subgraphs an Op may have read to
|
|
835
|
+
derive its output type (e.g. via ``infer_shape``), so ``(op, inputs)`` alone
|
|
836
|
+
no longer pins it down.
|
|
830
837
|
"""
|
|
831
838
|
|
|
832
839
|
_cache: weakref.WeakValueDictionary = weakref.WeakValueDictionary()
|
|
833
840
|
|
|
834
|
-
@staticmethod
|
|
835
|
-
def _input_to_key(inp: Variable):
|
|
836
|
-
"""Convert an input Variable to a hashable, value-based cache key element.
|
|
837
|
-
|
|
838
|
-
Non-Constants (NominalVariables, FrozenApply outputs) are already
|
|
839
|
-
globally interned, so ``id()`` is a correct identity key. Using
|
|
840
|
-
``id()`` instead of the object itself avoids strong references in
|
|
841
|
-
cache keys that would prevent GC from collecting chains of
|
|
842
|
-
FrozenApply nodes in a single pass.
|
|
843
|
-
|
|
844
|
-
Constants use their ``signature()`` for value-based deduplication.
|
|
845
|
-
"""
|
|
846
|
-
if isinstance(inp, Constant):
|
|
847
|
-
return inp.signature()
|
|
848
|
-
return id(inp)
|
|
849
|
-
|
|
850
841
|
def __new__(
|
|
851
842
|
cls,
|
|
852
843
|
op: "Op",
|
|
853
844
|
inputs: tuple[Variable, ...],
|
|
854
845
|
output_types: tuple["Type", ...],
|
|
855
846
|
):
|
|
856
|
-
cache_key = (
|
|
847
|
+
cache_key = (
|
|
848
|
+
op,
|
|
849
|
+
tuple(i.signature() if isinstance(i, Constant) else id(i) for i in inputs),
|
|
850
|
+
output_types,
|
|
851
|
+
)
|
|
857
852
|
cached = cls._cache.get(cache_key)
|
|
858
853
|
if cached is not None:
|
|
859
854
|
return cached
|
|
@@ -1074,12 +1074,17 @@ class FrozenFunctionGraph(AbstractFunctionGraph):
|
|
|
1074
1074
|
self._clients = clients
|
|
1075
1075
|
return self._clients
|
|
1076
1076
|
|
|
1077
|
-
def bind(
|
|
1077
|
+
def bind(
|
|
1078
|
+
self, replace: Sequence[Variable] | dict[Variable, Variable]
|
|
1079
|
+
) -> list[Variable]:
|
|
1078
1080
|
"""Return fresh outputs with root inputs substituted per *replace*.
|
|
1079
1081
|
|
|
1080
1082
|
Constants are reused; any non-Constant input not in *replace* raises KeyError.
|
|
1081
1083
|
"""
|
|
1082
|
-
|
|
1084
|
+
if isinstance(replace, dict):
|
|
1085
|
+
memo = replace.copy()
|
|
1086
|
+
else:
|
|
1087
|
+
memo = dict(zip(self.inputs, replace))
|
|
1083
1088
|
for node in self.toposort():
|
|
1084
1089
|
for i in node.inputs:
|
|
1085
1090
|
if i not in memo:
|
|
@@ -526,9 +526,11 @@ def walk_toposort(
|
|
|
526
526
|
|
|
527
527
|
Notes
|
|
528
528
|
-----
|
|
529
|
-
|
|
530
529
|
``deps(i)`` should behave like a pure function (no funny business with internal state).
|
|
531
530
|
|
|
531
|
+
The implementation uses identity (``is``), so items returned by ``deps``
|
|
532
|
+
must be the *same objects* as those yielded by ``graphs``.
|
|
533
|
+
|
|
532
534
|
The order of the return value list is determined by the order of nodes
|
|
533
535
|
returned by the `deps` function.
|
|
534
536
|
"""
|
|
@@ -423,21 +423,16 @@ def ifelse(
|
|
|
423
423
|
@node_rewriter([IfElse])
|
|
424
424
|
def cond_make_inplace(fgraph, node):
|
|
425
425
|
op = node.op
|
|
426
|
-
if
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
# optimization.
|
|
432
|
-
(
|
|
433
|
-
len(fgraph.apply_nodes) < 500
|
|
434
|
-
or not all(getattr(o.type, "ndim", -1) == 0 for o in node.outputs)
|
|
435
|
-
)
|
|
426
|
+
if op.as_view:
|
|
427
|
+
return False
|
|
428
|
+
# For big graph, do not make inplace scalar to speed up optimization.
|
|
429
|
+
if len(fgraph.apply_nodes) >= 500 and all(
|
|
430
|
+
getattr(o.type, "ndim", -1) == 0 for o in node.outputs
|
|
436
431
|
):
|
|
437
|
-
return
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
432
|
+
return False
|
|
433
|
+
return IfElse(n_outs=op.n_outs, as_view=True, name=op.name)(
|
|
434
|
+
*node.inputs, return_list=True
|
|
435
|
+
)
|
|
441
436
|
|
|
442
437
|
|
|
443
438
|
optdb.register(
|
|
@@ -549,8 +544,6 @@ def ifelse_lift_single_if_through_acceptable_ops(fgraph, main_node):
|
|
|
549
544
|
@node_rewriter([IfElse])
|
|
550
545
|
def cond_merge_ifs_true(fgraph, node):
|
|
551
546
|
op = node.op
|
|
552
|
-
if not isinstance(op, IfElse):
|
|
553
|
-
return False
|
|
554
547
|
t_ins = node.inputs[1:][: op.n_outs]
|
|
555
548
|
|
|
556
549
|
replace = {}
|
|
@@ -576,8 +569,6 @@ def cond_merge_ifs_true(fgraph, node):
|
|
|
576
569
|
@node_rewriter([IfElse])
|
|
577
570
|
def cond_merge_ifs_false(fgraph, node):
|
|
578
571
|
op = node.op
|
|
579
|
-
if not isinstance(op, IfElse):
|
|
580
|
-
return False
|
|
581
572
|
f_ins = node.inputs[1:][op.n_outs :]
|
|
582
573
|
|
|
583
574
|
replace = {}
|
|
@@ -656,8 +647,6 @@ class CondMerge(GraphRewriter):
|
|
|
656
647
|
def cond_remove_identical(fgraph, node):
|
|
657
648
|
op = node.op
|
|
658
649
|
|
|
659
|
-
if not isinstance(op, IfElse):
|
|
660
|
-
return False
|
|
661
650
|
aes = node.inputs[1:][: op.n_outs]
|
|
662
651
|
fs = node.inputs[1:][op.n_outs :]
|
|
663
652
|
|
|
@@ -11,6 +11,9 @@ from pytensor.link.numba.dispatch.basic import (
|
|
|
11
11
|
register_funcify_and_cache_key,
|
|
12
12
|
)
|
|
13
13
|
from pytensor.link.numba.dispatch.vectorize_codegen import (
|
|
14
|
+
NO_INDEXED_INPUTS,
|
|
15
|
+
NO_INDEXED_OUTPUTS,
|
|
16
|
+
NO_SIZE,
|
|
14
17
|
_jit_options,
|
|
15
18
|
_vectorized,
|
|
16
19
|
encode_literals,
|
|
@@ -90,7 +93,9 @@ def numba_funcify_Blockwise(op: BlockwiseWithCoreShape, node, **kwargs):
|
|
|
90
93
|
(), # constant_inputs
|
|
91
94
|
inputs,
|
|
92
95
|
tuple_core_shapes,
|
|
93
|
-
|
|
96
|
+
NO_SIZE,
|
|
97
|
+
NO_INDEXED_INPUTS,
|
|
98
|
+
NO_INDEXED_OUTPUTS,
|
|
94
99
|
)
|
|
95
100
|
|
|
96
101
|
return impl
|