U
    hâËdQ™  ã                   @   s¤  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mZm	Z	m
Z
mZmZ d dlmZmZ d dlmZ d dlmZ d dlmZ d dlmZmZ d dlmZ d d	lmZ d d
lmZmZ d dl m!Z! d dl"m#Z# d dl$m%Z% d dl&m'Z'm(Z( d dl)m
Z* d dl+m,Z, d dl+m-Z- d dl.m/Z/ dddddddddddddd d!d"gZ0G d#d$„ d$ej1ƒZ2G d%d&„ d&e3ƒZ4G d'd(„ d(ƒZ5G d)d*„ d*eƒZ6G d+d,„ d,eƒZ7G d-d.„ d.eej1ƒZ8dS )/é    N)ÚconfigÚ	serializeÚsigutilsÚtypesÚtypingÚutils)ÚCacheÚ	CacheImpl)Úglobal_compiler_lock)Ú
Dispatcher)ÚNumbaPerformanceWarning)ÚPurposeÚtypeof)Úget_current_device)Úwrap_arg)Úcompile_cudaÚCUDACompiler)Údriver)Úget_context)Úcuda_target)Úmissing_launch_config_msgÚnormalize_kernel_dimensions)r   ©Úcuda)Ú_dispatcher)ÚwarnZhsinZhcosZhlogZhlog10Zhlog2ZhexpZhexp10Zhexp2ZhsqrtZhrsqrtZhfloorZhceilZhrcpZhrintZhtruncZhdivc                
       sø   e Zd ZdZed0‡ fdd„	ƒZedd„ ƒZed	d
„ ƒZdd„ Z	edd„ ƒZ
edd„ ƒZe‡ fdd„ƒZdd„ Zdd„ Zedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd „ ƒZd!d"„ Zd#d$„ Zd%d&„ Zd1d'd(„Zd2d*d+„Zd3d,d-„Zd.d/„ Z‡  ZS )4Ú_Kernelz„
    CUDA Kernel specialized for a given set of argument types. When called, this
    object launches the kernel on the device.
    NFTc                    s¦  |rt dƒ‚tƒ  ¡  d| _d | _|| _|| _|| _|| _|p@g | _	||
rNdnddœ}t
ƒ j}t| jtj| j| j|||||d�	}|j}| jj}|j}|j}| |j|j||||||	¡\‰ }|sÂg }dˆ  ¡ k| _| jrÜdˆ _‡ fd	d
„tD ƒ}|�r>tj�sd}d|› �}t|ƒ‚tj tj  t!¡¡}tj "|d¡}| #|¡ |D ]}ˆ  $|¡ �qB|j%| _&|j'| _'|j(| _)ˆ | _*|j+| _+|| _|j| _|j,| _,g | _-g | _.g | _/d S )Nz,Cannot compile a device function as a kernelFé   r   )ÚfastmathÚopt©ÚdebugÚlineinfoÚinliner   Únvvm_optionsÚccZcudaCGGetIntrinsicHandleTc                    s"   g | ]}d |› �ˆ   ¡ kr|‘qS )Z__numba_wrapper_)Úget_asm_str)Ú.0Úfn©Úlib© úN/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/numba/cuda/dispatcher.pyÚ
<listcomp>l   s    ÿz$_Kernel.__init__.<locals>.<listcomp>z9https://numba.readthedocs.io/en/stable/cuda/bindings.htmlz¯Use of float16 requires the use of the NVIDIA CUDA bindings and setting the NUMBA_CUDA_USE_NVIDIA_BINDING environment variable to 1. Relevant documentation is available here:
zcpp_function_wrappers.cu)0ÚRuntimeErrorÚsuperÚ__init__Z
objectmodeÚentry_pointÚpy_funcÚargtypesr!   r"   Ú
extensionsr   Úcompute_capabilityr   r   ÚvoidÚtarget_contextÚ__code__Úco_filenameÚco_firstlinenoZprepare_cuda_kernelÚlibraryÚfndescr&   ÚcooperativeZneeds_cudadevrtÚcuda_fp16_math_funcsr   ZCUDA_USE_NVIDIA_BINDINGÚNotImplementedErrorÚosÚpathÚdirnameÚabspathÚ__file__ÚjoinÚappendZadd_linking_fileÚnameÚ
entry_nameÚ	signatureÚtype_annotationÚ_type_annotationÚ_codelibraryÚcall_helperÚenvironmentÚ_referenced_environmentsZliftedZreload_init)Úselfr2   r3   Úlinkr!   r"   r#   r   r4   Zmax_registersr   Údevicer$   r%   ÚcresZtgt_ctxÚcodeÚfilenameZlinenumÚkernelÚresÚsÚmsgZbasedirZfunctions_cu_pathÚfilepath©Ú	__class__r)   r,   r0   .   s~    


