From f40c44d5dd5fcb399908ac9bddc89683bff06501 Mon Sep 17 00:00:00 2001 From: Bram Veenboer Date: Tue, 12 Aug 2025 14:55:28 +0200 Subject: [PATCH] Add Python interface --- CMakeLists.txt | 10 +++++- python/CMakeLists.txt | 8 +++++ python/bindings.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 python/CMakeLists.txt create mode 100644 python/bindings.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e807f5e..ef1df5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,18 +3,22 @@ project(trigdx LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) option(TRIGDX_USE_MKL "Enable Intel MKL backend" OFF) option(TRIGDX_USE_GPU "Enable GPU backend" OFF) option(TRIGDX_USE_XSIMD "Enable XSIMD backend" OFF) option(TRIGDX_BUILD_TESTS "Build tests" ON) option(TRIGDX_BUILD_BENCHMARKS "Build tests" ON) +option(TRIGDX_BUILD_PYTHON "Build Python interface" ON) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/trigdx_config.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/include/trigdx/trigdx_config.hpp @ONLY) -if(TRIGDX_BUILD_TESTS OR TRIGDX_BUILD_BENCHMARKS) +if(TRIGDX_BUILD_TESTS + OR TRIGDX_BUILD_BENCHMARKS + OR TRIGDX_BUILD_PYTHON) include(FetchContent) endif() @@ -31,3 +35,7 @@ endif() if(TRIGDX_BUILD_BENCHMARKS) add_subdirectory(benchmarks) endif() + +if(TRIGDX_BUILD_PYTHON) + add_subdirectory(python) +endif() diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt new file mode 100644 index 0000000..81e1494 --- /dev/null +++ b/python/CMakeLists.txt @@ -0,0 +1,8 @@ +FetchContent_Declare( + pybind11 + GIT_REPOSITORY https://github.com/pybind/pybind11.git + GIT_TAG v3.0.0) +FetchContent_MakeAvailable(pybind11) + +pybind11_add_module(pytrigdx bindings.cpp) +target_link_libraries(pytrigdx PRIVATE trigdx) diff --git a/python/bindings.cpp b/python/bindings.cpp new file mode 100644 index 0000000..5c57756 --- /dev/null +++ b/python/bindings.cpp @@ -0,0 +1,80 @@ +#include + +#include +#include +#include + +namespace py = pybind11; + +py::array_t compute_sinf_py( + const Backend &backend, + py::array_t x) { + ssize_t n = x.shape(0); + auto x_ptr = x.data(); + + py::array_t s(n); + auto s_ptr = s.mutable_data(); + + backend.compute_sinf(static_cast(n), x_ptr, s_ptr); + + return s; +} + +py::array_t compute_cosf_py( + const Backend &backend, + py::array_t x) { + ssize_t n = x.shape(0); + auto x_ptr = x.data(); + + py::array_t c(n); + auto c_ptr = c.mutable_data(); + + backend.compute_cosf(static_cast(n), x_ptr, c_ptr); + + return c; +} + +std::tuple, py::array_t> compute_sincosf_py( + const Backend &backend, + py::array_t x) { + ssize_t n = x.shape(0); + auto x_ptr = x.data(); + + py::array_t s(n); + py::array_t c(n); + + backend.compute_sincosf(static_cast(n), x_ptr, s.mutable_data(), + c.mutable_data()); + + return std::make_tuple(s, c); +} + +template +void bind_backend(py::module &m, const char *name) { + py::class_>(m, name) + .def(py::init<>()) + .def("compute_sinf", &compute_sinf_py) + .def("compute_cosf", &compute_cosf_py) + .def("compute_sincosf", &compute_sincosf_py); +} + +PYBIND11_MODULE(pytrigdx, m) { + py::class_>(m, "Backend") + .def("init", &Backend::init); + + bind_backend(m, "Reference"); + bind_backend>(m, "Lookup16K"); + bind_backend>(m, "Lookup32K"); + bind_backend>(m, "LookupAVX16K"); + bind_backend>(m, "LookupAVX32K"); +#if defined(TRIGDX_USE_MKL) + bind_backend(m, "MKL"); +#endif +#if defined(TRIGDX_USE_GPU) + bind_backend(m, "GPU"); +#endif +#if defined(TRIGDX_USE_XSIMD) + bind_backend>(m, "LookupXSIMD16K"); + bind_backend>(m, "LookupXSIMD32K"); +#endif +} \ No newline at end of file