class_docstr: Builds ensembles out of runs that exist in the Backend
  
  This is used by EnsembleBuilderManager and created in a dask-client
  every time a run finishes and there is currently no EnsembleBuilder active.
docstr: Run the ensemble building process
  
  Parameters
  ----------
  iteration : int
      What iteration to associate with this run
  
  pynisher_context : str | None = None
      The pynisher context to run in. If None, defaults to
      multiprocessing.get_context(None)
  
  time_left : float | None = None
      How much time should be left for this run. Either this or `end_at` must
      be provided.
  
  end_at : float | None = None
      When this run should end. Either this or `time_left` must be provided.
  
  time_buffer : int = 5
      How much extra time to add as a buffer to this run. This means there is
      always some amount of time to do something useful.
  
  Returns
  -------
  (ensemble_history, nbest)
docstr_tok: ["Run","the","ensemble","building","process","Parameters","--","--","--","--","--","iteration",":","int","What","iteration","to","associate","with","this","run","pynisher_context",":","str","|","None","=","None","The","pynisher","context","to","run","in",".","If","None",",","defaults","to","multiprocessing.get_context","(","None",")","time_left",":","float","|","None","=","None","How","much","time","should","be","left","for","this","run",".","Either","this","or","`","end_at","`","must","be","provided",".","end_at",":","float","|","None","=","None","When","this","run","should","end",".","Either","this","or","`","time_left","`","must","be","provided",".","time_buffer",":","int","=","5","How","much","extra","time","to","add","as","a","buffer","to","this","run",".","This","means","there","is","always","some","amount","of","time","to","do","something","useful",".","Returns","--","--","--","-","(","ensemble_history",",","nbest",")"]
code: def run(
      self,
      iteration: int,
      pynisher_context: str | None = None,
      time_left: float | None = None,
      end_at: float | None = None,
      time_buffer: int = 5,
  ) -> tuple[list[dict[str, Any]], int | float]:
      """Run the ensemble building process
  
      Parameters
      ----------
      iteration : int
          What iteration to associate with this run
  
      pynisher_context : str | None = None
          The pynisher context to run in. If None, defaults to
          multiprocessing.get_context(None)
  
      time_left : float | None = None
          How much time should be left for this run. Either this or `end_at` must
          be provided.
  
      end_at : float | None = None
          When this run should end. Either this or `time_left` must be provided.
  
      time_buffer : int = 5
          How much extra time to add as a buffer to this run. This means there is
          always some amount of time to do something useful.
  
      Returns
      -------
      (ensemble_history, nbest)
      """
      if time_left is None and end_at is None:
          raise ValueError("Must provide either time_left or end_at.")
  
      elif time_left is not None and end_at is not None:
          raise ValueError("Cannot provide both time_left and end_at.")
  
      if not self.logger:
          self.logger = get_named_client_logger(
              name="EnsembleBuilder",
              port=self.logger_port,
          )
  
      process_start_time = time.time()
      while True:
          if time_left is not None:
              time_elapsed = time.time() - process_start_time
              time_left -= time_elapsed
          else:
              assert end_at is not None
              current_time = time.time()
              if current_time > end_at:
                  break
              else:
                  time_left = end_at - current_time
  
          wall_time_in_s = int(time_left - time_buffer)
          if wall_time_in_s < 1:
              break
  
          context = multiprocessing.get_context(pynisher_context)
          preload_modules(context)
  
          safe_ensemble_script = pynisher.enforce_limits(
              wall_time_in_s=wall_time_in_s,
              mem_in_mb=self.memory_limit,
              logger=self.logger,
              context=context,
          )(self.main)
  
          safe_ensemble_script(time_left, iteration)
  
          status = safe_ensemble_script.exit_status
          if isinstance(status, pynisher.MemorylimitException):
              # if ensemble script died because of memory error,
              # reduce nbest to reduce memory consumption and try it again
  
              # ATTENTION: main will start from scratch;
              # all data structures are empty again
              try:
                  self.previous_candidates_path.unlink()
              except:  # noqa E722
                  pass
  
              if (
                  isinstance(self.ensemble_nbest, numbers.Integral)
                  and self.ensemble_nbest <= 1
              ):
                  if self.read_at_most == 1:
                      self.logger.error(
                          "Memory Exception -- Unable to further reduce the number"
                          " of ensemble members and can no further limit the number"
                          " of ensemble members loaded per iteration, please restart"
                          " Auto-sklearn with a higher value for the argument"
                          f" `memory_limit` (current limit is {self.memory_limit}MB)."
                          " The ensemble builder will keep running to delete files"
                          " from disk in case this was enabled.",
                      )
                      self.ensemble_nbest = 0
                  else:
                      self.read_at_most = 1
                      self.logger.warning(
                          "Memory Exception -- Unable to further reduce the number of"
                          " ensemble members. Now reducing the number of predictions"
                          " per call to read at most to 1."
                      )
              else:
                  if isinstance(self.ensemble_nbest, numbers.Integral):
                      self.ensemble_nbest = max(
                          1, int(self.ensemble_nbest / 2)
                      )
                  else:
                      self.ensemble_nbest = self.ensemble_nbest / 2
                  self.logger.warning(
                      "Memory Exception -- restart with "
                      "less ensemble_nbest: %d" % self.ensemble_nbest
                  )
                  return [], self.ensemble_nbest
          elif isinstance(status, pynisher.AnythingException):
              return ([], self.ensemble_nbest)
          else:
              return safe_ensemble_script.result
  
      return [], self.ensemble_nbest
  
imports: from __future__ import annotations
  from typing import Any, Iterable, Mapping, Sequence, Type, cast
  import logging.handlers
  import multiprocessing
  import numbers
  import os
  import pickle
  import time
  import traceback
  from itertools import accumulate
  from pathlib import Path
  import numpy
  import pandas
  import pynisher
  from sklearn.utils.validation import check_random_state
  from autosklearn.automl_common.common.utils.backend import Backend
  from autosklearn.data.validation import SUPPORTED_FEAT_TYPES
  from autosklearn.data.xy_data_manager import XYDataManager
  from autosklearn.ensemble_building.run import Run, RunID
  from autosklearn.ensembles.abstract_ensemble import AbstractEnsemble
  from autosklearn.ensembles.ensemble_selection import EnsembleSelection
  from autosklearn.metrics import Scorer, calculate_loss, calculate_scores
  from autosklearn.util.disk import rmtree
  from autosklearn.util.functional import cut, findwhere, roundrobin, split
  from autosklearn.util.logging_ import get_named_client_logger
  from autosklearn.util.parallel import preload_modules
label_desc: Use image node_id 7 for calling the EnsembleBuilder obj's underlying member method code with example usage: obj.run(iteration, pynisher_context, time_left, end_at, time_buffer) and returns: list,  self, list,  self, list,  self, safe_ensemble_script