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.
Files changed (413) hide show
  1. {pytensor-2.18.5 → pytensor-2.18.6}/PKG-INFO +1 -1
  2. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/_version.py +3 -3
  3. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/basic.py +4 -3
  4. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/replace.py +5 -0
  5. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/slinalg.py +9 -1
  6. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/linker.py +9 -2
  7. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/slinalg.py +23 -1
  8. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/basic.py +87 -9
  9. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/basic.py +35 -6
  10. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/blas.py +9 -9
  11. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/blas_scipy.py +1 -5
  12. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/elemwise.py +35 -15
  13. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/math.py +25 -10
  14. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/linalg.py +2 -2
  15. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/shape.py +8 -5
  16. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/slinalg.py +103 -1
  17. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/special.py +28 -0
  18. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor.egg-info/PKG-INFO +1 -1
  19. {pytensor-2.18.5 → pytensor-2.18.6}/scripts/mypy-failing.txt +1 -2
  20. {pytensor-2.18.5 → pytensor-2.18.6}/LICENSE.txt +0 -0
  21. {pytensor-2.18.5 → pytensor-2.18.6}/MANIFEST.in +0 -0
  22. {pytensor-2.18.5 → pytensor-2.18.6}/README.rst +0 -0
  23. {pytensor-2.18.5 → pytensor-2.18.6}/bin/__init__.py +0 -0
  24. {pytensor-2.18.5 → pytensor-2.18.6}/bin/pytensor-cache +0 -0
  25. {pytensor-2.18.5 → pytensor-2.18.6}/bin/pytensor_cache.py +0 -0
  26. {pytensor-2.18.5 → pytensor-2.18.6}/doc/.templates/PLACEHOLDER +0 -0
  27. {pytensor-2.18.5 → pytensor-2.18.6}/doc/.templates/layout.html +0 -0
  28. {pytensor-2.18.5 → pytensor-2.18.6}/doc/LICENSE.txt +0 -0
  29. {pytensor-2.18.5 → pytensor-2.18.6}/doc/README.md +0 -0
  30. {pytensor-2.18.5 → pytensor-2.18.6}/doc/acknowledgement.rst +0 -0
  31. {pytensor-2.18.5 → pytensor-2.18.6}/doc/bcast.png +0 -0
  32. {pytensor-2.18.5 → pytensor-2.18.6}/doc/bcast.svg +0 -0
  33. {pytensor-2.18.5 → pytensor-2.18.6}/doc/conf.py +0 -0
  34. {pytensor-2.18.5 → pytensor-2.18.6}/doc/core_development_guide.rst +0 -0
  35. {pytensor-2.18.5 → pytensor-2.18.6}/doc/css.inc +0 -0
  36. {pytensor-2.18.5 → pytensor-2.18.6}/doc/dev_start_guide.rst +0 -0
  37. {pytensor-2.18.5 → pytensor-2.18.6}/doc/environment.yml +0 -0
  38. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/apply.png +0 -0
  39. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/apply.svg +0 -0
  40. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/apply2.svg +0 -0
  41. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/creating_a_c_op.rst +0 -0
  42. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/creating_a_numba_jax_op.rst +0 -0
  43. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/creating_an_op.rst +0 -0
  44. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/ctype.rst +0 -0
  45. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/extending_faq.rst +0 -0
  46. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/extending_pytensor_solution_1.py +0 -0
  47. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/graph_rewriting.rst +0 -0
  48. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/graphstructures.rst +0 -0
  49. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/index.rst +0 -0
  50. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/inplace.rst +0 -0
  51. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/op.rst +0 -0
  52. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/other_ops.rst +0 -0
  53. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/pics/symbolic_graph_opt.png +0 -0
  54. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
  55. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/pipeline.rst +0 -0
  56. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/scan.rst +0 -0
  57. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/tips.rst +0 -0
  58. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/type.rst +0 -0
  59. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/unittest.rst +0 -0
  60. {pytensor-2.18.5 → pytensor-2.18.6}/doc/extending/using_params.rst +0 -0
  61. {pytensor-2.18.5 → pytensor-2.18.6}/doc/faq.rst +0 -0
  62. {pytensor-2.18.5 → pytensor-2.18.6}/doc/generate_dtype_tensor_table.py +0 -0
  63. {pytensor-2.18.5 → pytensor-2.18.6}/doc/glossary.rst +0 -0
  64. {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/Elman_srnn.png +0 -0
  65. {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/PyTensor_RGB.svg +0 -0
  66. {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/blocksparse.png +0 -0
  67. {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/lstm.png +0 -0
  68. {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/lstm_memorycell.png +0 -0
  69. {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/talk2010.gif +0 -0
  70. {pytensor-2.18.5 → pytensor-2.18.6}/doc/images/talk2010.png +0 -0
  71. {pytensor-2.18.5 → pytensor-2.18.6}/doc/index.rst +0 -0
  72. {pytensor-2.18.5 → pytensor-2.18.6}/doc/install.rst +0 -0
  73. {pytensor-2.18.5 → pytensor-2.18.6}/doc/internal/how_to_release.rst +0 -0
  74. {pytensor-2.18.5 → pytensor-2.18.6}/doc/internal/index.rst +0 -0
  75. {pytensor-2.18.5 → pytensor-2.18.6}/doc/internal/metadocumentation.rst +0 -0
  76. {pytensor-2.18.5 → pytensor-2.18.6}/doc/introduction.rst +0 -0
  77. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/debugmode.rst +0 -0
  78. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/function.rst +0 -0
  79. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/index.rst +0 -0
  80. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/io.rst +0 -0
  81. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/mode.rst +0 -0
  82. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/nanguardmode.rst +0 -0
  83. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/opfromgraph.rst +0 -0
  84. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/ops.rst +0 -0
  85. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/profilemode.rst +0 -0
  86. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/compile/shared.rst +0 -0
  87. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/config.rst +0 -0
  88. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
  89. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
  90. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
  91. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
  92. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
  93. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
  94. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
  95. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp.html +0 -0
  96. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp.png +0 -0
  97. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp2.html +0 -0
  98. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp2.pdf +0 -0
  99. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/mlp2.png +0 -0
  100. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/ofg.html +0 -0
  101. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/examples/ofg2.html +0 -0
  102. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/index.ipynb +0 -0
  103. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/index.rst +0 -0
  104. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/index_files/index_10_0.png +0 -0
  105. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/index_files/index_11_0.png +0 -0
  106. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/index_files/index_24_0.png +0 -0
  107. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/d3viz/index_files/index_25_0.png +0 -0
  108. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/gradient.rst +0 -0
  109. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/features.rst +0 -0
  110. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/fgraph.rst +0 -0
  111. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/graph.rst +0 -0
  112. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/index.rst +0 -0
  113. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/op.rst +0 -0
  114. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/type.rst +0 -0
  115. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/graph/utils.rst +0 -0
  116. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/index.rst +0 -0
  117. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/misc/pkl_utils.rst +0 -0
  118. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/printing.rst +0 -0
  119. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/sandbox/index.rst +0 -0
  120. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/sandbox/linalg.rst +0 -0
  121. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/scalar/index.rst +0 -0
  122. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/scan.rst +0 -0
  123. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/sparse/index.rst +0 -0
  124. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/sparse/sandbox.rst +0 -0
  125. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/basic.rst +0 -0
  126. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/basic_opt.rst +0 -0
  127. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/bcast.png +0 -0
  128. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/bcast.svg +0 -0
  129. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/conv.rst +0 -0
  130. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/elemwise.rst +0 -0
  131. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/extra_ops.rst +0 -0
  132. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/fft.rst +0 -0
  133. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/index.rst +0 -0
  134. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/io.rst +0 -0
  135. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/math_opt.rst +0 -0
  136. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/nlinalg.rst +0 -0
  137. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/plot_fft.png +0 -0
  138. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/random/basic.rst +0 -0
  139. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/random/index.rst +0 -0
  140. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/random/utils.rst +0 -0
  141. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/slinalg.rst +0 -0
  142. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/tensor/utils.rst +0 -0
  143. {pytensor-2.18.5 → pytensor-2.18.6}/doc/library/typed_list.rst +0 -0
  144. {pytensor-2.18.5 → pytensor-2.18.6}/doc/links.rst +0 -0
  145. {pytensor-2.18.5 → pytensor-2.18.6}/doc/optimizations.rst +0 -0
  146. {pytensor-2.18.5 → pytensor-2.18.6}/doc/pylintrc +0 -0
  147. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/ccodegen.rst +0 -0
  148. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/compilation.rst +0 -0
  149. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/debugging_with_stepmode.rst +0 -0
  150. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/elemwise_compiler.rst +0 -0
  151. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/function.rst +0 -0
  152. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/functional.rst +0 -0
  153. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/how_to_make_ops.rst +0 -0
  154. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/index.rst +0 -0
  155. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/index2.rst +0 -0
  156. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/interactive_debugger.rst +0 -0
  157. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/logistic_regression_example.rst +0 -0
  158. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/performance.rst +0 -0
  159. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/randomnumbers.rst +0 -0
  160. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/rethinkccodegen.rst +0 -0
  161. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/sandbox.rst +0 -0
  162. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/software.rst +0 -0
  163. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/sparse.rst +0 -0
  164. {pytensor-2.18.5 → pytensor-2.18.6}/doc/sandbox/tensoroptools.rst +0 -0
  165. {pytensor-2.18.5 → pytensor-2.18.6}/doc/scripts/docgen.py +0 -0
  166. {pytensor-2.18.5 → pytensor-2.18.6}/doc/troubleshooting.rst +0 -0
  167. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/adding.rst +0 -0
  168. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/adding_solution_1.py +0 -0
  169. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/aliasing.rst +0 -0
  170. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/apply.png +0 -0
  171. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/apply.svg +0 -0
  172. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/bcast.png +0 -0
  173. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/broadcasting.rst +0 -0
  174. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/conditions.rst +0 -0
  175. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/debug_faq.rst +0 -0
  176. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/dlogistic.png +0 -0
  177. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/examples.rst +0 -0
  178. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/faq_tutorial.rst +0 -0
  179. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/gradients.rst +0 -0
  180. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/index.rst +0 -0
  181. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/loading_and_saving.rst +0 -0
  182. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/logistic.gp +0 -0
  183. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/logistic.png +0 -0
  184. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/loop.rst +0 -0
  185. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/loop_solution_1.py +0 -0
  186. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/modes.rst +0 -0
  187. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/modes_solution_1.py +0 -0
  188. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/multi_cores.rst +0 -0
  189. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/nan_tutorial.rst +0 -0
  190. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/pics/d3viz.png +0 -0
  191. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
  192. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
  193. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
  194. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/printing_drawing.rst +0 -0
  195. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/profiling.rst +0 -0
  196. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/profiling_example.py +0 -0
  197. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/profiling_example_out.prof +0 -0
  198. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/shape_info.rst +0 -0
  199. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/sparse.rst +0 -0
  200. {pytensor-2.18.5 → pytensor-2.18.6}/doc/tutorial/symbolic_graphs.rst +0 -0
  201. {pytensor-2.18.5 → pytensor-2.18.6}/doc/user_guide.rst +0 -0
  202. {pytensor-2.18.5 → pytensor-2.18.6}/pyproject.toml +0 -0
  203. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/__init__.py +0 -0
  204. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/bin/__init__.py +0 -0
  205. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/bin/pytensor_cache.py +0 -0
  206. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/breakpoint.py +0 -0
  207. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/__init__.py +0 -0
  208. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/builders.py +0 -0
  209. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/compiledir.py +0 -0
  210. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/compilelock.py +0 -0
  211. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/debugmode.py +0 -0
  212. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/function/__init__.py +0 -0
  213. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/function/pfunc.py +0 -0
  214. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/function/types.py +0 -0
  215. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/io.py +0 -0
  216. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/mode.py +0 -0
  217. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/monitormode.py +0 -0
  218. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/nanguardmode.py +0 -0
  219. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/ops.py +0 -0
  220. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/profiling.py +0 -0
  221. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/compile/sharedvalue.py +0 -0
  222. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/configdefaults.py +0 -0
  223. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/configparser.py +0 -0
  224. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/__init__.py +0 -0
  225. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/css/d3-context-menu.css +0 -0
  226. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/css/d3viz.css +0 -0
  227. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/d3viz.py +0 -0
  228. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/formatting.py +0 -0
  229. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/js/d3-context-menu.js +0 -0
  230. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/js/d3.v3.min.js +0 -0
  231. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/js/d3viz.js +0 -0
  232. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
  233. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
  234. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/gradient.py +0 -0
  235. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/__init__.py +0 -0
  236. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/destroyhandler.py +0 -0
  237. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/features.py +0 -0
  238. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/fg.py +0 -0
  239. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/null_type.py +0 -0
  240. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/op.py +0 -0
  241. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/rewriting/__init__.py +0 -0
  242. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/rewriting/basic.py +0 -0
  243. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/rewriting/db.py +0 -0
  244. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/rewriting/kanren.py +0 -0
  245. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/rewriting/unify.py +0 -0
  246. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/rewriting/utils.py +0 -0
  247. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/type.py +0 -0
  248. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/graph/utils.py +0 -0
  249. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/ifelse.py +0 -0
  250. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/__init__.py +0 -0
  251. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/basic.py +0 -0
  252. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/__init__.py +0 -0
  253. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/basic.py +0 -0
  254. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
  255. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
  256. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/cmodule.py +0 -0
  257. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/cutils.py +0 -0
  258. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/cvm.py +0 -0
  259. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/exceptions.py +0 -0
  260. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/interface.py +0 -0
  261. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/lazylinker_c.py +0 -0
  262. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/op.py +0 -0
  263. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/params_type.py +0 -0
  264. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/c/type.py +0 -0
  265. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/__init__.py +0 -0
  266. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/__init__.py +0 -0
  267. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/basic.py +0 -0
  268. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/blockwise.py +0 -0
  269. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/elemwise.py +0 -0
  270. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
  271. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/nlinalg.py +0 -0
  272. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/random.py +0 -0
  273. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/scalar.py +0 -0
  274. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/scan.py +0 -0
  275. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/shape.py +0 -0
  276. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/sparse.py +0 -0
  277. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/subtensor.py +0 -0
  278. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
  279. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/__init__.py +0 -0
  280. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/__init__.py +0 -0
  281. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/basic.py +0 -0
  282. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/cython_support.py +0 -0
  283. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/elemwise.py +0 -0
  284. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/elemwise_codegen.py +0 -0
  285. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
  286. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
  287. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/random.py +0 -0
  288. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/scalar.py +0 -0
  289. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/scan.py +0 -0
  290. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/sparse.py +0 -0
  291. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
  292. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/numba/linker.py +0 -0
  293. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/utils.py +0 -0
  294. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/link/vm.py +0 -0
  295. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/__init__.py +0 -0
  296. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/check_blas.py +0 -0
  297. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/check_blas_many.sh +0 -0
  298. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/check_duplicate_key.py +0 -0
  299. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
  300. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/elemwise_time_test.py +0 -0
  301. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/frozendict.py +0 -0
  302. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/may_share_memory.py +0 -0
  303. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/ordered_set.py +0 -0
  304. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/pkl_utils.py +0 -0
  305. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/misc/safe_asarray.py +0 -0
  306. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/printing.py +0 -0
  307. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/py.typed +0 -0
  308. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/raise_op.py +0 -0
  309. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/__init__.py +0 -0
  310. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/basic.py +0 -0
  311. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
  312. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
  313. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/c_code/gamma.c +0 -0
  314. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/loop.py +0 -0
  315. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/math.py +0 -0
  316. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scalar/sharedvar.py +0 -0
  317. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/__init__.py +0 -0
  318. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/basic.py +0 -0
  319. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/checkpoints.py +0 -0
  320. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/op.py +0 -0
  321. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/rewriting.py +0 -0
  322. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/scan_perform.pyx +0 -0
  323. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/scan_perform_ext.py +0 -0
  324. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/utils.py +0 -0
  325. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/scan/views.py +0 -0
  326. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/__init__.py +0 -0
  327. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/rewriting.py +0 -0
  328. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/sandbox/__init__.py +0 -0
  329. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/sandbox/sp.py +0 -0
  330. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/sandbox/sp2.py +0 -0
  331. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/sharedvar.py +0 -0
  332. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/type.py +0 -0
  333. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/sparse/utils.py +0 -0
  334. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/__init__.py +0 -0
  335. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/blas_c.py +0 -0
  336. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/blas_headers.py +0 -0
  337. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/blockwise.py +0 -0
  338. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
  339. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
  340. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/c_code/dimshuffle.c +0 -0
  341. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/conv/__init__.py +0 -0
  342. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/conv/abstract_conv.py +0 -0
  343. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/elemwise_cgen.py +0 -0
  344. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/exceptions.py +0 -0
  345. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/extra_ops.py +0 -0
  346. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/fft.py +0 -0
  347. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/fourier.py +0 -0
  348. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/functional.py +0 -0
  349. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/inplace.py +0 -0
  350. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/io.py +0 -0
  351. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/linalg.py +0 -0
  352. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/nlinalg.py +0 -0
  353. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/__init__.py +0 -0
  354. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/basic.py +0 -0
  355. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/op.py +0 -0
  356. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/rewriting/__init__.py +0 -0
  357. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/rewriting/basic.py +0 -0
  358. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/rewriting/jax.py +0 -0
  359. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/type.py +0 -0
  360. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/utils.py +0 -0
  361. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/random/var.py +0 -0
  362. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/__init__.py +0 -0
  363. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/basic.py +0 -0
  364. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/blas.py +0 -0
  365. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/blas_c.py +0 -0
  366. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/blas_scipy.py +0 -0
  367. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/blockwise.py +0 -0
  368. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/elemwise.py +0 -0
  369. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/extra_ops.py +0 -0
  370. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/jax.py +0 -0
  371. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/math.py +0 -0
  372. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/shape.py +0 -0
  373. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/special.py +0 -0
  374. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/subtensor.py +0 -0
  375. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
  376. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/sharedvar.py +0 -0
  377. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/sort.py +0 -0
  378. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/subtensor.py +0 -0
  379. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/type.py +0 -0
  380. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/type_other.py +0 -0
  381. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/utils.py +0 -0
  382. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/var.py +0 -0
  383. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/variable.py +0 -0
  384. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/tensor/xlogx.py +0 -0
  385. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/typed_list/__init__.py +0 -0
  386. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/typed_list/basic.py +0 -0
  387. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/typed_list/rewriting.py +0 -0
  388. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/typed_list/type.py +0 -0
  389. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/updates.py +0 -0
  390. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/utils.py +0 -0
  391. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor/version.py +0 -0
  392. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor.egg-info/SOURCES.txt +0 -0
  393. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor.egg-info/dependency_links.txt +0 -0
  394. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor.egg-info/entry_points.txt +0 -0
  395. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor.egg-info/requires.txt +0 -0
  396. {pytensor-2.18.5 → pytensor-2.18.6}/pytensor.egg-info/top_level.txt +0 -0
  397. {pytensor-2.18.5 → pytensor-2.18.6}/scripts/downstream_pr.sh +0 -0
  398. {pytensor-2.18.5 → pytensor-2.18.6}/scripts/upstream_pr.sh +0 -0
  399. {pytensor-2.18.5 → pytensor-2.18.6}/setup.cfg +0 -0
  400. {pytensor-2.18.5 → pytensor-2.18.6}/setup.py +0 -0
  401. {pytensor-2.18.5 → pytensor-2.18.6}/tests/link/c/c_code/test_cenum.h +0 -0
  402. {pytensor-2.18.5 → pytensor-2.18.6}/tests/link/c/c_code/test_quadratic_function.c +0 -0
  403. {pytensor-2.18.5 → pytensor-2.18.6}/tests/tensor/conv/c_code/corr3d_gemm.c +0 -0
  404. {pytensor-2.18.5 → pytensor-2.18.6}/tests/tensor/conv/c_code/corr_gemm.c +0 -0
  405. {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_breakpoint.py +0 -0
  406. {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_config.py +0 -0
  407. {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_gradient.py +0 -0
  408. {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_ifelse.py +0 -0
  409. {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_printing.py +0 -0
  410. {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_raise_op.py +0 -0
  411. {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_rop.py +0 -0
  412. {pytensor-2.18.5 → pytensor-2.18.6}/tests/test_updates.py +0 -0
  413. {pytensor-2.18.5 → pytensor-2.18.6}/versioneer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytensor
3
- Version: 2.18.5
3
+ Version: 2.18.6
4
4
  Summary: Optimizing compiler for evaluating mathematical expressions on CPUs and GPUs.
5
5
  Author-email: pymc-devs <pymc.devs@gmail.com>
6
6
  License: .. _license:
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-01-02T15:10:04+0100",
11
+ "date": "2024-01-12T14:29:52+0100",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "e180927564549f3bfffd5041c3008210de2d99b5",
15
- "version": "2.18.5"
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
- # We suppose that all outputs are always computed
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(i.owner for i in cur.inputs if i.owner)
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 typyfied
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
- fgraph.inputs.index(old_inp), reason="JAXLinker.fgraph_convert"
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__ }{{axis={self.axis}}}"
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__ }{{{', '.join(l)}}}"
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 DimShuffle, Elemwise, scalar_elemwise
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, batched_x):
3618
- batched_ndims = batched_x.type.ndim - node.inputs[0].type.ndim
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
- batched_x,
3630
+ batch_x,
3621
3631
  offset=op.offset,
3622
- axis1=op.axis1 + batched_ndims,
3623
- axis2=op.axis2 + batched_ndims,
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
- 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()
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 = node.tag.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 = np.core.numeric.normalize_axis_tuple(axis, ndim=max(1, inp_dims))
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
- @_vectorize_node.register(CAReduce)
1761
- def vectorize_careduce(op: CAReduce, node: Apply, x: TensorVariable) -> Apply:
1762
- batched_ndims = x.type.ndim - node.inputs[0].type.ndim
1763
- if not batched_ndims:
1764
- return node.op.make_node(x)
1765
- axes = op.axis
1766
- # e.g., sum(matrix, axis=None) -> sum(tensor4, axis=(2, 3))
1767
- # e.g., sum(matrix, axis=0) -> sum(tensor4, axis=(2,))
1768
- if axes is None:
1769
- axes = list(range(node.inputs[0].type.ndim))
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
- axes = list(axes)
1772
- new_axes = [axis + batched_ndims for axis in axes]
1773
- new_op = op.clone(axis=new_axes)
1774
- return new_op.make_node(x)
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 CAReduce, DimShuffle, Elemwise, scalar_elemwise
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
- # We thus prefer to use MaxAndArgmax, if possible. It does not
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 vectorize_node_to_matmul(op, node, batched_x, batched_y):
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 = solve(L, b, assume_a="sym", lower=True, b_ndim=2)
219
- x = solve(_T(L), Li_b, assume_a="sym", lower=False, b_ndim=2)
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(op: Unbroadcast, node: Apply, x: TensorVariable) -> Apply:
1107
- batched_ndims = x.type.ndim - node.inputs[0].type.ndim
1108
- old_axes = op.axes
1109
- new_axes = (old_axis + batched_ndims for old_axis in old_axes)
1110
- return cast(Apply, unbroadcast(x, *new_axes).owner)
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)