Skip to content

feat(simg4ox): support multithreaded Geant4 runs - #441

Open
plexoos wants to merge 6 commits into
mainfrom
support-mt-g4-run
Open

feat(simg4ox): support multithreaded Geant4 runs#441
plexoos wants to merge 6 commits into
mainfrom
support-mt-g4-run

Conversation

@plexoos

@plexoos plexoos commented Aug 25, 2026

Copy link
Copy Markdown
Member

Summary

  • Add --threads N to select serial or multithreaded Geant4 execution while preserving the serial default.
  • Construct worker-local Geant4 actions through G4VUserActionInitialization.
  • Retain each event’s photon payload and serialize access to the process-wide Opticks GPU context in event-ID order.
  • Merge worker CPU/GPU hit collections by event ID and write the existing g_hits.npy and s_hits.npy run outputs.
  • Add MT integration coverage and document the execution model with a Typst-generated timeline.

Runtime model

Geant4 event processing runs concurrently when --threads N is greater than one. Opticks GPU photon transport remains serialized because its event context is process-wide.

MT workers retain their generated photons on the G4Event until entering the ordered GPU section. Full CPU-side Opticks photon-history recording remains available in serial mode, while both modes collect sensitive-detector hits and produce run-wide hit arrays.

Select serial or MT Geant4 run managers through --threads and construct worker-local user actions through G4VUserActionInitialization.

Preserve per-event source photons for ordered GPU launches, serialize access to the process-wide Opticks context, and merge CPU/GPU hit arrays by event ID through a custom G4Run.

Add a two-worker CTest fixture, Geant macro, runner, and serial/MT usage documentation.
@plexoos plexoos self-assigned this Aug 25, 2026
@plexoos plexoos added the enhancement New feature or request label Aug 25, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 28e06447fa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/g4app.h Outdated

Copilot AI 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.

Pull request overview

Adds multithreaded Geant4 execution support to simg4ox while keeping Opticks GPU transport serialized, and updates tests/docs to reflect the new execution model.

Changes:

  • Add --threads N and select serial vs MT Geant4 run managers via G4RunManagerFactory.
  • Refactor Geant4 user actions to be worker-local via G4VUserActionInitialization, with serialized GPU processing in event-ID order and run-level hit merging.
  • Add an MT integration test plus expanded documentation (including a Typst timeline) describing the runtime model.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/test_simg4ox_multithread.sh New integration test driver script for MT runs and output validation.
tests/run_mt.mac New 5-event macro tailored for MT execution (init + beamOn).
tests/CMakeLists.txt Registers the new MT integration test and sets a dedicated working directory.
src/simg4ox.cpp Adds --threads CLI and uses Geant4 run-manager factory to select serial vs MT.
src/g4app.h Refactors actions for MT: worker-local actions, serialized GPU section, run merge by event ID.
src/CMakeLists.txt Updates simg4ox target description to reflect serial/MT CPU + serialized GPU launches.
README.md Documents --threads and the serialized GPU constraint at a high level.
examples/README.md Updates simg4ox example docs to cover Geant4 MT and ordered GPU serialization.
docs/performance-and-debugging.md Adds guidance for interpreting MT timings given serialized GPU work.
docs/inputs-outputs.md Documents simg4ox execution model and run-level output arrays in serial/MT.
docs/getting-started.md Adds how to run the new MT integration test and notes MT build requirements.
docs/assets/simg4ox-event-processing.typ Adds Typst source for an MT vs serial execution timeline graphic.
Suppressed comments (1)

src/g4app.h:401

  • This assert(primary_info && ...) guards a dereference, but assert is compiled out in release builds (when NDEBUG is set). In that case primary_info can be null and the next line will be undefined behavior. Prefer an explicit runtime check that either fails the event/run or returns safely.
            const auto* primary_info = dynamic_cast<const PrimaryPhotonInfo*>(event->GetUserInformation());
            assert(primary_info && "MT events must retain their generated photons for GPU processing");
            SEvt::SetInputPhoton(MakePhotonArray(primary_info->photons));
        }

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/g4app.h
Comment on lines +3 to 5
#include <condition_variable>
#include <cstring>
#include <filesystem>
Comment thread src/g4app.h Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 1 comment.

Comment thread src/g4app.h
Comment on lines +398 to +404
const PrimaryPhotonInfo* primary_info = nullptr;
if (order_gpu_events)
{
primary_info = dynamic_cast<const PrimaryPhotonInfo*>(event->GetUserInformation());
if (!primary_info)
throw std::runtime_error("MT event is missing its generated photons for GPU processing");
}

Copilot AI 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.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 1 comment.

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

tests/test_simg4ox_multithread.sh:34

  • The reused checker only counts matching log lines, sums hit counts, and checks aggregate array shape/dtype; it never reads event IDs or verifies event grouping/content. Consequently this MT test still passes if GPU launches occur out of event-ID order or if the worker merge produces the wrong event order, which are the central new guarantees. Add event-identifying test data/instrumentation and assert launch and aggregate ordering explicitly.
"${PYTHON}" "${REPO_DIR}/tests/check_simg4ox_multievent.py" \
    --log "${RUN_LOG}" \
    --output-dir "${PWD}" \
    --events 5

Comment thread tests/CMakeLists.txt Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 1 comment.

Comment thread tests/test_simg4ox_multithread.sh Outdated

Copilot AI 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.

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

tests/test_simg4ox_multithread.sh:29

  • This integration check only validates hit counts and array shapes; it does not verify the new event-to-payload association or event-ID ordering. generate_photons is called with its default seed of 0 for every event, so all event inputs are identical and a stale/swapped payload or incorrectly ordered merge would still pass. Make the test inputs observably event-specific and assert that the GPU and saved run arrays preserve event-ID order.
"${PYTHON}" "${REPO_DIR}/tests/check_simg4ox_multievent.py" \
    --log "${RUN_LOG}" \
    --output-dir "${PWD}" \
    --events 5

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants