Skip to content

Commit 6a1befe

Browse files
authored
Use spawn start method for multiprocessing inside the test to avoid deadlock/timeout on Azure (#5213)
* Fixes #5191 * use a spawn start method inside the test instead of pool to avoid deadlock (especially observed on Azure) * add duration for azure * add explicit comments to code
1 parent 9531c6e commit 6a1befe

File tree

2 files changed

+21
-10
lines changed

2 files changed

+21
-10
lines changed

azure-pipelines.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ jobs:
131131
displayName: 'Check installed packages'
132132
- powershell: |
133133
cd testsuite
134-
pytest MDAnalysisTests --disable-pytest-warnings -n logical --timeout=200 -rsx --cov=MDAnalysis
134+
pytest MDAnalysisTests --disable-pytest-warnings -n logical --timeout=200 -rsx --cov=MDAnalysis --durations=50
135135
displayName: 'Run MDAnalysis Test Suite'
136136
- script: |
137137
curl -s https://codecov.io/bash | bash

testsuite/MDAnalysisTests/parallelism/test_multiprocessing.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,19 @@ def cog(u, ag, frame_id):
129129

130130
def test_multiprocess_COG(u):
131131
ag = u.atoms[2:5]
132-
133132
ref = np.array([cog(u, ag, i) for i in range(3)])
134133

135-
p = multiprocessing.Pool(2)
136-
res = np.array([p.apply(cog, args=(u, ag, i)) for i in range(3)])
137-
p.close()
134+
# Explicitly use `spawn` for multiprocessing tests
135+
# As `fork` can lead to deadlock in pytest because each xdist worker creates a multiprocessing.Pool.
136+
# related issue: #5191; PR #5213
137+
ctx = multiprocessing.get_context("spawn")
138+
# The commented code can lead to timeout that is not marked as a failure due.
139+
# p = multiprocessing.Pool(2)
140+
# res = np.array([p.apply(cog, args=(u, ag, i)) for i in range(3)])
141+
# p.close()
142+
with ctx.Pool(2) as p:
143+
res = np.array(p.starmap(cog, [(u, ag, i) for i in range(3)]))
144+
138145
assert_equal(ref, res)
139146

140147

@@ -147,10 +154,11 @@ def test_universe_unpickle_in_new_process():
147154
u = mda.Universe(GRO, XTC)
148155
ref = [getnames(u, i) for i in range(3)]
149156

150-
p = multiprocessing.Pool(2)
151-
res = [p.apply(getnames, args=(u, i)) for i in range(3)]
152-
p.close()
153-
157+
# related issue: #5191; PR #5213
158+
ctx = multiprocessing.get_context("spawn")
159+
with ctx.Pool(2) as p:
160+
res = [p.apply_async(getnames, args=(u, i)) for i in range(3)]
161+
res = [r.get() for r in res]
154162
assert_equal(ref, res)
155163

156164

@@ -162,7 +170,10 @@ def test_creating_multiple_universe_without_offset(temp_xtc, ncopies=3):
162170
# a problem (see PR #3375 and issues #3230, #1988)
163171

164172
args = (GRO, str(temp_xtc))
165-
with multiprocessing.Pool(2) as p:
173+
174+
# related issue: #5191; PR #5213
175+
ctx = multiprocessing.get_context("spawn")
176+
with ctx.Pool(2) as p:
166177
universes = [p.apply_async(mda.Universe, args) for i in range(ncopies)]
167178
universes = [universe.get() for universe in universes]
168179

0 commit comments

Comments
 (0)