def test_remove_gaps():
    c = coordinates.Cabinet

    o0 = "o0"
    o1 = "o1"
    o2 = "o2"

    # Empty case
    assert transforms.remove_gaps([]) == []

    # Singletons (with and without need to move)
    assert transforms.remove_gaps([(o0, c(0, 0, 0))]) == [(o0, c(0, 0, 0))]
    assert transforms.remove_gaps([(o0, c(1, 2, 0))]) == [(o0, c(1, 2, 0))]
    assert transforms.remove_gaps([(o0, c(1, 2, 3))]) == [(o0, c(1, 2, 0))]

    # With and without gaps
    assert set(transforms.remove_gaps(
     [(o0, c(0,0,0)), (o1, c(0,0,1))])) ==\
     set([(o0, c(0,0,0)), (o1, c(0,0,1))])
    assert set(transforms.remove_gaps(
     [(o0, c(0,0,0)), (o1, c(0,0,2))])) ==\
     set([(o0, c(0,0,0)), (o1, c(0,0,1))])
    assert set(transforms.remove_gaps(
     [(o0, c(0,0,5)), (o1, c(0,0,2))])) ==\
     set([(o0, c(0,0,1)), (o1, c(0,0,0))])

    # Independent frames with restructuring needs
    assert set(transforms.remove_gaps(
     [(o0, c(1,0,5)), (o1, c(0,1,2))])) ==\
     set([(o0, c(1,0,0)), (o1, c(0,1,0))])
    assert set(transforms.remove_gaps(
     [(o0, c(0,0,0)), (o1, c(0,0,3)), (o2, c(1,0,3))])) ==\
     set([(o0, c(0,0,0)), (o1, c(0,0,1)), (o2, c(1,0,0))])
def cabinetised_boards(cabinet):
	from spinner import transforms
	from spinner import utils
	
	# Generate folded system
	hex_boards, folded_boards = utils.folded_torus(10, 8, "shear", "rows", (2, 2))
	
	# Divide into cabinets
	cabinetised_boards = transforms.cabinetise(folded_boards,
	                                           cabinet.num_cabinets,
	                                           cabinet.frames_per_cabinet,
	                                           cabinet.boards_per_frame)
	cabinetised_boards = transforms.remove_gaps(cabinetised_boards)
	
	return cabinetised_boards
def cabinetised_boards(cabinet):
    from spinner import transforms
    from spinner import utils

    # Generate folded system
    hex_boards, folded_boards = utils.folded_torus(10, 8, "shear", "rows",
                                                   (2, 2))

    # Divide into cabinets
    cabinetised_boards = transforms.cabinetise(folded_boards,
                                               cabinet.num_cabinets,
                                               cabinet.frames_per_cabinet,
                                               cabinet.boards_per_frame)
    cabinetised_boards = transforms.remove_gaps(cabinetised_boards)

    return cabinetised_boards
Exemplo n.º 4
0
def main(args=None):
	parser = argparse.ArgumentParser(
		description="Generate visual maps from the SpiNNaker network topology to "
		            "board locations.")
	arguments.add_version_args(parser)
	arguments.add_image_args(parser)
	arguments.add_topology_args(parser)
	arguments.add_cabinet_args(parser)
	
	# Process command-line arguments
	args = parser.parse_args(args)
	(w, h), transformation, uncrinkle_direction, folds =\
		arguments.get_topology_from_args(parser, args)
	
	cabinet, num_frames = arguments.get_cabinets_from_args(parser, args)
	
	aspect_ratio = get_machine_map_aspect_ratio(w, h)
	
	output_filename, file_type, image_width, image_height =\
		arguments.get_image_from_args(parser, args, aspect_ratio)
	
	# Generate folded system
	hex_boards, folded_boards = folded_torus(w, h,
	                                         transformation,
	                                         uncrinkle_direction,
	                                         folds)
	
	# Divide into cabinets
	cabinetised_boards = transforms.cabinetise(folded_boards,
	                                           cabinet.num_cabinets,
	                                           num_frames,
	                                           cabinet.boards_per_frame)
	cabinetised_boards = transforms.remove_gaps(cabinetised_boards)
	
	# Render the image
	Context = {"png": PNGContextManager, "pdf": PDFContextManager}[file_type]
	with Context(output_filename, image_width, image_height) as ctx:
		draw_machine_map(ctx, image_width, image_height,
		                 w, h, hex_boards, cabinetised_boards)
	
	return 0
