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
Cap PyTorch thread pools to avoid nproc^2 GlobalCPUThread explosion
Summary:
Two layers needed to prevent libtorch's thread-pool explosion under
concurrent forward() invocations:
1. dlrm.cpp: at::set_num_interop_threads(1) called in the DLRM
constructor BEFORE loadModel + warmup. Caps libtorch's native
parallel backend pool.
2. run.sh: OMP_NUM_THREADS=1 added to the leaf launch env. Caps
libtorch's OpenMP parallel backend pool — our internal libtorch
build uses OpenMP for tensor ops, which at::set_num_interop_threads
does NOT cover.
Also: per-thread JIT Module clone in dlrm.cpp. The shared
pimpl_->model.forward() was racing under concurrent invocation from
multiple GlobalCPUThread workers, producing SIGSEGV in
je_large_dalloc → torch::autograd::autogradNotImplementedFallbackImpl
→ at::arange → JIT interpreter. Each ThreadState now owns a deep
clone (via Module::clone()), so concurrent forward() touches disjoint
interpreter state.
Without these three fixes, on BGM (176 logical cores) the leaf
process accumulated 30,976 = nproc^2 threads named "GlobalCPUThread"
(folly NamedThreadFactory pool name, comm-truncated to 15 chars), all
stuck in __futex_wait, eventually triggering kernel-scheduler thrash
and the cascading deadlock that pinned the driver's inflight count
at the connection cap (sent_qps=0 forever).
t15 measured per-instance thread count drop: 30,976 → 88. t17
confirmed zero SIGSEGV across 16 iters at qps=80 (vs 6/16 crashes
without the Module clone). Multi-iter qps=80 stability went from 1/4
balanced to 2/4 (rtptest3440 s=0.025) and 4/4 (rtptest3424 s=0.10).
Reviewed By: YifanYuan3
Differential Revision: D105659812
0 commit comments