From c8cdc78435a8c3ed5eb7022bb920e9fe6ca4263e Mon Sep 17 00:00:00 2001 From: Hyungtae Lim Date: Thu, 21 May 2026 17:24:24 +0900 Subject: [PATCH] chore(release): v1.4.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Minor bump for the common-library refactor (#94) and the optional TBB parallelisation of classic Patchwork (#95). pypatchworkpp.patchwork gains 1.73x (120 -> 208 Hz on KITTI seq 00, i7-12700). pypatchworkpp.patchworkpp stays sequential after measurement — see #96 for the why. TBB is an optional build dependency: missing TBB falls back to a sequential loop with a CMake STATUS message; CI/wheel builds keep working without libtbb-dev installed. Bumps: - python/pyproject.toml 1.3.1 -> 1.4.0 - cpp/CMakeLists.txt 1.3.1 -> 1.4.0 CHANGELOG.md updated with the full v1.4.0 entry. See #94, #95, #96. --- CHANGELOG.md | 76 +++++++++++++++++++++++++++++++++++++++++++ cpp/CMakeLists.txt | 2 +- python/pyproject.toml | 2 +- 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20eabe6..8a934cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,81 @@ # Changelog +## v1.4.0 + +### Refactor — shared `common` library + optional TBB parallelisation + +`cpp/common/` is a new tiny static library holding the parts of the +codebase that are independent of the Patchwork / Patchwork++ +pipelines: + +- `cpp/common/include/patchwork/types.h` — `PointXYZ`, `PCAFeature` + (now carries the `principal_` field for parity with the original + Patchwork repo), `PatchStatus`. +- `cpp/common/include/patchwork/plane_fit.h` + + `cpp/common/src/plane_fit.cpp` — the SVD-based `estimate_plane`, + plus `xy2theta`, `xy2radius`, `point_z_cmp`. + +Both `cpp/patchwork/` and `cpp/patchworkpp/` now link this library +and the three drifted copies of the plane-fit math are collapsed to +one canonical implementation. Fix 2 in #90 was a concrete example of +that drift causing a real bug. + +### Perf — `pypatchworkpp.patchwork` is now multi-threaded + +Classic Patchwork's main loop uses `tbb::parallel_for` over all +`(zone, ring, sector)` patches when TBB is available, with a serial +reduction afterwards that walks the outcome buffer in deterministic +order so numerical results are byte-identical to the sequential path. + +Measured on KITTI seq 00 (i7-12700, 24 logical cores): + +| Configuration | Median ms/frame | Median Hz | +| -- | --: | --: | +| `--method patchwork` single-thread (taskset -c 0) | 8.31 | 120.4 | +| `--method patchwork` parallel (TBB default scheduler) | **4.81** | **207.8** | + +**1.73× speedup**. TBB is an **optional** build dependency: missing +TBB causes a CMake STATUS message and falls back to a sequential +loop (no FATAL_ERROR), so existing CI / wheel builds continue to +work even when `libtbb-dev` is not installed. + +### Perf — `pypatchworkpp.patchworkpp` stays sequential (intentional) + +The same TBB pattern was applied to Patchwork++'s main loop and +benchmarked at 1 / 2 / 4 / 8 / 16 / 24 threads. **Every multi-thread +configuration was slower** than single-thread (111 Hz → 93 Hz at 2 +threads, → 69 Hz at 24 threads). Root cause: per-patch work is small +(~14 µs avg) and dominated by short-lived `std::vector` / `Eigen` +allocations inside R-VPF + R-GPF, so concurrent malloc serialises on +the heap allocator. Patchwork++ remains sequential. Issue #96 +documents the measurement and the conditions under which we'd +revisit (thread-aware allocator, slab-allocated per-worker scratch, +or a real user CPU complaint). + +### Adds + +- `python/examples/bench_hz.py` — per-frame timing harness reporting + median / mean / p95 / p99 ms and Hz from `getTimeTaken()`. Useful + for future perf work. + +### Numerical equivalence + +KITTI 00-10 full sweep (23,201 frames), Patchwork++ paper protocol, +v1.3.1 → v1.4.0: + +| Method | F1 v1.3.1 | F1 v1.4.0 | Δ | +| --- | --- | --- | --- | +| `--method patchwork` | 96.0172 | 96.0172 | 0 (byte-identical) | +| `--method patchworkpp` | 96.2918 | 96.2919 | +0.0001 (float noise) | + +Both well within the ±0.05 budget set in the refactor plan. + +### References + +- #94 — PR (refactor: extract common library) +- #95 — PR (perf: TBB on classic Patchwork) +- #96 — Issue (why Patchwork++ has no TBB) + ## v1.3.1 ### Bug fix — `pypatchworkpp.patchworkpp` (Patchwork++) diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index d69fadf..4fca928 100755 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.11) -project(patchworkpp VERSION 1.3.1) +project(patchworkpp VERSION 1.4.0) option(USE_SYSTEM_EIGEN3 "Use system pre-installed Eigen" OFF) option(INCLUDE_CPP_EXAMPLES "Include C++ example codes, which require Open3D for visualization" OFF) diff --git a/python/pyproject.toml b/python/pyproject.toml index fb868bc..626551c 100644 --- a/python/pyproject.toml +++ b/python/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build" [project] name = "pypatchworkpp" -version = "1.3.1" +version = "1.4.0" requires-python = ">=3.8" description = "ground segmentation" dependencies = [