Exemplo n.º 5
0
def main(args=None):
	parser = argparse.ArgumentParser(
		description="Produce CSV listings of Ethernet connected chip physical and "
		            "network positions.")
	arguments.add_version_args(parser)
	arguments.add_topology_args(parser)
	arguments.add_cabinet_args(parser)
	
	# Process command-line arguments
	args = parser.parse_args(args)
	(w, h), transformation, uncrinkle_direction, folds =\
		arguments.get_topology_from_args(parser, args)
	
	cabinet, num_frames = arguments.get_cabinets_from_args(parser, args)
	
	# Generate folded system
	hex_boards, folded_boards = folded_torus(w, h,
	                                         transformation,
	                                         uncrinkle_direction,
	                                         folds)
	
	# Divide into cabinets
	cabinetised_boards = transforms.cabinetise(folded_boards,
	                                           cabinet.num_cabinets,
	                                           num_frames,
	                                           cabinet.boards_per_frame)
	cabinetised_boards = transforms.remove_gaps(cabinetised_boards)
	
	# Generate the output
	print("cabinet,frame,board,x,y")
	b2c = dict(cabinetised_boards)
	for board, hex_coord in sorted(hex_boards, key=(lambda v: topology.to_xy(v[1]))):
		x, y = topology.to_xy(topology.board_to_chip(hex_coord))
		c, f, b = b2c[board]
		print(",".join(map(str, [c,f,b, x,y])))
	
	
	return 0
Exemplo n.º 6
0
def main(args=None):
    parser = argparse.ArgumentParser(
        description=
        "Produce CSV listings of Ethernet connected chip physical and "
        "network positions.")
    arguments.add_version_args(parser)
    arguments.add_topology_args(parser)
    arguments.add_cabinet_args(parser)

    # Process command-line arguments
    args = parser.parse_args(args)
    (w, h), transformation, uncrinkle_direction, folds =\
     arguments.get_topology_from_args(parser, args)

    cabinet, num_frames = arguments.get_cabinets_from_args(parser, args)

    # Generate folded system
    hex_boards, folded_boards = folded_torus(w, h, transformation,
                                             uncrinkle_direction, folds)

    # Divide into cabinets
    cabinetised_boards = transforms.cabinetise(folded_boards,
                                               cabinet.num_cabinets,
                                               num_frames,
                                               cabinet.boards_per_frame)
    cabinetised_boards = transforms.remove_gaps(cabinetised_boards)

    # Generate the output
    print("cabinet,frame,board,x,y")
    b2c = dict(cabinetised_boards)
    for board, hex_coord in sorted(hex_boards,
                                   key=(lambda v: topology.to_xy(v[1]))):
        x, y = topology.to_xy(topology.board_to_chip(hex_coord))
        c, f, b = b2c[board]
        print(",".join(map(str, [c, f, b, x, y])))

    return 0
