Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating threads to update visualization asynchronously #2656

Open
wants to merge 22 commits into
base: main
Choose a base branch
from

Conversation

HMNS19
Copy link
Contributor

@HMNS19 HMNS19 commented Jan 31, 2025

Summary

This PR introduces a thread-based mechanism to handle model updates and visualization rendering concurrently. It ensures smooth execution of simulations by separating model step execution and visualization updates into independent threads, improving performance and responsiveness during simulations.
Fixes #2604

Motive

Previously, the visualization process could become a bottleneck during rapid simulations, as rendering was tightly coupled with model updates. This caused delays and UI responsiveness issues. By separating these operations into threads, the model execution is no longer hindered by the visualization process.

Implementation

  1. Introduced separate thread for visualisation:
    Handles visualization updates triggered by threading.Event (visualization_pause_event) to synchronize rendering with model steps.
  2. Thread Synchronization:
    Implemented visualization_pause_event to signal the visualization thread after each model step is completed, ensuring rendering happens efficiently without blocking the simulation.

Usage Examples

  • Play Button Behavior: The play button now ensures the simulation continues smoothly.

  • Concurrent Rendering: Visualization and simulation run in parallel, reducing delays.

  • Before
    Screenshot 2025-01-10 200323

  • After
    Screenshot 2025-01-31 130506

Additional Notes

  • Dependencies: Utilizes solara.use_thread and Python's threading mechanisms for concurrency.
  • Potential Side Effects: Proper adjustment of play_interval is recommended to balance simulation speed and rendering performance.

HMNS19 and others added 20 commits January 19, 2025 21:46
execution is slower,thread not stopping gracefully
pending-
eipstein not rendering prply(check other models)
stopping thread(use_thread)
graph inaccuracy
implementing bi-directional threads is ensuring synchronization between model execution and visualization, though this is resulting in reduced performance.
takes care of valueError and CancelledError.
pending changes:clean code
optimal performance in browser and jupyter
In use_threads, the threads for step and vis may compete for GI leading to slower execution, especially when sharing resources. In contrast, use_task, which is asyncio-based, avoids GIL contention.
Copy link

Performance benchmarks:

Model Size Init time [95% CI] Run time [95% CI]
BoltzmannWealth small 🔵 +0.8% [+0.2%, +1.3%] 🔵 +0.1% [-0.0%, +0.2%]
BoltzmannWealth large 🔵 +0.3% [-0.3%, +0.9%] 🔵 +0.5% [+0.2%, +0.9%]
Schelling small 🔵 +0.3% [+0.0%, +0.6%] 🔵 -0.3% [-0.4%, -0.2%]
Schelling large 🔵 +0.5% [+0.2%, +0.8%] 🔵 -0.3% [-0.7%, -0.0%]
WolfSheep small 🔵 -0.2% [-0.4%, +0.0%] 🔵 +0.0% [-0.1%, +0.2%]
WolfSheep large 🔵 +0.3% [-0.2%, +0.7%] 🔵 +0.4% [-0.1%, +0.8%]
BoidFlockers small 🔵 +0.8% [+0.3%, +1.4%] 🔵 +1.0% [+0.8%, +1.2%]
BoidFlockers large 🔵 +0.6% [+0.2%, +1.0%] 🔵 +0.1% [-0.1%, +0.3%]

@EwoutH
Copy link
Member

EwoutH commented Jan 31, 2025

Thanks for the PR and the detailed PR message!

I’m on vacation the whole of February, so I will leave the review to other maintainers.

Have you also tried using a separate thread for every figure?

@HMNS19
Copy link
Contributor Author

HMNS19 commented Feb 1, 2025

Thanks! Hope you have a great vacation!
I actually had a few questions about using separate threads for each figure. Right now, this PR allows the model to run in the background while plotting, without worrying about sync issues. But if we spawn a thread for each figure, wouldn’t we need to constantly keep the figures in sync with each other to avoid confusion? And wouldn’t that also require locks to manage shared data properly?

…control

This should improve the overall functionality and reliability of the SimulatorController, particularly in scenarios where stopping the execution is necessary.
@EwoutH
Copy link
Member

EwoutH commented Feb 1, 2025

But if we spawn a thread for each figure, wouldn’t we need to constantly keep the figures in sync with each other to avoid confusion?

That's an excellent point. You're right.

Another option could be that a new thread is used to draw all figures for a single step. Then the figures for a certain step will be ready at the same time.

You would have to guarantee that each frame is displayed for about the same time (or for a minimum duration).

It's up to you how complicated you make it in this PR. We could also keep this PR to a minimal, simple implementation and implement further ideas in future PRs.

@HMNS19
Copy link
Contributor Author

HMNS19 commented Feb 2, 2025

Yes, this PR ensures a single thread handles drawing all figures together for a specific step, ensuring synchronization.

You would have to guarantee that each frame is displayed for about the same time (or for a minimum duration).

Noted, currently even if the play interval is set, the model doesn’t always visualize it correctly, and the user has to manually adjust it leading to poor responsiveness.I'll start working on this and create a new PR to handle this issue.

@HMNS19
Copy link
Contributor Author

HMNS19 commented Feb 6, 2025

Hi @quaquel , Is this PR good to go, or does it need any changes? Since @EwoutH is on vacation, I wanted to check if anyone else could review it. I’d like to get some input regarding this PR before starting a follow-up to keep the next PR aligned.

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

Successfully merging this pull request may close these issues.

Improve visualization performance through multi-threading
2 participants