def initialize_environments(self,
                              batch_size=1,
                              parallelism=1,
                              per_env_kwargs=None,
                              **kwargs):
    """Initializes the environments.

    Args:
      batch_size: (int) Number of `self.base_env_name` envs to initialize.
      parallelism: (int) If this is greater than one then we run the envs in
        parallel using multi-threading.
      per_env_kwargs: (list or None) An optional list of dictionaries to pass to
        gym.make. If not None, length should match `batch_size`.
      **kwargs: (dict) Kwargs to pass to gym.make.
    """
    assert batch_size >= 1
    if per_env_kwargs is not None:
      assert batch_size == len(per_env_kwargs)
    else:
      per_env_kwargs = [{} for _ in range(batch_size)]

    # By now `per_env_kwargs` is a list of dictionaries of size batch_size.
    # The individual dictionaries maybe empty.

    def union_dicts(dict1, dict2):
      """Union `dict1` and `dict2`."""
      copy_dict1 = copy.copy(dict1)
      copy_dict1.update(dict2)
      return copy_dict1

    self._envs = [
        gym.make(self.base_env_name,
                 **union_dicts(kwargs, env_kwarg))
        for env_kwarg in per_env_kwargs
    ]
    self._parallelism = parallelism
    self._pool = multiprocessing.pool.ThreadPool(self._parallelism)
    if self._env_wrapper_fn is not None:
      self._envs = list(map(self._env_wrapper_fn, self._envs))

    self._verify_same_spaces()

    # If self.reward_range is None, i.e. this means that we should take the
    # reward range of the env.
    if self.reward_range is None:
      self._reward_range = self._envs[0].reward_range

    # This data structure stores the history of each env.
    #
    # NOTE: Even if the env is a NN and can step in all batches concurrently, it
    # is still valuable to store the trajectories separately.
    self._trajectories = trajectory.BatchTrajectory(batch_size=batch_size)
Initializes the environments.

    Args:
      batch_size: (int) Number of `self.base_env_name` envs to initialize.
      parallelism: (int) If this is greater than one then we run the envs in
        parallel using multi-threading.
      per_env_kwargs: (list or None) An optional list of dictionaries to pass to
        gym.make. If not None, length should match `batch_size`.
      **kwargs: (dict) Kwargs to pass to gym.make.
    
tensor2tensor/envs/gym_env_problem.py