
    ǄgZ#                        d dl Z d dlmZ d dlmZmZmZmZmZm	Z	m
Z
mZm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mZ d	d
gZ edd      Z ed       G d d
ee                Zd Z ed       G d d	e             Zy)    N)
namedtuple)	AnyCallableDictIteratorListOptionalSizedTypeVarUnion)default_collate)functional_datapipe)dataframe_wrapper)IterDataPipe)_check_unpickable_fnvalidate_input_colCollatorIterDataPipeMapperIterDataPipe_T_coT)	covariantmapc                   p     e Zd ZU dZeed<   eed<   	 	 d
dededdf fdZd Zde	e
   fdZdefd	Z xZS )r   a  
    Applies a function over each item from the source DataPipe (functional name: ``map``).

    The function can be any regular Python function or partial object. Lambda
    function is not recommended as it is not supported by pickle.

    Args:
        datapipe: Source Iterable DataPipe
        fn: Function being applied over each item
        input_col: Index or indices of data which ``fn`` is applied, such as:

            - ``None`` as default to apply ``fn`` to the data directly.
            - Integer(s) is used for list/tuple.
            - Key(s) is used for dict.

        output_col: Index of data where result of ``fn`` is placed. ``output_col`` can be specified
            only when ``input_col`` is not ``None``

            - ``None`` as default to replace the index that ``input_col`` specified; For ``input_col`` with
              multiple indices, the left-most one is used, and other indices will be removed.
            - Integer is used for list/tuple. ``-1`` represents to append result at the end.
            - Key is used for dict. New key is acceptable.

    Example:
        >>> # xdoctest: +SKIP
        >>> from torchdata.datapipes.iter import IterableWrapper, Mapper
        >>> def add_one(x):
        ...     return x + 1
        >>> dp = IterableWrapper(range(10))
        >>> map_dp_1 = dp.map(add_one)  # Invocation via functional form is preferred
        >>> list(map_dp_1)
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        >>> # We discourage the usage of `lambda` functions as they are not serializable with `pickle`
        >>> # Use `functools.partial` or explicitly define the function instead
        >>> map_dp_2 = Mapper(dp, lambda x: x + 1)
        >>> list(map_dp_2)
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    datapipefnNreturnc                    t         |           || _        t        |       || _        || _        ||t        d      t        |t        t        f      rt        |      dkD  rt        d      |d   }|| _        t        ||       y )Nz3`output_col` must be None when `input_col` is None.   z3`output_col` must be a single-element list or tupler   )super__init__r   r   r   	input_col
ValueError
isinstancelisttuplelen
output_colr   )selfr   r   r    r&   	__class__s        p/home/mcse/projects/flask_80/flask-venv/lib/python3.12/site-packages/torch/utils/data/datapipes/iter/callable.pyr   zMapperIterDataPipe.__init__E   s     	 R "!7RSSj4-0:" !VWW#AJ$2y)    c                 
   | j                   | j                  | j                        S | j                   | j                        }nlt        | j                   t        t
        f      r.t        fd| j                   D              } | j                  | }n| j                  | j                            }t        t
              rd}t	              nd}| j                  et        | j                   t        t
        f      r5|| j                   d   <   t        | j                   dd  d      D ]  }|=  n@|| j                   <   n0| j                  dk(  rj                  |       n|| j                  <   |rt              S S )Nc              3   (   K   | ]	  }|     y wN ).0coldatas     r)   	<genexpr>z/MapperIterDataPipe._apply_fn.<locals>.<genexpr>c   s     =sc=s   TFr   r   )reverse)r    r&   r   r"   r#   r$   sortedappend)r'   r1   resargst_flagidxs    `    r)   	_apply_fnzMapperIterDataPipe._apply_fn\   sF   >>!doo&=774= >>!''$-Cu6=dnn==D$''4.C''$t~~./C dE"F:DF??"$..4-8*-T^^A&'!$.."4dC "CS	" (+T^^$"$C (+T__% %uT{.$.r*   c              #   T   K   | j                   D ]  }| j                  |        y wr-   )r   r;   )r'   r1   s     r)   __iter__zMapperIterDataPipe.__iter__   s(     MM 	'D..&&	's   &(c                     t        | j                  t              rt        | j                        S t	        t        |       j                   d      )Nz# instance doesn't have valid length)r"   r   r
   r%   	TypeErrortype__name__)r'   s    r)   __len__zMapperIterDataPipe.__len__   s=    dmmU+t}}%%4:..//RSTTr*   )NN)rA   