þú   ý
ÿ
z_Kernel.__init__c                 C   s   | j S ©N)rL   ©rP   r+   r+   r,   r;   •   s    z_Kernel.libraryc                 C   s   | j S r]   )rK   r^   r+   r+   r,   rJ   ™   s    z_Kernel.type_annotationc                 C   s   | j S r]   )rO   r^   r+   r+   r,   Ú_find_referenced_environments�   s    z%_Kernel._find_referenced_environmentsc                 C   s
   | j  ¡ S r]   )r7   Úcodegenr^   r+   r+   r,   r`       s    z_Kernel.codegenc                 C   s   t | jjƒS r]   )ÚtuplerI   Úargsr^   r+   r+   r,   Úargument_types¤   s    z_Kernel.argument_typesc	           
         sX   |   | ¡}	t| |	ƒ ¡  d|	_||	_||	_||	_d|	_||	_||	_	||	_
||	_||	_|	S )ú&
        Rebuild an instance.
        N)Ú__new__r/   r0   r1   r=   rH   rI   rK   rL   r!   r"   rM   r4   )
Úclsr=   rG   rI   Úcodelibraryr!   r"   rM   r4   Úinstancer[   r+   r,   Ú_rebuild¨   s    
z_Kernel._rebuildc              
   C   s(   t | j| j| j| j| j| j| j| jd�S )a  
        Reduce the instance for serialization.
        Compiled definitions are serialized in PTX form.
        Type annotation are discarded.
        Thread, block and shared memory configuration are serialized.
        Stream information is discarded.
        )r=   rG   rI   rg   r!   r"   rM   r4   )	Údictr=   rH   rI   rL   r!   r"   rM   r4   r^   r+   r+   r,   Ú_reduce_states¾   s    
   ýz_Kernel._reduce_statesc                 C   s   | j  ¡  dS )z7
        Force binding to current CUDA context
        N)rL   Ú
get_cufuncr^   r+   r+   r,   ÚbindË   s    z_Kernel.bindc                 C   s   | j  ¡ jjS )zN
        The number of registers used by each thread for this kernel.
        )rL   rl   ÚattrsÚregsr^   r+   r+   r,   Úregs_per_threadÑ   s    z_Kernel.regs_per_threadc                 C   s   | j  ¡ jjS )zD
        The amount of constant memory used by this kernel.
        )rL   rl   rn   Úconstr^   r+   r+   r,   Úconst_mem_sizeØ   s    z_Kernel.const_mem_sizec                 C   s   | j  ¡ jjS )zM
        The amount of shared memory used per block for this kernel.
        )rL   rl   rn   Zsharedr^   r+   r+   r,   Úshared_mem_per_blockß   s    z_Kernel.shared_mem_per_blockc                 C   s   | j  ¡ jjS )z:
        The maximum allowable threads per block.
        )rL   rl   rn   Z
maxthreadsr^   r+   r+   r,   Úmax_threads_per_blockæ   s    z_Kernel.max_threads_per_blockc                 C   s   | j  ¡ jjS )zM
        The amount of local memory used per thread for this kernel.
        )rL   rl   rn   Úlocalr^   r+   r+   r,   Úlocal_mem_per_threadí   s    z_Kernel.local_mem_per_threadc                 C   s
   | j  ¡ S )z6
        Returns the LLVM IR for this kernel.
        )rL   Úget_llvm_strr^   r+   r+   r,   Úinspect_llvmô   s    z_Kernel.inspect_llvmc                 C   s   | j j|d�S )z7
        Returns the PTX code for this kernel.
        ©r%   )rL   r&   )rP   r%   r+   r+   r,   Úinspect_asmú   s    z_Kernel.inspect_asmc                 C   s
   | j  ¡ S )zp
        Returns the SASS code for this kernel.

        Requires nvdisasm to be available on the PATH.
        )rL   Zget_sassr^   r+   r+   r,   Úinspect_sass   s    z_Kernel.inspect_sassc                 C   sb   | j dkrtdƒ‚|dkr tj}td| j| jf |d� td|d� t| j |d� td|d� dS )úÚ
        Produce a dump of the Python source of this function annotated with the
        corresponding Numba IR and type information. The dump is written to
        *file*, or *sys.stdout* if *file* is *None*.
        Nz Type annotation is not availablez%s %s©ÚfilezP--------------------------------------------------------------------------------zP================================================================================)rK   Ú
ValueErrorÚsysÚstdoutÚprintrH   rc   )rP   r~   r+   r+   r,   Úinspect_types  s    
z_Kernel.inspect_typesr   c                 C   sH   t ƒ }| j ¡ }t|tƒr*t dd„ |¡}| |||¡}|jj	}|| S )aÕ  
        Calculates the maximum number of blocks that can be launched for this
        kernel in a cooperative grid in the current context, for the given block
        and dynamic shared memory sizes.

        :param blockdim: Block dimensions, either as a scalar for a 1D block, or
                         a tuple for 2D or 3D blocks.
        :param dynsmemsize: Dynamic shared memory size in bytes.
        :return: The maximum number of blocks in the grid.
        c                 S   s   | | S r]   r+   )ÚxÚyr+   r+   r,   Ú<lambda>(  ó    z5_Kernel.max_cooperative_grid_blocks.<locals>.<lambda>)
r   rL   rl   Ú
isinstancera   Ú	functoolsÚreduceZ$get_active_blocks_per_multiprocessorrR   ZMULTIPROCESSOR_COUNT)rP   ÚblockdimZdynsmemsizeÚctxÚcufuncZactive_per_smZsm_countr+   r+   r,   Úmax_cooperative_grid_blocks  s    

þz#_Kernel.max_cooperative_grid_blocksc                    sÊ  | j  ¡ ‰ | jrTˆ jd }ˆ j |¡\}}|t tj¡ks>t	‚t ¡ }	|j
d|d� g }
g }t| j|ƒD ]\}}|  ||||
|¡ qhtjr˜tj d¡}nd }|r¦|jp¨|}tjˆ jf|||||fžd| jiŽ | j�r´t t |	¡||¡ |	jdk�r´‡ fdd„‰‡fdd„d	D ƒ}‡fd
d„d	D ƒ}|	j}| j |¡\}}}|d k�rNd}n$|\}}}tj |¡}d|||f }d|||f }|�r¦d||d f f|dd …  }n|f}||Ž ‚|
D ]}|ƒ  �q¸d S )NZ__errcode__r   )Ústreamr=   c                    s<   ˆ j  dˆ j| f ¡\}}t ¡ }t t |¡||¡ |jS )Nz%s__%s__)	ÚmoduleÚget_global_symbolrG   ÚctypesÚc_intr   Údevice_to_hostÚ	addressofÚvalue)rG   ZmemÚszÚval)r�   r+   r,   Úload_symbolU  s    ÿÿ
z#_Kernel.launch.<locals>.load_symbolc                    s   g | ]}ˆ d | ƒ‘qS )Útidr+   ©r'   Úi©r™   r+   r,   r-   ]  s     z"_Kernel.launch.<locals>.<listcomp>Zzyxc                    s   g | ]}ˆ d | ƒ‘qS )Úctaidr+   r›   r�   r+   r,   r-   ^  s     Ú z"In function %r, file %s, line %s, z%stid=%s ctaid=%sz%s: %sé   )rL   rl   r!   rG   r�   r‘   r’   Zsizeofr“   ÚAssertionErrorZmemsetÚziprc   Ú_prepare_argsr   ÚUSE_NV_BINDINGZbindingZCUstreamÚhandleZlaunch_kernelr=   r”   r•   r–   rM   Zget_exceptionr@   rA   rC   )rP   rb   Úgriddimr‹   r�   Ú	sharedmemÚexcnameZexcmemZexcszZexcvalÚretrÚ
kernelargsÚtÚvZzero_streamZstream_handlerš   rž   rT   ZexcclsZexc_argsÚlocZlocinfoÚsymrZ   ÚlinenoÚprefixÚwbr+   )r�   r™   r,   Úlaunch/  sb    


ûú

þ
ÿz_Kernel.launchc                 C   sh  t | jƒD ]}|j||||d�\}}q
t|tjƒ�rt|ƒ ||¡}tj	}t 
d¡}	t 
d¡}
||jƒ}||jjƒ}t |¡}tjrŒt|ƒ}t 
|¡}| |	¡ | |
¡ | |¡ | |¡ | |¡ t|jƒD ]}| ||j| ƒ¡ qÒt|jƒD ]}| ||j| ƒ¡ qö�nPt|tjƒ�rBttd| ƒ|ƒ}| |¡ �n"|tjk�rtt t |¡ tj¡¡}| |¡ �nð|tjk�r˜t |¡}| |¡ �nÌ|tj k�r¼t !|¡}| |¡ �n¨|tj"k�rät #t|ƒ¡}| |¡ �n€|tj$k�r| t !|j%¡¡ | t !|j&¡¡ �nL|tj'k�rL| t |j%¡¡ | t |j&¡¡ �nt|tj(tj)fƒ�rz| t *| tj+¡¡¡ nêt|tj,ƒ�rÀt|ƒ ||¡}|j-}tj�r´t 
t|ƒ¡}| |¡ n¤t|tj.ƒ�rt/|ƒt/|ƒk�sät0‚t1||ƒD ]\}}|  2|||||¡ �qînVt|tj3ƒ�rZz|  2|j|j4|||¡ W n  t5k
�rV   t5||ƒ‚Y nX n
t5||ƒ‚dS )zF
        Convert arguments to ctypes and append to kernelargs
        )r�   r©   r   zc_%sN)6Úreversedr4   Zprepare_argsrˆ   r   ZArrayr   Z	to_devicer’   Z	c_ssize_tZc_void_pÚsizeZdtypeÚitemsizer   Zdevice_pointerr¤   ÚintrF   ÚrangeÚndimÚshapeÚstridesÚIntegerÚgetattrZfloat16Zc_uint16ÚnpÚviewZuint16Zfloat64Zc_doubleZfloat32Zc_floatÚbooleanZc_uint8Z	complex64ÚrealÚimagZ
complex128Z
NPDatetimeZNPTimedeltaZc_int64Zint64ZRecordZdevice_ctypes_pointerZ	BaseTupleÚlenr¡   r¢   r£   Z
EnumMemberr–   r?   )rP   Útyr˜   r�   r©   rª   Ú	extensionZdevaryZc_intpZmeminfoÚparentZnitemsrµ   ZptrÚdataZaxÚcvalZdevrecr«   r¬   r+   r+   r,   r£   w  s�    ü











    ÿz_Kernel._prepare_args)	NFFFFNNTF)N)r   )r   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r
   r0   Úpropertyr;   rJ   r_   r`   rc   Úclassmethodri   rk   rm   rp   rr   rs   rt   rv   rx   rz   r{   rƒ   rŽ   r²   r£   Ú__classcell__r+   r+   r[   r,   r   (   sR                þf











Hr   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚForAllc                 C   s6   |dk rt d| ƒ‚|| _|| _|| _|| _|| _d S )Nr   z0Can't create ForAll with negative task count: %s)r   Ú
dispatcherÚntasksÚthread_per_blockr�   r§   )rP   rÐ   rÑ   Útpbr�   r§   r+   r+   r,   r0   ×  s    ÿzForAll.__init__c                 G   s^   | j dkrd S | jjr| j}n| jj|Ž }|  |¡}| j | d | }|||| j| jf |Ž S )Nr   r    )rÑ   rÐ   ÚspecializedÚ
specializeÚ_compute_thread_per_blockr�   r§   )rP   rb   rÔ   r‹   r¦   r+   r+   r,   Ú__call__á  s    


