class_docstr: Object that is responsible for evaluating asynchronous multiple agents.
  
  Args:
      n_steps (int): Number of timesteps used in each evaluation.
      n_episodes (int): Number of episodes used in each evaluation.
      eval_interval (int): Interval of evaluations in steps.
      outdir (str): Path to a directory to save things.
      max_episode_len (int): Maximum length of episodes used in evaluations.
      step_offset (int): Offset of steps used to schedule evaluations.
      save_best_so_far_agent (bool): If set to True, after each evaluation,
          if the score (= mean return of evaluation episodes) exceeds
          the best-so-far score, the current agent is saved.
class_docstr_tok: ["Object","that","is","responsible","for","evaluating","asynchronous","multiple","agents",".","Args",":","n_steps","(","int",")",":","Number","of","timesteps","used","in","each","evaluation",".","n_episodes","(","int",")",":","Number","of","episodes","used","in","each","evaluation",".","eval_interval","(","int",")",":","Interval","of","evaluations","in","steps",".","outdir","(","str",")",":","Path","to","a","directory","to","save","things",".","max_episode_len","(","int",")",":","Maximum","length","of","episodes","used","in","evaluations",".","step_offset","(","int",")",":","Offset","of","steps","used","to","schedule","evaluations",".","save_best_so_far_agent","(","bool",")",":","If","set","to","True",",","after","each","evaluation",",","if","the","score","(","=","mean","return","of","evaluation","episodes",")","exceeds","the","best-so-far","score",",","the","current","agent","is","saved","."]
code: def __init__(
      self,
      n_steps,
      n_episodes,
      eval_interval,
      outdir,
      max_episode_len=None,
      step_offset=0,
      save_best_so_far_agent=True,
      logger=None,
  ):
      assert (n_steps is None) != (n_episodes is None), (
          "One of n_steps or n_episodes must be None. "
          + "Either we evaluate for a specified number "
          + "of episodes or for a specified number of timesteps."
      )
      self.start_time = time.time()
      self.n_steps = n_steps
      self.n_episodes = n_episodes
      self.eval_interval = eval_interval
      self.outdir = outdir
      self.max_episode_len = max_episode_len
      self.step_offset = step_offset
      self.save_best_so_far_agent = save_best_so_far_agent
      self.logger = logger or logging.getLogger(__name__)
  
      # Values below are shared among processes
      self.prev_eval_t = mp.Value(
          "l", self.step_offset - self.step_offset % self.eval_interval
      )
      self._max_score = mp.Value("f", np.finfo(np.float32).min)
      self.wrote_header = mp.Value("b", False)
  
      # Create scores.txt
      with open(os.path.join(self.outdir, "scores.txt"), "a"):
          pass
  
imports: import logging
  import multiprocessing
  import os
  import statistics
  import time
  import numpy
  import chainerrl
label_desc: Use image node_id 1 to create a new AsyncEvaluator object from inherited base classes: object with example: obj = AsyncEvaluator(n_steps, n_episodes, eval_interval, outdir, max_episode_len, step_offset, save_best_so_far_agent, logger)