Ë
    Úéñid  ã                   óŠ  — d dl Z d dlZd dlZd dlZd dlZd dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZ ej                   j#                  ej                   j%                  e«      «      Zej                   j)                  ed«      gZej                   j)                  ed	«      Zd
gZda e j2                  «       d„ «       Z e j2                  «       d„ «       Z G d„ de«      Zd„ ZddddddœZddddddœZ dZ! e"e!«      Z#d„ Z$ e%d„  e&d«      D «       «      Z'de'd<   de'd<   de'd<   d„ Z(d „ Z) G d!„ d"e«      Z* G d#„ d$e«      Z+y)%é    N)ÚPath)Úknobs)Úcompile_module_from_src)Ú_allocation)Ú	GPUTarget)Ú	GPUDriverÚincludeÚlibúlibcuda.so.1c            	      óÔ  — t         j                  j                  x} r| gS t        j                  ddg«      j                  d¬«      }|j                  «       D �cg c]  }d|v sŒ|j                  «       d   ‘Œ }}|D �cg c]!  }t        j                  j                  |«      ‘Œ# }}t        j                  d«      }|r^|s\|j                  d«      D �cg c]B  }t        j                  j                  t        j                  j                  |d«      «      sŒA|‘ŒD }}d	}|r|d
t        |«      z  z  }|dz  }n
|dz  }|dz  }t        d„ |D «       «      sJ |«       ‚|S c c}w c c}w c c}w )Nz/sbin/ldconfigz-pÚignore)Úerrorsr   éÿÿÿÿÚLD_LIBRARY_PATHú:zlibcuda.so cannot found!
z!Possible files are located at %s.z:Please create a symlink of libcuda.so to any of the files.z<Please make sure GPU is set up and then run "/sbin/ldconfig"z- (requires sudo) to refresh the linker cache.c              3   ó–   K  — | ]A  }t         j                  j                  t         j                  j                  |d «      «      –— ŒC y­w)r   N)ÚosÚpathÚexistsÚjoin)Ú.0r   s     ú_/var/www/pod-logistic/pod-ai/venv/lib/python3.12/site-packages/triton/backends/nvidia/driver.pyú	<genexpr>zlibcuda_dirs.<locals>.<genexpr>(   s,   è ø€ ÒSÀdŒr�w‰w�~‰~œbŸg™gŸl™l¨4°Ó@×AÑSùs   ‚AA	)r   ÚnvidiaÚlibcuda_pathÚ
subprocessÚcheck_outputÚdecodeÚ
splitlinesÚsplitr   r   ÚdirnameÚgetenvr   r   ÚstrÚany)	Úenv_libcuda_pathÚlibsÚlineÚlocsÚlocÚdirsÚenv_ld_library_pathÚdirÚmsgs	            r   Úlibcuda_dirsr.      sW  € ä Ÿ<™<×4Ñ4Ð4ÐÐ4Ø Ð!Ð!ä×"Ñ"Ð$4°dÐ#;Ó<×CÑCÈ8ÐCÓT€Dð *.¯©Ó):ÖU ¸nÐPTÒ>TˆD�J‰J‹L˜ÓÐU€DÐUØ,0Ö1 SŒB�G‰G�O‰O˜CÕ Ð1€DÐ1ÜŸ)™)Ð$5Ó6ÐÙ¡4Ø2×8Ñ8¸Ó=Ös˜ÄÇÁÇÁÔPR×PWÑPW×P\ÑP\Ð]`ÐbpÓPqÕAr’ÐsˆÐsØ
&€CÙØÐ2´S¸³YÑ>Ñ>ˆØÐKÑK‰àÐMÑMˆØÐ>Ñ>ˆÜÑSÈdÔSÔSÐXÐUXÓXÐSØ€Kùò VùÚ1ùò ts   Á	EÁ#EÁ>&E ÃAE%ÄE%c                  ó$   — t         gt        «       ¢S ©N)Úlibdevice_dirr.   © ó    r   Úlibrary_dirsr4   ,   s   € äÐ+œL›NÐ+Ð+r3   c                   ó$   ‡ — e Zd Zˆ fd„Zd„ Zˆ xZS )Ú	CudaUtilsc                 ód   •— t        | d«      st        t        | �  | «      | _        | j                  S )NÚinstance)ÚhasattrÚsuperr6   Ú__new__r8   )ÚclsÚ	__class__s    €r   r;   zCudaUtils.__new__8   s*   ø€ Ü�s˜JÔ'Ü ¤¨CÑ8¸Ó=ˆCŒLØ�|‰|Ðr3   c                 óx  — t        t        t        j                  j	                  t
        d«      «      j                  «       dt        «       t        t        ¬«      }|j                  a
