diff --git a/tests/distributed/test_custom_all_reduce_capture.py b/tests/distributed/test_custom_all_reduce_capture.py
new file mode 100644
index 000000000..79ab4382c
--- /dev/null
+++ b/tests/distributed/test_custom_all_reduce_capture.py
@@ -0,0 +1,43 @@
+from unittest.mock import Mock
+
+import torch
+
+from vllm.distributed.device_communicators import custom_all_reduce as custom_ar
+
+
+def _capturing_runtime(*, pcie_runtime):
+    runtime = object.__new__(custom_ar.CustomAllreduce)
+    runtime.disabled = False
+    runtime._IS_CAPTURING = True
+    runtime._pcie_runtime = pcie_runtime
+    runtime._ptr = 0
+    runtime.should_custom_ar = Mock(return_value=True)
+    runtime.all_reduce = Mock(return_value=object())
+    return runtime
+
+
+def test_b12x_pcie_warmup_runs_real_allreduce(monkeypatch):
+    runtime = _capturing_runtime(pcie_runtime=Mock())
+    inp = torch.ones(8)
+
+    monkeypatch.setattr(torch.cuda, "is_current_stream_capturing", lambda: False)
+    monkeypatch.setattr(custom_ar, "_is_piecewise_cudagraph_runtime", lambda: False)
+
+    result = runtime.custom_all_reduce(inp)
+
+    assert result is runtime.all_reduce.return_value
+    runtime.all_reduce.assert_called_once_with(inp, registered=False)
+
+
+def test_legacy_warmup_keeps_placeholder_behavior(monkeypatch):
+    runtime = _capturing_runtime(pcie_runtime=None)
+    inp = torch.ones(8)
+
+    monkeypatch.setattr(torch.cuda, "is_current_stream_capturing", lambda: False)
+    monkeypatch.setattr(custom_ar, "_is_piecewise_cudagraph_runtime", lambda: False)
+
+    result = runtime.custom_all_reduce(inp)
+
+    assert result.shape == inp.shape
+    assert result.dtype == inp.dtype
+    runtime.all_reduce.assert_not_called()
diff --git a/vllm/distributed/device_communicators/custom_all_reduce.py b/vllm/distributed/device_communicators/custom_all_reduce.py
index 5fb3fc888..f8a56346d 100644
--- a/vllm/distributed/device_communicators/custom_all_reduce.py
+++ b/vllm/distributed/device_communicators/custom_all_reduce.py
@@ -708,7 +708,7 @@ class CustomAllreduce:
                 # Piecewise CUDA graph execution can run split ops eagerly while
                 # graph capture bookkeeping is active. Those ops need a real
                 # all-reduce; returning a placeholder is only valid for warmup.
-                if _is_piecewise_cudagraph_runtime():
+                if self._pcie_runtime is not None or _is_piecewise_cudagraph_runtime():
                     return self.all_reduce(input, registered=False)
                 # If warm up, mimic the allocation pattern since custom
                 # allreduce is out-of-place.
