properly propagate exceptions in inverted list reading (#1407)
Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/1407 When Inverted list reading throws an exception, it is propagated until it reaches the openmp loop, which crashes the caller. This diff catches the exception and properly propagates it to the caller in Python. It should be possible to test it with an ondisk instead of relying on Manifold. Reviewed By: MDSilber Differential Revision: D23688968 fbshipit-source-id: 0943fac41d4e9b8b86535439e3fdee18ce96d4a5pull/1410/head
parent
8f6a019ecd
commit
d2d32af6c5
|
@ -255,6 +255,8 @@ void IndexIVF::make_direct_map (bool b)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void IndexIVF::set_direct_map_type (DirectMap::Type type)
|
||||
{
|
||||
direct_map.set_type (type, invlists, ntotal);
|
||||
|
@ -280,7 +282,6 @@ void IndexIVF::search (idx_t n, const float *x, idx_t k,
|
|||
}
|
||||
|
||||
|
||||
|
||||
void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
||||
const idx_t *keys,
|
||||
const float *coarse_dis ,
|
||||
|
@ -297,6 +298,7 @@ void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
|||
using HeapForL2 = CMax<float, idx_t>;
|
||||
|
||||
bool interrupt = false;
|
||||
std::string exception_string;
|
||||
|
||||
int pmode = this->parallel_mode & ~PARALLEL_MODE_NO_HEAP_INIT;
|
||||
bool do_heap_init = !(this->parallel_mode & PARALLEL_MODE_NO_HEAP_INIT);
|
||||
|
@ -307,6 +309,7 @@ void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
|||
pmode == 1 ? nprobe > 1 :
|
||||
nprobe * n > 1);
|
||||
|
||||
|
||||
#pragma omp parallel if(do_parallel) reduction(+: nlistv, ndis, nheap)
|
||||
{
|
||||
InvertedListScanner *scanner = get_InvertedListScanner(store_pairs);
|
||||
|
@ -375,19 +378,26 @@ void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
|||
|
||||
nlistv++;
|
||||
|
||||
InvertedLists::ScopedCodes scodes (invlists, key);
|
||||
try {
|
||||
InvertedLists::ScopedCodes scodes (invlists, key);
|
||||
|
||||
std::unique_ptr<InvertedLists::ScopedIds> sids;
|
||||
const Index::idx_t * ids = nullptr;
|
||||
std::unique_ptr<InvertedLists::ScopedIds> sids;
|
||||
const Index::idx_t * ids = nullptr;
|
||||
|
||||
if (!store_pairs) {
|
||||
sids.reset (new InvertedLists::ScopedIds (invlists, key));
|
||||
ids = sids->get();
|
||||
if (!store_pairs) {
|
||||
sids.reset (new InvertedLists::ScopedIds (invlists, key));
|
||||
ids = sids->get();
|
||||
}
|
||||
|
||||
nheap += scanner->scan_codes (list_size, scodes.get(),
|
||||
ids, simi, idxi, k);
|
||||
|
||||
} catch(const std::exception & e) {
|
||||
exception_string = demangle_cpp_symbol(typeid(e).name()) + " " + e.what();
|
||||
interrupt = true;
|
||||
return size_t(0);
|
||||
}
|
||||
|
||||
nheap += scanner->scan_codes (list_size, scodes.get(),
|
||||
ids, simi, idxi, k);
|
||||
|
||||
return list_size;
|
||||
};
|
||||
|
||||
|
@ -505,7 +515,11 @@ void IndexIVF::search_preassigned (idx_t n, const float *x, idx_t k,
|
|||
} // parallel section
|
||||
|
||||
if (interrupt) {
|
||||
FAISS_THROW_MSG ("computation interrupted");
|
||||
if (!exception_string.empty()) {
|
||||
FAISS_THROW_FMT ("search interrupted with: %s", exception_string.c_str());
|
||||
} else {
|
||||
FAISS_THROW_MSG ("computation interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
indexIVF_stats.nq += n;
|
||||
|
@ -546,6 +560,9 @@ void IndexIVF::range_search_preassigned (
|
|||
size_t nlistv = 0, ndis = 0;
|
||||
bool store_pairs = false;
|
||||
|
||||
bool interrupt = false;
|
||||
std::string exception_string;
|
||||
|
||||
std::vector<RangeSearchPartialResult *> all_pres (omp_get_max_threads());
|
||||
|
||||
#pragma omp parallel reduction(+: nlistv, ndis)
|
||||
|
@ -570,14 +587,22 @@ void IndexIVF::range_search_preassigned (
|
|||
|
||||
if (list_size == 0) return;
|
||||
|
||||
InvertedLists::ScopedCodes scodes (invlists, key);
|
||||
InvertedLists::ScopedIds ids (invlists, key);
|
||||
try {
|
||||
|
||||
InvertedLists::ScopedCodes scodes (invlists, key);
|
||||
InvertedLists::ScopedIds ids (invlists, key);
|
||||
|
||||
scanner->set_list (key, coarse_dis[i * nprobe + ik]);
|
||||
nlistv++;
|
||||
ndis += list_size;
|
||||
scanner->scan_codes_range (list_size, scodes.get(),
|
||||
ids.get(), radius, qres);
|
||||
|
||||
} catch(const std::exception & e) {
|
||||
exception_string = demangle_cpp_symbol(typeid(e).name()) + " " + e.what();
|
||||
interrupt = true;
|
||||
}
|
||||
|
||||
scanner->set_list (key, coarse_dis[i * nprobe + ik]);
|
||||
nlistv++;
|
||||
ndis += list_size;
|
||||
scanner->scan_codes_range (list_size, scodes.get(),
|
||||
ids.get(), radius, qres);
|
||||
};
|
||||
|
||||
if (parallel_mode == 0) {
|
||||
|
@ -634,6 +659,15 @@ void IndexIVF::range_search_preassigned (
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
if (interrupt) {
|
||||
if (!exception_string.empty()) {
|
||||
FAISS_THROW_FMT ("search interrupted with: %s", exception_string.c_str());
|
||||
} else {
|
||||
FAISS_THROW_MSG ("computation interrupted");
|
||||
}
|
||||
}
|
||||
|
||||
indexIVF_stats.nq += nx;
|
||||
indexIVF_stats.nlist += nlistv;
|
||||
indexIVF_stats.ndis += ndis;
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#include <faiss/impl/FaissException.h>
|
||||
#include <sstream>
|
||||
|
||||
#ifdef __GNUG__
|
||||
#include <cxxabi.h>
|
||||
#endif
|
||||
|
||||
namespace faiss {
|
||||
|
||||
FaissException::FaissException(const std::string& m)
|
||||
|
@ -63,4 +67,26 @@ void handleExceptions(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// From
|
||||
// https://stackoverflow.com/questions/281818/unmangling-the-result-of-stdtype-infoname
|
||||
|
||||
std::string demangle_cpp_symbol(const char* name) {
|
||||
#ifdef __GNUG__
|
||||
int status = -1;
|
||||
const char * res = abi::__cxa_demangle(name, nullptr, nullptr, &status);
|
||||
std::string sres;
|
||||
if (status == 0) {
|
||||
sres = res;
|
||||
}
|
||||
free((void*)res);
|
||||
return sres;
|
||||
#else
|
||||
// don't know how to do this on other platforms
|
||||
return std::string(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -66,6 +66,10 @@ struct ScopeDeleter1 {
|
|||
}
|
||||
};
|
||||
|
||||
/// make typeids more readable
|
||||
std::string demangle_cpp_symbol(const char* name);
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue