Exemple #1
0
def visualize_board(cgra_file):
    from arch import parse_cgra
    color_index = "imopr"
    board_meta = parse_cgra(cgra_file)["CGRA"]
    board_layout = board_meta[0]
    scale = 30
    board_info = board_meta[-1]
    height, width = board_info["height"], board_info["width"]
    im, draw = draw_board(width, height, scale)
    for y in range(height):
        for x in range(width):
            blk_type = board_layout[y][x]
            if blk_type is not None:
                index = color_index.index(blk_type)
                color = color_palette[index]
                draw_cell(draw, (x, y), color, scale)
    plt.imshow(im)
    plt.show()

    basename = os.path.basename(cgra_file)
    design_name, ext = os.path.splitext(basename)
    file_dir = os.path.dirname(os.path.realpath(__file__))
    output_dir = os.path.join(file_dir, "figures")
    if os.path.isdir(output_dir):
        output_png = design_name + "_cgra.png"
        output_path = os.path.join(output_dir, output_png)
        im.save(output_path)
        print("Image saved to", output_path)
Exemple #2
0
def main():
    if len(sys.argv) == 2:
        cgra_info = sys.argv[1]
        visualize_board(cgra_info)
        return
    if len(sys.argv) != 4:
        print("[Usage]:", sys.argv[0], "<cgra_info>",
              "[<design.packed>", "<design.place|design.route>]",
              file=sys.stderr)
        exit(1)
    cgra_info = sys.argv[1]
    packed_file = sys.argv[2]
    input_file = sys.argv[3]
    basename = os.path.basename(input_file)
    design_name, ext = os.path.splitext(basename)
    from arch import parse_cgra
    from arch import load_packed_file
    _, _, _, changed_pe = load_packed_file(packed_file)
    fold_reg = len(changed_pe) == 0
    board_meta = parse_cgra(cgra_info, fold_reg=fold_reg)["CGRA"]
    if ext == ".place":
        from arch import parse_placement
        board_pos, _ = parse_placement(input_file)
        visualize_placement_cgra(board_meta, board_pos, design_name, changed_pe)
    elif ext == ".route":
        from arch import parse_routing_result
        routing_result = parse_routing_result(input_file)
        visualize_routing(cgra_info, board_meta, packed_file, routing_result,
                          fold_reg=fold_reg)
Exemple #3
0
def visualize_board(cgra_file):
    from arch import parse_cgra
    color_index = "imoprI"
    layout = parse_cgra(cgra_file)["CGRA"]
    scale = 30
    height, width = layout.height(), layout.width()
    im, draw = draw_board(width, height, scale)
    for y in range(height):
        for x in range(width):
            blk_type = layout.get_blk_type(x, y)
            if blk_type is not None:
                index = color_index.index(blk_type)
                color = color_palette[index % len(color_palette)]
                draw_cell(draw, (x, y), color, scale)
    im.show()

    basename = os.path.basename(cgra_file)
    design_name, ext = os.path.splitext(basename)
    file_dir = os.path.dirname(os.path.realpath(__file__))
    output_dir = os.path.join(file_dir, "figures")
    if os.path.isdir(output_dir):
        output_png = design_name + "_cgra.png"
        output_path = os.path.join(output_dir, output_png)
        im.save(output_path)
        print("Image saved to", output_path)
Exemple #4
0
def main():
    parser = ArgumentParser("CGRA Router")
    parser.add_argument("-i",
                        "--input",
                        help="Packed netlist file, " + "e.g. harris.packed",
                        required=True,
                        action="store",
                        dest="packed_filename")
    parser.add_argument("-o",
                        "--output",
                        help="Routing result, " + "e.g. harris.route",
                        required=True,
                        action="store",
                        dest="route_file")
    parser.add_argument("-c",
                        "--cgra",
                        help="CGRA architecture file",
                        required=True,
                        action="store",
                        dest="arch_filename")
    parser.add_argument("-p",
                        "--placement",
                        help="Placement file",
                        required=True,
                        action="store",
                        dest="placement_filename")
    parser.add_argument("--no-reg-fold",
                        help="If set, the placer will treat " +
                        "registers as PE tiles",
                        action="store_true",
                        required=False,
                        dest="no_reg_fold",
                        default=False)
    parser.add_argument("--no-vis",
                        help="If set, the router won't show " +
                        "visualization result for routing",
                        action="store_true",
                        required=False,
                        dest="no_vis",
                        default=False)
    args = parser.parse_args()

    arch_filename = args.arch_filename
    packed_filename = args.packed_filename
    route_file = args.route_file

    vis_opt = not args.no_vis
    fold_reg = not args.no_reg_fold

    placement_filename = args.placement_filename
    meta = parse_cgra(arch_filename, fold_reg=fold_reg)["CGRA"]
    r = Router(arch_filename, meta, packed_filename, placement_filename)
    r.route()
    if vis_opt:
        r.vis_routing_resource()
    # r.compute_stats()

    save_routing_result(r.route_result, route_file)
