From 493372904160c195a2e0570ba4ae6f048a537204 Mon Sep 17 00:00:00 2001 From: Ian Lumsden Date: Thu, 15 May 2025 23:22:57 -0400 Subject: [PATCH 01/22] Implements C++ -> Python bridge for Adiak's annotation APIs --- src/interface/python/common.hpp | 9 + src/interface/python/pyadiak.cpp | 319 +++++++++++++++++++++++++++++++ src/interface/python/pyadiak.hpp | 14 ++ 3 files changed, 342 insertions(+) create mode 100644 src/interface/python/common.hpp create mode 100644 src/interface/python/pyadiak.cpp create mode 100644 src/interface/python/pyadiak.hpp diff --git a/src/interface/python/common.hpp b/src/interface/python/common.hpp new file mode 100644 index 0000000..4103d65 --- /dev/null +++ b/src/interface/python/common.hpp @@ -0,0 +1,9 @@ +#ifndef ADIAK_INTERFACE_PYTHON_COMMON_HPP_ +#define ADIAK_INTERFACE_PYTHON_COMMON_HPP_ + +#include +#include + +namespace py = pybind11; + +#endif /* ADIAK_INTERFACE_PYTHON_COMMON_HPP_ */ \ No newline at end of file diff --git a/src/interface/python/pyadiak.cpp b/src/interface/python/pyadiak.cpp new file mode 100644 index 0000000..1e44651 --- /dev/null +++ b/src/interface/python/pyadiak.cpp @@ -0,0 +1,319 @@ +#include "pyadiak.hpp" +#include "adiak.hpp" +#include +#include + +#include +#include +#include +#include +#include + +namespace adiak { +namespace python { + +// Bindings for MPI Comm derived from this StackOverflow post: +// https://stackoverflow.com/a/62449190 +struct mpi4py_comm { + mpi4py_comm() = default; + + mpi4py_comm(MPI_Comm comm) : m_comm(comm) {} + + MPI_Comm m_comm; +}; + +namespace pybind11 { +namespace detail { + +template <> struct type_caster { + PYBIND11_TYPE_CASTER(mpi4py_comm, _("mpi4py_comm")); + + bool load(py::handle src, bool) { + // If the comm is None, produce a mpi4py_comm object with m_comm set to + // MPI_COMM_NULL + if (src == py::none()) { + value.m_comm = MPI_COMM_NULL; + return !PyErr_Occured(); + } + // Get the underlying PyObject pointer to the mpi4py object + PyObject *py_capi_comm = src.ptr(); + // Make sure the PyObject pointer's underlying type is mpi4py's + // PyMPIComm_Type. If the type check passes, use PyMPIComm_Get (from + // mpi4py's C API) to get the actual MPI_Comm. If the type check fails, tell + // pybind11 that the conversion is invalid. + if (PyObject_TypeCheck(py_capi_comm, &PyMPIComm_Type)) { + value.m_comm = *PyMPIComm_Get(py_capi_comm); + } else { + return false; + } + // Tell pybind11 that the conversion to C++ was successfull so long as there + // were no Python errors + return !PyErr_Occured(); + } + + static py::handle cast(mpi4py_comm src, py::return_value_policy, py::handle) { + return PyMPIComm_New(src.m_comm); + } +}; + +} // namespace detail +} // namespace pybind11 + +// The 'is_templated_base_of' type trait is derived from the following +// StackOverflow post: +// https://stackoverflow.com/a/49163138 +template