pytensor 2.28.1__tar.gz → 2.28.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.28.1/pytensor.egg-info → pytensor-2.28.3}/PKG-INFO +1 -1
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/_version.py +3 -3
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/debugmode.py +8 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/function/__init__.py +16 -1
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/function/pfunc.py +8 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/function/types.py +81 -21
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/mode.py +5 -1
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/configdefaults.py +8 -1
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/configparser.py +1 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/features.py +8 -1
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/fg.py +11 -3
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/rewriting/basic.py +9 -3
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/elemwise.py +1 -6
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/scan.py +4 -2
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/slinalg.py +1 -2
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/basic.py +9 -2
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/elemwise.py +25 -83
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/scan.py +12 -3
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/slinalg.py +1 -2
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/subtensor.py +11 -5
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/basic.py +9 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/elemwise.py +1 -6
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/op.py +13 -33
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/rewriting.py +2 -0
- pytensor-2.28.3/pytensor/tensor/c_code/dimshuffle.c +86 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/elemwise.py +16 -21
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/math.py +1450 -169
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/basic.py +7 -1
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/subtensor.py +104 -28
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/shape.py +13 -18
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/slinalg.py +27 -15
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/subtensor.py +47 -17
- {pytensor-2.28.1 → pytensor-2.28.3/pytensor.egg-info}/PKG-INFO +1 -1
- {pytensor-2.28.1 → pytensor-2.28.3}/scripts/mypy-failing.txt +0 -1
- pytensor-2.28.1/pytensor/tensor/c_code/dimshuffle.c +0 -82
- {pytensor-2.28.1 → pytensor-2.28.3}/LICENSE.txt +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/MANIFEST.in +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/README.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/.templates/PLACEHOLDER +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/.templates/layout.html +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/.templates/nb-badges.html +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/.templates/rendered_citation.html +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/LICENSE.txt +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/README.md +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/acknowledgement.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/bcast.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/bcast.svg +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/blog.md +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/conf.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/core_development_guide.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/css.inc +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/dev_start_guide.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/environment.yml +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/apply.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/apply.svg +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/apply2.svg +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/creating_a_c_op.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/creating_a_numba_jax_op.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/creating_an_op.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/ctype.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/extending_faq.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/extending_pytensor_solution_1.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/graph_rewriting.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/graphstructures.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/index.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/inplace.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/op.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/other_ops.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/pics/symbolic_graph_opt.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/pipeline.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/scan.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/tips.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/type.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/unittest.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/using_params.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/faq.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/gallery/page_footer.md +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/gallery/rewrites/graph_rewrites.ipynb +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/gallery/scan/scan_tutorial.ipynb +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/generate_dtype_tensor_table.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/glossary.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/Elman_srnn.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/PyTensor.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/PyTensor_RGB.svg +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/PyTensor_logo.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/binder.svg +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/blocksparse.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/colab.svg +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/github.svg +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/lstm.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/lstm_memorycell.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/talk2010.gif +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/talk2010.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/index.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/install.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/internal/how_to_release.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/internal/index.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/internal/metadocumentation.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/introduction.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/debugmode.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/function.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/index.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/io.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/mode.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/nanguardmode.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/opfromgraph.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/ops.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/profilemode.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/shared.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/config.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/mlp.html +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/mlp.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/mlp2.html +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/mlp2.pdf +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/mlp2.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/ofg.html +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/ofg2.html +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/index.ipynb +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/index.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/index_files/index_10_0.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/index_files/index_11_0.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/index_files/index_24_0.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/index_files/index_25_0.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/features.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/fgraph.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/graph.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/index.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/op.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/replace.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/type.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/utils.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/index.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/misc/pkl_utils.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/printing.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/scalar/index.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/scan.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/sparse/index.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/sparse/sandbox.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/basic.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/basic_opt.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/bcast.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/bcast.svg +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/conv.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/elemwise.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/extra_ops.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/fft.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/functional.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/index.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/io.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/math_opt.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/nlinalg.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/plot_fft.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/random/distributions.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/random/index.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/slinalg.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/utils.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/typed_list.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/links.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/optimizations.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/pylintrc +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/robots.txt +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/troubleshooting.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/adding.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/adding_solution_1.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/aliasing.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/apply.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/apply.svg +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/bcast.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/broadcasting.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/conditions.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/debug_faq.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/dlogistic.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/examples.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/faq_tutorial.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/gradients.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/index.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/loading_and_saving.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/logistic.gp +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/logistic.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/loop.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/loop_solution_1.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/modes.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/modes_solution_1.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/multi_cores.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/nan_tutorial.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/pics/d3viz.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/printing_drawing.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/prng.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/profiling.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/profiling_example.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/profiling_example_out.prof +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/shape_info.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/sparse.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/symbolic_graphs.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/doc/user_guide.rst +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pyproject.toml +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/bin/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/bin/pytensor_cache.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/breakpoint.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/builders.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/compiledir.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/compilelock.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/io.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/monitormode.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/nanguardmode.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/ops.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/profiling.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/sharedvalue.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/css/d3viz.css +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/d3viz.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/formatting.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/js/d3viz.js +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/gradient.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/destroyhandler.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/null_type.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/op.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/replace.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/rewriting/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/rewriting/db.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/rewriting/kanren.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/rewriting/unify.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/rewriting/utils.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/type.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/utils.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/ifelse.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/cmodule.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/cutils.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/cvm.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/exceptions.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/interface.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/lazylinker_c.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/op.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/params_type.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/type.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/blas.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/blockwise.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/einsum.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/math.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/nlinalg.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/pad.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/random.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/scalar.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/shape.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/sort.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/sparse.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/subtensor.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/linker.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/_LAPACK.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/blockwise.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/cython_support.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/random.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/scalar.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/sparse.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/vectorize_codegen.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/linker.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/blas.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/blockwise.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/extra_ops.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/math.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/nlinalg.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/scalar.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/shape.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/sort.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/subtensor.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/linker.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/utils.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/vm.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/check_blas.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/check_blas_many.sh +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/check_duplicate_key.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/elemwise_time_test.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/frozendict.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/may_share_memory.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/ordered_set.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/pkl_utils.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/npy_2_compat.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/printing.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/py.typed +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/raise_op.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/c_code/gamma.c +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/c_code/incbet.c +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/loop.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/math.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/sharedvar.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/checkpoints.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/rewriting.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/scan_perform.pyx +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/scan_perform_ext.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/utils.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/views.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/sandbox/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/sandbox/sp.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/sandbox/sp2.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/sharedvar.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/type.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/utils.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/blas.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/blas_c.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/blas_headers.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/blas_scipy.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/blockwise.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/conv/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/conv/abstract_conv.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/einsum.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/elemwise_cgen.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/exceptions.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/extra_ops.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/fft.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/fourier.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/functional.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/inplace.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/interpolate.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/io.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/linalg.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/nlinalg.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/pad.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/op.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/rewriting/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/rewriting/basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/rewriting/jax.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/rewriting/numba.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/type.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/utils.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/var.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/blas.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/blas_c.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/blas_scipy.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/blockwise.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/einsum.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/elemwise.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/extra_ops.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/jax.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/linalg.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/math.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/numba.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/ofg.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/shape.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/special.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/sharedvar.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/sort.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/special.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/type.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/type_other.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/utils.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/var.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/variable.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/xlogx.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/typed_list/__init__.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/typed_list/basic.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/typed_list/rewriting.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/typed_list/type.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/updates.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/utils.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor.egg-info/SOURCES.txt +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor.egg-info/dependency_links.txt +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor.egg-info/entry_points.txt +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor.egg-info/requires.txt +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/pytensor.egg-info/top_level.txt +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/scripts/slowest_tests/update-slowest-times-issue.sh +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/setup.cfg +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/setup.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/tests/link/c/c_code/test_cenum.h +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/tests/link/c/c_code/test_quadratic_function.c +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/tests/tensor/conv/c_code/corr3d_gemm.c +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/tests/tensor/conv/c_code/corr_gemm.c +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_breakpoint.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_config.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_gradient.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_ifelse.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_printing.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_raise_op.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_rop.py +0 -0
- {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_updates.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2025-
|
|
11
|
+
"date": "2025-03-05T13:02:56+0100",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.28.
|
|
14
|
+
"full-revisionid": "89d5366c888f430003aa6f16a13ad9cdd2826d95",
|
|
15
|
+
"version": "2.28.3"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -1966,6 +1966,12 @@ class _Maker(FunctionMaker): # inheritance buys a few helper functions
|
|
|
1966
1966
|
If the outputs argument for pytensor.function was a list, then
|
|
1967
1967
|
output_keys is None. If the outputs argument was a dict, then
|
|
1968
1968
|
output_keys is a sorted list of the keys from that dict.
|
|
1969
|
+
trust_input : bool, default False
|
|
1970
|
+
If True, no input validation checks are performed when the function is
|
|
1971
|
+
called. This includes checking the number of inputs, their types and
|
|
1972
|
+
that multiple inputs are not aliased to each other. Failure to meet any
|
|
1973
|
+
of these conditions can lead to computational errors or to the
|
|
1974
|
+
interpreter crashing.
|
|
1969
1975
|
|
|
1970
1976
|
Notes
|
|
1971
1977
|
-----
|
|
@@ -1993,6 +1999,7 @@ class _Maker(FunctionMaker): # inheritance buys a few helper functions
|
|
|
1993
1999
|
output_keys=None,
|
|
1994
2000
|
name=None,
|
|
1995
2001
|
no_fgraph_prep=False,
|
|
2002
|
+
trust_input=False,
|
|
1996
2003
|
):
|
|
1997
2004
|
self.mode = mode
|
|
1998
2005
|
self.profile = profile
|
|
@@ -2146,6 +2153,7 @@ class _Maker(FunctionMaker): # inheritance buys a few helper functions
|
|
|
2146
2153
|
self.on_unused_input = on_unused_input # Used for the pickling/copy
|
|
2147
2154
|
self.output_keys = output_keys
|
|
2148
2155
|
self.name = name
|
|
2156
|
+
self.trust_input = trust_input
|
|
2149
2157
|
|
|
2150
2158
|
self.required = [(i.value is None) for i in self.inputs]
|
|
2151
2159
|
self.refeed = [
|
|
@@ -37,6 +37,7 @@ def function_dump(
|
|
|
37
37
|
profile: bool | ProfileStats | None = None,
|
|
38
38
|
on_unused_input: str | None = None,
|
|
39
39
|
extra_tag_to_remove: str | None = None,
|
|
40
|
+
trust_input: bool = False,
|
|
40
41
|
):
|
|
41
42
|
"""
|
|
42
43
|
This is helpful to make a reproducible case for problems during PyTensor
|
|
@@ -82,6 +83,7 @@ def function_dump(
|
|
|
82
83
|
"allow_input_downcast": allow_input_downcast,
|
|
83
84
|
"profile": profile,
|
|
84
85
|
"on_unused_input": on_unused_input,
|
|
86
|
+
"trust_input": trust_input,
|
|
85
87
|
}
|
|
86
88
|
with Path(filename).open("wb") as f:
|
|
87
89
|
pickler = pytensor.misc.pkl_utils.StripPickler(
|
|
@@ -107,6 +109,7 @@ def function(
|
|
|
107
109
|
allow_input_downcast: bool | None = None,
|
|
108
110
|
profile: bool | ProfileStats | None = None,
|
|
109
111
|
on_unused_input: str | None = None,
|
|
112
|
+
trust_input: bool = False,
|
|
110
113
|
):
|
|
111
114
|
"""
|
|
112
115
|
Return a :class:`callable object <pytensor.compile.function.types.Function>`
|
|
@@ -164,6 +167,12 @@ def function(
|
|
|
164
167
|
on_unused_input
|
|
165
168
|
What to do if a variable in the 'inputs' list is not used in the graph.
|
|
166
169
|
Possible values are 'raise', 'warn', 'ignore' and None.
|
|
170
|
+
trust_input: bool, default False
|
|
171
|
+
If True, no input validation checks are performed when the function is
|
|
172
|
+
called. This includes checking the number of inputs, their types and
|
|
173
|
+
that multiple inputs are not aliased to each other. Failure to meet any
|
|
174
|
+
of these conditions can lead to computational errors or to the
|
|
175
|
+
interpreter crashing.
|
|
167
176
|
|
|
168
177
|
Returns
|
|
169
178
|
-------
|
|
@@ -310,7 +319,12 @@ def function(
|
|
|
310
319
|
"semantics, which disallow using updates and givens"
|
|
311
320
|
)
|
|
312
321
|
fn = orig_function(
|
|
313
|
-
inputs,
|
|
322
|
+
inputs,
|
|
323
|
+
outputs,
|
|
324
|
+
mode=mode,
|
|
325
|
+
accept_inplace=accept_inplace,
|
|
326
|
+
name=name,
|
|
327
|
+
trust_input=trust_input,
|
|
314
328
|
)
|
|
315
329
|
else:
|
|
316
330
|
# note: pfunc will also call orig_function -- orig_function is
|
|
@@ -329,5 +343,6 @@ def function(
|
|
|
329
343
|
on_unused_input=on_unused_input,
|
|
330
344
|
profile=profile,
|
|
331
345
|
output_keys=output_keys,
|
|
346
|
+
trust_input=trust_input,
|
|
332
347
|
)
|
|
333
348
|
return fn
|
|
@@ -377,6 +377,7 @@ def pfunc(
|
|
|
377
377
|
on_unused_input=None,
|
|
378
378
|
output_keys=None,
|
|
379
379
|
fgraph: FunctionGraph | None = None,
|
|
380
|
+
trust_input: bool = False,
|
|
380
381
|
) -> Function:
|
|
381
382
|
"""
|
|
382
383
|
Function-constructor for graphs with shared variables.
|
|
@@ -425,6 +426,12 @@ def pfunc(
|
|
|
425
426
|
fgraph
|
|
426
427
|
An existing `FunctionGraph` from which to construct the returned
|
|
427
428
|
`Function`. When this is non-``None``, nothing is cloned.
|
|
429
|
+
trust_input : bool, default False
|
|
430
|
+
If True, no input validation checks are performed when the function is
|
|
431
|
+
called. This includes checking the number of inputs, their types and
|
|
432
|
+
that multiple inputs are not aliased to each other. Failure to meet any
|
|
433
|
+
of these conditions can lead to computational errors or to the
|
|
434
|
+
interpreter crashing.
|
|
428
435
|
|
|
429
436
|
Returns
|
|
430
437
|
-------
|
|
@@ -472,6 +479,7 @@ def pfunc(
|
|
|
472
479
|
on_unused_input=on_unused_input,
|
|
473
480
|
output_keys=output_keys,
|
|
474
481
|
fgraph=fgraph,
|
|
482
|
+
trust_input=trust_input,
|
|
475
483
|
)
|
|
476
484
|
|
|
477
485
|
|
|
@@ -5,6 +5,7 @@ import copyreg
|
|
|
5
5
|
import logging
|
|
6
6
|
import time
|
|
7
7
|
import warnings
|
|
8
|
+
from collections.abc import Sequence
|
|
8
9
|
from itertools import chain
|
|
9
10
|
from typing import TYPE_CHECKING
|
|
10
11
|
|
|
@@ -168,6 +169,59 @@ class Supervisor(Feature):
|
|
|
168
169
|
raise InconsistencyError(f"Trying to destroy a protected variable: {r}")
|
|
169
170
|
|
|
170
171
|
|
|
172
|
+
def add_supervisor_to_fgraph(
|
|
173
|
+
fgraph: FunctionGraph,
|
|
174
|
+
input_specs: Sequence[SymbolicInput],
|
|
175
|
+
accept_inplace: bool = False,
|
|
176
|
+
) -> None:
|
|
177
|
+
"""Setup Supervisor Feature in a FunctionGraph, so that inplace rewrites can be used.
|
|
178
|
+
|
|
179
|
+
Parameters
|
|
180
|
+
----------
|
|
181
|
+
fgraph: FunctionGraph
|
|
182
|
+
The FunctionGraph to setup the Supervisor Feature in.
|
|
183
|
+
input_specs: Sequence of SymbolicInput
|
|
184
|
+
The input specifications for the FunctionGraph.
|
|
185
|
+
Inputs with the attribute `mutable=False` and which are not already destroyed by an inplace operation
|
|
186
|
+
(if `accept_inplace` is True) will be protected from inplace operations.
|
|
187
|
+
Otherwise, they will be allowed to be destroyed.
|
|
188
|
+
accept_inplace: bool
|
|
189
|
+
Whether to allow inplace operations to already be present in the graph.
|
|
190
|
+
|
|
191
|
+
Raises
|
|
192
|
+
------
|
|
193
|
+
TypeError
|
|
194
|
+
If inplace operations are not allowed and the graph already contains inplace operations.
|
|
195
|
+
|
|
196
|
+
"""
|
|
197
|
+
|
|
198
|
+
has_destroy_handler = hasattr(fgraph, "destroyers")
|
|
199
|
+
if not (has_destroy_handler and accept_inplace):
|
|
200
|
+
# Check if fgraph already contains destructive operations,
|
|
201
|
+
# in which case we need to add a DestroyHandler or raise an error
|
|
202
|
+
for node in fgraph.apply_nodes:
|
|
203
|
+
if node.op.destroy_map:
|
|
204
|
+
if not accept_inplace:
|
|
205
|
+
raise TypeError(
|
|
206
|
+
f"Graph must not contain inplace operations: {node}"
|
|
207
|
+
)
|
|
208
|
+
else:
|
|
209
|
+
has_destroy_handler = True
|
|
210
|
+
fgraph.attach_feature(DestroyHandler())
|
|
211
|
+
break
|
|
212
|
+
|
|
213
|
+
# Protect all immutable inputs from inplace operations.
|
|
214
|
+
fgraph.attach_feature(
|
|
215
|
+
Supervisor(
|
|
216
|
+
input
|
|
217
|
+
for spec, input in zip(input_specs, fgraph.inputs, strict=True)
|
|
218
|
+
if not (
|
|
219
|
+
spec.mutable or has_destroy_handler and fgraph.has_destroyers([input])
|
|
220
|
+
)
|
|
221
|
+
)
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
|
|
171
225
|
def std_fgraph(
|
|
172
226
|
input_specs: list[SymbolicInput],
|
|
173
227
|
output_specs: list[SymbolicOutput],
|
|
@@ -229,24 +283,8 @@ def std_fgraph(
|
|
|
229
283
|
|
|
230
284
|
found_updates.extend(map(SymbolicOutput, updates))
|
|
231
285
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
if not accept_inplace:
|
|
235
|
-
raise TypeError(f"Graph must not contain inplace operations: {node}")
|
|
236
|
-
else:
|
|
237
|
-
fgraph.attach_feature(DestroyHandler())
|
|
238
|
-
break
|
|
239
|
-
|
|
240
|
-
# We need to protect all immutable inputs from inplace operations.
|
|
241
|
-
fgraph.attach_feature(
|
|
242
|
-
Supervisor(
|
|
243
|
-
input
|
|
244
|
-
for spec, input in zip(input_specs, fgraph.inputs, strict=True)
|
|
245
|
-
if not (
|
|
246
|
-
spec.mutable
|
|
247
|
-
or (hasattr(fgraph, "destroyers") and fgraph.has_destroyers([input]))
|
|
248
|
-
)
|
|
249
|
-
)
|
|
286
|
+
add_supervisor_to_fgraph(
|
|
287
|
+
fgraph=fgraph, input_specs=input_specs, accept_inplace=accept_inplace
|
|
250
288
|
)
|
|
251
289
|
|
|
252
290
|
# If named nodes are replaced, keep the name
|
|
@@ -335,6 +373,7 @@ class Function:
|
|
|
335
373
|
return_none: bool,
|
|
336
374
|
output_keys,
|
|
337
375
|
maker: "FunctionMaker",
|
|
376
|
+
trust_input: bool = False,
|
|
338
377
|
name: str | None = None,
|
|
339
378
|
):
|
|
340
379
|
"""
|
|
@@ -369,6 +408,12 @@ class Function:
|
|
|
369
408
|
TODO
|
|
370
409
|
maker
|
|
371
410
|
The `FunctionMaker` that created this instance.
|
|
411
|
+
trust_input : bool, default False
|
|
412
|
+
If True, no input validation checks are performed when the function is
|
|
413
|
+
called. This includes checking the number of inputs, their types and
|
|
414
|
+
that multiple inputs are not aliased to each other. Failure to meet any
|
|
415
|
+
of these conditions can lead to computational errors or to the
|
|
416
|
+
interpreter crashing.
|
|
372
417
|
name
|
|
373
418
|
A string name.
|
|
374
419
|
"""
|
|
@@ -382,7 +427,7 @@ class Function:
|
|
|
382
427
|
self.return_none = return_none
|
|
383
428
|
self.maker = maker
|
|
384
429
|
self.profile = None # reassigned in FunctionMaker.create
|
|
385
|
-
self.trust_input =
|
|
430
|
+
self.trust_input = trust_input # If True, we don't check the input parameter
|
|
386
431
|
self.name = name
|
|
387
432
|
self.nodes_with_inner_function = []
|
|
388
433
|
self.output_keys = output_keys
|
|
@@ -1303,7 +1348,12 @@ class FunctionMaker:
|
|
|
1303
1348
|
name : str
|
|
1304
1349
|
An optional name for this function. If used, the profile mode will
|
|
1305
1350
|
print the time spent in this function.
|
|
1306
|
-
|
|
1351
|
+
trust_input : bool, default False
|
|
1352
|
+
If True, no input validation checks are performed when the function is
|
|
1353
|
+
called. This includes checking the number of inputs, their types and
|
|
1354
|
+
that multiple inputs are not aliased to each other. Failure to meet any
|
|
1355
|
+
of these conditions can lead to computational errors or to the
|
|
1356
|
+
interpreter crashing.
|
|
1307
1357
|
"""
|
|
1308
1358
|
|
|
1309
1359
|
@staticmethod
|
|
@@ -1469,6 +1519,7 @@ class FunctionMaker:
|
|
|
1469
1519
|
output_keys=None,
|
|
1470
1520
|
name=None,
|
|
1471
1521
|
no_fgraph_prep=False,
|
|
1522
|
+
trust_input=False,
|
|
1472
1523
|
):
|
|
1473
1524
|
# Save the provided mode, not the instantiated mode.
|
|
1474
1525
|
# The instantiated mode don't pickle and if we unpickle an PyTensor
|
|
@@ -1571,6 +1622,7 @@ class FunctionMaker:
|
|
|
1571
1622
|
self.on_unused_input = on_unused_input # Used for the pickling/copy
|
|
1572
1623
|
self.output_keys = output_keys
|
|
1573
1624
|
self.name = name
|
|
1625
|
+
self.trust_input = trust_input
|
|
1574
1626
|
|
|
1575
1627
|
self.required = [(i.value is None) for i in self.inputs]
|
|
1576
1628
|
self.refeed = [
|
|
@@ -1688,6 +1740,7 @@ class FunctionMaker:
|
|
|
1688
1740
|
self.return_none,
|
|
1689
1741
|
self.output_keys,
|
|
1690
1742
|
self,
|
|
1743
|
+
trust_input=self.trust_input,
|
|
1691
1744
|
name=self.name,
|
|
1692
1745
|
)
|
|
1693
1746
|
|
|
@@ -1705,6 +1758,7 @@ def orig_function(
|
|
|
1705
1758
|
on_unused_input=None,
|
|
1706
1759
|
output_keys=None,
|
|
1707
1760
|
fgraph: FunctionGraph | None = None,
|
|
1761
|
+
trust_input: bool = False,
|
|
1708
1762
|
) -> Function:
|
|
1709
1763
|
"""
|
|
1710
1764
|
Return a Function that will calculate the outputs from the inputs.
|
|
@@ -1735,7 +1789,12 @@ def orig_function(
|
|
|
1735
1789
|
fgraph
|
|
1736
1790
|
An existing `FunctionGraph` to use instead of constructing a new one
|
|
1737
1791
|
from cloned `outputs`.
|
|
1738
|
-
|
|
1792
|
+
trust_input : bool, default False
|
|
1793
|
+
If True, no input validation checks are performed when the function is
|
|
1794
|
+
called. This includes checking the number of inputs, their types and
|
|
1795
|
+
that multiple inputs are not aliased to each other. Failure to meet any
|
|
1796
|
+
of these conditions can lead to computational errors or to the
|
|
1797
|
+
interpreter crashing.
|
|
1739
1798
|
"""
|
|
1740
1799
|
|
|
1741
1800
|
if profile:
|
|
@@ -1768,6 +1827,7 @@ def orig_function(
|
|
|
1768
1827
|
output_keys=output_keys,
|
|
1769
1828
|
name=name,
|
|
1770
1829
|
fgraph=fgraph,
|
|
1830
|
+
trust_input=trust_input,
|
|
1771
1831
|
)
|
|
1772
1832
|
with config.change_flags(compute_test_value="off"):
|
|
1773
1833
|
fn = m.create(defaults)
|
|
@@ -138,7 +138,11 @@ class AddDestroyHandler(GraphRewriter):
|
|
|
138
138
|
break
|
|
139
139
|
if not supervisor_added:
|
|
140
140
|
warnings.warn(
|
|
141
|
-
|
|
141
|
+
(
|
|
142
|
+
f"A Supervisor feature is missing from {fgraph}.\n"
|
|
143
|
+
"This is needed for inplace rewrites. Either exclude inplace rewrites or add a Supervisor feature.\n"
|
|
144
|
+
"A Supervisor feature can be added via `pytensor.compile.function.types.add_supervisor_to_fgraph`."
|
|
145
|
+
),
|
|
142
146
|
stacklevel=3,
|
|
143
147
|
)
|
|
144
148
|
|
|
@@ -418,11 +418,18 @@ def add_compile_configvars():
|
|
|
418
418
|
|
|
419
419
|
config.add(
|
|
420
420
|
"optimizer_verbose",
|
|
421
|
-
"
|
|
421
|
+
"Print information about rewrites that are applied during a graph transformation.",
|
|
422
422
|
BoolParam(False),
|
|
423
423
|
in_c_key=False,
|
|
424
424
|
)
|
|
425
425
|
|
|
426
|
+
config.add(
|
|
427
|
+
"optimizer_verbose_ignore",
|
|
428
|
+
"Do not print information for rewrites with these names when `optimizer_verbose` is `True`. Separate names with ','",
|
|
429
|
+
StrParam(""),
|
|
430
|
+
in_c_key=False,
|
|
431
|
+
)
|
|
432
|
+
|
|
426
433
|
config.add(
|
|
427
434
|
"on_opt_error",
|
|
428
435
|
(
|
|
@@ -567,6 +567,13 @@ class ReplaceValidate(History, Validator):
|
|
|
567
567
|
if verbose is None:
|
|
568
568
|
verbose = config.optimizer_verbose
|
|
569
569
|
|
|
570
|
+
if verbose:
|
|
571
|
+
print_reason = True
|
|
572
|
+
if config.optimizer_verbose_ignore:
|
|
573
|
+
print_reason = str(reason) not in config.optimizer_verbose_ignore.split(
|
|
574
|
+
","
|
|
575
|
+
)
|
|
576
|
+
|
|
570
577
|
for r, new_r in replacements:
|
|
571
578
|
try:
|
|
572
579
|
fgraph.replace(r, new_r, reason=reason, verbose=False, **kwargs)
|
|
@@ -608,7 +615,7 @@ class ReplaceValidate(History, Validator):
|
|
|
608
615
|
)
|
|
609
616
|
raise
|
|
610
617
|
|
|
611
|
-
if verbose:
|
|
618
|
+
if verbose and print_reason:
|
|
612
619
|
print( # noqa: T201
|
|
613
620
|
f"rewriting: rewrite {reason} replaces {r} of {r.owner} with {new_r} of {new_r.owner}"
|
|
614
621
|
)
|
|
@@ -490,10 +490,18 @@ class FunctionGraph(MetaObject):
|
|
|
490
490
|
"""
|
|
491
491
|
if verbose is None:
|
|
492
492
|
verbose = config.optimizer_verbose
|
|
493
|
+
|
|
493
494
|
if verbose:
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
495
|
+
print_reason = True
|
|
496
|
+
if config.optimizer_verbose_ignore:
|
|
497
|
+
print_reason = str(reason) not in config.optimizer_verbose_ignore.split(
|
|
498
|
+
","
|
|
499
|
+
)
|
|
500
|
+
|
|
501
|
+
if print_reason:
|
|
502
|
+
print( # noqa: T201
|
|
503
|
+
f"rewriting: rewrite {reason} replaces {var} of {var.owner} with {new_var} of {new_var.owner}"
|
|
504
|
+
)
|
|
497
505
|
|
|
498
506
|
new_var = var.type.filter_variable(new_var, allow_convert=True)
|
|
499
507
|
|
|
@@ -1305,9 +1305,15 @@ class SequentialNodeRewriter(NodeRewriter):
|
|
|
1305
1305
|
new_vars = list(new_repl.values())
|
|
1306
1306
|
|
|
1307
1307
|
if config.optimizer_verbose:
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1308
|
+
print_reason = True
|
|
1309
|
+
if config.optimizer_verbose_ignore:
|
|
1310
|
+
print_reason = str(
|
|
1311
|
+
rewrite
|
|
1312
|
+
) not in config.optimizer_verbose_ignore.split(",")
|
|
1313
|
+
if print_reason:
|
|
1314
|
+
print( # noqa: T201
|
|
1315
|
+
f"rewriting: rewrite {rewrite} replaces node {node} with {new_repl}"
|
|
1316
|
+
)
|
|
1311
1317
|
|
|
1312
1318
|
if self.profile:
|
|
1313
1319
|
self.node_created[rewrite] += len(
|
|
@@ -79,12 +79,7 @@ def jax_funcify_DimShuffle(op, **kwargs):
|
|
|
79
79
|
for augm in op.augment:
|
|
80
80
|
shape.insert(augm, 1)
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if not op.inplace:
|
|
85
|
-
res = jnp.copy(res)
|
|
86
|
-
|
|
87
|
-
return res
|
|
82
|
+
return jnp.reshape(res, shape)
|
|
88
83
|
|
|
89
84
|
return dimshuffle
|
|
90
85
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import jax
|
|
2
2
|
import jax.numpy as jnp
|
|
3
3
|
|
|
4
|
-
from pytensor.compile.mode import JAX
|
|
4
|
+
from pytensor.compile.mode import JAX, get_mode
|
|
5
5
|
from pytensor.link.jax.dispatch.basic import jax_funcify
|
|
6
6
|
from pytensor.scan.op import Scan
|
|
7
7
|
|
|
@@ -19,7 +19,9 @@ def jax_funcify_Scan(op: Scan, **kwargs):
|
|
|
19
19
|
)
|
|
20
20
|
|
|
21
21
|
# Optimize inner graph (exclude any defalut rewrites that are incompatible with JAX mode)
|
|
22
|
-
rewriter =
|
|
22
|
+
rewriter = (
|
|
23
|
+
get_mode(op.mode).including("jax").excluding(*JAX._optimizer.exclude).optimizer
|
|
24
|
+
)
|
|
23
25
|
rewriter(op.fgraph)
|
|
24
26
|
scan_inner_func = jax_funcify(op.fgraph, **kwargs)
|
|
25
27
|
|
|
@@ -53,7 +53,6 @@ def jax_funcify_Solve(op, **kwargs):
|
|
|
53
53
|
@jax_funcify.register(SolveTriangular)
|
|
54
54
|
def jax_funcify_SolveTriangular(op, **kwargs):
|
|
55
55
|
lower = op.lower
|
|
56
|
-
trans = op.trans
|
|
57
56
|
unit_diagonal = op.unit_diagonal
|
|
58
57
|
check_finite = op.check_finite
|
|
59
58
|
|
|
@@ -62,7 +61,7 @@ def jax_funcify_SolveTriangular(op, **kwargs):
|
|
|
62
61
|
A,
|
|
63
62
|
b,
|
|
64
63
|
lower=lower,
|
|
65
|
-
trans=
|
|
64
|
+
trans=0, # this is handled by explicitly transposing A, so it will always be 0 when we get to here.
|
|
66
65
|
unit_diagonal=unit_diagonal,
|
|
67
66
|
check_finite=check_finite,
|
|
68
67
|
)
|
|
@@ -16,9 +16,10 @@ from numba.core.errors import NumbaWarning, TypingError
|
|
|
16
16
|
from numba.cpython.unsafe.tuple import tuple_setitem # noqa: F401
|
|
17
17
|
from numba.extending import box, overload
|
|
18
18
|
|
|
19
|
-
from pytensor import config
|
|
19
|
+
from pytensor import In, config
|
|
20
20
|
from pytensor.compile import NUMBA
|
|
21
21
|
from pytensor.compile.builders import OpFromGraph
|
|
22
|
+
from pytensor.compile.function.types import add_supervisor_to_fgraph
|
|
22
23
|
from pytensor.compile.ops import DeepCopyOp
|
|
23
24
|
from pytensor.graph.basic import Apply
|
|
24
25
|
from pytensor.graph.fg import FunctionGraph
|
|
@@ -430,7 +431,13 @@ def numba_funcify_OpFromGraph(op, node=None, **kwargs):
|
|
|
430
431
|
# TODO: Not sure this is the right place to do this, should we have a rewrite that
|
|
431
432
|
# explicitly triggers the optimization of the inner graphs of OpFromGraph?
|
|
432
433
|
# The C-code defers it to the make_thunk phase
|
|
433
|
-
|
|
434
|
+
fgraph = op.fgraph
|
|
435
|
+
add_supervisor_to_fgraph(
|
|
436
|
+
fgraph=fgraph,
|
|
437
|
+
input_specs=[In(x, borrow=True, mutable=False) for x in fgraph.inputs],
|
|
438
|
+
accept_inplace=True,
|
|
439
|
+
)
|
|
440
|
+
NUMBA.optimizer(fgraph)
|
|
434
441
|
fgraph_fn = numba_njit(numba_funcify(op.fgraph, **kwargs))
|
|
435
442
|
|
|
436
443
|
if len(op.fgraph.outputs) == 1:
|
|
@@ -4,6 +4,7 @@ from textwrap import dedent, indent
|
|
|
4
4
|
import numba
|
|
5
5
|
import numpy as np
|
|
6
6
|
from numba.core.extending import overload
|
|
7
|
+
from numpy.lib.stride_tricks import as_strided
|
|
7
8
|
|
|
8
9
|
from pytensor.graph.op import Op
|
|
9
10
|
from pytensor.link.numba.dispatch import basic as numba_basic
|
|
@@ -411,97 +412,38 @@ def numba_funcify_CAReduce(op, node, **kwargs):
|
|
|
411
412
|
|
|
412
413
|
@numba_funcify.register(DimShuffle)
|
|
413
414
|
def numba_funcify_DimShuffle(op, node, **kwargs):
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
415
|
+
# We use `as_strided` to achieve the DimShuffle behavior of transposing and expanding/squezing dimensions in one call
|
|
416
|
+
# Numba doesn't currently support multiple expand/squeeze, and reshape is limited to contiguous arrays.
|
|
417
|
+
new_order = tuple(op._new_order)
|
|
418
|
+
shape_template = (1,) * node.outputs[0].ndim
|
|
419
|
+
strides_template = (0,) * node.outputs[0].ndim
|
|
418
420
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
no_transpose = all(i == j for i, j in enumerate(transposition))
|
|
422
|
-
if no_transpose:
|
|
423
|
-
|
|
424
|
-
@numba_basic.numba_njit
|
|
425
|
-
def transpose(x):
|
|
426
|
-
return x
|
|
427
|
-
|
|
428
|
-
else:
|
|
421
|
+
if new_order == ():
|
|
422
|
+
# Special case needed because of https://github.com/numba/numba/issues/9933
|
|
429
423
|
|
|
430
424
|
@numba_basic.numba_njit
|
|
431
|
-
def
|
|
432
|
-
return
|
|
433
|
-
|
|
434
|
-
shape_template = (1,) * ndim_new_shape
|
|
435
|
-
|
|
436
|
-
# When `len(shuffle) == 0`, the `shuffle_shape[j]` expression below
|
|
437
|
-
# is typed as `getitem(Tuple(), int)`, which has no implementation
|
|
438
|
-
# (since getting an item from an empty sequence doesn't make sense).
|
|
439
|
-
# To avoid this compile-time error, we omit the expression altogether.
|
|
440
|
-
if len(shuffle) > 0:
|
|
441
|
-
# Use the statically known shape if available
|
|
442
|
-
if all(length is not None for length in node.outputs[0].type.shape):
|
|
443
|
-
shape = node.outputs[0].type.shape
|
|
444
|
-
|
|
445
|
-
@numba_basic.numba_njit
|
|
446
|
-
def find_shape(array_shape):
|
|
447
|
-
return shape
|
|
448
|
-
|
|
449
|
-
else:
|
|
450
|
-
|
|
451
|
-
@numba_basic.numba_njit
|
|
452
|
-
def find_shape(array_shape):
|
|
453
|
-
shape = shape_template
|
|
454
|
-
j = 0
|
|
455
|
-
for i in range(ndim_new_shape):
|
|
456
|
-
if i not in augment:
|
|
457
|
-
length = array_shape[j]
|
|
458
|
-
shape = numba_basic.tuple_setitem(shape, i, length)
|
|
459
|
-
j = j + 1
|
|
460
|
-
return shape
|
|
461
|
-
|
|
462
|
-
else:
|
|
463
|
-
|
|
464
|
-
@numba_basic.numba_njit
|
|
465
|
-
def find_shape(array_shape):
|
|
466
|
-
return shape_template
|
|
467
|
-
|
|
468
|
-
if ndim_new_shape > 0:
|
|
469
|
-
|
|
470
|
-
@numba_basic.numba_njit
|
|
471
|
-
def dimshuffle_inner(x, shuffle):
|
|
472
|
-
x = transpose(x)
|
|
473
|
-
shuffle_shape = x.shape[: len(shuffle)]
|
|
474
|
-
new_shape = find_shape(shuffle_shape)
|
|
475
|
-
|
|
476
|
-
# FIXME: Numba's `array.reshape` only accepts C arrays.
|
|
477
|
-
res_reshape = np.reshape(np.ascontiguousarray(x), new_shape)
|
|
425
|
+
def squeeze_to_0d(x):
|
|
426
|
+
return as_strided(x, shape=(), strides=())
|
|
478
427
|
|
|
479
|
-
|
|
480
|
-
return res_reshape.copy()
|
|
481
|
-
else:
|
|
482
|
-
return res_reshape
|
|
428
|
+
return squeeze_to_0d
|
|
483
429
|
|
|
484
430
|
else:
|
|
485
431
|
|
|
486
432
|
@numba_basic.numba_njit
|
|
487
|
-
def
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
# E shuffle_shape = res.shape[: len(shuffle)]
|
|
502
|
-
@numba_basic.numba_njit(inline="always")
|
|
503
|
-
def dimshuffle(x):
|
|
504
|
-
return dimshuffle_inner(np.asarray(x), shuffle)
|
|
433
|
+
def dimshuffle(x):
|
|
434
|
+
old_shape = x.shape
|
|
435
|
+
old_strides = x.strides
|
|
436
|
+
|
|
437
|
+
new_shape = shape_template
|
|
438
|
+
new_strides = strides_template
|
|
439
|
+
for i, o in enumerate(new_order):
|
|
440
|
+
if o != -1:
|
|
441
|
+
new_shape = numba_basic.tuple_setitem(new_shape, i, old_shape[o])
|
|
442
|
+
new_strides = numba_basic.tuple_setitem(
|
|
443
|
+
new_strides, i, old_strides[o]
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
return as_strided(x, shape=new_shape, strides=new_strides)
|
|
505
447
|
|
|
506
448
|
return dimshuffle
|
|
507
449
|
|