Skip to content

[Misc] Migrate to nanobind#759

Open
hughperkins wants to merge 12 commits into
mainfrom
hp/nanobind-migration
Open

[Misc] Migrate to nanobind#759
hughperkins wants to merge 12 commits into
mainfrom
hp/nanobind-migration

Conversation

@hughperkins

Copy link
Copy Markdown
Collaborator

Issue: #

Brief Summary

copilot:summary

Walkthrough

copilot:walkthrough

Port the build system and all C++ binding units to nanobind:
- pyproject.toml + cmake: nanobind deps, PythonNanobind.cmake, nanobind_add_module/stub
- export.* / interfaces_registry: NB_MODULE, namespace nb, stl header swaps
- export_lang/math/misc/stream: API renames, rv_policy, getstate/setstate pickle,
  init lambdas, eigen, enum tag struct, set_lib_dir bytes arg, Program weakref
- dlpack_funcs: nb capsule/object, manual PyCapsule for DLPack consumed protocol
- memory_usage_monitor: drop pybind11 embed, read RSS from /proc on Linux
- py_exception_translator: register from NB_MODULE (not static init) to avoid dlopen crash

CPU smoke test green (kernel + field ops).
- NdarrayCxx: nb::is_weak_referenceable() (frontend caches weakrefs to ndarray
  kernel args for launch-context eviction); fixes 22 ndarray test failures.
- export.h: include nanobind/stl/variant.h so ASTBuilder::create_print's
  std::vector<std::variant<Expr,std::string>> arg converts (fixes print tests).
…o_dlpack

- expr.py: coerce np.bool_ -> native bool before make_const_expr_bool (nanobind's
  bool caster is strict; rejected numpy bool). Fixes ~42 const-bool failures
  (reduction, ifte, ast_refactor, diag, ...).
- dlpack_funcs.cpp: include <nanobind/stl/string.h> so nb::cast<std::string> for
  the torch __version__ check resolves the string caster. Without it nanobind
  treated std::string as an unregistered bound type and threw std::bad_cast,
  breaking all field-backend to_dlpack (57 tensor-layout/dlpack failures).
- test_utils.exclude_arch_platform: use 'is not None' instead of truthiness.
  nanobind enum members are falsy when their int value is 0 (Arch.x64 == 0),
  unlike pybind11 enums; a bare 'if exclude_arch' silently failed to exclude the
  x64/cpu arch (test_test exclude_* + test_field sparse_not_supported).
- make_global_load_stmt / make_global_store_stmt: add nb::arg().none() so None
  maps to nullptr for the Stmt* operands as pybind11 did (test_binding).
…ments

Rename QD_INTERFACE_DEF_WITH_PYBIND11 -> QD_INTERFACE_DEF_WITH_NANOBIND (the macro
already emits nanobind::module_ calls; only the name lagged) and update the few
remaining comments that referenced pybind11 (snode copy-ctor, launch_context_builder
bulk-arg note, logging singleton rationale) to be binding-accurate. No functional change.
@hughperkins

hughperkins commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator Author

Genesis uni tests passing:

Screenshot 2026-06-24 at 09 19 15

@hughperkins

Copy link
Copy Markdown
Collaborator Author

Apears we no longer need .pyi stub postprocessing:

Screenshot 2026-06-24 at 08 54 07

# Conflicts:
#	cmake/PythonNumpyPybind11.cmake
#	pyproject.toml
nanobind_add_stub emits the .pyi directly (richer, more accurate types than the old
pybind11-stubgen output), so the YAML signature-rewrite step is gone. Remove the now-unused
tools/gen_stubs.py, stub_replacements_funcs.yaml, stub_replacements_global.yaml, and the
ruamel.yaml build dep they were the only consumer of.
@hughperkins

Copy link
Copy Markdown
Collaborator Author

Genesis benchmark results:

2026024_nano_0842

The old pybind11-stubgen YAML post-processing injected readable parameter names
(e.g. get_tensor_type's shape/element_type). Restore them the nanobind-native way via
nb::arg(...) on the affected defs (get_tensor_type, make_const_expr_{bool,int,fp},
create_kernel, create_function, set_arg_ndarray, make_get_element_expr) so the generated
.pyi shows named, keyword-callable params instead of arg0/arg1. Verified against a freshly
generated stub. All call sites are positional, so no runtime impact.
@hughperkins hughperkins marked this pull request as ready for review June 24, 2026 13:49
Pure formatting (line-wrapping/indentation) from pre-commit clang-format on the
nanobind-ported files; no functional change.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: db14c1aeb7

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +42 to +43
#endif
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve memory monitoring on non-Linux platforms

When start_memory_monitoring() is used on macOS or Windows, this replacement now falls into the non-Linux branch and records 0 for every sample. The previous psutil-based implementation worked anywhere psutil was available, so this silently disables the exported memory monitor for non-Linux users instead of reporting process RSS or failing clearly.

Useful? React with 👍 / 👎.

@hughperkins

Copy link
Copy Markdown
Collaborator Author

reran genesis benchmarks after changes above. Still looking good:

2026024_nano_0950

@hughperkins

hughperkins commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator Author

Genesis unit tests still passing:

Screenshot 2026-06-24 at 10 24 24

@github-actions

Copy link
Copy Markdown

The nanobind-generated .pyi now types these binding params precisely (vs the
loose/Any signatures from the old pybind11-stubgen + YAML postprocessing), which
surfaced 3 real type mismatches in the frontend:

- expr.py make_const_expr_fp/int: coerce np.floating/np.integer to native
  float/int (mirrors the existing bool(val) coercion for make_const_expr_bool).
- impl.py expr_subscript: add `assert indices_expr_group is not None` before the
  tensor-index call (same narrowing already used earlier in subscript()).

Runtime behavior unchanged (CPU suite already green); these are static-typing
fixes only.
@github-actions

Copy link
Copy Markdown

…trations

clang-tidy's bugprone-unused-raii flags the discarded `nb::exception<T>(...)`
temporaries (the old pybind11 code used the free function py::register_exception,
which isn't flagged). The construction is the registration; the handle is meant
to be discarded. Suppress per line with NOLINTNEXTLINE, matching the existing
convention already used for `nb::class_<BitStructType>` in this file.
@github-actions

Copy link
Copy Markdown

# Conflicts:
#	quadrants/python/memory_usage_monitor.cpp
#	quadrants/python/memory_usage_monitor.h
@github-actions

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant