pytensor 2.20.0__tar.gz → 2.22.0__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 (412) hide show
  1. {pytensor-2.20.0 → pytensor-2.22.0}/MANIFEST.in +0 -1
  2. {pytensor-2.20.0/pytensor.egg-info → pytensor-2.22.0}/PKG-INFO +2 -2
  3. {pytensor-2.20.0 → pytensor-2.22.0}/doc/conf.py +34 -1
  4. {pytensor-2.20.0 → pytensor-2.22.0}/doc/dev_start_guide.rst +6 -12
  5. {pytensor-2.20.0 → pytensor-2.22.0}/doc/environment.yml +1 -1
  6. pytensor-2.22.0/doc/extending/creating_a_numba_jax_op.rst +285 -0
  7. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/pipeline.rst +1 -1
  8. {pytensor-2.20.0 → pytensor-2.22.0}/pyproject.toml +3 -3
  9. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/_version.py +3 -3
  10. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/bin/pytensor_cache.py +2 -2
  11. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/breakpoint.py +1 -1
  12. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/builders.py +11 -2
  13. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/mode.py +0 -2
  14. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/ops.py +1 -1
  15. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/configdefaults.py +9 -5
  16. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/basic.py +93 -47
  17. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/op.py +11 -2
  18. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/cmodule.py +35 -18
  19. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/params_type.py +21 -16
  20. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/random.py +153 -38
  21. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/basic.py +8 -1
  22. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/elemwise.py +11 -2
  23. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/random.py +60 -1
  24. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/linker.py +1 -1
  25. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/utils.py +7 -2
  26. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scalar/basic.py +3 -3
  27. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scan/checkpoints.py +8 -6
  28. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/__init__.py +1 -1
  29. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/basic.py +106 -2
  30. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/blas.py +8 -7
  31. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/elemwise.py +12 -2
  32. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/extra_ops.py +22 -12
  33. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/fft.py +5 -6
  34. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/io.py +1 -1
  35. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/math.py +1 -1
  36. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/nlinalg.py +133 -5
  37. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/random/basic.py +196 -82
  38. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/random/op.py +11 -7
  39. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/random/rewriting/jax.py +40 -1
  40. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/random/utils.py +10 -1
  41. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/basic.py +30 -65
  42. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/blockwise.py +0 -1
  43. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/linalg.py +77 -10
  44. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/math.py +0 -4
  45. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/shape.py +2 -3
  46. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/sort.py +2 -271
  47. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/subtensor.py +68 -3
  48. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/variable.py +24 -10
  49. {pytensor-2.20.0 → pytensor-2.22.0/pytensor.egg-info}/PKG-INFO +2 -2
  50. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor.egg-info/SOURCES.txt +0 -4
  51. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor.egg-info/requires.txt +1 -1
  52. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor.egg-info/top_level.txt +0 -1
  53. {pytensor-2.20.0 → pytensor-2.22.0}/versioneer.py +43 -47
  54. pytensor-2.20.0/bin/__init__.py +0 -9
  55. pytensor-2.20.0/bin/pytensor-cache +0 -12
  56. pytensor-2.20.0/bin/pytensor_cache.py +0 -14
  57. pytensor-2.20.0/doc/extending/creating_a_numba_jax_op.rst +0 -153
  58. pytensor-2.20.0/doc/scripts/docgen.py +0 -111
  59. {pytensor-2.20.0 → pytensor-2.22.0}/LICENSE.txt +0 -0
  60. {pytensor-2.20.0 → pytensor-2.22.0}/README.rst +0 -0
  61. {pytensor-2.20.0 → pytensor-2.22.0}/doc/.templates/PLACEHOLDER +0 -0
  62. {pytensor-2.20.0 → pytensor-2.22.0}/doc/.templates/layout.html +0 -0
  63. {pytensor-2.20.0 → pytensor-2.22.0}/doc/LICENSE.txt +0 -0
  64. {pytensor-2.20.0 → pytensor-2.22.0}/doc/README.md +0 -0
  65. {pytensor-2.20.0 → pytensor-2.22.0}/doc/acknowledgement.rst +0 -0
  66. {pytensor-2.20.0 → pytensor-2.22.0}/doc/bcast.png +0 -0
  67. {pytensor-2.20.0 → pytensor-2.22.0}/doc/bcast.svg +0 -0
  68. {pytensor-2.20.0 → pytensor-2.22.0}/doc/core_development_guide.rst +0 -0
  69. {pytensor-2.20.0 → pytensor-2.22.0}/doc/css.inc +0 -0
  70. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/apply.png +0 -0
  71. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/apply.svg +0 -0
  72. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/apply2.svg +0 -0
  73. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/creating_a_c_op.rst +0 -0
  74. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/creating_an_op.rst +0 -0
  75. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/ctype.rst +0 -0
  76. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/extending_faq.rst +0 -0
  77. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/extending_pytensor_solution_1.py +0 -0
  78. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/graph_rewriting.rst +0 -0
  79. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/graphstructures.rst +0 -0
  80. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/index.rst +0 -0
  81. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/inplace.rst +0 -0
  82. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/op.rst +0 -0
  83. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/other_ops.rst +0 -0
  84. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/pics/symbolic_graph_opt.png +0 -0
  85. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
  86. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/scan.rst +0 -0
  87. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/tips.rst +0 -0
  88. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/type.rst +0 -0
  89. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/unittest.rst +0 -0
  90. {pytensor-2.20.0 → pytensor-2.22.0}/doc/extending/using_params.rst +0 -0
  91. {pytensor-2.20.0 → pytensor-2.22.0}/doc/faq.rst +0 -0
  92. {pytensor-2.20.0 → pytensor-2.22.0}/doc/generate_dtype_tensor_table.py +0 -0
  93. {pytensor-2.20.0 → pytensor-2.22.0}/doc/glossary.rst +0 -0
  94. {pytensor-2.20.0 → pytensor-2.22.0}/doc/images/Elman_srnn.png +0 -0
  95. {pytensor-2.20.0 → pytensor-2.22.0}/doc/images/PyTensor_RGB.svg +0 -0
  96. {pytensor-2.20.0 → pytensor-2.22.0}/doc/images/blocksparse.png +0 -0
  97. {pytensor-2.20.0 → pytensor-2.22.0}/doc/images/lstm.png +0 -0
  98. {pytensor-2.20.0 → pytensor-2.22.0}/doc/images/lstm_memorycell.png +0 -0
  99. {pytensor-2.20.0 → pytensor-2.22.0}/doc/images/talk2010.gif +0 -0
  100. {pytensor-2.20.0 → pytensor-2.22.0}/doc/images/talk2010.png +0 -0
  101. {pytensor-2.20.0 → pytensor-2.22.0}/doc/index.rst +0 -0
  102. {pytensor-2.20.0 → pytensor-2.22.0}/doc/install.rst +0 -0
  103. {pytensor-2.20.0 → pytensor-2.22.0}/doc/internal/how_to_release.rst +0 -0
  104. {pytensor-2.20.0 → pytensor-2.22.0}/doc/internal/index.rst +0 -0
  105. {pytensor-2.20.0 → pytensor-2.22.0}/doc/internal/metadocumentation.rst +0 -0
  106. {pytensor-2.20.0 → pytensor-2.22.0}/doc/introduction.rst +0 -0
  107. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/compile/debugmode.rst +0 -0
  108. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/compile/function.rst +0 -0
  109. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/compile/index.rst +0 -0
  110. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/compile/io.rst +0 -0
  111. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/compile/mode.rst +0 -0
  112. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/compile/nanguardmode.rst +0 -0
  113. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/compile/opfromgraph.rst +0 -0
  114. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/compile/ops.rst +0 -0
  115. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/compile/profilemode.rst +0 -0
  116. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/compile/shared.rst +0 -0
  117. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/config.rst +0 -0
  118. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
  119. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
  120. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
  121. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
  122. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
  123. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
  124. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
  125. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/mlp.html +0 -0
  126. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/mlp.png +0 -0
  127. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/mlp2.html +0 -0
  128. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/mlp2.pdf +0 -0
  129. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/mlp2.png +0 -0
  130. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/ofg.html +0 -0
  131. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/examples/ofg2.html +0 -0
  132. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/index.ipynb +0 -0
  133. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/index.rst +0 -0
  134. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/index_files/index_10_0.png +0 -0
  135. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/index_files/index_11_0.png +0 -0
  136. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/index_files/index_24_0.png +0 -0
  137. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/d3viz/index_files/index_25_0.png +0 -0
  138. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/gradient.rst +0 -0
  139. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/graph/features.rst +0 -0
  140. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/graph/fgraph.rst +0 -0
  141. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/graph/graph.rst +0 -0
  142. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/graph/index.rst +0 -0
  143. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/graph/op.rst +0 -0
  144. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/graph/type.rst +0 -0
  145. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/graph/utils.rst +0 -0
  146. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/index.rst +0 -0
  147. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/misc/pkl_utils.rst +0 -0
  148. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/printing.rst +0 -0
  149. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/sandbox/index.rst +0 -0
  150. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/sandbox/linalg.rst +0 -0
  151. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/scalar/index.rst +0 -0
  152. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/scan.rst +0 -0
  153. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/sparse/index.rst +0 -0
  154. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/sparse/sandbox.rst +0 -0
  155. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/basic.rst +0 -0
  156. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/basic_opt.rst +0 -0
  157. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/bcast.png +0 -0
  158. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/bcast.svg +0 -0
  159. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/conv.rst +0 -0
  160. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/elemwise.rst +0 -0
  161. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/extra_ops.rst +0 -0
  162. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/fft.rst +0 -0
  163. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/index.rst +0 -0
  164. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/io.rst +0 -0
  165. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/math_opt.rst +0 -0
  166. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/nlinalg.rst +0 -0
  167. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/plot_fft.png +0 -0
  168. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/random/basic.rst +0 -0
  169. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/random/index.rst +0 -0
  170. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/random/utils.rst +0 -0
  171. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/slinalg.rst +0 -0
  172. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/tensor/utils.rst +0 -0
  173. {pytensor-2.20.0 → pytensor-2.22.0}/doc/library/typed_list.rst +0 -0
  174. {pytensor-2.20.0 → pytensor-2.22.0}/doc/links.rst +0 -0
  175. {pytensor-2.20.0 → pytensor-2.22.0}/doc/optimizations.rst +0 -0
  176. {pytensor-2.20.0 → pytensor-2.22.0}/doc/pylintrc +0 -0
  177. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/ccodegen.rst +0 -0
  178. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/compilation.rst +0 -0
  179. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/debugging_with_stepmode.rst +0 -0
  180. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/elemwise_compiler.rst +0 -0
  181. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/function.rst +0 -0
  182. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/functional.rst +0 -0
  183. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/how_to_make_ops.rst +0 -0
  184. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/index.rst +0 -0
  185. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/index2.rst +0 -0
  186. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/interactive_debugger.rst +0 -0
  187. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/logistic_regression_example.rst +0 -0
  188. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/performance.rst +0 -0
  189. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/randomnumbers.rst +0 -0
  190. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/rethinkccodegen.rst +0 -0
  191. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/sandbox.rst +0 -0
  192. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/software.rst +0 -0
  193. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/sparse.rst +0 -0
  194. {pytensor-2.20.0 → pytensor-2.22.0}/doc/sandbox/tensoroptools.rst +0 -0
  195. {pytensor-2.20.0 → pytensor-2.22.0}/doc/troubleshooting.rst +0 -0
  196. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/adding.rst +0 -0
  197. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/adding_solution_1.py +0 -0
  198. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/aliasing.rst +0 -0
  199. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/apply.png +0 -0
  200. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/apply.svg +0 -0
  201. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/bcast.png +0 -0
  202. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/broadcasting.rst +0 -0
  203. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/conditions.rst +0 -0
  204. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/debug_faq.rst +0 -0
  205. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/dlogistic.png +0 -0
  206. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/examples.rst +0 -0
  207. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/faq_tutorial.rst +0 -0
  208. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/gradients.rst +0 -0
  209. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/index.rst +0 -0
  210. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/loading_and_saving.rst +0 -0
  211. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/logistic.gp +0 -0
  212. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/logistic.png +0 -0
  213. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/loop.rst +0 -0
  214. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/loop_solution_1.py +0 -0
  215. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/modes.rst +0 -0
  216. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/modes_solution_1.py +0 -0
  217. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/multi_cores.rst +0 -0
  218. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/nan_tutorial.rst +0 -0
  219. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/pics/d3viz.png +0 -0
  220. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
  221. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
  222. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
  223. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/printing_drawing.rst +0 -0
  224. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/profiling.rst +0 -0
  225. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/profiling_example.py +0 -0
  226. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/profiling_example_out.prof +0 -0
  227. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/shape_info.rst +0 -0
  228. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/sparse.rst +0 -0
  229. {pytensor-2.20.0 → pytensor-2.22.0}/doc/tutorial/symbolic_graphs.rst +0 -0
  230. {pytensor-2.20.0 → pytensor-2.22.0}/doc/user_guide.rst +0 -0
  231. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/__init__.py +0 -0
  232. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/bin/__init__.py +0 -0
  233. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/__init__.py +0 -0
  234. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/compiledir.py +0 -0
  235. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/compilelock.py +0 -0
  236. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/debugmode.py +0 -0
  237. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/function/__init__.py +0 -0
  238. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/function/pfunc.py +0 -0
  239. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/function/types.py +0 -0
  240. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/io.py +0 -0
  241. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/monitormode.py +0 -0
  242. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/nanguardmode.py +0 -0
  243. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/profiling.py +0 -0
  244. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/compile/sharedvalue.py +0 -0
  245. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/configparser.py +0 -0
  246. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/d3viz/__init__.py +0 -0
  247. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/d3viz/css/d3-context-menu.css +0 -0
  248. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/d3viz/css/d3viz.css +0 -0
  249. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/d3viz/d3viz.py +0 -0
  250. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/d3viz/formatting.py +0 -0
  251. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/d3viz/js/d3-context-menu.js +0 -0
  252. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/d3viz/js/d3.v3.min.js +0 -0
  253. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/d3viz/js/d3viz.js +0 -0
  254. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
  255. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
  256. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/gradient.py +0 -0
  257. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/__init__.py +0 -0
  258. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/destroyhandler.py +0 -0
  259. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/features.py +0 -0
  260. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/fg.py +0 -0
  261. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/null_type.py +0 -0
  262. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/replace.py +0 -0
  263. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/rewriting/__init__.py +0 -0
  264. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/rewriting/basic.py +0 -0
  265. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/rewriting/db.py +0 -0
  266. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/rewriting/kanren.py +0 -0
  267. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/rewriting/unify.py +0 -0
  268. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/rewriting/utils.py +0 -0
  269. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/type.py +0 -0
  270. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/graph/utils.py +0 -0
  271. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/ifelse.py +0 -0
  272. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/__init__.py +0 -0
  273. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/basic.py +0 -0
  274. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/__init__.py +0 -0
  275. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/basic.py +0 -0
  276. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
  277. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
  278. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/cutils.py +0 -0
  279. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/cvm.py +0 -0
  280. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/exceptions.py +0 -0
  281. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/interface.py +0 -0
  282. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/lazylinker_c.py +0 -0
  283. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/op.py +0 -0
  284. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/c/type.py +0 -0
  285. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/__init__.py +0 -0
  286. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/__init__.py +0 -0
  287. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/basic.py +0 -0
  288. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/blockwise.py +0 -0
  289. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/elemwise.py +0 -0
  290. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
  291. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/nlinalg.py +0 -0
  292. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/scalar.py +0 -0
  293. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/scan.py +0 -0
  294. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/shape.py +0 -0
  295. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/slinalg.py +0 -0
  296. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/sparse.py +0 -0
  297. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/subtensor.py +0 -0
  298. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
  299. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/jax/linker.py +0 -0
  300. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/__init__.py +0 -0
  301. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/__init__.py +0 -0
  302. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/cython_support.py +0 -0
  303. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/elemwise_codegen.py +0 -0
  304. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
  305. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
  306. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/scalar.py +0 -0
  307. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/scan.py +0 -0
  308. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/slinalg.py +0 -0
  309. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/sparse.py +0 -0
  310. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
  311. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/link/vm.py +0 -0
  312. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/misc/__init__.py +0 -0
  313. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/misc/check_blas.py +0 -0
  314. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/misc/check_blas_many.sh +0 -0
  315. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/misc/check_duplicate_key.py +0 -0
  316. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
  317. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/misc/elemwise_time_test.py +0 -0
  318. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/misc/frozendict.py +0 -0
  319. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/misc/may_share_memory.py +0 -0
  320. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/misc/ordered_set.py +0 -0
  321. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/misc/pkl_utils.py +0 -0
  322. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/misc/safe_asarray.py +0 -0
  323. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/printing.py +0 -0
  324. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/py.typed +0 -0
  325. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/raise_op.py +0 -0
  326. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scalar/__init__.py +0 -0
  327. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
  328. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
  329. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scalar/c_code/gamma.c +0 -0
  330. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scalar/loop.py +0 -0
  331. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scalar/math.py +0 -0
  332. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scalar/sharedvar.py +0 -0
  333. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scan/__init__.py +0 -0
  334. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scan/basic.py +0 -0
  335. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scan/op.py +0 -0
  336. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scan/rewriting.py +0 -0
  337. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scan/scan_perform.pyx +0 -0
  338. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scan/scan_perform_ext.py +0 -0
  339. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scan/utils.py +0 -0
  340. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/scan/views.py +0 -0
  341. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/sparse/__init__.py +0 -0
  342. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/sparse/basic.py +0 -0
  343. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/sparse/rewriting.py +0 -0
  344. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/sparse/sandbox/__init__.py +0 -0
  345. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/sparse/sandbox/sp.py +0 -0
  346. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/sparse/sandbox/sp2.py +0 -0
  347. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/sparse/sharedvar.py +0 -0
  348. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/sparse/type.py +0 -0
  349. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/sparse/utils.py +0 -0
  350. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/blas_c.py +0 -0
  351. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/blas_headers.py +0 -0
  352. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/blas_scipy.py +0 -0
  353. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/blockwise.py +0 -0
  354. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
  355. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
  356. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/c_code/dimshuffle.c +0 -0
  357. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/conv/__init__.py +0 -0
  358. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/conv/abstract_conv.py +0 -0
  359. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/elemwise_cgen.py +0 -0
  360. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/exceptions.py +0 -0
  361. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/fourier.py +0 -0
  362. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/functional.py +0 -0
  363. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/inplace.py +0 -0
  364. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/linalg.py +0 -0
  365. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/random/__init__.py +0 -0
  366. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/random/rewriting/__init__.py +0 -0
  367. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/random/rewriting/basic.py +0 -0
  368. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/random/type.py +0 -0
  369. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/random/var.py +0 -0
  370. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/__init__.py +0 -0
  371. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/blas.py +0 -0
  372. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/blas_c.py +0 -0
  373. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/blas_scipy.py +0 -0
  374. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/elemwise.py +0 -0
  375. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/extra_ops.py +0 -0
  376. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/jax.py +0 -0
  377. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/shape.py +0 -0
  378. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/special.py +0 -0
  379. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/subtensor.py +0 -0
  380. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
  381. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/sharedvar.py +0 -0
  382. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/slinalg.py +0 -0
  383. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/special.py +0 -0
  384. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/type.py +0 -0
  385. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/type_other.py +0 -0
  386. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/utils.py +0 -0
  387. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/var.py +0 -0
  388. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/tensor/xlogx.py +0 -0
  389. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/typed_list/__init__.py +0 -0
  390. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/typed_list/basic.py +0 -0
  391. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/typed_list/rewriting.py +0 -0
  392. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/typed_list/type.py +0 -0
  393. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/updates.py +0 -0
  394. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/utils.py +0 -0
  395. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor/version.py +0 -0
  396. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor.egg-info/dependency_links.txt +0 -0
  397. {pytensor-2.20.0 → pytensor-2.22.0}/pytensor.egg-info/entry_points.txt +0 -0
  398. {pytensor-2.20.0 → pytensor-2.22.0}/scripts/mypy-failing.txt +0 -0
  399. {pytensor-2.20.0 → pytensor-2.22.0}/setup.cfg +0 -0
  400. {pytensor-2.20.0 → pytensor-2.22.0}/setup.py +0 -0
  401. {pytensor-2.20.0 → pytensor-2.22.0}/tests/link/c/c_code/test_cenum.h +0 -0
  402. {pytensor-2.20.0 → pytensor-2.22.0}/tests/link/c/c_code/test_quadratic_function.c +0 -0
  403. {pytensor-2.20.0 → pytensor-2.22.0}/tests/tensor/conv/c_code/corr3d_gemm.c +0 -0
  404. {pytensor-2.20.0 → pytensor-2.22.0}/tests/tensor/conv/c_code/corr_gemm.c +0 -0
  405. {pytensor-2.20.0 → pytensor-2.22.0}/tests/test_breakpoint.py +0 -0
  406. {pytensor-2.20.0 → pytensor-2.22.0}/tests/test_config.py +0 -0
  407. {pytensor-2.20.0 → pytensor-2.22.0}/tests/test_gradient.py +0 -0
  408. {pytensor-2.20.0 → pytensor-2.22.0}/tests/test_ifelse.py +0 -0
  409. {pytensor-2.20.0 → pytensor-2.22.0}/tests/test_printing.py +0 -0
  410. {pytensor-2.20.0 → pytensor-2.22.0}/tests/test_raise_op.py +0 -0
  411. {pytensor-2.20.0 → pytensor-2.22.0}/tests/test_rop.py +0 -0
  412. {pytensor-2.20.0 → pytensor-2.22.0}/tests/test_updates.py +0 -0
