pytensor 2.18.0__tar.gz → 2.18.2__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.
- {pytensor-2.18.0 → pytensor-2.18.2}/PKG-INFO +1 -1
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/using_params.rst +17 -21
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/_version.py +3 -3
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/function/types.py +10 -4
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/profiling.py +4 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/basic.py +5 -12
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/op.py +9 -56
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/replace.py +14 -13
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/basic.py +11 -2
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/cmodule.py +39 -12
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/interface.py +24 -1
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/op.py +2 -2
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/nlinalg.py +1 -3
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/basic.py +7 -16
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/raise_op.py +1 -1
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scan/op.py +1 -1
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scan/rewriting.py +42 -11
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/basic.py +84 -16
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/blas.py +81 -152
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/blockwise.py +33 -9
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/elemwise.py +1 -1
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/extra_ops.py +7 -3
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/math.py +19 -5
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/basic.py +12 -11
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/blas.py +33 -8
- pytensor-2.18.2/pytensor/tensor/rewriting/blockwise.py +201 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/linalg.py +10 -3
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/math.py +92 -160
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/shape.py +16 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/subtensor.py +109 -26
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/uncanonicalize.py +1 -1
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/shape.py +36 -20
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/subtensor.py +18 -1
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor.egg-info/PKG-INFO +1 -1
- {pytensor-2.18.0 → pytensor-2.18.2}/scripts/mypy-failing.txt +0 -1
- {pytensor-2.18.0 → pytensor-2.18.2}/tests/test_printing.py +17 -14
- pytensor-2.18.0/pytensor/tensor/rewriting/blockwise.py +0 -51
- {pytensor-2.18.0 → pytensor-2.18.2}/LICENSE.txt +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/MANIFEST.in +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/README.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/bin/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/bin/pytensor-cache +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/bin/pytensor_cache.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/.templates/PLACEHOLDER +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/.templates/layout.html +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/LICENSE.txt +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/README.md +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/acknowledgement.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/bcast.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/bcast.svg +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/conf.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/core_development_guide.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/css.inc +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/dev_start_guide.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/environment.yml +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/apply.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/apply.svg +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/apply2.svg +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/creating_a_c_op.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/creating_a_numba_jax_op.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/creating_an_op.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/ctype.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/extending_faq.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/extending_pytensor_solution_1.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/graph_rewriting.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/graphstructures.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/inplace.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/op.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/other_ops.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/pics/symbolic_graph_opt.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/pipeline.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/scan.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/tips.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/type.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/extending/unittest.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/faq.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/generate_dtype_tensor_table.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/glossary.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/images/Elman_srnn.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/images/PyTensor_RGB.svg +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/images/blocksparse.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/images/lstm.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/images/lstm_memorycell.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/images/talk2010.gif +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/images/talk2010.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/install.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/internal/how_to_release.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/internal/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/internal/metadocumentation.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/introduction.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/compile/debugmode.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/compile/function.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/compile/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/compile/io.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/compile/mode.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/compile/nanguardmode.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/compile/opfromgraph.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/compile/ops.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/compile/profilemode.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/compile/shared.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/config.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/mlp.html +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/mlp.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/mlp2.html +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/mlp2.pdf +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/mlp2.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/ofg.html +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/examples/ofg2.html +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/index.ipynb +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/index_files/index_10_0.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/index_files/index_11_0.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/index_files/index_24_0.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/d3viz/index_files/index_25_0.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/gradient.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/graph/features.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/graph/fgraph.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/graph/graph.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/graph/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/graph/op.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/graph/type.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/graph/utils.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/misc/pkl_utils.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/printing.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/sandbox/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/sandbox/linalg.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/scalar/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/scan.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/sparse/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/sparse/sandbox.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/basic.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/basic_opt.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/bcast.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/bcast.svg +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/conv.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/elemwise.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/extra_ops.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/fft.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/io.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/math_opt.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/nlinalg.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/plot_fft.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/random/basic.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/random/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/random/utils.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/slinalg.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/tensor/utils.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/library/typed_list.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/links.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/optimizations.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/pylintrc +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/ccodegen.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/compilation.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/debugging_with_stepmode.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/elemwise_compiler.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/function.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/functional.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/how_to_make_ops.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/index2.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/interactive_debugger.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/logistic_regression_example.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/performance.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/randomnumbers.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/rethinkccodegen.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/sandbox.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/software.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/sparse.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/sandbox/tensoroptools.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/scripts/docgen.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/troubleshooting.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/adding.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/adding_solution_1.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/aliasing.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/apply.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/apply.svg +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/bcast.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/broadcasting.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/conditions.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/debug_faq.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/dlogistic.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/examples.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/faq_tutorial.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/gradients.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/index.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/loading_and_saving.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/logistic.gp +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/logistic.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/loop.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/loop_solution_1.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/modes.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/modes_solution_1.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/multi_cores.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/nan_tutorial.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/pics/d3viz.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/printing_drawing.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/profiling.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/profiling_example.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/profiling_example_out.prof +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/shape_info.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/sparse.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/tutorial/symbolic_graphs.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/doc/user_guide.rst +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pyproject.toml +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/bin/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/bin/pytensor_cache.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/breakpoint.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/builders.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/compiledir.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/compilelock.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/debugmode.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/function/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/function/pfunc.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/io.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/mode.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/monitormode.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/nanguardmode.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/ops.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/compile/sharedvalue.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/configdefaults.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/configparser.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/d3viz/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/d3viz/css/d3-context-menu.css +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/d3viz/css/d3viz.css +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/d3viz/d3viz.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/d3viz/formatting.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/d3viz/js/d3-context-menu.js +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/d3viz/js/d3.v3.min.js +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/d3viz/js/d3viz.js +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/gradient.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/destroyhandler.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/features.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/fg.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/null_type.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/rewriting/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/rewriting/basic.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/rewriting/db.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/rewriting/kanren.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/rewriting/unify.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/rewriting/utils.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/type.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/graph/utils.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/ifelse.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/basic.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/cutils.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/cvm.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/exceptions.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/lazylinker_c.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/params_type.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/c/type.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/basic.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/blockwise.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/elemwise.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/random.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/scalar.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/scan.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/shape.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/slinalg.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/sparse.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/subtensor.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/jax/linker.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/cython_support.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/elemwise.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/elemwise_codegen.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/random.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/scalar.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/scan.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/slinalg.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/sparse.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/numba/linker.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/utils.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/link/vm.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/misc/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/misc/check_blas.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/misc/check_blas_many.sh +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/misc/check_duplicate_key.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/misc/elemwise_time_test.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/misc/frozendict.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/misc/may_share_memory.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/misc/ordered_set.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/misc/pkl_utils.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/misc/safe_asarray.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/printing.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/py.typed +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scalar/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scalar/basic.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scalar/c_code/gamma.c +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scalar/loop.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scalar/math.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scalar/sharedvar.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scan/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scan/basic.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scan/checkpoints.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scan/scan_perform.pyx +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scan/scan_perform_ext.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scan/utils.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/scan/views.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/sparse/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/sparse/basic.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/sparse/rewriting.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/sparse/sandbox/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/sparse/sandbox/sp.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/sparse/sandbox/sp2.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/sparse/sharedvar.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/sparse/type.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/sparse/utils.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/blas_c.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/blas_headers.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/blas_scipy.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/c_code/dimshuffle.c +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/conv/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/conv/abstract_conv.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/elemwise_cgen.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/exceptions.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/fft.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/fourier.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/functional.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/inplace.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/io.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/linalg.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/nlinalg.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/random/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/random/basic.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/random/op.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/random/rewriting/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/random/rewriting/basic.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/random/rewriting/jax.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/random/type.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/random/utils.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/random/var.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/blas_c.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/blas_scipy.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/elemwise.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/extra_ops.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/jax.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/rewriting/special.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/sharedvar.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/slinalg.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/sort.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/special.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/type.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/type_other.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/utils.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/var.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/variable.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/tensor/xlogx.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/typed_list/__init__.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/typed_list/basic.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/typed_list/rewriting.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/typed_list/type.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/updates.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/utils.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor/version.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor.egg-info/SOURCES.txt +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor.egg-info/dependency_links.txt +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor.egg-info/entry_points.txt +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor.egg-info/requires.txt +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/pytensor.egg-info/top_level.txt +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/scripts/downstream_pr.sh +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/scripts/upstream_pr.sh +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/setup.cfg +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/setup.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/tests/link/c/c_code/test_cenum.h +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/tests/link/c/c_code/test_quadratic_function.c +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/tests/tensor/conv/c_code/corr3d_gemm.c +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/tests/tensor/conv/c_code/corr_gemm.c +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/tests/test_breakpoint.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/tests/test_config.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/tests/test_gradient.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/tests/test_ifelse.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/tests/test_raise_op.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/tests/test_rop.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/tests/test_updates.py +0 -0
- {pytensor-2.18.0 → pytensor-2.18.2}/versioneer.py +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
.. _extending_op_params:
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Using
|
|
5
|
-
|
|
3
|
+
================
|
|
4
|
+
Using COp params
|
|
5
|
+
================
|
|
6
6
|
|
|
7
|
-
The
|
|
7
|
+
The COp params is a facility to pass some runtime parameters to the
|
|
8
8
|
code of an op without modifying it. It can enable a single instance
|
|
9
9
|
of C code to serve different needs and therefore reduce compilation.
|
|
10
10
|
|
|
@@ -53,7 +53,7 @@ following methods will be used for the type:
|
|
|
53
53
|
- :meth:`__hash__ <Type.__hash__>`
|
|
54
54
|
- :meth:`values_eq <Type.values_eq>`
|
|
55
55
|
|
|
56
|
-
Additionally
|
|
56
|
+
Additionally, to use your params with C code, you need to extend `COp`
|
|
57
57
|
and implement the following methods:
|
|
58
58
|
|
|
59
59
|
- :meth:`c_declare <CLinkerType.c_declare>`
|
|
@@ -65,24 +65,24 @@ You can also define other convenience methods such as
|
|
|
65
65
|
:meth:`c_headers <CLinkerType.c_headers>` if you need any special things.
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
Registering the params with your
|
|
69
|
-
|
|
68
|
+
Registering the params with your COp
|
|
69
|
+
------------------------------------
|
|
70
70
|
|
|
71
|
-
To declare that your
|
|
71
|
+
To declare that your `COp` uses params you have to set the class
|
|
72
72
|
attribute :attr:`params_type` to an instance of your params Type.
|
|
73
73
|
|
|
74
74
|
.. note::
|
|
75
75
|
|
|
76
76
|
If you want to have multiple parameters, PyTensor provides the convenient class
|
|
77
77
|
:class:`pytensor.link.c.params_type.ParamsType` that allows to bundle many parameters into
|
|
78
|
-
one object that will be available
|
|
78
|
+
one object that will be available to the C code (as a struct).
|
|
79
79
|
|
|
80
80
|
For example if we decide to use an int as the params the following
|
|
81
81
|
would be appropriate:
|
|
82
82
|
|
|
83
83
|
.. code-block:: python
|
|
84
84
|
|
|
85
|
-
class MyOp(
|
|
85
|
+
class MyOp(COp):
|
|
86
86
|
params_type = Generic()
|
|
87
87
|
|
|
88
88
|
After that you need to define a :meth:`get_params` method on your
|
|
@@ -115,12 +115,7 @@ Having declared a params for your Op will affect the expected
|
|
|
115
115
|
signature of :meth:`perform`. The new expected signature will have an
|
|
116
116
|
extra parameter at the end which corresponds to the params object.
|
|
117
117
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
If you do not account for this extra parameter, the code will fail
|
|
121
|
-
at runtime if it tries to run the python version.
|
|
122
|
-
|
|
123
|
-
Also, for the C code, the `sub` dictionary will contain an extra entry
|
|
118
|
+
The `sub` dictionary for `COp`s with params will contain an extra entry
|
|
124
119
|
`'params'` which will map to the variable name of the params object.
|
|
125
120
|
This is true for all methods that receive a `sub` parameter, so this
|
|
126
121
|
means that you can use your params in the :meth:`c_code <COp.c_code>`
|
|
@@ -131,7 +126,7 @@ A simple example
|
|
|
131
126
|
----------------
|
|
132
127
|
|
|
133
128
|
This is a simple example which uses a params object to pass a value.
|
|
134
|
-
This `
|
|
129
|
+
This `COp` will multiply a scalar input by a fixed floating point value.
|
|
135
130
|
|
|
136
131
|
Since the value in this case is a python float, we chose Generic as
|
|
137
132
|
the params type.
|
|
@@ -156,9 +151,10 @@ the params type.
|
|
|
156
151
|
inp = as_scalar(inp)
|
|
157
152
|
return Apply(self, [inp], [inp.type()])
|
|
158
153
|
|
|
159
|
-
def perform(self, node, inputs, output_storage
|
|
160
|
-
#
|
|
161
|
-
|
|
154
|
+
def perform(self, node, inputs, output_storage):
|
|
155
|
+
# Because params is a python float we can use `self.mul` directly.
|
|
156
|
+
# If it's something fancier, call `self.params_type.filter(self.get_params(node))`
|
|
157
|
+
output_storage[0][0] = inputs[0] * self.mul
|
|
162
158
|
|
|
163
159
|
def c_code(self, node, name, inputs, outputs, sub):
|
|
164
160
|
return ("%(z)s = %(x)s * PyFloat_AsDouble(%(p)s);" %
|
|
@@ -174,7 +170,7 @@ weights.
|
|
|
174
170
|
|
|
175
171
|
.. testcode::
|
|
176
172
|
|
|
177
|
-
from pytensor.
|
|
173
|
+
from pytensor.link.c.op import COp
|
|
178
174
|
from pytensor.link.c.type import Generic
|
|
179
175
|
from pytensor.scalar import as_scalar
|
|
180
176
|
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2023-
|
|
11
|
+
"date": "2023-12-10T11:56:35+0000",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "2.18.
|
|
14
|
+
"full-revisionid": "68b41a480bc9fed69db7331f60543e94241adbd5",
|
|
15
|
+
"version": "2.18.2"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -1474,7 +1474,7 @@ class FunctionMaker:
|
|
|
1474
1474
|
if getattr(mode, "profile", None):
|
|
1475
1475
|
raise TypeError("profile passed via 'mode'. This isn't supported anymore")
|
|
1476
1476
|
self.profile = profile
|
|
1477
|
-
if profile:
|
|
1477
|
+
if profile and config.cxx:
|
|
1478
1478
|
# This is very important:
|
|
1479
1479
|
# 1) We preload the cache here to not have its timing
|
|
1480
1480
|
# included with the rewrites.
|
|
@@ -1482,7 +1482,12 @@ class FunctionMaker:
|
|
|
1482
1482
|
# too much execution time during testing as we compile
|
|
1483
1483
|
# much more functions then the number of compile c
|
|
1484
1484
|
# module.
|
|
1485
|
+
start_get_cache = time.perf_counter()
|
|
1485
1486
|
pytensor.link.c.basic.get_module_cache().refresh()
|
|
1487
|
+
get_cache_time = time.perf_counter() - start_get_cache
|
|
1488
|
+
self.profile.linker_time += get_cache_time
|
|
1489
|
+
self.profile.preload_cache_time += get_cache_time
|
|
1490
|
+
|
|
1486
1491
|
# Handle the case where inputs and/or outputs is a single
|
|
1487
1492
|
# Variable (not in a list)
|
|
1488
1493
|
unpack_single = False
|
|
@@ -1722,7 +1727,8 @@ def orig_function(
|
|
|
1722
1727
|
|
|
1723
1728
|
"""
|
|
1724
1729
|
|
|
1725
|
-
|
|
1730
|
+
if profile:
|
|
1731
|
+
t1 = time.perf_counter()
|
|
1726
1732
|
mode = pytensor.compile.mode.get_mode(mode)
|
|
1727
1733
|
|
|
1728
1734
|
inputs = list(map(convert_function_input, inputs))
|
|
@@ -1755,8 +1761,8 @@ def orig_function(
|
|
|
1755
1761
|
with config.change_flags(compute_test_value="off"):
|
|
1756
1762
|
fn = m.create(defaults)
|
|
1757
1763
|
finally:
|
|
1758
|
-
|
|
1759
|
-
|
|
1764
|
+
if profile and fn:
|
|
1765
|
+
t2 = time.perf_counter()
|
|
1760
1766
|
profile.compile_time += t2 - t1
|
|
1761
1767
|
# TODO: append
|
|
1762
1768
|
profile.nb_nodes = len(fn.maker.fgraph.apply_nodes)
|
|
@@ -269,6 +269,9 @@ class ProfileStats:
|
|
|
269
269
|
linker_time: float = 0.0
|
|
270
270
|
# time spent linking graph (FunctionMaker.create)
|
|
271
271
|
|
|
272
|
+
preload_cache_time: float = 0.0
|
|
273
|
+
# time spent preloading the cache, so it does not affect rewrites profiling
|
|
274
|
+
|
|
272
275
|
import_time: float = 0.0
|
|
273
276
|
# time spent in importing compiled python module.
|
|
274
277
|
|
|
@@ -811,6 +814,7 @@ class ProfileStats:
|
|
|
811
814
|
),
|
|
812
815
|
file=file,
|
|
813
816
|
)
|
|
817
|
+
print(f" C-cache preloading {self.preload_cache_time:e}s", file=file)
|
|
814
818
|
print(f" Import time {self.import_time:e}s", file=file)
|
|
815
819
|
print(
|
|
816
820
|
f" Node make_thunk time {self.linker_node_make_thunks:e}s", file=file
|
|
@@ -30,7 +30,6 @@ import numpy as np
|
|
|
30
30
|
from pytensor.configdefaults import config
|
|
31
31
|
from pytensor.graph.utils import (
|
|
32
32
|
MetaObject,
|
|
33
|
-
MethodNotDefined,
|
|
34
33
|
Scratchpad,
|
|
35
34
|
TestValueError,
|
|
36
35
|
ValidatingScratchpad,
|
|
@@ -151,16 +150,6 @@ class Apply(Node, Generic[OpType]):
|
|
|
151
150
|
f"The 'outputs' argument to Apply must contain Variable instances with no owner, not {output}"
|
|
152
151
|
)
|
|
153
152
|
|
|
154
|
-
def run_params(self):
|
|
155
|
-
"""
|
|
156
|
-
Returns the params for the node, or NoParams if no params is set.
|
|
157
|
-
|
|
158
|
-
"""
|
|
159
|
-
try:
|
|
160
|
-
return self.op.get_params(self)
|
|
161
|
-
except MethodNotDefined:
|
|
162
|
-
return NoParams
|
|
163
|
-
|
|
164
153
|
def __getstate__(self):
|
|
165
154
|
d = self.__dict__
|
|
166
155
|
# ufunc don't pickle/unpickle well
|
|
@@ -1788,6 +1777,7 @@ def equal_computations(
|
|
|
1788
1777
|
ys: list[Union[np.ndarray, Variable]],
|
|
1789
1778
|
in_xs: Optional[list[Variable]] = None,
|
|
1790
1779
|
in_ys: Optional[list[Variable]] = None,
|
|
1780
|
+
strict_dtype=True,
|
|
1791
1781
|
) -> bool:
|
|
1792
1782
|
"""Checks if PyTensor graphs represent the same computations.
|
|
1793
1783
|
|
|
@@ -1919,7 +1909,10 @@ def equal_computations(
|
|
|
1919
1909
|
if dx != dy:
|
|
1920
1910
|
if isinstance(dx, Constant) and isinstance(dy, Constant):
|
|
1921
1911
|
if not dx.equals(dy):
|
|
1922
|
-
|
|
1912
|
+
if strict_dtype:
|
|
1913
|
+
return False
|
|
1914
|
+
elif not np.array_equal(dx.data, dy.data):
|
|
1915
|
+
return False
|
|
1923
1916
|
else:
|
|
1924
1917
|
return False
|
|
1925
1918
|
|
|
@@ -16,15 +16,13 @@ from typing import (
|
|
|
16
16
|
|
|
17
17
|
import pytensor
|
|
18
18
|
from pytensor.configdefaults import config
|
|
19
|
-
from pytensor.graph.basic import Apply,
|
|
19
|
+
from pytensor.graph.basic import Apply, Variable
|
|
20
20
|
from pytensor.graph.utils import (
|
|
21
21
|
MetaObject,
|
|
22
|
-
MethodNotDefined,
|
|
23
22
|
TestValueError,
|
|
24
23
|
add_tag_trace,
|
|
25
24
|
get_variable_trace_string,
|
|
26
25
|
)
|
|
27
|
-
from pytensor.link.c.params_type import Params, ParamsType
|
|
28
26
|
|
|
29
27
|
|
|
30
28
|
if TYPE_CHECKING:
|
|
@@ -37,10 +35,7 @@ StorageMapType = dict[Variable, StorageCellType]
|
|
|
37
35
|
ComputeMapType = dict[Variable, list[bool]]
|
|
38
36
|
InputStorageType = list[StorageCellType]
|
|
39
37
|
OutputStorageType = list[StorageCellType]
|
|
40
|
-
|
|
41
|
-
PerformMethodType = Callable[
|
|
42
|
-
[Apply, list[Any], OutputStorageType, ParamsInputType], None
|
|
43
|
-
]
|
|
38
|
+
PerformMethodType = Callable[[Apply, list[Any], OutputStorageType], None]
|
|
44
39
|
BasicThunkType = Callable[[], None]
|
|
45
40
|
ThunkCallableType = Callable[
|
|
46
41
|
[PerformMethodType, StorageMapType, ComputeMapType, Apply], None
|
|
@@ -202,7 +197,6 @@ class Op(MetaObject):
|
|
|
202
197
|
|
|
203
198
|
itypes: Optional[Sequence["Type"]] = None
|
|
204
199
|
otypes: Optional[Sequence["Type"]] = None
|
|
205
|
-
params_type: Optional[ParamsType] = None
|
|
206
200
|
|
|
207
201
|
_output_type_depends_on_input_value = False
|
|
208
202
|
"""
|
|
@@ -426,7 +420,6 @@ class Op(MetaObject):
|
|
|
426
420
|
node: Apply,
|
|
427
421
|
inputs: Sequence[Any],
|
|
428
422
|
output_storage: OutputStorageType,
|
|
429
|
-
params: ParamsInputType = None,
|
|
430
423
|
) -> None:
|
|
431
424
|
"""Calculate the function on the inputs and put the variables in the output storage.
|
|
432
425
|
|
|
@@ -442,8 +435,6 @@ class Op(MetaObject):
|
|
|
442
435
|
these lists). Each sub-list corresponds to value of each
|
|
443
436
|
`Variable` in :attr:`node.outputs`. The primary purpose of this method
|
|
444
437
|
is to set the values of these sub-lists.
|
|
445
|
-
params
|
|
446
|
-
A tuple containing the values of each entry in :attr:`Op.__props__`.
|
|
447
438
|
|
|
448
439
|
Notes
|
|
449
440
|
-----
|
|
@@ -481,22 +472,6 @@ class Op(MetaObject):
|
|
|
481
472
|
"""
|
|
482
473
|
return True
|
|
483
474
|
|
|
484
|
-
def get_params(self, node: Apply) -> Params:
|
|
485
|
-
"""Try to get parameters for the `Op` when :attr:`Op.params_type` is set to a `ParamsType`."""
|
|
486
|
-
if isinstance(self.params_type, ParamsType):
|
|
487
|
-
wrapper = self.params_type
|
|
488
|
-
if not all(hasattr(self, field) for field in wrapper.fields):
|
|
489
|
-
# Let's print missing attributes for debugging.
|
|
490
|
-
not_found = tuple(
|
|
491
|
-
field for field in wrapper.fields if not hasattr(self, field)
|
|
492
|
-
)
|
|
493
|
-
raise AttributeError(
|
|
494
|
-
f"{type(self).__name__}: missing attributes {not_found} for ParamsType."
|
|
495
|
-
)
|
|
496
|
-
# ParamsType.get_params() will apply filtering to attributes.
|
|
497
|
-
return self.params_type.get_params(self)
|
|
498
|
-
raise MethodNotDefined("get_params")
|
|
499
|
-
|
|
500
475
|
def prepare_node(
|
|
501
476
|
self,
|
|
502
477
|
node: Apply,
|
|
@@ -538,34 +513,12 @@ class Op(MetaObject):
|
|
|
538
513
|
else:
|
|
539
514
|
p = node.op.perform
|
|
540
515
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
p=p, i=node_input_storage, o=node_output_storage, n=node, params=None
|
|
548
|
-
):
|
|
549
|
-
r = p(n, [x[0] for x in i], o)
|
|
550
|
-
for o in node.outputs:
|
|
551
|
-
compute_map[o][0] = True
|
|
552
|
-
return r
|
|
553
|
-
|
|
554
|
-
else:
|
|
555
|
-
params_val = node.params_type.filter(params)
|
|
556
|
-
|
|
557
|
-
@is_thunk_type
|
|
558
|
-
def rval(
|
|
559
|
-
p=p,
|
|
560
|
-
i=node_input_storage,
|
|
561
|
-
o=node_output_storage,
|
|
562
|
-
n=node,
|
|
563
|
-
params=params_val,
|
|
564
|
-
):
|
|
565
|
-
r = p(n, [x[0] for x in i], o, params)
|
|
566
|
-
for o in node.outputs:
|
|
567
|
-
compute_map[o][0] = True
|
|
568
|
-
return r
|
|
516
|
+
@is_thunk_type
|
|
517
|
+
def rval(p=p, i=node_input_storage, o=node_output_storage, n=node):
|
|
518
|
+
r = p(n, [x[0] for x in i], o)
|
|
519
|
+
for o in node.outputs:
|
|
520
|
+
compute_map[o][0] = True
|
|
521
|
+
return r
|
|
569
522
|
|
|
570
523
|
rval.inputs = node_input_storage
|
|
571
524
|
rval.outputs = node_output_storage
|
|
@@ -640,7 +593,7 @@ class _NoPythonOp(Op):
|
|
|
640
593
|
|
|
641
594
|
"""
|
|
642
595
|
|
|
643
|
-
def perform(self, node, inputs, output_storage
|
|
596
|
+
def perform(self, node, inputs, output_storage):
|
|
644
597
|
raise NotImplementedError("No Python implementation is provided by this Op.")
|
|
645
598
|
|
|
646
599
|
|
|
@@ -3,7 +3,13 @@ from collections.abc import Iterable, Mapping, Sequence
|
|
|
3
3
|
from functools import partial, singledispatch
|
|
4
4
|
from typing import Optional, Union, cast, overload
|
|
5
5
|
|
|
6
|
-
from pytensor.graph.basic import
|
|
6
|
+
from pytensor.graph.basic import (
|
|
7
|
+
Apply,
|
|
8
|
+
Constant,
|
|
9
|
+
Variable,
|
|
10
|
+
io_toposort,
|
|
11
|
+
truncated_graph_inputs,
|
|
12
|
+
)
|
|
7
13
|
from pytensor.graph.fg import FunctionGraph
|
|
8
14
|
from pytensor.graph.op import Op
|
|
9
15
|
|
|
@@ -295,19 +301,14 @@ def vectorize_graph(
|
|
|
295
301
|
inputs = truncated_graph_inputs(seq_outputs, ancestors_to_include=replace.keys())
|
|
296
302
|
new_inputs = [replace.get(inp, inp) for inp in inputs]
|
|
297
303
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
304
|
+
vect_vars = dict(zip(inputs, new_inputs))
|
|
305
|
+
for node in io_toposort(inputs, seq_outputs):
|
|
306
|
+
vect_inputs = [vect_vars.get(inp, inp) for inp in node.inputs]
|
|
307
|
+
vect_node = vectorize_node(node, *vect_inputs)
|
|
308
|
+
for output, vect_output in zip(node.outputs, vect_node.outputs):
|
|
309
|
+
vect_vars[output] = vect_output
|
|
301
310
|
|
|
302
|
-
|
|
303
|
-
batched_inputs = [transform(inp) for inp in node.inputs]
|
|
304
|
-
batched_node = vectorize_node(node, *batched_inputs)
|
|
305
|
-
batched_var = batched_node.outputs[var.owner.outputs.index(var)]
|
|
306
|
-
|
|
307
|
-
return cast(Variable, batched_var)
|
|
308
|
-
|
|
309
|
-
# TODO: MergeOptimization or node caching?
|
|
310
|
-
seq_vect_outputs = [transform(out) for out in seq_outputs]
|
|
311
|
+
seq_vect_outputs = [vect_vars[out] for out in seq_outputs]
|
|
311
312
|
|
|
312
313
|
if isinstance(outputs, Sequence):
|
|
313
314
|
return seq_vect_outputs
|
|
@@ -20,6 +20,7 @@ from pytensor.graph.basic import (
|
|
|
20
20
|
io_toposort,
|
|
21
21
|
vars_between,
|
|
22
22
|
)
|
|
23
|
+
from pytensor.graph.utils import MethodNotDefined
|
|
23
24
|
from pytensor.link.basic import Container, Linker, LocalLinker, PerformLinker
|
|
24
25
|
from pytensor.link.c.cmodule import (
|
|
25
26
|
METH_VARARGS,
|
|
@@ -617,7 +618,12 @@ class CLinker(Linker):
|
|
|
617
618
|
# that needs it
|
|
618
619
|
self.node_params = dict()
|
|
619
620
|
for node in self.node_order:
|
|
620
|
-
|
|
621
|
+
if not isinstance(node.op, CLinkerOp):
|
|
622
|
+
continue
|
|
623
|
+
try:
|
|
624
|
+
params = node.op.get_params(node)
|
|
625
|
+
except MethodNotDefined:
|
|
626
|
+
params = NoParams
|
|
621
627
|
if params is not NoParams:
|
|
622
628
|
# try to avoid creating more than one variable for the
|
|
623
629
|
# same params.
|
|
@@ -803,7 +809,10 @@ class CLinker(Linker):
|
|
|
803
809
|
|
|
804
810
|
sub = dict(failure_var=failure_var)
|
|
805
811
|
|
|
806
|
-
|
|
812
|
+
try:
|
|
813
|
+
params = op.get_params(node)
|
|
814
|
+
except MethodNotDefined:
|
|
815
|
+
params = NoParams
|
|
807
816
|
if params is not NoParams:
|
|
808
817
|
params_var = symbol[self.node_params[params]]
|
|
809
818
|
|
|
@@ -2718,6 +2718,7 @@ def default_blas_ldflags():
|
|
|
2718
2718
|
found = True
|
|
2719
2719
|
break
|
|
2720
2720
|
if not found:
|
|
2721
|
+
_logger.debug("Required file '%s' not found", req)
|
|
2721
2722
|
raise RuntimeError(f"Required file {req} not found")
|
|
2722
2723
|
return libs
|
|
2723
2724
|
|
|
@@ -2744,7 +2745,9 @@ def default_blas_ldflags():
|
|
|
2744
2745
|
[pathlib.Path(p).resolve() for p in line[len("libraries: =") :].split(":")]
|
|
2745
2746
|
for line in stdout.decode(sys.stdout.encoding).splitlines()
|
|
2746
2747
|
if line.startswith("libraries: =")
|
|
2747
|
-
]
|
|
2748
|
+
]
|
|
2749
|
+
if len(maybe_lib_dirs) > 0:
|
|
2750
|
+
maybe_lib_dirs = maybe_lib_dirs[0]
|
|
2748
2751
|
return [str(d) for d in maybe_lib_dirs if d.exists() and d.is_dir()]
|
|
2749
2752
|
|
|
2750
2753
|
def check_libs(
|
|
@@ -2777,9 +2780,15 @@ def default_blas_ldflags():
|
|
|
2777
2780
|
res = try_blas_flag(flags)
|
|
2778
2781
|
if res:
|
|
2779
2782
|
if any("mkl" in flag for flag in flags):
|
|
2780
|
-
|
|
2783
|
+
try:
|
|
2784
|
+
check_mkl_openmp()
|
|
2785
|
+
except Exception as e:
|
|
2786
|
+
_logger.debug(e)
|
|
2787
|
+
_logger.debug("The following blas flags will be used: '%s'", res)
|
|
2781
2788
|
return res
|
|
2782
2789
|
else:
|
|
2790
|
+
_logger.debug(f"Supplied flags {res} failed to compile")
|
|
2791
|
+
_logger.debug("Supplied flags '%s' failed to compile", res)
|
|
2783
2792
|
raise RuntimeError(f"Supplied flags {flags} failed to compile")
|
|
2784
2793
|
|
|
2785
2794
|
# If no compiler is available we default to empty ldflags
|
|
@@ -2793,6 +2802,18 @@ def default_blas_ldflags():
|
|
|
2793
2802
|
|
|
2794
2803
|
cxx_library_dirs = get_cxx_library_dirs()
|
|
2795
2804
|
searched_library_dirs = cxx_library_dirs + _std_lib_dirs
|
|
2805
|
+
if sys.platform == "win32":
|
|
2806
|
+
# Conda on Windows saves MKL libraries under CONDA_PREFIX\Library\bin
|
|
2807
|
+
# From the conda manual (https://docs.conda.io/projects/conda-build/en/stable/user-guide/environment-variables.html)
|
|
2808
|
+
# it seems like conda could also save some libraries into the CONDA_PREFIX\Library\lib
|
|
2809
|
+
# directory. We will include both in our searched library dirs
|
|
2810
|
+
searched_library_dirs.append(os.path.join(sys.prefix, "Library", "bin"))
|
|
2811
|
+
searched_library_dirs.append(os.path.join(sys.prefix, "Library", "lib"))
|
|
2812
|
+
search_dirs = "\n".join(searched_library_dirs)
|
|
2813
|
+
_logger.debug(
|
|
2814
|
+
"Will search for BLAS libraries in the following directories:\n%s",
|
|
2815
|
+
search_dirs,
|
|
2816
|
+
)
|
|
2796
2817
|
all_libs = [
|
|
2797
2818
|
l
|
|
2798
2819
|
for path in [
|
|
@@ -2808,6 +2829,7 @@ def default_blas_ldflags():
|
|
|
2808
2829
|
maybe_add_to_os_environ_pathlist("PATH", rpath)
|
|
2809
2830
|
try:
|
|
2810
2831
|
# 1. Try to use MKL with INTEL OpenMP threading
|
|
2832
|
+
_logger.debug("Checking MKL flags with intel threading")
|
|
2811
2833
|
return check_libs(
|
|
2812
2834
|
all_libs,
|
|
2813
2835
|
required_libs=[
|
|
@@ -2820,19 +2842,21 @@ def default_blas_ldflags():
|
|
|
2820
2842
|
extra_compile_flags=[f"-Wl,-rpath,{rpath}"] if rpath is not None else [],
|
|
2821
2843
|
cxx_library_dirs=cxx_library_dirs,
|
|
2822
2844
|
)
|
|
2823
|
-
except Exception:
|
|
2824
|
-
|
|
2845
|
+
except Exception as e:
|
|
2846
|
+
_logger.debug(e)
|
|
2825
2847
|
try:
|
|
2826
2848
|
# 2. Try to use MKL with GNU OpenMP threading
|
|
2849
|
+
_logger.debug("Checking MKL flags with GNU OpenMP threading")
|
|
2827
2850
|
return check_libs(
|
|
2828
2851
|
all_libs,
|
|
2829
2852
|
required_libs=["mkl_core", "mkl_rt", "mkl_gnu_thread", "gomp", "pthread"],
|
|
2830
2853
|
extra_compile_flags=[f"-Wl,-rpath,{rpath}"] if rpath is not None else [],
|
|
2831
2854
|
cxx_library_dirs=cxx_library_dirs,
|
|
2832
2855
|
)
|
|
2833
|
-
except Exception:
|
|
2834
|
-
|
|
2856
|
+
except Exception as e:
|
|
2857
|
+
_logger.debug(e)
|
|
2835
2858
|
try:
|
|
2859
|
+
_logger.debug("Checking Lapack + blas")
|
|
2836
2860
|
# 3. Try to use LAPACK + BLAS
|
|
2837
2861
|
return check_libs(
|
|
2838
2862
|
all_libs,
|
|
@@ -2840,20 +2864,22 @@ def default_blas_ldflags():
|
|
|
2840
2864
|
extra_compile_flags=[f"-Wl,-rpath,{rpath}"] if rpath is not None else [],
|
|
2841
2865
|
cxx_library_dirs=cxx_library_dirs,
|
|
2842
2866
|
)
|
|
2843
|
-
except Exception:
|
|
2844
|
-
|
|
2867
|
+
except Exception as e:
|
|
2868
|
+
_logger.debug(e)
|
|
2845
2869
|
try:
|
|
2846
2870
|
# 4. Try to use BLAS alone
|
|
2871
|
+
_logger.debug("Checking blas alone")
|
|
2847
2872
|
return check_libs(
|
|
2848
2873
|
all_libs,
|
|
2849
2874
|
required_libs=["blas", "cblas"],
|
|
2850
2875
|
extra_compile_flags=[f"-Wl,-rpath,{rpath}"] if rpath is not None else [],
|
|
2851
2876
|
cxx_library_dirs=cxx_library_dirs,
|
|
2852
2877
|
)
|
|
2853
|
-
except Exception:
|
|
2854
|
-
|
|
2878
|
+
except Exception as e:
|
|
2879
|
+
_logger.debug(e)
|
|
2855
2880
|
try:
|
|
2856
2881
|
# 5. Try to use openblas
|
|
2882
|
+
_logger.debug("Checking openblas")
|
|
2857
2883
|
return check_libs(
|
|
2858
2884
|
all_libs,
|
|
2859
2885
|
required_libs=["openblas", "gfortran", "gomp", "m"],
|
|
@@ -2862,8 +2888,9 @@ def default_blas_ldflags():
|
|
|
2862
2888
|
else ["-fopenmp"],
|
|
2863
2889
|
cxx_library_dirs=cxx_library_dirs,
|
|
2864
2890
|
)
|
|
2865
|
-
except Exception:
|
|
2866
|
-
|
|
2891
|
+
except Exception as e:
|
|
2892
|
+
_logger.debug(e)
|
|
2893
|
+
_logger.debug("Failed to identify blas ldflags. Will leave them empty.")
|
|
2867
2894
|
return ""
|
|
2868
2895
|
|
|
2869
2896
|
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
+
import typing
|
|
1
2
|
import warnings
|
|
2
3
|
from abc import abstractmethod
|
|
3
|
-
from typing import Callable
|
|
4
|
+
from typing import Callable, Optional
|
|
4
5
|
|
|
5
6
|
from pytensor.graph.basic import Apply, Constant
|
|
6
7
|
from pytensor.graph.utils import MethodNotDefined
|
|
7
8
|
|
|
8
9
|
|
|
10
|
+
if typing.TYPE_CHECKING:
|
|
11
|
+
from pytensor.link.c.params_type import Params, ParamsType
|
|
12
|
+
|
|
13
|
+
|
|
9
14
|
class CLinkerObject:
|
|
10
15
|
"""Standard methods for an `Op` or `Type` used with the `CLinker`."""
|
|
11
16
|
|
|
@@ -172,6 +177,8 @@ class CLinkerObject:
|
|
|
172
177
|
class CLinkerOp(CLinkerObject):
|
|
173
178
|
"""Interface definition for `Op` subclasses compiled by `CLinker`."""
|
|
174
179
|
|
|
180
|
+
params_type: Optional["ParamsType"] = None
|
|
181
|
+
|
|
175
182
|
@abstractmethod
|
|
176
183
|
def c_code(
|
|
177
184
|
self,
|
|
@@ -362,6 +369,22 @@ class CLinkerOp(CLinkerObject):
|
|
|
362
369
|
"""
|
|
363
370
|
return ""
|
|
364
371
|
|
|
372
|
+
def get_params(self, node: Apply) -> "Params":
|
|
373
|
+
"""Try to get parameters for the `Op` when :attr:`Op.params_type` is set to a `ParamsType`."""
|
|
374
|
+
if self.params_type is not None:
|
|
375
|
+
wrapper = self.params_type
|
|
376
|
+
if not all(hasattr(self, field) for field in wrapper.fields):
|
|
377
|
+
# Let's print missing attributes for debugging.
|
|
378
|
+
not_found = tuple(
|
|
379
|
+
field for field in wrapper.fields if not hasattr(self, field)
|
|
380
|
+
)
|
|
381
|
+
raise AttributeError(
|
|
382
|
+
f"{type(self).__name__}: missing attributes {not_found} for ParamsType."
|
|
383
|
+
)
|
|
384
|
+
# ParamsType.get_params() will apply filtering to attributes.
|
|
385
|
+
return self.params_type.get_params(self)
|
|
386
|
+
raise MethodNotDefined("get_params")
|
|
387
|
+
|
|
365
388
|
|
|
366
389
|
class CLinkerType(CLinkerObject):
|
|
367
390
|
r"""Interface specification for `Type`\s that can be arguments to a `CLinkerOp`.
|
|
@@ -664,7 +664,7 @@ class _NoPythonCOp(COp):
|
|
|
664
664
|
|
|
665
665
|
"""
|
|
666
666
|
|
|
667
|
-
def perform(self, node, inputs, output_storage
|
|
667
|
+
def perform(self, node, inputs, output_storage):
|
|
668
668
|
raise NotImplementedError("No Python implementation is provided by this COp.")
|
|
669
669
|
|
|
670
670
|
|
|
@@ -675,7 +675,7 @@ class _NoPythonExternalCOp(ExternalCOp):
|
|
|
675
675
|
|
|
676
676
|
"""
|
|
677
677
|
|
|
678
|
-
def perform(self, node, inputs, output_storage
|
|
678
|
+
def perform(self, node, inputs, output_storage):
|
|
679
679
|
raise NotImplementedError(
|
|
680
680
|
"No Python implementation is provided by this ExternalCOp."
|
|
681
681
|
)
|
|
@@ -99,9 +99,7 @@ def jax_funcify_BatchedDot(op, **kwargs):
|
|
|
99
99
|
def batched_dot(a, b):
|
|
100
100
|
if a.shape[0] != b.shape[0]:
|
|
101
101
|
raise TypeError("Shapes must match in the 0-th dimension")
|
|
102
|
-
|
|
103
|
-
return jnp.einsum("n...j,nj...->n...", a, b)
|
|
104
|
-
return jnp.einsum("nij,njk->nik", a, b)
|
|
102
|
+
return jnp.matmul(a, b)
|
|
105
103
|
|
|
106
104
|
return batched_dot
|
|
107
105
|
|