Exemplo n.º 7
0
def main(args=None):
	parser = argparse.ArgumentParser(
		description="Generate illustrations of SpiNNaker machine wiring.")
	arguments.add_version_args(parser)
	arguments.add_image_args(parser)
	add_diagram_arguments(parser)
	arguments.add_topology_args(parser)
	arguments.add_cabinet_args(parser)
	arguments.add_subset_args(parser)
	
	# Process command-line arguments
	args = parser.parse_args(args)
	(w, h), transformation, uncrinkle_direction, folds =\
		arguments.get_topology_from_args(parser, args)
	
	cabinet, num_frames =\
		arguments.get_cabinets_from_args(parser, args)
	
	aspect_ratio, focus, wire_thickness, highlights, hide_labels =\
		get_diagram_arguments(parser, args, w, h, cabinet, num_frames)
	
	output_filename, file_type, image_width, image_height =\
		arguments.get_image_from_args(parser, args, aspect_ratio)
	
	wire_filter = arguments.get_subset_from_args(parser, args)
	
	# Generate folded system
	hex_boards, folded_boards = folded_torus(w, h,
	                                         transformation,
	                                         uncrinkle_direction,
	                                         folds)
	
	# Divide into cabinets
	cabinetised_boards = transforms.cabinetise(folded_boards,
	                                           cabinet.num_cabinets,
	                                           num_frames,
	                                           cabinet.boards_per_frame)
	cabinetised_boards = transforms.remove_gaps(cabinetised_boards)
	
	# Set up diagram
	md = MachineDiagram(cabinet)
	
	# Create lookup from cabinet coord to chip x/y to enable labelling of boards
	b2cab = dict(cabinetised_boards)
	b2chip = dict((b, topology.to_xy(topology.board_to_chip(c)))
	              for b, c in hex_boards)
	cab2chip = dict((b2cab[b], b2chip[b]) for b, c in cabinetised_boards)
	
	# Add labels
	if not hide_labels:
		for cabinet_num in range(cabinet.num_cabinets):
			md.add_label(cabinet_num, cabinet_num)
			for frame_num in range(cabinet.frames_per_cabinet):
				md.add_label(frame_num, cabinet_num, frame_num)
				for board_num in range(cabinet.boards_per_frame):
					# Only label boards which are actually part of the system
					xy = cab2chip.get((cabinet_num, frame_num, board_num), None)
					if xy is not None:
						md.add_label("{} ({},{})".format(board_num, xy.x, xy.y),
						             cabinet_num, frame_num, board_num)
						for socket in Direction:
							name = "".join(w[0] for w in socket.name.split("_")).upper()
							md.add_label(name, cabinet_num, frame_num, board_num, socket,
							             rgba=(1.0, 1.0, 1.0, 0.7))
	
	# Add highlights
	for highlight in highlights:
		md.add_highlight(*highlight, width=cabinet.board_dimensions.x/3.0)
	
	# Add wires
	wire_thickness_m = {
		"thick" : cabinet.board_dimensions.x / 5.0,
		"normal" : cabinet.board_dimensions.x / 10.0,
		"thin" : cabinet.board_dimensions.x / 20.0,
	}[wire_thickness]
	b2c = dict(cabinetised_boards)
	for direction in [Direction.north, Direction.west, Direction.north_east]:
		for b, c in cabinetised_boards:
			ob = b.follow_wire(direction)
			oc = b2c[ob]
			
			src = (c.cabinet, c.frame, c.board, direction)
			dst = (oc.cabinet, oc.frame, oc.board, direction.opposite)
			if wire_filter((src, dst)):
				md.add_wire(src, dst, width=wire_thickness_m)
	
	# Render the image
	Context = {"png": PNGContextManager,
	           "pdf": PDFContextManager}[file_type]
	with Context(output_filename, image_width, image_height) as ctx:
		md.draw(ctx, image_width, image_height, *(((list(focus) + [None]*3)[:3])*2))
	
	return 0
