o
    eiK                     @  s  d dl mZ d dlZd dlZd dlZd dlmZ d dlmZ d dlm	Z	m
Z
mZmZ d dlmZmZ d dlZd dlmZ d dlmZ d d	lmZmZmZmZmZ d d
lmZmZmZmZmZ erhd dlm Z m!Z! edZ"edZ#e$e%e	df B Z&e$e%e$df B dB Z'dzddZ(d{ddZ)d|ddZ*d}d%d&Z+d~d.d/Z,dd3d4Z-dd=d>Z.ddAdBZ/ddEdFZ0ddGdHZ1ddIdJZ2ddQdRZ3ddUdVZ4ddXdYZ5dd\d]Z6ddbdcZ7ddedfZ8ddgdhZ9ej:ddjdkZ;ddmdnZ<ddqdrZ=ddudvZ>ddxdyZ?dS )    )annotationsN)Callable)partial)AnycastNoReturnTYPE_CHECKING)	ParamSpecTypeVar)Tensor)is_batchedtensor)_add_batch_dim_remove_batch_dim_vmap_decrement_nesting_vmap_increment_nestinglazy_load_decompositions)_broadcast_to_and_flattentree_flatten	tree_map_tree_unflattenTreeSpec)	GeneratorIterable_P_R.fCallable[_P, _R]returnc                   s"   dt  d
 fdd	}|S )Nzvtorch.func.{grad, vjp, jacrev, hessian} don't yet support saved tensor hooks. Please open an issue with your use case.args_P.argskwargs	_P.kwargsr   r   c                    s@   t jj  | i |W  d    S 1 sw   Y  d S N)torchautogradgraphdisable_saved_tensors_hooks)r   r    r   message _/var/www/addictedbytheproject.nl/epg/venv/lib/python3.10/site-packages/torch/_functorch/vmap.pyfn5   s   $z.doesnt_support_saved_tensors_hooks.<locals>.fn)r   r   r    r!   r   r   )	functoolswraps)r   r+   r)   r'   r*   "doesnt_support_saved_tensors_hooks/   s
   r.   flat_in_dimslist[int | None]	flat_args	list[Any]intc                   sZ   dd t | |D  t dkrtd r)t fdd D r)td  d d S )	Nc                 S  s"   g | ]\}}|d ur| |qS r"   )size.0in_dimargr)   r)   r*   
<listcomp>A   s
    z0_validate_and_get_batch_size.<locals>.<listcomp>r   z/vmap: Expected at least one Tensor to vmap overc                 3  s    | ]	}| d  kV  qdS )r   Nr)   )r6   r4   batch_sizesr)   r*   	<genexpr>H   s    z/_validate_and_get_batch_size.<locals>.<genexpr>zTvmap: Expected all tensors to have the same size in the mapped dimension, got sizes z for the mapped dimension)ziplen
ValueErrorany)r/   r1   r)   r:   r*   _validate_and_get_batch_size>   s   rA   batched_outputsTensor | tuple[Tensor, ...]c                 C  s   t | tr	t| S dS )N   )
isinstancetupler>   )rB   r)   r)   r*   _num_outputsP   s   
rG   valuetuple[_R, ...] | _Rnum_elementserror_message_lambdaCallable[[], str]tuple[_R, ...]c                 C  s.   t | ts
| f| S t| |krt| | S r"   )rE   rF   r>   r?   )rH   rJ   rK   r)   r)   r*   	_as_tupleZ   s
   


rN   in_dims	in_dims_tr   tuple[Any, ...]funcCallable[..., Any]1tuple[int, list[int | None], list[Any], TreeSpec]c           	      C  s  t | tst | tstdt| d|  dt|  dt|dkr,tdt| dt|\}}t| |}|d u rRtdt| d|  dt| d  d	| d	t	t
||D ]~\}\}}t |tsx|d urxtdt| d|  d
| dt |trt |tstdt| d|  d
| dt| d	|d ur||  k s|| krtdt| d|  d
| d|  d|  d|  d|d ur|dk r||  ||< qYt|||||fS )Nvmap(z
, in_dims=zv, ...)(<inputs>): expected `in_dims` to be int or a (potentially nested) tuple matching the structure of inputs, got: .r   z)(<inputs>): got no inputs. Maybe you forgot to add inputs, or you are trying to vmap over a function with no inputs. The latter is unsupported.zb, ...)(<inputs>): in_dims is not compatible with the structure of `inputs`. in_dims has structure rD   z but inputs has structure z, ...)(<inputs>): Got in_dim=zE for an input but in_dim must be either an integer dimension or None.z' for an input but the input is of type zT. We cannot vmap over non-Tensor arguments, please use None as the respective in_dimz> for some input, but that input is a Tensor of dimensionality z  so expected in_dim to satisfy -z <= in_dim < )rE   r3   rF   r?   	_get_nametyper>   r   r   	enumerater=   r   dimrA   )	rO   r   rR   r1   	args_specr/   ir8   r7   r)   r)   r*   _process_batched_inputsf   sn   

