U
    ©Ê¹j1T  ã                   @   s¼   d dl Z d dlZd dlmZmZ ddlmZ e	ej
dƒshedƒej
jd< edƒej
jd< edƒej
jd< d d	lmZmZmZ d
d„ Zdd„ ZG dd„ dej
jƒZG dd„ dƒZddd„ZdS )é    N)Útree_flattenÚtree_unflattené   )Ú_dummy_typeZ_CudaStreamBaseÚ
_CUDAGraphÚ_graph_pool_handleÚ_cuda_isCurrentStreamCapturing)r   r   r   c                   C   s   t ƒ S )zÒ
    Returns True if CUDA graph capture is underway on the current CUDA stream, False otherwise.

    If a CUDA context does not exist on the current device, returns False without initializing the context.
    )r   © r	   r	   úP/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/cuda/graphs.pyÚis_current_stream_capturing   s    r   c                   C   s   t ƒ S )zß
    Returns an opaque token representing the id of a graph memory pool.
    See :ref:`Graph memory management<graph-memory-management>`.

    .. warning::
        This API is in beta and may change in future releases.
    )r   r	   r	   r	   r
   Úgraph_pool_handle$   s    r   c                       sv   e Zd ZdZ‡ fdd„Zd‡ fdd„	Z‡ fdd	„Z‡ fd
d„Z‡ fdd„Z‡ fdd„Z	‡ fdd„Z
‡ fdd„Z‡  ZS )Ú	CUDAGraphzw
    Wrapper around a CUDA graph.

    .. warning::
        This API is in beta and may change in future releases.
    c                    s   t ƒ  | ¡S ©N)ÚsuperÚ__new__)Úcls©Ú	__class__r	   r
   r   8   s    zCUDAGraph.__new__NÚglobalc                    s   t ƒ j||d� dS )aú  
        Begins capturing CUDA work on the current stream.

        Typically, you shouldn't call ``capture_begin`` yourself.
        Use :class:`~torch.cuda.graph` or :func:`~torch.cuda.make_graphed_callables`,
        which call ``capture_begin`` internally.

        Arguments:
            pool (optional): Token (returned by :func:`~torch.cuda.graph_pool_handle` or
                :meth:`other_Graph_instance.pool()<torch.cuda.CUDAGraph.pool>`) that hints this graph may share memory
                with the indicated pool.  See :ref:`Graph memory management<graph-memory-management>`.
            capture_error_mode (str, optional): specifies the cudaStreamCaptureMode for the graph capture stream.
                Can be "global", "thread_local" or "relaxed". During cuda graph capture, some actions, such as cudaMalloc,
                may be unsafe. "global" will error on actions in other threads, "thread_local" will only error for
                actions in the current thread, and "relaxed" will not error on these actions. Do NOT change this setting
                unless you're familiar with `cudaStreamCaptureMode <https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__STREAM.html#group__CUDART__STREAM_1g9d0535d93a214cbf126835257b16ba85>`_
        )ÚpoolÚcapture_error_modeN)r   Úcapture_begin)Úselfr   r   r   r	   r
   r   ;   s    zCUDAGraph.capture_beginc                    s   t ƒ  ¡  dS )aP  
        Ends CUDA graph capture on the current stream.
        After ``capture_end``, ``replay`` may be called on this instance.

        Typically, you shouldn't call ``capture_end`` yourself.
        Use :class:`~torch.cuda.graph` or :func:`~torch.cuda.make_graphed_callables`,
        which call ``capture_end`` internally.
        N)r   Úcapture_end©r   r   r	   r
   r   O   s    	zCUDAGraph.capture_endc                    s   t ƒ  ¡  dS )z?
        Replays the CUDA work captured by this graph.
        N)r   Úreplayr   r   r	   r
   r   Z   s    zCUDAGraph.replayc                    s   t ƒ  ¡  dS )zD
        Deletes the graph currently held by this instance.
        N)r   Úresetr   r   r	   r
   r   `   s    zCUDAGraph.resetc                    s
   t ƒ  ¡ S )zí
        Returns an opaque token representing the id of this graph's memory pool.
        This id can optionally be passed to another graph's ``capture_begin``,
        which hints the other graph may share the same memory pool.
        )r   r   r   r   r	   r
   r   f   s    zCUDAGraph.poolc                    s
   t ƒ  ¡ S )zB
        Enables debugging mode for CUDAGraph.debug_dump.
        )r   Úenable_debug_moder   r   r	   r
   r   n   s    zCUDAGraph.enable_debug_modec                    s   t ƒ  |¡S )zÖ
        Arguments:
            debug_path (required): Path to dump the graph to.

        Calls a debugging function to dump the graph if the debugging is
        enabled via CUDAGraph.enable_debug_mode()
        )r   Ú
debug_dump)r   Z
debug_pathr   r	   r
   r   t   s    zCUDAGraph.debug_dump)Nr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r   r   Ú__classcell__r	   r	   r   r
   r   0   s   r   c                   @   s4   e Zd ZdZdZdedœdd„Zdd„ Zd	d
„ ZdS )ÚgraphaÎ  
    Context-manager that captures CUDA work into a :class:`torch.cuda.CUDAGraph`
    object for later replay.

    See :ref:`CUDA Graphs <cuda-graph-semantics>` for a general introduction,
    detailed use, and constraints.

    Arguments:
        cuda_graph (torch.cuda.CUDAGraph): Graph object used for capture.
        pool (optional): Opaque token (returned by a call to :func:`~torch.cuda.graph_pool_handle()` or
            :meth:`other_Graph_instance.pool()<torch.cuda.CUDAGraph.pool>`) hinting this graph's capture
            may share memory from the specified pool. See :ref:`Graph memory management<graph-memory-management>`.
        stream (torch.cuda.Stream, optional): If supplied, will be set as the current stream in the context.
            If not supplied, ``graph`` sets its own internal side stream as the current stream in the context.
        capture_error_mode (str, optional): specifies the cudaStreamCaptureMode for the graph capture stream.
            Can be "global", "thread_local" or "relaxed". During cuda graph capture, some actions, such as cudaMalloc,
            may be unsafe. "global" will error on actions in other threads, "thread_local" will only error for
            actions in the current thread, and "relaxed" will not error on actions. Do NOT change this setting
            unless you're familiar with `cudaStreamCaptureMode <https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__STREAM.html#group__CUDART__STREAM_1g9d0535d93a214cbf126835257b16ba85>`_

    .. note::
        For effective memory sharing, if you pass a ``pool`` used by a previous capture and the previous capture
        used an explicit ``stream`` argument, you should pass the same ``stream`` argument to this capture.

    .. warning::
        This API is in beta and may change in future releases.

    .. _cudaStreamCaptureMode:
        https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__STREAM.html#group__CUDART__STREAM_1g9d0535d93a214cbf126835257b16ba85
    Nr   )r   c                 C   sr   | j jd krtj ¡ | j _|d kr&dn|f| _|d k	r:|n| j j| _| jd k	sRt‚tj | j¡| _	|| _
