Ë
    °ŒjS:  ã                   óÊ   — d dl Zd dlZd dlZd dlZd dlmZ d„ Zd„ Zdd„Z	dd„Z
d„ Zd„ Z	 	 dd	„Zd
„ Zdd„Zd„ Z G d„ d«      Z G d„ de«      Z G d„ d«      Z G d„ d«      Zy)é    N)Ú
ThreadPoolc                 ó¤   ‡ ‡— ‰ j                   \  }}‰j                   ||fk(  sJ ‚t        ˆ ˆfd„t        |«      D «       «      }|‰ j                  z  S )z6computes the intersection measure of two result tablesc              3   ój   •K  — | ]*  }t        j                  ‰|   ‰|   «      j                  –— Œ, y ­w©N)ÚnpÚintersect1dÚsize)Ú.0ÚiÚI1ÚI2s     €€úb/var/www/html/Fitness-lenito-AI-main/venv/lib/python3.12/site-packages/faiss/contrib/evaluation.pyÚ	<genexpr>z+knn_intersection_measure.<locals>.<genexpr>   s+   øè ø€ ÐF¹I°q”—‘  1¡ r¨!¡uÓ-×2Õ2¹Iùs   ƒ03)ÚshapeÚsumÚranger	   )r   r   ÚnqÚrankÚninters   ``   r   Úknn_intersection_measurer      sI   ù€ à�x‰x�H€BˆØ�8‰8˜˜D�zÒ!Ð!Ð!ÜÔF¼EÀ"¼IÓFÓF€FØ�B—G‘GÑÐó    c                 óÚ   — | j                   dz
  }||k  }t        j                  | «      }t        |«      D ]*  }||   || |   | |dz       j	                  «       z   ||dz   <   Œ, |||   ||   fS )zselect a set of resultsé   )r	   r   Ú
zeros_liker   r   )ÚlimsÚDÚIÚthreshr   ÚmaskÚnew_limsr   s           r   Úfilter_range_resultsr!      s{   € à	�‰�Q‰€BØˆv‰:€DÜ�}‰}˜TÓ"€HÜ�2ŽYˆØ" 1™+¨¨T°!©W°t¸AÀ¹E±{Ð(C×(GÑ(GÓ(IÑIˆ��Q‘Šð à�Q�t‘W˜a ™gÐ%Ð%r   c                 ó8  ‡ ‡‡‡‡‡	‡
— ˆˆ fd„Š
ˆˆfd„Š‰ j                   dz
  }‰j                   dz
  |k(  sJ ‚t        j                  |d¬«      Š	ˆˆ	ˆ
fd„}t        d«      }|j	                  |t        |«      «       t        ‰ dd ‰ dd	 z
  ‰dd ‰dd	 z
  ‰	|¬
«      S )ztcompute the precision and recall of range search results. The
    function does not take the distances into account.c                 ó    •— ‰‰|    ‰| dz       S ©Nr   © ©r   ÚIrefÚlims_refs    €€r   Úref_result_forz range_PR.<locals>.ref_result_for+   ó   ø€ Ø�H˜Q‘K (¨1¨q©5¡/Ð2Ð2r   c                 ó    •— ‰‰|    ‰| dz       S r$   r%   )r   ÚInewÚlims_news    €€r   Únew_result_forz range_PR.<locals>.new_result_for.   r*   r   r   Úint64©Údtypec                 ón   •—  ‰| «      } ‰| «      }t        j                  ||«      }t        |«      ‰| <   y r   )r   r   Úlen)ÚqÚgt_idsÚnew_idsÚinterr.   r   r)   s       €€€r   Úcompute_PR_forz range_PR.<locals>.compute_PR_for6   s:   ø€ ñ   Ó"ˆñ ! Ó#ˆô —‘˜v wÓ/ˆä˜“JˆˆqŠ	r   é   Néÿÿÿÿ©Úmode)r	   r   Úzerosr   Úmapr   Úcounts_to_PR)r(   r'   r-   r,   r<   r   r8   Úpoolr.   r   r)   s   ````    @@@r   Úrange_PRrA   '   s¡   þ€ õ3õ3ð 