"r]   
vmap_levelr[   r   c                   s"    fddt | |D }t||S )Nc                   s(   g | ]\}}|d u r|nt || qS r"   )r   r5   r^   r)   r*   r9      s    z*_create_batched_inputs.<locals>.<listcomp>)r=   r   )r/   r1   r^   r[   batched_inputsr)   r_   r*   _create_batched_inputs   s   

ra   namestrbatched_outputr   
batch_sizeout_dim
int | Nonetorch.Tensorc                 C  sp   |d u rt |tjrt|rtd|  d|  d|S t |tjs1td|  d|  dt| dt||||S )NrU   z	, ...): `z5` can not return a BatchedTensor when out_dim is Nonez%` must only return Tensors, got type z3. Did you mean to set out_dims= to None for output?)rE   r#   r   r   r?   rX   r   )rb   rd   r^   re   rf   r)   r)   r*   _maybe_remove_batch_dim   s   ri   out_dims
out_dims_tc           
        s   t | \}dfdd}g }t| tjr<ttr g}n+ttr0tdkr0t}nd u r8g}n|  nt}|d u rI|  n|} fddt	||D }	t
|	S )	Nr   r   c                
     s.   t dt  d dtd  d d	)NrU   , ..., out_dims=z`)(<inputs>): out_dims is not compatible with the structure of `outputs`. out_dims has structure rD   z but outputs has structure rV   )r?   rW   r   r)   )rR   rj   output_specr)   r*   incompatible_error   s   
z+_unwrap_batched.<locals>.incompatible_errorrD   c                   s$   g | ]\}}t t| |qS r)   )ri   rW   )r6   rd   rf   )re   rR   r^   r)   r*   r9      s    z#_unwrap_batched.<locals>.<listcomp>)r   r   )r   rE   r#   r   r3   rF   r>   listr   r=   r   )
rB   rj   r^   re   rR   flat_batched_outputsrn   flat_out_dimsbroadcast_resultflat_outputsr)   )re   rR   rj   rm   r^   r*   _unwrap_batched   s&   



rt   xNonec                 C  s4   t | trd S | d u rd S tdt| d| d)NrU   rl   z): `out_dims` must be an int, None or a python collection of ints representing where in the outputs the vmapped dimension should appear.)rE   r3   r?   rW   )ru   rR   rj   r)   r)   r*   _check_int_or_none   s   
rw   c                 C  s&   t | trd S ttt|| d|  d S )N)rR   rj   )rE   r3   r   r   rw   )rj   rR   r)   r)   r*   $_check_out_dims_is_int_or_int_pytree	  s   
rx   c                 C  s6   t | dr| jS t| tjrdt| j dS t| S )N__name__zfunctools.partial(z, ...))hasattrry   rE   r,   r   rW   rR   repr)rR   r)   r)   r*   rW     s
   
rW   )Callable[_P, Tensor | tuple[Tensor, ...]]
randomness
chunk_sizer   r    r!   c                 O  sp   t   t||  t||| \}}}	}
|d ur*t|	|||}t| |||
||fi |S t| |||	|
||fi |S r"   )r   rx   r]   _get_chunked_inputs_chunked_vmap
_flat_vmap)rR   rO   rj   r}   r~   r   r    re   r/   r1   r[   chunks_flat_argsr)   r)   r*   	vmap_impl  s<   	
r   total_elems	list[int]c                 C  s0   | | }|g| }| | }|dkr| | |S )Nr   )append)r   r~   n_chunkschunk_sizes	remainderr)   r)   r*   get_chunk_sizesH  s   

r   Iterable[tuple[Any, ...]]c                   sN   |f |d urt ||}tt| t fddt| |D }t| }|S )Nc                 3  s8    | ]\}}|d ur|j  |dn|gt  V  qd S )NrZ   )tensor_splitr>   )r6   tr7   
split_idxsr)   r*   r<   ]  s    	
z&_get_chunked_inputs.<locals>.<genexpr>)r   rF   	itertools
accumulater=   )r1   r/   re   r~   r   flat_args_chunksr   r)   r   r*   r   R  s   
	r   chunks_output_&tuple[list[tuple[Any, ...]], TreeSpec]c                 C  sX   g }d }| D ]}t |\}}|| |d u r|}qtt| }|d u r(td||fS )Nzarg_spec must not be None)r   r   ro   r=   AssertionError)r   flat_chunks_outputarg_specoutputflat_output	arg_specsflat_output_chunksr)   r)   r*   _flatten_chunks_outputo  s   