ÿÿzForAll.__call__c                 C   sZ   | j }|dkr|S tƒ }tt|j ¡ ƒƒ}t|j ¡ d| j	dd�}|j
f |Ž\}}|S d S )Nr   i   )ÚfuncZb2d_funcZmemsizeZblocksizelimit)rÒ   r   ÚnextÚiterÚ	overloadsÚvaluesrj   rL   rl   r§   Zget_max_potential_block_size)rP   rÐ   rÓ   rŒ   rV   ÚkwargsÚ_r+   r+   r,   rÖ   ï  s    üz ForAll._compute_thread_per_blockN)rÈ   rÉ   rÊ   r0   r×   rÖ   r+   r+   r+   r,   rÏ   Ö  s   
rÏ   c                   @   s   e Zd Zdd„ Zdd„ ZdS )Ú_LaunchConfigurationc           	      C   sd   || _ || _|| _|| _|| _tjr`d}|d |d  |d  }||k r`d|› d�}tt|ƒƒ d S )Né€   r   r    é   z
Grid size zB will likely result in GPU under-utilization due to low occupancy.)	rÐ   r¦   r‹   r�   r§   r   ZCUDA_LOW_OCCUPANCY_WARNINGSr   r   )	rP   rÐ   r¦   r‹   r�   r§   Zmin_grid_sizeZ	grid_sizerY   r+   r+   r,   r0     s    	z_LaunchConfiguration.__init__c                 G   s   | j  || j| j| j| j¡S r]   )rÐ   Úcallr¦   r‹   r�   r§   ©rP   rb   r+   r+   r,   r×     s     ÿz_LaunchConfiguration.__call__N)rÈ   rÉ   rÊ   r0   r×   r+   r+   r+   r,   rß     s   rß   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚCUDACacheImplc                 C   s   |  ¡ S r]   )rk   )rP   rV   r+   r+   r,   rŠ   "  s    zCUDACacheImpl.reducec                 C   s   t jf |ŽS r]   )r   ri   )rP   r7   Úpayloadr+   r+   r,   Úrebuild%  s    zCUDACacheImpl.rebuildc                 C   s   dS )NTr+   )rP   rS   r+   r+   r,   Úcheck_cachable(  s    zCUDACacheImpl.check_cachableN)rÈ   rÉ   rÊ   rŠ   ræ   rç   r+   r+   r+   r,   rä   !  s   rä   c                   @   s   e Zd ZdZeZdS )Ú	CUDACachezS
    Implements a cache that saves and loads CUDA kernels and compile results.
    N)rÈ   rÉ   rÊ   rË   rä   Z_impl_classr+   r+   r+   r,   rè   3  s   rè   c                       s8  e Zd ZdZdZeZef‡ fdd„	Ze	dd„ ƒZ
