§
    Y�’jÖ:  ã                  óª   — d Z ddlmZ ddlmZ ddlZddlmZm	Z
 erddlmZ g d¢Z G d„ d	¦  «        Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„Zddœdd„ZdS )a´  Python access to ATen's TensorIterator build pipeline.

:class:`TensorIterator` builds an iterator from a set of operands and flags
that mirror ``at::TensorIteratorConfig``, then exposes the post-build
shape / dtype / device / stride information for inspection.

This is a build-pipeline-only surface: there is no ``for_each`` here. Use it
to debug shape and dtype inference, validate custom-op contracts, or inspect
how ATen would lay out a kernel's iteration.

Construction is canonical, *not* a faithful replay of arbitrary
``TensorIteratorConfig`` call sequences. Operands are always registered in
the order ``outputs -> inputs -> const_inputs`` and setters are applied in
one fixed order. Notably:

* The C++ builder distinguishes ``add_input(a); add_const_input(b)`` from
  ``add_const_input(b); add_input(a)`` -- ``input(0)`` refers to different
  operands. This Python surface cannot express that distinction: every
  ``inputs[i]`` precedes every ``const_inputs[j]``.
* Some C++ setters have order-dependent side effects (e.g.
  ``promote_inputs_to_common_dtype(true)`` also flips
  ``check_all_same_dtype`` to ``false``). The Python surface materializes
  the *final* boolean state of each knob, not the call order, so it can't
  reproduce a sequence where an intermediate setter observed a
  since-overwritten value.

Every in-tree caller of ``at::TensorIteratorConfig`` fits the canonical-
recipe shape; the lossiness is theoretical, not practical.
é    )Úannotations)ÚTYPE_CHECKINGN)Ú_TensorIteratorÚ_TensorIteratorSpec)ÚSequence)ÚTensorIteratorÚ	binary_opÚbinary_float_opÚcomparison_opÚunary_opÚunary_float_opÚ
nullary_opÚ	reduce_opc                  ób  — e Zd ZdZdddddddddddddddddddœd=d"„Zed>d$„¦   «         Zed?d&„¦   «         Zed>d'„¦   «         Zed>d(„¦   «         Z	ed>d)„¦   «         Z
ed>d*„¦   «         Zed@d+„¦   «         Zed@d,„¦   «         ZedAd-„¦   «         ZdBd0„ZdCdBd2„ZdCdBd3„ZdCdDd5„ZdCdEd7„ZdFd8„ZdGd:„ZdHd<„ZdS )Ir   a¤  A built TensorIterator. Read-only view of the build-pipeline result.

    Constructor kwargs mirror ``at::TensorIteratorConfig``; defaults match
    the C++ defaults. See module docstring for canonical-recipe caveats.

    Examples
    --------
    Build a TI for a binary op with type promotion and inspect the result::

        >>> import torch
        >>> from torch._tensor_iterator import TensorIterator
        >>> a = torch.zeros(3, 4, dtype=torch.float32)
        >>> b = torch.zeros(3, 4, dtype=torch.float64)
        >>> it = TensorIterator(
        ...     outputs=[None],
        ...     const_inputs=[a, b],
        ...     promote_inputs_to_common_dtype=True,
        ...     cast_common_dtype_to_outputs=True,
        ... )
        >>> it.common_dtype
        torch.float64
        >>> it.numel
        12
        >>> it.ndim       # contiguous (3, 4) collapses to a single dim
        1

    Declare a static shape (the iterator skips broadcast/coalesce)::

        >>> a = torch.zeros(2, 6)
        >>> out = torch.empty(2, 6)
        >>> it = TensorIterator(
        ...     outputs=[out],
        ...     const_inputs=[a],
        ...     resize_outputs=False,
        ...     static_shape=(2, 6),
        ... )

    Build a reduction TI (output must be pre-allocated to the reduced shape)::

        >>> a = torch.zeros(3, 4)
        >>> out = torch.empty(3, 1)
        >>> it = TensorIterator(
        ...     outputs=[out],
        ...     const_inputs=[a],
        ...     resize_outputs=False,
        ...     is_reduction=True,
        ... )

    Inspect post-coalesce strides (in bytes; use ``element_strides`` for
    element units)::

        >>> a = torch.zeros(3, 4)
        >>> b = torch.zeros(3, 4)
        >>> it = TensorIterator(outputs=[None], const_inputs=[a, b])
        >>> tuple(it.strides(0))           # output byte strides
        (4,)
        >>> it.element_strides(0)          # ... in elements
        (1,)
    NTF© )ÚoutputsÚinputsÚconst_inputsÚcheck_all_same_dtypeÚcheck_all_same_deviceÚpromote_inputs_to_common_dtypeÚpromote_integer_inputs_to_floatÚcast_common_dtype_to_outputsÚenforce_safe_casting_to_outputÚenforce_linear_iterationÚresize_outputsÚcheck_mem_overlapÚallow_cpu_scalarsÚis_reductionÚstatic_dtypeÚstatic_deviceÚstatic_shapeÚsquash_dimsr   ú list[torch.Tensor | None] | Noner   úlist[torch.Tensor] | Noner   r   Úboolr   r   r   r   r   r   r   r   r   r   r    útorch.dtype | Noner!   útorch.device | Noner"   úSequence[int] | Noner#   úSequence[int]ÚreturnÚNonec               óö  — t          ¦   «         }|�t          |¦  «        ng |_        |�t          |¦  «        ng |_        |�t          |¦  «        ng |_        ||_        ||_        ||_        ||_        ||_	        |	|_
        |
