pytensor 2.27.0__tar.gz → 2.27.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 (428) hide show
  1. {pytensor-2.27.0/pytensor.egg-info → pytensor-2.27.1}/PKG-INFO +1 -1
  2. {pytensor-2.27.0 → pytensor-2.27.1}/doc/core_development_guide.rst +1 -1
  3. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/creating_a_c_op.rst +2 -2
  4. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/creating_an_op.rst +1 -1
  5. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/inplace.rst +1 -1
  6. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/other_ops.rst +1 -1
  7. {pytensor-2.27.0 → pytensor-2.27.1}/doc/install.rst +1 -1
  8. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/compile/mode.rst +9 -0
  9. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/random/index.rst +1 -1
  10. {pytensor-2.27.0 → pytensor-2.27.1}/doc/troubleshooting.rst +65 -26
  11. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/examples.rst +1 -9
  12. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/prng.rst +44 -62
  13. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/_version.py +3 -3
  14. pytensor-2.27.1/pytensor/graph/rewriting/__init__.py +4 -0
  15. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/rewriting/db.py +19 -12
  16. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/c/cmodule.py +31 -5
  17. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/basic.py +0 -18
  18. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/elemwise.py +4 -48
  19. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/blas_headers.py +5 -4
  20. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/einsum.py +20 -5
  21. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/math.py +34 -8
  22. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/math.py +92 -5
  23. {pytensor-2.27.0 → pytensor-2.27.1/pytensor.egg-info}/PKG-INFO +1 -1
  24. pytensor-2.27.0/pytensor/sparse/sandbox/__init__.py +0 -0
  25. {pytensor-2.27.0 → pytensor-2.27.1}/LICENSE.txt +0 -0
  26. {pytensor-2.27.0 → pytensor-2.27.1}/MANIFEST.in +0 -0
  27. {pytensor-2.27.0 → pytensor-2.27.1}/README.rst +0 -0
  28. {pytensor-2.27.0 → pytensor-2.27.1}/doc/.templates/PLACEHOLDER +0 -0
  29. {pytensor-2.27.0 → pytensor-2.27.1}/doc/.templates/layout.html +0 -0
  30. {pytensor-2.27.0 → pytensor-2.27.1}/doc/.templates/nb-badges.html +0 -0
  31. {pytensor-2.27.0 → pytensor-2.27.1}/doc/.templates/rendered_citation.html +0 -0
  32. {pytensor-2.27.0 → pytensor-2.27.1}/doc/LICENSE.txt +0 -0
  33. {pytensor-2.27.0 → pytensor-2.27.1}/doc/README.md +0 -0
  34. {pytensor-2.27.0 → pytensor-2.27.1}/doc/acknowledgement.rst +0 -0
  35. {pytensor-2.27.0 → pytensor-2.27.1}/doc/bcast.png +0 -0
  36. {pytensor-2.27.0 → pytensor-2.27.1}/doc/bcast.svg +0 -0
  37. {pytensor-2.27.0 → pytensor-2.27.1}/doc/blog.md +0 -0
  38. {pytensor-2.27.0 → pytensor-2.27.1}/doc/conf.py +0 -0
  39. {pytensor-2.27.0 → pytensor-2.27.1}/doc/css.inc +0 -0
  40. {pytensor-2.27.0 → pytensor-2.27.1}/doc/dev_start_guide.rst +0 -0
  41. {pytensor-2.27.0 → pytensor-2.27.1}/doc/environment.yml +0 -0
  42. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/apply.png +0 -0
  43. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/apply.svg +0 -0
  44. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/apply2.svg +0 -0
  45. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/creating_a_numba_jax_op.rst +0 -0
  46. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/ctype.rst +0 -0
  47. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/extending_faq.rst +0 -0
  48. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/extending_pytensor_solution_1.py +0 -0
  49. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/graph_rewriting.rst +0 -0
  50. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/graphstructures.rst +0 -0
  51. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/index.rst +0 -0
  52. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/op.rst +0 -0
  53. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/pics/symbolic_graph_opt.png +0 -0
  54. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
  55. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/pipeline.rst +0 -0
  56. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/scan.rst +0 -0
  57. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/tips.rst +0 -0
  58. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/type.rst +0 -0
  59. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/unittest.rst +0 -0
  60. {pytensor-2.27.0 → pytensor-2.27.1}/doc/extending/using_params.rst +0 -0
  61. {pytensor-2.27.0 → pytensor-2.27.1}/doc/faq.rst +0 -0
  62. {pytensor-2.27.0 → pytensor-2.27.1}/doc/gallery/page_footer.md +0 -0
  63. {pytensor-2.27.0 → pytensor-2.27.1}/doc/gallery/rewrites/graph_rewrites.ipynb +0 -0
  64. {pytensor-2.27.0 → pytensor-2.27.1}/doc/gallery/scan/scan_tutorial.ipynb +0 -0
  65. {pytensor-2.27.0 → pytensor-2.27.1}/doc/generate_dtype_tensor_table.py +0 -0
  66. {pytensor-2.27.0 → pytensor-2.27.1}/doc/glossary.rst +0 -0
  67. {pytensor-2.27.0 → pytensor-2.27.1}/doc/images/Elman_srnn.png +0 -0
  68. {pytensor-2.27.0 → pytensor-2.27.1}/doc/images/PyTensor.png +0 -0
  69. {pytensor-2.27.0 → pytensor-2.27.1}/doc/images/PyTensor_RGB.svg +0 -0
  70. {pytensor-2.27.0 → pytensor-2.27.1}/doc/images/PyTensor_logo.png +0 -0
  71. {pytensor-2.27.0 → pytensor-2.27.1}/doc/images/binder.svg +0 -0
  72. {pytensor-2.27.0 → pytensor-2.27.1}/doc/images/blocksparse.png +0 -0
  73. {pytensor-2.27.0 → pytensor-2.27.1}/doc/images/colab.svg +0 -0
  74. {pytensor-2.27.0 → pytensor-2.27.1}/doc/images/github.svg +0 -0
  75. {pytensor-2.27.0 → pytensor-2.27.1}/doc/images/lstm.png +0 -0
  76. {pytensor-2.27.0 → pytensor-2.27.1}/doc/images/lstm_memorycell.png +0 -0
  77. {pytensor-2.27.0 → pytensor-2.27.1}/doc/images/talk2010.gif +0 -0
  78. {pytensor-2.27.0 → pytensor-2.27.1}/doc/images/talk2010.png +0 -0
  79. {pytensor-2.27.0 → pytensor-2.27.1}/doc/index.rst +0 -0
  80. {pytensor-2.27.0 → pytensor-2.27.1}/doc/internal/how_to_release.rst +0 -0
  81. {pytensor-2.27.0 → pytensor-2.27.1}/doc/internal/index.rst +0 -0
  82. {pytensor-2.27.0 → pytensor-2.27.1}/doc/internal/metadocumentation.rst +0 -0
  83. {pytensor-2.27.0 → pytensor-2.27.1}/doc/introduction.rst +0 -0
  84. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/compile/debugmode.rst +0 -0
  85. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/compile/function.rst +0 -0
  86. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/compile/index.rst +0 -0
  87. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/compile/io.rst +0 -0
  88. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/compile/nanguardmode.rst +0 -0
  89. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/compile/opfromgraph.rst +0 -0
  90. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/compile/ops.rst +0 -0
  91. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/compile/profilemode.rst +0 -0
  92. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/compile/shared.rst +0 -0
  93. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/config.rst +0 -0
  94. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
  95. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
  96. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
  97. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
  98. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
  99. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
  100. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
  101. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/mlp.html +0 -0
  102. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/mlp.png +0 -0
  103. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/mlp2.html +0 -0
  104. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/mlp2.pdf +0 -0
  105. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/mlp2.png +0 -0
  106. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/ofg.html +0 -0
  107. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/examples/ofg2.html +0 -0
  108. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/index.ipynb +0 -0
  109. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/index.rst +0 -0
  110. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/index_files/index_10_0.png +0 -0
  111. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/index_files/index_11_0.png +0 -0
  112. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/index_files/index_24_0.png +0 -0
  113. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/d3viz/index_files/index_25_0.png +0 -0
  114. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/gradient.rst +0 -0
  115. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/graph/features.rst +0 -0
  116. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/graph/fgraph.rst +0 -0
  117. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/graph/graph.rst +0 -0
  118. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/graph/index.rst +0 -0
  119. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/graph/op.rst +0 -0
  120. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/graph/replace.rst +0 -0
  121. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/graph/type.rst +0 -0
  122. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/graph/utils.rst +0 -0
  123. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/index.rst +0 -0
  124. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/misc/pkl_utils.rst +0 -0
  125. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/printing.rst +0 -0
  126. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/scalar/index.rst +0 -0
  127. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/scan.rst +0 -0
  128. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/sparse/index.rst +0 -0
  129. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/sparse/sandbox.rst +0 -0
  130. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/basic.rst +0 -0
  131. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/basic_opt.rst +0 -0
  132. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/bcast.png +0 -0
  133. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/bcast.svg +0 -0
  134. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/conv.rst +0 -0
  135. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/elemwise.rst +0 -0
  136. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/extra_ops.rst +0 -0
  137. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/fft.rst +0 -0
  138. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/functional.rst +0 -0
  139. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/index.rst +0 -0
  140. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/io.rst +0 -0
  141. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/math_opt.rst +0 -0
  142. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/nlinalg.rst +0 -0
  143. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/plot_fft.png +0 -0
  144. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/random/distributions.rst +0 -0
  145. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/slinalg.rst +0 -0
  146. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/tensor/utils.rst +0 -0
  147. {pytensor-2.27.0 → pytensor-2.27.1}/doc/library/typed_list.rst +0 -0
  148. {pytensor-2.27.0 → pytensor-2.27.1}/doc/links.rst +0 -0
  149. {pytensor-2.27.0 → pytensor-2.27.1}/doc/optimizations.rst +0 -0
  150. {pytensor-2.27.0 → pytensor-2.27.1}/doc/pylintrc +0 -0
  151. {pytensor-2.27.0 → pytensor-2.27.1}/doc/robots.txt +0 -0
  152. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/adding.rst +0 -0
  153. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/adding_solution_1.py +0 -0
  154. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/aliasing.rst +0 -0
  155. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/apply.png +0 -0
  156. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/apply.svg +0 -0
  157. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/bcast.png +0 -0
  158. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/broadcasting.rst +0 -0
  159. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/conditions.rst +0 -0
  160. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/debug_faq.rst +0 -0
  161. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/dlogistic.png +0 -0
  162. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/faq_tutorial.rst +0 -0
  163. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/gradients.rst +0 -0
  164. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/index.rst +0 -0
  165. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/loading_and_saving.rst +0 -0
  166. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/logistic.gp +0 -0
  167. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/logistic.png +0 -0
  168. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/loop.rst +0 -0
  169. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/loop_solution_1.py +0 -0
  170. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/modes.rst +0 -0
  171. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/modes_solution_1.py +0 -0
  172. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/multi_cores.rst +0 -0
  173. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/nan_tutorial.rst +0 -0
  174. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/pics/d3viz.png +0 -0
  175. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
  176. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
  177. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
  178. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/printing_drawing.rst +0 -0
  179. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/profiling.rst +0 -0
  180. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/profiling_example.py +0 -0
  181. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/profiling_example_out.prof +0 -0
  182. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/shape_info.rst +0 -0
  183. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/sparse.rst +0 -0
  184. {pytensor-2.27.0 → pytensor-2.27.1}/doc/tutorial/symbolic_graphs.rst +0 -0
  185. {pytensor-2.27.0 → pytensor-2.27.1}/doc/user_guide.rst +0 -0
  186. {pytensor-2.27.0 → pytensor-2.27.1}/pyproject.toml +0 -0
  187. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/__init__.py +0 -0
  188. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/bin/__init__.py +0 -0
  189. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/bin/pytensor_cache.py +0 -0
  190. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/breakpoint.py +0 -0
  191. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/__init__.py +0 -0
  192. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/builders.py +0 -0
  193. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/compiledir.py +0 -0
  194. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/compilelock.py +0 -0
  195. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/debugmode.py +0 -0
  196. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/function/__init__.py +0 -0
  197. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/function/pfunc.py +0 -0
  198. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/function/types.py +0 -0
  199. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/io.py +0 -0
  200. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/mode.py +0 -0
  201. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/monitormode.py +0 -0
  202. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/nanguardmode.py +0 -0
  203. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/ops.py +0 -0
  204. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/profiling.py +0 -0
  205. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/compile/sharedvalue.py +0 -0
  206. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/configdefaults.py +0 -0
  207. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/configparser.py +0 -0
  208. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/d3viz/__init__.py +0 -0
  209. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/d3viz/css/d3-context-menu.css +0 -0
  210. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/d3viz/css/d3viz.css +0 -0
  211. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/d3viz/d3viz.py +0 -0
  212. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/d3viz/formatting.py +0 -0
  213. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/d3viz/js/d3-context-menu.js +0 -0
  214. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/d3viz/js/d3.v3.min.js +0 -0
  215. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/d3viz/js/d3viz.js +0 -0
  216. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
  217. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
  218. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/gradient.py +0 -0
  219. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/__init__.py +0 -0
  220. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/basic.py +0 -0
  221. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/destroyhandler.py +0 -0
  222. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/features.py +0 -0
  223. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/fg.py +0 -0
  224. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/null_type.py +0 -0
  225. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/op.py +0 -0
  226. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/replace.py +0 -0
  227. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/rewriting/basic.py +0 -0
  228. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/rewriting/kanren.py +0 -0
  229. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/rewriting/unify.py +0 -0
  230. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/rewriting/utils.py +0 -0
  231. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/type.py +0 -0
  232. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/graph/utils.py +0 -0
  233. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/ifelse.py +0 -0
  234. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/__init__.py +0 -0
  235. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/basic.py +0 -0
  236. {pytensor-2.27.0/pytensor/graph/rewriting → pytensor-2.27.1/pytensor/link/c}/__init__.py +0 -0
  237. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/c/basic.py +0 -0
  238. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
  239. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
  240. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/c/cutils.py +0 -0
  241. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/c/cvm.py +0 -0
  242. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/c/exceptions.py +0 -0
  243. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/c/interface.py +0 -0
  244. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/c/lazylinker_c.py +0 -0
  245. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/c/op.py +0 -0
  246. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/c/params_type.py +0 -0
  247. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/c/type.py +0 -0
  248. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/__init__.py +0 -0
  249. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/__init__.py +0 -0
  250. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/basic.py +0 -0
  251. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/blas.py +0 -0
  252. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/blockwise.py +0 -0
  253. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/einsum.py +0 -0
  254. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/elemwise.py +0 -0
  255. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
  256. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/math.py +0 -0
  257. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/nlinalg.py +0 -0
  258. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/pad.py +0 -0
  259. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/random.py +0 -0
  260. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/scalar.py +0 -0
  261. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/scan.py +0 -0
  262. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/shape.py +0 -0
  263. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/slinalg.py +0 -0
  264. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/sort.py +0 -0
  265. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/sparse.py +0 -0
  266. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/subtensor.py +0 -0
  267. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
  268. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/jax/linker.py +0 -0
  269. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/__init__.py +0 -0
  270. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/__init__.py +0 -0
  271. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/blockwise.py +0 -0
  272. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/cython_support.py +0 -0
  273. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
  274. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
  275. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/random.py +0 -0
  276. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/scalar.py +0 -0
  277. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/scan.py +0 -0
  278. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/slinalg.py +0 -0
  279. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/sparse.py +0 -0
  280. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/subtensor.py +0 -0
  281. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
  282. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/dispatch/vectorize_codegen.py +0 -0
  283. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/numba/linker.py +0 -0
  284. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/dispatch/__init__.py +0 -0
  285. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/dispatch/basic.py +0 -0
  286. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/dispatch/blas.py +0 -0
  287. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/dispatch/blockwise.py +0 -0
  288. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/dispatch/elemwise.py +0 -0
  289. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/dispatch/extra_ops.py +0 -0
  290. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/dispatch/math.py +0 -0
  291. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/dispatch/nlinalg.py +0 -0
  292. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/dispatch/scalar.py +0 -0
  293. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/dispatch/shape.py +0 -0
  294. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/dispatch/sort.py +0 -0
  295. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/dispatch/subtensor.py +0 -0
  296. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/pytorch/linker.py +0 -0
  297. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/utils.py +0 -0
  298. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/link/vm.py +0 -0
  299. {pytensor-2.27.0/pytensor/link/c → pytensor-2.27.1/pytensor/misc}/__init__.py +0 -0
  300. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/misc/check_blas.py +0 -0
  301. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/misc/check_blas_many.sh +0 -0
  302. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/misc/check_duplicate_key.py +0 -0
  303. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
  304. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/misc/elemwise_time_test.py +0 -0
  305. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/misc/frozendict.py +0 -0
  306. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/misc/may_share_memory.py +0 -0
  307. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/misc/ordered_set.py +0 -0
  308. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/misc/pkl_utils.py +0 -0
  309. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/printing.py +0 -0
  310. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/py.typed +0 -0
  311. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/raise_op.py +0 -0
  312. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scalar/__init__.py +0 -0
  313. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scalar/basic.py +0 -0
  314. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
  315. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
  316. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scalar/c_code/gamma.c +0 -0
  317. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scalar/c_code/incbet.c +0 -0
  318. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scalar/loop.py +0 -0
  319. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scalar/math.py +0 -0
  320. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scalar/sharedvar.py +0 -0
  321. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scan/__init__.py +0 -0
  322. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scan/basic.py +0 -0
  323. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scan/checkpoints.py +0 -0
  324. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scan/op.py +0 -0
  325. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scan/rewriting.py +0 -0
  326. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scan/scan_perform.pyx +0 -0
  327. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scan/scan_perform_ext.py +0 -0
  328. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scan/utils.py +0 -0
  329. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/scan/views.py +0 -0
  330. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/sparse/__init__.py +0 -0
  331. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/sparse/basic.py +0 -0
  332. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/sparse/rewriting.py +0 -0
  333. {pytensor-2.27.0/pytensor/misc → pytensor-2.27.1/pytensor/sparse/sandbox}/__init__.py +0 -0
  334. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/sparse/sandbox/sp.py +0 -0
  335. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/sparse/sandbox/sp2.py +0 -0
  336. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/sparse/sharedvar.py +0 -0
  337. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/sparse/type.py +0 -0
  338. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/sparse/utils.py +0 -0
  339. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/__init__.py +0 -0
  340. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/basic.py +0 -0
  341. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/blas.py +0 -0
  342. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/blas_c.py +0 -0
  343. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/blas_scipy.py +0 -0
  344. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/blockwise.py +0 -0
  345. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
  346. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
  347. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/c_code/dimshuffle.c +0 -0
  348. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/conv/__init__.py +0 -0
  349. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/conv/abstract_conv.py +0 -0
  350. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/elemwise.py +0 -0
  351. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/elemwise_cgen.py +0 -0
  352. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/exceptions.py +0 -0
  353. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/extra_ops.py +0 -0
  354. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/fft.py +0 -0
  355. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/fourier.py +0 -0
  356. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/functional.py +0 -0
  357. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/inplace.py +0 -0
  358. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/interpolate.py +0 -0
  359. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/io.py +0 -0
  360. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/linalg.py +0 -0
  361. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/nlinalg.py +0 -0
  362. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/pad.py +0 -0
  363. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/random/__init__.py +0 -0
  364. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/random/basic.py +0 -0
  365. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/random/op.py +0 -0
  366. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/random/rewriting/__init__.py +0 -0
  367. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/random/rewriting/basic.py +0 -0
  368. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/random/rewriting/jax.py +0 -0
  369. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/random/rewriting/numba.py +0 -0
  370. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/random/type.py +0 -0
  371. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/random/utils.py +0 -0
  372. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/random/var.py +0 -0
  373. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/__init__.py +0 -0
  374. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/basic.py +0 -0
  375. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/blas.py +0 -0
  376. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/blas_c.py +0 -0
  377. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/blas_scipy.py +0 -0
  378. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/blockwise.py +0 -0
  379. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/einsum.py +0 -0
  380. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/elemwise.py +0 -0
  381. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/extra_ops.py +0 -0
  382. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/jax.py +0 -0
  383. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/linalg.py +0 -0
  384. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/numba.py +0 -0
  385. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/ofg.py +0 -0
  386. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/shape.py +0 -0
  387. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/special.py +0 -0
  388. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/subtensor.py +0 -0
  389. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
  390. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/shape.py +0 -0
  391. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/sharedvar.py +0 -0
  392. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/slinalg.py +0 -0
  393. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/sort.py +0 -0
  394. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/special.py +0 -0
  395. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/subtensor.py +0 -0
  396. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/type.py +0 -0
  397. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/type_other.py +0 -0
  398. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/utils.py +0 -0
  399. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/var.py +0 -0
  400. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/variable.py +0 -0
  401. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/tensor/xlogx.py +0 -0
  402. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/typed_list/__init__.py +0 -0
  403. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/typed_list/basic.py +0 -0
  404. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/typed_list/rewriting.py +0 -0
  405. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/typed_list/type.py +0 -0
  406. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/updates.py +0 -0
  407. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor/utils.py +0 -0
  408. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor.egg-info/SOURCES.txt +0 -0
  409. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor.egg-info/dependency_links.txt +0 -0
  410. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor.egg-info/entry_points.txt +0 -0
  411. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor.egg-info/requires.txt +0 -0
  412. {pytensor-2.27.0 → pytensor-2.27.1}/pytensor.egg-info/top_level.txt +0 -0
  413. {pytensor-2.27.0 → pytensor-2.27.1}/scripts/mypy-failing.txt +0 -0
  414. {pytensor-2.27.0 → pytensor-2.27.1}/scripts/slowest_tests/update-slowest-times-issue.sh +0 -0
  415. {pytensor-2.27.0 → pytensor-2.27.1}/setup.cfg +0 -0
  416. {pytensor-2.27.0 → pytensor-2.27.1}/setup.py +0 -0
  417. {pytensor-2.27.0 → pytensor-2.27.1}/tests/link/c/c_code/test_cenum.h +0 -0
  418. {pytensor-2.27.0 → pytensor-2.27.1}/tests/link/c/c_code/test_quadratic_function.c +0 -0
  419. {pytensor-2.27.0 → pytensor-2.27.1}/tests/tensor/conv/c_code/corr3d_gemm.c +0 -0
  420. {pytensor-2.27.0 → pytensor-2.27.1}/tests/tensor/conv/c_code/corr_gemm.c +0 -0
  421. {pytensor-2.27.0 → pytensor-2.27.1}/tests/test_breakpoint.py +0 -0
  422. {pytensor-2.27.0 → pytensor-2.27.1}/tests/test_config.py +0 -0
  423. {pytensor-2.27.0 → pytensor-2.27.1}/tests/test_gradient.py +0 -0
  424. {pytensor-2.27.0 → pytensor-2.27.1}/tests/test_ifelse.py +0 -0
  425. {pytensor-2.27.0 → pytensor-2.27.1}/tests/test_printing.py +0 -0
  426. {pytensor-2.27.0 → pytensor-2.27.1}/tests/test_raise_op.py +0 -0
  427. {pytensor-2.27.0 → pytensor-2.27.1}/tests/test_rop.py +0 -0
  428. {pytensor-2.27.0 → pytensor-2.27.1}/tests/test_updates.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pytensor
