docs: def load_application(self, *args, **kwargs):
          """Load an application to a set of application cores.
  
          This method guarantees that once it returns, all required cores will
          have been loaded. If this is not possible after a small number of
          attempts, a :py:exc:`.SpiNNakerLoadingError` will be raised.
  
          This method can be called in either of the following ways::
  
              load_application("/path/to/app.aplx", {(x, y): {core, ...}, ...})
              load_application({"/path/to/app.aplx": {(x, y): {core, ...}, ...},
                                ...})
  
          Note that the latter format is the same format produced by
          :py:func:`~rig.place_and_route.util.build_application_map`.
  
          Parameters
          ----------
          app_id : int
          wait : bool
              Leave the application in a wait state after successfully loading
              it.
          n_tries : int
              Number attempts to make to load the application.
          app_start_delay : float
              Time to pause (in seconds) after loading to ensure that the
              application successfully reaches the wait state before checking for
              success.
          use_count : bool
              If True (the default) then the targets dictionary will be assumed
              to represent _all_ the cores that will be loaded and a faster
              method to determine whether all applications have been loaded
              correctly will be used. If False a fallback method will be used.
  
          Raises
          ------
          rig.machine_control.machine_controller.SpiNNakerLoadingError
              This exception is raised after some cores failed to load after
              ``n_tries`` attempts.
          """
          # Get keyword arguments
          app_id = kwargs.pop("app_id")
          wait = kwargs.pop("wait")
          n_tries = kwargs.pop("n_tries")
          app_start_delay = kwargs.pop("app_start_delay")
          use_count = kwargs.pop("use_count", True)
  
          # Coerce the arguments into a single form.  If there are two arguments
          # then assume that we have filename and a map of chips and cores;
          # otherwise there should be ONE argument which is of the form of the
          # return value of `build_application_map`.
          application_map = {}
          if len(args) == 1:
              application_map = args[0]
          elif len(args) == 2:
              application_map = {args[0]: args[1]}
          else:
              raise TypeError(
                  "load_application: accepts either 1 or 2 positional arguments:"
                  "a map of filenames to targets OR a single filename and its"
                  "targets"
              )
  
          # Count the number of cores being loaded
          core_count = sum(
              len(cores) for ts in six.itervalues(application_map) for
              cores in six.itervalues(ts)
          )
  
          # Mark all targets as unloaded
          unloaded = application_map
  
          # Try to load the applications, then determine which are unloaded
          tries = 0
          while unloaded != {} and tries <= n_tries:
              tries += 1
  
              # Load all unloaded applications, then pause to ensure they reach
              # the wait state
              self.flood_fill_aplx(unloaded, app_id=app_id, wait=True)
              time.sleep(app_start_delay)
  
              # If running in "fast" mode then check that the correct number of
              # cores are in the "wait" state, if so then break out of this loop.
              if (use_count and
                      core_count == self.count_cores_in_state("wait", app_id)):
                  unloaded = {}
                  continue
  
              # Query each target in turn to determine if it is loaded or
              # otherwise.  If it is loaded (in the wait state) then remove it
              # from the unloaded list.
              new_unloadeds = dict()
              for app_name, targets in iteritems(unloaded):
                  unloaded_targets = {}
                  for (x, y), cores in iteritems(targets):
                      unloaded_cores = set()
                      for p in cores:
                          # Read the struct value vcpu->cpu_state, if it is
                          # anything BUT wait then we mark this core as unloaded.
                          state = consts.AppState(
                              self.read_vcpu_struct_field("cpu_state", x, y, p)
                          )
                          if state is not consts.AppState.wait:
                              unloaded_cores.add(p)
  
                      if len(unloaded_cores) > 0:
                          unloaded_targets[(x, y)] = unloaded_cores
                  if len(unloaded_targets) > 0:
                      new_unloadeds[app_name] = unloaded_targets
              unloaded = new_unloadeds
  
          # If there are still unloaded cores then we bail
          if unloaded != {}:
              raise SpiNNakerLoadingError(unloaded)
  
          # If not waiting then send the start signal
          if not wait:
              self.send_signal("start", app_id)