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