3
- Version: 2.27.0
3
+ Version: 2.27.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: .. _license:
@@ -26,4 +26,4 @@ some of them might be outdated though:
26
26
 
27
27
  * :ref:`unittest` -- Tutorial on how to use unittest in testing PyTensor.
28
28
 
29
- * :ref:`sparse` -- Description of the ``sparse`` type in PyTensor.
29
+ * :ref:`libdoc_sparse` -- Description of the ``sparse`` type in PyTensor.
@@ -923,7 +923,7 @@ pre-defined macros. These section tags have no macros: ``init_code``,
923
923
  discussed below.
924
924
 
925
925
  * ``APPLY_SPECIFIC(str)`` which will automatically append a name
926
- unique to the :ref:`Apply` node that applies the `Op` at the end
926
+ unique to the :ref:`apply` node that applies the `Op` at the end
927
927
  of the provided ``str``. The use of this macro is discussed
928
928
  further below.
929
929
 
@@ -994,7 +994,7 @@ Apply node in their own names to avoid conflicts between the different
994
994
  versions of the apply-specific code. The code that wasn't
995
995
  apply-specific was simply defined in the ``c_support_code`` method.
996
996
 
997
- To make indentifiers that include the :ref:`Apply` node name use the
997
+ To make indentifiers that include the :ref:`apply` node name use the
998
998
  ``APPLY_SPECIFIC(str)`` macro. In the above example, this macro is