|| _d S )Nr	   )r   Údefault_capture_streamÚtorchÚcudaÚStreamr   Zcapture_streamÚAssertionErrorÚstreamÚ
stream_ctxÚ
cuda_graphr   )r   r,   r   r*   r   r	   r	   r
   Ú__init__    s    
ÿzgraph.__init__c                 C   s@   t j ¡  t ¡  t j ¡  | j ¡  | jj	| j
d| jiŽ d S )Nr   )r&   r'   ÚsynchronizeÚgcZcollectZempty_cacher+   Ú	__enter__r,   r   r   r   r   r	   r	   r
   r0   ¶   s    


ÿÿzgraph.__enter__c                 C   s   | j  ¡  | j |||¡ d S r   )r,   r   r+   Ú__exit__)r   Úexc_typeÚ	exc_valueÚ	tracebackr	   r	   r
   r1   Ä   s    
zgraph.__exit__)NNr   )	r   r    r!   r"   r%   Ústrr-   r0   r1   r	   r	   r	   r
   r$      s      ûûr$   é   Fc           %         s.  t  ¡ rt  ¡ rtdƒ‚d}t| tƒs6d}| f} |f}g ‰ t| |ƒD ]š\}}t|t jjƒrªt	|j
ƒdkr„t	|jƒdkr„t	|jƒdksŒtdƒ‚tdd„ | ¡ D ƒƒsªtdƒ‚t|ƒ\}}ˆ  t|ƒ¡ td	d„ |D ƒƒsDtd
ƒ‚qDdd„ ˆ D ƒ}	dd„ | D ƒ‰‡ ‡fdd„tt	| ƒƒD ƒ}
dd„ tt	| ƒƒD ƒ}dd„ tt	| ƒƒD ƒ}tƒ }t j ¡  t j t j ¡ ¡�„ t| ||
ƒD ]p\}}}t|ƒD ]V}t||Ž ƒ\}}t jjtdd„ |D ƒƒtdd„ |D ƒƒtdd„ |D ƒƒd|d�}�q†~~�qtW 5 Q R X t j ¡  g }g }t| ||ƒD ]T\}}}t jj||d�� ||Ž }W 5 Q R X t|ƒ\}}| t|ƒ¡ | |¡ �qg }g }tt|
ƒt|ƒt|ƒtˆƒƒD ]Ö\}}}}tdd„ |D ƒƒ}t jj||d��F t jjtdd„ |D ƒƒtdd„ |D ƒƒtdd„ |D ƒƒd|d�}W 5 Q R X g }d}|D ]0}|j�r4| || ¡ |d7 }n
| d¡ �qt|ƒ}| |¡ | |¡ �qŠtt|ƒƒ}tt|ƒƒ}dd„ } g }!t| ƒD ]ˆ\}"}| ||" ||" ˆ|" |	|" ||" |
|" ||" ||" ||" ƒ	}#t|t jjƒ�r
dd„ }$|$||j|#|j ƒ|_ |! |¡ n
|! |#¡ �qŽ|�r&|!d S t|!ƒS ) a¸  
    Accepts callables (functions or :class:`nn.Module<torch.nn.Module>`\ s)
    and returns graphed versions.

    Each graphed callable's forward pass runs its source callable's
    forward CUDA work as a CUDA graph inside a single autograd node.

    The graphed callable's forward pass also appends
    a backward node to the autograd graph. During backward, this node runs the
    callable's backward work as a CUDA graph.

    Therefore, each graphed callable should be a drop-in replacement for its source callable
    in an autograd-enabled training loop.

    See :ref:`Partial-network capture<partial-network-capture>` for detailed use and constraints.

    If you pass a tuple of several callables, their captures will use the same memory pool.
    See :ref:`Graph memory management<graph-memory-management>` for when this is appropriate.

    Arguments:
        callables (torch.nn.Module or Python function, or tuple of these): Callable or callables to graph.
            See :ref:`Graph memory management<graph-memory-management>` for when passing a tuple of callables
            is appropriate.  If you pass a tuple of callables, their order in the tuple must be the same order
            they'll run in the live workload.
        sample_args (tuple of Tensors, or tuple of tuples of Tensors): Samples args for each callable.
            If a single callable was passed, ``sample_args`` must be a single tuple of argument Tensors.
            If a tuple of callables was passed, ``sample_args`` must be tuple of tuples of argument Tensors.
        num_warmup_iters (int): The number of warmup iterations. Currently, ``DataDistributedParallel`` needs
            11 iterations for warm up. Default: ``3``.
        allow_unused_input (bool): If False, specifying inputs that were not used when computing outputs
            (and therefore their grad is always zero) is an error. Defaults to False.

    .. note::
        The ``requires_grad`` state of each Tensor in ``sample_args`` must match the state
        that's expected for the corresponding real input in the training loop.

    .. warning::
        This API is in beta and may change in future releases.

    .. warning::
        ``sample_args`` for each callable must contain only Tensors. Other types are not allowed.

    .. warning::
        Returned callables do not support higher order differentiation (e.g., double backward).

    .. warning::
        In any :class:`~torch.nn.Module` passed to :func:`~make_graphed_callables`, only parameters
        may be trainable. Buffers must have ``requires_grad=False``.

    .. warning::
        After you pass a :class:`torch.nn.Module` through :func:`~make_graphed_callables`,
        you may not add or remove any of that Module's parameters or buffers.

    .. warning::
        :class:`torch.nn.Module`\s passed to :func:`~torch.cuda.make_graphed_callables` must not have module hooks
        registered on them at the time they are passed. However, registering hooks on modules *after* passing them
        through :func:`~torch.cuda.make_graphed_callables` is allowed.

    .. warning::
        When running a graphed callable, you must pass its arguments in the same order and format
        they appeared in that callable's ``sample_args``.

    .. warning::
        The automatic mixed precision is supported in :func:`~torch.cuda.make_graphed_callables` only with disabled
        caching. The context manager `torch.cuda.amp.autocast()` must have `cache_enabled=False`.
    z_make_graphed_callables does not support the autocast caching. Please set `cache_enabled=False`.FTr   z§Modules must not have hooks registered at the time they are passed. However, registering hooks on modules after passing them through make_graphed_callables is allowed.c                 s   s   | ]}|j d kV  qdS )FN©Úrequires_grad©Ú.0Úbr	   r	   r
   Ú	<genexpr>'  s     z)make_graphed_callables.<locals>.<genexpr>zœIn any :class:`~torch.nn.Module` passed to :func:`~make_graphed_callables`, only parameters may be trainable. All buffers must have ``requires_grad=False``.c                 s   s   | ]}t |tjƒV  qd S r   )Ú