Exemple #5
0
def main():
    if len(sys.argv) != 4:
        print("Usage:",
              sys.argv[0],
              "<cgra_info.txt>",
              "<netlist.json>",
              "<netlist.route>",
              file=sys.stderr)
        exit(1)
    cgra_file = sys.argv[1]
    netlist = sys.argv[2]
    route_file = sys.argv[3]
    packed_file = route_file.replace(".route", ".packed")
    placement_file = route_file.replace(".route", ".place")
    board_layout = parse_cgra(cgra_file)["CGRA"]
    routing_result = parse_routing(route_file)
    placement, _ = parse_placement(placement_file)

    if hasattr(sys.stdout, 'isatty') and sys.stdout.isatty():
        meta = os.popen('stty size', 'r').read().split()
        cols = int(meta[-1])
        cols = int(cols)
        scale = cols - 15
    else:
        scale = 68
        cols = 80

    print("-" * cols)
    print("Area Usage:")
    usage = compute_area_usage(placement, board_layout)
    for entry in usage:
        percentage = usage[entry][0] / usage[entry][1] * 100
        num_bar = max(int(percentage / 100 * scale) - 2, 1)
        print("{0:4s} {1} {2} {3:.2f}%".format(entry.upper(), num_bar * '█',
                                               ' ' * (scale - num_bar - 2),
                                               percentage))

    print("-" * cols)
    net_wire = compute_total_wire(routing_result)
    total_wire = sum([net_wire[x] for x in net_wire])
    print("Total wire:", total_wire)

    # timing removed for future development

    print("-" * cols)
    r = parse_routing_resource(cgra_file)
    routing_resource = build_routing_resource(r)
    resource_usage = compute_routing_usage(routing_result, routing_resource)
    for bus in resource_usage:
        print("BUS:", bus)
        for track in resource_usage[bus]:
            total, left = resource_usage[bus][track]
            percentage = (total - left) / total * 100
            num_bar = int(percentage / 100 * scale)
            print("TRACK {0} {1} {2} {3:.2f}%".format(
                track, num_bar * '█', ' ' * (scale - num_bar - 5), percentage))
Exemple #6
0
def main():
    parser = ArgumentParser("CGRA graph creation")
    parser.add_argument("-i",
                        "--input",
                        help="CGRA info file",
                        required=True,
                        action="store",
                        dest="cgra_filename")
    parser.add_argument("-o",
                        "--output",
                        help="Graph output folder for "
                        "cyclone router",
                        required=True,
                        action="store",
                        dest="graph_dirname")
    parser.add_argument("-O",
                        "--override",
                        help="Override the existing one "
                        "if the output file exists",
                        required=False,
                        default=False,
                        action="store_true",
                        dest="override_graph")

    args = parser.parse_args()
    cgra_filename = args.cgra_filename
    graph_dirname = args.graph_dirname
    override_graph = args.override_graph

    # if the directory doesn't exit, create one
    if not os.path.isdir(graph_dirname):
        print("creating folder", graph_dirname)
        os.mkdir(graph_dirname)

    g_16_filename = os.path.join(graph_dirname, GRAPH_16)
    g_1_filename = os.path.join(graph_dirname, GRAPH_1)
    if os.path.isfile(g_16_filename) and not override_graph:
        print("found existing", g_16_filename, "skipped.")
        exit(0)
    elif os.path.isfile(g_16_filename):
        print("override existing graph file")

    layout = parse_cgra(cgra_filename)["CGRA"]
    raw_routing_resource = parse_routing_resource(cgra_filename)
    routing_resource = build_routing_resource(raw_routing_resource)
    g_1, g_16 = build_routing_graph(routing_resource, layout)
    pycyclone.io.dump_routing_graph(g_16, g_16_filename)
    pycyclone.io.dump_routing_graph(g_1, g_1_filename)

    print("graph saved to", g_1_filename, g_16_filename)