�‰˜Ñ	€BØ�=‰=˜1Ñ Ò"Ð"Ð"ä�X‰X�b Ô(€Föô �b‹>€DØ‡H�Hˆ^œU 2›YÔ'äØ��ˆ�x  �}Ñ$Ø��ˆ�x  �}Ñ$ØØô	ð r   c                 óÞ  — |dk(  r\| j                  «       |j                  «       |j                  «       }}} |dkD  r||z  }nd}| dkD  r	|| z  }||fS |dk(  rd}||fS d}||fS |dk(  r~| dk(  }d| |<   || z  }||   dk(  j                  t        «      ||<   |dk(  }t        j                  ||   dk(  «      sJ ‚d||<   d||<   ||z  }|j                  «       |j                  «       fS t        «       ‚)zÐcomputes a  precision-recall for a set of queries.
    ngt = nb of GT results per query
    nres = nb of found results per query
    ninter = nb of correct results per query (smaller than nres of course)
    Úoverallr   ç      ð?ç        Úaverager   )r   ÚastypeÚfloatr   ÚallÚmeanÚAssertionError)	ÚngtÚnresr   r<   Ú	precisionÚrecallr   ÚrecallsÚ
precisionss	            r   r?   r?   O   s/  € ð ˆyÒØŸG™G›I t§x¡x£z°6·:±:³<�6ˆTˆà�!Š8Ø ™‰IàˆIà�Š7Ø˜c‘\ˆFð ˜&Ð Ð ð �QŠYØˆFð ˜&Ð Ð ð ˆFà˜&Ð Ð à	�Ò	ð �a‰xˆØˆˆD‰	à˜3‘,ˆØ˜d™ q™×0Ñ0´Ó7ˆ�‰ð �q‰yˆÜ�v‰v�f˜T‘l aÑ'Ô(Ð(Ð(Øˆˆt‰ØˆˆT‰
à˜d‘]ˆ
à�‰Ó  '§,¡,£.Ð0Ð0ô ÓÐr   c                 ó  — t        j                  |«      }t        j                  |«      }t        | «      dz
  }t        |«      D ]9  }| |   | |dz      }}||| }	||| }
|
j	                  «       }|	|   ||| |
|   ||| Œ; ||fS )z$sort 2 arrays using the first as keyr   )r   Ú
empty_liker3   r   Úargsort)r   r   r   r   ÚD2r   r   Úl0Úl1ÚiiÚdiÚos               r   Úsort_range_res_2r[   ~   s˜   € ä	�‰�qÓ	€BÜ	�‰�qÓ	€BÜ	ˆT‹�Q‰€BÜ�2ŽYˆØ�a‘˜$˜q 1™u™+ˆBˆØˆr�"ˆXˆØˆr�"ˆXˆØ�J‰J‹LˆØ�q‘Eˆˆ2ˆbˆ	Ø�q‘Eˆˆ2ˆb‰	ð ð ˆrˆ6€Mr   c                 ó¼   — t        j                  |«      }t        | «      dz
  }t        |«      D ]*  }| |   | |dz      }}||| ||| ||| j	                  «        Œ, |S r$   )r   rS   r3   r   Úsort)r   r   r   r   r   rV   rW   s          r   Úsort_range_res_1r^   �   sh   € Ü	�‰�qÓ	€BÜ	ˆT‹�Q‰€BÜ�2ŽYˆØ�a‘˜$˜q 1™u™+ˆBˆØ�b˜�Hˆˆ2ˆbˆ	Ø
ˆ2ˆbˆ	�‰Õð ð €Ir   c           	      óF  ‡ ‡‡‡‡‡‡‡‡— d|v rt        ‰ ‰«      Šd|v rt        ‰‰‰«      \  ŠŠˆˆ fd„Šˆˆˆfd„Š‰ j                  dz
  }‰j                  dz
  |k(  sJ ‚t        ‰«      }	t	        j
                  ||	dfd¬«      Šˆˆˆˆfd	„}
