コード例 #1
0
ファイル: v_recorder.py プロジェクト: SpikeFrame/sPyNNaker
    def get_v(self, label, buffer_manager, region, state_region, placements,
              graph_mapper, partitionable_vertex):

        subvertices = \
            graph_mapper.get_subvertices_from_vertex(partitionable_vertex)

        ms_per_tick = self._machine_time_step / 1000.0

        data = list()
        missing_str = ""

        progress_bar = \
            ProgressBar(len(subvertices),
                        "Getting membrane voltage for {}".format(label))

        for subvertex in subvertices:

            vertex_slice = graph_mapper.get_subvertex_slice(subvertex)
            placement = placements.get_placement_of_subvertex(subvertex)

            x = placement.x
            y = placement.y
            p = placement.p

            # for buffering output info is taken form the buffer manager
            neuron_param_region_data_pointer, missing_data =\
                buffer_manager.get_data_for_vertex(
                    placement, region, state_region)
            if missing_data:
                missing_str += "({}, {}, {}); ".format(x, y, p)
            record_raw = neuron_param_region_data_pointer.read_all()
            record_length = len(record_raw)
            n_rows = record_length / ((vertex_slice.n_atoms + 1) * 4)
            record = (numpy.asarray(record_raw, dtype="uint8").
                      view(dtype="<i4")).reshape((n_rows,
                                                  (vertex_slice.n_atoms + 1)))
            split_record = numpy.array_split(record, [1, 1], 1)
            record_time = numpy.repeat(
                split_record[0] * float(ms_per_tick), vertex_slice.n_atoms, 1)
            record_ids = numpy.tile(
                numpy.arange(vertex_slice.lo_atom, vertex_slice.hi_atom + 1),
                len(record_time)).reshape((-1, vertex_slice.n_atoms))
            record_membrane_potential = split_record[2] / 32767.0

            part_data = numpy.dstack(
                [record_ids, record_time, record_membrane_potential])
            part_data = numpy.reshape(part_data, [-1, 3])
            data.append(part_data)
            progress_bar.update()

        progress_bar.end()
        if len(missing_str) > 0:
            logger.warn(
                "Population {} is missing membrane voltage data in region {}"
                " from the following cores: {}".format(
                    label, region, missing_str))
        data = numpy.vstack(data)
        order = numpy.lexsort((data[:, 1], data[:, 0]))
        result = data[order]
        return result
コード例 #2
0
    def get_spikes(self, label, buffer_manager, region, state_region,
                   placements, graph_mapper, partitionable_vertex,
                   base_key_function):

        results = list()
        missing_str = ""
        ms_per_tick = self._machine_time_step / 1000.0
        subvertices = \
            graph_mapper.get_subvertices_from_vertex(partitionable_vertex)
        progress_bar = ProgressBar(len(subvertices),
                                   "Getting spikes for {}".format(label))

        for subvertex in subvertices:

            placement = placements.get_placement_of_subvertex(subvertex)
            subvertex_slice = graph_mapper.get_subvertex_slice(subvertex)

            x = placement.x
            y = placement.y
            p = placement.p

            # Read the spikes
            raw_spike_data, data_missing = \
                buffer_manager.get_data_for_vertex(
                    placement, region, state_region)
            if data_missing:
                missing_str += "({}, {}, {}); ".format(x, y, p)
            spike_data = str(raw_spike_data.read_all())
            number_of_bytes_written = len(spike_data)

            offset = 0
            while offset < number_of_bytes_written:
                eieio_header = EIEIODataHeader.from_bytestring(
                    spike_data, offset)
                offset += eieio_header.size
                timestamp = eieio_header.payload_base * ms_per_tick
                timestamps = numpy.repeat([timestamp], eieio_header.count)
                keys = numpy.frombuffer(
                    spike_data, dtype="<u4", count=eieio_header.count,
                    offset=offset)
                neuron_ids = ((keys - base_key_function(subvertex)) +
                              subvertex_slice.lo_atom)
                offset += eieio_header.count * 4
                results.append(numpy.dstack((neuron_ids, timestamps))[0])
            progress_bar.update()

        progress_bar.end()
        if len(missing_str) > 0:
            logger.warn(
                "Population {} is missing spike data in region {} from the"
                " following cores: {}".format(label, region, missing_str))
        if len(results) != 0:
            result = numpy.vstack(results)
            result = result[numpy.lexsort((result[:, 1], result[:, 0]))]
        else:
            result = []
        return result
コード例 #3
0
    def get_synaptic_list_from_machine(self, graph_mapper, partitioned_graph,
                                       placements, transceiver, routing_infos):
        """ Get synaptic data for all connections in this Projection from the\
            machine.
        """
        if self._stored_synaptic_data_from_machine is None:
            timer = None
            if conf.config.getboolean("Reports", "display_algorithm_timings"):
                timer = Timer()
                timer.start_timing()

            subedges = \
                graph_mapper.get_partitioned_edges_from_partitionable_edge(
                    self)
            if subedges is None:
                subedges = list()

            synaptic_list = copy.copy(self._synapse_list)
            synaptic_list_rows = synaptic_list.get_rows()
            progress_bar = ProgressBar(
                len(subedges),
                "Reading back synaptic matrix for edge between"
                " {} and {}".format(self._pre_vertex.label,
                                    self._post_vertex.label))
            for subedge in subedges:
                n_rows = subedge.get_n_rows(graph_mapper)
                pre_vertex_slice = \
                    graph_mapper.get_subvertex_slice(subedge.pre_subvertex)
                post_vertex_slice = \
                    graph_mapper.get_subvertex_slice(subedge.post_subvertex)

                sub_edge_post_vertex = \
                    graph_mapper.get_vertex_from_subvertex(
                        subedge.post_subvertex)
                rows = sub_edge_post_vertex.get_synaptic_list_from_machine(
                    placements, transceiver, subedge.pre_subvertex, n_rows,
                    subedge.post_subvertex,
                    self._synapse_row_io, partitioned_graph,
                    routing_infos, subedge.weight_scales).get_rows()

                for i in range(len(rows)):
                    synaptic_list_rows[
                        i + pre_vertex_slice.lo_atom].set_slice_values(
                            rows[i], vertex_slice=post_vertex_slice)
                progress_bar.update()
            progress_bar.end()
            self._stored_synaptic_data_from_machine = synaptic_list
            if conf.config.getboolean("Reports", "display_algorithm_timings"):
                logger.info("Time to read matrix: {}".format(
                    timer.take_sample()))

        return self._stored_synaptic_data_from_machine
コード例 #4
0
    def _get_synaptic_data(self, as_list, data_to_get):

        post_vertex = self._projection_edge.post_vertex
        pre_vertex = self._projection_edge.pre_vertex

        # If in virtual board mode, the connection data should be set
        if self._virtual_connection_list is not None:
            post_vertex = self._projection_edge.post_vertex
            pre_vertex = self._projection_edge.pre_vertex
            return ConnectionHolder(
                data_to_get, as_list, pre_vertex.n_atoms, post_vertex.n_atoms,
                self._virtual_connection_list)

        connection_holder = ConnectionHolder(
            data_to_get, as_list, pre_vertex.n_atoms, post_vertex.n_atoms)

        # If we haven't run, add the holder to get connections, and return it
        if not self._spinnaker.has_ran:

            post_vertex.add_pre_run_connection_holder(
                connection_holder, self._projection_edge,
                self._synapse_information)
            return connection_holder

        # Otherwise, get the connections now
        graph_mapper = self._spinnaker.graph_mapper
        placements = self._spinnaker.placements
        transceiver = self._spinnaker.transceiver
        routing_infos = self._spinnaker.routing_infos
        partitioned_graph = self._spinnaker.partitioned_graph
        subedges = graph_mapper.get_partitioned_edges_from_partitionable_edge(
            self._projection_edge)
        progress = ProgressBar(
            len(subedges),
            "Getting {}s for projection between {} and {}".format(
                data_to_get, pre_vertex.label, post_vertex.label))
        for subedge in subedges:
            placement = placements.get_placement_of_subvertex(
                subedge.post_subvertex)
            connections = post_vertex.get_connections_from_machine(
                transceiver, placement, subedge, graph_mapper, routing_infos,
                self._synapse_information, partitioned_graph)
            if connections is not None:
                connection_holder.add_connections(connections)
            progress.update()
        progress.end()
        connection_holder.finish()
        return connection_holder
