From 9dea001130d16c21d9d918ea9ec9139953bea29c Mon Sep 17 00:00:00 2001 From: Sitao Huang Date: Mon, 4 Jun 2018 14:53:08 -0500 Subject: [PATCH] Multi-PE host code and Vivado HLS tcl script --- triangle_counting_hls/run_tc_hls.tcl | 13 ++ triangle_counting_host/tc_host_opt.py | 154 +++++++++++++++++ triangle_counting_host/tc_host_opt_4.py | 162 ++++++++++++++++++ triangle_counting_host/tc_host_opt_7.py | 210 ++++++++++++++++++++++++ 4 files changed, 539 insertions(+) create mode 100644 triangle_counting_hls/run_tc_hls.tcl create mode 100644 triangle_counting_host/tc_host_opt.py create mode 100644 triangle_counting_host/tc_host_opt_4.py create mode 100644 triangle_counting_host/tc_host_opt_7.py diff --git a/triangle_counting_hls/run_tc_hls.tcl b/triangle_counting_hls/run_tc_hls.tcl new file mode 100644 index 0000000..6f48098 --- /dev/null +++ b/triangle_counting_hls/run_tc_hls.tcl @@ -0,0 +1,13 @@ +open_project -reset tc_hls +set_top triangle_counting +add_files triangle_counting.cc +add_files -tb triangle_counting_tb.cc + +open_solution -reset "solution1" +set_part {xc7z020clg400-1} +create_clock -period 10 + +csynth_design +export_design -format ip_catalog -version "0.001" + +exit diff --git a/triangle_counting_host/tc_host_opt.py b/triangle_counting_host/tc_host_opt.py new file mode 100644 index 0000000..1d7583a --- /dev/null +++ b/triangle_counting_host/tc_host_opt.py @@ -0,0 +1,154 @@ +# coding: utf-8 + +import sys +import numpy as np +import os +import time +import math +from datetime import datetime +from pynq import Xlnk +from pynq import Overlay + +# load our design overlay +overlay = Overlay('tc_opt.bit') +print("tc_opt.bit loaded") + +myIP = overlay.triangle_counting_0 + +t0 = time.time() + +neighbor_list = [] +offset_list = [0] +edge_list = [] + +graph_file = open("graph/soc-Epinions1_adj.tsv") +# graph_file = open("graph/test.tsv") +lines = graph_file.readlines() + +degree_count = 0 +prev_node = 0 + +for line in lines: + node_a, node_b, _ = map(int, line.split()) + if prev_node != node_b: + offset_list.append(degree_count) + + prev_node = node_b + if node_a < node_b: + edge_list.extend([node_b, node_a]) + else: + neighbor_list.append(node_a) + degree_count += 1 + +offset_list.append(degree_count) + +print("neighbor_list size= ", len(neighbor_list)) +print("offset_list size= ", len(offset_list)) +print("edge_list size= ", len(edge_list)) + +t1 = time.time() + +print("Finished reading graph file. ") +t = t1 - t0 +print("Reading input file time: ", str(t)) + +xlnk = Xlnk() + +num_edge = len(edge_list) / 2 +num_batch = 4 +num_edge_batch = int(math.floor(float(num_edge) / num_batch)) +num_edge_last_batch = num_edge - (num_batch-1)*num_edge_batch + +neighbor = xlnk.cma_array(shape=(len(neighbor_list),), dtype=np.int32) +offset = xlnk.cma_array(shape=(len(offset_list),), dtype=np.int32) +edge1 = xlnk.cma_array(shape=(2*num_edge_batch,), dtype=np.int32) +edge2 = xlnk.cma_array(shape=(2*num_edge_batch,), dtype=np.int32) +edge3 = xlnk.cma_array(shape=(2*num_edge_batch,), dtype=np.int32) +edge4 = xlnk.cma_array(shape=(2*num_edge_last_batch,), dtype=np.int32) +progress = xlnk.cma_array(shape=(5,), dtype=np.int32) + +neighbor[:] = neighbor_list +offset[:] = offset_list +edge1[:] = edge_list[0:2*num_edge_batch-1] +edge2[:] = edge_list[2*num_edge_batch:4*num_edge_batch-1] +edge3[:] = edge_list[4*num_edge_batch:6*num_edge_batch-1] +edge4[:] = edge_list[6*num_edge_batch:-1] + +# neighbor[:] = [2, 4, 5, 3, 4, 5, 4, 5, 5] +# offset[:] = [0, 0, 3, 6, 8, 9, 9] +# edge[:] = [5, 4, 5, 3, 5, 2, 5, 1, 4, 3, 4, 2, 4, 1, 3, 2, 2, 1] + +myIP.write(0x00018, neighbor.physical_address) +myIP.write(0x00020, offset.physical_address) +myIP.write(0x00028, edge1.physical_address) +myIP.write(0x00030, 2*num_edge_batch) +myIP.write(0x00038, progress.physical_address) + +myIP.write(0x10018, neighbor.physical_address) +myIP.write(0x10020, offset.physical_address) +myIP.write(0x10028, edge2.physical_address) +myIP.write(0x10030, 2*num_edge_batch) +myIP.write(0x10038, progress.physical_address) + +myIP.write(0x20018, neighbor.physical_address) +myIP.write(0x20020, offset.physical_address) +myIP.write(0x20028, edge3.physical_address) +myIP.write(0x20030, 2*num_edge_batch) +myIP.write(0x20038, progress.physical_address) + +myIP.write(0x30018, neighbor.physical_address) +myIP.write(0x30020, offset.physical_address) +myIP.write(0x30028, edge4.physical_address) +myIP.write(0x30030, 2*num_edge_last_batch) +myIP.write(0x30038, progress.physical_address) + +# for i in range(neighbor.size): +# print("neighbor[%d] = %d" % (i, neighbor[i])) + +# for i in range(offset.size): +# print("offset[%d] = %d" % (i, offset[i])) + +# for i in range(edge.size): +# print("edge[%d] = %d" % (i, edge[i])) + +t2 = time.time() +t = t2 - t1 +print("Preparing input data time: ", str(t)) + +myIP.write(0x00000, 1) +myIP.write(0x10000, 1) +myIP.write(0x20000, 1) +myIP.write(0x30000, 1) + +isready = 0; +while( isready != 6 ): + isready = myIP.read(0x00000) + +isready = 0; +while( isready != 6 ): + isready = myIP.read(0x10000) + +isready = 0; +while( isready != 6 ): + isready = myIP.read(0x20000) + +isready = 0; +while( isready != 6 ): + isready = myIP.read(0x30000) + +t3 = time.time() +t = t3 - t2 +#tbatch = tbatch + t +#print("Computation finished") +print("PL Time: ", str(t)) + +result1 = myIP.read(0x00010) +result2 = myIP.read(0x10010) +result3 = myIP.read(0x20010) +result4 = myIP.read(0x30010) + +print("Return value 1: ", result1) +print("Return value 2: ", result2) +print("Return value 3: ", result3) +print("Return value 4: ", result4) +print("Number of triangles: ", result1+result2+result3+result4) diff --git a/triangle_counting_host/tc_host_opt_4.py b/triangle_counting_host/tc_host_opt_4.py new file mode 100644 index 0000000..9e295d2 --- /dev/null +++ b/triangle_counting_host/tc_host_opt_4.py @@ -0,0 +1,162 @@ +# coding: utf-8 + +import sys +import numpy as np +import os +import time +import math +from datetime import datetime +from pynq import Xlnk +from pynq import Overlay + +# load our design overlay +overlay = Overlay('tc_opt_4.bit') +print("tc_opt_4.bit loaded") + +acc0 = overlay.triangle_counting_0 +acc1 = overlay.triangle_counting_1 +acc2 = overlay.triangle_counting_2 +acc3 = overlay.triangle_counting_3 + +t0 = time.time() + +neighbor_list = [] +offset_list = [0] +edge_list = [] + +graph_file = open("../../graph/soc-Epinions1_adj.tsv") +# graph_file = open("graph/test.tsv") +lines = graph_file.readlines() + +degree_count = 0 +prev_node = 0 + +for line in lines: + node_a, node_b, _ = map(int, line.split()) + if prev_node != node_b: + offset_list.append(degree_count) + + prev_node = node_b + if node_a < node_b: + edge_list.extend([node_b, node_a]) + else: + neighbor_list.append(node_a) + degree_count += 1 + +offset_list.append(degree_count) + +print("neighbor_list size= ", len(neighbor_list)) +print("offset_list size= ", len(offset_list)) +print("edge_list size= ", len(edge_list)) + +t1 = time.time() + +print("Finished reading graph file. ") +t = t1 - t0 +print("Reading input file time: ", str(t)) + +xlnk = Xlnk() + +num_edge = int(len(edge_list) / 2) +num_batch = 4 +num_edge_batch = int(math.floor(float(num_edge) / num_batch)) +num_edge_last_batch = num_edge - (num_batch-1)*num_edge_batch + +print(num_edge) +print(num_batch) +print(num_edge_batch) +print(num_edge_last_batch) + +neighbor = xlnk.cma_array(shape=(len(neighbor_list),), dtype=np.int32) +offset = xlnk.cma_array(shape=(len(offset_list),), dtype=np.int32) +edge1 = xlnk.cma_array(shape=(2*num_edge_batch,), dtype=np.int32) +edge2 = xlnk.cma_array(shape=(2*num_edge_batch,), dtype=np.int32) +edge3 = xlnk.cma_array(shape=(2*num_edge_batch,), dtype=np.int32) +edge4 = xlnk.cma_array(shape=(2*num_edge_last_batch,), dtype=np.int32) +progress = xlnk.cma_array(shape=(5,), dtype=np.int32) + +neighbor[:] = neighbor_list +offset[:] = offset_list +edge1[:] = edge_list[0:2*num_edge_batch] +edge2[:] = edge_list[2*num_edge_batch:4*num_edge_batch] +edge3[:] = edge_list[4*num_edge_batch:6*num_edge_batch] +edge4[:] = edge_list[6*num_edge_batch:] + +# neighbor[:] = [2, 4, 5, 3, 4, 5, 4, 5, 5] +# offset[:] = [0, 0, 3, 6, 8, 9, 9] +# edge[:] = [5, 4, 5, 3, 5, 2, 5, 1, 4, 3, 4, 2, 4, 1, 3, 2, 2, 1] + +acc0.write(0x00018, neighbor.physical_address) +acc0.write(0x00020, offset.physical_address) +acc0.write(0x00028, edge1.physical_address) +acc0.write(0x00030, 2*num_edge_batch) +acc0.write(0x00038, progress.physical_address) + +acc1.write(0x00018, neighbor.physical_address) +acc1.write(0x00020, offset.physical_address) +acc1.write(0x00028, edge2.physical_address) +acc1.write(0x00030, 2*num_edge_batch) +acc1.write(0x00038, progress.physical_address) + +acc2.write(0x00018, neighbor.physical_address) +acc2.write(0x00020, offset.physical_address) +acc2.write(0x00028, edge3.physical_address) +acc2.write(0x00030, 2*num_edge_batch) +acc2.write(0x00038, progress.physical_address) + +acc3.write(0x00018, neighbor.physical_address) +acc3.write(0x00020, offset.physical_address) +acc3.write(0x00028, edge4.physical_address) +acc3.write(0x00030, 2*num_edge_last_batch) +acc3.write(0x00038, progress.physical_address) + +# for i in range(neighbor.size): +# print("neighbor[%d] = %d" % (i, neighbor[i])) + +# for i in range(offset.size): +# print("offset[%d] = %d" % (i, offset[i])) + +# for i in range(edge.size): +# print("edge[%d] = %d" % (i, edge[i])) + +t2 = time.time() +t = t2 - t1 +print("Preparing input data time: ", str(t)) + +acc0.write(0x00000, 1) +acc1.write(0x00000, 1) +acc2.write(0x00000, 1) +acc3.write(0x00000, 1) + +isready = 0; +while( isready != 6 ): + isready = acc0.read(0x00000) + +isready = 0; +while( isready != 6 ): + isready = acc1.read(0x00000) + +isready = 0; +while( isready != 6 ): + isready = acc2.read(0x00000) + +isready = 0; +while( isready != 6 ): + isready = acc3.read(0x00000) + +t3 = time.time() +t = t3 - t2 +#tbatch = tbatch + t +#print("Computation finished") +print("PL Time: ", str(t)) + +result1 = acc0.read(0x00010) +result2 = acc1.read(0x00010) +result3 = acc2.read(0x00010) +result4 = acc3.read(0x00010) + +print("Return value 1: ", result1) +print("Return value 2: ", result2) +print("Return value 3: ", result3) +print("Return value 4: ", result4) +print("Number of triangles: ", result1+result2+result3+result4) diff --git a/triangle_counting_host/tc_host_opt_7.py b/triangle_counting_host/tc_host_opt_7.py new file mode 100644 index 0000000..22df986 --- /dev/null +++ b/triangle_counting_host/tc_host_opt_7.py @@ -0,0 +1,210 @@ +# coding: utf-8 + +import sys +import numpy as np +import os +import time +import math +from datetime import datetime +from pynq import Xlnk +from pynq import Overlay + +# load our design overlay +overlay = Overlay('tc_opt.bit') +print("tc_opt.bit loaded") + +acc0 = overlay.triangle_counting_0 +acc1 = overlay.triangle_counting_1 +acc2 = overlay.triangle_counting_2 +acc3 = overlay.triangle_counting_3 +acc4 = overlay.triangle_counting_4 +acc5 = overlay.triangle_counting_5 +acc6 = overlay.triangle_counting_6 + +t0 = time.time() + +neighbor_list = [] +offset_list = [0] +edge_list = [] + +graph_file = open("graph/soc-Epinions1_adj.tsv") +# graph_file = open("graph/test.tsv") +lines = graph_file.readlines() + +degree_count = 0 +prev_node = 0 + +for line in lines: + node_a, node_b, _ = map(int, line.split()) + if prev_node != node_b: + offset_list.append(degree_count) + + prev_node = node_b + if node_a < node_b: + edge_list.extend([node_b, node_a]) + else: + neighbor_list.append(node_a) + degree_count += 1 + +offset_list.append(degree_count) + +print("neighbor_list size= ", len(neighbor_list)) +print("offset_list size= ", len(offset_list)) +print("edge_list size= ", len(edge_list)) + +t1 = time.time() + +print("Finished reading graph file. ") +t = t1 - t0 +print("Reading input file time: ", str(t)) + +xlnk = Xlnk() + +num_edge = int(len(edge_list) / 2) +num_batch = 7 +num_edge_batch = int(math.floor(float(num_edge) / num_batch)) +num_edge_last_batch = num_edge - (num_batch-1)*num_edge_batch + +print(num_edge) +print(num_batch) +print(num_edge_batch) +print(num_edge_last_batch) + +neighbor = xlnk.cma_array(shape=(len(neighbor_list),), dtype=np.int32) +offset = xlnk.cma_array(shape=(len(offset_list),), dtype=np.int32) +edge1 = xlnk.cma_array(shape=(2*num_edge_batch,), dtype=np.int32) +edge2 = xlnk.cma_array(shape=(2*num_edge_batch,), dtype=np.int32) +edge3 = xlnk.cma_array(shape=(2*num_edge_batch,), dtype=np.int32) +edge4 = xlnk.cma_array(shape=(2*num_edge_batch,), dtype=np.int32) +edge5 = xlnk.cma_array(shape=(2*num_edge_batch,), dtype=np.int32) +edge6 = xlnk.cma_array(shape=(2*num_edge_batch,), dtype=np.int32) +edge7 = xlnk.cma_array(shape=(2*num_edge_last_batch,), dtype=np.int32) +progress = xlnk.cma_array(shape=(5,), dtype=np.int32) + +neighbor[:] = neighbor_list +offset[:] = offset_list +edge1[:] = edge_list[0:2*num_edge_batch] +edge2[:] = edge_list[2*num_edge_batch:4*num_edge_batch] +edge3[:] = edge_list[4*num_edge_batch:6*num_edge_batch] +edge4[:] = edge_list[6*num_edge_batch:8*num_edge_batch] +edge5[:] = edge_list[8*num_edge_batch:10*num_edge_batch] +edge6[:] = edge_list[10*num_edge_batch:12*num_edge_batch] +edge7[:] = edge_list[12*num_edge_batch:] + +# neighbor[:] = [2, 4, 5, 3, 4, 5, 4, 5, 5] +# offset[:] = [0, 0, 3, 6, 8, 9, 9] +# edge[:] = [5, 4, 5, 3, 5, 2, 5, 1, 4, 3, 4, 2, 4, 1, 3, 2, 2, 1] + +acc0.write(0x18, neighbor.physical_address) +acc0.write(0x20, offset.physical_address) +acc0.write(0x28, edge1.physical_address) +acc0.write(0x30, 2*num_edge_batch) +acc0.write(0x38, progress.physical_address) + +acc1.write(0x18, neighbor.physical_address) +acc1.write(0x20, offset.physical_address) +acc1.write(0x28, edge2.physical_address) +acc1.write(0x30, 2*num_edge_batch) +acc1.write(0x38, progress.physical_address) + +acc2.write(0x18, neighbor.physical_address) +acc2.write(0x20, offset.physical_address) +acc2.write(0x28, edge3.physical_address) +acc2.write(0x30, 2*num_edge_batch) +acc2.write(0x38, progress.physical_address) + +acc3.write(0x18, neighbor.physical_address) +acc3.write(0x20, offset.physical_address) +acc3.write(0x28, edge4.physical_address) +acc3.write(0x30, 2*num_edge_batch) +acc3.write(0x38, progress.physical_address) + +acc4.write(0x18, neighbor.physical_address) +acc4.write(0x20, offset.physical_address) +acc4.write(0x28, edge5.physical_address) +acc4.write(0x30, 2*num_edge_batch) +acc4.write(0x38, progress.physical_address) + +acc5.write(0x18, neighbor.physical_address) +acc5.write(0x20, offset.physical_address) +acc5.write(0x28, edge6.physical_address) +acc5.write(0x30, 2*num_edge_batch) +acc5.write(0x38, progress.physical_address) + +acc6.write(0x18, neighbor.physical_address) +acc6.write(0x20, offset.physical_address) +acc6.write(0x28, edge7.physical_address) +acc6.write(0x30, 2*num_edge_last_batch) +acc6.write(0x38, progress.physical_address) + +# for i in range(neighbor.size): +# print("neighbor[%d] = %d" % (i, neighbor[i])) + +# for i in range(offset.size): +# print("offset[%d] = %d" % (i, offset[i])) + +# for i in range(edge.size): +# print("edge[%d] = %d" % (i, edge[i])) + +t2 = time.time() +t = t2 - t1 +print("Preparing input data time: ", str(t)) + +acc0.write(0x00, 1) +acc1.write(0x00, 1) +acc2.write(0x00, 1) +acc3.write(0x00, 1) +acc4.write(0x00, 1) +acc5.write(0x00, 1) +acc6.write(0x00, 1) + +isready = 0; +while( isready != 6 ): + isready = acc0.read(0x00) + +isready = 0; +while( isready != 6 ): + isready = acc1.read(0x00) + +isready = 0; +while( isready != 6 ): + isready = acc2.read(0x00) + +isready = 0; +while( isready != 6 ): + isready = acc3.read(0x00) + +isready = 0; +while( isready != 6 ): + isready = acc4.read(0x00) + +isready = 0; +while( isready != 6 ): + isready = acc5.read(0x00) + +isready = 0; +while( isready != 6 ): + isready = acc6.read(0x00) + +t3 = time.time() +t = t3 - t2 +#tbatch = tbatch + t +#print("Computation finished") +print("PL Time: ", str(t)) + +result1 = acc0.read(0x10) +result2 = acc1.read(0x10) +result3 = acc2.read(0x10) +result4 = acc3.read(0x10) +result5 = acc4.read(0x10) +result6 = acc5.read(0x10) +result7 = acc6.read(0x10) + +print("Return value 1: ", result1) +print("Return value 2: ", result2) +print("Return value 3: ", result3) +print("Return value 4: ", result4) +print("Return value 5: ", result5) +print("Return value 6: ", result6) +print("Return value 7: ", result7) +print("Number of triangles: ", result1+result2+result3+result4+result5+result6+result7)