-
Notifications
You must be signed in to change notification settings - Fork 7
Adds Python bindings to Adiak #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit
Hold shift + click to select a range
4933729
Implements C++ -> Python bridge for Adiak's annotation APIs
ilumsden ed20c53
Current progress on the tools interface
ilumsden a5e43cb
Finishes implementation of C++ -> Python bridge
ilumsden ce44053
Adds initial Python code for bindings
ilumsden 22ac407
Finishes implementation of Python bindings and adds build system support
ilumsden 82dccff
Updates GitHub Action to test build of Python bindings
ilumsden f2f90bb
Updates the CMake Action to properly install Python and MPI
ilumsden db71b96
Add missing file for python install paths
michaelmckinsey1 6f4d47e
Fix build errors & runtime errors
michaelmckinsey1 8d0abd4
Fix definitions for 4 args
michaelmckinsey1 c04e009
Add fini
michaelmckinsey1 fb282ab
Change types
michaelmckinsey1 0e9ce20
Change WITH -> ENABLE
michaelmckinsey1 0632d27
Add docpage
michaelmckinsey1 7012aa9
Allow nompi and update test
michaelmckinsey1 46f8657
Fix CI syntax and other issues
michaelmckinsey1 6f35f29
Fix cray build error
michaelmckinsey1 5187189
define enable_mpi
michaelmckinsey1 9857e3b
Undo change and custom type cast
michaelmckinsey1 3f5c223
Merge branch 'master' of github.com:LLNL/Adiak into python_bindings
michaelmckinsey1 7cb8c49
Add python test
michaelmckinsey1 2d34128
Add example
michaelmckinsey1 252ad44
Bump version
michaelmckinsey1 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,24 +25,59 @@ jobs: | |
| - { | ||
| name: "Ubuntu Latest GCC", | ||
| os: ubuntu-latest, | ||
| build_type: "Release", cc: "gcc", cxx: "g++" | ||
| build_type: "Release", cc: "gcc", cxx: "g++", | ||
| mpi_type: "none" | ||
| } | ||
| - { | ||
| name: "Ubuntu Latest Clang", | ||
| os: ubuntu-latest, | ||
| build_type: "Release", cc: "clang", cxx: "clang++" | ||
| build_type: "Release", cc: "clang", cxx: "clang++", | ||
| mpi_type: "none" | ||
| } | ||
| - { | ||
| name: "Ubuntu Latest GCC (MPI)", | ||
| os: ubuntu-latest, | ||
| build_type: "Release", cc: "gcc", cxx: "g++", | ||
| mpi_type: "mpich" | ||
| } | ||
| - { | ||
| name: "Ubuntu Latest Clang (MPI)", | ||
| os: ubuntu-latest, | ||
| build_type: "Release", cc: "clang", cxx: "clang++", | ||
| mpi_type: "mpich" | ||
| } | ||
| - { | ||
| name: "macOS Latest Clang", | ||
| os: macos-latest, | ||
| build_type: "Release", cc: "clang", cxx: "clang++" | ||
| build_type: "Release", cc: "clang", cxx: "clang++", | ||
| mpi_type: "none" | ||
| } | ||
| steps: | ||
| - name: Checkout repository and submodules | ||
| uses: actions/checkout@v2 | ||
| with: | ||
| submodules: recursive | ||
|
|
||
| - name: Install Python | ||
| uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: '3.13' | ||
|
|
||
| - name: Install MPI | ||
| if: ${{ matrix.config.mpi_type != 'none' }} | ||
| uses: mpi4py/[email protected] | ||
| with: | ||
| mpi: ${{matrix.config.mpi_type}} | ||
|
|
||
| - name: Install Python binding dependencies | ||
| run: | | ||
| python3 -m pip install pybind11 | ||
|
|
||
| - name: Install mpi4py | ||
| if: ${{ matrix.config.mpi_type != 'none' }} | ||
| run: | | ||
| python -m pip install mpi4py | ||
|
|
||
| - name: Create Build Environment | ||
| # Some projects don't allow in-source building, so create a separate build directory | ||
| # We'll use this as our working directory for all subsequent commands | ||
|
|
@@ -56,7 +91,13 @@ jobs: | |
| # Note the current convention is to use the -S and -B options here to specify source | ||
| # and build directories, but this is only available with CMake 3.13 and higher. | ||
| # The CMake binaries on the Github Actions machines are (as of this writing) 3.12 | ||
| run: cmake $GITHUB_WORKSPACE -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_C_COMPILER=${{matrix.config.cc}} -DCMAKE_CXX_COMPILER=${{matrix.config.cxx}} | ||
| run: | | ||
| EXTRA_OPTS="" | ||
| if [ "${{ matrix.config.mpi_type }}" != "none" ]; then | ||
| EXTRA_OPTS="-DENABLE_MPI=ON" | ||
| fi | ||
| cmake $GITHUB_WORKSPACE -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_C_COMPILER=${{matrix.config.cc}} -DCMAKE_CXX_COMPILER=${{matrix.config.cxx}} -DENABLE_PYTHON_BINDINGS=ON -Dpybind11_DIR=$(pybind11-config --cmakedir) \ | ||
| $EXTRA_OPTS | ||
|
|
||
| - name: Build | ||
| working-directory: ${{github.workspace}}/build | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| import sys | ||
| import sysconfig | ||
|
|
||
| if len(sys.argv) != 3 or sys.argv[1] not in ("purelib", "platlib"): | ||
| raise RuntimeError( | ||
| "Usage: python get_python_install_paths.py <purelib | platlib> <sysconfig_scheme>" | ||
| ) | ||
|
|
||
| install_dir = sysconfig.get_path(sys.argv[1], sys.argv[2], {"userbase": "", "base": ""}) | ||
|
|
||
| if install_dir.startswith("/"): | ||
| install_dir = install_dir[1:] | ||
|
|
||
| print(install_dir, end="") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| Python support | ||
| ============== | ||
|
|
||
| Adiak provides Python bindings based on `pybind11 <https://pybind11.readthedocs.io/en/stable/>`_ | ||
| for the metadata/annotation APIs (``init``, ``value``, ``fini``) and a set of convenience | ||
| collectors (e.g., ``collect_all()``, ``walltime()``). | ||
| To build Adiak with Python support, enable | ||
| the :code:`ENABLE_PYTHON_BINDINGS` option in the CMake configuration: | ||
|
|
||
| .. code-block:: sh | ||
|
|
||
| $ cmake -DENABLE_PYTHON_BINDINGS=ON .. | ||
|
|
||
| If you want to initialize Adiak with an MPI communicator from Python, also enable (or auto-detect) | ||
| MPI at configure time (mpi4py is only needed at runtime if you actually pass a communicator): | ||
|
|
||
| .. code-block:: sh | ||
|
|
||
| $ cmake -DENABLE_PYTHON_BINDINGS=ON -DENABLE_MPI=ON .. | ||
|
|
||
| Using the Python module | ||
| ----------------------- | ||
|
|
||
| The Python module requires pybind11 and an installation of Python that both supports | ||
| pybind11 and provides development headers (e.g., :code:`Python.h`) and libraries | ||
| (e.g., :code:`libpython3.8.so`). | ||
|
|
||
| The Adiak Python module is installed in either :code:`lib/pythonX.Y/site-packages/` and/or | ||
| :code:`lib64/pythonX.Y/site-packages` in the Adiak installation directory. In these paths, | ||
| :code:`X.Y` corresponds to the major and minor version numbers of the Python installation used. | ||
| Additionally, :code:`lib/` and :code:`lib64/` will be used in accordance with the configuration | ||
| of the Python installed. | ||
|
|
||
| To use the Adiak Python module, simply add the directories above to :code:`PYTHONPATH` or | ||
| :code:`sys.path`. Note that the module will be automatically added to :code:`PYTHONPATH` when | ||
| loading the Adiak package with Spack if the :code:`python` variant is enabled. | ||
| The module can then be imported with :code:`import pyadiak`. | ||
|
|
||
| Example: basic usage (serial) | ||
| ----------------------------- | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| from datetime import datetime | ||
| from pathlib import Path | ||
|
|
||
| from pyadiak.annotations import init, value, fini, collect_all, walltime, cputime, systime | ||
| from pyadiak.types import Version, Path as APath, CatStr, Category | ||
|
|
||
| def main(): | ||
| init(None) # serial mode | ||
|
|
||
| value("str", "s") | ||
| value("compiler", Version("[email protected]")) | ||
| value("mydouble", 3.14) | ||
| value("problemsize", 14000, category=Category.Tuning) | ||
| value("countdown", 9876543210) | ||
|
|
||
| grid = [4.5, 1.18, 0.24, 8.92] | ||
| value("gridvalues", grid) | ||
|
|
||
| names = {"bob", "jim", "greg"} | ||
| value("allnames", names) | ||
|
|
||
| # Flatten nested structures (or use JsonStr) | ||
| names_arr = ["first", "second", "third"] | ||
| xs = [1.0, 2.0, 3.0] | ||
| ys = [1.0, 4.0, 9.0] | ||
| value("points.names", names_arr) | ||
| value("points.x", xs) | ||
| value("points.y", ys) | ||
|
|
||
| # Time & paths are auto-wrapped; shown explicitly here for clarity | ||
| value("birthday", datetime.fromtimestamp(286551000)) # Timepoint | ||
| value("nullpath", APath(Path("/dev/null"))) # Path | ||
| value("githash", CatStr("a0c93767478f23602c2eb317f641b091c52cf374")) | ||
|
|
||
| collect_all() | ||
| walltime() | ||
| cputime() | ||
| systime() | ||
|
|
||
| fini() | ||
|
|
||
| if __name__ == "__main__": | ||
| main() | ||
|
|
||
|
|
||
| Example: MPI usage (optional) | ||
| ----------------------------- | ||
|
|
||
| If built with :code:`-DENABLE_MPI=ON` and :code:`mpi4py` is available: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| from mpi4py import MPI | ||
| from pyadiak.annotations import init, value, fini | ||
|
|
||
| def main(): | ||
| comm = MPI.COMM_WORLD | ||
| init(comm) # initialize with communicator | ||
| value("rank", comm.Get_rank()) | ||
| fini() | ||
|
|
||
| if __name__ == "__main__": | ||
| main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| set(PYADIAK_BINDING_SOURCES | ||
| mod.cpp | ||
| pyadiak_tool.cpp | ||
| pyadiak.cpp | ||
| types.cpp | ||
| ) | ||
|
|
||
| set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) | ||
|
|
||
| set(PYADIAK_SYSCONFIG_SCHEME "posix_user" CACHE STRING "Scheme used for searching for pyadiak's install path. Valid options can be determined with 'sysconfig.get_scheme_names()'") | ||
|
|
||
| execute_process( | ||
| COMMAND | ||
| ${Python_EXECUTABLE} ${CMAKE_SOURCE_DIR}/cmake/get_python_install_paths.py purelib ${PYADIAK_SYSCONFIG_SCHEME} | ||
| OUTPUT_VARIABLE | ||
| PYADIAK_SITELIB) | ||
| execute_process( | ||
| COMMAND | ||
| ${Python_EXECUTABLE} ${CMAKE_SOURCE_DIR}/cmake/get_python_install_paths.py platlib ${PYADIAK_SYSCONFIG_SCHEME} | ||
| OUTPUT_VARIABLE | ||
| PYADIAK_SITEARCH) | ||
|
|
||
| set(PYADIAK_SITELIB "${PYADIAK_SITELIB}/pyadiak") | ||
| set(PYADIAK_SITEARCH "${PYADIAK_SITEARCH}/pyadiak") | ||
|
|
||
| pybind11_add_module(__pyadiak_impl ${PYADIAK_BINDING_SOURCES}) | ||
| target_link_libraries(__pyadiak_impl PUBLIC adiak) | ||
| target_compile_features(__pyadiak_impl PUBLIC cxx_std_11) | ||
| target_include_directories(__pyadiak_impl PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) | ||
| execute_process( | ||
| COMMAND python3 -c "import mpi4py, os; print(os.path.join(os.path.dirname(mpi4py.__file__), 'include'))" | ||
| OUTPUT_VARIABLE MPI4PY_INCLUDE_DIR | ||
| OUTPUT_STRIP_TRAILING_WHITESPACE | ||
| ) | ||
| include_directories(${MPI4PY_INCLUDE_DIR}) | ||
|
|
||
| add_custom_target( | ||
| pyadiak_py_source_copy ALL # Always build pycaliper_test | ||
| COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/pyadiak | ||
| COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/pyadiak ${CMAKE_CURRENT_BINARY_DIR}/pyadiak | ||
| COMMENT "Copying pyadiak Python source to ${CMAKE_CURRENT_BINARY_DIR}/pyadiak" | ||
| ) | ||
| add_dependencies(__pyadiak_impl pyadiak_py_source_copy) | ||
|
|
||
| install( | ||
| DIRECTORY | ||
| pyadiak/ | ||
| DESTINATION | ||
| ${PYADIAK_SITELIB} | ||
| ) | ||
|
|
||
| install( | ||
| TARGETS | ||
| __pyadiak_impl | ||
| ARCHIVE DESTINATION | ||
| ${PYADIAK_SITEARCH} | ||
| LIBRARY DESTINATION | ||
| ${PYADIAK_SITEARCH} | ||
| ) | ||
|
|
||
| # Put the compiled extension inside the pyadiak package in the build tree | ||
| set(_py_pkg_dir "${CMAKE_BINARY_DIR}/src/interface/python/pyadiak") | ||
|
|
||
| set_target_properties(__pyadiak_impl PROPERTIES | ||
| LIBRARY_OUTPUT_DIRECTORY "${_py_pkg_dir}" # where the .so (MODULE/LIBRARY) goes | ||
| RUNTIME_OUTPUT_DIRECTORY "${_py_pkg_dir}" | ||
| ARCHIVE_OUTPUT_DIRECTORY "${_py_pkg_dir}" | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| #ifndef ADIAK_INTERFACE_PYTHON_COMMON_HPP_ | ||
| #define ADIAK_INTERFACE_PYTHON_COMMON_HPP_ | ||
|
|
||
| #include <adiak.hpp> | ||
| #include <adiak_internal.hpp> | ||
| #include <adiak_tool.h> | ||
| #include <pybind11/pybind11.h> | ||
| #include <pybind11/stl.h> | ||
|
|
||
| namespace py = pybind11; | ||
|
|
||
| #endif /* ADIAK_INTERFACE_PYTHON_COMMON_HPP_ */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| #include "pyadiak.hpp" | ||
| #include "pyadiak_tool.hpp" | ||
|
|
||
| PYBIND11_MODULE(__pyadiak_impl, m) { | ||
| // TODO add version | ||
|
|
||
| auto types_module = | ||
| m.def_submodule("types", "Submodule for type wrappers in Adiak"); | ||
| adiak::python::create_adiak_types_mod(types_module); | ||
|
|
||
| auto annotation_module = | ||
| m.def_submodule("annotations", "Submodule for annotation APIs"); | ||
| adiak::python::create_adiak_annotation_mod(annotation_module); | ||
|
|
||
| auto tool_module = m.def_submodule("tools", "Submodule for tool APIs"); | ||
| adiak::python::create_adiak_tool_mod(tool_module); | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.