999
999
  used when defining the functions ``vector_elemwise_mult`` and
1000
1000
  ``vector_times_vector`` as well as when calling function
@@ -7,7 +7,7 @@ Creating a new :class:`Op`: Python implementation
7
7
  So suppose you have looked through the library documentation and you don't see
8
8
  a function that does what you want.
9
9
 
10
- If you can implement something in terms of an existing :ref:`Op`, you should do that.
10
+ If you can implement something in terms of an existing :ref:`op`, you should do that.
11
11
  Odds are your function that uses existing PyTensor expressions is short,
12
12
  has no bugs, and potentially profits from rewrites that have already been
13
13
  implemented.
@@ -200,7 +200,7 @@ input(s)'s memory). From there, go to the previous section.
200
200
  certainly lead to erroneous computations.
201
201
 
202
202
  You can often identify an incorrect `Op.view_map` or :attr:`Op.destroy_map`
203
- by using :ref:`DebugMode`.
203
+ by using :ref:`DebugMode <debugmode>`.
204
204
 
205
205
  .. note::
206
206
  Consider using :class:`DebugMode` when developing
@@ -197,7 +197,7 @@ Want C speed without writing C code for your new Op? You can use Numba
197
197
  to generate the C code for you! Here is an `example
198
198
  Op <https://gist.github.com/nouiz/5492778#file-theano_op-py>`_ doing that.