dd„ Zejd	d
�d?dd„ƒZdd„ Zd@dd„Ze	dd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zdd„ Ze	dd„ ƒZdAd!d"„ZdBd#d$„ZdCd%d&„ZdDd'd(„ZdEd)d*„Zd+d,„ ZdFd-d.„Zd/d0„ Zd1d2„ Z dGd3d4„Z!dHd5d6„Z"dId7d8„Z#dJd9d:„Z$e%d;d<„ ƒZ&d=d>„ Z'‡  Z(S )KÚCUDADispatchera–  
    CUDA Dispatcher object. When configured and called, the dispatcher will
    specialize itself for the given arguments (if no suitable specialized
    version already exists) & compute capability, and launch on the device
    associated with the current context.

    Dispatcher objects are not to be constructed by the user, but instead are
    created using the :func:`numba.cuda.jit` decorator.
    Fc                    s"   t ƒ j|||d� d| _i | _d S )N)ÚtargetoptionsÚpipeline_classF)r/   r0   Ú_specializedÚspecializations)rP   r2   rê   rë   r[   r+   r,   r0   L  s
    
ÿ	zCUDADispatcher.__init__c                 C   s
   t  | ¡S r]   )Ú
cuda_typesré   r^   r+   r+   r,   Ú_numba_type_\  s    zCUDADispatcher._numba_type_c                 C   s   t | jƒ| _d S r]   )rè   r2   Ú_cacher^   r+   r+   r,   Úenable_caching`  s    zCUDADispatcher.enable_cachingrà   )Úmaxsizer   c                 C   s   t ||ƒ\}}t| ||||ƒS r]   )r   rß   )rP   r¦   r‹   r�   r§   r+   r+   r,   Ú	configurec  s    zCUDADispatcher.configurec                 C   s   t |ƒdkrtdƒ‚| j|Ž S )N)rá   r   é   z.must specify at least the griddim and blockdim)rÂ   r   ró   rã   r+   r+   r,   Ú__getitem__h  s    zCUDADispatcher.__getitem__c                 C   s   t | ||||d�S )a3  Returns a 1D-configured dispatcher for a given number of tasks.

        This assumes that:

        - the kernel maps the Global Thread ID ``cuda.grid(1)`` to tasks on a
          1-1 basis.
        - the kernel checks that the Global Thread ID is upper-bounded by
          ``ntasks``, and does nothing if it is not.

        :param ntasks: The number of tasks.
        :param tpb: The size of a block. An appropriate value is chosen if this
                    parameter is not supplied.
        :param stream: The stream on which the configured dispatcher will be
                       launched.
        :param sharedmem: The number of bytes of dynamic shared memory required
                          by the kernel.
        :return: A configured dispatcher, ready to launch on a set of
                 arguments.)rÓ   r�   r§   )rÏ   )rP   rÑ   rÓ   r�   r§   r+   r+   r,   Úforallm  s    zCUDADispatcher.forallc                 C   s   | j  d¡S )aS  
        A list of objects that must have a `prepare_args` function. When a
        specialized kernel is called, each argument will be passed through
        to the `prepare_args` (from the last object in this list to the
        first). The arguments to `prepare_args` are:

        - `ty` the numba type of the argument
        - `val` the argument value itself
        - `stream` the CUDA stream used for the current call to the kernel
        - `retr` a list of zero-arg functions that you may want to append
          post-call cleanup work to.

        The `prepare_args` function must return a tuple `(ty, val)`, which
        will be passed in turn to the next right-most `extension`. After all
        the extensions have been called, the resulting `(ty, val)` will be
        passed into Numba's default argument marshalling logic.
        r4   )rê   Úgetr^   r+   r+   r,   r4   ƒ  s    zCUDADispatcher.extensionsc                 O   s   t tƒ‚d S r]   )r   r   )rP   rb   rÝ   r+   r+   r,   r×   ˜  s    zCUDADispatcher.__call__c                 C   sB   | j rtt| j ¡ ƒƒ}ntjj| f|žŽ }| |||||¡ dS )zJ
        Compile if necessary and invoke this kernel with *args*.
        N)	rÔ   rÙ   rÚ   rÛ   rÜ   r   r   Z
_cuda_callr²   )rP   rb   r¦   r‹   r�   r§   rV   r+   r+   r,   râ   œ  s    zCUDADispatcher.callc                    s(   |rt ‚‡ fdd„|D ƒ}ˆ  t|ƒ¡S )Nc                    s   g | ]}ˆ   |¡‘qS r+   )Útypeof_pyval©r'   Úar^   r+   r,   r-   ª  s     z4CUDADispatcher._compile_for_args.<locals>.<listcomp>)r¡   Úcompilera   )rP   rb   Úkwsr3   r+   r^   r,   Ú_compile_for_args§  s    z CUDADispatcher._compile_for_argsc                 C   sN   zt |tjƒW S  tk
rH   t |¡rBt tj|dd�tjƒ Y S ‚ Y nX d S )NF)Úsync)r   r   Úargumentr   r   Zis_cuda_arrayZas_cuda_array)rP   r˜   r+   r+   r,   rø   ­  s    
ÿzCUDADispatcher.typeof_pyvalc                    s‚   t ƒ j}t‡ fdd„|D ƒƒ}ˆ jr,tdƒ‚ˆ j ||f¡}|rD|S ˆ j}tˆ j	|d�}| 
|¡ | ¡  d|_|ˆ j||f< |S )zd
        Create a new instance of this dispatcher specialized for the given
        *args*.
        c                    s   g | ]}ˆ j  |¡‘qS r+   )Z	typingctxZresolve_argument_typerù   r^   r+   r,   r-   Â  s     z-CUDADispatcher.specialize.<locals>.<listcomp>zDispatcher already specialized)rê   T)r   r5   ra   rÔ   r.   rí   r÷   rê   ré   r2   rû   Zdisable_compilerì   )rP   rb   r%   r3   Zspecializationrê   r+   r^   r,   rÕ   »  s$    ÿÿ
zCUDADispatcher.specializec                 C   s   | j S )z>
        True if the Dispatcher has been specialized.
        )rì   r^   r+   r+   r,   rÔ   Ó  s    zCUDADispatcher.specializedNc                 C   sH   |dk	r| j |j jS | jr0tt| j  ¡ ƒƒjS dd„ | j  ¡ D ƒS dS )aÑ  
        Returns the number of registers used by each thread in this kernel for
        the device in the current context.

        :param signature: The signature of the compiled kernel to get register
                          usage for. This may be omitted for a specialized
                          kernel.
        :return: The number of registers used by the compiled variant of the
                 kernel for the given signature and current device.
        Nc                 S   s   i | ]\}}||j “qS r+   )rp   ©r'   ÚsigÚoverloadr+   r+   r,   Ú
<dictcomp>ê  s   ÿ z6CUDADispatcher.get_regs_per_thread.<locals>.<dictcomp>)rÛ   rb   rp   rÔ   rÙ   rÚ   rÜ   Úitems©rP   rI   r+   r+   r,   Úget_regs_per_threadÚ  s    ÿz"CUDADispatcher.get_regs_per_threadc                 C   sH   |dk	r| j |j jS | jr0tt| j  ¡ ƒƒjS dd„ | j  ¡ D ƒS dS )aù  
        Returns the size in bytes of constant memory used by this kernel for
        the device in the current context.

        :param signature: The signature of the compiled kernel to get constant
                          memory usage for. This may be omitted for a
                          specialized kernel.
        :return: The size in bytes of constant memory allocated by the
                 compiled variant of the kernel for the given signature and
                 current device.
        Nc                 S   s   i | ]\}}||j “qS r+   )rr   r   r+   r+   r,   r  þ  s   ÿ z5CUDADispatcher.get_const_mem_size.<locals>.<dictcomp>)rÛ   rb   rr   rÔ   rÙ   rÚ   rÜ   r  r  r+   r+   r,   Úget_const_mem_sizeí  s    ÿz!CUDADispatcher.get_const_mem_sizec                 C   sH   |dk	r| j |j jS | jr0tt| j  ¡ ƒƒjS dd„ | j  ¡ D ƒS dS )aÆ  
        Returns the size in bytes of statically allocated shared memory
        for this kernel.

        :param signature: The signature of the compiled kernel to get shared
                          memory usage for. This may be omitted for a
                          specialized kernel.
        :return: The amount of shared memory allocated by the compiled variant
                 of the kernel for the given signature and current device.
        Nc                 S   s   i | ]\}}||j “qS r+   )rs   r   r+   r+   r,   r    s   ÿ z;CUDADispatcher.get_shared_mem_per_block.<locals>.<dictcomp>)rÛ   rb   rs   rÔ   rÙ   rÚ   rÜ   r  r  r+   r+   r,   Úget_shared_mem_per_block  s    ÿz'CUDADispatcher.get_shared_mem_per_blockc                 C   sH   |dk	r| j |j jS | jr0tt| j  ¡ ƒƒjS dd„ | j  ¡ D ƒS dS )a(  
        Returns the maximum allowable number of threads per block
        for this kernel. Exceeding this threshold will result in
        the kernel failing to launch.

        :param signature: The signature of the compiled kernel to get the max
                          threads per block for. This may be omitted for a
                          specialized kernel.
        :return: The maximum allowable threads per block for the compiled
                 variant of the kernel for the given signature and current
                 device.
        Nc                 S   s   i | ]\}}||j “qS r+   )rt   r   r+   r+   r,   r  &  s   ÿ z<CUDADispatcher.get_max_threads_per_block.<locals>.<dictcomp>)rÛ   rb   rt   rÔ   rÙ   rÚ   rÜ   r  r  r+   r+   r,   Úget_max_threads_per_block  s    ÿz(CUDADispatcher.get_max_threads_per_blockc                 C   sH   |dk	r| j |j jS | jr0tt| j  ¡ ƒƒjS dd„ | j  ¡ D ƒS dS )a¹  
        Returns the size in bytes of local memory per thread
        for this kernel.

        :param signature: The signature of the compiled kernel to get local
                          memory usage for. This may be omitted for a
                          specialized kernel.
        :return: The amount of local memory allocated by the compiled variant
                 of the kernel for the given signature and current device.
        Nc                 S   s   i | ]\}}||j “qS r+   )rv   r   r+   r+   r,   r  9  s   ÿ z;CUDADispatcher.get_local_mem_per_thread.<locals>.<dictcomp>)rÛ   rb   rv   rÔ   rÙ   rÚ   rÜ   r  r  r+   r+   r,   Úget_local_mem_per_thread)  s    ÿz'CUDADispatcher.get_local_mem_per_threadc                 C   sP   | j r|  t|ƒ¡ | jj}d |¡}tj||| jd�}t	 
| j¡}||||fS )zØ
        Get a typing.ConcreteTemplate for this dispatcher and the given
        *args* and *kws* types.  This allows resolution of the return type.

        A (template, pysig, args, kws) tuple is returned.
        zCallTemplate({0}))ÚkeyZ
signatures)Ú_can_compileÚcompile_devicera   r2   rÈ   Úformatr   Zmake_concrete_templateZnopython_signaturesr   Zpysignature)rP   rb   rü   Ú	func_namerG   Zcall_templateZpysigr+   r+   r,   Úget_call_template<  s    
  ÿz CUDADispatcher.get_call_templatec           
      C   s¼   || j kr®| j�– | j d¡}| j d¡}| j d¡}| j d¡}| j d¡rRdnd|dœ}tƒ j}t| j||||||||d	�	}	|	| j |< |	j 	|	j
|	j|	jg¡ W 5 Q R X n
| j | }	|	S )
zÎCompile the device function for the given argument types.

        Each signature is compiled once by caching the compiled function inside
        this object.

        Returns the `CompileResult`.
        r!   r"   r#   r   r   r   r   )r   r   r    )rÛ   Z_compiling_counterrê   r÷   r   r5   r   r2   r7   Zinsert_user_functionr1   r<   r;   )
rP   rb   Úreturn_typer!   r"   r#   r   r$   r%   rS   r+   r+   r,   r  W  s2    
þ
ú

þ
zCUDADispatcher.compile_devicec                 C   s,   dd„ |D ƒ}| j ||dd� || j|< d S )Nc                 S   s   g | ]
}|j ‘qS r+   )Ú_coderù   r+   r+   r,   r-     s     z/CUDADispatcher.add_overload.<locals>.<listcomp>Tr   )Z_insertrÛ   )rP   rV   r3   Zc_sigr+   r+   r,   Úadd_overload~  s    zCUDADispatcher.add_overloadc                 C   sØ   t  |¡\}}|dks$|tjks$t‚| jr<tt| j 	¡ ƒƒS | j 
|¡}|dk	rT|S | j || j¡}|dk	r€| j|  d7  < nH| j|  d7  < | js tdƒ‚t| j|f| jŽ}| ¡  | j ||¡ |  ||¡ |S )z
        Compile and bind to the current context a version of this kernel
        specialized for the given signature.
        Nr    zCompilation disabled)r   Znormalize_signaturer   Únoner¡   rÔ   rÙ   rÚ   rÛ   rÜ   r÷   rð   Zload_overloadZ	targetctxZ_cache_hitsZ_cache_missesr  r.   r   r2   rê   rm   Zsave_overloadr  )rP   r  r3   r  rV   r+   r+   r,   rû   ƒ  s$    zCUDADispatcher.compilec                 C   sh   | j  d¡}|dk	r8|r(| j| j ¡ S | j|  ¡ S n,|rPdd„ | j ¡ D ƒS dd„ | j ¡ D ƒS dS )zó
        Return the LLVM IR for this kernel.

        :param signature: A tuple of argument types.
        :return: The LLVM IR for the given signature, or a dict of LLVM IR
                 for all previously-encountered signatures.

        rR   Nc                 S   s   i | ]\}}||j  ¡ “qS r+   )r;   rw   r   r+   r+   r,   r  ¸  s   ÿ z/CUDADispatcher.inspect_llvm.<locals>.<dictcomp>c                 S   s   i | ]\}}||  ¡ “qS r+   )rx   r   r+   r+   r,   r  »  s   ÿ )rê   r÷   rÛ   r;   rw   rx   r  ©rP   rI   rR   r+   r+   r,   rx   §  s    	ÿÿzCUDADispatcher.inspect_llvmc                    s|   t ƒ j‰ | j d¡}|dk	rD|r2| j| j ˆ ¡S | j|  ˆ ¡S n4|r`‡ fdd„| j ¡ D ƒS ‡ fdd„| j ¡ D ƒS dS )a+  
        Return this kernel's PTX assembly code for for the device in the
        current context.

        :param signature: A tuple of argument types.
        :return: The PTX code for the given signature, or a dict of PTX codes
                 for all previously-encountered signatures.
        rR   Nc                    s   i | ]\}}||j  ˆ ¡“qS r+   )r;   r&   r   ry   r+   r,   r  Ð  s   ÿ z.CUDADispatcher.inspect_asm.<locals>.<dictcomp>c                    s   i | ]\}}||  ˆ ¡“qS r+   )rz   r   ry   r+   r,   r  Ó  s   ÿ )	r   r5   rê   r÷   rÛ   r;   r&   rz   r  r  r+   ry   r,   rz   ¾  s    	