@@ -8,6 +8,5 @@ global-include *.h
8
8
  global-include *.hh
9
9
  global-include *.sh
10
10
  recursive-include doc *
11
- include bin/pytensor-cache
12
11
  include versioneer.py
13
12
  include pytensor/_version.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytensor
3
- Version: 2.20.0
3
+ Version: 2.22.0
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:
@@ -74,7 +74,7 @@ Description-Content-Type: text/x-rst
74
74
  License-File: LICENSE.txt
75
75
  Requires-Dist: setuptools>=48.0.0
76
76
  Requires-Dist: scipy>=0.14
77
- Requires-Dist: numpy>=1.17.0
77
+ Requires-Dist: numpy<2,>=1.17.0
78
78
  Requires-Dist: filelock
79
79
  Requires-Dist: etuples
80
80
  Requires-Dist: logical-unification
@@ -121,6 +121,32 @@ html_logo = "images/PyTensor_RGB.svg"
121
121
  html_theme = "pymc_sphinx_theme"
122
122
  html_theme_options = {
123
123
  "use_search_override": False,
124
+ "icon_links": [
125
+ {
126
+ "url": "https://github.com/pymc-devs/pytensor/",
127
+ "icon": "fa-brands fa-github",
128
+ "name": "GitHub",
129
+ "type": "fontawesome",
130
+ },
131
+ {
132
+ "url": "https://twitter.com/pymc_devs/",
133
+ "icon": "fa-brands fa-twitter",
134
+ "name": "Twitter",
135
+ "type": "fontawesome",
136
+ },
137
+ {
138
+ "url": "https://www.youtube.com/c/PyMCDevelopers",
139
+ "icon": "fa-brands fa-youtube",
140
+ "name": "YouTube",
141
+ "type": "fontawesome",
142
+ },
143
+ {
144
+ "url": "https://discourse.pymc.io",
145
+ "icon": "fa-brands fa-discourse",
146
+ "name": "Discourse",
147
+ "type": "fontawesome",
148
+ },
149
+ ],
124
150
  }
