From e9561687e75e64ebd718895afaa1e36d1fc504ff Mon Sep 17 00:00:00 2001 From: qinli2 Date: Mon, 9 Jul 2018 16:52:21 -0500 Subject: [PATCH] multiple PE for ultrascale --- TC_onePort/multi_pe_tb.cc | 164 ++++++++++++++++++++++++++++++++++++++ TC_onePort/tc_multiPe.cc | 139 ++++++++++++++++++++++++++++++++ 2 files changed, 303 insertions(+) create mode 100644 TC_onePort/multi_pe_tb.cc create mode 100644 TC_onePort/tc_multiPe.cc diff --git a/TC_onePort/multi_pe_tb.cc b/TC_onePort/multi_pe_tb.cc new file mode 100644 index 0000000..f76f350 --- /dev/null +++ b/TC_onePort/multi_pe_tb.cc @@ -0,0 +1,164 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int triangle_counting(int neighbor[9], + int offset[7], + int edge[18], + int num_edges); +void triangle_counting_onePort(int* data_in); + +void read_graph(const char *filename, + std::vector *edge_list, + unsigned int num_pe, + std::vector &neighbor_list, + std::vector &offset_list) +{ + std::ifstream ifs(filename); + + int degree_count = 0; + int prev_node = 0; + int pe_idx = 0; + offset_list.push_back(0); + + if (ifs.is_open() && ifs.good()) + { + std::string str; + while (std::getline(ifs, str)) + { + if (!str.empty() && str[0] != '#') + { + std::istringstream ss(str); + int u, v; + ss >> u >> v; + if (prev_node != v) + { + offset_list.push_back(degree_count); + } + + prev_node = v; + if (u < v) + { + edge_list[pe_idx % num_pe].push_back(v); + edge_list[pe_idx % num_pe].push_back(u); + pe_idx++; + } + else + { + neighbor_list.push_back(u); + degree_count++; + } + } + } + } + ifs.close(); + offset_list.push_back(degree_count); +// num_edge = edge_list.size() / 2; +} + +int main() +{ + int num_edge = 0; + std::vector edge_list[8], neighbor_list, offset_list; + read_graph("soc-Epinions1_adj.tsv", edge_list,8, neighbor_list, offset_list); + std::cout << "neighbor_list size= " << neighbor_list.size() << std::endl; + std::cout << "offset_list size= " << offset_list.size() << std::endl; + std::cout << "edge_list0 size= " << edge_list[0].size() << std::endl; + std::cout << "edge_list1 size= " << edge_list[1].size() << std::endl; + std::cout << "edge_list2 size= " << edge_list[2].size() << std::endl; + std::cout << "edge_list3 size= " << edge_list[3].size() << std::endl; + std::cout << "edge_list4 size= " << edge_list[4].size() << std::endl; + std::cout << "edge_list5 size= " << edge_list[5].size() << std::endl; + std::cout << "edge_list6 size= " << edge_list[6].size() << std::endl; + std::cout << "edge_list7 size= " << edge_list[7].size() << std::endl; + + + int neighbor_size = neighbor_list.size(); + int offset_size = offset_list.size(); + + int num_edge0 = edge_list[0].size(); + int num_edge1 = edge_list[1].size(); + int num_edge2 = edge_list[2].size(); + int num_edge3 = edge_list[3].size(); + int num_edge4 = edge_list[4].size(); + int num_edge5 = edge_list[5].size(); + int num_edge6 = edge_list[6].size(); + int num_edge7 = edge_list[7].size(); + + + + + int *all_data = (int *)malloc( (11+ neighbor_size +offset_size + + num_edge0+num_edge1+num_edge2+num_edge3+num_edge4+num_edge5+num_edge6+num_edge7) * sizeof(int) ); + + //// all_data format + // [0]: result --- count + // [1-8]: num_edge + // [9]: neighbor_size + // [10]: offset_size + // [..]: neighbors + // [..]: offsets + // [..]: edges + + int *addr = all_data + 1; + + std::memcpy(addr, &num_edge0, 1 * sizeof(int)); + addr++; + std::memcpy(addr, &num_edge1, 1 * sizeof(int)); + addr++; + std::memcpy(addr, &num_edge2, 1 * sizeof(int)); + addr++; + std::memcpy(addr, &num_edge3, 1 * sizeof(int)); + addr++; + std::memcpy(addr, &num_edge4, 1 * sizeof(int)); + addr++; + std::memcpy(addr, &num_edge5, 1 * sizeof(int)); + addr++; + std::memcpy(addr, &num_edge6, 1 * sizeof(int)); + addr++; + std::memcpy(addr, &num_edge7, 1 * sizeof(int)); + addr++; + + std::memcpy(addr, &neighbor_size, 1 * sizeof(int)); + addr++; + + std::memcpy(addr, &offset_size, 1 * sizeof(int)); + addr++; + + std::memcpy(addr, neighbor_list.data(), neighbor_size * sizeof(int)); + addr += neighbor_size; + + std::memcpy(addr, offset_list.data(), offset_size * sizeof(int)); + addr += offset_size; + + std::memcpy(addr, edge_list[0].data(), num_edge0 * sizeof(int)); + addr += num_edge0; + std::memcpy(addr, edge_list[1].data(), num_edge1 * sizeof(int)); + addr += num_edge1; + std::memcpy(addr, edge_list[2].data(), num_edge2 * sizeof(int)); + addr += num_edge2; + std::memcpy(addr, edge_list[3].data(), num_edge3 * sizeof(int)); + addr += num_edge3; + std::memcpy(addr, edge_list[4].data(), num_edge4 * sizeof(int)); + addr += num_edge4; + std::memcpy(addr, edge_list[5].data(), num_edge5 * sizeof(int)); + addr += num_edge5; + std::memcpy(addr, edge_list[6].data(), num_edge6 * sizeof(int)); + addr += num_edge6; + std::memcpy(addr, edge_list[7].data(), num_edge7 * sizeof(int)); + + + + //int result = triangle_counting(neighbors, offsets, edges, num_edge); + triangle_counting_onePort(all_data); + + printf("result = %d\n", all_data[0]); + return 0; +} diff --git a/TC_onePort/tc_multiPe.cc b/TC_onePort/tc_multiPe.cc new file mode 100644 index 0000000..a4ba952 --- /dev/null +++ b/TC_onePort/tc_multiPe.cc @@ -0,0 +1,139 @@ +#include +#include +#define BUF_SIZE 4096 +#define MAX_NEIGHBORSIZE 1000000 +#define MAX_OFFSETSIZE 100000 +#define MAX_EDGESIZE 1000000 +#define NUM_PE 8 + +int neighbor_buf[MAX_NEIGHBORSIZE]; +int offset_buf[MAX_OFFSETSIZE]; +int edge_buf[NUM_PE][MAX_EDGESIZE]; +/*int edge1_buf[MAX_EDGESIZE]; +int edge2_buf[MAX_EDGESIZE]; +int edge3_buf[MAX_EDGESIZE]; +int edge4_buf[MAX_EDGESIZE]; +int edge5_buf[MAX_EDGESIZE]; +int edge6_buf[MAX_EDGESIZE]; +int edge7_buf[MAX_EDGESIZE];*/ +int num_edges_buf[NUM_PE]; +int triangle_counting(int neighbor[9], + int offset[7], + int edge[18], + int num_edges) +{ +// #pragma HLS INTERFACE m_axi port=neighbor depth = 32 offset=slave bundle=NEIGHBOR +//#pragma HLS INTERFACE m_axi port=offset depth = 32 offset=slave bundle=OFFSET +//#pragma HLS INTERFACE m_axi port=edge depth = 32 offset=slave bundle=EDGE + + unsigned int count = 0; + unsigned int i = 0; + unsigned int node_a, node_b; + unsigned int offset_a, offset_b; + unsigned int len_a, len_b; + + unsigned int idx_a = 0; + unsigned int idx_b = 0; + + unsigned int prev_node_a = 0; + unsigned int prev_node_b = 0; + + unsigned int local_a[BUF_SIZE]; + unsigned int local_b[BUF_SIZE]; + + for (i = 0; i < num_edges; i+=2) + { +#pragma HLS pipeline + node_a = edge[i]; + node_b = edge[i+1]; + + if (node_a != prev_node_a) + { + offset_a = offset[node_a]; + len_a = offset[node_a + 1] - offset_a; + //memcpy(local_a, (const unsigned int*)&(neighbor[offset_a]), len_a*sizeof(unsigned int)); + for (int index=0; index local_b[idx_b]) + idx_b++; + else + { + count++; + idx_a++; + idx_b++; + } + } + } + return count; +} + + + + +void triangle_counting_onePort(int* data_in) +{ +#pragma HLS INTERFACE m_axi port=data_in + + int addr = 1; + int out[NUM_PE]; + int s=0; + memcpy(num_edges_buf, (const unsigned int*)&(data_in[addr]), NUM_PE*sizeof(unsigned int)); + //int num_edges = data_in[addr]; + addr+=NUM_PE; + + int neighbor_size = data_in[addr]; + addr++; + int offset_size = data_in[addr]; + addr++; + + memcpy(neighbor_buf, (const unsigned int*)&(data_in[addr]), neighbor_size*sizeof(unsigned int)); + addr += neighbor_size; + + memcpy(offset_buf, (const unsigned int*)&(data_in[addr]), offset_size*sizeof(unsigned int)); + addr += offset_size; + + for(int i=0; i< NUM_PE; i++){ + memcpy(edge_buf[i], (const unsigned int*)&(data_in[addr]), num_edges_buf[i]*sizeof(unsigned int)); + addr += num_edges_buf[i]; + } + for(int i =0 ; i < NUM_PE; i++ ){ + out[i]=triangle_counting(neighbor_buf, + offset_buf, + edge_buf[i], + num_edges_buf[i]); + } + for(int i =0 ; i < NUM_PE; i++ ){ + s+=out[i]; + printf("%d ",out[i]); + } + + data_in[0]=s; + + + +} + +