Exemple #7
0
def generate_bitstream(board_filename, netlist_filename,
                       packed_filename, placement_filename,
                       routing_filename, output_filename,
                       io_json,
                       fold_reg=True):
    netlists, folded_blocks, id_to_name, changed_pe =\
        load_packed_file(packed_filename)
    g = build_graph(netlists)
    board_meta = arch.parse_cgra(board_filename, True)["CGRA"]
    placement, _ = parse_placement(placement_filename)
    route_result = parse_routing_result(routing_filename)
    tile_mapping = board_meta[-1]
    board_layout = board_meta[0]
    io_pad_name = board_meta[-2]["io_pad_name"]
    io_pad_bit = board_meta[-2]["io_pad_bit"]
    io16_tile = board_meta[-2]["io16_tile"]

    connections, instances = read_netlist_json(netlist_filename)

    output_string = ""

    # TODO: refactor this
    name_to_id = {}
    for blk_id in id_to_name:
        name_to_id[id_to_name[blk_id]] = blk_id

    # build PE tiles types
    pe_tiles = {}
    type_str = "mpir"
    for name in instances:
        instance = instances[name]
        blk_id = name_to_id[name]
        if blk_id in folded_blocks:
            continue
        blk_id = name_to_id[name]
        # it might be absorbed already
        if blk_id not in g.nodes():
            continue
        # it has to be a PE tile
        assert(blk_id[0] in type_str)
        pos = placement[blk_id]
        tile = tile_mapping[pos]

        # find out the PE type
        tile_op, print_order = get_tile_op(instance, blk_id, changed_pe)
        if tile_op is None:
            continue
        pins = get_tile_pins(blk_id, tile_op, folded_blocks, instances,
                             changed_pe, id_to_name, connections)

        # parse pins from the packing

        pe_tiles[blk_id] = (tile, tile_op, pins, print_order)

    tab = "\t" * 6
    # generate tile mapping
    # sort them for pretty printing
    pe_keys = list(pe_tiles.keys())
    pe_keys.sort(key=lambda x: int(pe_tiles[x][0]))
    pe_keys.sort(key=lambda x: pe_tiles[x][-1])
    output_string += "# PLACEMENT\n"
    for blk_id in pe_keys:
        tile, op, pins, _ = pe_tiles[blk_id]
        if "mem" in op:
            output_string += "Tx{:04X}_{}{}#{}\n".format(tile, op,
                                                         tab,
                                                         id_to_name[blk_id])
        else:
            output_string += "Tx{:04X}_{}({}){}# {}\n".format(tile, op,
                                                              ",".join(pins),
                                                              tab,
                                                              id_to_name[
                                                                  blk_id])
    # IO info
    io_pad_info, io_strings = generate_io(id_to_name, io16_tile, io_pad_bit,
                                          io_pad_name, placement, tile_mapping)

    assert len(io_strings) > 0
    output_string += "\n\n#IO\n"
    output_string += "\n".join(io_strings)

    output_string += "\n\n#ROUTING\n"
    net_id_list = list(route_result.keys())
    net_id_list.sort(key=lambda x: int(x[1:]))
    for net_id in net_id_list:
        path = route_result[net_id]
        output_string += "\n# net id: {}\n".format(net_id)
        netlist = netlists[net_id]
        for p in netlist:
            output_string += "# {}: {}::{}\n".format(p[0], id_to_name[p[0]],
                                                     p[1])

        for index, entry in enumerate(path):
            path_type = entry[0]
            if index == 0:
                assert (path_type == "src")
                s = handle_src(entry[1], entry[2], tile_mapping,
                               board_layout,
                               fold_reg=fold_reg)
                output_string += s
            else:
                if path_type == "src":
                    s = handle_src(entry[1], entry[2], tile_mapping,
                                   board_layout,
                                   fold_reg=fold_reg)
                    output_string += s
                elif path_type == "link":
                    track_out = entry[2][0]
                    assert (track_out[1] == 1)
                    track_in = find_track_in(entry[1][0], track_out,
                                             path[:index + 1])
                    s = handle_link(entry[1], entry[2],
                                    track_in,
                                    tile_mapping,
                                    board_layout)
                    if s not in output_string:
                        # Keyi:
                        # sometimes it will produce legal duplicated routing
                        # tracks.
                        output_string += s
                elif path_type == "sink":
                    if len(entry) == 4:
                        track_out = entry[-2]
                        assert len(track_out) == 4 and track_out[1] == 1
                    else:
                        assert len(entry) == 3
                        track_out = None
                    track_in = find_track_in(entry[-1][0], track_out,
                                             path[:index + 1])
                    s = handle_sink_entry(entry, track_in,
                                          tile_mapping, board_layout,
                                          folded_blocks, placement,
                                          fold_reg=fold_reg)
                    output_string += s
                else:
                    raise Exception("Unknown stage: " + path_type)

        output_string += "\n"

    with open(output_filename, "w+") as f:
        f.write(output_string)

    with open(io_json, "w+") as f:
        json.dump(io_pad_info, f, indent=2, separators=(',', ': '))
