diff --git a/.gitignore b/.gitignore index b0ac3a2..10e6d89 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,10 @@ _site/ .jekyll-cache/ .DS_Store -~$* \ No newline at end of file +~$* + +__pycache__/ +.vscode/ +*.o +*.so +build/ diff --git a/30_CCQ/main.md b/30_CCQ/main.md index 4c7c862..e4b1bc7 100644 --- a/30_CCQ/main.md +++ b/30_CCQ/main.md @@ -72,15 +72,15 @@ nanobind-example/ ├── CMakeLists.txt ├── pyproject.toml └── src - └── examplepkg + └── example_pkg ├── compute.py - ├── examplemod.cpp + ├── array_example_module.cpp └── __init__.py ``` --- -## nanobind `examplemod.cpp` +## nanobind `array_example_module.cpp` ```c++ template void double_arr( @@ -95,7 +95,7 @@ void double_arr( } } -NB_MODULE(examplemod, m) { +NB_MODULE(array_example_module, m) { m.def("double_arr", &double_arr); m.def("double_arr", &double_arr); } @@ -105,17 +105,17 @@ NB_MODULE(examplemod, m) { ## nanobind `compute.py` ```python -from . import examplemod +from . import array_example_module inarr = np.arange(20) outarr = np.empty_like(inarr) -examplemod.double_arr(outarr, inarr) +array_example_module.double_arr(outarr, inarr) ``` - Easy! nanobind will check that the array types have the expected shape, dtype, strides, etc. - A more sophisticated example would have nanobind returning a NumPy array -- Now we'll look at how `examplemod.cpp` gets built +- Now we'll look at how `array_example_module.cpp` gets built --- @@ -127,9 +127,9 @@ project(${SKBUILD_PROJECT_NAME} LANGUAGES CXX) find_package(Python 3.8 COMPONENTS Interpreter Development.Module REQUIRED) find_package(nanobind CONFIG REQUIRED) -nanobind_add_module(examplemod src/examplepkg/examplemod.cpp) +nanobind_add_module(array_example_module src/example_pkg/array_example_module.cpp) -install(TARGETS examplemod LIBRARY DESTINATION examplepkg) +install(TARGETS array_example_module LIBRARY DESTINATION example_pkg) ``` --- @@ -141,7 +141,7 @@ requires = ["scikit-build-core >= 0.5", "nanobind"] build-backend = "scikit_build_core.build" [project] -name = "examplepkg" +name = "example_pkg" version = "0.0.1" requires-python = ">=3.8" diff --git a/30_CCQ/nanobind-example/CMakeLists.txt b/30_CCQ/nanobind-example/CMakeLists.txt index 991114a..e99530c 100644 --- a/30_CCQ/nanobind-example/CMakeLists.txt +++ b/30_CCQ/nanobind-example/CMakeLists.txt @@ -4,6 +4,8 @@ project(${SKBUILD_PROJECT_NAME} LANGUAGES CXX) find_package(Python 3.8 COMPONENTS Interpreter Development.Module REQUIRED) find_package(nanobind CONFIG REQUIRED) -nanobind_add_module(examplemod src/examplepkg/examplemod.cpp) +nanobind_add_module(array_example_module src/example_pkg/array_example_module.cpp) +nanobind_add_module(struct_example_module src/example_pkg/struct_example_module.cpp) -install(TARGETS examplemod LIBRARY DESTINATION examplepkg) +install(TARGETS array_example_module LIBRARY DESTINATION example_pkg) +install(TARGETS struct_example_module LIBRARY DESTINATION example_pkg) diff --git a/30_CCQ/nanobind-example/README.md b/30_CCQ/nanobind-example/README.md index a59ef09..42506f9 100644 --- a/30_CCQ/nanobind-example/README.md +++ b/30_CCQ/nanobind-example/README.md @@ -15,5 +15,5 @@ $ pip install -e . --no-build-isolation ## Test ``` -$ python -m examplepkg.compute +$ python -m example_pkg.compute ``` diff --git a/30_CCQ/nanobind-example/pyproject.toml b/30_CCQ/nanobind-example/pyproject.toml index 12e57e4..4760873 100644 --- a/30_CCQ/nanobind-example/pyproject.toml +++ b/30_CCQ/nanobind-example/pyproject.toml @@ -3,7 +3,7 @@ requires = ["scikit-build-core >= 0.5", "nanobind"] build-backend = "scikit_build_core.build" [project] -name = "examplepkg" +name = "example_pkg" version = "0.0.1" requires-python = ">=3.8" diff --git a/30_CCQ/nanobind-example/src/examplepkg/__init__.py b/30_CCQ/nanobind-example/src/example_pkg/__init__.py similarity index 100% rename from 30_CCQ/nanobind-example/src/examplepkg/__init__.py rename to 30_CCQ/nanobind-example/src/example_pkg/__init__.py diff --git a/30_CCQ/nanobind-example/src/examplepkg/examplemod.cpp b/30_CCQ/nanobind-example/src/example_pkg/array_example_module.cpp similarity index 93% rename from 30_CCQ/nanobind-example/src/examplepkg/examplemod.cpp rename to 30_CCQ/nanobind-example/src/example_pkg/array_example_module.cpp index 618905e..3d72355 100644 --- a/30_CCQ/nanobind-example/src/examplepkg/examplemod.cpp +++ b/30_CCQ/nanobind-example/src/example_pkg/array_example_module.cpp @@ -15,8 +15,7 @@ void double_arr(nb::ndarray, nb::device::cpu> outarr, } } - -NB_MODULE(examplemod, m) { +NB_MODULE(array_example_module, m) { m.def("double_arr", &double_arr); m.def("double_arr", &double_arr); m.def("double_arr", &double_arr); diff --git a/30_CCQ/nanobind-example/src/examplepkg/compute.py b/30_CCQ/nanobind-example/src/example_pkg/compute.py similarity index 63% rename from 30_CCQ/nanobind-example/src/examplepkg/compute.py rename to 30_CCQ/nanobind-example/src/example_pkg/compute.py index 971dfac..94bc242 100644 --- a/30_CCQ/nanobind-example/src/examplepkg/compute.py +++ b/30_CCQ/nanobind-example/src/example_pkg/compute.py @@ -1,14 +1,12 @@ -from timeit import default_timer - import numpy as np -from . import examplemod +from . import array_example_module def main(): inarr = np.arange(20) outarr = np.empty_like(inarr) - examplemod.double_arr(outarr, inarr) + array_example_module.double_arr(outarr, inarr) print(inarr) print(outarr) diff --git a/30_CCQ/nanobind-example/src/example_pkg/struct_example_module.cpp b/30_CCQ/nanobind-example/src/example_pkg/struct_example_module.cpp new file mode 100644 index 0000000..4b72ca0 --- /dev/null +++ b/30_CCQ/nanobind-example/src/example_pkg/struct_example_module.cpp @@ -0,0 +1,35 @@ +#include +#include + +#include +#include +#include + +namespace nb = nanobind; + +struct S { + int i; + S(int i):i{i}{} + int m() const { return i+2;} +}; + +// A function using S +int f(S const & s){ return s.i;} + +// make S printable in C++ +std::ostream & operator<<(std::ostream &out, S const & s) { + return out << "S struct with i=" << s.i << '\n'; +} + +NB_MODULE(struct_example_module, m) { + nb::class_(m, "S") + .def_rw("i", &S::i) + .def(nb::init()) + .def("m", &S::m) + .def("__repr__", [](const S& s) { + std::stringstream stream; + stream << s; + return stream.str(); + }); + m.def("f", &f); +} diff --git a/30_CCQ/nanobind-example/src/example_pkg/test_struct.py b/30_CCQ/nanobind-example/src/example_pkg/test_struct.py new file mode 100644 index 0000000..96f3d50 --- /dev/null +++ b/30_CCQ/nanobind-example/src/example_pkg/test_struct.py @@ -0,0 +1,13 @@ +from . import struct_example_module + +def main(): + s = struct_example_module.S(3) + print() + print(f'{s = }') + print(f'{s.i = }') + print(f'{s.m() = }') + print(f'{struct_example_module.f(s) = }') + print() + +if __name__ == '__main__': + main()