pytensor 2.38.2__tar.gz → 2.38.3__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 (516) hide show
  1. {pytensor-2.38.2/pytensor.egg-info → pytensor-2.38.3}/PKG-INFO +3 -3
  2. {pytensor-2.38.2 → pytensor-2.38.3}/pyproject.toml +3 -2
  3. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/_version.py +3 -3
  4. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/cache.py +31 -0
  5. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/basic.py +5 -2
  6. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/basic.py +34 -0
  7. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/optimize.py +88 -73
  8. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/blockwise.py +38 -2
  9. {pytensor-2.38.2 → pytensor-2.38.3/pytensor.egg-info}/PKG-INFO +3 -3
  10. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor.egg-info/requires.txt +2 -2
  11. {pytensor-2.38.2 → pytensor-2.38.3}/LICENSE.txt +0 -0
  12. {pytensor-2.38.2 → pytensor-2.38.3}/MANIFEST.in +0 -0
  13. {pytensor-2.38.2 → pytensor-2.38.3}/README.rst +0 -0
  14. {pytensor-2.38.2 → pytensor-2.38.3}/doc/.templates/PLACEHOLDER +0 -0
  15. {pytensor-2.38.2 → pytensor-2.38.3}/doc/.templates/layout.html +0 -0
  16. {pytensor-2.38.2 → pytensor-2.38.3}/doc/.templates/nb-badges.html +0 -0
  17. {pytensor-2.38.2 → pytensor-2.38.3}/doc/.templates/rendered_citation.html +0 -0
  18. {pytensor-2.38.2 → pytensor-2.38.3}/doc/LICENSE.txt +0 -0
  19. {pytensor-2.38.2 → pytensor-2.38.3}/doc/README.md +0 -0
  20. {pytensor-2.38.2 → pytensor-2.38.3}/doc/_drafts/benchmark_mlx_v_jax_corrected.ipynb +0 -0
  21. {pytensor-2.38.2 → pytensor-2.38.3}/doc/_thumbnails/autodiff/vector_jacobian_product.png +0 -0
  22. {pytensor-2.38.2 → pytensor-2.38.3}/doc/acknowledgement.rst +0 -0
  23. {pytensor-2.38.2 → pytensor-2.38.3}/doc/bcast.png +0 -0
  24. {pytensor-2.38.2 → pytensor-2.38.3}/doc/bcast.svg +0 -0
  25. {pytensor-2.38.2 → pytensor-2.38.3}/doc/blog.md +0 -0
  26. {pytensor-2.38.2 → pytensor-2.38.3}/doc/conf.py +0 -0
  27. {pytensor-2.38.2 → pytensor-2.38.3}/doc/core_development_guide.rst +0 -0
  28. {pytensor-2.38.2 → pytensor-2.38.3}/doc/css.inc +0 -0
  29. {pytensor-2.38.2 → pytensor-2.38.3}/doc/dev_start_guide.rst +0 -0
  30. {pytensor-2.38.2 → pytensor-2.38.3}/doc/environment.yml +0 -0
  31. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/apply.png +0 -0
  32. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/apply.svg +0 -0
  33. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/apply2.svg +0 -0
  34. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/creating_a_c_op.rst +0 -0
  35. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/creating_a_numba_jax_op.rst +0 -0
  36. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/creating_an_op.rst +0 -0
  37. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/ctype.rst +0 -0
  38. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/extending_faq.rst +0 -0
  39. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/extending_pytensor_solution_1.py +0 -0
  40. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/graph_rewriting.rst +0 -0
  41. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/graphstructures.rst +0 -0
  42. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/index.rst +0 -0
  43. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/inplace.rst +0 -0
  44. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/op.rst +0 -0
  45. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/other_ops.rst +0 -0
  46. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/pics/symbolic_graph_opt.png +0 -0
  47. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
  48. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/pipeline.rst +0 -0
  49. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/scan.rst +0 -0
  50. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/tips.rst +0 -0
  51. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/type.rst +0 -0
  52. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/unittest.rst +0 -0
  53. {pytensor-2.38.2 → pytensor-2.38.3}/doc/extending/using_params.rst +0 -0
  54. {pytensor-2.38.2 → pytensor-2.38.3}/doc/faq.rst +0 -0
  55. {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/applications/normalizing_flows_in_pytensor.ipynb +0 -0
  56. {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/autodiff/vector_jacobian_product.ipynb +0 -0
  57. {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/introduction/pytensor_intro.ipynb +0 -0
  58. {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/optimize/root.ipynb +0 -0
  59. {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/page_footer.md +0 -0
  60. {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/rewrites/graph_rewrites.ipynb +0 -0
  61. {pytensor-2.38.2 → pytensor-2.38.3}/doc/gallery/scan/scan_tutorial.ipynb +0 -0
  62. {pytensor-2.38.2 → pytensor-2.38.3}/doc/generate_dtype_tensor_table.py +0 -0
  63. {pytensor-2.38.2 → pytensor-2.38.3}/doc/glossary.rst +0 -0
  64. {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/Elman_srnn.png +0 -0
  65. {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/PyTensor.png +0 -0
  66. {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/PyTensor_RGB.svg +0 -0
  67. {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/PyTensor_logo.png +0 -0
  68. {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/binder.svg +0 -0
  69. {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/blocksparse.png +0 -0
  70. {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/colab.svg +0 -0
  71. {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/github.svg +0 -0
  72. {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/lstm.png +0 -0
  73. {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/lstm_memorycell.png +0 -0
  74. {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/talk2010.gif +0 -0
  75. {pytensor-2.38.2 → pytensor-2.38.3}/doc/images/talk2010.png +0 -0
  76. {pytensor-2.38.2 → pytensor-2.38.3}/doc/index.rst +0 -0
  77. {pytensor-2.38.2 → pytensor-2.38.3}/doc/install.rst +0 -0
  78. {pytensor-2.38.2 → pytensor-2.38.3}/doc/internal/how_to_release.rst +0 -0
  79. {pytensor-2.38.2 → pytensor-2.38.3}/doc/internal/index.rst +0 -0
  80. {pytensor-2.38.2 → pytensor-2.38.3}/doc/internal/metadocumentation.rst +0 -0
  81. {pytensor-2.38.2 → pytensor-2.38.3}/doc/introduction.rst +0 -0
  82. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/debugmode.rst +0 -0
  83. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/function.rst +0 -0
  84. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/index.rst +0 -0
  85. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/io.rst +0 -0
  86. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/mode.rst +0 -0
  87. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/nanguardmode.rst +0 -0
  88. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/opfromgraph.rst +0 -0
  89. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/ops.rst +0 -0
  90. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/profilemode.rst +0 -0
  91. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/compile/shared.rst +0 -0
  92. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/config.rst +0 -0
  93. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
  94. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
  95. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
  96. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
  97. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
  98. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
  99. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
  100. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/mlp.html +0 -0
  101. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/mlp.png +0 -0
  102. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/mlp2.html +0 -0
  103. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/mlp2.pdf +0 -0
  104. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/mlp2.png +0 -0
  105. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/ofg.html +0 -0
  106. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/examples/ofg2.html +0 -0
  107. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/index.ipynb +0 -0
  108. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/index.rst +0 -0
  109. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/index_files/index_10_0.png +0 -0
  110. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/index_files/index_11_0.png +0 -0
  111. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/index_files/index_24_0.png +0 -0
  112. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/d3viz/index_files/index_25_0.png +0 -0
  113. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/features.rst +0 -0
  114. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/fgraph.rst +0 -0
  115. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/graph.rst +0 -0
  116. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/index.rst +0 -0
  117. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/op.rst +0 -0
  118. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/replace.rst +0 -0
  119. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/type.rst +0 -0
  120. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/graph/utils.rst +0 -0
  121. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/index.rst +0 -0
  122. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/misc/pkl_utils.rst +0 -0
  123. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/printing.rst +0 -0
  124. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/scalar/index.rst +0 -0
  125. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/scan.rst +0 -0
  126. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/sparse/index.rst +0 -0
  127. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/sparse/sandbox.rst +0 -0
  128. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/basic.rst +0 -0
  129. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/basic_opt.rst +0 -0
  130. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/bcast.png +0 -0
  131. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/bcast.svg +0 -0
  132. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/elemwise.rst +0 -0
  133. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/extra_ops.rst +0 -0
  134. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/fft.rst +0 -0
  135. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/functional.rst +0 -0
  136. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/index.rst +0 -0
  137. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/io.rst +0 -0
  138. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/math_opt.rst +0 -0
  139. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/nlinalg.rst +0 -0
  140. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/optimize.rst +0 -0
  141. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/plot_fft.png +0 -0
  142. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/random/distributions.rst +0 -0
  143. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/random/index.rst +0 -0
  144. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/slinalg.rst +0 -0
  145. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/tensor/utils.rst +0 -0
  146. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/typed_list.rst +0 -0
  147. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/index.md +0 -0
  148. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/linalg.md +0 -0
  149. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/math.md +0 -0
  150. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/module_functions.md +0 -0
  151. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/random.md +0 -0
  152. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/signal.md +0 -0
  153. {pytensor-2.38.2 → pytensor-2.38.3}/doc/library/xtensor/type.md +0 -0
  154. {pytensor-2.38.2 → pytensor-2.38.3}/doc/links.rst +0 -0
  155. {pytensor-2.38.2 → pytensor-2.38.3}/doc/optimizations.rst +0 -0
  156. {pytensor-2.38.2 → pytensor-2.38.3}/doc/pylintrc +0 -0
  157. {pytensor-2.38.2 → pytensor-2.38.3}/doc/robots.txt +0 -0
  158. {pytensor-2.38.2 → pytensor-2.38.3}/doc/troubleshooting.rst +0 -0
  159. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/adding.rst +0 -0
  160. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/adding_solution_1.py +0 -0
  161. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/aliasing.rst +0 -0
  162. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/apply.png +0 -0
  163. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/apply.svg +0 -0
  164. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/bcast.png +0 -0
  165. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/broadcasting.rst +0 -0
  166. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/conditions.rst +0 -0
  167. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/debug_faq.rst +0 -0
  168. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/dlogistic.png +0 -0
  169. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/examples.rst +0 -0
  170. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/faq_tutorial.rst +0 -0
  171. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/gradients.rst +0 -0
  172. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/index.rst +0 -0
  173. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/loading_and_saving.rst +0 -0
  174. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/logistic.gp +0 -0
  175. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/logistic.png +0 -0
  176. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/loop.rst +0 -0
  177. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/loop_solution_1.py +0 -0
  178. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/modes.rst +0 -0
  179. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/modes_solution_1.py +0 -0
  180. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/multi_cores.rst +0 -0
  181. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/nan_tutorial.rst +0 -0
  182. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/pics/d3viz.png +0 -0
  183. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
  184. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
  185. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
  186. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/printing_drawing.rst +0 -0
  187. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/prng.rst +0 -0
  188. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/profiling.rst +0 -0
  189. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/profiling_example.py +0 -0
  190. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/profiling_example_out.prof +0 -0
  191. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/shape_info.rst +0 -0
  192. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/sparse.rst +0 -0
  193. {pytensor-2.38.2 → pytensor-2.38.3}/doc/tutorial/symbolic_graphs.rst +0 -0
  194. {pytensor-2.38.2 → pytensor-2.38.3}/doc/user_guide.rst +0 -0
  195. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/__init__.py +0 -0
  196. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/bin/__init__.py +0 -0
  197. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/bin/pytensor_cache.py +0 -0
  198. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/breakpoint.py +0 -0
  199. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/__init__.py +0 -0
  200. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/builders.py +0 -0
  201. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/compiledir.py +0 -0
  202. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/compilelock.py +0 -0
  203. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/debugmode.py +0 -0
  204. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/function/__init__.py +0 -0
  205. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/function/pfunc.py +0 -0
  206. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/function/types.py +0 -0
  207. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/io.py +0 -0
  208. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/mode.py +0 -0
  209. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/monitormode.py +0 -0
  210. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/nanguardmode.py +0 -0
  211. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/ops.py +0 -0
  212. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/profiling.py +0 -0
  213. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/compile/sharedvalue.py +0 -0
  214. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/configdefaults.py +0 -0
  215. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/configparser.py +0 -0
  216. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/__init__.py +0 -0
  217. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/css/d3-context-menu.css +0 -0
  218. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/css/d3viz.css +0 -0
  219. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/d3viz.py +0 -0
  220. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/formatting.py +0 -0
  221. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/html/template.html +0 -0
  222. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/js/d3-context-menu.js +0 -0
  223. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/js/d3.v3.min.js +0 -0
  224. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/js/d3viz.js +0 -0
  225. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
  226. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
  227. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/gradient.py +0 -0
  228. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/__init__.py +0 -0
  229. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/basic.py +0 -0
  230. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/destroyhandler.py +0 -0
  231. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/features.py +0 -0
  232. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/fg.py +0 -0
  233. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/null_type.py +0 -0
  234. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/op.py +0 -0
  235. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/replace.py +0 -0
  236. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/rewriting/__init__.py +0 -0
  237. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/rewriting/basic.py +0 -0
  238. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/rewriting/db.py +0 -0
  239. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/rewriting/kanren.py +0 -0
  240. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/rewriting/unify.py +0 -0
  241. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/rewriting/utils.py +0 -0
  242. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/traversal.py +0 -0
  243. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/type.py +0 -0
  244. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/graph/utils.py +0 -0
  245. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/ifelse.py +0 -0
  246. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/ipython.py +0 -0
  247. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/__init__.py +0 -0
  248. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/basic.py +0 -0
  249. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/__init__.py +0 -0
  250. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/basic.py +0 -0
  251. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
  252. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
  253. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/cmodule.py +0 -0
  254. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/cutils.py +0 -0
  255. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/cvm.py +0 -0
  256. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/exceptions.py +0 -0
  257. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/interface.py +0 -0
  258. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/lazylinker_c.py +0 -0
  259. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/op.py +0 -0
  260. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/params_type.py +0 -0
  261. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/c/type.py +0 -0
  262. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/__init__.py +0 -0
  263. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/__init__.py +0 -0
  264. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/basic.py +0 -0
  265. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/blas.py +0 -0
  266. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/blockwise.py +0 -0
  267. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/einsum.py +0 -0
  268. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/elemwise.py +0 -0
  269. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
  270. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/math.py +0 -0
  271. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/nlinalg.py +0 -0
  272. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/pad.py +0 -0
  273. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/random.py +0 -0
  274. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/scalar.py +0 -0
  275. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/scan.py +0 -0
  276. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/shape.py +0 -0
  277. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/signal/__init__.py +0 -0
  278. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/signal/conv.py +0 -0
  279. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/slinalg.py +0 -0
  280. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/sort.py +0 -0
  281. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/sparse.py +0 -0
  282. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/subtensor.py +0 -0
  283. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
  284. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/linker.py +0 -0
  285. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/jax/ops.py +0 -0
  286. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/__init__.py +0 -0
  287. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/__init__.py +0 -0
  288. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/basic.py +0 -0
  289. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/blockwise.py +0 -0
  290. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/core.py +0 -0
  291. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/elemwise.py +0 -0
  292. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/extra_ops.py +0 -0
  293. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/math.py +0 -0
  294. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/nlinalg.py +0 -0
  295. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/shape.py +0 -0
  296. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/signal/__init__.py +0 -0
  297. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/signal/conv.py +0 -0
  298. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/slinalg.py +0 -0
  299. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/sort.py +0 -0
  300. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/dispatch/subtensor.py +0 -0
  301. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/mlx/linker.py +0 -0
  302. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/__init__.py +0 -0
  303. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/__init__.py +0 -0
  304. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/blockwise.py +0 -0
  305. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/compile_ops.py +0 -0
  306. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/cython_support.py +0 -0
  307. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/elemwise.py +0 -0
  308. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
  309. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/_LAPACK.py +0 -0
  310. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/__init__.py +0 -0
  311. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/__init__.py +0 -0
  312. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/cholesky.py +0 -0
  313. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/lu.py +0 -0
  314. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/lu_factor.py +0 -0
  315. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/qr.py +0 -0
  316. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/qz.py +0 -0
  317. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/decomposition/schur.py +0 -0
  318. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/__init__.py +0 -0
  319. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/cholesky.py +0 -0
  320. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/general.py +0 -0
  321. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/linear_control.py +0 -0
  322. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/lu_solve.py +0 -0
  323. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/posdef.py +0 -0
  324. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/symmetric.py +0 -0
  325. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/triangular.py +0 -0
  326. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/tridiagonal.py +0 -0
  327. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/solve/utils.py +0 -0
  328. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/linalg/utils.py +0 -0
  329. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
  330. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/random.py +0 -0
  331. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/scalar.py +0 -0
  332. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/scan.py +0 -0
  333. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/shape.py +0 -0
  334. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/signal/__init__.py +0 -0
  335. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/signal/conv.py +0 -0
  336. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/slinalg.py +0 -0
  337. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/sort.py +0 -0
  338. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/sparse/__init__.py +0 -0
  339. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/sparse/basic.py +0 -0
  340. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/sparse/math.py +0 -0
  341. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/sparse/variable.py +0 -0
  342. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/string_codegen.py +0 -0
  343. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/subtensor.py +0 -0
  344. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
  345. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/typed_list.py +0 -0
  346. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/dispatch/vectorize_codegen.py +0 -0
  347. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/numba/linker.py +0 -0
  348. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/__init__.py +0 -0
  349. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/basic.py +0 -0
  350. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/blas.py +0 -0
  351. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/blockwise.py +0 -0
  352. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/elemwise.py +0 -0
  353. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/extra_ops.py +0 -0
  354. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/math.py +0 -0
  355. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/nlinalg.py +0 -0
  356. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/scalar.py +0 -0
  357. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/shape.py +0 -0
  358. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/slinalg.py +0 -0
  359. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/sort.py +0 -0
  360. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/dispatch/subtensor.py +0 -0
  361. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/pytorch/linker.py +0 -0
  362. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/utils.py +0 -0
  363. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/link/vm.py +0 -0
  364. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/__init__.py +0 -0
  365. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/check_blas.py +0 -0
  366. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/check_blas_many.sh +0 -0
  367. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/check_duplicate_key.py +0 -0
  368. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
  369. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/elemwise_time_test.py +0 -0
  370. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/frozendict.py +0 -0
  371. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/may_share_memory.py +0 -0
  372. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/ordered_set.py +0 -0
  373. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/misc/pkl_utils.py +0 -0
  374. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/npy_2_compat.py +0 -0
  375. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/printing.py +0 -0
  376. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/py.typed +0 -0
  377. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/raise_op.py +0 -0
  378. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/__init__.py +0 -0
  379. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/basic.py +0 -0
  380. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
  381. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
  382. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/c_code/gamma.c +0 -0
  383. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/c_code/incbet.c +0 -0
  384. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/loop.py +0 -0
  385. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/math.py +0 -0
  386. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scalar/sharedvar.py +0 -0
  387. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/__init__.py +0 -0
  388. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/basic.py +0 -0
  389. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/checkpoints.py +0 -0
  390. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/op.py +0 -0
  391. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/rewriting.py +0 -0
  392. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/scan_perform.pyx +0 -0
  393. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/scan_perform_ext.py +0 -0
  394. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/utils.py +0 -0
  395. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/scan/views.py +0 -0
  396. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/__init__.py +0 -0
  397. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/basic.py +0 -0
  398. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/linalg.py +0 -0
  399. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/math.py +0 -0
  400. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/rewriting.py +0 -0
  401. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/sharedvar.py +0 -0
  402. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/type.py +0 -0
  403. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/utils.py +0 -0
  404. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/sparse/variable.py +0 -0
  405. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/__init__.py +0 -0
  406. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/_linalg/__init__.py +0 -0
  407. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/_linalg/solve/__init__.py +0 -0
  408. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/_linalg/solve/linear_control.py +0 -0
  409. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/_linalg/solve/rewriting.py +0 -0
  410. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/_linalg/solve/tridiagonal.py +0 -0
  411. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/blas.py +0 -0
  412. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/blas_c.py +0 -0
  413. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/blas_headers.py +0 -0
  414. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/blockwise.py +0 -0
  415. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
  416. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
  417. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/c_code/dimshuffle.c +0 -0
  418. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/einsum.py +0 -0
  419. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/elemwise.py +0 -0
  420. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/elemwise_cgen.py +0 -0
  421. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/exceptions.py +0 -0
  422. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/extra_ops.py +0 -0
  423. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/fft.py +0 -0
  424. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/fourier.py +0 -0
  425. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/functional.py +0 -0
  426. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/interpolate.py +0 -0
  427. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/linalg.py +0 -0
  428. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/math.py +0 -0
  429. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/nlinalg.py +0 -0
  430. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/pad.py +0 -0
  431. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/__init__.py +0 -0
  432. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/basic.py +0 -0
  433. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/op.py +0 -0
  434. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/rewriting/__init__.py +0 -0
  435. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/rewriting/basic.py +0 -0
  436. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/rewriting/jax.py +0 -0
  437. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/rewriting/numba.py +0 -0
  438. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/type.py +0 -0
  439. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/utils.py +0 -0
  440. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/random/var.py +0 -0
  441. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/reshape.py +0 -0
  442. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/__init__.py +0 -0
  443. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/basic.py +0 -0
  444. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/blas.py +0 -0
  445. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/blas_c.py +0 -0
  446. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/einsum.py +0 -0
  447. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/elemwise.py +0 -0
  448. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/extra_ops.py +0 -0
  449. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/jax.py +0 -0
  450. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/linalg.py +0 -0
  451. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/math.py +0 -0
  452. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/numba.py +0 -0
  453. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/ofg.py +0 -0
  454. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/reshape.py +0 -0
  455. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/shape.py +0 -0
  456. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/special.py +0 -0
  457. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/subtensor.py +0 -0
  458. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/subtensor_lift.py +0 -0
  459. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
  460. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/shape.py +0 -0
  461. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/sharedvar.py +0 -0
  462. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/signal/__init__.py +0 -0
  463. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/signal/conv.py +0 -0
  464. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/slinalg.py +0 -0
  465. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/sort.py +0 -0
  466. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/special.py +0 -0
  467. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/subtensor.py +0 -0
  468. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/type.py +0 -0
  469. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/type_other.py +0 -0
  470. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/utils.py +0 -0
  471. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/var.py +0 -0
  472. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/variable.py +0 -0
  473. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/tensor/xlogx.py +0 -0
  474. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/typed_list/__init__.py +0 -0
  475. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/typed_list/basic.py +0 -0
  476. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/typed_list/rewriting.py +0 -0
  477. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/typed_list/type.py +0 -0
  478. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/updates.py +0 -0
  479. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/utils.py +0 -0
  480. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/__init__.py +0 -0
  481. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/basic.py +0 -0
  482. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/indexing.py +0 -0
  483. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/linalg.py +0 -0
  484. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/math.py +0 -0
  485. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/random.py +0 -0
  486. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/reduction.py +0 -0
  487. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/__init__.py +0 -0
  488. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/basic.py +0 -0
  489. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/indexing.py +0 -0
  490. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/math.py +0 -0
  491. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/reduction.py +0 -0
  492. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/shape.py +0 -0
  493. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/utils.py +0 -0
  494. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/rewriting/vectorization.py +0 -0
  495. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/shape.py +0 -0
  496. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/signal.py +0 -0
  497. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/type.py +0 -0
  498. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor/xtensor/vectorization.py +0 -0
  499. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor.egg-info/SOURCES.txt +0 -0
  500. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor.egg-info/dependency_links.txt +0 -0
  501. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor.egg-info/entry_points.txt +0 -0
  502. {pytensor-2.38.2 → pytensor-2.38.3}/pytensor.egg-info/top_level.txt +0 -0
  503. {pytensor-2.38.2 → pytensor-2.38.3}/scripts/mypy-failing.txt +0 -0
  504. {pytensor-2.38.2 → pytensor-2.38.3}/scripts/slowest_tests/update-slowest-times-issue.sh +0 -0
  505. {pytensor-2.38.2 → pytensor-2.38.3}/setup.cfg +0 -0
  506. {pytensor-2.38.2 → pytensor-2.38.3}/setup.py +0 -0
  507. {pytensor-2.38.2 → pytensor-2.38.3}/tests/link/c/c_code/test_cenum.h +0 -0
  508. {pytensor-2.38.2 → pytensor-2.38.3}/tests/link/c/c_code/test_quadratic_function.c +0 -0
  509. {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_breakpoint.py +0 -0
  510. {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_config.py +0 -0
  511. {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_gradient.py +0 -0
  512. {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_ifelse.py +0 -0
  513. {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_printing.py +0 -0
  514. {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_raise_op.py +0 -0
  515. {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_rop.py +0 -0
  516. {pytensor-2.38.2 → pytensor-2.38.3}/tests/test_updates.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytensor
3
- Version: 2.38.2
3
+ Version: 2.38.3
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
@@ -31,7 +31,7 @@ License-File: LICENSE.txt
31
31
  Requires-Dist: setuptools>=59.0.0
32
32
  Requires-Dist: scipy<2,>=1
33
33
  Requires-Dist: numpy>=2.0
34
- Requires-Dist: numba<1,>0.57
34
+ Requires-Dist: numba<=0.65.1,>=0.58
35
35
  Requires-Dist: filelock>=3.15
36
36
  Requires-Dist: etuples
37
37
  Requires-Dist: logical-unification
@@ -60,7 +60,7 @@ Provides-Extra: jax
60
60
  Requires-Dist: jax; extra == "jax"
61
61
  Requires-Dist: jaxlib; extra == "jax"
62
62
  Provides-Extra: numba
63
- Requires-Dist: numba>=0.57; extra == "numba"
63
+ Requires-Dist: numba<=0.65.1,>=0.58; extra == "numba"
64
64
  Requires-Dist: llvmlite; extra == "numba"
65
65
  Dynamic: license-file
66
66
 
@@ -50,7 +50,7 @@ dependencies = [
50
50
  "setuptools>=59.0.0",
51
51
  "scipy>=1,<2",
52
52
  "numpy>=2.0",
53
- "numba>0.57,<1",
53
+ "numba>=0.58,<=0.65.1",
54
54
  "filelock>=3.15",
55
55
  "etuples",
56
56
  "logical-unification",
@@ -81,7 +81,7 @@ tests = [
81
81
  ]
82
82
  rtd = ["sphinx>=5.1.0,<6", "pygments", "pydot"]
83
83
  jax = ["jax", "jaxlib"]
84
- numba = ["numba>=0.57", "llvmlite"]
84
+ numba = ["numba>=0.58,<=0.65.1", "llvmlite"]
85
85
 
86
86
  [tool.setuptools.packages.find]
87
87
  include = ["pytensor*"]
@@ -158,6 +158,7 @@ lines-after-imports = 2
158
158
  "pytensor/bin/pytensor_cache.py" = ["T201"]
159
159
  "tests/compile/test_monitormode.py" = ["T201"]
160
160
  "scripts/run_mypy.py" = ["T201"]
161
+ "scripts/bump_numba_upper_bound.py" = ["T201"]
161
162
  # Test modules of optional backends that use `pytest.importorskip`, skip "E402"
162
163
  "tests/link/jax/**/test_*.py" = ["E402"]
163
164
  "tests/link/numba/**/test_*.py" = ["E402"]
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2026-03-06T13:58:13+0100",
11
+ "date": "2026-04-27T13:00:34+0200",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "7fa753b583fd16f46754b356c21055c9559080ef",
15
- "version": "2.38.2"
14
+ "full-revisionid": "74cb66529f26343d5034adbf38e8ccd9996449fc",
15
+ "version": "2.38.3"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -1,3 +1,4 @@
1
+ import uuid
1
2
  from collections.abc import Callable
2
3
  from hashlib import sha256
3
4
  from pickle import dump
@@ -8,6 +9,7 @@ from weakref import WeakKeyDictionary
8
9
  import numba
9
10
  from llvmlite import ir
10
11
  from numba.core import cgutils
12
+ from numba.core.bytecode import FunctionIdentity
11
13
  from numba.core.caching import CacheImpl, _CacheLocator
12
14
 
13
15
  from pytensor.configdefaults import config
@@ -18,6 +20,35 @@ NUMBA_CACHE_PATH.mkdir(parents=True, exist_ok=True)
18
20
  CACHED_SRC_FUNCTIONS: WeakKeyDictionary[Callable, str] = WeakKeyDictionary()
19
21
 
20
22
 
23
+ class _RandomUidIter:
24
+ """Iterator yielding cryptographically random 128-bit integers.
25
+
26
+ Replaces numba's default ``FunctionIdentity._unique_ids`` sequential
27
+ counter so that sibling forks — which inherit the counter state verbatim —
28
+ cannot allocate identical uids to same-qualname functions they
29
+ fresh-compile next. Identical uids produce byte-identical LLVM mangled
30
+ symbols with different bodies; a later process that loads both hits LLVM's
31
+ weak-merge and dispatches into the wrong body, segfaulting.
32
+
33
+ Numba only consumes ``_unique_ids`` via ``next(cls._unique_ids)`` (see
34
+ ``numba.core.bytecode.FunctionIdentity.from_function``), so any iterator
35
+ of unique ints is a drop-in replacement. ``uuid.uuid4`` pulls fresh
36
+ entropy from the OS on every call, making this generator fork-safe
37
+ without any re-seed hook.
38
+
39
+ See https://github.com/numba/numba/issues/10486.
40
+ """
41
+
42
+ def __iter__(self) -> "_RandomUidIter":
43
+ return self
44
+
45
+ def __next__(self) -> int:
46
+ return uuid.uuid4().int
47
+
48
+
49
+ FunctionIdentity._unique_ids = _RandomUidIter()
50
+
51
+
21
52
  class NumbaPyTensorCacheLocator(_CacheLocator):
22
53
  """Locator for Numba functions defined from PyTensor-generated source code.
23
54
 
@@ -13,7 +13,10 @@ from pytensor import config
13
13
  from pytensor.graph.basic import Apply, Constant, Variable
14
14
  from pytensor.graph.fg import FunctionGraph
15
15
  from pytensor.graph.type import Type
16
- from pytensor.link.numba.cache import compile_numba_function_src, hash_from_pickle_dump
16
+ from pytensor.link.numba.cache import (
17
+ compile_numba_function_src,
18
+ hash_from_pickle_dump,
19
+ )
17
20
  from pytensor.link.utils import (
18
21
  fgraph_to_python,
19
22
  )
@@ -33,7 +36,7 @@ def _filter_numba_warnings():
33
36
  "ignore",
34
37
  message=(
35
38
  "(\x1b\\[1m)*" # ansi escape code for bold text
36
- 'Cannot cache compiled function "numba_funcified_fgraph" as it uses dynamic globals'
39
+ 'Cannot cache compiled function "numba_funcified_fgraph.*" as it uses dynamic globals'
37
40
  ),
38
41
  category=NumbaWarning,
39
42
  )
@@ -1802,6 +1802,40 @@ def _get_vector_length_Alloc(var_inst, var):
1802
1802
  raise ValueError(f"Length of {var} cannot be determined")
1803
1803
 
1804
1804
 
1805
+ @_vectorize_node.register(Alloc)
1806
+ def vectorize_alloc(op, node, val, *shape):
1807
+ old_val, *old_shape = node.inputs
1808
+ [old_alloc] = node.outputs
1809
+
1810
+ assert len(shape) == len(old_shape), (
1811
+ "Number of shape entries can't change in vectorize_alloc"
1812
+ )
1813
+
1814
+ if not all(all(s.broadcastable) for s in shape):
1815
+ # May imply a non-square Alloc
1816
+ return vectorize_node_fallback(op, node, val, *shape)
1817
+
1818
+ val_batch_ndim = val.ndim - old_val.ndim
1819
+ shape_batch_ndim = max((s.ndim for s in shape), default=0)
1820
+
1821
+ # Add implicit core dims that alloc prepends (alloc aligns val to the right)
1822
+ n_implicit_core_dims = len(old_shape) - old_val.ndim
1823
+ if n_implicit_core_dims > 0:
1824
+ val = expand_dims(
1825
+ val, list(range(val_batch_ndim, val_batch_ndim + n_implicit_core_dims))
1826
+ )
1827
+
1828
+ new_alloc = alloc(
1829
+ val,
1830
+ *val.shape[:val_batch_ndim],
1831
+ *(s.squeeze() for s in shape),
1832
+ )
1833
+ # Expand leading batch dims implied by the shape entries (if any)
1834
+ new_alloc = atleast_Nd(new_alloc, n=shape_batch_ndim + old_alloc.ndim)
1835
+
1836
+ return [new_alloc]
1837
+
1838
+
1805
1839
  def full(shape, fill_value, dtype=None):
1806
1840
  """Return a new array of given shape and type, filled with `fill_value`.
1807
1841
 
@@ -35,7 +35,6 @@ from pytensor.tensor.math import tensordot
35
35
  from pytensor.tensor.reshape import pack, unpack
36
36
  from pytensor.tensor.slinalg import solve
37
37
  from pytensor.tensor.variable import TensorVariable, Variable
38
- from pytensor.utils import unzip
39
38
 
40
39
 
41
40
  # scipy.optimize can be slow to import, and will not be used by most users
@@ -214,22 +213,6 @@ class ScipyWrapperOp(Op, HasInnerGraph):
214
213
 
215
214
  return Apply(self, inputs, [self.inner_inputs[0].type(), ps.bool("success")])
216
215
 
217
- def connection_pattern(self, node=None):
218
- """
219
- All Ops that inherit from ScipyWrapperOp share the same connection pattern logic, because they all share the
220
- same output structure. There are two outputs: the optimized variable, and a success flag. The success flag is
221
- not differentiable, so it is never connected. The optimized variable is connected only to inputs that are
222
- both connected to the objective function and of float dtype.
223
- """
224
- fgraph = self.fgraph
225
- fx = fgraph.outputs[0]
226
- return [
227
- # Every input is disonnected to the second output (success)
228
- # And may or not be connected to the first output (opt_x)
229
- [connected, False]
230
- for [connected] in io_connection_pattern(fgraph.inputs, [fx])
231
- ]
232
-
233
216
 
234
217
  class ScipyScalarWrapperOp(ScipyWrapperOp):
235
218
  def build_fn(self):
@@ -277,6 +260,7 @@ class ScipyScalarWrapperOp(ScipyWrapperOp):
277
260
  inner_fx = self.inner_outputs[0]
278
261
 
279
262
  if is_minimization:
263
+ # The implicit function in minimization is grad(x, theta) == 0
280
264
  inner_fx = grad(inner_fx, inner_x)
281
265
 
282
266
  df_dx, *arg_grads = grad(
@@ -287,32 +271,35 @@ class ScipyScalarWrapperOp(ScipyWrapperOp):
287
271
  return_disconnected="disconnected",
288
272
  )
289
273
 
290
- outer_arg_grad_map = dict(zip(args, arg_grads))
291
- valid_args_and_grads = [
292
- (arg, g)
293
- for arg, g in outer_arg_grad_map.items()
294
- if not isinstance(g.type, DisconnectedType | NullType)
295
- ]
274
+ args_to_diff: tuple[bool, ...] = tuple(
275
+ not isinstance(g.type, DisconnectedType | NullType) for g in arg_grads
276
+ )
296
277
 
297
- if len(valid_args_and_grads) == 0:
278
+ if not any(args_to_diff):
298
279
  # No differentiable arguments, return disconnected gradients
299
280
  return arg_grads
300
281
 
301
- outer_args_to_diff, df_dthetas = unzip(valid_args_and_grads, n=2)
282
+ df_dthetas = [g for g, to_diff in zip(arg_grads, args_to_diff) if to_diff]
302
283
 
303
- replace = dict(zip(fgraph.inputs, (x_star, *args), strict=True))
284
+ # Make gradient an expression of the outer variables
304
285
  df_dx_star, *df_dthetas_stars = graph_replace(
305
- [df_dx, *df_dthetas], replace=replace
286
+ [df_dx, *df_dthetas], replace=tuple(zip(fgraph.inputs, (x_star, *args)))
306
287
  )
307
288
 
308
- arg_to_grad = dict(zip(outer_args_to_diff, df_dthetas_stars))
289
+ grad_wrt_args = []
290
+ df_dthetas_iter = iter(df_dthetas_stars)
291
+ for i, (arg, to_diff) in enumerate(zip(args, args_to_diff)):
292
+ if not to_diff:
293
+ # Store the null grad we got from the initial `grad` call
294
+ g = arg_grads[i]
295
+ assert isinstance(g.type, NullType | DisconnectedType)
296
+ else:
297
+ # Compute non-null grad and chain with output_grad
298
+ df_dtheta_star = next(df_dthetas_iter)
299
+ g = (-df_dtheta_star / df_dx_star) * output_grad
300
+ grad_wrt_args.append(g)
309
301
 
310
- grad_wrt_args = [
311
- (-arg_to_grad[arg] / df_dx_star) * output_grad
312
- if arg in arg_to_grad
313
- else outer_arg_grad_map[arg]
314
- for arg in args
315
- ]
302
+ assert next(df_dthetas_iter, None) is None, "Iterator was not exhausted"
316
303
 
317
304
  return grad_wrt_args
318
305
 
@@ -358,7 +345,7 @@ class ScipyVectorWrapperOp(ScipyWrapperOp):
358
345
 
359
346
  Notes
360
347
  -----
361
- The gradents are computed using the implicit function theorem. Given a fuction `f(x, theta) = 0`, and a function
348
+ The gradients are computed using the implicit function theorem. Given a function `f(x, theta) = 0`, and a function
362
349
  `x_star(theta)` that, given input parameters theta returns `x` such that `f(x_star(theta), theta) = 0`, we can
363
350
  compute the gradients of `x_star` with respect to `theta` as follows:
364
351
 
@@ -384,8 +371,12 @@ class ScipyVectorWrapperOp(ScipyWrapperOp):
384
371
  fgraph = self.fgraph
385
372
  inner_x, *inner_args = self.inner_inputs
386
373
  implicit_f = self.inner_outputs[0]
374
+ if is_minimization:
375
+ # The implicit function in minimization is grad(x, theta) == 0
376
+ implicit_f = grad(implicit_f, inner_x)
387
377
 
388
- df_dx, *arg_grads = grad(
378
+ # Call grad to see what arguments are connected
379
+ _, *arg_grads = grad(
389
380
  implicit_f.sum(),
390
381
  [inner_x, *inner_args],
391
382
  disconnected_inputs="ignore",
@@ -393,32 +384,22 @@ class ScipyVectorWrapperOp(ScipyWrapperOp):
393
384
  return_disconnected="disconnected",
394
385
  )
395
386
 
396
- inner_args_to_diff = [
397
- arg
398
- for arg, g in zip(inner_args, arg_grads)
399
- if not isinstance(g.type, DisconnectedType | NullType)
400
- ]
387
+ args_to_diff: tuple[bool, ...] = tuple(
388
+ not isinstance(g.type, DisconnectedType | NullType) for g in arg_grads
389
+ )
401
390
 
402
- if len(inner_args_to_diff) == 0:
391
+ if not args_to_diff:
403
392
  # No differentiable arguments, return disconnected/null gradients
404
393
  return arg_grads
405
394
 
406
- outer_args_to_diff = [
407
- arg
408
- for inner_arg, arg in zip(inner_args, args)
409
- if inner_arg in inner_args_to_diff
410
- ]
411
- invalid_grad_map = {
412
- arg: g for arg, g in zip(args, arg_grads) if arg not in outer_args_to_diff
413
- }
414
-
415
- if is_minimization:
416
- implicit_f = grad(implicit_f, inner_x)
417
-
418
395
  # Gradients are computed using the inner graph of the optimization op, not the actual inputs/outputs of the op.
419
396
  packed_inner_args, packed_arg_shapes, implicit_f = pack_inputs_of_objective(
420
397
  implicit_f,
421
- inner_args_to_diff,
398
+ [
399
+ inner_arg
400
+ for inner_arg, to_diff in zip(inner_args, args_to_diff)
401
+ if to_diff
402
+ ],
422
403
  )
423
404
 
424
405
  df_dx, df_dtheta = jacobian(
@@ -430,11 +411,11 @@ class ScipyVectorWrapperOp(ScipyWrapperOp):
430
411
 
431
412
  # Replace inner inputs (abstract dummies) with outer inputs (the actual user-provided symbols)
432
413
  # at the solution point. Innner arguments aren't needed anymore, delete them to avoid accidental references.
433
- del inner_x
434
- del inner_args
435
- inner_to_outer_map = dict(zip(fgraph.inputs, (x_star, *args)))
414
+ del inner_x, inner_args
415
+ inner_to_outer_map = tuple(zip(fgraph.inputs, (x_star, *args)))
436
416
  df_dx_star, df_dtheta_star = graph_replace(
437
- [df_dx, df_dtheta], inner_to_outer_map
417
+ [df_dx, df_dtheta],
418
+ replace=inner_to_outer_map,
438
419
  )
439
420
 
440
421
  if df_dtheta_star.ndim == 0 or df_dx_star.ndim == 0:
@@ -454,27 +435,49 @@ class ScipyVectorWrapperOp(ScipyWrapperOp):
454
435
  else:
455
436
  grad_wrt_args = [grad_wrt_args_packed]
456
437
 
457
- arg_to_grad = dict(zip(outer_args_to_diff, grad_wrt_args))
458
-
459
438
  final_grads = []
460
- for arg in args:
461
- arg_grad = arg_to_grad.get(arg, None)
462
-
463
- if arg_grad is None:
464
- final_grads.append(invalid_grad_map[arg])
465
- continue
466
-
467
- if arg_grad.ndim > 0 and output_grad.ndim > 0:
468
- g = tensordot(output_grad, arg_grad, [[0], [0]])
439
+ grad_wrt_args_iter = iter(grad_wrt_args)
440
+ for i, (arg, to_diff) in enumerate(zip(args, args_to_diff)):
441
+ if not to_diff:
442
+ # Store the null grad we got from the initial `grad` call
443
+ g = arg_grads[i]
444
+ assert isinstance(g.type, NullType | DisconnectedType)
469
445
  else:
470
- g = arg_grad * output_grad
471
- if isinstance(arg.type, ScalarType) and isinstance(g, TensorVariable):
472
- g = scalar_from_tensor(g)
446
+ # Compute non-null grad and chain with output_grad
447
+ arg_grad = next(grad_wrt_args_iter)
448
+ if arg_grad.ndim > 0 and output_grad.ndim > 0:
449
+ g = tensordot(output_grad, arg_grad, [[0], [0]])
450
+ else:
451
+ g = arg_grad * output_grad
452
+ if isinstance(arg.type, ScalarType) and isinstance(g, TensorVariable):
453
+ g = scalar_from_tensor(g)
473
454
  final_grads.append(g)
474
455
 
456
+ assert next(grad_wrt_args_iter, None) is None, "Iterator was not exhausted"
457
+
475
458
  return final_grads
476
459
 
477
460
 
461
+ def _optimizer_connection_pattern(fgraph, is_minimization):
462
+ """Compute connection pattern for scipy optimization Ops.
463
+
464
+ There are two outputs: the optimized variable, and a success flag. The success flag is
465
+ not differentiable, so it is never connected. The optimized variable is connected only
466
+ to inputs that are connected to the implicit function used in the gradient computation.
467
+
468
+ For minimization, the implicit function is grad(objective, x), not the objective itself.
469
+ An input may be connected to the objective but disconnected from its gradient (e.g. an
470
+ additive constant), so the connection pattern must reflect the actual implicit function.
471
+ """
472
+ inner_x = fgraph.inputs[0]
473
+ fx = fgraph.outputs[0]
474
+ if is_minimization:
475
+ fx = grad(fx, inner_x)
476
+ return [
477
+ [connected, False] for [connected] in io_connection_pattern(fgraph.inputs, [fx])
478
+ ]
479
+
480
+
478
481
  class MinimizeScalarOp(ScipyScalarWrapperOp):
479
482
  def __init__(
480
483
  self,
@@ -503,6 +506,9 @@ class MinimizeScalarOp(ScipyScalarWrapperOp):
503
506
  self._fn = None
504
507
  self._fn_wrapped = None
505
508
 
509
+ def connection_pattern(self, node=None):
510
+ return _optimizer_connection_pattern(self.fgraph, is_minimization=True)
511
+
506
512
  def __str__(self):
507
513
  return f"{self.__class__.__name__}(method={self.method})"
508
514
 
@@ -639,6 +645,9 @@ class MinimizeOp(ScipyVectorWrapperOp):
639
645
  self._fn = None
640
646
  self._fn_wrapped = None
641
647
 
648
+ def connection_pattern(self, node=None):
649
+ return _optimizer_connection_pattern(self.fgraph, is_minimization=True)
650
+
642
651
  def __str__(self):
643
652
  str_args = ", ".join(
644
653
  [
@@ -834,6 +843,9 @@ class RootScalarOp(ScipyScalarWrapperOp):
834
843
  self._fn = None
835
844
  self._fn_wrapped = None
836
845
 
846
+ def connection_pattern(self, node=None):
847
+ return _optimizer_connection_pattern(self.fgraph, is_minimization=False)
848
+
837
849
  def __str__(self):
838
850
  str_args = ", ".join(
839
851
  [f"{arg}={getattr(self, arg)}" for arg in ["method", "jac", "hess"]]
@@ -980,6 +992,9 @@ class RootOp(ScipyVectorWrapperOp):
980
992
  self._fn = None
981
993
  self._fn_wrapped = None
982
994
 
995
+ def connection_pattern(self, node=None):
996
+ return _optimizer_connection_pattern(self.fgraph, is_minimization=False)
997
+
983
998
  def __str__(self):
984
999
  str_args = ", ".join(
985
1000
  [f"{arg}={getattr(self, arg)}" for arg in ["method", "jac"]]
@@ -5,7 +5,14 @@ from pytensor.graph.replace import vectorize_graph
5
5
  from pytensor.graph.rewriting.basic import copy_stack_trace, dfs_rewriter
6
6
  from pytensor.graph.rewriting.unify import OpPattern, OpPatternOpTypeType
7
7
  from pytensor.graph.traversal import apply_ancestors
8
- from pytensor.tensor.basic import Alloc, ARange, alloc, shape_padleft
8
+ from pytensor.tensor.basic import (
9
+ Alloc,
10
+ AllocEmpty,
11
+ ARange,
12
+ alloc,
13
+ expand_dims,
14
+ shape_padleft,
15
+ )
9
16
  from pytensor.tensor.blockwise import Blockwise, _squeeze_left
10
17
  from pytensor.tensor.math import Dot
11
18
  from pytensor.tensor.rewriting.basic import (
@@ -89,6 +96,7 @@ optdb.register(
89
96
  blockwise_of(
90
97
  Dot
91
98
  | Alloc
99
+ | AllocEmpty
92
100
  | ARange
93
101
  | Subtensor
94
102
  | AdvancedSubtensor
@@ -106,7 +114,7 @@ def local_eager_useless_unbatched_blockwise(fgraph, node):
106
114
 
107
115
  @register_specialize("shape_unsafe")
108
116
  @node_rewriter([Blockwise])
109
- def local_blockwise_alloc(fgraph, node):
117
+ def local_blockwise_alloc_inputs(fgraph, node):
110
118
  """Push Allocs from the inputs to the output of Blockwise Ops.
111
119
 
112
120
  BOp = Blockwise(Op, signature="(x),(x)->(x)")
@@ -218,6 +226,34 @@ def local_blockwise_alloc(fgraph, node):
218
226
  return new_outs
219
227
 
220
228
 
229
+ @register_canonicalize
230
+ @register_specialize
231
+ @node_rewriter([blockwise_of(Alloc)])
232
+ def local_blockwise_alloc(fgraph, node):
233
+ val, *shape = node.inputs
234
+
235
+ if not all(all(s.broadcastable) for s in shape):
236
+ # May imply a non-square Alloc
237
+ return None
238
+
239
+ batch_ndim = node.op.batch_ndim(node)
240
+
241
+ # Add implicit core dims that alloc prepends (alloc aligns val to the right)
242
+ n_implicit_core_dims = node.outputs[0].ndim - val.ndim
243
+ if n_implicit_core_dims > 0:
244
+ val = expand_dims(
245
+ val, list(range(batch_ndim, batch_ndim + n_implicit_core_dims))
246
+ )
247
+
248
+ new_alloc = alloc(
249
+ val,
250
+ *val.shape[:batch_ndim],
251
+ *(s.squeeze() for s in shape),
252
+ )
253
+ copy_stack_trace(node.outputs[0], new_alloc)
254
+ return [new_alloc]
255
+
256
+
221
257
  @register_specialize
222
258
  @node_rewriter([blockwise_of(Reshape)])
223
259
  def local_blockwise_reshape(fgraph, node):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytensor
3
- Version: 2.38.2
3
+ Version: 2.38.3
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
@@ -31,7 +31,7 @@ License-File: LICENSE.txt
31
31
  Requires-Dist: setuptools>=59.0.0
32
32
  Requires-Dist: scipy<2,>=1
33
33
  Requires-Dist: numpy>=2.0
34
- Requires-Dist: numba<1,>0.57
34
+ Requires-Dist: numba<=0.65.1,>=0.58
35
35
  Requires-Dist: filelock>=3.15
36
36
  Requires-Dist: etuples
37
37
  Requires-Dist: logical-unification
@@ -60,7 +60,7 @@ Provides-Extra: jax
60
60
  Requires-Dist: jax; extra == "jax"
61
61
  Requires-Dist: jaxlib; extra == "jax"
62
62
  Provides-Extra: numba
63
- Requires-Dist: numba>=0.57; extra == "numba"
63
+ Requires-Dist: numba<=0.65.1,>=0.58; extra == "numba"
64
64
  Requires-Dist: llvmlite; extra == "numba"
65
65
  Dynamic: license-file
66
66
 
@@ -1,7 +1,7 @@
1
1
  setuptools>=59.0.0
2
2
  scipy<2,>=1
3
3
  numpy>=2.0
4
- numba<1,>0.57
4
+ numba<=0.65.1,>=0.58
5
5
  filelock>=3.15
6
6
  etuples
7
7
  logical-unification
@@ -22,7 +22,7 @@ jax
22
22
  jaxlib
23
23
 
24
24
  [numba]
25
- numba>=0.57
25
+ numba<=0.65.1,>=0.58
26
26
  llvmlite
27
27
 
28
28
  [rtd]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes