docs: def parallel_map(client, task, args, message, batchsize=1, background=False, nargs=None):
      """
      Helper to map a function over a sequence of inputs, in parallel, with progress meter.
      :param client: IPython.parallel.Client instance
      :param task: Function
      :param args: Must be a list of tuples of arguments that the task function will be mapped onto.
                   If the function takes a single argument, it still must be a 1-tuple.
      :param message: String for progress bar
      :param batchsize: Jobs are shipped in batches of this size. Higher numbers mean less network traffic,
                        but longer execution time per job.
      :return: IPython.parallel.AsyncMapResult
      """
      show_progress = bool(message)
      njobs = get_njobs(nargs, args)
      nproc = len(client)
      logger.debug('parallel_map: len(client) = {}'.format(len(client)))
      view = client.load_balanced_view()
      if show_progress:
          message += ' (IP:{}w:{}b)'.format(nproc, batchsize)
          pbar = setup_progressbar(message, njobs, simple_progress=True)
          if not background:
              pbar.start()
      map_result = view.map(task, *list(zip(*args)), chunksize=batchsize)
      if background:
          return map_result, client
      while not map_result.ready():
          map_result.wait(1)
          if show_progress:
              pbar.update(min(njobs, map_result.progress * batchsize))
      if show_progress:
          pbar.finish()
      return map_result