isinstancer&   ZTensor)r:   Úargr	   r	   r
   r<   .  s     zfIn the beta API, sample_args for each callable must contain only Tensors. Other types are not allowed.c                 S   s   g | ]}t |ƒ‘qS r	   )Úlen)r:   Úargsr	   r	   r
   Ú
<listcomp>5  s     z*make_graphed_callables.<locals>.<listcomp>c                 S   s*   g | ]"}t |tjjƒr"t| ¡ ƒnd ‘qS )r	   )r=   r&   ÚnnÚModuleÚtupleÚ
parameters)r:   Úcr	   r	   r
   rA   6  s   ÿc                    s   g | ]}ˆ | ˆ|  ‘qS r	   r	   ©r:   Úi©Zflatten_sample_argsZper_callable_module_paramsr	   r
   rA   :  s   ÿc                 S   s   g | ]}t j ¡ ‘qS r	   ©r&   r'   r   ©r:   Ú_r	   r	   r
   rA   ?  s     c                 S   s   g | ]}t j ¡ ‘qS r	   rJ   rK   r	   r	   r
   rA   @  s     c                 s   s   | ]}|j r|V  qd S r   r7   ©r:   Úor	   r	   r
   r<   O  s      c                 s   s   | ]}|j r|V  qd S r   r7   rG   r	   r	   r
   r<   P  s      c                 s   s   | ]}|j rt |¡V  qd S r   ©r8   r&   Z
