+
    œ°³j°ª  ã                  óì  a € 0 t $ R t^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H
t
 ^ RIHt ^ RIt^RIHt ^RIHt ^RIHtHtHt ^RIHtHt ]P2                  ! ]4      t]! R	R
7       ! R R4      4       t]P:                  R R l4       t]P:                  R R l4       t]P@                  PB                  R R l4       t"]P@                  PB                  R:R R ll4       t#Rs$R]%R&   ]P@                  PL                  R R l4       t'R R lt(R R lt)R R lt*R;R R  llt+R! R" lt,R# R$ lt-R% R& lt.R' R( lt/R) R* lt0R+ R, lt1]! R-R.R/7      R<R0 R1 ll4       t2R2 R3 lt3R4 R5 lt4R6 R7 lt5R;R8 R9 llt6R# )=uS  DeepGEMM integration: fused grouped GEMM kernels from `kernels-community/deep-gemm`.

Provides:
- `deepgemm_bf16_experts_forward`: BF16 M-grouped experts forward.
- `deepgemm_fp8_fp4_linear`: end-to-end FP8/FP4 linear (output dtype follows the input).
- `deepgemm_fp8_fp4_experts_forward`: FP8 (or FP4 on SM100+) M-grouped experts forward.
- `deepgemm_fp8_fp4_megamoe_experts_forward`: FP8xFP4 Mega MoE forward (SM100+).

Requirements: CUDA, Hopper (SM90+), CUDA runtime â‰¥ 12.3, kernels-community/deep-gemm
â‰¥ 2.5 (Mega MoE symbols required). Mega MoE additionally needs SM100+ at call time.
)ÚannotationsN)ÚCallable)Ú	dataclass)Úlogging)Údeprecate_kwarg)Úis_kernels_availableÚmaybe_import_errorÚresolve_internal_import)Ú_MISSING_KERNELS_MESSAGEÚlazy_load_kernelT)Úfrozenc                  óŠ   € ] tR t^6t$ RtR]R&   R]R&   R]R&   R]R&   R]R&   R]R&   R]R	&   R]R
&   R]R&   R]R&   R]R&   RtR# )ÚDeepGEMMz>Curated entry points exposed by `kernels-community/deep-gemm`.r   Úfp8_fp4_matmulÚgrouped_fp8_fp4_matmul_ntÚgrouped_fp8_fp4_matmul_nnÚgrouped_bf16_matmul_ntÚgrouped_bf16_matmul_nnÚper_token_cast_to_fp8Ú!transform_sf_into_required_layoutÚtransform_weights_for_mega_moeÚget_symm_buffer_for_mega_moeÚfp8_fp4_mega_moeÚintÚm_alignment© N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__Ú__static_attributes__r   ó    Úc/home/luca/screen-checking/.venv/lib/python3.14/site-packages/transformers/integrations/deepgemm.pyr   r   6   sI   ‡ áHàÓØ'Ó'Ø'Ó'Ø$Ó$Ø$Ó$Ø#Ó#Ø'/Ó/Ø$,Ó,Ø"*Ó*ØÓð ×r#   r   c               ó   € V ^8„  d   QhRR/# )é   Úreturnz
str | Noner   )Úformats   "r$   Ú__annotate__r)   N   s   € ÷ ñ ˜
ñ r#   c                 ó¨  € \         P                  P                  R4      ;'       g     \         P                  P                  R4      p V '       d   V # \        P                  ! R4      pV'       d=   \         P
                  P                  \         P
                  P                  V4      4      # \         P
                  P                  R4      '       d   R# R# )ur  Resolve the CUDA toolkit root the way DeepGEMM's JIT does:
``CUDA_HOME`` â†’ ``CUDA_PATH`` â†’ dir of ``which nvcc`` â†’ ``/usr/local/cuda`` (``None`` if none found).

Mirrors DeepGEMM's own ``_find_cuda_home`` so we agree on the path it will actually use, rather than
reusing ``torch.utils.cpp_extension.CUDA_HOME`` whose resolution inits a CUDA context (fork-unsafe).
Ú	CUDA_HOMEÚ	CUDA_PATHÚnvccz/usr/local/cudaN)ÚosÚenvironÚgetÚshutilÚwhichÚpathÚdirnameÚisdir)Ú	cuda_homer-   s     r$   Ú_get_cuda_homer7   M   s   € ô —
‘
—‘˜{Ó+×JÐJ¬r¯z©z¯~©~¸kÓ/J€IßØÐÜ�<Š<˜Ó€DßÜ�w‰w�‰œrŸw™wŸ™¨tÓ4Ó5Ð5Ü	‡w�w‡}�}Ð&×'Ò'Ù Ùr#   c               ó   € V ^8„  d   QhRR/# )r&   r'   útuple[int, int] | Noner   )r(   s   "r$   r)   r)   a   s   € ÷ +ñ +Ð1ñ +r#   c                 óþ  € \        4       p V f   R# \        P                  P                  V R4      p\        P                  P	                  V4      '       d–    \        V4      ;_uu_ 4       p\        P                  ! V4      pRRR4       XP                  RVP                  R/ 4      4      P                  RR4      pVP                  R4      R,          w  rV\        V4      \        V4      3# \        P                  P                  V R	4      p\        P                  P	                  V4      '       d€    \        V4      ;_uu_ 4       p\        P                  ! R
VP!                  4       4      pRRR4       X'       d5   \        VP#                  ^4      4      \        VP#                  ^4      4      3#  \        P                  P                  V RR4      p	\        P                  P	                  V	4      '       d�    \        V	4      ;_uu_ 4       p\        P                  ! RVP!                  4       4      pRRR4       X'       d4   \        VP#                  ^4      4      p
V
R,          V
R,          ^
,          3#  R# R#   + '       g   i     ELÿ; i  \        \        \        3 d     EL¹i ; i  + '       g   i     ELG; i  \        \        3 d     EL!i ; i  + '       g   i     L­; i  \        \        3 d     R# i ; i)a{  Version of the CUDA toolkit nvcc will use, as ``(major, minor)``, read off disk without a
subprocess from (in order) ``{CUDA_HOME}/version.json``, ``version.txt``, or the ``CUDA_VERSION``
define in ``include/cuda.h``. ``None`` if unreadable. This is the compiler that builds the kernels,
unlike ``torch.version.cuda`` (torch's bundled runtime, which never drives a JIT compile).
Nzversion.jsonÚ	cuda_nvccÚcudaÚversionÚ Ú.:Nr&   Nzversion.txtzCUDA Version (\d+)\.(\d+)Úincludezcuda.hz#define CUDA_VERSION (\d+)iè  )r7   r.   r3   ÚjoinÚisfileÚopenÚjsonÚloadr0   Úsplitr   ÚOSErrorÚ
ValueErrorÚAttributeErrorÚreÚsearchÚreadÚgroup)r6   Úversion_jsonÚfÚ
componentsr=   ÚmajorÚminorÚversion_txtÚmatchÚcuda_hÚcuda_versions              r$   Ú_get_nvcc_versionrW   `   s3  € ô Ó €IØÒÙä—7‘7—<‘< 	¨>Ó:€LÜ	‡w�w‡~�~�l×#Ò#ð	Ü�l×#Ô# qÜ!ŸYšY q›\�
÷ $à —n‘n [°*·.±.ÀÈÓ2LÓM×QÑQÐR[Ð]_Ó`ˆGØ"Ÿ=™=¨Ó-¨bÕ1‰LˆEÜ�u“:œs 5›zÐ)Ð)ô —'‘'—,‘,˜y¨-Ó8€KÜ	‡w�w‡~�~�k×"Ò"ð	Ü�k×"Ô" aÜŸ	š	Ð">ÀÇÁÃÓI�÷ #çÜ˜5Ÿ;™; q›>Ó*¬C°·±¸A³Ó,?Ð?Ð?ð ô �W‰W�\‰\˜) Y°Ó9€FÜ	‡w�w‡~�~�f×Òð	Ü�f—” ÜŸ	š	Ð"?ÀÇÁÃÓJ�÷ çÜ" 5§;¡;¨q£>Ó2�Ø# tÕ+¨l¸TÕ.AÀbÕ-HÐHÐHð ó ÷= $×#Ð#ûô
 œ¤^Ð4ô 	Úð	ú÷ #×"Ð"ûô œÐ$ô 	Úð	ú÷ —ûô
 œÐ$ô 	Øáð	ús‹   ÁJ Á*I7ÂA)J Ä1J< Å&J(Å*J< Å:3J< Ç6K' È	&KÈ/K' È?2K' É7J	Ê	J ÊJ%Ê$J%Ê(J9	Ê3	J< Ê<KËKËK$	ËK' Ë'K<Ë;K<c               ó   € V ^8„  d   QhRR/# )r&   r'   Úboolr   )r(   s   "r$   r)   r)   �   s   € ÷ 7ñ 7�$ñ 7r#   c                 óR   € \         P                  P                  4       ^ ,          ^
8¬  # )uš  Whether the current CUDA device is Blackwell (SM100+). `@assume_constant_result` makes dynamo
evaluate it once at trace time and inline the bool â€” keeping the untraceable
`torch.cuda.get_device_capability()` pybind out of the graph â€” so the branches on it (SF layout, cast
kwargs, psum layout, and the arch guards) stay compile-safe. Re-queries each eager call, so a faked
capability in tests is honoured.
)Útorchr<   Úget_device_capabilityr   r#   r$   Úis_sm100r]   �   s!   € ô �:‰:×+Ñ+Ó-¨aÕ0°BÑ6Ð6r#   c               ó    € V ^8„  d   QhRRRR/# )r&   Úraise_errorrY   r'   r   )r(   s   "r$   r)   r)   ›   s   € ÷ Bñ B dð B°tñ Br#   c                ó‚  € \        4       '       g   \        R\         2V R7      # \        P                  P                  4       '       g   \        RV R7      # \        P                  P                  4       w  rVR9  d   \        RV V R2V R7      # V^
8X  d   RMRp\        4       pVf#   \        RV^ ,           RV^,           R2V R7      # \        P                  P                  \        P                  P                  VRR	4      4      '       g&   \        R
V RV^ ,           RV^,           R2V R7      # \        4       pVf&   \        RV RV^ ,           RV^,           R2V R7      # WS8  dS   \        RV V RV^ ,           RV^,           RV^ ,           RV^,           RV RV^ ,           RV^,           R2V R7      # R# )uÀ  Whether the DeepGEMM kernel can be loaded in this environment: `kernels` installed, a CUDA GPU on a
supported arch (Hopper SM90 or Blackwell SM100), and a CUDA toolkit/nvcc new enough to JIT-compile it.
A one-glance gate for callers â€” including external stacks â€” deciding whether to dispatch to DeepGEMM.
With `raise_error=True` (used by the loader) it re-raises the specific `ImportError` explaining what's
missing instead of returning `False`.

