Skip to content

Commit

Permalink
use boost::mp11 for generating some binding code; req c++14
Browse files Browse the repository at this point in the history
  • Loading branch information
douglasdavis committed Feb 5, 2021
1 parent 5517acb commit 81091aa
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 53 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[submodule "extern/pybind11"]
path = extern/pybind11
url = https://github.com/pybind/pybind11.git
[submodule "extern/mp11"]
path = extern/mp11
url = https://github.com/boostorg/mp11.git
5 changes: 3 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ find_package(OpenMP)
add_subdirectory(extern/pybind11)

pybind11_add_module(_backend src/_backend.cpp)
set_target_properties(_backend PROPERTIES CXX_STANDARD 11)
set_target_properties(_backend PROPERTIES CXX_STANDARD 14)
target_link_libraries(_backend PUBLIC OpenMP::OpenMP_CXX)
target_compile_options(_backend PRIVATE -Wall -Wextra -pedantic)
target_include_directories(_backend PRIVATE extern/mp11/include)

pybind11_add_module(_backend2d src/_backend2d.cpp)
set_target_properties(_backend2d PROPERTIES CXX_STANDARD 11)
set_target_properties(_backend2d PROPERTIES CXX_STANDARD 14)
target_link_libraries(_backend2d PUBLIC OpenMP::OpenMP_CXX)
target_compile_options(_backend2d PRIVATE -Wall -Wextra -pedantic)
1 change: 1 addition & 0 deletions extern/mp11
Submodule mp11 added at 2d709e
6 changes: 2 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,8 @@ def get_cpp_std_flag():
setuptools.distutils.sysconfig.customize_compiler(compiler)
if has_flag(compiler, "-std=c++14"):
return "-std=c++14"
elif has_flag(compiler, "-std=c++11"):
return "-std=c++11"
else:
raise RuntimeError("C++11 (or later) compatible compiler required")
raise RuntimeError("C++14 (or later) compatible compiler required")


def conda_darwin_flags(flavor="inc"):
Expand Down Expand Up @@ -166,7 +164,7 @@ def get_extensions():
"pygram11._backend",
[os.path.join("src", "_backend.cpp")],
language="c++",
include_dirs=["extern/pybind11/include"],
include_dirs=["extern/pybind11/include", "extern/mp11/include"],
extra_compile_args=cpp_cflags,
extra_link_args=cpp_lflags,
),
Expand Down
81 changes: 34 additions & 47 deletions src/_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
/// pybind11
#include <pybind11/numpy.h>

/// Boost
#include <boost/mp11.hpp>

/// OpenMP
#include <omp.h>

Expand Down Expand Up @@ -987,62 +990,46 @@ py::array_t<py::ssize_t> f2d(py::array_t<Tx> x, py::array_t<Ty> y, py::ssize_t n
return counts;
}