t        d
«      }|j                  |
t        |«      «       t	        j
                  |	«      }t	        j
                  |	«      }t        |	«      D ]6  }t        ‰dd…|df   ‰dd…|df   ‰dd…|df   |¬«      \  }}|||<   |||<   Œ8 ||fS )zŒcompute precision-recall values for range search results
    for several thresholds on the "new" results.
    This is to plot PR curves
    ÚrefÚnewc                 ó    •— ‰‰|    ‰| dz       S r$   r%   r&   s    €€r   r)   z4range_PR_multiple_thresholds.<locals>.ref_result_for­   r*   r   c                 ó2   •— ‰|    ‰| dz      }}‰|| ‰|| fS r$   r%   )r   rV   rW   ÚDnewr,   r-   s      €€€r   r.   z4range_PR_multiple_thresholds.<locals>.new_result_for°   s/   ø€ Ø˜!‘˜h q¨1¡u™oˆBˆØ�B�rˆ{˜D  B˜KÐ'Ð'r   r   é   r/   r0   c                 ó   •—  ‰	| «      } ‰| «      \  }}t        |«      ‰| d d …df<   |j                  dk(  ry t        j                  |‰
«      }|‰| d d …df<   |j                  dk(  ry t        j                  ||«      }d||t        |«      k(  <   t        j                  ||   |k(  «      }t        j
                  dg|f«      }||   ‰| d d …df<   y )Nr   r   r:   é   )r3   r	   r   ÚsearchsortedÚcumsumÚhstack)r4   r5   Úres_idsÚres_disrM   rX   Ún_okÚcountsr.   r)   Ú
thresholdss          €€€€r   r8   z4range_PR_multiple_thresholds.<locals>.compute_PR_forº   sÓ   ø€ Ù Ó"ˆÙ)¨!Ó,Ñˆ�ä˜f›+ˆˆq’!�Qˆw‰à�<‰<˜1Òàô �‰˜w¨
Ó3ˆØˆˆq’!�Qˆw‰à�;‰;˜!ÒØô �_‰_˜V WÓ-ˆØ "ˆˆ2”�V“ÑÑÜ�y‰y˜ ™ wÑ.Ó/ˆô �y‰y˜1˜#˜t˜Ó%ˆØ˜t™*ˆˆq’!�QˆwŠr   r9   Nr   rg   r;   )
r^   r[   r	   r3   r   r=   r   r>   r   r?   )r(   r'   r-   rd   r,   ro   r<   Údo_sortr   Úntr8   r@   rQ   rP   ÚtÚpÚrrn   r.   r)   s   ``````           @@@r   Úrange_PR_multiple_thresholdsru   —   s(  ÿø€ ð �ÑÜ ¨$Ó/ˆð �ÑÜ% h°°dÓ;‰
ˆˆdõ3ö(ð 
�‰˜Ñ	€BØ�=‰=˜1Ñ Ò"Ð"Ð"ä	ˆZ‹€BÜ�X‰X�r˜2˜q�k¨Ô1€F÷%ô4 �b‹>€DØ‡H�Hˆ^œU 2›YÔ'ô —‘˜"“€JÜ�h‰h�r‹l€GÜ�2ŽYˆÜØ’1�a˜�7‰O˜V¢A q¨! G™_¨f²Q¸¸1°W©oÀDô
‰ˆˆ1ð ˆ
�1‰Øˆ�Š
ð ð �wÐÐr   c                 ó0  — t        j                  | |g«      }|j                  «        t        |«      }t        j                  |«      }|dd |dd z
  |dd |||kD     }t        j
                  || d¬«      dz
  }t        j
                  ||d¬«      dz
  }||fS )zrfor two tables, cluster them by merging values closer than thr.
    Returns the cluster ids for each table elementr   Nr:   Úright)Úside)r   rj   r]   r3   Úonesrh   )	Útab1Útab2ÚthrÚtabÚnÚdiffsÚunique_valsÚidx1Úidx2s	            r   Ú_cluster_tables_with_tolerancerƒ   é   s—   € ô �)‰)�T˜4�LÓ