ÿ
ÿzCUDADispatcher.inspect_asmc                 C   sB   | j  d¡rtdƒ‚|dk	r*| j|  ¡ S dd„ | j ¡ D ƒS dS )a§  
        Return this kernel's SASS assembly code for for the device in the
        current context.

        :param signature: A tuple of argument types.
        :return: The SASS code for the given signature, or a dict of SASS codes
                 for all previously-encountered signatures.

        SASS for the device in the current context is returned.

        Requires nvdisasm to be available on the PATH.
        rR   z(Cannot inspect SASS of a device functionNc                 S   s   i | ]\}}||  ¡ “qS r+   )r{   )r'   r  Údefnr+   r+   r,   r  é  s   ÿ z/CUDADispatcher.inspect_sass.<locals>.<dictcomp>)rê   r÷   r.   rÛ   r{   r  r  r+   r+   r,   r{   Ö  s    ÿzCUDADispatcher.inspect_sassc                 C   s2   |dkrt j}| j ¡ D ]\}}|j|d� qdS )r|   Nr}   )r€   r�   rÛ   r  rƒ   )rP   r~   rÞ   r  r+   r+   r,   rƒ   ì  s    zCUDADispatcher.inspect_typesc                 C   s   | ||ƒ}|S )rd   r+   )rf   r2   rê   rh   r+   r+   r,   ri   ø  s    
