o
    ۾iA                  
   @   s   d dl mZ zd dlmZ d dlZW n" ey4 Z zde	ev r"dndZ
ede
 de
 dedZ[ww ded	ejfd
dZdZejjdddgdgedZejdejdejd	ejfddZdejdejd	ejfddZdedejd	dfddZdS )    )GuideNnumpymlxz3To use the kernels in `outlines_core.kernels.mlx`, z9 must be installed. You can install it with `pip install `
vocab_sizereturnc                 C   s   t jd| d d fdt jdS )N          )dtype)npfullint32)r    r   M/home/ubuntu/.local/lib/python3.10/site-packages/outlines_core/kernels/mlx.pyallocate_token_bitmask   s
   r   aC  
// Batch index
uint batch = thread_position_in_grid.y;
// Element index
uint elem = thread_position_in_grid.x;

uint bit = ((elem >> 5) < mask_shape[1]) &&
            ((mask[batch * mask_shape[1] + (elem >> 5)] >> (elem & 31)) & 1);

out[batch * inp_shape[1] + elem] = bit ? inp[batch * inp_shape[1] + elem] : -INFINITY;
bitmask_apply_batchedinpmaskout)nameinput_namesoutput_namessourcedatac                 C   s>   t | |gd| jfg| jd | jd dfd| jg| jgdd S )NTr   r   )   r   r   )inputstemplategridthreadgroupoutput_shapesoutput_dtypes)_KERNELr   shape)r   r   r   r   r   _apply_token_bitmask_kernel)   s   
r&   logitsmask_npc                 C   s   t |}t| jdkr| nt j| dd} t|jdkr|nt j|dd}|jt jkr4td|j dt|jdkrDtd|j dt| jdkrTtd	| j d|jd | jd krotd
|jd  d| jd  dt	| |S )aa  
    Apply a logits bitmask inplace, setting the probability of invalid tokens
    to -infinity.

    Arguments:
        logits (mx.array): The logits tensor.

        mask (mx.array): The token bitmask representing the validity of each
          token in the logits tensor.

    Raises:
        ValueError: If any of the following conditions are not met:
            - `mask.dtype` is not `mx.int32`
            - `mask` is not a 2D array
            - `logits` is not a 2D array
            - `mask.shape`shape does not match `logits.shape`

    Returns:
        None: Modifies the mask array in place.
    r   r   )axis2Invalid mask dtype: Expected `np.int32`, but got ``.   6Invalid mask dimensions: Expected a 2D array, but got D.z8Invalid logits dimensions: Expected a 2D array, but got z.Invalid batch size: Expected `mask.shape[0]` (z) to match `logits.shape[0]` (z).)
mxarraylenr%   expand_dimsr   r   
ValueErrorndimr&   )r'   r(   r   r   r   r   apply_token_bitmask5   s(   
  
r5   guidec                 C   s   |j tjkrtd|j  d|jdkrtd|j d|jd dkr-td|j d	|jd
 s6td| |jj	|j
|jS )am  
    Writes a bitmask to represent the tokens permissible by the current state of the `guide`.
    Each bit in the bitmask corresponds to a token ID, with a bit value of 1 indicating that
    the token is allowed and 0 indicating that it is disallowed. This function directly modifies
    the `mask` array in-place.

    Arguments:
        guide (Guide): An instance of the `Guide` class that provides the current guidance state.
        mask (torch.Tensor): A 2D tensor of type `torch.int32` where the bitmask will be written.
                             The tensor must be contiguous, have a single batch dimension
                             (shape[0] == 1), and reside on the CPU.

    Raises:
        ValueError: If any of the following conditions are not met:
                    - `mask.dtype` is not `np.int32`
                    - `mask` is not a 2D tensor
                    - `mask` does not have a single batch dimension (shape[0] != 1)
                    - `mask` is not contiguous in memory
                    - `mask` is not on the CPU device

    Returns:
        None: Modifies the `mask` tensor in-place.
    r*   r+   r,   r-   r.   r   r   z_Invalid batch size: Batch mask writes are not supported. Expected shape[0] == 1, but got shape .C_CONTIGUOUSzJMask array must be contiguous in memory. Use `np.ascontiguousarray(mask)`.)r   r   r   r3   r4   r%   flagswrite_mask_intoctypesr   sizeitemsize)r6   r   r   r   r   fill_next_token_bitmaskc   s"   

r>   )outlines_corer   mlx.corecorer/   r   r   ImportErrorestrmissing_depintndarrayr   _KERNEL_SOURCEfastmetal_kernelr$   compiler0   r&   r5   r>   r   r   r   r   <module>   s2    .