pytensor 2.31.0__tar.gz → 2.31.1__tar.gz

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