コード例 #5
0
    def __call__(
            self, placements, graph_mapper, tags, executable_finder,
            partitioned_graph, partitionable_graph, routing_infos, hostname,
            report_default_directory, write_text_specs,
            app_data_runtime_folder):

        # Keep the results
        executable_targets = ExecutableTargets()
        dsg_targets = dict()

        # Keep delay extensions until the end
        delay_extension_placements = list()

        # create a progress bar for end users
        progress_bar = ProgressBar(len(list(placements.placements)),
                                   "Generating sPyNNaker data specifications")
        for placement in placements.placements:
            associated_vertex = graph_mapper.get_vertex_from_subvertex(
                placement.subvertex)

            if isinstance(associated_vertex, DelayExtensionVertex):
                delay_extension_placements.append(
                    (placement, associated_vertex))
            else:
                self._generate_data_spec_for_subvertices(
                    placement, associated_vertex, executable_targets,
                    dsg_targets, graph_mapper, tags, executable_finder,
                    partitioned_graph, partitionable_graph, routing_infos,
                    hostname, report_default_directory, write_text_specs,
                    app_data_runtime_folder)
                progress_bar.update()

        for placement, associated_vertex in delay_extension_placements:
            self._generate_data_spec_for_subvertices(
                placement, associated_vertex, executable_targets,
                dsg_targets, graph_mapper, tags, executable_finder,
                partitioned_graph, partitionable_graph, routing_infos,
                hostname, report_default_directory, write_text_specs,
                app_data_runtime_folder)
            progress_bar.update()

        # finish the progress bar
        progress_bar.end()

        return {'executable_targets': executable_targets,
                'dsg_targets': dsg_targets}
コード例 #6
0
    def __call__(self, subgraph, graph_mapper):
        """
        :param subgraph: the subgraph whose edges are to be updated
        :param graph_mapper: the graph mapper between partitionable and \
                partitioned graphs.
        """

        # create progress bar
        progress_bar = ProgressBar(
            len(subgraph.subedges), "Updating edge weights")

        # start checking subedges to decide which ones need pruning....
        for subedge in subgraph.subedges:
            if isinstance(subedge, AbstractWeightUpdatable):
                subedge.update_weight(graph_mapper)
            progress_bar.update()
        progress_bar.end()

        # return nothing
        return {'subgraph': subgraph}
コード例 #7
0
    def __call__(self,
                 placements,
                 machine,
                 partitioned_graph,
                 k=1,
                 l=0,
                 m=0,
                 bw_per_route_entry=BW_PER_ROUTE_ENTRY,
                 max_bw=MAX_BW):
        """ Find routes between the subedges with the allocated information,
            placed in the given places

        :param placements: The placements of the subedges
        :type placements:\
                    :py:class:`pacman.model.placements.placements.Placements`
        :param machine: The machine through which the routes are to be found
        :type machine: :py:class:`spinn_machine.machine.Machine`
        :param partitioned_graph: the partitioned_graph object
        :type partitioned_graph:\
                    :py:class:`pacman.partitioned_graph.partitioned_graph.PartitionedGraph`
        :return: The discovered routes
        :rtype:\
                    :py:class:`pacman.model.routing_tables.multicast_routing_tables.MulticastRoutingTables`
        :raise pacman.exceptions.PacmanRoutingException: If something\
                   goes wrong with the routing
        """

        # set up basic data structures
        self._routing_paths = MulticastRoutingTableByPartition()
        self._k = k
        self._l = l
        self._m = m
        self._bw_per_route_entry = bw_per_route_entry
        self._max_bw = max_bw
        self._machine = machine

        nodes_info = self._initiate_node_info(machine)
        dijkstra_tables = self._initiate_dijkstra_tables(machine)
        self._update_all_weights(nodes_info, machine)

        # each subvertex represents a core in the board
        progress = ProgressBar(len(list(placements.placements)),
                               "Creating routing entries")

        for placement in placements.placements:
            subvert = placement.subvertex
            out_going_sub_edges = \
                partitioned_graph.outgoing_subedges_from_subvertex(subvert)
            out_going_sub_edges = filter(
                lambda edge: isinstance(edge, MultiCastPartitionedEdge),
                out_going_sub_edges)

            dest_chips = set()
            subedges_to_route = list()

            for subedge in out_going_sub_edges:
                destination_subvertex = subedge.post_subvertex
                destination_placement = placements.get_placement_of_subvertex(
                    destination_subvertex)

                chip = machine.get_chip_at(destination_placement.x,
                                           destination_placement.y)
                dest_chips.add((chip.x, chip.y))
                subedges_to_route.append(subedge)

            if len(dest_chips) != 0:
                self._update_all_weights(nodes_info, machine)
                self._reset_tables(dijkstra_tables)
                dijkstra_tables[(placement.x,
                                 placement.y)]["activated?"] = True
                dijkstra_tables[(placement.x, placement.y)]["lowest cost"] = 0
                self._propagate_costs_until_reached_destinations(
                    dijkstra_tables, nodes_info, dest_chips, placement.x,
                    placement.y)

            for subedge in subedges_to_route:
                dest = subedge.post_subvertex
                dest_placement = placements.get_placement_of_subvertex(dest)
                self._retrace_back_to_source(dest_placement.x,
                                             dest_placement.y, dijkstra_tables,
                                             dest_placement.p, subedge,
                                             nodes_info, placement.p,
                                             partitioned_graph)
            progress.update()
        progress.end()
        return {'routing_paths': self._routing_paths}
    def host_based_data_specification_execution(
            hostname, transceiver, write_text_specs,
            application_data_runtime_folder, machine, report_default_directory,
            app_id, dsg_targets):
        """

        :param hostname:
        :param transceiver:
        :param write_text_specs:
        :param application_data_runtime_folder:
        :param machine:
        :param report_default_directory:
        :param app_id:
        :param dsg_targets:
        :return:
        """
        processor_to_app_data_base_address = dict()

        # create a progress bar for end users
        progress_bar = ProgressBar(
            len(list(dsg_targets)),
            "Executing data specifications and loading data")

        for ((x, y, p), data_spec_file_path) in dsg_targets.iteritems():

            # build specification reader
            data_spec_file_path = dsg_targets[x, y, p]
            data_spec_reader = FileDataReader(data_spec_file_path)

            # build application data writer
            app_data_file_path = \
                AbstractDataSpecableVertex.get_application_data_file_path(
                    x, y, p, hostname, application_data_runtime_folder)

            data_writer = FileDataWriter(app_data_file_path)

            # generate a file writer for DSE report (app pointer table)
            report_writer = None
            if write_text_specs:
                new_report_directory = os.path.join(report_default_directory,
                                                    "data_spec_text_files")

                if not os.path.exists(new_report_directory):
                    os.mkdir(new_report_directory)

                file_name = "{}_DSE_report_for_{}_{}_{}.txt".format(
                    hostname, x, y, p)
                report_file_path = os.path.join(new_report_directory,
                                                file_name)
                report_writer = FileDataWriter(report_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
            host_based_data_spec_executor = DataSpecificationExecutor(
                data_spec_reader, data_writer, memory_available, report_writer)

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

            bytes_used_by_spec = \
                host_based_data_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)

            # the base address address needs to be passed to the DSE to
            # generate the pointer table with absolute addresses
            host_based_data_spec_executor.write_dse_output_file(start_address)

            # close the application data file writer
            data_writer.close()

            # the data is written to memory
            file_reader = FileDataReader(app_data_file_path)
            app_data = file_reader.readall()
            bytes_written_by_spec = len(app_data)
            transceiver.write_memory(x, y, start_address, app_data)
            file_reader.close()

            # 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
            }

            # update the progress bar
            progress_bar.update()

        # close the progress bar
        progress_bar.end()
        return {
            'processor_to_app_data_base_address':
            processor_to_app_data_base_address,
            'LoadedApplicationDataToken': True
        }
    def __call__(self, subgraph, n_keys_map, routing_tables):

        # check that this algorithm supports the constraints
        utility_calls.check_algorithm_can_support_constraints(
            constrained_vertices=subgraph.partitions,
            supported_constraints=[
                KeyAllocatorFixedMaskConstraint,
                KeyAllocatorFixedKeyAndMaskConstraint,
                KeyAllocatorContiguousRangeContraint
            ],
            abstract_constraint_type=AbstractKeyAllocatorConstraint)

        # verify that no edge has more than 1 of a constraint ,and that
        # constraints are compatible
        routing_info_allocator_utilities.\
            check_types_of_edge_constraint(subgraph)

        routing_infos = RoutingInfo()

        # Get the partitioned edges grouped by those that require the same key
        (fixed_key_groups, fixed_mask_groups, fixed_field_groups,
         flexi_field_groups, continuous_groups, none_continuous_groups) = \
            routing_info_allocator_utilities.get_edge_groups(subgraph)

        # Even non-continuous keys will be continuous
        for group in none_continuous_groups:
            continuous_groups.add(group)

        # Go through the groups and allocate keys
        progress_bar = ProgressBar(len(subgraph.partitions),
                                   "Allocating routing keys")

        # allocate the groups that have fixed keys
        for group in fixed_key_groups:  # fixed keys groups

            # Get any fixed keys and masks from the group and attempt to
            # allocate them
            fixed_mask = None
            fixed_key_and_mask_constraint = \
                utility_calls.locate_constraints_of_type(
                    group.constraints,
                    KeyAllocatorFixedKeyAndMaskConstraint)[0]

            # attempt to allocate them
            self._allocate_fixed_keys_and_masks(
                fixed_key_and_mask_constraint.keys_and_masks, fixed_mask)

            # update the pacman data objects
            self._update_routing_objects(
                fixed_key_and_mask_constraint.keys_and_masks, routing_infos,
                group)

            continuous_groups.remove(group)

            progress_bar.update()

        for group in fixed_mask_groups:  # fixed mask groups

            # get mask and fields if need be
            fixed_mask = utility_calls.locate_constraints_of_type(
                group.constraints, KeyAllocatorFixedMaskConstraint)[0].mask

            fields = None
            if group in fixed_field_groups:
                fields = utility_calls.locate_constraints_of_type(
                    group.constraints,
                    KeyAllocatorFixedFieldConstraint)[0].fields
                fixed_field_groups.remove(group)

            # try to allocate
            keys_and_masks = self._allocate_keys_and_masks(
                fixed_mask, fields, n_keys_map.n_keys_for_partition(group))

            # update the pacman data objects
            self._update_routing_objects(keys_and_masks, routing_infos, group)

            continuous_groups.remove(group)

            progress_bar.update()

        for group in fixed_field_groups:
            fields = utility_calls.locate_constraints_of_type(
                group.constraints, KeyAllocatorFixedFieldConstraint)[0].fields

            # try to allocate
            keys_and_masks = self._allocate_keys_and_masks(
                None, fields, n_keys_map.n_keys_for_partition(group))

            # update the pacman data objects
            self._update_routing_objects(keys_and_masks, routing_infos, group)

            continuous_groups.remove(group)

            progress_bar.update()

        if len(flexi_field_groups) != 0:
            raise exceptions.PacmanConfigurationException(
                "MallocBasedRoutingInfoAllocator does not support FlexiField")

        # Sort the rest of the groups, using the routing tables for guidance
        # Group partitions by those which share routes in any table
        partition_groups = OrderedDict()
        routers = reversed(
            sorted(
                routing_tables.get_routers(),
                key=lambda item: len(
                    routing_tables.get_entries_for_router(item[0], item[1]))))
        for x, y in routers:

            # Find all partitions that share a route in this table
            partitions_by_route = defaultdict(OrderedSet)
            routing_table = routing_tables.get_entries_for_router(x, y)
            for partition, entry in routing_table.iteritems():
                if partition in continuous_groups:
                    entry_hash = sum([1 << i for i in entry.out_going_links])
                    entry_hash += sum(
                        [1 << (i + 6) for i in entry.out_going_processors])
                    partitions_by_route[entry_hash].add(partition)

            for entry_hash, partitions in partitions_by_route.iteritems():

                found_groups = list()
                for partition in partitions:
                    if partition in partition_groups:
                        found_groups.append(partition_groups[partition])

                if len(found_groups) == 0:

                    # If no group was found, create a new one
                    for partition in partitions:
                        partition_groups[partition] = partitions

                elif len(found_groups) == 1:

                    # If a single other group was found, merge it
                    for partition in partitions:
                        found_groups[0].add(partition)
                        partition_groups[partition] = found_groups[0]

                else:

                    # Merge the groups
                    new_group = partitions
                    for group in found_groups:
                        for partition in group:
                            new_group.add(partition)
                    for partition in new_group:
                        partition_groups[partition] = new_group

        # Sort partitions by largest group
        continuous_groups = OrderedSet(
            tuple(group) for group in partition_groups.itervalues())
        continuous_groups = reversed(
            sorted([group for group in continuous_groups],
                   key=lambda group: len(group)))

        for group in continuous_groups:
            for partition in group:
                keys_and_masks = self._allocate_keys_and_masks(
                    None, None, n_keys_map.n_keys_for_partition(partition))

                # update the pacman data objects
                self._update_routing_objects(keys_and_masks, routing_infos,
                                             partition)
                progress_bar.update()

        progress_bar.end()
        return {'routing_infos': routing_infos}