r   r   r   list[tuple[Any, ...] | None]list[Tensor]c                 C  s   t | |}|d u rtdt|t|kr#tdt| dt| g }t|D ]"\}}|| }|d u r=td| d|tj||d d ||< q)|S )Nzflat_out_dims must not be Nonezlen(flat_out_dims)=z != len(flat_output_chunks)=zchunk at index z must not be Noner   )r   r   r>   rY   r   r#   cat)rj   r   r   rq   r   idxrf   chunkr)   r)   r*   _concat_chunked_outputs  s   

r   r   c                 K  s   g }|dkr
t  nd }|D ]*}	t|	}
t||
}|dkrq|d ur't | |t| |||
|||fi | qt|\}}~t||t	tt
tdf d B  |}t||S )Nsamer   .)r#   get_rng_statero   rA   set_rng_stater   r   r   r   r   rF   r   r   )rR   r/   r   r[   rj   r}   r    chunks_outputrsflat_args_tupler1   re   r   r   r   r)   r)   r*   r     s8   	


r   c                 C  s   | dvrt d|  d S )N)error	differentr   zLOnly allowed values for randomness are 'error', 'different', or 'same'. Got )RuntimeError)r}   r)   r)   r*   _check_randomness_arg  s
   r   Generator[int, None, None]c                 c  s(    zt | |}|V  W t  d S t  w r"   )r   r   )re   r}   r^   r)   r)   r*   vmap_increment_nesting  s
   
r   *Callable[..., Tensor | tuple[Tensor, ...]]c                 K  sZ   t ||}t||||}	| |	i |}
t|
|||| W  d    S 1 s&w   Y  d S r"   )r   ra   rt   )rR   re   r/   r1   r[   rj   r}   r    r^   r`   rB   r)   r)   r*   r     s   
$r   Callable[..., _R]Callable[..., tuple[Any, Any]]c                   s   d fdd}|S )	Nr   r   r    r   tuple[Any, Any]c                    sR   t  }t| |}|i |}t||W  d    S 1 s"w   Y  d S r"   )r   wrap_batchedunwrap_batched)r   r    r^   r`   rB   re   rR   rO   r}   r)   r*   inner  s
   $zrestore_vmap.<locals>.inner)r   r   r    r   r   r   r)   )rR   rO   re   r}   r   r)   r   r*   restore_vmap  s   r   bdimslevelc                 C  s8   t | \}}t||}|d u rtdt||||}|S )Nzflat_bdims must not be None)r   r   r   ra   )r   r   r   r1   spec
flat_bdimsresultr)   r)   r*   r     s   
r   r   c                   sR   t | \}}t|dkr| dfS  fdd|D }t| \}}t||t||fS )Nr   r)   c                   s0   g | ]}t |tjrtjj| n|d fqS r"   )rE   r#   r   _C
_functorchrt   )r6   r8   r   r)   r*   r9   .  s    
z"unwrap_batched.<locals>.<listcomp>)r   r>   r=   r   )r   r   r1   r   r   r   r   r)   r   r*   r   *  s   
r   )r   r   r   r   )r/   r0   r1   r2   r   r3   )rB   rC   r   r3   )rH   rI   rJ   r3   rK   rL   r   rM   )rO   rP   r   rQ   rR   rS   r   rT   )
r/   r0   r1   r2   r^   r3   r[   r   r   rQ   )rb   rc   rd   r   r^   r3   re   r3   rf   rg   r   rh   )rB   rC   rj   rk   r^   r3   re   r3   rR   rS   r   rQ   )ru   r   rR   rS   rj   rk   r   rv   )rj   rk   rR   rS   r   rv   )rR   rS   r   rc   )rR   r|   rO   rP   rj   rk   r}   rc   r~   rg   r   r   r    r!   r   r   )r   r3   r~   r3   r   r   )
r1   r2   r/   r0   re   r3   r~   rg   r   r   )r   r2   r   r   )rj   rk   r   r   r   r   r   r   )rR   r|   r/   r0   r   r   r[   r   rj   rk   r}   rc   r    r   r   r   )r}   rc   r   rv   )re   r3   r}   rc   r   r   )rR   r   re   r3   r/   r0   r1   r2   r[   r   rj   rk   r}   rc   r    r   r   r   )
rR   r   rO   rP   re   r3   r}   rc   r   r   )r   rQ   r   rP   r   r3   r   rQ   )r   r   r   r3   r   r   )@
__future__r   
contextlibr,   r   collections.abcr   r   typingr   r   r   r   typing_extensionsr	   r
   r#   r   torch._C._functorchr   torch._functorch.predispatchr   r   r   r   r   torch.utils._pytreer   r   r   r   r   r   r   r   r   r3   rF   rP   rk   r.   rA   rG   rN   r]   ra   ri   rt   rw   rx   rW   r   r   r   r   r   r   r   contextmanagerr   r   r   r   r   r)   r)   r)   r*   <module>   sV   	






?


-



*





=


&
