pytensor 2.31.0__tar.gz → 2.31.1__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.31.0/pytensor.egg-info → pytensor-2.31.1}/PKG-INFO +1 -1
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/_version.py +3 -3
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/mode.py +2 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scan/rewriting.py +4 -6
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/__init__.py +1 -0
- pytensor-2.31.1/pytensor/tensor/_linalg/__init__.py +2 -0
- pytensor-2.31.1/pytensor/tensor/_linalg/solve/__init__.py +2 -0
- pytensor-2.31.1/pytensor/tensor/_linalg/solve/rewriting.py +198 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/blas_c.py +88 -112
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/linalg.py +7 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/subtensor.py +10 -1
- {pytensor-2.31.0 → pytensor-2.31.1/pytensor.egg-info}/PKG-INFO +1 -1
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor.egg-info/SOURCES.txt +3 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/LICENSE.txt +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/MANIFEST.in +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/README.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/.templates/PLACEHOLDER +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/.templates/layout.html +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/.templates/nb-badges.html +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/.templates/rendered_citation.html +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/LICENSE.txt +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/README.md +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/acknowledgement.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/bcast.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/bcast.svg +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/blog.md +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/conf.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/core_development_guide.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/css.inc +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/dev_start_guide.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/environment.yml +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/apply.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/apply.svg +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/apply2.svg +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/creating_a_c_op.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/creating_a_numba_jax_op.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/creating_an_op.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/ctype.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/extending_faq.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/extending_pytensor_solution_1.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/graph_rewriting.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/graphstructures.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/index.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/inplace.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/op.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/other_ops.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/pics/symbolic_graph_opt.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/pipeline.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/scan.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/tips.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/type.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/unittest.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/extending/using_params.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/faq.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/gallery/page_footer.md +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/gallery/rewrites/graph_rewrites.ipynb +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/gallery/scan/scan_tutorial.ipynb +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/generate_dtype_tensor_table.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/glossary.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/images/Elman_srnn.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/images/PyTensor.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/images/PyTensor_RGB.svg +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/images/PyTensor_logo.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/images/binder.svg +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/images/blocksparse.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/images/colab.svg +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/images/github.svg +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/images/lstm.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/images/lstm_memorycell.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/images/talk2010.gif +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/images/talk2010.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/index.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/install.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/internal/how_to_release.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/internal/index.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/internal/metadocumentation.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/introduction.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/compile/debugmode.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/compile/function.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/compile/index.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/compile/io.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/compile/mode.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/compile/nanguardmode.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/compile/opfromgraph.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/compile/ops.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/compile/profilemode.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/compile/shared.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/config.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/mlp.html +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/mlp.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/mlp2.html +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/mlp2.pdf +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/mlp2.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/ofg.html +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/examples/ofg2.html +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/index.ipynb +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/index.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/index_files/index_10_0.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/index_files/index_11_0.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/index_files/index_24_0.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/d3viz/index_files/index_25_0.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/graph/features.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/graph/fgraph.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/graph/graph.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/graph/index.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/graph/op.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/graph/replace.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/graph/type.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/graph/utils.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/index.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/misc/pkl_utils.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/printing.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/scalar/index.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/scan.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/sparse/index.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/sparse/sandbox.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/basic.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/basic_opt.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/bcast.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/bcast.svg +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/conv.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/elemwise.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/extra_ops.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/fft.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/functional.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/index.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/io.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/math_opt.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/nlinalg.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/plot_fft.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/random/distributions.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/random/index.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/slinalg.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/tensor/utils.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/library/typed_list.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/links.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/optimizations.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/pylintrc +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/robots.txt +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/troubleshooting.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/adding.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/adding_solution_1.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/aliasing.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/apply.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/apply.svg +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/bcast.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/broadcasting.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/conditions.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/debug_faq.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/dlogistic.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/examples.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/faq_tutorial.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/gradients.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/index.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/loading_and_saving.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/logistic.gp +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/logistic.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/loop.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/loop_solution_1.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/modes.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/modes_solution_1.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/multi_cores.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/nan_tutorial.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/pics/d3viz.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/printing_drawing.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/prng.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/profiling.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/profiling_example.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/profiling_example_out.prof +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/shape_info.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/sparse.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/tutorial/symbolic_graphs.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/doc/user_guide.rst +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pyproject.toml +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/bin/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/bin/pytensor_cache.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/breakpoint.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/builders.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/compiledir.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/compilelock.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/debugmode.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/function/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/function/pfunc.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/function/types.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/io.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/monitormode.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/nanguardmode.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/ops.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/profiling.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/compile/sharedvalue.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/configdefaults.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/configparser.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/d3viz/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/d3viz/css/d3viz.css +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/d3viz/d3viz.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/d3viz/formatting.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/d3viz/html/template.html +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/d3viz/js/d3viz.js +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/gradient.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/destroyhandler.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/features.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/fg.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/null_type.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/op.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/replace.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/rewriting/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/rewriting/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/rewriting/db.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/rewriting/kanren.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/rewriting/unify.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/rewriting/utils.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/type.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/graph/utils.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/ifelse.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/cmodule.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/cutils.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/cvm.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/exceptions.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/interface.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/lazylinker_c.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/op.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/params_type.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/c/type.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/blas.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/blockwise.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/einsum.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/elemwise.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/math.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/nlinalg.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/pad.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/random.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/scalar.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/scan.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/shape.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/signal/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/signal/conv.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/slinalg.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/sort.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/sparse.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/subtensor.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/jax/linker.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/blockwise.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/cython_support.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/elemwise.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/_LAPACK.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/decomposition/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/decomposition/cholesky.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/decomposition/lu.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/decomposition/lu_factor.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/solve/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/solve/cholesky.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/solve/general.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/solve/lu_solve.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/solve/norm.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/solve/posdef.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/solve/symmetric.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/solve/triangular.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/solve/tridiagonal.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/solve/utils.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/linalg/utils.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/random.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/scalar.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/scan.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/signal/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/signal/conv.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/slinalg.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/sparse.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/subtensor.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/dispatch/vectorize_codegen.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/numba/linker.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/dispatch/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/dispatch/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/dispatch/blas.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/dispatch/blockwise.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/dispatch/elemwise.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/dispatch/extra_ops.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/dispatch/math.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/dispatch/nlinalg.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/dispatch/scalar.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/dispatch/shape.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/dispatch/sort.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/dispatch/subtensor.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/pytorch/linker.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/utils.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/link/vm.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/misc/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/misc/check_blas.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/misc/check_blas_many.sh +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/misc/check_duplicate_key.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/misc/elemwise_time_test.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/misc/frozendict.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/misc/may_share_memory.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/misc/ordered_set.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/misc/pkl_utils.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/npy_2_compat.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/printing.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/py.typed +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/raise_op.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scalar/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scalar/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scalar/c_code/gamma.c +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scalar/c_code/incbet.c +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scalar/loop.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scalar/math.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scalar/sharedvar.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scan/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scan/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scan/checkpoints.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scan/op.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scan/scan_perform.pyx +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scan/scan_perform_ext.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scan/utils.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/scan/views.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/sparse/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/sparse/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/sparse/rewriting.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/sparse/sandbox/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/sparse/sandbox/sp.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/sparse/sandbox/sp2.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/sparse/sharedvar.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/sparse/type.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/sparse/utils.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/blas.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/blas_headers.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/blas_scipy.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/blockwise.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/c_code/dimshuffle.c +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/conv/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/conv/abstract_conv.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/einsum.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/elemwise.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/elemwise_cgen.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/exceptions.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/extra_ops.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/fft.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/fourier.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/functional.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/inplace.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/interpolate.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/io.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/linalg.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/math.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/nlinalg.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/pad.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/random/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/random/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/random/op.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/random/rewriting/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/random/rewriting/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/random/rewriting/jax.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/random/rewriting/numba.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/random/type.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/random/utils.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/random/var.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/blas.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/blas_c.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/blas_scipy.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/blockwise.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/conv.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/einsum.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/elemwise.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/extra_ops.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/jax.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/math.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/numba.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/ofg.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/shape.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/special.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/subtensor_lift.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/shape.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/sharedvar.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/signal/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/signal/conv.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/slinalg.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/sort.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/special.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/subtensor.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/type.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/type_other.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/utils.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/var.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/variable.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/tensor/xlogx.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/typed_list/__init__.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/typed_list/basic.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/typed_list/rewriting.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/typed_list/type.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/updates.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor/utils.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor.egg-info/dependency_links.txt +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor.egg-info/entry_points.txt +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor.egg-info/requires.txt +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/pytensor.egg-info/top_level.txt +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/scripts/mypy-failing.txt +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/scripts/slowest_tests/update-slowest-times-issue.sh +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/setup.cfg +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/setup.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/tests/link/c/c_code/test_cenum.h +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/tests/link/c/c_code/test_quadratic_function.c +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/tests/tensor/conv/c_code/corr3d_gemm.c +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/tests/tensor/conv/c_code/corr_gemm.c +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/tests/test_breakpoint.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/tests/test_config.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/tests/test_gradient.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/tests/test_ifelse.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/tests/test_printing.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/tests/test_raise_op.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/tests/test_rop.py +0 -0
- {pytensor-2.31.0 → pytensor-2.31.1}/tests/test_updates.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2025-05-
|
|
11
|
+
"date": "2025-05-22T00:05:15+0800",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.31.
|
|
14
|
+
"full-revisionid": "4829455bac15db5db652e3ab73e6baf08f6ea8b9",
|
|
15
|
+
"version": "2.31.1"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -2561,7 +2561,6 @@ scan_seqopt1.register(
|
|
|
2561
2561
|
position=1,
|
|
2562
2562
|
)
|
|
2563
2563
|
|
|
2564
|
-
|
|
2565
2564
|
scan_seqopt1.register(
|
|
2566
2565
|
"scan_push_out_non_seq",
|
|
2567
2566
|
in2out(scan_push_out_non_seq, ignore_newtrees=True),
|
|
@@ -2569,10 +2568,9 @@ scan_seqopt1.register(
|
|
|
2569
2568
|
"fast_run",
|
|
2570
2569
|
"scan",
|
|
2571
2570
|
"scan_pushout",
|
|
2572
|
-
position=
|
|
2571
|
+
position=3,
|
|
2573
2572
|
)
|
|
2574
2573
|
|
|
2575
|
-
|
|
2576
2574
|
scan_seqopt1.register(
|
|
2577
2575
|
"scan_push_out_seq",
|
|
2578
2576
|
in2out(scan_push_out_seq, ignore_newtrees=True),
|
|
@@ -2580,7 +2578,7 @@ scan_seqopt1.register(
|
|
|
2580
2578
|
"fast_run",
|
|
2581
2579
|
"scan",
|
|
2582
2580
|
"scan_pushout",
|
|
2583
|
-
position=
|
|
2581
|
+
position=4,
|
|
2584
2582
|
)
|
|
2585
2583
|
|
|
2586
2584
|
|
|
@@ -2592,7 +2590,7 @@ scan_seqopt1.register(
|
|
|
2592
2590
|
"more_mem",
|
|
2593
2591
|
"scan",
|
|
2594
2592
|
"scan_pushout",
|
|
2595
|
-
position=
|
|
2593
|
+
position=5,
|
|
2596
2594
|
)
|
|
2597
2595
|
|
|
2598
2596
|
|
|
@@ -2605,7 +2603,7 @@ scan_seqopt1.register(
|
|
|
2605
2603
|
"more_mem",
|
|
2606
2604
|
"scan",
|
|
2607
2605
|
"scan_pushout",
|
|
2608
|
-
position=
|
|
2606
|
+
position=6,
|
|
2609
2607
|
)
|
|
2610
2608
|
|
|
2611
2609
|
scan_eqopt2.register(
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
from collections.abc import Container
|
|
2
|
+
from copy import copy
|
|
3
|
+
|
|
4
|
+
from pytensor.graph import Constant, graph_inputs
|
|
5
|
+
from pytensor.graph.rewriting.basic import copy_stack_trace, in2out, node_rewriter
|
|
6
|
+
from pytensor.scan.op import Scan
|
|
7
|
+
from pytensor.scan.rewriting import scan_seqopt1
|
|
8
|
+
from pytensor.tensor.basic import atleast_Nd
|
|
9
|
+
from pytensor.tensor.blockwise import Blockwise
|
|
10
|
+
from pytensor.tensor.elemwise import DimShuffle
|
|
11
|
+
from pytensor.tensor.rewriting.basic import register_specialize
|
|
12
|
+
from pytensor.tensor.rewriting.linalg import is_matrix_transpose
|
|
13
|
+
from pytensor.tensor.slinalg import Solve, lu_factor, lu_solve
|
|
14
|
+
from pytensor.tensor.variable import TensorVariable
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def decompose_A(A, assume_a):
|
|
18
|
+
if assume_a == "gen":
|
|
19
|
+
return lu_factor(A, check_finite=False)
|
|
20
|
+
else:
|
|
21
|
+
raise NotImplementedError
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def solve_lu_decomposed_system(A_decomp, b, b_ndim, assume_a, transposed=False):
|
|
25
|
+
if assume_a == "gen":
|
|
26
|
+
return lu_solve(A_decomp, b, b_ndim=b_ndim, trans=transposed)
|
|
27
|
+
else:
|
|
28
|
+
raise NotImplementedError
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _split_lu_solve_steps(
|
|
32
|
+
fgraph, node, *, eager: bool, allowed_assume_a: Container[str]
|
|
33
|
+
):
|
|
34
|
+
if not isinstance(node.op.core_op, Solve):
|
|
35
|
+
return None
|
|
36
|
+
|
|
37
|
+
def get_root_A(a: TensorVariable) -> tuple[TensorVariable, bool]:
|
|
38
|
+
# Find the root variable of the first input to Solve
|
|
39
|
+
# If `a` is a left expand_dims or matrix transpose (DimShuffle variants),
|
|
40
|
+
# the root variable is the pre-DimShuffled input.
|
|
41
|
+
# Otherwise, `a` is considered the root variable.
|
|
42
|
+
# We also return whether the root `a` is transposed.
|
|
43
|
+
transposed = False
|
|
44
|
+
if a.owner is not None and isinstance(a.owner.op, DimShuffle):
|
|
45
|
+
if a.owner.op.is_left_expand_dims:
|
|
46
|
+
[a] = a.owner.inputs
|
|
47
|
+
elif is_matrix_transpose(a):
|
|
48
|
+
[a] = a.owner.inputs
|
|
49
|
+
transposed = True
|
|
50
|
+
return a, transposed
|
|
51
|
+
|
|
52
|
+
def find_solve_clients(var, assume_a):
|
|
53
|
+
clients = []
|
|
54
|
+
for cl, idx in fgraph.clients[var]:
|
|
55
|
+
if (
|
|
56
|
+
idx == 0
|
|
57
|
+
and isinstance(cl.op, Blockwise)
|
|
58
|
+
and isinstance(cl.op.core_op, Solve)
|
|
59
|
+
and (cl.op.core_op.assume_a == assume_a)
|
|
60
|
+
):
|
|
61
|
+
clients.append(cl)
|
|
62
|
+
elif isinstance(cl.op, DimShuffle) and cl.op.is_left_expand_dims:
|
|
63
|
+
# If it's a left expand_dims, recurse on the output
|
|
64
|
+
clients.extend(find_solve_clients(cl.outputs[0], assume_a))
|
|
65
|
+
return clients
|
|
66
|
+
|
|
67
|
+
assume_a = node.op.core_op.assume_a
|
|
68
|
+
|
|
69
|
+
if assume_a not in allowed_assume_a:
|
|
70
|
+
return None
|
|
71
|
+
|
|
72
|
+
A, _ = get_root_A(node.inputs[0])
|
|
73
|
+
|
|
74
|
+
# Find Solve using A (or left expand_dims of A)
|
|
75
|
+
# TODO: We could handle arbitrary shuffle of the batch dimensions, just need to propagate
|
|
76
|
+
# that to the A_decomp outputs
|
|
77
|
+
A_solve_clients_and_transpose = [
|
|
78
|
+
(client, False) for client in find_solve_clients(A, assume_a)
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
# Find Solves using A.T
|
|
82
|
+
for cl, _ in fgraph.clients[A]:
|
|
83
|
+
if isinstance(cl.op, DimShuffle) and is_matrix_transpose(cl.out):
|
|
84
|
+
A_T = cl.out
|
|
85
|
+
A_solve_clients_and_transpose.extend(
|
|
86
|
+
(client, True) for client in find_solve_clients(A_T, assume_a)
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
if not eager and len(A_solve_clients_and_transpose) == 1:
|
|
90
|
+
# If theres' a single use don't do it... unless it's being broadcast in a Blockwise (or we're eager)
|
|
91
|
+
# That's a "reuse" inside the inner vectorized loop
|
|
92
|
+
batch_ndim = node.op.batch_ndim(node)
|
|
93
|
+
(client, _) = A_solve_clients_and_transpose[0]
|
|
94
|
+
original_A, b = client.inputs
|
|
95
|
+
if not any(
|
|
96
|
+
a_bcast and not b_bcast
|
|
97
|
+
for a_bcast, b_bcast in zip(
|
|
98
|
+
original_A.type.broadcastable[:batch_ndim],
|
|
99
|
+
b.type.broadcastable[:batch_ndim],
|
|
100
|
+
strict=True,
|
|
101
|
+
)
|
|
102
|
+
):
|
|
103
|
+
return None
|
|
104
|
+
|
|
105
|
+
A_decomp = decompose_A(A, assume_a=assume_a)
|
|
106
|
+
|
|
107
|
+
replacements = {}
|
|
108
|
+
for client, transposed in A_solve_clients_and_transpose:
|
|
109
|
+
_, b = client.inputs
|
|
110
|
+
b_ndim = client.op.core_op.b_ndim
|
|
111
|
+
new_x = solve_lu_decomposed_system(
|
|
112
|
+
A_decomp, b, b_ndim=b_ndim, assume_a=assume_a, transposed=transposed
|
|
113
|
+
)
|
|
114
|
+
[old_x] = client.outputs
|
|
115
|
+
new_x = atleast_Nd(new_x, n=old_x.type.ndim).astype(old_x.type.dtype)
|
|
116
|
+
copy_stack_trace(old_x, new_x)
|
|
117
|
+
replacements[old_x] = new_x
|
|
118
|
+
|
|
119
|
+
return replacements
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _scan_split_non_sequence_lu_decomposition_solve(
|
|
123
|
+
fgraph, node, *, allowed_assume_a: Container[str]
|
|
124
|
+
):
|
|
125
|
+
"""If the A of a Solve within a Scan is a function of non-sequences, split the LU decomposition step.
|
|
126
|
+
|
|
127
|
+
The LU decomposition step can then be pushed out of the inner loop by the `scan_pushout_non_sequences` rewrite.
|
|
128
|
+
"""
|
|
129
|
+
scan_op: Scan = node.op
|
|
130
|
+
non_sequences = set(scan_op.inner_non_seqs(scan_op.inner_inputs))
|
|
131
|
+
new_scan_fgraph = scan_op.fgraph
|
|
132
|
+
|
|
133
|
+
changed = False
|
|
134
|
+
while True:
|
|
135
|
+
for inner_node in new_scan_fgraph.toposort():
|
|
136
|
+
if (
|
|
137
|
+
isinstance(inner_node.op, Blockwise)
|
|
138
|
+
and isinstance(inner_node.op.core_op, Solve)
|
|
139
|
+
and inner_node.op.core_op.assume_a in allowed_assume_a
|
|
140
|
+
):
|
|
141
|
+
A, b = inner_node.inputs
|
|
142
|
+
if all(
|
|
143
|
+
(isinstance(root_inp, Constant) or (root_inp in non_sequences))
|
|
144
|
+
for root_inp in graph_inputs([A])
|
|
145
|
+
):
|
|
146
|
+
if new_scan_fgraph is scan_op.fgraph:
|
|
147
|
+
# Clone the first time to avoid mutating the original fgraph
|
|
148
|
+
new_scan_fgraph, equiv = new_scan_fgraph.clone_get_equiv()
|
|
149
|
+
non_sequences = {equiv[non_seq] for non_seq in non_sequences}
|
|
150
|
+
inner_node = equiv[inner_node] # type: ignore
|
|
151
|
+
|
|
152
|
+
replace_dict = _split_lu_solve_steps(
|
|
153
|
+
new_scan_fgraph,
|
|
154
|
+
inner_node,
|
|
155
|
+
eager=True,
|
|
156
|
+
allowed_assume_a=allowed_assume_a,
|
|
157
|
+
)
|
|
158
|
+
assert (
|
|
159
|
+
isinstance(replace_dict, dict) and len(replace_dict) > 0
|
|
160
|
+
), "Rewrite failed"
|
|
161
|
+
new_scan_fgraph.replace_all(replace_dict.items())
|
|
162
|
+
changed = True
|
|
163
|
+
break # Break to start over with a fresh toposort
|
|
164
|
+
else: # no_break
|
|
165
|
+
break # Nothing else changed
|
|
166
|
+
|
|
167
|
+
if not changed:
|
|
168
|
+
return
|
|
169
|
+
|
|
170
|
+
# Return a new scan to indicate that a rewrite was done
|
|
171
|
+
new_scan_op = copy(scan_op)
|
|
172
|
+
new_scan_op.fgraph = new_scan_fgraph
|
|
173
|
+
new_outs = new_scan_op.make_node(*node.inputs).outputs
|
|
174
|
+
copy_stack_trace(node.outputs, new_outs)
|
|
175
|
+
return new_outs
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
@register_specialize
|
|
179
|
+
@node_rewriter([Blockwise])
|
|
180
|
+
def reuse_lu_decomposition_multiple_solves(fgraph, node):
|
|
181
|
+
return _split_lu_solve_steps(fgraph, node, eager=False, allowed_assume_a={"gen"})
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
@node_rewriter([Scan])
|
|
185
|
+
def scan_split_non_sequence_lu_decomposition_solve(fgraph, node):
|
|
186
|
+
return _scan_split_non_sequence_lu_decomposition_solve(
|
|
187
|
+
fgraph, node, allowed_assume_a={"gen"}
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
scan_seqopt1.register(
|
|
192
|
+
"scan_split_non_sequence_lu_decomposition_solve",
|
|
193
|
+
in2out(scan_split_non_sequence_lu_decomposition_solve, ignore_newtrees=True),
|
|
194
|
+
"fast_run",
|
|
195
|
+
"scan",
|
|
196
|
+
"scan_pushout",
|
|
197
|
+
position=2,
|
|
198
|
+
)
|
|
@@ -344,6 +344,7 @@ def gemv_c_code(y, A, x, z, alpha, beta, fail, force_init_beta=False, params=Non
|
|
|
344
344
|
"""
|
|
345
345
|
code = """
|
|
346
346
|
|
|
347
|
+
bool is_float;
|
|
347
348
|
int elemsize;
|
|
348
349
|
float fbeta;
|
|
349
350
|
double dbeta;
|
|
@@ -361,11 +362,23 @@ def gemv_c_code(y, A, x, z, alpha, beta, fail, force_init_beta=False, params=Non
|
|
|
361
362
|
%(fail)s;
|
|
362
363
|
}
|
|
363
364
|
|
|
364
|
-
if
|
|
365
|
-
|
|
365
|
+
if ((PyArray_DESCR(%(y)s)->type_num != PyArray_DESCR(%(x)s)->type_num)
|
|
366
|
+
|| (PyArray_DESCR(%(y)s)->type_num != PyArray_DESCR(%(A)s)->type_num))
|
|
367
|
+
{
|
|
368
|
+
PyErr_SetString(PyExc_TypeError, "GEMV: dtypes of A, x, y do not match");
|
|
369
|
+
%(fail)s;
|
|
370
|
+
}
|
|
371
|
+
if (PyArray_DESCR(%(y)s)->type_num == NPY_DOUBLE) {
|
|
372
|
+
is_float = 0;
|
|
373
|
+
elemsize = 8;
|
|
374
|
+
}
|
|
375
|
+
else if (PyArray_DESCR(%(y)s)->type_num == NPY_FLOAT) {
|
|
376
|
+
elemsize = 4;
|
|
377
|
+
is_float = 1;
|
|
378
|
+
}
|
|
366
379
|
else {
|
|
367
|
-
PyErr_SetString(PyExc_NotImplementedError, "complex Gemv");
|
|
368
380
|
%(fail)s;
|
|
381
|
+
PyErr_SetString(PyExc_NotImplementedError, "GEMV: Inputs must be float or double");
|
|
369
382
|
}
|
|
370
383
|
|
|
371
384
|
fbeta = dbeta = ((dtype_%(beta)s*)PyArray_DATA(%(beta)s))[0];
|
|
@@ -408,37 +421,40 @@ def gemv_c_code(y, A, x, z, alpha, beta, fail, force_init_beta=False, params=Non
|
|
|
408
421
|
Py_INCREF(%(z)s);
|
|
409
422
|
}
|
|
410
423
|
}
|
|
424
|
+
|
|
411
425
|
{
|
|
412
|
-
char TRANS = 'T';
|
|
413
|
-
char NOTRANS = 'N';
|
|
414
426
|
int NA0 = PyArray_DIMS(%(A)s)[0];
|
|
415
427
|
int NA1 = PyArray_DIMS(%(A)s)[1];
|
|
416
|
-
/* This formula is needed in the case where A is actually a row or
|
|
417
|
-
* column matrix, because BLAS sometimes insists that the strides:
|
|
418
|
-
* - are not smaller than the number of elements in the array
|
|
419
|
-
* - are not 0.
|
|
420
|
-
*/
|
|
421
|
-
int SA0 = (NA0 > 1) ? (PyArray_STRIDES(%(A)s)[0] / elemsize) : (NA1 + 1);
|
|
422
|
-
int SA1 = (NA1 > 1) ? (PyArray_STRIDES(%(A)s)[1] / elemsize) : (NA0 + 1);
|
|
423
|
-
int Sz = PyArray_STRIDES(%(z)s)[0] / elemsize;
|
|
424
|
-
int Sx = PyArray_STRIDES(%(x)s)[0] / elemsize;
|
|
425
|
-
|
|
426
|
-
dtype_%(A)s* A_data = (dtype_%(A)s*) PyArray_DATA(%(A)s);
|
|
427
|
-
dtype_%(x)s* x_data = (dtype_%(x)s*) PyArray_DATA(%(x)s);
|
|
428
|
-
dtype_%(z)s* z_data = (dtype_%(z)s*) PyArray_DATA(%(z)s);
|
|
429
|
-
// gemv expects pointers to the beginning of memory arrays,
|
|
430
|
-
// but numpy provides a pointer to the first element,
|
|
431
|
-
// so when the stride is negative, we need to get the last one.
|
|
432
|
-
if (Sx < 0)
|
|
433
|
-
x_data += (NA1 - 1) * Sx;
|
|
434
|
-
if (Sz < 0)
|
|
435
|
-
z_data += (NA0 - 1) * Sz;
|
|
436
428
|
|
|
437
429
|
if (NA0 * NA1)
|
|
438
430
|
{
|
|
431
|
+
// Non-empty A matrix
|
|
432
|
+
|
|
433
|
+
/* In the case where A is actually a row or column matrix,
|
|
434
|
+
* the strides corresponding to the dummy dimension don't matter,
|
|
435
|
+
* but BLAS requires these to be no smaller than the number of elements in the array.
|
|
436
|
+
*/
|
|
437
|
+
int SA0 = (NA0 > 1) ? (PyArray_STRIDES(%(A)s)[0] / elemsize) : NA1;
|
|
438
|
+
int SA1 = (NA1 > 1) ? (PyArray_STRIDES(%(A)s)[1] / elemsize) : NA0;
|
|
439
|
+
int Sz = PyArray_STRIDES(%(z)s)[0] / elemsize;
|
|
440
|
+
int Sx = PyArray_STRIDES(%(x)s)[0] / elemsize;
|
|
441
|
+
|
|
442
|
+
dtype_%(A)s* A_data = (dtype_%(A)s*) PyArray_DATA(%(A)s);
|
|
443
|
+
dtype_%(x)s* x_data = (dtype_%(x)s*) PyArray_DATA(%(x)s);
|
|
444
|
+
dtype_%(z)s* z_data = (dtype_%(z)s*) PyArray_DATA(%(z)s);
|
|
445
|
+
|
|
446
|
+
// gemv expects pointers to the beginning of memory arrays,
|
|
447
|
+
// but numpy provides a pointer to the first element,
|
|
448
|
+
// so when the stride is negative, we need to get the last one.
|
|
449
|
+
if (Sx < 0)
|
|
450
|
+
x_data += (NA1 - 1) * Sx;
|
|
451
|
+
if (Sz < 0)
|
|
452
|
+
z_data += (NA0 - 1) * Sz;
|
|
453
|
+
|
|
439
454
|
if ( ((SA0 < 0) || (SA1 < 0)) && (abs(SA0) == 1 || (abs(SA1) == 1)) )
|
|
440
455
|
{
|
|
441
456
|
// We can treat the array A as C-or F-contiguous by changing the order of iteration
|
|
457
|
+
// printf("GEMV: Iterating in reverse NA0=%%d, NA1=%%d, SA0=%%d, SA1=%%d\\n", NA0, NA1, SA0, SA1);
|
|
442
458
|
if (SA0 < 0){
|
|
443
459
|
A_data += (NA0 -1) * SA0; // Jump to first row
|
|
444
460
|
SA0 = -SA0; // Iterate over rows in reverse
|
|
@@ -452,27 +468,45 @@ def gemv_c_code(y, A, x, z, alpha, beta, fail, force_init_beta=False, params=Non
|
|
|
452
468
|
} else if ((SA0 < 0) || (SA1 < 0) || ((SA0 != 1) && (SA1 != 1)))
|
|
453
469
|
{
|
|
454
470
|
// Array isn't contiguous, we have to make a copy
|
|
455
|
-
// - if the copy is too long, maybe call vector/vector dot on
|
|
456
|
-
//
|
|
457
|
-
// printf("GEMV: Making a copy SA0=%%d, SA1=%%d\\n", SA0, SA1);
|
|
471
|
+
// - if the copy is too long, maybe call vector/vector dot on each row instead
|
|
472
|
+
// printf("GEMV: Making a copy NA0=%%d, NA1=%%d, SA0=%%d, SA1=%%d\\n", NA0, NA1, SA0, SA1);
|
|
458
473
|
npy_intp dims[2];
|
|
459
474
|
dims[0] = NA0;
|
|
460
475
|
dims[1] = NA1;
|
|
461
|
-
|
|
462
|
-
PyArrayObject * A_copy = (PyArrayObject *) PyArray_Copy(
|
|
463
|
-
%(A)s);
|
|
476
|
+
PyArrayObject * A_copy = (PyArrayObject *) PyArray_Copy(%(A)s);
|
|
464
477
|
if (!A_copy)
|
|
465
478
|
%(fail)s
|
|
466
479
|
Py_XDECREF(%(A)s);
|
|
467
480
|
%(A)s = A_copy;
|
|
468
|
-
SA0 = (NA0 > 1) ? (PyArray_STRIDES(%(A)s)[0] / elemsize) :
|
|
469
|
-
SA1 = (NA1 > 1) ? (PyArray_STRIDES(%(A)s)[1] / elemsize) :
|
|
481
|
+
SA0 = (NA0 > 1) ? (PyArray_STRIDES(%(A)s)[0] / elemsize) : NA1;
|
|
482
|
+
SA1 = (NA1 > 1) ? (PyArray_STRIDES(%(A)s)[1] / elemsize) : NA0;
|
|
470
483
|
A_data = (dtype_%(A)s*) PyArray_DATA(%(A)s);
|
|
471
484
|
}
|
|
485
|
+
//else {printf("GEMV: Using the original array NA0=%%d, NA1=%%d, SA0=%%d, SA1=%%d\\n", NA0, NA1, SA0, SA1);}
|
|
472
486
|
|
|
473
|
-
if (
|
|
487
|
+
if (NA0 == 1)
|
|
488
|
+
{
|
|
489
|
+
// Vector-vector dot product, it seems faster to avoid GEMV
|
|
490
|
+
dtype_%(alpha)s alpha = ((dtype_%(alpha)s*)PyArray_DATA(%(alpha)s))[0];
|
|
491
|
+
|
|
492
|
+
if (is_float)
|
|
493
|
+
{
|
|
494
|
+
z_data[0] *= fbeta;
|
|
495
|
+
z_data[0] += alpha * sdot_(&NA1, (float*)(A_data), &SA1,
|
|
496
|
+
(float*)x_data, &Sx);
|
|
497
|
+
}
|
|
498
|
+
else
|
|
499
|
+
{
|
|
500
|
+
z_data[0] *= dbeta;
|
|
501
|
+
z_data[0] += alpha * ddot_(&NA1, (double*)(A_data), &SA1,
|
|
502
|
+
(double*)x_data, &Sx);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
else if (SA0 == 1)
|
|
474
506
|
{
|
|
475
|
-
|
|
507
|
+
// F-contiguous
|
|
508
|
+
char NOTRANS = 'N';
|
|
509
|
+
if (is_float)
|
|
476
510
|
{
|
|
477
511
|
float alpha = ((dtype_%(alpha)s*)PyArray_DATA(%(alpha)s))[0];
|
|
478
512
|
sgemv_(&NOTRANS, &NA0, &NA1,
|
|
@@ -482,7 +516,7 @@ def gemv_c_code(y, A, x, z, alpha, beta, fail, force_init_beta=False, params=Non
|
|
|
482
516
|
&fbeta,
|
|
483
517
|
(float*)z_data, &Sz);
|
|
484
518
|
}
|
|
485
|
-
else
|
|
519
|
+
else
|
|
486
520
|
{
|
|
487
521
|
double alpha = ((dtype_%(alpha)s*)PyArray_DATA(%(alpha)s))[0];
|
|
488
522
|
dgemv_(&NOTRANS, &NA0, &NA1,
|
|
@@ -492,97 +526,39 @@ def gemv_c_code(y, A, x, z, alpha, beta, fail, force_init_beta=False, params=Non
|
|
|
492
526
|
&dbeta,
|
|
493
527
|
(double*)z_data, &Sz);
|
|
494
528
|
}
|
|
495
|
-
else
|
|
496
|
-
{
|
|
497
|
-
PyErr_SetString(PyExc_AssertionError,
|
|
498
|
-
"neither float nor double dtype");
|
|
499
|
-
%(fail)s
|
|
500
|
-
}
|
|
501
529
|
}
|
|
502
530
|
else if (SA1 == 1)
|
|
503
531
|
{
|
|
504
|
-
|
|
532
|
+
// C-contiguous
|
|
533
|
+
char TRANS = 'T';
|
|
534
|
+
if (is_float)
|
|
505
535
|
{
|
|
506
536
|
float alpha = ((dtype_%(alpha)s*)PyArray_DATA(%(alpha)s))[0];
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
if (fbeta != 0.f) {
|
|
514
|
-
z_data[0] = fbeta*z_data[0];
|
|
515
|
-
} else {
|
|
516
|
-
z_data[0] = 0.f;
|
|
517
|
-
}
|
|
518
|
-
z_data[0] += alpha*sdot_(&NA1,
|
|
519
|
-
(float*)(A_data), &SA1,
|
|
520
|
-
(float*)x_data, &Sx);
|
|
521
|
-
}
|
|
522
|
-
else
|
|
523
|
-
{
|
|
524
|
-
sgemv_(&TRANS, &NA1, &NA0,
|
|
525
|
-
&alpha,
|
|
526
|
-
(float*)(A_data), &SA0,
|
|
527
|
-
(float*)x_data, &Sx,
|
|
528
|
-
&fbeta,
|
|
529
|
-
(float*)z_data, &Sz);
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
else if (PyArray_DESCR(%(A)s)->type_num == NPY_DOUBLE)
|
|
533
|
-
{
|
|
534
|
-
double alpha = ((dtype_%(alpha)s*)PyArray_DATA(%(alpha)s))[0];
|
|
535
|
-
|
|
536
|
-
// Check for vector-vector dot (NA0 == 1). The code may work
|
|
537
|
-
// for SA1 != 1 as well, but has not been tested for this case,
|
|
538
|
-
// so SA1 == 1 is required for safety.
|
|
539
|
-
if (NA0 == 1 && SA1 == 1)
|
|
540
|
-
{
|
|
541
|
-
if (dbeta != 0.) {
|
|
542
|
-
z_data[0] = dbeta*z_data[0];
|
|
543
|
-
} else {
|
|
544
|
-
z_data[0] = 0.;
|
|
545
|
-
}
|
|
546
|
-
z_data[0] += alpha*ddot_(&NA1,
|
|
547
|
-
(double*)(A_data), &SA1,
|
|
548
|
-
(double*)x_data, &Sx);
|
|
549
|
-
}
|
|
550
|
-
else
|
|
551
|
-
{
|
|
552
|
-
dgemv_(&TRANS, &NA1, &NA0,
|
|
553
|
-
&alpha,
|
|
554
|
-
(double*)(A_data), &SA0,
|
|
555
|
-
(double*)x_data, &Sx,
|
|
556
|
-
&dbeta,
|
|
557
|
-
(double*)z_data, &Sz);
|
|
558
|
-
}
|
|
537
|
+
sgemv_(&TRANS, &NA1, &NA0,
|
|
538
|
+
&alpha,
|
|
539
|
+
(float*)(A_data), &SA0,
|
|
540
|
+
(float*)x_data, &Sx,
|
|
541
|
+
&fbeta,
|
|
542
|
+
(float*)z_data, &Sz);
|
|
559
543
|
}
|
|
560
544
|
else
|
|
561
545
|
{
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
546
|
+
double alpha = ((dtype_%(alpha)s*)PyArray_DATA(%(alpha)s))[0];
|
|
547
|
+
dgemv_(&TRANS, &NA1, &NA0,
|
|
548
|
+
&alpha,
|
|
549
|
+
(double*)(A_data), &SA0,
|
|
550
|
+
(double*)x_data, &Sx,
|
|
551
|
+
&dbeta,
|
|
552
|
+
(double*)z_data, &Sz);
|
|
565
553
|
}
|
|
566
554
|
}
|
|
567
555
|
else
|
|
568
556
|
{
|
|
569
557
|
PyErr_SetString(PyExc_AssertionError,
|
|
570
|
-
|
|
571
|
-
"copied into a memory-contiguous one.");
|
|
558
|
+
"A is neither C nor F-contiguous, it should have been copied into a memory-contiguous array;");
|
|
572
559
|
%(fail)s
|
|
573
560
|
}
|
|
574
561
|
}
|
|
575
|
-
else if (dbeta != 1.0)
|
|
576
|
-
{
|
|
577
|
-
// the matrix has at least one dim of length 0
|
|
578
|
-
// so we do this loop, which either iterates over 0 elements
|
|
579
|
-
// or else it does the right thing for length-0 A.
|
|
580
|
-
dtype_%(z)s * zptr = (dtype_%(z)s*)(PyArray_DATA(%(z)s));
|
|
581
|
-
for (int i = 0; i < NA0; ++i)
|
|
582
|
-
{
|
|
583
|
-
zptr[i * Sz] = (dbeta == 0.0 ? 0.0 : zptr[i * Sz] * dbeta);
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
562
|
}
|
|
587
563
|
"""
|
|
588
564
|
return code % locals()
|
|
@@ -613,7 +589,7 @@ class CGemv(BaseBLAS, Gemv):
|
|
|
613
589
|
return code
|
|
614
590
|
|
|
615
591
|
def c_code_cache_version(self):
|
|
616
|
-
return (
|
|
592
|
+
return (16, blas_header_version(), check_force_gemv_init())
|
|
617
593
|
|
|
618
594
|
|
|
619
595
|
cgemv_inplace = CGemv(inplace=True)
|
|
@@ -75,6 +75,13 @@ def is_matrix_transpose(x: TensorVariable) -> bool:
|
|
|
75
75
|
if ndims < 2:
|
|
76
76
|
return False
|
|
77
77
|
transpose_order = (*range(ndims - 2), ndims - 1, ndims - 2)
|
|
78
|
+
|
|
79
|
+
# Allow expand_dims on the left of the transpose
|
|
80
|
+
if (diff := len(transpose_order) - len(node.op.new_order)) > 0:
|
|
81
|
+
transpose_order = (
|
|
82
|
+
*(["x"] * diff),
|
|
83
|
+
*transpose_order,
|
|
84
|
+
)
|
|
78
85
|
return node.op.new_order == transpose_order
|
|
79
86
|
return False
|
|
80
87
|
|
|
@@ -25,6 +25,7 @@ from pytensor.tensor.basic import (
|
|
|
25
25
|
alloc,
|
|
26
26
|
cast,
|
|
27
27
|
concatenate,
|
|
28
|
+
expand_dims,
|
|
28
29
|
get_scalar_constant_value,
|
|
29
30
|
get_underlying_scalar_constant_value,
|
|
30
31
|
register_infer_shape,
|
|
@@ -1576,7 +1577,15 @@ def local_blockwise_advanced_inc_subtensor(fgraph, node):
|
|
|
1576
1577
|
x = alloc(x, *batch_shape, *core_shape)
|
|
1577
1578
|
|
|
1578
1579
|
new_idxs = [slice(None)] * batch_ndim + new_idxs
|
|
1579
|
-
|
|
1580
|
+
x_view = x[tuple(new_idxs)]
|
|
1581
|
+
|
|
1582
|
+
# We need to introduce any implicit expand_dims on core dimension of y
|
|
1583
|
+
y_core_ndim = y.type.ndim - batch_ndim
|
|
1584
|
+
if (missing_y_core_ndim := x_view.type.ndim - batch_ndim - y_core_ndim) > 0:
|
|
1585
|
+
missing_axes = tuple(range(batch_ndim, batch_ndim + missing_y_core_ndim))
|
|
1586
|
+
y = expand_dims(y, missing_axes)
|
|
1587
|
+
|
|
1588
|
+
symbolic_idxs = x_view.owner.inputs[1:]
|
|
1580
1589
|
new_out = op.core_op.make_node(x, y, *symbolic_idxs).outputs
|
|
1581
1590
|
copy_stack_trace(node.outputs, new_out)
|
|
1582
1591
|
return new_out
|
|
@@ -394,6 +394,9 @@ pytensor/tensor/utils.py
|
|
|
394
394
|
pytensor/tensor/var.py
|
|
395
395
|
pytensor/tensor/variable.py
|
|
396
396
|
pytensor/tensor/xlogx.py
|
|
397
|
+
pytensor/tensor/_linalg/__init__.py
|
|
398
|
+
pytensor/tensor/_linalg/solve/__init__.py
|
|
399
|
+
pytensor/tensor/_linalg/solve/rewriting.py
|
|
397
400
|
pytensor/tensor/c_code/alt_blas_common.h
|
|
398
401
|
pytensor/tensor/c_code/alt_blas_template.c
|
|
399
402
|
pytensor/tensor/c_code/dimshuffle.c
|
|
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
|