o
    ©Ci—'  ã                   @   s’   d dl Z d dlZd dlZd dlZe e¡Ze jfdd„Z	e j
Z
dd„ Ze jddfdd	„Zdd
d„Zddd„Zddd„Z		ddd„Zddd„ZdS )é    Nc                 C   s  t  d| j|f ¡ t ¡ }| j\}}t |¡}tj|||d}t ||¡}	t ¡ r8t  dt ¡  ¡ t 	|	¡}	d}
|D ]3}|jd }|	 
|¡ |	 | |¡\}}||
7 }| ||¡ |	 ¡  |
|7 }
t  d|
t ¡ | f ¡ q<| ¡  t  dt ¡ | |
f ¡ |j|jfS )z¤Computes the exact KNN search results for a dataset that possibly
    does not fit in RAM but for which we have an iterator that
    returns it block by block.
    z%knn_ground_truth queries size %s k=%d©Úkeep_maxúrunning on %d GPUsr   ú%d db elements, %.3f szGT time: %.3f s (%d vectors))ÚLOGÚinfoÚshapeÚtimeÚfaissÚis_similarity_metricÚ
ResultHeapÚ	IndexFlatÚget_num_gpusÚindex_cpu_to_all_gpusÚaddÚsearchÚ
add_resultÚresetÚfinalizeÚDÚI)ÚxqÚdb_iteratorÚkÚmetric_typeÚt0ÚnqÚdr   ÚrhÚindexÚi0ÚxbiÚnir   r   © r#   úw/var/www/html/fyndo/python/python_agents/rag_suite/venv/lib/python3.10/site-packages/faiss/contrib/exhaustive_search.pyÚknn_ground_truth   s,   




r%   c                 C   sÚ  | j \}}t d| ¡ t|jdƒ}| | |¡\}}|jtjkr-|dd…|d f |k }	n|dd…|d f |k}	|	 	¡ dkrgt d|	 	¡  ¡ t
|tjƒr\|}
t ||j¡}| |
¡ | | |	 |¡\}}}t d¡ g g }}d}t|ƒD ]]}|	| s³|jtjkr||dd…f |k  	¡ }n||dd…f |k 	¡ }| ||d|…f ¡ | ||d|…f ¡ qw|| ||d  }}| |||… ¡ | |||… ¡ |d7 }qwt dgdd	„ |D ƒ ¡}|t |¡t |¡fS )
zÞGPU does not support range search, so we emulate it with
    knn search + fallback to CPU index.

    The index_cpu can either be a CPU index or a numpy table that will
    be used to construct a Flat index if needed.
    zGPU search %d queriesi   Né   r   zCPU search remain %dÚcombinec                 S   ó   g | ]}t |ƒ‘qS r#   ©Úlen)Ú.0Údir#   r#   r$   Ú
<listcomp>]   ó    z$range_search_gpu.<locals>.<listcomp>)r   r   ÚdebugÚminÚntotalr   r   r
   Ú	METRIC_L2ÚsumÚ
isinstanceÚnpÚndarrayr   r   Úrange_searchÚrangeÚappendÚcumsumÚhstack)r   Úr2Ú	index_gpuÚ	index_cpur   r   r   r   r   ÚmaskÚxbÚ
lim_remainÚD_remainÚI_remainÚD_resÚI_resÚnrÚiÚnvÚl0Úl1Úlimsr#   r#   r$   Úrange_search_gpu6   s<   




rL   Féÿÿÿÿc                    s  | j \}}t ¡ }tj| dd} t ||¡}	|dkrt ¡ }|r6t d| ¡ t 	¡ }
||
_
tj|	|
|d}d}dd„ t|ƒD ƒ}d	d„ t|ƒD ƒ}|D ]r}|j d }|dkrk| |¡ t| |||ƒ\}}}| ¡  n|	 |¡ |	 | |¡\}}}|	 ¡  ||7 }t|ƒD ]'}|| ||d
  }}||kr¬||  |||… ¡ ||  |||… ¡ q…||7 }t d|t ¡ | f ¡ qLtjddd‰tjddd‰ ‡ fdd„|D ƒ}‡fdd„|D ƒ}dd„ |D ƒ}t|ƒ|ksîJ ‚tj|d
 dd}t |¡|d
d…< |t |¡t |¡fS )z§Computes the range-search search results for a dataset that possibly
    does not fit in RAM but for which we have an iterator that
    returns it block by block.
    Úfloat32©ÚdtyperM   r   ©ÚcoÚngpur   c                 S   ó   g | ]}g ‘qS r#   r#   ©r+   Ú_ir#   r#   r$   r-   v   ó    z&range_ground_truth.<locals>.<listcomp>c                 S   rT   r#   r#   rU   r#   r#   r$   r-   w   rW   r&   r   Úint64c                    ó"   g | ]}|g krt  |¡nˆ ‘qS r#   ©r5   r;   ©r+   rG   )Úempty_Dr#   r$   r-   Ž   ó   " c                    rY   r#   rZ   r[   )Úempty_Ir#   r$   r-      r]   c                 S   r(   r#   r)   r[   r#   r#   r$   r-      r.   Úuint64N)r   r	   r5   Úascontiguousarrayr
   r   r   r   r   ÚGpuMultipleClonerOptionsÚshardr   r8   r   rL   r   r7   r9   Úzerosr*   r:   r;   )r   r   Ú	thresholdr   rb   rS   r   r   r   r   rR   r=   r    r   r   r!   r"   Úlims_iÚDiÚIiÚjrI   rJ   ÚsizesrK   r#   )r\   r^   r$   Úrange_ground_trutha   sR   




