Skip to content

Report Kamino contact buffer overflow - #3791

Open
rubengrandia wants to merge 4 commits into
newton-physics:mainfrom
rubengrandia:rgrandia/report_kamino_contact_overflow
Open

Report Kamino contact buffer overflow#3791
rubengrandia wants to merge 4 commits into
newton-physics:mainfrom
rubengrandia:rgrandia/report_kamino_contact_overflow

Conversation

@rubengrandia

@rubengrandia rubengrandia commented Aug 4, 2026

Copy link
Copy Markdown
Member

Description

Add graph-capture-friendly, one-time wp.printf warnings when Kamino truncates contacts because either per-world or model contact capacity is exhausted. Apply the diagnostic to primitive narrow-phase contact generation and Newton-to-Kamino contact conversion, with regression coverage for both paths.

Implements disneyresearch/newton#115.

A user-facing overflow API is out of scope: Newton does not yet have an established API for this diagnostic. This PR therefore limits behavior to a single warning, following the precedent introduced for DVI in #3613.

Checklist

  • New or existing tests cover these changes
  • The documentation is up to date with these changes
  • CHANGELOG.md has been updated (if user-facing change)

Test plan

uv run --extra dev -m unittest newton._src.solvers.kamino.tests.test_geometry_contacts newton._src.solvers.kamino.tests.test_geometry_primitive

Summary by CodeRabbit

  • Bug Fixes

    • Improved contact-capacity management during collision detection, including safer handling when storage limits are reached.
    • Overflow warnings are now emitted once per collision pass and reset appropriately for subsequent passes.
    • Standardized capacity handling across supported collision types, with consistent contact truncation behavior.
  • Tests

    • Added coverage for warning state transitions after overflow, successful processing, and repeated overflow.
    • Expanded validation for undersized contact storage across collision-processing scenarios.

@rubengrandia
rubengrandia requested a review from a team as a code owner August 4, 2026 12:33
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3efa5664-ee15-4f13-90eb-c32e9408ac61

📥 Commits

Reviewing files that changed from the base of the PR and between abf6c9f and c3a0e4b.

📒 Files selected for processing (3)
  • newton/_src/solvers/kamino/_src/geometry/contacts.py
  • newton/_src/solvers/kamino/_src/geometry/primitive/narrowphase.py
  • newton/_src/solvers/kamino/_src/geometry/unified.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • newton/_src/solvers/kamino/_src/geometry/unified.py
  • newton/_src/solvers/kamino/_src/geometry/contacts.py
  • newton/_src/solvers/kamino/_src/geometry/primitive/narrowphase.py

📝 Walkthrough

Walkthrough

Kamino centralizes contact-capacity reservation through a new reserve_contact_capacity helper that performs atomic world and model reservations, enforces limits with rollback, and emits one-time overflow warnings via a private Warp flag. Contact conversion, the unified contact writer, and primitive narrow-phase colliders all use this shared helper. The collision pipeline allocates the warning flag, clears it before each pass, forwards it through the narrow-phase kernel, and validates allocation. Tests verify flag state transitions across truncation and recovery scenarios.

Changes

Contact overflow handling