!€CØ‡H�H„JÜˆC‹€AÜ�G‰G�A‹J€EØ�A�B�˜#˜c˜r˜(Ñ"€Eˆ!ˆ"€IØ�e˜c‘kÑ"€KÜ�?‰?˜;¨°7Ô;¸aÑ?€DÜ�?‰?˜;¨°7Ô;¸aÑ?€DØ�ˆ:Ðr   c           
      óì  — t         j                  j                  | |||¬«       t        j                  «       }t        t        |«      «      D ]¦  }t        j                  ||   ||   k(  «      rŒ"|| |   j                  «       z  |z   }t        | |   ||   |«      \  }	}
t        j                  |	«      D ]>  }||	d   k(  rŒ|	|k(  }|j                  t        |||f   «      t        |||f   «      «       Œ@ Œ¨ y)zQtest that knn search results are identical, with possible ties.
    Raise if not.)ÚrtolÚatolr:   N)r   ÚtestingÚassert_allcloseÚunittestÚTestCaser   r3   rI   Úmaxrƒ   ÚuniqueÚassertEqualÚset)ÚDrefr'   rd   r,   r…   r†   Útestcaser   rt   ÚDrefCÚDnewCÚdisr   s                r   Úcheck_ref_knn_with_drawsr”   ÷   sæ   € ô ‡J�J×Ñ˜t T°¸4ÐÔ@ä× Ñ Ó"€HÜ”3�t“9ÖˆÜ�6‰6�$�q‘'˜T !™WÑ$Ô%Øð �4˜‘7—;‘;“=Ñ  4Ñ'ˆä5°d¸1±g¸tÀA¹wÈÓJ‰ˆˆuä—9‘9˜UÖ#ˆCØ�e˜B‘iÒØØ˜C‘<ˆDØ× Ñ ¤ T¨!¨T¨'¡]Ó!3´S¸¸aÀ¸g¹Ó5GÕHñ	 $ñ r   c                 ó®  — t         j                  j                  | |«       t        | «      dz
  }t	        |«      D ]™  }| |   | |dz      }	}|||	 }
|||	 }|||	 }|||	 }t        j
                  |
|k(  «      rn;d„ } ||
|«      \  }
} |||«      \  }}t         j                  j                  |
|«       t         j                  j                  ||d¬«       Œ› y)zKcompare range search results wrt. a reference result,
    throw if it failsr   c                 ó6   — | j                  «       }| |   ||   fS r   )rT   )r   r   rZ   s      r   Úsort_by_idsz,check_ref_range_results.<locals>.sort_by_ids  s   € Ø—I‘I“K�Ø˜‘t˜Q˜q™T�zÐ!r   é   )ÚdecimalN)r   r‡   Úassert_array_equalr3   r   rI   Úassert_array_almost_equal)ÚLrefr�   r'   ÚLnewrd   r,   r   r   rV   rW   ÚIi_refÚIi_newÚDi_refÚDi_newr—   s                  r   Úcheck_ref_range_resultsr¢     sÞ   € ô ‡J�J×!Ñ! $¨Ô-Ü	ˆT‹�Q‰€BÜ�2ŽYˆØ�a‘˜$˜q 1™u™+ˆBˆØ�b˜�ˆØ�b˜�ˆØ�b˜�ˆØ�b˜�ˆÜ�6‰6�&˜FÑ"Ô#Øò"ñ
  +¨6°6Ó:ÑˆV�VÙ*¨6°6Ó:ÑˆV�VÜ�J‰J×)Ñ)¨&°&Ô9Ü
�
‰
×,Ñ,¨V°VÀQÐ,ÕGñ% r   c                   ó:   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zd„ Zd„ Z	d„ Z
y	)
ÚOperatingPointszw
    Manages a set of search parameters with associated performance and time.
    Keeps the Pareto optimal points.
    c                 ó    — g | _         g | _        y r   )Úoperating_pointsÚsuboptimal_points©Úselfs    r   Ú__init__zOperatingPoints.__init__2  s   € ð!