Exemplo n.º 8
0
def main(args=None):
	parser = argparse.ArgumentParser(
		description="Print basic wiring statistics for a specified "
		            " configuration of boards.")
	arguments.add_version_args(parser)
	arguments.add_topology_args(parser)
	arguments.add_histogram_args(parser)
	arguments.add_wire_length_args(parser)
	arguments.add_cabinet_args(parser)
	
	# Process and display command-line arguments
	args = parser.parse_args(args)
	(w, h), transformation, uncrinkle_direction, folds =\
		arguments.get_topology_from_args(parser, args)
	histogram_bins = arguments.get_histogram_from_args(parser, args)
	wire_lengths, min_slack =\
		arguments.get_wire_lengths_from_args(parser, args)
	cabinet, num_frames = arguments.get_cabinets_from_args(parser, args)
	
	print(heading("Wiring Statistics", 1))
	print(heading("Folding Parameters", 2))
	print(table([["Parameter", "Value", "Unit"],
	             ["Number of boards", 3 * w * h, ""],
	             ["System dimensions", "{}x{}".format(w, h), "triads"],
	             ["Transformation", transformation, ""],
	             ["Uncrinkle Direction", uncrinkle_direction, ""],
	             ["Folds", "{}x{}".format(*folds), "pieces"],
	             ["Number of cabinets", cabinet.num_cabinets, ""],
	             ["Number of frames-per-cabinet", num_frames, ""],
	             ["Number of boards-per-frame", cabinet.boards_per_frame, ""],
	            ]))
	
	# Generate folded system and report wire-lengths after folding
	hex_boards, folded_boards = folded_torus(w, h,
	                                         transformation,
	                                         uncrinkle_direction,
	                                         folds)
	print(heading("Non-cabinetised measurements", 2))
	print(avg_wire_length_table(folded_boards, "boards"))
	
	# Divide into cabinets and report crossings
	cabinetised_boards = transforms.cabinetise(folded_boards,
	                                           cabinet.num_cabinets,
	                                           num_frames,
	                                           cabinet.boards_per_frame)
	cabinetised_boards = transforms.remove_gaps(cabinetised_boards)
	
	print(heading("Inter-cabinet/Inter-frame wiring", 2))
	print(wire_counts_table(cabinetised_boards))
	
	# Map to real, physical cabinets and measure wire lengths
	physical_boards = transforms.cabinet_to_physical(cabinetised_boards, cabinet)
	
	print(heading("Cabinetised measurements", 2))
	print("All wire lengths described in this section do not include any slack.\n")
	print(avg_wire_length_table(physical_boards, "meters",
	                            cabinet.board_wire_offset))
	
	# Generate a histogram of wire lengths
	print(heading("Wire length histogram", 2))
	print("Wire lengths are selected which include at least {} meters "
	      "of slack.\n".format(min_slack))
	print(wire_length_table(physical_boards,
	                        wire_lengths if wire_lengths else histogram_bins,
	                        min_slack,
	                        cabinet.board_wire_offset))
	
	return 0
Exemplo n.º 9
0
def main(args=None):
    parser = argparse.ArgumentParser(
        description=
        "Textually enumerate every connection required in a machine.")

    parser.add_argument("--sort-by",
                        "-s",
                        choices=["installation-order", "board", "wire-length"],
                        default="board",
                        help="Specifies the order the connections should be "
                        "listed in the file: installation-order sorts in "
                        "the most sensible order for installation, "
                        "board lists wires on a board-by-board basis, "
                        "wire-length lists in order of wire length.")

    arguments.add_version_args(parser)

    arguments.add_topology_args(parser)
    arguments.add_cabinet_args(parser)
    arguments.add_wire_length_args(parser)

    # Process command-line arguments
    args = parser.parse_args(args)
    (w, h), transformation, uncrinkle_direction, folds =\
     arguments.get_topology_from_args(parser, args)

    cabinet, num_frames = arguments.get_cabinets_from_args(parser, args)

    wire_lengths, min_slack = arguments.get_wire_lengths_from_args(
        parser, args, mandatory=True)

    # Generate folded system
    hex_boards, folded_boards = folded_torus(w, h, transformation,
                                             uncrinkle_direction, folds)

    # Divide into cabinets
    cabinetised_boards = transforms.cabinetise(folded_boards,
                                               cabinet.num_cabinets,
                                               num_frames,
                                               cabinet.boards_per_frame)
    cabinetised_boards = transforms.remove_gaps(cabinetised_boards)
    physical_boards = transforms.cabinet_to_physical(cabinetised_boards,
                                                     cabinet)

    # Generate wiring plan
    wires_between_boards, wires_between_frames, wires_between_cabinets =\
     generate_wiring_plan(cabinetised_boards, physical_boards,
                          cabinet.board_wire_offset, wire_lengths, min_slack)
    flat_wiring_plan = flatten_wiring_plan(wires_between_boards,
                                           wires_between_frames,
                                           wires_between_cabinets,
                                           cabinet.board_wire_offset)

    # Convert wiring plan into cabinet coordinates
    b2c = dict(cabinetised_boards)
    wires = []
    for ((src_board, src_direction), (dst_board, dst_direction), wire_length) \
        in flat_wiring_plan:

        sc, sf, sb = b2c[src_board]
        dc, df, db = b2c[dst_board]
        wires.append(((sc, sf, sb, src_direction), (dc, df, db, dst_direction),
                      wire_length, src_board, dst_board))

    b2p = dict(physical_boards)

    # Order as requested on the command-line
    if args.sort_by == "board":
        wires = sorted(wires)
    elif args.sort_by == "wire-length":
        wires = sorted(wires, key=(lambda w: (w[2], w[:2])))
    elif args.sort_by == "installation-order":  # pragma: no branch
        pass  # List is initially in assembly order

    print("C  F  B  Socket      C  F  B  Socket      Length")
    print("-- -- -- ----------  -- -- -- ----------  ------")
    for ((sc, sf, sb, src_direction), (dc, df, db, dst_direction), wire_length,
         src_board, dst_board) in wires:
        print("{:2d} {:2d} {:2d} {:10s}  {:2d} {:2d} {:2d} {:10s}  {:0.2f}".
              format(sc, sf, sb, src_direction.name.replace("_", " "), dc, df,
                     db, dst_direction.name.replace("_", " "), wire_length))

    return 0