Exemple #8
0
def main():
    # only the main thread needs it
    import numpy as np
    from argparse import ArgumentParser
    from arch.parser import parse_emb
    from arch import make_board, parse_cgra, generate_place_on_board, parse_fpga
    from arch.cgra import place_special_blocks, save_placement, prune_netlist
    from arch.cgra_packer import load_packed_file
    from arch.fpga import load_packed_fpga_netlist
    from arch import mock_board_meta
    from visualize import visualize_placement_cgra

    parser = ArgumentParser("CGRA Placer")
    parser.add_argument("-i",
                        "--input",
                        help="Packed netlist file, " + "e.g. harris.packed",
                        required=True,
                        action="store",
                        dest="packed_filename")
    parser.add_argument("-e",
                        "--embedding",
                        help="Netlist embedding file, " + "e.g. harris.emb",
                        required=True,
                        action="store",
                        dest="netlist_embedding")
    parser.add_argument("-o",
                        "--output",
                        help="Placement result, " + "e.g. harris.place",
                        required=True,
                        action="store",
                        dest="placement_filename")
    parser.add_argument("-c",
                        "--cgra",
                        help="CGRA architecture file",
                        action="store",
                        dest="cgra_arch",
                        default="")
    parser.add_argument("--no-reg-fold",
                        help="If set, the placer will treat " +
                        "registers as PE tiles",
                        action="store_true",
                        required=False,
                        dest="no_reg_fold",
                        default=False)
    parser.add_argument("--no-vis",
                        help="If set, the placer won't show " +
                        "visualization result for placement",
                        action="store_true",
                        required=False,
                        dest="no_vis",
                        default=False)
    parser.add_argument("-s",
                        "--seed",
                        help="Seed for placement. " + "default is 0",
                        type=int,
                        default=0,
                        required=False,
                        action="store",
                        dest="seed")

    parser.add_argument("-a",
                        "--aws",
                        help="Serverless configuration for " +
                        "detailed placement. If set, will try to connect to "
                        "that arn",
                        dest="aws_config",
                        type=str,
                        required=False,
                        action="store",
                        default="")
    parser.add_argument("-f",
                        "--fpga",
                        action="store",
                        dest="fpga_arch",
                        default="",
                        help="ISPD FPGA architecture file")
    parser.add_argument("--mock",
                        action="store",
                        dest="mock_size",
                        default=0,
                        type=int,
                        help="Mock CGRA board with "
                        "provided size")
    args = parser.parse_args()

    cgra_arch = args.cgra_arch
    fpga_arch = args.fpga_arch
    mock_size = args.mock_size

    if len(cgra_arch) == 0 ^ len(fpga_arch) == 0 and mock_size == 0:
        parser.error("Must provide wither --fpga or --cgra")

    packed_filename = args.packed_filename
    netlist_embedding = args.netlist_embedding
    placement_filename = args.placement_filename
    aws_config = args.aws_config
    fpga_place = len(fpga_arch) > 0

    seed = args.seed
    print("Using seed", seed, "for placement")
    # just in case for some library
    random.seed(seed)
    np.random.seed(seed)

    vis_opt = not args.no_vis
    fold_reg = not args.no_reg_fold
    # FPGA params override
    if mock_size > 0:
        fold_reg = False
        board_meta = mock_board_meta(mock_size)
    elif fpga_place:
        fold_reg = False
        board_meta = parse_fpga(fpga_arch)
    else:
        board_meta = parse_cgra(cgra_arch, fold_reg=fold_reg)
    print(fold_reg)
    # Common routine
    board_name, board_meta = board_meta.popitem()
    print("INFO: Placing for", board_name)
    num_dim, raw_emb = parse_emb(netlist_embedding)
    board = make_board(board_meta)
    board_info = board_meta[-1]
    place_on_board = generate_place_on_board(board_meta, fold_reg=fold_reg)

    fixed_blk_pos = {}
    special_blocks = set()
    emb = {}

    # FPGA
    if fpga_place:
        netlists, fixed_blk_pos, _ = load_packed_fpga_netlist(packed_filename)
        num_of_kernels = None
        id_to_name = {}
        for blk_id in raw_emb:
            id_to_name[blk_id] = blk_id
            if blk_id[0] == "i":
                special_blocks.add(blk_id)
            else:
                emb[blk_id] = raw_emb[blk_id]
        # place fixed IO locations
        for blk_id in fixed_blk_pos:
            pos = fixed_blk_pos[blk_id]
            place_on_board(board, blk_id, pos)

        folded_blocks = {}
        changed_pe = {}

    else:
        # CGRA
        raw_netlist, folded_blocks, id_to_name, changed_pe = \
            load_packed_file(packed_filename)
        num_of_kernels = get_num_clusters(id_to_name)
        netlists = prune_netlist(raw_netlist)

        for blk_id in raw_emb:
            if blk_id[0] == "i":
                special_blocks.add(blk_id)
            else:
                emb[blk_id] = raw_emb[blk_id]
        # place the spacial blocks first
        place_special_blocks(board, special_blocks, fixed_blk_pos, raw_netlist,
                             id_to_name, place_on_board, board_meta)

    # common routine
    data_x = np.zeros((len(emb), num_dim))
    blks = list(emb.keys())
    for i in range(len(blks)):
        data_x[i] = emb[blks[i]]

    centroids, cluster_cells, clusters = perform_global_placement(
        blks,
        data_x,
        emb,
        fixed_blk_pos,
        netlists,
        board_meta,
        fold_reg=fold_reg,
        num_clusters=num_of_kernels,
        seed=seed,
        fpga_place=fpga_place,
        vis=vis_opt)

    # placer with each cluster
    board_pos = perform_detailed_placement(centroids, cluster_cells, clusters,
                                           fixed_blk_pos, netlists, fold_reg,
                                           seed, board_info, aws_config)
    # refinement
    board_pos = refine_global_thunder(board_meta, board_pos, netlists,
                                      fixed_blk_pos, fold_reg)

    for blk_id in board_pos:
        pos = board_pos[blk_id]
        place_on_board(board, blk_id, pos)

    # save the placement file
    save_placement(board_pos, id_to_name, folded_blocks, placement_filename)
    basename_file = os.path.basename(placement_filename)
    design_name, _ = os.path.splitext(basename_file)
    if vis_opt:
        visualize_placement_cgra(board_meta, board_pos, design_name,
                                 changed_pe)
