perf(eval): avoid full-coordinate overlap temporaries - #577
Open
JESUSROYETH wants to merge 1 commit into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Optimizes evaluator box overlap calculations by avoiding large (N, M, 4) temporary arrays.
Changes:
- Computes intersection width and height from individual coordinate planes.
- Reduces peak memory usage while preserving IoU/IoA behavior.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
_calculate_box_iouscurrently broadcasts both four-coordinate inputs into two(N, M, 4)arrays, then only reads one plane from each edge. Those temporaries grow fast with the number of boxes.This patch gets the same width and height directly from the coordinate planes instead. The subtraction order after that stays the same, but now the biggest intermediates are
(N, M), not(N, M, 4).Validation
First I ran develop against itself to check the harness is sane, then 8,000 seeded comparisons covering IoU and IoA, XYXY and XYWH, float32/64 and integer inputs, strided views, different NaN payloads, infinities, signed zero and subnormals. Output bits are exact in every one of them.
I also ran the full similarity matrices and per-sequence CLEAR/HOTA/Identity payloads on 7 MOT17 sequences (2,652 matrices) and 25 DanceTrack sequences (25,508 matrices), and the bit-level digests match develop in all of them.
The existing box suite already covers both public functions, both formats, empty inputs, zero-area boxes and the numeric edge cases, so I did not add new tests for this.
pytest -m 'not integration'passes with 1,564 tests, the 4 evaluator integration tests pass, andpre-commit run --all-filesis clean.Performance
CPU-only, Python 3.12.3 / NumPy 1.26.4. I load the inputs before timing, alternate the run order, and run garbage collection before each sample. These are paired medians, full observed range in brackets.
The DanceTrack end-to-end effect is small because building the overlap matrix is only a small part of that workload.
At 1000×1000 boxes, peak traced allocation goes from 88.02 MB to 40.02 MB. Local timing for that allocation-heavy case was noisy on its own, but the ranges never overlap: 33.40-172.54 ms/call on develop against 6.97-11.17 ms/call with this patch, over 15 paired runs.
This implementation comes from the TrackEval port in #210. Its correctness tests use small matrices with tolerance comparisons, so they cover the result but don't catch the temporary-allocation cost.