Exemplo n.º 10
0
def main(args=None):
    parser = argparse.ArgumentParser(
        description=
        "Interactively guide the user through the process of wiring up a "
        "SpiNNaker machine.")
    arguments.add_version_args(parser)

    parser.add_argument("--no-tts",
                        action="store_true",
                        default=False,
                        help="disable text-to-speech announcements of wiring "
                        "steps")

    parser.add_argument("--no-auto-advance",
                        action="store_true",
                        default=False,
                        help="disable auto-advancing through wiring steps")

    parser.add_argument("--fix",
                        action="store_true",
                        default=False,
                        help="detect errors in existing wiring and just show "
                        "corrective steps")

    parser.add_argument(
        "--log",
        type=str,
        metavar="LOGFILE",
        help="record the times at which each cable is installed")

    arguments.add_topology_args(parser)
    arguments.add_cabinet_args(parser)
    arguments.add_wire_length_args(parser)
    arguments.add_bmp_args(parser)
    arguments.add_proxy_args(parser)
    arguments.add_subset_args(parser)

    # Process command-line arguments
    args = parser.parse_args(args)
    (w, h), transformation, uncrinkle_direction, folds =\
     arguments.get_topology_from_args(parser, args)

    cabinet, num_frames = arguments.get_cabinets_from_args(parser, args)

    wire_lengths, min_slack = arguments.get_wire_lengths_from_args(
        parser, args, mandatory=True)

    bmp_ips = arguments.get_bmps_from_args(parser, args, cabinet.num_cabinets,
                                           num_frames)

    proxy_host_port = arguments.get_proxy_from_args(parser, args)

    wire_filter = arguments.get_subset_from_args(parser, args)

    if cabinet.num_cabinets == num_frames == 1:
        num_boards = 3 * w * h
    else:
        num_boards = cabinet.boards_per_frame

    # Generate folded system
    hex_boards, folded_boards = folded_torus(w, h, transformation,
                                             uncrinkle_direction, folds)

    # Divide into cabinets
    cabinetised_boards = transforms.cabinetise(folded_boards,
                                               cabinet.num_cabinets,
                                               num_frames,
                                               cabinet.boards_per_frame)
    cabinetised_boards = transforms.remove_gaps(cabinetised_boards)
    physical_boards = transforms.cabinet_to_physical(cabinetised_boards,
                                                     cabinet)

    # Focus on only the boards which are part of the system
    if cabinet.num_cabinets > 1:
        focus = [slice(0, cabinet.num_cabinets)]
    elif num_frames > 1:
        focus = [0, slice(0, num_frames)]
    else:
        focus = [0, 0, slice(0, w * h * 3)]

    # Generate wiring plan
    wires_between_boards, wires_between_frames, wires_between_cabinets =\
     generate_wiring_plan(cabinetised_boards, physical_boards,
                          cabinet.board_wire_offset, wire_lengths, min_slack)
    flat_wiring_plan = flatten_wiring_plan(wires_between_boards,
                                           wires_between_frames,
                                           wires_between_cabinets,
                                           cabinet.board_wire_offset)

    # Create a BMP connection/wiring probe or connect to a proxy
    if proxy_host_port is None:
        if len(bmp_ips) == 0:
            if args.fix:
                parser.error(
                    "--fix requires that all BMPs be listed with --bmp")
            bmp_controller = None
            wiring_probe = None
        else:
            bmp_controller = BMPController(bmp_ips)

        # Create a wiring probe
        if bmp_controller is not None and (not args.no_auto_advance
                                           or args.fix):
            wiring_probe = WiringProbe(bmp_controller, cabinet.num_cabinets,
                                       num_frames, num_boards)
    else:
        # Fix is not supported since the proxy client does not recreate the
        # discover_wires method of WiringProbe.
        if args.fix:
            parser.error("--fix cannot be used with --proxy")

        # The proxy object provides a get_link_target and set_led method compatible
        # with those provided by bmp_controller and wiring_probe. Since these are
        # the only methods used, we use the proxy client object in place of
        # bmp_controller and wiring_probe.
        bmp_controller = wiring_probe = ProxyClient(*proxy_host_port)

    # Create a TimingLogger if required
    if args.log:
        if os.path.isfile(args.log):
            logfile = open(args.log, "a")
            add_header = False
        else:
            logfile = open(args.log, "w")
            add_header = True
        timing_logger = TimingLogger(logfile, add_header)
    else:
        logfile = None
        timing_logger = None

    # Convert wiring plan into cabinet coordinates
    b2c = dict(cabinetised_boards)
    wires = []
    for ((src_board, src_direction), (dst_board, dst_direction), wire_length) \
        in flat_wiring_plan:

        sc, sf, sb = b2c[src_board]
        dc, df, db = b2c[dst_board]
        wires.append(((sc, sf, sb, src_direction), (dc, df, db, dst_direction),
                      wire_length))

    # Filter wires according to user-specified rules
    wires = list(filter(wire_filter, wires))
    if len(wires) == 0:
        parser.error("--subset selects no wires")

    if not args.fix:
        # If running normally, just run through the full set of wires
        wiring_plan = wires
    else:
        # If running in fix mode, generate a list of fixes to make
        correct_wires = set((src, dst) for src, dst, length in wires)
        actual_wires = set(wiring_probe.discover_wires())

        to_remove = actual_wires - correct_wires
        to_add = correct_wires - actual_wires

        # Remove all bad wires first, then re-add good ones (note ordering now is
        # just reset to cabinets right-to-left, frames top-to-bottom and boards
        # left-to-right).
        wiring_plan = [(src, dst, None) for src, dst in sorted(to_remove)]
        for src, dst, length in wires:
            if (src, dst) in to_add:
                wiring_plan.append((src, dst, length))

        if len(wiring_plan) == 0:
            print("No corrections required.")
            return 0

    # Intialise the GUI and launch the mainloop
    ui = InteractiveWiringGuide(cabinet=cabinet,
                                wire_lengths=wire_lengths,
                                wires=wiring_plan,
                                bmp_controller=bmp_controller,
                                use_tts=not args.no_tts,
                                focus=focus,
                                wiring_probe=wiring_probe,
                                auto_advance=not args.no_auto_advance,
                                timing_logger=timing_logger)
    ui.mainloop()

    if logfile is not None:
        logfile.close()

    return 0