|j                  | _        |j                  | _        |j                  | _        |j                  | _        |j                  | _        y )Nzdriver.cÚ
cuda_utils©ÚsrcÚnamer4   Úinclude_dirsÚ	libraries)r   r   r   r   r   r!   Ú	read_textr4   rC   rD   ÚPyCUtensorMapÚload_binaryÚget_device_propertiesÚcuOccupancyMaxActiveClustersÚset_printf_fifo_sizeÚfill_tma_descriptor)ÚselfÚmods     r   Ú__init__zCudaUtils.__init__=   s‹   € Ü%Ü”R—W‘W—\‘\¤'¨:Ó6Ó7×AÑAÓCØÜ%›Ü%Üô
ˆð ×)Ñ)ˆØŸ?™?ˆÔØ%(×%>Ñ%>ˆÔ"Ø,/×,LÑ,LˆÔ)Ø$'×$<Ñ$<ˆÔ!Ø#&×#:Ñ#:ˆÕ r3   )Ú__name__Ú
__module__Ú__qualname__r;   rN   Ú__classcell__©r=   s   @r   r6   r6   6   s   ø„ ôö
;r3   r6   c                 ó¢   — | d   dk(  ry| j                  d«      ryi dd“dd“d	d
“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“dd“|    S )Nr   Ú*ÚCUdeviceptrÚ
tensordescÚCUtensorMapÚi1Úint8_tÚi8Úi16Úint16_tÚi32Úint32_tÚi64Úint64_tÚu1Úuint8_tÚu8Úu16Úuint16_tÚu32Úuint32_tÚu64Úuint64_tÚfp16ÚdoubleÚbf16Úfp32Úf32Úfp64Ú	nvTmaDesc)Ú
startswith)Útys    r   Ú	ty_to_cpprt   S   sï   € Ø	ˆ!�u�‚|ØØ	‡}�}�\Ô"ØðØˆhðàˆhðð 	ˆyðð 	ˆyð	ð
 	ˆyðð 	ˆiðð 	ˆiðð 	ˆzðð 	ˆzðð 	ˆzðð 	�ðð 	�ðð 	�ðð 	ˆxðð 	�ðð  	�]ð!ð" 	ñ#
ð 
r3   rf   rh   rj   )rk   rm   rn   ro   rp   Ú	pack_fp16Ú	pack_bf16Ú	pack_fp32Ú	pack_fp64ÚiiiKKppOOOOOOc                 ó  ‡‡‡‡— ˆfd„}ˆfd„Šˆfd„Šˆfd„Š ||j                  «       «      }t        |«      D ��ci c]  \  }}||“Œ
 }}}dj                  |j                  «       D �cg c]
  } ‰|«      ‘Œ c}«      }t        |z   }	g }