コード例 #10
0
    def get_data(label, buffer_manager, region, placements, graph_mapper,
                 application_vertex, machine_time_step, variable):
        """ method for reading a uint32 mapped to time and neuron ids from
        the SpiNNaker machine

        :param label: vertex label
        :param buffer_manager: the manager for buffered data
        :param region: the dsg region id used for this data
        :param placements: the placements object
        :param graph_mapper: the mapping between application and machine
        vertices
        :param application_vertex:
        :param machine_time_step:
        :param variable:
        :return:
        """

        vertices = graph_mapper.get_machine_vertices(application_vertex)

        ms_per_tick = machine_time_step / 1000.0

        data = list()
        missing_str = ""

        progress_bar = \
            ProgressBar(
                len(vertices), "Getting {} for {}".format(variable, label))

        for vertex in vertices:

            vertex_slice = graph_mapper.get_slice(vertex)
            placement = placements.get_placement_of_vertex(vertex)

            x = placement.x
            y = placement.y
            p = placement.p

            # for buffering output info is taken form the buffer manager
            neuron_param_region_data_pointer, missing_data = \
                buffer_manager.get_data_for_vertex(
                    placement, region)
            if missing_data:
                missing_str += "({}, {}, {}); ".format(x, y, p)
            record_raw = neuron_param_region_data_pointer.read_all()
            record_length = len(record_raw)
            n_rows = record_length / ((vertex_slice.n_atoms + 1) * 4)
            record = (numpy.asarray(record_raw,
                                    dtype="uint8").view(dtype="<i4")).reshape(
                                        (n_rows, (vertex_slice.n_atoms + 1)))
            split_record = numpy.array_split(record, [1, 1], 1)
            record_time = numpy.repeat(split_record[0] * float(ms_per_tick),
                                       vertex_slice.n_atoms, 1)
            record_ids = numpy.tile(
                numpy.arange(vertex_slice.lo_atom, vertex_slice.hi_atom + 1),
                len(record_time)).reshape((-1, vertex_slice.n_atoms))
            record_membrane_potential = split_record[2] / 32767.0

            part_data = numpy.dstack(
                [record_ids, record_time, record_membrane_potential])
            part_data = numpy.reshape(part_data, [-1, 3])
            data.append(part_data)
            progress_bar.update()

        progress_bar.end()
        if len(missing_str) > 0:
            logger.warn("Population {} is missing {} data in region {}"
                        " from the following cores: {}".format(
                            label, variable, region, missing_str))
        data = numpy.vstack(data)
        order = numpy.lexsort((data[:, 1], data[:, 0]))
        result = data[order]
        return result
