U
    hâËd  ã                   @   sè   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lmZ d dlmZ d	d
„ Zedd„ ƒZedd„ ƒZedd„ ƒZee e¡ddd�dd„ ƒZedd„ ƒZdd„ Zedd„ ƒZedd„ ƒZedd„ ƒZd S )!é    )Úir)ÚcudaÚtypes)Úcgutils)ÚRequireLiteralValue)Ú	signature)Úoverload_attribute)Ú	nvvmutils)Ú	intrinsicc                 C   sB   | j }|dkrtj}n |dkr.t tj|¡}ntdƒ‚t|tjƒS )Né   )é   é   zargument can only be 1, 2, 3)Zliteral_valuer   Úint32ÚUniTupleÚ
ValueErrorr   )ÚndimÚvalÚrestype© r   úN/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/numba/cuda/intrinsics.pyÚ_type_grid_function   s    r   c                 C   s,   t |tjƒst|ƒ‚t|ƒ}dd„ }||fS )a  grid(ndim)

    Return the absolute position of the current thread in the entire grid of
    blocks.  *ndim* should correspond to the number of dimensions declared when
    instantiating the kernel. If *ndim* is 1, a single integer is returned.
    If *ndim* is 2 or 3, a tuple of the given number of integers is returned.

    Computation of the first integer is as follows::

        cuda.threadIdx.x + cuda.blockIdx.x * cuda.blockDim.x

    and is similar for the other two indices, but using the ``y`` and ``z``
    attributes.
    c                 S   sJ   |j }|tjkrtj|dd�S t|tjƒrFtj||jd�}t 	||¡S d S )Nr   )Údim)
Úreturn_typer   r   r	   Zget_global_idÚ
isinstancer   Úcountr   Ú
pack_array)ÚcontextÚbuilderÚsigÚargsr   Zidsr   r   r   Úcodegen1   s    
zgrid.<locals>.codegen©r   r   ZIntegerLiteralr   r   ©Ú	typingctxr   r   r    r   r   r   Úgrid   s
    r$   c                    s8   t |tjƒst|ƒ‚t|ƒ}dd„ ‰ ‡ fdd„}||fS )a  gridsize(ndim)

    Return the absolute size (or shape) in threads of the entire grid of
    blocks. *ndim* should correspond to the number of dimensions declared when
    instantiating the kernel. If *ndim* is 1, a single integer is returned.
    If *ndim* is 2 or 3, a tuple of the given number of integers is returned.

    Computation of the first integer is as follows::

        cuda.blockDim.x * cuda.gridDim.x

    and is similar for the other two indices, but using the ``y`` and ``z``
    attributes.
    c                 S   s0   t  | d|› �¡}t  | d|› �¡}|  ||¡S )Nzntid.znctaid.)r	   Ú	call_sregÚmul)r   r   ZntidZnctaidr   r   r   Ú_nthreads_for_dimR   s    z#gridsize.<locals>._nthreads_for_dimc                    sx   |j }ˆ |dƒ}|tjkr|S t|tjƒrtˆ |dƒ}|jdkrNt |||f¡S |jdkrtˆ |dƒ}t ||||f¡S d S )NÚxÚyr   r   Úz)r   r   r   r   r   r   r   r   )r   r   r   r   r   ÚnxÚnyZnz©r'   r   r   r    W   s    





zgridsize.<locals>.codegenr!   r"   r   r-   r   Úgridsize<   s    r.   c                 C   s   t tjƒ}dd„ }||fS )Nc                 S   s   t  |d¡S )NÚwarpsize)r	   r%   )r   r   r   r   r   r   r   r    m   s    z_warpsize.<locals>.codegen)r   r   r   ©r#   r   r    r   r   r   Ú	_warpsizei   s    
r1   r/   r   )Útargetc                 C   s   dd„ }|S )z_
    The size of a warp. All architectures implemented to date have a warp size
    of 32.
    c                 S   s   t ƒ S )N)r1   )Úmodr   r   r   Úgety   s    zcuda_warpsize.<locals>.getr   )r3   r4   r   r   r   Úcuda_warpsizes   s    r5   c                 C   s   t tjƒ}dd„ }||fS )a  
    Synchronize all threads in the same thread block.  This function implements
    the same pattern as barriers in traditional multi-threaded programming: this
    function waits until all threads in the block call it, at which point it
    returns control to all its callers.
    c                 S   s<   d}|j }t t ¡ d¡}t |||¡}| |d¡ |  ¡ S )Nzllvm.nvvm.barrier0r   )Úmoduler   ÚFunctionTypeZVoidTyper   Úget_or_insert_functionÚcallZget_dummy_value)r   r   r   r   ÚfnameZlmodÚfntyÚsyncr   r   r   r    ‹   s    zsyncthreads.<locals>.codegen)r   r   Únoner0   r   r   r   Úsyncthreads�   s    
r>   c                    s2   t |tjƒsd S ttjtjƒ}‡ fdd„}||fS )Nc                    s6   t  t  d¡t  d¡f¡}t |j|ˆ ¡}| ||¡S )Né    )r   r7   ZIntTyper   r8   r6   r9   )r   r   r   r   r;   r<   ©r:   r   r   r    œ   s    z'_syncthreads_predicate.<locals>.codegen)r   r   ÚIntegerr   Úi4)r#   Ú	predicater:   r   r    r   r@   r   Ú_syncthreads_predicate–   s
    rD   c                 C   s   d}t | ||ƒS )z 
    syncthreads_count(predicate)

    An extension to numba.cuda.syncthreads where the return value is a count
    of the threads where predicate is true.
    zllvm.nvvm.barrier0.popc©rD   ©r#   rC   r:   r   r   r   Úsyncthreads_count¤   s    rG   c                 C   s   d}t | ||ƒS )z�
    syncthreads_and(predicate)

    An extension to numba.cuda.syncthreads where 1 is returned if predicate is
    true for all threads or 0 otherwise.
    zllvm.nvvm.barrier0.andrE   rF   r   r   r   Úsyncthreads_and°   s    rH   c                 C   s   d}t | ||ƒS )z›
    syncthreads_or(predicate)

    An extension to numba.cuda.syncthreads where 1 is returned if predicate is
    true for any thread or 0 otherwise.
    zllvm.nvvm.barrier0.orrE   rF   r   r   r   Úsyncthreads_or¼   s    rI   N)Zllvmliter   Znumbar   r   Z
numba.corer   Znumba.core.errorsr   Znumba.core.typingr   Znumba.core.extendingr   Z
numba.cudar	   Znumba.cuda.extendingr
   r   r$   r.   r1   ÚModuler5   r>   rD   rG   rH   rI   r   r   r   r   Ú<module>   s2   
 
,
	