|j                  «       D ]  } ‰||
«       Œ t        |
«      D ��ci c]  \  }}||“Œ
 }}}t	        |«      dkD  r)ddj                  d„ |j                  «       D «       «      z   nd}g }|j                  «       D ]P  \  }}|d	k(  rŒ|t        v r|j                  t        |   › d
|› �«       Œ2|j                  t        |«      › d
|› �«       ŒR dj                  |«      }g }|j                  «       D ]u  \  }}|d   dk(  r|j                  d|› d�«       Œ$|t        v r|j                  d|› d�«       ŒB|dk(  r|j                  d|› �«       Œ\|d	k7  sŒb|j                  d|› �«       Œw t        t	        |«      «      }d}|j                  «       D ��cg c]  \  }}|d   dk(  rd|› d|› d|› d|› d�	‘Œ }}}|j                  «       D ��cg c]  \  }}|dk(  rd|› d|› d|› d�‘Œ }}}|j                  «       D ��cg c])  \  }}|t        v rt        |   › d|› dt        |   › d|› d�‘Œ+ }}}|j                  «       D ��cg c]  \  }}|d	k7  sŒd|› �‘Œ }}}|j                  d «       |j                  d!«       d"t	        |«      dkD  rd|z   nd› d#dj                  |«      › d$|j                  |j                  «       D ��cg c]  \  }} ‰|«      › d|› d%�‘Œ c}}«      › d&|	› d'|› d(|j                  |«      › d|j                  |«      › d|j                  |«      › d)t	        |«      dkD  rddj                  |«      z   nd› d*�}|S c c}}w c c}w c c}}w c c}}w c c}}w c c}}w c c}}w c c}}w )+Nc                 ó¢  •— g }d}| D �]1  }t        |t        «      �r|j                  d«      rû‰
r‰
|   nd }|dz  }t        j                  d|«      }|j                  d«      }|j                  d«      }|j                  d«      dz   }|€J|j                  d|z   «       t        d|z  «      D ]  }	|j                  d«       Œ |j                  d	«       n|j                  d
«       t        |«      D ]  }	|j                  d«       Œ t        |«      D ]  }	|j                  d«       Œ �Œ!|j                  |«       �Œ4 ‰
r|t        ‰
«      k(  sJ ‚|S )Nr   rW   é   ztensordesc<([^[>]*)\[([^]]*)\]é   ú,rU   r`   rY   rq   r^   )
Ú
isinstancer#   rr   ÚreÚmatchÚgroupÚcountÚappendÚrangeÚlen)Ú	signatureÚoutputÚtensordesc_idxÚsigÚmetar�   ÚdtypeÚshapeÚndimÚ_Útensordesc_metas             €r   Ú_expand_signaturez(make_launcher.<locals>._expand_signature�   sC  ø€ ØˆØˆð ó 	#ˆCÜ˜#œsÕ#¨¯©°|Ô(DÙ:I� ~Ò6Èt�Ø !Ñ#�äŸ™Ð!CÀSÓI�ØŸ™ A›�ØŸ™ A›�Ø—{‘{ 3Ó'¨!Ñ+�à�<Ø—M‘M #¨¡+Ô.ô # 1 t¡8›_ò -˜ØŸ™ eÕ,ð-à—M‘M $Õ'à—M‘M +Ô.ä˜t›ò )�AØ—M‘M %Õ(ð)ä˜t›ò )�AØ—M‘M %Õ(ò)ð —‘˜cÖ"ð9	#ñ< # n¼¸OÓ8LÒ&LÐLÐLØˆr3   c                 ój   •— t        | t        «      r| D ]  } ‰||«       Œ y |j                  | «       y r0   )r   Útupler„   )rŠ   rˆ   ÚxÚ_flatten_signatures      €r   r•   z)make_launcher.<locals>._flatten_signature¨   s4   ø€ ä�cœ5Ô!Øò .�Ù" 1 fÕ-ñ.ð �M‰M˜#Õr3   c                 ó˜   •— t        | t        «      r!dj                  t        ‰| «      «      }d|› d�S | d   dk(  ry| dv ryt	        | «      S )Nr~   ú[ú]r   rU   z	PyObject*©Ú	constexprrq   )r   r“   r   Úmaprt   )rs   ÚvalÚ_extracted_types     €r   r�   z&make_launcher.<locals>._extracted_type°   sT   ø€ Ü�bœ%Ô Ø—(‘(œ3˜°Ó3Ó4ˆCØ�s�e˜1�:ÐØˆa‰5�CŠ<ØØÐ+Ñ+ØÜ˜‹}Ðr3   c                 óØ   •— t        | t        «      r!dj                  t        ‰| «      «      }d|› d�S | d   dk(  ry| dv ry| j	                  d«      ryd	d
dddddddddœ
t        | «         S )NÚ ú(ú)r   rU   ÚOr™   rW   ÚdÚlÚbÚhÚiÚLÚBÚHÚIÚK)
rl   ÚlongrZ   r]   r_   ra   rc   rf   rh   rj   )r   r“   r   r›   rr   rt   )rs   rœ   Ú	format_ofs     €r   r®   z make_launcher.<locals>.format_ofº   s�   ø€ Ü�bœ%Ô Ø—'‘'œ#˜i¨Ó,Ó-ˆCØ�s�e˜1�:ÐØˆa‰5�CŠ<ØØÐ+Ñ+ØØ�=‰=˜Ô&ØàØØØØØØØØØñ
ô �B‹-ñð 	r3   rŸ   r   z, c              3   ó,   K  — | ]  \  }}d |› �–— Œ y­w)z&_argNr2   )r   r§   rs   s      r   r   z make_launcher.<locals>.<genexpr>Û   s   è ø€ Ò L±°°B 5¨¨¤Ñ Lùs   ‚rš   z argrU   Úptr_infoz.dev_ptrÚ_argÚ_storagerq   z*tma_ptrz
  zDevicePtrInfo ptr_infoz = getPointer(_argz); if (!ptr_infoz.valid) return NULL;zCUtensorMap* tma_ptrz = getTmaDesc(_argz); if (!tma_ptrz) return NULL;z _argz_storage = z(_argz);z&argz&global_scratchz&profile_scratchaÊ  
#include "cuda.h"
#include <dlfcn.h>
#include <stdbool.h>
#include <stdlib.h>
#define PY_SSIZE_T_CLEAN
#include <Python.h>

typedef struct {
  PyObject_HEAD;
  _Alignas(128) CUtensorMap tensorMap;
} PyCUtensorMapObject;

static inline void gpuAssert(CUresult code, const char *file, int line)
{
   if (code != CUDA_SUCCESS)
   {
      const char* prefix = "Triton Error [CUDA]: ";
      const char* str;
      cuGetErrorString(code, &str);
      char err[1024] = {0};
      strcat(err, prefix);
      strcat(err, str);
      PyGILState_STATE gil_state;
      gil_state = PyGILState_Ensure();
      PyErr_SetString(PyExc_RuntimeError, err);
      PyGILState_Release(gil_state);
   }
}

#define CUDA_CHECK(ans) { gpuAssert((ans), __FILE__, __LINE__); }

typedef CUresult (*cuLaunchKernelEx_t)(const CUlaunchConfig* config, CUfunction f, void** kernelParams, void** extra);

static cuLaunchKernelEx_t getLaunchKernelExHandle() {
  // Open the shared library
  void* handle = dlopen("libcuda.so.1", RTLD_LAZY);
  if (!handle) {
    PyErr_SetString(PyExc_RuntimeError, "Failed to open libcuda.so.1");
    return NULL;
  }
  // Clear any existing error
  dlerror();
  cuLaunchKernelEx_t cuLaunchKernelExHandle = (cuLaunchKernelEx_t)dlsym(handle, "cuLaunchKernelEx");
  // Check for errors
  const char *dlsym_error = dlerror();
  if (dlsym_error) {
    PyErr_SetString(PyExc_RuntimeError, "Failed to retrieve cuLaunchKernelEx from libcuda.so.1");
    return NULL;
  }
  return cuLaunchKernelExHandle;
}

static void _launch(int gridX, int gridY, int gridZ, int num_warps, int num_ctas, int launch_cooperative_grid, int launch_pdl, int shared_memory, CUstream stream, CUfunction function, CUdeviceptr global_scratch, CUdeviceptr profile_scratchz) {
  void *params[] = { au   };
  if (gridX*gridY*gridZ > 0) {
    // 4 attributes that we can currently pass maximum
    CUlaunchAttribute launchAttr[4];
    static cuLaunchKernelEx_t cuLaunchKernelExHandle = NULL;
    if (cuLaunchKernelExHandle == NULL) {
      cuLaunchKernelExHandle = getLaunchKernelExHandle();
    }
    CUlaunchConfig config;
    config.gridDimX = gridX * num_ctas;
    config.gridDimY = gridY;
    config.gridDimZ = gridZ;

    config.blockDimX = 32 * num_warps;
    config.blockDimY = 1;
    config.blockDimZ = 1;
    config.sharedMemBytes = shared_memory;
    config.hStream = stream;
    config.attrs = launchAttr;
    int num_attrs = 0;

    if (launch_pdl != 0) {
      CUlaunchAttribute pdlAttr = { .id = CU_LAUNCH_ATTRIBUTE_PROGRAMMATIC_STREAM_SERIALIZATION, .value = 1};
      launchAttr[num_attrs] = pdlAttr;
      ++num_attrs;
    }

    if (launch_cooperative_grid != 0) {
      CUlaunchAttribute coopAttr = { .id = CU_LAUNCH_ATTRIBUTE_COOPERATIVE, .value = 1};
      launchAttr[num_attrs] = coopAttr;
      ++num_attrs;
    }

    if (num_ctas != 1) {
      CUlaunchAttribute clusterAttr = {};
      clusterAttr.id = CU_LAUNCH_ATTRIBUTE_CLUSTER_DIMENSION;
      clusterAttr.value.clusterDim.x = num_ctas;
      clusterAttr.value.clusterDim.y = 1;
      clusterAttr.value.clusterDim.z = 1;
      launchAttr[num_attrs] = clusterAttr;
      ++num_attrs;

      CUlaunchAttribute clusterSchedulingAttr = {};
      clusterSchedulingAttr.id = CU_LAUNCH_ATTRIBUTE_CLUSTER_SCHEDULING_POLICY_PREFERENCE;
      clusterSchedulingAttr.value.clusterSchedulingPolicyPreference = CU_CLUSTER_SCHEDULING_POLICY_SPREAD;
      launchAttr[num_attrs] = clusterSchedulingAttr;
      ++num_attrs;
    }

    // num_ctas == 16 is non-portable. Does work for H100 and B200 tho
    config.numAttrs = num_attrs;
    if (num_ctas == 16) {
      CUDA_CHECK(cuFuncSetAttribute(
          function,
          CU_FUNC_ATTRIBUTE_NON_PORTABLE_CLUSTER_SIZE_ALLOWED,
          1
      ));
    }

    CUDA_CHECK(cuLaunchKernelExHandle(&config, function, params, 0));
  }
}

typedef struct _DevicePtrInfo {
    CUdeviceptr dev_ptr;
    bool valid;
} DevicePtrInfo;

static PyObject* data_ptr_str = NULL;
static PyObject* py_tensor_map_type = NULL;

static inline DevicePtrInfo getPointer(PyObject *obj, int idx) {
  DevicePtrInfo ptr_info;
  ptr_info.dev_ptr = 0;
  ptr_info.valid = true;
  if (PyLong_Check(obj)) {
    ptr_info.dev_ptr = PyLong_AsUnsignedLongLong(obj);
    return ptr_info;
  }
  if (obj == Py_None) {
    // valid nullptr
    return ptr_info;
  }
  PyObject *ret = PyObject_CallMethodNoArgs(obj, data_ptr_str);
  if (!ret) {
    PyErr_SetString(PyExc_TypeError, "Pointer argument must be either uint64 or have data_ptr method");
    ptr_info.valid = false;
    goto cleanup;
  }
  if (!PyLong_Check(ret)) {
    PyErr_SetString(PyExc_TypeError, "data_ptr method of Pointer object must return 64-bit int");
    ptr_info.valid = false;
    goto cleanup;
  }
  ptr_info.dev_ptr = PyLong_AsUnsignedLongLong(ret);
  if(!ptr_info.dev_ptr)
    return ptr_info;
  uint64_t dev_ptr;
  int status = cuPointerGetAttribute(&dev_ptr, CU_POINTER_ATTRIBUTE_DEVICE_POINTER, ptr_info.dev_ptr);
  if (status == CUDA_ERROR_INVALID_VALUE) {
      PyErr_Format(PyExc_ValueError,
                   "Pointer argument (at %d) cannot be accessed from Triton (cpu tensor?)", idx);
      ptr_info.valid = false;
  } else if (status != CUDA_SUCCESS) {
      CUDA_CHECK(status);  // Catch any other cuda API errors
      ptr_info.valid = false;
  }
  ptr_info.dev_ptr = dev_ptr;
cleanup:
  Py_XDECREF(ret);
  return ptr_info;

}

static inline CUtensorMap* getTmaDesc(PyObject *obj) {
  if (sizeof(CUtensorMap*) != 8) {
    PyErr_SetString(PyExc_SystemError, "getTmaDesc() requires 64-bit compilation");
    return NULL;
  }

if (Py_TYPE(obj) != (PyTypeObject*)py_tensor_map_type) {
    PyErr_Format(PyExc_TypeError, "object must be of type PyCUtensorMap, got %s", Py_TYPE(obj)->tp_name);
    return NULL;
}

  CUtensorMap* map = &((PyCUtensorMapObject*)obj)->tensorMap;
  uintptr_t align_128 = (uintptr_t)map & (128 - 1);
  if (align_128 != 0) {
    PyErr_Format(PyExc_ValueError, "CUtensorMap must be aligned to 128B, but got (&map) mod 128 = %ld", align_128);
    return NULL;
  }
  return map;
}

static void ensureCudaContext() {
  CUcontext pctx;
  CUDA_CHECK(cuCtxGetCurrent(&pctx));
  if (!pctx) {
    // Ensure device context.
    CUdevice device;
    CUDA_CHECK(cuDeviceGet(&device, 0));
    CUDA_CHECK(cuDevicePrimaryCtxRetain(&pctx, device));
    CUDA_CHECK(cuCtxSetCurrent(pctx));
  }
}

static uint16_t pack_fp16(double f) {
    uint16_t result;
    // from https://github.com/python/pythoncapi-compat
#if 0x030600B1 <= PY_VERSION_HEX && PY_VERSION_HEX <= 0x030B00A1 && !defined(PYPY_VERSION)
    _PyFloat_Pack2(f, (unsigned char*)&result, 1);
#else
    PyFloat_Pack2(f, (unsigned char*)&result, 1);
#endif
    return result;
}

static uint16_t pack_bf16(double f) {
    float f32 = (float)f;
    uint32_t u32 = *(uint32_t*)&f32;
    return (uint16_t)(u32 >> 16);
}

static uint32_t pack_fp32(double f) {
    float f32 = (float)f;
    return *(uint32_t*)&f32;
}

static uint64_t pack_fp64(double f) {
    return *(uint64_t*)&f;
}

static PyObject* launch(PyObject* self, PyObject* args) {
  // ensure cuda context is valid before calling any CUDA APIs, e.g. before getPointer calls cuPointerGetAttributes
  ensureCudaContext();

  int gridX, gridY, gridZ;
  uint64_t _stream;
  uint64_t _function;
  int launch_cooperative_grid;
  int launch_pdl;
  PyObject *launch_enter_hook = NULL;
  PyObject *launch_exit_hook = NULL;
  PyObject *kernel_metadata = NULL;
  PyObject *launch_metadata = NULL;
  PyObject *global_scratch_obj = NULL;
  PyObject *profile_scratch_obj = NULL;
  ú;z
  if(!PyArg_ParseTuple(args, "aM  ", &gridX, &gridY, &gridZ,
                                           &_stream, &_function, &launch_cooperative_grid, &launch_pdl, &global_scratch_obj, &profile_scratch_obj,
                                           &kernel_metadata, &launch_metadata,
                                           &launch_enter_hook, &launch_exit_hooka   )) {
    return NULL;
  }

  int num_warps, num_ctas, shared_memory;
  if (!PyArg_ParseTuple(kernel_metadata, "iii", &num_warps, &num_ctas, &shared_memory)) {
    PyErr_SetString(PyExc_TypeError, "kernel_metadata must be a tuple");
    return NULL;
  }

  // extract launch metadata
  if (launch_enter_hook != Py_None){
    PyObject* ret = PyObject_CallOneArg(launch_enter_hook, launch_metadata);
    if (!ret)
      return NULL;
    Py_DECREF(ret);
  }

  CUdeviceptr global_scratch = 0;
  if (global_scratch_obj != Py_None) {
    DevicePtrInfo global_scratch_info = getPointer(global_scratch_obj, -1);
    if (!global_scratch_info.valid) {
      return NULL;
    }
    global_scratch = global_scratch_info.dev_ptr;
  }

  CUdeviceptr profile_scratch = 0;
  if (profile_scratch_obj != Py_None) {
    DevicePtrInfo profile_scratch_info = getPointer(profile_scratch_obj, -1);
    if (!profile_scratch_info.valid) {
      return NULL;
    }
    profile_scratch = profile_scratch_info.dev_ptr;
  }

  // raise exception asap
  zÌ
  Py_BEGIN_ALLOW_THREADS;
  _launch(gridX, gridY, gridZ, num_warps, num_ctas, launch_cooperative_grid, launch_pdl, shared_memory, (CUstream)_stream, (CUfunction)_function, global_scratch, profile_scratchap  );
  Py_END_ALLOW_THREADS;
  if (PyErr_Occurred()) {
    return NULL;
  }

  if(launch_exit_hook != Py_None){
    PyObject* ret = PyObject_CallOneArg(launch_exit_hook, launch_metadata);
    if (!ret)
      return NULL;
    Py_DECREF(ret);
  }

  Py_RETURN_NONE;
}

static PyMethodDef ModuleMethods[] = {
  {"launch", launch, METH_VARARGS, "Entry point for all kernels with this signature"},
  {NULL, NULL, 0, NULL} // sentinel
};

static struct PyModuleDef ModuleDef = {
  PyModuleDef_HEAD_INIT,
  "__triton_launcher",
  NULL, //documentation
  -1, //size
  ModuleMethods
};

PyMODINIT_FUNC PyInit___triton_launcher(void) {
  data_ptr_str = PyUnicode_InternFromString("data_ptr");
  if(data_ptr_str == NULL) {
    return NULL;
  }
  PyObject* driver_mod = PyImport_ImportModule("triton.backends.nvidia.driver");
  if (driver_mod == NULL) {
    return NULL;
  }
  py_tensor_map_type = PyObject_GetAttrString(driver_mod, "PyCUtensorMap");
  if (py_tensor_map_type == NULL) {
    return NULL;
  }

  PyObject *m = PyModule_Create(&ModuleDef);
  if(m == NULL) {
    return NULL;
  }
  PyModule_AddFunctions(m, ModuleMethods);
  return m;
}
)ÚvaluesÚ	enumerater   Ú_BASE_ARGS_FORMATr†   ÚitemsÚFLOAT_STORAGE_TYPEr„   rt   r…   ÚFLOAT_PACK_FUNCTION)Ú	constantsr‡   r�   r‘   Úexpand_signaturer§   Úsrs   Úargs_formatÚformatÚflat_signaturerŠ   Ú	args_listÚarg_decl_listÚ	arg_declsÚinternal_args_listÚparamsÚnewlineÚ	ptr_declsÚ	tma_declsÚfloat_storage_declsrA   r�   r•   r®   s     `                   @@@r   Úmake_launcherrÉ      s  û€ ô%ôNôôñ. )¨×)9Ñ)9Ó);Ó<ÐÜ"+Ð,<Ó"=×>™$˜!˜Q��A‘Ð>€IÑ>à—'‘'°9×3CÑ3CÓ3EÖF¨R™9 R�=ÒFÓG€KÜ Ñ,€Fà€NØ×ÑÓ!ò 0ˆÙ˜3 Õ/ð0ä"+¨NÓ";×<™$˜!˜Q��A‘Ð<€IÑ<ÜPSÐT]ÓP^ÐabÒPb��t—y‘yÑ L¸)¿/¹/Ó:KÔ LÓLÒLÐhj€Ið €MØ—‘Ó"ò <‰ˆˆ2Ø�ÒØØÔ#Ñ#Ø× Ñ Ô$6°rÑ$:Ð#;¸4À¸sÐ!CÕDà× Ñ ¤I¨b£M ?°$°q°cÐ!:Õ;ð<ð —	‘	˜-Ó(€IØÐØ—‘Ó"ò 	2‰ˆˆ2Øˆa‰5�CŠ<Ø×%Ñ%¨°°°8Ð&<Õ=ØÔ%Ñ%Ø×%Ñ%¨¨Q¨C¨xÐ&8Õ9Ø�;Òà×%Ñ%¨°° nÕ5Ø�;ÓØ×%Ñ%¨¨Q¨C jÕ1ð	2ô ”3�y“>Ó"€Fð €Gð —_‘_Ó&÷áˆAˆrØˆa‰5�CŠ<ð !  Ð#5°a°S¸¸1¸#Ð=MÈaÈSÐPdÒeð€Iñ ð fo×etÑetÓev÷Ù\aÐ\]Ð_aØ�Òð ˜q˜cÐ!3°A°3°oÀaÀSÈÒWð€Iñ ð —_‘_Ó&÷áˆAˆrØÔ#Ñ#ô ˜bÑ!Ð
" %¨ s¨+Ô6IÈ"Ñ6MÐ5NÈeÐTUÐSVÐVXÒYðÐñ ð
 '0§o¡oÓ&7×M™U˜Q ¸2ÀÓ;L��Q�CŠjÐM€FÑMØ
