def test_single_dim_norm(): with pm.Node(name="elem1") as graph: m = pm.parameter("m") x = pm.input("x", shape=m) w = pm.state("w", shape=m) i = pm.index(0, m - 1, name="i") w[i] = (w[i] * x[i]) x_ = np.random.randint(0, 10, 3) w_ = np.random.randint(0, 10, 3) coarse_eval = graph("w", x=x_, w=w_) np_result = x_ * w_ np.testing.assert_allclose(coarse_eval, np_result) shape_pass = NormalizeGraph({"m": 3}) graph_shapes = shape_pass(graph) shape_res = graph_shapes("w", x=x_, w=w_) np.testing.assert_allclose(shape_res, np_result) lower_pass = Lower({}) lowered_graph = lower_pass(graph_shapes) input_info = {f"w/w({i},)": w_[i] for i in range(len(w_))} input_info.update({f"x/x({i},)": x_[i] for i in range(len(x_))}) fine_grained_eval = lowered_graph("w/w(1,)", input_info) assert fine_grained_eval == np_result[1] pb_path = f"{OUTPATH}/{graph.name}.srdfg" pm.pb_store(lowered_graph, OUTPATH) loaded_node = pm.pb_load(pb_path) input_info = {f"w/w({i},)": w_[i] for i in range(len(w_))} input_info.update({f"x/x({i},)": x_[i] for i in range(len(x_))}) fine_grained_eval = loaded_node("w/w(1,)", input_info) assert fine_grained_eval == np_result[1]
def test_conv_embedded_values(x_shape, w_shape, params): shape_dict = { "n": x_shape[0], "ic": x_shape[1], "ih": x_shape[2], "iw": x_shape[3], "nf": w_shape[0], "kh": w_shape[2], "kw": w_shape[3], "stride": params["stride"], "pad": params["pad"] } graph, input_info0, out_info, keys = conv(x_shape, w_shape, params, coarse=True, debug_matrix=True) ngraph, input_info1, out_info, keys = conv(x_shape, w_shape, params, coarse=False, debug_matrix=True) lower_pass = pm.Lower({}) lowered = lower_pass(ngraph) pb_path = f"{OUTPATH}/{graph.name}.srdfg" pm.pb_store(lowered, OUTPATH) node = pm.pb_load(pb_path) assert len(node.nodes) == len(lowered.nodes) assert list(node.nodes.keys()) == list(lowered.nodes.keys())
def test_linear_deserialize(): graph_name = "linear_reg1" with pm.Node(name=graph_name) as graph: m = pm.placeholder("m") x_ = pm.placeholder("x", shape=(m)) y_ = pm.placeholder("y") w_ = pm.placeholder("w", shape=(m)) mu = pm.parameter(name="mu", default=1.0) i = pm.index(0, (m - 1).set_name("m-1"), name="i") h = pm.sum([i], (x_[i] * w_[i]).set_name("x*w"), name="h") d = (h - y_).set_name("h-y") g = (d * x_[i]).set_name("d*x") mug = (mu * g[i]).set_name("mu*g[i]") w_ = ((w_[i]) - mug).set_name("w_out") x = np.random.randint(0, 10, 10) y = np.random.randint(0, 10, 1)[0] w = np.random.randint(0, 10, 10) graph_res = graph("w_out", {"x": x, "y": y, "w": w}) actual_res = w - ((np.sum(x * w) - y) * x) * 1.0 np.testing.assert_allclose(graph_res, actual_res) cwd = Path(f"{__file__}").parent base_path = f"{cwd}/pmlang_examples" full_path = f"{base_path}/outputs" pb_path = f"{full_path}/{graph_name}.srdfg" pm.pb_store(graph, full_path) node = pm.pb_load(pb_path) new_graph_res = node("w_out", {"x": x, "y": y, "w": w}) np.testing.assert_allclose(graph_res, new_graph_res) np.testing.assert_allclose(actual_res, new_graph_res)
def test_linear_reg(): m_ = 3 graph, input_info, out_info, keys = linear(m=m_, coarse=True) coarse_eval = graph(keys, input_info) np.testing.assert_allclose(coarse_eval, out_info["w"]) fgraph, input_info, out_info, keys = linear(m=m_, coarse=False) lower_pass = Lower({}) lowered_graph = lower_pass(fgraph, {}) all_vals = lowered_graph(keys, input_info) out = np.asarray(all_vals).reshape(out_info["w"].shape) np.testing.assert_allclose(out, out_info["w"]) cwd = Path(f"{__file__}").parent base_path = f"{cwd}/pmlang_examples" full_path = f"{base_path}/outputs" pb_path = f"{full_path}/{graph.name}.srdfg" pm.pb_store(lowered_graph, full_path) loaded_node = pm.pb_load(pb_path) _, input_info, out_info, keys = linear(m=m_, coarse=False) loaded_res = loaded_node(keys, input_info) out = np.asarray(loaded_res).reshape(out_info["w"].shape) np.testing.assert_allclose(out, out_info["w"])
def test_resnet18_train(): filename = f"resnet18_train.onnx" filepath = f"{BENCH_DIR}/full_dnns/{filename}" assert Path(filepath).exists() graph = pm.from_onnx(filepath) full_path = f"{BENCH_DIR}/full_dnns" pb_path = f"{full_path}/resnet18_train.srdfg" pm.pb_store(graph, full_path) node = pm.pb_load(pb_path, verbose=True) assert len(node.nodes) == len(graph.nodes)
def test_genesys_conv_bias(): graph = pm.pb_load(f"{LAYER_DIR}/resnet18_conv_bias.srdfg") genesys = define_genesys(GENESYS_CFG) program = initialize_program(graph, genesys) program.add_compilation_step("pad_operands", pad_operands, preproc=True, stage_kwargs={'shaped_nodes': []}) program.add_compilation_step("tile", tile) program.add_compilation_step("hoist", hoist, dependencies=["tile"]) program.compile() res = program.emit("string_final") print(res)
def test_genesys_global_avg_pool(): from pprint import pprint graph = pm.pb_load(f"{LAYER_DIR}/resnet18_globalaveragepool.srdfg") genesys = define_genesys(GENESYS_CFG) program = initialize_program(graph, genesys) program.add_compilation_step("pad_operands", pad_operands, preproc=True, stage_kwargs={'shaped_nodes': []}) program.add_compilation_step("tile", tile) program.add_compilation_step("hoist", hoist, dependencies=["tile"]) program.compile() res = program.emit("json_no_ops") pprint(res)
def test_resnet_simulation(): # Load polymath program graph = pm.pb_load(f"{BENCH_DIR}/resnet18v1.srdfg") # Create Genesys architecture graph genesys_cfg = parse_cfg() genesys = generate_genesys(genesys_cfg) # Compile the program program = compile(graph, genesys, f"{BENCH_DIR}", store_output=True, output_type="json")
def test_genesys_gemm(): graph = pm.pb_load(f"{LAYER_DIR}/resnet18_gemm.srdfg") batch_size_pass = pm.UpdateBatchSize(32, graph.op_name) graph = batch_size_pass(graph) genesys = define_genesys(GENESYS_CFG) program = initialize_program(graph, genesys) program.add_compilation_step("pad_operands", pad_operands, preproc=True, stage_kwargs={'shaped_nodes': []}) program.add_compilation_step("tile", tile) program.add_compilation_step("hoist", hoist, dependencies=["tile"]) program.compile() res = program.emit("json_no_ops") pprint(res)
def test_lenet(): filename = f"lenet.onnx" full_path = f"{BENCH_DIR}/full_dnns" filepath = f"{full_path}/{filename}" pb_path = f"{full_path}/lenet.srdfg" assert Path(filepath).exists() graph = pm.from_onnx(filepath) pm.pb_store(graph, full_path) node = pm.pb_load(pb_path, verbose=True) assert len(node.nodes) == len(graph.nodes) for name, n in node.nodes.items(): if n.op_name == "conv": print(n.kwargs.keys()) break
def test_tabla_linear(m_): shape_dict = {"m": m_} graph, input_info, out_info, keys = linear(m=m_, coarse=True) lgraph, input_info, out_info, keys = linear(m=m_, coarse=False) cwd = Path(f"{__file__}").parent base_path = f"{cwd}/pmlang_examples" full_path = f"{base_path}/outputs" graph_name = f"{graph.name}_{m_}" tabla_path = f"{full_path}/{graph_name}_tabla.json" tabla_ir, tabla_graph = pm.generate_tabla(graph, shape_dict, tabla_path, context_dict=input_info, add_kwargs=True) cwd = Path(f"{__file__}").parent base_path = f"{cwd}/pmlang_examples" full_path = f"{base_path}/outputs" pb_path = f"{full_path}/{graph.name}.srdfg" pm.pb_store(graph, full_path) node = pm.pb_load(pb_path)
def test_lower_group_op(): with pm.Node(name="linear_reg1") as graph: m = pm.parameter(name="m") x = pm.input("x", shape=(m)) y = pm.input("y") w = pm.state("w", shape=(m)) i = pm.index(0, m - 1, name="i") h = pm.sum([i], w[i] * x[i], name="h") m_ = 3 n_ = 3 x_ = np.random.randint(0, 10, m_) w_ = np.random.randint(0, 10, (m_)) np_result = np.sum(x_ * w_) np.testing.assert_allclose(graph("h", {"w": w_, "x": x_}), np_result) np.testing.assert_allclose(graph("h", w=w_, x=x_), np_result) shape_pass = NormalizeGraph({"m": m_, "n": n_}) graph_shapes = shape_pass(graph) shape_res = graph_shapes("h", x=x_, w=w_) np.testing.assert_allclose(shape_res, np_result) lower_pass = Lower({}) lowered_graph = lower_pass(graph_shapes) input_info = {f"w/w({i},)": w_[i] for i in range(len(w_))} input_info.update({f"x/x({i},)": x_[i] for i in range(len(x_))}) # fine_grained_eval = lowered_graph("h/h(4,)", input_info) assert fine_grained_eval == np_result pb_path = f"{OUTPATH}/linear_reg1.srdfg" pm.pb_store(lowered_graph, OUTPATH) loaded_node = pm.pb_load(pb_path) # input_info = {f"w/w({i},)": w_[i] for i in range(len(w_))} input_info.update({f"x/x({i},)": x_[i] for i in range(len(x_))}) loaded_res = loaded_node("h/h(4,)", input_info) assert loaded_node.func_hash() == lowered_graph.func_hash() assert loaded_res == np_result
def run_benchmark(benchmark_name, output_type="simulation"): assert benchmark_name in ['resnet18', 'resnet50', 'maskrcnn'] graph = pm.pb_load(f"{MODEL_DIR}/{benchmark_name}.srdfg") genesys = define_genesys(GENESYS_CFG) program = initialize_program(graph, genesys) program.add_compilation_step("pad_operands", pad_operands, preproc=True, stage_kwargs={'shaped_nodes': []}) program.add_compilation_step("tile", tile) program.add_compilation_step("hoist", hoist, dependencies=["tile"]) program.compile() if output_type == 'simulation': res = program.emit("json") with open(f"{BENCH_DIR}/compilation_output/{benchmark_name}.json", 'w') as outfile: json.dump(res, outfile) else: res = program.emit("string_final") with open(f"{BENCH_DIR}/compilation_output/{benchmark_name}.txt", 'w') as outfile: outfile.write(res)
def test_reco(): m_ = 3 n_ = 3 k_ = 2 shape_dict = {"m": n_, "k": k_, "n": n_} graph, input_info, out_info, keys = reco(coarse=True, **shape_dict) coarse_eval = graph(keys, input_info) np.testing.assert_allclose(coarse_eval[0], out_info["w1"]) np.testing.assert_allclose(coarse_eval[1], out_info["w2"]) fgraph, input_info, out_info, keys = reco(coarse=False, **shape_dict) lower_pass = Lower({}) lowered_graph = lower_pass(fgraph, {}) all_vals = lowered_graph(keys, input_info) w1_elems = np.prod(out_info["w1"].shape) w2_elems = np.prod(out_info["w2"].shape) out1 = np.asarray(list(all_vals[0:w1_elems])).reshape(out_info["w1"].shape) out2 = np.asarray(list(all_vals[w1_elems:])).reshape(out_info["w2"].shape) np.testing.assert_allclose(out1, out_info["w1"]) np.testing.assert_allclose(out2, out_info["w2"]) cwd = Path(f"{__file__}").parent base_path = f"{cwd}/pmlang_examples" full_path = f"{base_path}/outputs" pb_path = f"{full_path}/{graph.name}.srdfg" pm.pb_store(lowered_graph, full_path) loaded_node = pm.pb_load(pb_path) _, input_info, out_info, keys = reco(coarse=False, **shape_dict) loaded_res = loaded_node(keys, input_info) lres1 = np.asarray(list(loaded_res[0:w1_elems])).reshape(out_info["w1"].shape) lres2 = np.asarray(list(loaded_res[w1_elems:])).reshape(out_info["w2"].shape) np.testing.assert_allclose(lres1, out_info["w1"]) np.testing.assert_allclose(lres2, out_info["w2"])
def test_genesys_add(): graph = pm.pb_load(f"{LAYER_DIR}/resnet18_add.srdfg") GENESYS_DTYPES['SIMD'] = 'FXP16' GENESYS_DTYPES['SYSTOLIC_ARRAY'] = {} GENESYS_DTYPES['SYSTOLIC_ARRAY']['inp_weight'] = 'FXP4' GENESYS_DTYPES['SYSTOLIC_ARRAY']['bias_out'] = 'FXP16' update_genesys_cfg_from_dtypes() genesys = define_genesys(GENESYS_CFG) print(genesys.get_subgraph_node("VMEM1").size_bytes) program = initialize_program(graph, genesys) program.add_compilation_step("update_operand_dtypes", update_operand_dtypes, preproc=True, stage_kwargs={'dtype_map': GENESYS_DTYPES}) program.add_compilation_step("pad_operands", pad_operands, preproc=True, stage_kwargs={'shaped_nodes': []}) program.add_compilation_step("tile", tile) program.add_compilation_step("hoist", hoist, dependencies=["tile"]) program.compile() res = program.emit("json_no_ops") pprint(res)
def get_single_conv2d_node(): resnet18 = pm.pb_load(f"{BENCH_DIR}/resnet18v1.srdfg") for name, node in resnet18.nodes.items(): if node.name == "conv": return node