o
    ci                     @   s   d dl mZ d dlmZ d dlmZmZ eG dd dZdedefdd	Z	ded
edefddZ
dedededefddZdS )    )List)OldAPIStack)
TensorTypeTensorStructTypec                   @   sb   e Zd ZdZdedee defddZdeee  fdd	Zdee fd
dZ	dd Z
dd ZdS )RepeatedValuesa  Represents a variable-length list of items from spaces.Repeated.

    RepeatedValues are created when you use spaces.Repeated, and are
    accessible as part of input_dict["obs"] in ModelV2 forward functions.

    Example:
        Suppose the gym space definition was:
            Repeated(Repeated(Box(K), N), M)

        Then in the model forward function, input_dict["obs"] is of type:
            RepeatedValues(RepeatedValues(<Tensor shape=(B, M, N, K)>))

        The tensor is accessible via:
            input_dict["obs"].values.values

        And the actual data lengths via:
            # outer repetition, shape [B], range [0, M]
            input_dict["obs"].lengths
                -and-
            # inner repetition, shape [B, M], range [0, N]
            input_dict["obs"].values.lengths

    Attributes:
        values: The padded data tensor of shape [B, max_len, ..., sz],
            where B is the batch dimension, max_len is the max length of this
            list, followed by any number of sub list max lens, followed by the
            actual data size.
        lengths (List[int]): Tensor of shape [B, ...] that represents the
            number of valid items in each list. When the list is nested within
            other lists, there will be extra dimensions for the parent list
            max lens.
        max_len: The max number of items allowed in each list.

    TODO(ekl): support conversion to tf.RaggedTensor.
    valueslengthsmax_lenc                 C   s   || _ || _|| _d | _d S N)r   r   r	   _unbatched_repr)selfr   r   r	    r   T/home/ubuntu/.local/lib/python3.10/site-packages/ray/rllib/models/repeated_values.py__init__-   s   
zRepeatedValues.__init__returnc                 C   s   | j du rXt| j}|du rtdt|}|  }g }t|D ]4}t| j| dr4t| j| 	 }n	t| j| 
 }g }t|D ]}|t||| qC|| q || _ | j S )a  Unbatch both the repeat and batch dimensions into Python lists.

        This is only supported in PyTorch / TF eager mode.

        This lets you view the data unbatched in its original form, but is
        not efficient for processing.

        .. testcode::
            :skipif: True

            batch = RepeatedValues(<Tensor shape=(B, N, K)>)
            items = batch.unbatch_all()
            print(len(items) == B)

        .. testoutput::

            True

        .. testcode::
            :skipif: True

            print(max(len(x) for x in items) <= N)

        .. testoutput::

            True

        .. testcode::
            :skipif: True

            print(items)

        .. testoutput::

            [[<Tensor_1 shape=(K)>, ..., <Tensor_N, shape=(K)>],
             ...
             [<Tensor_1 shape=(K)>, <Tensor_2 shape=(K)>],
             ...
             [<Tensor_1 shape=(K)>],
             ...
             [<Tensor_1 shape=(K)>, ..., <Tensor_N shape=(K)>]]
        NzjCannot call unbatch_all() when batch_dim is unknown. This is probably because you are using TF graph mode.item)r   _get_batch_dim_helperr   
ValueErrorintunbatch_repeat_dimrangehasattrr   r   numpyappend_batch_index_helper)r   Bslicesresultidynamic_lendynamic_slicejr   r   r   unbatch_all3   s&   
,
zRepeatedValues.unbatch_allc                 C   s   t | j| jS )ak  Unbatches the repeat dimension (the one `max_len` in size).

        This removes the repeat dimension. The result will be a Python list of
        with length `self.max_len`. Note that the data is still padded.

        .. testcode::
            :skipif: True

            batch = RepeatedValues(<Tensor shape=(B, N, K)>)
            items = batch.unbatch()
            len(items) == batch.max_len

        .. testoutput::

            True

        .. testcode::
            :skipif: True

            print(items)

        .. testoutput::

            [<Tensor_1 shape=(B, K)>, ..., <Tensor_N shape=(B, K)>]
        )_unbatch_helperr   r	   r   r   r   r   r   w   s   z!RepeatedValues.unbatch_repeat_dimc                 C   s   d t| jt| j| jS )Nz0RepeatedValues(value={}, lengths={}, max_len={}))formatreprr   r   r	   r$   r   r   r   __repr__   s   zRepeatedValues.__repr__c                 C   s   t | S r
   )r&   r$   r   r   r   __str__   s   zRepeatedValues.__str__N)__name__
__module____qualname____doc__r   r   r   r   r"   r   r'   r(   r   r   r   r   r      s    $Dr   vr   c                 C   sn   t | tr|  D ]}t|  S dS t | trt| d S t | tr(t| jS | jd }t|dr5|j}|S )z5Tries to find the batch dimension size of v, or None.r   valueN)	
isinstancedictr   r   tupler   shaper   r.   )r-   ur   r   r   r   r      s   





r   r	   c                    s   t tr fdd D S t tr t fddD S t tr6tj }fddt|D S fddt D S )z3Recursively unpacks the repeat dimension (max_len).c                    s   i | ]
\}}|t | qS r   r#   .0kr3   r	   r   r   
<dictcomp>   s    z#_unbatch_helper.<locals>.<dictcomp>c                 3   s    | ]}t | V  qd S r
   r4   r6   r3   r8   r   r   	<genexpr>   s    z"_unbatch_helper.<locals>.<genexpr>c                    s.   g | ]\}}t | jd d |df  jqS N.)r   r   r	   )r6   r   r3   r-   r   r   
<listcomp>   s    z#_unbatch_helper.<locals>.<listcomp>c                    s   g | ]} d d |df qS r<   r   )r6   r   r=   r   r   r>          )	r/   r0   itemsr1   r   r#   r   	enumerater   )r-   r	   	unbatchedr   )r	   r-   r   r#      s   



r#   r   r!   c                    s   t | tr fdd|  D S t | tr"t fdd| D S t | tr/t|   S t | tr<|  }|  S |  df S )z;Selects the item at the ith batch index and jth repetition.c                    s   i | ]\}}|t | qS r   r   r5   r   r!   r   r   r9      r?   z'_batch_index_helper.<locals>.<dictcomp>c                 3   s    | ]	}t | V  qd S r
   rC   r:   rD   r   r   r;      s    z&_batch_index_helper.<locals>.<genexpr>.)r/   r0   r@   r1   listr   r   r"   )r-   r   r!   rB   r   rD   r   r      s   



r   N)typingr   ray.rllib.utils.annotationsr   ray.rllib.utils.typingr   r   r   r   r   r#   r   r   r   r   r   <module>   s     