‡M�MÐ#Ô$Ø
‡M�MÐ$Ô%ð5pôj EHð  IRó  ESð  VWò  EWð  quð  xAò  qAð  ]_ð  p`ð `Ø—y‘y Ó(Ð)ð {*ðv ‡<�<À	ÇÁÓ@Q×R±u°q¸"‘O BÓ'Ð(¨¨a¨S°Ò2ÓRÓSÐTð U Ø &˜xð (Qð R[ÐP[ð %\ðJ ‡<�<�	ÓÐð Ø
‡<�<�	ÓÐð Ø
‡<�<Ð#Ó$Ð%ð &rô [^ð  _qó  [rð  uvò  [vð  swð  z~÷  zCñ  zCð  DVó  zWò  sWð  |~ð  rð 2ð}P€Cðb
 €JùóM ?ùâFùó =ùó8ùó
ùóùó
 Nùóh Ss5   ½OÁ*O"Â7O'È)!O-É O3Ê.O9ËO?Ë#O?ÍPc              #   ó$   K  — | ]  }||f–— Œ
 y ­wr0   r2   )r   r§   s     r   r   r   \  s   è ø€ Ò:¨1  A¤Ñ:ùs   ‚é   é
   é   é	   c           
      óB  — |€L| j                   g| j                  ¢| j                  ¢| j                  dk(  ‘| j                  ¢| j                  ¢S |d   }|d   }|d   }|d   }|d   }| j                  }| j                  }|d   dk(  sJ ‚| j                  dk(  rdnd	}	|rt	        |«      }|dxx   d