コード例 #11
0
    def __call__(self, subgraph, n_keys_map, graph_mapper=None):

        # check that this algorithm supports the constraints
        utility_calls.check_algorithm_can_support_constraints(
            constrained_vertices=subgraph.partitions,
            supported_constraints=[
                KeyAllocatorFixedMaskConstraint,
                KeyAllocatorFixedKeyAndMaskConstraint,
                KeyAllocatorContiguousRangeContraint
            ],
            abstract_constraint_type=AbstractKeyAllocatorConstraint)

        # verify that no edge has more than 1 of a constraint ,and that
        # constraints are compatible
        routing_info_allocator_utilities.\
            check_types_of_edge_constraint(subgraph)

        routing_infos = RoutingInfo()

        # Get the partitioned edges grouped by those that require the same key
        (fixed_key_groups, fixed_mask_groups, fixed_field_groups,
         flexi_field_groups, continuous_groups, none_continuous_groups) = \
            routing_info_allocator_utilities.get_edge_groups(subgraph)

        # Even non-continuous keys will be continuous
        for group in none_continuous_groups:
            continuous_groups.add(group)

        # Go through the groups and allocate keys
        progress_bar = ProgressBar(len(subgraph.partitions),
                                   "Allocating routing keys")

        # allocate the groups that have fixed keys
        for group in fixed_key_groups:  # fixed keys groups

            # Get any fixed keys and masks from the group and attempt to
            # allocate them
            fixed_mask = None
            fixed_key_and_mask_constraint = \
                utility_calls.locate_constraints_of_type(
                    group.constraints,
                    KeyAllocatorFixedKeyAndMaskConstraint)[0]

            # attempt to allocate them
            self._allocate_fixed_keys_and_masks(
                fixed_key_and_mask_constraint.keys_and_masks, fixed_mask)

            # update the pacman data objects
            self._update_routing_objects(
                fixed_key_and_mask_constraint.keys_and_masks, routing_infos,
                group)

            continuous_groups.remove(group)

            progress_bar.update()

        for group in fixed_mask_groups:  # fixed mask groups

            # get mask and fields if need be
            fixed_mask = utility_calls.locate_constraints_of_type(
                group.constraints, KeyAllocatorFixedMaskConstraint)[0].mask

            fields = None
            if group in fixed_field_groups:
                fields = utility_calls.locate_constraints_of_type(
                    group.constraints,
                    KeyAllocatorFixedFieldConstraint)[0].fields
                fixed_field_groups.remove(group)

            # try to allocate
            keys_and_masks = self._allocate_keys_and_masks(
                fixed_mask, fields, n_keys_map.n_keys_for_partition(group))

            # update the pacman data objects
            self._update_routing_objects(keys_and_masks, routing_infos, group)

            continuous_groups.remove(group)

            progress_bar.update()

        for group in fixed_field_groups:
            fields = utility_calls.locate_constraints_of_type(
                group.constraints, KeyAllocatorFixedFieldConstraint)[0].fields

            # try to allocate
            keys_and_masks = self._allocate_keys_and_masks(
                None, fields, n_keys_map.n_keys_for_partition(group))

            # update the pacman data objects
            self._update_routing_objects(keys_and_masks, routing_infos, group)

            continuous_groups.remove(group)

            progress_bar.update()

        if len(flexi_field_groups) != 0:
            raise exceptions.PacmanConfigurationException(
                "MallocBasedRoutingInfoAllocator does not support FlexiField")

        # If there is a graph, group by source vertex and sort by vertex slice
        # (lo_atom)
        if graph_mapper is not None:
            vertex_groups = defaultdict(list)
            for partition in continuous_groups:
                vertex = graph_mapper.get_vertex_from_subvertex(
                    partition.edges[0].pre_subvertex)
                vertex_groups[vertex].append(partition)
            vertex_partitions = list()
            for vertex_group in vertex_groups.itervalues():
                sorted_partitions = sorted(
                    vertex_group,
                    key=lambda part: graph_mapper.get_subvertex_slice(
                        part.edges[0].pre_subvertex))
                vertex_partitions.extend(sorted_partitions)
            continuous_groups = vertex_partitions

        for group in continuous_groups:
            keys_and_masks = self._allocate_keys_and_masks(
                None, None, n_keys_map.n_keys_for_partition(group))

            # update the pacman data objects
            self._update_routing_objects(keys_and_masks, routing_infos, group)

        progress_bar.end()
        return {'routing_infos': routing_infos}
コード例 #12
0
    def __call__(self, partitioned_graph, placements, n_keys_map):
        """
        Allocates routing information to the partitioned edges in a\
        partitioned graph

        :param partitioned_graph: The partitioned graph to allocate the \
                    outing info for
        :type partitioned_graph:\
                    :py:class:`pacman.model.partitioned_graph.partitioned_graph.PartitionedGraph`
        :param placements: The placements of the subvertices
        :type placements:\
                    :py:class:`pacman.model.placements.placements.Placements`
        :param n_keys_map: A map between the partitioned edges and the number\
                    of keys required by the edges
        :type n_keys_map:\
                    :py:class:`pacman.model.routing_info.abstract_partitioned_edge_n_keys_map.AbstractPartitionedEdgeNKeysMap`
        :return: The routing information
        :rtype: :py:class:`pacman.model.routing_info.routing_info.RoutingInfo`,
                :py:class:`pacman.model.routing_tables.multicast_routing_table.MulticastRoutingTable
        :raise pacman.exceptions.PacmanRouteInfoAllocationException: If\
                   something goes wrong with the allocation
        """

        # check that this algorithm supports the constraints put onto the
        # partitioned_edges
        supported_constraints = [KeyAllocatorContiguousRangeContraint]
        utility_calls.check_algorithm_can_support_constraints(
            constrained_vertices=partitioned_graph.partitions,
            supported_constraints=supported_constraints,
            abstract_constraint_type=AbstractKeyAllocatorConstraint)

        # take each subedge and create keys from its placement
        progress_bar = ProgressBar(len(partitioned_graph.subvertices),
                                   "Allocating routing keys")
        routing_infos = RoutingInfo()
        for subvert in partitioned_graph.subvertices:
            partitions = partitioned_graph.\
                outgoing_edges_partitions_from_vertex(subvert)
            for partition in partitions.values():
                n_keys = n_keys_map.n_keys_for_partition(partition)
                if n_keys > MAX_KEYS_SUPPORTED:
                    raise PacmanRouteInfoAllocationException(
                        "This routing info allocator can only support up to {}"
                        " keys for any given subedge; cannot therefore"
                        " allocate keys to {}, which is requesting {} keys".
                        format(MAX_KEYS_SUPPORTED, partition, n_keys))
                placement = placements.get_placement_of_subvertex(subvert)
                if placement is not None:
                    key = self._get_key_from_placement(placement)
                    keys_and_masks = list(
                        [BaseKeyAndMask(base_key=key, mask=MASK)])
                    subedge_routing_info = PartitionRoutingInfo(
                        keys_and_masks, partition)
                    routing_infos.add_partition_info(subedge_routing_info)
                else:
                    raise PacmanRouteInfoAllocationException(
                        "This subvertex '{}' has no placement! this should "
                        "never occur, please fix and try again.".format(
                            subvert))

            progress_bar.update()
        progress_bar.end()

        return {'routing_infos': routing_infos}
コード例 #13
0
    def __call__(self, placements, tags, partitioned_graph, routing_infos,
                 hostname, report_default_directory, write_text_specs,
                 app_data_runtime_folder, executable_finder):
        """ generates the dsg for the graph.

        :return:
        """

        # iterate though subvertices and call generate_data_spec for each
        # vertex
        executable_targets = ExecutableTargets()
        dsg_targets = dict()

        # create a progress bar for end users
        progress_bar = ProgressBar(len(list(placements.placements)),
                                   "Generating data specifications")
        for placement in placements.placements:
            if isinstance(placement.subvertex,
                          AbstractPartitionedDataSpecableVertex):
                ip_tags = tags.get_ip_tags_for_vertex(placement.subvertex)
                reverse_ip_tags = \
                    tags.get_reverse_ip_tags_for_vertex(
                        placement.subvertex)
                file_path = placement.subvertex.generate_data_spec(
                    placement, partitioned_graph, routing_infos, hostname,
                    report_default_directory, ip_tags, reverse_ip_tags,
                    write_text_specs, app_data_runtime_folder)

                # link dsg file to subvertex
                dsg_targets[placement.x, placement.y, placement.p] = file_path

                progress_bar.update()

                # Get name of binary from vertex
                binary_name = placement.subvertex.get_binary_file_name()

                # Attempt to find this within search paths
                binary_path = executable_finder.get_executable_path(
                    binary_name)
                if binary_path is None:
                    raise exceptions.ExecutableNotFoundException(binary_name)

                if not executable_targets.has_binary(binary_path):
                    executable_targets.add_binary(binary_path)
                executable_targets.add_processor(binary_path, placement.x,
                                                 placement.y, placement.p)
            elif isinstance(placement.subvertex, AbstractDataSpecableVertex):
                ip_tags = tags.get_ip_tags_for_vertex(placement.subvertex)
                reverse_ip_tags = \
                    tags.get_reverse_ip_tags_for_vertex(
                        placement.subvertex)
                file_path = placement.subvertex.generate_data_spec(
                    placement.subvertex, placement, partitioned_graph, None,
                    routing_infos, hostname, None, report_default_directory,
                    ip_tags, reverse_ip_tags, write_text_specs,
                    app_data_runtime_folder)

                # link dsg file to subvertex
                mapping_key = \
                    placement.x, placement.y, placement.p, \
                    placement.subvertex.label
                dsg_targets[mapping_key] = file_path

                progress_bar.update()

                # Get name of binary from vertex
                binary_name = placement.subvertex.get_binary_file_name()

                # Attempt to find this within search paths
                binary_path = executable_finder.get_executable_path(
                    binary_name)
                if binary_path is None:
                    raise exceptions.ExecutableNotFoundException(binary_name)

                if not executable_targets.has_binary(binary_path):
                    executable_targets.add_binary(binary_path)
                executable_targets.add_processor(binary_path, placement.x,
                                                 placement.y, placement.p)
            else:
                progress_bar.update()

                # Get name of binary from vertex
                binary_name = placement.subvertex.get_binary_file_name()

                # Attempt to find this within search paths
                binary_path = executable_finder.get_executable_path(
                    binary_name)
                if binary_path is None:
                    raise exceptions.ExecutableNotFoundException(binary_name)

                if not executable_targets.has_binary(binary_path):
                    executable_targets.add_binary(binary_path)
                executable_targets.add_processor(binary_path, placement.x,
                                                 placement.y, placement.p)

        # finish the progress bar
        progress_bar.end()

        return {
            'executable_targets': executable_targets,
            'dsg_targets': dsg_targets
        }
コード例 #14
0
    def __call__(self, partitioned_graph, machine, placements):
        progress_bar = ProgressBar(8, "Routing")

        vertices_resources, nets, net_names = \
            rig_converters.convert_to_rig_partitioned_graph(
                partitioned_graph)
        progress_bar.update()

        rig_machine = rig_converters.convert_to_rig_machine(machine)
        progress_bar.update()

        rig_constraints = rig_converters.create_rig_machine_constraints(
            machine)
        progress_bar.update()

        rig_constraints.extend(
            rig_converters.create_rig_partitioned_graph_constraints(
                partitioned_graph, rig_machine))
        progress_bar.update()

        rig_placements, rig_allocations = \
            rig_converters.convert_to_rig_placements(placements)
        progress_bar.update()

        rig_routes = route(vertices_resources, nets, rig_machine,
                           rig_constraints, rig_placements, rig_allocations,
                           "cores")
        rig_routes = {
            name: rig_routes[net]
            for net, name in net_names.iteritems()
        }
        progress_bar.update()

        placements = rig_converters.convert_from_rig_placements(
            rig_placements, rig_allocations, partitioned_graph)
        progress_bar.update()
        routes = rig_converters.convert_from_rig_routes(
            rig_routes, partitioned_graph)
        progress_bar.update()
        progress_bar.end()

        return {"routing_paths": routes}
コード例 #15
0
    def get_spikes(
            self, label, buffer_manager, region,
            placements, graph_mapper, application_vertex, machine_time_step):

        spike_times = list()
        spike_ids = list()
        ms_per_tick = machine_time_step / 1000.0

        vertices = \
            graph_mapper.get_machine_vertices(application_vertex)

        missing_str = ""

        progress_bar = ProgressBar(len(vertices),
                                   "Getting spikes for {}".format(label))
        for vertex in vertices:

            placement = placements.get_placement_of_vertex(vertex)
            vertex_slice = graph_mapper.get_slice(vertex)

            x = placement.x
            y = placement.y
            p = placement.p
            lo_atom = vertex_slice.lo_atom

            # Read the spikes
            n_words = int(math.ceil(vertex_slice.n_atoms / 32.0))
            n_bytes_per_block = n_words * 4

            # for buffering output info is taken form the buffer manager
            neuron_param_region_data_pointer, data_missing = \
                buffer_manager.get_data_for_vertex(
                    placement, region)
            if data_missing:
                missing_str += "({}, {}, {}); ".format(x, y, p)
            raw_data = neuron_param_region_data_pointer.read_all()
            offset = 0
            while offset < len(raw_data):
                ((time, n_blocks), offset) = (
                    struct.unpack_from("<II", raw_data, offset), offset + 8)
                (spike_data, offset) = (numpy.frombuffer(
                    raw_data, dtype="uint8",
                    count=n_bytes_per_block * n_blocks, offset=offset),
                    offset + (n_bytes_per_block * n_blocks))
                spikes = spike_data.view("<i4").byteswap().view("uint8")
                bits = numpy.fliplr(numpy.unpackbits(spikes).reshape(
                    (-1, 32))).reshape((-1, n_bytes_per_block * 8))
                indices = numpy.nonzero(bits)[1]
                times = numpy.repeat([time * ms_per_tick], len(indices))
                indices = indices + lo_atom
                spike_ids.append(indices)
                spike_times.append(times)
            progress_bar.update()

        progress_bar.end()
        if len(missing_str) > 0:
            logger.warn(
                "Population {} is missing spike data in region {} from the"
                " following cores: {}".format(label, region, missing_str))

        if len(spike_ids) > 0:
            spike_ids = numpy.hstack(spike_ids)
            spike_times = numpy.hstack(spike_times)
            result = numpy.dstack((spike_ids, spike_times))[0]
            return result[numpy.lexsort((spike_times, spike_ids))]

        return numpy.zeros((0, 2))
コード例 #16
0
def run_model(data, n_chips=None, n_ihcan=0, fs=44100, resample_factor=1):

    # Set up the simulation
    g.setup(n_chips_required=n_chips, model_binary_module=model_binaries)

    # Get the number of cores available for use
    n_cores = 0
    machine = g.machine()

    # Create a OME for each chip
    boards = dict()

    #changed to lists to ensure data is read back in the same order that verticies are instantiated
    ihcans = list()

    cf_index = 0
    count = 0
    for chip in machine.chips:
        if count >= n_chips:
            break
        else:
            boards[chip.x, chip.y] = chip.ip_address

            for j in range(n_ihcan):
                ihcan = IHCANVertex(data[j][:], fs, resample_factor)
                g.add_machine_vertex_instance(ihcan)
                # constrain placement to local chip
                ihcan.add_constraint(ChipAndCoreConstraint(chip.x, chip.y))
                #ihcans[chip.x, chip.y,j] = ihcan
                ihcans.append(ihcan)

            count = count + 1

# Run the simulation
    g.run(None)

    # Wait for the application to finish
    txrx = g.transceiver()
    app_id = globals_variables.get_simulator()._app_id
    #logger.info("Running {} worker cores".format(n_workers))
    logger.info("Waiting for application to finish...")
    running = txrx.get_core_state_count(app_id, CPUState.RUNNING)
    while running > 0:
        time.sleep(0.5)
        error = txrx.get_core_state_count(app_id, CPUState.RUN_TIME_EXCEPTION)
        watchdog = txrx.get_core_state_count(app_id, CPUState.WATCHDOG)
        if error > 0 or watchdog > 0:
            error_msg = "Some cores have failed ({} RTE, {} WDOG)".format(
                error, watchdog)
            raise Exception(error_msg)
        running = txrx.get_core_state_count(app_id, CPUState.RUNNING)

    # Get the data back
    samples = list()
    progress = ProgressBar(len(ihcans), "Reading results")

    for ihcan in ihcans:
        samples.append(ihcan.read_samples(g.buffer_manager()))
        progress.update()
    progress.end()
    samples = numpy.hstack(samples)

    # Close the machine
    g.stop()

    print "channels running: ", len(ihcans) / 5.0
    print "output data: {} fibres with length {}".format(
        len(ihcans) * 2, len(samples))
    #if(len(samples) != len(ihcans)*2*numpy.floor(len(data[0][0])/100)*100*(1.0/resample_factor)):
    if (len(samples) !=
            len(ihcans) * 2 * numpy.floor(len(data[0][0]) / 96) * 96):
        #print "samples length {} isn't expected size {}".format(len(samples),len(ihcans)*2*numpy.floor(len(data[0][0])/100)*100*(1.0/resample_factor))
        print "samples length {} isn't expected size {}".format(
            len(samples),
            len(ihcans) * 2 * numpy.floor(len(data[0][0]) / 96) * 96)

    return samples
コード例 #17
0
    def __call__(self, machine, file_path):
        """

        :param machine:
        :param file_path:
        :return:
        """
        progress_bar = ProgressBar(
            ((machine.max_chip_x + 1) * (machine.max_chip_y + 1)) + 2,
            "Converting to json machine")

        # write basic stuff
        json_dictory_rep = dict()
        json_dictory_rep['width'] = machine.max_chip_x + 1
        json_dictory_rep['height'] = machine.max_chip_y + 1
        json_dictory_rep['chip_resources'] = dict()
        json_dictory_rep['chip_resources']['cores'] = CHIP_HOMOGENIOUS_CORES
        json_dictory_rep['chip_resources']['sdram'] = CHIP_HOMOGENIOUS_SDRAM
        json_dictory_rep['chip_resources']['sram'] = CHIP_HOMOGENIOUS_SRAM
        json_dictory_rep['chip_resources']["router_entries"] = \
            ROUTER_HOMOGENIOUS_ENTRIES
        json_dictory_rep['chip_resources']['tags'] = CHIP_HOMOGENIOUS_TAGS

        # handle exceptions
        json_dictory_rep['dead_chips'] = list()
        json_dictory_rep['dead_links'] = list()
        chip_resource_exceptions = defaultdict()

        # write dead chips
        for x_coord in range(0, machine.max_chip_x + 1):
            for y_coord in range(0, machine.max_chip_y + 1):
                if (not machine.is_chip_at(x_coord, y_coord)
                        or machine.get_chip_at(x_coord, y_coord).virtual):
                    json_dictory_rep['dead_chips'].append([x_coord, y_coord])
                else:
                    # write dead links
                    for link_id in range(0, ROUTER_MAX_NUMBER_OF_LINKS):
                        router = machine.get_chip_at(x_coord, y_coord).router
                        if not router.is_link(link_id):
                            json_dictory_rep['dead_links'].append([
                                x_coord, y_coord, "{}".format(
                                    constants.EDGES(link_id).name.lower())
                            ])
                    self._check_for_exceptions(json_dictory_rep, x_coord,
                                               y_coord, machine,
                                               chip_resource_exceptions)
                progress_bar.update()

        # convert dict into list
        chip_resouce_exceptions_list = []
        for (chip_x, chip_y) in chip_resource_exceptions:
            chip_resouce_exceptions_list.append(
                [chip_x, chip_y, chip_resource_exceptions[(chip_x, chip_y)]])
        progress_bar.update()

        # store exceptions into json form
        json_dictory_rep['chip_resource_exceptions'] = \
            chip_resouce_exceptions_list

        # dump to json file
        file_to_write = open(file_path, "w")
        json.dump(json_dictory_rep, file_to_write)
        file_to_write.close()

        # validate the schema
        machine_schema_file_path = os.path.join(
            os.path.dirname(file_format_schemas.__file__), "machine.json")
        file_to_read = open(machine_schema_file_path, "r")
        machine_schema = json.load(file_to_read)
        jsonschema.validate(json_dictory_rep, machine_schema)

        # update and complete progress bar
        progress_bar.update()
        progress_bar.end()

        return {'file_machine': file_path}
コード例 #18
0
    def __call__(self, app_id, txrx, executable_targets, has_ran):

        if not has_ran:
            raise exceptions.ConfigurationException(
                "The ran token is not set correctly, please fix and try again")

        total_processors = executable_targets.total_processors
        all_core_subsets = executable_targets.all_core_subsets

        progress_bar = ProgressBar(
            total_processors,
            "Turning off all the cores within the simulation")

        # check that the right number of processors are in sync0
        processors_finished = txrx.get_core_state_count(
            app_id, CPUState.FINISHED)
        finished_cores = processors_finished

        while processors_finished != total_processors:

            if processors_finished > finished_cores:
                progress_bar.update(finished_cores - processors_finished)
                finished_cores = processors_finished

            processors_rte = txrx.get_core_state_count(
                app_id, CPUState.RUN_TIME_EXCEPTION)
            processors_watchdogged = txrx.get_core_state_count(
                app_id, CPUState.WATCHDOG)

            if processors_rte > 0 or processors_watchdogged > 0:
                error_cores = helpful_functions.get_cores_in_state(
                    all_core_subsets,
                    {CPUState.RUN_TIME_EXCEPTION, CPUState.WATCHDOG}, txrx)
                fail_message = helpful_functions.get_core_status_string(
                    error_cores)
                raise exceptions.ExecutableFailedToStopException(
                    "{} of {} processors went into an error state when"
                    " shutting down: {}".format(
                        processors_rte + processors_watchdogged,
                        total_processors, fail_message),
                    helpful_functions.get_core_subsets(error_cores), True)

            successful_cores_finished = set(
                helpful_functions.get_cores_in_state(all_core_subsets,
                                                     CPUState.FINISHED, txrx))

            all_cores = set(all_core_subsets)
            unsuccessful_cores = all_cores - successful_cores_finished

            for core_subset in unsuccessful_cores:
                for processor in core_subset.processor_ids:
                    byte_data = struct.pack(
                        "<I", constants.SDP_RUNNING_MESSAGE_CODES.
                        SDP_STOP_ID_CODE.value)

                    txrx.send_sdp_message(
                        SDPMessage(sdp_header=SDPHeader(
                            flags=SDPFlag.REPLY_NOT_EXPECTED,
                            destination_port=(constants.SDP_PORTS.
                                              RUNNING_COMMAND_SDP_PORT.value),
                            destination_cpu=processor,
                            destination_chip_x=core_subset.x,
                            destination_chip_y=core_subset.y),
                                   data=byte_data))

            processors_finished = txrx.get_core_state_count(
                app_id, CPUState.FINISHED)

        progress_bar.end()