|_        ||_        ||_        ||_        ||_        |�||_        |�||_        |�(t          |¦  «        |_        t          |¦  «        |_        |                     ¦   «         | _        d S ©N)Ú_CTensorIteratorSpecÚlistr   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   ÚbuildÚ_impl)Úselfr   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   Úspecs                       úDC:\Projects\DSCons\.venv\Lib\site-packages\torch\_tensor_iterator.pyÚ__init__zTensorIterator.__init__w   s  € õ, $Ñ%Ô%ˆØ(/Ð(;•t˜G‘}”}�}ÀˆŒØ&,Ð&8•d˜6‘l”l�l¸bˆŒØ2>Ð2J�D Ñ.Ô.Ð.ÐPRˆÔà$8ˆÔ!Ø%:ˆÔ"Ø.LˆÔ+Ø/NˆÔ,Ø,HˆÔ)Ø.LˆÔ+Ø(@ˆÔ%Ø,ˆÔØ!2ˆÔØ!2ˆÔØ(ˆÔàÐ#Ø ,ˆDÔØÐ$Ø!.ˆDÔØÐ#Ý $ \Ñ 2Ô 2ˆDÔÝ# KÑ0Ô0ˆDÔà'+§z¢z¡|¤|ˆŒ
ˆ
ˆ
ó    Úintc                ó   — | j         j        S r.   )r2   Úndim©r3   s    r5   r:   zTensorIterator.ndim¨   s   € àŒzŒÐr7   Ú
memoryviewc                ó   — | j         j        S )a‘  Iterator shape (post coalesce/reorder), as a zero-copy
        ``memoryview`` of ``int64`` elements. The view holds a reference
        to this iterator and keeps it alive for as long as the view is
        reachable; copy via ``tuple(it.shape)`` if you need a snapshot
        you can outlive the iterator with. Hot-path readers (dispatch
        conditionals) get index access without an allocation.)r2   Úshaper;   s    r5   r>   zTensorIterator.shape¬   s   € ð ŒzÔÐr7   c                ó   — | j         j        S r.   )r2   Únumelr;   s    r5   r@   zTensorIterator.numel¶   s   € àŒzÔÐr7   c                ó   — | j         j        S r.   )r2   Úntensorsr;   s    r5   rB   zTensorIterator.ntensorsº   ó   € àŒzÔ"Ð"r7   c                ó   — | j         j        S r.   )r2   Úninputsr;   s    r5   rE   zTensorIterator.ninputs¾   s   € àŒzÔ!Ð!r7   c                ó   — | j         j        S r.   )r2   Únoutputsr;   s    r5   rG   zTensorIterator.noutputsÂ   rC   r7   c                ó   — | j         j        S r.   )r2   Úis_contiguousr;   s    r5   rI   zTensorIterator.is_contiguousÆ   ó   € àŒzÔ'Ð'r7   c                ó   — | j         j        S r.   )r2   Úis_trivial_1dr;   s    r5   rL   zTensorIterator.is_trivial_1dÊ   rJ   r7   c                ó   — | j         j        S )aL  The inferred computation dtype, or ``None`` if no single dtype
        was inferred. Populated whenever TensorIterator can resolve a
        common dtype -- under promotion flags, or when every input
        already shares a dtype. ``None`` does not mean "promotion was
        not requested"; it means inference produced no answer.)r2   Úcommon_dtyper;   s    r5   rN   zTensorIterator.common_dtypeÎ   s   € ð ŒzÔ&Ð&r7   Úindexútorch.Tensorc                ó6   — | j                              |¦  «        S )at  Return the iterator's current operand at ``index``.

        Note: under ``promote_inputs_to_common_dtype`` /
        ``cast_common_dtype_to_outputs`` (CPU paths), this may be a
        promoted/cast kernel temporary rather than the tensor that was
        registered with the config -- it's the iterator's view of the
        operand a kernel would actually iterate over.)r2   Útensor©r3   rO   s     r5   rR   zTensorIterator.tensor×   s   € ð Œz× Ò  Ñ'Ô'Ð'r7   r   c                ó6   — | j                              |¦  «        S )zbReturn the iterator's current input. See :meth:`tensor` for the
        promoted-temporary caveat.)r2   ÚinputrS   s     r5   rU   zTensorIterator.inputá   s   € ð Œz×Ò Ñ&Ô&Ð&r7   c                ó6   — | j                              |¦  «        S )z_Return the iterator's current output. See :meth:`tensor` for the
        cast-temporary caveat.)r2   ÚoutputrS   s     r5   rW   zTensorIterator.outputæ   s   € ð Œz× Ò  Ñ'Ô'Ð'r7   útorch.dtypec                ó6   — | j                              |¦  «        S r.   )r2   ÚdtyperS   s     r5   rZ   zTensorIterator.dtypeë   s   € ØŒz×Ò Ñ&Ô&Ð&r7   útorch.devicec                ó6   — | j                              |¦  «        S r.   )r2   ÚdevicerS   s     r5   r]   zTensorIterator.deviceî   s   € ØŒz× Ò  Ñ'Ô'Ð'r7   c                ó6   — | j                              |¦  «        S )aK  Per-operand strides in bytes (post reorder/coalesce), as a
        zero-copy ``memoryview`` of ``int64`` elements. The view holds a
        reference to this iterator and keeps it alive for as long as the
        view is reachable; copy via ``tuple(it.strides(i))`` if you need
        a snapshot you can outlive the iterator with.)r2   ÚstridesrS   s     r5   r_   zTensorIterator.stridesñ   s   € ð Œz×!Ò! %Ñ(Ô(Ð(r7   útuple[int, ...]c                ó6   — | j                              |¦  «        S )zÿPer-operand strides in elements (byte stride / element size).

        Allocates a fresh tuple on every call. Don't use on a hot path:
        cache the result, or read :meth:`strides` once and divide by
        :meth:`element_size` of the operand inline.)r2   Úelement_stridesrS   s     r5   rb   zTensorIterator.element_stridesù   s   € ð Œz×)Ò)¨%Ñ0Ô0Ð0r7   Ústrc                ó*   — t          | j        ¦  «        S r.   )Úreprr2   r;   s    r5   Ú__repr__zTensorIterator.__repr__  s   € Ý�D”JÑÔÐr7   )&r   r$   r   r%   r   r%   r   r&   r   r&   r   r&   r   r&   r   r&   r   r&   r   r&   r   r&   r   r&   r   r&   r   r&   r    r'   r!   r(   r"   r)   r#   r*   r+   r,   )r+   r8   )r+   r<   )r+   r&   )r+   r'   )rO   r8   r+   rP   )r   )rO   r8   r+   rX   )rO   r8   r+   r[   )rO   r8   r+   r<   )rO   r8   r+   r`   )r+   rc   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r6   Úpropertyr:   r>   r@   rB   rE   rG   rI   rL   rN   rR   rU   rW   rZ   r]   r_   rb   rf   r   r7   r5   r   r   :   sJ  € € € € € ð:ð :ð~ 59Ø,0Ø26Ø%)Ø&*Ø/4Ø05Ø-2Ø/4Ø).Ø#Ø"&Ø"'Ø"Ø+/Ø-1Ø-1Ø%'ð)/4ð /4ð /4ð /4ð /4ð /4ðb ðð ð ñ „Xðð ð ð  ð  ñ „Xð ð ð ð  ð  ñ „Xð ð ð#ð #ð #ñ „Xð#ð ð"ð "ð "ñ „Xð"ð ð#ð #ð #ñ „Xð#ð ð(ð (ð (ñ „Xð(ð ð(ð (ð (ñ „Xð(ð ð'ð 'ð 'ñ „Xð'ð(ð (ð (ð (ð'ð 'ð 'ð 'ð 'ð
(ð (ð (ð (ð (ð
'ð 'ð 'ð 'ð 'ð(ð (ð (ð (ð (ð)ð )ð )ð )ð1ð 1ð 1ð 1ð ð  ð  ð  ð  ð  r7   r   Úoutútorch.Tensor | NoneÚarP   Úbr+   c                ó2   — t          | g||gdddd¬¦  «        S )z0Equivalent of ``at::TensorIterator::binary_op``.T)r   r   r   r   r   r   ©r   ©rl   rn   ro   s      r5   r	   r	   
  s3   € õ Ø�Ø˜�VØØ'+Ø%)Ø'+ðñ ô ð r7   c           	     ó4   — t          | g||gddddd¬¦  «        S )z6Equivalent of ``at::TensorIterator::binary_float_op``.T)r   r   r   r   r   r   r   rq   rr   s      r5   r
   r
     s6   € õ Ø�Ø˜�VØØ'+Ø%)Ø'+Ø(,ðñ ô ð r7   c                ó„   — | €t           j        nd}| duo| j        t           j        k    }t          | g||gdd||¬¦  «        S )aH  Equivalent of ``at::TensorIterator::comparison_op``.

    When ``out`` is ``None``, the output dtype is forced to bool. When ``out``
    is a defined non-bool tensor, the common dtype is cast back to its dtype
    via ``cast_common_dtype_to_outputs``. The bool-output case skips that cast
    as a performance optimization.
    NT)r   r   r   r   r   r    )Útorchr&   rZ   r   )rl   rn   ro   r    Úcast_to_outputss        r5   r   r   '  sY   € ð "% •5”:�:°$€LØ �oÐA¨#¬)µu´zÒ*A€OÝØ�Ø˜�VØØ'+Ø%4Ø!ðñ ô ð r7   c                ó(   — t          | g|g¬¦  «        S )z/Equivalent of ``at::TensorIterator::unary_op``.)r   r   rq   ©rl   rn   s     r5   r   r   =  s   € å 3 %°q°cÐ:Ñ:Ô:Ð:r7   c                ó0   — t          | g|gdddd¬¦  «        S )z5Equivalent of ``at::TensorIterator::unary_float_op``.T)r   r   r   r   r   r   rq   rx   s     r5   r   r   B  s/   € åØ�Ø�SØ'+Ø%)Ø'+Ø(,ðñ ô ð r7   c                óJ   — | €t          d¦  «        ‚t          | gdd¬¦  «        S )z¼Equivalent of ``at::TensorIterator::nullary_op``.

    Unlike the binary/unary factories, ``out`` must be a defined tensor;
    the C++ named constructor takes a non-undefined output.
    NzAnullary_op requires a defined output tensor; None is not allowed.F)r   r   r   )Ú	TypeErrorr   )rl   s    r5   r   r   N  sB   € ð €{ÝØOñ
ô 
ð 	
õ Ø�Ø"Øðñ ô ð r7   )Úout2r|   c               óH  — |��	| j         |j         cxk    r|j         k    s)n t          d| j         › d|j         › d|j         › �¦  «        ‚|                      ¦   «         |                     ¦   «         k    r9t          d|                      ¦   «         › d|                     ¦   «         › �¦  «        ‚| j        |j        k    s*|                      ¦   «         |                     ¦   «         k    rt          d¦  «        ‚t          | |g|gdddd	¬
¦  «        S t          | g|gd	ddd	¬¦  «        S )a½  Equivalent of ``at::TensorIterator::reduce_op``.

    Pass ``out2`` for the two-output reduction overload (e.g. ``min`` returning
    values + indices). The output tensor(s) must be pre-allocated and shaped
    correctly: this factory does not allocate or resize. With ``out2``, both
    outputs must live on ``a``'s device and share its sizes/strides -- the
    C++ named constructor asserts this and the same checks are mirrored
    here.
    NzAreduce_op: out, out2, and the input must share a device, got out=z, out2=z, a=z4reduce_op: out and out2 must have the same dim, got z and z=reduce_op: out and out2 must have identical sizes and stridesFT)r   r   r   r   r   r   )r   r   r   r   r   r   )r]   ÚRuntimeErrorÚdimr>   Ústrider   )rl   rn   r|   s      r5   r   r   _  sx  € ð( ÑØŒz˜QœXÐ4Ð4Ò4Ð4¨¬Ò4Ð4Ð4Ð4ÝðJØœ:ðJð JØ.2¬kðJð JØ?@¼xðJð Jñô ð ð �7Š7‰9Œ9˜Ÿš™
œ
Ò"Ð"Ýð0Ø—7’7‘9”9ð0ð 0Ø#'§8¢8¡:¤:ð0ð 0ñô ð ð Œ9˜œ
Ò"Ð" c§j¢j¡l¤l°d·k²k±m´mÒ&CÐ&CÝØOñô ð õ Ø˜$�KØ˜Ø!&Ø Ø#Øð
ñ 
ô 
ð 	
õ Ø�Ø�SØ'+ØØØðñ ô ð r7   )rl   rm   rn   rP   ro   rP   r+   r   )rl   rm   rn   rP   r+   r   )rl   rP   r+   r   )rl   rP   rn   rP   r|   rm   r+   r   )rj   Ú
__future__r   Útypingr   ru   Útorch._Cr   Ú_CTensorIteratorr   r/   Úcollections.abcr   Ú__all__r   r	   r
   r   r   r   r   r   r   r7   r5   ú<module>r‡      si  ððð ð< #Ð "Ð "Ð "Ð "Ð "à  Ð  Ð  Ð  Ð  Ð  à €€€ðð ð ð ð ð ð ð ð ð )Ø(Ð(Ð(Ð(Ð(Ð(ð	ð 	ð 	€ðH ð H ð H ð H ð H ñ H ô H ð H ð`ð ð ð ðð ð ð ðð ð ð ð,;ð ;ð ;ð ;ð
	ð 	ð 	ð 	ðð ð ð ð* !%ð	2ð 2ð 2ð 2ð 2ð 2ð 2ð 2r7   