Skip to content

Commit b1e7aed

Browse files
fix(iluvatar): fix GPUTarget cuda->corex remap for flagtree triton 3.6.x; add Worker-level inductor patch
1 parent f331ac3 commit b1e7aed

2 files changed

Lines changed: 184 additions & 4 deletions

File tree

vllm_fl/dispatch/backends/vendor/iluvatar/iluvatar.py

Lines changed: 164 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,173 @@ def _iluvatar_get_clock_rate_in_khz():
191191
"Failed to patch triton perf model for iluvatar: %s", e
192192
)
193193

194-
# Apply triton patches at module import time so that Worker subprocesses
195-
# (which do not call pre_register_and_update) also get the patches applied.
196-
patch_triton_language_for_iluvatar()
197-
patch_triton_perf_model_for_iluvatar()
194+
def patch_triton_testing_tflops_for_iluvatar() -> None:
195+
"""Patch triton.ops.matmul_perf_model.get_max_tensorcore_tflops for iluvatar.
196+
197+
On BI-V150, torch.cuda.get_device_capability() returns a value < 8,
198+
which triggers `assert dtype == torch.float16` in the original flagtree
199+
triton implementation. BF16 models fail this assert.
200+
201+
NOTE: patching triton.testing.get_max_tensorcore_tflops is insufficient
202+
because matmul_perf_model.py binds the function directly via
203+
`from ..testing import get_max_tensorcore_tflops`, so the module-level
204+
name in matmul_perf_model must be patched directly.
205+
206+
TODO: Remove once flagtree triton handles non-NVIDIA capability correctly.
207+
"""
208+
try:
209+
import triton.testing as _tt
210+
import triton.ops.matmul_perf_model as _mpm_ops
211+
import torch as _torch
212+
if getattr(_mpm_ops, "_iluvatar_tflops_patched", False):
213+
return
214+
from triton.runtime import driver as _driver
215+
216+
def _get_max_tensorcore_tflops(dtype, clock_rate, device=None):
217+
if not device:
218+
device = _torch.cuda.current_device()
219+
num_subcores = (
220+
_driver.active.utils.get_device_properties(device)
221+
["multiprocessor_count"] * 4)
222+
if dtype in [_torch.float32, _torch.int32]:
223+
ops_per_sub_core = 256
224+
elif dtype in [_torch.float16, _torch.bfloat16, _torch.int16]:
225+
ops_per_sub_core = 512
226+
else:
227+
ops_per_sub_core = 512 # safe fallback for unknown dtypes
228+
return num_subcores * clock_rate * ops_per_sub_core * 1e-9
229+
230+
# Patch both the testing module and the matmul_perf_model module
231+
# (the latter binds the function directly at import time).
232+
_tt.get_max_tensorcore_tflops = _get_max_tensorcore_tflops
233+
_mpm_ops.get_max_tensorcore_tflops = _get_max_tensorcore_tflops
234+
_mpm_ops._iluvatar_tflops_patched = True
235+
logger.info(
236+
"Patched triton.ops.matmul_perf_model.get_max_tensorcore_tflops "
237+
"for iluvatar (bfloat16 support, no capability assert)."
238+
)
239+
except Exception as e:
240+
logger.warning(
241+
"Failed to patch triton.testing.get_max_tensorcore_tflops "
242+
"for iluvatar: %s", e
243+
)
244+
198245
patch_triton_chained_or_for_iluvatar()
199246

200247