Exemple #9
0
def main():
    parser = ArgumentParser("CGRA Placer")
    parser.add_argument("-i",
                        "--input",
                        help="Packed netlist file, " + "e.g. harris.packed",
                        required=True,
                        action="store",
                        dest="packed_filename")
    parser.add_argument("-e",
                        "--embedding",
                        help="Netlist embedding file, " + "e.g. harris.emb",
                        required=True,
                        action="store",
                        dest="netlist_embedding")
    parser.add_argument("-o",
                        "--output",
                        help="Placement result, " + "e.g. harris.place",
                        required=True,
                        action="store",
                        dest="placement_filename")
    parser.add_argument("-c",
                        "--cgra",
                        help="CGRA architecture file",
                        required=True,
                        action="store",
                        dest="arch_filename")
    parser.add_argument("--no-reg-fold",
                        help="If set, the placer will treat " +
                        "registers as PE tiles",
                        action="store_true",
                        required=False,
                        dest="no_reg_fold",
                        default=False)
    parser.add_argument("--no-vis",
                        help="If set, the placer won't show " +
                        "visualization result for placement",
                        action="store_true",
                        required=False,
                        dest="no_vis",
                        default=False)
    parser.add_argument("-s",
                        "--seed",
                        help="Seed for placement. " + "default is 0",
                        type=int,
                        default=0,
                        required=False,
                        action="store",
                        dest="seed")

    args = parser.parse_args()

    arch_filename = args.arch_filename
    packed_filename = args.packed_filename
    netlist_embedding = args.netlist_embedding
    placement_filename = args.placement_filename

    seed = args.seed
    print("Using seed", seed, "for placement")
    # just in case for some library
    random.seed(seed)
    np.random.seed(seed)

    vis_opt = not args.no_vis
    fold_reg = not args.no_reg_fold

    board_meta = parse_cgra(arch_filename, fold_reg=fold_reg)
    board_name, board_meta = board_meta.popitem()
    print("INFO: Placing for", board_name)
    num_dim, raw_emb = parse_emb(netlist_embedding)
    board = make_board(board_meta)
    place_on_board = generate_place_on_board(board_meta, fold_reg=fold_reg)
    is_cell_legal = generate_is_cell_legal(board_meta, fold_reg=fold_reg)

    fixed_blk_pos = {}
    emb = {}
    raw_netlist, folded_blocks, id_to_name, changed_pe = \
        load_packed_file(packed_filename)
    netlists = prune_netlist(raw_netlist)
    special_blocks = set()
    for blk_id in raw_emb:
        if blk_id[0] == "i":
            special_blocks.add(blk_id)
        else:
            emb[blk_id] = raw_emb[blk_id]
    # place the spacial blocks first
    place_special_blocks(board, special_blocks, fixed_blk_pos, raw_netlist,
                         id_to_name, place_on_board, board_meta)

    data_x = np.zeros((len(emb), num_dim))
    blks = list(emb.keys())
    for i in range(len(blks)):
        data_x[i] = emb[blks[i]]

    num_of_kernels = get_num_clusters(id_to_name)

    centroids, cluster_cells, clusters, fallback = perform_global_placement(
        blks,
        data_x,
        emb,
        fixed_blk_pos,
        netlists,
        board,
        is_cell_legal,
        board_meta,
        fold_reg=fold_reg,
        num_clusters=num_of_kernels,
        seed=seed)

    # anneal with each cluster
    board_pos = perform_detailed_placement(board, centroids, cluster_cells,
                                           clusters, fixed_blk_pos, netlists,
                                           raw_netlist, fold_reg, seed,
                                           fallback)

    # do a macro placement
    # macro_result = macro_placement(board, board_pos, fixed_blk_pos, netlists,
    #                               is_cell_legal, board_meta)
    # board_pos.update(macro_result)

    # only use deblock when we have lots of clusters
    # if len(clusters) > 2:
    #     board_pos = perform_deblock_placement(board, board_pos, fixed_blk_pos,
    #                                          netlists)

    for blk_id in board_pos:
        pos = board_pos[blk_id]
        place_on_board(board, blk_id, pos)

    # save the placement file
    save_placement(board_pos, id_to_name, folded_blocks, placement_filename)
    basename_file = os.path.basename(placement_filename)
    design_name, _ = os.path.splitext(basename_file)
    if vis_opt:
        visualize_placement_cgra(board_meta, board_pos, design_name,
                                 changed_pe)
