Esempio n. 1
0
def main(args=None):
    parser = argparse.ArgumentParser(
        description="Print basic topological statistics for a specified "
        " configuration of boards.")
    arguments.add_version_args(parser)
    arguments.add_topology_args(parser)
    args = parser.parse_args(args)
    (w, h), transformation, uncrinkle_direction, folds =\
     arguments.get_topology_from_args(parser, args)

    out = ""
    out += heading("Topology Statistics", 1)
    out += "\n"
    out += table([
        ["Measurement", "Value", "Unit"],
        ["Network dimensions", "{}x{}".format(w * 12, h * 12), "chips"],
        ["Board array", "{}x{}".format(w, h), "triad"],
        ["Number of boards", 3 * w * h, ""],
        ["Number of cables", 3 * w * h * 3, ""],
        ["Number of chips", 3 * w * h * 48, ""],
        ["Number of cores", 3 * w * h * 48 * 18, ""],
    ])

    print(out)

    return 0
Esempio n. 2
0
def test_get_topology_from_args_bad(argstring):
	parser = ArgumentParser()
	arguments.add_topology_args(parser)
	
	with pytest.raises(SystemExit):
		args = parser.parse_args(argstring.split())
		arguments.get_topology_from_args(parser, args)
def main(args=None):
	parser = argparse.ArgumentParser(
		description="Print basic topological statistics for a specified "
		            " configuration of boards.")
	arguments.add_version_args(parser)
	arguments.add_topology_args(parser)
	args = parser.parse_args(args)
	(w, h), transformation, uncrinkle_direction, folds =\
		arguments.get_topology_from_args(parser, args)
	
	out = ""
	out += heading("Topology Statistics", 1)
	out += "\n"
	out += table([["Measurement", "Value", "Unit"],
	              ["Network dimensions", "{}x{}".format(w*12, h*12), "chips"],
	              ["Board array", "{}x{}".format(w, h), "triad"],
	              ["Number of boards", 3 * w * h, ""],
	              ["Number of cables", 3 * w * h * 3, ""],
	              ["Number of chips", 3 * w * h * 48, ""],
	              ["Number of cores", 3 * w * h * 48 * 18, ""],
	             ])
	
	print(out)
	
	return 0
def test_get_diagram_arguments(argstring, to_check):
	parser = ArgumentParser()
	arguments.add_topology_args(parser)
	arguments.add_cabinet_args(parser)
	add_diagram_arguments(parser)
	
	args = parser.parse_args(argstring.split())
	
	(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)
	
	if "wire_thickness" in to_check:
		assert wire_thickness == to_check.pop("wire_thickness")
	
	if "focus" in to_check:
		assert focus == to_check.pop("focus")
	
	if "highlight" in to_check:
		assert highlights == to_check.pop("highlight")
	
	if "hide_labels" in to_check:
		assert hide_labels == to_check.pop("hide_labels")
	
	# Make sure none of the test-cases define something to test which isn't
	# tested...
	assert len(to_check) == 0
def test_get_diagram_arguments(argstring, to_check):
    parser = ArgumentParser()
    arguments.add_topology_args(parser)
    arguments.add_cabinet_args(parser)
    add_diagram_arguments(parser)

    args = parser.parse_args(argstring.split())

    (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)

    if "wire_thickness" in to_check:
        assert wire_thickness == to_check.pop("wire_thickness")

    if "focus" in to_check:
        assert focus == to_check.pop("focus")

    if "highlight" in to_check:
        assert highlights == to_check.pop("highlight")

    if "hide_labels" in to_check:
        assert hide_labels == to_check.pop("hide_labels")

    # Make sure none of the test-cases define something to test which isn't
    # tested...
    assert len(to_check) == 0
def main(args=None):
	parser = argparse.ArgumentParser(
		description="Start a proxy server to enable multiple interactive wiring "
		            "sessions to interact with the same SpiNNaker machine.")
	arguments.add_version_args(parser)
	
	parser.add_argument("--host", "-H", type=str, default="",
	                    help="Host interface to listen on (default: any)")
	
	parser.add_argument("--port", "-p", type=int, default=DEFAULT_PORT,
	                    help="Port listen on (default: %(default)d)")
	
	parser.add_argument("--verbose", "-v", action="count", default=0,
	                    help="Increase verbosity.")
	
	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 cabinet.num_cabinets == num_frames == 1:
		num_boards = 3 * w * h
	else:
		num_boards = cabinet.boards_per_frame
	
	# Set verbosity level
	if args.verbose == 1:
		logging.basicConfig(level=logging.INFO)
	elif args.verbose >= 2:
		logging.basicConfig(level=logging.DEBUG)
	
	# Create a BMP connection
	if len(bmp_ips) == 0:
		parser.error("All BMPs must be supplied using --bmp")
	bmp_controller = BMPController(bmp_ips)
	
	# Create a wiring probe
	wiring_probe = WiringProbe(bmp_controller,
	                           cabinet.num_cabinets,
	                           num_frames,
	                           num_boards)
	
	proxy_server = ProxyServer(bmp_controller, wiring_probe,
	                           args.host, args.port)
	
	print("Proxy server starting...")
	proxy_server.main()
	
	return 0
