
    gD                         d dl Z d dlZd dlZd dlZd dlmZ d dlZd dlZd dlm	Z	 d dl
Z
d dlZd dlZd dlZd dlmZ  G d d          Z G d d          Zd	ej        ej        d d d
dddddd ddfdZdS )    N)
ThreadPool)Queue)get_invlistc                   f    e Zd ZdZ	 	 ddZd Zd Zd Zd Zd	 Z	d
 Z
d Zd Zd Zd Zd Zd ZdS )BigBatchSearcherz
    Object that manages all the data related to the computation
    except the actual within-bucket matching and the organization of the
    computation (parallel or not)
    r   Fc                 $   || _         g | _        || _        || _        || _        t          j        |j                  }t          j        t          |          ||          | _
        dgdz  | _        t          j                    x| _        | _        d S )N)keep_maxr      )verbosetictocxqindexuse_float16faissis_similarity_metricmetric_type
ResultHeaplenrht_accutime	t_displayt0)selfr   r   kr   r   r	   s          \/var/www/html/mpstechhub/venv/lib/python3.11/site-packages/faiss/contrib/big_batch_search.py__init__zBigBatchSearcher.__init__   s     
&-e.?@@"3r77AAAAcAg#'9;;.    c                 6    t          j                     | _        d S N)r   	t_accu_t0r   s    r   start_t_accuzBigBatchSearcher.start_t_accu0   s    r   c                 b    | j         |xx         t          j                    | j        z
  z  cc<   d S r    )r   r   r!   )r   ns     r   stop_t_accuzBigBatchSearcher.stop_t_accu3   s+    A$)++66r   c                 x    |t          j                     f| _        | j        dk    rt          |dd           d S d S )Nr   Tendflush)r   r   r   print)r   names     r   ticzBigBatchSearcher.tic6   sD    TY[[)<!$D------ r   c                     | j         \  }}t          j                    |z
  }| j        dk    rt          | d|dd           |S )Nr   z: .3fz s)r   r   r   r,   )r   r-   r   dts       r   toczBigBatchSearcher.toc;   sQ    ;bY[[2<!T''R''''(((	r   c                    | j         dk    s0| j         dk    r'|dk    r!t          j                    | j        dz   k     rd S t          j                    | j        z
  }t	          d|dd| d| j        j         d	| j        d
         dd| j        d         dd| j        d         dd| j        d         dd| j        d         dd| j        d         ddt          j	        || j        j        z  |dz   z  |z
             dt          j                     | j         dk    rdndd           t          j                    | _        d S )N      i  g      ?[z.1fz	 s] list /z times prep q r   r0   z prep b z comp z res    z	 wait in    z
 wait out    z eta )secondsz mem r(   
Tr)   )r   r   r   r   r,   r   nlistr   datetime	timedeltar   get_mem_usage_kb)r   lts      r   reportzBigBatchSearcher.reportB   s   <1LADTY[[4>C+??? FIKK$'!.7 . . . .DJ$4 . . KNM. .8<AM. .KNB. .-1[^B. . {1~,. . A-	. .
 %a
0@.@!A#.Fq.HIII. . )++. . **
	
 
	
 
	
 
	
 r   c                    |                      d           d}t          | j                  }t          j        || j        j        fd          }t          d||          D ]V}t          |||z             }| j        j	        
                    | j        ||         | j        j                  \  }}||||<   W|                                  || _        d S )Nzcoarse quantizationi   int32)dtyper   )r.   r   r   npemptyr   nproberangemin	quantizersearchr2   q_assign)r   bsnqrN   i0i1q_dis_i
q_assign_is           r   coarse_quantizationz$BigBatchSearcher.coarse_quantizationW   s    &'''\\8R!237CCC2r"" 	) 	)BRb!!B"&*"6"="=2
 1#3 #3GZ )HRUOO


 r   c                    |                      d           | j        }|dz  }t          j        | j        | j        j        dz   d          | _        | j                                        | _        | j	        dk    rt          d| j        d                    | j        dd          | _        | `|                                  d S )Nzbucket sortr4      )nbucketntr   z  number of -1s:)r.   rN   r   matrix_bucket_sort_inplacer   r=   bucket_limsravel	query_idsr   r,   r2   )r   rN   s     r   reorder_assignzBigBatchSearcher.reorder_assigne   s    =A ;M4:#3a#7B@ @ @,,..<!$d&6q&9:::+ABB/M




r   c                    t          j                     }| j        }| j        |         | j        |dz            }}| j        ||         }| j        |         }| j        r||j                            |          z
  }t          j                     }t          |j	        |          \  }	}
| j
        |
                                }
n| 
                    |
          }
| j        r*|
                    d          }
|                    d          }t          j                     }| j        dxx         ||z
  z  cc<   | j        dxx         ||z
  z  cc<   |||	|
fS )z4 prepare the queries and database items for bucket lr4   Nfloat16r   )r   r   r[   r]   r   by_residualrL   reconstructr   invlistsdecode_funcr\   r   astyper   )r   rA   r   r   rQ   rR   q_subsetxq_lt1list_idsxb_lt2s               r   prepare_bucketzBigBatchSearcher.prepare_bucketr   s<   Y[[
!!$d&6q1u&=B>"R%(wx  	9%/55a888DY[[$U^Q77$#::<<DD##D))D 	*;;y))D;;y))DY[[A"r'!A"r'!x--r   c                     |dS t          j                     }||}n||         }| j                            |||           | j        dxx         t          j                     |z
  z  cc<   dS )z,add the bucket results to the heap structureNr8   )r   r   add_result_subsetr   )r   rf   Dri   Ir   s         r   add_results_to_heapz$BigBatchSearcher.add_results_to_heap   sm    9FY[[9AAA!!(Aq111A$)++**r   c                 H    | j         j        | j        j        | j        j        fS r    )r   shaper   rI   r=   r"   s    r   sizes_in_checkpointz$BigBatchSearcher.sizes_in_checkpoint   s    tz0$*2BCCr   c                    |dz   }t          |d          5 }t          j        |                                 || j        j        | j        j        fd|d           d d d            n# 1 swxY w Y   t          j        ||           d S )Nz.tmpwb)sizes	completedr   )	openpickledumprt   r   ro   rp   osreplace)r   fnamerx   tmpnamefs        r   write_checkpointz!BigBatchSearcher.write_checkpoint   s    &.'4   	AK!5577!*79dgi0  b  	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	
7E"""""s   AA%%A),A)c                 >   t          |d          5 }t          j        |          }d d d            n# 1 swxY w Y   |d         |                                 k    sJ |d         d         | j        j        d d <   |d         d         | j        j        d d <   |d         S )Nrbrw   r   r   r4   rx   )rz   r{   loadrt   r   ro   rp   )r   r   r   ckps       r   read_checkpointz BigBatchSearcher.read_checkpoint   s    % 	!!+a..C	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	! 	!7|t779999994y|	!!!4y|	!!!;s   266N)r   F)__name__
__module____qualname____doc__r   r#   r&   r.   r2   rC   rU   r^   rl   rq   rt   r   r    r   r   r   r      s          	/ / / /$% % %7 7 7. . .
  % % %*! ! !  . . .8
+ 
+ 
+D D D
# 
# 
#         r   r   c                   :    e Zd ZdZdej        ej        fdZd ZdS )BlockComputerz computation within one bucket knn_functionc                    || _         |j        t          j        k    r%t          j        |j        |j                  }d }d}n|j        t          j        k    r\t          j        |j        |j	        j
        |j	        j        |j                  }|j	        |_	        |j	        j        }d|_        |j        }n~|j        t          j        k    rQt          j        |j        |j        j        |j                  }|j        |_        |j        j        }d|_        |j        }nt'          d|j         d          || _        |dk    rd n|| _        || _        || _        || _        || _        d S )Nc                 ,    |                      d          S )Nfloat32)view)xs    r   <lambda>z(BlockComputer.__init__.<locals>.<lambda>   s    AFF9$5$5 r   FTzindex type z not supportedr   )r   	__class__r   IndexIVFFlat	IndexFlatdr   
IndexIVFPQIndexPQpqMnbitsdecode
is_trainedra   IndexIVFScalarQuantizerIndexScalarQuantizersqqtypeRuntimeError
index_helprd   methodpairwise_distancesknn)r   r   r   r   r   r   rd   ra   s           r   r   zBlockComputer.__init__   sP    
?e000%2CDDJ55KKK_ 000UX^U5FH HJ!HJM$-.K$(J!+KK_ ===3):< <J!HJM$-.K$(J!+KKLU_LLLMMM$#)W#4#444+&"4r   c                    | j         j        }|j        dk    s|j        dk    rd x}}n| j        dk    rWt	          j        || j        j                   t          |          | j        _	        | j        
                    ||          \  }}nF| j        dk    r|                     |||          }d }n | j        dk    r | j        |||fd|i|\  }}||fS )Nr   r   r   )metricr   r   )r   r   sizer   r   copy_array_to_vectorr   codesr   ntotalrM   r   r   )	r   rg   rj   ri   r   
extra_argsr   ro   rp   s	            r   block_searchzBlockComputer.block_search   s    j,9>>TY!^^LA[G##&tT_-BCCC%(]]DO"?))$22DAqq[000''d;'GGAAA[N**48D$LL+LLLDAq!tr   N)	r   r   r   r   r   r   r   r   r   r   r   r   r   r      sN        ))
 "$7	! ! ! !F    r   r   r   Fr4   i   ry   c                    
123  j         }|dv sJ |j        }t          |          |z  t          j        d          j        z  }t          |          z  t          j        d          j        t          j        d          j        z   z  }||z   |z   }|dk    r(t          j        d| d| d| d	| d
|dz  dd           t           |||          1t           |||          22j
        1_
        2j        1_        |1                                 n|1_        1                                 | j        }t!                      }|||fd j        fk    sJ t"          j                            |          rQt          j        d|            1                    |          }t          j        dt          |                      nt          j        d           |dk    rt+          ||          D ]}1                    |           1                    |          \  }}}}t1          j                    }2                    |||          \  }}1j        dxx         t1          j                    |z
  z  cc<   1                    ||||           n|dk    r1 fd}1                    |          } d}!t9          d          }"t+          ||          D ]}1                    |           |"                    ||!|dz   f          }#| \  }}}}1                                 2                    |||          \  }}1                    d           ||||f}!1                                 |#                                 } 1                    d            1j        |!  |"!                                 nd 33fd}$d#1fd	}%2
fd}&tE          d          }'tE          d          }( |$|&
d
t!                      |(|'          }) |$|%|	||||'d          }*t1          j                    }+	 t          j        d           |(                                 },|,sn |,\  }-}.}/}0}}}}|-|k    rddz   1j        dxx         |0z  cc<   1j        dxx         |.z  cc<   1j        dxx         |/z  cc<   t          j        d|-            1                    ||||           t          j        d |-            |#                    |-           1                    |-           |Wt1          j                    |+z
  |k    r=t          j        d!           1$                    ||           t1          j                    }+L|*%                                 |)%                                 1&                    d"           1j'        (                                 1)                                 1j'        j*        1j'        j+        fS )$a  
    Search queries xq in the IVF index, with a search function that collects
    batches of query vectors per inverted list. This can be faster than the
    regular search indexes.
    Supports IVFFlat, IVFPQ and IVFScalarQuantizer.

    Supports three computation methods:
    method = "index":
        build a flat index and populate it separately for each index
    method = "pairwise_distances":
        decompress codes and compute all pairwise distances for the queries
        and index and add result to heap
    method = "knn_function":
        decompress codes and compute knn results for the queries

    threaded=0: sequential execution
    threaded=1: prefetch next bucket while computing the current one
    threaded=2: prefetch prefetch_threads buckets at a time.

    compute_threads>1: the knn function will get an additional thread_no that
        tells which worker should handle this.

    In threaded mode, the computation is tiled with the bucket perparation and
    the writeback of results (useful to maximize GPU utilization).

    use_float16: convert all matrices to float16 (faster for GPU gemm)

    q_assign: override coarse assignment, should be a matrix of size nq * nprobe

    checkpointing (only for threaded > 1):
    checkpoint: file where the checkpoints are stored
    checkpoint_freq: when to perform checkpoinging. Should be a multiple of threaded

    start_list, end_list: process only a subset of invlists
    )r   r   r   rE   int64r   r   zmemory: queries z assign z result z total z = i   @r0   z GiB)r   r   )r   r   r   Nzrecovering checkpoint: z   already completed: z$no checkpoint: starting from scratchr5   r4   c                 `    | 
 j         |   |j        k     r                    |          S dS )z` perform the addition for the previous bucket and
            prefetch the next (if applicable) N)rq   r=   rl   )to_addrA   bbsr   s     r   add_results_and_prefetchz2big_batch_search.<locals>.add_results_and_prefetcha  sA     !''005;))!,,, r   r9   c                    	 	 t          |          5 		 fdt          ||          D             }|D ]}|                                 	                                 	                                 d d d            n# 1 swxY w Y                       d            d S #  t          j                     t          j	                      xY w)Nc                 L    g | ] }|v                     |f           !S ))args)apply_async).0irx   input_queueoutput_queuepooltasks     r   
<listcomp>zAbig_batch_search.<locals>.task_manager_thread.<locals>.<listcomp>  sT     / / / I--	  ++{; , = = .--r   )
r   rJ   getclosejoinput	traceback	print_exc_threadinterrupt_main)
r   	pool_size
start_taskend_taskrx   r   r   resrr   s
   `   ```  @r   task_manager_threadz-big_batch_search.<locals>.task_manager_thread~  s4   	** 	 d/ / / / / / / / "'z8!<!</ / /C
 !    JJLLLIIKKK	  	  	  	  	  	  	  	  	  	  	  	  	  	  	    &&&&&#%%%&(((s/   B& A"B8B& BB& BB& &)Cc                  j    t          j        |           }d|_        |                                 |S )N)targetr   T)	threadingThreaddaemonstart)r   task_managerr   s     r   r   z&big_batch_search.<locals>.task_manager  sB    $+*  L #'L   r   c                 &   	 t          j        d|                                 |           \  }}}}|                    | ||||f           t          j        d|             d S #  t	          j                     t          j                      xY w)NzPrepare start: zPrepare end: )logginginforl   r   r   r   r   r   )task_idr   r   rf   rg   ri   rj   r   s          r   prepare_taskz&big_batch_search.<locals>.prepare_task  s    8w88999141C1CG1L1L.$$  '8T8T!JKKK6W6677777#%%%&(((s   A"A' ')Bc           
      t   	 t          j        d|             d}	 t          j                    }t          j        d|             |                                }t          j                    |z
  }||                    d            n|\  }}}	}
}t          j        d|  d|            t          j                    }dk    r                    |	||
|           \  }}n                    |	||
          \  }}t          j                    |z
  }t          j        d	|  d|            t          j                    }|                    |||||||
|f           t          j                    |z
  }Xt          j        d
|             d S #  t          j                     t          j	                      xY w)NzCompute start: r   TzCompute input: task zCompute work: task z, centroid r4   )	thread_idzCompute output: task zCompute end: )
r   r   r   r   r   r   r   r   r   r   )r   r   r   
t_wait_outr   input_value	t_wait_incentroidrf   rg   ri   rj   ro   rp   	t_computecompcomputation_threadsr   s                  r   compute_taskz&big_batch_search.<locals>.compute_task  s    8w88999
2BL!A!A!ABBB"-//"3"3K $	b 0I"*#---?J<HhhL!Uw!U!U8!U!UVVVB*Q..#00 $!w  1    11  $00tXqII1 $	b 0IL!W!W!WX!W!WXXXB $$!9j)XqRZ\]^   "&r!1J122 6W6677777#%%%&(((s   F	F )F7TzWaiting for resultr:   zAdding to heap start: centroid zAdding to heap end: centroid zwriting checkpointzfinalize heapr    ),rI   nbytesr   rG   rF   itemsizer   r   r   r   rd   ra   rU   rN   r^   r=   setr}   pathexistsr   rJ   rC   rl   r   r   r   rq   r   r   r#   r&   r   r   r   addr   r   r.   r   finalizer2   ro   rp   )4r   r   r   r   r   r   r   threadedr   prefetch_threadsr   rN   
checkpointcheckpoint_freq
start_listend_listcrash_atrI   mem_queries
mem_assignmem_resmem_totrx   rA   rf   rg   ri   rj   t0iro   rp   r   prefetched_bucketr   r   prefetched_bucket_ar   r   r   prepare_to_compute_queuecompute_to_main_queuecompute_task_managerprepare_task_managert_checkpointvaluer   r   r   r   r   r   r   s4   ` `       `                                      @@@r   big_batch_searchr     s   h \FDDDDD)KR6!BHW$5$5$>>J"ggk
"
(9


&	'G J&0G{{N{ N NJ N NN N&-N N29U2CMN N N	
 	
 	

 r1  C -	  D &CO&CO!!!!;IH%!U[)999997>>*%% 	AL?:??@@@++J77ILB#i..BBCCCCL?@@@1}} z8,, 	> 	>AJJqMMM-0-?-?-B-B*HdHd)++C$$T41==DAqJqMMMTY[[3..MMM##Ha1====	> 
Q	- 	- 	- 	- 	- 	-  ..z::!}}z8,, 	 	AJJqMMM"&"2"2(61q5/#; #;->*HdHd$$T41==DAqOOAq(A-F 3 7 7 9 9OOA((

	 	 	4	  	  	  	  	 		 		 		 		 		 		!	 !	 !	 !	 !	 !	 !	F $)88  %a+|EE!$ 
  
  ,|$ 
  
 y{{	/L-...)--//E SXPHiY!Xq8##AJqMMMY&MMMJqMMMY&MMMJqMMMZ'MMMLE8EEFFF##Ha1===LCCCDDDMM(###JJx   %9;;-??L!5666((Y???#'9;;L+	/. 	!!###!!###GGOFOOGGIII68SVXr   )r   r{   r}   r   multiprocessing.poolr   r   r   queuer   r   r>   numpyrG   r   faiss.contrib.inspect_toolsr   r   r   r   r   r  r   r   r   <module>r     sO     				  + + + + + +                      3 3 3 3 3 3X  X  X  X  X  X  X  X v5 5 5 5 5 5 5 5t  3IY Y Y Y Y Yr   