Exemple #10
0
def generate_bitstream(board_filename, netlist_filename, packed_filename,
                       placement_filename, routing_filename, output_filename,
                       io_json):
    netlists, folded_blocks, id_to_name, changed_pe = \
        load_packed_file(packed_filename)
    blks = get_blks(netlists)
    board_meta = arch.parse_cgra(board_filename, True)["CGRA"]
    placement, _ = parse_placement(placement_filename)
    tile_mapping = board_meta[-1]
    board_layout = board_meta[0]
    io_pad_name = board_meta[-2]["io_pad_name"]
    io_pad_bit = board_meta[-2]["io_pad_bit"]
    io16_tile = board_meta[-2]["io16_tile"]

    connections, instances = read_netlist_json(netlist_filename)

    output_string = ""

    # TODO: refactor this
    name_to_id = {}
    for blk_id in id_to_name:
        name_to_id[id_to_name[blk_id]] = blk_id

    # build PE tiles types
    pe_tiles = {}
    type_str = "mpirI"
    for name in instances:
        instance = instances[name]
        blk_id = name_to_id[name]
        if blk_id in folded_blocks:
            continue
        blk_id = name_to_id[name]
        # it might be absorbed already
        if blk_id not in blks:
            continue
        # it has to be a PE tile
        assert (blk_id[0] in type_str)
        pos = placement[blk_id]
        tile = tile_mapping[pos]

        # find out the PE type
        tile_op, print_order = get_tile_op(instance, blk_id, changed_pe)
        if tile_op is None:
            continue
        pins = get_tile_pins(blk_id, tile_op, folded_blocks, instances,
                             changed_pe, id_to_name, connections)

        # parse pins from the packing

        pe_tiles[blk_id] = (tile, tile_op, pins, print_order)

    tab = "\t" * 6
    # generate tile mapping
    # sort them for pretty printing
    pe_keys = list(pe_tiles.keys())
    pe_keys.sort(key=lambda x: int(pe_tiles[x][0]))
    pe_keys.sort(key=lambda x: pe_tiles[x][-1])
    output_string += "# PLACEMENT\n"
    for blk_id in pe_keys:
        tile, op, pins, _ = pe_tiles[blk_id]
        if "mem" in op:
            output_string += "Tx{:04X}_{}{}#{}\n".format(
                tile, op, tab, id_to_name[blk_id])
        else:
            output_string += "Tx{:04X}_{}({}){}# {}\n".format(
                tile, op, ",".join(pins), tab, id_to_name[blk_id])
    # IO info
    io_pad_info, io_strings = generate_io(id_to_name, io16_tile, io_pad_bit,
                                          io_pad_name, placement, tile_mapping)

    assert len(io_strings) > 0
    output_string += "\n\n#IO\n"
    output_string += "\n".join(io_strings)

    output_string += "\n\n#ROUTING\n"

    routes = generate_routing(routing_filename, tile_mapping, board_layout)
    net_id_list = list(routes.keys())
    net_id_list.sort(key=lambda x: int(x[1:]))

    for net_id in net_id_list:
        output_string += "\n# net id: {}\n".format(net_id)
        netlist = netlists[net_id]
        for p in netlist:
            output_string += "# {}: {}::{}\n".format(p[0], id_to_name[p[0]],
                                                     p[1])
        output_string += routes[net_id]

        output_string += "\n"

    with open(output_filename, "w+") as f:
        f.write(output_string)

    with open(io_json, "w+") as f:
        json.dump(io_pad_info, f, indent=2, separators=(',', ': '))
