def test_for_inside_branch(): sdfg = dace.SDFG('for_in_branch') state_init = sdfg.add_state('init') branch_guard = sdfg.add_state('branch_guard') loop_guard = sdfg.add_state('loop_guard') loop_state = sdfg.add_state('loop_state') branch_merge = sdfg.add_state('branch_merge') sdfg.add_edge(state_init, branch_guard, InterstateEdge(assignments={ 'i': '0', })) sdfg.add_edge(branch_guard, branch_merge, InterstateEdge(condition=CodeProperty.from_string('i < 10', language=Language.Python))) sdfg.add_edge( branch_guard, loop_guard, InterstateEdge(condition=CodeProperty.from_string('not (i < 10)', language=Language.Python), assignments={ 'j': '0', })) sdfg.add_edge(loop_guard, loop_state, InterstateEdge(condition=CodeProperty.from_string('j < 10', language=Language.Python))) sdfg.add_edge(loop_guard, branch_merge, InterstateEdge(condition=CodeProperty.from_string('not (j < 10)', language=Language.Python))) sdfg.add_edge(loop_state, loop_guard, InterstateEdge(assignments={ 'j': 'j + 1', })) propagate_states(sdfg) state_check_executions(branch_guard, 1, False) state_check_executions(loop_guard, 11, True) state_check_executions(loop_state, 10, True) state_check_executions(branch_merge, 1, False)
def make_write_sdfg(): sdfg = SDFG("spmv_write") begin = sdfg.add_state("begin") entry = sdfg.add_state("entry") state = sdfg.add_state("body") end = sdfg.add_state("end") sdfg.add_edge(begin, entry, InterstateEdge(assignments={"h": "0"})) sdfg.add_edge( entry, state, InterstateEdge(condition=CodeProperty.from_string( "h < H", language=Language.Python))) sdfg.add_edge( entry, end, InterstateEdge(condition=CodeProperty.from_string( "h >= H", language=Language.Python))) sdfg.add_edge(state, entry, InterstateEdge(assignments={"h": "h + 1"})) result_to_write_in = state.add_stream("b_pipe", dtype, storage=StorageType.FPGA_Local) b = state.add_array("b_mem", (H, ), dtype, storage=StorageType.FPGA_Global) state.add_memlet_path(result_to_write_in, b, memlet=Memlet.simple(b, "h")) return sdfg
def test_conditional_fake_merge(): sdfg = dace.SDFG('fake_merge') state_init = sdfg.add_state('init') state_a = sdfg.add_state('A') state_b = sdfg.add_state('B') state_c = sdfg.add_state('C') state_d = sdfg.add_state('D') state_e = sdfg.add_state('E') sdfg.add_edge(state_init, state_a, InterstateEdge(assignments={ 'i': '0', 'j': '0', })) sdfg.add_edge(state_a, state_b, InterstateEdge(condition=CodeProperty.from_string('i < 10', language=Language.Python))) sdfg.add_edge(state_a, state_c, InterstateEdge(condition=CodeProperty.from_string('not (i < 10)', language=Language.Python))) sdfg.add_edge(state_b, state_d, InterstateEdge()) sdfg.add_edge(state_c, state_d, InterstateEdge(condition=CodeProperty.from_string('j < 10', language=Language.Python))) sdfg.add_edge(state_c, state_e, InterstateEdge(condition=CodeProperty.from_string('not (j < 10)', language=Language.Python))) propagate_states(sdfg) state_check_executions(state_d, 1, True) state_check_executions(state_e, 1, True)
def make_nested_sdfg(): sdfg = dace.SDFG('vol_propagation_nested') assign_loop_bound = sdfg.add_state('assign') guard_state = sdfg.add_state('guard') loop_state = sdfg.add_state('for') end_state = sdfg.add_state('endfor') sdfg.add_edge(assign_loop_bound, guard_state, InterstateEdge(assignments={'i': '0'})) sdfg.add_edge( guard_state, loop_state, InterstateEdge(condition=CodeProperty.from_string( 'i < loop_bound', language=Language.Python))) sdfg.add_edge(loop_state, guard_state, InterstateEdge(assignments={'i': 'i+1'})) sdfg.add_edge( guard_state, end_state, InterstateEdge(condition=CodeProperty.from_string( 'not (i < loop_bound)', language=Language.Python))) in_bound = assign_loop_bound.add_stream('IN_bound', dace.int32, storage=StorageType.FPGA_Local) loop_bound = assign_loop_bound.add_scalar( 'loop_bound', dace.int32, transient=True, storage=StorageType.FPGA_Registers) assign_loop_bound.add_memlet_path(in_bound, loop_bound, memlet=Memlet.simple(loop_bound, '0')) in_a = loop_state.add_array('IN_a', [N], dace.int32, storage=StorageType.FPGA_Global) out_stream = loop_state.add_stream('OUT_stream', dace.int32, storage=StorageType.FPGA_Local) tasklet2 = loop_state.add_tasklet('compute', {'_IN_a'}, {'_OUT_stream'}, '_OUT_stream = _IN_a[0]') loop_state.add_memlet_path(in_a, tasklet2, dst_conn='_IN_a', memlet=Memlet.simple(in_a, '0:N')) loop_state.add_memlet_path(tasklet2, out_stream, src_conn='_OUT_stream', memlet=Memlet.simple(out_stream, '0')) return sdfg
def make_read_row(): sdfg = SDFG("spmv_read_row") begin = sdfg.add_state("begin") entry = sdfg.add_state("entry") end = sdfg.add_state("end") body = sdfg.add_state("body") sdfg.add_edge(begin, entry, InterstateEdge(assignments={"h": "0"})) sdfg.add_edge( entry, body, InterstateEdge(condition=CodeProperty.from_string( "h < H + 1", language=Language.Python))) sdfg.add_edge( entry, end, InterstateEdge(condition=CodeProperty.from_string( "h >= H + 1", language=Language.Python))) sdfg.add_edge(body, entry, InterstateEdge(assignments={"h": "h + 1"})) a_row_mem = body.add_array("A_row_mem", (H + 1, ), itype, storage=StorageType.FPGA_Global) to_val_pipe = body.add_stream("to_val_pipe", itype, storage=StorageType.FPGA_Local) to_col_pipe = body.add_stream("to_col_pipe", itype, storage=StorageType.FPGA_Local) to_compute_pipe = body.add_stream("to_compute_pipe", itype, storage=StorageType.FPGA_Local) to_x_pipe = body.add_stream("to_x_pipe", itype, storage=StorageType.FPGA_Local) tasklet = body.add_tasklet( "read_row", {"row_in"}, {"to_val_out", "to_col_out", "to_compute_out", "to_x_out"}, "to_val_out = row_in\n" "to_col_out = row_in\n" "to_compute_out = row_in\n" "to_x_out = row_in") body.add_memlet_path(a_row_mem, tasklet, dst_conn="row_in", memlet=Memlet.simple(a_row_mem, "h")) body.add_memlet_path(tasklet, to_val_pipe, src_conn="to_val_out", memlet=Memlet.simple(to_val_pipe, "0")) body.add_memlet_path(tasklet, to_col_pipe, src_conn="to_col_out", memlet=Memlet.simple(to_col_pipe, "0")) body.add_memlet_path(tasklet, to_compute_pipe, src_conn="to_compute_out", memlet=Memlet.simple(to_compute_pipe, "0")) body.add_memlet_path(tasklet, to_x_pipe, src_conn="to_x_out", memlet=Memlet.simple(to_x_pipe, "0")) return sdfg
def make_compute_nested_sdfg(): sdfg = SDFG("spmv_compute_nested") if_state = sdfg.add_state("if") then_state = sdfg.add_state("then") else_state = sdfg.add_state("else") end_state = sdfg.add_state("end") sdfg.add_edge( if_state, then_state, InterstateEdge(condition=CodeProperty.from_string( "c == 0", language=Language.Python))) sdfg.add_edge( if_state, else_state, InterstateEdge(condition=CodeProperty.from_string( "c != 0", language=Language.Python))) sdfg.add_edge(then_state, end_state, InterstateEdge()) sdfg.add_edge(else_state, end_state, InterstateEdge()) a_in = if_state.add_scalar("a_in", dtype, storage=StorageType.FPGA_Registers) x_in = if_state.add_scalar("x_in", dtype, storage=StorageType.FPGA_Registers) b_tmp_out = if_state.add_scalar("b_tmp", dtype, transient=True, storage=StorageType.FPGA_Registers) tasklet = if_state.add_tasklet("compute", {"_a_in", "_x_in"}, {"_b_out"}, "_b_out = _a_in * _x_in") if_state.add_memlet_path(a_in, tasklet, dst_conn="_a_in", memlet=Memlet.simple(a_in, "0")) if_state.add_memlet_path(x_in, tasklet, dst_conn="_x_in", memlet=Memlet.simple(x_in, "0")) if_state.add_memlet_path(tasklet, b_tmp_out, src_conn="_b_out", memlet=Memlet.simple(b_tmp_out, "0")) b_tmp_then_in = then_state.add_scalar("b_tmp", dtype, transient=True, storage=StorageType.FPGA_Registers) b_then_out = then_state.add_scalar("b_out", dtype, storage=StorageType.FPGA_Registers) then_state.add_memlet_path(b_tmp_then_in, b_then_out, memlet=Memlet.simple(b_then_out, "0")) b_tmp_else_in = else_state.add_scalar("b_tmp", dtype, transient=True, storage=StorageType.FPGA_Registers) b_else_in = else_state.add_scalar("b_in", dtype, storage=StorageType.FPGA_Registers) b_else_out = else_state.add_scalar("b_out", dtype, storage=StorageType.FPGA_Registers) else_tasklet = else_state.add_tasklet("b_wcr", {"_b_in", "b_prev"}, {"_b_out"}, "_b_out = b_prev + _b_in") else_state.add_memlet_path(b_tmp_else_in, else_tasklet, dst_conn="_b_in", memlet=Memlet.simple(b_tmp_else_in, "0")) else_state.add_memlet_path(b_else_in, else_tasklet, dst_conn="b_prev", memlet=Memlet.simple(b_else_in, "0")) else_state.add_memlet_path(else_tasklet, b_else_out, src_conn="_b_out", memlet=Memlet.simple(b_else_out, "0")) return sdfg
def make_iteration_space(sdfg): pre_state = sdfg.add_state("pre_state") rows_begin = sdfg.add_state("rows_begin") rows_entry = sdfg.add_state("rows_entry") rows_end = sdfg.add_state("rows_end") shift_rowptr = sdfg.add_state("shift_rowptr") read_rowptr = sdfg.add_state("read_rowptr") cols_begin = sdfg.add_state("cols_begin") cols_entry = sdfg.add_state("cols_entry") cols_end = sdfg.add_state("cols_end") body = sdfg.add_state("compute") post_state = sdfg.add_state("post_state") sdfg.add_edge(pre_state, rows_begin, InterstateEdge()) sdfg.add_edge(rows_begin, rows_entry, InterstateEdge(assignments={"h": "0"})) sdfg.add_edge( rows_entry, shift_rowptr, InterstateEdge(condition=CodeProperty.from_string( "h < H", language=Language.Python))) sdfg.add_edge( rows_entry, rows_end, InterstateEdge(condition=CodeProperty.from_string( "h >= H", language=Language.Python))) sdfg.add_edge(shift_rowptr, read_rowptr, InterstateEdge()) sdfg.add_edge(read_rowptr, cols_begin, InterstateEdge()) sdfg.add_edge(cols_begin, cols_entry, InterstateEdge(assignments={"c": "0"})) sdfg.add_edge( cols_entry, body, InterstateEdge(condition=CodeProperty.from_string( "c < row_end - row_begin", language=Language.Python))) sdfg.add_edge( cols_entry, cols_end, InterstateEdge(condition=CodeProperty.from_string( "c >= row_end - row_begin", language=Language.Python))) sdfg.add_edge(body, cols_entry, InterstateEdge(assignments={"c": "c + 1"})) sdfg.add_edge(cols_end, post_state, InterstateEdge()) sdfg.add_edge(post_state, rows_entry, InterstateEdge(assignments={"h": "h + 1"})) row_end_first = pre_state.add_scalar("row_end", itype, transient=True, storage=StorageType.FPGA_Registers) row_pipe_first = pre_state.add_stream("row_pipe", itype, storage=StorageType.FPGA_Local) pre_state.add_memlet_path(row_pipe_first, row_end_first, memlet=Memlet.simple(row_end_first, "0")) row_end_shift = shift_rowptr.add_scalar("row_end", itype, transient=True, storage=StorageType.FPGA_Registers) row_begin_shift = shift_rowptr.add_scalar( "row_begin", itype, transient=True, lifetime=AllocationLifetime.SDFG, storage=StorageType.FPGA_Registers) shift_rowptr.add_memlet_path(row_end_shift, row_begin_shift, memlet=Memlet.simple(row_begin_shift, "0")) row_pipe = read_rowptr.add_stream("row_pipe", itype, storage=StorageType.FPGA_Local) row_end = read_rowptr.add_scalar("row_end", itype, transient=True, storage=StorageType.FPGA_Registers) read_rowptr.add_memlet_path(row_pipe, row_end, memlet=Memlet.simple(row_end, "0")) return pre_state, body, post_state