diff --git a/CMakeLists.txt b/CMakeLists.txt index c1fc42c6..1e27fee7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,16 +76,23 @@ find_package(Python COMPONENTS Interpreter Development.Module REQUIRED) # default installation directories: Python pyamrex_set_default_install_dirs_python() -# pybind11 -# builds pybind11 from git (default), form local source or +# nanobind +# builds nanobind from git (default), form local source or # finds an existing install -include(${pyAMReX_SOURCE_DIR}/cmake/dependencies/pybind11.cmake) +include(${pyAMReX_SOURCE_DIR}/cmake/dependencies/nanobind.cmake) # Targets ##################################################################### # # collect all objects for compilation -add_library(pyAMReX MODULE src/pyAMReX.cpp) +nanobind_build_library( + nanobind # Target name + NB_STATIC STABLE_API LTO # Optional flags (see below) +) + +nanobind_add_module(pyAMReX + src/pyAMReX.cpp +) add_library(pyAMReX::pyAMReX ALIAS pyAMReX) # own headers @@ -110,7 +117,7 @@ set_target_properties(pyAMReX PROPERTIES # link dependencies target_link_libraries(pyAMReX PUBLIC AMReX::amrex) -target_link_libraries(pyAMReX PRIVATE pybind11::module pybind11::lto pybind11::windows_extras) +#target_link_libraries(pyAMReX PRIVATE nanobind) #::module nanobind::lto nanobind::windows_extras) # binary name: we will encoded 1D, 2D and 3D in here so we can provide a # wrapper library that pre-compiled all three geometry variants of AMReX @@ -118,14 +125,14 @@ target_link_libraries(pyAMReX PRIVATE pybind11::module pybind11::lto pybind11::w # set Python module properties set_target_properties(pyAMReX PROPERTIES - # hide symbols for combining multiple pybind11 modules downstream & for + # hide symbols for combining multiple nanobind modules downstream & for # reduced binary size CXX_VISIBILITY_PRESET "hidden" CUDA_VISIBILITY_PRESET "hidden" - # name of the pybind-generated python module, which is wrapped in another + # name of the nanobind-generated python module, which is wrapped in another # fluffy front-end modules, so we can extend it with pure Python - ARCHIVE_OUTPUT_NAME amrex_pybind - LIBRARY_OUTPUT_NAME amrex_pybind + ARCHIVE_OUTPUT_NAME amrex_nanobind + LIBRARY_OUTPUT_NAME amrex_nanobind # build output directories - mainly set to run tests from CMake & IDEs ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_PYTHON_OUTPUT_DIRECTORY}/amrex LIBRARY_OUTPUT_DIRECTORY ${CMAKE_PYTHON_OUTPUT_DIRECTORY}/amrex @@ -152,10 +159,10 @@ if(EMSCRIPTEN) set_target_properties(pyAMReX PROPERTIES PREFIX "") else() - pybind11_extension(pyAMReX) + nanobind_extension(pyAMReX) endif() if(NOT MSVC AND NOT ${CMAKE_BUILD_TYPE} MATCHES Debug|RelWithDebInfo) - pybind11_strip(pyAMReX) + nanobind_strip(pyAMReX) endif() # AMReX helper function: propagate CUDA specific target & source properties diff --git a/README.md b/README.md index bbaa4e45..8b2a1e2e 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ pyAMReX depends on the following popular third party software. - a mature [C++17](https://en.wikipedia.org/wiki/C%2B%2B17) compiler, e.g., GCC 8, Clang 7, NVCC 11.0, MSVC 19.15 or newer - [CMake 3.20.0+](https://cmake.org) - [AMReX *development*](https://amrex-codes.github.io): we automatically download and compile a copy of AMReX -- [pybind11](https://github.com/pybind/pybind11/) 2.10.1+: we automatically download and compile a copy of pybind11 ([new BSD](https://github.com/pybind/pybind11/blob/master/LICENSE)) +- [pybind11](https://github.com/pybind/nanobind/) 2.10.1+: we automatically download and compile a copy of pybind11 ([new BSD](https://github.com/pybind/nanobind/blob/master/LICENSE)) - [Python](https://python.org) 3.7+ - [Numpy](https://numpy.org) 1.15+ diff --git a/cmake/dependencies/nanobind.cmake b/cmake/dependencies/nanobind.cmake new file mode 100644 index 00000000..9bf024cc --- /dev/null +++ b/cmake/dependencies/nanobind.cmake @@ -0,0 +1,60 @@ +function(find_nanobind) + if(TARGET nanobind::module) + message(STATUS "nanobind::module target already imported") + elseif(pyAMReX_nanobind_src) + message(STATUS "Compiling local nanobind ...") + message(STATUS "nanobind source path: ${pyAMReX_nanobind_src}") + elseif(pyAMReX_nanobind_internal) + message(STATUS "Downloading nanobind ...") + message(STATUS "nanobind repository: ${pyAMReX_nanobind_repo} (${pyAMReX_nanobind_branch})") + include(FetchContent) + endif() + if(TARGET nanobind::module) + # nothing to do, target already exists in the superbuild + elseif(pyAMReX_nanobind_internal OR pyAMReX_nanobind_src) + set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) + + if(pyAMReX_nanobind_src) + add_subdirectory(${pyAMReX_nanobind_src} _deps/localnanobind-build/) + else() + FetchContent_Declare(fetchednanobind + GIT_REPOSITORY ${pyAMReX_nanobind_repo} + GIT_TAG ${pyAMReX_nanobind_branch} + BUILD_IN_SOURCE 0 + ) + FetchContent_GetProperties(fetchednanobind) + + if(NOT fetchednanobind_POPULATED) + FetchContent_Populate(fetchednanobind) + add_subdirectory(${fetchednanobind_SOURCE_DIR} ${fetchednanobind_BINARY_DIR}) + endif() + + # advanced fetch options + mark_as_advanced(FETCHCONTENT_BASE_DIR) + mark_as_advanced(FETCHCONTENT_FULLY_DISCONNECTED) + mark_as_advanced(FETCHCONTENT_QUIET) + mark_as_advanced(FETCHCONTENT_SOURCE_DIR_FETCHEDnanobind) + mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED) + mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED_FETCHEDnanobind) + endif() + elseif(NOT pyAMReX_nanobind_internal) + find_package(nanobind 1.2.0 CONFIG REQUIRED) + message(STATUS "nanobind: Found version '${nanobind_VERSION}'") + endif() +endfunction() + +# local source-tree +set(pyAMReX_nanobind_src "" + CACHE PATH + "Local path to nanobind source directory (preferred if set)") + +# Git fetcher +option(pyAMReX_nanobind_internal "Download & build nanobind" ON) +set(pyAMReX_nanobind_repo "https://github.com/wjakob/nanobind.git" + CACHE STRING + "Repository URI to pull and build nanobind from if(pyAMReX_nanobind_internal)") +set(pyAMReX_nanobind_branch "v1.2.0" + CACHE STRING + "Repository branch for pyAMReX_nanobind_repo if(pyAMReX_nanobind_internal)") + +find_nanobind() diff --git a/cmake/dependencies/pybind11.cmake b/cmake/dependencies/pybind11.cmake deleted file mode 100644 index 626f5e66..00000000 --- a/cmake/dependencies/pybind11.cmake +++ /dev/null @@ -1,60 +0,0 @@ -function(find_pybind11) - if(TARGET pybind11::module) - message(STATUS "pybind11::module target already imported") - elseif(pyAMReX_pybind11_src) - message(STATUS "Compiling local pybind11 ...") - message(STATUS "pybind11 source path: ${pyAMReX_pybind11_src}") - elseif(pyAMReX_pybind11_internal) - message(STATUS "Downloading pybind11 ...") - message(STATUS "pybind11 repository: ${pyAMReX_pybind11_repo} (${pyAMReX_pybind11_branch})") - include(FetchContent) - endif() - if(TARGET pybind11::module) - # nothing to do, target already exists in the superbuild - elseif(pyAMReX_pybind11_internal OR pyAMReX_pybind11_src) - set(CMAKE_POLICY_DEFAULT_CMP0077 NEW) - - if(pyAMReX_pybind11_src) - add_subdirectory(${pyAMReX_pybind11_src} _deps/localpybind11-build/) - else() - FetchContent_Declare(fetchedpybind11 - GIT_REPOSITORY ${pyAMReX_pybind11_repo} - GIT_TAG ${pyAMReX_pybind11_branch} - BUILD_IN_SOURCE 0 - ) - FetchContent_GetProperties(fetchedpybind11) - - if(NOT fetchedpybind11_POPULATED) - FetchContent_Populate(fetchedpybind11) - add_subdirectory(${fetchedpybind11_SOURCE_DIR} ${fetchedpybind11_BINARY_DIR}) - endif() - - # advanced fetch options - mark_as_advanced(FETCHCONTENT_BASE_DIR) - mark_as_advanced(FETCHCONTENT_FULLY_DISCONNECTED) - mark_as_advanced(FETCHCONTENT_QUIET) - mark_as_advanced(FETCHCONTENT_SOURCE_DIR_FETCHEDpybind11) - mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED) - mark_as_advanced(FETCHCONTENT_UPDATES_DISCONNECTED_FETCHEDpybind11) - endif() - elseif(NOT pyAMReX_pybind11_internal) - find_package(pybind11 2.10.1 CONFIG REQUIRED) - message(STATUS "pybind11: Found version '${pybind11_VERSION}'") - endif() -endfunction() - -# local source-tree -set(pyAMReX_pybind11_src "" - CACHE PATH - "Local path to pybind11 source directory (preferred if set)") - -# Git fetcher -option(pyAMReX_pybind11_internal "Download & build pybind11" ON) -set(pyAMReX_pybind11_repo "https://github.com/pybind/pybind11.git" - CACHE STRING - "Repository URI to pull and build pybind11 from if(pyAMReX_pybind11_internal)") -set(pyAMReX_pybind11_branch "v2.10.1" - CACHE STRING - "Repository branch for pyAMReX_pybind11_repo if(pyAMReX_pybind11_internal)") - -find_pybind11() diff --git a/src/AmrCore/AmrMesh.cpp b/src/AmrCore/AmrMesh.cpp index a49010cb..4be9fead 100644 --- a/src/AmrCore/AmrMesh.cpp +++ b/src/AmrCore/AmrMesh.cpp @@ -6,16 +6,24 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_AmrMesh(py::module &m) { +void init_AmrMesh(py::module_ &m) { py::class_< AmrInfo >(m, "AmrInfo") .def("__repr__", [](AmrInfo const & amr_info) { @@ -27,28 +35,28 @@ void init_AmrMesh(py::module &m) { .def(py::init< >()) - .def_readwrite("verbose", &AmrInfo::verbose) - .def_readwrite("max_level", &AmrInfo::max_level) + .def_rw("verbose", &AmrInfo::verbose) + .def_rw("max_level", &AmrInfo::max_level) // note: https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html#making-opaque-types - //.def_readwrite("ref_ratio", &AmrInfo::ref_ratio) - //.def_readwrite("blocking_factor", &AmrInfo::blocking_factor) - //.def_readwrite("max_grid_size", &AmrInfo::max_grid_size) - //.def_readwrite("n_error_buf", &AmrInfo::n_error_buf) + //.def_rw("ref_ratio", &AmrInfo::ref_ratio) + //.def_rw("blocking_factor", &AmrInfo::blocking_factor) + //.def_rw("max_grid_size", &AmrInfo::max_grid_size) + //.def_rw("n_error_buf", &AmrInfo::n_error_buf) .def("ref_ratio", [](AmrInfo const & amr_info, int lev){ return amr_info.ref_ratio.at(lev); }) .def("blocking_factor", [](AmrInfo const & amr_info, int lev){ return amr_info.blocking_factor.at(lev); }) .def("max_grid_size", [](AmrInfo const & amr_info, int lev){ return amr_info.max_grid_size.at(lev); }) .def("n_error_buf", [](AmrInfo const & amr_info, int lev){ return amr_info.n_error_buf.at(lev); }) - .def_readwrite("grid_eff", &AmrInfo::grid_eff) - .def_readwrite("n_proper", &AmrInfo::n_proper) - .def_readwrite("use_fixed_upto_level", &AmrInfo::use_fixed_upto_level) - .def_readwrite("use_fixed_coarse_grids", &AmrInfo::use_fixed_coarse_grids) - .def_readwrite("refine_grid_layout", &AmrInfo::refine_grid_layout) - .def_readwrite("refine_grid_layout_dims", &AmrInfo::refine_grid_layout_dims) - .def_readwrite("check_input", &AmrInfo::check_input) - .def_readwrite("use_new_chop", &AmrInfo::use_new_chop) - .def_readwrite("iterate_on_new_grids", &AmrInfo::iterate_on_new_grids) + .def_rw("grid_eff", &AmrInfo::grid_eff) + .def_rw("n_proper", &AmrInfo::n_proper) + .def_rw("use_fixed_upto_level", &AmrInfo::use_fixed_upto_level) + .def_rw("use_fixed_coarse_grids", &AmrInfo::use_fixed_coarse_grids) + .def_rw("refine_grid_layout", &AmrInfo::refine_grid_layout) + .def_rw("refine_grid_layout_dims", &AmrInfo::refine_grid_layout_dims) + .def_rw("check_input", &AmrInfo::check_input) + .def_rw("use_new_chop", &AmrInfo::use_new_chop) + .def_rw("iterate_on_new_grids", &AmrInfo::iterate_on_new_grids) ; diff --git a/src/Base/AMReX.cpp b/src/Base/AMReX.cpp index 51146411..719e5b19 100644 --- a/src/Base/AMReX.cpp +++ b/src/Base/AMReX.cpp @@ -3,19 +3,27 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; namespace amrex { struct Config {}; } -void init_AMReX(py::module& m) +void init_AMReX(py::module_& m) { py::class_(m, "AMReX") .def_static("empty", &AMReX::empty) @@ -26,18 +34,18 @@ void init_AMReX(py::module& m) ; py::class_(m, "Config") - .def_property_readonly_static( + .def_prop_rw_static( "amrex_version", [](py::object) { return Version(); }, "AMReX library version") - .def_property_readonly_static( + .def_prop_rw_static( "spacedim", [](py::object) { return AMREX_SPACEDIM; }) - .def_property_static( + .def_prop_rw_static( "verbose", [](py::object) { return Verbose(); }, [](py::object, const int v) { SetVerbose(v); }) - .def_property_readonly_static( + .def_prop_rw_static( "have_mpi", [](py::object){ #ifdef AMREX_USE_MPI @@ -46,7 +54,7 @@ void init_AMReX(py::module& m) return false; #endif }) - .def_property_readonly_static( + .def_prop_rw_static( "have_gpu", [](py::object){ #ifdef AMREX_USE_GPU @@ -55,7 +63,7 @@ void init_AMReX(py::module& m) return false; #endif }) - .def_property_readonly_static( + .def_prop_rw_static( "have_omp", [](py::object){ #ifdef AMREX_USE_OMP @@ -64,7 +72,7 @@ void init_AMReX(py::module& m) return false; #endif }) - .def_property_readonly_static( + .def_prop_rw_static( "gpu_backend", [](py::object){ #ifdef AMREX_USE_CUDA @@ -109,7 +117,7 @@ void init_AMReX(py::module& m) // This is a convenience helper/bandage for making work with Python // garbage collectors in various implementations more easy. // https://github.com/AMReX-Codes/pyamrex/issues/81 - auto m_gc = py::module::import("gc"); + auto m_gc = py::module_::import_("gc"); auto collect = m_gc.attr("collect"); collect(); }; diff --git a/src/Base/Arena.cpp b/src/Base/Arena.cpp index cb018179..3c373bf9 100644 --- a/src/Base/Arena.cpp +++ b/src/Base/Arena.cpp @@ -5,15 +5,23 @@ */ #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_Arena(py::module &m) { +void init_Arena(py::module_ &m) { py::class_< Arena >(m, "Arena"); m.def("The_Arena", &The_Arena, py::return_value_policy::reference) diff --git a/src/Base/Array4.cpp b/src/Base/Array4.cpp index 1807372b..8c94a394 100644 --- a/src/Base/Array4.cpp +++ b/src/Base/Array4.cpp @@ -7,15 +7,23 @@ #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; @@ -75,7 +83,7 @@ namespace template< typename T > -void make_Array4(py::module &m, std::string typestr) +void make_Array4(py::module_ &m, std::string typestr) { // dispatch simpler via: py::format_descriptor::format() naming auto const array_name = std::string("Array4_").append(typestr); @@ -92,9 +100,9 @@ void make_Array4(py::module &m, std::string typestr) .def("index_assert", &Array4::index_assert) #endif - .def_property_readonly("size", &Array4::size) - .def_property_readonly("nComp", &Array4::nComp) - .def_property_readonly("num_comp", &Array4::nComp) + .def_prop_rw_readonly("size", &Array4::size) + .def_prop_rw_readonly("nComp", &Array4::nComp) + .def_prop_rw_readonly("num_comp", &Array4::nComp) .def(py::init< >()) .def(py::init< Array4 const & >()) @@ -147,7 +155,7 @@ void make_Array4(py::module &m, std::string typestr) // CPU: __array_interface__ v3 // https://numpy.org/doc/stable/reference/arrays.interface.html - .def_property_readonly("__array_interface__", [](Array4 const & a4) { + .def_prop_rw_readonly("__array_interface__", [](Array4 const & a4) { return array_interface(a4); }) @@ -161,7 +169,7 @@ void make_Array4(py::module &m, std::string typestr) // Nvidia GPUs: __cuda_array_interface__ v3 // https://numba.readthedocs.io/en/latest/cuda/cuda_array_interface.html - .def_property_readonly("__cuda_array_interface__", [](Array4 const & a4) { + .def_prop_rw_readonly("__cuda_array_interface__", [](Array4 const & a4) { auto d = array_interface(a4); // data: @@ -219,7 +227,7 @@ void make_Array4(py::module &m, std::string typestr) m.def("makePolymorphic", &makePolymorphic< Array4 >); } -void init_Array4(py::module &m) { +void init_Array4(py::module_ &m) { make_Array4< float >(m, "float"); make_Array4< double >(m, "double"); make_Array4< long double >(m, "longdouble"); diff --git a/src/Base/BaseFab.cpp b/src/Base/BaseFab.cpp index e5d696f6..e7b00050 100644 --- a/src/Base/BaseFab.cpp +++ b/src/Base/BaseFab.cpp @@ -5,18 +5,26 @@ */ #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; namespace { template< typename T > - void init_bf(py::module &m, std::string typestr) { + void init_bf(py::module_ &m, std::string typestr) { auto const bf_name = std::string("BaseFab_").append(typestr); py::class_< BaseFab >(m, bf_name.c_str()) .def("__repr__", @@ -121,6 +129,6 @@ namespace } } -void init_BaseFab(py::module &m) { +void init_BaseFab(py::module_ &m) { init_bf(m, "Real"); } diff --git a/src/Base/Box.cpp b/src/Base/Box.cpp index 404d8c90..6c317df0 100644 --- a/src/Base/Box.cpp +++ b/src/Base/Box.cpp @@ -7,14 +7,21 @@ #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; namespace @@ -65,7 +72,7 @@ namespace }; } -void init_Box(py::module &m) { +void init_Box(py::module_ &m) { py::class_< Direction >(m, "Direction"); @@ -106,24 +113,24 @@ void init_Box(py::module &m) { py::arg("small"), py::arg("big"), py::arg("t") ) - .def_property_readonly("lo_vect", [](Box const & bx){ return bx.smallEnd(); }) - .def_property_readonly("hi_vect", [](Box const & bx){ return bx.bigEnd(); }) - .def_property_readonly("small_end", [](Box const & bx){ return bx.smallEnd(); }) - .def_property_readonly("big_end", [](Box const & bx){ return bx.bigEnd(); }) + .def_prop_rw_readonly("lo_vect", [](Box const & bx){ return bx.smallEnd(); }) + .def_prop_rw_readonly("hi_vect", [](Box const & bx){ return bx.bigEnd(); }) + .def_prop_rw_readonly("small_end", [](Box const & bx){ return bx.smallEnd(); }) + .def_prop_rw_readonly("big_end", [](Box const & bx){ return bx.bigEnd(); }) /* - .def_property("small_end", + .def_prop_rw("small_end", py::overload_cast<>(&Box::smallEnd, py::const_), py::overload_cast< IntVect const & >(&Box::setSmall)) - .def_property("big_end", + .def_prop_rw("big_end", &Box::bigEnd, &Box::setBig) */ - .def_property("type", + .def_prop_rw("type", py::overload_cast<>(&Box::type, py::const_), &Box::setType) - .def_property_readonly("ix_type", &Box::ixType) - .def_property_readonly("size", &Box::size) + .def_prop_rw_readonly("ix_type", &Box::ixType) + .def_prop_rw_readonly("size", &Box::size) .def("length", py::overload_cast<>(&Box::length, py::const_), @@ -134,14 +141,14 @@ void init_Box(py::module &m) { .def("numPts", &Box::numPts, "Return the number of points in the Box.") - .def_property_readonly("is_empty", &Box::isEmpty) - .def_property_readonly("ok", &Box::ok) - .def_property_readonly("cell_centered", &Box::cellCentered) - .def_property_readonly("num_pts", &Box::numPts) - .def_property_readonly("d_num_pts", &Box::d_numPts) - .def_property_readonly("volume", &Box::volume) - .def_property_readonly("the_unit_box", &Box::TheUnitBox) - .def_property_readonly("is_square", &Box::isSquare) + .def_prop_rw_readonly("is_empty", &Box::isEmpty) + .def_prop_rw_readonly("ok", &Box::ok) + .def_prop_rw_readonly("cell_centered", &Box::cellCentered) + .def_prop_rw_readonly("num_pts", &Box::numPts) + .def_prop_rw_readonly("d_num_pts", &Box::d_numPts) + .def_prop_rw_readonly("volume", &Box::volume) + .def_prop_rw_readonly("the_unit_box", &Box::TheUnitBox) + .def_prop_rw_readonly("is_square", &Box::isSquare) .def("contains", py::overload_cast< IntVect const & >(&Box::contains, py::const_)) diff --git a/src/Base/BoxArray.cpp b/src/Base/BoxArray.cpp index f025b609..3ceca5c1 100644 --- a/src/Base/BoxArray.cpp +++ b/src/Base/BoxArray.cpp @@ -7,16 +7,24 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_BoxArray(py::module &m) { +void init_BoxArray(py::module_ &m) { /* A collection of Boxes stored in an Array. It is a * reference-counted concrete class, not a polymorphic one; i.e. you * cannot use any of the List member functions with a BoxList @@ -50,19 +58,19 @@ void init_BoxArray(py::module &m) { BoxArray (BoxList&& bl, IntVect const& max_grid_size); */ - .def_property_readonly("size", &BoxArray::size) - .def_property_readonly("capacity", &BoxArray::capacity) - .def_property_readonly("empty", &BoxArray::empty) - .def_property_readonly("numPts", &BoxArray::numPts) - .def_property_readonly("d_numPts", &BoxArray::d_numPts) + .def_prop_rw_readonly("size", &BoxArray::size) + .def_prop_rw_readonly("capacity", &BoxArray::capacity) + .def_prop_rw_readonly("empty", &BoxArray::empty) + .def_prop_rw_readonly("numPts", &BoxArray::numPts) + .def_prop_rw_readonly("d_numPts", &BoxArray::d_numPts) /* - .def_property("type", + .def_prop_rw("type", py::overload_cast<>(&BoxArray::type, py::const_), &Box::setType) - .def_property_readonly("length", + .def_prop_rw_readonly("length", py::overload_cast<>(&Box::length, py::const_)) - .def_property_readonly("is_empty", &Box::isEmpty) + .def_prop_rw_readonly("is_empty", &Box::isEmpty) */ .def("define", diff --git a/src/Base/CoordSys.cpp b/src/Base/CoordSys.cpp index 689e4fbb..88931f31 100644 --- a/src/Base/CoordSys.cpp +++ b/src/Base/CoordSys.cpp @@ -1,15 +1,23 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_CoordSys(py::module& m) +void init_CoordSys(py::module_& m) { py::class_ coord_sys(m, "CoordSys"); coord_sys.def("__repr__", diff --git a/src/Base/Dim3.cpp b/src/Base/Dim3.cpp index 21381fbc..a18fff05 100644 --- a/src/Base/Dim3.cpp +++ b/src/Base/Dim3.cpp @@ -1,15 +1,23 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_Dim3(py::module& m) +void init_Dim3(py::module_& m) { py::class_(m, "Dim3") .def("__repr__", @@ -27,15 +35,15 @@ void init_Dim3(py::module& m) } ) .def(py::init()) - .def_readwrite("x", &Dim3::x) - .def_readwrite("y", &Dim3::y) - .def_readwrite("z", &Dim3::z) + .def_rw("x", &Dim3::x) + .def_rw("y", &Dim3::y) + .def_rw("z", &Dim3::z) ; py::class_(m, "XDim3") .def(py::init()) - .def_readwrite("x", &XDim3::x) - .def_readwrite("y", &XDim3::y) - .def_readwrite("z", &XDim3::z) + .def_rw("x", &XDim3::x) + .def_rw("y", &XDim3::y) + .def_rw("z", &XDim3::z) ; } diff --git a/src/Base/DistributionMapping.cpp b/src/Base/DistributionMapping.cpp index c7b536b4..dcac649c 100644 --- a/src/Base/DistributionMapping.cpp +++ b/src/Base/DistributionMapping.cpp @@ -8,16 +8,24 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_DistributionMapping(py::module &m) { +void init_DistributionMapping(py::module_ &m) { py::class_< DistributionMapping >(m, "DistributionMapping") .def("__repr__", [](DistributionMapping const & dm) { @@ -55,12 +63,12 @@ void init_DistributionMapping(py::module &m) { //.def("define", // py::overload_cast< Vector< int > && >(&DistributionMapping::define)) //! Length of the underlying processor map. - .def_property_readonly("size", &DistributionMapping::size) - .def_property_readonly("capacity", &DistributionMapping::capacity) - .def_property_readonly("empty", &DistributionMapping::empty) + .def_prop_rw_readonly("size", &DistributionMapping::size) + .def_prop_rw_readonly("capacity", &DistributionMapping::capacity) + .def_prop_rw_readonly("empty", &DistributionMapping::empty) //! Number of references to this DistributionMapping - .def_property_readonly("link_count", &DistributionMapping::linkCount) + .def_prop_rw_readonly("link_count", &DistributionMapping::linkCount) /** * \brief Returns a constant reference to the mapping of boxes in the diff --git a/src/Base/FArrayBox.cpp b/src/Base/FArrayBox.cpp index 76590df4..1731bcb6 100644 --- a/src/Base/FArrayBox.cpp +++ b/src/Base/FArrayBox.cpp @@ -5,18 +5,26 @@ */ #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_FArrayBox(py::module &m) { +void init_FArrayBox(py::module_ &m) { py::class_< FArrayBox, BaseFab >(m, "FArrayBox") .def("__repr__", [](FArrayBox const & /* fab */) { diff --git a/src/Base/Geometry.cpp b/src/Base/Geometry.cpp index bab92b77..ab616947 100644 --- a/src/Base/Geometry.cpp +++ b/src/Base/Geometry.cpp @@ -4,18 +4,26 @@ #include #include -#include -// #include -#include +#include +// #include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_Geometry(py::module& m) +void init_Geometry(py::module_& m) { py::class_(m, "GeometryData") .def("__repr__", @@ -24,17 +32,17 @@ void init_Geometry(py::module& m) } ) .def(py::init<>()) - .def_readonly("prob_domain", &GeometryData::prob_domain) - .def_readonly("domain", &GeometryData::domain) - .def_readonly("coord", &GeometryData::coord) - .def_property_readonly("dx", + .def_ro("prob_domain", &GeometryData::prob_domain) + .def_ro("domain", &GeometryData::domain) + .def_ro("coord", &GeometryData::coord) + .def_prop_rw_readonly("dx", [](const GeometryData& gd){ std::array dx {AMREX_D_DECL( gd.dx[0], gd.dx[1], gd.dx[2] )}; return dx; }) - .def_property_readonly("is_periodic", + .def_prop_rw_readonly("is_periodic", [](const GeometryData& gd){ std::array per {AMREX_D_DECL( gd.is_periodic[0], gd.is_periodic[1], gd.is_periodic[2] diff --git a/src/Base/IntVect.cpp b/src/Base/IntVect.cpp index e3544890..ac37bf29 100644 --- a/src/Base/IntVect.cpp +++ b/src/Base/IntVect.cpp @@ -7,19 +7,27 @@ #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_IntVect(py::module &m) { +void init_IntVect(py::module_ &m) { py::class_< IntVect >(m, "IntVect") .def("__repr__", [](py::object& obj) { @@ -45,10 +53,10 @@ void init_IntVect(py::module &m) { .def(py::init()) .def(py::init&>()) - .def_property_readonly("sum", &IntVect::sum) - .def_property_readonly("max", + .def_prop_rw_readonly("sum", &IntVect::sum) + .def_prop_rw_readonly("max", py::overload_cast<>(&IntVect::max, py::const_)) - .def_property_readonly("min", + .def_prop_rw_readonly("min", py::overload_cast<>(&IntVect::min, py::const_)) .def_static("zero_vector", &IntVect::TheZeroVector) .def_static("unit_vector", &IntVect::TheUnitVector) diff --git a/src/Base/Iterator.H b/src/Base/Iterator.H index cf814d99..72b25574 100644 --- a/src/Base/Iterator.H +++ b/src/Base/Iterator.H @@ -13,13 +13,21 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; namespace pyAMReX @@ -31,7 +39,7 @@ namespace pyAMReX * explicitly, otherwise we will jump directly to the 2nd element. We do * this the same way as pybind11 does this, via a little state: * https://github.com/AMReX-Codes/pyamrex/pull/50 - * https://github.com/pybind/pybind11/blob/v2.10.0/include/pybind11/pybind11.h#L2269-L2282 + * https://github.com/pybind/nanobind/blob/v2.10.0/include/nanobind/nanobind.h#L2269-L2282 * * To avoid unnecessary (and expensive) copies, remember to only call this * helper always with py::return_value_policy::reference_internal! diff --git a/src/Base/MultiFab.cpp b/src/Base/MultiFab.cpp index deb65551..84ae946a 100644 --- a/src/Base/MultiFab.cpp +++ b/src/Base/MultiFab.cpp @@ -13,21 +13,29 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_MultiFab(py::module &m) { +void init_MultiFab(py::module_ &m) { py::class_< MFInfo >(m, "MFInfo") - .def_readwrite("alloc", &MFInfo::alloc) - .def_readwrite("arena", &MFInfo::arena) - .def_readwrite("tags", &MFInfo::tags) + .def_rw("alloc", &MFInfo::alloc) + .def_rw("arena", &MFInfo::arena) + .def_rw("tags", &MFInfo::tags) .def(py::init< >()) @@ -38,17 +46,17 @@ void init_MultiFab(py::module &m) { ; py::class_< FabArrayBase >(m, "FabArrayBase") - .def_property_readonly("is_all_cell_centered", &FabArrayBase::is_cell_centered) - .def_property_readonly("is_all_nodal", + .def_prop_rw_readonly("is_all_cell_centered", &FabArrayBase::is_cell_centered) + .def_prop_rw_readonly("is_all_nodal", py::overload_cast< >(&FabArrayBase::is_nodal, py::const_)) .def("is_nodal", py::overload_cast< int >(&FabArrayBase::is_nodal, py::const_)) - .def_property_readonly("nComp", &FabArrayBase::nComp) - .def_property_readonly("num_comp", &FabArrayBase::nComp) - .def_property_readonly("size", &FabArrayBase::size) + .def_prop_rw_readonly("nComp", &FabArrayBase::nComp) + .def_prop_rw_readonly("num_comp", &FabArrayBase::nComp) + .def_prop_rw_readonly("size", &FabArrayBase::size) - .def_property_readonly("nGrowVect", &FabArrayBase::nGrowVect) + .def_prop_rw_readonly("nGrowVect", &FabArrayBase::nGrowVect) /* data access in Box index space */ .def("__iter__", @@ -107,9 +115,9 @@ void init_MultiFab(py::module &m) { py::overload_cast< int, const IntVect& >(&MFIter::grownnodaltilebox, py::const_), py::arg("int"), py::arg("ng")) - .def_property_readonly("is_valid", &MFIter::isValid) - .def_property_readonly("index", &MFIter::index) - .def_property_readonly("length", &MFIter::length) + .def_prop_rw_readonly("is_valid", &MFIter::isValid) + .def_prop_rw_readonly("index", &MFIter::index) + .def_prop_rw_readonly("length", &MFIter::length) ; py::class_< FabArray, FabArrayBase >(m, "FabArray_FArrayBox") diff --git a/src/Base/PODVector.cpp b/src/Base/PODVector.cpp index 0a746561..cd5e3757 100644 --- a/src/Base/PODVector.cpp +++ b/src/Base/PODVector.cpp @@ -6,14 +6,22 @@ #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; namespace @@ -38,7 +46,7 @@ namespace } template > -void make_PODVector(py::module &m, std::string typestr, std::string allocstr) +void make_PODVector(py::module_ &m, std::string typestr, std::string allocstr) { using PODVector_type = PODVector; auto const podv_name = std::string("PODVector_").append(typestr) @@ -81,10 +89,10 @@ void make_PODVector(py::module &m, std::string typestr, std::string allocstr) // // swap - .def_property_readonly("__array_interface__", [](PODVector_type const & podvector) { + .def_prop_rw_readonly("__array_interface__", [](PODVector_type const & podvector) { return array_interface(podvector); }) - .def_property_readonly("__cuda_array_interface__", [](PODVector_type const & podvector) { + .def_prop_rw_readonly("__cuda_array_interface__", [](PODVector_type const & podvector) { // Nvidia GPUs: __cuda_array_interface__ v3 // https://numba.readthedocs.io/en/latest/cuda/cuda_array_interface.html auto d = array_interface(podvector); @@ -112,7 +120,7 @@ void make_PODVector(py::module &m, std::string typestr, std::string allocstr) } template -void make_PODVector(py::module &m, std::string typestr) +void make_PODVector(py::module_ &m, std::string typestr) { // see Src/Base/AMReX_GpuContainers.H make_PODVector> (m, typestr, "std"); @@ -125,7 +133,7 @@ void make_PODVector(py::module &m, std::string typestr) #endif } -void init_PODVector(py::module& m) { +void init_PODVector(py::module_& m) { make_PODVector (m, "real"); make_PODVector (m, "int"); } diff --git a/src/Base/ParallelDescriptor.cpp b/src/Base/ParallelDescriptor.cpp index 257941d4..89712237 100644 --- a/src/Base/ParallelDescriptor.cpp +++ b/src/Base/ParallelDescriptor.cpp @@ -6,18 +6,26 @@ #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_ParallelDescriptor(py::module &m) { +void init_ParallelDescriptor(py::module_ &m) { auto mpd = m.def_submodule("ParallelDescriptor"); mpd.def("NProcs", py::overload_cast<>(&ParallelDescriptor::NProcs)); diff --git a/src/Base/ParmParse.cpp b/src/Base/ParmParse.cpp index f3be0871..f550d8b7 100644 --- a/src/Base/ParmParse.cpp +++ b/src/Base/ParmParse.cpp @@ -8,18 +8,26 @@ #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_ParmParse(py::module &m) { +void init_ParmParse(py::module_ &m) { py::class_(m, "ParmParse") .def("__repr__", [](ParmParse const &) { diff --git a/src/Base/Periodicity.cpp b/src/Base/Periodicity.cpp index e791185a..48654ae3 100644 --- a/src/Base/Periodicity.cpp +++ b/src/Base/Periodicity.cpp @@ -8,17 +8,25 @@ #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_Periodicity(py::module &m) { +void init_Periodicity(py::module_ &m) { py::class_< Periodicity >(m, "Periodicity") .def("__repr__", [](Periodicity const & p) { @@ -35,11 +43,11 @@ void init_Periodicity(py::module &m) { .def(py::init<>()) .def(py::init< IntVect const & >()) - .def_property_readonly("is_any_periodic", &Periodicity::isAnyPeriodic) - .def_property_readonly("is_all_periodic", &Periodicity::isAllPeriodic) - .def_property_readonly("domain", &Periodicity::Domain, + .def_prop_rw_readonly("is_any_periodic", &Periodicity::isAnyPeriodic) + .def_prop_rw_readonly("is_all_periodic", &Periodicity::isAllPeriodic) + .def_prop_rw_readonly("domain", &Periodicity::Domain, "Cell-centered domain Box \"infinitely\" long in non-periodic directions.") - .def_property_readonly("shift_IntVect", &Periodicity::shiftIntVect) + .def_prop_rw_readonly("shift_IntVect", &Periodicity::shiftIntVect) .def("is_periodic", &Periodicity::isPeriodic, py::arg("dir")) diff --git a/src/Base/RealBox.cpp b/src/Base/RealBox.cpp index da62ddf3..6e77d475 100644 --- a/src/Base/RealBox.cpp +++ b/src/Base/RealBox.cpp @@ -12,19 +12,27 @@ #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_RealBox(py::module &m) { +void init_RealBox(py::module_ &m) { py::class_< RealBox >(m, "RealBox") .def("__repr__", @@ -62,7 +70,7 @@ void init_RealBox(py::module &m) { py::arg("bx"), py::arg("dx"), py::arg("base") ) - .def_property_readonly( + .def_prop_rw_readonly( "xlo", [](RealBox const & rb){ std::array xlo {AMREX_D_DECL( @@ -71,7 +79,7 @@ void init_RealBox(py::module &m) { return xlo; } ) - .def_property_readonly( + .def_prop_rw_readonly( "xhi", [](RealBox const & rb){ std::array xhi {AMREX_D_DECL( diff --git a/src/Base/RealVect.cpp b/src/Base/RealVect.cpp index 2cafc9da..d373845b 100644 --- a/src/Base/RealVect.cpp +++ b/src/Base/RealVect.cpp @@ -7,19 +7,27 @@ #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; -void init_RealVect(py::module &m) { +void init_RealVect(py::module_ &m) { py::class_< RealVect>(m, "RealVect") .def("__repr__", @@ -116,10 +124,10 @@ void init_RealVect(py::module &m) { .def(+py::self) .def(-py::self) - .def_property_readonly("sum", &RealVect::sum, "Sum of the components of this vector") - .def_property_readonly("vectorLength", &RealVect::vectorLength, "Length or 2-Norm of this vector") - .def_property_readonly("radSquared", &RealVect::radSquared, "Length squared of this vector") - .def_property_readonly("product", &RealVect::product, "Product of entries of this vector") + .def_prop_rw_readonly("sum", &RealVect::sum, "Sum of the components of this vector") + .def_prop_rw_readonly("vectorLength", &RealVect::vectorLength, "Length or 2-Norm of this vector") + .def_prop_rw_readonly("radSquared", &RealVect::radSquared, "Length squared of this vector") + .def_prop_rw_readonly("product", &RealVect::product, "Product of entries of this vector") .def("minDir", &RealVect::minDir, "direction or index of minimum value of this vector") .def("maxDir", &RealVect::maxDir, "direction or index of maximum value of this vector") diff --git a/src/Base/Vector.cpp b/src/Base/Vector.cpp index 8d1000f9..404a954c 100644 --- a/src/Base/Vector.cpp +++ b/src/Base/Vector.cpp @@ -6,10 +6,18 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -17,7 +25,7 @@ #include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; namespace @@ -42,7 +50,7 @@ namespace } template > -void make_Vector(py::module &m, std::string typestr) +void make_Vector(py::module_ &m, std::string typestr) { using Vector_type = Vector; auto const v_name = std::string("Vector_").append(typestr); @@ -66,10 +74,10 @@ void make_Vector(py::module &m, std::string typestr) .def("size", &Vector_type::size) - .def_property_readonly("__array_interface__", [](Vector_type const & vector) { + .def_prop_rw_readonly("__array_interface__", [](Vector_type const & vector) { return array_interface(vector); }) - .def_property_readonly("__cuda_array_interface__", [](Vector_type const & vector) { + .def_prop_rw_readonly("__cuda_array_interface__", [](Vector_type const & vector) { // Nvidia GPUs: __cuda_array_interface__ v3 // https://numba.readthedocs.io/en/latest/cuda/cuda_array_interface.html auto d = array_interface(vector); @@ -97,7 +105,7 @@ void make_Vector(py::module &m, std::string typestr) ; } -void init_Vector(py::module& m) { +void init_Vector(py::module_& m) { make_Vector (m, "Real"); if constexpr(!std::is_same_v) make_Vector (m, "ParticleReal"); diff --git a/src/Particle/ArrayOfStructs.cpp b/src/Particle/ArrayOfStructs.cpp index 8d31b4fa..206d497c 100644 --- a/src/Particle/ArrayOfStructs.cpp +++ b/src/Particle/ArrayOfStructs.cpp @@ -7,12 +7,20 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; namespace @@ -63,7 +71,7 @@ namespace template class Allocator=DefaultAllocator> -void make_ArrayOfStructs(py::module &m, std::string allocstr) +void make_ArrayOfStructs(py::module_ &m, std::string allocstr) { using AOSType = ArrayOfStructs; using ParticleType = T_ParticleType; @@ -91,10 +99,10 @@ void make_ArrayOfStructs(py::module &m, std::string allocstr) .def("back", py::overload_cast<>(&AOSType::back),"get back member. Problem!!!!! this is perfo") // setter & getter - .def_property_readonly("__array_interface__", [](AOSType const & aos) { + .def_prop_rw_readonly("__array_interface__", [](AOSType const & aos) { return array_interface(aos); }) - .def_property_readonly("__cuda_array_interface__", [](AOSType const & aos) { + .def_prop_rw_readonly("__cuda_array_interface__", [](AOSType const & aos) { // Nvidia GPUs: __cuda_array_interface__ v3 // https://numba.readthedocs.io/en/latest/cuda/cuda_array_interface.html auto d = array_interface(aos); @@ -122,7 +130,7 @@ void make_ArrayOfStructs(py::module &m, std::string allocstr) } template -void make_ArrayOfStructs(py::module &m) +void make_ArrayOfStructs(py::module_ &m) { // AMReX legacy AoS position + id/cpu particle ype using ParticleType = Particle; @@ -131,7 +139,7 @@ void make_ArrayOfStructs(py::module &m) // !AMREX_USE_GPU: DefaultAllocator = std::allocator // AMREX_USE_GPU: DefaultAllocator = amrex::ArenaAllocator - // work-around for https://github.com/pybind/pybind11/pull/4581 + // work-around for https://github.com/pybind/nanobind/pull/4581 //make_ArrayOfStructs (m, "std"); //make_ArrayOfStructs (m, "arena"); #ifdef AMREX_USE_GPU @@ -150,7 +158,7 @@ void make_ArrayOfStructs(py::module &m) #endif } -void init_ArrayOfStructs(py::module& m) { +void init_ArrayOfStructs(py::module_& m) { make_ArrayOfStructs<0, 0> (m); // WarpX 22.07, ImpactX 22.07, HiPACE++ 22.07 make_ArrayOfStructs<1, 1> (m); // test in ParticleContainer make_ArrayOfStructs<2, 1> (m); // test diff --git a/src/Particle/Particle.cpp b/src/Particle/Particle.cpp index 9ea4f275..657c44cd 100644 --- a/src/Particle/Particle.cpp +++ b/src/Particle/Particle.cpp @@ -9,9 +9,17 @@ #include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -23,7 +31,7 @@ #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; using pReal = amrex_particle_real; @@ -54,7 +62,7 @@ namespace } template -void make_Particle(py::module &m) +void make_Particle(py::module_ &m) { using ParticleType = Particle; auto const particle_name = std::string("Particle_").append(std::to_string(T_NReal) + "_" + std::to_string(T_NInt)); @@ -169,8 +177,8 @@ void make_Particle(py::module &m) s << p; return s.str(); }) - .def_readonly_static("NReal", &ParticleType::NReal) - .def_readonly_static("NInt", &ParticleType::NInt) + .def_ro_static("NReal", &ParticleType::NReal) + .def_ro_static("NInt", &ParticleType::NInt) .def("pos", [](const ParticleType &p, int index) { return p.pos(index); }) .def("pos", [](const ParticleType &p) { return p.pos(); }) .def("setPos", [](ParticleType &p, int index, Real val) { AMREX_ASSERT(index > 0 && index < AMREX_SPACEDIM); p.m_pos[index] = val; }) @@ -293,19 +301,19 @@ void make_Particle(py::module &m) .def("id", [](const ParticleType &p) { const int m_id = p.id(); return m_id; }) .def("NextID", [](const ParticleType &p) {return p.NextID();}) .def("NextID", [](const ParticleType &p, Long nextid) { p.NextID(nextid); }) - .def_property("x", [](ParticleType &p){ return p.pos(0);}, [](ParticleType &p, Real val){ p.m_pos[0] = val; }) + .def_prop_rw("x", [](ParticleType &p){ return p.pos(0);}, [](ParticleType &p, Real val){ p.m_pos[0] = val; }) #if (AMREX_SPACEDIM >= 2) - .def_property("y", [](ParticleType &p){ return p.pos(1);}, [](ParticleType &p, Real val){ p.m_pos[1] = val; }) + .def_prop_rw("y", [](ParticleType &p){ return p.pos(1);}, [](ParticleType &p, Real val){ p.m_pos[1] = val; }) #endif #if (AMREX_SPACEDIM == 3) - .def_property("z", [](ParticleType &p){ return p.pos(2);}, [](ParticleType &p, Real val){ p.m_pos[2] = val; }) + .def_prop_rw("z", [](ParticleType &p){ return p.pos(2);}, [](ParticleType &p, Real val){ p.m_pos[2] = val; }) #endif ; } -void init_Particle(py::module& m) { +void init_Particle(py::module_& m) { // TODO: we might need to move all or most of the defines in here into a // test/example submodule, so they do not collide with downstream projects diff --git a/src/Particle/ParticleContainer.H b/src/Particle/ParticleContainer.H index 02f5c34f..0400d080 100644 --- a/src/Particle/ParticleContainer.H +++ b/src/Particle/ParticleContainer.H @@ -18,13 +18,21 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -namespace py = pybind11; +namespace py = nanobind; template std::string particle_type_suffix () @@ -44,7 +52,7 @@ std::string particle_type_suffix () } template -void make_Base_Iterators (py::module &m, std::string allocstr) +void make_Base_Iterators (py::module_ &m, std::string allocstr) { using iterator_base = T_ParIterBase; using container = typename iterator_base::ContainerType; @@ -67,12 +75,12 @@ void make_Base_Iterators (py::module &m, std::string allocstr) .def("soa", &iterator_base::GetStructOfArrays, py::return_value_policy::reference_internal) - .def_property_readonly_static("is_soa_particle", [](const py::object&){ return ParticleType::is_soa_particle;}) - .def_property_readonly("num_particles", &iterator_base::numParticles) - .def_property_readonly("num_real_particles", &iterator_base::numRealParticles) - .def_property_readonly("num_neighbor_particles", &iterator_base::numNeighborParticles) - .def_property_readonly("level", &iterator_base::GetLevel) - .def_property_readonly("pair_index", &iterator_base::GetPairIndex) + .def_prop_rw_static("is_soa_particle", [](const py::object&){ return ParticleType::is_soa_particle;}) + .def_prop_rw_readonly("num_particles", &iterator_base::numParticles) + .def_prop_rw_readonly("num_real_particles", &iterator_base::numRealParticles) + .def_prop_rw_readonly("num_neighbor_particles", &iterator_base::numNeighborParticles) + .def_prop_rw_readonly("level", &iterator_base::GetLevel) + .def_prop_rw_readonly("pair_index", &iterator_base::GetPairIndex) .def("geom", &iterator_base::Geom, py::arg("level")) // eq. to void operator++() @@ -96,7 +104,7 @@ void make_Base_Iterators (py::module &m, std::string allocstr) } template class Allocator=DefaultAllocator> -void make_Iterators (py::module &m, std::string allocstr) +void make_Iterators (py::module_ &m, std::string allocstr) { using iterator = T_ParIter; using container = typename iterator::ContainerType; @@ -124,12 +132,12 @@ void make_Iterators (py::module &m, std::string allocstr) py::arg("particle_container"), py::arg("level")) .def(py::init(), py::arg("particle_container"), py::arg("level"), py::arg("info")) - .def_property_readonly_static("is_soa_particle", [](const py::object&){ return ParticleType::is_soa_particle;}) + .def_prop_rw_static("is_soa_particle", [](const py::object&){ return ParticleType::is_soa_particle;}) ; } template -void make_ParticleInitData (py::module &m) { +void make_ParticleInitData (py::module_ &m) { using ParticleType = T_ParticleType; using ParticleInitData = ParticleInitType; // depends on https://github.com/AMReX-Codes/amrex/pull/3280 @@ -140,21 +148,21 @@ void make_ParticleInitData (py::module &m) { std::string("ParticleInitType_") + suffix; auto py_particle_init_data = py::class_(m, particle_init_data_type.c_str()) .def(py::init<>()) - .def_property_readonly_static("is_soa_particle", [](const py::object&){return ParticleType::is_soa_particle;}) - .def_readwrite("real_array_data", &ParticleInitData::real_array_data) - .def_readwrite("int_array_data", &ParticleInitData::int_array_data) + .def_prop_rw_static("is_soa_particle", [](const py::object&){return ParticleType::is_soa_particle;}) + .def_rw("real_array_data", &ParticleInitData::real_array_data) + .def_rw("int_array_data", &ParticleInitData::int_array_data) ; // only legacy particle has an AoS data structure for positions and id+cpu if constexpr (!ParticleType::is_soa_particle) py_particle_init_data - .def_readwrite("real_struct_data", &ParticleInitData::real_struct_data) - .def_readwrite("int_struct_data", &ParticleInitData::int_struct_data); + .def_rw("real_struct_data", &ParticleInitData::real_struct_data) + .def_rw("int_struct_data", &ParticleInitData::int_struct_data); } template class Allocator=DefaultAllocator> -void make_ParticleContainer_and_Iterators (py::module &m, std::string allocstr) +void make_ParticleContainer_and_Iterators (py::module_ &m, std::string allocstr) { using ParticleType = T_ParticleType; using ParticleContainerType = ParticleContainer_impl< @@ -178,13 +186,13 @@ void make_ParticleContainer_and_Iterators (py::module &m, std::string allocstr) const Vector&, const Vector&>()) - .def_property_readonly_static("is_soa_particle", [](const py::object&){return ParticleType::is_soa_particle;}) - .def_property_readonly_static("NStructReal", [](const py::object&){return ParticleContainerType::NStructReal; }) - .def_property_readonly_static("NStructInt", [](const py::object&){return ParticleContainerType::NStructInt; }) - .def_property_readonly_static("NArrayReal", [](const py::object&){return ParticleContainerType::NArrayReal; }) - .def_property_readonly_static("NArrayInt", [](const py::object&){return ParticleContainerType::NArrayInt; }) + .def_prop_rw_static("is_soa_particle", [](const py::object&){return ParticleType::is_soa_particle;}) + .def_prop_rw_static("NStructReal", [](const py::object&){return ParticleContainerType::NStructReal; }) + .def_prop_rw_static("NStructInt", [](const py::object&){return ParticleContainerType::NStructInt; }) + .def_prop_rw_static("NArrayReal", [](const py::object&){return ParticleContainerType::NArrayReal; }) + .def_prop_rw_static("NArrayInt", [](const py::object&){return ParticleContainerType::NArrayInt; }) - .def_property_readonly("finest_level", &ParticleContainerBase::finestLevel) + .def_prop_rw_readonly("finest_level", &ParticleContainerBase::finestLevel) // ParticleContainer ( const ParticleContainer &) = delete; // ParticleContainer& operator= ( const ParticleContainer & ) = delete; @@ -379,7 +387,7 @@ void make_ParticleContainer_and_Iterators (py::module &m, std::string allocstr) /** Create ParticleContainers and Iterators */ template -void make_ParticleContainer_and_Iterators (py::module &m) +void make_ParticleContainer_and_Iterators (py::module_ &m) { // TODO for pure SoA // depends on https://github.com/AMReX-Codes/amrex/pull/3280 @@ -390,7 +398,7 @@ void make_ParticleContainer_and_Iterators (py::module &m) // !AMREX_USE_GPU: DefaultAllocator = std::allocator // AMREX_USE_GPU: DefaultAllocator = amrex::ArenaAllocator - // work-around for https://github.com/pybind/pybind11/pull/4581 + // work-around for https://github.com/pybind/nanobind/pull/4581 //make_ParticleContainer_and_Iterators(m, "std"); // CPU DefaultAllocator //make_ParticleContainer_and_Iterators -void init_ParticleContainer_HiPACE(py::module& m); -void init_ParticleContainer_ImpactX(py::module& m); -void init_ParticleContainer_WarpX(py::module& m); +void init_ParticleContainer_HiPACE(py::module_& m); +void init_ParticleContainer_ImpactX(py::module_& m); +void init_ParticleContainer_WarpX(py::module_& m); -void init_ParticleContainer(py::module& m) { +void init_ParticleContainer(py::module_& m) { using namespace amrex; // TODO: we might need to move all or most of the defines in here into a diff --git a/src/Particle/ParticleContainer_HiPACE.cpp b/src/Particle/ParticleContainer_HiPACE.cpp index 4342879f..b2fcdb55 100644 --- a/src/Particle/ParticleContainer_HiPACE.cpp +++ b/src/Particle/ParticleContainer_HiPACE.cpp @@ -8,7 +8,7 @@ #include -void init_ParticleContainer_HiPACE(py::module& /* m */) { +void init_ParticleContainer_HiPACE(py::module_& /* m */) { using namespace amrex; // TODO: we might need to move all or most of the defines in here into a diff --git a/src/Particle/ParticleContainer_ImpactX.cpp b/src/Particle/ParticleContainer_ImpactX.cpp index 53530c0d..c773333f 100644 --- a/src/Particle/ParticleContainer_ImpactX.cpp +++ b/src/Particle/ParticleContainer_ImpactX.cpp @@ -9,7 +9,7 @@ #include -void init_ParticleContainer_ImpactX(py::module& m) { +void init_ParticleContainer_ImpactX(py::module_& m) { using namespace amrex; // TODO: we might need to move all or most of the defines in here into a diff --git a/src/Particle/ParticleContainer_WarpX.cpp b/src/Particle/ParticleContainer_WarpX.cpp index 10c338ea..2b04ca23 100644 --- a/src/Particle/ParticleContainer_WarpX.cpp +++ b/src/Particle/ParticleContainer_WarpX.cpp @@ -8,7 +8,7 @@ #include -void init_ParticleContainer_WarpX(py::module& m) { +void init_ParticleContainer_WarpX(py::module_& m) { using namespace amrex; // TODO: we might need to move all or most of the defines in here into a diff --git a/src/Particle/ParticleTile.cpp b/src/Particle/ParticleTile.cpp index a88dd342..7af5d1c8 100644 --- a/src/Particle/ParticleTile.cpp +++ b/src/Particle/ParticleTile.cpp @@ -9,21 +9,29 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; //Forward declaration template -void make_Particle(py::module &m); +void make_Particle(py::module_ &m); template -void make_ParticleTileData(py::module &m) { +void make_ParticleTileData(py::module_ &m) { using ParticleType = T_ParticleType; constexpr int NStructReal = ParticleType::NReal; constexpr int NStructInt = ParticleType::NInt; @@ -37,9 +45,9 @@ void make_ParticleTileData(py::module &m) { std::to_string(NArrayInt); py::class_(m, particle_tile_data_type.c_str()) .def(py::init()) - .def_readonly("m_size", &ParticleTileDataType::m_size) - .def_readonly("m_num_runtime_real", &ParticleTileDataType::m_num_runtime_real) - .def_readonly("m_num_runtime_int", &ParticleTileDataType::m_num_runtime_int) + .def_ro("m_size", &ParticleTileDataType::m_size) + .def_ro("m_num_runtime_real", &ParticleTileDataType::m_num_runtime_real) + .def_ro("m_num_runtime_int", &ParticleTileDataType::m_num_runtime_int) .def("getSuperParticle", &ParticleTileDataType::template getSuperParticle) .def("setSuperParticle", &ParticleTileDataType::setSuperParticle) // setter & getter @@ -53,7 +61,7 @@ void make_ParticleTileData(py::module &m) { template class Allocator=DefaultAllocator> -void make_ParticleTile(py::module &m, std::string allocstr) +void make_ParticleTile(py::module_ &m, std::string allocstr) { using ParticleType = T_ParticleType; constexpr int NStructReal = ParticleType::NReal; @@ -67,8 +75,8 @@ void make_ParticleTile(py::module &m, std::string allocstr) std::to_string(NArrayInt) + "_" + allocstr; py::class_(m, particle_tile_type.c_str()) .def(py::init()) - .def_readonly_static("NAR", &ParticleTileType::NAR) - .def_readonly_static("NAI", &ParticleTileType::NAI) + .def_ro_static("NAR", &ParticleTileType::NAR) + .def_ro_static("NAI", &ParticleTileType::NAI) .def("define", &ParticleTileType::define) .def("GetArrayOfStructs", py::overload_cast<>(&ParticleTileType::GetArrayOfStructs), @@ -120,7 +128,7 @@ void make_ParticleTile(py::module &m, std::string allocstr) } template -void make_ParticleTile(py::module &m) +void make_ParticleTile(py::module_ &m) { make_ParticleTileData(m); @@ -128,7 +136,7 @@ void make_ParticleTile(py::module &m) // !AMREX_USE_GPU: DefaultAllocator = std::allocator // AMREX_USE_GPU: DefaultAllocator = amrex::ArenaAllocator - // work-around for https://github.com/pybind/pybind11/pull/4581 + // work-around for https://github.com/pybind/nanobind/pull/4581 //make_ParticleTile(m, "std"); //make_ParticleTile; using ParticleType_1_1 = Particle<1, 1>; diff --git a/src/Particle/StructOfArrays.cpp b/src/Particle/StructOfArrays.cpp index 9f1f980f..10942547 100644 --- a/src/Particle/StructOfArrays.cpp +++ b/src/Particle/StructOfArrays.cpp @@ -7,18 +7,26 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -namespace py = pybind11; +namespace py = nanobind; using namespace amrex; template class Allocator=DefaultAllocator> -void make_StructOfArrays(py::module &m, std::string allocstr) +void make_StructOfArrays(py::module_ &m, std::string allocstr) { using SOAType = StructOfArrays; @@ -44,13 +52,13 @@ void make_StructOfArrays(py::module &m, std::string allocstr) } template -void make_StructOfArrays(py::module &m) +void make_StructOfArrays(py::module_ &m) { // see Src/Base/AMReX_GpuContainers.H // !AMREX_USE_GPU: DefaultAllocator = std::allocator // AMREX_USE_GPU: DefaultAllocator = amrex::ArenaAllocator - // work-around for https://github.com/pybind/pybind11/pull/4581 + // work-around for https://github.com/pybind/nanobind/pull/4581 //make_StructOfArrays(m, "std"); //make_StructOfArrays(m, "arena"); #ifdef AMREX_USE_GPU @@ -69,7 +77,7 @@ void make_StructOfArrays(py::module &m) #endif } -void init_StructOfArrays(py::module& m) { +void init_StructOfArrays(py::module_& m) { make_StructOfArrays< 2, 1>(m); make_StructOfArrays< 4, 0>(m); // HiPACE++ 22.07 make_StructOfArrays< 5, 0>(m); // ImpactX 22.07 - 23.06 diff --git a/src/amrex/__init__.py b/src/amrex/__init__.py index a22aac17..dcc4e57f 100644 --- a/src/amrex/__init__.py +++ b/src/amrex/__init__.py @@ -16,13 +16,13 @@ os.add_dll_directory(p) # import core bindings to C++ -from . import amrex_pybind -from .amrex_pybind import * # noqa +from . import amrex_nanobind +from .amrex_nanobind import * # noqa -__version__ = amrex_pybind.__version__ -__doc__ = amrex_pybind.__doc__ -__license__ = amrex_pybind.__license__ -__author__ = amrex_pybind.__author__ +__version__ = amrex_nanobind.__version__ +__doc__ = amrex_nanobind.__doc__ +__license__ = amrex_nanobind.__license__ +__author__ = amrex_nanobind.__author__ # at this place we can enhance Python classes with additional methods written # in pure Python or add some other Python logic diff --git a/src/pyAMReX.cpp b/src/pyAMReX.cpp index 0bee2fb2..79a2261c 100644 --- a/src/pyAMReX.cpp +++ b/src/pyAMReX.cpp @@ -6,46 +6,54 @@ #include #include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #define STRINGIFY(x) #x #define MACRO_STRINGIFY(x) STRINGIFY(x) -namespace py = pybind11; +namespace py = nanobind; // forward declarations of exposed classes -void init_AMReX(py::module&); -void init_Arena(py::module&); -void init_Array4(py::module&); -void init_BaseFab(py::module&); -void init_Box(py::module &); -void init_RealBox(py::module &); -void init_BoxArray(py::module &); -void init_CoordSys(py::module&); -void init_Dim3(py::module&); -void init_DistributionMapping(py::module&); -void init_FArrayBox(py::module&); -void init_Geometry(py::module&); -void init_IntVect(py::module &); -void init_RealVect(py::module &); -void init_AmrMesh(py::module &); -void init_MultiFab(py::module &); -void init_ParallelDescriptor(py::module &); -void init_ParmParse(py::module &); -void init_Particle(py::module &); -void init_StructOfArrays(py::module &); -void init_ArrayOfStructs(py::module &); -void init_ParticleTile(py::module &); -void init_ParticleContainer(py::module &); -void init_Periodicity(py::module &); -void init_PODVector(py::module &); -void init_Vector(py::module &); +void init_AMReX(py::module_&); +void init_Arena(py::module_&); +void init_Array4(py::module_&); +void init_BaseFab(py::module_&); +void init_Box(py::module_ &); +void init_RealBox(py::module_ &); +void init_BoxArray(py::module_ &); +void init_CoordSys(py::module_&); +void init_Dim3(py::module_&); +void init_DistributionMapping(py::module_&); +void init_FArrayBox(py::module_&); +void init_Geometry(py::module_&); +void init_IntVect(py::module_ &); +void init_RealVect(py::module_ &); +void init_AmrMesh(py::module_ &); +void init_MultiFab(py::module_ &); +void init_ParallelDescriptor(py::module_ &); +void init_ParmParse(py::module_ &); +void init_Particle(py::module_ &); +void init_StructOfArrays(py::module_ &); +void init_ArrayOfStructs(py::module_ &); +void init_ParticleTile(py::module_ &); +void init_ParticleContainer(py::module_ &); +void init_Periodicity(py::module_ &); +void init_PODVector(py::module_ &); +void init_Vector(py::module_ &); -PYBIND11_MODULE(amrex_pybind, m) { +NB_MODULE(amrex_pybind, m) { m.doc() = R"pbdoc( amrex_pybind ----------- @@ -125,7 +133,7 @@ PYBIND11_MODULE(amrex_pybind, m) { m.attr("__license__") = "BSD-3-Clause-LBNL"; // TODO broken numpy if not at least v1.15.0: raise warning - // auto numpy = py::module::import("numpy"); + // auto numpy = py::module_::import("numpy"); // auto npversion = numpy.attr("__version__"); // std::cout << "numpy version: " << py::str(npversion) << std::endl; }