Layer / File(s) Summary
Overflow warning flag and reservation function
newton/_src/solvers/kamino/_src/geometry/contacts.py
ContactsKaminoData adds a private integer-array flag. reserve_contact_capacity reserves world and model capacity atomically, rolls back partial failures, caps output on overflow, and emits warnings once through an atomic flag.
Contact conversion with reservation
newton/_src/solvers/kamino/_src/geometry/contacts.py
The Newton-to-Kamino conversion kernel receives the overflow-warning flag and uses reserve_contact_capacity to reserve indices. The launcher allocates and passes the flag.
Unified contact writer with reservation
newton/_src/solvers/kamino/_src/geometry/unified.py
The contact writer delegates capacity allocation to reserve_contact_capacity, replacing inline atomic operations. The overflow-warning buffer is renamed to _contact_overflow_warning_emitted.
Pipeline state allocation and validation
newton/_src/solvers/kamino/_src/geometry/primitive/pipeline.py, newton/_src/solvers/kamino/_src/geometry/unified.py
The pipeline allocates the overflow-warning flag at finalization, clears it before collision passes, forwards it to narrow-phase processing, and validates allocation during finalized-state checks.
Primitive narrow-phase with reservation
newton/_src/solvers/kamino/_src/geometry/primitive/narrowphase.py
Contact writers (add_single_contact and add_multiple_contacts) use reserve_contact_capacity instead of inline atomic operations. All primitive colliders propagate the overflow-warning buffer through the call chain to contact writers. The narrow-phase kernel and launcher receive and pass the buffer.
Test validation of overflow behavior
newton/_src/solvers/kamino/tests/test_geometry_contacts.py, newton/_src/solvers/kamino/tests/test_geometry_primitive.py, newton/_src/solvers/kamino/tests/test_solvers_dvi.py
Tests verify that the overflow-warning flag is set after truncation, cleared on non-overflow runs, and set again on subsequent overflows. Tests cover conversion, primitive narrow-phase, and DVI solver integration.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

  • newton-physics/newton#3732: Both changes modify Kamino contact-capacity overflow handling in contacts.py and unified.py.
  • newton-physics/newton#3613: Both changes modify Kamino contact handling and overflow management used by the DVI solver.
  • newton-physics/newton#2280: Both changes modify Kamino's primitive/unified collision pipeline and narrow-phase interfaces, with overflow-capacity handling extending mesh/heightfield support.

Suggested labels: kamino

