diff --git a/CMakeLists.txt b/CMakeLists.txt index a4d576c..ec58d7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ include(FetchContent) FetchContent_Declare( nanobind GIT_REPOSITORY https://github.com/wjakob/nanobind.git - GIT_TAG v2.2.0 + GIT_TAG d698692936bae1c4963e5c42f41fd88e9095b1c0 ) FetchContent_MakeAvailable(nanobind) diff --git a/README.md b/README.md index 77e6b81..3733e50 100644 --- a/README.md +++ b/README.md @@ -45,9 +45,11 @@ According to the [scikit-build-core documentation](https://scikit-build-core.rea 2. Then use this very long command: ``` -python -m pip install --no-build-isolation --config-settings=editable.rebuild=true -Cbuild-dir=build -ve. +CMAKE_BUILD_PARALLEL_LEVEL=10 python -m pip install --no-build-isolation --config-settings=editable.rebuild=true -Cbuild-dir=build -ve. ``` +The `CMAKE_BUILD_PARALLEL_LEVEL=10` will invoke with 10 parallel build threads. + ### Adding a missing binding Bindings are fairly mechanical to write. For example, suppose we didn't have a diff --git a/src/sparse_map_noop.cpp b/src/sparse_map_noop.cpp new file mode 100644 index 0000000..66778bf --- /dev/null +++ b/src/sparse_map_noop.cpp @@ -0,0 +1,27 @@ +#include "default_types.h" +#include +#include +#include +#include + +namespace nb = nanobind; +using namespace nb::literals; + +namespace pyigl +{ + auto sparse_map_noop( const Eigen::Map> &A) + { + return A; + } +} + +// Bind the wrapper to the Python module +void bind_sparse_map_noop(nb::module_ &m) +{ + m.def( + "sparse_map_noop", + &pyigl::sparse_map_noop, + "A"_a, +R"("Returns input A)"); +} + diff --git a/src/sparse_map_shape.cpp b/src/sparse_map_shape.cpp new file mode 100644 index 0000000..48349e8 --- /dev/null +++ b/src/sparse_map_shape.cpp @@ -0,0 +1,29 @@ +#include "default_types.h" +#include +#include +#include +#include + +namespace nb = nanobind; +using namespace nb::literals; + +namespace pyigl +{ + auto sparse_map_shape( const Eigen::Map> &A) + { + Eigen::Matrix dims(A.rows(), A.cols()); + return dims; + } +} + +// Bind the wrapper to the Python module +void bind_sparse_map_shape(nb::module_ &m) +{ + m.def( + "sparse_map_shape", + &pyigl::sparse_map_shape, + "A"_a, +R"("Returns shape of A as 2-vector)"); +} + + diff --git a/src/sparse_noop.cpp b/src/sparse_noop.cpp new file mode 100644 index 0000000..b28d55c --- /dev/null +++ b/src/sparse_noop.cpp @@ -0,0 +1,27 @@ +#include "default_types.h" +#include +#include +#include +#include + +namespace nb = nanobind; +using namespace nb::literals; + +namespace pyigl +{ + auto sparse_noop( const Eigen::SparseMatrix &A) + { + return A; + } +} + +// Bind the wrapper to the Python module +void bind_sparse_noop(nb::module_ &m) +{ + m.def( + "sparse_noop", + &pyigl::sparse_noop, + "A"_a, +R"("Returns input A)"); +} + diff --git a/src/sparse_shape.cpp b/src/sparse_shape.cpp new file mode 100644 index 0000000..f04b4f0 --- /dev/null +++ b/src/sparse_shape.cpp @@ -0,0 +1,29 @@ +#include "default_types.h" +#include +#include +#include +#include + +namespace nb = nanobind; +using namespace nb::literals; + +namespace pyigl +{ + auto sparse_shape( const Eigen::SparseMatrix &A) + { + Eigen::Matrix dims(A.rows(), A.cols()); + return dims; + } +} + +// Bind the wrapper to the Python module +void bind_sparse_shape(nb::module_ &m) +{ + m.def( + "sparse_shape", + &pyigl::sparse_shape, + "A"_a, +R"("Returns shape of A as 2-vector)"); +} + + diff --git a/test_sparse.py b/test_sparse.py new file mode 100644 index 0000000..74074d8 --- /dev/null +++ b/test_sparse.py @@ -0,0 +1,36 @@ +import igl +import time + +V, F = igl.icosahedron() +V, F = igl.upsample(V, F) +V, F = igl.upsample(V, F) +V, F = igl.upsample(V, F) +V, F = igl.upsample(V, F) +V, F = igl.upsample(V, F) +V, F = igl.upsample(V, F) + +max_iters = 6 +for i in range(max_iters): + A = igl.adjacency_matrix(F) + n = A.shape[0] + + start = time.time() + dims = igl.sparse_shape(A) + t_shape = time.time() - start + + start = time.time() + A2 = igl.sparse_noop(A) + t_noop = time.time() - start + + start = time.time() + dims = igl.sparse_map_shape(A) + t_map_shape = time.time() - start + + start = time.time() + A2 = igl.sparse_map_noop(A) + t_map_noop = time.time() - start + + print(f"{n} {t_shape:.6g} {t_noop:.6g} {t_map_shape:.6g} {t_map_noop:.6g}") + + if i != max_iters-1: + V, F = igl.upsample(V, F)