You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
tests/ut/py/test_hostsub_fork_shm.py::TestParallelExecution::test_parallel_wall_time fails on macOS CI in roughly 2% of runs (4 of 218 sampled ut (macos-latest, 3.10) jobs over Jul 20-26; 0 of 101 Ubuntu jobs).
The test forks 3 workers, dispatches a time.sleep(0.2) callable to each, and asserts the wall time is under 80% of fully-serial.
This is not a marginal threshold. Measured on aarch64 Linux over 7 consecutive runs:
elapsed
ideal parallel
0.200 s
Linux actual
median 0.203 s, max 0.204 s
assertion threshold
0.480 s
macOS when failing
0.49 - 0.57 s
fully serial
0.600 s
Linux lands 1.5% above ideal with a 2 ms spread. The macOS failures are 2.5-2.9x that, and 85-95% of fully serial — parallelism essentially did not happen. Raising the threshold would silence exactly the signal this test exists to produce.
Only observed on macOS runners, ~1 in 50. I have no macOS box and could not reproduce it; everything below is from CI logs plus controlled Linux experiments.
Expected Behavior
Three children that each only time.sleep(0.2) finish in ~0.2 s wall time, as they do on Linux.
Actual Behavior
expected parallel wall time < 0.48s (serial would be 0.60s), got 0.57s
Not CPU scarcity, which was my leading hypothesis. The test's _worker_loop is a deliberate tight spin (# tight spin (same as L2 AICPU spin-wait — no yield)), so I expected 3 spinning children plus the parent to oversubscribe a narrow runner and starve the parent between its three sequential dispatch() calls. Pinning the test to 2 and to 3 cores with taskset on Linux gives 5/5 passes at each width. The mechanism does not hold: during the 0.2 s work window the children are inside time.sleep() and consume no CPU, so only the parent needs a core.
Not fork cost. The pool is constructed before start = time.monotonic().
Still unknown — and not resolvable without a macOS runner:
The runner's actual core count. No CI log line reports it.
Whether macOS thread QoS / scheduler behaviour deprioritises a process that has been spinning, delaying the parent's 2nd and 3rd dispatch() by ~0.2 s each. This is the shape the numbers suggest (near-serial = each worker starting a full sleep-period late), but I have no way to observe it.
Please do not "fix" this by relaxing the threshold or adding a retry. At 0.49-0.57 s against a 0.203 s Linux baseline, something is serialising three sleeping processes. A wider bound makes the symptom disappear while leaving whatever does that in place.
A cheap first step for whoever has a macOS machine: print os.cpu_count() and per-worker dispatch/completion timestamps from the test, then read which of the three workers started late.
Platform
All / Unknown
Runtime Variant
All / Unknown
Description
tests/ut/py/test_hostsub_fork_shm.py::TestParallelExecution::test_parallel_wall_timefails on macOS CI in roughly 2% of runs (4 of 218 sampledut (macos-latest, 3.10)jobs over Jul 20-26; 0 of 101 Ubuntu jobs).The test forks 3 workers, dispatches a
time.sleep(0.2)callable to each, and asserts the wall time is under 80% of fully-serial.This is not a marginal threshold. Measured on aarch64 Linux over 7 consecutive runs:
Linux lands 1.5% above ideal with a 2 ms spread. The macOS failures are 2.5-2.9x that, and 85-95% of fully serial — parallelism essentially did not happen. Raising the threshold would silence exactly the signal this test exists to produce.
Steps to Reproduce
Only observed on macOS runners, ~1 in 50. I have no macOS box and could not reproduce it; everything below is from CI logs plus controlled Linux experiments.
Expected Behavior
Three children that each only
time.sleep(0.2)finish in ~0.2 s wall time, as they do on Linux.Actual Behavior
Git Commit ID
b28bd58
CANN Version
N/A (pure-Python unit test, no NPU)
Driver Version
N/A
Host Platform
macOS (aarch64)
Additional Context
Ruled out, with the evidence:
_SubWorkerPooland its_worker_loopare defined locally in the test file; it never importssimpler.worker. Neither Refactor: fold the three child mailbox loops into one state machine #1494 (unifying the child mailbox loops) nor Fix: exit a forked worker child once its parent is gone #1495 (parent-death detection) can affect it.test_l4_sub_and_l3_dispatch(a lost update on a shared counter). Unrelated mechanism, unrelated file._worker_loopis a deliberate tight spin (# tight spin (same as L2 AICPU spin-wait — no yield)), so I expected 3 spinning children plus the parent to oversubscribe a narrow runner and starve the parent between its three sequentialdispatch()calls. Pinning the test to 2 and to 3 cores withtaskseton Linux gives 5/5 passes at each width. The mechanism does not hold: during the 0.2 s work window the children are insidetime.sleep()and consume no CPU, so only the parent needs a core.start = time.monotonic().Still unknown — and not resolvable without a macOS runner:
dispatch()by ~0.2 s each. This is the shape the numbers suggest (near-serial = each worker starting a full sleep-period late), but I have no way to observe it.Please do not "fix" this by relaxing the threshold or adding a retry. At 0.49-0.57 s against a 0.203 s Linux baseline, something is serialising three sleeping processes. A wider bound makes the symptom disappear while leaving whatever does that in place.
A cheap first step for whoever has a macOS machine: print
os.cpu_count()and per-worker dispatch/completion timestamps from the test, then read which of the three workers started late.