o
    Ù°“i¯  ã                   @  s¬   d 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
 G dd	„ d	ƒZzdd
lZG dd„ dƒZdddd„ZW n eyI   dddd„ZY nw ddd„Zddd„Zd
S ) zStream context.é    )Úannotations)Úc_void_p)ÚAnyé   )Úcore©Údevicec                   @  s.   e Zd ZdZddd	„Zdd
d„Zddd„ZdS )ÚStreamContexta1  Represent a stream context in the FFI system.

    StreamContext helps setup ffi environment stream by python `with` statement.
    When entering `with` scope, it caches the current environment stream and
    setup the given new stream.
    When exiting `with` scope, it recovers the stream to the cached environment stream.

    Parameters
    ----------
    device
        The device to which the stream belongs.

    stream
        The stream handle.

    See Also
    --------
    :py:func:`tvm_ffi.use_raw_stream`, :py:func:`tvm_ffi.use_torch_stream`

    r   úcore.DeviceÚstreamúint | c_void_pÚreturnÚNonec                 C  s   |  ¡ | _|j| _|| _dS )z<Initialize a stream context with a device and stream handle.N)Údlpack_device_typeÚdevice_typeÚindexÚ	device_idr   )Úselfr   r   © r   úB/home/ubuntu/.local/lib/python3.10/site-packages/tvm_ffi/stream.pyÚ__init__3   s   

zStreamContext.__init__c                 C  s   t  | j| j| j¡| _| S )z-Enter the context and set the current stream.)r   Ú_env_set_current_streamr   r   r   Úprev_stream)r   r   r   r   Ú	__enter__9   s   ÿzStreamContext.__enter__Úargsr   c                 G  s   t  | j| j| j¡| _dS )z1Exit the context and restore the previous stream.N)r   r   r   r   r   ©r   r   r   r   r   Ú__exit__@   s   
ÿzStreamContext.__exit__N)r   r
   r   r   r   r   )r   r	   ©r   r   r   r   ©Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r   r	      s
    

r	   Nc                   @  s.   e Zd ZdZddd„Zddd	„Zddd„ZdS )ÚTorchStreamContextz9Context manager that syncs Torch and FFI stream contexts.Úcontextr   r   r   c                 C  s
   || _ dS )z?Initialize with an optional Torch stream/graph context wrapper.N)Útorch_context)r   r$   r   r   r   r   M   s   
zTorchStreamContext.__init__c                 C  s@   | j r| j  ¡  tj ¡ }ttt|jƒƒ|jƒ| _	| j	 ¡  | S )z)Enter both Torch and FFI stream contexts.)
r%   r   ÚtorchÚcudaÚcurrent_streamr	   r   ÚstrÚcuda_streamÚffi_context)r   r(   r   r   r   r   Q   s   

ÿ
zTorchStreamContext.__enter__r   c                 G  s"   | j r	| j j|Ž  | jj|Ž  dS )z(Exit both Torch and FFI stream contexts.N)r%   r   r+   r   r   r   r   r   \   s   zTorchStreamContext.__exit__N)r$   r   r   r   )r   r#   r   r   r   r   r   r   r#   J   s
    

r#   r$   r   r   c                 C  s   t | ƒS )a  Create an FFI stream context with a Torch stream or graph.

        cuda graph or current stream if `None` provided.

        Parameters
        ----------
        context
            The wrapped torch stream or cuda graph.

        Returns
        -------
        context
            The ffi stream context wrapping torch stream context.

        Examples
        --------
        .. code-block:: python

            s = torch.cuda.Stream()
            with tvm_ffi.use_torch_stream(torch.cuda.stream(s)):
                ...

            g = torch.cuda.CUDAGraph()
            with tvm_ffi.use_torch_stream(torch.cuda.graph(g)):
                ...

        Note
        ----
        When working with a raw ``cudaStream_t`` handle, use
        :py:func:`tvm_ffi.use_raw_stream` instead.

        )r#   ©r$   r   r   r   Úuse_torch_streamb   s   !r-   c                 C  s   t dƒ‚)z5Raise an informative error when Torch is unavailable.zCannot import torch)ÚImportErrorr,   r   r   r   r-   ‡   s   r   r
   r   r   c                 C  s    t |ttfƒstdƒ‚t| |ƒS )aÆ  Create an FFI stream context with the given device and stream handle.

    Parameters
    ----------
    device
        The device to which the stream belongs.

    stream
        The stream handle (for example, a CUDA ``cudaStream_t`` as an integer, or ``0``).

    Returns
    -------
    context
        The FFI stream context.

    Examples
    --------
    The example below uses a CPU device and a dummy stream handle. On CUDA, pass a
    real ``cudaStream_t`` integer.

    .. code-block:: python

        import tvm_ffi

        dev = tvm_ffi.device("cpu:0")
        with tvm_ffi.use_raw_stream(dev, 0):
            # Within the context, the current stream for this device is set
            assert tvm_ffi.get_raw_stream(dev) == 0

    See Also
    --------
    :py:func:`tvm_ffi.use_torch_stream`
        Use a Torch stream or CUDA graph as the source of truth.
    :py:func:`tvm_ffi.get_raw_stream`
        Query the current FFI stream for a device.

    z‚use_raw_stream only accepts int or c_void_p as stream input, try use_torch_stream when using torch.cuda.Stream or torch.cuda.graph)Ú
isinstanceÚintr   Ú
ValueErrorr	   )r   r   r   r   r   Úuse_raw_streamŒ   s
   &ÿ
r2   r0   c                 C  s   t  |  ¡ | j¡S )ap  Get the current FFI stream of a given device.

    Parameters
    ----------
    device
        The device to which the stream belongs.

    Returns
    -------
    stream
        The current FFI stream as an integer handle.

    Examples
    --------
    .. code-block:: python

        import tvm_ffi

        dev = tvm_ffi.device("cpu:0")
        # Default stream is implementation-defined; set it explicitly
        with tvm_ffi.use_raw_stream(dev, 0):
            assert tvm_ffi.get_raw_stream(dev) == 0

    See Also
    --------
    :py:func:`tvm_ffi.use_raw_stream`
        Set the current stream for a device.

    )r   Ú_env_get_current_streamr   r   r   r   r   r   Úget_raw_streamº   s   r4   )N)r$   r   r   r#   )r   r
   r   r   r   r	   )r   r
   r   r0   )r"   Ú
__future__r   Úctypesr   Útypingr   Ú r   Ú_tensorr   r	   r&   r#   r-   r.   r2   r4   r   r   r   r   Ú<module>   s    *#þ
.