예제 #1
0
파일: stencil.py 프로젝트: stkaplan/legion
def main():
    print_once('Running stencil.py')

    conf = parse_args(pygion.input_args(True))

    nbloated = np.array([conf.nx, conf.ny])
    nt = np.array([conf.ntx, conf.nty])
    init = conf.init

    n = nbloated - 2 * RADIUS
    assert np.all(n >= nt), "grid too small"

    grid = Ispace(n + nt * 2 * RADIUS)
    tiles = Ispace(nt)

    point = Fspace(OrderedDict([
        ('input', DTYPE),
        ('output', DTYPE),
    ]))

    points = Region(grid, point)

    private = make_private_partition(points, tiles, n, nt)
    interior = make_interior_partition(points, tiles, n, nt)
    exterior = make_exterior_partition(points, tiles, n, nt)

    xm = Region([nt[0] * RADIUS, n[1]], point)
    xp = Region([nt[0] * RADIUS, n[1]], point)
    ym = Region([n[0], nt[1] * RADIUS], point)
    yp = Region([n[0], nt[1] * RADIUS], point)
    pxm_in = make_ghost_x_partition(xm, tiles, n, nt, -1)
    pxp_in = make_ghost_x_partition(xp, tiles, n, nt, 1)
    pym_in = make_ghost_y_partition(ym, tiles, n, nt, -1)
    pyp_in = make_ghost_y_partition(yp, tiles, n, nt, 1)
    pxm_out = make_ghost_x_partition(xm, tiles, n, nt, 0)
    pxp_out = make_ghost_x_partition(xp, tiles, n, nt, 0)
    pym_out = make_ghost_y_partition(ym, tiles, n, nt, 0)
    pyp_out = make_ghost_y_partition(yp, tiles, n, nt, 0)

    init = conf.init

    for r in [points, xm, xp, ym, yp]:
        for f in ['input', 'output']:
            pygion.fill(r, f, init)

    tsteps = conf.tsteps + 2 * conf.tprune
    tprune = conf.tprune

    trace = Trace()
    for t in range(tsteps):
        if t == tprune:
            pygion.execution_fence(block=True)
            start_time = pygion.c.legion_get_current_time_in_nanos()
        with trace:
            if _constant_time_launches:
                index_launch(tiles, stencil, private[ID], interior[ID],
                             pxm_in[ID], pxp_in[ID], pym_in[ID], pyp_in[ID],
                             False)
                index_launch(tiles, increment, private[ID], exterior[ID],
                             pxm_out[ID], pxp_out[ID], pym_out[ID],
                             pyp_out[ID], False)
            else:
                for i in IndexLaunch(tiles):
                    stencil(private[i], interior[i], pxm_in[i], pxp_in[i],
                            pym_in[i], pyp_in[i], False)
                for i in IndexLaunch(tiles):
                    increment(private[i], exterior[i], pxm_out[i], pxp_out[i],
                              pym_out[i], pyp_out[i], False)
        if t == tsteps - tprune - 1:
            pygion.execution_fence(block=True)
            stop_time = pygion.c.legion_get_current_time_in_nanos()

    if _constant_time_launches:
        index_launch(tiles, check, private[ID], interior[ID], tsteps, init)
    else:
        for i in IndexLaunch(tiles):
            check(private[i], interior[i], tsteps, init)

    print_once('ELAPSED TIME = %7.3f s' % ((stop_time - start_time) / 1e9))
