Source code for spinn_front_end_common.interface.interface_functions.host_execute_data_specification
from spinn_utilities.progress_bar import ProgressBar
# data spec imports
from data_specification import DataSpecificationExecutor, constants
from data_specification.exceptions import DataSpecificationException
# spinn_storage_handlers import
from spinn_storage_handlers import FileDataReader
import logging
import struct
import numpy
logger = logging.getLogger(__name__)
[docs]class HostExecuteDataSpecification(object):
""" Executes the host based data specification
"""
__slots__ = []
def __call__(self, transceiver, machine, app_id, dsg_targets):
"""
:param machine: the python representation of the spinnaker machine
:param transceiver: the spinnman instance
:param app_id: the application ID of the simulation
:param dsg_targets: map of placement to file path
:return: map of placement and dsg data, and loaded data flag.
"""
processor_to_app_data_base_address = dict()
# create a progress bar for end users
progress = ProgressBar(
dsg_targets, "Executing data specifications and loading data")
for ((x, y, p), data_spec_file_path) in progress.over(
dsg_targets.iteritems()):
# build specification reader
data_spec_file_path = dsg_targets[x, y, p]
data_spec_reader = FileDataReader(data_spec_file_path)
# maximum available memory
# however system updates the memory available
# independently, so the check on the space available actually
# happens when memory is allocated
chip = machine.get_chip_at(x, y)
memory_available = chip.sdram.size
# generate data spec executor
executor = DataSpecificationExecutor(
data_spec_reader, memory_available)
# run data spec executor
try:
# bytes_used_by_spec, bytes_written_by_spec = \
executor.execute()
except DataSpecificationException as e:
logger.error(
"Error executing data specification for {}, {}, {}".format(
x, y, p))
raise e
bytes_used_by_spec = executor.get_constructed_data_size()
# allocate memory where the app data is going to be written
# this raises an exception in case there is not enough
# SDRAM to allocate
start_address = transceiver.malloc_sdram(
x, y, bytes_used_by_spec, app_id)
# Write the header and pointer table and load it
header = executor.get_header()
pointer_table = executor.get_pointer_table(start_address)
data_to_write = numpy.concatenate(
(header, pointer_table)).tostring()
transceiver.write_memory(x, y, start_address, data_to_write)
bytes_written_by_spec = len(data_to_write)
# Write each region
for region_id in range(constants.MAX_MEM_REGIONS):
region = executor.get_region(region_id)
if region is not None:
max_pointer = region.max_write_pointer
if not region.unfilled and max_pointer > 0:
# Get the data up to what has been written
data = region.region_data[:max_pointer]
# Write the data to the position
position = pointer_table[region_id]
transceiver.write_memory(x, y, position, data)
bytes_written_by_spec += len(data)
# set user 0 register appropriately to the application data
user_0_address = \
transceiver.get_user_0_register_address_from_core(x, y, p)
start_address_encoded = \
buffer(struct.pack("<I", start_address))
transceiver.write_memory(
x, y, user_0_address, start_address_encoded)
# write information for the memory map report
processor_to_app_data_base_address[x, y, p] = {
'start_address': start_address,
'memory_used': bytes_used_by_spec,
'memory_written': bytes_written_by_spec}
return processor_to_app_data_base_address, True