empty_likerM   r	   r	   r
   r<   Q  s     )ÚoutputsÚinputsZgrad_outputsZonly_inputsZallow_unused)r   c                 s   s"   | ]}|j rt |¡nd V  qd S r   rO   rM   r	   r	   r
   r<   t  s    c                 s   s   | ]}|j r|V  qd S r   r7   rM   r	   r	   r
   r<   z  s      c                 s   s   | ]}|j r|V  qd S r   r7   rG   r	   r	   r
   r<   {  s      c                 s   s   | ]}|d k	r|V  qd S r   r	   rM   r	   r	   r
   r<   |  s      r   Nc	           
         s8   G ‡‡‡‡‡‡‡	fdd„dt jjƒ‰ ‡ ‡‡fdd„}	|	S )Nc                       s@   e Zd Ze‡‡‡‡fdd„ƒZeejjj‡ ‡‡fdd„ƒƒZ	dS )zOmake_graphed_callables.<locals>.make_graphed_autograd_function.<locals>.Graphedc                    s`   t ˆƒD ].}ˆ|  ¡ ||  ¡ krˆ|  || ¡ qˆ  ¡  tˆtƒsNt‚tdd„ ˆD ƒƒS )Nc                 s   s   | ]}|  ¡ V  qd S r   ©ÚdetachrM   r	   r	   r
   r<   ª  s     zjmake_graphed_callables.<locals>.make_graphed_autograd_function.<locals>.Graphed.forward.<locals>.<genexpr>)ÚrangeÚdata_ptrÚcopy_r   r=   rD   r)   )ÚctxrQ   rH   )Ú	fwd_graphÚlen_user_argsÚstatic_input_surfaceÚstatic_outputsr	   r
   Úforward¢  s    zWmake_graphed_callables.<locals>.make_graphed_autograd_function.<locals>.Graphed.forwardc                    sr   t |ƒt ˆƒkst‚tˆ|ƒD ]*\}}|d k	r| ¡ | ¡ kr| |¡ qˆ  ¡  tˆtƒs`t‚tdd„ ˆD ƒƒS )Nc                 s   s"   | ]}|d k	r|  ¡ n|V  qd S r   rR   r9   r	   r	   r
   r<   º  s    zkmake_graphed_callables.<locals>.make_graphed_autograd_function.<locals>.Graphed.backward.<locals>.<genexpr>)r?   r)   ÚziprU   rV   r   r=   rD   )rW   ZgradsÚgÚgrad)Ú	bwd_graphÚstatic_grad_inputsÚstatic_grad_outputsr	   r
   Úbackward¬  s    ÿzXmake_graphed_callables.<locals>.make_graphed_autograd_function.<locals>.Graphed.backwardN)