zCUDADispatcher._rebuildc                 C   s   t | j| jd�S )zd
        Reduce the instance for serialization.
        Compiled definitions are discarded.
        )r2   rê   )rj   r2   rê   r^   r+   r+   r,   rk      s    ÿzCUDADispatcher._reduce_states)r   r   )r   r   r   )N)N)N)N)N)N)N)N)N)N))rÈ   rÉ   rÊ   rË   Z
_fold_argsr   Ztargetdescrr   r0   rÌ   rï   rñ   r‰   Ú	lru_cacheró   rõ   rö   r4   r×   râ   rý   rø   rÕ   rÔ   r  r  r  r	  r
  r  r  r  rû   rx   rz   r{   rƒ   rÍ   ri   rk   rÎ   r+   r+   r[   r,   ré   :  sH   










'$




ré   )9Únumpyr½   r@   r€   r’   r‰   Z
numba.corer   r   r   r   r   r   Znumba.core.cachingr   r	   Znumba.core.compiler_lockr
   Znumba.core.dispatcherr   Znumba.core.errorsr   Znumba.core.typing.typeofr   r   Znumba.cuda.apir   Znumba.cuda.argsr   Znumba.cuda.compilerr   r   Znumba.cuda.cudadrvr   Znumba.cuda.cudadrv.devicesr   Znumba.cuda.descriptorr   Znumba.cuda.errorsr   r   Z
numba.cudarî   Znumbar   r   Úwarningsr   r>   ZReduceMixinr   ÚobjectrÏ   rß   rä   rè   ré   r+   r+   r+   r,   Ú<module>   s\          ø   1.