code: def run_train(args, ds, res):
      nq, d = ds.nq, ds.d
      nb, d = ds.nq, ds.d
  
      print("build index, key=", args.indexkey)
  
      index = faiss.index_factory(
          d,
          args.indexkey,
          faiss.METRIC_L2
          if ds.metric == "L2"
          else faiss.METRIC_INNER_PRODUCT,
      )
  
      index_ivf, vec_transform = unwind_index_ivf(index)
  
      if args.by_residual != -1:
          by_residual = args.by_residual == 1
          print("setting by_residual = ", by_residual)
          index_ivf.by_residual  # check if field exists
          index_ivf.by_residual = by_residual
  
      if index_ivf:
          print("Update add-time parameters")
          # adjust default parameters used at add time for quantizers
          # because otherwise the assignment is inaccurate
          quantizer = faiss.downcast_index(index_ivf.quantizer)
          if isinstance(quantizer, faiss.IndexRefine):
              print(
                  "   update quantizer k_factor=",
                  quantizer.k_factor,
                  end=" -> ",
              )
              quantizer.k_factor = 32 if index_ivf.nlist < 1e6 else 64
              print(quantizer.k_factor)
              base_index = faiss.downcast_index(quantizer.base_index)
              if isinstance(base_index, faiss.IndexIVF):
                  print(
                      "   update quantizer nprobe=",
                      base_index.nprobe,
                      end=" -> ",
                  )
                  base_index.nprobe = (
                      16
                      if base_index.nlist < 1e5
                      else 32
                      if base_index.nlist < 4e6
                      else 64
                  )
                  print(base_index.nprobe)
          elif isinstance(quantizer, faiss.IndexHNSW):
              hnsw = quantizer.hnsw
              print(
                  f"   update HNSW quantizer options, before: "
                  f"{hnsw.efSearch=:} {hnsw.efConstruction=:}"
              )
              hnsw.efSearch = 40 if index_ivf.nlist < 4e6 else 64
              hnsw.efConstruction = 200
              print(
                  f"       after: {hnsw.efSearch=:} {hnsw.efConstruction=:}"
              )
  
      apply_AQ_options(index_ivf or index, args)
  
      if index_ivf:
          index_ivf.verbose = True
          index_ivf.quantizer.verbose = True
          index_ivf.cp.verbose = True
      else:
          index.verbose = True
  
      maxtrain = args.maxtrain
      if maxtrain == 0:
          if "IMI" in args.indexkey:
              maxtrain = int(256 * 2 ** (np.log2(index_ivf.nlist) / 2))
          elif index_ivf:
              maxtrain = 50 * index_ivf.nlist
          else:
              # just guess...
              maxtrain = 256 * 100
          maxtrain = max(maxtrain, 256 * 100)
          print("setting maxtrain to %d" % maxtrain)
  
      try:
          xt2 = ds.get_train(maxtrain=maxtrain)
      except NotImplementedError:
          print("No training set: training on database")
          xt2 = ds.get_database()[:maxtrain]
  
      print("train, size", xt2.shape)
      assert np.all(np.isfinite(xt2))
  
      if isinstance(vec_transform, faiss.OPQMatrix) and isinstance(
          index_ivf, faiss.IndexIVFPQFastScan
      ):
          print("  Forcing OPQ training PQ to PQ4")
          ref_pq = index_ivf.pq
          training_pq = faiss.ProductQuantizer(
              ref_pq.d, ref_pq.M, ref_pq.nbits
          )
          vec_transform.pq
          vec_transform.pq = training_pq
  
      if args.get_centroids_from == "":
          if args.clustering_niter >= 0:
              print(
                  (
                      "setting nb of clustering iterations to %d"
                      % args.clustering_niter
                  )
              )
              index_ivf.cp.niter = args.clustering_niter
  
          if args.train_on_gpu:
              print("add a training index on GPU")
              train_index = faiss.index_cpu_to_all_gpus(
                  faiss.IndexFlatL2(index_ivf.d)
              )
              index_ivf.clustering_index = train_index
  
      else:
          print("Getting centroids from", args.get_centroids_from)
          src_index = faiss.read_index(args.get_centroids_from)
          src_quant = faiss.downcast_index(src_index.quantizer)
          centroids = src_quant.reconstruct_n()
          print("  centroid table shape", centroids.shape)
  
          if isinstance(vec_transform, faiss.VectorTransform):
              print("  training vector transform")
              vec_transform.train(xt2)
              print("  transform centroids")
              centroids = vec_transform.apply_py(centroids)
  
          if not index_ivf.quantizer.is_trained:
              print("  training quantizer")
              index_ivf.quantizer.train(centroids)
  
          print("  add centroids to quantizer")
          index_ivf.quantizer.add(centroids)
          del src_index
  
      t0 = time.time()
      index.train(xt2)
      res.train_time = time.time() - t0
      print("  train in %.3f s" % res.train_time)
      return index
  
file_path: faiss/benchs/bench_all_ivf/bench_all_ivf.py
imports: import argparse
  import os
  import sys
  import time
  import json
  import faiss
  import numpy
label_desc: Use image node_id 4 for calling a global function with example usage: run_train(args, ds, res) and returns: index