Skip to content

Switch PyPartMC's binding system from pybind11 to nanobind #431

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2a4147c
initial setup commit
Griger5 May 9, 2025
c442b01
hacky trick relying on cmake undocumented feature, that fixes the iss…
Griger5 May 23, 2025
345ca3e
first util and rand bindings, first passing tests
Griger5 May 23, 2025
1a44871
add: bindings to the rest of the util.cpp
Griger5 May 25, 2025
f8d1cef
WIP: refactored nanobind_json, created bindings for AeroData, AeroDat…
Griger5 May 26, 2025
f6d91c3
refactored AeroData so that the tests are passing
Griger5 May 27, 2025
52b6c52
add: custom nanobind caster for std::valarray
Griger5 May 28, 2025
e0bb9ec
add: BinGrid bindings
Griger5 May 28, 2025
13d407c
revert to old aero_data.hpp thanks to the new caster
Griger5 May 28, 2025
094b5bf
add: missing changes
Griger5 May 28, 2025
73c055f
fix JSON caster so it catches circular reference, add AeroMode bindings
Griger5 May 28, 2025
86939e5
pull main into branch
Griger5 May 29, 2025
c444e5d
add accidentally deleted line
Griger5 May 29, 2025
406b491
delete unused header files
Griger5 May 29, 2025
40fb1c0
add: bindings for AeroData
Griger5 May 29, 2025
5232372
add: pyproject.toml
Griger5 May 30, 2025
73a1543
add: EnvState bindings
Griger5 May 31, 2025
8dc75f3
add: GasData bindings
Griger5 May 31, 2025
1ab9a8a
swith nanobind_json to Gracjan fork
slayoo Jun 4, 2025
69ab2f9
switch to pypartmc branch commit for nanobind_json submodule
slayoo Jun 4, 2025
93943a1
WIP: current working version
Griger5 Jun 13, 2025
8917174
add: semi-working AeroParticle bindings
Griger5 Jun 13, 2025
ca2ea1c
add: AeroState bindigns. README example working
Griger5 Jun 13, 2025
068b682
bindings for GasState and RunPartOpt
Griger5 Jul 3, 2025
3a53b76
add: bindings for condense functions
Griger5 Jul 3, 2025
d58fcdf
add output bindings, fix error in GasData
Griger5 Jul 8, 2025
721f722
add: bindings for run_part functions and Scenario
Griger5 Jul 8, 2025
936b0d8
add: AeroBinned bindings
Griger5 Jul 12, 2025
263dd83
add: RunSectOpt and RunExactOpt bindings
Griger5 Jul 12, 2025
1fc6302
add: missing input bindings
Griger5 Jul 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
[submodule "pybind11"]
path = gitmodules/pybind11
url = https://github.com/pybind/pybind11
shallow = true
[submodule "partmc"]
path = gitmodules/partmc
url = https://github.com/compdyn/partmc
shallow = true
[submodule "pybind11_json"]
path = gitmodules/pybind11_json
url = https://github.com/pybind/pybind11_json
shallow = true
[submodule "json"]
path = gitmodules/json
url = https://github.com/nlohmann/json
Expand Down Expand Up @@ -58,3 +50,13 @@
path = gitmodules/hdf5
url = https://github.com/HDFGroup/hdf5.git
shallow = true
[submodule "gitmodules/nanobind"]
path = gitmodules/nanobind
url = https://github.com/wjakob/nanobind
[submodule "gitmodules/nanobind_json"]
path = gitmodules/nanobind_json
url = https://github.com/Griger5/nanobind_json
[submodule "."]
branch = pypartmc
[submodule "nanobind_json"]
branch = pypartmc
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
files: '.py'
exclude: '.git'
default_stages: [commit]
default_stages: [pre-commit]

repos:
- repo: https://github.com/psf/black
Expand Down
79 changes: 46 additions & 33 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ endforeach()

project(_PyPartMC LANGUAGES C CXX Fortran)

