Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions funasr/train_utils/device_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ def force_gatherable(data, device):
_ACCELERATOR_DEVICE_TYPES = ("cuda", "npu", "xpu")

#: Default ``torch.distributed`` backend per accelerator, most preferred first.
#: Only Ascend NPU is listed. Every other device keeps the historical ``"nccl"``
#: default, exactly as before this change, so the backend this module selects at
#: runtime is always one that has been exercised on real hardware. XPU does use
#: XCCL (the former oneCCL name ``"ccl"``), but selecting that backend is not
#: covered by hardware here and is tracked separately, outside this change.
_ACCELERATOR_DIST_BACKENDS = {"npu": ("hccl",)}
#: Ascend NPU uses HCCL; Intel XPU uses XCCL, whose former oneCCL name ``"ccl"``
#: is still the only spelling some builds expose. Either spelling is taken from
#: the build's own ``is_<backend>_available()`` probe where it exists, and the
#: first name of the list is used when the build reports no probe at all.
#: Devices that are not listed keep the historical ``"nccl"`` default.
_ACCELERATOR_DIST_BACKENDS = {"npu": ("hccl",), "xpu": ("xccl", "ccl")}


def _accelerator_module(device_type):
Expand Down Expand Up @@ -161,11 +161,11 @@ def get_default_dist_backend():
selected backend matches the build. A non-CUDA accelerator never falls back
to NCCL. This is only the default — an explicit ``backend=...`` still wins.

XPU is deliberately absent: it is a valid ``torch.distributed`` backend
(XCCL / the former oneCCL name ``"ccl"``), but no XPU hardware is available
to this change, so XPU keeps the historical ``"nccl"`` value here rather
than advertising a runtime path nobody can exercise. Selecting XCCL is a
separate follow-up.
Intel XPU resolves to XCCL, or to the legacy oneCCL name ``"ccl"`` on a
build that only exposes ``is_ccl_available()``. It used to keep the
historical ``"nccl"`` here, which on an XPU-only build (no NCCL) made
``init_process_group`` fail before the process group existed. The explicit
``backend=...`` argument is unaffected.
"""
candidates = _ACCELERATOR_DIST_BACKENDS.get(get_accelerator_device_type())
if not candidates:
Expand Down
26 changes: 21 additions & 5 deletions tests/test_distributed_device_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,33 @@ def test_npu_backend_needs_no_capability_probe(self):
with mock.patch.object(device_funcs, "_dist_backend_available", return_value=False):
self.assertEqual(device_funcs.get_default_dist_backend(), "hccl")

def test_xpu_keeps_the_historical_nccl_default(self):
"""XPU is a valid ``torch.distributed`` backend (XCCL / oneCCL), but this
change has no XPU hardware to exercise it, so it must not advertise XCCL:
the value for an XPU run stays exactly what it was before the change."""
def test_default_dist_backend_for_xpu_is_xccl(self):
"""An XPU run gets XCCL instead of the historical NCCL default, which an
XPU-only build (no NCCL) cannot initialise at all."""
self._patch(xpu=True)
self.assertEqual(device_funcs.get_default_dist_backend(), "xccl")
with mock.patch.object(
device_funcs,
"_dist_backend_available",
side_effect=lambda backend: backend == "xccl",
):
self.assertEqual(device_funcs.get_default_dist_backend(), "nccl")
self.assertEqual(device_funcs.get_default_dist_backend(), "xccl")

def test_xpu_backend_prefers_xccl_over_the_legacy_ccl_name(self):
"""When the build exposes both probes, the current XCCL name wins."""
self._patch(xpu=True)
with mock.patch.object(device_funcs, "_dist_backend_available", return_value=True):
self.assertEqual(device_funcs.get_default_dist_backend(), "xccl")

def test_xpu_backend_falls_back_to_the_legacy_ccl_name(self):
"""A build whose probe only knows the former oneCCL name still resolves."""
self._patch(xpu=True)
with mock.patch.object(
device_funcs,
"_dist_backend_available",
side_effect=lambda backend: backend == "ccl",
):
self.assertEqual(device_funcs.get_default_dist_backend(), "ccl")

def test_clear_accelerator_cache_dispatches_to_active_backend(self):
modules = self._patch(npu=True)
Expand Down
Loading