`@assume_constant_result` makes dynamo evaluate this once at trace time and inline the bool (its probe
is untraceable â€” an `lru_cache`'d import check + the `get_device_capability` pybind + nvcc lookup), so
the check can sit in a compiled dispatch gate (e.g. `fp8_linear`) without breaking the graph.

FP4 / Mega MoE additionally need Blackwell (SM100); the relevant forwards enforce that via
`_assert_sm100_requirements` / `is_sm100()`, since this env check can't see which dtype path the
caller will take.
zDeepGEMM kernel unavailable: ©r_   z9DeepGEMM kernel requires CUDA, but CUDA is not available.zJDeepGEMM requires Hopper (SM90) or Blackwell (SM100); current device is SMr?   u(   DeepGEMM's JIT needs a CUDA toolkit â‰¥ z8, but none was found. Set `CUDA_HOME` to a CUDA toolkit.Úbinr-   z:DeepGEMM's JIT compiles with nvcc, but none was found in `u,   /bin`. Point `CUDA_HOME` at a full CUDA â‰¥ z& toolkit (not a runtime-only install).zDeepGEMM found nvcc in `u–   /bin` but could not read its CUDA version (no parseable `version.json`, `version.txt`, or `include/cuda.h`). Point `CUDA_HOME` at a complete CUDA â‰¥ z	 toolkit.zDeepGEMM on SMu    needs a CUDA â‰¥ z toolkit, but nvcc z in `u.   ` is too old. Point `CUDA_HOME` at a CUDA â‰¥ T)é	   é
   )é   rc   )re   é   )r   r   r
   r[   r<   Úis_availabler\   r7   r.   r3   rB   rA   rW   )r_   rQ   rR   Úmin_cudar6   Únvcc_versions   &     r$   Úis_deepgemm_loadablerj   š   sý  € ô   ×!Ò!Ü!Ð$AÔBZÐA[Ð"\ÐjuÔvÐvÜ�:‰:×"Ñ"×$Ò$Ü!Ð"]ÐkvÔwÐwä—:‘:×3Ñ3Ó5�L€Eð �GÔÜ!ØXÐY^ÐX_Ð`eÐ_fÐfgÐhØ#ô
ð 	
ð   2œ+‰w¨7€HÜÓ €IØÒÜ!Ø6°xÀµ{°mÀ1ÀXÈaÅ[ÀMð R1ð 1à#ô
ð 	
ô �7‰7�>‰>œ"Ÿ'™'Ÿ,™, y°%¸Ó@×AÒAÜ!ØHÈÈð T.Ø.6°q­k¨]¸!¸HÀQ½K¸=ÐHnðpà#ô
ð 	
ô %Ó&€LØÒÜ!Ø& y kð 2!à!)¨!¥ ¨Q¨x¸­{¨m¸9ðFð $ô	
ð 	
ð ÔÜ!Ø˜U˜G E 7Ð*<¸XÀa½[¸MÈÈ8ÐTUÍ;È-ÐWjØ˜A�Ð˜q ¨a¥Ð 1°°y°kð BØ  ��} A h¨q¥k ]°)ð=ð $ô	
ð 	
ñ r#   zDeepGEMM | NoneÚ	_DEEPGEMMc               ó   € V ^8„  d   QhRR/# )r&   r'   ÚNoner   )r(   s   "r$   r)   r)   ç   s   € ÷ Dñ D˜tñ Dr#   c                 ó–  € \         e   R# \        RR7       \        R4      p V f   \        R4      h\	        V RR4      p\	        V RR4      p\	        V RR4      p\	        V R	R4      p\	        V R
R4      p\        V RR7      p\	        V RR4      p\	        V RR4      p\	        V RR4      p	\	        V RR4      p
\	        V RR4      pRV3RV3RV3R	V3R
V3RV3RV3RV3RV	3RV
3RV33 UUu. uF  w  rÍVe   K  VNK  	  pppV'       d%   \        RRP                  V4       R\         24      h\        VVVVVVVVV	VV
! 4       R7      s R# u uppi )uÝ  Load DeepGEMM once into the `_DEEPGEMM` module global, raising `ImportError` if the env or any
required symbol is missing. Under NO circumstances may this function return a value: it rides
through `@allow_in_graph` as an opaque fx node, whose return must be proxyable â€” returning the
bundle (e.g. from the warm-cache short-circuit) breaks torch.compile with
`Unsupported: torch.* op returned non-Tensor`. Callers read `_DEEPGEMM` back from the global.

`@allow_in_graph` makes `torch.compile` treat the untraceable cold path (hub download + dynamic
import via `lazy_load_kernel`) as a single opaque node instead of tracing into it; it returns `None`
(proxyable) and populates the global, which `load_deepgemm_kernel` then returns.
NTra   z	deep-gemmuc   Failed to load `kernels-community/deep-gemm` â€” check that a build matches the current torch/CUDA.Úfp8_fp4_gemm_ntÚ$m_grouped_fp8_fp4_gemm_nt_contiguousÚ$m_grouped_fp8_fp4_gemm_nn_contiguousÚ!m_grouped_bf16_gemm_nt_contiguousÚ!m_grouped_bf16_gemm_nn_contiguouszutils.per_token_cast_to_fp8)Úchained_pathr   r   r   Ú&get_mk_alignment_for_contiguous_layoutr   z-DeepGEMM kernel is missing required symbols: z, z. )r   r   r   r   r   r   r   r   r   r   r   )	rk   rj   r   ÚImportErrorÚgetattrr	   rA   r
   r   )Úkernelr   r   r   r   r   r   r   r   r   Úget_mk_alignmentr   ÚnameÚattrÚmissings                  r$   Ú_load_deepgemm_kernelr}   æ   sá  € ô ÒÙä TÕ*Ü˜kÓ*€FØ‚~ÜØqó
ð 	
ô ˜VÐ%6¸Ó=€NÜ '¨Ð0VÐX\Ó ]ÐÜ '¨Ð0VÐX\Ó ]ÐÜ$ VÐ-PÐRVÓWÐÜ$ VÐ-PÐRVÓWÐÜ3°FÐIfÔgÐÜ(/°Ð8[Ð]aÓ(bÐ%Ü%,¨VÐ5UÐW[Ó%\Ð"Ü#*¨6Ð3QÐSWÓ#XÐ Ü˜vÐ'OÐQUÓVÐÜ˜vÐ'9¸4Ó@Ðð
  Ð/Ø3Ð5NÐOØ3Ð5NÐOØ0Ð2HÐIØ0Ð2HÐIØ*Ð,AÐBØ0Ð2SÐTØ-Ð/MÐNØ+Ð-IÐJØ5Ð7GÐHØÐ!1Ð2ñ
ôñ
‰JˆDð ÷ 	ˆñ
ð ñ ÷" ÜØ;¸D¿I¹IÀgÓ<NÐ;OÈrÔRjÐQkÐló
ð 	
ô Ø%Ø";Ø";Ø5Ø5Ø3Ø*KØ'EØ%AØ)Ù$Ó&ô‚Iùó-s   Ã&EÃ3Ec               ó   € V ^8„  d   QhRR/# )r&   r'   r   r   )r(   s   "r$   r)   r)   .  s   € ÷ ñ ˜hñ r#   c                 ó"   € \        4        \        # ©N)r}   rk   r   r#   r$   Úload_deepgemm_kernelr�   .  s   € ÜÔÜÐr#   c               ó$   € V ^8„  d   QhRRRRRR/# )r&   Úweightútorch.TensorÚscaler'   rm   r   )r(   s   "r$   r)   r)   6  s!   € ÷ !
ñ !
 |ð !
¸Lð !
ÈTñ !
r#   c                óÒ   € \        4       '       g-   V P                  \        P                  8X  d   \	        R4      hR# VP                  \        P
                  8X  d   \	        R4      hR# )u=  Before-load guard for DeepGEMM's FP8/FP4 arch constraints on the given weight/scale dtypes:

  - FP4 (``int8``-packed) weights have no Hopper (SM90) kernel â€” they need Blackwell (SM100+).
  - Blackwell has no float32 scale-factor path: ``_coerce_sf_for_kernel`` would silently round a
    ``float32`` scale to UE8M0 and corrupt the output. UE8M0 scales load as ``float8_e8m0fnu`` (the
    loader normalizes even float32-container checkpoints like dsv4-flash-base), so a ``float32`` scale
    on SM100 means a genuine non-UE8M0 checkpoint.

Uses `is_sm100()` (compile-safe via `assume_constant_result`), so the whole guard folds to a constant under
``torch.compile``: the valid case compiles away to nothing, while an unsupported combo fails loud
rather than letting the hot path silently corrupt (unlike an ``is_compiling`` skip, which would miss a
model compiled from cold with no eager warmup). Both raise ``NotImplementedError``, which
``fp8_linear`` treats as "DeepGEMM declined" and falls back to Triton (SM90 consuming float32 SFs
directly is fine, so those cases are no-ops).
z DeepGEMM's FP4 (int8-packed) path requires a Blackwell (SM100+) GPU; FP4 weights have no Hopper (SM90) kernel. Use an FP8 checkpoint, or run on a Blackwell GPU.Nu§  DeepGEMM has no float32 scale-factor path on Blackwell (SM100): these scales are plain float32 (quantization_config.scale_fmt='float'), and rounding them to UE8M0 would silently corrupt the output. Use a checkpoint quantized with scale_fmt='ue8m0', or a path that consumes float32 block scales directly â€” the FP8 linear falls back to Triton automatically; for experts use `model.set_experts_implementation('grouped_mm')`.)r]   Údtyper[   Úint8ÚNotImplementedErrorÚfloat32)rƒ   r…   s   &&r$   Ú_assert_sm100_requirementsr‹   6  s]   € ô  �:Š:à�<‰<œ5Ÿ:™:Ô%Ü%ðZóð ñ 	ð ‡{�{”e—m‘mÔ#Ü!ð@ó
ð 	
ñ $r#   c               ó    € V ^8„  d   QhRRRR/# )r&   Úsfr„   r'   r   )r(   s   "r$   r)   r)   Z  s   € ÷ 
Yñ 
Y�|ð 
Y¨ñ 
Yr#   c                óª   € V P                  \        P                  4      pVR,           P                  R4      P                  \        P                  4      # )u­  Round each fp32 SF up to the nearest power of 2 (zero mantissa).

Mirrors `deep_gemm.utils.math.ceil_to_ue8m0`. On SM100 the kernel's
`pack_fp32_into_ue8m0` cleanly extracts the biased exponent only when the
mantissa is already zero â€” its inner shifts (`>> 15`, `>> 7`, `<< 1`)
otherwise leak mantissa bits into adjacent UE8M0 byte slots and silently
corrupt the SF. SM90 consumes raw fp32 SFs without going through this path.
iÿÿ i  €ÿ)Úviewr[   Úint32Úbitwise_and_Úfloat)r�   Úint_views   & r$   Ú_ceil_to_ue8m0r”   Z  s<   € ð �w‰w”u—{‘{Ó#€HØ˜Õ&×4Ñ4Ð5EÓF×KÑKÌEÏKÉKÓXÐXr#   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r&   r�   r„   r]   rY   Úexpected_mnz
int | Noner'   r   )r(   s   "r$   r)   r)   g  s)   € ÷ 9ñ 9˜lð 9°dð 9Èð 9Ð_kñ 9r#   c                ó   € V P                   \        P                  8X  dŒ   VeA   V P                  R4      V8  d+   W P                  R4      ,          pV P	                  VRR7      p V'       d/   V P                  4       P                  \        P                  4      p MCV P                  4       p M2V P                   \        P                  8X  d   V'       d   \        V 4      p V P                  4       R9  d   \        RV P                  4        R24      hV'       g   V P                  4       # V P                  R4      pV P                  R4      p^V P                  4       ,          pV) V,          ) V,          pV P                  4       ^8X  d   ^V3M
WW,          ^V3p\        V P                  4       4      V8X  d   V # \        P                   ! V P"                  W€P                   V P$                  R7      p	V	P'                  V 4       V	# )uF  Lay out `sf` as DeepGEMM's dispatch expects, per arch.

On SM100 the int-SF path only *checks* the SF (`tma_stride_check`) and never
transforms it, so we hand it a TMA-aligned MN-major layout (`stride(-2) == 1`,
`stride(-1) == align(mn, 16/esize)`). On SM90 DeepGEMM transforms SFA itself
(`get_mn_major_tma_aligned_tensor`) and only *checks* SFB against
`sm90_sfb_check`, which rejects TMA padding (`stride(-1)` must equal `size(-2)`,
not `align(mn, â€¦)`); a padded weight SF trips `layout.hpp` whenever `mn` isn't a
multiple of `16/esize` (e.g. N=576 â†’ mn=5). So on SM90 we return the raw
row-major SF and let DeepGEMM lay it out.

Inputs come in three flavors:
  - `float8_e8m0fnu` on SM100: raw UE8M0 bytes â€” pack 4 K-bytes â†’ int32
    (last dim /4) for the kernel's `(INT, 1, gran_k)` path.
  - `float8_e8m0fnu` on SM90: SM90 dispatch only accepts FP32 SFs, so cast
    UE8M0 â†’ FP32 (exact upcast â€” UE8M0 is the biased-exponent half of a
    pow-of-2 FP32, so `.float()` rebuilds the original FP32 scale exactly).
  - `float32`: per-token / per-block SFs from `per_token_cast_to_fp8` or
    on-disk weights â€” round to UE8M0 on SM100 (see `_ceil_to_ue8m0`).
  - `int32`: already-packed UE8M0 â€” pass through.

When `expected_mn` is set and the SF's M-dim is smaller (block-quantized
UE8M0, e.g. DSv4-Flash compressor weights with `(N/128, K/128)` SFs), we
repeat the SF on the M-axis to per-row before packing â€” the `(INT, 1, gran_k)`
DeepGEMM kernel branch is the only UE8M0 path on SM100; for `gran_mn > 1`
the kernel only handles FP32 SFs and would otherwise reject our INT SF here.
©Údimz"DeepGEMM SF must be 2D or 3D, got ÚD©r‡   Údeviceéþÿÿÿ)r&   rf   éÿÿÿÿ)r‡   r[   Úfloat8_e8m0fnuÚsizeÚrepeat_interleaveÚ
contiguousr�   r�   r’   rŠ   r”   r™   rH   Úelement_sizeÚtupleÚstrideÚempty_stridedÚshaperœ   Úcopy_)
r�   r]   r–   Úgran_mnÚmnÚkfÚalign_toÚ
aligned_mnÚtarget_stridesÚouts
   &&&       r$   Ú_coerce_sf_for_kernelr°   g  su  € ð8 
‡x�x”5×'Ñ'Ô'ØÒ" r§w¡w¨r£{°[Ô'@Ø!§W¡W¨R£[Õ0ˆGØ×%Ñ% g°2Ð%Ó6ˆBßØ—‘“×%Ñ%¤e§k¡kÓ2‰Bà—‘“‰BØ	�‰”U—]‘]Ô	"§xÜ˜BÓˆà	‡v�vƒx�vÔÜÐ=¸b¿f¹f»h¸ZÀqÐIÓJÐJ÷ Ø�}‰}‹Ðà	�‰�‹€BØ	�‰�‹€BØ�R—_‘_Ó&Õ&€HØ�3˜(•?Ð# hÕ.€JØ(*¯©«°A¬�a˜‘_¸B½OÈQÐPZÐ;[€NäˆR�Y‰Y‹[Ó˜^Ô+Øˆ	Ü
×
Ò
˜bŸh™h¨¿h¹hÈrÏyÉyÔ
Y€CØ‡I�Iˆb„MØ€Jr#   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r&   rƒ   r„   Úweight_scale_invÚ
block_sizeztuple | Noner]   rY   r'   Údictr   )r(   s   "r$   r)   r)   £  s4   € ÷ /ñ /Øð/Ø,8ð/ØFRð/Ø^bð/à	ñ/r#   c                ó  € V P                   \        P                  8X  d	   RRR^ RR/# Vf   \        R4      h\	        V4      pVR	9  d   \        RV R24      hVP                   \        P
                  8X  d   V'       d	   RRR^€RR/# RRR^€/# )
u#  Pick the `per_token_cast_to_fp8` kwargs from weight dtype + SF dtype + arch.

Cases mirror the kernel's recipes:
  - FP4 weights (`int8`): gran_k=32 packed-UE8M0 SF. SM100+ only.
  - FP8 weights + UE8M0 SF on SM100: gran_k=128 packed-UE8M0 SF (DSv4).
  - FP8 weights + UE8M0 SF on SM90: gran_k=128 FP32 SF â€” the SM90 dispatch in
    `layout.hpp` only matches FP32 SFs, so we keep act SFs as FP32 (and float
    the weight SF in `_coerce_sf_for_kernel`; UE8M0 â†’ FP32 is an exact upcast).
  - FP8 weights + float SF: gran_k=128 float SF (DSv3).
Ú	use_ue8m0TÚgran_kÚuse_packed_ue8m0z]DeepGEMM requires block-wise quantized FP8 weights, but the experts have no `block_size` set.u?   DeepGEMM requires `block_size` âˆˆ {(128, 128), (1, 128)}, got r?   F))é€   r¹   )é   r¹   )r‡   r[   rˆ   rH   r¤   rŸ   )rƒ   r²   r³   r]   s   &&&&r$   Ú_select_fp8_cast_kwargsr»   £  s¤   € ð ‡|�|”u—z‘zÔ!Ø˜T 8¨RÐ1CÀTÐJÐJàÒÜØkó
ð 	
ô �zÓ"€JØÐ/Ô/ÜÐ\Ð]gÐ\hÐhiÐjÓkÐkØ×Ñ¤×!5Ñ!5Ô5¿(Ø˜T 8¨SÐ2DÀdÐKÐKØ˜ ¨#Ð.Ð.r#   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR	/# )
r&   Úexpert_ids_sortedr„   Únum_expertsr   Ú	alignmentÚuse_psum_layoutrY   r'   z&tuple[torch.Tensor, torch.Tensor, int]r   )r(   s   "r$   r)   r)   Â  s4   € ÷ !?ñ !?Ø#ð!?Ø25ð!?ØBEð!?ØX\ð!?à+ñ!?r#   c                ó<  € V P                   pV P                  ^ 4      pVP                  R8X  d   V P                  4       MV P	                  4       p\
        P                  ! Wa^ V^,
          R7      P                  4       pWr,           ^,
          V,          V,          pV\        WQ4      V^,
          ,          ,           p	W‡,
          p
\
        P                  P                  P                  V
P                  ^ 4      R4      p\
        P                  ! WTR7      W°,          ,           pV'       d!   VP                  ^ 4      P	                  4       pMS\
        P                  ! V	3RV\
        P                  R7      p\
        P                   ! W8  V P	                  4       R4      WÜ&   WÍV	3# )av  Build the TMA-aligned grouped layout DeepGEMM expects.

Returns `(sorted_to_padded, grouped_layout, total_padded_rows)`:
  - `grouped_layout` is per-row expert id (Hopper, with `-1` for padding /
    sentinels) or a cumsum of aligned per-expert counts (Blackwell).
  - EP sentinels (values == `num_experts`) are routed past the last expert
    block so DeepGEMM skips them.
Úcpu)ÚbinsÚminÚmax©rœ   ©rœ   r‡   )rº   é    rž   )rœ   r    Útyper’   r   r[   ÚhistcÚlongrÄ   ÚnnÚ
functionalÚpadÚcumsumÚarangeÚfullr�   Úwhere)r½   r¾   r¿   rÀ   rœ   Ú
num_tokensÚhistc_inputÚtokens_per_expertÚaligned_tokens_per_expertÚtotal_padded_rowsÚpadding_per_expertÚcumulative_paddingÚsorted_to_paddedÚgrouped_layouts   &&&&          r$   Ú!_build_deepgemm_contiguous_layoutrÜ   Â  sR  € ð ×%Ñ%€FØ"×'Ñ'¨Ó*€Jð 06¯{©{¸eÔ/CÐ#×)Ñ)Ô+ÐIZ×I^ÑI^ÓI`€KÜŸš KÀqÈkÐ\]ÍoÔ^×cÑcÓeÐØ"3Õ"?À!Õ"CÈ	Õ!QÐU^Õ ^Ðà"¤S¨Ó%AÀYÐQRÅ]Õ%SÕSÐð 3ÕFÐÜŸ™×,Ñ,×0Ñ0Ð1C×1JÑ1JÈ1Ó1MÈvÓVÐÜ—|’| JÔ>ÐASÕAfÕfÐçØ2×9Ñ9¸!Ó<×@Ñ@ÓB‰äŸšÐ%6Ð$8¸"ÀVÔSX×S^ÑS^Ô_ˆÜ+0¯;ª;Ð7HÑ7VÐXi×XmÑXmÓXoÐqsÓ+tˆÑ(àÐ->Ð>Ð>r#   c               ó(   € V ^8„  d   QhRRRRRRRR/# )r&   Úxr„   rÚ   r×   r   r'   r   )r(   s   "r$   r)   r)   æ  s*   € ÷ ñ ˜ð ¸ð ÐZ]ð Ðbnñ r#   c                ó�   € \         P                  ! V.V P                  R,          O5RV P                  RV P                  / pWV&   V# )z;Pad a sorted tensor into the TMA-aligned contiguous layout.:rº   NNrœ   r‡   )r[   Úemptyr§   rœ   r‡   )rÞ   rÚ   r×   Úpaddeds   &&& r$   Ú_pad_for_deepgemmrâ   æ  sA   € ä�[Š[Ð*ÐY¨Q¯W©W°R­[ÒYÀÇÁÐYÐQR×QXÑQXÑY€FØ ÐÑØ€Mr#   c               ó$   € V ^8„  d   QhRRRRRR/# )r&   Úx_paddedr„   rÚ   r'   r   )r(   s   "r$   r)   r)   í  s#   € ÷ &ñ &°\ð &ÐUað &Ðfrñ &r#   c                ó   € W,          # r€   r   )rä   rÚ   s   &&r$   Ú&_unpad_from_deepgemm_contiguous_layoutræ   í  s   € ØÕ%Ð%r#   c               ó4   € V ^8„  d   QhRRRRRRRRRRRR	R
R/# )r&   Úhidden_statesr„   Útop_k_indexÚtop_k_weightsr¾   r   r   rÀ   rY   r'   r¤   r   )r(   s   "r$   r)   r)   ô  sN   € ÷ /ñ /Øð/àð/ð  ð/ð ð	/ð
 ð/ð ð/ð ñ/r#   c                óP  € VP                  R4      pVP                  R4      pVP                  R4      p\        P                  ! V4      w  ršW
