a
    ij                     @   s   d Z ddlZddlZddl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 eZeZe
d	ZG d
d dZeedddZdS )z	Tree API.    N)AnyCallableIterableIteratorOptionalTypeVar)enp)etqdm)Arraybackend)Tree_Toutc                   @   s   e Zd ZdZejdddZedef e	e
 e	e dddZd	d
dedef e	e
 ee ee	e dddZe	ee  ee	e  dddZee	ed   e	ed  dddZdde	e ee	ej dddZd	S )TreeAPIzETree API, using either `jax.tree_utils`, `tf.nest` or `tree` backend.r   c                 C   s
   || _ d S Nr   )selfr    r   T/home/ghrups/robot-bench/.venv/lib/python3.9/site-packages/etils/etree/tree_utils.py__init__#   s    zTreeAPI.__init__.)map_fntreesreturnc                 G   s   | j j|g|R  S )zSame as `tree.map_structure`.

    Args:
      map_fn: Worker function
      *trees: Nested input to pass to the `map_fn`

    Returns:
      The nested structure after `map_fn` has been applied.
    r   map)r   r   r   r   r   r   r   &   s    zTreeAPI.mapNF)num_threadsprogress_bar)r   r   r   r   r   c                G   s   t jj|d~}t|j|}| jj|g|R  }| j|\}}	t j	|}
|rdt
j|
t|d}
|
D ]}| rh| qhW d   n1 s0    Y  | jdd |S )a_  Same as `tree.map_structure` but apply `map_fn` in parallel.

    Args:
      map_fn: Worker function
      *trees: Nested input to pass to the `map_fn`
      num_threads: Number of workers (default to CPU count * 5)
      progress_bar: If True, display a progression bar.

    Returns:
      The nested structure after `map_fn` has been applied.
    )max_workers)totalNc                 S   s   |   S r   )result)fr   r   r   <lambda>[       z&TreeAPI.parallel_map.<locals>.<lambda>)
concurrentfuturesZThreadPoolExecutor	functoolspartialZsubmitr   r   flattenZas_completedr	   Ztqdmlen	exception)r   r   r   r   r   executorZlaunch_workerr#   leaves_itrr   r   r   r   parallel_map6   s    (zTreeAPI.parallel_map)treer   c                 c   s2   | j |\}}t| D ]}| j ||V  qdS )a\  Unpack a tree of iterable.

    This is the reverse operation of `tree.map_structure(zip, *trees)`

    Example:

    ```python
    etree.unzip({'a': np.array([1, 2, 3])}) == [{'a': 1}, {'a': 2}, {'a': 3}]
    ```

    Args:
      tree: The tree to unzip

    Yields:
      Trees of same structure than the input, but with individual elements.
    N)r   r&   zipZ	unflatten)r   r.   r*   ZtreedefZ
leaf_elemsr   r   r   unzip]   s    zTreeAPI.unzipz*sz
n_trees *s)r   r   c                 C   s   | j jtg|R  S )ah  Stack a tree of `Iterable[Array]`.

    Supports `jax`, `tf`, `np`.

    Example:

    ```python
    etree.stack([
        {'a': np.array([1])},
        {'a': np.array([2])},
        {'a': np.array([3])},
    ]) == {
        'a': np.array([[1], [2], [3]])
    }
    ```

    Args:
      trees: The list of tree to stack

    Returns:
      Tree of arrays.
    )r   r   _stack)r   r   r   r   r   stackr   s    zTreeAPI.stackTignore_other)r.   r4   r   c                   s    fdd}| j ||S )a  Inspect a tree of array, works with any array type.

    Example:

    ```python
    model = MyModel()
    variables = model.init(jax.random.PRNGKey(0), x)

    # Inspect the `variables` tree structures
    print(etree.spec_like(variables))
    ```

    Args:
      tree: The tree of array
      ignore_other: If `True`, non-array are forwarded as-is.

    Returns:
      The tree of `enp.ArraySpec`.
    c                    s8   t j| s( r| S tdt|  nt j| S d S )NzUnknown array type: )r   	ArraySpecZis_array	TypeErrortypeZ
from_array)arrayr3   r   r   _to_spec_array   s
    z)TreeAPI.spec_like.<locals>._to_spec_arrayr   )r   r.   r4   r9   r   r3   r   	spec_like   s    	zTreeAPI.spec_like)__name__
__module____qualname____doc__backend_libBackendr   r   r   r   _Tinr   r   intboolr-   r   _Tr   r0   r
   r2   r   r5   r:   r   r   r   r   r       s2   

' 
r   )arrsr   c                  G   s   t j| d }|| S )zStack arrays together.r   )r   ZlazyZget_xnpr2   )rE   Zxnpr   r   r   r1      s    r1   )r>   concurrent.futuresr"   r$   typingr   r   r   r   r   r   Zetilsr   r	   Zetils.array_typesr
   Zetils.etreer   r?   Zetils.etree.typingr   rD   rA   r   r   r1   r   r   r   r   <module>   s     