199
199
 
200
- .. _alternate_PyTensor_types:
200
+ .. _alternate_pytensor_types:
201
201
 
202
202
  Alternate PyTensor Types
203
203
  ========================
@@ -10,7 +10,7 @@ The latest release of PyTensor can be installed from Pypi using `pip`:
10
10
  pip install pytensor
11
11
 
12
12
 
13
- Or via conda-force:
13
+ Or via conda-forge:
14
14
 
15
15
  .. code-block:: bash
16
16
 
@@ -20,6 +20,9 @@ PyTensor defines the following modes by name:
20
20
 
21
21
  - ``'FAST_COMPILE'``: Apply just a few graph rewrites and only use Python implementations.
22
22
  - ``'FAST_RUN'``: Apply all rewrites, and use C implementations where possible.
23
+ - ``NUMBA``: Apply all relevant related rewrites and compile the whole graph using Numba.
24
+ - ``JAX``: Apply all relevant rewrites and compile the whole graph using JAX.
25
+ - ``PYTORCH`` Apply all relevant rewrites and compile the whole graph using PyTorch compile.
23
26
  - ``'DebugMode'``: A mode for debugging. See :ref:`DebugMode <debugmode>` for details.
24
27
  - ``'NanGuardMode``: :ref:`Nan detector <nanguardmode>`
25
28
  - ``'DEBUG_MODE'``: Deprecated. Use the string DebugMode.
@@ -28,6 +31,12 @@ The default mode is typically ``FAST_RUN``, but it can be controlled via the
28
31
  configuration variable :attr:`config.mode`, which can be
29
32
  overridden by passing the keyword argument to :func:`pytensor.function`.
30
33
 
34
+ For Numba, JAX, and PyTorch, we exclude rewrites that introduce C-only Ops,
35
+ as well as BLAS optimizations, as those are done automatically by the respective backends.
36
+
37
+ For JAX we also exclude fusion and inplace optimizations, as JAX does not support them
38
+ at the user level. They are performed automatically by JAX.
39
+
31
40
  .. TODO::
32
41
 
33
42
  For a finer level of control over which rewrites are applied, and whether
@@ -83,7 +83,7 @@ Low-level objects
83
83
  .. automodule:: pytensor.tensor.random.op
84
84
  :members: RandomVariable, default_rng
85
85
 
86
- ..automodule:: pytensor.tensor.random.type
86
+ .. automodule:: pytensor.tensor.random.type
87
87
  :members: RandomType, RandomGeneratorType, random_generator_type
88
88
 
89
89
  .. automodule:: pytensor.tensor.random.var
@@ -145,44 +145,64 @@ How do I configure/test my BLAS library
145
145
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
146
146
 
147
147
  There are many ways to configure BLAS for PyTensor. This is done with the PyTensor
148
- flags ``blas__ldflags`` (:ref:`libdoc_config`). The default is to use the BLAS
149
- installation information in NumPy, accessible via
150
- ``numpy.__config__.show()``. You can tell pytensor to use a different
151
- version of BLAS, in case you did not compile NumPy with a fast BLAS or if NumPy
152
- was compiled with a static library of BLAS (the latter is not supported in
153
- PyTensor).
148
+ flags ``blas__ldflags`` (:ref:`libdoc_config`). If not specified, PyTensor will
149
+ attempt to find a local BLAS library to link against, prioritizing specialized implementations.
150
+ The details can be found in :func:`pytensor.link.c.cmodule.default_blas_ldflags`.
154
151
 
