pytensor 2.38.2__tar.gz → 2.38.3__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-2.38.2/pytensor.egg-info → pytensor-2.38.3}/PKG-INFO +3 -3
- {pytensor-2.38.2 → pytensor-2.38.3}/pyproject.toml +3 -2
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/_version.py +3 -3
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/cache.py +31 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/basic.py +5 -2
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/basic.py +34 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/optimize.py +88 -73
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/blockwise.py +38 -2
- {pytensor-2.38.2 → pytensor-2.38.3/pytensor.egg-info}/PKG-INFO +3 -3
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor.egg-info/requires.txt +2 -2
- {pytensor-2.38.2 → pytensor-2.38.3}/LICENSE.txt +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/MANIFEST.in +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/README.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/.templates/PLACEHOLDER +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/.templates/layout.html +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/.templates/nb-badges.html +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/.templates/rendered_citation.html +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/LICENSE.txt +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/README.md +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/_drafts/benchmark_mlx_v_jax_corrected.ipynb +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/_thumbnails/autodiff/vector_jacobian_product.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/acknowledgement.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/bcast.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/bcast.svg +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/blog.md +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/conf.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/core_development_guide.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/css.inc +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/dev_start_guide.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/environment.yml +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/apply.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/apply.svg +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/apply2.svg +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/creating_a_c_op.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/creating_a_numba_jax_op.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/creating_an_op.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/ctype.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/extending_faq.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/extending_pytensor_solution_1.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/graph_rewriting.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/graphstructures.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/index.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/inplace.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/op.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/other_ops.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/pics/symbolic_graph_opt.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/pipeline.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/scan.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/tips.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/type.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/unittest.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/using_params.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/faq.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/applications/normalizing_flows_in_pytensor.ipynb +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/autodiff/vector_jacobian_product.ipynb +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/introduction/pytensor_intro.ipynb +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/optimize/root.ipynb +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/page_footer.md +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/rewrites/graph_rewrites.ipynb +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/scan/scan_tutorial.ipynb +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/generate_dtype_tensor_table.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/glossary.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/Elman_srnn.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/PyTensor.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/PyTensor_RGB.svg +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/PyTensor_logo.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/binder.svg +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/blocksparse.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/colab.svg +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/github.svg +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/lstm.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/lstm_memorycell.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/talk2010.gif +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/talk2010.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/index.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/install.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/internal/how_to_release.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/internal/index.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/internal/metadocumentation.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/introduction.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/debugmode.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/function.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/index.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/io.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/mode.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/nanguardmode.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/opfromgraph.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/ops.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/profilemode.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/shared.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/config.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/mlp.html +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/mlp.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/mlp2.html +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/mlp2.pdf +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/mlp2.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/ofg.html +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/ofg2.html +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/index.ipynb +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/index.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/index_files/index_10_0.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/index_files/index_11_0.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/index_files/index_24_0.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/index_files/index_25_0.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/features.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/fgraph.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/graph.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/index.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/op.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/replace.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/type.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/utils.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/index.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/misc/pkl_utils.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/printing.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/scalar/index.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/scan.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/sparse/index.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/sparse/sandbox.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/basic.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/basic_opt.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/bcast.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/bcast.svg +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/elemwise.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/extra_ops.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/fft.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/functional.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/index.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/io.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/math_opt.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/nlinalg.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/optimize.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/plot_fft.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/random/distributions.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/random/index.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/slinalg.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/utils.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/typed_list.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/index.md +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/linalg.md +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/math.md +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/module_functions.md +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/random.md +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/signal.md +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/type.md +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/links.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/optimizations.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/pylintrc +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/robots.txt +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/troubleshooting.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/adding.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/adding_solution_1.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/aliasing.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/apply.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/apply.svg +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/bcast.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/broadcasting.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/conditions.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/debug_faq.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/dlogistic.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/examples.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/faq_tutorial.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/gradients.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/index.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/loading_and_saving.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/logistic.gp +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/logistic.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/loop.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/loop_solution_1.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/modes.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/modes_solution_1.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/multi_cores.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/nan_tutorial.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/pics/d3viz.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/printing_drawing.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/prng.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/profiling.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/profiling_example.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/profiling_example_out.prof +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/shape_info.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/sparse.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/symbolic_graphs.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/doc/user_guide.rst +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/bin/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/bin/pytensor_cache.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/breakpoint.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/builders.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/compiledir.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/compilelock.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/debugmode.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/function/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/function/pfunc.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/function/types.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/io.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/mode.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/monitormode.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/nanguardmode.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/ops.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/profiling.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/sharedvalue.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/configdefaults.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/configparser.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/css/d3viz.css +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/d3viz.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/formatting.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/html/template.html +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/js/d3viz.js +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/gradient.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/destroyhandler.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/features.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/fg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/null_type.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/op.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/replace.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/rewriting/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/rewriting/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/rewriting/db.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/rewriting/kanren.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/rewriting/unify.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/rewriting/utils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/traversal.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/type.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/utils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/ifelse.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/ipython.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/cmodule.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/cutils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/cvm.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/exceptions.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/interface.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/lazylinker_c.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/op.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/params_type.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/type.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/blas.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/blockwise.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/einsum.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/elemwise.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/math.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/nlinalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/pad.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/random.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/scalar.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/scan.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/shape.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/signal/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/signal/conv.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/slinalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/sort.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/sparse.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/subtensor.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/linker.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/ops.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/blockwise.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/core.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/elemwise.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/extra_ops.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/math.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/nlinalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/shape.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/signal/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/signal/conv.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/slinalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/sort.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/subtensor.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/linker.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/blockwise.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/compile_ops.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/cython_support.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/elemwise.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/_LAPACK.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/cholesky.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/lu.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/lu_factor.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/qr.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/qz.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/schur.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/cholesky.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/general.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/linear_control.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/lu_solve.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/posdef.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/symmetric.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/triangular.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/tridiagonal.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/utils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/utils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/random.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/scalar.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/scan.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/shape.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/signal/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/signal/conv.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/slinalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/sort.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/sparse/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/sparse/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/sparse/math.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/sparse/variable.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/string_codegen.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/subtensor.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/typed_list.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/vectorize_codegen.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/linker.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/blas.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/blockwise.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/elemwise.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/extra_ops.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/math.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/nlinalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/scalar.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/shape.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/slinalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/sort.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/subtensor.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/linker.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/utils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/vm.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/check_blas.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/check_blas_many.sh +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/check_duplicate_key.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/elemwise_time_test.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/frozendict.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/may_share_memory.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/ordered_set.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/pkl_utils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/npy_2_compat.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/printing.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/py.typed +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/raise_op.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/c_code/gamma.c +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/c_code/incbet.c +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/loop.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/math.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/sharedvar.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/checkpoints.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/op.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/rewriting.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/scan_perform.pyx +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/scan_perform_ext.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/utils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/views.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/linalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/math.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/rewriting.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/sharedvar.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/type.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/utils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/variable.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/_linalg/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/_linalg/solve/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/_linalg/solve/linear_control.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/_linalg/solve/rewriting.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/_linalg/solve/tridiagonal.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/blas.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/blas_c.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/blas_headers.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/blockwise.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/c_code/dimshuffle.c +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/einsum.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/elemwise.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/elemwise_cgen.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/exceptions.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/extra_ops.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/fft.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/fourier.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/functional.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/interpolate.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/linalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/math.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/nlinalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/pad.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/op.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/rewriting/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/rewriting/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/rewriting/jax.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/rewriting/numba.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/type.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/utils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/var.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/reshape.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/blas.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/blas_c.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/einsum.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/elemwise.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/extra_ops.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/jax.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/linalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/math.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/numba.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/ofg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/reshape.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/shape.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/special.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/subtensor.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/subtensor_lift.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/shape.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/sharedvar.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/signal/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/signal/conv.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/slinalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/sort.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/special.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/subtensor.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/type.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/type_other.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/utils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/var.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/variable.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/xlogx.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/typed_list/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/typed_list/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/typed_list/rewriting.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/typed_list/type.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/updates.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/utils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/indexing.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/linalg.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/math.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/random.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/reduction.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/__init__.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/basic.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/indexing.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/math.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/reduction.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/shape.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/utils.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/vectorization.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/shape.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/signal.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/type.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/vectorization.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor.egg-info/SOURCES.txt +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor.egg-info/dependency_links.txt +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor.egg-info/entry_points.txt +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/pytensor.egg-info/top_level.txt +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/scripts/mypy-failing.txt +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/scripts/slowest_tests/update-slowest-times-issue.sh +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/setup.cfg +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/setup.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/tests/link/c/c_code/test_cenum.h +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/tests/link/c/c_code/test_quadratic_function.c +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_breakpoint.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_config.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_gradient.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_ifelse.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_printing.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_raise_op.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_rop.py +0 -0
- {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_updates.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pytensor
|
|
3
|
-
Version: 2.38.
|
|
3
|
+
Version: 2.38.3
|
|
4
4
|
Summary: Optimizing compiler for evaluating mathematical expressions on CPUs and GPUs.
|
|
5
5
|
Author-email: pymc-devs <pymc.devs@gmail.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -31,7 +31,7 @@ License-File: LICENSE.txt
|
|
|
31
31
|
Requires-Dist: setuptools>=59.0.0
|
|
32
32
|
Requires-Dist: scipy<2,>=1
|
|
33
33
|
Requires-Dist: numpy>=2.0
|
|
34
|
-
Requires-Dist: numba
|
|
34
|
+
Requires-Dist: numba<=0.65.1,>=0.58
|
|
35
35
|
Requires-Dist: filelock>=3.15
|
|
36
36
|
Requires-Dist: etuples
|
|
37
37
|
Requires-Dist: logical-unification
|
|
@@ -60,7 +60,7 @@ Provides-Extra: jax
|
|
|
60
60
|
Requires-Dist: jax; extra == "jax"
|
|
61
61
|
Requires-Dist: jaxlib; extra == "jax"
|
|
62
62
|
Provides-Extra: numba
|
|
63
|
-
Requires-Dist: numba
|
|
63
|
+
Requires-Dist: numba<=0.65.1,>=0.58; extra == "numba"
|
|
64
64
|
Requires-Dist: llvmlite; extra == "numba"
|
|
65
65
|
Dynamic: license-file
|
|
66
66
|
|
|
@@ -50,7 +50,7 @@ dependencies = [
|
|
|
50
50
|
"setuptools>=59.0.0",
|
|
51
51
|
"scipy>=1,<2",
|
|
52
52
|
"numpy>=2.0",
|
|
53
|
-
"numba
|
|
53
|
+
"numba>=0.58,<=0.65.1",
|
|
54
54
|
"filelock>=3.15",
|
|
55
55
|
"etuples",
|
|
56
56
|
"logical-unification",
|
|
@@ -81,7 +81,7 @@ tests = [
|
|
|
81
81
|
]
|
|
82
82
|
rtd = ["sphinx>=5.1.0,<6", "pygments", "pydot"]
|
|
83
83
|
jax = ["jax", "jaxlib"]
|
|
84
|
-
numba = ["numba>=0.
|
|
84
|
+
numba = ["numba>=0.58,<=0.65.1", "llvmlite"]
|
|
85
85
|
|
|
86
86
|
[tool.setuptools.packages.find]
|
|
87
87
|
include = ["pytensor*"]
|
|
@@ -158,6 +158,7 @@ lines-after-imports = 2
|
|
|
158
158
|
"pytensor/bin/pytensor_cache.py" = ["T201"]
|
|
159
159
|
"tests/compile/test_monitormode.py" = ["T201"]
|
|
160
160
|
"scripts/run_mypy.py" = ["T201"]
|
|
161
|
+
"scripts/bump_numba_upper_bound.py" = ["T201"]
|
|
161
162
|
# Test modules of optional backends that use `pytest.importorskip`, skip "E402"
|
|
162
163
|
"tests/link/jax/**/test_*.py" = ["E402"]
|
|
163
164
|
"tests/link/numba/**/test_*.py" = ["E402"]
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2026-
|
|
11
|
+
"date": "2026-04-27T13:00:34+0200",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.38.
|
|
14
|
+
"full-revisionid": "74cb66529f26343d5034adbf38e8ccd9996449fc",
|
|
15
|
+
"version": "2.38.3"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import uuid
|
|
1
2
|
from collections.abc import Callable
|
|
2
3
|
from hashlib import sha256
|
|
3
4
|
from pickle import dump
|
|
@@ -8,6 +9,7 @@ from weakref import WeakKeyDictionary
|
|
|
8
9
|
import numba
|
|
9
10
|
from llvmlite import ir
|
|
10
11
|
from numba.core import cgutils
|
|
12
|
+
from numba.core.bytecode import FunctionIdentity
|
|
11
13
|
from numba.core.caching import CacheImpl, _CacheLocator
|
|
12
14
|
|
|
13
15
|
from pytensor.configdefaults import config
|
|
@@ -18,6 +20,35 @@ NUMBA_CACHE_PATH.mkdir(parents=True, exist_ok=True)
|
|
|
18
20
|
CACHED_SRC_FUNCTIONS: WeakKeyDictionary[Callable, str] = WeakKeyDictionary()
|
|
19
21
|
|
|
20
22
|
|
|
23
|
+
class _RandomUidIter:
|
|
24
|
+
"""Iterator yielding cryptographically random 128-bit integers.
|
|
25
|
+
|
|
26
|
+
Replaces numba's default ``FunctionIdentity._unique_ids`` sequential
|
|
27
|
+
counter so that sibling forks — which inherit the counter state verbatim —
|
|
28
|
+
cannot allocate identical uids to same-qualname functions they
|
|
29
|
+
fresh-compile next. Identical uids produce byte-identical LLVM mangled
|
|
30
|
+
symbols with different bodies; a later process that loads both hits LLVM's
|
|
31
|
+
weak-merge and dispatches into the wrong body, segfaulting.
|
|
32
|
+
|
|
33
|
+
Numba only consumes ``_unique_ids`` via ``next(cls._unique_ids)`` (see
|
|
34
|
+
``numba.core.bytecode.FunctionIdentity.from_function``), so any iterator
|
|
35
|
+
of unique ints is a drop-in replacement. ``uuid.uuid4`` pulls fresh
|
|
36
|
+
entropy from the OS on every call, making this generator fork-safe
|
|
37
|
+
without any re-seed hook.
|
|
38
|
+
|
|
39
|
+
See https://github.com/numba/numba/issues/10486.
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
def __iter__(self) -> "_RandomUidIter":
|
|
43
|
+
return self
|
|
44
|
+
|
|
45
|
+
def __next__(self) -> int:
|
|
46
|
+
return uuid.uuid4().int
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
FunctionIdentity._unique_ids = _RandomUidIter()
|
|
50
|
+
|
|
51
|
+
|
|
21
52
|
class NumbaPyTensorCacheLocator(_CacheLocator):
|
|
22
53
|
"""Locator for Numba functions defined from PyTensor-generated source code.
|
|
23
54
|
|
|
@@ -13,7 +13,10 @@ from pytensor import config
|
|
|
13
13
|
from pytensor.graph.basic import Apply, Constant, Variable
|
|
14
14
|
from pytensor.graph.fg import FunctionGraph
|
|
15
15
|
from pytensor.graph.type import Type
|
|
16
|
-
from pytensor.link.numba.cache import
|
|
16
|
+
from pytensor.link.numba.cache import (
|
|
17
|
+
compile_numba_function_src,
|
|
18
|
+
hash_from_pickle_dump,
|
|
19
|
+
)
|
|
17
20
|
from pytensor.link.utils import (
|
|
18
21
|
fgraph_to_python,
|
|
19
22
|
)
|
|
@@ -33,7 +36,7 @@ def _filter_numba_warnings():
|
|
|
33
36
|
"ignore",
|
|
34
37
|
message=(
|
|
35
38
|
"(\x1b\\[1m)*" # ansi escape code for bold text
|
|
36
|
-
'Cannot cache compiled function "numba_funcified_fgraph" as it uses dynamic globals'
|
|
39
|
+
'Cannot cache compiled function "numba_funcified_fgraph.*" as it uses dynamic globals'
|
|
37
40
|
),
|
|
38
41
|
category=NumbaWarning,
|
|
39
42
|
)
|
|
@@ -1802,6 +1802,40 @@ def _get_vector_length_Alloc(var_inst, var):
|
|
|
1802
1802
|
raise ValueError(f"Length of {var} cannot be determined")
|
|
1803
1803
|
|
|
1804
1804
|
|
|
1805
|
+
@_vectorize_node.register(Alloc)
|
|
1806
|
+
def vectorize_alloc(op, node, val, *shape):
|
|
1807
|
+
old_val, *old_shape = node.inputs
|
|
1808
|
+
[old_alloc] = node.outputs
|
|
1809
|
+
|
|
1810
|
+
assert len(shape) == len(old_shape), (
|
|
1811
|
+
"Number of shape entries can't change in vectorize_alloc"
|
|
1812
|
+
)
|
|
1813
|
+
|
|
1814
|
+
if not all(all(s.broadcastable) for s in shape):
|
|
1815
|
+
# May imply a non-square Alloc
|
|
1816
|
+
return vectorize_node_fallback(op, node, val, *shape)
|
|
1817
|
+
|
|
1818
|
+
val_batch_ndim = val.ndim - old_val.ndim
|
|
1819
|
+
shape_batch_ndim = max((s.ndim for s in shape), default=0)
|
|
1820
|
+
|
|
1821
|
+
# Add implicit core dims that alloc prepends (alloc aligns val to the right)
|
|
1822
|
+
n_implicit_core_dims = len(old_shape) - old_val.ndim
|
|
1823
|
+
if n_implicit_core_dims > 0:
|
|
1824
|
+
val = expand_dims(
|
|
1825
|
+
val, list(range(val_batch_ndim, val_batch_ndim + n_implicit_core_dims))
|
|
1826
|
+
)
|
|
1827
|
+
|
|
1828
|
+
new_alloc = alloc(
|
|
1829
|
+
val,
|
|
1830
|
+
*val.shape[:val_batch_ndim],
|
|
1831
|
+
*(s.squeeze() for s in shape),
|
|
1832
|
+
)
|
|
1833
|
+
# Expand leading batch dims implied by the shape entries (if any)
|
|
1834
|
+
new_alloc = atleast_Nd(new_alloc, n=shape_batch_ndim + old_alloc.ndim)
|
|
1835
|
+
|
|
1836
|
+
return [new_alloc]
|
|
1837
|
+
|
|
1838
|
+
|
|
1805
1839
|
def full(shape, fill_value, dtype=None):
|
|
1806
1840
|
"""Return a new array of given shape and type, filled with `fill_value`.
|
|
1807
1841
|
|
|
@@ -35,7 +35,6 @@ from pytensor.tensor.math import tensordot
|
|
|
35
35
|
from pytensor.tensor.reshape import pack, unpack
|
|
36
36
|
from pytensor.tensor.slinalg import solve
|
|
37
37
|
from pytensor.tensor.variable import TensorVariable, Variable
|
|
38
|
-
from pytensor.utils import unzip
|
|
39
38
|
|
|
40
39
|
|
|
41
40
|
# scipy.optimize can be slow to import, and will not be used by most users
|
|
@@ -214,22 +213,6 @@ class ScipyWrapperOp(Op, HasInnerGraph):
|
|
|
214
213
|
|
|
215
214
|
return Apply(self, inputs, [self.inner_inputs[0].type(), ps.bool("success")])
|
|
216
215
|
|
|
217
|
-
def connection_pattern(self, node=None):
|
|
218
|
-
"""
|
|
219
|
-
All Ops that inherit from ScipyWrapperOp share the same connection pattern logic, because they all share the
|
|
220
|
-
same output structure. There are two outputs: the optimized variable, and a success flag. The success flag is
|
|
221
|
-
not differentiable, so it is never connected. The optimized variable is connected only to inputs that are
|
|
222
|
-
both connected to the objective function and of float dtype.
|
|
223
|
-
"""
|
|
224
|
-
fgraph = self.fgraph
|
|
225
|
-
fx = fgraph.outputs[0]
|
|
226
|
-
return [
|
|
227
|
-
# Every input is disonnected to the second output (success)
|
|
228
|
-
# And may or not be connected to the first output (opt_x)
|
|
229
|
-
[connected, False]
|
|
230
|
-
for [connected] in io_connection_pattern(fgraph.inputs, [fx])
|
|
231
|
-
]
|
|
232
|
-
|
|
233
216
|
|
|
234
217
|
class ScipyScalarWrapperOp(ScipyWrapperOp):
|
|
235
218
|
def build_fn(self):
|
|
@@ -277,6 +260,7 @@ class ScipyScalarWrapperOp(ScipyWrapperOp):
|
|
|
277
260
|
inner_fx = self.inner_outputs[0]
|
|
278
261
|
|
|
279
262
|
if is_minimization:
|
|
263
|
+
# The implicit function in minimization is grad(x, theta) == 0
|
|
280
264
|
inner_fx = grad(inner_fx, inner_x)
|
|
281
265
|
|
|
282
266
|
df_dx, *arg_grads = grad(
|
|
@@ -287,32 +271,35 @@ class ScipyScalarWrapperOp(ScipyWrapperOp):
|
|
|
287
271
|
return_disconnected="disconnected",
|
|
288
272
|
)
|
|
289
273
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
for arg, g in outer_arg_grad_map.items()
|
|
294
|
-
if not isinstance(g.type, DisconnectedType | NullType)
|
|
295
|
-
]
|
|
274
|
+
args_to_diff: tuple[bool, ...] = tuple(
|
|
275
|
+
not isinstance(g.type, DisconnectedType | NullType) for g in arg_grads
|
|
276
|
+
)
|
|
296
277
|
|
|
297
|
-
if
|
|
278
|
+
if not any(args_to_diff):
|
|
298
279
|
# No differentiable arguments, return disconnected gradients
|
|
299
280
|
return arg_grads
|
|
300
281
|
|
|
301
|
-
|
|
282
|
+
df_dthetas = [g for g, to_diff in zip(arg_grads, args_to_diff) if to_diff]
|
|
302
283
|
|
|
303
|
-
|
|
284
|
+
# Make gradient an expression of the outer variables
|
|
304
285
|
df_dx_star, *df_dthetas_stars = graph_replace(
|
|
305
|
-
[df_dx, *df_dthetas], replace=
|
|
286
|
+
[df_dx, *df_dthetas], replace=tuple(zip(fgraph.inputs, (x_star, *args)))
|
|
306
287
|
)
|
|
307
288
|
|
|
308
|
-
|
|
289
|
+
grad_wrt_args = []
|
|
290
|
+
df_dthetas_iter = iter(df_dthetas_stars)
|
|
291
|
+
for i, (arg, to_diff) in enumerate(zip(args, args_to_diff)):
|
|
292
|
+
if not to_diff:
|
|
293
|
+
# Store the null grad we got from the initial `grad` call
|
|
294
|
+
g = arg_grads[i]
|
|
295
|
+
assert isinstance(g.type, NullType | DisconnectedType)
|
|
296
|
+
else:
|
|
297
|
+
# Compute non-null grad and chain with output_grad
|
|
298
|
+
df_dtheta_star = next(df_dthetas_iter)
|
|
299
|
+
g = (-df_dtheta_star / df_dx_star) * output_grad
|
|
300
|
+
grad_wrt_args.append(g)
|
|
309
301
|
|
|
310
|
-
|
|
311
|
-
(-arg_to_grad[arg] / df_dx_star) * output_grad
|
|
312
|
-
if arg in arg_to_grad
|
|
313
|
-
else outer_arg_grad_map[arg]
|
|
314
|
-
for arg in args
|
|
315
|
-
]
|
|
302
|
+
assert next(df_dthetas_iter, None) is None, "Iterator was not exhausted"
|
|
316
303
|
|
|
317
304
|
return grad_wrt_args
|
|
318
305
|
|
|
@@ -358,7 +345,7 @@ class ScipyVectorWrapperOp(ScipyWrapperOp):
|
|
|
358
345
|
|
|
359
346
|
Notes
|
|
360
347
|
-----
|
|
361
|
-
The
|
|
348
|
+
The gradients are computed using the implicit function theorem. Given a function `f(x, theta) = 0`, and a function
|
|
362
349
|
`x_star(theta)` that, given input parameters theta returns `x` such that `f(x_star(theta), theta) = 0`, we can
|
|
363
350
|
compute the gradients of `x_star` with respect to `theta` as follows:
|
|
364
351
|
|
|
@@ -384,8 +371,12 @@ class ScipyVectorWrapperOp(ScipyWrapperOp):
|
|
|
384
371
|
fgraph = self.fgraph
|
|
385
372
|
inner_x, *inner_args = self.inner_inputs
|
|
386
373
|
implicit_f = self.inner_outputs[0]
|
|
374
|
+
if is_minimization:
|
|
375
|
+
# The implicit function in minimization is grad(x, theta) == 0
|
|
376
|
+
implicit_f = grad(implicit_f, inner_x)
|
|
387
377
|
|
|
388
|
-
|
|
378
|
+
# Call grad to see what arguments are connected
|
|
379
|
+
_, *arg_grads = grad(
|
|
389
380
|
implicit_f.sum(),
|
|
390
381
|
[inner_x, *inner_args],
|
|
391
382
|
disconnected_inputs="ignore",
|
|
@@ -393,32 +384,22 @@ class ScipyVectorWrapperOp(ScipyWrapperOp):
|
|
|
393
384
|
return_disconnected="disconnected",
|
|
394
385
|
)
|
|
395
386
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
if not isinstance(g.type, DisconnectedType | NullType)
|
|
400
|
-
]
|
|
387
|
+
args_to_diff: tuple[bool, ...] = tuple(
|
|
388
|
+
not isinstance(g.type, DisconnectedType | NullType) for g in arg_grads
|
|
389
|
+
)
|
|
401
390
|
|
|
402
|
-
if
|
|
391
|
+
if not args_to_diff:
|
|
403
392
|
# No differentiable arguments, return disconnected/null gradients
|
|
404
393
|
return arg_grads
|
|
405
394
|
|
|
406
|
-
outer_args_to_diff = [
|
|
407
|
-
arg
|
|
408
|
-
for inner_arg, arg in zip(inner_args, args)
|
|
409
|
-
if inner_arg in inner_args_to_diff
|
|
410
|
-
]
|
|
411
|
-
invalid_grad_map = {
|
|
412
|
-
arg: g for arg, g in zip(args, arg_grads) if arg not in outer_args_to_diff
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
if is_minimization:
|
|
416
|
-
implicit_f = grad(implicit_f, inner_x)
|
|
417
|
-
|
|
418
395
|
# Gradients are computed using the inner graph of the optimization op, not the actual inputs/outputs of the op.
|
|
419
396
|
packed_inner_args, packed_arg_shapes, implicit_f = pack_inputs_of_objective(
|
|
420
397
|
implicit_f,
|
|
421
|
-
|
|
398
|
+
[
|
|
399
|
+
inner_arg
|
|
400
|
+
for inner_arg, to_diff in zip(inner_args, args_to_diff)
|
|
401
|
+
if to_diff
|
|
402
|
+
],
|
|
422
403
|
)
|
|
423
404
|
|
|
424
405
|
df_dx, df_dtheta = jacobian(
|
|
@@ -430,11 +411,11 @@ class ScipyVectorWrapperOp(ScipyWrapperOp):
|
|
|
430
411
|
|
|
431
412
|
# Replace inner inputs (abstract dummies) with outer inputs (the actual user-provided symbols)
|
|
432
413
|
# at the solution point. Innner arguments aren't needed anymore, delete them to avoid accidental references.
|
|
433
|
-
del inner_x
|
|
434
|
-
|
|
435
|
-
inner_to_outer_map = dict(zip(fgraph.inputs, (x_star, *args)))
|
|
414
|
+
del inner_x, inner_args
|
|
415
|
+
inner_to_outer_map = tuple(zip(fgraph.inputs, (x_star, *args)))
|
|
436
416
|
df_dx_star, df_dtheta_star = graph_replace(
|
|
437
|
-
[df_dx, df_dtheta],
|
|
417
|
+
[df_dx, df_dtheta],
|
|
418
|
+
replace=inner_to_outer_map,
|
|
438
419
|
)
|
|
439
420
|
|
|
440
421
|
if df_dtheta_star.ndim == 0 or df_dx_star.ndim == 0:
|
|
@@ -454,27 +435,49 @@ class ScipyVectorWrapperOp(ScipyWrapperOp):
|
|
|
454
435
|
else:
|
|
455
436
|
grad_wrt_args = [grad_wrt_args_packed]
|
|
456
437
|
|
|
457
|
-
arg_to_grad = dict(zip(outer_args_to_diff, grad_wrt_args))
|
|
458
|
-
|
|
459
438
|
final_grads = []
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
if arg_grad.ndim > 0 and output_grad.ndim > 0:
|
|
468
|
-
g = tensordot(output_grad, arg_grad, [[0], [0]])
|
|
439
|
+
grad_wrt_args_iter = iter(grad_wrt_args)
|
|
440
|
+
for i, (arg, to_diff) in enumerate(zip(args, args_to_diff)):
|
|
441
|
+
if not to_diff:
|
|
442
|
+
# Store the null grad we got from the initial `grad` call
|
|
443
|
+
g = arg_grads[i]
|
|
444
|
+
assert isinstance(g.type, NullType | DisconnectedType)
|
|
469
445
|
else:
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
446
|
+
# Compute non-null grad and chain with output_grad
|
|
447
|
+
arg_grad = next(grad_wrt_args_iter)
|
|
448
|
+
if arg_grad.ndim > 0 and output_grad.ndim > 0:
|
|
449
|
+
g = tensordot(output_grad, arg_grad, [[0], [0]])
|
|
450
|
+
else:
|
|
451
|
+
g = arg_grad * output_grad
|
|
452
|
+
if isinstance(arg.type, ScalarType) and isinstance(g, TensorVariable):
|
|
453
|
+
g = scalar_from_tensor(g)
|
|
473
454
|
final_grads.append(g)
|
|
474
455
|
|
|
456
|
+
assert next(grad_wrt_args_iter, None) is None, "Iterator was not exhausted"
|
|
457
|
+
|
|
475
458
|
return final_grads
|
|
476
459
|
|
|
477
460
|
|
|
461
|
+
def _optimizer_connection_pattern(fgraph, is_minimization):
|
|
462
|
+
"""Compute connection pattern for scipy optimization Ops.
|
|
463
|
+
|
|
464
|
+
There are two outputs: the optimized variable, and a success flag. The success flag is
|
|
465
|
+
not differentiable, so it is never connected. The optimized variable is connected only
|
|
466
|
+
to inputs that are connected to the implicit function used in the gradient computation.
|
|
467
|
+
|
|
468
|
+
For minimization, the implicit function is grad(objective, x), not the objective itself.
|
|
469
|
+
An input may be connected to the objective but disconnected from its gradient (e.g. an
|
|
470
|
+
additive constant), so the connection pattern must reflect the actual implicit function.
|
|
471
|
+
"""
|
|
472
|
+
inner_x = fgraph.inputs[0]
|
|
473
|
+
fx = fgraph.outputs[0]
|
|
474
|
+
if is_minimization:
|
|
475
|
+
fx = grad(fx, inner_x)
|
|
476
|
+
return [
|
|
477
|
+
[connected, False] for [connected] in io_connection_pattern(fgraph.inputs, [fx])
|
|
478
|
+
]
|
|
479
|
+
|
|
480
|
+
|
|
478
481
|
class MinimizeScalarOp(ScipyScalarWrapperOp):
|
|
479
482
|
def __init__(
|
|
480
483
|
self,
|
|
@@ -503,6 +506,9 @@ class MinimizeScalarOp(ScipyScalarWrapperOp):
|
|
|
503
506
|
self._fn = None
|
|
504
507
|
self._fn_wrapped = None
|
|
505
508
|
|
|
509
|
+
def connection_pattern(self, node=None):
|
|
510
|
+
return _optimizer_connection_pattern(self.fgraph, is_minimization=True)
|
|
511
|
+
|
|
506
512
|
def __str__(self):
|
|
507
513
|
return f"{self.__class__.__name__}(method={self.method})"
|
|
508
514
|
|
|
@@ -639,6 +645,9 @@ class MinimizeOp(ScipyVectorWrapperOp):
|
|
|
639
645
|
self._fn = None
|
|
640
646
|
self._fn_wrapped = None
|
|
641
647
|
|
|
648
|
+
def connection_pattern(self, node=None):
|
|
649
|
+
return _optimizer_connection_pattern(self.fgraph, is_minimization=True)
|
|
650
|
+
|
|
642
651
|
def __str__(self):
|
|
643
652
|
str_args = ", ".join(
|
|
644
653
|
[
|
|
@@ -834,6 +843,9 @@ class RootScalarOp(ScipyScalarWrapperOp):
|
|
|
834
843
|
self._fn = None
|
|
835
844
|
self._fn_wrapped = None
|
|
836
845
|
|
|
846
|
+
def connection_pattern(self, node=None):
|
|
847
|
+
return _optimizer_connection_pattern(self.fgraph, is_minimization=False)
|
|
848
|
+
|
|
837
849
|
def __str__(self):
|
|
838
850
|
str_args = ", ".join(
|
|
839
851
|
[f"{arg}={getattr(self, arg)}" for arg in ["method", "jac", "hess"]]
|
|
@@ -980,6 +992,9 @@ class RootOp(ScipyVectorWrapperOp):
|
|
|
980
992
|
self._fn = None
|
|
981
993
|
self._fn_wrapped = None
|
|
982
994
|
|
|
995
|
+
def connection_pattern(self, node=None):
|
|
996
|
+
return _optimizer_connection_pattern(self.fgraph, is_minimization=False)
|
|
997
|
+
|
|
983
998
|
def __str__(self):
|
|
984
999
|
str_args = ", ".join(
|
|
985
1000
|
[f"{arg}={getattr(self, arg)}" for arg in ["method", "jac"]]
|
|
@@ -5,7 +5,14 @@ from pytensor.graph.replace import vectorize_graph
|
|
|
5
5
|
from pytensor.graph.rewriting.basic import copy_stack_trace, dfs_rewriter
|
|
6
6
|
from pytensor.graph.rewriting.unify import OpPattern, OpPatternOpTypeType
|
|
7
7
|
from pytensor.graph.traversal import apply_ancestors
|
|
8
|
-
from pytensor.tensor.basic import
|
|
8
|
+
from pytensor.tensor.basic import (
|
|
9
|
+
Alloc,
|
|
10
|
+
AllocEmpty,
|
|
11
|
+
ARange,
|
|
12
|
+
alloc,
|
|
13
|
+
expand_dims,
|
|
14
|
+
shape_padleft,
|
|
15
|
+
)
|
|
9
16
|
from pytensor.tensor.blockwise import Blockwise, _squeeze_left
|
|
10
17
|
from pytensor.tensor.math import Dot
|
|
11
18
|
from pytensor.tensor.rewriting.basic import (
|
|
@@ -89,6 +96,7 @@ optdb.register(
|
|
|
89
96
|
blockwise_of(
|
|
90
97
|
Dot
|
|
91
98
|
| Alloc
|
|
99
|
+
| AllocEmpty
|
|
92
100
|
| ARange
|
|
93
101
|
| Subtensor
|
|
94
102
|
| AdvancedSubtensor
|
|
@@ -106,7 +114,7 @@ def local_eager_useless_unbatched_blockwise(fgraph, node):
|
|
|
106
114
|
|
|
107
115
|
@register_specialize("shape_unsafe")
|
|
108
116
|
@node_rewriter([Blockwise])
|
|
109
|
-
def
|
|
117
|
+
def local_blockwise_alloc_inputs(fgraph, node):
|
|
110
118
|
"""Push Allocs from the inputs to the output of Blockwise Ops.
|
|
111
119
|
|
|
112
120
|
BOp = Blockwise(Op, signature="(x),(x)->(x)")
|
|
@@ -218,6 +226,34 @@ def local_blockwise_alloc(fgraph, node):
|
|
|
218
226
|
return new_outs
|
|
219
227
|
|
|
220
228
|
|
|
229
|
+
@register_canonicalize
|
|
230
|
+
@register_specialize
|
|
231
|
+
@node_rewriter([blockwise_of(Alloc)])
|
|
232
|
+
def local_blockwise_alloc(fgraph, node):
|
|
233
|
+
val, *shape = node.inputs
|
|
234
|
+
|
|
235
|
+
if not all(all(s.broadcastable) for s in shape):
|
|
236
|
+
# May imply a non-square Alloc
|
|
237
|
+
return None
|
|
238
|
+
|
|
239
|
+
batch_ndim = node.op.batch_ndim(node)
|
|
240
|
+
|
|
241
|
+
# Add implicit core dims that alloc prepends (alloc aligns val to the right)
|
|
242
|
+
n_implicit_core_dims = node.outputs[0].ndim - val.ndim
|
|
243
|
+
if n_implicit_core_dims > 0:
|
|
244
|
+
val = expand_dims(
|
|
245
|
+
val, list(range(batch_ndim, batch_ndim + n_implicit_core_dims))
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
new_alloc = alloc(
|
|
249
|
+
val,
|
|
250
|
+
*val.shape[:batch_ndim],
|
|
251
|
+
*(s.squeeze() for s in shape),
|
|
252
|
+
)
|
|
253
|
+
copy_stack_trace(node.outputs[0], new_alloc)
|
|
254
|
+
return [new_alloc]
|
|
255
|
+
|
|
256
|
+
|
|
221
257
|
@register_specialize
|
|
222
258
|
@node_rewriter([blockwise_of(Reshape)])
|
|
223
259
|
def local_blockwise_reshape(fgraph, node):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pytensor
|
|
3
|
-
Version: 2.38.
|
|
3
|
+
Version: 2.38.3
|
|
4
4
|
Summary: Optimizing compiler for evaluating mathematical expressions on CPUs and GPUs.
|
|
5
5
|
Author-email: pymc-devs <pymc.devs@gmail.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -31,7 +31,7 @@ License-File: LICENSE.txt
|
|
|
31
31
|
Requires-Dist: setuptools>=59.0.0
|
|
32
32
|
Requires-Dist: scipy<2,>=1
|
|
33
33
|
Requires-Dist: numpy>=2.0
|
|
34
|
-
Requires-Dist: numba
|
|
34
|
+
Requires-Dist: numba<=0.65.1,>=0.58
|
|
35
35
|
Requires-Dist: filelock>=3.15
|
|
36
36
|
Requires-Dist: etuples
|
|
37
37
|
Requires-Dist: logical-unification
|
|
@@ -60,7 +60,7 @@ Provides-Extra: jax
|
|
|
60
60
|
Requires-Dist: jax; extra == "jax"
|
|
61
61
|
Requires-Dist: jaxlib; extra == "jax"
|
|
62
62
|
Provides-Extra: numba
|
|
63
|
-
Requires-Dist: numba
|
|
63
|
+
Requires-Dist: numba<=0.65.1,>=0.58; extra == "numba"
|
|
64
64
|
Requires-Dist: llvmlite; extra == "numba"
|
|
65
65
|
Dynamic: license-file
|
|
66
66
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|