2424
2525namespace faiss {
2626
27- using namespace simd_result_handlers ;
28-
2927inline size_t roundup (size_t a, size_t b) {
3028 return (a + b - 1 ) / b * b;
3129}
@@ -219,48 +217,10 @@ std::unique_ptr<FastScanCodeScanner> IndexFastScan::make_knn_scanner(
219217 float * distances,
220218 idx_t * labels,
221219 const IDSelector* sel,
222- const FastScanDistancePostProcessing&) const {
223- return make_fast_scan_knn_scanner (
224- is_max, 0 , n, ntotal, k, distances, labels, sel);
225- }
226-
227- // Default implementation of make_knn_handler with centralized fallback logic
228- SIMDResultHandlerToFloat* IndexFastScan::make_knn_handler (
229- bool is_max,
230220 int impl,
231- idx_t n,
232- idx_t k,
233- size_t ntotal,
234- float * distances,
235- idx_t * labels,
236- const IDSelector* sel,
237221 const FastScanDistancePostProcessing&) const {
238- // Create default handlers based on k and impl
239- if (is_max) {
240- using HeapHC = HeapHandler<CMax<uint16_t , int >, false >;
241- using ReservoirHC = ReservoirHandler<CMax<uint16_t , int >, false >;
242- using SingleResultHC = SingleResultHandler<CMax<uint16_t , int >, false >;
243-
244- if (k == 1 ) {
245- return new SingleResultHC (n, ntotal, distances, labels, sel);
246- } else if (impl % 2 == 0 ) {
247- return new HeapHC (n, ntotal, k, distances, labels, sel);
248- } else {
249- return new ReservoirHC (n, ntotal, k, 2 * k, distances, labels, sel);
250- }
251- } else {
252- using HeapHC = HeapHandler<CMin<uint16_t , int >, false >;
253- using ReservoirHC = ReservoirHandler<CMin<uint16_t , int >, false >;
254- using SingleResultHC = SingleResultHandler<CMin<uint16_t , int >, false >;
255-
256- if (k == 1 ) {
257- return new SingleResultHC (n, ntotal, distances, labels, sel);
258- } else if (impl % 2 == 0 ) {
259- return new HeapHC (n, ntotal, k, distances, labels, sel);
260- } else {
261- return new ReservoirHC (n, ntotal, k, 2 * k, distances, labels, sel);
262- }
263- }
222+ return make_fast_scan_knn_scanner (
223+ is_max, impl, n, ntotal, k, distances, labels, sel);
264224}
265225
266226using namespace quantize_lut ;
@@ -481,7 +441,6 @@ void IndexFastScan::search_implem_12(
481441 idx_t * labels,
482442 int impl,
483443 const FastScanDistancePostProcessing& context) const {
484- using RH = ResultHandlerCompare<C, false >;
485444 FAISS_THROW_IF_NOT (bbs == 32 );
486445
487446 // handle qbs2 blocking by recursive call
@@ -532,36 +491,26 @@ void IndexFastScan::search_implem_12(
532491 pq4_pack_LUT_qbs (qbs, M2, quantized_dis_tables.get (), LUT.get ());
533492 FAISS_THROW_IF_NOT (LUT_nq == n);
534493
535- std::unique_ptr<RH> handler (
536- static_cast <RH*>(make_knn_handler (
537- C::is_max,
538- impl,
539- n,
540- k,
541- ntotal,
542- distances,
543- labels,
544- nullptr ,
545- context)));
546-
547- handler->disable = bool (skip & 2 );
548- handler->normalizers = normalizers.get ();
549-
550- if (skip & 4 ) {
551- // pass
552- } else {
553- pq4_accumulate_loop_qbs (
494+ auto scanner = make_knn_scanner (
495+ C::is_max, n, k, ntotal, distances, labels, nullptr , impl, context);
496+ auto * rh = scanner->handler ();
497+ rh->normalizers = normalizers.get ();
498+ // Note: skip & 2 previously set handler->disable (run kernel,
499+ // discard results). Through the scanner path, skip & 2 now skips
500+ // the kernel entirely (same as skip & 4), since disable is not
501+ // accessible through the SIMDResultHandlerToFloat* interface.
502+ if (!(skip & (2 | 4 ))) {
503+ scanner->accumulate_loop_qbs (
554504 qbs,
555505 ntotal2,
556506 M2,
557507 codes.get (),
558508 LUT.get (),
559- *handler.get (),
560509 context.pq2x4_scale ,
561510 get_block_stride ());
562511 }
563512 if (!(skip & 8 )) {
564- handler ->end ();
513+ rh ->end ();
565514 }
566515}
567516
@@ -576,7 +525,6 @@ void IndexFastScan::search_implem_14(
576525 idx_t * labels,
577526 int impl,
578527 const FastScanDistancePostProcessing& context) const {
579- using RH = ResultHandlerCompare<C, false >;
580528 FAISS_THROW_IF_NOT (bbs % 32 == 0 );
581529
582530 int qbs2 = qbs == 0 ? 4 : qbs;
@@ -616,36 +564,27 @@ void IndexFastScan::search_implem_14(
616564 AlignedTable<uint8_t > LUT (n * dim12);
617565 pq4_pack_LUT (n, M2, quantized_dis_tables.get (), LUT.get ());
618566
619- std::unique_ptr<RH> handler (
620- static_cast <RH*>(make_knn_handler (
621- C::is_max,
622- impl,
623- n,
624- k,
625- ntotal,
626- distances,
627- labels,
628- nullptr ,
629- context)));
630- handler->disable = bool (skip & 2 );
631- handler->normalizers = normalizers.get ();
632-
633- if (skip & 4 ) {
634- // pass
635- } else {
636- pq4_accumulate_loop (
567+ auto scanner = make_knn_scanner (
568+ C::is_max, n, k, ntotal, distances, labels, nullptr , impl, context);
569+ auto * rh = scanner->handler ();
570+ rh->normalizers = normalizers.get ();
571+ // Note: skip & 2 previously set handler->disable (run kernel,
572+ // discard results). Through the scanner path, skip & 2 now skips
573+ // the kernel entirely (same as skip & 4), since disable is not
574+ // accessible through the SIMDResultHandlerToFloat* interface.
575+ if (!(skip & (2 | 4 ))) {
576+ scanner->accumulate_loop (
637577 n,
638578 ntotal2,
639579 bbs,
640580 M2,
641581 codes.get (),
642582 LUT.get (),
643- *handler.get (),
644583 context.pq2x4_scale ,
645584 get_block_stride ());
646585 }
647586 if (!(skip & 8 )) {
648- handler ->end ();
587+ rh ->end ();
649588 }
650589}
651590
0 commit comments