Esempio n. 7
0
def test_get_cabinets_from_args_num_cabinets_num_frames(argstring,
                                                        num_cabinets,
                                                        num_frames):
	# Ensure that the number of frames/cabinets required is worked out correctly.
	parser = ArgumentParser()
	arguments.add_topology_args(parser)
	arguments.add_cabinet_args(parser)
	
	args = parser.parse_args(argstring.split())
	cabinet, actual_num_frames =\
		arguments.get_cabinets_from_args(parser, args)
	actual_num_cabinets = cabinet.num_cabinets
	
	assert actual_num_cabinets == num_cabinets
	assert actual_num_frames == num_frames
Esempio n. 8
0
def test_get_topology_from_args_dimensions(argstring, dimensions,
                                           transformation, uncrinkle_direction,
                                           folds):
	parser = ArgumentParser()
	arguments.add_topology_args(parser)
	
	args = parser.parse_args(argstring.split())
	(actual_dimensions,
	 actual_transformation,
	 actual_uncrinkle_direction,
	 actual_folds) = arguments.get_topology_from_args(parser, args)
	
	assert actual_dimensions == dimensions
	assert actual_transformation == transformation
	assert actual_uncrinkle_direction == uncrinkle_direction
	assert actual_folds == folds
Esempio n. 9
0
def test_get_cabinets_from_args(with_topology,
                                set_num_cabinets,
                                set_num_frames):
	parser = ArgumentParser()
	if with_topology:
		arguments.add_topology_args(parser)
	arguments.add_cabinet_args(parser)
	
	unique_copy = unique.copy()
	del unique_copy["num_cabinets"]
	
	# Construct an argument string to set all possible arguments
	argstring = " ".join("--{} {}".format(name.replace("_", "-"),
	                                      " ".join(map(str, vals))
	                                      if isinstance(vals, tuple)
	                                      else str(vals))
	                     for (name, vals) in iteritems(unique_copy))
	
	if with_topology:
		argstring += " -n 3"
	if set_num_cabinets:
		argstring += " --num-cabinets 1"
	if set_num_frames:
		argstring += " --num-frames 1"
	
	args = parser.parse_args(argstring.split())
	cabinet, num_frames = arguments.get_cabinets_from_args(parser, args)
	
	# Check all arguments propagated through to the cabinet
	for name, value in iteritems(unique_copy):
		if name in board_wire_offset_fields:
			cabinet.board_wire_offset[board_wire_offset_fields[name]] == value
		else:
			assert hasattr(cabinet, name)
			assert getattr(cabinet, name) == value
	
	# Check that the cabinet/frame count is correct
	if ((not with_topology and not set_num_frames) or
	    (set_num_cabinets and not set_num_frames)):
		assert cabinet.num_cabinets == 1
		assert num_frames == 2
	else:
		assert cabinet.num_cabinets == 1
		assert num_frames == 1
Esempio n. 10
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
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
Esempio n. 12
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
Esempio n. 13
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
Esempio n. 14
0
def main(args=None):
    parser = argparse.ArgumentParser(
        description="Start a proxy server to enable multiple interactive wiring "
        "sessions to interact with the same SpiNNaker machine.")
    arguments.add_version_args(parser)

    parser.add_argument("--host",
                        "-H",
                        type=str,
                        default="",
                        help="Host interface to listen on (default: any)")

    parser.add_argument("--port",
                        "-p",
                        type=int,
                        default=DEFAULT_PORT,
                        help="Port listen on (default: %(default)d)")

    parser.add_argument("--verbose",
                        "-v",
                        action="count",
                        default=0,
                        help="Increase verbosity.")

    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 cabinet.num_cabinets == num_frames == 1:
        num_boards = 3 * w * h
    else:
        num_boards = cabinet.boards_per_frame

    # Set verbosity level
    if args.verbose == 1:
        logging.basicConfig(level=logging.INFO)
    elif args.verbose >= 2:
        logging.basicConfig(level=logging.DEBUG)

    # Create a BMP connection
    if len(bmp_ips) == 0:
        parser.error("All BMPs must be supplied using --bmp")
    bmp_controller = BMPController(bmp_ips)

    # Create a wiring probe
    wiring_probe = WiringProbe(bmp_controller, cabinet.num_cabinets,
                               num_frames, num_boards)

    proxy_server = ProxyServer(bmp_controller, wiring_probe, args.host,
                               args.port)

    print("Proxy server starting...")
    proxy_server.main()

    return 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
Esempio n. 16
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
Esempio n. 17
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
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
Esempio n. 19
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