コード例 #19
0
    def __init__(
            self, width=None, height=None, with_wrap_arounds=False,
            version=None, n_cpus_per_chip=18, with_monitors=True,
            sdram_per_chip=None):
        """

        :param width: the width of the virtual machine in chips
        :type width: int
        :param height: the height of the virtual machine in chips
        :type height: int
        :param with_wrap_arounds: bool defining if wrap around links exist
        :type with_wrap_arounds: bool
        :param version: the version id of a board; if None, a machine is\
                    created with the correct dimensions, otherwise the machine\
                    will be a single board of the given version
        :type version: int
        :param n_cpus_per_chip: The number of CPUs to put on each chip
        :type n_cpus_per_chip: int
        :param with_monitors: True if CPU 0 should be marked as a monitor
        :type with_monitors: bool
        :param sdram_per_chip: The amount of SDRAM to give to each chip
        :type sdram_per_chip: int or None
        """
        Machine.__init__(self, ())

        if ((width is not None and width < 0) or
                (height is not None and height < 0)):
            raise exceptions.SpinnMachineInvalidParameterException(
                "width or height", "{} or {}".format(width, height),
                "Negative dimensions are not supported")

        if version is None and (width is None or height is None):
            raise exceptions.SpinnMachineInvalidParameterException(
                "version, width, height",
                "{}, {}, {}".format(version, width, height),
                "Either version must be specified, "
                "or width and height must both be specified")

        if version is not None and (version < 2 or version > 5):
            raise exceptions.SpinnMachineInvalidParameterException(
                "version", str(version),
                "Version must be between 2 and 5 inclusive or None")

        if ((version == 5 or version == 4) and
                with_wrap_arounds is not None and with_wrap_arounds):
            raise exceptions.SpinnMachineInvalidParameterException(
                "version and with_wrap_arounds",
                "{} and True".format(version),
                "A version {} board does not have wrap arounds; set "
                "version to None or with_wrap_arounds to None".format(version))

        if (version == 2 or version == 3) and with_wrap_arounds is not None:
            raise exceptions.SpinnMachineInvalidParameterException(
                "version and with_wrap_arounds",
                "{} and {}".format(version, with_wrap_arounds),
                "A version {} board has complex wrap arounds; set "
                "version to None or with_wrap_arounds to None".format(version))

        if ((version == 5 or version == 4) and (
                (width is not None and width != 8) or
                (height is not None and height != 8))):
            raise exceptions.SpinnMachineInvalidParameterException(
                "version, width, height",
                "{}, {}, {}".format(version, width, height),
                "A version {} board has a width and height of 8; set "
                "version to None or width and height to None".format(version))

        if ((version == 2 or version == 3) and (
                (width is not None and width != 2) or
                (height is not None and height != 2))):
            raise exceptions.SpinnMachineInvalidParameterException(
                "version, width, height",
                "{}, {}, {}".format(version, width, height),
                "A version {} board has a width and height of 2; set "
                "version to None or width and height to None".format(version))

        if version == 5 or version == 4:
            if width is None:
                width = 8
            if height is None:
                height = 8
            with_wrap_arounds = False
        if version == 2 or version == 3:
            if width is None:
                width = 2
            if height is None:
                height = 2
            with_wrap_arounds = True

        # if x and y are none, assume a 48 chip board
        logger.debug("width = {} and height  = {}".format(width, height))

        # calculate the chip ids which this machine is going to have
        chip_ids = list()
        for i in xrange(width):
            for j in xrange(height):
                coords = (i, j)
                if (version == 5 and width == 8 and height == 8 and
                        coords in _48boardgaps):

                    # a chip doesn't exist in this static position
                    # on these boards, so nullify it
                    pass
                else:
                    chip_ids.append((i, j))

        progress_bar = ProgressBar(
            width * height, "Generating a virtual machine")

        # Create the chips and their links
        for i in xrange(width):
            for j in xrange(height):
                coords = (i, j)
                if (version == 5 and width == 8 and height == 8 and
                        coords in _48boardgaps):

                    # a chip doesn't exist in this static position
                    # on these boards, so nullify it
                    pass
                else:
                    processors = list()
                    for processor_id in range(0, n_cpus_per_chip):
                        processor = Processor(processor_id, 200000000)
                        if processor_id == 0 and with_monitors:
                            processor.is_monitor = True
                        processors.append(processor)
                    chip_links = self._calculate_links(
                        i, j, width, height, with_wrap_arounds, version,
                        chip_ids)
                    chip_router = Router(chip_links, False)
                    if sdram_per_chip is None:
                        sdram = SDRAM()
                    else:
                        system_base_address = (
                            SDRAM.DEFAULT_BASE_ADDRESS + sdram_per_chip)
                        sdram = SDRAM(system_base_address=system_base_address)

                    chip = Chip(i, j, processors, chip_router, sdram, 0, 0,
                                "127.0.0.1")
                    self.add_chip(chip)

                progress_bar.update()

        progress_bar.end()

        processor_count = 0
        for chip in self.chips:
            processor_count += len(list(chip.processors))

        link_count = 0
        for chip in self.chips:
            link_count += len(list(chip.router.links))

        logger.debug(
            "Static Allocation Complete;"
            " {} calculated app cores and {} links!".format(
                processor_count, link_count))
コード例 #20
0
    def get_spikes(self, label, buffer_manager, region, state_region,
                   placements, graph_mapper, partitionable_vertex):

        spike_times = list()
        spike_ids = list()
        ms_per_tick = self._machine_time_step / 1000.0

        subvertices = \
            graph_mapper.get_subvertices_from_vertex(partitionable_vertex)

        missing_str = ""

        progress_bar = ProgressBar(len(subvertices),
                                   "Getting spikes for {}".format(label))
        for subvertex in subvertices:

            placement = placements.get_placement_of_subvertex(subvertex)
            subvertex_slice = graph_mapper.get_subvertex_slice(subvertex)

            x = placement.x
            y = placement.y
            p = placement.p
            lo_atom = subvertex_slice.lo_atom

            # Read the spikes
            n_words = int(math.ceil(subvertex_slice.n_atoms / 32.0))
            n_bytes = n_words * 4
            n_words_with_timestamp = n_words + 1

            # for buffering output info is taken form the buffer manager
            neuron_param_region_data_pointer, data_missing = \
                buffer_manager.get_data_for_vertex(
                    placement, region, state_region)
            if data_missing:
                missing_str += "({}, {}, {}); ".format(x, y, p)
            record_raw = neuron_param_region_data_pointer.read_all()
            raw_data = (numpy.asarray(record_raw, dtype="uint8").
                        view(dtype="<i4")).reshape(
                [-1, n_words_with_timestamp])
            split_record = numpy.array_split(raw_data, [1, 1], 1)
            record_time = split_record[0] * float(ms_per_tick)
            spikes = split_record[2].byteswap().view("uint8")
            bits = numpy.fliplr(numpy.unpackbits(spikes).reshape(
                (-1, 32))).reshape((-1, n_bytes * 8))
            time_indices, indices = numpy.where(bits == 1)
            times = record_time[time_indices].reshape((-1))
            indices = indices + lo_atom
            spike_ids.append(indices)
            spike_times.append(times)
            progress_bar.update()

        progress_bar.end()
        if len(missing_str) > 0:
            logger.warn(
                "Population {} is missing spike data in region {} from the"
                " following cores: {}".format(label, region, missing_str))

        spike_ids = numpy.hstack(spike_ids)
        spike_times = numpy.hstack(spike_times)
        result = numpy.dstack((spike_ids, spike_times))[0]
        return result[numpy.lexsort((spike_times, spike_ids))]
    def __call__(self, report_default_directory, dsg_targets, transceiver):
        """

        :param report_default_directory:
        :param processor_to_app_data_base_address:
        :return:
        """

        directory_name = os.path.join(
            report_default_directory, MEM_MAP_SUBDIR_NAME)
        if not os.path.exists(directory_name):
            os.makedirs(directory_name)

        progress_bar = ProgressBar(len(dsg_targets),
                                   "Writing memory map reports")
        for (x, y, p) in dsg_targets:

            file_name = os.path.join(
                directory_name,
                "memory_map_from_processor"
                "_{0:d}_{1:d}_{2:d}.txt".format(x, y, p))
            output = None
            try:
                output = open(file_name, "w")
            except IOError:
                logger.error("Generate_placement_reports: Can't open file"
                             " {} for writing.".format(file_name))

            output.write("On chip data specification executor\n\n")

            report_data_address_pointer = transceiver.\
                get_user_1_register_address_from_core(x, y, p)

            report_data_address_encoded = buffer(transceiver.read_memory(
                x, y, report_data_address_pointer, 4))

            report_data_address = struct.unpack_from(
                "<I", report_data_address_encoded)[0]

            report_bytes = \
                _MemoryChannelState.STRUCT_SIZE * constants.MAX_MEM_REGIONS

            mem_map_report_data = buffer(transceiver.read_memory(
                x, y, report_data_address, report_bytes))

            offset = 0
            for i in xrange(constants.MAX_MEM_REGIONS):
                region = _MemoryChannelState.from_bytestring(
                    mem_map_report_data, offset)
                offset += _MemoryChannelState.STRUCT_SIZE

                if region.start_address == 0:
                    output.write("Region {0:d}: Unused\n\n".format(i))
                else:
                    if region.unfilled:
                        space_written = 0
                    else:
                        space_written = region.written

                    output.write(
                        "Region {0:d}:\n\t"
                        "start address: 0x{1:x}\n\t"
                        "size: {2:d}\n\t"
                        "unfilled: {3:s}\n\t"
                        "write pointer: 0x{4:x}\n\t"
                        "size currently written(based on the "
                        "write pointer): {5:d}\n\n".format(
                            i, region.start_address, region.size,
                            region.unfilled_tf, region.write_pointer,
                            space_written))

            output.flush()
            output.close()
            progress_bar.update()
        progress_bar.end()