155
- The short way to configure the PyTensor flags ``blas__ldflags`` is by setting the
156
- environment variable :envvar:`PYTENSOR_FLAGS` to ``blas__ldflags=XXX`` (in bash
157
- ``export PYTENSOR_FLAGS=blas__ldflags=XXX``)
152
+ Users can manually set the PyTensor flags ``blas__ldflags`` to link against a
153
+ specific version. This is useful even if the default version is the desired one,
154
+ as it will avoid the costly work of trying to find the best BLAS library at runtime.
158
155
 
159
- The ``${HOME}/.pytensorrc`` file is the simplest way to set a relatively
160
- permanent option like this one. Add a ``[blas]`` section with an ``ldflags``
161
- entry like this:
156
+ The PyTensor flags can be set in a few ways:
157
+
158
+ 1. In the ``${HOME}/.pytensorrc`` file.
162
159
 
163
160
  .. code-block:: cfg
164
161
 
165
162
  # other stuff can go here
166
163
  [blas]
167
- ldflags = -lf77blas -latlas -lgfortran #put your flags here
164
+ ldflags = -llapack -lblas -lcblas # put your flags here
168
165
 
169
166
  # other stuff can go here
170
167
 
171
- For more information on the formatting of ``~/.pytensorrc`` and the
172
- configuration options that you can put there, see :ref:`libdoc_config`.
168
+ 2. In BASH before running your script:
169
+
170
+ .. code-block:: bash
171
+
172
+ export PYTENSOR_FLAGS="blas__ldflags='-llapack -lblas -lcblas'"
173
+
174
+ 3. In an Ipython/Jupyter notebook before importing PyTensor:
175
+
176
+ .. code-block:: python
177
+
178
+ %set_env PYTENSOR_FLAGS=blas__ldflags='-llapack -lblas -lcblas'
179
+
180
+
181
+ 4. In `pytensor.config` directly:
182
+
183
+ .. code-block:: python
184
+
185
+ import pytensor
186
+ pytensor.config.blas__ldflags = '-llapack -lblas -lcblas'
187
+
188
+
189
+ (For more information on the formatting of ``~/.pytensorrc`` and the
190
+ configuration options that you can put there, see :ref:`libdoc_config`.)
191
+
192
+ You can find the default BLAS library that PyTensor is linking against by
193
+ checking ``pytensor.config.blas__ldflags``
194
+ or running :func:`pytensor.link.c.cmodule.default_blas_ldflags`.
173
195
 
174
196
  Here are some different way to configure BLAS:
175
197
 
176
- 0) Do nothing and use the default config, which is to link against the same
177
- BLAS against which NumPy was built. This does not work in the case NumPy was
178
- compiled with a static library (e.g. ATLAS is compiled by default only as a
179
- static library).
198
+ 0) Do nothing and use the default config.
199
+ This will usually work great for installation via conda/mamba/pixi (conda-forge channel).
200
+ It will usually fail to link altogether for installation via pip.
180
201
 
181
202
  1) Disable the usage of BLAS and fall back on NumPy for dot products. To do
182
- this, set the value of ``blas__ldflags`` as the empty string (ex: ``export
183
- PYTENSOR_FLAGS=blas__ldflags=``). Depending on the kind of matrix operations your
184
- PyTensor code performs, this might slow some things down (vs. linking with BLAS
185
- directly).
203
+ this, set the value of ``blas__ldflags`` as the empty string.
204
+ Depending on the kind of matrix operations your PyTensor code performs,
205
+ this might slow some things down (vs. linking with BLAS directly).
186
206
 
187
207
  2) You can install the default (reference) version of BLAS if the NumPy version
188
208
  (against which PyTensor links) does not work. If you have root or sudo access in
@@ -208,10 +228,29 @@ correctly (for example, for MKL this might be ``-lmkl -lguide -lpthread`` or
208
228
  ``-lmkl_intel_lp64 -lmkl_intel_thread -lmkl_core -lguide -liomp5 -lmkl_mc
209
229
  -lpthread``).
210
230
 
231
+ 5) Use another backend such as Numba or JAX that perform their own BLAS optimizations,
232
+ by setting the configuration mode to ``"NUMBA"`` or ``"JAX"`` and making sure those packages are installed.
233
+ This configuration mode can be set in all the ways that the BLAS flags can be set, described above.
234
+
235
+ Alternatively, you can pass `mode='NUMBA'` when compiling individual PyTensor functions without changing the default.
236
+ or use the ``config.change_flags`` context manager.
237
+
238
+ .. code-block:: python
239
+
240
+ from pytensor import function, config
241
+ from pytensor.tensor import matrix
242
+
243
+ x = matrix('x')
244
+ y = x @ x.T
245
+ f = function([x], y, mode='NUMBA')
246
+
247
+ with config.change_flags(mode='NUMBA'):
248
+ # compiling function that benefits from BLAS using NUMBA
249
+ f = function([x], y)
250
+
211
251
  .. note::
212
252
 
213
- Make sure your BLAS
214
- libraries are available as dynamically-loadable libraries.
253
+ Make sure your BLAS libraries are available as dynamically-loadable libraries.
215
254
  ATLAS is often installed only as a static library. PyTensor is not able to
216
255
  use this static library. Your ATLAS installation might need to be modified
