pytensor 2.18.5__tar.gz → 2.18.6__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.18.5 → pytensor-2.18.6}/PKG-INFO +1 -1
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/_version.py +3 -3
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/basic.py +4 -3
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/replace.py +5 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/slinalg.py +9 -1
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/linker.py +9 -2
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/slinalg.py +23 -1
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/basic.py +87 -9
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/basic.py +35 -6
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/blas.py +9 -9
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/blas_scipy.py +1 -5
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/elemwise.py +35 -15
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/math.py +25 -10
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/linalg.py +2 -2
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/shape.py +8 -5
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/slinalg.py +103 -1
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/special.py +28 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor.egg-info/PKG-INFO +1 -1
- {pytensor-2.18.5 → pytensor-2.18.6}/scripts/mypy-failing.txt +1 -2
- {pytensor-2.18.5 → pytensor-2.18.6}/LICENSE.txt +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/MANIFEST.in +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/README.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/bin/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/bin/pytensor-cache +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/bin/pytensor_cache.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/.templates/PLACEHOLDER +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/.templates/layout.html +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/LICENSE.txt +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/README.md +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/acknowledgement.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/bcast.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/bcast.svg +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/conf.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/core_development_guide.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/css.inc +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/dev_start_guide.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/environment.yml +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/apply.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/apply.svg +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/apply2.svg +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/creating_a_c_op.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/creating_a_numba_jax_op.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/creating_an_op.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/ctype.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/extending_faq.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/extending_pytensor_solution_1.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/graph_rewriting.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/graphstructures.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/inplace.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/op.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/other_ops.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/pics/symbolic_graph_opt.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/pipeline.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/scan.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/tips.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/type.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/unittest.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/using_params.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/faq.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/generate_dtype_tensor_table.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/glossary.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/Elman_srnn.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/PyTensor_RGB.svg +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/blocksparse.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/lstm.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/lstm_memorycell.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/talk2010.gif +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/talk2010.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/install.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/internal/how_to_release.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/internal/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/internal/metadocumentation.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/introduction.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/debugmode.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/function.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/io.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/mode.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/nanguardmode.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/opfromgraph.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/ops.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/profilemode.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/shared.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/config.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp.html +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp2.html +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp2.pdf +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp2.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/ofg.html +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/ofg2.html +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/index.ipynb +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/index_files/index_10_0.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/index_files/index_11_0.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/index_files/index_24_0.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/index_files/index_25_0.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/gradient.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/features.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/fgraph.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/graph.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/op.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/type.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/utils.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/misc/pkl_utils.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/printing.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/sandbox/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/sandbox/linalg.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/scalar/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/scan.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/sparse/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/sparse/sandbox.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/basic.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/basic_opt.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/bcast.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/bcast.svg +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/conv.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/elemwise.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/extra_ops.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/fft.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/io.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/math_opt.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/nlinalg.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/plot_fft.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/random/basic.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/random/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/random/utils.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/slinalg.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/utils.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/typed_list.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/links.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/optimizations.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/pylintrc +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/ccodegen.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/compilation.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/debugging_with_stepmode.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/elemwise_compiler.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/function.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/functional.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/how_to_make_ops.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/index2.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/interactive_debugger.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/logistic_regression_example.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/performance.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/randomnumbers.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/rethinkccodegen.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/sandbox.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/software.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/sparse.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/tensoroptools.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/scripts/docgen.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/troubleshooting.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/adding.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/adding_solution_1.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/aliasing.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/apply.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/apply.svg +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/bcast.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/broadcasting.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/conditions.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/debug_faq.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/dlogistic.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/examples.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/faq_tutorial.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/gradients.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/index.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/loading_and_saving.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/logistic.gp +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/logistic.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/loop.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/loop_solution_1.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/modes.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/modes_solution_1.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/multi_cores.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/nan_tutorial.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/pics/d3viz.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/printing_drawing.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/profiling.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/profiling_example.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/profiling_example_out.prof +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/shape_info.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/sparse.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/symbolic_graphs.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/doc/user_guide.rst +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pyproject.toml +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/bin/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/bin/pytensor_cache.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/breakpoint.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/builders.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/compiledir.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/compilelock.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/debugmode.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/function/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/function/pfunc.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/function/types.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/io.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/mode.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/monitormode.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/nanguardmode.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/ops.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/profiling.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/sharedvalue.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/configdefaults.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/configparser.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/css/d3viz.css +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/d3viz.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/formatting.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/js/d3viz.js +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/gradient.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/destroyhandler.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/features.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/fg.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/null_type.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/op.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/rewriting/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/rewriting/basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/rewriting/db.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/rewriting/kanren.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/rewriting/unify.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/rewriting/utils.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/type.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/utils.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/ifelse.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/cmodule.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/cutils.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/cvm.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/exceptions.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/interface.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/lazylinker_c.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/op.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/params_type.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/type.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/blockwise.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/elemwise.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/nlinalg.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/random.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/scalar.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/scan.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/shape.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/sparse.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/subtensor.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/cython_support.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/elemwise.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/elemwise_codegen.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/random.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/scalar.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/scan.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/sparse.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/linker.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/utils.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/vm.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/check_blas.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/check_blas_many.sh +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/check_duplicate_key.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/elemwise_time_test.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/frozendict.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/may_share_memory.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/ordered_set.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/pkl_utils.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/safe_asarray.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/printing.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/py.typed +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/raise_op.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/c_code/gamma.c +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/loop.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/math.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/sharedvar.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/checkpoints.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/op.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/rewriting.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/scan_perform.pyx +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/scan_perform_ext.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/utils.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/views.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/rewriting.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/sandbox/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/sandbox/sp.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/sandbox/sp2.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/sharedvar.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/type.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/utils.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/blas_c.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/blas_headers.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/blockwise.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/c_code/dimshuffle.c +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/conv/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/conv/abstract_conv.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/elemwise_cgen.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/exceptions.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/extra_ops.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/fft.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/fourier.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/functional.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/inplace.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/io.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/linalg.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/nlinalg.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/op.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/rewriting/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/rewriting/basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/rewriting/jax.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/type.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/utils.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/var.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/blas.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/blas_c.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/blas_scipy.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/blockwise.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/elemwise.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/extra_ops.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/jax.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/math.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/shape.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/special.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/subtensor.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/sharedvar.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/sort.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/subtensor.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/type.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/type_other.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/utils.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/var.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/variable.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/xlogx.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/typed_list/__init__.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/typed_list/basic.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/typed_list/rewriting.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/typed_list/type.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/updates.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/utils.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/version.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor.egg-info/SOURCES.txt +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor.egg-info/dependency_links.txt +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor.egg-info/entry_points.txt +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor.egg-info/requires.txt +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/pytensor.egg-info/top_level.txt +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/scripts/downstream_pr.sh +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/scripts/upstream_pr.sh +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/setup.cfg +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/setup.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/tests/link/c/c_code/test_cenum.h +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/tests/link/c/c_code/test_quadratic_function.c +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/tests/tensor/conv/c_code/corr3d_gemm.c +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/tests/tensor/conv/c_code/corr_gemm.c +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_breakpoint.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_config.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_gradient.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_ifelse.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_printing.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_raise_op.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_rop.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_updates.py +0 -0
- {pytensor-2.18.5 → pytensor-2.18.6}/versioneer.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2024-01-
|
|
11
|
+
"date": "2024-01-12T14:29:52+0100",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.18.
|
|
14
|
+
"full-revisionid": "0666fd564d2d67384051c5bb6e0c09e713e0329c",
|
|
15
|
+
"version": "2.18.6"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -1439,15 +1439,16 @@ def io_toposort(
|
|
|
1439
1439
|
order = []
|
|
1440
1440
|
while todo:
|
|
1441
1441
|
cur = todo.pop()
|
|
1442
|
-
|
|
1443
|
-
if cur.outputs[0] in computed:
|
|
1442
|
+
if all(out in computed for out in cur.outputs):
|
|
1444
1443
|
continue
|
|
1445
1444
|
if all(i in computed or i.owner is None for i in cur.inputs):
|
|
1446
1445
|
computed.update(cur.outputs)
|
|
1447
1446
|
order.append(cur)
|
|
1448
1447
|
else:
|
|
1449
1448
|
todo.append(cur)
|
|
1450
|
-
todo.extend(
|
|
1449
|
+
todo.extend(
|
|
1450
|
+
i.owner for i in cur.inputs if (i.owner and i not in computed)
|
|
1451
|
+
)
|
|
1451
1452
|
return order
|
|
1452
1453
|
|
|
1453
1454
|
compute_deps = None
|
|
@@ -306,6 +306,11 @@ def vectorize_graph(
|
|
|
306
306
|
vect_inputs = [vect_vars.get(inp, inp) for inp in node.inputs]
|
|
307
307
|
vect_node = vectorize_node(node, *vect_inputs)
|
|
308
308
|
for output, vect_output in zip(node.outputs, vect_node.outputs):
|
|
309
|
+
if output in vect_vars:
|
|
310
|
+
# This can happen when some outputs of a multi-output node are given a replacement,
|
|
311
|
+
# while some of the remaining outputs are still needed in the graph.
|
|
312
|
+
# We make sure we don't overwrite the provided replacement with the newly vectorized output
|
|
313
|
+
continue
|
|
309
314
|
vect_vars[output] = vect_output
|
|
310
315
|
|
|
311
316
|
seq_vect_outputs = [vect_vars[out] for out in seq_outputs]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import jax
|
|
2
2
|
|
|
3
3
|
from pytensor.link.jax.dispatch.basic import jax_funcify
|
|
4
|
-
from pytensor.tensor.slinalg import Cholesky, Solve, SolveTriangular
|
|
4
|
+
from pytensor.tensor.slinalg import BlockDiagonal, Cholesky, Solve, SolveTriangular
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
@jax_funcify.register(Cholesky)
|
|
@@ -45,3 +45,11 @@ def jax_funcify_SolveTriangular(op, **kwargs):
|
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
return solve_triangular
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@jax_funcify.register(BlockDiagonal)
|
|
51
|
+
def jax_funcify_BlockDiagonalMatrix(op, **kwargs):
|
|
52
|
+
def block_diag(*inputs):
|
|
53
|
+
return jax.scipy.linalg.block_diag(*inputs)
|
|
54
|
+
|
|
55
|
+
return block_diag
|
|
@@ -23,7 +23,7 @@ class JAXLinker(JITLinker):
|
|
|
23
23
|
# Replace any shared RNG inputs so that their values can be updated in place
|
|
24
24
|
# without affecting the original RNG container. This is necessary because
|
|
25
25
|
# JAX does not accept RandomState/Generators as inputs, and they will have to
|
|
26
|
-
# be
|
|
26
|
+
# be tipyfied
|
|
27
27
|
if shared_rng_inputs:
|
|
28
28
|
warnings.warn(
|
|
29
29
|
f"The RandomType SharedVariables {shared_rng_inputs} will not be used "
|
|
@@ -52,9 +52,16 @@ class JAXLinker(JITLinker):
|
|
|
52
52
|
else: # no break
|
|
53
53
|
raise ValueError()
|
|
54
54
|
input_storage[input_storage_idx] = new_inp_storage
|
|
55
|
+
# We need to change the order of the inputs of the FunctionGraph
|
|
56
|
+
# so that the new input is in the same position as to old one,
|
|
57
|
+
# to align with the storage_map. We hope this is safe!
|
|
58
|
+
old_inp_fgrap_index = fgraph.inputs.index(old_inp)
|
|
55
59
|
fgraph.remove_input(
|
|
56
|
-
|
|
60
|
+
old_inp_fgrap_index,
|
|
61
|
+
reason="JAXLinker.fgraph_convert",
|
|
57
62
|
)
|
|
63
|
+
fgraph.inputs.remove(new_inp)
|
|
64
|
+
fgraph.inputs.insert(old_inp_fgrap_index, new_inp)
|
|
58
65
|
|
|
59
66
|
return jax_funcify(
|
|
60
67
|
fgraph, input_storage=input_storage, storage_map=storage_map, **kwargs
|
|
@@ -9,7 +9,7 @@ from scipy import linalg
|
|
|
9
9
|
|
|
10
10
|
from pytensor.link.numba.dispatch import basic as numba_basic
|
|
11
11
|
from pytensor.link.numba.dispatch.basic import numba_funcify
|
|
12
|
-
from pytensor.tensor.slinalg import SolveTriangular
|
|
12
|
+
from pytensor.tensor.slinalg import BlockDiagonal, SolveTriangular
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
_PTR = ctypes.POINTER
|
|
@@ -273,3 +273,25 @@ def numba_funcify_SolveTriangular(op, node, **kwargs):
|
|
|
273
273
|
return res
|
|
274
274
|
|
|
275
275
|
return solve_triangular
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
@numba_funcify.register(BlockDiagonal)
|
|
279
|
+
def numba_funcify_BlockDiagonal(op, node, **kwargs):
|
|
280
|
+
dtype = node.outputs[0].dtype
|
|
281
|
+
|
|
282
|
+
# TODO: Why do we always inline all functions? It doesn't work with starred args, so can't use it in this case.
|
|
283
|
+
@numba_basic.numba_njit(inline="never")
|
|
284
|
+
def block_diag(*arrs):
|
|
285
|
+
shapes = np.array([a.shape for a in arrs], dtype="int")
|
|
286
|
+
out_shape = [int(s) for s in np.sum(shapes, axis=0)]
|
|
287
|
+
out = np.zeros((out_shape[0], out_shape[1]), dtype=dtype)
|
|
288
|
+
|
|
289
|
+
r, c = 0, 0
|
|
290
|
+
for arr, shape in zip(arrs, shapes):
|
|
291
|
+
rr, cc = shape
|
|
292
|
+
out[r : r + rr, c : c + cc] = arr
|
|
293
|
+
r += rr
|
|
294
|
+
c += cc
|
|
295
|
+
return out
|
|
296
|
+
|
|
297
|
+
return block_diag
|
|
@@ -7,6 +7,7 @@ http://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps
|
|
|
7
7
|
TODO: Automatic methods for determining best sparse format?
|
|
8
8
|
|
|
9
9
|
"""
|
|
10
|
+
from typing import Literal
|
|
10
11
|
from warnings import warn
|
|
11
12
|
|
|
12
13
|
import numpy as np
|
|
@@ -47,6 +48,7 @@ from pytensor.tensor.math import (
|
|
|
47
48
|
trunc,
|
|
48
49
|
)
|
|
49
50
|
from pytensor.tensor.shape import shape, specify_broadcastable
|
|
51
|
+
from pytensor.tensor.slinalg import BaseBlockDiagonal, _largest_common_dtype
|
|
50
52
|
from pytensor.tensor.type import TensorType
|
|
51
53
|
from pytensor.tensor.type import continuous_dtypes as tensor_continuous_dtypes
|
|
52
54
|
from pytensor.tensor.type import discrete_dtypes as tensor_discrete_dtypes
|
|
@@ -60,7 +62,6 @@ from pytensor.tensor.variable import (
|
|
|
60
62
|
|
|
61
63
|
sparse_formats = ["csc", "csr"]
|
|
62
64
|
|
|
63
|
-
|
|
64
65
|
"""
|
|
65
66
|
Types of sparse matrices to use for testing.
|
|
66
67
|
|
|
@@ -183,7 +184,6 @@ def as_sparse_variable(x, name=None, ndim=None, **kwargs):
|
|
|
183
184
|
|
|
184
185
|
as_sparse = as_sparse_variable
|
|
185
186
|
|
|
186
|
-
|
|
187
187
|
as_sparse_or_tensor_variable = as_symbolic
|
|
188
188
|
|
|
189
189
|
|
|
@@ -1800,7 +1800,7 @@ class SpSum(Op):
|
|
|
1800
1800
|
return r
|
|
1801
1801
|
|
|
1802
1802
|
def __str__(self):
|
|
1803
|
-
return f"{self.__class__.__name__
|
|
1803
|
+
return f"{self.__class__.__name__}{{axis={self.axis}}}"
|
|
1804
1804
|
|
|
1805
1805
|
|
|
1806
1806
|
def sp_sum(x, axis=None, sparse_grad=False):
|
|
@@ -2775,19 +2775,14 @@ class GreaterEqualSD(__ComparisonOpSD):
|
|
|
2775
2775
|
|
|
2776
2776
|
greater_equal_s_d = GreaterEqualSD()
|
|
2777
2777
|
|
|
2778
|
-
|
|
2779
2778
|
eq = __ComparisonSwitch(equal_s_s, equal_s_d, equal_s_d)
|
|
2780
2779
|
|
|
2781
|
-
|
|
2782
2780
|
neq = __ComparisonSwitch(not_equal_s_s, not_equal_s_d, not_equal_s_d)
|
|
2783
2781
|
|
|
2784
|
-
|
|
2785
2782
|
lt = __ComparisonSwitch(less_than_s_s, less_than_s_d, greater_than_s_d)
|
|
2786
2783
|
|
|
2787
|
-
|
|
2788
2784
|
gt = __ComparisonSwitch(greater_than_s_s, greater_than_s_d, less_than_s_d)
|
|
2789
2785
|
|
|
2790
|
-
|
|
2791
2786
|
le = __ComparisonSwitch(less_equal_s_s, less_equal_s_d, greater_equal_s_d)
|
|
2792
2787
|
|
|
2793
2788
|
ge = __ComparisonSwitch(greater_equal_s_s, greater_equal_s_d, less_equal_s_d)
|
|
@@ -2992,7 +2987,7 @@ class Remove0(Op):
|
|
|
2992
2987
|
l = []
|
|
2993
2988
|
if self.inplace:
|
|
2994
2989
|
l.append("inplace")
|
|
2995
|
-
return f"{self.__class__.__name__
|
|
2990
|
+
return f"{self.__class__.__name__}{{{', '.join(l)}}}"
|
|
2996
2991
|
|
|
2997
2992
|
def make_node(self, x):
|
|
2998
2993
|
"""
|
|
@@ -3291,6 +3286,7 @@ class TrueDot(Op):
|
|
|
3291
3286
|
# Simplify code by splitting into DotSS and DotSD.
|
|
3292
3287
|
|
|
3293
3288
|
__props__ = ()
|
|
3289
|
+
|
|
3294
3290
|
# The grad_preserves_dense attribute doesn't change the
|
|
3295
3291
|
# execution behavior. To let the optimizer merge nodes with
|
|
3296
3292
|
# different values of this attribute we shouldn't compare it
|
|
@@ -4260,3 +4256,85 @@ class ConstructSparseFromList(Op):
|
|
|
4260
4256
|
|
|
4261
4257
|
|
|
4262
4258
|
construct_sparse_from_list = ConstructSparseFromList()
|
|
4259
|
+
|
|
4260
|
+
|
|
4261
|
+
class SparseBlockDiagonal(BaseBlockDiagonal):
|
|
4262
|
+
__props__ = (
|
|
4263
|
+
"n_inputs",
|
|
4264
|
+
"format",
|
|
4265
|
+
)
|
|
4266
|
+
|
|
4267
|
+
def __init__(self, n_inputs: int, format: Literal["csc", "csr"] = "csc"):
|
|
4268
|
+
super().__init__(n_inputs)
|
|
4269
|
+
self.format = format
|
|
4270
|
+
|
|
4271
|
+
def make_node(self, *matrices):
|
|
4272
|
+
matrices = self._validate_and_prepare_inputs(
|
|
4273
|
+
matrices, as_sparse_or_tensor_variable
|
|
4274
|
+
)
|
|
4275
|
+
dtype = _largest_common_dtype(matrices)
|
|
4276
|
+
out_type = matrix(format=self.format, dtype=dtype)
|
|
4277
|
+
|
|
4278
|
+
return Apply(self, matrices, [out_type])
|
|
4279
|
+
|
|
4280
|
+
def perform(self, node, inputs, output_storage, params=None):
|
|
4281
|
+
dtype = node.outputs[0].type.dtype
|
|
4282
|
+
output_storage[0][0] = scipy.sparse.block_diag(
|
|
4283
|
+
inputs, format=self.format
|
|
4284
|
+
).astype(dtype)
|
|
4285
|
+
|
|
4286
|
+
|
|
4287
|
+
def block_diag(*matrices: TensorVariable, format: Literal["csc", "csr"] = "csc"):
|
|
4288
|
+
r"""
|
|
4289
|
+
Construct a block diagonal matrix from a sequence of input matrices.
|
|
4290
|
+
|
|
4291
|
+
Given the inputs `A`, `B` and `C`, the output will have these arrays arranged on the diagonal:
|
|
4292
|
+
|
|
4293
|
+
[[A, 0, 0],
|
|
4294
|
+
[0, B, 0],
|
|
4295
|
+
[0, 0, C]]
|
|
4296
|
+
|
|
4297
|
+
Parameters
|
|
4298
|
+
----------
|
|
4299
|
+
A, B, C ... : tensors
|
|
4300
|
+
Input tensors to form the block diagonal matrix. last two dimensions of the inputs will be used, and all
|
|
4301
|
+
inputs should have at least 2 dimensins.
|
|
4302
|
+
|
|
4303
|
+
Note that the input matrices need not be sparse themselves, and will be automatically converted to the
|
|
4304
|
+
requested format if they are not.
|
|
4305
|
+
|
|
4306
|
+
format: str, optional
|
|
4307
|
+
The format of the output sparse matrix. One of 'csr' or 'csc'. Default is 'csr'. Ignored if sparse=False.
|
|
4308
|
+
|
|
4309
|
+
Returns
|
|
4310
|
+
-------
|
|
4311
|
+
out: sparse matrix tensor
|
|
4312
|
+
Symbolic sparse matrix in the specified format.
|
|
4313
|
+
|
|
4314
|
+
Examples
|
|
4315
|
+
--------
|
|
4316
|
+
Create a sparse block diagonal matrix from two sparse 2x2 matrices:
|
|
4317
|
+
|
|
4318
|
+
..code-block:: python
|
|
4319
|
+
import numpy as np
|
|
4320
|
+
from pytensor.sparse import block_diag
|
|
4321
|
+
from scipy.sparse import csr_matrix
|
|
4322
|
+
|
|
4323
|
+
A = csr_matrix([[1, 2], [3, 4]])
|
|
4324
|
+
B = csr_matrix([[5, 6], [7, 8]])
|
|
4325
|
+
result_sparse = block_diag(A, B, format='csr', name='X')
|
|
4326
|
+
|
|
4327
|
+
print(result_sparse)
|
|
4328
|
+
>>> SparseVariable{csr,int32}
|
|
4329
|
+
|
|
4330
|
+
print(result_sparse.toarray().eval())
|
|
4331
|
+
>>> array([[1, 2, 0, 0],
|
|
4332
|
+
>>> [3, 4, 0, 0],
|
|
4333
|
+
>>> [0, 0, 5, 6],
|
|
4334
|
+
>>> [0, 0, 7, 8]])
|
|
4335
|
+
"""
|
|
4336
|
+
if len(matrices) == 1:
|
|
4337
|
+
return matrices
|
|
4338
|
+
|
|
4339
|
+
_sparse_block_diagonal = SparseBlockDiagonal(n_inputs=len(matrices), format=format)
|
|
4340
|
+
return _sparse_block_diagonal(*matrices)
|
|
@@ -43,7 +43,12 @@ from pytensor.tensor import (
|
|
|
43
43
|
get_vector_length,
|
|
44
44
|
)
|
|
45
45
|
from pytensor.tensor.blockwise import Blockwise
|
|
46
|
-
from pytensor.tensor.elemwise import
|
|
46
|
+
from pytensor.tensor.elemwise import (
|
|
47
|
+
DimShuffle,
|
|
48
|
+
Elemwise,
|
|
49
|
+
get_normalized_batch_axes,
|
|
50
|
+
scalar_elemwise,
|
|
51
|
+
)
|
|
47
52
|
from pytensor.tensor.exceptions import NotScalarConstantError
|
|
48
53
|
from pytensor.tensor.shape import (
|
|
49
54
|
Shape,
|
|
@@ -3614,13 +3619,18 @@ def diagonal(a, offset=0, axis1=0, axis2=1):
|
|
|
3614
3619
|
|
|
3615
3620
|
|
|
3616
3621
|
@_vectorize_node.register(ExtractDiag)
|
|
3617
|
-
def vectorize_extract_diag(op: ExtractDiag, node,
|
|
3618
|
-
|
|
3622
|
+
def vectorize_extract_diag(op: ExtractDiag, node, batch_x):
|
|
3623
|
+
core_ndim = node.inputs[0].type.ndim
|
|
3624
|
+
batch_ndim = batch_x.type.ndim - core_ndim
|
|
3625
|
+
batch_axis1, batch_axis2 = get_normalized_batch_axes(
|
|
3626
|
+
(op.axis1, op.axis2), core_ndim, batch_ndim
|
|
3627
|
+
)
|
|
3628
|
+
|
|
3619
3629
|
return diagonal(
|
|
3620
|
-
|
|
3630
|
+
batch_x,
|
|
3621
3631
|
offset=op.offset,
|
|
3622
|
-
axis1=
|
|
3623
|
-
axis2=
|
|
3632
|
+
axis1=batch_axis1,
|
|
3633
|
+
axis2=batch_axis2,
|
|
3624
3634
|
).owner
|
|
3625
3635
|
|
|
3626
3636
|
|
|
@@ -4269,6 +4279,25 @@ def take_along_axis(arr, indices, axis=0):
|
|
|
4269
4279
|
return arr[_make_along_axis_idx(arr.shape, indices, axis)]
|
|
4270
4280
|
|
|
4271
4281
|
|
|
4282
|
+
def ix_(*args):
|
|
4283
|
+
"""
|
|
4284
|
+
PyTensor np.ix_ analog
|
|
4285
|
+
|
|
4286
|
+
See numpy.lib.index_tricks.ix_ for reference
|
|
4287
|
+
"""
|
|
4288
|
+
out = []
|
|
4289
|
+
nd = len(args)
|
|
4290
|
+
for k, new in enumerate(args):
|
|
4291
|
+
if new is None:
|
|
4292
|
+
out.append(slice(None))
|
|
4293
|
+
new = as_tensor(new)
|
|
4294
|
+
if new.ndim != 1:
|
|
4295
|
+
raise ValueError("Cross index must be 1 dimensional")
|
|
4296
|
+
new = new.reshape((1,) * k + (new.size,) + (1,) * (nd - k - 1))
|
|
4297
|
+
out.append(new)
|
|
4298
|
+
return tuple(out)
|
|
4299
|
+
|
|
4300
|
+
|
|
4272
4301
|
__all__ = [
|
|
4273
4302
|
"take_along_axis",
|
|
4274
4303
|
"expand_dims",
|
|
@@ -144,20 +144,20 @@ except ImportError as e:
|
|
|
144
144
|
# If check_init_y() == True we need to initialize y when beta == 0.
|
|
145
145
|
def check_init_y():
|
|
146
146
|
if check_init_y._result is None:
|
|
147
|
-
if not have_fblas:
|
|
147
|
+
if not have_fblas: # pragma: no cover
|
|
148
148
|
check_init_y._result = False
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
149
|
+
else:
|
|
150
|
+
y = float("NaN") * np.ones((2,))
|
|
151
|
+
x = np.ones((2,))
|
|
152
|
+
A = np.ones((2, 2))
|
|
153
|
+
gemv = _blas_gemv_fns[y.dtype]
|
|
154
|
+
gemv(1.0, A.T, x, 0.0, y, overwrite_y=True, trans=True)
|
|
155
|
+
check_init_y._result = np.isnan(y).any()
|
|
156
156
|
|
|
157
157
|
return check_init_y._result
|
|
158
158
|
|
|
159
159
|
|
|
160
|
-
check_init_y._result = None
|
|
160
|
+
check_init_y._result = None # type: ignore
|
|
161
161
|
|
|
162
162
|
|
|
163
163
|
class Gemv(Op):
|
|
@@ -19,17 +19,13 @@ if have_fblas:
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
class ScipyGer(Ger):
|
|
22
|
-
def prepare_node(self, node, storage_map, compute_map, impl):
|
|
23
|
-
if impl == "py":
|
|
24
|
-
node.tag.local_ger = _blas_ger_fns[np.dtype(node.inputs[0].type.dtype)]
|
|
25
|
-
|
|
26
22
|
def perform(self, node, inputs, output_storage):
|
|
27
23
|
cA, calpha, cx, cy = inputs
|
|
28
24
|
(cZ,) = output_storage
|
|
29
25
|
# N.B. some versions of scipy (e.g. mine) don't actually work
|
|
30
26
|
# in-place on a, even when I tell it to.
|
|
31
27
|
A = cA
|
|
32
|
-
local_ger =
|
|
28
|
+
local_ger = _blas_ger_fns[cA.dtype]
|
|
33
29
|
if A.size == 0:
|
|
34
30
|
# We don't have to compute anything, A is empty.
|
|
35
31
|
# We need this special case because Numpy considers it
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from copy import copy
|
|
2
|
+
from typing import Union
|
|
2
3
|
|
|
3
4
|
import numpy as np
|
|
5
|
+
from numpy.core.numeric import normalize_axis_tuple
|
|
4
6
|
|
|
5
7
|
import pytensor.tensor.basic
|
|
6
8
|
from pytensor.configdefaults import config
|
|
@@ -1399,7 +1401,7 @@ class CAReduce(COp):
|
|
|
1399
1401
|
# scalar inputs are treated as 1D regarding axis in this `Op`
|
|
1400
1402
|
if axis is not None:
|
|
1401
1403
|
try:
|
|
1402
|
-
axis =
|
|
1404
|
+
axis = normalize_axis_tuple(axis, ndim=max(1, inp_dims))
|
|
1403
1405
|
except np.AxisError:
|
|
1404
1406
|
raise np.AxisError(axis, ndim=inp_dims)
|
|
1405
1407
|
|
|
@@ -1757,18 +1759,36 @@ def vectorize_dimshuffle(op: DimShuffle, node: Apply, x: TensorVariable) -> Appl
|
|
|
1757
1759
|
return DimShuffle(input_broadcastable, new_order).make_node(x)
|
|
1758
1760
|
|
|
1759
1761
|
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
axes
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1762
|
+
def get_normalized_batch_axes(
|
|
1763
|
+
core_axes: Union[None, int, tuple[int, ...]],
|
|
1764
|
+
core_ndim: int,
|
|
1765
|
+
batch_ndim: int,
|
|
1766
|
+
) -> tuple[int, ...]:
|
|
1767
|
+
"""Compute batch axes for a batched operation, from the core input ndim and axes.
|
|
1768
|
+
|
|
1769
|
+
e.g., sum(matrix, axis=None) -> sum(tensor4, axis=(2, 3))
|
|
1770
|
+
batch_axes(None, 2, 4) -> (2, 3)
|
|
1771
|
+
|
|
1772
|
+
e.g., sum(matrix, axis=0) -> sum(tensor4, axis=(2,))
|
|
1773
|
+
batch_axes(0, 2, 4) -> (2,)
|
|
1774
|
+
|
|
1775
|
+
e.g., sum(tensor3, axis=(0, -1)) -> sum(tensor4, axis=(1, 3))
|
|
1776
|
+
batch_axes((0, -1), 3, 4) -> (1, 3)
|
|
1777
|
+
"""
|
|
1778
|
+
if core_axes is None:
|
|
1779
|
+
core_axes = tuple(range(core_ndim))
|
|
1770
1780
|
else:
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1781
|
+
core_axes = normalize_axis_tuple(core_axes, core_ndim)
|
|
1782
|
+
return tuple(core_axis + batch_ndim for core_axis in core_axes)
|
|
1783
|
+
|
|
1784
|
+
|
|
1785
|
+
@_vectorize_node.register(CAReduce)
|
|
1786
|
+
def vectorize_careduce(op: CAReduce, node: Apply, batch_x: TensorVariable) -> Apply:
|
|
1787
|
+
core_ndim = node.inputs[0].type.ndim
|
|
1788
|
+
batch_ndim = batch_x.type.ndim - core_ndim
|
|
1789
|
+
|
|
1790
|
+
if not batch_ndim:
|
|
1791
|
+
return node.op.make_node(batch_x)
|
|
1792
|
+
|
|
1793
|
+
batch_axes = get_normalized_batch_axes(op.axis, core_ndim, batch_ndim)
|
|
1794
|
+
return op.clone(axis=batch_axes).make_node(batch_x)
|
|
@@ -27,7 +27,13 @@ from pytensor.tensor.basic import (
|
|
|
27
27
|
switch,
|
|
28
28
|
)
|
|
29
29
|
from pytensor.tensor.blockwise import Blockwise, vectorize_node_fallback
|
|
30
|
-
from pytensor.tensor.elemwise import
|
|
30
|
+
from pytensor.tensor.elemwise import (
|
|
31
|
+
CAReduce,
|
|
32
|
+
DimShuffle,
|
|
33
|
+
Elemwise,
|
|
34
|
+
get_normalized_batch_axes,
|
|
35
|
+
scalar_elemwise,
|
|
36
|
+
)
|
|
31
37
|
from pytensor.tensor.shape import shape, specify_broadcastable
|
|
32
38
|
from pytensor.tensor.type import (
|
|
33
39
|
DenseTensorType,
|
|
@@ -134,7 +140,7 @@ class MaxAndArgmax(COp):
|
|
|
134
140
|
_f16_ok = True
|
|
135
141
|
|
|
136
142
|
def __init__(self, axis):
|
|
137
|
-
assert isinstance(axis, list)
|
|
143
|
+
assert isinstance(axis, (tuple, list))
|
|
138
144
|
self.axis = tuple(axis)
|
|
139
145
|
|
|
140
146
|
def get_params(self, node):
|
|
@@ -465,6 +471,19 @@ class Argmax(COp):
|
|
|
465
471
|
return [x.zeros_like()]
|
|
466
472
|
|
|
467
473
|
|
|
474
|
+
@_vectorize_node.register(Argmax)
|
|
475
|
+
@_vectorize_node.register(MaxAndArgmax)
|
|
476
|
+
def vectorize_argmax_node(op, node, batch_x):
|
|
477
|
+
core_ndim = node.inputs[0].type.ndim
|
|
478
|
+
batch_ndim = batch_x.type.ndim - core_ndim
|
|
479
|
+
|
|
480
|
+
if not batch_ndim:
|
|
481
|
+
return node.op.make_node(batch_x)
|
|
482
|
+
|
|
483
|
+
batch_axes = get_normalized_batch_axes(op.axis, core_ndim, batch_ndim)
|
|
484
|
+
return type(op)(axis=batch_axes).make_node(batch_x)
|
|
485
|
+
|
|
486
|
+
|
|
468
487
|
def makeKeepDims(x, y, axis):
|
|
469
488
|
"""
|
|
470
489
|
Reintroduces in y with length one the axes of x which have been left out
|
|
@@ -671,13 +690,7 @@ def max(x, axis=None, keepdims=False):
|
|
|
671
690
|
# thing is supporting all user interface features, not speed.
|
|
672
691
|
# Some cases can be implemented only with CAReduce.
|
|
673
692
|
|
|
674
|
-
|
|
675
|
-
# support all axis arguments, so we may need to fall back to CAReduce.
|
|
676
|
-
|
|
677
|
-
try:
|
|
678
|
-
out = max_and_argmax(x, axis)[0]
|
|
679
|
-
except Exception:
|
|
680
|
-
out = Max(axis)(x)
|
|
693
|
+
out = max_and_argmax(x, axis)[0]
|
|
681
694
|
|
|
682
695
|
if keepdims:
|
|
683
696
|
out = makeKeepDims(x, out, axis)
|
|
@@ -2948,9 +2961,11 @@ def matmul(x1: "ArrayLike", x2: "ArrayLike", dtype: Optional["DTypeLike"] = None
|
|
|
2948
2961
|
|
|
2949
2962
|
|
|
2950
2963
|
@_vectorize_node.register(Dot)
|
|
2951
|
-
def
|
|
2964
|
+
def vectorize_node_dot_to_matmul(op, node, batched_x, batched_y):
|
|
2952
2965
|
old_x, old_y = node.inputs
|
|
2953
2966
|
if old_x.type.ndim == 2 and old_y.type.ndim == 2:
|
|
2967
|
+
# If original input is equivalent to a matrix-matrix product,
|
|
2968
|
+
# return specialized Matmul Op to avoid unnecessary new Ops.
|
|
2954
2969
|
return matmul(batched_x, batched_y).owner
|
|
2955
2970
|
else:
|
|
2956
2971
|
return vectorize_node_fallback(op, node, batched_x, batched_y)
|
|
@@ -215,8 +215,8 @@ def psd_solve_with_chol(fgraph, node):
|
|
|
215
215
|
# N.B. this can be further reduced to a yet-unwritten cho_solve Op
|
|
216
216
|
# __if__ no other Op makes use of the L matrix during the
|
|
217
217
|
# stabilization
|
|
218
|
-
Li_b =
|
|
219
|
-
x =
|
|
218
|
+
Li_b = solve_triangular(L, b, lower=True, b_ndim=2)
|
|
219
|
+
x = solve_triangular(_T(L), Li_b, lower=False, b_ndim=2)
|
|
220
220
|
return [x]
|
|
221
221
|
|
|
222
222
|
|
|
@@ -18,6 +18,7 @@ from pytensor.scalar import int32
|
|
|
18
18
|
from pytensor.tensor import _get_vector_length, as_tensor_variable
|
|
19
19
|
from pytensor.tensor import basic as ptb
|
|
20
20
|
from pytensor.tensor import get_vector_length
|
|
21
|
+
from pytensor.tensor.elemwise import get_normalized_batch_axes
|
|
21
22
|
from pytensor.tensor.exceptions import NotScalarConstantError
|
|
22
23
|
from pytensor.tensor.type import DenseTensorType, TensorType, int_dtypes, tensor
|
|
23
24
|
from pytensor.tensor.type_other import NoneConst
|
|
@@ -1103,8 +1104,10 @@ def unbroadcast(x, *axes):
|
|
|
1103
1104
|
|
|
1104
1105
|
|
|
1105
1106
|
@_vectorize_node.register(Unbroadcast)
|
|
1106
|
-
def _vectorize_unbroadcast(
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1107
|
+
def _vectorize_unbroadcast(
|
|
1108
|
+
op: Unbroadcast, node: Apply, batch_x: TensorVariable
|
|
1109
|
+
) -> Apply:
|
|
1110
|
+
core_ndim = node.inputs[0].type.ndim
|
|
1111
|
+
batch_ndim = batch_x.type.ndim - core_ndim
|
|
1112
|
+
batch_axes = get_normalized_batch_axes(op.axes, core_ndim, batch_ndim)
|
|
1113
|
+
return cast(Apply, unbroadcast(batch_x, *batch_axes).owner)
|