125
151
  html_context = {
126
152
  "github_user": "pymc-devs",
@@ -190,6 +216,7 @@ html_use_smartypants = True
190
216
  # Output file base name for HTML help builder.
191
217
  htmlhelp_basename = "pytensor_doc"
192
218
 
219
+
193
220
  # Options for the linkcode extension
194
221
  # ----------------------------------
195
222
  # Resolve function
@@ -239,7 +266,13 @@ latex_elements = {
239
266
  # (source start file, target name, title, author, document class
240
267
  # [howto/manual]).
241
268
  latex_documents = [
242
- ("index", "pytensor.tex", "PyTensor Documentation", "PyTensor Developers", "manual"),
269
+ (
270
+ "index",
271
+ "pytensor.tex",
272
+ "PyTensor Documentation",
273
+ "PyTensor Developers",
274
+ "manual",
275
+ ),
243
276
  ]
244
277
 
245
278
  # The name of an image file (relative to this directory) to place at the top of
@@ -168,15 +168,9 @@ create a virtual environment in the project directory:
168
168
 
169
169
  .. code-block:: bash
170
170
 
171
- conda env create -n pytensor-dev -f environment.yml
171
+ conda env create -f environment.yml
172
172
  conda activate pytensor-dev
173
173
 
174
- Afterward, you can install the development dependencies:
175
-
176
- .. code-block:: bash
177
-
178
- pip install -r requirements.txt
179
-
180
174
  Next, ``pre-commit`` needs to be configured so that the linting and code quality
181
175
  checks are performed before each commit:
182
176
 
@@ -202,12 +196,12 @@ see the `NumPy development guide <https://numpy.org/doc/stable/dev/>`_.
202
196
  Contributing to the documentation
203
197
  ---------------------------------
204
198
 
205
- To contribute to the documentation, first follow the instructions in the previous section. Afterward, you can install the documentation dependencies in the virtual environment you created:
206
-
199
+ The documentation build dependencies have also been included in the virtual environment you created. You can also create a separate virtual environment just for the documentation using the `environment.yml` file located inside the `doc` folder.
207
200
 
208
201
  .. code-block:: bash
209
202
 
210
- pip install -r requirements-rtd.txt
203
+ conda env create -f doc/environment.yml
204
+ conda activate pytensor-docs
211
205
 
212
206
 
213
207
  You can now build the documentation from the root of the project with:
@@ -215,7 +209,7 @@ You can now build the documentation from the root of the project with:
215
209
 
216
210
  .. code-block:: bash
217
211
 
218
- python doc/scripts/docgen.py
212
+ python -m sphinx -b html ./doc ./html
219
213
 
220
214
 
221
215
  Afterward, you can go to `html/index.html` and navigate the changes in a browser. One way to do this is to go to the `html` directory and run:
@@ -226,7 +220,7 @@ Afterward, you can go to `html/index.html` and navigate the changes in a browser
226
220
  python -m http.server
227
221
 
228
222
  **Do not commit the `html` directory. The documentation is built automatically.**
229
-
223
+ For more documentation customizations such as different formats e.g., PDF, refer to the `Sphinx documentation <https://www.sphinx-doc.org/en/master/usage/builders/index.html>`_.
230
224
 
231
225
  Other tools that might help
232
226
  ===========================
@@ -12,7 +12,7 @@ dependencies:
12
12
  - sphinx>=5.1.0,<6
13
13
  - mock
14
14
  - pillow
15
+ - pymc-sphinx-theme
15
16
  - pip
16
17
  - pip:
17
- - git+https://github.com/pymc-devs/pymc-sphinx-theme
18
18
  - -e ..
@@ -0,0 +1,285 @@
1
+ Adding JAX and Numba support for `Op`\s
2
+ =======================================
3
+
4
+ PyTensor is able to convert its graphs into JAX and Numba compiled functions. In order to do
5
+ this, each :class:`Op` in an PyTensor graph must have an equivalent JAX/Numba implementation function.
6
+
7
+ This tutorial will explain how JAX and Numba implementations are created for an :class:`Op`. It will
8
+ focus specifically on the JAX case, but the same mechanisms are used for Numba as well.
9
+
10
+ Step 1: Identify the PyTensor :class:`Op` you'd like to implement in JAX
11
+ ------------------------------------------------------------------------
12
+
13
+ Find the source for the PyTensor :class:`Op` you'd like to be supported in JAX, and
14
+ identify the function signature and return values. These can be determined by
15
+ looking at the :meth:`Op.make_node` implementation. In general, one needs to be familiar
16
+ with PyTensor :class:`Op`\s in order to provide a conversion implementation, so first read
17
+ :ref:`creating_an_op` if you are not familiar.
18
+
19
+ For example, you want to extend support for :class:`CumsumOp`\:
20
+
21
+ .. code:: python
22
+
23
+ class CumsumOp(Op):
24
+ __props__ = ("axis",)
25
+
26
+ def __new__(typ, *args, **kwargs):
27
+ obj = object.__new__(CumOp, *args, **kwargs)
28
+ obj.mode = "add"
29
+ return obj
30
+
31
+
32
+ :class:`CumsumOp` turns out to be a variant of :class:`CumOp`\ :class:`Op`
33
+ which currently has an :meth:`Op.make_node` as follows:
34
+
35
+ .. code:: python
36
+
37
+ def make_node(self, x):
38
+ x = ptb.as_tensor_variable(x)
39
+ out_type = x.type()
40
+
41
+ if self.axis is None:
42
+ out_type = vector(dtype=x.dtype) # Flatten
43
+ elif self.axis >= x.ndim or self.axis < -x.ndim:
44
+ raise ValueError(f"axis(={self.axis}) out of bounds")
45
+
46
+ return Apply(self, [x], [out_type])
47
+
48
+ The :class:`Apply` instance that's returned specifies the exact types of inputs that
49
+ our JAX implementation will receive and the exact types of outputs it's expected to
50
+ return--both in terms of their data types and number of dimensions/shapes.
51
+ The actual inputs our implementation will receive are necessarily numeric values
52
+ or NumPy :class:`ndarray`\s; all that :meth:`Op.make_node` tells us is the
53
+ general signature of the underlying computation.
54
+
55
+ More specifically, the :class:`Apply` implies that there is one input that is
56
+ automatically converted to PyTensor variables via :func:`as_tensor_variable`.
57
+ There is another parameter, `axis`, that is used to determine the direction
58
+ of the operation, hence shape of the output. The check that follows imply that
59
+ `axis` must refer to a dimension in the input tensor. The input's elements
60
+ could also have any data type (e.g. floats, ints), so our JAX implementation
61
+ must be able to handle all the possible data types.
62
+
63
+ It also tells us that there's only one return value, that it has a data type
64
+ determined by :meth:`x.type()` i.e., the data type of the original tensor.
65
+ This implies that the result is necessarily a matrix.
66
+
67
+ Some class may have a more complex behavior. For example, the :class:`CumOp`\ :class:`Op`
68
+ also has another variant :class:`CumprodOp`\ :class:`Op` with the exact signature
69
+ as :class:`CumsumOp`\ :class:`Op`. The difference lies in that the `mode` attribute in
70
+ :class:`CumOp` definition:
71
+
72
+ .. code:: python
73
+
74
+ class CumOp(COp):
75
+ # See function cumsum/cumprod for docstring
76
+
77
+ __props__ = ("axis", "mode")
78
+ check_input = False
79
+ params_type = ParamsType(
80
+ c_axis=int_t, mode=EnumList(("MODE_ADD", "add"), ("MODE_MUL", "mul"))
81
+ )
82
+
83
+ def __init__(self, axis: int | None = None, mode="add"):
84
+ if mode not in ("add", "mul"):
85
+ raise ValueError(f'{type(self).__name__}: Unknown mode "{mode}"')
86
+ self.axis = axis
87
+ self.mode = mode
88
+
89
+ c_axis = property(lambda self: np.MAXDIMS if self.axis is None else self.axis)
90
+
91
+ `__props__` is used to parametrize the general behavior of the :class:`Op`. One need to
92
+ pay attention to this to decide whether the JAX implementation should support all variants
93
+ or raise an explicit NotImplementedError for cases that are not supported e.g., when
94
+ :class:`CumsumOp` of :class:`CumOp("add")` is supported but not :class:`CumprodOp` of
95
+ :class:`CumOp("mul")`.
96
+
97
+ Next, we look at the :meth:`Op.perform` implementation to see exactly
98
+ how the inputs and outputs are used to compute the outputs for an :class:`Op`
99
+ in Python. This method is effectively what needs to be implemented in JAX.
100
+
101
+ Step 2: Find the relevant JAX method (or something close)
102
+ ---------------------------------------------------------
103
+
104
+ With a precise idea of what the PyTensor :class:`Op` does we need to figure out how
105
+ to implement it in JAX. In the best case scenario, JAX has a similarly named
106
+ function that performs exactly the same computations as the :class:`Op`. For
107
+ example, the :class:`Eye` operator has a JAX equivalent: :func:`jax.numpy.eye`
108
+ (see `the documentation <https://jax.readthedocs.io/en/latest/_autosummary/jax.numpy.eye.html?highlight=eye>`_).
109
+
110
+ If we wanted to implement an :class:`Op` like :class:`IfElse`, we might need to
111
+ recreate the functionality with some custom logic. In many cases, at least some
112
+ custom logic is needed to reformat the inputs and outputs so that they exactly
113
+ match the `Op`'s.
114
+
115
+ Here's an example for :class:`IfElse`:
116
+
117
+ .. code:: python
118
+
119
+ def ifelse(cond, *args, n_outs=n_outs):
120
+ res = jax.lax.cond(
121
+ cond, lambda _: args[:n_outs], lambda _: args[n_outs:], operand=None
122
+ )
123
+ return res if n_outs > 1 else res[0]
124
+
125
+ In this case, :class:`CumOp` is implemented with NumPy's :func:`numpy.cumsum`
126
+ and :func:`numpy.cumprod`, which have JAX equivalents: :func:`jax.numpy.cumsum`
127
+ and :func:`jax.numpy.cumprod`.
128
+
129
+ .. code:: python
130
+
131
+ def perform(self, node, inputs, output_storage):
132
+ x = inputs[0]
133
+ z = output_storage[0]
134
+ if self.mode == "add":
135
+ z[0] = np.cumsum(x, axis=self.axis)
136
+ else:
137
+ z[0] = np.cumprod(x, axis=self.axis)
138
+
139
+ Step 3: Register the function with the `jax_funcify` dispatcher
140
+ ---------------------------------------------------------------
141
+
142
+ With the PyTensor `Op` replicated in JAX, we'll need to register the
143
+ function with the PyTensor JAX `Linker`. This is done through the use of
144
+ `singledispatch`. If you don't know how `singledispatch` works, see the
145
+ `Python documentation <https://docs.python.org/3/library/functools.html#functools.singledispatch>`_.
146
+
147
+ The relevant dispatch functions created by `singledispatch` are :func:`pytensor.link.numba.dispatch.numba_funcify` and
148
+ :func:`pytensor.link.jax.dispatch.jax_funcify`.
149
+
150
+ Here's an example for the `CumOp`\ `Op`:
151
+
152
+ .. code:: python
153
+
154
+ import jax.numpy as jnp
155
+
156
+ from pytensor.tensor.extra_ops import CumOp
157
+ from pytensor.link.jax.dispatch import jax_funcify
158
+
159
+
160
+ @jax_funcify.register(CumOp)
161
+ def jax_funcify_CumOp(op, **kwargs):
162
+ axis = op.axis
163
+ mode = op.mode
164
+
165
+ def cumop(x, axis=axis, mode=mode):
166
+ if mode == "add":
167
+ return jnp.cumsum(x, axis=axis)
168
+ else:
169
+ return jnp.cumprod(x, axis=axis)
170
+
171
+ return cumop
172
+
173
+ Suppose `jnp.cumprod` does not exist, we will need to register the function as follows:
174
+
175
+ .. code:: python
176
+
177
+ import jax.numpy as jnp
178
+
179
+ from pytensor.tensor.extra_ops import CumOp
180
+ from pytensor.link.jax.dispatch import jax_funcify
181
+
182
+
183
+ @jax_funcify.register(CumOp)
184
+ def jax_funcify_CumOp(op, **kwargs):
185
+ axis = op.axis
186
+ mode = op.mode
187
+
188
+ def cumop(x, axis=axis, mode=mode):
189
+ if mode == "add":
190
+ return jnp.cumsum(x, axis=axis)
191
+ else:
192
+ raise NotImplementedError("JAX does not support cumprod function at the moment.")
193
+
194
+ return cumop
195
+
196
+ Step 4: Write tests
197
+ -------------------
198
+
199
+ Test that your registered `Op` is working correctly by adding tests to the
200
+ appropriate test suites in PyTensor (e.g. in ``tests.link.jax`` and one of
201
+ the modules in ``tests.link.numba``). The tests should ensure that your implementation can
202
+ handle the appropriate types of inputs and produce outputs equivalent to `Op.perform`.
203
+ Check the existing tests for the general outline of these kinds of tests. In
204
+ most cases, a helper function can be used to easily verify the correspondence
205
+ between a JAX/Numba implementation and its `Op`.
206
+
207
+ For example, the :func:`compare_jax_and_py` function streamlines the steps
208
+ involved in making comparisons with `Op.perform`.
209
+
210
+ Here's a small example of a test for :class:`CumOp` above:
211
+
212
+ .. code:: python
213
+
214
+ import numpy as np
215
+ import pytensor.tensor as pt
216
+ from pytensor.configdefaults import config
217
+ from tests.link.jax.test_basic import compare_jax_and_py
218
+ from pytensor.graph import FunctionGraph
219
+ from pytensor.graph.op import get_test_value
220
+
221
+ def test_jax_CumOp():
222
+ """Test JAX conversion of the `CumOp` `Op`."""
223
+
224
+ # Create a symbolic input for the first input of `CumOp`
225
+ a = pt.matrix("a")
226
+
227
+ # Create test value tag for a
228
+ a.tag.test_value = np.arange(9, dtype=config.floatX).reshape((3, 3))
229
+
230
+ # Create the output variable
231
+ out = pt.cumsum(a, axis=0)
232
+
233
+ # Create a PyTensor `FunctionGraph`
234
+ fgraph = FunctionGraph([a], [out])
235
+
236
+ # Pass the graph and inputs to the testing function
237
+ compare_jax_and_py(fgraph, [get_test_value(i) for i in fgraph.inputs])
238
+
239
+ # For the second mode of CumOp
240
+ out = pt.cumprod(a, axis=1)
241
+ fgraph = FunctionGraph([a], [out])
242
+ compare_jax_and_py(fgraph, [get_test_value(i) for i in fgraph.inputs])
243
+
244
+ If the variant :class:`CumprodOp` is not implemented, we can add a test for it as follows:
245
+
246
+ .. code:: python
247
+
248
+ import pytest
249
+
250
+ def test_jax_CumOp():
251
+ """Test JAX conversion of the `CumOp` `Op`."""
252
+ a = pt.matrix("a")
253
+ a.tag.test_value = np.arange(9, dtype=config.floatX).reshape((3, 3))
254
+
255
+ with pytest.raises(NotImplementedError):
256
+ out = pt.cumprod(a, axis=1)
257
+ fgraph = FunctionGraph([a], [out])
258
+ compare_jax_and_py(fgraph, [get_test_value(i) for i in fgraph.inputs])
259
+
260
+ Note
261
+ ----
262
+ In out previous example of extending JAX, :class:`Eye`\ :class:`Op` was used with the test function as follows:
263
+
264
+ .. code:: python
265
+ def test_jax_Eye():
266
+ """Test JAX conversion of the `Eye` `Op`."""
267
+
268
+ # Create a symbolic input for `Eye`
269
+ x_at = pt.scalar()
270
+
271
+ # Create a variable that is the output of an `Eye` `Op`
272
+ eye_var = pt.eye(x_at)
273
+
274
+ # Create an PyTensor `FunctionGraph`
275
+ out_fg = FunctionGraph(outputs=[eye_var])
276
+
277
+ # Pass the graph and any inputs to the testing function
278
+ compare_jax_and_py(out_fg, [3])
279
+
280
+ This one nowadays leads to a test failure due to new restrictions in JAX + JIT,
281
+ as reported in issue `#654 <https://github.com/pymc-devs/pytensor/issues/654>`_.
282
+ All jitted functions now must have constant shape, which means a graph like the
283
+ one of :class:`Eye` can never be translated to JAX, since it's fundamentally a
284
+ function with dynamic shapes. In other words, only PyTensor graphs with static shapes
285
+ can be translated to JAX at the moment.
@@ -88,7 +88,7 @@ case if ``borrow`` was True, the thunk would be allowed to reuse--or
88
88
  The compile cache is based upon the C++ code of the graph to be compiled.
89
89
  So, if you change compilation configuration variables, such as
90
90
  :attr:`config.blas__ldflags`, you will need to manually remove your compile cache,
91
- using ``PyTensor/bin/pytensor-cache clear``
91
+ using ``pytensor-cache clear``
92
92
 
93
93
  PyTensor also implements a lock mechanism that prevents multiple compilations
94
94
  within the same compilation directory (to avoid crashes with parallel
@@ -48,7 +48,7 @@ keywords = [
48
48
  dependencies = [
49
49
  "setuptools>=48.0.0",
50
50
  "scipy>=0.14",
51
- "numpy>=1.17.0",
51
+ "numpy>=1.17.0,<2",
52
52
  "filelock",
53
53
  "etuples",
54
54
  "logical-unification",
@@ -82,7 +82,7 @@ jax = ["jax", "jaxlib"]
82
82
  numba = ["numba>=0.57"]
83
83
 
84
84
  [tool.setuptools.packages.find]
85
- include = ["pytensor*", "bin"]
85
+ include = ["pytensor*"]
86
86
 
87
87
  [tool.setuptools.package-data]
88
88
  pytensor = ["py.typed"]
@@ -122,7 +122,7 @@ testpaths = "tests/"
122
122
 
123
123
  [tool.ruff]
124
124
  line-length = 88
125
- exclude = ["doc/", "pytensor/_version.py", "bin/pytensor_cache.py"]
125
+ exclude = ["doc/", "pytensor/_version.py"]
126
126
 
127
127
  [tool.ruff.lint]
128
128
  select = ["C", "E", "F", "I", "UP", "W", "RUF"]
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-03-28T18:19:27+0100",
11
+ "date": "2024-05-22T14:12:17+0200",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "ef22377d7e6ea6c74c36a8dc634ef7f1f1f8f9c6",
15
- "version": "2.20.0"
14
+ "full-revisionid": "bb028ae2330433755b9d4aa32ab6e8d0c9f662fc",
15
+ "version": "2.22.0"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -75,9 +75,9 @@ def main():
75
75
  if items:
76
76
  _logger.warning(
77
77
  "There remain elements in the cache dir that you may "
78
- "need to erase manually. The cache dir is:\n %s\n"
78
+ f"need to erase manually. The cache dir is:\n {config.compiledir}\n"
79
79
  'You can also call "pytensor-cache purge" to '
80
- "remove everything from that directory." % config.compiledir
80
+ "remove everything from that directory."
81
81
  )
82
82
  _logger.debug(f"Remaining elements ({len(items)}): {', '.join(items)}")
83
83
  elif sys.argv[1] == "list":
@@ -105,7 +105,7 @@ class PdbBreakpoint(Op):
105
105
  except Exception:
106
106
  raise ValueError(
107
107
  "Some of the inputs to the PdbBreakpoint op "
108
- "'%s' could not be casted to NumPy arrays" % self.name
108
+ f"'{self.name}' could not be casted to NumPy arrays"
109
109
  )
110
110
 
111
111
  print("\n")
@@ -7,7 +7,7 @@ from functools import partial
7
7
  from typing import cast
8
8
 
9
9
  import pytensor.tensor as pt
10
- from pytensor import function
10
+ from pytensor.compile.function import function
11
11
  from pytensor.compile.function.pfunc import rebuild_collect_shared
12
12
  from pytensor.compile.mode import optdb
13
13
  from pytensor.compile.sharedvalue import SharedVariable
@@ -400,6 +400,15 @@ class OpFromGraph(Op, HasInnerGraph):
400
400
  Check :func:`pytensor.function` for more arguments, only works when not
401
401
  inline.
402
402
  """
403
+ ignore_unused_inputs = kwargs.get("on_unused_input", False) == "ignore"
404
+ if not ignore_unused_inputs and len(inputs) != len(set(inputs)):
405
+ var_counts = {var: inputs.count(var) for var in inputs}
406
+ duplicated_inputs = [var for var, count in var_counts.items() if count > 1]
407
+ raise ValueError(
408
+ f"There following variables were provided more than once as inputs to the OpFromGraph, resulting in an "
409
+ f"invalid graph: {duplicated_inputs}. Use dummy variables or var.copy() to distinguish "
410
+ f"variables when creating the OpFromGraph graph."
411
+ )
403
412
 
404
413
  if not (isinstance(inputs, list) and isinstance(outputs, list)):
405
414
  raise TypeError("Inputs and outputs must be lists")
@@ -700,7 +709,7 @@ class OpFromGraph(Op, HasInnerGraph):
700
709
  if not isinstance(roverrides_l, list):
701
710
  raise TypeError(
702
711
  "Rop overriding function should return a list, "
703
- 'got "%s"' % type(roverrides_l)
712
+ f'got "{type(roverrides_l)}"'
704
713
  )
705
714
  all_rops_l, all_rops_ov_l = zip(
706
715
  *[
@@ -452,13 +452,11 @@ JAX = Mode(
452
452
  JAXLinker(),
453
453
  RewriteDatabaseQuery(
454
454
  include=["fast_run", "jax"],
455
- # TODO: "local_uint_constant_indices" can be reintroduced once https://github.com/google/jax/issues/16836 is fixed.
456
455
  exclude=[
457
456
  "cxx_only",
458
457
  "BlasOpt",
459
458
  "fusion",
460
459
  "inplace",
461
- "local_uint_constant_indices",
462
460
  ],
463
461
  ),
464
462
  )
@@ -252,7 +252,7 @@ class FromFunctionOp(Op):
252
252
  return hash(type(self)) ^ hash(self.__fn)
253
253
 
254
254
  def __str__(self):
255
- return "FromFunctionOp{%s}" % self.__fn.__name__
255
+ return f"FromFunctionOp{{{self.__fn.__name__}}}"
256
256
 
257
257
  def perform(self, node, inputs, outputs):
258
258
  outs = self.__fn(*inputs)
@@ -1437,12 +1437,16 @@ add_vm_configvars()
1437
1437
  add_numba_configvars()
1438
1438
 
1439
1439
  # TODO: `gcc_version_str` is used by other modules.. Should it become an immutable config var?
1440
- try:
1441
- p_out = output_subprocess_Popen([config.cxx, "-dumpversion"])
1442
- gcc_version_str = p_out[0].strip().decode()
1443
- except OSError:
1444
- # Typically means gcc cannot be found.
1440
+ if config.cxx != "":
1441
+ try:
1442
+ p_out = output_subprocess_Popen([config.cxx, "-dumpversion"])
1443
+ gcc_version_str = p_out[0].strip().decode()
1444
+ except OSError:
1445
+ # Typically means gcc cannot be found.
1446
+ gcc_version_str = "GCC_NOT_FOUND"
1447
+ else:
1445
1448
  gcc_version_str = "GCC_NOT_FOUND"
1449
+
1446
1450
  # TODO: The caching dir resolution is a procedural mess of helper functions, local variables
1447
1451
  # and config definitions. And the result is also not particularly pretty..
1448
1452
  add_caching_dir_configvars()