ˆÔð "$ˆÕr   c                 ó   — t         ‚)z/return -1 if k1 > k2, 1 if k2 > k1, 0 otherwise©ÚNotImplementedError©r©   Úk1Úk2s      r   Úcompare_keyszOperatingPoints.compare_keys9  s   € ä!Ð!r   c                 ó   — t         ‚)zKparameters to say we do nothing, takes 0 time and has 0
        performancer¬   r¨   s    r   Údo_nothing_keyzOperatingPoints.do_nothing_key=  s
   € ô "Ð!r   c                 óH   — | j                   D ]  \  }}}||k\  sŒ||k  sŒ y y)NFT)r¦   )r©   Úperf_newÚt_newÚ_Úperfrr   s         r   Úis_pareto_optimalz!OperatingPoints.is_pareto_optimalB  s.   € Ø×/Ô/‰JˆAˆt�QØ�xÓ A¨£JÙð 0ð r   c                 ó®   — d}d}| j                   | j                  z   D ]2  \  }}}| j                  ||«      }|dkD  r||kD  r|}|dk  sŒ+||k  sŒ1|}Œ4 ||fS )z*predicts the bound on time and performancerE   rD   r   )r¦   r§   r±   )r©   ÚkeyÚmin_timeÚmax_perfÚkey2r¸   rr   Úcmps           r   Úpredict_boundszOperatingPoints.predict_boundsH  ss   € àˆØˆØ!×2Ñ2°T×5KÑ5KÔK‰MˆD�$˜Ø×#Ñ# C¨Ó.ˆCØ�QŠwØ�x’<Ø �HØ�Q‹wØ˜(“?Ø#‘Hð Lð ˜Ð!Ð!r   c                 óN   — | j                  |«      \  }}| j                  ||«      S r   )rÀ   r¹   )r©   r»   r½   r¼   s       r   Úshould_run_experimentz%OperatingPoints.should_run_experimentV  s*   € Ø#×2Ñ2°3Ó7Ñˆ�8Ø×%Ñ% h°Ó9Ð9r   c                 ó¶  — | j                  ||«      r©d}|t        | j                  «      k  rp| j                  |   \  }}}||k\  r:||k  r5| j                  j	                  | j                  j                  |«      «       n|dz  }|t        | j                  «      k  rŒp| j                  j	                  |||f«       y| j                  j	                  |||f«       y)Nr   r   TF)r¹   r3   r¦   r§   ÚappendÚpop)r©   r»   r¸   rr   r   Úop_LsÚperf2Út2s           r   Úadd_operating_pointz#OperatingPoints.add_operating_pointZ  sÍ   € Ø×!Ñ! $¨Ô*ØˆAà”c˜$×/Ñ/Ó0Ò0Ø#'×#8Ñ#8¸Ñ#;Ñ ��u˜bØ˜5’= Q¨"¢WØ×*Ñ*×1Ñ1°$×2GÑ2G×2KÑ2KÈAÓ2NÕOà˜‘F�Að ”c˜$×/Ñ/Ó0Ó0ð ×!Ñ!×(Ñ(¨#¨t°Q¨Ô8Øà×"Ñ"×)Ñ)¨3°°a¨.Ô9Ør   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rª   r±   r³   r¹   rÀ   rÂ   rÉ   r%   r   r   r¤   r¤   ,  s*   „ ñò
$ò"ò"ò
ò"ò:ór   r¤   c                   ó^   — e Zd ZdZd„ Zd„ Zd„ Zd„ Zd„ Ze	j                  fd„Zd„ Zd	„ Zd
„ Zy)ÚOperatingPointsWithRangeszõ
    Set of parameters that are each picked from a discrete range of values.
    An increase of each parameter is assumed to make the operation slower
    and more accurate.
    A key = int array of indices in the ordered set of parameters.
    c                 ó<   — t         j                  | «       g | _        y r   )r¤   rª   Úrangesr¨   s    r   rª   z"OperatingPointsWithRanges.__init__s  s   € Ü× Ñ  Ô&àˆ�r   c                 ó>   — | j                   j                  ||f«       y r   )rÑ   rÄ   ©r©   ÚnameÚvaluess      r   Ú	add_rangez#OperatingPointsWithRanges.add_rangex  s   € Ø�‰×Ñ˜D &˜>Õ*r   c                 óh   — t        j                  ||k\  «      ryt        j                  ||k\  «      ryy)Nr   r:   r   )r   rI   r®   s      r   r±   z&OperatingPointsWithRanges.compare_keys{  s+   € Ü�6‰6�"˜‘(ÔØÜ�6‰6�"˜‘(ÔØØr   c                 ó^   — t        j                  t        | j                  «      t        ¬«      S )Nr0   )r   r=   r3   rÑ   Úintr¨   s    r   r³   z(OperatingPointsWithRanges.do_nothing_key‚  s   € Ü�x‰xœ˜DŸK™KÓ(´Ô4Ð4r   c                 ó–   — t        t        j                  | j                  D ��cg c]  \  }}t	        |«      ‘Œ c}}«      «      S c c}}w r   )rÙ   r   ÚprodrÑ   r3   rÓ   s      r   Únum_experimentsz)OperatingPointsWithRanges.num_experiments…  s4   € Ü”2—7‘7¸D¿KºKÔH¹K©L¨D°&œC �K¸KÒHÓIÓJÐJùÓHs   ¤Ac                 ó@  — |dk(  s|dk\  sJ ‚| j                  «       }t        j                  j                  d«      }|dk(  s||k  r|j	                  |dz
  «      }n|j                  |dz
  |dz
  d¬«      }d|dz
  g|D �cg c]  }t        |«      dz   ‘Œ c}z   }|S c c}w )z|sample a set of experiments of max size n_autotune
        (run all experiments in random order if n_autotune is 0)
        r   rg   é{   F)r	   Úreplacer   )rÜ   r   ÚrandomÚRandomStateÚpermutationÚchoicerÙ   )r©   Ú