217
256
  to provide dynamically loadable libraries. (On Linux this
@@ -267,7 +306,7 @@ configuration information. Then, it will print the running time of the same
267
306
  benchmarks for your installation. Try to find a CPU similar to yours in
268
307
  the table, and check that the single-threaded timings are roughly the same.
269
308
 
270
- PyTensor should link to a parallel version of Blas and use all cores
309
+ PyTensor should link to a parallel version of BLAS and use all cores
271
310
  when possible. By default it should use all cores. Set the environment
272
311
  variable "OMP_NUM_THREADS=N" to specify to use N threads.
273
312
 
@@ -347,15 +347,7 @@ afterwards compile this expression to get functions,
347
347
  using pseudo-random numbers is not as straightforward as it is in
348
348
  NumPy, though also not too complicated.
349
349
 
350
- The way to think about putting randomness into PyTensor's computations is
351
- to put random variables in your graph. PyTensor will allocate a NumPy
352
- `RandomStream` object (a random number generator) for each such
353
- variable, and draw from it as necessary. We will call this sort of
354
- sequence of random numbers a *random stream*. *Random streams* are at
355
- their core shared variables, so the observations on shared variables
356
- hold here as well. PyTensor's random objects are defined and implemented in
357
- :ref:`RandomStream<libdoc_tensor_random_utils>` and, at a lower level,
358
- in :ref:`RandomVariable<libdoc_tensor_random_basic>`.
350
+ The general user-facing API is documented in :ref:`RandomStream<libdoc_tensor_random_basic>`
359
351
 
360
352
  For a more technical explanation of how PyTensor implements random variables see :ref:`prng`.
361
353
 
@@ -31,8 +31,8 @@ In the first line np.random.default_rng(seed) creates a random Generator.
31
31
  >>> rng # doctest: +SKIP
32
32
  Generator(PCG64) at 0x7F6C04535820
33
33
 
34
- Every numpy Generator holds a BitGenerator, which is able to generate high-quality sequences of pseudo random bits.
35
- Numpy generators convert these sequences of bits into sequences of numbers that follow a specific statistical distribution.
34
+ Every NumPy Generator holds a BitGenerator, which is able to generate high-quality sequences of pseudo random bits.
35
+ NumPy generators' methods convert these sequences of bits into sequences of numbers that follow a specific statistical distribution.
36
36
  For more details, you can read `NumPy random sampling documentation <https://numpy.org/doc/stable/reference/random>`_.
37
37
 
38
38
  >>> rng.bit_generator # doctest: +SKIP
@@ -47,6 +47,7 @@ For more details, you can read `NumPy random sampling documentation <https://num
47
47
 
48
48
  When we call rng.uniform(size=2), the Generator class requested a new array of pseudo random bits (state) from the BitGenerator,
49
49
  and used a deterministic mapping function to convert those into a float64 numbers.
50
+
50
51
  It did this twice, because we requested two draws via the size argument.
51
52
  In the long-run this deterministic mapping function should produce draws that are statistically indistinguishable from a true uniform distribution.
52
53
 
@@ -71,7 +72,7 @@ array([0.033, 0.972, 0.459, 0.71 , 0.765])
71
72
  SciPy
72
73
  -----
73
74
 
74
- Scipy wraps these Numpy routines in a slightly different API.
75
+ SciPy wraps these NumPy routines in a slightly different API.
75
76
 
76
77
  >>> import scipy.stats as st
77
78
  >>> rng = np.random.default_rng(seed=123)
@@ -82,7 +83,7 @@ PyTensor
82
83
  --------
83
84
 
84
85
  PyTensor does not implement its own bit/generators methods.
85
- Just like Scipy, it borrows NumPy routines directly.
86
+ Just like SciPy, it borrows NumPy routines directly.
86
87
 
87
88
  The low-level API of PyTensor RNGs is similar to that of SciPy,
88
89
  whereas the higher-level API of RandomStreams is more like that of NumPy.
@@ -95,20 +96,19 @@ We will look at RandomStreams shortly, but we will start with the low-level API.
95
96
  >>> x = pt.random.uniform(size=2, rng=rng)
96
97
  >>> f = pytensor.function([rng], x)
97
98
 
98
- We created a function that takes a Numpy RandomGenerator and returns two uniform draws. Let's evaluate it
99
+ We created a function that takes a NumPy RandomGenerator and returns two uniform draws. Let's evaluate it
99
100
 
100
101
  >>> rng_val = np.random.default_rng(123)
101
102
  >>> print(f(rng_val), f(rng_val))
102
103
  [0.68235186 0.05382102] [0.68235186 0.05382102]
103
104
 
104
- The first numbers were exactly the same as the numpy and scipy calls, because we are using the very same routines.
105
+ The first numbers were exactly the same as the NumPy and SciPy calls, because we are using the very same routines.
105
106
 
106
107
  Perhaps surprisingly, we got the same results when we called the function the second time!
107
108
  This is because PyTensor functions do not hold an internal state and do not modify inputs inplace unless requested to.
108
109
 
109
- We made sure that the rng_val was not modified when calling our Pytensor function, by copying it before using it.
110
- This may feel inefficient (and it is), but PyTensor is built on a pure functional approach, which is not allowed to have side-effects
111
- (such as changing global variables) by default.
110
+ We made sure that the rng_val was not modified when calling our PyTensor function, by copying it before using it.
111
+ This may feel inefficient (and it is), but PyTensor is built on a pure functional approach, which is not allowed to have side-effects by default.
112
112
 
113
113
  We will later see how we can get around this issue by making the inputs mutable or using shared variables with explicit update rules.
114
114
 
@@ -129,8 +129,8 @@ In this case we had to advance it twice to get two completely new draws, because
129
129
  But other distributions could need more states for a single draw, or they could be clever and reuse the same state for multiple draws.
130
130
 
131
131
  Because it is not in generally possible to know how much one should modify the generator's bit generator,
132
- PyTensor RandomVariables actually return the copied generator as a hidden output.
133
- This copied generator can be safely used again because it contains the bit generator that was already modified when taking draws.
132
+ PyTensor RandomVariables actually return the used generator as a hidden output.
133
+ This generator can be safely used again because it contains the bit generator that was already modified when taking draws.
134
134
 
135
135
  >>> next_rng, x = x.owner.outputs
136
136
  >>> next_rng.type, x.type
@@ -148,7 +148,6 @@ uniform_rv{"(),()->()"}.0 [id A] <RandomGeneratorType> 'next_rng'
148
148
  └─ 1.0 [id G] <Scalar(float32, shape=())>
149
149
  uniform_rv{"(),()->()"}.1 [id A] <Vector(float64, shape=(2,))> 'x'
150
150
  └─ ···
151
- <ipykernel.iostream.OutStream at 0x7fa5d3a475e0>
152
151
 
153
152
  We can see the single node with [id A], has two outputs, which we named next_rng and x. By default only the second output x is given to the user directly, and the other is "hidden".
154
153
 
@@ -226,14 +225,14 @@ This is exactly what RandomStream does behind the scenes
226
225
  >>> x.owner.inputs[0], x.owner.inputs[0].default_update # doctest: +SKIP
227
226
  (RNG(<Generator(PCG64) at 0x7FA45F4A3760>), uniform_rv{"(),()->()"}.0)
228
227
 
229
- From the example here, you can see that RandomStream uses a NumPy-like API in contrast to
230
- the SciPy-like API of `pytensor.tensor.random`. Full documentation can be found at
231
- :doc:`../library/tensor/random/basic`.
232
-
233
228
  >>> f = pytensor.function([], x)
234
229
  >>> print(f(), f(), f())
235
230
  0.19365083425294516 0.7541389670292019 0.2762903411491048
236
231
 
232
+ From the example here, you can see that RandomStream uses a NumPy-like API in contrast to
233
+ the SciPy-like API of `pytensor.tensor.random`. Full documentation can be found at
234
+ :doc:`libdoc_tensor_random_basic`.
235
+
237
236
  Shared RNGs are created by default
238
237
  ----------------------------------
239
238
 
@@ -279,7 +278,7 @@ RandomStreams provide a helper method to achieve the same
279
278
  Inplace optimization
280
279
  ====================
281
280
 
282
- As mentioned before, by default RandomVariables return a copy of the next RNG state, which can be quite slow.
281
+ As mentioned, RandomVariable Ops default to making a copy of the input RNG before using it, which can be quite slow.
283
282
 
284
283
  >>> rng = np.random.default_rng(123)
285
284
  >>> rng_shared = pytensor.shared(rng, name="rng")
@@ -291,13 +290,13 @@ uniform_rv{"(),()->()"}.1 [id A] 'x' 0
291
290
  ├─ NoneConst{None} [id C]
292
291
  ├─ 0.0 [id D]
293
292
  └─ 1.0 [id E]
294
- <ipykernel.iostream.OutStream at 0x7fa5d3a475e0>
293
+
295
294
 
296
295
  >>> %timeit f() # doctest: +SKIP
297
- 169 µs ± 24.6 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
296
+ 81.8 µs ± 15.4 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
298
297
 
299
298
  >>> %timeit rng.uniform() # doctest: +SKIP
300
- 3.56 µs ± 106 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
299
+ 2.15 µs ± 63.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
301
300
 
302
301
  Like other PyTensor operators, RandomVariable's can be given permission to modify inputs inplace during their operation.
303
302
 
@@ -307,16 +306,6 @@ If the flag is set, the RNG will not be copied before taking random draws.
307
306
  >>> x.owner.op.inplace
308
307
  False
309
308
 
310
- This flag is printed as the last argument of the Op in the `dprint`
311
-
312
- >>> pytensor.dprint(x) # doctest: +SKIP
313
- uniform_rv{"(),()->()"}.1 [id A] 'x' 0
314
- ├─ rng [id B]
315
- ├─ NoneConst{None} [id C]
316
- ├─ 0.0 [id D]
317
- └─ 1.0 [id E]
318
- <ipykernel.iostream.OutStream at 0x7fa5d3a475e0>
319
-
320
309
  For illustration purposes, we will subclass the Uniform Op class and set inplace to True by default.
321
310
 
322
311
  Users should never do this directly!
@@ -336,27 +325,21 @@ uniform_rv{"(),()->()"}.1 [id A] d={0: [0]} 0
336
325
  ├─ NoneConst{None} [id C]
337
326
  ├─ 0.0 [id D]
338
327
  └─ 1.0 [id E]
339
- <ipykernel.iostream.OutStream at 0x7fa5d3a475e0>
340
328
 
341
- The destroy map annotation tells us that the first output of the x variable is allowed to alter the first input.
329
+ The destroy map annotation tells us that the first output of the x variable is allowed to modify the first input.
342
330
 
343
331
  >>> %timeit inplace_f() # doctest: +SKIP
344
- 35.5 µs ± 1.87 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
332
+ 9.71 µs ± 2.06 µs per loop (mean ± std. dev. of 7 runs, 100000 loops each)
345
333
 
346
- Performance is now much closer to calling numpy directly, with only a small overhead introduced by the PyTensor function.
334
+ Performance is now much closer to calling NumPy directly, with a small overhead introduced by the PyTensor function.
347
335
 
348
336
  The `random_make_inplace <https://github.com/pymc-devs/pytensor/blob/3fcf6369d013c597a9c964b2400a3c5e20aa8dce/pytensor/tensor/random/rewriting/basic.py#L42-L52>`_
349
337
  rewrite automatically replaces RandomVariable Ops by their inplace counterparts, when such operation is deemed safe. This happens when:
350
338
 
351
339
  #. An input RNG is flagged as `mutable` and is used in not used anywhere else.
352
- #. A RNG is created intermediately and used in not used anywhere else.
340
+ #. A RNG is created intermediately and not used anywhere else.
353
341
 
354
- The first case is true when a users uses the `mutable` `kwarg` directly, or much more commonly,
355
- when a shared RNG is used and a (default or manual) update expression is given.
356
- In this case, a RandomVariable is allowed to modify the RNG because the shared variable holding it will be rewritten anyway.
357
-
358
- The second case is not very common, because RNGs are not usually chained across multiple RandomVariable Ops.
359
- See more details in the next section.
342
+ The first case is true when a users uses the `mutable` `kwarg` directly.
360
343
 
361
344
  >>> from pytensor.compile.io import In
362
345
  >>> rng = pt.random.type.RandomGeneratorType()("rng")
@@ -371,7 +354,9 @@ uniform_rv{"(),()->()"}.1 [id A] d={0: [0]} 0
371
354
  ├─ NoneConst{None} [id C]
372
355
  ├─ 0.0 [id D]
373
356
  └─ 1.0 [id E]
374
- <ipykernel.iostream.OutStream at 0x7fa5d3a475e0>
357
+
358
+ Or, much more commonly, when a shared RNG is used and a (default or manual) update expression is given.
359
+ In this case, a RandomVariable is allowed to modify the RNG because the shared variable holding it will be rewritten anyway.
375
360
 
376
361
  >>> rng = pytensor.shared(np.random.default_rng(), name="rng")
377
362
  >>> next_rng, x = pt.random.uniform(rng=rng).owner.outputs
@@ -385,7 +370,9 @@ uniform_rv{"(),()->()"}.1 [id A] d={0: [0]} 0
385
370
  └─ 1.0 [id E]
386
371
  uniform_rv{"(),()->()"}.0 [id A] d={0: [0]} 0
387
372
  └─ ···
388
- <ipykernel.iostream.OutStream at 0x7fa5d3a475e0>
373
+
374
+ The second case is not very common, because RNGs are not usually chained across multiple RandomVariable Ops.
375
+ See more details in the next section.
389
376
 
390
377
  Multiple random variables
391
378
  =========================
@@ -420,7 +407,6 @@ normal_rv{"(),()->()"}.0 [id A] <RandomGeneratorType> 'next_rng_x' 0
420
407
  └─ ···
421
408
  normal_rv{"(),()->()"}.0 [id F] <RandomGeneratorType> 'next_rng_y' 1
422
409
  └─ ···
423
- <ipykernel.iostream.OutStream at 0x7fa5d3a475e0>
424
410
 
425
411
  >>> f(), f(), f()
426
412
  ([array(-9.8912135), array(-9.80160951)],
@@ -450,7 +436,6 @@ normal_rv{"(),()->()"}.0 [id A] <RandomGeneratorType> 0
450
436
  └─ ···
451
437
  normal_rv{"(),()->()"}.0 [id F] <RandomGeneratorType> 1
452
438
  └─ ···
453
- <ipykernel.iostream.OutStream at 0x7fa5d3a475e0>
454
439
 
455
440
  >>> f(), f(), f()
456
441
  ([array(-5.81223492), array(-5.85081162)],
@@ -460,15 +445,15 @@ normal_rv{"(),()->()"}.0 [id F] <RandomGeneratorType> 1
460
445
  We could have used a single rng.
461
446
 
462
447
  >>> rng_x = pytensor.shared(np.random.default_rng(seed=123), name="rng_x")
463
- >>> next_rng_x, x = pt.random.normal(loc=0, scale=1, rng=rng).owner.outputs
448
+ >>> next_rng_x, x = pt.random.normal(loc=0, scale=1, rng=rng_x).owner.outputs
464
449
  >>> next_rng_x.name = "next_rng_x"
465
450
  >>> next_rng_y, y = pt.random.normal(loc=100, scale=1, rng=next_rng_x).owner.outputs
466
451
  >>> next_rng_y.name = "next_rng_y"
467
452
  >>>
468
- >>> f = pytensor.function([], [x, y], updates={rng: next_rng_y})
453
+ >>> f = pytensor.function([], [x, y], updates={rng_x: next_rng_y})
469
454
  >>> pytensor.dprint(f, print_type=True) # doctest: +SKIP
470
455
  normal_rv{"(),()->()"}.1 [id A] <Scalar(float64, shape=())> 0
471
- ├─ rng [id B] <RandomGeneratorType>
456
+ ├─ rng_x [id B] <RandomGeneratorType>
472
457
  ├─ NoneConst{None} [id C] <NoneTypeT>
473
458
  ├─ 0 [id D] <Scalar(int8, shape=())>
474
459
  └─ 1 [id E] <Scalar(int8, shape=())>
@@ -480,24 +465,23 @@ normal_rv{"(),()->()"}.1 [id F] <Scalar(float64, shape=())> 1
480
465
  └─ 1 [id E] <Scalar(int8, shape=())>
481
466
  normal_rv{"(),()->()"}.0 [id F] <RandomGeneratorType> 'next_rng_y' 1
482
467
  └─ ···
483
- <ipykernel.iostream.OutStream at 0x7fa5d3a475e0>
484
468
 
485
469
  >>> f(), f()
486
- ([array(0.91110389), array(101.4795275)],
487
- [array(0.0908175), array(100.59639646)])
470
+ ([array(-0.98912135), array(99.63221335)],
471
+ [array(1.28792526), array(100.19397442)])
488
472
 
489
- It works, but that graph is slightly unorthodox in Pytensor.
473
+ It works, but that graph is slightly unorthodox in PyTensor.
490
474
 
491
- One practical reason is that it is more difficult to define the correct update expression for the shared RNG variable.
475
+ One practical reason why, is that it is more difficult to define the correct update expression for the shared RNG variable.
492
476
 
493
- One techincal reason is that it makes rewrites more challenging in cases where RandomVariables could otherwise be manipulated independently.
477
+ One techincal reason why, is that it makes rewrites more challenging in cases where RandomVariables could otherwise be manipulated independently.
494
478
 
495
479
  Creating multiple RNG variables
496
480
  -------------------------------
497
481
 
498
482
  RandomStreams generate high quality seeds for multiple variables, following the NumPy best practices https://numpy.org/doc/stable/reference/random/parallel.html#parallel-random-number-generation.
499
483
 
500
- Users who create their own RNGs should follow the same practice!
484
+ Users who sidestep RandomStreams, either by creating their own RNGs or relying on RandomVariable's default shared RNGs, should follow the same practice!
501
485
 
502
486
  Random variables in inner graphs
503
487
  ================================
@@ -629,7 +613,7 @@ RNGs in Scan are only supported via shared variables in non-sequences at the mom
629
613
  >>> print(err)
630
614
  Tensor type field must be a TensorType; found <class 'pytensor.tensor.random.type.RandomGeneratorType'>.
631
615
 
632
- In the future, TensorTypes may be allowed as explicit recurring states, rendering the use of updates optional or unnecessary
616
+ In the future, RandomGenerator variables may be allowed as explicit recurring states, rendering the internal use of updates optional or unnecessary
633
617
 
634
618
  OpFromGraph
635
619
  -----------
@@ -671,7 +655,7 @@ Other backends (and their limitations)
671
655
  Numba
672
656
  -----
673
657
 
674
- NumPy random generator can be used with Numba backend.
658
+ NumPy random generators can be natively used with the Numba backend.
675
659
 
676
660
  >>> rng = pytensor.shared(np.random.default_rng(123), name="randomstate_rng")
677
661
  >>> x = pt.random.normal(rng=rng)
@@ -692,7 +676,6 @@ Inner graphs:
692
676
  └─ *4-<Scalar(float32, shape=())> [id K] <Scalar(float32, shape=())>
693
677
  ← normal_rv{"(),()->()"}.1 [id G] <Scalar(float64, shape=())>
694
678
  └─ ···
695
- <ipykernel.iostream.OutStream at 0x7fa5d3a475e0>
696
679
 
697
680
  >>> print(numba_fn(), numba_fn())
698
681
  -0.9891213503478509 -0.9891213503478509
@@ -700,11 +683,11 @@ Inner graphs:
700
683
  JAX
701
684
  ---
702
685
 
703
- JAX uses a different type of PRNG than those of Numpy. This means that the standard shared RNGs cannot be used directly in graphs transpiled to JAX.
686
+ JAX uses a different type of PRNG than those of NumPy. This means that the standard shared RNGs cannot be used directly in graphs transpiled to JAX.
704
687
 
705
- Instead a copy of the Shared RNG variable is made, and its bit generator state is given a jax_state entry that is actually used by the JAX random variables.
688
+ Instead a copy of the Shared RNG variable is made, and its bit generator state is expanded with a jax_state entry. This is what's actually used by the JAX random variables.
706
689
 
707
- In general, update rules are still respected, but they won't be used on the original shared variable, only the copied one actually used in the transpiled function
690
+ In general, update rules are still respected, but they won't update/rely on the original shared variable.
708
691
 
709
692
  >>> import jax
710
693
  >>> rng = pytensor.shared(np.random.default_rng(123), name="rng")
@@ -718,7 +701,6 @@ uniform_rv{"(),()->()"}.1 [id A] <Scalar(float64, shape=())> 0
718
701
  └─ 1.0 [id E] <Scalar(float32, shape=())>
719
702
  uniform_rv{"(),()->()"}.0 [id A] <RandomGeneratorType> 0
720
703
  └─ ···
721
- <ipykernel.iostream.OutStream at 0x7fa5d3a475e0>
722
704
 
723
705
  >>> print(jax_fn(), jax_fn())
724
706
  [Array(0.07577298, dtype=float64)] [Array(0.09217023, dtype=float64)]
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-01-24T10:30:26+0100",
11
+ "date": "2025-02-03T19:06:21+0100",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "4ea425938a3f82604d234ac1db2c3239b8d9cd8d",
15
- "version": "2.27.0"
14
+ "full-revisionid": "c22e79e1bbf54deb7043a3a778b6e91295d25e07",
15
+ "version": "2.27.1"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -0,0 +1,4 @@
1
+ from pytensor.graph.rewriting.utils import rewrite_graph
2
+
3
+
4
+ all = ("rewrite_graph",)
@@ -35,6 +35,7 @@ class RewriteDatabase:
35
35
  rewriter: Union["RewriteDatabase", RewritesType],
36
36
  *tags: str,
37
37
  use_db_name_as_tag=True,
38
+ overwrite_existing=False,
38
39
  ):
39
40
  """Register a new rewriter to the database.
40
41
 
@@ -56,7 +57,8 @@ class RewriteDatabase:
56
57
  ``local_remove_all_assert``. Setting `use_db_name_as_tag` to
57
58
  ``False`` removes that behavior. This means that only the rewrite's name
58
59
  and/or its tags will enable it.
59
-
60
+ overwrite_existing:
61
+ Overwrite the existing rewriter with a new one having the same name
60
62
  """
61
63
  if not isinstance(
62
64
  rewriter,
@@ -66,22 +68,27 @@ class RewriteDatabase:
66
68
  ):
67
69
  raise TypeError(f"{rewriter} is not a valid rewrite type.")
68
70
 
69
- if name in self.__db__:
70
- raise ValueError(f"The tag '{name}' is already present in the database.")
71
-
72
71
  if use_db_name_as_tag:
73
72
  if self.name is not None:
74
73
  tags = (*tags, self.name)
75
74
 
76
75
  rewriter.name = name
77
- # This restriction is there because in many place we suppose that
78
- # something in the RewriteDatabase is there only once.
79
- if rewriter.name in self.__db__:
80
- raise ValueError(
81
- f"Tried to register {rewriter.name} again under the new name {name}. "
82
- "The same rewrite cannot be registered multiple times in"
83
- " an `RewriteDatabase`; use `ProxyDB` instead."
84
- )
76
+
77
+ # if tag collides with name
78
+ if name in self.__db__ and name not in self._names:
79
+ raise ValueError(f"The tag '{name}' is already present in the database.")
80
+
81
+ if name in self.__db__ or rewriter.name in self.__db__:
82
+ if overwrite_existing:
83
+ self.remove_tags(name, *tags)
84
+ old_rewriter = self.__db__[name].pop()
85
+ self._names.remove(name)
86
+ self.__db__[old_rewriter.__class__.__name__].remove(old_rewriter)
87
+ else:
88
+ raise ValueError(
89
+ f"The tag '{name}' is already present in the database."
90
+ )
91
+
85
92
  self.__db__[name] = OrderedSet([rewriter])
86
93
  self._names.add(name)
87
94
  self.__db__[rewriter.__class__.__name__].add(rewriter)