pytensor 2.18.4__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.4 → pytensor-2.18.6}/PKG-INFO +1 -1
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/_version.py +3 -3
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/basic.py +4 -3
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/replace.py +9 -4
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/scalar.py +18 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/slinalg.py +9 -1
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/linker.py +9 -2
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/slinalg.py +23 -1
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scalar/math.py +95 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/sparse/basic.py +87 -9
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/basic.py +35 -6
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/blas.py +9 -9
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/blas_scipy.py +1 -5
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/elemwise.py +35 -15
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/inplace.py +15 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/math.py +43 -10
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/linalg.py +2 -2
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/math.py +53 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/shape.py +11 -1
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/shape.py +8 -5
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/slinalg.py +103 -1
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/special.py +47 -1
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor.egg-info/PKG-INFO +1 -1
- {pytensor-2.18.4 → pytensor-2.18.6}/scripts/mypy-failing.txt +1 -2
- {pytensor-2.18.4 → pytensor-2.18.6}/LICENSE.txt +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/MANIFEST.in +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/README.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/bin/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/bin/pytensor-cache +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/bin/pytensor_cache.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/.templates/PLACEHOLDER +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/.templates/layout.html +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/LICENSE.txt +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/README.md +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/acknowledgement.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/bcast.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/bcast.svg +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/conf.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/core_development_guide.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/css.inc +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/dev_start_guide.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/environment.yml +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/apply.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/apply.svg +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/apply2.svg +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/creating_a_c_op.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/creating_a_numba_jax_op.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/creating_an_op.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/ctype.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/extending_faq.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/extending_pytensor_solution_1.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/graph_rewriting.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/graphstructures.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/inplace.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/op.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/other_ops.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/pics/symbolic_graph_opt.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/pipeline.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/scan.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/tips.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/type.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/unittest.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/extending/using_params.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/faq.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/generate_dtype_tensor_table.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/glossary.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/images/Elman_srnn.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/images/PyTensor_RGB.svg +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/images/blocksparse.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/images/lstm.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/images/lstm_memorycell.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/images/talk2010.gif +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/images/talk2010.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/install.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/internal/how_to_release.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/internal/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/internal/metadocumentation.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/introduction.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/compile/debugmode.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/compile/function.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/compile/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/compile/io.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/compile/mode.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/compile/nanguardmode.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/compile/opfromgraph.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/compile/ops.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/compile/profilemode.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/compile/shared.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/config.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp.html +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp2.html +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp2.pdf +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp2.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/ofg.html +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/examples/ofg2.html +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/index.ipynb +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/index_files/index_10_0.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/index_files/index_11_0.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/index_files/index_24_0.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/d3viz/index_files/index_25_0.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/gradient.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/graph/features.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/graph/fgraph.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/graph/graph.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/graph/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/graph/op.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/graph/type.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/graph/utils.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/misc/pkl_utils.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/printing.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/sandbox/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/sandbox/linalg.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/scalar/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/scan.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/sparse/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/sparse/sandbox.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/basic.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/basic_opt.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/bcast.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/bcast.svg +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/conv.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/elemwise.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/extra_ops.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/fft.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/io.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/math_opt.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/nlinalg.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/plot_fft.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/random/basic.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/random/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/random/utils.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/slinalg.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/tensor/utils.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/library/typed_list.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/links.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/optimizations.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/pylintrc +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/ccodegen.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/compilation.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/debugging_with_stepmode.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/elemwise_compiler.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/function.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/functional.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/how_to_make_ops.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/index2.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/interactive_debugger.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/logistic_regression_example.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/performance.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/randomnumbers.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/rethinkccodegen.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/sandbox.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/software.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/sparse.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/sandbox/tensoroptools.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/scripts/docgen.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/troubleshooting.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/adding.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/adding_solution_1.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/aliasing.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/apply.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/apply.svg +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/bcast.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/broadcasting.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/conditions.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/debug_faq.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/dlogistic.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/examples.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/faq_tutorial.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/gradients.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/index.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/loading_and_saving.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/logistic.gp +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/logistic.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/loop.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/loop_solution_1.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/modes.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/modes_solution_1.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/multi_cores.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/nan_tutorial.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/pics/d3viz.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/printing_drawing.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/profiling.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/profiling_example.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/profiling_example_out.prof +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/shape_info.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/sparse.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/tutorial/symbolic_graphs.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/doc/user_guide.rst +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pyproject.toml +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/bin/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/bin/pytensor_cache.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/breakpoint.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/builders.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/compiledir.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/compilelock.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/debugmode.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/function/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/function/pfunc.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/function/types.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/io.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/mode.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/monitormode.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/nanguardmode.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/ops.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/profiling.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/compile/sharedvalue.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/configdefaults.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/configparser.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/d3viz/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/d3viz/css/d3viz.css +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/d3viz/d3viz.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/d3viz/formatting.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/d3viz/js/d3viz.js +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/gradient.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/destroyhandler.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/features.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/fg.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/null_type.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/op.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/rewriting/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/rewriting/basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/rewriting/db.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/rewriting/kanren.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/rewriting/unify.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/rewriting/utils.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/type.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/graph/utils.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/ifelse.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/cmodule.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/cutils.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/cvm.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/exceptions.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/interface.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/lazylinker_c.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/op.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/params_type.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/c/type.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/blockwise.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/elemwise.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/nlinalg.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/random.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/scan.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/shape.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/sparse.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/subtensor.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/cython_support.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/elemwise.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/elemwise_codegen.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/random.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/scalar.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/scan.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/sparse.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/numba/linker.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/utils.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/link/vm.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/misc/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/misc/check_blas.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/misc/check_blas_many.sh +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/misc/check_duplicate_key.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/misc/elemwise_time_test.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/misc/frozendict.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/misc/may_share_memory.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/misc/ordered_set.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/misc/pkl_utils.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/misc/safe_asarray.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/printing.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/py.typed +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/raise_op.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scalar/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scalar/basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scalar/c_code/gamma.c +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scalar/loop.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scalar/sharedvar.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scan/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scan/basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scan/checkpoints.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scan/op.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scan/rewriting.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scan/scan_perform.pyx +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scan/scan_perform_ext.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scan/utils.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/scan/views.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/sparse/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/sparse/rewriting.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/sparse/sandbox/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/sparse/sandbox/sp.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/sparse/sandbox/sp2.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/sparse/sharedvar.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/sparse/type.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/sparse/utils.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/blas_c.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/blas_headers.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/blockwise.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/c_code/dimshuffle.c +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/conv/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/conv/abstract_conv.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/elemwise_cgen.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/exceptions.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/extra_ops.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/fft.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/fourier.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/functional.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/io.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/linalg.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/nlinalg.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/random/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/random/basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/random/op.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/random/rewriting/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/random/rewriting/basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/random/rewriting/jax.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/random/type.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/random/utils.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/random/var.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/blas.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/blas_c.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/blas_scipy.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/blockwise.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/elemwise.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/extra_ops.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/jax.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/special.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/subtensor.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/sharedvar.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/sort.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/subtensor.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/type.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/type_other.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/utils.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/var.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/variable.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/tensor/xlogx.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/typed_list/__init__.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/typed_list/basic.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/typed_list/rewriting.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/typed_list/type.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/updates.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/utils.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor/version.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor.egg-info/SOURCES.txt +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor.egg-info/dependency_links.txt +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor.egg-info/entry_points.txt +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor.egg-info/requires.txt +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/pytensor.egg-info/top_level.txt +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/scripts/downstream_pr.sh +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/scripts/upstream_pr.sh +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/setup.cfg +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/setup.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/tests/link/c/c_code/test_cenum.h +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/tests/link/c/c_code/test_quadratic_function.c +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/tests/tensor/conv/c_code/corr3d_gemm.c +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/tests/tensor/conv/c_code/corr_gemm.c +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/tests/test_breakpoint.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/tests/test_config.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/tests/test_gradient.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/tests/test_ifelse.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/tests/test_printing.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/tests/test_raise_op.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/tests/test_rop.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/tests/test_updates.py +0 -0
- {pytensor-2.18.4 → pytensor-2.18.6}/versioneer.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "
|
|
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
|
|
@@ -256,7 +256,7 @@ def vectorize_graph(
|
|
|
256
256
|
import pytensor
|
|
257
257
|
import pytensor.tensor as pt
|
|
258
258
|
|
|
259
|
-
from pytensor.graph import
|
|
259
|
+
from pytensor.graph import vectorize_graph
|
|
260
260
|
|
|
261
261
|
# Original graph
|
|
262
262
|
x = pt.vector("x")
|
|
@@ -264,7 +264,7 @@ def vectorize_graph(
|
|
|
264
264
|
|
|
265
265
|
# Vectorized graph
|
|
266
266
|
new_x = pt.matrix("new_x")
|
|
267
|
-
new_y =
|
|
267
|
+
new_y = vectorize_graph(y, replace={x: new_x})
|
|
268
268
|
|
|
269
269
|
fn = pytensor.function([new_x], new_y)
|
|
270
270
|
fn([[0, 1, 2], [2, 1, 0]])
|
|
@@ -277,7 +277,7 @@ def vectorize_graph(
|
|
|
277
277
|
import pytensor
|
|
278
278
|
import pytensor.tensor as pt
|
|
279
279
|
|
|
280
|
-
from pytensor.graph import
|
|
280
|
+
from pytensor.graph import vectorize_graph
|
|
281
281
|
|
|
282
282
|
# Original graph
|
|
283
283
|
x = pt.vector("x")
|
|
@@ -286,7 +286,7 @@ def vectorize_graph(
|
|
|
286
286
|
|
|
287
287
|
# Vectorized graph
|
|
288
288
|
new_x = pt.matrix("new_x")
|
|
289
|
-
[new_y1, new_y2] =
|
|
289
|
+
[new_y1, new_y2] = vectorize_graph([y1, y2], replace={x: new_x})
|
|
290
290
|
|
|
291
291
|
fn = pytensor.function([new_x], [new_y1, new_y2])
|
|
292
292
|
fn([[-10, 0, 10], [-11, 0, 11]])
|
|
@@ -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]
|
|
@@ -21,11 +21,14 @@ from pytensor.scalar.basic import (
|
|
|
21
21
|
Sub,
|
|
22
22
|
)
|
|
23
23
|
from pytensor.scalar.math import (
|
|
24
|
+
BetaIncInv,
|
|
24
25
|
Erf,
|
|
25
26
|
Erfc,
|
|
26
27
|
Erfcinv,
|
|
27
28
|
Erfcx,
|
|
28
29
|
Erfinv,
|
|
30
|
+
GammaIncCInv,
|
|
31
|
+
GammaIncInv,
|
|
29
32
|
Iv,
|
|
30
33
|
Ive,
|
|
31
34
|
Log1mexp,
|
|
@@ -226,6 +229,20 @@ def jax_funcify_Second(op, **kwargs):
|
|
|
226
229
|
return second
|
|
227
230
|
|
|
228
231
|
|
|
232
|
+
@jax_funcify.register(GammaIncInv)
|
|
233
|
+
def jax_funcify_GammaIncInv(op, **kwargs):
|
|
234
|
+
gammaincinv = try_import_tfp_jax_op(op, jax_op_name="igammainv")
|
|
235
|
+
|
|
236
|
+
return gammaincinv
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
@jax_funcify.register(GammaIncCInv)
|
|
240
|
+
def jax_funcify_GammaIncCInv(op, **kwargs):
|
|
241
|
+
gammainccinv = try_import_tfp_jax_op(op, jax_op_name="igammacinv")
|
|
242
|
+
|
|
243
|
+
return gammainccinv
|
|
244
|
+
|
|
245
|
+
|
|
229
246
|
@jax_funcify.register(Erf)
|
|
230
247
|
def jax_funcify_Erf(op, node, **kwargs):
|
|
231
248
|
def erf(x):
|
|
@@ -250,6 +267,7 @@ def jax_funcify_Erfinv(op, **kwargs):
|
|
|
250
267
|
return erfinv
|
|
251
268
|
|
|
252
269
|
|
|
270
|
+
@jax_funcify.register(BetaIncInv)
|
|
253
271
|
@jax_funcify.register(Erfcx)
|
|
254
272
|
@jax_funcify.register(Erfcinv)
|
|
255
273
|
def jax_funcify_from_tfp(op, **kwargs):
|
|
@@ -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
|
|
@@ -733,6 +733,64 @@ class GammaIncC(BinaryScalarOp):
|
|
|
733
733
|
gammaincc = GammaIncC(upgrade_to_float, name="gammaincc")
|
|
734
734
|
|
|
735
735
|
|
|
736
|
+
class GammaIncInv(BinaryScalarOp):
|
|
737
|
+
"""
|
|
738
|
+
Inverse to the regularized lower incomplete gamma function.
|
|
739
|
+
"""
|
|
740
|
+
|
|
741
|
+
nfunc_spec = ("scipy.special.gammaincinv", 2, 1)
|
|
742
|
+
|
|
743
|
+
@staticmethod
|
|
744
|
+
def st_impl(k, x):
|
|
745
|
+
return scipy.special.gammaincinv(k, x)
|
|
746
|
+
|
|
747
|
+
def impl(self, k, x):
|
|
748
|
+
return GammaIncInv.st_impl(k, x)
|
|
749
|
+
|
|
750
|
+
def grad(self, inputs, grads):
|
|
751
|
+
(k, x) = inputs
|
|
752
|
+
(gz,) = grads
|
|
753
|
+
return [
|
|
754
|
+
grad_not_implemented(self, 0, k),
|
|
755
|
+
gz * exp(gammaincinv(k, x)) * gamma(k) * (gammaincinv(k, x) ** (1 - k)),
|
|
756
|
+
]
|
|
757
|
+
|
|
758
|
+
def c_code(self, *args, **kwargs):
|
|
759
|
+
raise NotImplementedError()
|
|
760
|
+
|
|
761
|
+
|
|
762
|
+
gammaincinv = GammaIncInv(upgrade_to_float, name="gammaincinv")
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
class GammaIncCInv(BinaryScalarOp):
|
|
766
|
+
"""
|
|
767
|
+
Inverse to the regularized upper incomplete gamma function.
|
|
768
|
+
"""
|
|
769
|
+
|
|
770
|
+
nfunc_spec = ("scipy.special.gammainccinv", 2, 1)
|
|
771
|
+
|
|
772
|
+
@staticmethod
|
|
773
|
+
def st_impl(k, x):
|
|
774
|
+
return scipy.special.gammainccinv(k, x)
|
|
775
|
+
|
|
776
|
+
def impl(self, k, x):
|
|
777
|
+
return GammaIncCInv.st_impl(k, x)
|
|
778
|
+
|
|
779
|
+
def grad(self, inputs, grads):
|
|
780
|
+
(k, x) = inputs
|
|
781
|
+
(gz,) = grads
|
|
782
|
+
return [
|
|
783
|
+
grad_not_implemented(self, 0, k),
|
|
784
|
+
gz * -exp(gammainccinv(k, x)) * gamma(k) * (gammainccinv(k, x) ** (1 - k)),
|
|
785
|
+
]
|
|
786
|
+
|
|
787
|
+
def c_code(self, *args, **kwargs):
|
|
788
|
+
raise NotImplementedError()
|
|
789
|
+
|
|
790
|
+
|
|
791
|
+
gammainccinv = GammaIncCInv(upgrade_to_float, name="gammainccinv")
|
|
792
|
+
|
|
793
|
+
|
|
736
794
|
def _make_scalar_loop(n_steps, init, constant, inner_loop_fn, name, loop_op=ScalarLoop):
|
|
737
795
|
init = [as_scalar(x) if x is not None else None for x in init]
|
|
738
796
|
constant = [as_scalar(x) for x in constant]
|
|
@@ -1648,6 +1706,43 @@ def betainc_grad(p, q, x, wrtp: bool):
|
|
|
1648
1706
|
return grad
|
|
1649
1707
|
|
|
1650
1708
|
|
|
1709
|
+
class BetaIncInv(ScalarOp):
|
|
1710
|
+
"""
|
|
1711
|
+
Inverse of the regularized incomplete beta function.
|
|
1712
|
+
"""
|
|
1713
|
+
|
|
1714
|
+
nfunc_spec = ("scipy.special.betaincinv", 3, 1)
|
|
1715
|
+
|
|
1716
|
+
def impl(self, a, b, x):
|
|
1717
|
+
return scipy.special.betaincinv(a, b, x)
|
|
1718
|
+
|
|
1719
|
+
def grad(self, inputs, grads):
|
|
1720
|
+
(a, b, x) = inputs
|
|
1721
|
+
(gz,) = grads
|
|
1722
|
+
return [
|
|
1723
|
+
grad_not_implemented(self, 0, a),
|
|
1724
|
+
grad_not_implemented(self, 0, b),
|
|
1725
|
+
gz
|
|
1726
|
+
* exp(betaln(a, b))
|
|
1727
|
+
* ((1 - betaincinv(a, b, x)) ** (1 - b))
|
|
1728
|
+
* (betaincinv(a, b, x) ** (1 - a)),
|
|
1729
|
+
]
|
|
1730
|
+
|
|
1731
|
+
def c_code(self, *args, **kwargs):
|
|
1732
|
+
raise NotImplementedError()
|
|
1733
|
+
|
|
1734
|
+
|
|
1735
|
+
betaincinv = BetaIncInv(upgrade_to_float_no_complex, name="betaincinv")
|
|
1736
|
+
|
|
1737
|
+
|
|
1738
|
+
def betaln(a, b):
|
|
1739
|
+
"""
|
|
1740
|
+
Beta function from gamma function.
|
|
1741
|
+
"""
|
|
1742
|
+
|
|
1743
|
+
return gammaln(a) + gammaln(b) - gammaln(a + b)
|
|
1744
|
+
|
|
1745
|
+
|
|
1651
1746
|
class Hyp2F1(ScalarOp):
|
|
1652
1747
|
"""
|
|
1653
1748
|
Gaussian hypergeometric function ``2F1(a, b; c; z)``.
|
|
@@ -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)
|