V,          ,          pWŠ,          p\	        W“WE4      w  rÞpW“8¬  P                  R4      pV	P                  V^,
          R7       VVV	VV
VVV3# )zãSort tokens by expert id and build the M-grouped padded layout.

Returns `(sorted_hidden_states_g, sample_weights_g, expert_ids_g,
          sentinel_mask, perm, sorted_to_padded, grouped_layout,
          total_padded_rows)`.
)rÅ   rž   )r    Úreshaper[   ÚsortrÜ   Ú	unsqueezeÚclamp_)rè   ré   rê   r¾   r   rÀ   Ú	num_top_kÚ
expert_idsÚsample_weightsÚexpert_ids_gÚpermÚsorted_hidden_states_gÚsample_weights_grÚ   rÛ   r×   Úsentinel_masks   &&&&&&           r$   Ú_dispatch_routed_inputrø   ô  sÃ   € ð × Ñ  Ó$€IØ×$Ñ$ RÓ(€JØ"×*Ñ*¨2Ó.€Nô Ÿš JÓ/Ñ€LØ*°9Õ+<Õ=ÐØ%Õ+Ðô
 ;\Ø ;ó;Ñ7ÐÐ&7ð "Ñ0×;Ñ;¸BÓ?€MØ×Ñ˜K¨!�OÐÔ,àØØØØØØØð	ð 	r#   c               ó@   € V ^8„  d   QhRRRRRRRRRRRRR	RR
RRRRR/
# )r&   Ú
out_paddedr„   Úsorted_weightsr÷   rô   rÚ   rÓ   r   rð   Ú
hidden_dimÚ	out_dtypeztorch.dtyper'   r   )r(   s   "r$   r)   r)   &  sx   € ÷ _ñ _Øð_à ð_ð  ð_ð ð	_ð
 #ð_ð ð_ð ð_ð ð_ð ð_ð ñ_r#   c	                óœ  € \        W4      p	W‘P                  V	P                  4      P                  R4      ,          p
V
P	                  VR4       \
        P                  ! V4      p\
        P                  ! VP                  ^ 4      V	P                  R7      W³&   W«,          P                  WVV4      P                  ^R7      P                  V4      # )uR   Unpad â†’ weighted multiply â†’ mask sentinels â†’ restore order â†’ top-k reduce.g        rÆ   r˜   rž   )ræ   Útor‡   rî   Úmasked_fill_r[   Ú
empty_likerÐ   r    rœ   r�   Úsum)rú   rû   r÷   rô   rÚ   rÓ   rð   rü   rý   r¯   ÚweightedÚinv_perms   &&&&&&&&&   r$   Ú_combine_routed_outputr  &  s    € ô 1°Ó
N€CØ×&Ñ& s§y¡yÓ1×;Ñ;¸BÓ?Õ?€Hð ×Ñ˜-¨Ô-Ü×Ò Ó%€HÜ—\’\ $§)¡)¨A£,°s·z±zÔB€H�NàÕ×"Ñ" :¸*ÓE×IÑIÈaÐIÓP×SÑSÐT]Ó^Ð^r#   Úoutput_dtypezv5.16)r=   c               ó8   € V ^8„  d   QhRRRRRRRRRRR	R
RRRR/# )r&   Úinputr„   rƒ   r²   Úbiasztorch.Tensor | Noner³   r9   r  ztorch.dtype | NoneÚactivation_scaler'   r   )r(   s   "r$   r)   r)   A  sX   € ÷ )ñ )Øð)àð)ð #ð)ð ð	)ð
 'ð)ð %ð)ð *ð)ð ñ)r#   c                ó¶  € Ve   \        R4      hV P                  \        P                  \        P                  39  d   \        RV P                   24      h\        W4       \        4       p\        WV\        4       4      pV P                  R	V P                  R	,          4      p	VP                  ! V	3/ VB w  r«\        P                  ! V