z  cc<   t
        j                  j                  j                  j                  j                  | j                   j                  «       ||t        |   ||||	«      }
|
g|¢|¢S )NÚnanÚswizzleÚ	elem_sizeÚ	elem_typeÚ
block_sizeÚ
fp4_paddedr   r|   r   r}   )Úbaser�   ÚstridesÚpaddingÚlistÚtritonÚruntimeÚdriverÚactiveÚutilsrK   Údata_ptrÚTMA_DTYPE_DEVICE_TO_HOST)ÚargÚmetadatarÑ   rÒ   rÓ   rÔ   rÕ   r�   r×   rØ   Úcu_tensor_maps              r   Úmake_tensordesc_argrä   b  s2  € ØÐð —‘Ðc˜3Ÿ9™9Ðc s§{¡{Ðc°C·K±KÀ5Ñ4HÐcÈ3Ï9É9ÐcÐWZ×WbÑWbÐcÐcà�yÑ!€GØ˜Ñ%€IØ˜Ñ%€IØ˜,Ñ'€JØ˜,Ñ'€Jà�I‰I€EØ�k‰k€GØ�2‰;˜!ÒÐÐØ—;‘; %Ò'‰a¨Q€GáÜ�U“ˆØˆb‹	�Q‰‹	ä—N‘N×)Ñ)×0Ñ0×6Ñ6×JÑJØ�‰×ÑÓØØÜ  Ñ+ØØØØó	€Mð Ð,˜EÐ, GÐ,Ð,r3   c           
      óv  ‡ ‡‡— t        d„ |j                  «       D «       «      }|s‰ S t        t        |j                  «       «      D ��cg c]*  \  }}t	        |t
        «      sŒ|j                  d«      sŒ)|‘Œ, c}}«      Š‰rt        ‰«      t        ‰«      k(  sJ ‚‰sd gt        ‰«      z  Šˆ ˆˆfd„}|S c c}}w )Nc              3   ób   K  — | ]'  }t        |t        «      xr |j                  d «      –— Œ) y­w)rW   N)r   r#   rr   )r   rŠ   s     r   r   z)wrap_handle_tensordesc.<locals>.<genexpr>Š  s)   è ø€ ÒrÐX[œj¨¬cÓ2ÒS°s·~±~ÀlÓ7SÓSÑrùs   ‚-/rW   c                  óÜ   •— t        | d t         «      }d}t        | t        d  «      D ]>  \  }}|‰v r$|j                  t	        |‰|   «      «       |dz  }Œ.|j                  |«       Œ@  ‰|Ž S )Nr   r|   )rÙ   Ú_BASE_ARGS_FORMAT_LENrµ   Úextendrä   r„   )ÚargsÚ
