From 3cc8e73ab4e07f66034b4c6fd4f6be2b8d18d7f1 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Fri, 14 Jun 2024 15:00:57 -0400 Subject: [PATCH] xo-pyjit: initial commit --- .gitignore | 6 ++++ CMakeLists.txt | 28 +++++++++++++++ cmake/xo-bootstrap-macros.cmake | 35 +++++++++++++++++++ cmake/xo_pyjitConfig.cmake.in | 7 ++++ include/README.md | 1 + src/pyjit/CMakeLists.txt | 9 +++++ src/pyjit/pyjit.cpp | 60 +++++++++++++++++++++++++++++++++ src/pyjit/pyjit.hpp.in | 25 ++++++++++++++ 8 files changed, 171 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 cmake/xo-bootstrap-macros.cmake create mode 100644 cmake/xo_pyjitConfig.cmake.in create mode 100644 include/README.md create mode 100644 src/pyjit/CMakeLists.txt create mode 100644 src/pyjit/pyjit.cpp create mode 100644 src/pyjit/pyjit.hpp.in diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..13c0afb7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# clangd working space (see emacs+lsp) +.cache +# typical cmake build directory (source-tree-nephew) +.build* +# symlink to builddir/compile_commands.json; should be set manually in dev sandbox +compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..bacd5c53 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,28 @@ +# xo-pyjit/CMakeLists.txt + +cmake_minimum_required(VERSION 3.10) + +project(xo_pyjit VERSION 0.1) + +include(GNUInstallDirs) +include(cmake/xo-bootstrap-macros.cmake) + +xo_cxx_toplevel_options3() + +# ---------------------------------------------------------------- +# c++ settings (usually temporary) + +set(PROJECT_CXX_FLAGS "") +add_definitions(${PROJECT_CXX_FLAGS}) + +# ---------------------------------------------------------------- + +add_subdirectory(src/pyjit) +#add_subdirectory(utest) + +# ---------------------------------------------------------------- +# provide find_package() support + +xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) + +# end CMakeLists.txt diff --git a/cmake/xo-bootstrap-macros.cmake b/cmake/xo-bootstrap-macros.cmake new file mode 100644 index 00000000..aba31169 --- /dev/null +++ b/cmake/xo-bootstrap-macros.cmake @@ -0,0 +1,35 @@ +# ---------------------------------------------------------------- +# for example: +# $ PREFIX=/usr/local # for example +# $ cmake -DCMAKE_MODULE_PATH=prefix -DCMAKE_INSTALL_PREFIX=$PREFIX -B .build +# +# will get +# CMAKE_MODULE_PATH +# from xo-cmake-config --cmake-module-path +# +# and expect .cmake macros in +# CMAKE_MODULE_PATH/xo_macros/xo_cxx.cmake +# ---------------------------------------------------------------- + +find_program(XO_CMAKE_CONFIG_EXECUTABLE NAMES xo-cmake-config REQUIRED) + +if ("${XO_CMAKE_CONFIG_EXECUTABLE}" STREQUAL "XO_CMAKE_CONFIG_EXECUTABLE-NOT_FOUND") + message(FATAL "could not find xo-cmake-config executable") +endif() + +message(STATUS "XO_CMAKE_CONFIG_EXECUTABLE=${XO_CMAKE_CONFIG_EXECUTABLE}") + +if (NOT XO_SUBMODULE_BUILD) + if (("${CMAKE_MODULE_PATH}" STREQUAL "") OR ("${CMAKE_MODULE_PATH}" STREQUAL prefix)) + # default to typical install location for xo-project-macros + execute_process(COMMAND ${XO_CMAKE_CONFIG_EXECUTABLE} --cmake-module-path OUTPUT_VARIABLE CMAKE_MODULE_PATH) + message(STATUS "CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}") + endif() +endif() + +# needs to have been installed somewhere on CMAKE_MODULE_PATH, +# (e.g. from xo-cmake with the same value for CMAKE_INSTALL_PREFIX) +# +include(xo_macros/xo_cxx) + +xo_cxx_bootstrap_message() diff --git a/cmake/xo_pyjitConfig.cmake.in b/cmake/xo_pyjitConfig.cmake.in new file mode 100644 index 00000000..5d7de08a --- /dev/null +++ b/cmake/xo_pyjitConfig.cmake.in @@ -0,0 +1,7 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(xo_jit) +find_dependency(xo_pyexpression) +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/include/README.md b/include/README.md new file mode 100644 index 00000000..9db0605f --- /dev/null +++ b/include/README.md @@ -0,0 +1 @@ +placeholder for future xo-pymatrix header files diff --git a/src/pyjit/CMakeLists.txt b/src/pyjit/CMakeLists.txt new file mode 100644 index 00000000..d6d84521 --- /dev/null +++ b/src/pyjit/CMakeLists.txt @@ -0,0 +1,9 @@ +# xo-pyjit/src/pyjit/CMakeLists.txt + +set(SELF_LIB xo_pyjit) +set(SELF_SRCS pyjit.cpp) + +xo_pybind11_library(${SELF_LIB} ${PROJECT_NAME}Targets ${SELF_SRCS}) +xo_pybind11_dependency(${SELF_LIB} xo_jit) +xo_pybind11_dependency(${SELF_LIB} xo_pyexpression) +xo_dependency(${SELF_LIB} refcnt) diff --git a/src/pyjit/pyjit.cpp b/src/pyjit/pyjit.cpp new file mode 100644 index 00000000..a8a532ec --- /dev/null +++ b/src/pyjit/pyjit.cpp @@ -0,0 +1,60 @@ +/* @file pyjit.cpp */ + +#include "pyjit.hpp" +#include "xo/pyexpression/pyexpression.hpp" +#include "xo/jit/Jit.hpp" +#include "xo/pyutil/pyutil.hpp" + +namespace xo { + namespace jit { + using xo::ast::Expression; + using xo::ref::rp; + using xo::ref::unowned_ptr; + namespace py = pybind11; + + PYBIND11_MODULE(XO_PYJIT_MODULE_NAME(), m) { + // e.g. for xo::ast::Expression + XO_PYEXPRESSION_IMPORT_MODULE(); // py::module_::import("pyexpression"); + + m.doc() = "pybind11 plugin for xo-jit"; + + py::class_>(m, "Jit") + .def_static("make", &Jit::make, + py::doc("create Jit instance. Not threadsafe," + " but does not share resources with any other Jit instance")) + + .def("codegen", + [](Jit & jit, const rp & expr) { + return jit.codegen(expr.borrow()); + }, + py::arg("x"), + py::doc("generate llvm (IR) code for Expression x"), + /* we're assuming llvm-generated code lives for as long as the Jit + * instance that created it. + * + * RC 14jun2024 - I think this is true modulo use of llvm resource trackers. + */ + py::return_value_policy::reference_internal) + ; + + py::class_>(m, "llvm_Value") + .def("print", + [](llvm::Value & x) { + std::string buf; + llvm::raw_string_ostream ss(buf); + x.print(ss); + return buf; + }) + .def("__repr__", + &Jit::display_string) + ; + + } + + + } /*namespace jit*/ +} /*namespace xo*/ + + +/* end pyjit.cpp */ diff --git a/src/pyjit/pyjit.hpp.in b/src/pyjit/pyjit.hpp.in new file mode 100644 index 00000000..8abdc8e3 --- /dev/null +++ b/src/pyjit/pyjit.hpp.in @@ -0,0 +1,25 @@ +/* @file pyjit.hpp + * + * automatically generated from src/xo_pyjit/pyjit.hpp.in + * see src/xo_pyjit/CMakeLists.txt + */ + +/* python requires module name = library name + * example: + * PYBIND11_MODULE(XO_PYJIT_MODULE_NAME(), m) { ... } + */ +#define XO_PYJIT_MODULE_NAME() @SELF_LIB@ + +/* example: + * py::module_::import(XO_PYJIT_MODULE_NAME_STR) + */ +#define XO_PYJIT_MODULE_NAME_STR "@SELF_LIB@" + +/* example: + * XO_PYJIT_IMPORT_MODULE() + * replaces + * py::module_::import("pyjit") + */ +#define XO_PYJIT_IMPORT_MODULE() py::module_::import("@SELF_LIB@") + +/* end pyjit.hpp */