Skip to content

Commit 222c0b7

Browse files
committed
Initialise manager, lock, and queue lazily.
1 parent 787dcb3 commit 222c0b7

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

src/somd2/runner/_runner.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,20 @@ class Runner(_RunnerBase):
4040
Standard simulation runner class. (Uncoupled simulations.)
4141
"""
4242

43-
from multiprocessing import Manager
43+
_manager = None
4444

45-
_manager = Manager()
46-
_lock = _manager.Lock()
47-
_queue = _manager.Queue()
45+
@classmethod
46+
def _init_manager(cls):
47+
"""
48+
Initialise the shared-memory Manager the first time a Runner is
49+
constructed in the parent process. Deferred from class definition time
50+
so that importing this module does not fork a manager process before
51+
OpenMM threads have been started.
52+
"""
53+
if cls._manager is None:
54+
from multiprocessing import Manager
55+
56+
cls._manager = Manager()
4857

4958
def __init__(self, system, config):
5059
"""
@@ -73,6 +82,16 @@ def __init__(self, system, config):
7382
# Call the base class constructor.
7483
super().__init__(system, config)
7584

85+
# Initialise the shared-memory manager lazily so that importing this
86+
# module does not fork a manager process before OpenMM threads exist.
87+
Runner._init_manager()
88+
89+
# Create Lock and Queue as instance attributes so that they are
90+
# pickled as manager proxies and shared correctly across all spawned
91+
# worker processes, preventing race conditions on the GPU pool.
92+
self._lock = Runner._manager.Lock()
93+
self._queue = Runner._manager.Queue()
94+
7695
# Store the array of lambda values for energy sampling.
7796
if self._config.lambda_energy is not None:
7897
self._lambda_energy = self._config.lambda_energy.copy()

0 commit comments

Comments
 (0)