P                  ^ ,          VP                  ^ ,          V P                  V P                  R7      pVP                  R4      '       d   ^^VR,          3MRpVP!                  V
\#        V\        4       V
P%                  ^ 4      R7      3V\#        V\        4       VP%                  ^ 4      R7      3VVR7       VP                  V P                  RR	 VP                  ^ ,          3,           4      pVe   VP'                  V4       V# )
uç   End-to-end DeepGEMM linear: per-token activation quant + FP8/FP4 matmul.

Static (per-tensor) activation quantization is rejected â€” DeepGEMM needs
per-row SFs. Callers should route static activations through the Triton fallback.
Nz@DeepGEMM linear does not support static activation quantization.z7DeepGEMM linear requires FP16 or BF16 activations, got rÇ   r¸   r·   ©r–   )Úreciperž   )r‰   r‡   r[   Úbfloat16Úfloat16rH   r‹   r�   r»   r]   r�   r§   r   rà   rœ   r0   r   r°   r    Úadd_)r  rƒ   r²   r	  r³   r  r
  ÚdeepgemmÚcast_kwargsÚinput_2dÚ	qinput_2dÚscale_2dÚoutputÚ	sf_recipes   &&&&&&&       r$   Údeepgemm_fp8_fp4_linearr  @  sŽ  € ð Ò#Ü!Ð"dÓeÐeØ‡{�{œ5Ÿ>™>¬5¯=©=Ð9Ô9ÜÐRÐSX×S^ÑS^ÐR_Ð`ÓaÐaô ˜vÔ8ä#Ó%€HÜ)¨&ÀJÔPXÓPZÓ[€Kà�z‰z˜"˜eŸk™k¨"�oÓ.€HØ"×8Ò8¸ÑQÀ[ÑQÑ€IÜ�[Š[˜Ÿ™¨Õ+¨V¯\©\¸!­_ÀUÇ\Á\ÐY^×YdÑYdÔe€Fð 2=·±ÐAS×1TÒ1T��A�{ 8Õ,Ñ-ÐZ^€IØ×ÑØ	Ô)¨(´H³JÈIÏNÉNÐ[\ÓL]Ô^Ð_Ø	Ô&Ð'7¼»ÐQW×Q\ÑQ\Ð]^ÓQ_Ô`ÐaØØð	 ô ð �[‰[˜Ÿ™ S bÐ)¨V¯\©\¸!­_Ð,>Õ>Ó?€FØÒØ�‰�DÔØ€Mr#   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# ©r&   Úselfútorch.nn.Modulerè   r„   ré   rê   r'   r   )r(   s   "r$   r)   r)   m  s:   € ÷ >ñ >Ø