final_argsr‰   r§   rá   ÚlauncherÚtensordesc_indicesr�   s        €€€r   Úinnerz%wrap_handle_tensordesc.<locals>.inner”  s…   ø€ Ü˜$Ð5Ô 5Ð6Ó7ˆ
ØˆÜ Ô%:Ð%;Ð <Ó=ò 	'‰FˆAˆsØÐ&Ñ&Ø×!Ñ!Ô"5°c¸?È>Ñ;ZÓ"[Ô\Ø !Ñ#‘à×!Ñ! #Õ&ð	'ñ ˜Ð$Ð$r3   )r$   r´   Úsetrµ   r   r#   rr   r†   )rì   r‡   r�   Úhas_tensor_desc_argr§   rŠ   rî   rí   s   ` `    @r   Úwrap_handle_tensordescrñ   ‰  s¬   ú€ ÜÑrÐ_h×_oÑ_oÓ_qÔrÓrÐÙØˆäÜ" 9×#3Ñ#3Ó#5Ó6×p‰vˆq�#¼*ÀSÌ#Õ:NÐSV×SaÑSaÐbnÕSoŠÓpórÐá¤# oÓ"6¼#Ð>PÓ:QÒ"QÐQÐQÙØ˜&¤3Ð'9Ó#:Ñ:ˆö	%ð €Lùó! 	qs   Á	B5
Á"B5
Á4B5
c                   ó   — e Zd Zd„ Zd„ Zy)ÚCudaLauncherc                 ó´  ‡— t        ‰d«      r‰j                  n	t        «       }ˆfd„}|j                  «       D ��ci c]  \  }} ||«      |“Œ }}}‰j                  j                  «       D ��ci c]  \  }}||“Œ
 }}}t        |dd «      }t        |||«      Št        ‰dt        «       t        t        ¬«      }	t        |dd«      | _        t        |	j                  ||«      | _        |j                  | _        |j                  | _        |j                   | _        |j"                  | _        |j$                  | _        |j&                  | _        y c c}}w c c}}w )Nrº   c                 ót   •— t        | t        «      r&‰j                  j                  j	                  | «      fS | S r0   )r   r#   ÚfnÚ	arg_namesÚindex)r”   rA   s    €r   ú<lambda>z'CudaLauncher.__init__.<locals>.<lambda>¦  s-   ø€ ¼ZÈÌ3Ô=O˜SŸV™V×-Ñ-×3Ñ3°AÓ6Ð9€ ÐUV€ r3   r�   Ú__triton_launcherr@   Únum_ctasr|   )r9   rº   Údictr·   r‡   ÚgetattrrÉ   r   r4   rC   rD   rû   rñ   ÚlaunchÚglobal_scratch_sizeÚglobal_scratch_alignÚprofile_scratch_sizeÚprofile_scratch_alignÚlaunch_cooperative_gridÚ
