o
    %ݫi^                     @   s   d Z ddlZddlmZ ddlmZ ddlmZmZ ddl	Z	eG dd dZ
G dd	 d	Zde	jfd
ee dee	j fddZdS )zThis module implements utilities and abstractions for use with
`torch.autocast`, i.e. Automatic Mixed Precision.

Authors
 * Sylvain de Langen 2023
 * Adel Moumen 2025
    N)nullcontext)	dataclass)CallableOptionalc                   @   s(   e Zd ZU dZejed< edd ZdS )	AMPConfigzConfiguration for automatic mixed precision (AMP).

    Arguments
    ---------
    dtype : torch.dtype
        The dtype to use for AMP.
    dtypec                 C   sN   |du s|dkrt tjS |dkrt tjS |dkrt tjS td| d)a8  Create an AMPConfig from a string name.

        Arguments
        ---------
        name : str
            The name of the AMPConfig to create.  Must be one of `fp32`,
            `fp16`, or `bf16`.

        Returns
        -------
        AMPConfig
            The AMPConfig corresponding to the name.
        Nfp32fp16bf16zSpecified autocast mode (z4) incorrect, expected one of `fp32`, `fp16`, `bf16`.)r   torchfloat32float16bfloat16
ValueError)selfname r   N/home/ubuntu/.local/lib/python3.10/site-packages/speechbrain/utils/autocast.py	from_name   s   



zAMPConfig.from_nameN)	__name__
__module____qualname____doc__r   r   __annotations__classmethodr   r   r   r   r   r      s
   
 
r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	TorchAutocasta  
    A context manager that conditionally enables ``torch.autocast`` for GPU operations.

    This manager wraps around ``torch.autocast`` to automatically enable autocasting when
    running on a GPU and a data type other than float32 is specified. If the desired
    data type is float32, autocasting is bypassed and the context manager behaves as a
    no-op.

    Parameters
    ----------
    *args : tuple
        Positional arguments forwarded to `torch.autocast`.
        See the PyTorch documentation: https://pytorch.org/docs/stable/amp.html#torch.autocast
    **kwargs : dict
        Keyword arguments forwarded to `torch.autocast`.
        Typically includes the `dtype` argument to specify the desired precision.
        See the PyTorch documentation for more details.
    c                 O   s:   | dtjtjk}|rtj|i || _d S t | _d S )Nr   )getr   r   autocastcontextr   )r   argskwargsenabledr   r   r   __init__L   s   zTorchAutocast.__init__c              
   C   sh   z| j  W S  ty3 } z!t| j dr.t| j dr.| j j}| j j}td| d| d| d}~ww )a  
        Enter the autocast context.

        Returns
        -------
        context
            The result of entering the underlying autocast context manager.

        Raises
        ------
        RuntimeError
            If an error occurs while entering the autocast context and the context
            provides 'device' and 'fast_dtype' attributes, a RuntimeError is raised
            with additional diagnostic information.
        device
fast_dtypez$Error during autocasting with dtype=z on device=z.
N)r   	__enter__RuntimeErrorhasattrr#   r$   )r   er#   r   r   r   r   r%   S   s    zTorchAutocast.__enter__c                 C   s   | j |||S )a  
        Exit the autocast context.

        Parameters
        ----------
        exc_type : type
            Exception type if an exception occurred, otherwise None.
        exc_val : Exception
            Exception instance if an exception occurred, otherwise None.
        exc_tb : traceback
            Traceback object if an exception occurred, otherwise None.

        Returns
        -------
        bool or None
            The result of exiting the underlying autocast context manager.
        )r   __exit__)r   exc_typeexc_valexc_tbr   r   r   r)   q   s   zTorchAutocast.__exit__N)r   r   r   r   r"   r%   r)   r   r   r   r   r   8   s
    r   fwdcast_inputsc                    sP    du rt jt|dS tjjj |dt  dddtf fdd}|S )a  Decorator for forward methods which, by default, *disables* autocast
    and casts any floating-point tensor parameters into the specified dtype
    (much like `torch.cuda.amp.custom_fwd`).

    The *wrapped forward* will gain an additional `force_allow_autocast` keyword
    parameter.
    When set to `True`, the function will ignore `cast_inputs` and will not
    disable autocast, as if this decorator was not specified.
    (Thus, modules can specify a default recommended precision, and users can
    override that behavior when desired.)

    Note that as of PyTorch 2.1.1, this will **only** affect **CUDA** AMP.
    Non-CUDA AMP will be unaffected and no input tensors will be cast!
    This usecase may be supported by this function in the future.

    When autocast is *not* active, this decorator does not change any behavior.

    Arguments
    ---------
    fwd: Optional[Callable]
        The function to wrap. If omitted, returns a partial application of the
        decorator, e.g. allowing
        `new_decorator = fwd_default_precision(cast_inputs=torch.float32)`.

        Reminder: If you are decorating a function directly, this argument is
        already specified implicitly.

    cast_inputs: Optional[torch.dtype]
        If not `None` (the default being `torch.float32`), then any
        floating-point inputs to the wrapped function will be cast to the
        specified type.

        Note: When autocasting is enabled, output tensors of autocast-compatible
        operations may be of the autocast data type.
        Disabling autocast *without* casting inputs will not change this fact,
        so lower precision operations can happen even inside of an
        autocast-disabled region, which this argument helps avoid if desired.

    Returns
    -------
    The wrapped function
    N)r.   F)force_allow_autocastr/   c                    s    | r	 |i |S |i |S )a-  Wrapped forward function from fwd_default_precision.

        Arguments
        ---------
        *args: tuple
            Arguments to be forwarded to the unwrapped function.
        force_allow_autocast: bool
            When `True`, the wrapped function will be executed directly with no
            change to the autocast context and no input casting.
        **kwargs: dict
            Arguments to be forwarded to the unwrapped function.

        Returns
        -------
        The wrapped function if force_allow_autocast, else the original
        r   )r/   r   r    r-   wrapped_fwdr   r   wrapper   s   z&fwd_default_precision.<locals>.wrapper)		functoolspartialfwd_default_precisionr   cudaamp
custom_fwdwrapsbool)r-   r.   r2   r   r0   r   r5      s   .r5   )r   r3   
contextlibr   dataclassesr   typingr   r   r   r   r   r   r   r5   r   r   r   r   <module>   s     &O