ð>àð>ð ð>ð  ð	>ð
 ñ>r#   c                óž  € VP                   \        P                  8w  d   \        R VP                    24      h\	        4       pV P
                  '       d   VP                  MVP                  pVP                  pVP                  R4      pVP                  ^ 4      pVP                  R4      p	\        WW0P                  VP                  \        4       4      w  p
pppppppV P                  '       d   V P                  MV P                   pV P"                  pV P$                  '       d+   V P                  '       d   V P&                  MV P(                  MRpV P$                  '       d   V P*                  MRpV P
                  '       d   VP,                  R,          MVP,                  ^,          p\/        W¯V4      p\        P0                  ! VVWaP                   R7      pV! VVVV\        4       R7       V P$                  '       d   VP3                  ^ VVV,          4       V P                  '       d   V P5                  V4      MV P7                  V4      p\        P0                  ! VW–VP                   R7      pV! VVVV\        4       R7       V P$                  '       d   VP3                  ^ VVV,          4       \9        VVVVVVVV	VP                   4	      # )ú;DeepGEMM experts path requires bfloat16 hidden states, got NrÇ   )rÀ   rž   )r‡   r[   r  rH   r�   Úis_transposedr   r   rœ   r    rø   r¾   r   r]   Úhas_gateÚgate_up_projÚup_projÚ	down_projÚhas_biasÚgate_up_proj_biasÚup_proj_biasÚdown_proj_biasr§   râ   rà   Ú
