Skip to content

Conversation

@jmaack24
Copy link
Member

No description provided.

@jmaack24 jmaack24 requested a review from Copilot December 11, 2025 22:27
@jmaack24 jmaack24 self-assigned this Dec 11, 2025
@jmaack24 jmaack24 linked an issue Dec 11, 2025 that may be closed by this pull request
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements multi-threading support in the NativeRunner to enable parallel ray tracing. The implementation introduces a ThreadManager class to coordinate multiple worker threads, refactors the TRayData structure to handle thread-safe ray data collection, and updates the trace functions to support concurrent execution.

Key changes include:

  • Addition of ThreadManager class for thread coordination and monitoring
  • Refactoring of ray tracing to split work across multiple threads with unique seeds
  • Conversion of ray numbering from unsigned int to uint_fast64_t to support larger simulations

Reviewed changes

Copilot reviewed 21 out of 21 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
thread_manager.hpp/cpp New ThreadManager class for managing multiple worker threads, tracking progress, and handling cancellation
trace.hpp/cpp Refactored trace_native to spawn multiple threads and added trace_single_thread for per-thread execution
native_runner.hpp/cpp Added thread count and seed management, delegated status/cancel operations to ThreadManager
native_runner_types.hpp/cpp Completely refactored TRayData from block-based storage to thread-indexed map structure for concurrent access
pt_optimizations.hpp/cpp Changed rec_hash parameter from reference to pointer for thread sharing
process_interaction.cpp Removed commented-out myrng_counter increments
generate_ray.hpp/cpp Made PosSunStage parameter const for thread safety
simulation_runner.hpp Added UNKNOWN status and status_string utility function
native_runner_test.cpp Changed EXPECT_EQ to ASSERT_EQ in critical assertions, added tests for multi-threaded cancellation and ray ID assignment
native_runner_multithreading_test.cpp New regression test for multi-threaded performance validation
count_absorbed_native.cpp Updated ray variable type from unsigned int to uint_fast64_t
simulation_data.hpp Enhanced comment documentation for clear() method
mtrand.hpp Code formatting improvements (whitespace and brace placement)
CMakeLists.txt Added thread_manager.cpp to build and new multithreading test file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jmaack24 jmaack24 requested a review from Copilot December 15, 2025 17:22
Copy link
Contributor

Copilot AI left a comment

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 24 out of 24 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Collaborator

@qualand qualand left a comment

Choose a reason for hiding this comment

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

I merged this into my validation branch and see no performance change when switching to multi-threading. Maybe we should discuss when you get a chance.

Comment on lines 73 to 76
// // TODO: This should throw an error...
// // Get RaySource data (this runner assumes there is only the Sun)
// assert(data->get_number_of_ray_sources() == 1);

Copy link
Collaborator

Choose a reason for hiding this comment

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

Remove

if (data->get_number_of_elements() <= 0)
{
throw std::invalid_argument("SimulationData has no elements.");
// return RunnerStatus::ERROR;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Remove

ThreadInfo my_info;
my_info.manager = manager;
my_info.System = System;
my_info.NumberOfRays = NumberOfRays / nthreads;
Copy link
Collaborator

Choose a reason for hiding this comment

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

This method does not preserve the expected ray count. Can we set unique number of rays by thread? This would allow each thread to run the truncated value of <NumberOfRays / nthreads> and one thread with the added remainder.

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed

TSystem *System,
unsigned int seed,
uint_fast64_t NumberOfRays,
uint_fast64_t MaxNumberOfRays, // TODO: How to handle MaxRays?
Copy link
Collaborator

Choose a reason for hiding this comment

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

We can handle the Max number of rays the same way as the number of rays. Each thread assigned with the truncated value of MaxNumberOfRays / nthreads, then one thread gets the remainder. This should preserve the user input of MaxNumberOfRays.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done


TEST(NativeRunner, Multithreading)
{
const uint_fast64_t NRAYS = 50000;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you add a check that confirms NRAYS in preserved in results?

runner.print_log(std::cout);
}

ASSERT_EQ(nrec, NRAYS);
Copy link
Collaborator

Choose a reason for hiding this comment

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

This works because 50,000 is divisible by 4.

std::cout << "Num Elements: " << sd.get_number_of_elements() << std::endl;

// Parameters
SimulationParameters &params = sd.get_simulation_parameters();
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is there a reason why should not put number of threads in the simulation parameters?

Copy link
Member Author

Choose a reason for hiding this comment

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

Number of threads is really a property of the ray tracer and not the ray tracing problem. It logically doesn't belong in the simulation parameters.

@taylorbrown75
Copy link
Collaborator

I merged this into my validation branch and see no performance change when switching to multi-threading. Maybe we should discuss when you get a chance.

I tested this by merging it into the legacy GUI branch, and adding threads did not speed up the simulation in my case either.

@qualand
Copy link
Collaborator

qualand commented Dec 18, 2025

I merged this into my validation branch and see no performance change when switching to multi-threading. Maybe we should discuss when you get a chance.

I tested this by merging it into the legacy GUI branch, and adding threads did not speed up the simulation in my case either.

Taylor, I resolved this issue on my end yesterday. The reason I didn't see a speed increase was because the number of rays I was running was too small and the ray data process method after the trace was the bigger bottleneck. Just an FYI.

Copy link
Collaborator

@qualand qualand left a comment

Choose a reason for hiding this comment

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

Thanks for updating the method to maintain desired ray count!

@taylorbrown75
Copy link
Collaborator

I merged this into my validation branch and see no performance change when switching to multi-threading. Maybe we should discuss when you get a chance.

I tested this by merging it into the legacy GUI branch, and adding threads did not speed up the simulation in my case either.

Taylor, I resolved this issue on my end yesterday. The reason I didn't see a speed increase was because the number of rays I was running was too small and the ray data process method after the trace was the bigger bottleneck. Just an FYI.

My issue is related to running in debug from the GUI. I ran the same stinput case via testing in release and saw speed improvement with added threads.

@jmaack24
Copy link
Member Author

Any objections to merging?

@qualand qualand merged commit 51f7ecc into develop Dec 19, 2025
12 checks passed
@qualand qualand deleted the 90-implement-nativerunner-multi-threading-capability branch December 19, 2025 18:34
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.

Implement NativeRunner multi-threading capability

4 participants