Source code for spinn_front_end_common.interface.interface_functions.application_runner

import logging
import time

from spinn_front_end_common.utilities.exceptions import ConfigurationException
from spinn_front_end_common.utilities.utility_objs import ExecutableStartType

from spinnman.messages.scp.enums import Signal
from spinnman.model.enums import CPUState

logger = logging.getLogger(__name__)


[docs]class ApplicationRunner(object): """ Ensures all cores are initialised correctly, ran, and completed\ successfully. """ __slots__ = [] def __call__( self, buffer_manager, wait_on_confirmation, send_stop_notification, send_start_notification, notification_interface, executable_targets, executable_start_type, app_id, txrx, runtime, time_scale_factor, loaded_reverse_iptags_token, loaded_iptags_token, loaded_routing_tables_token, loaded_binaries_token, loaded_application_data_token, no_sync_changes, time_threshold, run_until_complete=False): # check all tokens are valid if (not loaded_reverse_iptags_token or not loaded_iptags_token or not loaded_routing_tables_token or not loaded_binaries_token or not loaded_application_data_token): raise ConfigurationException( "Not all valid tokens have been given in the positive state") logger.info("*** Running simulation... *** ") # Get the expected state of the application, depending on the run type expected_states = None sync_signal = None if executable_start_type == ExecutableStartType.RUNNING: expected_states = [ CPUState.RUNNING, CPUState.FINISHED, CPUState.PAUSED, CPUState.SYNC0, CPUState.SYNC1 ] elif executable_start_type == ExecutableStartType.SYNC: sync_signal = Signal.SYNC0 expected_states = [CPUState.SYNC0] elif (executable_start_type == ExecutableStartType.USES_SIMULATION_INTERFACE): if no_sync_changes % 2 == 0: expected_states = [CPUState.SYNC0] sync_signal = Signal.SYNC0 else: expected_states = [CPUState.SYNC1] sync_signal = Signal.SYNC1 # when it falls out of the running, it'll be in a next sync state, # thus update needed no_sync_changes += 1 if expected_states is None: raise ConfigurationException( "Unknown executable start type {}".format( executable_start_type)) # wait for all cores to be ready txrx.wait_for_cores_to_be_in_state( executable_targets.all_core_subsets, app_id, expected_states) # set the buffer manager into a resume state, so that if it had ran # before it'll work again buffer_manager.resume() # every thing is in sync0 so load the initial buffers buffer_manager.load_initial_buffers() # wait till external app is ready for us to start if required if notification_interface is not None and wait_on_confirmation: notification_interface.wait_for_confirmation() # set off the executables that are in sync state if sync_signal is not None: txrx.send_signal(app_id, sync_signal) txrx.wait_for_cores_to_be_in_state( executable_targets.all_core_subsets, app_id, [CPUState.RUNNING, CPUState.PAUSED, CPUState.FINISHED]) # Send start notification if notification_interface is not None and send_start_notification: notification_interface.send_start_resume_notification() # Wait for the application to finish if runtime is None and not run_until_complete: logger.info("Application is set to run forever - exiting") else: timeout = None if not run_until_complete: time_to_wait = ((runtime * time_scale_factor) / 1000.0) + 0.1 logger.info( "Application started - waiting {} seconds for it to stop" .format(time_to_wait)) time.sleep(time_to_wait) timeout = time_threshold else: logger.info( "Application started - waiting until finished") txrx.wait_for_cores_to_be_in_state( executable_targets.all_core_subsets, app_id, [CPUState.FINISHED, CPUState.PAUSED], timeout=timeout) if (notification_interface is not None and send_stop_notification and runtime is not None): notification_interface.send_stop_pause_notification() return True, no_sync_changes