find_package(PythonInterp REQUIRED)
find_package(Python 3.8
REQUIRED COMPONENTS Interpreter Development.Module
OPTIONAL_COMPONENTS Development.SABIModule)
message(STATUS "Python_EXECUTABLE= ${Python_EXECUTABLE}")

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

Expand All @@ -33,6 +36,12 @@ if(CMAKE_Fortran_COMPILER_ID STREQUAL GNU)
add_compile_options($<$<AND:$<COMPILE_LANGUAGE:Fortran>,$<CONFIG:DEBUG>>:-fcheck=bounds>)
endif()

# Shadow the CMake intrinsic install function so that included CMake code from dependency submodules does not
# interfere with "make install" issued by scikit-build (note that our intentional install() call is replaced with
# _install() below - following https://cmake.org/pipermail/cmake/2011-March/043320.html)
macro(install)
endmacro(install)

macro(add_prefix prefix rootlist)
set(outlist)
foreach(root ${${rootlist}})
Expand Down Expand Up @@ -512,14 +521,17 @@ if(DEFINED ENV{MOSAIC_HOME})
endif()

### PYBIND11 & PyPartMC ############################################################################
find_package(nanobind CONFIG REQUIRED)

add_subdirectory(gitmodules/pybind11)
pybind11_add_module(_PyPartMC ${PyPartMC_sources})
# add_subdirectory(gitmodules/pybind11)
add_subdirectory(gitmodules/nanobind)
nanobind_add_module(_PyPartMC STABLE_ABI ${PyPartMC_sources})
add_dependencies(_PyPartMC partmclib)
set(PYPARTMC_INCLUDE_DIRS
"${CMAKE_BINARY_DIR}/include;"
"${CMAKE_SOURCE_DIR}/gitmodules/json/include;"
"${CMAKE_SOURCE_DIR}/gitmodules/pybind11_json/include;"
"${CMAKE_SOURCE_DIR}/gitmodules/nanobind/include;"
"${CMAKE_SOURCE_DIR}/gitmodules/nanobind_json/include;"
"${CMAKE_SOURCE_DIR}/gitmodules/span/include;"
"${CMAKE_SOURCE_DIR}/gitmodules/string_view-standalone/include;"
"${CMAKE_SOURCE_DIR}/gitmodules/optional/include;"
Expand All @@ -545,7 +557,7 @@ endif()
foreach(target _PyPartMC)
target_compile_options(${target} PRIVATE
$<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -Wpedantic -Werror>
# $<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wall -Wextra -Wpedantic -Werror>
$<$<NOT:$<CXX_COMPILER_ID:MSVC>>:-Wno-unused-parameter>
)
endforeach()
Expand All @@ -555,31 +567,32 @@ file(GLOB PyPartMC_headers ${CMAKE_SOURCE_DIR}/src/*.hpp)
if (NOT "${CMAKE_REQUIRED_INCLUDES}" STREQUAL "")
message("CMAKE_REQUIRED_INCLUDES not empty! (${CMAKE_REQUIRED_INCLUDES})")
endif()
foreach(file ${PyPartMC_headers})
set(CMAKE_REQUIRED_INCLUDES "${PYPARTMC_INCLUDE_DIRS};${pybind11_INCLUDE_DIRS}")
set(CMAKE_REQUIRED_FLAGS "-Werror")
string(REGEX REPLACE "[\-./:]" "_" file_var ${file})
check_cxx_source_compiles("
// https://github.com/nlohmann/json/issues/1408
#if defined(_WIN32) || defined(_WIN64)
# define HAVE_SNPRINTF
#endif
#include \"${file}\"
int main() { return 0;}
"
_header_self_contained_${file_var}
)
unset(CMAKE_REQUIRED_INCLUDES)
unset(CMAKE_REQUIRED_FLAGS)
if (NOT _header_self_contained_${file_var})
message(SEND_ERROR "non-self-contained header: ${file}")
if (${CMAKE_VERSION} VERSION_LESS "3.26.0")
file(READ "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log" tmp)
else()
file(READ "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeConfigureLog.yaml" tmp)
endif()
message(FATAL_ERROR ${tmp})
endif()
unset(file_var)
endforeach()

# foreach(file ${PyPartMC_headers})
# set(CMAKE_REQUIRED_INCLUDES "${PYPARTMC_INCLUDE_DIRS};${pybind11_INCLUDE_DIRS}")
# set(CMAKE_REQUIRED_FLAGS "-Werror")
# string(REGEX REPLACE "[\-./:]" "_" file_var ${file})
# check_cxx_source_compiles("
# // https://github.com/nlohmann/json/issues/1408
# #if defined(_WIN32) || defined(_WIN64)
# # define HAVE_SNPRINTF
# #endif
# #include \"${file}\"
# int main() { return 0;}
# "
# _header_self_contained_${file_var}
# )
# unset(CMAKE_REQUIRED_INCLUDES)
# unset(CMAKE_REQUIRED_FLAGS)
# if (NOT _header_self_contained_${file_var})
# message(SEND_ERROR "non-self-contained header: ${file}")
# if (${CMAKE_VERSION} VERSION_LESS "3.26.0")
# file(READ "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log" tmp)
# else()
# file(READ "${CMAKE_BINARY_DIR}/CMakeFiles/CMakeConfigureLog.yaml" tmp)
# endif()
# message(FATAL_ERROR ${tmp})
# endif()
# unset(file_var)
# endforeach()

_install(TARGETS _PyPartMC LIBRARY DESTINATION PyPartMC)
1 change: 1 addition & 0 deletions gitmodules/nanobind
Submodule nanobind added at d4b245
1 change: 1 addition & 0 deletions gitmodules/nanobind_json
Submodule nanobind_json added at 6e9e15
1 change: 0 additions & 1 deletion gitmodules/pybind11
Submodule pybind11 deleted from 68a0b2
1 change: 0 additions & 1 deletion gitmodules/pybind11_json
Submodule pybind11_json deleted from 32043f
25 changes: 25 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[tool.setuptools_scm]
local_scheme = "no-local-version"
version_scheme = "post-release"

[build-system]
requires = ["scikit-build-core >=0.4.3", "nanobind >=1.3.2", "setuptools-scm==8.3.1"]
build-backend = "scikit_build_core.build"

[project]
name = "PyPartMC"
dynamic = ["version"]
description = "Python interface to PartMC"
readme = "README.md"
requires-python = ">=3.8"
authors = [
{name = "https://github.com/open-atmos/PyPartMC/graphs/contributors", email = "[email protected]"}
]
classifiers = [
"License :: GPL-3.0",
]

[project.urls]
Documentation = "https://open-atmos.github.io/PyPartMC"
Source = "https://github.com/open-atmos/PyPartMC/"
Tracker = "https://github.com/open-atmos/PyPartMC/issues"
168 changes: 0 additions & 168 deletions setup.py

This file was deleted.

13 changes: 7 additions & 6 deletions PyPartMC/__init__.py → src/PyPartMC/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,11 @@ def __generate_si():
SI-prefix-aware unit multipliers, resulting in e.g.: `p = 1000 * si.hPa`
notation. Note: no dimensional analysis is done! """

with __build_extension_env():
import _PyPartMC
from _PyPartMC import *
from _PyPartMC import __all__ as _PyPartMC_all # pylint: disable=no-name-in-module
from _PyPartMC import __version__, __versions_of_build_time_dependencies__
# with __build_extension_env():
# from . import _PyPartMC
from ._PyPartMC import *

__all__ = tuple([*_PyPartMC_all, "si"])
# from ._PyPartMC import __all__ as _PyPartMC_all # pylint: disable=no-name-in-module
# from ._PyPartMC import __version__, __versions_of_build_time_dependencies__

# __all__ = tuple([*_PyPartMC_all, "si"])
1 change: 0 additions & 1 deletion src/aero_binned.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include "bin_grid.hpp"
#include "aero_dist.hpp"
#include "aero_data.hpp"
#include "pybind11/stl.h"

extern "C" void f_aero_binned_ctor(void *ptr) noexcept;
extern "C" void f_aero_binned_dtor(void *ptr) noexcept;
Expand Down
Loading
Loading