[XPU] Honor device_ids for worker device placement (#56015)
Signed-off-by: Chaojun Zhang <chaojun.zhang@intel.com> Co-authored-by: Kunshang Ji <kunshang.ji@intel.com>
Chaojun Zhang committed
Sep 16, 2026 at 11:53 UTC
622934e61fb27aceea346b95d82edaa350d985d1
3 files changed
+44
-19
.buildkite/intel_jobs/test-intel.yaml
+1
-1
@@ -97,7 +97,7 @@ steps:
97
commands:
98
- >-
99
bash .buildkite/scripts/hardware_ci/run-intel-test.sh
100
- 'cd tests &&
100
+ 'cd tests && pip install dpctl &&
101
pytest -v -s v1/core --ignore=v1/core/test_reset_prefix_cache_e2e.py --ignore=v1/core/test_scheduler_e2e.py &&
102
pytest -v -s v1/engine --ignore=v1/engine/test_output_processor.py &&
103
pytest -v -s v1/sample --ignore=v1/sample/test_logprobs.py --ignore=v1/sample/test_logprobs_e2e.py -k "not test_topk_only and not test_topp_only and not test_topk_and_topp" &&
vllm/v1/engine/core.py
+4
-7
@@ -2452,13 +2452,10 @@ class EngineCoreActorMixin:
2452
def _set_visible_devices(self, vllm_config: VllmConfig, local_dp_rank: int):
2453
from vllm.platforms import current_platform
2454
2455
- if current_platform.is_xpu():
2456
- pass
2457
- else:
2458
- device_control_env_var = current_platform.device_control_env_var
2459
- self._set_assigned_physical_gpu_ids(
2460
- vllm_config, local_dp_rank, device_control_env_var
2461
- )
2455
+ device_control_env_var = current_platform.device_control_env_var
2456
+ self._set_assigned_physical_gpu_ids(
2457
+ vllm_config, local_dp_rank, device_control_env_var
2458
+ )
2459
2460
def _set_assigned_physical_gpu_ids(
2461
self,
vllm/v1/worker/xpu_worker.py
+39
-11
@@ -115,27 +115,55 @@ class XPUWorker(Worker):
115
116
self.local_rank += dp_local_rank * replica_world_size
117
118
- assert self.local_rank < visible_device_count, (
119
- f"DP adjusted local rank {self.local_rank} is out of bounds. "
120
- )
121
- assert parallel_config.local_world_size <= visible_device_count, (
122
- f"local_world_size ({parallel_config.local_world_size}) must "
123
- f"be less than or equal to the number of visible devices "
124
- f"({visible_device_count})."
125
- )
126
-
118
device = self.device_config.device
119
if (
120
isinstance(device, torch.device)
121
and device.type == "xpu"
122
and current_platform.is_xpu()
123
):
133
- self.device = torch.device(f"xpu:{self.local_rank}")
124
+ assigned_physical_gpu_ids = self.parallel_config.assigned_physical_gpu_ids
125
+ if assigned_physical_gpu_ids is not None:
126
+ from vllm.platforms.interface import set_assigned_physical_gpu_ids
127
+
128
+ set_assigned_physical_gpu_ids(assigned_physical_gpu_ids)
129
+ assert self.local_rank < len(assigned_physical_gpu_ids), (
130
+ f"local_rank {self.local_rank} is out of bounds for "
131
+ f"assigned_physical_gpu_ids {assigned_physical_gpu_ids}"
132
+ )
133
+ # NOTE: local_world_size is derived from parallel_config.nnodes,
134
+ # which is only set for the "mp" multi-node backend. With the
135
+ # "ray"/"external_launcher" backends nnodes stays 1, so
136
+ # local_world_size collapses to the full world_size and this
137
+ # check wrongly fires on cross-node deployments.
138
+ # assigned_physical_gpu_ids is already per-node and the
139
+ # local_rank bound above fully validates the mapping for
140
+ # these backends, so skip the check for them.
141
+ if parallel_config.distributed_executor_backend not in (
142
+ "ray",
143
+ "external_launcher",
144
+ ):
145
+ assert parallel_config.local_world_size <= len(
146
+ assigned_physical_gpu_ids
147
+ ), (
148
+ f"local_world_size ({parallel_config.local_world_size})"
149
+ " exceeds assigned_physical_gpu_ids count "
150
+ f"({len(assigned_physical_gpu_ids)})"
151
+ )
152
+ else:
153
+ assert self.local_rank < torch.accelerator.device_count(), (
154
+ f"DP adjusted local rank {self.local_rank} is out of "
155
+ f"bounds for {torch.accelerator.device_count()} devices."
156
+ )
157
+
158
+ visible_device_index = (
159
+ current_platform.logical_device_id_to_visible_device_id(self.local_rank)
160
+ )
161
+ self.device = torch.device(f"xpu:{visible_device_index}")
162
torch.accelerator.set_device_index(self.device)
163
current_platform.check_if_supports_dtype(self.model_config.dtype)
164
torch.accelerator.empty_cache()
165
self.init_gpu_memory = torch.xpu.get_device_properties(
138
- self.local_rank
166
+ visible_device_index
167
).total_memory
168
else:
169
raise RuntimeError(f"Unsupported device type: {self.device_config.device}")