n_autotuneÚrsÚtotexÚexperimentsÚcnos         r   Úsample_experimentsz,OperatingPointsWithRanges.sample_experimentsˆ  s²   € ð ˜QŠ *°¢/Ð1Ð1Ø×$Ñ$Ó&ˆÜ�Y‰Y×"Ñ" 3Ó'ˆØ˜Š?˜e jÒ0ØŸ.™.¨°©Ó3‰KàŸ)™)Ø˜‘	 
¨Q¡¸ð $ó ˆKð ˜% !™)�nÁÓ'LÁ¸¬¨C«°1«ÀÑ'LÑLˆØÐùò (Ms   Á?Bc                 óî   — t        j                  t        | j                  «      t        ¬«      }t        | j                  «      D ]'  \  }\  }}|t        |«      z  ||<   |t        |«      z  }Œ) |dk(  sJ ‚|S )z/Convert a sequential experiment number to a keyr0   r   )r   r=   r3   rÑ   rÙ   Ú	enumerate)r©   rè   Úkr   rÔ   rÕ   s         r   Ú
cno_to_keyz$OperatingPointsWithRanges.cno_to_key™  si   € ä�H‰H”S˜Ÿ™Ó%¬SÔ1ˆÜ!*¨4¯;©;Ö!7ÑˆA‰~��fØœ˜V›Ñ$ˆAˆa‰DØ”C˜“KÑ‰Cð "8ð �aŠxˆˆxØˆr   c           	      óx   — t        | j                  «      D ���ci c]  \  }\  }}||||      “Œ c}}}S c c}}}w )z3Convert a key to a dictionary with parameter values)rë   rÑ   )r©   rì   r   rÔ   rÕ   s        r   Úget_parametersz(OperatingPointsWithRanges.get_parameters¢  sF   € ô 9BÀ$Ç+Á+Ô8Nõ
Ù8NÑ#4 1¡n t¨VˆD�&˜˜1™‘,ÑÐ8Nó
ð 	
ùô 
s   š5c                 ó”   — | j                   D ]&  \  }}||k(  sŒ|D �cg c]
  }||k  sŒ	|‘Œ }}||dd  y t        d|› d�«      ‚c c}w )z$remove too large values from a rangeNz
parameter z
 not found)rÑ   ÚRuntimeError)r©   rÔ   Úmax_valÚname2rÕ   ÚvÚval2s          r   Úrestrict_rangez(OperatingPointsWithRanges.restrict_range¨  s\   € à!Ÿ[œ[‰MˆE�6Ø�u‹}Ù#)Ó9¡6˜a¨Q°«[š 6�Ð9Ø �‘q�	Ùð	 )ô
 ˜Z¨ v¨ZÐ8Ó9Ð9ùò :s
   �
A¨AN)rÊ   rË   rÌ   rÍ   rª   rÖ   r±   r³   rÜ   r   rà   ré   rí   rï   rö   r%   r   r   rÏ   rÏ   k  s>   „ ñòò
+òò5òKð 13·	±	ó ò"ò
ó:r   rÏ   c                   ó   — e Zd Zd„ Zd„ Zy)Ú	TimerIterc                 ó    — g | _         |j                  | _        || _        |j                  dk\  r t	        j
                  |j                  «       y y )Nr   )ÚtsÚrunsÚtimerrq   ÚfaissÚomp_set_num_threads)r©   rü   s     r   rª   zTimerIter.__init__·  s=   € ØˆŒØ—J‘JˆŒ	ØˆŒ