Exemplo n.º 11
0
def main(args=None):
	parser = argparse.ArgumentParser(
		description="Interactively guide the user through the process of wiring up a "
		            "SpiNNaker machine.")
	arguments.add_version_args(parser)
	
	parser.add_argument("--no-tts", action="store_true", default=False,
	                    help="disable text-to-speech announcements of wiring "
	                         "steps")
	
	parser.add_argument("--no-auto-advance", action="store_true", default=False,
	                    help="disable auto-advancing through wiring steps")
	
	parser.add_argument("--fix", action="store_true", default=False,
	                    help="detect errors in existing wiring and just show "
	                         "corrective steps")
	
	parser.add_argument("--log", type=str, metavar="LOGFILE",
	                    help="record the times at which each cable is installed")
	
	arguments.add_topology_args(parser)
	arguments.add_cabinet_args(parser)
	arguments.add_wire_length_args(parser)
	arguments.add_bmp_args(parser)
	arguments.add_proxy_args(parser)
	arguments.add_subset_args(parser)
	
	# Process command-line arguments
	args = parser.parse_args(args)
	(w, h), transformation, uncrinkle_direction, folds =\
		arguments.get_topology_from_args(parser, args)
	
	cabinet, num_frames = arguments.get_cabinets_from_args(parser, args)
	
	wire_lengths, min_slack = arguments.get_wire_lengths_from_args(
		parser, args, mandatory=True)
	
	bmp_ips = arguments.get_bmps_from_args(parser, args,
	                                       cabinet.num_cabinets,
	                                       num_frames)
	
	proxy_host_port = arguments.get_proxy_from_args(parser, args)
	
	wire_filter = arguments.get_subset_from_args(parser, args)
	
	if cabinet.num_cabinets == num_frames == 1:
		num_boards = 3 * w * h
	else:
		num_boards = cabinet.boards_per_frame
	
	# Generate folded system
	hex_boards, folded_boards = folded_torus(w, h,
	                                         transformation,
	                                         uncrinkle_direction,
	                                         folds)
	
	# Divide into cabinets
	cabinetised_boards = transforms.cabinetise(folded_boards,
	                                           cabinet.num_cabinets,
	                                           num_frames,
	                                           cabinet.boards_per_frame)
	cabinetised_boards = transforms.remove_gaps(cabinetised_boards)
	physical_boards = transforms.cabinet_to_physical(cabinetised_boards, cabinet)
	
	# Focus on only the boards which are part of the system
	if cabinet.num_cabinets > 1:
		focus = [slice(0, cabinet.num_cabinets)]
	elif num_frames > 1:
		focus = [0, slice(0, num_frames)]
	else:
		focus = [0, 0, slice(0, w*h*3)]
	
	
	# Generate wiring plan
	wires_between_boards, wires_between_frames, wires_between_cabinets =\
		generate_wiring_plan(cabinetised_boards, physical_boards,
		                     cabinet.board_wire_offset, wire_lengths, min_slack)
	flat_wiring_plan = flatten_wiring_plan(wires_between_boards,
	                                       wires_between_frames,
	                                       wires_between_cabinets,
	                                       cabinet.board_wire_offset)
	
	# Create a BMP connection/wiring probe or connect to a proxy
	if proxy_host_port is None:
		if len(bmp_ips) == 0:
			if args.fix:
				parser.error("--fix requires that all BMPs be listed with --bmp")
			bmp_controller = None
			wiring_probe = None
		else:
			bmp_controller = BMPController(bmp_ips)
		
		# Create a wiring probe
		if bmp_controller is not None and (not args.no_auto_advance or args.fix):
			wiring_probe = WiringProbe(bmp_controller,
			                           cabinet.num_cabinets,
			                           num_frames,
			                           num_boards)
	else:
		# Fix is not supported since the proxy client does not recreate the
		# discover_wires method of WiringProbe.
		if args.fix:
			parser.error("--fix cannot be used with --proxy")
		
		# The proxy object provides a get_link_target and set_led method compatible
		# with those provided by bmp_controller and wiring_probe. Since these are
		# the only methods used, we use the proxy client object in place of
		# bmp_controller and wiring_probe.
		bmp_controller = wiring_probe = ProxyClient(*proxy_host_port)
	
	# Create a TimingLogger if required
	if args.log:
		if os.path.isfile(args.log):
			logfile = open(args.log, "a")
			add_header = False
		else:
			logfile = open(args.log, "w")
			add_header = True
		timing_logger = TimingLogger(logfile, add_header)
	else:
		logfile = None
		timing_logger = None
	
	# Convert wiring plan into cabinet coordinates
	b2c = dict(cabinetised_boards)
	wires = []
	for ((src_board, src_direction), (dst_board, dst_direction), wire_length) \
	    in flat_wiring_plan:
		
		sc, sf, sb = b2c[src_board]
		dc, df, db = b2c[dst_board]
		wires.append(((sc, sf, sb, src_direction),
		              (dc, df, db, dst_direction),
		              wire_length))
	
	# Filter wires according to user-specified rules
	wires = list(filter(wire_filter, wires))
	if len(wires) == 0:
		parser.error("--subset selects no wires")
	
	if not args.fix:
		# If running normally, just run through the full set of wires
		wiring_plan = wires
	else:
		# If running in fix mode, generate a list of fixes to make
		correct_wires = set((src, dst) for src, dst, length in wires)
		actual_wires = set(wiring_probe.discover_wires())
		
		to_remove = actual_wires - correct_wires
		to_add = correct_wires - actual_wires
		
		# Remove all bad wires first, then re-add good ones (note ordering now is
		# just reset to cabinets right-to-left, frames top-to-bottom and boards
		# left-to-right).
		wiring_plan = [(src, dst, None) for src, dst in sorted(to_remove)]
		for src, dst, length in wires:
			if (src, dst) in to_add:
				wiring_plan.append((src, dst, length))
		
		if len(wiring_plan) == 0:
			print("No corrections required.")
			return 0

	
	# Intialise the GUI and launch the mainloop
	ui = InteractiveWiringGuide(cabinet=cabinet,
	                            wire_lengths=wire_lengths,
	                            wires=wiring_plan,
	                            bmp_controller=bmp_controller,
	                            use_tts=not args.no_tts,
	                            focus=focus,
	                            wiring_probe=wiring_probe,
	                            auto_advance=not args.no_auto_advance,
	                            timing_logger=timing_logger)
	ui.mainloop()
	
	if logfile is not None:
		logfile.close()
	
	return 0
