Skip to content

Conversation

@agheata
Copy link
Member

@agheata agheata commented Jan 20, 2026

This Pull request:

Refactors and accelerates geometry overlap checking by splitting the procedure into well-defined stages, introducing candidate filtering and parallel execution, and fixing long-standing meshing and caching issues affecting correctness and performance. Preserves backward-compatibility of interfaces.

Changes or fixes:

  • Three-stage overlap checking workflow
image
  1. Candidate enumeration
    • Traverses the geometry tree.
    • Uses oriented bounding box (OBB) tests to reject non-overlapping volume pairs early. This gives in general a sizeable candidate reduction compared to the legacy version, and a massive one for assembly-dominated setups (a factor of ~1000 for ALICE O² geometry)
  2. Surface point generation and caching
    • Generates surface sampling points per shape using the values set via TGeoManager::SetPoints() (default 20) and TGeoManager::SetNmeshVertices() (default 1000).
    • Introduces a thread-safe per-shape mesh cache inside TGeoChecker.
    • Cache invalidation is correctly handled when the number of mesh points or mesh segments changes
    • Fixes incorrect behavior caused by:
      • reuse of static TBuffer3D buffers
      • stale mesh caches in TGeoCompositeShape / TGeoBoolNode
      • inconsistent GetPointsOnSegments() contracts in several shapes
  3. Exact overlap checking following check points density
    • Performs navigation-based overlap tests using cached surface points.
    • This stage is now parallelized using ROOT Implicit MT.
  • Parallel execution

    • Only the final overlap checking stage is parallelized (safe and scalable).
    • Uses ROOT::TThreadExecutor and respects ROOT::EnableImplicitMT(N).
    • Demonstrates good strong scaling on realistic detector geometries.
  • Correctness fixes in meshing

    • Reworked GetPointsOnSegments() for several shapes to:
      • avoid dependence on TBuffer3D static storage
      • generate points only on valid surface generators
      • respect a strict contract: return true only if exactly npoints are filled
    • Fixed incorrect assumptions in legacy implementations (e.g. TGeoBBox, TGeoTube, TGeoCone, TGeoPcon, TGeoCtub).
  • Performance impact

    • The check is more thorough (points more uniformly spread on solid surfaces) and typically much faster, because it reduces the number of candidates for the expensive check, and parallelizes this most expensive part.
    • On typical setups (e.g. cmsRun4D116), the gain using 32 threads is significant (from 6 sec to 2 sec on a 16-core machine for this example).
    • On assembly-rich setups (e.g. o2sim_geometry) the gain is massive (from ~4 hours to ~15 sec on the same machine)
    • Below is a strong scaling plot showing both the total time and the time for the parallelized checking stage for ALICE. Note that this is not the typical profile, it is shown mainly to show the scaling of the parallelized stage. For most setups, the weight of the sequential stages 1 and 2 is much smaller that the weight of the parallel stage 3.
c_strong_scaling

Checklist:

  • tested changes locally
  • updated the docs (if necessary)

This PR was done at the request of ALICE experiment, but provides setup-independent enhancements of the overlap checking feature

agheata and others added 15 commits January 20, 2026 10:42
Voxels marked as needing rebuild are built lazily, but this is a thread unsafe operation as it touches shared data. This introduces a method TGeoManager::RebuildVoxels that is called before checking overlaps, removing rebuilding potentially happening during the checking. The method TGeoChecker::CheckOverlaps is rewritten to avoid changing the list of overlaps attached to nodes, which was also a thread unsafe construct.
…;lelizable compute phase.

Checking overlaps by sampling points in volumes implemented now as CheckOverlapsBySampling, and marked as deprecated. In future we will support a surface-based sampling like in Geant4.
…y checks.

This reduces by a large factor the number of real checks to be done. In assembly-based setups such as ALICE, the factor is ~1000.
…d added new ones.

The legacy implementations for solids did not honour the contract that in case a shape overrides this method, it has to provide exactly the requested number of points if it returns true. The legacy versions even wrote more than the requested points, overwriting memory.

Fixes cache overriding of points by visualization, that made the point generation not deterministic.
…site shapes.

Previously, mesh points set via TGeoCompositeShape::SetPoints were cached only at the first call, making mesh generation invariant to the number of segments requested via TGeoManager. Now the caches are invalidated and rebuild lazily whenever the number of segment changes in the manager.
@agheata
Copy link
Member Author

agheata commented Jan 20, 2026

Working on fixing no-IMT mode

@github-actions
Copy link

github-actions bot commented Jan 20, 2026

Test Results

    22 files      22 suites   3d 14h 56m 12s ⏱️
 3 770 tests  3 769 ✅ 0 💤 1 ❌
75 878 runs  75 876 ✅ 0 💤 2 ❌

For more details on these failures, see this check.

Results for commit 793c33b.

♻️ This comment has been updated with latest results.

@agheata agheata marked this pull request as draft January 22, 2026 09:38
This was needed because the test is run in the same process as test_material_units, which changes the statically-initialized unit system in TGeoManager, inducing wrong material interpretation in GDML import used in the current test. This is not normal and should be debugged separately, but forcing the ROOT units seems to fix the problem

Split the geometry tests to avoid static interference
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant