def _execute(txrx, machine, app_id, x, y, p, data_spec_path):
        # pylint: disable=too-many-arguments, too-many-locals

        # build specification reader
        reader = FileDataReader(data_spec_path)

        # maximum available memory
        # however system updates the memory available
        # independently, so the check on the space available actually
        # happens when memory is allocated

        # generate data spec executor
        executor = DataSpecificationExecutor(
            reader,
            machine.get_chip_at(x, y).sdram.size)

        # run data spec executor
        try:
            # bytes_used_by_spec, bytes_written_by_spec = \
            executor.execute()
        except DataSpecificationException:
            logger.error("Error executing data specification for {}, {}, {}",
                         x, y, p)
            raise

        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 = txrx.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()
        txrx.write_memory(x, y, start_address, data_to_write)
        bytes_written_by_spec = len(data_to_write)

        # Write each region
        for region_id in _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
                    txrx.write_memory(x, y, pointer_table[region_id], data)
                    bytes_written_by_spec += len(data)

        # set user 0 register appropriately to the application data
        write_address_to_user0(txrx, x, y, p, start_address)
        return {
            'start_address': start_address,
            'memory_used': bytes_used_by_spec,
            'memory_written': bytes_written_by_spec
        }
    def __execute(self, core, reader, writer_func):
        x, y, p = core

        # Maximum available memory.
        # However, system updates the memory available independently, so the
        # space available check actually happens when memory is allocated.
        memory_available = self._machine.get_chip_at(x, y).sdram.size

        # generate data spec executor
        executor = DataSpecificationExecutor(reader, memory_available)

        # run data spec executor
        try:
            executor.execute()
        except DataSpecificationException:
            logger.error("Error executing data specification for {}, {}, {}",
                         x, y, p)
            raise

        bytes_allocated = 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 = self._txrx.malloc_sdram(x, y, bytes_allocated,
                                                self._app_id)

        # Do the actual writing ------------------------------------

        # Write the header and pointer table
        header = executor.get_header()
        pointer_table = executor.get_pointer_table(start_address)
        data_to_write = numpy.concatenate((header, pointer_table)).tostring()
        # NB: DSE meta-block is always small (i.e., one SDP write)
        self._txrx.write_memory(x, y, start_address, data_to_write)
        bytes_written = len(data_to_write)

        # Write each region
        for region_id in _MEM_REGIONS:
            region = executor.get_region(region_id)
            if region is None:
                continue
            max_pointer = region.max_write_pointer
            if region.unfilled or max_pointer == 0:
                continue

            # Get the data up to what has been written
            data = region.region_data[:max_pointer]

            # Write the data to the position
            writer_func(x, y, pointer_table[region_id], data)
            bytes_written += len(data)

        # set user 0 register appropriately to the application data
        write_address_to_user0(self._txrx, x, y, p, start_address)

        return DataWritten(start_address, bytes_allocated, bytes_written)
Beispiel #3
0
    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
    def test_simple_spec(self):

        # Create a sdram just to set max chip size
        SDRAM(1000)
        # Write a data spec to execute
        temp_spec = mktemp()
        spec_writer = io.FileIO(temp_spec, "w")
        spec = DataSpecificationGenerator(spec_writer)
        spec.reserve_memory_region(0, 100)
        spec.reserve_memory_region(1, 200, empty=True)
        spec.reserve_memory_region(2, 4)
        spec.reserve_memory_region(3, 12, reference=1)
        spec.reference_memory_region(4, 2)
        spec.switch_write_focus(0)
        spec.write_array([0, 1, 2])
        spec.set_write_pointer(20)
        spec.write_value(4)
        spec.switch_write_focus(2)
        spec.write_value(3)
        spec.set_write_pointer(0)
        spec.write_value(10)
        spec.end_specification()

        # Execute the spec
        spec_reader = io.FileIO(temp_spec, "r")
        executor = DataSpecificationExecutor(spec_reader, 400)
        executor.execute()

        # Test the size
        header_and_table_size = (constants.MAX_MEM_REGIONS + 2) * 4
        self.assertEqual(executor.get_constructed_data_size(),
                         header_and_table_size + 100 + 200 + 4 + 12)

        # Test the unused regions
        for region in range(5, constants.MAX_MEM_REGIONS):
            self.assertIsNone(executor.get_region(region))

        # Test region 0
        region_0 = executor.get_region(0)
        self.assertEqual(region_0.allocated_size, 100)
        self.assertEqual(region_0.max_write_pointer, 24)
        self.assertFalse(region_0.unfilled)
        self.assertIsNone(region_0.reference)
        self.assertEqual(region_0.region_data[:region_0.max_write_pointer],
                         struct.pack("<IIIIII", 0, 1, 2, 0, 0, 4))

        # Test region 1
        region_1 = executor.get_region(1)
        self.assertIsInstance(region_1, MemoryRegionReal)
        self.assertEqual(region_1.allocated_size, 200)
        self.assertTrue(region_1.unfilled)
        self.assertIsNone(region_1.reference)

        # Test region 2
        region_2 = executor.get_region(2)
        self.assertIsInstance(region_2, MemoryRegionReal)
        self.assertEqual(region_2.allocated_size, 4)
        self.assertIsNone(region_2.reference)
        self.assertEqual(region_2.region_data, struct.pack("<I", 10))

        # Test region 3
        region_3 = executor.get_region(3)
        self.assertIsInstance(region_3, MemoryRegionReal)
        self.assertEqual(region_3.allocated_size, 12)
        self.assertEqual(region_3.reference, 1)
        self.assertEqual(executor.referenceable_regions, [3])

        # Test region 4
        region_4 = executor.get_region(4)
        self.assertIsInstance(region_4, MemoryRegionReference)
        self.assertEqual(region_4.ref, 2)
        self.assertEqual(executor.references_to_fill, [4])

        # Test the pointer table
        table = executor.get_pointer_table(0)
        self.assertEqual(len(table), constants.MAX_MEM_REGIONS)
        self.assertEqual(table[0], header_and_table_size)
        self.assertEqual(table[1], header_and_table_size + 100)
        self.assertEqual(table[2], header_and_table_size + 300)
        self.assertEqual(table[3], header_and_table_size + 304)
        # 4 is also 0 because it is a reference
        for region in range(4, constants.MAX_MEM_REGIONS):
            self.assertEqual(table[region], 0)

        # Test the header
        header = executor.get_header()
        self.assertEqual(len(header), 2)
        self.assertEqual(header[0], constants.APPDATA_MAGIC_NUM)
        self.assertEqual(header[1], constants.DSE_VERSION)