def _find_one_to_one_vertices(vertex, graph):
    """ Find vertices which have one to one connections with the given\
        vertex, and where their constraints don't force them onto\
        different chips.

    :param graph: the graph to look for other one to one vertices
    :param vertex: the vertex to use as a basis for one to one connections
    :return: set of one to one vertices
    """
    # Virtual vertices can't be forced on other chips
    if isinstance(vertex, AbstractVirtualVertex):
        return []
    found_vertices = set()
    vertices_seen = {vertex}

    # look for one to ones leaving this vertex
    outgoing = graph.get_edges_starting_at_vertex(vertex)
    vertices_to_try = [
        edge.post_vertex for edge in outgoing
        if edge.post_vertex not in vertices_seen]
    while vertices_to_try:
        next_vertex = vertices_to_try.pop()
        if next_vertex not in vertices_seen and \
                not isinstance(next_vertex, AbstractVirtualVertex):
            vertices_seen.add(next_vertex)
            edges = graph.get_edges_ending_at_vertex(next_vertex)
            if is_single(edges):
                found_vertices.add(next_vertex)
                outgoing = graph.get_edges_starting_at_vertex(next_vertex)
                vertices_to_try.extend([
                    edge.post_vertex for edge in outgoing
                    if edge.post_vertex not in vertices_seen])

    # look for one to ones entering this vertex
    incoming = graph.get_edges_ending_at_vertex(vertex)
    vertices_to_try = [
        edge.pre_vertex for edge in incoming
        if edge.pre_vertex not in vertices_seen]
    while vertices_to_try:
        next_vertex = vertices_to_try.pop()
        if next_vertex not in vertices_seen:
            vertices_seen.add(next_vertex)
            edges = graph.get_edges_starting_at_vertex(next_vertex)
            if is_single(edges):
                found_vertices.add(next_vertex)
                incoming = graph.get_edges_ending_at_vertex(next_vertex)
                vertices_to_try.extend([
                    edge.pre_vertex for edge in incoming
                    if edge.pre_vertex not in vertices_seen])

    extra_vertices = get_vertices_on_same_chip(vertex, graph)
    for vertex in extra_vertices:
        found_vertices.add(vertex)
    return found_vertices
    def generate_machine_data_specification(
            self, spec, placement, machine_graph, routing_info, iptags,
            reverse_iptags, machine_time_step, time_scale_factor,
            data_n_time_steps):
        # Generate the system data region for simulation .c requirements
        generate_system_data_region(spec, self.DATA_REGIONS.SYSTEM.value,
                                    self, machine_time_step, time_scale_factor)

        # reserve memory regions for every data region
        spec.reserve_memory_region(
            region=self.DATA_REGIONS.TRANSMISSIONS.value,
            size=self.TRANSMISSION_DATA_SIZE, label="inputs")

        spec.reserve_memory_region(
            region=self.DATA_REGIONS.POSITION.value,
            size=self.POSITION_DATA_SIZE, label="position"
        )

        spec.reserve_memory_region(
            region=self.DATA_REGIONS.NEIGHBOUR_KEYS.value,
            size=self.NEIGHBOUR_KEYS_SIZE
        )

        spec.reserve_memory_region(
            region=self.DATA_REGIONS.VELOCITY.value,
            size=self.VELOCITY_SIZE
        )

        spec.reserve_memory_region(
            region=self.DATA_REGIONS.VERTEX_INDEX.value,
            size=self.VERTEX_INDEX_SIZE
        )

        spec.reserve_memory_region(
            region=self.DATA_REGIONS.RESULTS.value,
            size=recording_utilities.get_recording_header_size(1))

        # get recorded buffered regions sorted
        spec.switch_write_focus(self.DATA_REGIONS.RESULTS.value)
        spec.write_array(recording_utilities.get_recording_header_array(
            [self.RECORDING_ELEMENT_SIZE * data_n_time_steps]))

        # check got right number of keys and edges going into me
        partitions = \
            machine_graph.get_outgoing_edge_partitions_starting_at_vertex(self)
        if not is_single(partitions):
            raise ConfigurationException(
                "Can only handle one type of partition.")

        # check for duplicates
        edges = list(machine_graph.get_edges_ending_at_vertex(self))
        if len(edges) != 8:
            raise ConfigurationException(
                "I've not got the right number of connections. I have {} "
                "instead of 8".format(
                    len(machine_graph.get_edges_ending_at_vertex(self))))

        for edge in edges:
            if edge.pre_vertex == self:
                raise ConfigurationException(
                    "I'm connected to myself, this is deemed an error"
                    " please fix.")

        # write key needed to transmit with
        key = routing_info.get_first_key_from_pre_vertex(
            self, self.PARTITION_ID)

        spec.switch_write_focus(
            region=self.DATA_REGIONS.TRANSMISSIONS.value)
        spec.write_value(0 if key is None else 1)
        spec.write_value(0 if key is None else key)

        # write POSITION data
        spec.switch_write_focus(
            region=self.DATA_REGIONS.POSITION.value
        )
        spec.write_value(int(self._x_position))
        spec.write_value(int(self._y_position))

        #write VERTEX_INDEX data. Mainly for add a random delay
        spec.switch_write_focus(region=self.DATA_REGIONS.VERTEX_INDEX.value)
        spec.write_value(machine_graph.vertices.index(self))
        self.offset = generate_offset(placement.p)
        spec.write_value(self.offset)

        # write the neighbour keys and masks
        self._write_key_data(spec, routing_info, machine_graph)

        #write velocity data in two dimension, x and y
        spec.switch_write_focus(region=self.DATA_REGIONS.VELOCITY.value)
        spec.write_value(self.u_x, data_type=DataType.FLOAT_32)
        spec.write_value(self.u_y, data_type=DataType.FLOAT_32)

        # End-of-Spec:
        spec.end_specification()