Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
76 changes: 76 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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++)
Expand Down
2 changes: 1 addition & 1 deletion cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
2 changes: 1 addition & 1 deletion python/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = [
Expand Down
Loading