€rj   c           
      C   sp   |r||k}n||k }t  | ¡}d}t| ƒD ]\}}	t|	ƒ}	||||	 …  ¡ ||< ||	7 }q||| || fS )z select a set of results r   )r5   Ú
zeros_likeÚ	enumerateÚintr3   )
ÚnresÚdisÚidsÚthreshr   r?   Únew_nresÚorG   rF   r#   r#   r$   Úthreshold_radius_nres—   s   


rt   c                 C   s‚   |r||k}n||k }t  | ¡}t| ƒd }t|ƒD ]}| | | |d  }	}
|| ||	|
…  ¡  ||d < q||| || fS )z= restrict range-search results to those below a given radius r&   )r5   rk   r*   r8   r3   )rK   ro   rp   rq   r   r?   Únew_limsÚnrG   rI   rJ   r#   r#   r$   Úthreshold_radius¦   s   

"rw   c           
      C   sì   t  dd„ | D ƒ¡}t|ƒ|ksJ ‚|r&| t|ƒ| d ¡ |d|  }n	| |¡ || }|jdkr9t|ƒ}nt|ƒ}t d| ¡ d}t	| ƒD ] \}\}}}	t
|||	||d\}}}	|t|ƒ7 }|||	f| |< qJt d	| ¡ ||fS )
z‘find radius that reduces number of results to target_nres, and
    applies it in-place to the result batches used in
    range_search_max_resultsc                 S   s   g | ]\}}}|‘qS r#   r#   )r+   Ú_ro   r#   r#   r$   r-   ¸   ó    z apply_maxres.<locals>.<listcomp>r&   rM   rN   z   setting radius to %sr   r   z.   updated previous results, new nb results %d)r5   r;   r*   Ú	partitionrP   Úfloatrm   r   r/   rl   rt   )
Úres_batchesÚtarget_nresr   ÚalldisÚradiusÚtotresrG   rn   ro   rp   r#   r#   r$   Úapply_maxres´   s(   



ÿr   c                 C   st  |du r|dus
J ‚t d| ƒ}|du r |dusJ ‚t |d ƒ}|dkr(t ¡ }|r@t d| ¡ t ¡ }||_tj| ||d}	t ¡ }
d }}d } }}g }|D ]}t ¡ }|dkrgt	|||	| ƒ\}}}n	|  
||¡\}}}|dd… |dd…  }|t|ƒ7 }|t|ƒ7 }t ¡ }|jtjkr—| d	¡}|t|ƒ7 }| |||f¡ |durÃ||krÃt d
||f ¡ t||t | j¡d\}}t ¡ }||| 7 }||| 7 }t dt ¡ |
 ||f ¡ qRt d||||f ¡ |r||krt||t | j¡d\}}t dd„ |D ƒ¡}t dd„ |D ƒ¡}t dd„ |D ƒ¡}tjt|ƒd dd}t |¡|dd…< ||||fS )a  Performs a range search with many queries (given by an iterator)
    and adjusts the threshold on-the-fly so that the total results
    table does not grow larger than max_results.

    If ngpu != 0, the function moves the index to this many GPUs to
    speed up search.
    Ngš™™™™™é?g      ø?rM   r   rQ   r   r&   Úint16z-too many results %d > %d, scaling back radiusr   z'   [%.3f s] %d queries done, %d resultszBsearch done in %.3f s + %.3f s, total %d results, end threshold %gc                 S   s   g | ]\}}}|‘qS r#   r#   ©r+   Únres_iÚdis_iÚids_ir#   r#   r$   r-     ry   z,range_search_max_results.<locals>.<listcomp>c                 S   s   g | ]\}}}|‘qS r#   r#   rƒ   r#   r#   r$   r-      ry   c                 S   s   g | ]\}}}|‘qS r#   r#   rƒ   r#   r#   r$   r-   !  ry   r_   rO   )rm   r
   r   r   r   ra   rb   r   r	   rL   r7   r*   rP   r5   rN   Úastyper9   r   r   r   r/   r;   rc   r:   )r   Úquery_iteratorr   Úmax_resultsÚmin_resultsrb   rS   Úclip_to_minrR   r=   Út_startÚt_searchÚt_post_processÚqtotr€   Ú
raw_totresr|   Úxqir   re   rf   rg   r„   Út1Út2rn   ro   rp   rK   r#   r#   r$   Úrange_search_max_resultsÐ   sx   
ÿ

þ
ÿÿÿ

þr”   é    é N  c                 c   s\    t | ƒ}|}d}||k r,| ||| … }|V  ||k r |d9 }|t |ƒ7 }||k sdS dS )z¤ produces batches of progressively increasing sizes. This is useful to
    adjust the search radius progressively without overflowing with
    intermediate results r   é   Nr)   )r   Ústart_bsÚmax_bsr   ÚbsrG   r‘   r#   r#   r$   Úexponential_query_iterator)  s   €ûr›   )F)NNFr   F)r•   r–   )r
   r	   Únumpyr5   ÚloggingÚ	getLoggerÚ__name__r   r2   r%   ÚknnrL   rj   rt   rw   r   r”   r›   r#   r#   r#   r$   Ú<module>   s$   
"+
ÿ
6


þY