Exemple #11
0
def main():
    # only the main thread needs it
    # this is to avoid loading unnecessary crop while calling from aws lambda
    from argparse import ArgumentParser
    from arch import parse_cgra, parse_fpga
    from arch.cgra import place_special_blocks, save_placement, prune_netlist
    from arch.cgra_packer import load_packed_file
    from arch.fpga import load_packed_fpga_netlist
    from arch import mock_board_meta
    from visualize import visualize_placement_cgra

    parser = ArgumentParser("CGRA Placer")
    parser.add_argument("-i",
                        "--input",
                        help="Packed netlist file, " + "e.g. harris.packed",
                        required=True,
                        action="store",
                        dest="packed_filename")
    parser.add_argument("-o",
                        "--output",
                        help="Placement result, " + "e.g. harris.place",
                        required=True,
                        action="store",
                        dest="placement_filename")
    parser.add_argument("-c",
                        "--cgra",
                        help="CGRA architecture file",
                        action="store",
                        dest="cgra_arch",
                        default="")
    parser.add_argument("--no-reg-fold",
                        help="If set, the placer will treat " +
                        "registers as PE tiles",
                        action="store_true",
                        required=False,
                        dest="no_reg_fold",
                        default=False)
    parser.add_argument("--no-vis",
                        help="If set, the placer won't show " +
                        "visualization result for placement",
                        action="store_true",
                        required=False,
                        dest="no_vis",
                        default=False)
    parser.add_argument("-s",
                        "--seed",
                        help="Seed for placement. " + "default is 0",
                        type=int,
                        default=0,
                        required=False,
                        action="store",
                        dest="seed")

    parser.add_argument("-a",
                        "--aws",
                        help="Serverless configuration for " +
                        "detailed placement. If set, will try to connect to "
                        "that arn",
                        dest="aws_config",
                        type=str,
                        required=False,
                        action="store",
                        default="")
    parser.add_argument("-f",
                        "--fpga",
                        action="store",
                        dest="fpga_arch",
                        default="",
                        help="ISPD FPGA architecture file")
    parser.add_argument("-l",
                        "--layout",
                        action="store",
                        dest="cgra_layout",
                        default="",
                        help="CGRA layout file")
    parser.add_argument("--mock",
                        action="store",
                        dest="mock_size",
                        default=0,
                        type=int,
                        help="Mock CGRA board with "
                        "provided size")
    args = parser.parse_args()

    cgra_arch = args.cgra_arch
    fpga_arch = args.fpga_arch
    cgra_layout = args.cgra_layout
    mock_size = args.mock_size

    if sum([len(cgra_arch) != 0,
            len(fpga_arch) != 0,
            len(cgra_layout) != 0]) != 1 and \
            mock_size == 0:
        parser.error("Must provide wither --fpga, --cgra, or --layout")

    packed_filename = args.packed_filename
    placement_filename = args.placement_filename
    aws_config = args.aws_config
    fpga_place = len(fpga_arch) > 0

    seed = args.seed
    print("Using seed", seed, "for placement")

    vis_opt = not args.no_vis
    fold_reg = not args.no_reg_fold
    # FPGA params override
    if mock_size > 0:
        fold_reg = False
        board_meta = mock_board_meta(mock_size)
    elif fpga_place:
        fold_reg = False
        board_meta = parse_fpga(fpga_arch)
    else:
        if len(cgra_arch) > 0:
            board_meta = parse_cgra(cgra_arch)
        else:
            board_meta = {"cgra": pythunder.io.load_layout(cgra_layout)}
    # Common routine
    board_name, layout = board_meta.popitem()
    print("INFO: Placing for", board_name)
    board = make_board(layout)

    pythunder.io.dump_layout(layout, "cgra.layout")

    fixed_blk_pos = {}
    special_blocks = set()

    # FPGA
    if fpga_place:
        netlists, fixed_blk_pos, _ = load_packed_fpga_netlist(packed_filename)
        id_to_name = {}
        # place fixed IO locations
        for blk_id in fixed_blk_pos:
            pos = fixed_blk_pos[blk_id]
            place_on_board(board, blk_id, pos)

        folded_blocks = {}
        changed_pe = {}

    else:
        # CGRA
        raw_netlist, folded_blocks, id_to_name, changed_pe = \
            load_packed_file(packed_filename)
        netlists = prune_netlist(raw_netlist)
        for blk in id_to_name:
            if blk[0] == "i" or blk[0] == "I":
                special_blocks.add(blk)

        # place the spacial blocks first
        place_special_blocks(board, special_blocks, fixed_blk_pos, raw_netlist,
                             place_on_board, layout)

    # common routine
    # produce layout structure
    centroids, cluster_cells, clusters = perform_global_placement(
        fixed_blk_pos, netlists, layout, seed=seed, vis=vis_opt)

    # placer with each cluster
    board_pos = perform_detailed_placement(centroids, cluster_cells, clusters,
                                           fixed_blk_pos, netlists, fold_reg,
                                           seed, layout, aws_config)
    # refinement
    board_pos = refine_global_thunder(layout, board_pos, netlists,
                                      fixed_blk_pos, fold_reg)

    for blk_id in board_pos:
        pos = board_pos[blk_id]
        place_on_board(board, blk_id, pos)

    # save the placement file
    save_placement(board_pos, id_to_name, folded_blocks, placement_filename)
    basename_file = os.path.basename(placement_filename)
    design_name, _ = os.path.splitext(basename_file)
    if vis_opt:
        visualize_placement_cgra(layout, board_pos, design_name, changed_pe)