index_add_Ú_apply_gateÚact_fnr  )r  rè   ré   rê   r  Úgrouped_bf16_matmulrœ   rð   rÓ   rü   Úsorted_hiddenrû   ró   r÷   rô   rÚ   rÛ   r×   Ú	weight_upÚweight_downÚup_biasÚ	down_biasÚ
up_out_dimÚactÚproj_outr¯   s   &&&&                      r$   Údeepgemm_bf16_experts_forwardr4  m  sW  € ð ×ÑœeŸn™nÔ,ÜÐVÐWd×WjÑWjÐVkÐlÓmÐmä#Ó%€Hà=A×=O×=OÐ=O˜(×9Ò9ÐU]×UtÑUtÐà×!Ñ!€FØ× Ñ  Ó$€IØ×#Ñ# AÓ&€JØ×#Ñ# BÓ'€Jô 	Ø M×3CÑ3CÀX×EYÑEYÔ[cÓ[eó	ñ	ØØØØØØØØð
 &*§]§] ]�×!Ò!¸¿¹€IØ—.‘.€KØRV×R_×R_ÐR_¨¯¯¨ˆt×%Ò%¸D×<MÒ<MÐei€GØ'+§}§} }�×#Ò#¸$€Ið )-×(:×(:Ð(:�—‘ Ö$À	ÇÁÐPQÕ@R€JÜ
˜MÐ=NÓ
O€CÜ�{Š{Ð,¨jÀ×ObÑObÔc€HÙ˜˜Y¨°.ÔRZÓR\Õ]Ø‡}‡}€}Ø×Ñ˜AÐ/°¸Õ1FÔGà-1¯]¯]¨]ˆt×Ñ Ô)ÀÇÁÈHÓ@U€Hô �+Š+Ð'¨È-×J]ÑJ]Ô
^€CÙ˜ +¨s°NÔT\ÓT^Õ_Ø‡}‡}€}Ø�‰�qÐ*¨I°lÕ,CÔDä!ØØØØØØØØØ×Ñó
ð 
r#   c          
     ó,   € V ^8„  d   QhRRRRRRRRRR/# r  r   )r(   s   "r$   r)   r)   ®  sA   € ÷ Zñ ZØ
ðZàðZð ðZð  ð	Zð
 ñZr#   c                ó   € V P                   '       d   \        R 4      h\        V P                  V P                  4       \        4       pV P                  R8X  d   \        R4      hVP                  \        P                  8w  d   \        RVP                   24      hV P                  '       d   VP                  MVP                  pVP                  pVP!                  R