template <typename T>
void inject1d(py::module_& m) {
using namespace pybind11::literals;
// clang-format off

/// unweighted
m.def("_f1d", &f1d<T>,
"x"_a.noconvert(), "bins"_a, "xmin"_a, "xmax"_a, "flow"_a);
m.def("_v1d", &v1d<T>,
"x"_a.noconvert(), "edges"_a, "flow"_a);

/// weighted
m.def("_f1dw", &f1dw<T, double>,
"x"_a.noconvert(), "w"_a.noconvert(), "bins"_a, "xmin"_a, "xmax"_a, "flow"_a);
m.def("_f1dw", &f1dw<T, float>,
"x"_a.noconvert(), "w"_a.noconvert(), "bins"_a, "xmin"_a, "xmax"_a, "flow"_a);
m.def("_v1dw", &v1dw<T, double>,
"x"_a.noconvert(), "w"_a.noconvert(), "edges"_a, "flow"_a);
m.def("_v1dw", &v1dw<T, float>,
"x"_a.noconvert(), "w"_a.noconvert(), "edges"_a, "flow"_a);

/// multiweight
m.def("_f1dmw", &f1dmw<T, double>,
"x"_a.noconvert(), "w"_a.noconvert(), "bins"_a, "xmin"_a, "xmax"_a, "flow"_a);
m.def("_f1dmw", &f1dmw<T, float>,
"x"_a.noconvert(), "w"_a.noconvert(), "bins"_a, "xmin"_a, "xmax"_a, "flow"_a);
m.def("_v1dmw", &v1dmw<T, double>,
"x"_a.noconvert(), "w"_a.noconvert(), "edges"_a, "flow"_a);
m.def("_v1dmw", &v1dmw<T, float>,
"x"_a.noconvert(), "w"_a.noconvert(), "edges"_a, "flow"_a);

// clang-format on
using namespace pybind11::literals;
using boost::mp11::mp_for_each;
using boost::mp11::mp_list;
using boost::mp11::mp_product;

using pg_mp_list = mp_list<double, float, py::ssize_t, int, unsigned long, unsigned int>;
using pg_mp_list = pg_mp_list;
using pg_weight_list = mp_list<double, float>;
using pg_type_weight_pairs = mp_product<mp_list, pg_mp_list, pg_weight_list>;
using pg_type_pairs = mp_product<mp_list, pg_mp_list, pg_mp_list>;

// clang-format off
template <typename Tx>
void inject1d(py::module_& m, const Tx&) {
m.def("_f1d", &f1d<Tx>, "x"_a.noconvert(), "b"_a, "x1"_a, "x2"_a, "f"_a);
m.def("_v1d", &v1d<Tx>, "x"_a.noconvert(), "b"_a, "f"_a);
}

template <typename Tx, typename Ty>
void inject2d(py::module_& m) {
using namespace pybind11::literals;
// clang-format off
template <typename Tx, typename Tw>
void inject1dw(py::module_& m, const mp_list<Tx, Tw>&) {
m.def("_f1dw", &f1dw<Tx, Tw>, "x"_a.noconvert(), "w"_a.noconvert(), "b"_a, "x1"_a, "x2"_a, "f"_a);
m.def("_f1dmw", &f1dmw<Tx, Tw>, "x"_a.noconvert(), "w"_a.noconvert(), "b"_a, "x1"_a, "x2"_a, "f"_a);
m.def("_v1dw", &v1dw<Tx, Tw>, "x"_a.noconvert(), "w"_a.noconvert(), "b"_a, "f"_a);
m.def("_v1dmw", &v1dmw<Tx, Tw>, "x"_a.noconvert(), "w"_a.noconvert(), "b"_a, "f"_a);
}

template <typename Tx, typename Ty>
void inject2d(py::module_& m, const mp_list<Tx, Ty>&) {
m.def("_f2d", &f2d<Tx, Ty>,
"x"_a.noconvert(), "y"_a.noconvert(),
"binsx"_a, "xmin"_a, "xmax"_a, "binsy"_a, "ymin"_a, "ymax"_a, "bool"_a);

// clang-format on
"bx"_a, "x1"_a, "x2"_a,
"by"_a, "y1"_a, "y2"_a, "f"_a);
}
// clang-format on

PYBIND11_MODULE(_backend, m) {
m.doc() = "pygram11 C++ backend.";
m.def("_omp_get_max_threads", []() { return omp_get_max_threads(); });

inject1d<double>(m);
inject1d<float>(m);
inject1d<py::ssize_t>(m);
inject1d<int>(m);
inject1d<unsigned int>(m);
inject1d<unsigned long>(m);

inject2d<double, double>(m);
mp_for_each<pg_mp_list>([&](const auto& x) { inject1d(m, x); });
mp_for_each<pg_type_weight_pairs>([&](const auto& x) { inject1dw(m, x); });
mp_for_each<pg_type_pairs>([&](const auto& x) { inject2d(m, x); });
}

0 comments on commit 81091aa

Please sign in to comment.