o
    پi)                     @   s   d dl Z d dlZd dlZd dlZd dlmZmZ d dlZe	ej
dd  Zedkr7d dlmZmZmZmZ nd dlmZmZmZmZ eedr`z
d dlZe  W n ey_   ed Y nw G dd	 d	Zd
d ZdS )    N)CallableOptional.   )_calculate_shapes_parse_gufunc_signature_parse_input_dimensions_update_dim_sizes__IPYTHON__zdCouldn't patch nest_asyncio because it's not installed. Running in the notebook might be have issuesc                   @   sX   e Zd ZdZddedee fddZdd Zd	d
 Z	dd Z
dd Zdd Zdd ZdS )	vectorizea  Returns an object that acts like a function but takes arrays as an input.

    The vectorized function evaluates `func` over successive tuples of the input
    chararrays and returns a single NumPy chararrays or a tuple of NumPy chararrays.

    Its behavior is similar to NumPy's `vectorize` for Python functions: the function
    being vectorized is executed in a `for` loop. Coroutines, however, are executed
    concurrently.

    Part of the code was adapted from `numpy.lib.function_base`.

    Nfunc	signaturec                 C   sD   || _ || _t|| _t| | |d urt|| _d S d | _d S N)	r   r   inspectiscoroutinefunctionis_coroutine_fn	functoolsupdate_wrapperr   _in_and_out_core_dimensions)selfr   r    r   A/home/ubuntu/.local/lib/python3.10/site-packages/outlines/base.py__init__5   s   
zvectorize.__init__c                 O   s:   |s|s|   S | jdur| j|i |S | j|i |S )zCall the vectorized function.N)
call_thunkr   call_with_signaturecall_no_signature)r   argskwargsr   r   r   __call__C   s
   
zvectorize.__call__c                 C   sB   | j rt }z||  }W |  |S |  w |  }|S )zeCall a vectorized thunk.

        Thunks have no arguments and can thus be called directly.

        )r   asyncionew_event_looprun_until_completer   close)r   loopoutputsr   r   r   r   L   s   
zvectorize.call_thunkc                    s   dd |D }dd |  D }tjg |t| R  j  fdd|D } fdd|  D }| jr>|  ||}n|  ||}dd |D }t	 fddt
| D }t	d	d |D }tt|}|d
krp|d S |S )a  Call functions and coroutines when no signature is specified.

        When no signature is specified we assume that all of the function's
        inputs and outputs are scalars (core dimension of zero). We first
        broadcast the input arrays, then iteratively apply the function over the
        elements of the broadcasted arrays and finally reshape the results to
        match the input shape.

        Functions are executed in a for loop, coroutines are executed
        concurrently.

        c                 S      g | ]}t |qS r   nparray.0argr   r   r   
<listcomp>k       z/vectorize.call_no_signature.<locals>.<listcomp>c                 S      i | ]
\}}|t |qS r   r&   r*   keyvaluer   r   r   
<dictcomp>l       z/vectorize.call_no_signature.<locals>.<dictcomp>c                    s   g | ]}t | qS r   r'   broadcast_tor)   broadcast_shaper   r   r,   p   s    c                       i | ]\}}|t | qS r   r4   r/   r6   r   r   r2   q       c                 S       g | ]}t |tr|n|fqS r   
isinstancetupler*   resultsr   r   r   r,   ~       c                    s    g | ]}t |  qS r   )r'   asarrayreshapesqueezer*   xr6   r   r   r,      s     c                 S   &   g | ]}t |d kr| n|qS r   r'   ndimitemrD   r   r   r   r,         &    r   )itemsr'   	broadcastlistvaluesshaper   vectorize_call_coroutinevectorize_callr=   ziplen)r   r   r   r$   	n_resultsr   r6   r   r   ]   s&   
zvectorize.call_no_signaturec                    s  | j \}}t|t| }|t|krtdt|t|f dd |D }dd | D }t|t|  |\ }t ||}dd t||D } fdd| D }t|}| j	rf| 
 ||}	n|  ||}	dd |	D }	tt|	 }
t|
}||krtd	| d
| t|
|D ]\}}|D ]}t||| qqt ||}tdd t|t|	 D }	tdd |	D }	|dkr|	d S |	S )z<Call functions and coroutines when a signature is specified.z9wrong number of positional arguments: expected %r, got %rc                 S   r%   r   )r'   rA   r)   r   r   r   r,      r-   z1vectorize.call_with_signature.<locals>.<listcomp>c                 S   r.   r   r&   r/   r   r   r   r2      r3   z1vectorize.call_with_signature.<locals>.<dictcomp>c                 S   s    g | ]\}}t j||d dqS )T)subokr4   )r*   r+   rQ   r   r   r   r,      s    c                    r8   r   r4   r/   r6   r   r   r2      r9   c                 S   r:   r   r;   r>   r   r   r   r,      r@   z4wrong number of outputs from the function, expected z, got c                 S   s$   g | ]\}}t || qS r   )r'   hstackrB   rC   )r*   rQ   r?   r   r   r   r,      s    c                 S   rF   rG   rH   rD   r   r   r   r,      rK   rL   r   )r   rU   	TypeErrorrM   r   rO   rP   r   rT   r   rR   rS   
ValueErrorr	   r=   )r   r   r   input_core_dimsoutput_core_dimsnum_args	dim_sizesinput_shapesn_outr$   flat_outputsrV   r?   	core_dimsresultshapesr   r6   r   r      sZ   

zvectorize.call_with_signaturec                    sZ   g }t j| D ]# t fdd|D } fdd| D }|| j|i | q|S )ae  Run the function in a for loop.

        A possible extension would be to parallelize the calls.

        Parameters
        ----------
        broadcast_shape
            The brodcast shape of the input arrays.
        args
            The function's broadcasted arguments.
        kwargs
            The function's broadcasted keyword arguments.

        c                 3       | ]}|  V  qd S r   r   r)   indexr   r   	<genexpr>       z+vectorize.vectorize_call.<locals>.<genexpr>c                       i | ]	\}}||  qS r   r   r/   rf   r   r   r2          z,vectorize.vectorize_call.<locals>.<dictcomp>)r'   ndindexr=   rM   appendr   )r   r7   r   r   r$   current_argscurrent_kwargsr   rf   r   rS      s   zvectorize.vectorize_callc                    s@    fdd}t  }z|| }W |  |S |  w )ay  Run coroutines concurrently.

        Creates as many tasks as needed and executes them in a new event
        loop.

        Parameters
        ----------
        broadcast_shape
            The brodcast shape of the input arrays.
        args
            The function's broadcasted arguments.
        kwargs
            The function's broadcasted keyword arguments.

        c                     sl   g } t j D ]# t fddD } fdd D }| j|i | qtj|  I d H }|S )Nc                 3   re   r   r   r)   rf   r   r   rh      ri   zVvectorize.vectorize_call_coroutine.<locals>.create_and_gather_tasks.<locals>.<genexpr>c                    rj   r   r   r/   rf   r   r   r2     rk   zWvectorize.vectorize_call_coroutine.<locals>.create_and_gather_tasks.<locals>.<dictcomp>)r'   rl   r=   rM   rm   r   r   gather)tasksrn   ro   r$   r   r7   r   r   rf   r   create_and_gather_tasks   s   zCvectorize.vectorize_call_coroutine.<locals>.create_and_gather_tasks)r   r    r!   r"   )r   r7   r   r   rs   r#   r$   r   rr   r   rR      s   
z"vectorize.vectorize_call_coroutiner   )__name__
__module____qualname____doc__r   r   strr   r   r   r   r   rS   rR   r   r   r   r   r   '   s    	-Kr   c                 C   s\   g }t | |D ]"\}}|jjtjkr$|jt|jk r$|t|j}|| qt|S )a(  Update the dtype of arrays.

    String arrays contain strings of fixed length. Here they are initialized with
    the type of the first results, so that if the next results contain longer
    strings they will be truncated when added to the output arrays. Here we
    update the type if the current results contain longer strings than in the
    current output array.

    Parameters
    ----------
    arrays
        Arrays that contain the vectorized function's results.
    results
        The current output of the function being vectorized.

    )	rT   dtypetyper'   str_r(   astyperm   r=   )arraysr?   updated_arraysr(   rc   r   r   r   _update_arrays_type  s   r   )r   builtinsr   r   typingr   r   numpyr'   int__version__splitnp_major_versionnumpy.lib._function_base_implr   r   r   r	   numpy.lib.function_basehasattrnest_asyncioapplyImportErrorprintr   r   r   r   r   r   <module>   s,    
	 k