Exemple #12
0
def main():
    if len(sys.argv) != 4:
        print("Usage:", sys.argv[0], "<cgra_info.txt>", "<netlist.json>",
              "<netlist.route>",
              file=sys.stderr)
        exit(1)
    cgra_file = sys.argv[1]
    netlist = sys.argv[2]
    route_file = sys.argv[3]
    packed_file = route_file.replace(".route", ".packed")
    placement_file = route_file.replace(".route", ".place")
    board_meta = parse_cgra(cgra_file)["CGRA"]
    routing_result = parse_routing_result(route_file)
    placement, _ = parse_placement(placement_file)

    if hasattr(sys.stdout, 'isatty') and sys.stdout.isatty():
        meta = os.popen('stty size', 'r').read().split()
        cols = int(meta[-1])
        cols = int(cols)
        scale = cols - 15
    else:
        scale = 68
        cols = 80

    # print("Latency:")
    # print("Total:", total_time)
    # latency_info = compute_latency(net_path, routing_result, placement)
    # total_time = sum([latency_info[key] for key in latency_info])
    # for entry in latency_info:
    #     time = latency_info[entry]
    #     percentage = int(time / total_time * 100)
    #     num_bar = int(percentage / (100 / scale))
    #     s = "{0:4s} {1} {2} {3}".format(entry.upper(),
    #                                    num_bar * '█', ' ' * (scale - num_bar),
    #                                     time)
    # print(s)

    print("-" * cols)
    print("Area Usage:")
    usage = compute_area_usage(placement, board_meta[0])
    for entry in usage:
        percentage = usage[entry][0] / usage[entry][1] * 100
        num_bar = int(percentage / 100 * scale)
        print("{0:4s} {1} {2} {3:.2f}%".format(entry.upper(),
                                               num_bar * '█',
                                               ' ' * (scale - num_bar - 2),
                                               percentage))

    print("-" * cols)
    net_wire = compute_total_wire(routing_result)
    total_wire = sum([net_wire[x] for x in net_wire])
    print("Total wire:", total_wire)

    print("-" * cols)
    total_delay, detailed_delay = find_critical_path_delay(netlist,
                                                           packed_file,
                                                           routing_result,
                                                           placement)
    print("Critical Path:")
    clock_speed = 1e6 / total_delay
    total_delay_formatted = "{:.2f} ns".format(total_delay / 1000)
    print("Delay:", total_delay_formatted, "Max Clock Speed:",
          "{0:.2f} MHz".format(clock_speed))
    delay_keys = list(detailed_delay.keys())
    delay_keys.sort(key=lambda x: detailed_delay[x], reverse=True)
    for entry in delay_keys:
        percentage = detailed_delay[entry] / total_delay * 100
        num_bar = int(percentage / 100 * scale)
        print("{0:4s} {1} {2} {3:.2f}%".format(entry.upper(),
                                               num_bar * '█',
                                               ' ' * (scale - num_bar - 2),
                                               percentage))

    print("-" * cols)
    r = parse_routing_resource(cgra_file)
    routing_resource = build_routing_resource(r)
    resource_usage = compute_routing_usage(routing_result, routing_resource,
                                           board_meta[0])
    for bus in resource_usage:
        print("BUS:", bus)
        for track in resource_usage[bus]:
            left = 0
            total = 0
            for _, l, t in resource_usage[bus][track]:
                left += l
                total += t
            percentage = (total - left) / total * 100
            num_bar = int(percentage / 100 * scale)
            print("TRACK {0} {1} {2} {3:.2f}%".format(track,
                                                      num_bar * '█',
                                                      ' ' * (scale -
                                                             num_bar - 5),
                                                      percentage))