Exemplo n.º 12
0
def main(args=None):
	parser = argparse.ArgumentParser(
		description="Validate the wiring of a SpiNNaker system.")
	arguments.add_version_args(parser)
	
	parser.add_argument("--verbose", "-v", action="store_true", default=False,
	                    help="list all incorrect and missing wires")
	
	arguments.add_topology_args(parser)
	arguments.add_cabinet_args(parser)
	arguments.add_bmp_args(parser)
	
	# Process command-line arguments
	args = parser.parse_args(args)
	(w, h), transformation, uncrinkle_direction, folds =\
		arguments.get_topology_from_args(parser, args)
	
	cabinet, num_frames = arguments.get_cabinets_from_args(parser, args)
	
	bmp_ips = arguments.get_bmps_from_args(parser, args,
	                                       cabinet.num_cabinets,
	                                       num_frames)
	
	if len(bmp_ips) == 0:
		parser.error("BMP host names must be provided for every frame.")
	
	# Generate folded system
	hex_boards, folded_boards = folded_torus(w, h,
	                                         transformation,
	                                         uncrinkle_direction,
	                                         folds)
	
	# Divide into cabinets
	cabinetised_boards = transforms.cabinetise(folded_boards,
	                                           cabinet.num_cabinets,
	                                           num_frames,
	                                           cabinet.boards_per_frame)
	cabinetised_boards = transforms.remove_gaps(cabinetised_boards)
	
	# Generate list of wires
	wires = plan.enumerate_wires(cabinetised_boards)
	
	# Set up the wiring probe
	bmp_controller = BMPController(bmp_ips)
	if cabinet.num_cabinets == 1 and num_frames == 1:
		num_boards = 3 * w * h
	else:
		num_boards = cabinet.boards_per_frame
	wiring_probe = probe.WiringProbe(bmp_controller,
	                                 cabinet.num_cabinets,
	                                 num_frames,
	                                 num_boards)
	
	
	# Check for the presence of every wire
	missing = []
	b2c = dict(cabinetised_boards)
	for ((src_board, src_direction), (dst_board, dst_direction)) in wires:
		src = tuple(list(b2c[src_board]) + [src_direction])
		dst = tuple(list(b2c[dst_board]) + [dst_direction])
		actual_dst = wiring_probe.get_link_target(*src)
		actual_src = wiring_probe.get_link_target(*dst)
		
		if actual_dst != dst or actual_src != src:
			missing.append((src, dst))
	
	if missing:
		sys.stderr.write("{} wires missing or erroneously connected.\n".format(
			len(missing), len(wires)))
		
		if args.verbose:
			for src, dst in missing:
				print("C:{} F:{} B:{} {} <--> C:{} F:{} B:{} {}".format(
					src[0], src[1], src[2], src[3].name.replace("_", " "),
					dst[0], dst[1], dst[2], dst[3].name.replace("_", " ")))
		else:
			print("Add --verbose for a complete list.")
		
		return -1
	else:
		sys.stderr.write("All {} wires correctly connected.\n".format(len(wires)))
		return 0