Skip to content

Commit

Permalink
multiple PE for ultrascale
Browse files Browse the repository at this point in the history
  • Loading branch information
qinli2 authored Jul 9, 2018
1 parent 7b76fb7 commit e956168
Show file tree
Hide file tree
Showing 2 changed files with 303 additions and 0 deletions.
164 changes: 164 additions & 0 deletions TC_onePort/multi_pe_tb.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <cstring>
#include <sys/mman.h>
#include <unistd.h>

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<int> *edge_list,
unsigned int num_pe,
std::vector<int> &neighbor_list,
std::vector<int> &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<int> 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;
}
139 changes: 139 additions & 0 deletions TC_onePort/tc_multiPe.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#include <string.h>
#include <stdio.h>
#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<len_a; index++){
local_a[index]=neighbor[offset_a+index];
}
prev_node_a = node_a;
}

if (node_b != prev_node_b)
{
offset_b = offset[node_b];
len_b = offset[node_b + 1] - offset_b;
//memcpy(local_b, (const unsigned int*)&(neighbor[offset_b]), len_b*sizeof(unsigned int));
for (int index=0; index<len_b; index++){
local_b[index]=neighbor[offset_b+index];
}
prev_node_b = node_b;
}

idx_a = 0;
idx_b = 0;

while (idx_a < len_a && idx_b < len_b)
{
#pragma HLS pipeline
if (local_a[idx_a] < local_b[idx_b])
idx_a++;
else if (local_a[idx_a] > 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;



}


0 comments on commit e956168

Please sign in to comment.