Suggested reviewers: guirec-maloisel, chschuma-disney

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective: adding contact buffer overflow reporting functionality to Kamino.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@newton/_src/solvers/kamino/_src/geometry/primitive/pipeline.py`:
- Around line 195-202: Reset the overflow warning flag before every kernel
launch so each execution can emit one diagnostic: clear
self._contact_overflow_warning_emitted before primitive_narrowphase in
newton/_src/solvers/kamino/_src/geometry/primitive/pipeline.py lines 195-202,
and clear contacts_out._data.contact_overflow_warning_emitted after
contacts_out.clear() and before wp.launch() in
newton/_src/solvers/kamino/_src/geometry/contacts.py lines 1401-1401. Add
reuse-based tests in newton/_src/solvers/kamino/tests/test_geometry_primitive.py
lines 1099-1112 and newton/_src/solvers/kamino/tests/test_geometry_contacts.py
lines 1395-1395, asserting the flag is 0 after a non-overflow run and returns to
1 after a subsequent overflow run.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: cacea4d6-1748-4ae6-a702-1f26c259ab82

📥 Commits

Reviewing files that changed from the base of the PR and between 0efb72d and e2854a9.

📒 Files selected for processing (5)
  • newton/_src/solvers/kamino/_src/geometry/contacts.py
  • newton/_src/solvers/kamino/_src/geometry/primitive/narrowphase.py
  • newton/_src/solvers/kamino/_src/geometry/primitive/pipeline.py
  • newton/_src/solvers/kamino/tests/test_geometry_contacts.py
  • newton/_src/solvers/kamino/tests/test_geometry_primitive.py

Comment thread newton/_src/solvers/kamino/_src/geometry/primitive/pipeline.py
@rubengrandia

Copy link
Copy Markdown
Member Author

Open question is how often the warning should emit. @Guirec-Maloisel , @chschuma-disney . We have it currently configured to warn only once. Alternative would be to reset and warn every step.

@codecov

codecov Bot commented Aug 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Comment thread newton/_src/solvers/kamino/_src/geometry/primitive/narrowphase.py
Comment thread newton/_src/solvers/kamino/_src/geometry/contacts.py Outdated
Comment thread newton/_src/solvers/kamino/_src/geometry/contacts.py Outdated

@Guirec-Maloisel Guirec-Maloisel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding the open question (warning frequency): not really sure, but I think I'm leaning towards having this warning more frequently (once per time step with culled contacts), because by construction it can't really be a false positive. So I'd say it's worse if it gets potentially overlooked (because hidden in the middle of many lines about modules being loaded etc; with wp.printf() we can't send this through the proper warning channel with colored text); than to annoy some users (for which the fix should be relatively straightforward).

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
newton/_src/solvers/kamino/_src/geometry/contacts.py (1)

422-432: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the return packing and the reserved count contract.

reserve_contact_capacity is shared by three modules, and it returns a packed wp.vec3i whose components are not self-describing. Callers must also know that component 1 is the retained count, which can be smaller than num_contacts. Both current callers pass num_contacts=1 and ignore component 1, so partial reservations stay latent. Add a Google-style Args:/Returns: block that names each component and states the caller obligation.

♻️ Proposed docstring
-    """Reserve contact capacity and return the model/world indices and number reserved."""
+    """Reserve contact capacity atomically in the per-world and model contact counters.
+
+    Args:
+        model_max_contacts: Contact capacity of the model buffer.
+        world_max_contacts: Contact capacity of world ``wid``.
+        wid: World index of the contacts to reserve.
+        num_contacts: Number of contacts requested.
+        contact_model_num: Model-level active contact counter, shape ``(1,)``.
+        contact_world_num: Per-world active contact counters, shape ``(num_worlds,)``.
+        contact_overflow_warning_emitted: One-time overflow warning flag, shape ``(1,)``.
+
+    Returns:
+        ``(model_index, num_reserved, world_index)``. ``model_index`` is ``-1`` when no
+        capacity was reserved. ``num_reserved`` can be smaller than ``num_contacts``,
+        so callers that request more than one contact must write only ``num_reserved``
+        contacts starting at ``model_index``/``world_index``.
+    """
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@newton/_src/solvers/kamino/_src/geometry/contacts.py` around lines 422 - 432,
The reserve_contact_capacity function lacks documentation explaining its packed
wp.vec3i return value and the contract that component 1 represents the retained
count, which may be smaller than num_contacts. Add a Google-style docstring with
Args and Returns sections that names each component of the returned wp.vec3i,
explicitly states that the retained count can be smaller than the requested
num_contacts parameter, and clarifies the caller obligation to handle and check
for partial reservations instead of assuming full allocation.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@newton/_src/solvers/kamino/_src/geometry/contacts.py`:
- Around line 422-432: The reserve_contact_capacity function lacks documentation
explaining its packed wp.vec3i return value and the contract that component 1
represents the retained count, which may be smaller than num_contacts. Add a
Google-style docstring with Args and Returns sections that names each component
of the returned wp.vec3i, explicitly states that the retained count can be
smaller than the requested num_contacts parameter, and clarifies the caller
obligation to handle and check for partial reservations instead of assuming full
allocation.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: e33b4419-8686-4b79-8514-07efd870efdf

📥 Commits

Reviewing files that changed from the base of the PR and between e2854a9 and 915f1d8.

📒 Files selected for processing (7)
  • newton/_src/solvers/kamino/_src/geometry/contacts.py
  • newton/_src/solvers/kamino/_src/geometry/primitive/narrowphase.py
  • newton/_src/solvers/kamino/_src/geometry/primitive/pipeline.py
  • newton/_src/solvers/kamino/_src/geometry/unified.py
  • newton/_src/solvers/kamino/tests/test_geometry_contacts.py
  • newton/_src/solvers/kamino/tests/test_geometry_primitive.py
  • newton/_src/solvers/kamino/tests/test_solvers_dvi.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • newton/_src/solvers/kamino/tests/test_geometry_contacts.py
  • newton/_src/solvers/kamino/tests/test_geometry_primitive.py
  • newton/_src/solvers/kamino/_src/geometry/primitive/pipeline.py
  • newton/_src/solvers/kamino/_src/geometry/primitive/narrowphase.py

@rubengrandia

Copy link
Copy Markdown
Member Author

Regarding the open question (warning frequency): not really sure, but I think I'm leaning towards having this warning more frequently (once per time step with culled contacts), because by construction it can't really be a false positive. So I'd say it's worse if it gets potentially overlooked (because hidden in the middle of many lines about modules being loaded etc; with wp.printf() we can't send this through the proper warning channel with colored text); than to annoy some users (for which the fix should be relatively straightforward).

Sounds good. I updated it to reset the flag every simulation step. If it becomes too annoying we can always make it less verbose again.

@Guirec-Maloisel Guirec-Maloisel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates, looks good to me now! I think I can live with the warnings being slightly less specific.

Leaving approval to @chschuma-disney in case he has a different opinion on the warning frequency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants