code: def build_learner(args, bandits, download_mnist):
      # set up loggers:
      logger = logging.getLogger()
      level = logging.INFO
      if "RANK" in os.environ and os.environ["RANK"] != "0":
          level = logging.CRITICAL
      logger.setLevel(level)
      visualizer = (
          visdom.Visdom(args.visdom) if args.visualize else None
      )
  
      # allow comparisons between plain and private algorithm:
      if args.seed is not None:
          torch.manual_seed(args.seed)
          random.seed(args.seed)
  
      if args.plaintext:
          logging.info("Using plain text bandit")
          kwargs = {"dtype": torch.double, "device": "cpu"}
      else:
          logging.info(f"Using encrypted bandit with {args.backend}")
          kwargs = {
              "backend": args.backend,
              "precision": args.precision,
              "nr_iters": args.nr_iters,
          }
  
      # set up variables for progress monitoring:
      window = [None]
      title = "Cumulative reward (encrypted %s, epsilon = %2.2f)" % (
          args.learner,
          args.epsilon,
      )
      progress_iter = 100
      buffers = {
          key: [None] * progress_iter
          for key in ["idx", "reward", "cumulative_reward", "iter_time"]
      }
  
      # closures that perform progress monitoring and checkpointing:
      monitor_func = get_monitor_func(
          args, buffers, visualizer, window, title, progress_iter
      )
      checkpoint_func = get_checkpoint_func(args)
  
      # compute pca:
      context, _ = load_data(
          split=args.mnist_split,
          pca=None,
          download_mnist_func=download_mnist,
      )
      pca = examples.util.pca(context, args.pca)
  
      # create or load clustering if custom number of arms is used:
      clusters = None
      if args.number_arms is not None:
          clusters_file = "clusters_K=%d_pca=%d.torch" % (
              args.number_arms,
              args.pca,
          )
          clusters_file = os.path.join(
              args.memoize_folder, clusters_file
          )
  
          # load precomputed clusters from file:
          if os.path.exists(clusters_file):
              logging.info("Loading clusters from file...")
              clusters = torch.load(clusters_file)
          else:
              # load data and allocate clusters:
              context, _ = load_data(
                  split=args.mnist_split,
                  pca=pca,
                  download_mnist_func=download_mnist,
              )
              clusters = context.new(
                  (args.number_arms, context.size(1))
              )
  
              # run clustering in process 0:
              if (
                  not torch.distributed.is_initialized()
                  or torch.distributed.get_rank() == 0
              ):
                  logging.info("Performing clustering to get arms...")
                  clusters = examples.util.kmeans(
                      context, args.number_arms
                  )
                  torch.save(clusters, clusters_file)
  
              # if run is distributed, synchronize clusters:
              if torch.distributed.is_initialized():
                  torch.distributed.barrier()
                  torch.distributed.broadcast(clusters, 0)
  
      # run contextual bandit algorithm on MNIST:
      sampler = load_data_sampler(
          split=args.mnist_split,
          pca=pca,
          clusters=clusters,
          bandwidth=args.bandwidth,
          permfile=args.permfile,
          download_mnist_func=download_mnist,
      )
      assert hasattr(bandits, args.learner), (
          "unknown learner: %s" % args.learner
      )
  
      def learner_func():
          getattr(bandits, args.learner)(
              sampler,
              epsilon=args.epsilon,
              monitor_func=monitor_func,
              checkpoint_func=checkpoint_func,
              checkpoint_every=args.checkpoint_every,
              **kwargs,
          )
  
      return learner_func
  
file_path: CrypTen/examples/bandits/launcher.py
imports: import argparse
  import logging
  import os
  import random
  import examples.util
  import torch
  import visdom
  from examples.multiprocess_launcher import MultiProcessLauncher
  from examples.util import NoopContextManager, process_mnist_files
  from torchvision.datasets.mnist import MNIST
label_desc: Use image node_id 8 for calling a global function with example usage: build_learner(args, bandits, download_mnist) and returns: learner_func