Ø�8‰8�qŠ=Ü×%Ñ% e§h¡hÕ/ð r   c                 ó‚  — | j                   }| xj                  dz  c_        | j                  j                  t	        j                  «       «       t        | j                  «      dk\  r| j                  d   | j                  d   z
  nd}| j                  dk(  s||j                  kD  rš|j                  dk\  rt        j                  |j                  «       t        j                  | j                  «      }|dd  |d d z
  }t        |«      |j                  k(  r||j                  d  |_        t        ‚|d d  |_        t        ‚y )Nr   rg   r:   r   )rü   rû   rú   rÄ   Útimer3   Úmax_secsrq   rý   rþ   Úremember_ntr   ÚarrayÚwarmupÚtimesÚStopIteration)r©   rü   Ú
total_timerú   r  s        r   Ú__next__zTimerIter.__next__¾  sø   € Ø—
‘
ˆØ�	Š	�Q‰�	Ø�‰�‰”t—y‘y“{Ô#Ü14°T·W±W³ÀÒ1B�T—W‘W˜R‘[ 4§7¡7¨1¡:Ò-Èˆ
Ø�9‰9˜Š?˜j¨5¯>©>Ò9Ø�x‰x˜1Š}Ü×)Ñ)¨%×*;Ñ*;Ô<Ü—‘˜$Ÿ'™'Ó"ˆBØ�q�r�F˜R  ˜WÑ$ˆEÜ�5‹z˜UŸZ™ZÒ'Ø# E§L¡L NÐ3�”ô  Ðð $¡A˜h�”ÜÐð :r   N)rÊ   rË   rÌ   rª   r  r%   r   r   rø   rø   ¶  s   „ ò0ó r   rø   c                   óL   — e Zd ZdZdddej
                  fd„Zd„ Zd„ Zd„ Z	d	„ Z
y
)ÚRepeatTimeru!  
    This is yet another timer object. It is adapted to Faiss by
    taking a number of openmp threads to set on input. It should be called
    in an explicit loop as:

    timer = RepeatTimer(warmup=1, nt=1, runs=6)

    for _ in timer:
        # perform operation

    print(f"time={timer.get_ms():.1f} Â± {timer.get_ms_std():.1f} ms")

    the same timer can be re-used. In that case it is reset each time it
    enters a loop. It focuses on ms-scale times because for second scale
    it's usually less relevant to repeat the operation.
    r   r:   r   c                 ó|   — ||k  sJ ‚|| _         || _        || _        || _        t	        j
                  «       | _        y r   )r  rq   rû   r  rý   Úomp_get_max_threadsr  )r©   r  rq   rû   r  s        r   rª   zRepeatTimer.__init__â  s;   € Ø˜Š}Ðˆ}ØˆŒØˆŒØˆŒ	Ø ˆŒÜ ×4Ñ4Ó6ˆÕr   c                 ó   — t        | «      S r   )rø   r¨   s    r   Ú__iter__zRepeatTimer.__iter__ê  s   € Ü˜‹Ðr   c                 óF   — t        j                  | j                  «      dz  S )Néè  )r   rJ   r  r¨   s    r   ÚmszRepeatTimer.msí  s   € Ü�w‰w�t—z‘zÓ" TÑ)Ð)r   c                 óz   — t        | j                  «      dkD  r"t        j                  | j                  «      dz  S dS )Nr   r  rE   )r3   r  r   Ústdr¨   s    r   Úms_stdzRepeatTimer.ms_stdð  s.   € Ü,/°·
±
«O¸aÒ,?Œr�v‰v�d—j‘jÓ! DÑ(ÐHÀSÐHr   c                 ó,   — t        | j                  «      S )zQeffective number of runs (may be lower than runs - warmup due
        to timeout))r3   r  r¨   s    r   ÚnrunszRepeatTimer.nrunsó  s   € ô �4—:‘:‹Ðr   N)rÊ   rË   rÌ   rÍ   r   Úinfrª   r  r  r  r  r%   r   r   r
  r
  Ð  s0   „ ñð"   B¨Q¸¿¹ó 7òò*òIór   r
  )rC   )rC   zref,new)gñhãˆµøä>r   )Únumpyr   r‰   r   rý   Úmultiprocessing.poolr   r   r!   rA   r?   r[   r^   ru   rƒ   r”   r¢   r¤   rÏ   rø   r
  r%   r   r   Ú<module>r     s„   ðó Û Û Û å +òò&ó%óP,ò^òð" 
ØóJòdóIò,H÷><ñ <ô~D: ô D:÷V ñ  ÷4&ò &r   