248+
def patch_sampler_compile_for_iluvatar() -> None:
249+
# Disable torch.compile on vllm sampler ops for Iluvatar.
250+
# flagtree triton only supports Iluvatar backend, not cuda target.
251+
# TODO: Remove once flagtree triton supports cuda inductor target.
252+
try:
253+
import importlib
254+
_tts = importlib.import_module('vllm.v1.sample.ops.topk_topp_sampler')
255+
if not getattr(_tts, '_iluvatar_compile_patched', False):
256+
_orig = _tts.compiled_random_sample
257+
_tts.compiled_random_sample = getattr(_orig, '__wrapped__', _orig)
258+
_tts._iluvatar_compile_patched = True
259+
logger.info('patch_sampler_compile_for_iluvatar: unwrapped topk_topp_sampler.compiled_random_sample')
260+
except Exception as e:
261+
logger.warning('patch_sampler_compile_for_iluvatar (topk_topp): %s', e)
262+
try:
263+
import importlib
264+
_lp = importlib.import_module('vllm.v1.sample.ops.logprobs')
265+
if not getattr(_lp, '_iluvatar_compile_patched', False):
266+
_orig = _lp.batched_count_greater_than
267+
_lp.batched_count_greater_than = getattr(_orig, '__wrapped__', _orig)
268+
_lp._iluvatar_compile_patched = True
269+
logger.info('patch_sampler_compile_for_iluvatar: unwrapped logprobs.batched_count_greater_than')
270+
except Exception as e:
271+
logger.warning('patch_sampler_compile_for_iluvatar (logprobs): %s', e)
272+
273+
patch_sampler_compile_for_iluvatar()
274+
275+
276+
def patch_torch_inductor_for_iluvatar() -> None:
277+
"""Patch torch._inductor GPUTarget to use the correct triton backend name.
278+
279+
torch._inductor always passes device_type='cuda' to GPUTarget, but
280+
flagtree triton only registers an 'iluvatar' (3.6.x) or 'corex' (3.2.x)
281+
backend -- never 'cuda'.
282+
283+
Fix: subclass GPUTarget to intercept 'cuda' and remap it to whatever
284+
backend name flagtree triton actually registered.
285+
286+
Compatibility: safe to call when not using flagtree -- if triton
287+
has a 'cuda' backend or no backends at all, the patch is skipped.
288+
289+
Hardware gate: Iluvatar only.
290+
TODO: Remove once torch._inductor or flagtree natively handles this.
291+
"""
292+
try:
293+
import triton.backends as _tb
294+
_registered = list(getattr(_tb, 'backends', {}).keys())
295+
# If 'cuda' is already registered (standard triton), no patch needed
296+
if 'cuda' in _registered or not _registered:
297+
logger.debug('patch_torch_inductor_for_iluvatar: triton has cuda backend or no backends, skipping')
298+
return
299+
# Probe the actual target string expected by supports_target().
300+
# In flagtree triton 3.6.x, the registered backend name is 'iluvatar'
301+
# but its supports_target() checks backend == 'corex', so we must
302+
# discover the correct probe string at runtime.
303+
_target = None
304+
try:
305+
from triton.backends.compiler import GPUTarget as _GPUTarget
306+
for _probe in ('corex', 'iluvatar') + tuple(_registered):
307+
try:
308+
_t = object.__new__(_GPUTarget)
309+
_GPUTarget.__init__(_t, _probe, 90, False)
310+
for _bname in _registered:
311+
if _tb.backends[_bname].compiler.supports_target(_t):
312+
_target = _probe
313+
break
314+
except Exception:
315+
pass
316+
if _target:
317+
break
318+
except Exception:
319+
pass
320+
if not _target:
321+
_target = 'corex' # safe default for all known flagtree versions
322+
except Exception:
323+
logger.debug('patch_torch_inductor_for_iluvatar: cannot inspect triton backends, skipping')
324+
return
325+
326+
try:
327+
import torch._inductor.runtime.triton_heuristics as _th
328+
from triton.backends.compiler import GPUTarget as _OrigGPUTarget
329+
330+
if getattr(_th, '_iluvatar_gputarget_patched', False):
331+
return
332+
333+
_remap_target = _target
334+
335+
class _IluvatarGPUTarget(_OrigGPUTarget):
336+
"""GPUTarget wrapper that remaps 'cuda' to the flagtree backend."""
337+
def __new__(cls, backend, *args, **kwargs):
338+
if backend == 'cuda':
339+
backend = _remap_target
340+
return super().__new__(cls)
341+
342+
def __init__(self, backend, *args, **kwargs):
343+
if backend == 'cuda':
344+
backend = _remap_target
345+
super().__init__(backend, *args, **kwargs)
346+
347+
_th.GPUTarget = _IluvatarGPUTarget
348+
_th._iluvatar_gputarget_patched = True
349+
logger.info(
350+
"Patched torch._inductor GPUTarget: 'cuda' -> '%s' (iluvatar)",
351+
_remap_target,
352+
)
353+
except Exception as e:
354+
logger.warning(
355+
"Failed to patch torch._inductor for iluvatar triton backend: %s", e
356+
)
357+
358+
patch_torch_inductor_for_iluvatar()
359+
360+
201361
class IluvatarBackend(Backend):
202362
"""
203363
Iluvatar backend for operator implementations.

vllm_fl/worker/worker.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,26 @@ def initialize_cache(self, num_gpu_blocks: int, num_cpu_blocks: int) -> None:
320320
self.cache_config.num_cpu_blocks = num_cpu_blocks
321321

322322
def init_device(self):
323+
# Iluvatar: patch sampler ops to disable torch.compile (flagtree triton
324+
# does not support cuda inductor target). Must run in Worker process,
325+
# after module imports, before any forward pass.
326+
# _iluvatar_worker_sampler_patch
327+
# TODO: Remove once flagtree triton supports cuda inductor target.
328+
if getattr(current_platform, "vendor_name", "") == "iluvatar":
329+
try:
330+
from vllm_fl.dispatch.backends.vendor.iluvatar.iluvatar import (
331+
patch_sampler_compile_for_iluvatar,
332+
patch_torch_inductor_for_iluvatar,
333+
)
334+
# Remap inductor GPUTarget cuda->corex so flagtree triton
335+
# backend selection works. Must run in every Worker process.
336+
patch_torch_inductor_for_iluvatar()
337+
patch_sampler_compile_for_iluvatar()
338+
except Exception as _e:
339+
import logging as _lg
340+
_lg.getLogger(__name__).warning(
341+
"iluvatar worker patch failed: %s", _e
342+
)
323343
# This env var set by Ray causes exceptions with graph building.
324344
if (
325345
self.parallel_config.data_parallel_size > 1

0 commit comments

Comments
 (0)