コード例 #22
0
    def __call__(self, machine, placements):
        """ see AbstractTagAllocatorAlgorithm.allocate_tags
        """

        resource_tracker = ResourceTracker(machine)

        # Check that the algorithm can handle the constraints
        progress_bar = ProgressBar(placements.n_placements, "Allocating tags")
        placements_with_tags = list()
        for placement in placements.placements:
            utility_calls.check_algorithm_can_support_constraints(
                constrained_vertices=[placement.subvertex],
                supported_constraints=[
                    TagAllocatorRequireIptagConstraint,
                    TagAllocatorRequireReverseIptagConstraint
                ],
                abstract_constraint_type=AbstractTagAllocatorConstraint)
            if len(
                    utility_calls.locate_constraints_of_type(
                        placement.subvertex.constraints,
                        AbstractTagAllocatorConstraint)):
                placements_with_tags.append(placement)
            progress_bar.update()

        # Go through and allocate the tags
        tags = Tags()
        for placement in placements_with_tags:
            vertex = placement.subvertex

            # Get the constraint details for the tags
            (board_address, ip_tags, reverse_ip_tags) =\
                utility_calls.get_ip_tag_info(vertex.constraints)

            # Allocate the tags, first-come, first-served, using the
            # fixed placement of the vertex, and the required resources
            chips = [(placement.x, placement.y)]
            resources = vertex.resources_required
            (_, _, _, returned_ip_tags, returned_reverse_ip_tags) = \
                resource_tracker.allocate_resources(
                    resources, chips, placement.p, board_address, ip_tags,
                    reverse_ip_tags)

            # Put the allocated ip tag information into the tag object
            if returned_ip_tags is not None:
                for (tag_constraint, (board_address,
                                      tag)) in zip(ip_tags, returned_ip_tags):
                    ip_tag = IPTag(board_address, tag,
                                   tag_constraint.ip_address,
                                   tag_constraint.port,
                                   tag_constraint.strip_sdp)
                    tags.add_ip_tag(ip_tag, vertex)

            # Put the allocated reverse ip tag information into the tag object
            if returned_reverse_ip_tags is not None:
                for (tag_constraint, (board_address,
                                      tag)) in zip(reverse_ip_tags,
                                                   returned_reverse_ip_tags):
                    reverse_ip_tag = ReverseIPTag(board_address, tag,
                                                  tag_constraint.port,
                                                  placement.x, placement.y,
                                                  placement.p,
                                                  tag_constraint.sdp_port)
                    tags.add_reverse_ip_tag(reverse_ip_tag, vertex)

        progress_bar.end()
        return {'tags': tags}
コード例 #23
0
    def get_spikes(self, label, buffer_manager, region, state_region,
                   placements, graph_mapper, partitionable_vertex):

        spike_times = list()
        spike_ids = list()
        ms_per_tick = self._machine_time_step / 1000.0

        subvertices = \
            graph_mapper.get_subvertices_from_vertex(partitionable_vertex)

        missing_str = ""

        progress_bar = ProgressBar(len(subvertices),
                                   "Getting spikes for {}".format(label))
        for subvertex in subvertices:

            placement = placements.get_placement_of_subvertex(subvertex)
            subvertex_slice = graph_mapper.get_subvertex_slice(subvertex)

            x = placement.x
            y = placement.y
            p = placement.p
            lo_atom = subvertex_slice.lo_atom

            # Read the spikes
            n_words = int(math.ceil(subvertex_slice.n_atoms / 32.0))
            n_bytes_per_block = n_words * 4

            # for buffering output info is taken form the buffer manager
            neuron_param_region_data_pointer, data_missing = \
                buffer_manager.get_data_for_vertex(
                    placement, region, state_region)
            if data_missing:
                missing_str += "({}, {}, {}); ".format(x, y, p)
            raw_data = neuron_param_region_data_pointer.read_all()
            offset = 0
            while offset < len(raw_data):
                ((time, n_blocks), offset) = (
                    struct.unpack_from("<II", raw_data, offset), offset + 8)
                (spike_data, offset) = (numpy.frombuffer(
                    raw_data, dtype="uint8",
                    count=n_bytes_per_block * n_blocks, offset=offset),
                    offset + (n_bytes_per_block * n_blocks))
                spikes = spike_data.view("<i4").byteswap().view("uint8")
                bits = numpy.fliplr(numpy.unpackbits(spikes).reshape(
                    (-1, 32))).reshape((-1, n_bytes_per_block * 8))
                indices = numpy.nonzero(bits)[1]
                times = numpy.repeat([time * ms_per_tick], len(indices))
                indices = indices + lo_atom
                spike_ids.append(indices)
                spike_times.append(times)
            progress_bar.update()

        progress_bar.end()
        if len(missing_str) > 0:
            logger.warn(
                "Population {} is missing spike data in region {} from the"
                " following cores: {}".format(label, region, missing_str))

        spike_ids = numpy.hstack(spike_ids)
        spike_times = numpy.hstack(spike_times)
        result = numpy.dstack((spike_ids, spike_times))[0]
        return result[numpy.lexsort((spike_times, spike_ids))]
コード例 #24
0
    def __call__(self, graph, machine):
        """ Partition a partitionable_graph so that each subvertex will fit\
            on a processor within the machine

        :param graph: The partitionable_graph to partition
        :type graph:\
                    :py:class:`pacman.model.graph.partitionable_graph.PartitionableGraph`
        :param machine: The machine with respect to which to partition the\
                    partitionable_graph
        :type machine: :py:class:`spinn_machine.machine.Machine`
        :return: A partitioned_graph of partitioned vertices and partitioned\
                    edges
        :rtype:\
                    :py:class:`pacman.model.partitioned_graph.partitioned_graph.PartitionedGraph`
        :raise pacman.exceptions.PacmanPartitionException: If something\
                   goes wrong with the partitioning
        """
        utility_calls.check_algorithm_can_support_constraints(
            constrained_vertices=graph.vertices,
            abstract_constraint_type=AbstractPartitionerConstraint,
            supported_constraints=[PartitionerMaximumSizeConstraint,
                                   PartitionerSameSizeAsVertexConstraint])

        # Load the vertices and create the subgraph to fill
        vertices = graph.vertices
        subgraph = PartitionedGraph(
            label="partitioned graph for {}".format(graph.label))
        graph_mapper = GraphMapper(graph.label, subgraph.label)

        # sort out vertex's by constraints
        vertices = utility_calls.sort_objects_by_constraint_authority(vertices)

        # Set up the progress
        n_atoms = 0
        for vertex in vertices:
            n_atoms += vertex.n_atoms
        progress_bar = ProgressBar(n_atoms, "Partitioning graph vertices")

        resource_tracker = ResourceTracker(machine)

        # Partition one vertex at a time
        for vertex in vertices:

            # check that the vertex hasn't already been partitioned
            subverts_from_vertex = \
                graph_mapper.get_subvertices_from_vertex(vertex)

            # if not, partition
            if subverts_from_vertex is None:
                self._partition_vertex(
                    vertex, subgraph, graph_mapper, resource_tracker, graph)
            progress_bar.update(vertex.n_atoms)
        progress_bar.end()

        partition_algorithm_utilities.generate_sub_edges(
            subgraph, graph_mapper, graph)

        results = dict()
        results['partitioned_graph'] = subgraph
        results['graph_mapper'] = graph_mapper
        results['nChips'] = len(resource_tracker.keys)
        return results