__module____qualname____doc__r   __annotations__r   r   r;   r   r   r=   intrB   __classcell__r(   s   @r)   r   r      sc    %N L ** * 
*.!/F'(5/ 'U Ur*   c                 .   t        |j                        dkD  rt        d      |d   }t        j                  |      }g }g }| j                         D ]  }||vst        d       |D ]|  }|| v rt        | |         st        d      | |   }n!	 dd lm} |j                  j                         }|j                  t        |              |||         }
|j                  |
       ~ t        d|      } || }|S # t        $ r}	t        d      |	d }	~	ww xY w)Nr   z%Only supports one DataFrame per batchr   zConversion keys missmatchz5Collate (DF)DataPipe requires callable as dict valuesz?unable to import default collation function from the TorchArrowCollateResult)r%   itemsRuntimeError
df_wrapperget_columnskeyscallabletorcharrow.pytorchpytorchrecDefault	Exceptionr6   strr   )
conversionitemdfcolumns_nametuple_namestuple_valuesnamecollation_fntapevaluetpl_clsr$   s                r)   _collate_helperrd      s7   
4::BCC	aB))"-LKL! <|#:;;<  #:Jt,-"K  &d+L0"ww0 	3t9%RX&E")#0 +6G\"EL  "Us    C::	DDDcollatec                   t     e Zd ZdZedfdedeedef   e	ee
ef   eeef   f   df   dee   ddf fdZ xZS )	r   af  
    Collates samples from DataPipe to Tensor(s) by a custom collate function (functional name: ``collate``).

    By default, it uses :func:`torch.utils.data.default_collate`.

    .. note::
        While writing a custom collate function, you can import :func:`torch.utils.data.default_collate` for the
        default behavior and `functools.partial` to specify any additional arguments.

    Args:
        datapipe: Iterable DataPipe being collated
        collate_fn: Customized collate function to collect and combine data or a batch of data.
            Default function collates to Tensor(s) based on data type.

    Example:
        >>> # xdoctest: +SKIP
        >>> # Convert integer data to float Tensor
        >>> class MyIterDataPipe(torch.utils.data.IterDataPipe):
        ...     def __init__(self, start, end):
        ...         super(MyIterDataPipe).__init__()
        ...         assert end > start, "this example code only works with end >= start"
        ...         self.start = start
        ...         self.end = end
        ...
        ...     def __iter__(self):
        ...         return iter(range(self.start, self.end))
        ...
        ...     def __len__(self):
        ...         return self.end - self.start
        ...
        >>> ds = MyIterDataPipe(start=3, end=7)
        >>> print(list(ds))
        [3, 4, 5, 6]
        >>> def collate_fn(batch):
        ...     return torch.tensor(batch, dtype=torch.float)
        ...
        >>> collated_ds = CollateIterDataPipe(ds, collate_fn=collate_fn)
        >>> print(list(collated_ds))
        [tensor(3.), tensor(4.), tensor(5.), tensor(6.)]
    Nr   rX   .
collate_fnr   c                     |t         |   ||       y t        |      rt         |   ||       y t        j                  t
        |      }t         |   ||       y )N)r   )r   r   rQ   	functoolspartialrd   )r'   r   rX   rg   r(   s       r)   r   zCollatorIterDataPipe.__init__   s]     !GX*5
# j 9 '..
K
 j 9r*   )rA   rC   rD   rE   r   r   r   r   r   r   rW   r	   r   rH   rI   s   @r)   r   r      sy    '\ )-:: S#XU38_eHcM6J%J KTQ
: X&: 
: :r*   )ri   collectionsr   typingr   r   r   r   r   r	   r
   r   r   torch.utils.data._utils.collater   %torch.utils.data.datapipes._decoratorr   $torch.utils.data.datapipes.dataframer   rN   #torch.utils.data.datapipes.datapiper   'torch.utils.data.datapipes.utils.commonr   r   __all__r   r   rd   r   r.   r*   r)   <module>rs      s     " W W W ; E P <  	4( UlUe, lU lU^(V Y<:- <:  <:r*   