@@ -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+
198245patch_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+
201361class IluvatarBackend (Backend ):
202362 """
203363 Iluvatar backend for operator implementations.
0 commit comments