U
    Jc                     @   s   d dl Z d dlZd dlmZ d dlmZ eejj	Z
eejjZG dd deZejejdddZdd	 Zd
d ZdddZdddZdddZdS )    N)Enumc                   @   s&   e Zd ZdZdZdZedddZdS )
DQuantTypez
    Different quantization methods for auto_quantize API are identified here.
    auto_quantize API currently supports fp16 and bfp16 methods.
    )Zfp16Zbfp16)returnc                 C   s   | j S N)value)self r   [/tmp/pip-unpacked-wheel-gikjz4vx/torch/distributed/algorithms/_quantization/quantization.py__str__   s    zDQuantType.__str__N)__name__
__module____qualname____doc__FP16BFP16strr
   r   r   r   r	   r      s   r   )tensorr   c                 C   s   t | tt S r   )torchclampTORCH_HALF_MINTORCH_HALF_MAXZhalf)r   r   r   r	   _fp32_to_fp16_with_clamp   s    r   c                 C   s\   t | tjstdt|  |tjkr0t| S |tjkrHtj	j
| S td| dd S )Nz;_quantize_tensor expecting torch.Tensor as input but found Quantization type  is not supported)
isinstancer   TensorRuntimeErrortyper   r   r   r   opsquantizationZ_FloatToBfloat16Quantized)r   qtyper   r   r	   _quantize_tensor   s    


r!   c                    sD   t | trtdd | D s.tdt|   fdd| D }|S )Nc                 s   s   | ]}t |tjV  qd S r   r   r   r   .0pr   r   r	   	<genexpr>*   s    z(_quantize_tensor_list.<locals>.<genexpr>zH_quantize_tensor_list expecting list of torch.Tensor as input but found c                    s   g | ]}t | qS r   )r!   r$   tr    r   r	   
<listcomp>0   s     z)_quantize_tensor_list.<locals>.<listcomp>r   listallr   r   )tensor_listr    Zquantized_tensor_listr   r)   r	   _quantize_tensor_list)   s    r/   c                 C   s   t | tjstdt|  |tjkrr| jtjkrHtd| j dq| jtjkrd|d krd| 	 S | 	 | S nJ|tj
kr| jtjkrtd| j dqtjj| S ntd| dd S )Nz=_dequantize_tensor expecting torch.Tensor as input but found ztensor dtype is z while expected to be FP16.r   r   )r   r   r   r   r   r   r   Zdtypefloat16floatr   r   r   Z_Bfloat16QuantizedToFloat)r   r    
quant_lossr   r   r	   _dequantize_tensor3   s*    


r3   c                    sD   t | trtdd | D s.tdt|   fdd| D }|S )Nc                 s   s   | ]}t |tjV  qd S r   r"   r#   r   r   r	   r&   O   s    z*_dequantize_tensor_list.<locals>.<genexpr>zJ_dequantize_tensor_list expecting list of torch.Tensor as input but found c                    s   g | ]}t | qS r   )r3   r'   r)   r   r	   r*   U   s     z+_dequantize_tensor_list.<locals>.<listcomp>r+   )r.   r    r2   Zdequantized_tensor_listr   r)   r	   _dequantize_tensor_listN   s    r4   c                    s   t   fdd}|S )a  
    This is a prototype API that automatically quantize the input tensors, choose the precision types, and
    pass other necessary arguments and then dequantizes the output.
    Currently it only supports:
        . FP16 and BFP16 quantization method supported for gloo and nccl backends
        . all_gather, all_to_all collective ops
    Note: BFP16 only supports 2D tensors.
    Args:
        func (Callable): A function representing collective operations.
        qtype (QuantType): Quantization method
        quant_loss (float, optional): This can be used to improve accuracy in the dequantization.
    Returns:
        (Callable): the same collective as func but enables automatic quantization/dequantization.
    c                     s  | dd }| dd}|dkr(td tjkr| d }t| d }t|}tj||||d tt|d	D ]\}}|||< qvn tjkr| d }t| d }t|}tj||||d tt|d	D ]\}}|||< qn tj	krl| d }| d
d }	| dd }
t| d }t|}tj	|||	|
|d tt
|d	D ]\}}|||< qVntd  dd S )Ngroupasync_opFTz,The async_op=True mode is not supported yet.r      )r5   r6   )r2   
out_splits	in_splits)r5   zThe collective op z is not supported yet)getr   distZ
all_gatherr!   r/   	enumerater4   Z
all_to_allZall_to_all_singler3   )argskwargsr5   r6   ZtensorsZinput_tensorsZout_tensorsir(   r8   r9   funcr    r2   r   r	   wrapperh   s@    





zauto_quantize.<locals>.wrapper)	functoolswraps)rA   r    r2   rB   r   r@   r	   auto_quantizeY   s    &rE   )N)N)N)rC   r   Ztorch.distributedZdistributedr;   enumr   Zfinfor0   minr   maxr   r   r   r   r!   r/   r3   r4   rE   r   r   r   r	   <module>   s   


