Fix init_prism centroid; make test-prism's parallel loops thread-safe - #81
Merged
Merged
Conversation
…aths Two related bugs surfaced by running the --enable-openmp test suite against test-prism, both pre-existing: 1) init_prism assigned prsm->centroid BEFORE the shift-to-o->center logic, then the shift only updated a local `centroid` variable. After construction, any prism whose center was modified ended up with prsm->centroid stale relative to the (shifted) vertices. 2) point_in_objectp, normal_to_object, and point_in_periodic_objectp each called geom_fix_object_ptr(&o) on every query. For prisms that path calls reinit_prism, which free()s + malloc()s shared per-prism arrays (vertices_p, vertices_top_p, ...). Under OpenMP the test was crashing with "malloc(): unaligned tcache chunk" / "free(): double free". This matches what PR NanoComp#75 already did for geom_get_bounding_box -- callers are now responsible for calling geom_fix_object_ptr after mutating o.center. test-prism: after the random-shift branch, call geom_fix_object_ptr on the block and prism once, single-threaded, before the parallel test loops run. Verified at OMP_NUM_THREADS = 1, 2, 4, 8, 16, 32, 64, 128, 166: all clean (0 point failures, 0 segment failures, no heap corruption). make check passes.
stevengj
reviewed
May 22, 2026
Per review feedback, point_in_objectp / normal_to_object / point_in_periodic_objectp are restored to their original behavior (call geom_fix_object_ptr internally) rather than being silently turned into thin aliases for the *_fixed_* variants. Their doc comments now state they are NOT thread-safe and direct concurrent callers at the *_fixed_* entry points. test-prism's parallel loops switched from point_in_objectp / normal_to_object to point_in_fixed_objectp / normal_to_fixed_object, which are pure reads and safe to call from multiple threads against an object that was fixed up once beforehand. Combined with the init_prism centroid fix in the previous commit, make check passes cleanly across OMP_NUM_THREADS = 1, 2, 4, 8, 16, 64, 166 (21 trials each: 0 point-inclusion failures, 0 segment failures, no heap-corruption signatures).
Collaborator
|
The revised PR looks good to me. |
Luochenghuang
added a commit
to Luochenghuang/libctl
that referenced
this pull request
May 29, 2026
Drops the macos-latest matrix entry per maintainer preference (less useful: project is primarily Linux-targeted, macOS runners cost more minutes, and the existing Travis macOS coverage didn't exercise anything Linux didn't). Adds --enable-openmp to the configure step and matrices the run on OMP_NUM_THREADS = 1 and 8. Both values share the same build; only the runtime thread count differs. This catches regressions in the parallel test paths (test-prism's #pragma omp parallel for loops in test_point_inclusion, test_normal_to_object, and test_line_segment_intersection) that a serial-only run wouldn't flag — same matrix philosophy used to validate the prism thread-safety work in PR NanoComp#75 / NanoComp#81.
Luochenghuang
added a commit
to Luochenghuang/libctl
that referenced
this pull request
May 29, 2026
Drops the macos-latest matrix entry per maintainer preference (less useful: project is primarily Linux-targeted, macOS runners cost more minutes, and the existing Travis macOS coverage didn't exercise anything Linux didn't). Adds --enable-openmp to the configure step and matrices the run on OMP_NUM_THREADS = 1 and 8. Both values share the same build; only the runtime thread count differs. This catches regressions in the parallel test paths (test-prism's #pragma omp parallel for loops in test_point_inclusion, test_normal_to_object, and test_line_segment_intersection) that a serial-only run wouldn't flag — same matrix philosophy used to validate the prism thread-safety work in PR NanoComp#75 / NanoComp#81.
stevengj
pushed a commit
that referenced
this pull request
May 29, 2026
* Migrate CI from Travis to GitHub Actions
Replaces the Travis configuration with an equivalent GitHub Actions
workflow at .github/workflows/ci.yml. Same matrix (ubuntu-latest +
macos-latest), same build pipeline (autogen.sh, make, make check,
make install), same on-failure log dump for utils/*.log.
Two minor modernizations:
- Switches the Ubuntu guile package from guile-2.0-dev to
guile-3.0-dev. guile-2.0 was dropped from Ubuntu after 20.04;
libctl already builds and runs against guile 3.0.
- macOS dependency install adds autoconf/automake/libtool explicitly
rather than relying on the runner image to provide them.
Workflow triggers on push to master, pull_request to master, and
manual workflow_dispatch. fail-fast disabled so a failure on one OS
doesn't cancel the other.
Also removes the Travis CI badge from README.md and replaces it with
a GitHub Actions badge pointing at the new workflow.
* CI: drop macOS, add OMP_NUM_THREADS matrix to exercise parallel tests
Drops the macos-latest matrix entry per maintainer preference (less
useful: project is primarily Linux-targeted, macOS runners cost more
minutes, and the existing Travis macOS coverage didn't exercise
anything Linux didn't).
Adds --enable-openmp to the configure step and matrices the run on
OMP_NUM_THREADS = 1 and 8. Both values share the same build; only
the runtime thread count differs. This catches regressions in the
parallel test paths (test-prism's #pragma omp parallel for loops in
test_point_inclusion, test_normal_to_object, and
test_line_segment_intersection) that a serial-only run wouldn't
flag — same matrix philosophy used to validate the prism
thread-safety work in PR #75 / #81.
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.
After #75 + #79,
test-prismwith--enable-openmpwas still failing atOMP_NUM_THREADS >= 2with heap corruption and intermittent point-inclusion mismatches. Two issues.1.
init_prismwritesprsm->centroidbefore the optional shiftThe line
prsm->centroid = centroid = ...happens before theelseblock that shifts bothverticesand the localcentroidto land ono->center. The shift only updates the local —prsm->centroidstays at the pre-shift value, while the vertex arrays reflect the shifted geometry. Block-vs-prism point-inclusion then disagrees on the difference between old and new placement.The pre-PR auto-fix in
point_in_objectpmasked this in serial code (the second call recomputedcentroidfrom the now-shifted vertices), but #79's parallel loop exposed it.Fix: move
prsm->centroid = centroid;to after the if/else. Idempotent in serial code too — not OpenMP-specific.2. test-prism's parallel loops were calling the thread-unsafe wrappers
point_in_objectp/normal_to_object/point_in_periodic_objectpcallgeom_fix_object_ptron every invocation, which for prisms doesfree/mallocon shared per-prism arrays. Two threads racing on the same prism corrupt the allocator — the original crash from #79.The wrappers are kept as-is (preserving API contract for callers that mutate object parameters between queries) but their doc comments now mark them as not thread-safe and direct concurrent callers at the
*_fixed_*variants.In test-prism:
test_point_inclusion: switch topoint_in_fixed_objectp.test_normal_to_object(disabled but still parallel): switch tonormal_to_fixed_object.run_unit_tests: callgeom_fix_object_ptronthe_blockandthe_prisminside theP_SHIFTblock, before the parallel loops run.Verification
make checkpasses. Three trials each atOMP_NUM_THREADS = 1, 2, 4, 8, 16, 64, 166: 21/21 clean (0/10000 points failed, 0/1000 segments failed, no heap-corruption signatures).