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