class_docstr: manages a local index, that does the coarse quantization and a set
  of sub_indexes. The sub_indexes search a subset of the inverted
  lists. The SplitPerListIndex merges results from the sub-indexes
class_docstr_tok: ["manages","a","local","index",",","that","does","the","coarse","quantization","and","a","set","of","sub_indexes",".","The","sub_indexes","search","a","subset","of","the","inverted","lists",".","The","SplitPerListIndex","merges","results","from","the","sub-indexes"]
code: def range_search(self, x, radius):
      xqo, list_nos, coarse_dis = self.index.transform_and_assign(x)
      assign = self.balance_lists(list_nos)
      nq = len(x)
  
      def do_query(i):
          sub_index = self.sub_indexes[i]
          list_nos_i = list_nos.copy()
          list_nos_i[assign != i] = -1
          t0 = time.time()
          limi, Di, Ii = sub_index.ivf_range_search_preassigned(
              xqo, list_nos_i, coarse_dis, radius
          )
          if self.verbose:
              print("slice %d: %.3f s" % (i, time.time() - t0))
          return limi, Di, Ii
  
      D = [[] for i in range(nq)]
      I = [[] for i in range(nq)]
  
      sizes = np.zeros(nq, dtype=int)
      for lims, Di, Ii in self.pool.imap(do_query, range(self.ni)):
          for i in range(nq):
              l0, l1 = lims[i : i + 2]
              D[i].append(Di[l0:l1])
              I[i].append(Ii[l0:l1])
              sizes[i] += l1 - l0
      lims = np.zeros(nq + 1, dtype=int)
      lims[1:] = np.cumsum(sizes)
      D = np.hstack([j for i in D for j in i])
      I = np.hstack([j for i in I for j in i])
      return lims, D, I
  
imports: import time
  from faiss.contrib import rpc
  import combined_index
  import argparse
  from multiprocessing.pool import ThreadPool
  import faiss
  import numpy
label_desc: Use image node_id 8 for calling the SplitPerListIndex obj's underlying member method code with example usage: obj.range_search(x, radius) and returns: lims,  D,  I, limi,  Di,  Ii