launch_pdl)
rL   rA   râ   rº   Úarg_idxÚidxÚvaluer‡   r�   rM   s
    `        r   rN   zCudaLauncher.__init__¤  s'  ø€ Ü%,¨S°+Ô%>�C—M’MÄDÃFˆ	ÛVˆØ;D¿?¹?Ó;L×M©Z¨S°%‘W˜S“\ 5Ñ(ÐMˆ	ÑMØ25·-±-×2EÑ2EÓ2G×H¡J C¨�S˜%‘ZÐHˆ	ÑHÜ! (Ð,=¸tÓDˆÜ˜I y°/ÓBˆÜ%ØØ$Ü%›Ü%Üô
ˆô   ¨*°aÓ8ˆŒÜ,¨S¯Z©Z¸ÀOÓTˆŒØ#+×#?Ñ#?ˆÔ Ø$,×$AÑ$AˆÔ!Ø$,×$AÑ$AˆÔ!Ø%-×%CÑ%CˆÔ"Ø'/×'GÑ'GˆÔ$Ø"×-Ñ-ˆ�ùó' NùÛHs   ¼EÁ/Ec                 ó.  ‡ ‡‡‡‡— ˆˆˆˆ ˆfd„} |‰ j                   ‰ j                  t        j                  «      } |‰ j                  ‰ j
                  t        j                  «      }	 ‰ j                  ‰‰‰‰|‰ j                  ‰ j                  ||	g	|¢­Ž  y )Nc                 óx   •— | dkD  r4‰‰z  ‰z  }|‰	j                   z  | z  }|j                  «       } |||‰
«      S y ©Nr   )rû   Úget)ÚsizeÚalignÚ	allocatorÚ	grid_sizeÚ
alloc_sizeÚalloc_fnÚgridXÚgridYÚgridZrL   Ústreams         €€€€€r   Úallocate_scratchz/CudaLauncher.__call__.<locals>.allocate_scratch¾  sH   ø€ Ø�aŠxØ! E™M¨EÑ1�	Ø&¨¯©Ñ6¸Ñ=�
Ø$Ÿ=™=›?�Ù 
¨E°6Ó:Ð:Ør3   )
rÿ   r   r   Ú
_allocatorr  r  Ú_profile_allocatorrþ   r  r  )
rL   r  r  r  r  Úfunctionrê   r  Úglobal_scratchÚprofile_scratchs
   `````     r   Ú__call__zCudaLauncher.__call__¼  sŠ   ü€ ÷	ð 	ñ *¨$×*BÑ*BÀD×D]ÑD]Ô_j×_uÑ_uÓvˆÙ*¨4×+DÑ+DÀd×F`ÑF`Ü+6×+IÑ+IóKˆàˆ�‰�E˜5 %¨°¸4×;WÑ;WÐY]×YhÑYhØ" Oð	<Ø6:ô	<r3   N)rO   rP   rQ   rN   r  r2   r3   r   ró   ró   ¢  s   „ ò.ó0<r3   ró   c                   ób   ‡ — e Zd Zˆ fd„Zd„ Zd„ Zd„ Zed„ «       Zde	de	fd„Z