4      pVP!                  ^ 4      pVP!                  R
4      p	V P"                  '       d   V P$                  MV P&                  p
V P"                  '       d   V P(                  MV P*                  pV P                  pV P                  p\-        W«V P.                  \1        4       4      p\3        WW0P4                  VP6                  \1        4       4      w  ppppppppVP9                  R4      '       d   ^^VR,          3MRpVP:                  ! V3/ VB w  pp\=        VVV4      p\=        VVV4      p\        P>                  ! VV
P@                  ^,          V\        P                  R7      pV! V\C        V\1        4       VR7      3V
\C        V\1        4       V
P!                  R4      R7      3VVV\1        4       R	7       V P"                  '       d   V PE                  V4      MV PG                  V4      pVP:                  ! V3/ VB w  pp\        P>                  ! VW–\        P                  R7      pV! V\C        V\1        4       VR7      3V\C        V\1        4       VP!                  R4      R7      3VVV\1        4       R	7       \I        VVVVVVVV	VP                  4	      # )zðDeepGEMM experts selected on a model spanning multiple CUDA devices in one process; its kernels are bound to a single CUDA context and corrupt across devices. Use `experts_implementation='grouped_mm'`, or run one device per process (TP/EP).ÚstaticzJDeepGEMM experts dispatch does not support static activation quantization.r  r¸   r·   NrÇ   r  )r  rÀ   rž   r�   )%Ú_deepgemm_disabledÚRuntimeErrorr‹   r#  Údown_proj_scale_invr�   Úactivation_schemer‰   r‡   r[   r  rH   r  r   r   rœ   r    r   r!  r"  Úgate_up_proj_scale_invÚup_proj_scale_invr»   r³   r]   rø   r¾   r   r0   r   râ   rà   r§   r°   r)  r*  r  )r  rè   ré   rê   r  Úgrouped_fp8_fp4_matmulrœ   rð   rÓ   rü   r-  Úweight_scale_upr.  Úweight_scale_downr  r,  rû   Ú_expert_ids_gr÷   rô   rÚ   rÛ   r×   r  Úact_fp8Ú
act_scalesr3  Úproj_fp8Úproj_scalesr¯   s   &&&&                          r$   Ú deepgemm_fp8_fp4_experts_forwardrF  ®  s.  € ð ××Ðô ð\ó
ð 	
ô ˜tŸ~™~¨t×/GÑ/GÔHä#Ó%€Hà×Ñ Ô)Ü!Ð"nÓoÐoØ×ÑœeŸn™nÔ,ÜÐVÐWd×WjÑWjÐVkÐlÓmÐmà.2×.@×.@Ð.@ˆ×*Ò*Àh×FhÑFhð ð ×!Ñ!€FØ× Ñ  Ó$€IØ×#Ñ# AÓ&€JØ×#Ñ# BÓ'€Jà%)§]§] ]�×!Ò!¸¿¹€IØ59·]·]°]�d×1Ò1È×H^ÑH^€OØ—.‘.€KØ×0Ñ0Ðä)¨)ÀdÇoÁoÔW_ÓWaÓb€Kô 	Ø M×3CÑ3CÀX×EYÑEYÔ[cÓ[eó	ñ	ØØØØØØØØð 2=·±ÐAS×1TÒ1T��A�{ 8Õ,Ñ-ÐZ^€Ið #×8Ò8¸ÑVÈ+ÑVÑ€GˆZÜ Ð)9Ð;LÓM€GÜ" :Ð/?ÐARÓS€JÜ�{Š{Ð,¨i¯o©o¸aÕ.@ÈÔW\×WeÑWeÔf€HÙØ	Ô'¨
´H³JÐL]Ô^Ð_Ø	Ô)¨/¼8»:ÐS\×SaÑSaÐbdÓSeÔfÐgØØØÜ ›
õð .2¯]¯]¨]ˆt×Ñ Ô)ÀÇÁÈHÓ@U€Hð %×:Ò:¸8ÑSÀ{ÑSÑ€HˆkÜ
�+Š+Ð'¨Ì%Ï.É.Ô
Y€CÙØ	Ô(¨´h³jÐN_Ô`ÐaØ	Ô+Ð,=¼x»zÐWb×WgÑWgÐhjÓWkÔlÐmØØØÜ ›
õô "ØØØØØØØØØ×Ñó
ð 
r#   c               ó    € V ^8„  d   QhRRRR/# )r&   Úmoduler  r'   rm   r   )r(   s   "r$   r)   r)     s   € ÷ 7Rñ 7R /ð 7R°dñ 7Rr#   c                ó  € \        4       pV P                  P                  pV P                  P                  pV P                  P                  P                  \        P                  4      P                  4       pV P                  P                  P                  \        P                  4      P                  4       pV P                  pV P                  pV P                  pV^ ,          ^ 8w  g   V^ ,          ^ 8w  d   \        RV RV R24      hVP                  VP                  4       ^V,          VRVR7      p	VP                  VP                  4       VVRVR7      p
VP!                  WI3WZ34      w  w  r¹w  rÊ\        P"                  P%                  VRR7      V n        \        P"                  P%                  V	RR7      V n        \        P"                  P%                  VRR7      V n	        \        P"                  P%                  V
RR7      V n        R# )	uí  One-shot pack + permute of an FP8Experts module's L1/L2 weights into the
Mega MoE UTCCP layout. Called lazily on the first megamoe forward; idempotent
via the caller's ``_megamoe_transformed`` flag.

Steps:
  1. Cast UE8M0 SF â†’ FP32 and call ``transform_sf_into_required_layout`` â†’
     packed int32 in MN-major TMA-aligned layout.
  2. Run ``transform_weights_for_mega_moe``: interleaves gate/up on L1 and
     transposes both SFs for UTCCP.
  3. Overwrite the loader-side parameters in place; the interleave preserves
     the ``[E_local, 2*I, *]`` leading dims so downstream ``.size(...)`` reads
     stay valid.

Unwraps any ``DTensor`` wrappers FSDP2/EP may have placed around the loader-
side Parameters â€” the kernel takes raw pointers.
zwDeepGEMM Mega MoE requires `hidden_dim` and `intermediate_hidden` divisible by 32 (FP8 SF granularity); got hidden_dim=z, intermediate_hidden=r?   )r  Ú
num_groupsF)Úrequires_gradN)rº   é    )r�   r<  Údatar:  r!  r�   r[   rˆ   r¢   r#  Úintermediate_dimr¾   rü   rH   r   r’   r   rÌ   Ú	Parameter)rH  r  Úgate_up_sf_rawÚdown_sf_rawÚ	gate_up_wÚdown_wÚintermediate_hiddenÚnum_local_expertsrü   Ú
gate_up_sfÚdown_sfÚgate_upÚdowns   &            r$   Úsetup_megamoe_weightsrZ    sä  € ô" $Ó%€HØ×2Ñ2×7Ñ7€NØ×,Ñ,×1Ñ1€Kà×#Ñ#×(Ñ(×-Ñ-¬e¯j©jÓ9×DÑDÓF€IØ×Ñ×"Ñ"×'Ñ'¬¯
©
Ó3×>Ñ>Ó@€Fà ×1Ñ1ÐØ×*Ñ*ÐØ×"Ñ"€Jà�B…˜!ÔÐ2°RÕ7¸1Ô<Üð4Ø4>°<Ð?UÐViÐUjÐjkðmó
ð 	
ð
 ×;Ñ;Ø×ÑÓØ	ÐÕØØØ$ð <ó €Jð ×8Ñ8Ø×ÑÓØØØØ$ð 9ó €Gð .6×-TÑ-TØ	ÐØ	Ðó.Ñ*Ñ€W™?˜Dô  Ÿ(™(×,Ñ,¨WÀEÐ,ÓJ€FÔÜ$)§H¡H×$6Ñ$6°zÐQVÐ$6Ó$W€FÔ!Ü—x‘x×)Ñ)¨$¸eÐ)ÓD€FÔÜ!&§¡×!3Ñ!3°GÈ5Ð!3Ó!Q€FÖr#   c               ó0   € V ^8„  d   QhRRRRRRRRRRR	R/# )
r&   r  r  rè   r„   ré   rê   Úprocess_groupz%torch.distributed.ProcessGroup | Noner'   r   )r(   s   "r$   r)   r)   E  sL   € ÷ V%ñ V%Ø
ðV%àðV%ð ðV%ð  ð	V%ð
 9ðV%ð ñV%r#   c                óº  € \        V P                  V P                  4       V P                  P                  \        P
                  8w  d$   \        RV P                  P                   R24      hVf   \        R4      h\        4       p\        V RR4      '       g   \        V 4       RV n        VP                  R4      pVP                  ^ 4      pVP                  R4      pV P                  P                  ^ 4      p	V P                  P                  ^4      ^,          p
W”P                  4       ,          p\        V RR4      e   V P                  P                  V8  d   VP                  VVVVVV
R	7      V n        VP!                  VR^ RR
7      w  rÍV P                  P"                  RV P%                  V4       V P                  P&                  RV P%                  V4       V P                  P(                  RV P%                  V4       V P                  P*                  RV P%                  V4       \        P,                  ! Wx3\        P.                  VP0                  R7      pVP3                  VV P                  V P4                  3V P6                  V P                  3V P                  \        \        V RR4      RR4      R7       VP9                  VP                  4      # )u·  FP8 acts Ã— FP4 weights Mega MoE forward (SM100+).

Fuses EP dispatch + L1 + SwiGLU + L2 + EP combine into one kernel,
overlapping NVLink with tensor-core compute. The kernel handles the full
`(num_tokens, hidden) â†’ (num_tokens, hidden)` MoE forward including the
weighted top-k reduction; the caller must NOT all-reduce the output.

`process_group` is supplied automatically by `MoeTensorParalellExperts._prepare_input_fn`
when the module is wrapped for TP â€” it's required for the symm-buffer rendezvous
on first forward. `top_k_index` is GLOBAL expert ids (`-1` marks skipped slots).

Caller-managed `self` attributes:
  - `gate_up_proj`, `gate_up_proj_scale_inv`: L1 weight + UE8M0 SF.
  - `down_proj`, `down_proj_scale_inv`: L2 weight + UE8M0 SF.
  Both pairs must be transformed together via
  `transform_weights_for_mega_moe((gate_up, gate_up_sf), (down, down_sf))`.
  - `config.swiglu_limit` (optional): SwiGLU clamp; absent â†’ unclamped.
zJDeepGEMM Mega MoE requires FP4-packed expert weights (dtype=`int8`), got `z/`. Use the 'deepgemm' dispatch for FP8 experts.Nz©DeepGEMM Mega MoE requires a `process_group` for the EP group. The TP wrapping (MoeTensorParalellMegaMoeExperts) supplies it automatically; pass it explicitly otherwise.Ú_megamoe_transformedFTÚsymm_buffer)ÚhiddenÚnum_topkr¾   Únum_max_tokens_per_rankrT  )r¶   r·   r¸   r›   ÚconfigÚswiglu_limit)Úactivation_clamprž   )r‹   r!  r:  r‡   r[   rˆ   r‰   rH   r�   rw   rZ  r^  r    r_  rb  r   r   rÞ   r¨   Úx_sfÚtopk_idxÚtopk_weightsrà   r  rœ   r   r<  r#  rÿ   )r  rè   ré   rê   r\  r  rð   rÓ   rü   rU  rT  Únum_global_expertsÚx_fp8rf  Úys   &&&&&          r$   Ú(deepgemm_fp8_fp4_megamoe_experts_forwardrl  E  s¡  € ô8 ˜t×0Ñ0°$×2JÑ2JÔKà×Ñ×Ñ¤%§*¡*Ô,Ü!ðØ×!Ñ!×'Ñ'Ð(Ð(WðYó
ð 	
ð
 ÒÜðió
ð 	
ô
 $Ó%€Hô �4Ð/°×7Ò7Ü˜dÔ#Ø$(ˆÔ!à× Ñ  Ó$€IØ×#Ñ# AÓ&€JØ×#Ñ# BÓ'€JØ×)Ñ)×.Ñ.¨qÓ1ÐØ×+Ñ+×0Ñ0°Ó3°qÕ8ÐØ*×-?Ñ-?Ó-AÕAÐô ˆt�] DÓ)Ò1°T×5EÑ5E×5]Ñ5]Ð`jÔ5jØ#×@Ñ@ØØØØ*Ø$.Ø 3ð Aó 
ˆÔð ×0Ñ0°È$ÐWYÐlpÐ0Óq�K€EØ×Ñ×Ñ�{˜
Ð#×)Ñ)¨%Ô0Ø×Ñ×Ñ˜+˜:Ð&×,Ñ,¨TÔ2Ø×Ñ×Ñ˜k˜zÐ*×0Ñ0°Ô=Ø×Ñ×!Ñ! + :Ð.×4Ñ4°]ÔCô 	�Š�ZÐ,´E·N±NÈ=×K_ÑK_Ô`€AØ×ÑØ	Ø	×	Ñ	˜D×7Ñ7Ð8Ø	�‰˜×1Ñ1Ð2Ø×ÑÜ ¤¨¨x¸Ó!>ÀÐPTÓUð ô ð �4‰4�×#Ñ#Ó$Ð$r#   )Fr€   )NNNN)7Ú__conditional_annotations__r    Ú
__future__r   Ú	functoolsrD   r.   rJ   r1   Úcollections.abcr   Údataclassesr   r[   Úutilsr   Úutils.deprecationr   Úutils.import_utilsr   r   r	   Úhub_kernelsr
   r   Ú
get_loggerr   Úloggerr   Úcacher7   rW   Ú_dynamoÚassume_constant_resultr]   rj   rk   r!   Úallow_in_graphr}   r�   r‹   r”   r°   r»   rÜ   râ   ræ   rø   r  r  r4  rF  rZ  rl  )rm  s   @r$   Ú<module>r|     s  øðô
õ #ã Û Û 	Û 	Û Ý $Ý !ã å Ý /÷ñ ÷
 Dð 
×	Ò	˜HÓ	%€ñ
 �$Ô÷ð ó ðð, ‡�ôó ðð$ ‡�ô+ó ð+ð\ ‡�×%Ñ%ô7ó &ð7ð ‡�×%Ñ%öBó &ðBðP "€	ˆ?Ó !ð ‡�×ÑôDó ðDõNõ!
õH
Y÷9õx/õ>!?õHõ&õ/õd_ñ4 �¨Ô1ö)ó 2ð)õX>õBZõz7R÷tV%ñ V%r#   