pytensor 2.28.1__tar.gz → 2.28.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 (429) hide show
  1. {pytensor-2.28.1/pytensor.egg-info → pytensor-2.28.3}/PKG-INFO +1 -1
  2. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/_version.py +3 -3
  3. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/debugmode.py +8 -0
  4. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/function/__init__.py +16 -1
  5. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/function/pfunc.py +8 -0
  6. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/function/types.py +81 -21
  7. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/mode.py +5 -1
  8. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/configdefaults.py +8 -1
  9. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/configparser.py +1 -0
  10. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/features.py +8 -1
  11. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/fg.py +11 -3
  12. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/rewriting/basic.py +9 -3
  13. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/elemwise.py +1 -6
  14. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/scan.py +4 -2
  15. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/slinalg.py +1 -2
  16. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/basic.py +9 -2
  17. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/elemwise.py +25 -83
  18. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/scan.py +12 -3
  19. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/slinalg.py +1 -2
  20. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/subtensor.py +11 -5
  21. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/basic.py +9 -0
  22. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/elemwise.py +1 -6
  23. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/op.py +13 -33
  24. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/rewriting.py +2 -0
  25. pytensor-2.28.3/pytensor/tensor/c_code/dimshuffle.c +86 -0
  26. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/elemwise.py +16 -21
  27. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/math.py +1450 -169
  28. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/basic.py +7 -1
  29. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/subtensor.py +104 -28
  30. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/shape.py +13 -18
  31. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/slinalg.py +27 -15
  32. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/subtensor.py +47 -17
  33. {pytensor-2.28.1 → pytensor-2.28.3/pytensor.egg-info}/PKG-INFO +1 -1
  34. {pytensor-2.28.1 → pytensor-2.28.3}/scripts/mypy-failing.txt +0 -1
  35. pytensor-2.28.1/pytensor/tensor/c_code/dimshuffle.c +0 -82
  36. {pytensor-2.28.1 → pytensor-2.28.3}/LICENSE.txt +0 -0
  37. {pytensor-2.28.1 → pytensor-2.28.3}/MANIFEST.in +0 -0
  38. {pytensor-2.28.1 → pytensor-2.28.3}/README.rst +0 -0
  39. {pytensor-2.28.1 → pytensor-2.28.3}/doc/.templates/PLACEHOLDER +0 -0
  40. {pytensor-2.28.1 → pytensor-2.28.3}/doc/.templates/layout.html +0 -0
  41. {pytensor-2.28.1 → pytensor-2.28.3}/doc/.templates/nb-badges.html +0 -0
  42. {pytensor-2.28.1 → pytensor-2.28.3}/doc/.templates/rendered_citation.html +0 -0
  43. {pytensor-2.28.1 → pytensor-2.28.3}/doc/LICENSE.txt +0 -0
  44. {pytensor-2.28.1 → pytensor-2.28.3}/doc/README.md +0 -0
  45. {pytensor-2.28.1 → pytensor-2.28.3}/doc/acknowledgement.rst +0 -0
  46. {pytensor-2.28.1 → pytensor-2.28.3}/doc/bcast.png +0 -0
  47. {pytensor-2.28.1 → pytensor-2.28.3}/doc/bcast.svg +0 -0
  48. {pytensor-2.28.1 → pytensor-2.28.3}/doc/blog.md +0 -0
  49. {pytensor-2.28.1 → pytensor-2.28.3}/doc/conf.py +0 -0
  50. {pytensor-2.28.1 → pytensor-2.28.3}/doc/core_development_guide.rst +0 -0
  51. {pytensor-2.28.1 → pytensor-2.28.3}/doc/css.inc +0 -0
  52. {pytensor-2.28.1 → pytensor-2.28.3}/doc/dev_start_guide.rst +0 -0
  53. {pytensor-2.28.1 → pytensor-2.28.3}/doc/environment.yml +0 -0
  54. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/apply.png +0 -0
  55. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/apply.svg +0 -0
  56. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/apply2.svg +0 -0
  57. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/creating_a_c_op.rst +0 -0
  58. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/creating_a_numba_jax_op.rst +0 -0
  59. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/creating_an_op.rst +0 -0
  60. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/ctype.rst +0 -0
  61. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/extending_faq.rst +0 -0
  62. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/extending_pytensor_solution_1.py +0 -0
  63. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/graph_rewriting.rst +0 -0
  64. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/graphstructures.rst +0 -0
  65. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/index.rst +0 -0
  66. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/inplace.rst +0 -0
  67. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/op.rst +0 -0
  68. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/other_ops.rst +0 -0
  69. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/pics/symbolic_graph_opt.png +0 -0
  70. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
  71. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/pipeline.rst +0 -0
  72. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/scan.rst +0 -0
  73. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/tips.rst +0 -0
  74. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/type.rst +0 -0
  75. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/unittest.rst +0 -0
  76. {pytensor-2.28.1 → pytensor-2.28.3}/doc/extending/using_params.rst +0 -0
  77. {pytensor-2.28.1 → pytensor-2.28.3}/doc/faq.rst +0 -0
  78. {pytensor-2.28.1 → pytensor-2.28.3}/doc/gallery/page_footer.md +0 -0
  79. {pytensor-2.28.1 → pytensor-2.28.3}/doc/gallery/rewrites/graph_rewrites.ipynb +0 -0
  80. {pytensor-2.28.1 → pytensor-2.28.3}/doc/gallery/scan/scan_tutorial.ipynb +0 -0
  81. {pytensor-2.28.1 → pytensor-2.28.3}/doc/generate_dtype_tensor_table.py +0 -0
  82. {pytensor-2.28.1 → pytensor-2.28.3}/doc/glossary.rst +0 -0
  83. {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/Elman_srnn.png +0 -0
  84. {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/PyTensor.png +0 -0
  85. {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/PyTensor_RGB.svg +0 -0
  86. {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/PyTensor_logo.png +0 -0
  87. {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/binder.svg +0 -0
  88. {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/blocksparse.png +0 -0
  89. {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/colab.svg +0 -0
  90. {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/github.svg +0 -0
  91. {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/lstm.png +0 -0
  92. {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/lstm_memorycell.png +0 -0
  93. {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/talk2010.gif +0 -0
  94. {pytensor-2.28.1 → pytensor-2.28.3}/doc/images/talk2010.png +0 -0
  95. {pytensor-2.28.1 → pytensor-2.28.3}/doc/index.rst +0 -0
  96. {pytensor-2.28.1 → pytensor-2.28.3}/doc/install.rst +0 -0
  97. {pytensor-2.28.1 → pytensor-2.28.3}/doc/internal/how_to_release.rst +0 -0
  98. {pytensor-2.28.1 → pytensor-2.28.3}/doc/internal/index.rst +0 -0
  99. {pytensor-2.28.1 → pytensor-2.28.3}/doc/internal/metadocumentation.rst +0 -0
  100. {pytensor-2.28.1 → pytensor-2.28.3}/doc/introduction.rst +0 -0
  101. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/debugmode.rst +0 -0
  102. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/function.rst +0 -0
  103. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/index.rst +0 -0
  104. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/io.rst +0 -0
  105. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/mode.rst +0 -0
  106. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/nanguardmode.rst +0 -0
  107. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/opfromgraph.rst +0 -0
  108. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/ops.rst +0 -0
  109. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/profilemode.rst +0 -0
  110. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/compile/shared.rst +0 -0
  111. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/config.rst +0 -0
  112. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
  113. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
  114. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
  115. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
  116. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
  117. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
  118. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
  119. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/mlp.html +0 -0
  120. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/mlp.png +0 -0
  121. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/mlp2.html +0 -0
  122. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/mlp2.pdf +0 -0
  123. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/mlp2.png +0 -0
  124. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/ofg.html +0 -0
  125. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/examples/ofg2.html +0 -0
  126. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/index.ipynb +0 -0
  127. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/index.rst +0 -0
  128. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/index_files/index_10_0.png +0 -0
  129. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/index_files/index_11_0.png +0 -0
  130. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/index_files/index_24_0.png +0 -0
  131. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/d3viz/index_files/index_25_0.png +0 -0
  132. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/features.rst +0 -0
  133. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/fgraph.rst +0 -0
  134. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/graph.rst +0 -0
  135. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/index.rst +0 -0
  136. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/op.rst +0 -0
  137. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/replace.rst +0 -0
  138. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/type.rst +0 -0
  139. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/graph/utils.rst +0 -0
  140. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/index.rst +0 -0
  141. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/misc/pkl_utils.rst +0 -0
  142. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/printing.rst +0 -0
  143. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/scalar/index.rst +0 -0
  144. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/scan.rst +0 -0
  145. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/sparse/index.rst +0 -0
  146. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/sparse/sandbox.rst +0 -0
  147. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/basic.rst +0 -0
  148. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/basic_opt.rst +0 -0
  149. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/bcast.png +0 -0
  150. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/bcast.svg +0 -0
  151. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/conv.rst +0 -0
  152. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/elemwise.rst +0 -0
  153. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/extra_ops.rst +0 -0
  154. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/fft.rst +0 -0
  155. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/functional.rst +0 -0
  156. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/index.rst +0 -0
  157. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/io.rst +0 -0
  158. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/math_opt.rst +0 -0
  159. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/nlinalg.rst +0 -0
  160. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/plot_fft.png +0 -0
  161. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/random/distributions.rst +0 -0
  162. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/random/index.rst +0 -0
  163. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/slinalg.rst +0 -0
  164. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/tensor/utils.rst +0 -0
  165. {pytensor-2.28.1 → pytensor-2.28.3}/doc/library/typed_list.rst +0 -0
  166. {pytensor-2.28.1 → pytensor-2.28.3}/doc/links.rst +0 -0
  167. {pytensor-2.28.1 → pytensor-2.28.3}/doc/optimizations.rst +0 -0
  168. {pytensor-2.28.1 → pytensor-2.28.3}/doc/pylintrc +0 -0
  169. {pytensor-2.28.1 → pytensor-2.28.3}/doc/robots.txt +0 -0
  170. {pytensor-2.28.1 → pytensor-2.28.3}/doc/troubleshooting.rst +0 -0
  171. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/adding.rst +0 -0
  172. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/adding_solution_1.py +0 -0
  173. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/aliasing.rst +0 -0
  174. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/apply.png +0 -0
  175. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/apply.svg +0 -0
  176. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/bcast.png +0 -0
  177. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/broadcasting.rst +0 -0
  178. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/conditions.rst +0 -0
  179. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/debug_faq.rst +0 -0
  180. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/dlogistic.png +0 -0
  181. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/examples.rst +0 -0
  182. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/faq_tutorial.rst +0 -0
  183. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/gradients.rst +0 -0
  184. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/index.rst +0 -0
  185. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/loading_and_saving.rst +0 -0
  186. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/logistic.gp +0 -0
  187. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/logistic.png +0 -0
  188. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/loop.rst +0 -0
  189. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/loop_solution_1.py +0 -0
  190. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/modes.rst +0 -0
  191. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/modes_solution_1.py +0 -0
  192. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/multi_cores.rst +0 -0
  193. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/nan_tutorial.rst +0 -0
  194. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/pics/d3viz.png +0 -0
  195. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
  196. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
  197. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
  198. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/printing_drawing.rst +0 -0
  199. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/prng.rst +0 -0
  200. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/profiling.rst +0 -0
  201. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/profiling_example.py +0 -0
  202. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/profiling_example_out.prof +0 -0
  203. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/shape_info.rst +0 -0
  204. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/sparse.rst +0 -0
  205. {pytensor-2.28.1 → pytensor-2.28.3}/doc/tutorial/symbolic_graphs.rst +0 -0
  206. {pytensor-2.28.1 → pytensor-2.28.3}/doc/user_guide.rst +0 -0
  207. {pytensor-2.28.1 → pytensor-2.28.3}/pyproject.toml +0 -0
  208. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/__init__.py +0 -0
  209. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/bin/__init__.py +0 -0
  210. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/bin/pytensor_cache.py +0 -0
  211. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/breakpoint.py +0 -0
  212. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/__init__.py +0 -0
  213. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/builders.py +0 -0
  214. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/compiledir.py +0 -0
  215. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/compilelock.py +0 -0
  216. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/io.py +0 -0
  217. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/monitormode.py +0 -0
  218. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/nanguardmode.py +0 -0
  219. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/ops.py +0 -0
  220. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/profiling.py +0 -0
  221. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/compile/sharedvalue.py +0 -0
  222. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/__init__.py +0 -0
  223. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/css/d3-context-menu.css +0 -0
  224. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/css/d3viz.css +0 -0
  225. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/d3viz.py +0 -0
  226. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/formatting.py +0 -0
  227. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/js/d3-context-menu.js +0 -0
  228. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/js/d3.v3.min.js +0 -0
  229. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/js/d3viz.js +0 -0
  230. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
  231. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
  232. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/gradient.py +0 -0
  233. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/__init__.py +0 -0
  234. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/basic.py +0 -0
  235. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/destroyhandler.py +0 -0
  236. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/null_type.py +0 -0
  237. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/op.py +0 -0
  238. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/replace.py +0 -0
  239. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/rewriting/__init__.py +0 -0
  240. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/rewriting/db.py +0 -0
  241. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/rewriting/kanren.py +0 -0
  242. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/rewriting/unify.py +0 -0
  243. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/rewriting/utils.py +0 -0
  244. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/type.py +0 -0
  245. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/graph/utils.py +0 -0
  246. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/ifelse.py +0 -0
  247. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/__init__.py +0 -0
  248. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/basic.py +0 -0
  249. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/__init__.py +0 -0
  250. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/basic.py +0 -0
  251. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
  252. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
  253. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/cmodule.py +0 -0
  254. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/cutils.py +0 -0
  255. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/cvm.py +0 -0
  256. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/exceptions.py +0 -0
  257. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/interface.py +0 -0
  258. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/lazylinker_c.py +0 -0
  259. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/op.py +0 -0
  260. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/params_type.py +0 -0
  261. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/c/type.py +0 -0
  262. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/__init__.py +0 -0
  263. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/__init__.py +0 -0
  264. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/basic.py +0 -0
  265. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/blas.py +0 -0
  266. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/blockwise.py +0 -0
  267. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/einsum.py +0 -0
  268. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
  269. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/math.py +0 -0
  270. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/nlinalg.py +0 -0
  271. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/pad.py +0 -0
  272. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/random.py +0 -0
  273. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/scalar.py +0 -0
  274. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/shape.py +0 -0
  275. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/sort.py +0 -0
  276. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/sparse.py +0 -0
  277. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/subtensor.py +0 -0
  278. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
  279. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/jax/linker.py +0 -0
  280. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/__init__.py +0 -0
  281. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/_LAPACK.py +0 -0
  282. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/__init__.py +0 -0
  283. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/blockwise.py +0 -0
  284. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/cython_support.py +0 -0
  285. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
  286. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
  287. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/random.py +0 -0
  288. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/scalar.py +0 -0
  289. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/sparse.py +0 -0
  290. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
  291. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/dispatch/vectorize_codegen.py +0 -0
  292. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/numba/linker.py +0 -0
  293. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/__init__.py +0 -0
  294. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/blas.py +0 -0
  295. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/blockwise.py +0 -0
  296. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/extra_ops.py +0 -0
  297. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/math.py +0 -0
  298. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/nlinalg.py +0 -0
  299. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/scalar.py +0 -0
  300. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/shape.py +0 -0
  301. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/sort.py +0 -0
  302. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/dispatch/subtensor.py +0 -0
  303. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/pytorch/linker.py +0 -0
  304. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/utils.py +0 -0
  305. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/link/vm.py +0 -0
  306. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/__init__.py +0 -0
  307. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/check_blas.py +0 -0
  308. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/check_blas_many.sh +0 -0
  309. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/check_duplicate_key.py +0 -0
  310. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
  311. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/elemwise_time_test.py +0 -0
  312. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/frozendict.py +0 -0
  313. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/may_share_memory.py +0 -0
  314. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/ordered_set.py +0 -0
  315. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/misc/pkl_utils.py +0 -0
  316. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/npy_2_compat.py +0 -0
  317. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/printing.py +0 -0
  318. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/py.typed +0 -0
  319. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/raise_op.py +0 -0
  320. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/__init__.py +0 -0
  321. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/basic.py +0 -0
  322. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
  323. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
  324. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/c_code/gamma.c +0 -0
  325. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/c_code/incbet.c +0 -0
  326. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/loop.py +0 -0
  327. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/math.py +0 -0
  328. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scalar/sharedvar.py +0 -0
  329. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/__init__.py +0 -0
  330. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/basic.py +0 -0
  331. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/checkpoints.py +0 -0
  332. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/rewriting.py +0 -0
  333. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/scan_perform.pyx +0 -0
  334. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/scan_perform_ext.py +0 -0
  335. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/utils.py +0 -0
  336. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/scan/views.py +0 -0
  337. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/__init__.py +0 -0
  338. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/basic.py +0 -0
  339. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/sandbox/__init__.py +0 -0
  340. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/sandbox/sp.py +0 -0
  341. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/sandbox/sp2.py +0 -0
  342. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/sharedvar.py +0 -0
  343. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/type.py +0 -0
  344. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/sparse/utils.py +0 -0
  345. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/__init__.py +0 -0
  346. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/basic.py +0 -0
  347. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/blas.py +0 -0
  348. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/blas_c.py +0 -0
  349. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/blas_headers.py +0 -0
  350. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/blas_scipy.py +0 -0
  351. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/blockwise.py +0 -0
  352. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
  353. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
  354. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/conv/__init__.py +0 -0
  355. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/conv/abstract_conv.py +0 -0
  356. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/einsum.py +0 -0
  357. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/elemwise_cgen.py +0 -0
  358. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/exceptions.py +0 -0
  359. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/extra_ops.py +0 -0
  360. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/fft.py +0 -0
  361. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/fourier.py +0 -0
  362. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/functional.py +0 -0
  363. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/inplace.py +0 -0
  364. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/interpolate.py +0 -0
  365. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/io.py +0 -0
  366. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/linalg.py +0 -0
  367. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/nlinalg.py +0 -0
  368. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/pad.py +0 -0
  369. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/__init__.py +0 -0
  370. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/op.py +0 -0
  371. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/rewriting/__init__.py +0 -0
  372. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/rewriting/basic.py +0 -0
  373. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/rewriting/jax.py +0 -0
  374. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/rewriting/numba.py +0 -0
  375. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/type.py +0 -0
  376. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/utils.py +0 -0
  377. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/random/var.py +0 -0
  378. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/__init__.py +0 -0
  379. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/basic.py +0 -0
  380. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/blas.py +0 -0
  381. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/blas_c.py +0 -0
  382. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/blas_scipy.py +0 -0
  383. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/blockwise.py +0 -0
  384. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/einsum.py +0 -0
  385. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/elemwise.py +0 -0
  386. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/extra_ops.py +0 -0
  387. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/jax.py +0 -0
  388. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/linalg.py +0 -0
  389. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/math.py +0 -0
  390. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/numba.py +0 -0
  391. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/ofg.py +0 -0
  392. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/shape.py +0 -0
  393. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/special.py +0 -0
  394. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
  395. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/sharedvar.py +0 -0
  396. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/sort.py +0 -0
  397. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/special.py +0 -0
  398. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/type.py +0 -0
  399. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/type_other.py +0 -0
  400. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/utils.py +0 -0
  401. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/var.py +0 -0
  402. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/variable.py +0 -0
  403. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/tensor/xlogx.py +0 -0
  404. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/typed_list/__init__.py +0 -0
  405. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/typed_list/basic.py +0 -0
  406. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/typed_list/rewriting.py +0 -0
  407. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/typed_list/type.py +0 -0
  408. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/updates.py +0 -0
  409. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor/utils.py +0 -0
  410. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor.egg-info/SOURCES.txt +0 -0
  411. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor.egg-info/dependency_links.txt +0 -0
  412. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor.egg-info/entry_points.txt +0 -0
  413. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor.egg-info/requires.txt +0 -0
  414. {pytensor-2.28.1 → pytensor-2.28.3}/pytensor.egg-info/top_level.txt +0 -0
  415. {pytensor-2.28.1 → pytensor-2.28.3}/scripts/slowest_tests/update-slowest-times-issue.sh +0 -0
  416. {pytensor-2.28.1 → pytensor-2.28.3}/setup.cfg +0 -0
  417. {pytensor-2.28.1 → pytensor-2.28.3}/setup.py +0 -0
  418. {pytensor-2.28.1 → pytensor-2.28.3}/tests/link/c/c_code/test_cenum.h +0 -0
  419. {pytensor-2.28.1 → pytensor-2.28.3}/tests/link/c/c_code/test_quadratic_function.c +0 -0
  420. {pytensor-2.28.1 → pytensor-2.28.3}/tests/tensor/conv/c_code/corr3d_gemm.c +0 -0
  421. {pytensor-2.28.1 → pytensor-2.28.3}/tests/tensor/conv/c_code/corr_gemm.c +0 -0
  422. {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_breakpoint.py +0 -0
  423. {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_config.py +0 -0
  424. {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_gradient.py +0 -0
  425. {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_ifelse.py +0 -0
  426. {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_printing.py +0 -0
  427. {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_raise_op.py +0 -0
  428. {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_rop.py +0 -0
  429. {pytensor-2.28.1 → pytensor-2.28.3}/tests/test_updates.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pytensor
3
- Version: 2.28.1
3
+ Version: 2.28.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: .. _license:
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-02-24T18:22:58+0100",
11
+ "date": "2025-03-05T13:02:56+0100",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "67017a662a65abaa0e388925762aa3c903abe840",
15
- "version": "2.28.1"
14
+ "full-revisionid": "89d5366c888f430003aa6f16a13ad9cdd2826d95",
15
+ "version": "2.28.3"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -1966,6 +1966,12 @@ class _Maker(FunctionMaker): # inheritance buys a few helper functions
1966
1966
  If the outputs argument for pytensor.function was a list, then
1967
1967
  output_keys is None. If the outputs argument was a dict, then
1968
1968
  output_keys is a sorted list of the keys from that dict.
1969
+ trust_input : bool, default False
1970
+ If True, no input validation checks are performed when the function is
1971
+ called. This includes checking the number of inputs, their types and
1972
+ that multiple inputs are not aliased to each other. Failure to meet any
1973
+ of these conditions can lead to computational errors or to the
1974
+ interpreter crashing.
1969
1975
 
1970
1976
  Notes
1971
1977
  -----
@@ -1993,6 +1999,7 @@ class _Maker(FunctionMaker): # inheritance buys a few helper functions
1993
1999
  output_keys=None,
1994
2000
  name=None,
1995
2001
  no_fgraph_prep=False,
2002
+ trust_input=False,
1996
2003
  ):
1997
2004
  self.mode = mode
1998
2005
  self.profile = profile
@@ -2146,6 +2153,7 @@ class _Maker(FunctionMaker): # inheritance buys a few helper functions
2146
2153
  self.on_unused_input = on_unused_input # Used for the pickling/copy
2147
2154
  self.output_keys = output_keys
2148
2155
  self.name = name
2156
+ self.trust_input = trust_input
2149
2157
 
2150
2158
  self.required = [(i.value is None) for i in self.inputs]
2151
2159
  self.refeed = [
@@ -37,6 +37,7 @@ def function_dump(
37
37
  profile: bool | ProfileStats | None = None,
38
38
  on_unused_input: str | None = None,
39
39
  extra_tag_to_remove: str | None = None,
40
+ trust_input: bool = False,
40
41
  ):
41
42
  """
42
43
  This is helpful to make a reproducible case for problems during PyTensor
@@ -82,6 +83,7 @@ def function_dump(
82
83
  "allow_input_downcast": allow_input_downcast,
83
84
  "profile": profile,
84
85
  "on_unused_input": on_unused_input,
86
+ "trust_input": trust_input,
85
87
  }
86
88
  with Path(filename).open("wb") as f:
87
89
  pickler = pytensor.misc.pkl_utils.StripPickler(
@@ -107,6 +109,7 @@ def function(
107
109
  allow_input_downcast: bool | None = None,
108
110
  profile: bool | ProfileStats | None = None,
109
111
  on_unused_input: str | None = None,
112
+ trust_input: bool = False,
110
113
  ):
111
114
  """
112
115
  Return a :class:`callable object <pytensor.compile.function.types.Function>`
@@ -164,6 +167,12 @@ def function(
164
167
  on_unused_input
165
168
  What to do if a variable in the 'inputs' list is not used in the graph.
166
169
  Possible values are 'raise', 'warn', 'ignore' and None.
170
+ trust_input: bool, default False
171
+ If True, no input validation checks are performed when the function is
172
+ called. This includes checking the number of inputs, their types and
173
+ that multiple inputs are not aliased to each other. Failure to meet any
174
+ of these conditions can lead to computational errors or to the
175
+ interpreter crashing.
167
176
 
168
177
  Returns
169
178
  -------
@@ -310,7 +319,12 @@ def function(
310
319
  "semantics, which disallow using updates and givens"
311
320
  )
312
321
  fn = orig_function(
313
- inputs, outputs, mode=mode, accept_inplace=accept_inplace, name=name
322
+ inputs,
323
+ outputs,
324
+ mode=mode,
325
+ accept_inplace=accept_inplace,
326
+ name=name,
327
+ trust_input=trust_input,
314
328
  )
315
329
  else:
316
330
  # note: pfunc will also call orig_function -- orig_function is
@@ -329,5 +343,6 @@ def function(
329
343
  on_unused_input=on_unused_input,
330
344
  profile=profile,
331
345
  output_keys=output_keys,
346
+ trust_input=trust_input,
332
347
  )
333
348
  return fn
@@ -377,6 +377,7 @@ def pfunc(
377
377
  on_unused_input=None,
378
378
  output_keys=None,
379
379
  fgraph: FunctionGraph | None = None,
380
+ trust_input: bool = False,
380
381
  ) -> Function:
381
382
  """
382
383
  Function-constructor for graphs with shared variables.
@@ -425,6 +426,12 @@ def pfunc(
425
426
  fgraph
426
427
  An existing `FunctionGraph` from which to construct the returned
427
428
  `Function`. When this is non-``None``, nothing is cloned.
429
+ trust_input : bool, default False
430
+ If True, no input validation checks are performed when the function is
431
+ called. This includes checking the number of inputs, their types and
432
+ that multiple inputs are not aliased to each other. Failure to meet any
433
+ of these conditions can lead to computational errors or to the
434
+ interpreter crashing.
428
435
 
429
436
  Returns
430
437
  -------
@@ -472,6 +479,7 @@ def pfunc(
472
479
  on_unused_input=on_unused_input,
473
480
  output_keys=output_keys,
474
481
  fgraph=fgraph,
482
+ trust_input=trust_input,
475
483
  )
476
484
 
477
485
 
@@ -5,6 +5,7 @@ import copyreg
5
5
  import logging
6
6
  import time
7
7
  import warnings
8
+ from collections.abc import Sequence
8
9
  from itertools import chain
9
10
  from typing import TYPE_CHECKING
10
11
 
@@ -168,6 +169,59 @@ class Supervisor(Feature):
168
169
  raise InconsistencyError(f"Trying to destroy a protected variable: {r}")
169
170
 
170
171
 
172
+ def add_supervisor_to_fgraph(
173
+ fgraph: FunctionGraph,
174
+ input_specs: Sequence[SymbolicInput],
175
+ accept_inplace: bool = False,
176
+ ) -> None:
177
+ """Setup Supervisor Feature in a FunctionGraph, so that inplace rewrites can be used.
178
+
179
+ Parameters
180
+ ----------
181
+ fgraph: FunctionGraph
182
+ The FunctionGraph to setup the Supervisor Feature in.
183
+ input_specs: Sequence of SymbolicInput
184
+ The input specifications for the FunctionGraph.
185
+ Inputs with the attribute `mutable=False` and which are not already destroyed by an inplace operation
186
+ (if `accept_inplace` is True) will be protected from inplace operations.
187
+ Otherwise, they will be allowed to be destroyed.
188
+ accept_inplace: bool
189
+ Whether to allow inplace operations to already be present in the graph.
190
+
191
+ Raises
192
+ ------
193
+ TypeError
194
+ If inplace operations are not allowed and the graph already contains inplace operations.
195
+
196
+ """
197
+
198
+ has_destroy_handler = hasattr(fgraph, "destroyers")
199
+ if not (has_destroy_handler and accept_inplace):
200
+ # Check if fgraph already contains destructive operations,
201
+ # in which case we need to add a DestroyHandler or raise an error
202
+ for node in fgraph.apply_nodes:
203
+ if node.op.destroy_map:
204
+ if not accept_inplace:
205
+ raise TypeError(
206
+ f"Graph must not contain inplace operations: {node}"
207
+ )
208
+ else:
209
+ has_destroy_handler = True
210
+ fgraph.attach_feature(DestroyHandler())
211
+ break
212
+
213
+ # Protect all immutable inputs from inplace operations.
214
+ fgraph.attach_feature(
215
+ Supervisor(
216
+ input
217
+ for spec, input in zip(input_specs, fgraph.inputs, strict=True)
218
+ if not (
219
+ spec.mutable or has_destroy_handler and fgraph.has_destroyers([input])
220
+ )
221
+ )
222
+ )
223
+
224
+
171
225
  def std_fgraph(
172
226
  input_specs: list[SymbolicInput],
173
227
  output_specs: list[SymbolicOutput],
@@ -229,24 +283,8 @@ def std_fgraph(
229
283
 
230
284
  found_updates.extend(map(SymbolicOutput, updates))
231
285
 
232
- for node in fgraph.apply_nodes:
233
- if node.op.destroy_map:
234
- if not accept_inplace:
235
- raise TypeError(f"Graph must not contain inplace operations: {node}")
236
- else:
237
- fgraph.attach_feature(DestroyHandler())
238
- break
239
-
240
- # We need to protect all immutable inputs from inplace operations.
241
- fgraph.attach_feature(
242
- Supervisor(
243
- input
244
- for spec, input in zip(input_specs, fgraph.inputs, strict=True)
245
- if not (
246
- spec.mutable
247
- or (hasattr(fgraph, "destroyers") and fgraph.has_destroyers([input]))
248
- )
249
- )
286
+ add_supervisor_to_fgraph(
287
+ fgraph=fgraph, input_specs=input_specs, accept_inplace=accept_inplace
250
288
  )
251
289
 
252
290
  # If named nodes are replaced, keep the name
@@ -335,6 +373,7 @@ class Function:
335
373
  return_none: bool,
336
374
  output_keys,
337
375
  maker: "FunctionMaker",
376
+ trust_input: bool = False,
338
377
  name: str | None = None,
339
378
  ):
340
379
  """
@@ -369,6 +408,12 @@ class Function:
369
408
  TODO
370
409
  maker
371
410
  The `FunctionMaker` that created this instance.
411
+ trust_input : bool, default False
412
+ If True, no input validation checks are performed when the function is
413
+ called. This includes checking the number of inputs, their types and
414
+ that multiple inputs are not aliased to each other. Failure to meet any
415
+ of these conditions can lead to computational errors or to the
416
+ interpreter crashing.
372
417
  name
373
418
  A string name.
374
419
  """
@@ -382,7 +427,7 @@ class Function:
382
427
  self.return_none = return_none
383
428
  self.maker = maker
384
429
  self.profile = None # reassigned in FunctionMaker.create
385
- self.trust_input = False # If True, we don't check the input parameter
430
+ self.trust_input = trust_input # If True, we don't check the input parameter
386
431
  self.name = name
387
432
  self.nodes_with_inner_function = []
388
433
  self.output_keys = output_keys
@@ -1303,7 +1348,12 @@ class FunctionMaker:
1303
1348
  name : str
1304
1349
  An optional name for this function. If used, the profile mode will
1305
1350
  print the time spent in this function.
1306
-
1351
+ trust_input : bool, default False
1352
+ If True, no input validation checks are performed when the function is
1353
+ called. This includes checking the number of inputs, their types and
1354
+ that multiple inputs are not aliased to each other. Failure to meet any
1355
+ of these conditions can lead to computational errors or to the
1356
+ interpreter crashing.
1307
1357
  """
1308
1358
 
1309
1359
  @staticmethod
@@ -1469,6 +1519,7 @@ class FunctionMaker:
1469
1519
  output_keys=None,
1470
1520
  name=None,
1471
1521
  no_fgraph_prep=False,
1522
+ trust_input=False,
1472
1523
  ):
1473
1524
  # Save the provided mode, not the instantiated mode.
1474
1525
  # The instantiated mode don't pickle and if we unpickle an PyTensor
@@ -1571,6 +1622,7 @@ class FunctionMaker:
1571
1622
  self.on_unused_input = on_unused_input # Used for the pickling/copy
1572
1623
  self.output_keys = output_keys
1573
1624
  self.name = name
1625
+ self.trust_input = trust_input
1574
1626
 
1575
1627
  self.required = [(i.value is None) for i in self.inputs]
1576
1628
  self.refeed = [
@@ -1688,6 +1740,7 @@ class FunctionMaker:
1688
1740
  self.return_none,
1689
1741
  self.output_keys,
1690
1742
  self,
1743
+ trust_input=self.trust_input,
1691
1744
  name=self.name,
1692
1745
  )
1693
1746
 
@@ -1705,6 +1758,7 @@ def orig_function(
1705
1758
  on_unused_input=None,
1706
1759
  output_keys=None,
1707
1760
  fgraph: FunctionGraph | None = None,
1761
+ trust_input: bool = False,
1708
1762
  ) -> Function:
1709
1763
  """
1710
1764
  Return a Function that will calculate the outputs from the inputs.
@@ -1735,7 +1789,12 @@ def orig_function(
1735
1789
  fgraph
1736
1790
  An existing `FunctionGraph` to use instead of constructing a new one
1737
1791
  from cloned `outputs`.
1738
-
1792
+ trust_input : bool, default False
1793
+ If True, no input validation checks are performed when the function is
1794
+ called. This includes checking the number of inputs, their types and
1795
+ that multiple inputs are not aliased to each other. Failure to meet any
1796
+ of these conditions can lead to computational errors or to the
1797
+ interpreter crashing.
1739
1798
  """
1740
1799
 
1741
1800
  if profile:
@@ -1768,6 +1827,7 @@ def orig_function(
1768
1827
  output_keys=output_keys,
1769
1828
  name=name,
1770
1829
  fgraph=fgraph,
1830
+ trust_input=trust_input,
1771
1831
  )
1772
1832
  with config.change_flags(compute_test_value="off"):
1773
1833
  fn = m.create(defaults)
@@ -138,7 +138,11 @@ class AddDestroyHandler(GraphRewriter):
138
138
  break
139
139
  if not supervisor_added:
140
140
  warnings.warn(
141
- f"A Supervisor feature is missing from {fgraph}.",
141
+ (
142
+ f"A Supervisor feature is missing from {fgraph}.\n"
143
+ "This is needed for inplace rewrites. Either exclude inplace rewrites or add a Supervisor feature.\n"
144
+ "A Supervisor feature can be added via `pytensor.compile.function.types.add_supervisor_to_fgraph`."
145
+ ),
142
146
  stacklevel=3,
143
147
  )
144
148
 
@@ -418,11 +418,18 @@ def add_compile_configvars():
418
418
 
419
419
  config.add(
420
420
  "optimizer_verbose",
421
- "If True, we print all optimization being applied",
421
+ "Print information about rewrites that are applied during a graph transformation.",
422
422
  BoolParam(False),
423
423
  in_c_key=False,
424
424
  )
425
425
 
426
+ config.add(
427
+ "optimizer_verbose_ignore",
428
+ "Do not print information for rewrites with these names when `optimizer_verbose` is `True`. Separate names with ','",
429
+ StrParam(""),
430
+ in_c_key=False,
431
+ )
432
+
426
433
  config.add(
427
434
  "on_opt_error",
428
435
  (
@@ -81,6 +81,7 @@ class PyTensorConfigParser:
81
81
  allow_gc: bool
82
82
  optimizer: str
83
83
  optimizer_verbose: bool
84
+ optimizer_verbose_ignore: str
84
85
  on_opt_error: str
85
86
  nocleanup: bool
86
87
  on_unused_input: str
@@ -567,6 +567,13 @@ class ReplaceValidate(History, Validator):
567
567
  if verbose is None:
568
568
  verbose = config.optimizer_verbose
569
569
 
570
+ if verbose:
571
+ print_reason = True
572
+ if config.optimizer_verbose_ignore:
573
+ print_reason = str(reason) not in config.optimizer_verbose_ignore.split(
574
+ ","
575
+ )
576
+
570
577
  for r, new_r in replacements:
571
578
  try:
572
579
  fgraph.replace(r, new_r, reason=reason, verbose=False, **kwargs)
@@ -608,7 +615,7 @@ class ReplaceValidate(History, Validator):
608
615
  )
609
616
  raise
610
617
 
611
- if verbose:
618
+ if verbose and print_reason:
612
619
  print( # noqa: T201
613
620
  f"rewriting: rewrite {reason} replaces {r} of {r.owner} with {new_r} of {new_r.owner}"
614
621
  )
@@ -490,10 +490,18 @@ class FunctionGraph(MetaObject):
490
490
  """
491
491
  if verbose is None:
492
492
  verbose = config.optimizer_verbose
493
+
493
494
  if verbose:
494
- print( # noqa: T201
495
- f"rewriting: rewrite {reason} replaces {var} of {var.owner} with {new_var} of {new_var.owner}"
496
- )
495
+ print_reason = True
496
+ if config.optimizer_verbose_ignore:
497
+ print_reason = str(reason) not in config.optimizer_verbose_ignore.split(
498
+ ","
499
+ )
500
+
501
+ if print_reason:
502
+ print( # noqa: T201
503
+ f"rewriting: rewrite {reason} replaces {var} of {var.owner} with {new_var} of {new_var.owner}"
504
+ )
497
505
 
498
506
  new_var = var.type.filter_variable(new_var, allow_convert=True)
499
507
 
@@ -1305,9 +1305,15 @@ class SequentialNodeRewriter(NodeRewriter):
1305
1305
  new_vars = list(new_repl.values())
1306
1306
 
1307
1307
  if config.optimizer_verbose:
1308
- print( # noqa: T201
1309
- f"rewriting: rewrite {rewrite} replaces node {node} with {new_repl}"
1310
- )
1308
+ print_reason = True
1309
+ if config.optimizer_verbose_ignore:
1310
+ print_reason = str(
1311
+ rewrite
1312
+ ) not in config.optimizer_verbose_ignore.split(",")
1313
+ if print_reason:
1314
+ print( # noqa: T201
1315
+ f"rewriting: rewrite {rewrite} replaces node {node} with {new_repl}"
1316
+ )
1311
1317
 
1312
1318
  if self.profile:
1313
1319
  self.node_created[rewrite] += len(
@@ -79,12 +79,7 @@ def jax_funcify_DimShuffle(op, **kwargs):
79
79
  for augm in op.augment:
80
80
  shape.insert(augm, 1)
81
81
 
82
- res = jnp.reshape(res, shape)
83
-
84
- if not op.inplace:
85
- res = jnp.copy(res)
86
-
87
- return res
82
+ return jnp.reshape(res, shape)
88
83
 
89
84
  return dimshuffle
90
85
 
@@ -1,7 +1,7 @@
1
1
  import jax
2
2
  import jax.numpy as jnp
3
3
 
4
- from pytensor.compile.mode import JAX
4
+ from pytensor.compile.mode import JAX, get_mode
5
5
  from pytensor.link.jax.dispatch.basic import jax_funcify
6
6
  from pytensor.scan.op import Scan
7
7
 
@@ -19,7 +19,9 @@ def jax_funcify_Scan(op: Scan, **kwargs):
19
19
  )
20
20
 
21
21
  # Optimize inner graph (exclude any defalut rewrites that are incompatible with JAX mode)
22
- rewriter = op.mode_instance.excluding(*JAX._optimizer.exclude).optimizer
22
+ rewriter = (
23
+ get_mode(op.mode).including("jax").excluding(*JAX._optimizer.exclude).optimizer
24
+ )
23
25
  rewriter(op.fgraph)
24
26
  scan_inner_func = jax_funcify(op.fgraph, **kwargs)
25
27
 
@@ -53,7 +53,6 @@ def jax_funcify_Solve(op, **kwargs):
53
53
  @jax_funcify.register(SolveTriangular)
54
54
  def jax_funcify_SolveTriangular(op, **kwargs):
55
55
  lower = op.lower
56
- trans = op.trans
57
56
  unit_diagonal = op.unit_diagonal
58
57
  check_finite = op.check_finite
59
58
 
@@ -62,7 +61,7 @@ def jax_funcify_SolveTriangular(op, **kwargs):
62
61
  A,
63
62
  b,
64
63
  lower=lower,
65
- trans=trans,
64
+ trans=0, # this is handled by explicitly transposing A, so it will always be 0 when we get to here.
66
65
  unit_diagonal=unit_diagonal,
67
66
  check_finite=check_finite,
68
67
  )
@@ -16,9 +16,10 @@ from numba.core.errors import NumbaWarning, TypingError
16
16
  from numba.cpython.unsafe.tuple import tuple_setitem # noqa: F401
17
17
  from numba.extending import box, overload
18
18
 
19
- from pytensor import config
19
+ from pytensor import In, config
20
20
  from pytensor.compile import NUMBA
21
21
  from pytensor.compile.builders import OpFromGraph
22
+ from pytensor.compile.function.types import add_supervisor_to_fgraph
22
23
  from pytensor.compile.ops import DeepCopyOp
23
24
  from pytensor.graph.basic import Apply
24
25
  from pytensor.graph.fg import FunctionGraph
@@ -430,7 +431,13 @@ def numba_funcify_OpFromGraph(op, node=None, **kwargs):
430
431
  # TODO: Not sure this is the right place to do this, should we have a rewrite that
431
432
  # explicitly triggers the optimization of the inner graphs of OpFromGraph?
432
433
  # The C-code defers it to the make_thunk phase
433
- NUMBA.optimizer(op.fgraph)
434
+ fgraph = op.fgraph
435
+ add_supervisor_to_fgraph(
436
+ fgraph=fgraph,
437
+ input_specs=[In(x, borrow=True, mutable=False) for x in fgraph.inputs],
438
+ accept_inplace=True,
439
+ )
440
+ NUMBA.optimizer(fgraph)
434
441
  fgraph_fn = numba_njit(numba_funcify(op.fgraph, **kwargs))
435
442
 
436
443
  if len(op.fgraph.outputs) == 1:
@@ -4,6 +4,7 @@ from textwrap import dedent, indent
4
4
  import numba
5
5
  import numpy as np
6
6
  from numba.core.extending import overload
7
+ from numpy.lib.stride_tricks import as_strided
7
8
 
8
9
  from pytensor.graph.op import Op
9
10
  from pytensor.link.numba.dispatch import basic as numba_basic
@@ -411,97 +412,38 @@ def numba_funcify_CAReduce(op, node, **kwargs):
411
412
 
412
413
  @numba_funcify.register(DimShuffle)
413
414
  def numba_funcify_DimShuffle(op, node, **kwargs):
414
- shuffle = tuple(op.shuffle)
415
- transposition = tuple(op.transposition)
416
- augment = tuple(op.augment)
417
- inplace = op.inplace
415
+ # We use `as_strided` to achieve the DimShuffle behavior of transposing and expanding/squezing dimensions in one call
416
+ # Numba doesn't currently support multiple expand/squeeze, and reshape is limited to contiguous arrays.
417
+ new_order = tuple(op._new_order)
418
+ shape_template = (1,) * node.outputs[0].ndim
419
+ strides_template = (0,) * node.outputs[0].ndim
418
420
 
419
- ndim_new_shape = len(shuffle) + len(augment)
420
-
421
- no_transpose = all(i == j for i, j in enumerate(transposition))
422
- if no_transpose:
423
-
424
- @numba_basic.numba_njit
425
- def transpose(x):
426
- return x
427
-
428
- else:
421
+ if new_order == ():
422
+ # Special case needed because of https://github.com/numba/numba/issues/9933
429
423
 
430
424
  @numba_basic.numba_njit
431
- def transpose(x):
432
- return np.transpose(x, transposition)
433
-
434
- shape_template = (1,) * ndim_new_shape
435
-
436
- # When `len(shuffle) == 0`, the `shuffle_shape[j]` expression below
437
- # is typed as `getitem(Tuple(), int)`, which has no implementation
438
- # (since getting an item from an empty sequence doesn't make sense).
439
- # To avoid this compile-time error, we omit the expression altogether.
440
- if len(shuffle) > 0:
441
- # Use the statically known shape if available
442
- if all(length is not None for length in node.outputs[0].type.shape):
443
- shape = node.outputs[0].type.shape
444
-
445
- @numba_basic.numba_njit
446
- def find_shape(array_shape):
447
- return shape
448
-
449
- else:
450
-
451
- @numba_basic.numba_njit
452
- def find_shape(array_shape):
453
- shape = shape_template
454
- j = 0
455
- for i in range(ndim_new_shape):
456
- if i not in augment:
457
- length = array_shape[j]
458
- shape = numba_basic.tuple_setitem(shape, i, length)
459
- j = j + 1
460
- return shape
461
-
462
- else:
463
-
464
- @numba_basic.numba_njit
465
- def find_shape(array_shape):
466
- return shape_template
467
-
468
- if ndim_new_shape > 0:
469
-
470
- @numba_basic.numba_njit
471
- def dimshuffle_inner(x, shuffle):
472
- x = transpose(x)
473
- shuffle_shape = x.shape[: len(shuffle)]
474
- new_shape = find_shape(shuffle_shape)
475
-
476
- # FIXME: Numba's `array.reshape` only accepts C arrays.
477
- res_reshape = np.reshape(np.ascontiguousarray(x), new_shape)
425
+ def squeeze_to_0d(x):
426
+ return as_strided(x, shape=(), strides=())
478
427
 
479
- if not inplace:
480
- return res_reshape.copy()
481
- else:
482
- return res_reshape
428
+ return squeeze_to_0d
483
429
 
484
430
  else:
485
431
 
486
432
  @numba_basic.numba_njit
487
- def dimshuffle_inner(x, shuffle):
488
- return np.reshape(np.ascontiguousarray(x), ())
489
-
490
- # Without the following wrapper function we would see this error:
491
- # E No implementation of function Function(<built-in function getitem>) found for signature:
492
- # E
493
- # E >>> getitem(UniTuple(int64 x 2), slice<a:b>)
494
- # E
495
- # E There are 22 candidate implementations:
496
- # E - Of which 22 did not match due to:
497
- # E Overload of function 'getitem': File: <numerous>: Line N/A.
498
- # E With argument(s): '(UniTuple(int64 x 2), slice<a:b>)':
499
- # E No match.
500
- # ...(on this line)...
501
- # E shuffle_shape = res.shape[: len(shuffle)]
502
- @numba_basic.numba_njit(inline="always")
503
- def dimshuffle(x):
504
- return dimshuffle_inner(np.asarray(x), shuffle)
433
+ def dimshuffle(x):
434
+ old_shape = x.shape
435
+ old_strides = x.strides
436
+
437
+ new_shape = shape_template
438
+ new_strides = strides_template
439
+ for i, o in enumerate(new_order):
440
+ if o != -1:
441
+ new_shape = numba_basic.tuple_setitem(new_shape, i, old_shape[o])
442
+ new_strides = numba_basic.tuple_setitem(
443
+ new_strides, i, old_strides[o]
444
+ )
445
+
446
+ return as_strided(x, shape=new_shape, strides=new_strides)
505
447
 
506
448
  return dimshuffle
507
449