예제 #2
0
def main():
    print_once('Running circuit_sparse.py')

    conf = parse_args(pygion.input_args(True))

    assert conf.num_pieces % conf.pieces_per_superpiece == 0, "pieces should be evenly distributed to superpieces"
    conf.shared_nodes_per_piece = int(
        math.ceil(conf.nodes_per_piece * conf.pct_shared_nodes / 100.0))
    print_once(
        "circuit settings: loops=%d prune=%d pieces=%d (pieces/superpiece=%d) nodes/piece=%d (nodes/piece=%d) wires/piece=%d pct_in_piece=%d seed=%d"
        % (conf.num_loops, conf.prune, conf.num_pieces,
           conf.pieces_per_superpiece, conf.nodes_per_piece,
           conf.shared_nodes_per_piece, conf.wires_per_piece,
           conf.pct_wire_in_piece, conf.random_seed))

    num_pieces = conf.num_pieces
    num_superpieces = conf.num_pieces // conf.pieces_per_superpiece
    num_circuit_nodes = num_pieces * conf.nodes_per_piece
    num_circuit_wires = num_pieces * conf.wires_per_piece

    node = Fspace(
        OrderedDict([
            ('node_cap', pygion.float32),
            ('leakage', pygion.float32),
            ('charge', pygion.float32),
            ('node_voltage', pygion.float32),
        ]))
    wire = Fspace(
        OrderedDict([
            ('in_ptr', pygion.int64),
            ('in_ptr_r', pygion.uint8),
            ('out_ptr', pygion.int64),
            ('out_ptr_r', pygion.uint8),
            ('inductance', pygion.float32),
            ('resistance', pygion.float32),
            ('wire_cap', pygion.float32),
        ] + [('current_%d' % i, pygion.float32)
             for i in range(WIRE_SEGMENTS)] +
                    [('voltage_%d' % i, pygion.float32)
                     for i in range(WIRE_SEGMENTS - 1)]))

    all_nodes = Region([num_circuit_nodes], node)
    all_wires = Region([num_circuit_wires], wire)

    node_size = np.dtype(list(
        map(lambda x: (x[0], x[1].numpy_type), node.field_types.items())),
                         align=True).itemsize
    wire_size = np.dtype(list(
        map(lambda x: (x[0], x[1].numpy_type), wire.field_types.items())),
                         align=True).itemsize
    print_once("Circuit memory usage:")
    print_once("  Nodes : %10d * %4d bytes = %12d bytes" %
               (num_circuit_nodes, node_size, num_circuit_nodes * node_size))
    print_once("  Wires : %10d * %4d bytes = %12d bytes" %
               (num_circuit_wires, wire_size, num_circuit_wires * wire_size))
    total = ((num_circuit_nodes * node_size) + (num_circuit_wires * wire_size))
    print_once("  Total                             %12d bytes" % total)

    snpp = conf.shared_nodes_per_piece
    pnpp = conf.nodes_per_piece - conf.shared_nodes_per_piece
    pps = conf.pieces_per_superpiece
    num_shared_nodes = num_pieces * snpp

    privacy_coloring = Region([2], {'rect': pygion.rect1d})
    np.copyto(privacy_coloring.rect,
              np.array([(num_shared_nodes, num_circuit_nodes - 1),
                        (0, num_shared_nodes - 1)],
                       dtype=privacy_coloring.rect.dtype),
              casting='no')
    privacy_part = Partition.restrict(privacy_coloring, [2], np.eye(1), [1],
                                      disjoint_complete)
    all_nodes_part = Partition.image(all_nodes, privacy_part, 'rect', [2],
                                     disjoint_complete)

    all_private = all_nodes_part[0]
    all_shared = all_nodes_part[1]

    launch_domain = Ispace([num_superpieces])

    private_part = Partition.restrict(all_private, launch_domain,
                                      np.eye(1) * pnpp * pps,
                                      Domain([pnpp * pps], [num_shared_nodes]),
                                      disjoint_complete)
    shared_part = Partition.restrict(all_shared, launch_domain,
                                     np.eye(1) * snpp * pps, [snpp * pps],
                                     disjoint_complete)

    wires_part = Partition.equal(all_wires, launch_domain)

    ghost_ranges = Region([num_superpieces],
                          OrderedDict([('rect', pygion.rect1d)]))
    ghost_ranges_part = Partition.equal(ghost_ranges, launch_domain)

    if _constant_time_launches:
        c = Future(conf[0], value_type=Config)
        index_launch(launch_domain, init_piece, ID, c, ghost_ranges_part[ID],
                     private_part[ID], shared_part[ID], all_shared,
                     wires_part[ID])
    else:
        for i in IndexLaunch(launch_domain):
            init_piece(i, conf[0], ghost_ranges_part[i], private_part[i],
                       shared_part[i], all_shared, wires_part[i])

    ghost_part = Partition.image(all_shared, ghost_ranges_part, 'rect',
                                 launch_domain)

    if _constant_time_launches:
        index_launch(launch_domain, init_pointers, private_part[ID],
                     shared_part[ID], ghost_part[ID], wires_part[ID])
    else:
        for i in IndexLaunch(launch_domain):
            init_pointers(private_part[i], shared_part[i], ghost_part[i],
                          wires_part[i])

    steps = conf.steps
    prune = conf.prune
    num_loops = conf.num_loops + 2 * prune

    trace = Trace()
    for j in range(num_loops):
        if j == prune:
            pygion.execution_fence(block=True)
            start_time = pygion.c.legion_get_current_time_in_nanos()
        with trace:
            if _constant_time_launches:
                index_launch(launch_domain, calculate_new_currents, False,
                             steps, private_part[ID], shared_part[ID],
                             ghost_part[ID], wires_part[ID])
                index_launch(launch_domain, distribute_charge,
                             private_part[ID], shared_part[ID], ghost_part[ID],
                             wires_part[ID])
                index_launch(launch_domain, update_voltages, False,
                             private_part[ID], shared_part[ID])
            else:
                for i in IndexLaunch(launch_domain):
                    calculate_new_currents(False, steps, private_part[i],
                                           shared_part[i], ghost_part[i],
                                           wires_part[i])
                for i in IndexLaunch(launch_domain):
                    distribute_charge(private_part[i], shared_part[i],
                                      ghost_part[i], wires_part[i])
                for i in IndexLaunch(launch_domain):
                    update_voltages(False, private_part[i], shared_part[i])
        if j == num_loops - prune - 1:
            pygion.execution_fence(block=True)
            stop_time = pygion.c.legion_get_current_time_in_nanos()

    sim_time = (stop_time - start_time) / 1e9
    print_once('ELAPSED TIME = %7.3f s' % sim_time)

    # Compute the floating point operations per second
    num_circuit_nodes = conf.num_pieces * conf.nodes_per_piece
    num_circuit_wires = conf.num_pieces * conf.wires_per_piece
    # calculate currents
    operations = num_circuit_wires * (WIRE_SEGMENTS * 6 +
                                      (WIRE_SEGMENTS - 1) * 4) * conf.steps
    # distribute charge
    operations += (num_circuit_wires * 4)
    # update voltages
    operations += (num_circuit_nodes * 4)
    # multiply by the number of loops
    operations *= conf.num_loops

    # Compute the number of gflops
    gflops = (1e-9 * operations) / sim_time
    print_once("GFLOPS = %7.3f GFLOPS" % gflops)