U
    yÊ¹jz  ã                   @   s¾   d dl Z ddlmZmZ ddlmZ ddlmZ dd„ Zeddd	„ iƒed
dd	„ iƒeejdœdd„ƒƒƒZ	eddd	„ iƒed
dd	„ iƒeejdœdd„ƒƒƒZ
G dd„ de jjƒZejZdS )é    Né   )Ú
heuristicsÚjit)Úlanguage©Únext_power_of_2c                 C   s   | dk rdS | dk rdS dS )Ni   é   i    é   é   © )ÚNr   r   úW/var/www/html/bwave/python/venv/lib/python3.8/site-packages/triton/ops/cross_entropy.pyÚ	num_warps   s
    r   c                 C   s   t | d ƒS ©Nr   ©r   ©Únargsr   r   r   Ú<lambda>   ó    r   ÚBLOCKc                 C   s   t | d ƒS r   r   r   r   r   r   r      r   )r   c                 C   sà   t  d¡}t  d|¡}t  || ¡}| ||  | } |||  | }	|||  | }
t j| ||k tdƒ d�}| t j¡}|t  |d¡ }t  t  	t  
|¡d¡¡| }t j|	|||k d� t  ¡  t  |
¡}t  || |¡ d S ©Nr   Úinf)ÚmaskÚother)r   )ÚtlÚ
program_idÚarangeÚloadÚfloatÚtoÚfloat32ÚmaxÚlogÚsumÚexpÚstoreZdebug_barrier)ZLOGITSÚPROBSÚIDXZLOSSr   r   ÚrowÚcolsÚidxZ
WRIT_PROBSZ
READ_PROBSÚlogitsÚprobsr   r   r   Ú_forward   s    

r-   c                 C   s   t | d ƒS r   r   r   r   r   r   r   )   r   c                 C   s   t | d ƒS r   r   r   r   r   r   r   *   r   c                 C   s¤   t  d¡}t  d|¡}t  || ¡}| ||  | } t j| ||k tdƒd� }t  | t j¡¡}||k}	t  || ¡}
||	 |
 }t j| | | j	j
¡||k d� d S r   )r   r   r   r   r   r$   r   r    r%   ÚdtypeZ
element_ty)r&   r'   ZDPROBSr   r   r(   r)   r*   r,   ÚdeltaZdoutZdinr   r   r   Ú	_backward)   s    
r0   c                   @   s$   e Zd Zedd„ ƒZedd„ ƒZdS )Ú_cross_entropyc           	         s~   |j tjkstdƒ‚ˆ jˆ j  }}ˆ jd ‰tj|||d�}tjˆ ||d�}‡ ‡fdd„}t| ˆ |||ˆƒ | ||¡ |S )Nz(Indices are expected to be of type long.éÿÿÿÿ)r.   Údevicec                    s   ˆ   ¡ ˆ fS ©N©Znumel©Úopt©r+   Ún_colsr   r   r   H   r   z(_cross_entropy.forward.<locals>.<lambda>)	r.   ÚtorchZint64ÚAssertionErrorr3   ÚshapeZ
empty_liker-   Zsave_for_backward)	ÚclsÚctxr+   Úindicesr3   r.   ÚresultÚneg_logprobsÚgridr   r8   r   Úforward>   s    
z_cross_entropy.forwardc                    s<   |j \‰}ˆjd ‰ ‡ ‡fdd„}t| ˆ||ˆ ƒ ˆdfS )a  We know d(-log(p[i])/dlogit[k] = -id_mat[i,k] + p[k]
        so we initialize the gradient as neg_logprobs, so we can just exponentiate
        to get p[k], which is most of what we need...  neg_logprobs will be
        modified in place to become the gradient we want
        r2   c                    s   ˆ  ¡ ˆ  fS r4   r5   r6   ©r9   rA   r   r   r   Z   r   z)_cross_entropy.backward.<locals>.<lambda>N)Zsaved_tensorsr<   r0   )r=   r>   Zdneg_logprobsr?   rB   r   rD   r   ÚbackwardN   s
    

z_cross_entropy.backwardN)Ú__name__Ú
__module__Ú__qualname__ÚclassmethodrC   rE   r   r   r   r   r1   =   s   
r1   )r:   Ú r   r   r   r   r   r   Z	constexprr-   r0   ZautogradÚFunctionr1   ÚapplyZcross_entropyr   r   r   r   Ú<module>   s   "