d	„ Zd
„ Zd„ Zˆ xZS )Ú
CudaDriverc                 óV   •— t        «       | _        t        | _        t        ‰| �  «        y r0   )r6   rÞ   ró   Úlauncher_clsr:   rN   )rL   r=   s    €r   rN   zCudaDriver.__init__Ï  s   ø€ Ü“[ˆŒ
Ü(ˆÔÜ‰ÑÕr3   c                 ó~   — | j                  «       }| j                  |«      }|d   dz  |d   z   }d}t        d||«      S )Nr   rÌ   r|   é    Úcuda)Úget_current_deviceÚget_device_capabilityr   )rL   ÚdeviceÚ
capabilityÚ	warp_sizes       r   Úget_current_targetzCudaDriver.get_current_targetÔ  sK   € Ø×(Ñ(Ó*ˆØ×/Ñ/°Ó7ˆ
Ø ‘] RÑ'¨*°Q©-Ñ7ˆ
Øˆ	Ü˜ ¨YÓ7Ð7r3   c                 óJ   — dd l }|j                  d| j                  «       «      S )Nr   r#  )Útorchr&  r$  ©rL   r+  s     r   Úget_active_torch_devicez"CudaDriver.get_active_torch_deviceÛ  s   € ÛØ�|‰|˜F D×$;Ñ$;Ó$=Ó>Ð>r3   c                 ó"   — dd l }|j                  S r
  )r+  r#  r,  s     r   Úget_device_interfacezCudaDriver.get_device_interfaceß  s   € ÛØ�z‰zÐr3   c                  ó’   — 	 dd l } | j                  j                  «       xr | j                  j                  d u S # t
        $ r Y yw xY w)Nr   F)r+  r#  Úis_availableÚversionÚhipÚImportError)r+  s    r   Ú	is_activezCudaDriver.is_activeã  sC   € ð	ÛØ—:‘:×*Ñ*Ó,ÒL°%·-±-×2CÑ2CÀtÐ2KÐLøÜò 	Ùð	ús   ‚7: º	AÁArs   Úreturnc                 ó   — t        |«      S r0   )rt   )rL   rs   s     r   Úmap_python_to_cpp_typez!CudaDriver.map_python_to_cpp_typeë  s   € Ü˜‹}Ðr3   c                 ó   — ddl m} |S )Nr   )Údo_bench)Útriton.testingr:  )rL   r:  s     r   Úget_benchmarkerzCudaDriver.get_benchmarkerî  s
   € Ý+Øˆr3   c                 ób   — dd l }d}|j                  t        |dz  «      |j                  d¬«      S )Nr   i   é   r#  )rŒ   r&  )r+  ÚemptyÚint)rL   r+  Ú
cache_sizes      r   Úget_empty_cache_for_benchmarkz(CudaDriver.get_empty_cache_for_benchmarkò  s.   € Ûð
 'ˆ
Ø�{‰{œ3˜z¨Q™Ó/°u·y±yÈˆ{ÓPÐPr3   c                 ó$   — |j                  «        y r0   )Úzero_)rL   Úcaches     r   Úclear_cachezCudaDriver.clear_cacheû  s   € Ø�‰�r3   )rO   rP   rQ   rN   r)  r-  r/  Ústaticmethodr5  r#   r8  r<  rB  rF  rR   rS   s   @r   r  r  Í  sN   ø„ ôò
8ò?òð ñó ðð¨ð °ó òòQör3   r  ),Ú	functoolsr   r   rÚ   r€   Úpathlibr   r   Útriton.runtime.buildr   Útriton.runtimer   Útriton.backends.compilerr   Útriton.backends.driverr   r   r!   ÚrealpathÚ__file__r   rC   r1   rD   rF   Ú	lru_cacher.   r4   Úobjectr6   rt   r¸   r¹   r¶   r†   rè   rÉ   rü   r…   rà   rä   rñ   ró   r  r2   r3   r   ú<module>rR     sw  ðÛ Û 	Û Û Û 	Ý Ý Ý 8Ý &Ý .Ý ,à
�'‰'�/‰/˜"Ÿ'™'×*Ñ*¨8Ó4Ó
5€Ø—‘—‘˜W iÓ0Ð1€Ø—‘—‘˜W eÓ,€ØÐ€	Ø€ð €×ÑÓñó ðð. €×ÑÓñ,ó ð,ô;�ô ;ò:
ð4 ØØØØñÐ ð ØØØØñÐ ð $Ð ÙÐ-Ó.Ð òYñz  Ñ:±°b³	Ô:Ó:Ð Ø Ð ˜Ñ ØÐ ˜Ñ Ø Ð ˜Ñ ò$-òNô2(<�6ô (<ôV/�õ /r3   