r   r    r!   Ústaticmethodr\   r&   ÚautogradÚfunctionZonce_differentiablerc   r	   )r`   rX   rY   ra   rb   rZ   r[   r	   r
   ÚGraphed¡  s
   	rg   c                     s(   t | ƒ\}}ˆ jt|ƒˆ Ž }t|ˆƒS r   )Ú_tree_flattenÚapplyrD   Ú_tree_unflatten)Ú	user_argsZflatten_user_argsrL   Úout)rg   Úmodule_paramsÚoutput_unflatten_specr	   r
   Úfunctionalized¾  s    zVmake_graphed_callables.<locals>.make_graphed_autograd_function.<locals>.functionalized)r&   re   ÚFunction)
rX   r`   rm   rY   rn   rZ   r[   rb   ra   ro   r	   )
rg   r`   rX   rY   rm   rn   ra   rb   rZ   r[   r
   Úmake_graphed_autograd_function–  s    $z>make_graphed_callables.<locals>.make_graphed_autograd_functionc                    s   ‡ ‡‡‡fdd„}|S )Nc                     s   ˆ j ˆkrˆ| Ž S ˆ| Ž S d S r   )Útraining)rk   ©ÚfuncÚgraph_training_stateÚgraphedÚorig_fwdr	   r
   Únew_fwdÚ  s    
zEmake_graphed_callables.<locals>.make_graphed_forward.<locals>.new_fwdr	   )rt   ru   rv   rw   rx   r	   rs   r
   Úmake_graphed_forwardÙ  s    z4make_graphed_callables.<locals>.make_graphed_forward)!r&   Zis_autocast_enabledZis_autocast_cache_enabledÚRuntimeErrorr=   rD   r]   rB   rC   r?   Z_backward_hooksZ_forward_hooksZ_forward_pre_hooksr)   ÚallÚbuffersrh   ÚappendrT   r   r'   r.   r*   r(   re   r_   r$   Úreversedr8   ÚlistÚ	enumeraterr   r\   )%Z	callablesZsample_argsZnum_warmup_itersZallow_unused_inputZjust_one_callablerF   r@   Zflatten_argrL   Zper_callable_len_user_argsZ"per_callable_static_input_surfacesZ
fwd_graphsZ
bwd_graphsZmempoolrt   rZ   rP   Zgrad_inputsZper_callable_static_outputsZ"per_callable_output_unflatten_specrX   Zflatten_outputsÚspecZ per_callable_static_grad_outputsZper_callable_static_grad_inputsr[   r`   rm   rb   ra   Zgrad_idxr>   rq   ÚretrH   rv   ry   r	   rI   r
   Úmake_graphed_callablesÊ   sî    Eÿ
ÿþýûÿÿþ
þ
  ÿÿù
	
üÿû

3÷rƒ   )r6   F)r/   r&   Ztorch.utils._pytreer   rh   r   rj   Z_utilsr   ÚhasattrZ_CÚ__dict__Ztorch._Cr   r   r   r   r   r   r$   rƒ   r	   r	   r	   r
   Ú<module>   s"   ÿ
OL   ÿ