pytensor 3.1.1__tar.gz → 3.1.2__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.1.1/pytensor.egg-info → pytensor-3.1.2}/PKG-INFO +1 -1
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/_version.py +3 -3
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/builders.py +3 -48
- pytensor-3.1.2/pytensor/compile/inner_function.py +84 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/mode.py +1 -1
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/elemwise.py +13 -5
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/op.py +29 -57
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/optimize.py +52 -106
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/random/rewriting/numba.py +9 -4
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/indexed_elemwise.py +119 -47
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/optimize.py +2 -2
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/subtensor.py +37 -10
- {pytensor-3.1.1 → pytensor-3.1.2/pytensor.egg-info}/PKG-INFO +1 -1
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor.egg-info/SOURCES.txt +1 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/LICENSE.txt +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/MANIFEST.in +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/README.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/.templates/PLACEHOLDER +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/.templates/layout.html +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/.templates/nb-badges.html +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/.templates/rendered_citation.html +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/LICENSE.txt +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/README.md +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/_drafts/benchmark_mlx_v_jax_corrected.ipynb +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/_thumbnails/autodiff/vector_jacobian_product.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/acknowledgement.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/bcast.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/bcast.svg +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/blog.md +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/conf.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/core_development_guide.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/css.inc +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/dev_start_guide.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/environment.yml +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/apply.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/apply.svg +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/apply2.svg +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/creating_a_c_op.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/creating_a_numba_jax_op.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/creating_an_op.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/ctype.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/extending_faq.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/extending_pytensor_solution_1.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/graph_rewriting.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/graphstructures.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/index.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/inplace.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/op.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/other_ops.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/pics/symbolic_graph_opt.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/pipeline.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/scan.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/tips.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/type.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/unittest.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/extending/using_params.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/faq.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/gallery/applications/normalizing_flows_in_pytensor.ipynb +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/gallery/applications/tiny_transformer_llm.ipynb +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/gallery/autodiff/vector_jacobian_product.ipynb +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/gallery/introduction/pytensor_intro.ipynb +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/gallery/optimize/root.ipynb +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/gallery/page_footer.md +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/gallery/rewrites/graph_rewrites.ipynb +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/gallery/scan/scan_tutorial.ipynb +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/generate_dtype_tensor_table.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/glossary.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/images/Elman_srnn.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/images/PyTensor.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/images/PyTensor_RGB.svg +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/images/PyTensor_logo.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/images/binder.svg +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/images/blocksparse.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/images/colab.svg +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/images/github.svg +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/images/lstm.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/images/lstm_memorycell.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/images/talk2010.gif +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/images/talk2010.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/index.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/install.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/internal/how_to_release.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/internal/index.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/internal/metadocumentation.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/introduction.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/compile/debugmode.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/compile/function.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/compile/index.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/compile/io.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/compile/mode.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/compile/nanguardmode.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/compile/opfromgraph.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/compile/ops.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/compile/profilemode.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/compile/shared.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/config.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/mlp.html +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/mlp.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/mlp2.html +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/mlp2.pdf +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/mlp2.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/ofg.html +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/examples/ofg2.html +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/index.ipynb +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/index.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/index_files/index_10_0.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/index_files/index_11_0.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/index_files/index_24_0.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/d3viz/index_files/index_25_0.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/graph/features.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/graph/fgraph.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/graph/graph.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/graph/index.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/graph/op.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/graph/replace.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/graph/type.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/graph/utils.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/index.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/misc/pkl_utils.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/printing.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/scalar/index.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/scan.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/sparse/index.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/sparse/sandbox.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/basic.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/basic_opt.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/bcast.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/bcast.svg +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/elemwise.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/extra_ops.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/fft.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/functional.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/index.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/io.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/linalg.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/math_opt.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/nlinalg.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/optimize.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/plot_fft.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/random.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/slinalg.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/tensor/utils.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/typed_list.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/xtensor/index.md +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/xtensor/linalg.md +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/xtensor/math.md +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/xtensor/module_functions.md +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/xtensor/random.md +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/xtensor/signal.md +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/library/xtensor/type.md +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/links.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/optimizations.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/pylintrc +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/robots.txt +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/troubleshooting.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/adding.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/adding_solution_1.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/aliasing.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/apply.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/apply.svg +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/bcast.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/broadcasting.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/conditions.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/debug_faq.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/dlogistic.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/examples.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/faq_tutorial.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/gradients.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/index.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/loading_and_saving.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/logistic.gp +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/logistic.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/loop.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/loop_solution_1.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/modes.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/modes_solution_1.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/multi_cores.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/nan_tutorial.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/pics/d3viz.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/printing_drawing.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/prng.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/profiling.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/profiling_example.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/profiling_example_out.prof +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/shape_info.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/sparse.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/tutorial/symbolic_graphs.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/doc/user_guide.rst +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pyproject.toml +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/_sparse_lazy.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/alloc.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/blockwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/core.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/diagonal.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/dimshuffle.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/dot.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/elemwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/orthogonal.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/permutation.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/positive_definite.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/reshape.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/selection.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/shape.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/specify.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/subtensor.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/symmetric.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/assumptions/triangular.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/bin/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/bin/pytensor_cache.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/breakpoint.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/aliasing.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/compiledir.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/compilelock.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/debug/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/debug/debugmode.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/debug/dump.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/debug/monitormode.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/debug/nanguardmode.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/debug/profiling.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/executor.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/io.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/maker.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/ops.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/rebuild.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/rewriting.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/compile/sharedvalue.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/configdefaults.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/configparser.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/d3viz/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/d3viz/css/d3viz.css +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/d3viz/d3viz.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/d3viz/formatting.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/d3viz/html/template.html +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/d3viz/js/d3viz.js +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/gradient.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/destroyhandler.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/features.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/fg.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/null_type.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/op.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/replace.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/rewriting/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/rewriting/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/rewriting/db.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/rewriting/kanren.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/rewriting/reachability.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/rewriting/unify.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/rewriting/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/traversal.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/type.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/graph/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/ifelse.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/ipython.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/cmodule.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/cutils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/cvm.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/exceptions.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/interface.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/lazylinker_c.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/op.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/params_type.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/c/type.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/blas.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/blockwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/einsum.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/elemwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/linalg/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/linalg/constructors.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/linalg/decomposition.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/linalg/inverse.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/linalg/products.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/linalg/solvers.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/linalg/summary.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/math.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/pad.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/random.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/scalar.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/scan.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/shape.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/signal/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/signal/conv.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/sort.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/sparse.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/subtensor.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/linker.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/jax/ops.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/blas.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/blockwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/einsum.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/elemwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/extra_ops.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/linalg/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/linalg/decomposition.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/linalg/inverse.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/linalg/products.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/linalg/solvers.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/linalg/summary.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/math.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/pad.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/scalar.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/shape.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/signal/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/signal/conv.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/sort.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/subtensor.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/dispatch/tensor_basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/mlx/linker.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/cache.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/blockwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/compile_ops.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/cython_support.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/_LAPACK.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/constructors.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/decomposition/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/decomposition/cholesky.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/decomposition/dispatch.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/decomposition/eigen.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/decomposition/lu.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/decomposition/lu_factor.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/decomposition/qr.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/decomposition/qz.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/decomposition/schur.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/decomposition/svd.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/inverse.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/products.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/solvers/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/solvers/cholesky.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/solvers/dispatch.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/solvers/general.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/solvers/hermitian.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/solvers/linear_control.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/solvers/lu_solve.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/solvers/posdef.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/solvers/symmetric.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/solvers/triangular.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/solvers/tridiagonal.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/solvers/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/summary.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/linalg/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/random.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/scalar.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/scan.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/shape.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/signal/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/signal/conv.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/sort.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/sparse/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/sparse/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/sparse/math.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/sparse/variable.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/string_codegen.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/subtensor.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/typed_list.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/dispatch/vectorize_codegen.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/numba/linker.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/blas.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/blockwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/elemwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/extra_ops.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/linalg/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/linalg/decomposition.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/linalg/inverse.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/linalg/products.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/linalg/summary.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/math.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/scalar.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/shape.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/sort.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/dispatch/subtensor.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/pytorch/linker.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/link/vm.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/misc/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/misc/check_blas.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/misc/check_blas_many.sh +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/misc/check_duplicate_key.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/misc/elemwise_time_test.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/misc/frozendict.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/misc/may_share_memory.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/misc/ordered_set.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/misc/pkl_utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/npy_2_compat.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/printing.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/py.typed +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/raise_op.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scalar/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scalar/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scalar/c_code/gamma.c +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scalar/c_code/incbet.c +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scalar/loop.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scalar/math.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scalar/sharedvar.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/checkpoints.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/rewriting/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/rewriting/db.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/rewriting/inner_graph.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/rewriting/inplace.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/rewriting/io.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/rewriting/merge.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/rewriting/push_out.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/rewriting/trace.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/rewriting/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/scan_perform.pyx +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/scan_perform_ext.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/scan/views.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/sparse/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/sparse/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/sparse/linalg.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/sparse/math.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/sparse/rewriting.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/sparse/sharedvar.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/sparse/type.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/sparse/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/sparse/variable.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blas/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blas/_core.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blas/batched.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blas/blas_c.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blas/c_code/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blas/c_code/alt_blas_common.h +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blas/c_code/alt_blas_template.c +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blas/c_code/blas_headers.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blas/c_code/codegen.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blas/gemm.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blas/gemv.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blas/ger.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/blockwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/c_code/dimshuffle.c +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/einsum.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/elemwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/elemwise_cgen.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/exceptions.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/extra_ops.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/fft.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/fourier.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/functional.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/interpolate.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/_lazy.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/constructors.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/decomposition/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/decomposition/cholesky.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/decomposition/eigen.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/decomposition/lu.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/decomposition/qr.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/decomposition/schur.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/decomposition/svd.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/dtype_utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/inverse.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/products.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/solvers/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/solvers/core.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/solvers/general.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/solvers/linear_control.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/solvers/lstsq.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/solvers/psd.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/solvers/triangular.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/solvers/tridiagonal.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/linalg/summary.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/math.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/nlinalg.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/pad.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/random/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/random/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/random/op.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/random/rewriting/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/random/rewriting/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/random/rewriting/jax.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/random/type.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/random/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/random/variable.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/reshape.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/assumptions.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/blas.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/blas_c.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/blockwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/einsum.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/elemwise.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/extra_ops.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/jax.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/linalg/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/linalg/decomposition.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/linalg/inverse.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/linalg/products.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/linalg/solvers.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/linalg/summary.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/linalg/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/math.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/numba.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/ofg.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/reshape.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/shape.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/special.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/subtensor_lift.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/shape.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/sharedvar.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/signal/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/signal/conv.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/slinalg.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/sort.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/special.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/subtensor.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/symbolic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/type.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/type_other.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/var.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/variable.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/tensor/xlogx.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/typed_list/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/typed_list/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/typed_list/rewriting.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/typed_list/type.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/indexing.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/linalg.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/math.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/random/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/random/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/random/type.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/random/variable.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/reduction.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/rewriting/__init__.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/rewriting/basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/rewriting/indexing.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/rewriting/math.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/rewriting/reduction.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/rewriting/shape.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/rewriting/utils.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/rewriting/vectorization.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/shape.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/signal.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/type.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor/xtensor/vectorization.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor.egg-info/dependency_links.txt +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor.egg-info/entry_points.txt +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor.egg-info/requires.txt +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/pytensor.egg-info/top_level.txt +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/scripts/mypy-failing.txt +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/scripts/slowest_tests/update-slowest-times-issue.sh +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/setup.cfg +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/setup.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/tests/link/c/c_code/test_cenum.h +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/tests/link/c/c_code/test_quadratic_function.c +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/tests/test_basic.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/tests/test_breakpoint.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/tests/test_config.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/tests/test_gradient.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/tests/test_ifelse.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/tests/test_printing.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/tests/test_raise_op.py +0 -0
- {pytensor-3.1.1 → pytensor-3.1.2}/tests/test_rop.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2026-07-
|
|
11
|
+
"date": "2026-07-06T16:55:07+0200",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "3.1.
|
|
14
|
+
"full-revisionid": "47d3d0e3721d0488734b84051da78031081c7dc2",
|
|
15
|
+
"version": "3.1.2"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -8,8 +8,7 @@ from collections.abc import Callable, Sequence
|
|
|
8
8
|
from copy import copy
|
|
9
9
|
from functools import partial
|
|
10
10
|
|
|
11
|
-
from pytensor.compile.
|
|
12
|
-
from pytensor.compile.mode import get_mode
|
|
11
|
+
from pytensor.compile.inner_function import HasInnerFunction
|
|
13
12
|
from pytensor.compile.sharedvalue import SharedVariable
|
|
14
13
|
from pytensor.gradient import DisconnectedType, disconnected_type, grad, pushforward
|
|
15
14
|
from pytensor.graph.basic import (
|
|
@@ -20,7 +19,7 @@ from pytensor.graph.basic import (
|
|
|
20
19
|
)
|
|
21
20
|
from pytensor.graph.fg import FrozenFunctionGraph, FunctionGraph
|
|
22
21
|
from pytensor.graph.null_type import NullType
|
|
23
|
-
from pytensor.graph.op import
|
|
22
|
+
from pytensor.graph.op import Op, io_connection_pattern
|
|
24
23
|
from pytensor.graph.replace import clone_replace
|
|
25
24
|
from pytensor.graph.traversal import graph_inputs
|
|
26
25
|
from pytensor.graph.utils import MissingInputError
|
|
@@ -114,7 +113,7 @@ def construct_nominal_fgraph(
|
|
|
114
113
|
return fgraph
|
|
115
114
|
|
|
116
115
|
|
|
117
|
-
class OpFromGraph(
|
|
116
|
+
class OpFromGraph(HasInnerFunction, Op):
|
|
118
117
|
r"""Create an Op from inputs and outputs lists of variables.
|
|
119
118
|
|
|
120
119
|
The signature is similar to :func:`pytensor.function` and the resulting Op's perform will do
|
|
@@ -840,50 +839,6 @@ class OpFromGraph(Op, HasInnerGraph):
|
|
|
840
839
|
|
|
841
840
|
return ret
|
|
842
841
|
|
|
843
|
-
@property
|
|
844
|
-
def fn(self):
|
|
845
|
-
"""Lazily compile the inner function graph."""
|
|
846
|
-
if getattr(self, "_fn", None) is not None:
|
|
847
|
-
return self._fn
|
|
848
|
-
|
|
849
|
-
# ``op.fgraph`` is already backend-optimized (inplace included): the
|
|
850
|
-
# ``ofg_inner_graph`` rewrite ran the backend optimizer on it during the
|
|
851
|
-
# outer compile. So we only need to link it. The linker forces
|
|
852
|
-
# ``minimum_compile`` back in via its ``required_rewrites``, and (for an
|
|
853
|
-
# inner graph) ``minimum_compile`` *is* that inner-graph rewrite -- so we
|
|
854
|
-
# exclude ``compile_inner_graph`` to stop it re-baking an already-baked
|
|
855
|
-
# graph. ``prepare_fgraph`` still inserts the boundary deepcopies; passing
|
|
856
|
-
# ``fgraph=`` avoids a re-clone. Unused inputs (e.g. rng, size) and
|
|
857
|
-
# internal-only inplace ops are expected and tolerated.
|
|
858
|
-
mode = (
|
|
859
|
-
get_mode(None)
|
|
860
|
-
.clone(optimizer="minimum_compile")
|
|
861
|
-
.excluding("compile_inner_graph")
|
|
862
|
-
)
|
|
863
|
-
unfrozen_fgraph = self.fgraph.unfreeze()
|
|
864
|
-
self._fn = mode.function_maker(
|
|
865
|
-
[In(inp, borrow=True) for inp in unfrozen_fgraph.inputs],
|
|
866
|
-
[Out(out, borrow=True) for out in unfrozen_fgraph.outputs],
|
|
867
|
-
mode,
|
|
868
|
-
fgraph=unfrozen_fgraph,
|
|
869
|
-
accept_inplace=True,
|
|
870
|
-
on_unused_input="ignore",
|
|
871
|
-
).create()
|
|
872
|
-
self._fn.trust_input = True
|
|
873
|
-
|
|
874
|
-
return self._fn
|
|
875
|
-
|
|
876
|
-
@property
|
|
877
|
-
def inner_inputs(self):
|
|
878
|
-
# A list (not the frozen tuple) so callers that concatenate inner
|
|
879
|
-
# inputs/outputs keep list semantics. Read-only views of the immutable
|
|
880
|
-
# graph; manipulating them requires a fresh/unfrozen graph.
|
|
881
|
-
return list(self.fgraph.inputs)
|
|
882
|
-
|
|
883
|
-
@property
|
|
884
|
-
def inner_outputs(self):
|
|
885
|
-
return list(self.fgraph.outputs)
|
|
886
|
-
|
|
887
842
|
def clone(self):
|
|
888
843
|
# The inner graph is immutable (a frozen ``FunctionGraph``), so there is
|
|
889
844
|
# nothing to deep-clone -- mirror ``Composite.clone``.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"""Shared machinery for `Op`\\s that execute a lazily linked inner function."""
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from pytensor.compile.io import In, Out
|
|
6
|
+
from pytensor.compile.mode import Mode
|
|
7
|
+
from pytensor.graph.fg import FrozenFunctionGraph, FunctionGraph
|
|
8
|
+
from pytensor.graph.op import HasInnerGraph
|
|
9
|
+
from pytensor.graph.rewriting.basic import SequentialGraphRewriter
|
|
10
|
+
from pytensor.link.basic import Linker
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from pytensor.compile.function.types import Function
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def link_only_mode(linker: str | Linker) -> Mode:
|
|
18
|
+
"""A `Mode` that links a graph without rewriting it at all.
|
|
19
|
+
|
|
20
|
+
The bare rewriter also bypasses the ``minimum_compile`` pass the linker
|
|
21
|
+
would otherwise force onto a database query.
|
|
22
|
+
"""
|
|
23
|
+
return Mode(linker, SequentialGraphRewriter())
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class HasInnerFunction(HasInnerGraph):
|
|
27
|
+
"""`HasInnerGraph` op whose ``perform`` runs a lazily linked inner function.
|
|
28
|
+
|
|
29
|
+
The frozen inner graph was already baked for the backend by the
|
|
30
|
+
``compile_inner_graph`` rewrites during the outer compile, so linking it
|
|
31
|
+
needs no further rewrites (see `link_only_mode`).
|
|
32
|
+
|
|
33
|
+
The linker never comes from the config default mode: ``perform`` only runs
|
|
34
|
+
under the py/c backend family -- JIT backends (numba/jax/...) funcify
|
|
35
|
+
``op.fgraph`` directly and never call ``perform`` -- so a JIT default must
|
|
36
|
+
not win, and the JIT inner-graph rewrites were never applied to this graph.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
_fn = None
|
|
40
|
+
fgraph: FrozenFunctionGraph
|
|
41
|
+
|
|
42
|
+
def link_mode(self, impl: str | None) -> Mode:
|
|
43
|
+
"""The `Mode` to link the inner function with, given a thunk ``impl``."""
|
|
44
|
+
return link_only_mode("cvm" if impl == "c" else "vm")
|
|
45
|
+
|
|
46
|
+
def link_fgraph(self, fgraph: FunctionGraph, mode: Mode) -> "Function":
|
|
47
|
+
"""Link an already-baked inner ``fgraph`` under ``mode``, no rewrites."""
|
|
48
|
+
fn = mode.function_maker(
|
|
49
|
+
[In(inp) for inp in fgraph.inputs],
|
|
50
|
+
[Out(out) for out in fgraph.outputs],
|
|
51
|
+
mode,
|
|
52
|
+
fgraph=fgraph,
|
|
53
|
+
accept_inplace=True,
|
|
54
|
+
on_unused_input="ignore",
|
|
55
|
+
).create()
|
|
56
|
+
fn.trust_input = True
|
|
57
|
+
return fn
|
|
58
|
+
|
|
59
|
+
def compile_fn(self, mode: Mode) -> "Function":
|
|
60
|
+
"""Build the inner function under ``mode`` (override to massage the graph)."""
|
|
61
|
+
return self.link_fgraph(self.fgraph.unfreeze(), mode)
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def fn(self) -> "Function":
|
|
65
|
+
if self._fn is None:
|
|
66
|
+
self._fn = self.compile_fn(self.link_mode(None))
|
|
67
|
+
return self._fn
|
|
68
|
+
|
|
69
|
+
def make_thunk(self, node, storage_map, compute_map, no_recycling, impl=None):
|
|
70
|
+
if self._fn is None:
|
|
71
|
+
self._fn = self.compile_fn(self.link_mode(impl))
|
|
72
|
+
return super().make_thunk(
|
|
73
|
+
node, storage_map, compute_map, no_recycling, impl=impl
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def inner_inputs(self):
|
|
78
|
+
# Read-only views of the immutable inner graph, as lists so callers
|
|
79
|
+
# that concatenate inputs/outputs keep list semantics.
|
|
80
|
+
return list(self.fgraph.inputs)
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def inner_outputs(self):
|
|
84
|
+
return list(self.fgraph.outputs)
|
|
@@ -305,7 +305,7 @@ class Mode:
|
|
|
305
305
|
def __init__(
|
|
306
306
|
self,
|
|
307
307
|
linker: str | Linker | None = None,
|
|
308
|
-
optimizer: str | RewriteDatabaseQuery = "default",
|
|
308
|
+
optimizer: str | RewriteDatabaseQuery | GraphRewriter = "default",
|
|
309
309
|
db: RewriteDatabase = None,
|
|
310
310
|
):
|
|
311
311
|
if linker is None:
|
|
@@ -122,8 +122,12 @@ def scalar_in_place_fn_IntDiv(op, idx, res, arr):
|
|
|
122
122
|
|
|
123
123
|
@scalar_in_place_fn.register(Maximum)
|
|
124
124
|
def scalar_in_place_fn_Maximum(op, idx, res, arr):
|
|
125
|
+
# `arr != arr` catches NaN, which the comparison alone would drop; once the
|
|
126
|
+
# accumulator is NaN neither clause fires again, so NaN sticks (numpy
|
|
127
|
+
# semantics, matching the C backend). For integer dtypes LLVM folds the
|
|
128
|
+
# always-false clause away.
|
|
125
129
|
return [
|
|
126
|
-
f"if {res}[{idx}] < {arr}:",
|
|
130
|
+
f"if {res}[{idx}] < {arr} or {arr} != {arr}:",
|
|
127
131
|
CODE_TOKEN.INDENT,
|
|
128
132
|
f"{res}[{idx}] = {arr}",
|
|
129
133
|
CODE_TOKEN.DEDENT,
|
|
@@ -132,8 +136,9 @@ def scalar_in_place_fn_Maximum(op, idx, res, arr):
|
|
|
132
136
|
|
|
133
137
|
@scalar_in_place_fn.register(Minimum)
|
|
134
138
|
def scalar_in_place_fn_Minimum(op, idx, res, arr):
|
|
139
|
+
# See NaN comment in scalar_in_place_fn_Maximum
|
|
135
140
|
return [
|
|
136
|
-
f"if {res}[{idx}] > {arr}:",
|
|
141
|
+
f"if {res}[{idx}] > {arr} or {arr} != {arr}:",
|
|
137
142
|
CODE_TOKEN.INDENT,
|
|
138
143
|
f"{res}[{idx}] = {arr}",
|
|
139
144
|
CODE_TOKEN.DEDENT,
|
|
@@ -369,8 +374,11 @@ def create_multiaxis_reducer(
|
|
|
369
374
|
else:
|
|
370
375
|
identity = np.iinfo(acc_dtype).min
|
|
371
376
|
|
|
372
|
-
# Make sure it has the correct dtype
|
|
373
|
-
identity
|
|
377
|
+
# Make sure it has the correct dtype. Cast through ``astype`` rather than the
|
|
378
|
+
# scalar constructor so a negative identity (``-1`` for bitwise AND) wraps
|
|
379
|
+
# into an unsigned acc_dtype like C does instead of raising: ``np.uint64(-1)``
|
|
380
|
+
# is out of range, but ``-1`` cast to uint64 is all-ones -- the AND identity.
|
|
381
|
+
identity = np.asarray(identity).astype(acc_dtype)[()]
|
|
374
382
|
|
|
375
383
|
kept_axes = [i for i in range(ndim) if i not in axes]
|
|
376
384
|
n_kept = len(kept_axes)
|
|
@@ -840,7 +848,7 @@ def numba_funcify_CAReduce(op, node, **kwargs):
|
|
|
840
848
|
)
|
|
841
849
|
careduce_fn = numba_basic.numba_njit(careduce_py_fn, boundscheck=False)
|
|
842
850
|
|
|
843
|
-
cache_version =
|
|
851
|
+
cache_version = 4
|
|
844
852
|
careduce_key = sha256(
|
|
845
853
|
str(
|
|
846
854
|
(
|
|
@@ -59,6 +59,7 @@ from pytensor import tensor as pt
|
|
|
59
59
|
from pytensor.compile.aliasing import add_supervisor_to_fgraph
|
|
60
60
|
from pytensor.compile.builders import construct_nominal_fgraph, infer_shape
|
|
61
61
|
from pytensor.compile.debug.profiling import register_profiler_printer
|
|
62
|
+
from pytensor.compile.inner_function import HasInnerFunction, link_only_mode
|
|
62
63
|
from pytensor.compile.io import In, Out
|
|
63
64
|
from pytensor.compile.mode import Mode, get_mode
|
|
64
65
|
from pytensor.configdefaults import config
|
|
@@ -76,7 +77,7 @@ from pytensor.graph.basic import (
|
|
|
76
77
|
)
|
|
77
78
|
from pytensor.graph.features import NoOutputFromInplace
|
|
78
79
|
from pytensor.graph.fg import FrozenFunctionGraph, FunctionGraph
|
|
79
|
-
from pytensor.graph.op import
|
|
80
|
+
from pytensor.graph.op import Op, io_connection_pattern
|
|
80
81
|
from pytensor.graph.replace import clone_replace
|
|
81
82
|
from pytensor.graph.traversal import graph_inputs
|
|
82
83
|
from pytensor.graph.type import HasShape
|
|
@@ -835,7 +836,7 @@ class ScanMethodsMixin:
|
|
|
835
836
|
)
|
|
836
837
|
|
|
837
838
|
|
|
838
|
-
class Scan(Op, ScanMethodsMixin
|
|
839
|
+
class Scan(HasInnerFunction, Op, ScanMethodsMixin):
|
|
839
840
|
r"""An `Op` implementing `for` and `while` loops.
|
|
840
841
|
|
|
841
842
|
This `Op` has an "inner-graph" that represents the steps performed during
|
|
@@ -1542,12 +1543,26 @@ class Scan(Op, ScanMethodsMixin, HasInnerGraph):
|
|
|
1542
1543
|
|
|
1543
1544
|
return wrapped_inputs, wrapped_outputs
|
|
1544
1545
|
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1546
|
+
def link_mode(self, impl):
|
|
1547
|
+
# ``self.mode`` is a deprecated per-op override, respected when given:
|
|
1548
|
+
# its linker is used as-is. Otherwise the default py/c rule applies,
|
|
1549
|
+
# except FAST_COMPILE forces the pure-python VM.
|
|
1550
|
+
mode = self.mode
|
|
1551
|
+
if mode in (None, "FAST_RUN"):
|
|
1552
|
+
return super().link_mode(impl)
|
|
1553
|
+
if mode == "FAST_COMPILE":
|
|
1554
|
+
return link_only_mode(VMLinker(use_cloop=False, c_thunks=False))
|
|
1555
|
+
linker = get_mode(mode).clone(link_kwargs=dict(allow_gc=self.allow_gc)).linker
|
|
1556
|
+
# Scan's python/cython perform sets preallocated MIT-MOT updates through
|
|
1557
|
+
# the VM, which only a VMLinker provides.
|
|
1558
|
+
if any(self.mitmots_preallocated) and not isinstance(linker, VMLinker):
|
|
1559
|
+
raise NotImplementedError(
|
|
1560
|
+
"Python/Cython implementation of Scan with preallocated MIT-MOT "
|
|
1561
|
+
f"outputs requires a VMLinker, got {linker}"
|
|
1562
|
+
)
|
|
1563
|
+
return link_only_mode(linker)
|
|
1550
1564
|
|
|
1565
|
+
def compile_fn(self, mode):
|
|
1551
1566
|
# Compile a throwaway copy of the (already math-optimized) inner graph.
|
|
1552
1567
|
# The canonical inner graph is immutable; linking setup (MIT-MOT update
|
|
1553
1568
|
# wrapping, supervisor) and any inplace happen on this transient.
|
|
@@ -1565,45 +1580,10 @@ class Scan(Op, ScanMethodsMixin, HasInnerGraph):
|
|
|
1565
1580
|
elif self.profile:
|
|
1566
1581
|
profile = self.profile
|
|
1567
1582
|
|
|
1568
|
-
|
|
1569
|
-
# ``scan_inner_graph`` ran the backend optimizer on it during the outer
|
|
1570
|
-
# compile. So we only need to link it (``prepare_fgraph`` still inserts the
|
|
1571
|
-
# boundary deepcopies). The linker forces ``minimum_compile`` back in via
|
|
1572
|
-
# its ``required_rewrites``, and (for an inner graph) ``minimum_compile``
|
|
1573
|
-
# *is* that inner-graph rewrite -- so we exclude ``compile_inner_graph`` to
|
|
1574
|
-
# stop it re-baking an already-baked graph. Only the linker choice depends
|
|
1575
|
-
# on ``self.mode``.
|
|
1576
|
-
mode = self.mode
|
|
1577
|
-
if mode in (None, "FAST_RUN"):
|
|
1578
|
-
mode_instance = Mode("cvm", "minimum_compile").excluding(
|
|
1579
|
-
"compile_inner_graph"
|
|
1580
|
-
)
|
|
1581
|
-
elif mode == "FAST_COMPILE":
|
|
1582
|
-
mode_instance = Mode(
|
|
1583
|
-
VMLinker(use_cloop=False, c_thunks=False), "minimum_compile"
|
|
1584
|
-
).excluding("compile_inner_graph")
|
|
1585
|
-
else:
|
|
1586
|
-
mode_instance = (
|
|
1587
|
-
get_mode(mode)
|
|
1588
|
-
.clone(
|
|
1589
|
-
optimizer="minimum_compile",
|
|
1590
|
-
link_kwargs=dict(allow_gc=self.allow_gc),
|
|
1591
|
-
message=f"{self.name or 'Scan'} sub profile",
|
|
1592
|
-
)
|
|
1593
|
-
.excluding("compile_inner_graph")
|
|
1594
|
-
)
|
|
1595
|
-
# Scan python and cython perform relies on the VM being able to set updates for preallocated MIT-MOT,
|
|
1596
|
-
# which only the VMs produced by VMLinker do
|
|
1597
|
-
if any(self.mitmots_preallocated) and not isinstance(
|
|
1598
|
-
mode_instance.linker, VMLinker
|
|
1599
|
-
):
|
|
1600
|
-
raise NotImplementedError(
|
|
1601
|
-
f"Python/Cython implementation of Scan with preallocated MIT-MOT outputs requires a VMLinker, got {mode_instance.linker}"
|
|
1602
|
-
)
|
|
1603
|
-
self._fn = mode_instance.function_maker(
|
|
1583
|
+
return mode.function_maker(
|
|
1604
1584
|
wrapped_inputs,
|
|
1605
1585
|
wrapped_outputs,
|
|
1606
|
-
mode=
|
|
1586
|
+
mode=mode,
|
|
1607
1587
|
# The (already-optimized) inner graph may carry inplace ops baked in
|
|
1608
1588
|
# by scan_inner_graph; prepare_fgraph has already attached the
|
|
1609
1589
|
# DestroyHandler + Supervisor, so accept them here.
|
|
@@ -1613,19 +1593,6 @@ class Scan(Op, ScanMethodsMixin, HasInnerGraph):
|
|
|
1613
1593
|
fgraph=inner_fgraph,
|
|
1614
1594
|
).create()
|
|
1615
1595
|
|
|
1616
|
-
return self._fn
|
|
1617
|
-
|
|
1618
|
-
@property
|
|
1619
|
-
def inner_inputs(self):
|
|
1620
|
-
# A list (not the frozen tuple) so the many ``inner_*`` slicing helpers
|
|
1621
|
-
# and their callers keep list semantics. These are read-only views of the
|
|
1622
|
-
# immutable graph; rewrites that rebuild a Scan must ``unfreeze`` first.
|
|
1623
|
-
return list(self.fgraph.inputs)
|
|
1624
|
-
|
|
1625
|
-
@property
|
|
1626
|
-
def inner_outputs(self):
|
|
1627
|
-
return list(self.fgraph.outputs)
|
|
1628
|
-
|
|
1629
1596
|
def clone(self) -> "Scan":
|
|
1630
1597
|
# The inner graph is immutable (a frozen ``FunctionGraph``), so there is
|
|
1631
1598
|
# nothing to deep-clone -- mirror ``Composite.clone``.
|
|
@@ -1686,6 +1653,11 @@ class Scan(Op, ScanMethodsMixin, HasInnerGraph):
|
|
|
1686
1653
|
# coherent
|
|
1687
1654
|
self.validate_inner_graph()
|
|
1688
1655
|
|
|
1656
|
+
# Lazily link the inner function for this thunk's backend (see
|
|
1657
|
+
# ``HasInnerFunction``); Scan drives the resulting VM itself below.
|
|
1658
|
+
if self._fn is None:
|
|
1659
|
+
self._fn = self.compile_fn(self.link_mode(impl))
|
|
1660
|
+
|
|
1689
1661
|
# Setting up all my variables in what I believe is a more Cython
|
|
1690
1662
|
# friendly form
|
|
1691
1663
|
|
|
@@ -6,15 +6,13 @@ from functools import singledispatch
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
|
|
8
8
|
import pytensor.scalar as ps
|
|
9
|
-
from pytensor.compile.
|
|
10
|
-
from pytensor.compile.mode import get_mode
|
|
9
|
+
from pytensor.compile.inner_function import HasInnerFunction
|
|
11
10
|
from pytensor.gradient import DisconnectedType, grad, jacobian
|
|
12
11
|
from pytensor.graph.basic import Apply, Constant
|
|
13
12
|
from pytensor.graph.fg import FrozenFunctionGraph, FunctionGraph
|
|
14
13
|
from pytensor.graph.null_type import NullType
|
|
15
14
|
from pytensor.graph.op import (
|
|
16
15
|
ComputeMapType,
|
|
17
|
-
HasInnerGraph,
|
|
18
16
|
Op,
|
|
19
17
|
StorageMapType,
|
|
20
18
|
io_connection_pattern,
|
|
@@ -164,7 +162,37 @@ def _find_optimization_parameters(
|
|
|
164
162
|
]
|
|
165
163
|
|
|
166
164
|
|
|
167
|
-
|
|
165
|
+
def _tensorize_scalar_parameters(
|
|
166
|
+
objective: TensorVariable, args: list[Variable]
|
|
167
|
+
) -> tuple[TensorVariable, list[Variable], list[Variable]]:
|
|
168
|
+
"""Replace ``ScalarType`` parameters with equivalent ``TensorType`` inputs.
|
|
169
|
+
|
|
170
|
+
scipy hands every value to the objective as a numpy array, and stores/forwards
|
|
171
|
+
a ``ScalarType`` value as a bare python float -- which no C thunk accepts under
|
|
172
|
+
``trust_input``. Re-expressing such a parameter as a 0-d ``TensorType`` input
|
|
173
|
+
(reconstructed inside the graph with ``scalar_from_tensor``) makes the op
|
|
174
|
+
boundary array-typed, so scipy passes a preserved 0-d ndarray. Returns the
|
|
175
|
+
rewritten objective, the inner-graph parameters, and the matching outer inputs.
|
|
176
|
+
"""
|
|
177
|
+
replacements: dict[Variable, Variable] = {}
|
|
178
|
+
inner_args: list[Variable] = []
|
|
179
|
+
outer_args: list[Variable] = []
|
|
180
|
+
for arg in args:
|
|
181
|
+
if isinstance(arg.type, ScalarType):
|
|
182
|
+
inner = tensor(name=arg.name, shape=(), dtype=arg.type.dtype)
|
|
183
|
+
replacements[arg] = scalar_from_tensor(inner)
|
|
184
|
+
inner_args.append(inner)
|
|
185
|
+
outer_args.append(tensor_from_scalar(arg))
|
|
186
|
+
else:
|
|
187
|
+
inner_args.append(arg)
|
|
188
|
+
outer_args.append(arg)
|
|
189
|
+
|
|
190
|
+
if replacements:
|
|
191
|
+
[objective] = graph_replace([objective], replacements)
|
|
192
|
+
return objective, inner_args, outer_args
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class ScipyWrapperOp(HasInnerFunction, Op):
|
|
168
196
|
"""Shared logic for scipy optimization ops.
|
|
169
197
|
|
|
170
198
|
The inner graph is held frozen (immutable) as ``self.fgraph``, so the
|
|
@@ -178,57 +206,12 @@ class ScipyWrapperOp(Op, HasInnerGraph):
|
|
|
178
206
|
# of the same type for eq/hash. Subclasses override.
|
|
179
207
|
_scipy_props: tuple[str, ...] = ()
|
|
180
208
|
|
|
181
|
-
def build_fn(self):
|
|
182
|
-
"""
|
|
183
|
-
This is overloaded because scipy converts scalar inputs to lists, changing the return type. The
|
|
184
|
-
wrapper function logic is there to handle this.
|
|
185
|
-
"""
|
|
186
|
-
fgraph = self.fgraph.unfreeze()
|
|
187
|
-
# ``optimize_inner_graph`` already baked this graph for the active backend
|
|
188
|
-
# (inplace included), exactly like ``OpFromGraph``. So we only link it --
|
|
189
|
-
# ``minimum_compile`` excluding ``compile_inner_graph`` (the rewrite that
|
|
190
|
-
# already ran); ``prepare_fgraph`` still inserts the boundary deepcopies.
|
|
191
|
-
# ``accept_inplace`` admits the baked inplace ops; backend optimization can
|
|
192
|
-
# leave a declared input unused (e.g. a folded core-shape vector), hence
|
|
193
|
-
# ``on_unused_input="ignore"``.
|
|
194
|
-
self._fn = fn = function(
|
|
195
|
-
fgraph.inputs,
|
|
196
|
-
fgraph.outputs,
|
|
197
|
-
mode=get_mode(None)
|
|
198
|
-
.clone(optimizer="minimum_compile")
|
|
199
|
-
.excluding("compile_inner_graph"),
|
|
200
|
-
accept_inplace=True,
|
|
201
|
-
trust_input=True,
|
|
202
|
-
on_unused_input="ignore",
|
|
203
|
-
)
|
|
204
|
-
|
|
205
|
-
# Do this reassignment to see the compiled graph in the dprint
|
|
206
|
-
# self.fgraph = fn.maker.fgraph
|
|
207
|
-
|
|
208
|
-
self._fn_wrapped = LRUCache1(fn)
|
|
209
|
-
|
|
210
|
-
@property
|
|
211
|
-
def fn(self):
|
|
212
|
-
if self._fn is None:
|
|
213
|
-
self.build_fn()
|
|
214
|
-
return self._fn
|
|
215
|
-
|
|
216
209
|
@property
|
|
217
210
|
def fn_wrapped(self):
|
|
218
211
|
if self._fn_wrapped is None:
|
|
219
|
-
self.
|
|
212
|
+
self._fn_wrapped = LRUCache1(self.fn)
|
|
220
213
|
return self._fn_wrapped
|
|
221
214
|
|
|
222
|
-
@property
|
|
223
|
-
def inner_inputs(self):
|
|
224
|
-
# A list (not the frozen tuple) so callers that concatenate inner
|
|
225
|
-
# inputs/outputs keep list semantics.
|
|
226
|
-
return list(self.fgraph.inputs)
|
|
227
|
-
|
|
228
|
-
@property
|
|
229
|
-
def inner_outputs(self):
|
|
230
|
-
return list(self.fgraph.outputs)
|
|
231
|
-
|
|
232
215
|
def _prop_values(self):
|
|
233
216
|
return tuple(getattr(self, name) for name in self._scipy_props)
|
|
234
217
|
|
|
@@ -280,7 +263,7 @@ class ScipyWrapperOp(Op, HasInnerGraph):
|
|
|
280
263
|
impl: str | None,
|
|
281
264
|
):
|
|
282
265
|
"""Trigger the compilation of the inner fgraph so it shows in the dprint before the first call"""
|
|
283
|
-
self.
|
|
266
|
+
self.fn
|
|
284
267
|
|
|
285
268
|
def make_node(self, *inputs):
|
|
286
269
|
assert len(inputs) == len(self.inner_inputs)
|
|
@@ -305,7 +288,7 @@ def rewrite_optimize_inner_graph(linker, op, node, inner, *, mode):
|
|
|
305
288
|
|
|
306
289
|
|
|
307
290
|
class ScipyScalarWrapperOp(ScipyWrapperOp):
|
|
308
|
-
def
|
|
291
|
+
def compile_fn(self, mode):
|
|
309
292
|
# We need to adjust the graph to work with what scipy will be passing into the inner function --
|
|
310
293
|
# always scalar array of float64 type
|
|
311
294
|
fgraph = self.fgraph.unfreeze()
|
|
@@ -315,24 +298,10 @@ class ScipyScalarWrapperOp(ScipyWrapperOp):
|
|
|
315
298
|
|
|
316
299
|
new_outputs = graph_replace(fgraph.outputs, {x: new_x})
|
|
317
300
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
self._fn = fn = function(
|
|
321
|
-
[new_root_x, *args],
|
|
322
|
-
new_outputs,
|
|
323
|
-
mode=get_mode(None)
|
|
324
|
-
.clone(optimizer="minimum_compile")
|
|
325
|
-
.excluding("compile_inner_graph"),
|
|
326
|
-
accept_inplace=True,
|
|
327
|
-
trust_input=True,
|
|
328
|
-
on_unused_input="ignore",
|
|
301
|
+
return self.link_fgraph(
|
|
302
|
+
FunctionGraph([new_root_x, *args], new_outputs, clone=False), mode
|
|
329
303
|
)
|
|
330
304
|
|
|
331
|
-
# Do this reassignment to see the compiled graph in the dprint
|
|
332
|
-
# self.fgraph = fn.maker.fgraph
|
|
333
|
-
|
|
334
|
-
self._fn_wrapped = LRUCache1(fn)
|
|
335
|
-
|
|
336
305
|
def compute_implicit_gradients(
|
|
337
306
|
self,
|
|
338
307
|
x_star: TensorVariable,
|
|
@@ -407,34 +376,21 @@ class ScipyScalarWrapperOp(ScipyWrapperOp):
|
|
|
407
376
|
|
|
408
377
|
|
|
409
378
|
class ScipyVectorWrapperOp(ScipyWrapperOp):
|
|
410
|
-
def
|
|
379
|
+
def compile_fn(self, mode):
|
|
411
380
|
# We need to adjust the graph to work with what scipy will be passing into the inner function --
|
|
412
381
|
# always a vector array with size of at least 1
|
|
413
382
|
if self.inner_inputs[0].type.shape != ():
|
|
414
|
-
return super().
|
|
383
|
+
return super().compile_fn(mode)
|
|
415
384
|
|
|
416
385
|
fgraph = self.fgraph.unfreeze()
|
|
417
386
|
x, *args = fgraph.inputs
|
|
418
387
|
new_root_x = x[None].type()
|
|
419
388
|
new_x = new_root_x.squeeze()
|
|
420
389
|
new_outputs = graph_replace(fgraph.outputs, {x: new_x})
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
self._fn = fn = function(
|
|
424
|
-
[new_root_x, *args],
|
|
425
|
-
new_outputs,
|
|
426
|
-
mode=get_mode(None)
|
|
427
|
-
.clone(optimizer="minimum_compile")
|
|
428
|
-
.excluding("compile_inner_graph"),
|
|
429
|
-
accept_inplace=True,
|
|
430
|
-
trust_input=True,
|
|
431
|
-
on_unused_input="ignore",
|
|
390
|
+
return self.link_fgraph(
|
|
391
|
+
FunctionGraph([new_root_x, *args], new_outputs, clone=False), mode
|
|
432
392
|
)
|
|
433
393
|
|
|
434
|
-
# Do this reassignment to see the compiled graph in the dprint
|
|
435
|
-
# self.fgraph = fn.maker.fgraph
|
|
436
|
-
self._fn_wrapped = LRUCache1(fn)
|
|
437
|
-
|
|
438
394
|
def compute_implicit_gradients(
|
|
439
395
|
self,
|
|
440
396
|
x_star: TensorVariable,
|
|
@@ -698,6 +654,7 @@ def minimize_scalar(
|
|
|
698
654
|
value, based on the requested convergence criteria.
|
|
699
655
|
"""
|
|
700
656
|
args = _find_optimization_parameters(objective, x)
|
|
657
|
+
objective, args, outer_args = _tensorize_scalar_parameters(objective, args)
|
|
701
658
|
|
|
702
659
|
minimize_scalar_op = MinimizeScalarOp(
|
|
703
660
|
x,
|
|
@@ -707,7 +664,7 @@ def minimize_scalar(
|
|
|
707
664
|
optimizer_kwargs=optimizer_kwargs,
|
|
708
665
|
)
|
|
709
666
|
|
|
710
|
-
solution, success = minimize_scalar_op(x, *
|
|
667
|
+
solution, success = minimize_scalar_op(x, *outer_args)
|
|
711
668
|
|
|
712
669
|
return solution, success
|
|
713
670
|
|
|
@@ -905,6 +862,7 @@ def minimize(
|
|
|
905
862
|
|
|
906
863
|
packed_input, packed_shapes, objective = pack_inputs_of_objective(objective, x)
|
|
907
864
|
args = _find_optimization_parameters(objective, packed_input)
|
|
865
|
+
objective, args, outer_args = _tensorize_scalar_parameters(objective, args)
|
|
908
866
|
|
|
909
867
|
minimize_op = MinimizeOp(
|
|
910
868
|
packed_input,
|
|
@@ -917,7 +875,7 @@ def minimize(
|
|
|
917
875
|
optimizer_kwargs=optimizer_kwargs,
|
|
918
876
|
)
|
|
919
877
|
|
|
920
|
-
solution, success = minimize_op(packed_input, *
|
|
878
|
+
solution, success = minimize_op(packed_input, *outer_args)
|
|
921
879
|
|
|
922
880
|
if packed_shapes is not None:
|
|
923
881
|
solution = unpack(solution, packed_shapes)
|
|
@@ -1065,6 +1023,7 @@ def root_scalar(
|
|
|
1065
1023
|
Boolean indicating whether the root-finding was successful. If True, the solution is a root of the equation
|
|
1066
1024
|
"""
|
|
1067
1025
|
args = _find_optimization_parameters(equation, variable)
|
|
1026
|
+
equation, args, outer_args = _tensorize_scalar_parameters(equation, args)
|
|
1068
1027
|
|
|
1069
1028
|
root_scalar_op = RootScalarOp(
|
|
1070
1029
|
variable,
|
|
@@ -1076,7 +1035,7 @@ def root_scalar(
|
|
|
1076
1035
|
optimizer_kwargs=optimizer_kwargs,
|
|
1077
1036
|
)
|
|
1078
1037
|
|
|
1079
|
-
solution, success = root_scalar_op(variable, *
|
|
1038
|
+
solution, success = root_scalar_op(variable, *outer_args)
|
|
1080
1039
|
|
|
1081
1040
|
return solution, success
|
|
1082
1041
|
|
|
@@ -1139,7 +1098,7 @@ class RootOp(ScipyVectorWrapperOp):
|
|
|
1139
1098
|
)
|
|
1140
1099
|
return f"{self.__class__.__name__}({str_args})"
|
|
1141
1100
|
|
|
1142
|
-
def
|
|
1101
|
+
def compile_fn(self, mode):
|
|
1143
1102
|
fgraph = self.fgraph.unfreeze()
|
|
1144
1103
|
variables, *args = fgraph.inputs
|
|
1145
1104
|
outputs = fgraph.outputs
|
|
@@ -1157,24 +1116,10 @@ class RootOp(ScipyVectorWrapperOp):
|
|
|
1157
1116
|
|
|
1158
1117
|
new_outputs = graph_replace(outputs, {variables: new_variables})
|
|
1159
1118
|
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
self._fn = fn = function(
|
|
1163
|
-
[new_root_variables, *args],
|
|
1164
|
-
new_outputs,
|
|
1165
|
-
mode=get_mode(None)
|
|
1166
|
-
.clone(optimizer="minimum_compile")
|
|
1167
|
-
.excluding("compile_inner_graph"),
|
|
1168
|
-
accept_inplace=True,
|
|
1169
|
-
trust_input=True,
|
|
1170
|
-
on_unused_input="ignore",
|
|
1119
|
+
return self.link_fgraph(
|
|
1120
|
+
FunctionGraph([new_root_variables, *args], new_outputs, clone=False), mode
|
|
1171
1121
|
)
|
|
1172
1122
|
|
|
1173
|
-
# Do this reassignment to see the compiled graph in the dprint
|
|
1174
|
-
# self.fgraph = fn.maker.fgraph
|
|
1175
|
-
|
|
1176
|
-
self._fn_wrapped = LRUCache1(fn)
|
|
1177
|
-
|
|
1178
1123
|
def perform(self, node, inputs, outputs):
|
|
1179
1124
|
global optimize
|
|
1180
1125
|
if optimize is None:
|
|
@@ -1260,6 +1205,7 @@ def root(
|
|
|
1260
1205
|
equations, variables
|
|
1261
1206
|
)
|
|
1262
1207
|
args = _find_optimization_parameters(equations, packed_variables)
|
|
1208
|
+
equations, args, outer_args = _tensorize_scalar_parameters(equations, args)
|
|
1263
1209
|
|
|
1264
1210
|
root_op = RootOp(
|
|
1265
1211
|
packed_variables,
|
|
@@ -1271,7 +1217,7 @@ def root(
|
|
|
1271
1217
|
use_vectorized_jac=use_vectorized_jac,
|
|
1272
1218
|
)
|
|
1273
1219
|
|
|
1274
|
-
solution, success = root_op(packed_variables, *
|
|
1220
|
+
solution, success = root_op(packed_variables, *outer_args)
|
|
1275
1221
|
if packed_shapes is not None:
|
|
1276
1222
|
solution = unpack(solution, packed_shapes)
|
|
1277
1223
|
|