diff --git a/.gitignore b/.gitignore index eca3eb79..84524578 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ src/parser/y.tab.h src/parser/y.tab.c .vscode/ src/finalcode -src/backends src/finalcode.exe src/bin/*.o *.out diff --git a/graphcode/generated_sycl/PageRankDSLV2.cpp b/graphcode/generated_sycl/PageRankDSLV2.cpp new file mode 100644 index 00000000..611a132d --- /dev/null +++ b/graphcode/generated_sycl/PageRankDSLV2.cpp @@ -0,0 +1,186 @@ +#ifndef GENCPP_PAGERANKDSLV2_H +#define GENCPP_PAGERANKDSLV2_H +#include +#include +#include +#include "../graph.hpp" +using namespace sycl; + +void Compute_PR(graph &g, float beta, float delta, int maxIter, + float *pageRank) +{ + queue Q(default_selector_v); + std::cout << "Selected device: " << Q.get_device().get_info() << std::endl; + // CSR BEGIN + int V = g.num_nodes(); + int E = g.num_edges(); + + printf("#nodes:%d\n", V); + printf("#edges:%d\n", E); + int *edgeLen = g.getEdgeLen(); + + int *h_meta; + int *h_data; + int *h_src; + int *h_weight; + int *h_rev_meta; + + h_meta = (int *)malloc((V + 1) * sizeof(int)); + h_data = (int *)malloc((E) * sizeof(int)); + h_src = (int *)malloc((E) * sizeof(int)); + h_weight = (int *)malloc((E) * sizeof(int)); + h_rev_meta = (int *)malloc((V + 1) * sizeof(int)); + + for (int i = 0; i <= V; i++) + { + int temp = g.indexofNodes[i]; + h_meta[i] = temp; + temp = g.rev_indexofNodes[i]; + h_rev_meta[i] = temp; + } + + for (int i = 0; i < E; i++) + { + int temp = g.edgeList[i]; + h_data[i] = temp; + temp = g.srcList[i]; + h_src[i] = temp; + temp = edgeLen[i]; + h_weight[i] = temp; + } + + int *d_meta; + int *d_data; + int *d_src; + int *d_weight; + int *d_rev_meta; + bool *d_modified_next; + + d_meta = malloc_device((1 + V), Q); + d_data = malloc_device((E), Q); + d_src = malloc_device((E), Q); + d_weight = malloc_device((E), Q); + d_rev_meta = malloc_device((V + 1), Q); + d_modified_next = malloc_device((V), Q); + + Q.submit([&](handler &h) + { h.memcpy(d_meta, h_meta, sizeof(int) * (V + 1)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_data, h_data, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_src, h_src, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_weight, h_weight, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_rev_meta, h_rev_meta, sizeof(int) * ((V + 1))); }) + .wait(); + + // CSR END + // LAUNCH CONFIG + int NUM_THREADS = 1048576; + int stride = NUM_THREADS; + + // TIMER START + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + + // DECLAR DEVICE AND HOST vars in params + float *d_pageRank; + d_pageRank = malloc_device(V, Q); + + // BEGIN DSL PARSING + float num_nodes = (float)g.num_nodes(); // asst in main + + float *d_pageRank_nxt; + d_pageRank_nxt = malloc_device(V, Q); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < V; i += stride) d_pageRank[i] = (float)1 / num_nodes; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < V; i += stride) d_pageRank_nxt[i] = (float)0; }); }) + .wait(); + + int iterCount = 0; // asst in main + + float diff; // asst in main + + do + { + diff = 0.000000; + float *d_diff = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.memcpy(d_diff, &diff, 1 * sizeof(float)); }) + .wait(); + + float *d_delta = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.memcpy(d_delta, &delta, 1 * sizeof(float)); }) + .wait(); + + float *d_num_nodes = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.memcpy(d_num_nodes, &num_nodes, 1 * sizeof(float)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> v) + {for (; v < V; v += NUM_THREADS){ // BEGIN KER FUN via ADDKERNEL + float sum = 0.000000; // asst in main + + // for all else part + for (int edge = d_rev_meta[v]; edge < d_rev_meta[v+1]; edge++) + {int nbr = d_src[edge] ; + sum = sum + d_pageRank[nbr] / (d_meta[nbr+1]-d_meta[nbr]); + + } // end FOR NBR ITR. TMP FIX! + float val = (1 - delta) / num_nodes + delta * sum; // asst in main + + atomic_ref atomic_data(d_diff[0]); + atomic_data += val - d_pageRank[v]; + d_pageRank_nxt[v] = val; +} }); }) + .wait(); // end KER FUNC + + Q.submit([&](handler &h) + { h.memcpy(&diff, d_diff, 1 * sizeof(float)); }) + .wait(); + + Q.submit([&](handler &h) + { h.memcpy(&delta, d_delta, 1 * sizeof(float)); }) + .wait(); + + Q.submit([&](handler &h) + { h.memcpy(&num_nodes, d_num_nodes, 1 * sizeof(float)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_pageRank[i] = d_pageRank_nxt[i]; }); }) + .wait(); + iterCount++; + + } while ((diff > beta) && (iterCount < maxIter)); + + // free up!! all propVars in this BLOCK! + free(d_pageRank_nxt, Q); + + // TIMER STOP + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + std::cout << "Time required: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + Q.submit([&](handler &h) + { h.memcpy(pageRank, d_pageRank, sizeof(float) * (V)); }) + .wait(); +} // end FUN + +#endif diff --git a/graphcode/generated_sycl/PageRank_DSL_V2.cpp b/graphcode/generated_sycl/PageRank_DSL_V2.cpp new file mode 100644 index 00000000..b4ab50d8 --- /dev/null +++ b/graphcode/generated_sycl/PageRank_DSL_V2.cpp @@ -0,0 +1,194 @@ +#ifndef GENCPP_PAGERANK_DSL_V2_H +#define GENCPP_PAGERANK_DSL_V2_H +#include +#include +#include +#include "../graph.hpp" +using namespace sycl; + +void Compute_PR(graph &g, float beta, float delta, int maxIter, + float *pageRank) +{ + queue Q(default_selector_v); + std::cout << "Selected device: " << Q.get_device().get_info() << std::endl; + // CSR BEGIN + int V = g.num_nodes(); + int E = g.num_edges(); + + printf("#nodes:%d\n", V); + printf("#edges:%d\n", E); + int *edgeLen = g.getEdgeLen(); + + int *h_meta; + int *h_data; + int *h_src; + int *h_weight; + int *h_rev_meta; + + h_meta = (int *)malloc((V + 1) * sizeof(int)); + h_data = (int *)malloc((E) * sizeof(int)); + h_src = (int *)malloc((E) * sizeof(int)); + h_weight = (int *)malloc((E) * sizeof(int)); + h_rev_meta = (int *)malloc((V + 1) * sizeof(int)); + + for (int i = 0; i <= V; i++) + { + int temp = g.indexofNodes[i]; + h_meta[i] = temp; + temp = g.rev_indexofNodes[i]; + h_rev_meta[i] = temp; + } + + for (int i = 0; i < E; i++) + { + int temp = g.edgeList[i]; + h_data[i] = temp; + temp = g.srcList[i]; + h_src[i] = temp; + temp = edgeLen[i]; + h_weight[i] = temp; + } + + int *d_meta; + int *d_data; + int *d_src; + int *d_weight; + int *d_rev_meta; + bool *d_modified_next; + + d_meta = malloc_device((1 + V), Q); + d_data = malloc_device((E), Q); + d_src = malloc_device((E), Q); + d_weight = malloc_device((E), Q); + d_rev_meta = malloc_device((V + 1), Q); + d_modified_next = malloc_device((V), Q); + + Q.submit([&](handler &h) + { h.memcpy(d_meta, h_meta, sizeof(int) * (V + 1)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_data, h_data, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_src, h_src, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_weight, h_weight, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_rev_meta, h_rev_meta, sizeof(int) * ((V + 1))); }) + .wait(); + + // CSR END + // LAUNCH CONFIG + int NUM_THREADS = 1048576; + int stride = NUM_THREADS; + + // TIMER START + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + + // DECLAR DEVICE AND HOST vars in params + float *d_pageRank; + d_pageRank = malloc_device(V, Q); + + // BEGIN DSL PARSING + float num_nodes = (float)g.num_nodes(); // asst in main + + float *d_pageRank_nxt; + d_pageRank_nxt = malloc_device(V, Q); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < V; i += stride) d_pageRank[i] = (float)1 / num_nodes; }); }) + .wait(); + + int iterCount = 0; // asst in main + + float diff; // asst in main + + do + { + diff = 0.000000; + float *d_delta = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.memcpy(d_delta, &delta, 1 * sizeof(float)); }) + .wait(); + + float *d_diff = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.memcpy(d_diff, &diff, 1 * sizeof(float)); }) + .wait(); + + float *d_num_nodes = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.memcpy(d_num_nodes, &num_nodes, 1 * sizeof(float)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> v) + {for (; v < V; v += NUM_THREADS){ // BEGIN KER FUN via ADDKERNEL + float sum = 0.000000; // asst in main + + // for all else part + for (int edge = d_rev_meta[v]; edge < d_rev_meta[v+1]; edge++) + {int nbr = d_src[edge] ; + sum = sum + d_pageRank[nbr] / (d_meta[nbr+1]-d_meta[nbr]); + + } // end FOR NBR ITR. TMP FIX! + float val = (1 - delta) / num_nodes + delta * sum; // asst in main + + atomic_ref atomic_data(d_diff[0]); + atomic_data += val - d_pageRank[v]; + d_pageRank_nxt[v] = val; + } }); }) + .wait(); // end KER FUNC + + Q.submit([&](handler &h) + { h.memcpy(&delta, d_delta, 1 * sizeof(float)); }) + .wait(); + + Q.submit([&](handler &h) + { h.memcpy(&diff, d_diff, 1 * sizeof(float)); }) + .wait(); + + Q.submit([&](handler &h) + { h.memcpy(&num_nodes, d_num_nodes, 1 * sizeof(float)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_pageRank[i] = d_pageRank_nxt[i]; }); }) + .wait(); + iterCount++; + + } while ((diff > beta) && (iterCount < maxIter)); + + // free up!! all propVars in this BLOCK! + free(d_pageRank_nxt, Q); + + // TIMER STOP + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + std::cout << "Time required: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + Q.submit([&](handler &h) + { h.memcpy(pageRank, d_pageRank, sizeof(float) * (V)); }) + .wait(); + for (int i = 0; i < V; i++) + std::cout << i << " " << pageRank[i] << std::endl; +} // end FUN + +int main(int argc, char **argv) +{ + graph G1(argv[1]); + G1.parseGraph(); + float beta = 0.001; + int maxIter = 100; + float delta = 0.85; + float *pageRank; + pageRank = (float *)malloc(G1.num_nodes() * sizeof(float)); + Compute_PR(G1, beta, delta, maxIter, pageRank); + return 0; +} +#endif \ No newline at end of file diff --git a/graphcode/generated_sycl/SSSP_V2.cpp b/graphcode/generated_sycl/SSSP_V2.cpp new file mode 100644 index 00000000..c87cc52a --- /dev/null +++ b/graphcode/generated_sycl/SSSP_V2.cpp @@ -0,0 +1,206 @@ +#ifndef GENCPP_SSSP_V2_H +#define GENCPP_SSSP_V2_H +#include +#include +#include +#include "../graph.hpp" +using namespace sycl; + +void Compute_SSSP(graph &g, int *dist, int src) +{ + queue Q(default_selector_v); + std::cout << "Selected device: " << Q.get_device().get_info() << std::endl; + // CSR BEGIN + int V = g.num_nodes(); + int E = g.num_edges(); + + printf("#nodes:%d\n", V); + printf("#edges:%d\n", E); + int *edgeLen = g.getEdgeLen(); + + int *h_meta; + int *h_data; + int *h_src; + int *h_weight; + int *h_rev_meta; + + h_meta = (int *)malloc((V + 1) * sizeof(int)); + h_data = (int *)malloc((E) * sizeof(int)); + h_src = (int *)malloc((E) * sizeof(int)); + h_weight = (int *)malloc((E) * sizeof(int)); + h_rev_meta = (int *)malloc((V + 1) * sizeof(int)); + + for (int i = 0; i <= V; i++) + { + int temp = g.indexofNodes[i]; + h_meta[i] = temp; + temp = g.rev_indexofNodes[i]; + h_rev_meta[i] = temp; + } + + for (int i = 0; i < E; i++) + { + int temp = g.edgeList[i]; + h_data[i] = temp; + temp = g.srcList[i]; + h_src[i] = temp; + temp = edgeLen[i]; + h_weight[i] = temp; + } + + int *d_meta; + int *d_data; + int *d_src; + int *d_weight; + int *d_rev_meta; + bool *d_modified_next; + + d_meta = malloc_device((1 + V), Q); + d_data = malloc_device((E), Q); + d_src = malloc_device((E), Q); + d_weight = malloc_device((E), Q); + d_rev_meta = malloc_device((V + 1), Q); + d_modified_next = malloc_device((V), Q); + + Q.submit([&](handler &h) + { h.memcpy(d_meta, h_meta, sizeof(int) * (V + 1)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_data, h_data, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_src, h_src, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_weight, h_weight, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_rev_meta, h_rev_meta, sizeof(int) * ((V + 1))); }) + .wait(); + + // CSR END + // LAUNCH CONFIG + int NUM_THREADS = 1048576; + int stride = NUM_THREADS; + + // TIMER START + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + + // DECLAR DEVICE AND HOST vars in params + int *d_dist; + d_dist = malloc_device(V, Q); + + // BEGIN DSL PARSING + bool *d_modified; + d_modified = malloc_device(V, Q); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < V; i += stride) d_dist[i] = (int)INT_MAX; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < V; i += stride) d_modified[i] = (bool)false; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.single_task([=]() + { d_modified[src] = (bool)true; }); }) + .wait(); // InitIndexDevice + + Q.submit([&](handler &h) + { h.single_task([=]() + { d_dist[src] = (int)0; }); }) + .wait(); // InitIndexDevice + + bool finished = false; // asst in main + + // FIXED POINT variables + // BEGIN FIXED POINT + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified_next[i] = false; }); }) + .wait(); + + while (!finished) + { + + finished = true; + bool *d_finished = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.memcpy(d_finished, &finished, 1 * sizeof(bool)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> v) + {for (; v < V; v += NUM_THREADS){ // BEGIN KER FUN via ADDKERNEL +if (d_modified[v] == true){ // if filter begin +// for all else part +for (int edge = d_meta[v]; edge < d_meta[v+1]; edge++) { // FOR NBR ITR +int nbr = d_data[edge]; +int e = edge; + int dist_new = d_dist[v] + d_weight[e]; +bool modified_new = true; +if(d_dist[v]!= INT_MAX && d_dist[nbr] > dist_new) +{ + atomic_ref atomic_data(d_dist[nbr]); + atomic_data.fetch_min(dist_new); + d_modified_next[nbr] = modified_new; + *d_finished = false ; +} + +} // end FOR NBR ITR. TMP FIX! + +} // if filter end +} }); }) + .wait(); // end KER FUNC + + Q.submit([&](handler &h) + { h.memcpy(&finished, d_finished, 1 * sizeof(bool)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified[i] = d_modified_next[i]; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified_next[i] = false; }); }) + .wait(); + + } // END FIXED POINT + + // free up!! all propVars in this BLOCK! + free(d_modified, Q); + + // TIMER STOP + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + std::cout << "Time required: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + Q.submit([&](handler &h) + { h.memcpy(dist, d_dist, sizeof(int) * (V)); }) + .wait(); + for (int i = 0; i < V; i++) + std::cout << i << " " << dist[i] << std::endl; + // std::cout << "Number of rounds required for convergence: " << k << std::endl; + +} // end FUN + +int main(int argc, char **argv) +{ + graph G1(argv[1]); + G1.parseGraph(true); + int src = atoi(argv[2]); + int *dist; + dist = (int *)malloc(G1.num_nodes() * sizeof(int)); + Compute_SSSP(G1, dist, src); + return 0; +} +#endif \ No newline at end of file diff --git a/graphcode/generated_sycl/bc_dslV2.cpp b/graphcode/generated_sycl/bc_dslV2.cpp new file mode 100644 index 00000000..98cc950b --- /dev/null +++ b/graphcode/generated_sycl/bc_dslV2.cpp @@ -0,0 +1,198 @@ +#ifndef GENCPP_BC_DSLV2_H +#define GENCPP_BC_DSLV2_H +#include +#include +#include +#include "../graph.hpp" +using namespace sycl; + +void Compute_BC(graph& g,float* BC,std::set& sourceSet) +{ + queue Q(default_selector_v); + std::cout << "Selected device: " << Q.get_device().get_info() << std::endl; + // CSR BEGIN + int V = g.num_nodes(); + int E = g.num_edges(); + + printf("#nodes:%d\n",V); + printf("#edges:%d\n",E); + int* edgeLen = g.getEdgeLen(); + + int *h_meta; + int *h_data; + int *h_src; + int *h_weight; + int *h_rev_meta; + + h_meta = (int *)malloc( (V+1)*sizeof(int)); + h_data = (int *)malloc( (E)*sizeof(int)); + h_src = (int *)malloc( (E)*sizeof(int)); + h_weight = (int *)malloc( (E)*sizeof(int)); + h_rev_meta = (int *)malloc( (V+1)*sizeof(int)); + + for(int i=0; i<= V; i++) { + int temp = g.indexofNodes[i]; + h_meta[i] = temp; + temp = g.rev_indexofNodes[i]; + h_rev_meta[i] = temp; + } + + for(int i=0; i< E; i++) { + int temp = g.edgeList[i]; + h_data[i] = temp; + temp = g.srcList[i]; + h_src[i] = temp; + temp = edgeLen[i]; + h_weight[i] = temp; + } + + + int* d_meta; + int* d_data; + int* d_src; + int* d_weight; + int* d_rev_meta; + bool* d_modified_next; + + d_meta=malloc_device((1+V), Q); + d_data=malloc_device((E), Q); + d_src=malloc_device((E), Q); + d_weight=malloc_device((E), Q); + d_rev_meta=malloc_device((V+1), Q); + d_modified_next=malloc_device((V), Q); + + Q.submit([&](handler &h) + { h.memcpy( d_meta, h_meta, sizeof(int)*(V+1)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy( d_data, h_data, sizeof(int)*(E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy( d_src, h_src, sizeof(int)*(E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_weight, h_weight, sizeof(int)*(E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_rev_meta, h_rev_meta, sizeof(int)*((V+1))); }) + .wait(); + + // CSR END + //LAUNCH CONFIG + int NUM_THREADS = 1048576; + int stride = NUM_THREADS; + + // TODO: TIMER START + + //DECLAR DEVICE AND HOST vars in params + float* d_BC; + d_BC=malloc_device(V, Q); + + + //BEGIN DSL PARSING + Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){ + for (; i < V; i += stride) d_BC[i] = (float)0;}); +}).wait(); + +double* d_sigma; +d_sigma=malloc_device(V, Q); + +float* d_delta; +d_delta=malloc_device(V, Q); + +// Generate for all statement +// for all else part +//FOR SIGNATURE of SET - Assumes set for on .cu only +std::set::iterator itr; +for(itr=sourceSet.begin();itr!=sourceSet.end();itr++) +{ + int src = *itr; + Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){ + for (; i < V; i += stride) d_delta[i] = (float)0;}); +}).wait(); + +Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){ + for (; i < V; i += stride) d_sigma[i] = (double)0;}); +}).wait(); + +Q.submit([&](handler &h){ h.single_task([=](){ +d_sigma[src] = (double)1;}); +}).wait(); //InitIndexDevice + + +//EXTRA vars for ITBFS AND REVBFS +bool finished; +int hops_from_source=0; +bool* d_finished; d_finished = malloc_device(1, Q); +int* d_hops_from_source; d_hops_from_source = malloc_device(1, Q); +Q.submit([&](handler &h){ h.single_task([=](){ *d_hops_from_source = 0; }); }).wait(); +int* d_level; d_level = malloc_device(V, Q); + +//EXTRA vars INITIALIZATION +Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){ +for (; i < V; i += stride) d_level[i] = (int)-1; +}); }).wait(); +Q.submit([&](handler &h){ h.single_task([=](){ +d_level[src] = 0; +}); }).wait() + +// long k =0 ;// For DEBUG +do { +finished = true; +Q.submit([&](handler &h) +{ h.memcpy(d_finished, &finished, sizeof(bool)*(1)); }) +.wait(); + +//Kernel LAUNCH +Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> v) +if(d_level[v] == *d_hops_from_source) { +// Generate for all statement +// for all else part +for (int edge = d_meta[v]; edge < d_meta[v+1]; edge++) { // FOR NBR ITR +int w = d_data[edge]; +if(d_level[w] == -1) { + d_level[w] = *d_hops_from_source + 1; + *d_finished = false; +} +if(d_level[w] == *d_hops_from_source + 1) { + d_sigma[w] = d_sigma[w] + d_sigma[v]; + +} +} +} // end if d lvl +}).wait(); // kernel end + + +Q.submit([&](handler &h) +{ h.memcpy(&finished, d_finished, sizeof(bool)*(1)); }) +.wait(); +}while(!finished); +// addCudaRevBFSIterationLoop +//BACKWARD PASS +while(hops_from_source > 1) { + +//KERNEL Launch +back_pass<<>>(V, d_meta, d_data, d_weight, d_delta, d_sigma, d_level, d_hops_from_source, d_finished +// generatePropParams +); ///DONE from varList + +// addCudaRevBFSIterKernel +hops_from_source--; +Q.submit([&](handler &h) +{ h.memcpy(d_hops_from_source, &hops_from_source, sizeof(int)*(1)); }) +.wait(); +} +//accumulate_bc<<>>(V,d_delta, d_BC, d_level, src); + +} + +//cudaFree up!! all propVars in this BLOCK! +free(d_delta, Q); +free(d_sigma, Q); + +Q.submit([&](handler &h) +{ h.memcpy( BC, d_BC, sizeof(float)*(V)); }) +.wait(); +} //end FUN + +#endif diff --git a/graphcode/generated_sycl/bc_dsl_v2.cpp b/graphcode/generated_sycl/bc_dsl_v2.cpp new file mode 100644 index 00000000..b424f270 --- /dev/null +++ b/graphcode/generated_sycl/bc_dsl_v2.cpp @@ -0,0 +1,266 @@ +#ifndef GENCPP_BC_DSL_V2_H +#define GENCPP_BC_DSL_V2_H +#include +#include +#include +#include "../graph.hpp" +using namespace sycl; + +void Compute_BC(graph &g, float *BC, std::set &sourceSet) +{ + queue Q(default_selector_v); + std::cout << "Selected device: " << Q.get_device().get_info() << std::endl; + // CSR BEGIN + int V = g.num_nodes(); + int E = g.num_edges(); + + printf("#nodes:%d\n", V); + printf("#edges:%d\n", E); + int *edgeLen = g.getEdgeLen(); + + int *h_meta; + int *h_data; + int *h_src; + int *h_weight; + int *h_rev_meta; + + h_meta = (int *)malloc((V + 1) * sizeof(int)); + h_data = (int *)malloc((E) * sizeof(int)); + h_src = (int *)malloc((E) * sizeof(int)); + h_weight = (int *)malloc((E) * sizeof(int)); + h_rev_meta = (int *)malloc((V + 1) * sizeof(int)); + + for (int i = 0; i <= V; i++) + { + int temp = g.indexofNodes[i]; + h_meta[i] = temp; + temp = g.rev_indexofNodes[i]; + h_rev_meta[i] = temp; + } + + for (int i = 0; i < E; i++) + { + int temp = g.edgeList[i]; + h_data[i] = temp; + temp = g.srcList[i]; + h_src[i] = temp; + temp = edgeLen[i]; + h_weight[i] = temp; + } + + int *d_meta; + int *d_data; + int *d_src; + int *d_weight; + int *d_rev_meta; + bool *d_modified_next; + + d_meta = malloc_device((1 + V), Q); + d_data = malloc_device((E), Q); + d_src = malloc_device((E), Q); + d_weight = malloc_device((E), Q); + d_rev_meta = malloc_device((V + 1), Q); + d_modified_next = malloc_device((V), Q); + + Q.submit([&](handler &h) + { h.memcpy(d_meta, h_meta, sizeof(int) * (V + 1)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_data, h_data, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_src, h_src, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_weight, h_weight, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_rev_meta, h_rev_meta, sizeof(int) * ((V + 1))); }) + .wait(); + + // CSR END + // LAUNCH CONFIG + int NUM_THREADS = 1048576; + int stride = NUM_THREADS; + + // TIMER START + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + + // DECLAR DEVICE AND HOST vars in params + float *d_BC; + d_BC = malloc_device(V, Q); + + // BEGIN DSL PARSING + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < V; i += stride) d_BC[i] = (float)0; }); }) + .wait(); + + // for all else part + // FOR SIGNATURE of SET - Assumes set for on .cu only + std::set::iterator itr; + for (itr = sourceSet.begin(); itr != sourceSet.end(); itr++) + { + int src = *itr; + double *d_sigma; + d_sigma = malloc_device(V, Q); + + float *d_delta; + d_delta = malloc_device(V, Q); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < V; i += stride) d_delta[i] = (float)0; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < V; i += stride) d_sigma[i] = (double)0; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.single_task([=]() + { d_sigma[src] = (double)1; }); }) + .wait(); // InitIndexDevice + + // EXTRA vars for ITBFS AND REVBFS + bool finished; + int hops_from_source = 0; + bool *d_finished; + d_finished = malloc_device(1, Q); + int *d_hops_from_source; + d_hops_from_source = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.single_task([=]() + { *d_hops_from_source = 0; }); }) + .wait(); + int *d_level; + d_level = malloc_device(V, Q); + + // EXTRA vars INITIALIZATION + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_level[i] = (int)-1; }); }) + .wait(); + Q.submit([&](handler &h) + { h.single_task([=]() + { d_level[src] = 0; }); }) + .wait(); + + // long k =0 ;// For DEBUG + do + { + finished = true; + Q.submit([&](handler &h) + { h.memcpy(d_finished, &finished, sizeof(bool) * (1)); }) + .wait(); + + // Kernel LAUNCH + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> v) + {for (; v < V; v += NUM_THREADS){ +if(d_level[v] == *d_hops_from_source) { +// for all else part +for (int edge = d_meta[v]; edge < d_meta[v+1]; edge++) { // FOR NBR ITR +int w = d_data[edge]; +if(d_level[w] == -1) { + d_level[w] = *d_hops_from_source + 1; + *d_finished = false; +} +if(d_level[w] == *d_hops_from_source + 1) { + // atomic update + atomic_ref atomic_data(d_sigma[w]); + atomic_data += d_sigma[v]; + +} +} +} // end if d lvl +} }); }) + .wait(); // kernel end + + Q.submit([&](handler &h) + { h.single_task([=]() + { *d_hops_from_source += 1; }); }) + .wait(); + ++hops_from_source; // updating the level to process in the next iteration + + Q.submit([&](handler &h) + { h.memcpy(&finished, d_finished, sizeof(bool) * (1)); }) + .wait(); + } while (!finished); + + hops_from_source--; + Q.submit([&](handler &h) + { h.memcpy(d_hops_from_source, &hops_from_source, sizeof(int) * (1)); }) + .wait(); + + // BACKWARD PASS + while (hops_from_source > 1) + { + + // KERNEL Launch + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> v) + {for (; v < V; v += NUM_THREADS){ +if(d_level[v] == *d_hops_from_source-1) { +// for all else part +for (int edge = d_meta[v]; edge < d_meta[v+1]; edge++) { // FOR NBR ITR +int w = d_data[edge]; +if(d_level[w] == *d_hops_from_source) { +d_delta[v] = d_delta[v] + (d_sigma[v] / d_sigma[w]) * (1 + d_delta[w]); + +} // end IF +} // end FOR +d_BC[v] = d_BC[v] + d_delta[v]; +} // end if d lvl + } }); }) + .wait(); // kernel end + + hops_from_source--; + Q.submit([&](handler &h) + { h.memcpy(d_hops_from_source, &hops_from_source, sizeof(int) * (1)); }) + .wait(); + } + + // free up!! all propVars in this BLOCK! + free(d_delta, Q); + free(d_sigma, Q); + } + + // TIMER STOP + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + std::cout << "Time required: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + Q.submit([&](handler &h) + { h.memcpy(BC, d_BC, sizeof(float) * (V)); }) + .wait(); + // for (int i = 0; i < V; i++) + // std::cout << i << " " << BC[i] / 2.0 << std::endl; + +} // end FUN + +int main(int argc, char **argv) +{ + graph G1(argv[1]); + G1.parseGraph(); + float *BC; + std::vector sourceSize = {1, 20, 80, 150}; + for (auto size : sourceSize) + { + std::set sourceSet; + for (int i = 0; i < size; i++) + sourceSet.insert(i); + std::cout << "Num sources: " << size << std::endl; + BC = (float *)malloc(G1.num_nodes() * sizeof(float)); + Compute_BC(G1, BC, sourceSet); + free(BC); + } + + return 0; +} +#endif \ No newline at end of file diff --git a/graphcode/generated_sycl/bc_dsl_v3.cpp b/graphcode/generated_sycl/bc_dsl_v3.cpp new file mode 100644 index 00000000..3289c505 --- /dev/null +++ b/graphcode/generated_sycl/bc_dsl_v3.cpp @@ -0,0 +1,198 @@ +#ifndef GENCPP_BC_DSL_V3_H +#define GENCPP_BC_DSL_V3_H +#include +#include +#include +#include "../graph.hpp" +using namespace sycl; + +void Compute_BC(graph& g,double* BC,std::set& sourceSet) +{ + queue Q(default_selector_v); + std::cout << "Selected device: " << Q.get_device().get_info() << std::endl; + // CSR BEGIN + int V = g.num_nodes(); + int E = g.num_edges(); + + printf("#nodes:%d\n",V); + printf("#edges:%d\n",E); + int* edgeLen = g.getEdgeLen(); + + int *h_meta; + int *h_data; + int *h_src; + int *h_weight; + int *h_rev_meta; + + h_meta = (int *)malloc( (V+1)*sizeof(int)); + h_data = (int *)malloc( (E)*sizeof(int)); + h_src = (int *)malloc( (E)*sizeof(int)); + h_weight = (int *)malloc( (E)*sizeof(int)); + h_rev_meta = (int *)malloc( (V+1)*sizeof(int)); + + for(int i=0; i<= V; i++) { + int temp = g.indexofNodes[i]; + h_meta[i] = temp; + temp = g.rev_indexofNodes[i]; + h_rev_meta[i] = temp; + } + + for(int i=0; i< E; i++) { + int temp = g.edgeList[i]; + h_data[i] = temp; + temp = g.srcList[i]; + h_src[i] = temp; + temp = edgeLen[i]; + h_weight[i] = temp; + } + + + int* d_meta; + int* d_data; + int* d_src; + int* d_weight; + int* d_rev_meta; + bool* d_modified_next; + + d_meta=malloc_device((1+V), Q); + d_data=malloc_device((E), Q); + d_src=malloc_device((E), Q); + d_weight=malloc_device((E), Q); + d_rev_meta=malloc_device((V+1), Q); + d_modified_next=malloc_device((V), Q); + + Q.submit([&](handler &h) + { h.memcpy( d_meta, h_meta, sizeof(int)*(V+1)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy( d_data, h_data, sizeof(int)*(E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy( d_src, h_src, sizeof(int)*(E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_weight, h_weight, sizeof(int)*(E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_rev_meta, h_rev_meta, sizeof(int)*((V+1))); }) + .wait(); + + // CSR END + //LAUNCH CONFIG + int NUM_THREADS = 1048576; + int stride = NUM_THREADS; + + // TODO: TIMER START + + //DECLAR DEVICE AND HOST vars in params + double* d_BC; + d_BC=malloc_device(V, Q); + + + //BEGIN DSL PARSING + Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){ + for (; i < V; i += stride) d_BC[i] = (double)0;}); +}).wait(); + +double* d_sigma; +d_sigma=malloc_device(V, Q); + +double* d_delta; +d_delta=malloc_device(V, Q); + +// Generate for all statement +// for all else part +//FOR SIGNATURE of SET - Assumes set for on .cu only +std::set::iterator itr; +for(itr=sourceSet.begin();itr!=sourceSet.end();itr++) +{ + int src = *itr; + Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){ + for (; i < V; i += stride) d_delta[i] = (double)0;}); +}).wait(); + +Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){ + for (; i < V; i += stride) d_sigma[i] = (double)0;}); +}).wait(); + +Q.submit([&](handler &h){ h.single_task([=](){ +d_sigma[src] = (double)1;}); +}).wait(); //InitIndexDevice + + +//EXTRA vars for ITBFS AND REVBFS +bool finished; +int hops_from_source=0; +bool* d_finished; d_finished = malloc_device(1, Q); +int* d_hops_from_source; d_hops_from_source = malloc_device(1, Q); +Q.submit([&](handler &h){ h.single_task([=](){ *d_hops_from_source = 0; }); }).wait(); +int* d_level; d_level = malloc_device(V, Q); + +//EXTRA vars INITIALIZATION +Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){ +for (; i < V; i += stride) d_level[i] = (int)-1; +}); }).wait(); +Q.submit([&](handler &h){ h.single_task([=](){ +d_level[src] = 0; +}); }).wait() + +// long k =0 ;// For DEBUG +do { +finished = true; +Q.submit([&](handler &h) +{ h.memcpy(d_finished, &finished, sizeof(bool)*(1)); }) +.wait(); + +//Kernel LAUNCH +Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> v) +if(d_level[v] == *d_hops_from_source) { +// Generate for all statement +// for all else part +for (int edge = d_meta[v]; edge < d_meta[v+1]; edge++) { // FOR NBR ITR +int w = d_data[edge]; +if(d_level[w] == -1) { + d_level[w] = *d_hops_from_source + 1; + *d_finished = false; +} +if(d_level[w] == *d_hops_from_source + 1) { + d_sigma[w] = d_sigma[w] + d_sigma[v]; + +} +} +} // end if d lvl +}).wait(); // kernel end + + +Q.submit([&](handler &h) +{ h.memcpy(&finished, d_finished, sizeof(bool)*(1)); }) +.wait(); +}while(!finished); +// addCudaRevBFSIterationLoop +//BACKWARD PASS +while(hops_from_source > 1) { + +//KERNEL Launch +back_pass<<>>(V, d_meta, d_data, d_weight, d_delta, d_sigma, d_level, d_hops_from_source, d_finished +// generatePropParams +); ///DONE from varList + +// addCudaRevBFSIterKernel +hops_from_source--; +Q.submit([&](handler &h) +{ h.memcpy(d_hops_from_source, &hops_from_source, sizeof(int)*(1)); }) +.wait(); +} +//accumulate_bc<<>>(V,d_delta, d_BC, d_level, src); + +} + +//cudaFree up!! all propVars in this BLOCK! +free(d_delta, Q); +free(d_sigma, Q); + +Q.submit([&](handler &h) +{ h.memcpy( BC, d_BC, sizeof(double)*(V)); }) +.wait(); +} //end FUN + +#endif diff --git a/graphcode/generated_sycl/mst_dsl_v2.cpp b/graphcode/generated_sycl/mst_dsl_v2.cpp new file mode 100644 index 00000000..ade63cec --- /dev/null +++ b/graphcode/generated_sycl/mst_dsl_v2.cpp @@ -0,0 +1,446 @@ +#ifndef GENCPP_MST_DSL_V2_H +#define GENCPP_MST_DSL_V2_H +#include +#include +#include +#include "../graph.hpp" +using namespace sycl; + +void Boruvka(graph &g) +{ + queue Q(default_selector_v); + std::cout << "Selected device: " << Q.get_device().get_info() << std::endl; + // CSR BEGIN + int V = g.num_nodes(); + int E = g.num_edges(); + + printf("#nodes:%d\n", V); + printf("#edges:%d\n", E); + int *edgeLen = g.getEdgeLen(); + + int *h_meta; + int *h_data; + int *h_src; + int *h_weight; + int *h_rev_meta; + + h_meta = (int *)malloc((V + 1) * sizeof(int)); + h_data = (int *)malloc((E) * sizeof(int)); + h_src = (int *)malloc((E) * sizeof(int)); + h_weight = (int *)malloc((E) * sizeof(int)); + h_rev_meta = (int *)malloc((V + 1) * sizeof(int)); + + for (int i = 0; i <= V; i++) + { + int temp = g.indexofNodes[i]; + h_meta[i] = temp; + temp = g.rev_indexofNodes[i]; + h_rev_meta[i] = temp; + } + + for (int i = 0; i < E; i++) + { + int temp = g.edgeList[i]; + h_data[i] = temp; + temp = g.srcList[i]; + h_src[i] = temp; + temp = edgeLen[i]; + h_weight[i] = temp; + } + + int *d_meta; + int *d_data; + int *d_src; + int *d_weight; + int *d_rev_meta; + bool *d_modified_next; + + d_meta = malloc_device((1 + V), Q); + d_data = malloc_device((E), Q); + d_src = malloc_device((E), Q); + d_weight = malloc_device((E), Q); + d_rev_meta = malloc_device((V + 1), Q); + d_modified_next = malloc_device((V), Q); + + Q.submit([&](handler &h) + { h.memcpy(d_meta, h_meta, sizeof(int) * (V + 1)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_data, h_data, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_src, h_src, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_weight, h_weight, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_rev_meta, h_rev_meta, sizeof(int) * ((V + 1))); }) + .wait(); + + // CSR END + // LAUNCH CONFIG + int NUM_THREADS = 1048576; + int stride = NUM_THREADS; + + // TIMER START + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + + // DECLAR DEVICE AND HOST vars in params + + // BEGIN DSL PARSING + int *d_nodeId; + d_nodeId = malloc_device(V, Q); + + int *d_color; + d_color = malloc_device(V, Q); + + bool *d_isMSTEdge; + d_isMSTEdge = malloc_device(E, Q); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < V; i += stride) d_nodeId[i] = (int)-1; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < V; i += stride) d_color[i] = (int)-1; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < E; i += stride) d_isMSTEdge[i] = (bool)false; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> u) + {for (; u < V; u += NUM_THREADS){ // BEGIN KER FUN via ADDKERNEL +d_nodeId[u] = d_nodeId[u]+ u + 1; +d_color[u] = d_color[u]+ u + 1; +} }); }) + .wait(); // end KER FUNC + + bool *d_modified; + d_modified = malloc_device(V, Q); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified[i] = (bool)false; }); }) + .wait(); + + bool noNewComp = false; // asst in main + + // FIXED POINT variables + // BEGIN FIXED POINT + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified_next[i] = false; }); }) + .wait(); + + while (!noNewComp) + { + + noNewComp = true; + bool *d_noNewComp = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.memcpy(d_noNewComp, &noNewComp, 1 * sizeof(bool)); }) + .wait(); + + int *d_minEdge; + d_minEdge = malloc_device(V, Q); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_minEdge[i] = (int)-1; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> src) + {for (; src < V; src += NUM_THREADS){ // BEGIN KER FUN via ADDKERNEL +// for all else part +for (int edge = d_meta[src]; edge < d_meta[src+1]; edge++) { // FOR NBR ITR +int dst = d_data[edge]; +if (d_color[src] != d_color[dst]){ // if filter begin +int e = edge; +int minEdge = d_minEdge[src]; +if (minEdge == -1){ // if filter begin +d_minEdge[src] = e; + +} // if filter end +if (minEdge != -1){ // if filter begin +int minDst = d_data[minEdge]; +if (d_weight[e] < d_weight[minEdge] || (d_weight[e] == d_weight[minEdge] && d_color[dst] < d_color[minDst])){ // if filter begin +d_minEdge[src] = e; + +} // if filter end + +} // if filter end + +} // if filter end + +} // end FOR NBR ITR. TMP FIX! +} }); }) + .wait(); // end KER FUNC + + int *d_minEdgeOfComp; + d_minEdgeOfComp = malloc_device(V, Q); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_minEdgeOfComp[i] = (int)-1; }); }) + .wait(); + + bool finishedMinEdge = false; // asst in main + + // FIXED POINT variables + // BEGIN FIXED POINT + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified_next[i] = false; }); }) + .wait(); + + while (!finishedMinEdge) + { + + finishedMinEdge = true; + bool *d_finishedMinEdge = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.memcpy(d_finishedMinEdge, &finishedMinEdge, 1 * sizeof(bool)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> u) + {for (; u < V; u += NUM_THREADS){ // BEGIN KER FUN via ADDKERNEL +int comp = d_color[u]; // asst in main + +int minEdge = d_minEdgeOfComp[comp]; // asst in main + +int e = d_minEdge[u]; // asst in main + +if (e != -1){ // if filter begin +int dst = d_data[e]; // asst in main + +if (minEdge == -1){ // if filter begin +d_minEdgeOfComp[comp] = e; +*d_finishedMinEdge = false; + +} // if filter end +if (minEdge != -1){ // if filter begin +int minDst = d_data[minEdge]; +if (d_weight[e] < d_weight[minEdge] || (d_weight[e] == d_weight[minEdge] && d_color[dst] < d_color[minDst])){ // if filter begin +d_minEdgeOfComp[comp] = e; +*d_finishedMinEdge = false; + +} // if filter end + +} // if filter end + +} // if filter end +} }); }) + .wait(); // end KER FUNC + + Q.submit([&](handler &h) + { h.memcpy(&finishedMinEdge, d_finishedMinEdge, 1 * sizeof(bool)); }) + .wait(); + + Q.submit([&](handler &h) + { h.memcpy(&finishedMinEdge, d_finishedMinEdge, 1 * sizeof(bool)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified[i] = d_modified_next[i]; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified_next[i] = false; }); }) + .wait(); + + } // END FIXED POINT + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> src) + {for (; src < V; src += NUM_THREADS){ // BEGIN KER FUN via ADDKERNEL +if (d_color[src] == d_nodeId[src]){ // if filter begin +int srcMinEdge = d_minEdgeOfComp[src]; +if (srcMinEdge != -1){ // if filter begin +int dst = d_data[srcMinEdge]; +int dstLead = d_color[dst]; +int dstMinEdge = d_minEdgeOfComp[dstLead]; +if (dstMinEdge != -1){ // if filter begin +int dstOfDst = d_data[dstMinEdge]; +int dstOfDstLead = d_color[dstOfDst]; +if (d_color[src] == d_color[dstOfDstLead] && d_color[src] > d_color[dstLead]){ // if filter begin +d_minEdgeOfComp[dstLead] = -1; + +} // if filter end + +} // if filter end + +} // if filter end + +} // if filter end +} }); }) + .wait(); // end KER FUNC + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> src) + {for (; src < V; src += NUM_THREADS){ // BEGIN KER FUN via ADDKERNEL +if (d_color[src] == d_nodeId[src]){ // if filter begin +int srcMinEdge = d_minEdgeOfComp[src]; +if (srcMinEdge != -1){ // if filter begin +d_isMSTEdge[srcMinEdge] = true; + +} // if filter end + +} // if filter end +} }); }) + .wait(); // end KER FUNC + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> src) + {for (; src < V; src += NUM_THREADS){ // BEGIN KER FUN via ADDKERNEL +if (d_color[src] == d_nodeId[src]){ // if filter begin +int srcMinEdge = d_minEdgeOfComp[src]; +if (srcMinEdge != -1){ // if filter begin +*d_noNewComp = false; +int dst = d_data[srcMinEdge]; +d_color[src] = d_color[dst]; + +} // if filter end + +} // if filter end +} }); }) + .wait(); // end KER FUNC + + Q.submit([&](handler &h) + { h.memcpy(&noNewComp, d_noNewComp, 1 * sizeof(bool)); }) + .wait(); + + bool finished = false; // asst in main + + // FIXED POINT variables + // BEGIN FIXED POINT + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified_next[i] = false; }); }) + .wait(); + + while (!finished) + { + + finished = true; + bool *d_finished = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.memcpy(d_finished, &finished, 1 * sizeof(bool)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> u) + {for (; u < V; u += NUM_THREADS){ // BEGIN KER FUN via ADDKERNEL +int my_color = d_color[u]; // asst in main + +int other_color = d_color[my_color]; // asst in main + +if (my_color != other_color){ // if filter begin +*d_finished = false; +d_color[u] = other_color; + +} // if filter end +} }); }) + .wait(); // end KER FUNC + + Q.submit([&](handler &h) + { h.memcpy(&finished, d_finished, 1 * sizeof(bool)); }) + .wait(); + + Q.submit([&](handler &h) + { h.memcpy(&finished, d_finished, 1 * sizeof(bool)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified[i] = d_modified_next[i]; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified_next[i] = false; }); }) + .wait(); + + } // END FIXED POINT + + // free up!! all propVars in this BLOCK! + free(d_minEdgeOfComp, Q); + free(d_minEdge, Q); + + Q.submit([&](handler &h) + { h.memcpy(&noNewComp, d_noNewComp, 1 * sizeof(bool)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified[i] = d_modified_next[i]; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified_next[i] = false; }); }) + .wait(); + + } // END FIXED POINT + + bool *h_isMSTEdge; + h_isMSTEdge = (bool *)malloc((E) * sizeof(bool)); + Q.submit([&](handler &h) + { h.memcpy(h_isMSTEdge, d_isMSTEdge, sizeof(bool) * (E)); }) + .wait(); + + long long mst = 0; + for (int i = 0; i < E; i++) + { + if (h_isMSTEdge[i] == true) + mst += h_weight[i]; + } + printf("MST Weight: %lld\n", mst); + + // cudaFree up!! all propVars in this BLOCK! + free(d_isMSTEdge, Q); + free(d_modified, Q); + free(d_color, Q); + free(d_nodeId, Q); + + // TIMER STOP + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + std::cout << "Time required: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + +} // end FUN + +int main(int argc, char **argv) +{ + char *inp = argv[1]; + bool isWeighted = atoi(argv[2]) ? true : false; + printf("Taking input from: %s\n", inp); + graph g(inp); + g.parseGraph(); + Boruvka(g); + return 0; +} +#endif \ No newline at end of file diff --git a/graphcode/generated_sycl/sssp_dslV2.cpp b/graphcode/generated_sycl/sssp_dslV2.cpp new file mode 100644 index 00000000..c5a1276d --- /dev/null +++ b/graphcode/generated_sycl/sssp_dslV2.cpp @@ -0,0 +1,212 @@ +#ifndef GENCPP_SSSP_DSLV2_H +#define GENCPP_SSSP_DSLV2_H +#include +#include +#include +#include "../graph.hpp" +using namespace sycl; + +void Compute_SSSP(graph &g, int *dist, int *weight, int src) +{ + queue Q(default_selector_v); + std::cout << "Selected device: " << Q.get_device().get_info() << std::endl; + // CSR BEGIN + int V = g.num_nodes(); + int E = g.num_edges(); + + printf("#nodes:%d\n", V); + printf("#edges:%d\n", E); + int *edgeLen = g.getEdgeLen(); + + int *h_meta; + int *h_data; + int *h_src; + int *h_weight; + int *h_rev_meta; + + h_meta = (int *)malloc((V + 1) * sizeof(int)); + h_data = (int *)malloc((E) * sizeof(int)); + h_src = (int *)malloc((E) * sizeof(int)); + h_weight = (int *)malloc((E) * sizeof(int)); + h_rev_meta = (int *)malloc((V + 1) * sizeof(int)); + + for (int i = 0; i <= V; i++) + { + int temp = g.indexofNodes[i]; + h_meta[i] = temp; + temp = g.rev_indexofNodes[i]; + h_rev_meta[i] = temp; + } + + for (int i = 0; i < E; i++) + { + int temp = g.edgeList[i]; + h_data[i] = temp; + temp = g.srcList[i]; + h_src[i] = temp; + temp = edgeLen[i]; + h_weight[i] = temp; + } + + int *d_meta; + int *d_data; + int *d_src; + int *d_weight; + int *d_rev_meta; + bool *d_modified_next; + + d_meta = malloc_device((1 + V), Q); + d_data = malloc_device((E), Q); + d_src = malloc_device((E), Q); + d_weight = malloc_device((E), Q); + d_rev_meta = malloc_device((V + 1), Q); + d_modified_next = malloc_device((V), Q); + + Q.submit([&](handler &h) + { h.memcpy(d_meta, h_meta, sizeof(int) * (V + 1)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_data, h_data, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_src, h_src, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_weight, h_weight, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_rev_meta, h_rev_meta, sizeof(int) * ((V + 1))); }) + .wait(); + + // CSR END + // LAUNCH CONFIG + int NUM_THREADS = 1048576; + int stride = NUM_THREADS; + + // TIMER START + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + + // DECLAR DEVICE AND HOST vars in params + int *d_dist; + d_dist = malloc_device(V, Q); + + int *d_weight; + d_weight = malloc_device(E, Q); + + // BEGIN DSL PARSING + bool *d_modified; + d_modified = malloc_device(V, Q); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < V; i += stride) d_dist[i] = (int)INT_MAX; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < V; i += stride) d_modified[i] = (bool)false; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.single_task([=]() + { d_modified[src] = (bool)true; }); }) + .wait(); // InitIndexDevice + + Q.submit([&](handler &h) + { h.single_task([=]() + { d_dist[src] = (int)0; }); }) + .wait(); // InitIndexDevice + + bool finished = false; // asst in main + + // FIXED POINT variables + // BEGIN FIXED POINT + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified_next[i] = false; }); }) + .wait(); + + while (!finished) + { + + finished = true; + bool *d_finished = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.memcpy(d_finished, &finished, 1 * sizeof(bool)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> v) + {for (; v < V; v += NUM_THREADS){ // BEGIN KER FUN via ADDKERNEL +if (d_modified[v] == true){ // if filter begin +// for all else part +for (int edge = d_meta[v]; edge < d_meta[v+1]; edge++) { // FOR NBR ITR +int nbr = d_data[edge]; +int e = edge; + int dist_new = d_dist[v] + d_weight[e]; +bool modified_new = true; +if(d_dist[v]!= INT_MAX && d_dist[nbr] > dist_new) +{ + atomic_ref atomic_data(d_dist[nbr]); + atomic_data.fetch_min(dist_new); + d_modified_next[nbr] = modified_new; + *d_finished = false ; +} + +} // end FOR NBR ITR. TMP FIX! + +} // if filter end +} }); }) + .wait(); // end KER FUNC + + Q.submit([&](handler &h) + { h.memcpy(&finished, d_finished, 1 * sizeof(bool)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified[i] = d_modified_next[i]; }); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { +for (; i < V; i += stride) d_modified_next[i] = false; }); }) + .wait(); + + } // END FIXED POINT + + // free up!! all propVars in this BLOCK! + free(d_modified, Q); + + // TIMER STOP + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + std::cout << "Time required: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + Q.submit([&](handler &h) + { h.memcpy(dist, d_dist, sizeof(int) * (V)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(weight, d_weight, sizeof(int) * (E)); }) + .wait(); + for (int i = 0; i < V; i++) + std::cout << i << " " << dist[i] << std::endl; + // std::cout << "Number of rounds required for convergence: " << k << std::endl; + +} // end FUN + +int main(int argc, char **argv) +{ + graph G1(argv[1]); + G1.parseGraph(true); + int src = atoi(argv[2]); + int *dist; + dist = (int *)malloc(G1.num_nodes() * sizeof(int)); + Compute_SSSP(G1, dist, src); + return 0; +} +#endif diff --git a/graphcode/generated_sycl/triangle_count_dsl.cpp b/graphcode/generated_sycl/triangle_count_dsl.cpp new file mode 100644 index 00000000..5715bdd0 --- /dev/null +++ b/graphcode/generated_sycl/triangle_count_dsl.cpp @@ -0,0 +1,147 @@ +#ifndef GENCPP_TRIANGLE_COUNT_DSL_H +#define GENCPP_TRIANGLE_COUNT_DSL_H +#include +#include +#include +#include "../graph.hpp" +using namespace sycl; + +void Compute_TC(graph &g) +{ + queue Q(default_selector_v); + std::cout << "Selected device: " << Q.get_device().get_info() << std::endl; + // CSR BEGIN + int V = g.num_nodes(); + int E = g.num_edges(); + + printf("#nodes:%d\n", V); + printf("#edges:%d\n", E); + int *edgeLen = g.getEdgeLen(); + + int *h_meta; + int *h_data; + int *h_src; + int *h_weight; + int *h_rev_meta; + + h_meta = (int *)malloc((V + 1) * sizeof(int)); + h_data = (int *)malloc((E) * sizeof(int)); + h_src = (int *)malloc((E) * sizeof(int)); + h_weight = (int *)malloc((E) * sizeof(int)); + h_rev_meta = (int *)malloc((V + 1) * sizeof(int)); + + for (int i = 0; i <= V; i++) + { + int temp = g.indexofNodes[i]; + h_meta[i] = temp; + temp = g.rev_indexofNodes[i]; + h_rev_meta[i] = temp; + } + + for (int i = 0; i < E; i++) + { + int temp = g.edgeList[i]; + h_data[i] = temp; + temp = g.srcList[i]; + h_src[i] = temp; + temp = edgeLen[i]; + h_weight[i] = temp; + } + + int *d_meta; + int *d_data; + int *d_src; + int *d_weight; + int *d_rev_meta; + bool *d_modified_next; + + d_meta = malloc_device((1 + V), Q); + d_data = malloc_device((E), Q); + d_src = malloc_device((E), Q); + d_weight = malloc_device((E), Q); + d_rev_meta = malloc_device((V + 1), Q); + d_modified_next = malloc_device((V), Q); + + Q.submit([&](handler &h) + { h.memcpy(d_meta, h_meta, sizeof(int) * (V + 1)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_data, h_data, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_src, h_src, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_weight, h_weight, sizeof(int) * (E)); }) + .wait(); + Q.submit([&](handler &h) + { h.memcpy(d_rev_meta, h_rev_meta, sizeof(int) * ((V + 1))); }) + .wait(); + + // CSR END + // LAUNCH CONFIG + int NUM_THREADS = 1048576; + int stride = NUM_THREADS; + + // TIMER START + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + + // DECLAR DEVICE AND HOST vars in params + + // BEGIN DSL PARSING + long triangle_count = 0; // asst in main + + long *d_triangle_count = malloc_device(1, Q); + Q.submit([&](handler &h) + { h.memcpy(d_triangle_count, &triangle_count, 1 * sizeof(long)); }) + .wait(); + + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> v) + {for (; v < V; v += NUM_THREADS){ // BEGIN KER FUN via ADDKERNEL + // for all else part + for (int edge = d_meta[v]; edge < d_meta[v+1]; edge++) { // FOR NBR ITR + int u = d_data[edge]; + if (u < v){ // if filter begin + // for all else part + for (int edge = d_meta[v]; edge < d_meta[v+1]; edge++) { // FOR NBR ITR + int w = d_data[edge]; + if (w > v){ // if filter begin + if (findNeighborSorted(u, w, d_meta, d_data)){ // if filter begin + atomic_ref atomic_data(d_triangle_count[0]); + atomic_data += 1; + + } // if filter end + + } // if filter end + + } // end FOR NBR ITR. TMP FIX! + + } // if filter end + + } // end FOR NBR ITR. TMP FIX! + } }); }) + .wait(); // end KER FUNC + + Q.submit([&](handler &h) + { h.memcpy(&triangle_count, d_triangle_count, 1 * sizeof(long)); }) + .wait(); + + // TIMER STOP + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + std::cout << "Time required: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + std::cout << "Num Triangles = " << triangle_count << std::endl; + +} // end FUN + +int main(int argc, char **argv) +{ + graph G1(argv[1]); + G1.parseGraph(); + int src = 0; + int *dist; + Compute_TC(G1); + return 0; +} +#endif \ No newline at end of file diff --git a/graphcode/graph.hpp b/graphcode/graph.hpp index 0ca14be3..7cd82b2b 100644 --- a/graphcode/graph.hpp +++ b/graphcode/graph.hpp @@ -1,183 +1,176 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include "graph_ompv2.hpp" -//using namespace std; +// using namespace std; class edge { - public: +public: int32_t source; int32_t destination; int32_t weight; int32_t id; /* -unique Id for each edge. -useful in adding properties to edges. */ - int dir; + int dir; }; - - -//bool counter=true; +// bool counter=true; class graph { - private: +private: int32_t nodesTotal; int32_t edgesTotal; - int32_t* edgeLen; - int32_t* diff_edgeLen; - int32_t* rev_edgeLen; - int32_t* diff_rev_edgeLen; - char* filePath; - std::map> edges; - - - public: - int32_t* indexofNodes; /* stores prefix sum for outneighbours of a node*/ - int32_t* rev_indexofNodes; /* stores prefix sum for inneighbours of a node*/ - int32_t* edgeList; /*stores destination corresponding to edgeNo. - required for iteration over out neighbours */ - int32_t* srcList; /*stores source corresponding to edgeNo. - required for iteration over in neighbours */ - std::vector graph_edge; - int32_t* diff_indexofNodes; - int32_t* diff_edgeList; - int32_t* diff_rev_indexofNodes; - int32_t* diff_rev_edgeList; - int32_t* perNodeCSRSpace; - int32_t* perNodeRevCSRSpace; - int32_t* edgeMap; - std::map outDeg; - std::map inDeg; - - graph(char* file) - { - filePath=file; - nodesTotal=0; - edgesTotal=0; + int32_t *edgeLen; + int32_t *diff_edgeLen; + int32_t *rev_edgeLen; + int32_t *diff_rev_edgeLen; + char *filePath; + std::map> edges; + +public: + int32_t *indexofNodes; /* stores prefix sum for outneighbours of a node*/ + int32_t *rev_indexofNodes; /* stores prefix sum for inneighbours of a node*/ + int32_t *edgeList; /*stores destination corresponding to edgeNo. + required for iteration over out neighbours */ + int32_t *srcList; /*stores source corresponding to edgeNo. + required for iteration over in neighbours */ + std::vector graph_edge; + int32_t *diff_indexofNodes; + int32_t *diff_edgeList; + int32_t *diff_rev_indexofNodes; + int32_t *diff_rev_edgeList; + int32_t *perNodeCSRSpace; + int32_t *perNodeRevCSRSpace; + int32_t *edgeMap; + std::map outDeg; + std::map inDeg; + + graph(char *file) + { + filePath = file; + nodesTotal = 0; + edgesTotal = 0; diff_edgeList = NULL; diff_indexofNodes = NULL; diff_rev_indexofNodes = NULL; diff_rev_edgeList = NULL; rev_edgeLen = NULL; - } - - - std::map> getEdges() + std::map> getEdges() { - return edges; + return edges; } - int* getEdgeLen() + int *getEdgeLen() { return edgeLen; } - int num_nodes() + int num_nodes() { - return nodesTotal+1; //change it to nodesToTal + return nodesTotal + 1; // change it to nodesToTal } - int num_edges() - { - if(diff_edgeList !=NULL) - { - return (edgesTotal + diff_indexofNodes[nodesTotal+1]); - } - else - return edgesTotal; + int num_edges() + { + if (diff_edgeList != NULL) + { + return (edgesTotal + diff_indexofNodes[nodesTotal + 1]); + } + else + return edgesTotal; } + std::vector getInOutNbrs(int v) + { - std::vector getInOutNbrs(int v){ - - std::vector resVec; + std::vector resVec; - std::vector inEdges = getInNeighbors(v); - resVec.insert(resVec.end(), inEdges.begin(), inEdges.end()); - std::vector Edges = getNeighbors(v); - resVec.insert(resVec.end(), Edges.begin(), Edges.end()); - - return resVec; + std::vector inEdges = getInNeighbors(v); + resVec.insert(resVec.end(), inEdges.begin(), inEdges.end()); + std::vector Edges = getNeighbors(v); + resVec.insert(resVec.end(), Edges.begin(), Edges.end()); + return resVec; } edge getEdge(int s, int d) + { + + int startEdge = indexofNodes[s]; + int endEdge = indexofNodes[s + 1] - 1; + edge foundEdge; + + for (edge e : getNeighbors(s)) + { + int nbr = e.destination; + if (nbr == d) + { + return e; + } + } + } + + // library function to check candidate vertex is in the path from root to dest in SPT. + bool inRouteFromSource(int candidate, int dest, int *parent) + { + + while (parent[dest] != -1) { + if (parent[dest] == candidate) + return true; - int startEdge=indexofNodes[s]; - int endEdge=indexofNodes[s+1]-1; - edge foundEdge ; - - for ( edge e: getNeighbors(s)) - { - int nbr = e.destination; - if(nbr == d) - { - return e; - } - - } - - + dest = parent[dest]; } + return false; + } - // library function to check candidate vertex is in the path from root to dest in SPT. - bool inRouteFromSource(int candidate, int dest, int* parent) + bool check_if_nbr(int s, int d) { + /*int startEdge=indexofNodes[s]; + int endEdge=indexofNodes[s+1]-1; - while(parent[dest]!=-1) - { - if(parent[dest]==candidate) - return true; + if(edgeList[startEdge]==d) + return true; + if(edgeList[endEdge]==d) + return true; - dest = parent[dest]; - } + int mid; - return false; + while(startEdge<=endEdge) + { + mid = (startEdge+endEdge)/2; - } - + if(edgeList[mid]==d) + return true; + if(d= dest || nbrsCount == 0) + insertAt = startIndex; + else if (edgeList[endIndex - 1] <= dest) + insertAt = endIndex; + else + start = mid + 1; + } + * / + for (edge e : getNeighbors(s)) + { + int nbr = e.destination; + if (nbr == d) + return true; + } - int getOutDegree(int v){ + return false; +} - return outDeg[v]; +int +common_nbrscount(int node1, int node2) +{ + int count = 0; + int a = indexofNodes[node1 + 1]; + int b = indexofNodes[node2 + 1]; + int i = indexofNodes[node1]; + int j = indexofNodes[node2]; + while (i < a && j < b) + { + int n = edgeList[i]; + int m = edgeList[j]; + + if (n == m) + { + i++; + j++; + count++; } + else if (n < m) + i++; + else + j++; + } + + return count; +} - int getInDegree(int v){ - - return inDeg[v]; +void addEdge(int src, int dest) +{ + int startIndex = indexofNodes[src]; + int endIndex = indexofNodes[src + 1]; + int nbrsCount = endIndex - startIndex; + int insertAt = 0; + + if (edgeList[startIndex] >= dest || nbrsCount == 0) + insertAt = startIndex; + else if (edgeList[endIndex - 1] <= dest) + insertAt = endIndex; + else + { + for (int i = startIndex; i < endIndex - 1; i++) // find the correct index to insert. + { + if (edgeList[i] <= dest && edgeList[i + 1] >= dest) + { + insertAt = i + 1; + break; + } } + } - void addEdge(int src, int dest) - { - int startIndex = indexofNodes[src]; - int endIndex = indexofNodes[src+1]; - int nbrsCount = endIndex - startIndex ; - int insertAt = 0; - - if(edgeList[startIndex]>=dest||nbrsCount==0) - insertAt = startIndex; - else if(edgeList[endIndex-1]<=dest) - insertAt = endIndex; - else - { - - for(int i=startIndex;i=dest) - { - insertAt = i+1; - break; - } - } - } - - edgeList = (int32_t*)realloc(edgeList,sizeof(int32_t)*(edgesTotal+1)); - edgeLen = (int32_t*)realloc(edgeLen,sizeof(int32_t)*(edgesTotal+1)); - - for(int i=edgesTotal-1;i>=insertAt;i--) //shift the elements - { - edgeList[i+1] = edgeList[i]; - edgeLen[i+1] = edgeLen[i] ; - //edgeMap[i+1] = edgeMap[i]; - } - - edgeList[insertAt] = dest; - edgeLen[insertAt] = 1; // to be changed. the weight should be from paramters. - - //update the CSR offset array. - #pragma omp parallel for - for(int i=src+1;i<=nodesTotal+1;i++) - { - indexofNodes[i]+=1; - } - - edge newEdge; - newEdge.source = src; - newEdge.destination = dest; - edges[src].push_back(newEdge); - edgesTotal++; - - } - - void delEdge(int src, int dest) - { - int startEdge=indexofNodes[src]; - int endEdge=indexofNodes[src+1]-1; - int mid ; - - while(startEdge<=endEdge) - { - mid = (startEdge+endEdge)/2; + edgeList = (int32_t *)realloc(edgeList, sizeof(int32_t) * (edgesTotal + 1)); + edgeLen = (int32_t *)realloc(edgeLen, sizeof(int32_t) * (edgesTotal + 1)); - if(edgeList[mid]==dest) - break; - - if(dest= insertAt; i--) // shift the elements + { + edgeList[i + 1] = edgeList[i]; + edgeLen[i + 1] = edgeLen[i]; + // edgeMap[i+1] = edgeMap[i]; + } - while(startEdge<=endEdge) - { - mid = (startEdge+endEdge)/2; + edgeList[insertAt] = dest; + edgeLen[insertAt] = 1; // to be changed. the weight should be from paramters. - if(srcList[mid]==src) - break; - - if(src parseUpdates(char* updateFile) - { + if (edgeList[mid] == dest) + break; - std::vector update_vec = parseUpdateFile(updateFile); - return update_vec; - - } + if (dest < edgeList[mid]) + endEdge = mid - 1; + else + startEdge = mid + 1; + } - std::vector getDeletesFromBatch(int updateIndex, int batchSize, std::vector updateVec) - { - std::vector deleteVec = getDeletions(updateIndex, batchSize, updateVec); - return deleteVec; - } - - std::vector getAddsFromBatch(int updateIndex, int batchSize, std::vector updateVec) + /* int startEdge=rev_indexofNodes[dest]; + int endEdge=rev_indexofNodes[dest+1]-1; + int mid ; + + while(startEdge<=endEdge) + { + mid = (startEdge+endEdge)/2; + + if(srcList[mid]==src) + break; + + if(src parseUpdates(char *updateFile) +{ + + std::vector update_vec = parseUpdateFile(updateFile); + return update_vec; +} + +std::vector getDeletesFromBatch(int updateIndex, int batchSize, std::vector updateVec) +{ + std::vector deleteVec = getDeletions(updateIndex, batchSize, updateVec); + return deleteVec; +} + +std::vector getAddsFromBatch(int updateIndex, int batchSize, std::vector updateVec) +{ + std::vector addVec = getAdditions(updateIndex, batchSize, updateVec); + return addVec; +} + +void propagateNodeFlags(bool *modified) +{ + + bool finished = false; + while (!finished) { - std::vector addVec = getAdditions(updateIndex, batchSize, updateVec); - return addVec; - - } + finished = true; - void propagateNodeFlags(bool* modified){ - - bool finished = false; - while (!finished) - { - finished = true; - - for(int v = 0 ; v <= nodesTotal ; v++) + for (int v = 0; v <= nodesTotal; v++) for (edge e : getNeighbors(v)) { if (!modified[e.destination]) @@ -393,438 +423,401 @@ class graph finished = false; } } - } - } +} - +void parseEdges() +{ + // printf("OH HELLOHIHod \n"); + std::ifstream infile; + infile.open(filePath); + std::string line; - void parseEdges() + while (std::getline(infile, line)) { - //printf("OH HELLOHIHod \n"); - std::ifstream infile; - infile.open(filePath); - std::string line; + // std::stringstream(line); + if (line.length() == 0 || line[0] < '0' || line[0] > '9') + { + continue; + } + std::stringstream ss(line); + edgesTotal++; - while (std::getline(infile,line)) - { + // edgesTotal++; //TO BE REMOVED - // std::stringstream(line); + // edgesTotal++; //TO BE REMOVED - if (line.length()==0||line[0] < '0' || line[0] >'9') { - continue; + edge e; - } + int32_t source; + int32_t destination; + int32_t weightVal = 1; - std::stringstream ss(line); + ss >> source; + if (source > nodesTotal) + nodesTotal = source; - edgesTotal++; - - //edgesTotal++; //TO BE REMOVED + ss >> destination; + if (destination > nodesTotal) + nodesTotal = destination; - //edgesTotal++; //TO BE REMOVED + ss >> weightVal; // for edgelists having weight too. + e.source = source; + e.destination = destination; + e.weight = weightVal; + edges[source].push_back(e); + graph_edge.push_back(e); - edge e; - - - int32_t source; - int32_t destination; - int32_t weightVal; - - ss>>source; - if(source>nodesTotal) - nodesTotal=source; - - ss>>destination; - if(destination>nodesTotal) - nodesTotal=destination; - - ss>>weightVal; //for edgelists having weight too. - e.source=source; - e.destination=destination; - e.weight=weightVal; - - edges[source].push_back(e); - graph_edge.push_back(e); - - - ss>>weightVal; //for edgelists having weight too. - - } - - - - infile.close(); - - - } + ss >> weightVal; // for edgelists having weight too. + } + infile.close(); +} + +void parseGraph(bool isWeighted = false) +{ + + parseEdges(isWeighted); + + printf("Here half\n"); +// printf("HELLO AFTER THIS %d \n",nodesTotal); +#pragma omp parallel for + for (int i = 0; i <= nodesTotal; i++) // change to 1-nodesTotal. + { + std::vector &edgeOfVertex = edges[i]; - - void parseGraph() - { - - - parseEdges(); - - printf("Here half\n"); - //printf("HELLO AFTER THIS %d \n",nodesTotal); - #pragma omp parallel for - for(int i=0;i<=nodesTotal;i++)//change to 1-nodesTotal. - { - std::vector& edgeOfVertex=edges[i]; - - sort(edgeOfVertex.begin(),edgeOfVertex.end(), - [](const edge& e1,const edge& e2) { - if(e1.source!=e2.source) - return e1.source edgeofVertex = edges[i]; + + indexofNodes[i] = edge_no; + + std::vector::iterator itr; + + for (itr = edgeofVertex.begin(); itr != edgeofVertex.end(); itr++) { - std::vector edgeofVertex=edges[i]; - indexofNodes[i]=edge_no; + edgeList[edge_no] = (*itr).destination; - std::vector::iterator itr; + edgeLen[edge_no] = (*itr).weight; + edge_no++; + } - for(itr=edgeofVertex.begin();itr!=edgeofVertex.end();itr++) - { + perNodeCSRSpace[i] = 0; + perNodeRevCSRSpace[i] = 0; + } + indexofNodes[nodesTotal + 1] = edge_no; // change to nodesTotal+1. - edgeList[edge_no]=(*itr).destination; +#pragma omp parallel for num_threads(4) + for (int i = 0; i < nodesTotal + 1; i++) + rev_indexofNodes[i] = 0; - edgeLen[edge_no]=(*itr).weight; - edge_no++; - } + /* Prefix Sum computation for in neighbours + Loads rev_indexofNodes and srcList. + */ - perNodeCSRSpace[i] = 0; - perNodeRevCSRSpace[i] = 0; - + /* count indegrees first */ + int32_t *edge_indexinrevCSR = new int32_t[edgesTotal]; + +#pragma omp parallel for num_threads(4) + for (int i = 0; i <= nodesTotal; i++) + { + + for (int j = indexofNodes[i]; j < indexofNodes[i + 1]; j++) + { + int dest = edgeList[j]; + int temp = __sync_fetch_and_add(&rev_indexofNodes[dest], 1); + edge_indexinrevCSR[j] = temp; } + } - - indexofNodes[nodesTotal+1]=edge_no;//change to nodesTotal+1. - - - #pragma omp parallel for num_threads(4) - for(int i=0;i vect; + vect.insert(vect.begin(), srcList + rev_indexofNodes[i], srcList + rev_indexofNodes[i + 1]); + std::sort(vect.begin(), vect.end()); + for (int j = 0; j < vect.size(); j++) + srcList[j + rev_indexofNodes[i]] = vect[j]; + int srcListIndex; + + for (int j = 0; j < vect.size(); j++) + { + srcListIndex = j + rev_indexofNodes[i]; + for (int k = 0; k < vect.size(); k++) + { + if (vertexInter[k + rev_indexofNodes[i]] == srcList[srcListIndex]) { - for(int j=indexofNodes[i];j vect; - vect.insert(vect.begin(),srcList+rev_indexofNodes[i],srcList+rev_indexofNodes[i+1]); - std::sort(vect.begin(),vect.end()); - for(int j=0;j& batchUpdate, int k, int size) + void updateCSRDel(std::vector & batchUpdate, int k, int size) { int num_nodes = nodesTotal + 1; - std::vector> perNodeUpdateInfo; - std::vector> perNodeUpdateRevInfo; + std::vector> perNodeUpdateInfo; + std::vector> perNodeUpdateRevInfo; std::vector slicedUpdates; - if(rev_edgeLen==NULL) - rev_edgeLen = new int[edgesTotal]; - for(int i=0;i& batchUpdate, int k, int size) + void updateCSRAdd(std::vector & batchUpdate, int k, int size) { int num_nodes = nodesTotal + 1; - std::vector> perNodeUpdateInfo; - std::vector> perNodeUpdateRevInfo; + std::vector> perNodeUpdateInfo; + std::vector> perNodeUpdateRevInfo; std::vector slicedUpdates; - - for(int i=0;i getNeighbors(int node) + { + std::vector out_edges; + std::vector getNeighbors(int node) + { -std::vector getNeighbors( int node) - { - - std::vector out_edges; + std::vector out_edges; - for(int i=indexofNodes[node]; i getInNeighbors(int node) + { - std::vector getInNeighbors( int node) - { - - std::vector in_edges; + std::vector in_edges; - for(int i=rev_indexofNodes[node]; i getNeighbors( int node) in_edges.push_back(e); e.dir = 0; } + } + } + } + + if (diff_edgeList != NULL) + { + for (int j = diff_indexofNodes[node]; j < diff_indexofNodes[node + 1]; j++) + { + int nbr = diff_edgeList[j]; + if (nbr != INT_MAX / 2) + { + edge e; + e.source = node; + e.destination = nbr; + e.weight = diff_edgeLen[j]; + e.id = edgesTotal + j; + // printf(" weight %d\n", e.weight); + out_edges.push_back(e); + } + } + } + + return out_edges; + } - } + for (int i = rev_indexofNodes[node]; i < rev_indexofNodes[node + 1]; i++) + { + int nbr = srcList[i]; + if (nbr != INT_MAX / 2) + { + edge e; + e.source = node; + e.destination = nbr; + e.weight = rev_edgeLen[i]; + in_edges.push_back(e); + } + } + if (diff_rev_edgeList != NULL) + { + for (int j = diff_rev_indexofNodes[node]; j < diff_rev_indexofNodes[node + 1]; j++) + { + int nbr = diff_rev_edgeList[j]; + if (nbr != INT_MAX / 2) + { + edge e; + e.source = node; + e.destination = nbr; + e.weight = diff_rev_edgeLen[j]; + in_edges.push_back(e); } - - return in_edges; - + } } -}; + return in_edges; +} +} +; + +bool findNeighborSorted(int s, int d, int *d_meta, int *d_data) // we can move this to graph.hpp file +{ + int startEdge = d_meta[s]; + int endEdge = d_meta[s + 1] - 1; + + if (d_data[startEdge] == d) + return true; + if (d_data[endEdge] == d) + return true; + + int mid = (startEdge + endEdge) / 2; + + while (startEdge <= endEdge) + { + if (d_data[mid] == d) + return true; + + if (d < d_data[mid]) + endEdge = mid - 1; + else + startEdge = mid + 1; + + mid = (startEdge + endEdge) / 2; + } + + return false; +} \ No newline at end of file diff --git a/graphcode/manual_sycl/README.md b/graphcode/manual_sycl/README.md new file mode 100644 index 00000000..c0c5d53f --- /dev/null +++ b/graphcode/manual_sycl/README.md @@ -0,0 +1,83 @@ +# Graph Algorithms Framework in SYCL + +A large number of problems in the real world can be modelled as graph algorithms, for example, social networks, road connections, molecular interactions, planetary forces, etc. The execution time required for these algorithms is considerable for large graphs. They can be parallelised and sped up using GPUs. Once an algorithm is implemented for a specific backend, e.g. Nvidia GPUs in CUDA, it is not possible to run the same implementation of the algorithm on other GPUs like AMD or Intel. This is a problem as the same algorithm needs to be implemented and optimised in different languages depending on the available hardware to get the best performance. + +* To enable the platform portability of graph algorithms by implementing them in SYCL. +* To optimise the SYCL code and compare the performance on large graphs with existing implementations. +* To create a framework that enables implementing graph algorithms quickly, hiding the complexities of SYCL syntax. +* To implement the following graph algorithms: single source shortest path, betweenness centrality, pagerank, minimum spanning tree, and triangle count using the developed framework. + +[DPC++](https://github.com/intel/llvm), Intel's implementation of SYCL has been used in this project. + + +## Installation Instructions + +1. Clone the repo. +2. Install SYCL locally: [Steps](https://intel.github.io/llvm-docs/GetStartedGuide.html#install-low-level-runtime) or Use [devcloud](). +3. Follow the relevant steps to compile the programs. +4. You can include the file `graph.h` in your custom applications to use the framework. + +## Converting graphs to CSR format +Use the `csr.py` script to convert a raw graph, represented as edge list, into CSR format. + +Use the following command: +`python3 csr.py {graph-name}` + +to convert a raw graph stored at the location `raw_graphs/{graph-name}.txt` into the CSR format. The output files(V, I, E, W, RI, RE) are stored inside the folder `csr_graphs/{graph-name}`. + +## Single source shortest path + +Implemented using two methods: +1. [Topology driven](https://github.com/PrasannaIITM/Graph-Algorithms-Framework-In-SYCL/blob/main/single_source_shortest_path/sssp_vtop.cpp) +2. [Data driven](https://github.com/PrasannaIITM/Graph-Algorithms-Framework-In-SYCL/blob/main/single_source_shortest_path/sssp_vdp.cpp) + +After compiling the required file, use the following command to run the program: + `./[executable] [graph-name] [source-vertex-id] [num-parallel-workers]` + +The results and timing information are stored in `single_source_shortest_path/output` folder in the files `{graph-name}_sssp_{method}_results_{num-parallel-workers}.txt` and `{graph-name}_sssp_{method}_time_{num-parallel-workers}.txt` respectively. + +## Betweenness centrality +Implemented using two methods: + +1. [Vertex Parallel](https://github.com/PrasannaIITM/Graph-Algorithms-Framework-In-SYCL/blob/main/betweenness_centrality/bc_vp.cpp) +2. [Work Efficient](https://github.com/PrasannaIITM/Graph-Algorithms-Framework-In-SYCL/blob/main/betweenness_centrality/bc_we.cpp) + +After compiling the required file, use the following command to run the program: + `./[executable] [graph-name] [num-parallel-workers] [num-sources] [path-to-sources-file]` + +The results and timing information are stored in `betweenness_centrality/output` folder in the files `{graph-name}_{num-sources}_bc_{method}_results_{num-parallel-workers}.txt` and `{graph-name}_{num-sources}_bc_{method}_time_{num-parallel-workers}.txt` respectively. + +## Pagerank +Implemented using the pull-based approach. + +[Code](https://github.com/PrasannaIITM/Graph-Algorithms-Framework-In-SYCL/blob/main/pagerank/pr_pull.cpp) + +After compiling, use the following command to run the program: +`./[executable] [graph-name] [num-parallel-workers]` + +The results and timing information are stored in `pagerank/output` folder in the files `{graph-name}_pr_pull_results_{num-parallel-workers}.txt` and `{graph-name}_pr_pull_time_{num-parallel-workers}.txt` respectively. + + +## Minimum Spanning Tree +Implemented using the parallel version of Borvuka's algorithm. + +[Code](https://github.com/PrasannaIITM/Graph-Algorithms-Framework-In-SYCL/blob/main/min_spanning_tree/mst_vb.cpp) + +After compiling, use the following command to run the program: +`./[executable] [graph-name] [num-parallel-workers]` + +The results and timing information are stored in `min_spanning_tree/output` folder in the files `{graph-name}_mst_vb_results_{num-parallel-workers}.txt` and `{graph-name}_mst_vb_time_{num-parallel-workers}.txt` respectively. + +## Triangle count +Simple parallel approach optimised by storing edges in sorted order in CSR to find if two edges are connected in O(log(outdegree)) time using binary search. + +[Code](https://github.com/PrasannaIITM/Graph-Algorithms-Framework-In-SYCL/blob/main/triangle_count/tc_bs.cpp) + +After compiling, use the following command to run the program: +`./[executable] [graph-name] [num-parallel-workers]` + +The results and timing information are stored in `triangle_count/output` folder in the files `{graph-name}_tc_bs_results_{num-parallel-workers}.txt` and `{graph-name}_tc_bs_time_{num-parallel-workers}.txt` respectively. + +## Poster + +![](https://github.com/PrasannaIITM/Graph-Algorithms-Framework-In-SYCL/blob/main/poster.png?raw=true) diff --git a/graphcode/manual_sycl/betweenness_centrality/bc_vp.cpp b/graphcode/manual_sycl/betweenness_centrality/bc_vp.cpp new file mode 100644 index 00000000..3b3deaa6 --- /dev/null +++ b/graphcode/manual_sycl/betweenness_centrality/bc_vp.cpp @@ -0,0 +1,166 @@ +#include +#include +#include +#define DEBUG 0 +#include "../graph.h" +using namespace sycl; + +int main(int argc, char **argv) +{ + std::chrono::steady_clock::time_point tic_0 = std::chrono::steady_clock::now(); + std::ofstream logfile; + + std::string name = argv[1]; + int NUM_THREADS = atoi(argv[2]); + int sSize = atoi(argv[3]); + std::string str_sSize = std::to_string(sSize); + std::vector sourceSet; + + std::ifstream input("betweenness_centrality/sources/" + name + "/" + str_sSize); + int num; + while ((input >> num)) + { + sourceSet.push_back(num); + } + input.close(); + + std::string NUM_THREADS_STR = std::to_string(NUM_THREADS); + + logfile.open("betweenness_centrality/output/" + name + "_" + str_sSize + "_bc_vp_f_time_" + NUM_THREADS_STR + ".txt"); + + logfile << "Processing " << name << std::endl; + default_selector d_selector; + queue Q(d_selector); + logfile << "Selected device: " << Q.get_device().get_info() << std::endl; + logfile << "Number of parallel work items: " << NUM_THREADS << std::endl; + + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + graph *g = malloc_shared(1, Q); + g->load_graph(name, Q); + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + logfile << "Time to load data from files: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + int N = g->get_num_nodes(); + int stride = NUM_THREADS; + + std::vector bc(N); + + float *dev_bc = malloc_device(bc.size(), Q); + Q.submit([&](handler &h) + { h.parallel_for( + NUM_THREADS, [=](id<1> v) + { + for (; v < N; v += stride) + { + dev_bc[v] = 0; + } }); }) + .wait(); + float *dev_delta = malloc_device(N, Q); + + int *dev_d = malloc_device(N, Q); + int *dev_sigma = malloc_device(N, Q); + + tic = std::chrono::steady_clock::now(); + logfile << "Starting betweenness centrality calculation..." << std::endl; + + int *S = malloc_shared(N, Q); + int *ends = malloc_shared(N, Q); + int *position = malloc_shared(1, Q); + int *s = malloc_shared(1, Q); + *s = 0; + int *finish_limit_position = malloc_shared(1, Q); + int *done = malloc_shared(1, Q); + int *current_depth = malloc_shared(1, Q); + + for (auto x : sourceSet) + { + *s = x; + initialize(dev_d, INT_MAX, NUM_THREADS, N, Q, *s, 0); + initialize(dev_sigma, 0, NUM_THREADS, N, Q, *s, 1); + initialize(dev_delta, float(0), NUM_THREADS, N, Q); + + *current_depth = 0; + *done = 0; + *position = 0; + *finish_limit_position = 1; + ends[0] = 0; + + while (!*done) + { + *done = 1; + forall(N, NUM_THREADS) + { + if (dev_d[u] == *current_depth) + { + ATOMIC_INT atomic_data(*position); + int t = atomic_data++; + S[t] = u; + int r; + for_neighbours(u, r) + { + int w = get_neighbour(r); + if (dev_d[w] == INT_MAX) + { + dev_d[w] = dev_d[u] + 1; + *done = 0; + } + + if (dev_d[w] == (dev_d[u] + 1)) + { + ATOMIC_INT atomic_data(dev_sigma[w]); + atomic_data += dev_sigma[u]; + } + } + } + } + end; + *current_depth += 1; + ends[*finish_limit_position] = *position; + ++*finish_limit_position; + } + + for (int itr1 = *finish_limit_position - 1; itr1 >= 0; itr1--) + { + Q.submit([&](handler &h) + { h.parallel_for( + NUM_THREADS, [=](id<1> i) + { + for(int itr2 = ends[itr1] + i; itr2 < ends[itr1 + 1]; itr2 += stride){ + for(int itr3 = g->I[S[itr2]]; itr3 < g->I[S[itr2] + 1]; itr3++){ + int consider = g->E[itr3]; + if(dev_d[consider] == dev_d[S[itr2]] + 1){ + dev_delta[S[itr2]] += (((float)dev_sigma[S[itr2]] / dev_sigma[consider]) * ((float)1 + dev_delta[consider])); + + } + } + + if(S[itr2] != *s){ + dev_bc[S[itr2]] += dev_delta[S[itr2]]; + } + } }); }) + .wait(); + } + } + + toc = std::chrono::steady_clock::now(); + logfile << "Time to run betweenness centrality: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + memcpy(&bc[0], dev_bc, N, Q); + + tic = std::chrono::steady_clock::now(); + std::ofstream resultfile; + + resultfile.open("betweenness_centrality/output/" + name + "_" + str_sSize + "_bc_vp_f_result_" + NUM_THREADS_STR + ".txt"); + + for (int i = 0; i < N; i++) + { + resultfile << i << " " << bc[i] / 2.0 << std::endl; + } + resultfile.close(); + toc = std::chrono::steady_clock::now(); + logfile << "Time to write data to file: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + std::chrono::steady_clock::time_point toc_0 = std::chrono::steady_clock::now(); + logfile << "Total time taken: " << std::chrono::duration_cast(toc_0 - tic_0).count() << "[µs]" << std::endl; + return 0; +} diff --git a/graphcode/manual_sycl/betweenness_centrality/bc_we.cpp b/graphcode/manual_sycl/betweenness_centrality/bc_we.cpp new file mode 100644 index 00000000..8b727794 --- /dev/null +++ b/graphcode/manual_sycl/betweenness_centrality/bc_we.cpp @@ -0,0 +1,191 @@ +#include +#include +#include +#define DEBUG 0 +#include "../graph.h" + +using namespace sycl; + +int main(int argc, char **argv) +{ + + std::chrono::steady_clock::time_point tic_0 = std::chrono::steady_clock::now(); + std::ofstream logfile; + + std::string name = argv[1]; + int NUM_THREADS = atoi(argv[2]); + int sSize = atoi(argv[3]); + std::string str_sSize = std::to_string(sSize); + std::vector sourceSet; + + std::ifstream input("betweenness_centrality/sources/" + name + "/" + str_sSize); + int num; + while ((input >> num)) + { + sourceSet.push_back(num); + } + input.close(); + + std::string NUM_THREADS_STR = std::to_string(NUM_THREADS); + + logfile.open("betweenness_centrality/output/" + name + "_" + str_sSize + "_bc_we_time_" + NUM_THREADS_STR + ".txt"); + + logfile << "Processing " << name << std::endl; + default_selector d_selector; + queue Q(d_selector); + logfile << "Selected device: " << Q.get_device().get_info() << std::endl; + logfile << "Number of parallel work items: " << NUM_THREADS << std::endl; + + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + graph *g = malloc_shared(1, Q); + g->load_graph(name, Q); + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + logfile << "Time to load data from files: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + int N = g->get_num_nodes(); + int stride = NUM_THREADS; + + std::vector bc(N); + + int *dev_d = malloc_device(N, Q); + int *dev_sigma = malloc_device(N, Q); + float *dev_bc = malloc_device(bc.size(), Q); + initialize(dev_bc, float(0), NUM_THREADS, N, Q); + float *dev_delta = malloc_device(N, Q); + + tic = std::chrono::steady_clock::now(); + logfile << "Starting betweenness centrality calculation..." << std::endl; + + int *s = malloc_shared(1, Q); + *s = 0; + + int *q_curr = malloc_shared(N, Q); + int *q_curr_len = malloc_shared(1, Q); + + int *q_next = malloc_shared(N, Q); + int *q_next_len = malloc_shared(1, Q); + + int *S = malloc_shared(N, Q); + int *S_len = malloc_shared(1, Q); + + int *ends = malloc_shared(N, Q); + int *ends_len = malloc_shared(1, Q); + int *depth = malloc_shared(1, Q); + + for (auto x : sourceSet) + { + *s = x; + + initialize(dev_d, INT_MAX, NUM_THREADS, N, Q, *s, 0); + initialize(dev_sigma, 0, NUM_THREADS, N, Q, *s, 1); + initialize(dev_delta, float(0), NUM_THREADS, N, Q); + + q_curr[0] = *s; + *q_curr_len = 1; + *q_next_len = 0; + S[0] = *s; + *S_len = 1; + ends[0] = 0; + ends[1] = 1; + *ends_len = 2; + *depth = 0; + + while (1) + { + forall(*q_curr_len, NUM_THREADS) + { + int v = q_curr[u], v_itr; + for_neighbours(v, v_itr) + { + int w = get_neighbour(v_itr); + + ATOMIC_INT atomic_data(dev_d[w]); + int old = INT_MAX; + old = atomic_data.compare_exchange_strong(old, dev_d[v] + 1); + if (old) + { + ATOMIC_INT atomic_data(*q_next_len); + int t = atomic_data++; + q_next[t] = w; + } + + if (dev_d[w] == dev_d[v] + 1) + { + ATOMIC_INT atomic_data(dev_sigma[w]); + atomic_data += dev_sigma[v]; + } + } + } + end; + + if (*q_next_len == 0) + { + break; + } + else + { + forall(*q_next_len, NUM_THREADS) + { + q_curr[u] = q_next[u]; + S[u + *S_len] = q_next[u]; + } + end; + + ends[*ends_len] = ends[*ends_len - 1] + *q_next_len; + *ends_len += 1; + int new_curr_len = *q_next_len; + *q_curr_len = new_curr_len; + *S_len += new_curr_len; + *q_next_len = 0; + *depth += 1; + } + } + while (*depth >= 0) + { + forall(ends[*depth + 1] - ends[*depth], NUM_THREADS) + { + int tid = u + ends[*depth]; + int w = S[tid]; + int dsw = 0, r; + for_neighbours(w, r) + { + int v = get_neighbour(r); + if (dev_d[v] == dev_d[w] + 1) + { + dev_delta[w] += (((float)dev_sigma[w] / dev_sigma[v]) * ((float)1 + dev_delta[v])); + } + } + if (w != *s) + { + dev_bc[w] += dev_delta[w]; + } + } + end; + + *depth -= 1; + } + } + + logfile << std::endl; + toc = std::chrono::steady_clock::now(); + logfile << "Time to run betweenness centrality: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + memcpy(&bc[0], dev_bc, N, Q); + + tic = std::chrono::steady_clock::now(); + std::ofstream resultfile; + + resultfile.open("betweenness_centrality/output/" + name + "_" + str_sSize + "_bc_we_result_" + NUM_THREADS_STR + ".txt"); + + for (int i = 0; i < N; i++) + { + resultfile << i << " " << bc[i] / 2.0 << std::endl; + } + resultfile.close(); + toc = std::chrono::steady_clock::now(); + logfile << "Time to write data to file: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + std::chrono::steady_clock::time_point toc_0 = std::chrono::steady_clock::now(); + logfile << "Total time taken: " << std::chrono::duration_cast(toc_0 - tic_0).count() << "[µs]" << std::endl; + return 0; +} diff --git a/graphcode/manual_sycl/csr.py b/graphcode/manual_sycl/csr.py new file mode 100644 index 00000000..88c140ca --- /dev/null +++ b/graphcode/manual_sycl/csr.py @@ -0,0 +1,156 @@ +from collections import defaultdict +import sys +import os + +DEBUG = 0 + +def log(x): + if DEBUG: + print(x) +name = sys.argv[1] + +try: + isWeighted = int(sys.argv[2]) +except: + isWeighted = 0 + +filename = f"raw_graphs/udwt_graphs/{name}.txt" + +os.system(f"cd csr_graphs; rm -r {name}; mkdir {name}") + +with open(filename) as f: + l = f.readlines() + +for i in range(len(l)): + try: + l[i] = list(map(int, l[i].strip().split())) + except: + log(f"[WARN] Unable to parse line {i}") + +g = defaultdict(dict) +seen = set() + +for i in range(0, len(l)): + try: + if isWeighted: + [u, v, w] = l[i] + else: + [u, v] = l[i] + w = 1 + + if DEBUG: + log(f"{u} {v} {w}") + + if u == v: + log(f"[WARN] found self loop {u} -> {v}") + continue + + if v in g[u]: + log(f"[WARN] found duplicate edge {u} -> {v}") + g[u][v] = min(g[u][v], w) + else: + g[u][v] = w + + seen.add(u) + seen.add(v) + except: + log(f"[WARN] Skipped line {i} = {l[i]}") + +V = sorted(list(seen)) +print(len(V)) +maxEdge = V[-1] +make_cont = False + +try: + assert V == [i for i in range(maxEdge + 1)] +except: + print("Not continuous") + make_cont = True + +E = [] +I = [] +W = [] +pos = 0 +for v in V: + I.append(pos) + for nn in sorted(g[v].keys()): + nw = g[v][nn] + E.append(nn) + W.append(nw) + pos += 1 +I.append(pos) + +if DEBUG: + log(V) + log(I) + log(E) + log(W) + +if make_cont: + print("Curr max = ", V[-1]) + print("Num nodes = ", len(V)) + + id_map = {V[i] : i for i in range(len(V))} + + new_V = [i for i in range(len(V))] + + new_E = [id_map[E[i]] for i in range(len(E))] + + print(f"Prev edges = {len(E)}, New edges = {len(new_E)}") + + E = new_E + V = new_V + +with open(f"csr_graphs/{name}/V", "w") as f: + f.write(" ".join(list(map(str, V)))) + +with open(f"csr_graphs/{name}/I", "w") as f: + f.write(" ".join(list(map(str, I)))) + +with open(f"csr_graphs/{name}/E", "w") as f: + for i, ele in enumerate(E): + f.write(f"{ele}") + if i != len(E) - 1: + f.write(" ") + + +with open(f"csr_graphs/{name}/W", "w") as f: + for i, ele in enumerate(W): + f.write(f"{ele}") + if i != len(W) - 1: + f.write(" ") + +rev_graph = defaultdict(list) + +ne = len(E) +n = len(V) + +for i in range(n): + u = V[i] + for j in range(I[i], I[i+1]): + v = E[j] + rev_graph[v].append(u) + +RE = [] +RI = [] +prev = 0 + +for i in range(n): + RI.append(prev) + prev += len(rev_graph[i]) + for j in rev_graph[i]: + RE.append(j) +RI.append(prev) + +with open(f"csr_graphs/{name}/RE", "w") as f: + for i, ele in enumerate(RE): + f.write(f"{ele}") + if i != len(RE) - 1: + f.write(" ") + +with open(f"csr_graphs/{name}/RI", "w") as f: + for i, ele in enumerate(RI): + f.write(f"{ele}") + if i != len(RI) - 1: + f.write(" ") + diff --git a/graphcode/manual_sycl/graph.h b/graphcode/manual_sycl/graph.h new file mode 100644 index 00000000..8e7c745e --- /dev/null +++ b/graphcode/manual_sycl/graph.h @@ -0,0 +1,212 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "utils.h" + +using namespace sycl; + +#define ATOMIC_INT atomic_ref +#define ATOMIC_FLOAT atomic_ref +#define get_node(j) g->V[j] +#define get_neighbour(j) g->E[j] +#define get_parent(j) g->RE[j] +#define get_weight(j) g->W[j] +#define get_num_neighbours(j) g->I[j + 1] - g->I[j] +#define begin_neighbours(u) g->I[u] +#define end_neighbours(u) g->I[u + 1] +#define begin_parents(u) g->RI[u] +#define end_parents(u) g->RI[u + 1] +#define for_neighbours(u, j) for (j = begin_neighbours(u); j < end_neighbours(u); j++) +#define for_parents(u, j) for (j = begin_parents(u); j < end_parents(u); j++) + +#define forall(N, NUM_THREADS) Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> u){for (; u < N; u += NUM_THREADS) +#define end \ + }); \ + }).wait(); + +class graph +{ +private: + int32_t num_nodes; + int32_t num_edges; + std::string gname; + +public: + int *V, *I, *E, *W, *RE, *RI; + + int get_num_nodes() + { + return num_nodes; + } + + int get_num_edges() + { + return num_edges; + } + + std::string get_graph_name() + { + return gname; + } + + void set_num_nodes(int n) + { + num_nodes = n; + } + + void set_num_edges(int n) + { + num_edges = n; + } + + void set_graph_name(std::string name) + { + gname = name; + } + + void load_graph(std::string name, queue Q) + { + std::vector h_V, h_I, h_E, h_W, h_RE, h_RI; + + load_from_file("csr_graphs/" + name + "/V", h_V); + load_from_file("csr_graphs/" + name + "/I", h_I); + load_from_file("csr_graphs/" + name + "/E", h_E); + load_from_file("csr_graphs/" + name + "/W", h_W); + load_from_file("csr_graphs/" + name + "/RE", h_RE); + load_from_file("csr_graphs/" + name + "/RI", h_RI); + + int num_nodes = h_V.size(); + int num_edges = h_E.size(); + + set_num_edges(num_edges); + set_num_nodes(num_nodes); + set_graph_name(name); + V = malloc_device(num_nodes, Q); + I = malloc_device((num_nodes + 1), Q); + E = malloc_device(num_edges, Q); + W = malloc_device(num_edges, Q); + RE = malloc_device(num_edges, Q); + RI = malloc_device((num_nodes + 1), Q); + + Q.submit([&](handler &h) + { h.memcpy(V, &h_V[0], h_V.size() * sizeof(int)); }); + + Q.submit([&](handler &h) + { h.memcpy(I, &h_I[0], h_I.size() * sizeof(int)); }); + + Q.submit([&](handler &h) + { h.memcpy(E, &h_E[0], h_E.size() * sizeof(int)); }); + + Q.submit([&](handler &h) + { h.memcpy(W, &h_W[0], h_W.size() * sizeof(int)); }); + + Q.submit([&](handler &h) + { h.memcpy(RE, &h_RE[0], h_RE.size() * sizeof(int)); }); + + Q.submit([&](handler &h) + { h.memcpy(RI, &h_RI[0], h_RI.size() * sizeof(int)); }); + + Q.wait(); + } + + void free_memory(queue Q) + { + free(V, Q); + free(I, Q); + free(E, Q); + free(W, Q); + free(RE, Q); + free(RI, Q); + } +}; + +// initialize device arr with val, if needed set arr[pos] = pos_val +template +void initialize(T *arr, T val, int NUM_THREADS, int N, queue Q, int pos = -1, T pos_val = -1) +{ + int stride = NUM_THREADS; + Q.submit([&](handler &h) + { h.parallel_for(NUM_THREADS, [=](id<1> i) + { + for (; i < N; i += stride) + { + arr[i] = val; + + if (i == pos) + { + arr[pos] = pos_val; + } + } }); }); + Q.wait(); +} + +// memcpy from src to dest +template +void memcpy(T *dest, T *src, int N, queue Q) +{ + Q.submit([&](handler &h) + { h.memcpy(dest, src, N * sizeof(T)); }) + .wait(); +} + +// copy contents of src to dest, both src and dest are of length N +template +void copy(T *dest, T *src, int NUM_THREADS, int N, queue Q) +{ + int stride = NUM_THREADS; + Q.submit([&](handler &h) + { h.parallel_for( + NUM_THREADS, [=](id<1> i) + { + for (; i < N ;i += stride) + { + dest[i] = src[i]; + } }); }) + .wait(); +} + +// returns True if u and v are neighbours +int neighbours(int v, int w, graph *g) +{ + int connected = 0; + int start_edge = begin_neighbours(v); + int end_edge = end_neighbours(v) - 1; + + if (get_neighbour(start_edge) == w) + { + connected = 1; + } + else if (get_neighbour(end_edge) == w) + { + connected = 1; + } + else + { + int mid = start_edge + (end_edge - start_edge) / 2; + while (start_edge <= end_edge) + { + if (get_neighbour(mid) == w) + { + connected = 1; + break; + } + if (w < get_neighbour(mid)) + { + end_edge = mid - 1; + } + else + { + start_edge = mid + 1; + } + mid = start_edge + (end_edge - start_edge) / 2; + } + } + + return connected; +} \ No newline at end of file diff --git a/graphcode/manual_sycl/min_spanning_tree/mst_vb.cpp b/graphcode/manual_sycl/min_spanning_tree/mst_vb.cpp new file mode 100644 index 00000000..7a25db6c --- /dev/null +++ b/graphcode/manual_sycl/min_spanning_tree/mst_vb.cpp @@ -0,0 +1,237 @@ +#include +#include +#include +#define DEBUG 0 +#include "../graph.h" + +using namespace sycl; + +int main(int argc, char **argv) +{ + + std::chrono::steady_clock::time_point tic_0 = std::chrono::steady_clock::now(); + std::ofstream logfile; + + std::string name = argv[1]; + int NUM_THREADS = atoi(argv[2]); + std::string NUM_THREADS_STR = std::to_string(NUM_THREADS); + + logfile.open("min_spanning_tree/output/" + name + "_mst_vb_time_" + NUM_THREADS_STR + ".txt"); + + logfile << "Processing " << name << std::endl; + default_selector d_selector; + queue Q(d_selector); + logfile << "Selected device: " << Q.get_device().get_info() << std::endl; + logfile << "Number of parallel work items: " << NUM_THREADS << std::endl; + + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + graph *g = malloc_shared(1, Q); + g->load_graph(name, Q); + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + logfile << "Time to load data from files: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + int n_vertices = g->get_num_nodes(); + int n_edges = g->get_num_edges(); + int stride = NUM_THREADS; + + int *d_parent = malloc_device(n_vertices, Q); + copy(d_parent, g->V, NUM_THREADS, n_vertices, Q); + int *d_local_min_edge = malloc_device(n_vertices, Q); + int *d_comp_min_edge = malloc_device(n_vertices, Q); + int *d_edge_in_mst = malloc_device(n_edges, Q); + initialize(d_edge_in_mst, 0, NUM_THREADS, n_edges, Q); + + bool *rem_comp = malloc_shared(1, Q); + int *counter = malloc_shared(1, Q); + bool *found_min_edge = malloc_shared(1, Q); + bool *parents_updated = malloc_shared(1, Q); + + tic = std::chrono::steady_clock::now(); + logfile << "Starting minimum spanning tree calculation..." << std::endl; + + *rem_comp = false; + *counter = 0; + + while (!*rem_comp) + { + *rem_comp = true; + + initialize(d_local_min_edge, -1, NUM_THREADS, n_vertices, Q); + initialize(d_comp_min_edge, -1, NUM_THREADS, n_vertices, Q); + + // find minimum edge to different component from each node + forall(n_vertices, NUM_THREADS) + { + int edge; + for_neighbours(u, edge) + { + int v = get_neighbour(edge); + // if u and v in different components + if (d_parent[u] != d_parent[v]) + { + int curr_min_edge = d_local_min_edge[u]; + if (curr_min_edge == -1) + { + d_local_min_edge[u] = edge; + } + else + { + int curr_neigh = get_neighbour(curr_min_edge); + int curr_edge_weight = get_weight(edge), curr_min_edge_weight = get_weight(curr_min_edge); + if (curr_edge_weight < curr_min_edge_weight || (curr_edge_weight == curr_min_edge_weight && d_parent[v] < d_parent[curr_neigh])) + { + d_local_min_edge[u] = edge; + } + } + } + } + } + end; + + // find the minimum edge from the component + *found_min_edge = false; + while (!*found_min_edge) + { + *found_min_edge = true; + forall(n_vertices, NUM_THREADS) + { + int my_comp = d_parent[u]; + + int comp_min_edge = d_comp_min_edge[my_comp]; + + int my_min_edge = d_local_min_edge[u]; + + if (my_min_edge != -1) + { + int v = get_neighbour(my_min_edge); + + if (comp_min_edge == -1) + { + d_comp_min_edge[my_comp] = my_min_edge; + *found_min_edge = false; + } + else + { + int curr_min_neigh = get_neighbour(comp_min_edge); + int my_min_edge_weight = get_weight(my_min_edge), comp_min_edge_weight = get_weight(comp_min_edge); + if (my_min_edge_weight < comp_min_edge_weight || (my_min_edge_weight == comp_min_edge_weight && d_parent[v] < d_parent[curr_min_neigh])) + { + d_comp_min_edge[my_comp] = my_min_edge; + *found_min_edge = false; + } + } + } + } + end; + } + + // remove cycles of 2 nodes + forall(n_vertices, NUM_THREADS) + { + // if u is the representative of its component + if (d_parent[u] == get_node(u)) + { + int comp_min_edge = d_comp_min_edge[u]; + if (comp_min_edge != -1) + { + int v = get_neighbour(comp_min_edge); + int parent_v = d_parent[v]; + + int v_comp_min_edge = d_comp_min_edge[parent_v]; + if (v_comp_min_edge != -1) + { + // v is comp(u)'s neighbour + // w is comp(v)'s neighbour + int w = get_neighbour(v_comp_min_edge); + if (d_parent[u] == d_parent[w] && d_parent[u] < d_parent[v]) + { + d_comp_min_edge[d_parent[v]] = -1; + } + } + } + } + } + end; + + // update the MST edges + forall(n_vertices, NUM_THREADS) + { + // if u is the representative of its component + if (d_parent[u] == get_node(u)) + { + int curr_comp_min_edge = d_comp_min_edge[u]; + if (curr_comp_min_edge != -1) + { + d_edge_in_mst[curr_comp_min_edge] = 1; + ATOMIC_INT atomic_data(*counter); + atomic_data += 1; + } + } + } + end; + + logfile << "Num Edges: " << *counter << std::endl; + + // update parents + forall(n_vertices, NUM_THREADS) + { + // if u is the representative of its component + if (d_parent[u] == get_node(u)) + { + int curr_comp_min_edge = d_comp_min_edge[u]; + if (curr_comp_min_edge != -1) + { + *rem_comp = false; + int v = get_neighbour(curr_comp_min_edge); + d_parent[u] = d_parent[v]; + } + } + } + end; + + // flatten parents + *parents_updated = false; + while (!*parents_updated) + { + *parents_updated = true; + forall(n_vertices, NUM_THREADS) + { + int parent_u = d_parent[u]; + int parent_parent_u = d_parent[parent_u]; + + if (parent_u != parent_parent_u) + { + *parents_updated = false; + d_parent[u] = parent_parent_u; + } + } + end; + } + } + toc = std::chrono::steady_clock::now(); + logfile << "Time to run minimum spanning tree: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + tic = std::chrono::steady_clock::now(); + std::ofstream resultfile; + + resultfile.open("min_spanning_tree/output/" + name + "_mst_vb_result_" + NUM_THREADS_STR + ".txt"); + + std::vector op(n_edges); + memcpy(&op[0], d_edge_in_mst, n_edges, Q); + + int count = 0; + for (int i = 0; i < n_edges; i++) + { + if (op[i] == 1) + count++; + resultfile << i << " " << op[i] << std::endl; + } + resultfile << "Num edges included in MST: " << count << " Total nodes in graph: " << n_vertices << std::endl; + resultfile.close(); + toc = std::chrono::steady_clock::now(); + logfile << "Time to write data to file: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + std::chrono::steady_clock::time_point toc_0 = std::chrono::steady_clock::now(); + logfile << "Total time taken: " << std::chrono::duration_cast(toc_0 - tic_0).count() << "[µs]" << std::endl; + return 0; +} diff --git a/graphcode/manual_sycl/pagerank/pr_pull.cpp b/graphcode/manual_sycl/pagerank/pr_pull.cpp new file mode 100644 index 00000000..de8bbded --- /dev/null +++ b/graphcode/manual_sycl/pagerank/pr_pull.cpp @@ -0,0 +1,103 @@ +#include +#include +#include +#define DEBUG 0 +#include "../graph.h" + +using namespace sycl; + +int main(int argc, char **argv) +{ + + std::chrono::steady_clock::time_point tic_0 = std::chrono::steady_clock::now(); + std::ofstream logfile; + + std::string name = argv[1]; + int NUM_THREADS = atoi(argv[2]); + std::string NUM_THREADS_STR = std::to_string(NUM_THREADS); + + logfile.open("pagerank/output/" + name + "_pr_pull_time_" + NUM_THREADS_STR + ".txt"); + + logfile << "Processing " << name << std::endl; + + default_selector d_selector; + queue Q(d_selector); + logfile << "Selected device: " << Q.get_device().get_info() << std::endl; + logfile << "Number of parallel work items: " << NUM_THREADS << std::endl; + + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + graph *g = malloc_shared(1, Q); + g->load_graph(name, Q); + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + logfile << "Time to load data from files: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + float beta = 0.001; + int maxIter = 100; + float delta = 0.85; + + int N = g->get_num_nodes(); + int stride = NUM_THREADS; + + std::vector pagerank(N); + float *dev_pagerank = malloc_device(N, Q); + initialize(dev_pagerank, float(1 / N), NUM_THREADS, N, Q); + + float *dev_pagerank_i = malloc_device(N, Q); + initialize(dev_pagerank_i, float(1 / N), NUM_THREADS, N, Q); + + tic = std::chrono::steady_clock::now(); + logfile << "Starting Pagerank..." << std::endl; + float *diff = malloc_shared(1, Q); + int iterCount = 0; + do + { + forall(N, NUM_THREADS) + { + float sum = 0; + // pull + int u_itr; + for_parents(u, u_itr) + { + int nbr = get_parent(u_itr); + sum = sum + dev_pagerank[nbr] / (get_num_neighbours(nbr)); + } + float val = (1 - delta) / N + delta * sum; + ATOMIC_FLOAT atomic_data(*diff); + atomic_data += (float)val - dev_pagerank[u]; + dev_pagerank_i[u] = val; + } + end; + + forall(N, NUM_THREADS) + { + dev_pagerank[u] = dev_pagerank_i[u]; + } + end; + + iterCount += 1; + } while ((*diff > beta) && (iterCount < maxIter)); + + toc = std::chrono::steady_clock::now(); + logfile << "Time to run Pagerank: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + tic = std::chrono::steady_clock::now(); + std::ofstream resultfile; + int num_covered = 0; + + memcpy(&pagerank[0], dev_pagerank, N, Q); + + resultfile.open("pagerank/output/" + name + "_pr_pull_result_" + NUM_THREADS_STR + ".txt"); + + for (int i = 0; i < N; i++) + { + resultfile << i << " " << pagerank[i] << std::endl; + } + resultfile.close(); + toc = std::chrono::steady_clock::now(); + logfile << "Time to write data to file: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + std::chrono::steady_clock::time_point toc_0 = std::chrono::steady_clock::now(); + logfile << "Total time taken: " << std::chrono::duration_cast(toc_0 - tic_0).count() << "[µs]" << std::endl; + + return 0; +} diff --git a/graphcode/manual_sycl/poster.png b/graphcode/manual_sycl/poster.png new file mode 100644 index 00000000..f2323197 Binary files /dev/null and b/graphcode/manual_sycl/poster.png differ diff --git a/graphcode/manual_sycl/scripts/connected_comp.py b/graphcode/manual_sycl/scripts/connected_comp.py new file mode 100644 index 00000000..367b59d2 --- /dev/null +++ b/graphcode/manual_sycl/scripts/connected_comp.py @@ -0,0 +1,84 @@ +from collections import defaultdict +import random + + +class Graph: + def __init__(self, N = 0, g = defaultdict(list)): + self.V = N + self.graph = g + self.comps = [] + + def addEdge(self,u,v): + self.graph[u].append(v) + + def DFSUtil(self, v): + self.visited[v]= True + self.curr.append(v) + for i in self.graph[v]: + if self.visited[i]==False: + self.DFSUtil(i) + + + def fillOrder(self, v): + self.visited[v]= True + for i in self.graph[v]: + if self.visited[i]==False: + self.fillOrder(i) + self.stack.append(v) + + def getTranspose(self): + g = Graph(self.V) + for i in self.graph: + for j in self.graph[i]: + g.addEdge(j,i) + return g + + def printSCCs(self): + self.stack = [] + self.visited =[False]*(self.V) + for i in range(self.V): + if self.visited[i]==False: + self.fillOrder(i) + + gr = self.getTranspose() + + gr.visited =[False]*(self.V) + while self.stack: + i = self.stack.pop() + gr.curr = [] + if not gr.visited[i]: + gr.DFSUtil(i) + self.comps.append(gr.curr.copy()) + + self.comps.sort(reverse=True, key = lambda x : len(x)) + for comp in self.comps: + print(len(comp), comp[0]) + +DEBUG = 0 +HERE = 1 + +name = "simple_random" +if HERE: + filename = f"raw_graphs/{name}.txt" +else: + filename = f"/lfs/usrhome/btech/ee19b106/graph_algorithms/raw_graphs/{name}.txt" + +with open(filename) as f: + l = f.readlines() + +l = l[1:] + +for i in range(len(l)): + l[i] = list(map(int, l[i].strip().split(" "))) + +g = defaultdict(list) +seen = set() + +for i in range(0, len(l)): + [u, v] = l[i] + g[u].append(v) + seen.add(u) + seen.add(v) + +G = Graph(len(seen), g) +G.printSCCs() \ No newline at end of file diff --git a/graphcode/manual_sycl/scripts/csr.py b/graphcode/manual_sycl/scripts/csr.py new file mode 100644 index 00000000..f46e4985 --- /dev/null +++ b/graphcode/manual_sycl/scripts/csr.py @@ -0,0 +1,65 @@ +from collections import defaultdict +import random + +DEBUG = 0 +HERE = 1 + +name = "GermanyRoadud" +if HERE: + filename = f"raw_graphs/{name}.txt" +else: + filename = f"/lfs/usrhome/btech/ee19b106/graph_algorithms/raw_graphs/{name}.txt" + +with open(filename) as f: + l = f.readlines() + +# l = l[1:] + +for i in range(len(l)): + l[i] = list(map(int, l[i].strip().split())) + +g = defaultdict(list) + +for i in range(0, len(l), 2): + try: + [u, v] = l[i] + assert l[i + 1][::-1] == l[i] + except: + print("REV Edge not found?") + w = random.randint(1, 100) + if DEBUG: + print(f"{u} {v} {w}") + g[u].append([v, w]) + g[v].append([u, w]) + +V = sorted(list(g.keys())) +E = [] +I = [] +W = [] +pos = 0 +for v in V: + I.append(pos) + for [nn, nw] in g[v]: + E.append(nn) + W.append(nw) + pos += 1 +I.append(pos) + +if DEBUG: + print(V) + print(I) + print(E) + print(W) + +with open(f"csr_graphs/{name}/V", "w") as f: + f.write(" ".join(list(map(str, V)))) + +with open(f"csr_graphs/{name}/I", "w") as f: + f.write(" ".join(list(map(str, I)))) + +with open(f"csr_graphs/{name}/E", "w") as f: + f.write(" ".join(list(map(str, E)))) + +with open(f"csr_graphs/{name}/W", "w") as f: + f.write(" ".join(list(map(str, W)))) + diff --git a/graphcode/manual_sycl/scripts/csr_sorted.py b/graphcode/manual_sycl/scripts/csr_sorted.py new file mode 100644 index 00000000..fd0cf4a9 --- /dev/null +++ b/graphcode/manual_sycl/scripts/csr_sorted.py @@ -0,0 +1,81 @@ +from collections import defaultdict +import random + +DEBUG = 0 +HERE = 1 + +name = "simplebcud" +if HERE: + filename = f"raw_graphs/{name}.txt" +else: + filename = f"/lfs/usrhome/btech/ee19b106/graph_algorithms/raw_graphs/{name}.txt" + +with open(filename) as f: + l = f.readlines() + +# l = l[1:] + +for i in range(len(l)): + try: + l[i] = list(map(int, l[i].strip().split(" "))) + except: + print(f"[WARN] Unable to parse line {i}") + +g = defaultdict(list) +seen = set() + +for i in range(0, len(l)): + try: + [u, v] = l[i] + w = random.randint(1, 100) + if DEBUG: + print(f"{u} {v} {w}") + g[u].append([v, w]) + seen.add(u) + seen.add(v) + except: + print(f"[WARN] Skipped line {i} = {l[i]}") + +V = sorted(list(seen)) +maxEdge = V[-1] +try: + assert V == [i for i in range(maxEdge + 1)] +except: + print("Not continuous") +E = [] +I = [] +W = [] +pos = 0 +for v in V: + I.append(pos) + for [nn, nw] in sorted(g[v]): + E.append(nn) + W.append(nw) + pos += 1 +I.append(pos) + +if DEBUG: + print(V) + print(I) + print(E) + print(W) + +with open(f"csr_graphs/{name}/V", "w") as f: + f.write(" ".join(list(map(str, V)))) + +with open(f"csr_graphs/{name}/I", "w") as f: + f.write(" ".join(list(map(str, I)))) + +with open(f"csr_graphs/{name}/E", "w") as f: + for i, ele in enumerate(E): + f.write(f"{ele}") + if i != len(E) - 1: + f.write(" ") + + +with open(f"csr_graphs/{name}/W", "w") as f: + for i, ele in enumerate(W): + f.write(f"{ele}") + if i != len(W) - 1: + f.write(" ") + diff --git a/graphcode/manual_sycl/scripts/csr_twitter.py b/graphcode/manual_sycl/scripts/csr_twitter.py new file mode 100644 index 00000000..6224c8f1 --- /dev/null +++ b/graphcode/manual_sycl/scripts/csr_twitter.py @@ -0,0 +1,81 @@ +from collections import defaultdict +import random + +DEBUG = 0 +HERE = 1 + +name = "clean-soc-sinaweibo" +if HERE: + filename = f"raw_graphs/{name}.txt" +else: + filename = f"/lfs/usrhome/btech/ee19b106/graph_algorithms/raw_graphs/{name}.txt" + +with open(filename) as f: + l = f.readlines() + +# l = l[1:] + +for i in range(len(l)): + try: + l[i] = list(map(int, l[i].strip().split(" "))) + except: + print(f"[WARN] Unable to parse line {i}") + +g = defaultdict(list) +seen = set() + +for i in range(0, len(l)): + try: + [u, v] = l[i] + w = random.randint(1, 100) + if DEBUG: + print(f"{u} {v} {w}") + g[u].append([v, w]) + seen.add(u) + seen.add(v) + except: + print(f"[WARN] Skipped line {i} = {l[i]}") + +V = sorted(list(seen)) +maxEdge = V[-1] +try: + assert V == [i for i in range(maxEdge + 1)] +except: + print("Not continuous") +E = [] +I = [] +W = [] +pos = 0 +for v in V: + I.append(pos) + for [nn, nw] in g[v]: + E.append(nn) + W.append(nw) + pos += 1 +I.append(pos) + +if DEBUG: + print(V) + print(I) + print(E) + print(W) + +with open(f"csr_graphs/{name}/V", "w") as f: + f.write(" ".join(list(map(str, V)))) + +with open(f"csr_graphs/{name}/I", "w") as f: + f.write(" ".join(list(map(str, I)))) + +with open(f"csr_graphs/{name}/E", "w") as f: + for i, ele in enumerate(E): + f.write(f"{ele}") + if i != len(E) - 1: + f.write(" ") + + +with open(f"csr_graphs/{name}/W", "w") as f: + for i, ele in enumerate(W): + f.write(f"{ele}") + if i != len(W) - 1: + f.write(" ") + diff --git a/graphcode/manual_sycl/scripts/csr_u_to_ud.py b/graphcode/manual_sycl/scripts/csr_u_to_ud.py new file mode 100644 index 00000000..d25efd87 --- /dev/null +++ b/graphcode/manual_sycl/scripts/csr_u_to_ud.py @@ -0,0 +1,89 @@ +from collections import defaultdict +from email.policy import default +import random + +DEBUG = 0 +HERE = 1 + +d_name = "simplebcd" +name = d_name+"_ud" +if HERE: + filename = f"raw_graphs/{d_name}.txt" +else: + filename = f"/lfs/usrhome/btech/ee19b106/graph_algorithms/raw_graphs/{d_name}.txt" + +with open(filename) as f: + l = f.readlines() + +# l = l[1:] + +for i in range(len(l)): + try: + l[i] = list(map(int, l[i].strip().split(" "))) + except: + print(f"[WARN] Unable to parse line {i}") + +g = defaultdict(list) +neigh = defaultdict(set) +seen = set() + +for i in range(0, len(l)): + try: + [u, v] = l[i] + w = random.randint(1, 100) + if DEBUG: + print(f"{u} {v} {w}") + if v in neigh[u]: + continue + neigh[u].add(v) + neigh[v].add(u) + g[u].append([v, w]) + g[v].append([u, w]) + seen.add(u) + seen.add(v) + except: + print(f"[WARN] Skipped line {i} = {l[i]}") + +V = sorted(list(seen)) +maxEdge = V[-1] +try: + assert V == [i for i in range(maxEdge + 1)] +except: + print("Not continuous") +E = [] +I = [] +W = [] +pos = 0 +for v in V: + I.append(pos) + for [nn, nw] in sorted(g[v]): + E.append(nn) + W.append(nw) + pos += 1 +I.append(pos) + +if DEBUG: + print(V) + print(I) + print(E) + print(W) + +with open(f"csr_graphs/{name}/V", "w") as f: + f.write(" ".join(list(map(str, V)))) + +with open(f"csr_graphs/{name}/I", "w") as f: + f.write(" ".join(list(map(str, I)))) + +with open(f"csr_graphs/{name}/E", "w") as f: + for i, ele in enumerate(E): + f.write(f"{ele}") + if i != len(E) - 1: + f.write(" ") + + +with open(f"csr_graphs/{name}/W", "w") as f: + for i, ele in enumerate(W): + f.write(f"{ele}") + if i != len(W) - 1: + f.write(" ") + diff --git a/graphcode/manual_sycl/scripts/make_RE_RI.py b/graphcode/manual_sycl/scripts/make_RE_RI.py new file mode 100644 index 00000000..3e1e0155 --- /dev/null +++ b/graphcode/manual_sycl/scripts/make_RE_RI.py @@ -0,0 +1,52 @@ +from collections import defaultdict +name = "simple" + +f = open(f"csr_graphs/{name}/V") +V = list(map(int, list(f.readlines()[0].strip().split()))) + +f = open(f"csr_graphs/{name}/I") +I = list(map(int, list(f.readlines()[0].strip().split()))) + +f = open(f"csr_graphs/{name}/E") +E = list(map(int, list(f.readlines()[0].strip().split()))) + +rev_graph = defaultdict(list) + +ne = len(E) +n = len(V) + +for i in range(n): + u = V[i] + for j in range(I[i], I[i+1]): + v = E[j] + rev_graph[v].append(u) + +# print(rev_graph) + +RE = [] +RI = [] +prev = 0 +for i in range(n): + RI.append(prev) + prev += len(rev_graph[i]) + for j in rev_graph[i]: + RE.append(j) +RI.append(prev) + +# print(RI) +# print(RE) + +with open(f"csr_graphs/{name}/RE", "w") as f: + for i, ele in enumerate(RE): + f.write(f"{ele}") + if i != len(RE) - 1: + f.write(" ") + + +with open(f"csr_graphs/{name}/RI", "w") as f: + for i, ele in enumerate(RI): + f.write(f"{ele}") + if i != len(RI) - 1: + f.write(" ") + + diff --git a/graphcode/manual_sycl/scripts/make_cont_nodes.py b/graphcode/manual_sycl/scripts/make_cont_nodes.py new file mode 100644 index 00000000..c6569d04 --- /dev/null +++ b/graphcode/manual_sycl/scripts/make_cont_nodes.py @@ -0,0 +1,28 @@ +name = "cleancom-orkutud" +f = open(f"csr_graphs/{name}/V") +V = list(map(int, f.readlines()[0].strip().split())) + + +f = open(f"csr_graphs/{name}/E") +E = list(map(int, f.readlines()[0].strip().split())) + +print("Curr max = ", V[-1]) +print("Num nodes = ", len(V)) + +id_map = {V[i] : i for i in range(len(V))} + +new_V = [i for i in range(len(V))] + +new_E = [id_map[E[i]] for i in range(len(E))] + +print(f"Prev edges = {len(E)}, New edges = {len(new_E)}") + +with open(f"csr_graphs/{name}/V", "w") as f: + f.write(" ".join(list(map(str, new_V)))) + +with open(f"csr_graphs/{name}/E", "w") as f: + for i, ele in enumerate(new_E): + f.write(f"{ele}") + if i != len(new_E) - 1: + f.write(" ") + \ No newline at end of file diff --git a/graphcode/manual_sycl/single_source_shortest_path/sssp_vdp.cpp b/graphcode/manual_sycl/single_source_shortest_path/sssp_vdp.cpp new file mode 100644 index 00000000..c8d0da17 --- /dev/null +++ b/graphcode/manual_sycl/single_source_shortest_path/sssp_vdp.cpp @@ -0,0 +1,132 @@ +#include +#include +#include +#define DEBUG 0 +#include "../graph.h" + +using namespace sycl; + +int main(int argc, char **argv) +{ + + std::chrono::steady_clock::time_point tic_0 = std::chrono::steady_clock::now(); + std::ofstream logfile; + + std::string name = argv[1]; + int source = atoi(argv[2]); + int NUM_THREADS = atoi(argv[3]); + std::string NUM_THREADS_STR = std::to_string(NUM_THREADS); + + default_selector d_selector; + queue Q(d_selector); + + logfile.open("single_source_shortest_path/output/" + name + "_sssp_dp_time_" + NUM_THREADS_STR + ".txt"); + + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + + graph *g = malloc_shared(1, Q); + g->load_graph(name, Q); + + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + logfile << "Processing " << g->get_graph_name() << std::endl; + logfile << "Num nodes: " << g->get_num_nodes() << "\t" + << "Num edges: " << g->get_num_edges() << std::endl; + logfile << "Time to load data from files: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + logfile << "Selected device: " << Q.get_device().get_info() << std::endl; + logfile << "Number of parallel work items: " << NUM_THREADS << std::endl; + + int N = g->get_num_nodes(); + int stride = NUM_THREADS; + + std::vector dist(N, INT_MAX); + + int *dev_dist = malloc_device(N, Q); + initialize(dev_dist, INT_MAX, NUM_THREADS, N, Q, source, 0); + + int *dev_dist_i = malloc_device(N, Q); + initialize(dev_dist_i, INT_MAX, NUM_THREADS, N, Q, source, 0); + + tic = std::chrono::steady_clock::now(); + logfile << "Starting SSSP..." << std::endl; + int *active_count = malloc_shared(1, Q); + int *wl = malloc_shared(N, Q); + *active_count = 1; + wl[0] = source; + + for (int round = 1; round < N; round++) + { + if (*active_count == 0) + { + logfile << "Number of rounds required for convergence: " << round << std::endl; + break; + } + forall(*active_count, NUM_THREADS) + { + int node = wl[u]; + int n_itr; + for_neighbours(node, n_itr) + { + int w = get_weight(n_itr); + int v = get_neighbour(n_itr); + + int dnode = dev_dist[node]; + int dv = dev_dist[v]; + int new_dist = dnode + w; + + if (dnode == INT_MAX) + { + continue; + } + + ATOMIC_INT atomic_data(dev_dist_i[v]); + atomic_data.fetch_min(new_dist); + } + } + end; + + *active_count = 0; + free(wl, Q); + wl = malloc_shared(N, Q); + + forall(N, NUM_THREADS) + { + if (dev_dist[u] > dev_dist_i[u]) + { + dev_dist[u] = dev_dist_i[u]; + ATOMIC_INT atomic_data(*active_count); + wl[atomic_data++] = u; + } + dev_dist_i[u] = dev_dist[u]; + } + end; + } + toc = std::chrono::steady_clock::now(); + logfile << "Time to run SSSP: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + tic = std::chrono::steady_clock::now(); + std::ofstream resultfile; + int num_covered = 0; + + memcpy(&dist[0], dev_dist, N, Q); + + resultfile.open("single_source_shortest_path/output/" + name + "_sssp_dp_result_" + NUM_THREADS_STR + ".txt"); + + for (int i = 0; i < N; i++) + { + if (dist[i] != INT_MAX) + { + num_covered += 1; + } + resultfile << i << " " << dist[i] << std::endl; + } + resultfile.close(); + toc = std::chrono::steady_clock::now(); + logfile << "Time to write data to file: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + std::chrono::steady_clock::time_point toc_0 = std::chrono::steady_clock::now(); + logfile << "Total time taken: " << std::chrono::duration_cast(toc_0 - tic_0).count() << "[µs]" << std::endl; + logfile << "Percentage coverage from given source: " << 100 * (1.0 * num_covered) / N << std::endl + << "Number of nodes covered: " << num_covered << std::endl; + + return 0; +} diff --git a/graphcode/manual_sycl/single_source_shortest_path/sssp_vtop.cpp b/graphcode/manual_sycl/single_source_shortest_path/sssp_vtop.cpp new file mode 100644 index 00000000..37af316b --- /dev/null +++ b/graphcode/manual_sycl/single_source_shortest_path/sssp_vtop.cpp @@ -0,0 +1,133 @@ +#include +#include +#include +#define DEBUG 0 +#include "../graph.h" + +using namespace sycl; + +int main(int argc, char **argv) +{ + + std::chrono::steady_clock::time_point tic_0 = std::chrono::steady_clock::now(); + std::ofstream logfile; + + std::string name = argv[1]; + int source = atoi(argv[2]); + int NUM_THREADS = atoi(argv[3]); + std::string NUM_THREADS_STR = std::to_string(NUM_THREADS); + + default_selector d_selector; + queue Q(d_selector); + + logfile.open("single_source_shortest_path/output/" + name + "_sssp_top_time_" + NUM_THREADS_STR + ".txt"); + + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + + graph *g = malloc_shared(1, Q); + g->load_graph(name, Q); + + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + logfile << "Processing " << g->get_graph_name() << std::endl; + logfile << "Num nodes: " << g->get_num_nodes() << "\t" + << "Num edges: " << g->get_num_edges() << std::endl; + logfile << "Time to load data from files: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + logfile << "Selected device: " << Q.get_device().get_info() << std::endl; + logfile << "Number of parallel work items: " << NUM_THREADS << std::endl; + + int N = g->get_num_nodes(); + int stride = NUM_THREADS; + std::vector dist(N, INT_MAX); + + int *dev_flag = malloc_device(N, Q); + initialize(dev_flag, 0, NUM_THREADS, N, Q, source, 1); + + int *dev_dist = malloc_device(N, Q); + initialize(dev_dist, INT_MAX, NUM_THREADS, N, Q, source, 0); + + int *dev_dist_i = malloc_device(N, Q); + initialize(dev_dist_i, INT_MAX, NUM_THREADS, N, Q, source, 0); + + tic = std::chrono::steady_clock::now(); + logfile << "Starting SSSP..." << std::endl; + int *early_stop = malloc_shared(1, Q); + + for (int round = 1; round < N; round++) + { + + if (*early_stop == 1) + { + logfile << "Number of rounds required for convergence: " << round << std::endl; + break; + } + *early_stop = 1; + + forall(N, NUM_THREADS) + { + if (dev_flag[u]) + { + dev_flag[u] = 0; + int u_itr; + for_neighbours(u, u_itr) + { + int v = get_neighbour(u_itr); + int w = get_weight(u_itr); + + int du = dev_dist[u]; + int dv = dev_dist[v]; + int new_dist = du + w; + + if (du == INT_MAX) + { + continue; + } + ATOMIC_INT atomic_data(dev_dist_i[v]); + atomic_data.fetch_min(new_dist); + } + } + } + end; + + forall(N, NUM_THREADS) + { + if (dev_dist[u] > dev_dist_i[u]) + { + dev_dist[u] = dev_dist_i[u]; + dev_flag[u] = 1; + *early_stop = 0; + } + dev_dist_i[u] = dev_dist[u]; + } + end; + } + + toc = std::chrono::steady_clock::now(); + logfile << "Time to run SSSP: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + tic = std::chrono::steady_clock::now(); + std::ofstream resultfile; + int num_covered = 0; + + memcpy(&dist[0], dev_dist, N, Q); + + resultfile.open("single_source_shortest_path/output/" + name + "_sssp_top_result_" + NUM_THREADS_STR + ".txt"); + + for (int i = 0; i < N; i++) + { + if (dist[i] != INT_MAX) + { + num_covered += 1; + } + resultfile << i << " " << dist[i] << std::endl; + } + resultfile.close(); + toc = std::chrono::steady_clock::now(); + logfile << "Time to write data to file: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + std::chrono::steady_clock::time_point toc_0 = std::chrono::steady_clock::now(); + logfile << "Total time taken: " << std::chrono::duration_cast(toc_0 - tic_0).count() << "[µs]" << std::endl; + logfile << "Percentage coverage from given source: " << 100 * (1.0 * num_covered) / N << std::endl + << "Number of nodes covered: " << num_covered << std::endl; + g->free_memory(Q); + return 0; +} diff --git a/graphcode/manual_sycl/triangle_count/tc_bs.cpp b/graphcode/manual_sycl/triangle_count/tc_bs.cpp new file mode 100644 index 00000000..bd981e17 --- /dev/null +++ b/graphcode/manual_sycl/triangle_count/tc_bs.cpp @@ -0,0 +1,94 @@ +#include +#include +#include +#define DEBUG 0 +#include "../graph.h" + +using namespace sycl; + +int main(int argc, char **argv) +{ + + std::chrono::steady_clock::time_point tic_0 = std::chrono::steady_clock::now(); + std::ofstream logfile; + + std::string name = argv[1]; + int NUM_THREADS = atoi(argv[2]); + std::string NUM_THREADS_STR = std::to_string(NUM_THREADS); + + logfile.open("triangle_count/output/" + name + "_tc_bs_time_" + NUM_THREADS_STR + ".txt"); + + logfile << "Processing " << name << std::endl; + + default_selector d_selector; + queue Q(d_selector); + logfile << "Selected device: " << Q.get_device().get_info() << std::endl; + logfile << "Number of parallel work items: " << NUM_THREADS << std::endl; + + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + + graph *g = malloc_shared(1, Q); + g->load_graph(name, Q); + + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + logfile << "Time to load data from files: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + int N = g->get_num_nodes(); + int stride = NUM_THREADS; + + tic = std::chrono::steady_clock::now(); + logfile << "Starting triangle count..." << std::endl; + + int triangle_count = 0; + int *dev_triangle_count = malloc_device(1, Q); + + memcpy(dev_triangle_count, &triangle_count, 1, Q); + + forall(N, NUM_THREADS) + { + int u_itr1, u_itr2; + for_neighbours(u, u_itr1) + { + int v = get_neighbour(u_itr1); + if (v < u) + { + for_neighbours(u, u_itr2) + { + int w = get_neighbour(u_itr2); + int nbrs_connected = 0; + if (w > u) + { + nbrs_connected = neighbours(v, w, g); + } + if (nbrs_connected) + { + ATOMIC_INT atomic_data(dev_triangle_count[0]); + atomic_data += 1; + } + } + } + } + } + end; + + toc = std::chrono::steady_clock::now(); + logfile << "Time to run triangle count: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + memcpy(&triangle_count, dev_triangle_count, 1, Q); + + tic = std::chrono::steady_clock::now(); + std::ofstream resultfile; + + resultfile.open("triangle_count/output/" + name + "_tc_bs_result_" + NUM_THREADS_STR + ".txt"); + + resultfile << "Number of triangles in graph = " << triangle_count << std::endl; + + resultfile.close(); + toc = std::chrono::steady_clock::now(); + logfile << "Time to write data to file: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + std::chrono::steady_clock::time_point toc_0 = std::chrono::steady_clock::now(); + logfile << "Total time taken: " << std::chrono::duration_cast(toc_0 - tic_0).count() << "[µs]" << std::endl; + + return 0; +} diff --git a/graphcode/manual_sycl/triangle_count/tc_lin.cpp b/graphcode/manual_sycl/triangle_count/tc_lin.cpp new file mode 100644 index 00000000..4cccb898 --- /dev/null +++ b/graphcode/manual_sycl/triangle_count/tc_lin.cpp @@ -0,0 +1,119 @@ +#include +#include +#include +#define DEBUG 0 + +using namespace sycl; + +int main(int argc, char **argv) +{ + + std::chrono::steady_clock::time_point tic_0 = std::chrono::steady_clock::now(); + std::ofstream logfile; + + std::string name = argv[1]; + int NUM_THREADS = atoi(argv[2]); + std::string NUM_THREADS_STR = std::to_string(NUM_THREADS); + + logfile.open("triangle_count/output/" + name + "_tc_lin_time_" + NUM_THREADS_STR + ".txt"); + + logfile << "Processing " << name << std::endl; + + default_selector d_selector; + queue Q(d_selector); + logfile << "Selected device: " << Q.get_device().get_info() << std::endl; + logfile << "Number of parallel work items: " << NUM_THREADS << std::endl; + + std::chrono::steady_clock::time_point tic = std::chrono::steady_clock::now(); + std::vector V, I, E, RE, RI; + load_from_file("csr_graphs/" + name + "/V", V); + load_from_file("csr_graphs/" + name + "/I", I); + load_from_file("csr_graphs/" + name + "/E", E); + + std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now(); + logfile << "Time to load data from files: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + int *dev_V = malloc_device(V.size(), Q); + int *dev_I = malloc_device(I.size(), Q); + int *dev_E = malloc_device(E.size(), Q); + + Q.submit([&](handler &h) + { h.memcpy(dev_V, &V[0], V.size() * sizeof(int)); }); + + Q.submit([&](handler &h) + { h.memcpy(dev_I, &I[0], I.size() * sizeof(int)); }); + + Q.submit([&](handler &h) + { h.memcpy(dev_E, &E[0], E.size() * sizeof(int)); }); + + Q.wait(); + + int N = V.size(); + int stride = NUM_THREADS; + + tic = std::chrono::steady_clock::now(); + logfile << "Starting triangle count..." << std::endl; + int triangle_count = 0; + logfile << "H1" << std::endl; + int *dev_triangle_count = malloc_device(1, Q); + logfile << "H2" << std::endl; + Q.submit([&](handler &h) + { h.memcpy(dev_triangle_count, &triangle_count, sizeof(int)); }) + .wait(); + logfile << "H3" << std::endl; + + Q.submit([&](handler &h) + { h.parallel_for( + NUM_THREADS, [=](id<1> i) + { + for (; i < N; i += stride) + { + for (int edge1 = dev_I[i]; edge1 < dev_I[i + 1]; edge1++) + { + int u = dev_E[edge1]; + if(u < i){ + for (int edge2 = dev_I[i]; edge2 < dev_I[i + 1]; edge2++){ + int w = dev_E[edge2]; + if(w > i){ + int nbrs_connected = 0; + for (int edge = dev_I[u]; edge < dev_I[u + 1]; edge++){ + int nbr = dev_E[edge]; + if(nbr == w){ + nbrs_connected = 1; + break; + } + } + if(nbrs_connected){ + atomic_ref atomic_data(*dev_triangle_count); + atomic_data+=1; + } + } + } + } + } +} }); }) + .wait(); + + toc = std::chrono::steady_clock::now(); + logfile << "Time to run triangle count: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + Q.submit([&](handler &h) + { h.memcpy(&triangle_count, dev_triangle_count, sizeof(int)); }) + .wait(); + + tic = std::chrono::steady_clock::now(); + std::ofstream resultfile; + + resultfile.open("triangle_count/output/" + name + "_tc_lin_result_" + NUM_THREADS_STR + ".txt"); + + resultfile << "Number of triangles in graph = " << triangle_count << std::endl; + + resultfile.close(); + toc = std::chrono::steady_clock::now(); + logfile << "Time to write data to file: " << std::chrono::duration_cast(toc - tic).count() << "[µs]" << std::endl; + + std::chrono::steady_clock::time_point toc_0 = std::chrono::steady_clock::now(); + logfile << "Total time taken: " << std::chrono::duration_cast(toc_0 - tic_0).count() << "[µs]" << std::endl; + + return 0; +} diff --git a/graphcode/manual_sycl/utils.h b/graphcode/manual_sycl/utils.h new file mode 100644 index 00000000..420ffca3 --- /dev/null +++ b/graphcode/manual_sycl/utils.h @@ -0,0 +1,23 @@ +#include +#include +#include + +void load_from_file(std::string filename, std::vector &vec) +{ + std::ifstream input; + input.open(filename); + int num; + while ((input >> num)) + { + vec.push_back(num); + } + input.close(); +} + +void print_vector(std::vector vec) +{ + for (auto x : vec) + std::cout << x << " "; + std::cout << "len = " << vec.size(); + std::cout << std::endl; +} \ No newline at end of file diff --git a/src/Makefile b/src/Makefile index 737acdfb..0f750aac 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ EXPENDABLES_WINDOWS = bin/MainContext.o bin/ASTHelper.o bin/SymbolTableBuilder.o bin/SymbolTableNew.o bin/y.tab.o bin/lex.yy.o parser/y.tab.c parser/lex.yy.c bin/deviceVarsAnalyser.o bin/analyserUtil.o bin/dv*.o bin/bv*.o EXPENDABLES = bin/MainContext.o bin/ASTHelper.o bin/SymbolTableBuilder.o bin/SymbolTableNew.o bin/y.tab.o bin/lex.yy.o parser/y.tab.c parser/lex.yy.c bin/deviceVarsAnalyser.o bin/blockVarsAnalyser.o ANALYSER = bin/dataRaceAnalyser.o -PROGRAMS = bin/MainContext.o bin/ASTHelper.o bin/SymbolTableBuilder.o bin/SymbolTableNew.o bin/y.tab.o bin/lex.yy.o bin/cu_dsl_cpp_generator.o bin/ac_dsl_cpp_generator.o bin/om_dsl_cpp_generator.o bin/mpi_dsl_cpp_generator.o bin/om_dyn_dsl_cpp_generator.o bin/mpi_dsl_cpp_generator_helper.o bin/mpi_dsl_cpp_expression_generator.o bin/mpi_dsl_cpp_statement_generator.o bin/mpi_dsl_dyn_cpp_generator.o +PROGRAMS = bin/MainContext.o bin/ASTHelper.o bin/SymbolTableBuilder.o bin/SymbolTableNew.o bin/y.tab.o bin/lex.yy.o bin/cu_dsl_cpp_generator.o bin/ac_dsl_cpp_generator.o bin/om_dsl_cpp_generator.o bin/mpi_dsl_cpp_generator.o bin/om_dyn_dsl_cpp_generator.o bin/mpi_dsl_cpp_generator_helper.o bin/mpi_dsl_cpp_expression_generator.o bin/mpi_dsl_cpp_statement_generator.o bin/mpi_dsl_dyn_cpp_generator.o bin/sycl_dsl_cpp_generator.o #bin/ac_dsl_cpp_generator.o #bin/om_dsl_cpp_generator.o A_PROGRAM = bin/attachPropAnalyser.o bin/dataRaceAnalyser.o bin/deviceVarsAnalyser.o bin/blockVarsAnalyser.o bin/analyserUtil.o @@ -39,6 +39,10 @@ bin/om_dsl_cpp_generator.o: backends/backend_omp/dsl_cpp_generator.cpp backends/ bin/mpi_dsl_cpp_generator.o: backends/backend_mpi/dsl_cpp_generator.h backends/backend_mpi/dsl_cpp_generator.cpp backends/dslCodePad.h $(CC) $(CFLAGS) -c backends/backend_mpi/dsl_cpp_generator.cpp -o bin/mpi_dsl_cpp_generator.o +#sycl +bin/sycl_dsl_cpp_generator.o: backends/backend_sycl/dsl_cpp_generator.cpp backends/dslCodePad.h + $(CC) $(CFLAGS) -c backends/backend_sycl/dsl_cpp_generator.cpp -o bin/sycl_dsl_cpp_generator.o + #dyn OMP bin/om_dyn_dsl_cpp_generator.o: backends/backend_omp/dsl_dyn_cpp_generator.cpp backends/dslCodePad.h $(CC) $(CFLAGS) -c backends/backend_omp/dsl_dyn_cpp_generator.cpp -o bin/om_dyn_dsl_cpp_generator.o diff --git a/src/backends/backend_sycl/analyserUtil.cpp b/src/backends/backend_sycl/analyserUtil.cpp new file mode 100644 index 00000000..4fcf5f24 --- /dev/null +++ b/src/backends/backend_sycl/analyserUtil.cpp @@ -0,0 +1,197 @@ +#ifndef ANALYSER_UTILITY +#define ANALYSER_UTILITY + +#include "../../ast/ASTNodeTypes.hpp" +#include +#include "../../symbolutil/SymbolTable.h" + +#define propKey pair + +enum variable_type +{ + READ = 1, + WRITE, + READ_WRITE +}; + +class usedVariables +{ +private: + struct hash_pair + { + template + size_t operator()(const pair &p) const + { + auto hash1 = hash{}(p.first); + auto hash2 = hash{}(p.second); + return hash1 ^ hash2; + } + }; + + unordered_map readVars, writeVars; + unordered_map readProp, writeProp; + +public: + usedVariables() {} + + void addVariable(Identifier *iden, int type) + { + if (type & 1) + readVars.insert({iden->getSymbolInfo(), iden}); + if (type & 2) + writeVars.insert({iden->getSymbolInfo(), iden}); + } + + void addPropAccess(PropAccess *prop, int type) + { + Identifier *iden1 = prop->getIdentifier1(); + Identifier *iden2 = prop->getIdentifier2(); + propKey prop_key = make_pair(iden1->getSymbolInfo(), iden2->getSymbolInfo()); + + if (type & 1) + readProp.insert({prop_key, prop}); + if (type & 2) + writeProp.insert({prop_key, prop}); + } + + void merge(usedVariables usedVars1) + { + for (pair iden : usedVars1.readVars) + this->readVars.insert({iden.first, iden.second}); + + for (pair iden : usedVars1.writeVars) + this->writeVars.insert({iden.first, iden.second}); + + for (pair iden : usedVars1.readProp) + this->readProp.insert({iden.first, iden.second}); + + for (pair iden : usedVars1.writeProp) + this->writeProp.insert({iden.first, iden.second}); + } + + void removeVariable(Identifier *iden, int type) + { + TableEntry *symbInfo = iden->getSymbolInfo(); + if (type & 1) + { + if (readVars.find(symbInfo) != readVars.end()) + readVars.erase(symbInfo); + } + + if (type & 2) + { + if (writeVars.find(symbInfo) != writeVars.end()) + writeVars.erase(symbInfo); + } + } + + bool isUsedVar(Identifier *iden, int type = READ_WRITE) + { + TableEntry *symbInfo = iden->getSymbolInfo(); + if (type == READ) + return (readVars.find(symbInfo) != readVars.end()); + else if (type == WRITE) + return (writeVars.find(symbInfo) != writeVars.end()); + else + return ((readVars.find(symbInfo) != readVars.end()) || (writeVars.find(symbInfo) != writeVars.end())); + } + + list getVariables(int type = READ_WRITE) + { + list result; + + if (type == READ) + { + for (pair iden : readVars) + result.push_back(iden.second); + } + else if (type == WRITE) + { + for (pair iden : writeVars) + result.push_back(iden.second); + } + else if (type == READ_WRITE) + { + for (pair iden : readVars) + result.push_back(iden.second); + + for (pair iden : writeVars) + { + if (readVars.find(iden.first) == readVars.end()) + result.push_back(iden.second); + } + } + return result; + } + + bool hasVariables(int type = READ_WRITE) + { + if (type == READ) + return (readVars.size() > 0); + else if (type == WRITE) + return (writeVars.size() > 0); + else + return ((writeVars.size() > 0) || (readVars.size() > 0)); + } + + bool isUsedPropAcess(PropAccess *propId, int type = READ_WRITE) + { + Identifier *iden1 = propId->getIdentifier1(); + Identifier *iden2 = propId->getIdentifier2(); + propKey prop_key = make_pair(iden1->getSymbolInfo(), iden2->getSymbolInfo()); + + if (type == READ) + return (readProp.find(prop_key) != readProp.end()); + else if (type == WRITE) + return (writeProp.find(prop_key) != writeProp.end()); + else + return ((readProp.find(prop_key) != readProp.end()) || (writeProp.find(prop_key) != writeProp.end())); + } + + bool isUsedProp(PropAccess *propId, int type = READ_WRITE) + { + Identifier *iden2 = propId->getIdentifier2(); + TableEntry *symbInfo = iden2->getSymbolInfo(); + + if (type & 1) + { + for (pair iden : readProp) + if (iden.first.second == symbInfo) + return true; + } + if (type & 2) + { + for (pair iden : writeProp) + if (iden.first.second == symbInfo) + return true; + } + return false; + } + + list getPropAcess(int type = READ_WRITE) + { + list result; + if (type & 1) + { + for (pair iden : readProp) + result.push_back(iden.second); + } + if (type & 2) + { + for (pair iden : writeProp) + result.push_back(iden.second); + } + return result; + } + + void clear() + { + readVars.clear(); + writeVars.clear(); + + readProp.clear(); + writeProp.clear(); + } +}; + +#endif \ No newline at end of file diff --git a/src/backends/backend_sycl/dsl_cpp_generator.cpp b/src/backends/backend_sycl/dsl_cpp_generator.cpp new file mode 100644 index 00000000..3fdfb3c4 --- /dev/null +++ b/src/backends/backend_sycl/dsl_cpp_generator.cpp @@ -0,0 +1,2083 @@ +#include + +#include + +#include "../../ast/ASTHelper.cpp" +#include "dsl_cpp_generator.h" +#include "getUsedVars.cpp" + +bool flag_for_device_variable = 0; // temporary fix to accomodate device variable and +std::unordered_set fixedPointVariables = {}; +//~ using namespace spsycl; +namespace spsycl +{ + + void dsl_cpp_generator::addIncludeToFile(const char *includeName, dslCodePad &file, bool isCppLib) + { + if (!isCppLib) + file.push('"'); + else + file.push('<'); + + file.pushString(includeName); + if (!isCppLib) + file.push('"'); + else + file.push('>'); + file.NewLine(); + } + + void dsl_cpp_generator::generation_begin() + { + char temp[1024]; + main.pushString("#ifndef GENCPP_"); + main.pushUpper(fileName); + main.pushstr_newL("_H"); + main.pushString("#define GENCPP_"); + main.pushUpper(fileName); + main.pushstr_newL("_H"); + main.pushString("#include "); + addIncludeToFile("CL/sycl.hpp", main, true); + main.pushString("#include "); + addIncludeToFile("iostream", main, true); + main.pushString("#include "); + addIncludeToFile("fstream", main, true); + main.pushString("#include "); + addIncludeToFile("../graph.hpp", main, false); + main.pushstr_newL("using namespace sycl;"); + main.NewLine(); + } + + void dsl_cpp_generator::setCurrentFunc(Function *func) + { + currentFunc = func; + } + + const char *dsl_cpp_generator::convertToCppType(Type *type, bool isElementOfProp = false) + { + if (type->isPrimitiveType()) + { + int typeId = type->gettypeId(); + switch (typeId) + { + case TYPE_INT: + return "int"; + case TYPE_BOOL: + return "bool"; + case TYPE_LONG: + return "long"; + case TYPE_FLOAT: + return "float"; + case TYPE_DOUBLE: + return "double"; + case TYPE_NODE: + return "int"; + case TYPE_EDGE: + return "int"; + default: + assert(false); + } + } + else if (type->isPrimitiveType() || isElementOfProp) + { + Type *targetType = type->getInnerTargetType(); + if (targetType->isPrimitiveType()) + { + int typeId = targetType->gettypeId(); + switch (typeId) + { + case TYPE_INT: + return "int"; + case TYPE_BOOL: + return "bool"; + case TYPE_LONG: + return "long"; + case TYPE_FLOAT: + return "float"; + case TYPE_DOUBLE: + return "double"; + default: + assert(false); + } + } + } + else if (type->isPropType()) + { + Type *targetType = type->getInnerTargetType(); + if (targetType->isPrimitiveType()) + { + int typeId = targetType->gettypeId(); + switch (typeId) + { + case TYPE_INT: + return "int*"; + case TYPE_BOOL: + return "bool*"; + case TYPE_LONG: + return "long*"; + case TYPE_FLOAT: + return "float*"; + case TYPE_DOUBLE: + return "double*"; + default: + assert(false); + } + } + } + else if (type->isNodeEdgeType()) + { + return "int"; // need to be modified. + } + else if (type->isGraphType()) + { + return "graph&"; + } + else if (type->isCollectionType()) + { + int typeId = type->gettypeId(); + + switch (typeId) + { + case TYPE_SETN: + return "std::set&"; + + default: + assert(false); + } + } + + return "NA"; + } + + void dsl_cpp_generator::generateCSRArrays(const char *gId) + { + char strBuffer[1024]; + // assuming DSL does not contain variables V and E + sprintf(strBuffer, "int V = %s.num_nodes();", gId); + main.pushstr_newL(strBuffer); + sprintf(strBuffer, "int E = %s.num_edges();", gId); + main.pushstr_newL(strBuffer); + main.NewLine(); + + main.pushstr_newL("printf(\"#nodes:%d\\n\",V);"); + main.pushstr_newL("printf(\"#edges:\%d\\n\",E);"); + + sprintf(strBuffer, "int* edgeLen = %s.getEdgeLen();", gId); // assuming DSL do not contain variables as V and E + main.pushstr_newL(strBuffer); + main.NewLine(); + + // These H & D arrays of CSR do not change. Hence hardcoded! + main.pushstr_newL("int *h_meta;"); + main.pushstr_newL("int *h_data;"); + main.pushstr_newL("int *h_src;"); + main.pushstr_newL("int *h_weight;"); + main.pushstr_newL("int *h_rev_meta;"); // done only to handle PR since other doesn't uses it + main.NewLine(); + + main.pushstr_newL("h_meta = (int *)malloc( (V+1)*sizeof(int));"); + main.pushstr_newL("h_data = (int *)malloc( (E)*sizeof(int));"); + main.pushstr_newL("h_src = (int *)malloc( (E)*sizeof(int));"); + main.pushstr_newL("h_weight = (int *)malloc( (E)*sizeof(int));"); + main.pushstr_newL("h_rev_meta = (int *)malloc( (V+1)*sizeof(int));"); + main.NewLine(); + + main.pushstr_newL("for(int i=0; i<= V; i++) {"); + sprintf(strBuffer, "int temp = %s.indexofNodes[i];", gId); + main.pushstr_newL(strBuffer); + main.pushstr_newL("h_meta[i] = temp;"); + sprintf(strBuffer, "temp = %s.rev_indexofNodes[i];", gId); + main.pushstr_newL(strBuffer); + main.pushstr_newL("h_rev_meta[i] = temp;"); + main.pushstr_newL("}"); + main.NewLine(); + + main.pushstr_newL("for(int i=0; i< E; i++) {"); + sprintf(strBuffer, "int temp = %s.edgeList[i];", gId); + main.pushstr_newL(strBuffer); + main.pushstr_newL("h_data[i] = temp;"); + sprintf(strBuffer, "temp = %s.srcList[i];", gId); + main.pushstr_newL(strBuffer); + main.pushstr_newL("h_src[i] = temp;"); + main.pushstr_newL("temp = edgeLen[i];"); + main.pushstr_newL("h_weight[i] = temp;"); + main.pushstr_newL("}"); + main.NewLine(); + } + + void dsl_cpp_generator::generateFuncHeader(Function *proc) + { + main.pushString("void "); + main.pushString(proc->getIdentifier()->getIdentifier()); + + main.push('('); + int maximum_arginline = 4; + int arg_currNo = 0; + int argumentTotal = proc->getParamList().size(); + list paramList = proc->getParamList(); + list::iterator itr; + + for (itr = paramList.begin(); itr != paramList.end(); itr++) + { + arg_currNo++; + argumentTotal--; + + Type *type = (*itr)->getType(); + main.pushString(convertToCppType(type)); + char *parName = (*itr)->getIdentifier()->getIdentifier(); + + main.pushString(" "); + char str[80]; + strcpy(str, "d_"); + strcat(str, (*itr)->getIdentifier()->getIdentifier()); + cout << "param :" << parName << endl; + cout << "paramD:" << str << endl; + + if (type->isGraphType()) + { + std::cout << "========== SET TRUE" << '\n'; + genCSR = true; + } + + main.pushString(parName); + if (argumentTotal > 0) + main.pushString(","); + if (arg_currNo == maximum_arginline) + { + main.NewLine(); + arg_currNo = 0; + } + } + + main.pushString(")"); + main.NewLine(); + return; + } + + void dsl_cpp_generator::generateMallocDeviceStr(const char *dVar, const char *typeStr, const char *sizeOfType) + { + char strBuffer[1024]; + sprintf(strBuffer, "%s=malloc_device<%s>(%s, Q);", dVar, typeStr, sizeOfType); + main.pushstr_newL(strBuffer); + } + + // Only for device variables + void dsl_cpp_generator::generateMallocDevice(Type *type, const char *identifier) + { + char strBuffer[1024]; + sprintf(strBuffer, "d_%s=malloc_device<%s>(%s, Q);", identifier, + convertToCppType(type->getInnerTargetType()), + (type->isPropNodeType()) + ? "V" + : "E"); // this assumes PropNode type IS PROPNODE? V : E + + main.pushstr_newL(strBuffer); + main.NewLine(); + } + + void dsl_cpp_generator::generateMallocDeviceParams(list paramList) + { + list::iterator itr; + for (itr = paramList.begin(); itr != paramList.end(); itr++) + { + Type *type = (*itr)->getType(); + if (type->isPropType()) + { + Type *innerType = type->getInnerTargetType(); + main.pushString(convertToCppType(innerType)); + main.pushString("*"); + main.space(); + char str[80]; + strcpy(str, "d_"); + strcat(str, (*itr)->getIdentifier()->getIdentifier()); + main.pushString(str); + main.pushstr_newL(";"); + generateMallocDevice(type, (*itr)->getIdentifier()->getIdentifier()); + } + } + } + + void dsl_cpp_generator::generateMemCpyStr(const char *sVarName, const char *tVarName, const char *type, const char *sizeV) + { + char strBuffer[1024]; + sprintf(strBuffer, "Q.submit([&](handler &h)"); + main.pushstr_newL(strBuffer); + + sprintf(strBuffer, "{ h.memcpy(%8s, %8s, sizeof(%3s)*(%s)); })", sVarName, tVarName, type, sizeV); + main.pushstr_newL(strBuffer); + + sprintf(strBuffer, ".wait();"); + main.pushstr_newL(strBuffer); + } + + void dsl_cpp_generator::generateLaunchConfig() + { + // int NUM_THREADS = 1048576; + // int stride = NUM_THREADS; + + char strBuffer[1024]; + main.NewLine(); + + sprintf(strBuffer, "int NUM_THREADS = 1048576;"); + main.pushstr_newL(strBuffer); + + sprintf(strBuffer, "int stride = NUM_THREADS;"); + main.pushstr_newL(strBuffer); + } + + void dsl_cpp_generator::generateFuncBody(Function *proc) + { + char strBuffer[1024]; + int maximum_arginline = 4; + int arg_currNo = 0; + int argumentTotal = proc->getParamList().size(); + list paramList = proc->getParamList(); + list::iterator itr; + + const char *gId; + + for (itr = paramList.begin(); itr != paramList.end(); itr++) + { + arg_currNo++; + argumentTotal--; + + Type *type = (*itr)->getType(); + + const char *parName = (*itr)->getIdentifier()->getIdentifier(); + cout << "param:" << parName << endl; + if (type->isGraphType()) + { + genCSR = true; + gId = parName; + } + + if (arg_currNo == maximum_arginline) + { + arg_currNo = 0; + } + } + + sprintf(strBuffer, "queue Q(default_selector_v);"); + main.pushstr_newL(strBuffer); + sprintf(strBuffer, "std::cout << \"Selected device: \" << Q.get_device().get_info() << std::endl;"); + main.pushstr_newL(strBuffer); + + if (genCSR) + { + main.pushstr_newL("// CSR BEGIN"); + generateCSRArrays(gId); + + main.NewLine(); + sprintf(strBuffer, "int* d_meta;"); + main.pushstr_newL(strBuffer); + sprintf(strBuffer, "int* d_data;"); + main.pushstr_newL(strBuffer); + sprintf(strBuffer, "int* d_src;"); + main.pushstr_newL(strBuffer); + sprintf(strBuffer, "int* d_weight;"); + main.pushstr_newL(strBuffer); + sprintf(strBuffer, "int* d_rev_meta;"); + main.pushstr_newL(strBuffer); + sprintf(strBuffer, "bool* d_modified_next;"); + main.pushstr_newL(strBuffer); + main.NewLine(); + + generateMallocDeviceStr("d_meta", "int", "(1+V)"); + generateMallocDeviceStr("d_data", "int", "(E)"); + generateMallocDeviceStr("d_src", "int", "(E)"); + generateMallocDeviceStr("d_weight", "int", "(E)"); + generateMallocDeviceStr("d_rev_meta", "int", "(V+1)"); + generateMallocDeviceStr("d_modified_next", "bool", "(V)"); + + main.NewLine(); + + generateMemCpyStr("d_meta", "h_meta", "int", "V+1"); + generateMemCpyStr("d_data", "h_data", "int", "E"); + generateMemCpyStr("d_src", "h_src", "int", "E"); + generateMemCpyStr("d_weight", "h_weight", "int", "E"); + generateMemCpyStr("d_rev_meta", "h_rev_meta", "int", "(V+1)"); + main.NewLine(); + + main.pushstr_newL("// CSR END"); + + main.pushString("//LAUNCH CONFIG"); + + generateLaunchConfig(); + + main.NewLine(); + + main.pushstr_newL("// TIMER START"); + generateStartTimer(); + } + } + + void dsl_cpp_generator::castIfRequired(Type *type, Identifier *methodID, dslCodePad &main) + { + string predefinedFunc("num_nodes"); + if (predefinedFunc.compare(methodID->getIdentifier()) == 0) + { + if (type->gettypeId() != TYPE_INT) + { + char strBuffer[1024]; + sprintf(strBuffer, "(%s)", convertToCppType(type)); + main.pushString(strBuffer); + } + } + } + + void dsl_cpp_generator::generate_exprLiteral(Expression *expr, bool isMainFile) + { + char valBuffer[1024]; + + int expr_valType = expr->getExpressionFamily(); + + switch (expr_valType) + { + case EXPR_INTCONSTANT: + sprintf(valBuffer, "%ld", expr->getIntegerConstant()); + break; + + case EXPR_FLOATCONSTANT: + sprintf(valBuffer, "%lf", expr->getFloatConstant()); + break; + case EXPR_BOOLCONSTANT: + sprintf(valBuffer, "%s", expr->getBooleanConstant() ? "true" : "false"); + break; + default: + assert(false); + } + + main.pushString(valBuffer); + } + + void dsl_cpp_generator::generate_exprInfinity(Expression *expr, bool isMainFile) + { + char valBuffer[1024]; + if (expr->getTypeofExpr()) + { + int typeClass = expr->getTypeofExpr(); + switch (typeClass) + { + case TYPE_INT: + sprintf(valBuffer, "%s", + expr->isPositiveInfinity() ? "INT_MAX" : "INT_MIN"); + break; + case TYPE_LONG: + sprintf(valBuffer, "%s", + expr->isPositiveInfinity() ? "LLONG_MAX" : "LLONG_MIN"); + break; + case TYPE_FLOAT: + sprintf(valBuffer, "%s", + expr->isPositiveInfinity() ? "FLT_MAX" : "FLT_MIN"); + break; + case TYPE_DOUBLE: + sprintf(valBuffer, "%s", + expr->isPositiveInfinity() ? "DBL_MAX" : "DBL_MIN"); + break; + default: + sprintf(valBuffer, "%s", + expr->isPositiveInfinity() ? "INT_MAX" : "INT_MIN"); + break; + } + } + else + { + sprintf(valBuffer, "%s", expr->isPositiveInfinity() ? "INT_MAX" : "INT_MIN"); + } + main.pushString(valBuffer); + } + + void dsl_cpp_generator::generate_exprPropId(PropAccess *propId, bool isMainFile) + { + char strBuffer[1024]; + Identifier *id1 = propId->getIdentifier1(); + Identifier *id2 = propId->getIdentifier2(); + ASTNode *propParent = propId->getParent(); + bool relatedToReduction = + propParent != NULL ? propParent->getTypeofNode() == NODE_REDUCTIONCALLSTMT + : false; + if (id2->getSymbolInfo() != NULL && + id2->getSymbolInfo()->getId()->get_fp_association() && + relatedToReduction) + { + sprintf(strBuffer, "d_%s_next[%s]", id2->getIdentifier(), + id1->getIdentifier()); + } + else + { + if (!isMainFile) + sprintf(strBuffer, "d_%s[%s]", id2->getIdentifier(), id1->getIdentifier()); // PREFIX D + else + sprintf(strBuffer, "%s[%s]", id2->getIdentifier(), id1->getIdentifier()); + } + main.pushString(strBuffer); + } + + void dsl_cpp_generator::generate_exprArL(Expression *expr, bool isMainFile, bool isAtomic) + { + if (expr->hasEnclosedBrackets()) + { + main.pushString("("); + } + if (!isAtomic) + generateExpr(expr->getLeft(), isMainFile); + main.space(); + const char *operatorString = getOperatorString(expr->getOperatorType()); + if (!isAtomic) + main.pushstr_space(operatorString); + generateExpr(expr->getRight(), isMainFile); + if (expr->hasEnclosedBrackets()) + { + main.pushString(")"); + } + } + + void dsl_cpp_generator::generate_exprRelational(Expression *expr, bool isMainFile) + { + if (expr->hasEnclosedBrackets()) + { + main.pushString("("); + } + generateExpr(expr->getLeft(), isMainFile); + + main.space(); + const char *operatorString = getOperatorString(expr->getOperatorType()); + main.pushstr_space(operatorString); + generateExpr(expr->getRight(), isMainFile); + if (expr->hasEnclosedBrackets()) + { + main.pushString(")"); + } + } + + void dsl_cpp_generator::generate_exprProcCall(Expression *expr, bool isMainFile) + { + proc_callExpr *proc = (proc_callExpr *)expr; + string methodId(proc->getMethodId()->getIdentifier()); + if (methodId == "get_edge") + { + main.pushString("edge"); + } + else if (methodId == "count_outNbrs") + { + char strBuffer[1024]; + list argList = proc->getArgList(); + assert(argList.size() == 1); + Identifier *nodeId = argList.front()->getExpr()->getId(); + sprintf(strBuffer, "(%s[%s+1]-%s[%s])", "d_meta", nodeId->getIdentifier(), "d_meta", nodeId->getIdentifier()); + main.pushString(strBuffer); + } + else if (methodId == "is_an_edge") + { + char strBuffer[1024]; + list argList = proc->getArgList(); + assert(argList.size() == 2); + Identifier *srcId = argList.front()->getExpr()->getId(); + Identifier *destId = argList.back()->getExpr()->getId(); + //~ Identifier* objectId = proc->getId1(); + sprintf(strBuffer, "%s(%s, %s, %s, %s)", "findNeighborSorted", srcId->getIdentifier(), destId->getIdentifier(), "d_meta", "d_data"); + main.pushString(strBuffer); + } + else + { + char strBuffer[1024]; + list argList = proc->getArgList(); + if (argList.size() == 0) + { + Identifier *objectId = proc->getId1(); + sprintf(strBuffer, "%s.%s( )", objectId->getIdentifier(), proc->getMethodId()->getIdentifier()); + main.pushString(strBuffer); + } + } + } + + void dsl_cpp_generator::generate_exprUnary(Expression *expr, bool isMainFile) + { + if (expr->hasEnclosedBrackets()) + { + main.pushString("("); + } + + if (expr->getOperatorType() == OPERATOR_NOT) + { + const char *operatorString = getOperatorString(expr->getOperatorType()); + main.pushString(operatorString); + generateExpr(expr->getUnaryExpr(), isMainFile); + } + + if (expr->getOperatorType() == OPERATOR_INC || + expr->getOperatorType() == OPERATOR_DEC) + { + generateExpr(expr->getUnaryExpr(), isMainFile); + const char *operatorString = getOperatorString(expr->getOperatorType()); + main.pushString(operatorString); + } + + if (expr->hasEnclosedBrackets()) + { + main.pushString(")"); + } + } + + void dsl_cpp_generator::generate_exprIdentifier(Identifier *id, bool isMainFile) + { + main.pushString(id->getIdentifier()); + } + + void dsl_cpp_generator::generateExpr(Expression *expr, bool isMainFile, bool isAtomic) + { + if (expr->isLiteral()) + { + generate_exprLiteral(expr, isMainFile); + } + else if (expr->isInfinity()) + { + generate_exprInfinity(expr, isMainFile); + } + else if (expr->isIdentifierExpr()) + { + generate_exprIdentifier(expr->getId(), isMainFile); + } + else if (expr->isPropIdExpr()) + { + generate_exprPropId(expr->getPropId(), isMainFile); + } + else if (expr->isArithmetic() || expr->isLogical()) + { + generate_exprArL(expr, isMainFile, isAtomic); + } + else if (expr->isRelational()) + { + generate_exprRelational(expr, isMainFile); + } + else if (expr->isProcCallExpr()) + { + generate_exprProcCall(expr, isMainFile); + } + else if (expr->isUnary()) + { + generate_exprUnary(expr, isMainFile); + } + else + { + assert(false); + } + } + + void dsl_cpp_generator::generateVariableDecl(declaration *declStmt, bool isMainFile) + { + Type *type = declStmt->getType(); + + if (type->isPropType()) + { + if (type->getInnerTargetType()->isPrimitiveType()) + { + Type *innerType = type->getInnerTargetType(); + main.pushString(convertToCppType(innerType)); + main.pushString("*"); + main.space(); + main.pushString("d_"); + main.pushString(declStmt->getdeclId()->getIdentifier()); + main.pushstr_newL(";"); + generateMallocDevice(type, declStmt->getdeclId()->getIdentifier()); + } + } + else if (type->isPrimitiveType()) + { + char strBuffer[1024]; + const char *varType = convertToCppType(type); + const char *varName = declStmt->getdeclId()->getIdentifier(); + cout << "varT:" << varType << endl; + cout << "varN:" << varName << endl; + + sprintf(strBuffer, "%s %s", varType, varName); + main.pushString(strBuffer); + + if (declStmt->isInitialized()) + { + main.pushString(" = "); + if (declStmt->getExpressionAssigned()->getExpressionFamily() == EXPR_PROCCALL) + { + proc_callExpr *pExpr = (proc_callExpr *)declStmt->getExpressionAssigned(); + Identifier *methodId = pExpr->getMethodId(); + castIfRequired(type, methodId, main); + } + generateExpr(declStmt->getExpressionAssigned(), isMainFile); // PRINTS RHS? YES + } + main.pushstr_newL("; // asst in main"); + main.NewLine(); + } + else if (type->isNodeEdgeType()) + { + main.pushstr_space(convertToCppType(type)); + main.pushString(declStmt->getdeclId()->getIdentifier()); + if (declStmt->isInitialized()) + { + main.pushString(" = "); + generateExpr(declStmt->getExpressionAssigned(), isMainFile); + main.pushstr_newL(";"); + } + } + } + + void dsl_cpp_generator::generateDeviceAssignmentStmt(assignment *asmt, bool isMainFile) + { + bool isDevice = false; + std::cout << "\tASST \n"; + char strBuffer[300]; + if (asmt->lhs_isIdentifier()) + { + Identifier *id = asmt->getId(); + + main.pushString(id->getIdentifier()); + } + else if (asmt->lhs_isProp()) // the check for node and edge property to be carried out. + { + PropAccess *propId = asmt->getPropId(); + if (asmt->isDeviceAssignment()) + { + isDevice = true; + Type *typeB = propId->getIdentifier2()->getSymbolInfo()->getType()->getInnerTargetType(); + const char *varType = convertToCppType(typeB); + + main.pushstr_newL("Q.submit([&](handler &h){ h.single_task([=](){"); + + sprintf(strBuffer, "d_%s[%s] = (%s)", + propId->getIdentifier2()->getIdentifier(), + propId->getIdentifier1()->getIdentifier(), + varType); + main.pushString(strBuffer); + } + else + { + main.pushString("d_"); /// IMPORTANT + main.pushString(propId->getIdentifier2()->getIdentifier()); + main.push('['); + main.pushString(propId->getIdentifier1()->getIdentifier()); + main.push(']'); + } + } + + if (!isDevice) + main.pushString(" = "); + + generateExpr(asmt->getExpr(), isMainFile); + + if (isDevice) + { + main.pushstr_newL(";});"); + main.pushstr_newL("}).wait(); //InitIndexDevice"); + main.NewLine(); + } + else + main.pushstr_newL("; //InitIndex"); + } + + void dsl_cpp_generator::generateAtomicDeviceAssignmentStmt(assignment *asmt, bool isMainFile) + { + bool isAtomic = false; + bool isResult = false; + std::cout << "\tASST\n"; + char strBuffer[1024]; + + if (asmt->lhs_isIdentifier()) + { + Identifier *id = asmt->getId(); + Expression *exprAssigned = asmt->getExpr(); + if (asmt->hasPropCopy()) // prop_copy is of the form (propId = propId) + { + char strBuffer[1024]; + Identifier *rhsPropId2 = exprAssigned->getId(); + Type *type = id->getSymbolInfo()->getType(); + main.pushstr_newL("Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){"); + sprintf(strBuffer, "for (; i < V; i += stride) d_%s[i] = d_%s[i];", id->getIdentifier(), rhsPropId2->getIdentifier()); + main.pushString(strBuffer); + main.pushstr_newL("}); }).wait();"); + } + else + { + if (fixedPointVariables.find(id->getIdentifier()) != fixedPointVariables.end()) + { + main.pushString("*d_"); + } + main.pushString(id->getIdentifier()); + } + } + else if (asmt->lhs_isProp()) // the check for node and edge property to be + // carried out. + { + PropAccess *propId = asmt->getPropId(); + bool defaultAction = true; + if (asmt->isDeviceAssignment()) + { + std::cout << "\t DEVICE ASST" << '\n'; + defaultAction = false; + main.pushString("d_"); /// IMPORTANT + main.pushString(propId->getIdentifier2()->getIdentifier()); + main.push('['); + main.pushString(propId->getIdentifier1()->getIdentifier()); + main.push(']'); + } + if (asmt->getAtomicSignal()) + { + main.pushstr_newL("// atomic update"); + defaultAction = false; + const char *typVar = convertToCppType(propId->getIdentifier2()->getSymbolInfo()->getType(), true); + sprintf(strBuffer, "atomic_ref<%s, memory_order::relaxed, memory_scope::device, access::address_space::global_space> atomic_data(", typVar); + main.pushString(strBuffer); + main.pushString("d_"); /// IMPORTANT + main.pushString(propId->getIdentifier2()->getIdentifier()); + main.push('['); + main.pushString(propId->getIdentifier1()->getIdentifier()); + main.push(']'); + isAtomic = true; + std::cout << "\t ATOMIC ASST" << '\n'; + } + if (asmt->isAccumulateKernel()) + { // NOT needed + isResult = true; + std::cout << "\t RESULT NO BC by 2 ASST" << '\n'; + defaultAction = false; + main.pushString("d_"); /// IMPORTANT + main.pushString(propId->getIdentifier2()->getIdentifier()); + main.push('['); + main.pushString(propId->getIdentifier1()->getIdentifier()); + main.push(']'); + } + if (defaultAction) + { + main.pushString("d_"); /// IMPORTANT + main.pushString(propId->getIdentifier2()->getIdentifier()); + main.push('['); + main.pushString(propId->getIdentifier1()->getIdentifier()); + main.push(']'); + } + } + + if (isAtomic) + { + main.pushstr_newL(");"); + main.pushString("atomic_data += "); + } + else if (!asmt->hasPropCopy()) + main.pushString(" = "); + + //~ std::cout<< "------>BEG EXP" << '\n'; + if (!asmt->hasPropCopy()) + generateExpr(asmt->getExpr(), isMainFile, isAtomic); + //~ std::cout<< "------>END EXP" << '\n'; + + if (isAtomic) + main.pushstr_newL(";"); + else if (isResult) + main.pushstr_newL(";"); // No need "/2.0;" for directed graphs + else if (!asmt->hasPropCopy()) + main.pushstr_newL(";"); + } + + void dsl_cpp_generator::generateIfStmt(ifStmt *ifstmt, bool isMainFile) + { + Expression *condition = ifstmt->getCondition(); + main.pushString("if ("); + std::cout << "=======IF FILTER" << '\n'; + generateExpr(condition, isMainFile); + main.pushstr_newL("){ // if filter begin "); + + generateStatement(ifstmt->getIfBody(), isMainFile); + main.pushstr_newL("} // if filter end"); + if (ifstmt->getElseBody() == NULL) + return; + main.pushstr_newL("else"); + generateStatement(ifstmt->getElseBody(), isMainFile); + } + + void dsl_cpp_generator::generateDoWhileStmt(dowhileStmt *doWhile, bool isMainFile) + { + flag_for_device_variable = 1; // done for PR fix + main.pushstr_newL("do{"); + generateStatement(doWhile->getBody(), isMainFile); + main.pushString("}while("); + generateExpr(doWhile->getCondition(), isMainFile); + main.pushstr_newL(");"); + } + + void dsl_cpp_generator::generateMemCpySymbol(char *var, const char *typeStr, bool direction) + { + char strBuffer[1024]; + if (direction) + { + sprintf(strBuffer, "%s *d_%s = malloc_device<%s>(1, Q);", typeStr, var, typeStr); + main.pushstr_newL(strBuffer); + main.pushstr_newL("Q.submit([&](handler &h)"); + sprintf(strBuffer, "{ h.memcpy(d_%s, &%s, 1 * sizeof(%s)); })", var, var, typeStr); + main.pushstr_newL(strBuffer); + main.pushstr_newL(".wait();"); + main.NewLine(); + } + else + { + main.pushstr_newL("Q.submit([&](handler &h)"); + sprintf(strBuffer, "{ h.memcpy(&%s, d_%s, 1 * sizeof(%s)); })", var, var, typeStr); + main.pushstr_newL(strBuffer); + main.pushstr_newL(".wait();"); + main.NewLine(); + } + } + + blockStatement *dsl_cpp_generator::includeIfToBlock(forallStmt *forAll) + { + Expression *filterExpr = forAll->getfilterExpr(); + Expression *modifiedFilterExpr = filterExpr; + if (filterExpr->getExpressionFamily() == EXPR_RELATIONAL) + { + Expression *expr1 = filterExpr->getLeft(); + Expression *expr2 = filterExpr->getRight(); + if (expr1->isIdentifierExpr()) + { + /*if it is a nodeproperty, the filter is on the nodes that are iterated on + One more check can be applied to check if the iterating type is a neigbor + iteration or allgraph iterations. + */ + if (expr1->getId()->getSymbolInfo() != NULL) + { + if (expr1->getId()->getSymbolInfo()->getType()->isPropNodeType()) + { + Identifier *iterNode = forAll->getIterator(); + Identifier *nodeProp = expr1->getId(); + PropAccess *propIdNode = (PropAccess *)Util::createPropIdNode(iterNode, nodeProp); + Expression *propIdExpr = Expression::nodeForPropAccess(propIdNode); + modifiedFilterExpr = (Expression *)Util::createNodeForRelationalExpr(propIdExpr, expr2, filterExpr->getOperatorType()); + } + } + } + } + + ifStmt *ifNode = (ifStmt *)Util::createNodeForIfStmt(modifiedFilterExpr, forAll->getBody(), NULL); + blockStatement *newBlock = new blockStatement(); + newBlock->setTypeofNode(NODE_BLOCKSTMT); + newBlock->addStmtToBlock(ifNode); + return newBlock; + } + + void dsl_cpp_generator::addKernel(forallStmt *forAll) + { + Identifier *iterator = forAll->getIterator(); + const char *loopVar = iterator->getIdentifier(); + char strBuffer[1024]; + + usedVariables usedVars = getVariablesForAll(forAll); + list vars = usedVars.getVariables(); + + sprintf(strBuffer, "Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> %s){for (; %s < V; %s += NUM_THREADS)", loopVar, loopVar, loopVar); + main.pushString(strBuffer); + main.pushstr_newL("{ // BEGIN KER FUN via ADDKERNEL"); + + if (forAll->hasFilterExpr()) + { + blockStatement *changedBody = includeIfToBlock(forAll); + cout << "============CHANGED BODY TYPE==============" << (changedBody->getTypeofNode() == NODE_BLOCKSTMT); + forAll->setBody(changedBody); + } + + statement *body = forAll->getBody(); + assert(body->getTypeofNode() == NODE_BLOCKSTMT); + blockStatement *block = (blockStatement *)body; + list statementList = block->returnStatements(); + + printf("start of kernel block \n"); + + for (statement *stmt : statementList) + { + generateStatement(stmt, false); // false. All these stmts should be inside kernel + //~ if (stmt->getTypeofNode() == NODE_FORALLSTMT) { + } + main.pushstr_newL("}"); + main.pushstr_newL("}); }).wait(); // end KER FUNC"); + main.NewLine(); + } + + bool dsl_cpp_generator::allGraphIteration(char *methodId) + { + string methodString(methodId); + + return (methodString == "nodes" || methodString == "edges"); + } + + bool dsl_cpp_generator::neighbourIteration(char *methodId) + { + string methodString(methodId); + return (methodString == "neighbors" || methodString == "nodes_to"); + } + + bool dsl_cpp_generator::elementsIteration(char *extractId) + { + string extractString(extractId); + return (extractString == "elements"); + } + + void dsl_cpp_generator::generateInitkernelStr(const char *inVarType, const char *inVarName, const char *initVal) + { + char strBuffer[1024]; + main.pushstr_newL("Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){"); + sprintf(strBuffer, "for (; i < V; i += stride) %s[i] = (%s)%s;", inVarName, inVarType, initVal); + main.pushstr_newL(strBuffer); + main.pushstr_newL("}); }).wait();"); + } + + void dsl_cpp_generator::generateForAllSignature(forallStmt *forAll, bool isMainFile) + { + char strBuffer[1024]; + Identifier *iterator = forAll->getIterator(); + + if (forAll->isSourceProcCall()) + { + proc_callExpr *extractElemFunc = forAll->getExtractElementFunc(); + Identifier *iteratorMethodId = extractElemFunc->getMethodId(); + if (allGraphIteration(iteratorMethodId->getIdentifier())) + { + char *methodId = iteratorMethodId->getIdentifier(); + string s(methodId); + if (s.compare("nodes") == 0) + { + sprintf(strBuffer, "for (%s %s = 0; %s < %s; %s++) {", "int", iterator->getIdentifier(), iterator->getIdentifier(), "V", iterator->getIdentifier()); + main.pushstr_newL(strBuffer); + } + } + else if (neighbourIteration(iteratorMethodId->getIdentifier())) + { + char *methodId = iteratorMethodId->getIdentifier(); + string s(methodId); + if (s.compare("neighbors") == 0) + { + list argList = extractElemFunc->getArgList(); + assert(argList.size() == 1); + Identifier *nodeNbr = argList.front()->getExpr()->getId(); + sprintf(strBuffer, "for (%s %s = %s[%s]; %s < %s[%s+1]; %s++) { // FOR NBR ITR ", "int", "edge", "d_meta", nodeNbr->getIdentifier(), "edge", "d_meta", nodeNbr->getIdentifier(), "edge"); + main.pushstr_newL(strBuffer); + sprintf(strBuffer, "%s %s = %s[%s];", "int", iterator->getIdentifier(), "d_data", "edge"); // needs to move the addition of + main.pushstr_newL(strBuffer); + } + if (s.compare("nodes_to") == 0) // for pageRank + { + list argList = extractElemFunc->getArgList(); + assert(argList.size() == 1); + Identifier *nodeNbr = argList.front()->getExpr()->getId(); + sprintf(strBuffer, "for (%s %s = %s[%s]; %s < %s[%s+1]; %s++)", "int", "edge", "d_rev_meta", nodeNbr->getIdentifier(), "edge", "d_rev_meta", nodeNbr->getIdentifier(), "edge"); + main.pushstr_newL(strBuffer); + main.pushString("{"); + sprintf(strBuffer, "%s %s = %s[%s] ;", "int", iterator->getIdentifier(), "d_src", "edge"); // needs to move the addition of + main.pushstr_newL(strBuffer); + } + } + } + else if (forAll->isSourceField()) + { + } + else + { + Identifier *sourceId = forAll->getSource(); + if (sourceId != NULL) + { + if (sourceId->getSymbolInfo()->getType()->gettypeId() == TYPE_SETN) + { // FOR SET + //~ std::cout << "+++++ ++++++++++" << '\n'; + main.pushstr_newL("//FOR SIGNATURE of SET - Assumes set for on .cu only"); + main.pushstr_newL("std::set::iterator itr;"); + sprintf(strBuffer, "for(itr=%s.begin();itr!=%s.end();itr++) ", sourceId->getIdentifier(), sourceId->getIdentifier()); + main.pushstr_newL(strBuffer); + } + } + } + } + + void dsl_cpp_generator::generateForAll(forallStmt *forAll, bool isMainFile) + { + proc_callExpr *extractElemFunc = forAll->getExtractElementFunc(); + PropAccess *sourceField = forAll->getPropSource(); + Identifier *sourceId = forAll->getSource(); + + Identifier *collectionId; + if (sourceField != NULL) + { + collectionId = sourceField->getIdentifier1(); + } + if (sourceId != NULL) + { + collectionId = sourceId; + } + Identifier *iteratorMethodId; + if (extractElemFunc != NULL) + iteratorMethodId = extractElemFunc->getMethodId(); + statement *body = forAll->getBody(); + char strBuffer[1024]; + + if (forAll->isForall()) + { + std::cout << "Entered for all" << std::endl; + if (!isOptimized) + { + std::cout << "============EARLIER NOT OPT=============" << '\n'; + usedVariables usedVars = getVariablesForAll(forAll); + list vars = usedVars.getVariables(); + + for (Identifier *iden : vars) + { + std::cout << "varName:" << iden->getIdentifier() << '\n'; + Type *type = iden->getSymbolInfo()->getType(); + + if (type->isPrimitiveType() && (fixedPointVariables.find(iden->getIdentifier()) == fixedPointVariables.end())) + { + generateMemCpySymbol(iden->getIdentifier(), convertToCppType(type), true); + } + + /*else if(type->isPropType()) + { + Type* innerType = type->getInnerTargetType(); + string dIden = "d_" + string(iden->getIdentifier()); + generateCudaMemCpyStr(dIden.c_str(), iden->getIdentifier(), convertToCppType(innerType), "V", true); + }*/ + } + } + + addKernel(forAll); + + if (!isOptimized) + { + usedVariables usedVars = getVariablesForAll(forAll); + list vars = usedVars.getVariables(); + for (Identifier *iden : vars) + { + Type *type = iden->getSymbolInfo()->getType(); + if (type->isPrimitiveType()) + generateMemCpySymbol(iden->getIdentifier(), convertToCppType(type), false); + /*else if(type->isPropType()) + { + Type* innerType = type->getInnerTargetType(); + string dIden = "d_" + string(iden->getIdentifier()); + generateCudaMemCpyStr(iden->getIdentifier(),dIden.c_str(), convertToCppType(innerType), "V", false); + }*/ + } + /*memcpy from symbol*/ + } + } + else + { // IS FOR + main.pushstr_newL("// for all else part"); + + generateForAllSignature(forAll, false); // FOR LINE + + if (forAll->hasFilterExpr()) + { + blockStatement *changedBody = includeIfToBlock(forAll); + cout << "============CHANGED BODY TYPE==============" << (changedBody->getTypeofNode() == NODE_BLOCKSTMT); + forAll->setBody(changedBody); + } + + if (extractElemFunc != NULL) + { + if (neighbourIteration(iteratorMethodId->getIdentifier())) + { + cout << "\t ITERATE Neighbour \n"; + char *wItr = forAll->getIterator()->getIdentifier(); + std::cout << "src:" << wItr << '\n'; + char *nbrVar; + + if (forAll->getParent()->getParent()->getTypeofNode() == NODE_ITRBFS) + { + list argList = extractElemFunc->getArgList(); + assert(argList.size() == 1); + Identifier *nodeNbr = argList.front()->getExpr()->getId(); + nbrVar = nodeNbr->getIdentifier(); + + sprintf(strBuffer, "if(d_level[%s] == -1) {", wItr); + main.pushstr_newL(strBuffer); + sprintf(strBuffer, "d_level[%s] = *d_hops_from_source + 1;", wItr); + + main.pushstr_newL(strBuffer); + main.pushstr_newL("*d_finished = false;"); + main.pushstr_newL("}"); + + sprintf(strBuffer, "if(d_level[%s] == *d_hops_from_source + 1) {", wItr); + main.pushstr_newL(strBuffer); + + generateBlock((blockStatement *)forAll->getBody(), false, false); + + main.pushstr_newL("}"); + + main.pushstr_newL("}"); + } + else if (forAll->getParent()->getParent()->getTypeofNode() == NODE_ITRRBFS) + { // ITERATE REV BFS + char strBuffer[1024]; + list argList = extractElemFunc->getArgList(); + assert(argList.size() == 1); + Identifier *nodeNbr = argList.front()->getExpr()->getId(); + nbrVar = nodeNbr->getIdentifier(); + std::cout << "V?:" << nbrVar << '\n'; + + sprintf(strBuffer, "if(d_level[%s] == *d_hops_from_source) {", wItr); + main.pushstr_newL(strBuffer); + generateBlock((blockStatement *)forAll->getBody(), false, false); + main.pushstr_newL("} // end IF "); + main.pushstr_newL("} // end FOR"); + } + else + { + generateStatement(forAll->getBody(), isMainFile); + main.pushstr_newL("} // end FOR NBR ITR. TMP FIX!"); + std::cout << "FOR BODY END" << '\n'; + } + } + else + { + printf("FOR NORML"); + generateStatement(forAll->getBody(), false); + main.pushstr_newL("}"); + } + } + else + { + if (collectionId->getSymbolInfo()->getType()->gettypeId() == TYPE_SETN) + { // FOR SET + if (body->getTypeofNode() == NODE_BLOCKSTMT) + { + main.pushstr_newL("{"); + printf("FOR"); + sprintf(strBuffer, "int %s = *itr;", forAll->getIterator()->getIdentifier()); + main.pushstr_newL(strBuffer); + generateBlock((blockStatement *)body, false); // FOR BODY for + main.pushstr_newL("}"); + } + else + generateStatement(forAll->getBody(), false); + } + else + { + cout << iteratorMethodId->getIdentifier() << "\n"; + generateStatement(forAll->getBody(), false); + } + if (forAll->isForall() && forAll->hasFilterExpr()) + { + Expression *filterExpr = forAll->getfilterExpr(); + generatefixedpt_filter(filterExpr, false); + } + } + } + } + + void dsl_cpp_generator::generatefixedpt_filter(Expression *filterExpr, bool isMainFile) + { + Expression *lhs = filterExpr->getLeft(); + //~ char strBuffer[1024]; + if (lhs->isIdentifierExpr()) + { + // TODO + } + } + + void dsl_cpp_generator::generateFixedPoint(fixedPointStmt *fixedPointConstruct, bool isMainFile) + { + std::cout << "IN FIX PT" << '\n'; + char strBuffer[1024]; + Expression *convergeExpr = fixedPointConstruct->getDependentProp(); + Identifier *fixedPointId = fixedPointConstruct->getFixedPointId(); + + assert(convergeExpr->getExpressionFamily() == EXPR_UNARY || + convergeExpr->getExpressionFamily() == EXPR_ID); + + Identifier *dependentId = NULL; + //~ bool isNot = false; + assert(convergeExpr->getExpressionFamily() == EXPR_UNARY || convergeExpr->getExpressionFamily() == EXPR_ID); + + if (convergeExpr->getExpressionFamily() == EXPR_UNARY) + { + if (convergeExpr->getUnaryExpr()->getExpressionFamily() == EXPR_ID) + { + dependentId = convergeExpr->getUnaryExpr()->getId(); + //~ isNot = true; + } + } + + const char *modifiedVar = dependentId->getIdentifier(); + char *fixPointVar = fixedPointId->getIdentifier(); + string fixPointVarName(fixPointVar); + fixedPointVariables.insert(fixPointVarName); + + //~ const char *modifiedVarType = convertToCppType(dependentId->getSymbolInfo()->getType()->getInnerTargetType()); // BOTH are of type bool + const char *fixPointVarType = convertToCppType(fixedPointId->getSymbolInfo()->getType()); + + main.pushstr_newL("// FIXED POINT variables"); + // char modifiedVarPrev[80] = "d_"; + char modifiedVarNext[80] = "d_"; + + // strcat(modifiedVarPrev, modifiedVar);strcat(modifiedVarPrev, "_prev"); + strcat(modifiedVarNext, modifiedVar); + strcat(modifiedVarNext, "_next"); + + if (convergeExpr->getExpressionFamily() == EXPR_ID) + dependentId = convergeExpr->getId(); + + if (dependentId != NULL) + { + if (dependentId->getSymbolInfo()->getType()->isPropType()) + { + if (dependentId->getSymbolInfo()->getType()->isPropNodeType()) + { + main.pushstr_newL("//BEGIN FIXED POINT"); + + main.pushstr_newL("Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){"); + + sprintf(strBuffer, "for (; i < V; i += stride) %s[i] = false", modifiedVarNext); + main.pushString(strBuffer); + main.pushstr_newL(";});"); + main.pushstr_newL("}).wait();"); + main.NewLine(); + + // main.pushstr_newL("int k=0; // #fixpt-Iterations"); + sprintf(strBuffer, "while(!%s) {", fixPointVar); + main.pushstr_newL(strBuffer); + + std::cout << "Size::" << graphId.size() << '\n'; + main.NewLine(); + sprintf(strBuffer, "%s = %s", fixPointVar, "true"); + main.pushString(strBuffer); + main.pushstr_newL(";"); + + generateMemCpySymbol(fixPointVar, fixPointVarType, true); + + if (fixedPointConstruct->getBody()->getTypeofNode() != NODE_BLOCKSTMT) + generateStatement(fixedPointConstruct->getBody(), isMainFile); + else + generateBlock((blockStatement *)fixedPointConstruct->getBody(), false, isMainFile); + + generateMemCpySymbol(fixPointVar, fixPointVarType, false); + + main.pushstr_newL("Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){"); + sprintf(strBuffer, "for (; i < V; i += stride) d_%s[i] = %s[i]", modifiedVar, modifiedVarNext); + main.pushString(strBuffer); + main.pushstr_newL(";});"); + main.pushstr_newL("}).wait();"); + main.NewLine(); + + main.pushstr_newL("Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){"); + sprintf(strBuffer, "for (; i < V; i += stride) %s[i] = false", modifiedVarNext); + main.pushString(strBuffer); + main.pushstr_newL(";});"); + main.pushstr_newL("}).wait();"); + main.NewLine(); + + // main.pushstr_newL("k++;"); + Expression *initializer = dependentId->getSymbolInfo()->getId()->get_assignedExpr(); + assert(initializer->isBooleanLiteral()); + } + } + } + main.pushstr_newL("} // END FIXED POINT"); + main.NewLine(); + } + + void dsl_cpp_generator::generateReductionCallStmt(reductionCallStmt *stmt, bool isMainFile) + { + reductionCall *reduceCall = stmt->getReducCall(); + char strBuffer[1024]; + + if (reduceCall->getReductionType() == REDUCE_MIN) + { + if (stmt->isListInvolved()) + { + list argList = reduceCall->getargList(); + list leftList = stmt->getLeftList(); + list rightList = stmt->getRightList(); + printf("LEFT LIST SIZE %lu \n", leftList.size()); + + main.space(); + if (stmt->getAssignedId()->getSymbolInfo()->getType()->isPropType()) + { + Type *type = stmt->getAssignedId()->getSymbolInfo()->getType(); + + main.pushstr_space(convertToCppType(type->getInnerTargetType())); + } + sprintf(strBuffer, "%s_new", stmt->getAssignedId()->getIdentifier()); + std::cout << "VAR:" << stmt->getAssignedId()->getIdentifier() << '\n'; + main.pushString(strBuffer); + + list::iterator argItr; + argItr = argList.begin(); + argItr++; + main.pushString(" = "); + + generateExpr((*argItr)->getExpr(), isMainFile); + main.pushstr_newL(";"); + list::iterator itr1; + list::iterator itr2; + itr2 = rightList.begin(); + itr1 = leftList.begin(); + itr1++; + + for (; itr1 != leftList.end(); itr1++) + { + ASTNode *node = *itr1; + ASTNode *node1 = *itr2; + + if (node->getTypeofNode() == NODE_ID) + { + main.pushstr_space(convertToCppType(((Identifier *)node)->getSymbolInfo()->getType())); + sprintf(strBuffer, "%s_new", ((Identifier *)node)->getIdentifier()); + main.pushString(strBuffer); + main.pushString(" = "); + generateExpr((Expression *)node1, isMainFile); + } + if (node->getTypeofNode() == NODE_PROPACCESS) + { + PropAccess *p = (PropAccess *)node; + Type *type = p->getIdentifier2()->getSymbolInfo()->getType(); + if (type->isPropType()) + { + main.pushstr_space(convertToCppType(type->getInnerTargetType())); + } + + sprintf(strBuffer, "%s_new", p->getIdentifier2()->getIdentifier()); + main.pushString(strBuffer); + main.pushString(" = "); + generateExpr((Expression *)node1, isMainFile); + main.pushstr_newL(";"); + } + itr2++; + } + + main.pushString("if("); + sprintf(strBuffer, "d_%s[v]!= INT_MAX && ", stmt->getAssignedId()->getIdentifier()); + main.pushString(strBuffer); + generate_exprPropId(stmt->getTargetPropId(), isMainFile); + + sprintf(strBuffer, " > %s_new)", stmt->getAssignedId()->getIdentifier()); + main.pushstr_newL(strBuffer); + main.pushstr_newL("{"); + + if (stmt->isTargetId()) + { + Identifier *targetId = stmt->getTargetId(); + main.pushstr_space(convertToCppType(targetId->getSymbolInfo()->getType())); + main.pushstr_space("oldValue"); + main.pushstr_space("="); + generate_exprIdentifier(stmt->getTargetId(), isMainFile); + main.pushstr_newL(";"); + } + else + { + PropAccess *targetProp = stmt->getTargetPropId(); + Type *type = targetProp->getIdentifier2()->getSymbolInfo()->getType(); + if (type->isPropType()) + { + } + } + + main.pushString("atomic_ref atomic_data("); + generate_exprPropId(stmt->getTargetPropId(), isMainFile); + main.pushstr_newL(");"); + main.pushString("atomic_data.fetch_min("); + sprintf(strBuffer, "%s_new);", stmt->getAssignedId()->getIdentifier()); + main.pushstr_newL(strBuffer); + + itr1 = leftList.begin(); + itr1++; + for (; itr1 != leftList.end(); itr1++) + { + ASTNode *node = *itr1; + Identifier *affected_Id = NULL; + if (node->getTypeofNode() == NODE_ID) + { + generate_exprIdentifier((Identifier *)node, isMainFile); + } + if (node->getTypeofNode() == NODE_PROPACCESS) + { + generate_exprPropId((PropAccess *)node, isMainFile); + } + main.space(); + main.pushstr_space("="); + if (node->getTypeofNode() == NODE_ID) + { + generate_exprIdentifier((Identifier *)node, isMainFile); + affected_Id = (Identifier *)node; + } + if (node->getTypeofNode() == NODE_PROPACCESS) // here + { + generate_exprIdentifier(((PropAccess *)node)->getIdentifier2(), isMainFile); + affected_Id = ((PropAccess *)node)->getIdentifier2(); + } + main.pushString("_new"); + main.pushstr_newL(";"); + + if (affected_Id->getSymbolInfo()->getId()->get_fp_association()) + { + char *fpId = affected_Id->getSymbolInfo()->getId()->get_fpId(); + sprintf(strBuffer, "*d_%s = %s ;", fpId, "false"); + std::cout << "FPID ========> " << fpId << '\n'; + main.pushstr_newL(strBuffer); + } + } + main.pushstr_newL("}"); + } + } + } + + void dsl_cpp_generator::generateReductionOpStmt(reductionCallStmt *stmt, bool isMainFile) + { + char strBuffer[1024]; + if (stmt->isLeftIdentifier()) + { + Identifier *id = stmt->getLeftId(); + const char *typVar = convertToCppType(id->getSymbolInfo()->getType()); + sprintf(strBuffer, "atomic_ref<%s, memory_order::relaxed, memory_scope::device, access::address_space::global_space> atomic_data(d_%s[0])", typVar, id->getIdentifier()); + main.pushString(strBuffer); + main.pushstr_newL(";"); + sprintf(strBuffer, "atomic_data += "); + main.pushString(strBuffer); + generateExpr(stmt->getRightSide(), isMainFile); + main.pushstr_newL(";"); + } + else + { + generate_exprPropId(stmt->getPropAccess(), isMainFile); + main.pushString(" = "); + generate_exprPropId(stmt->getPropAccess(), isMainFile); + const char *operatorString = getOperatorString(stmt->reduction_op()); + main.pushstr_space(operatorString); + generateExpr(stmt->getRightSide(), isMainFile); + main.pushstr_newL(";"); + } + } + + void dsl_cpp_generator::generateReductionStmt(reductionCallStmt *stmt, bool isMainFile) + { + if (stmt->is_reducCall()) + { + generateReductionCallStmt(stmt, isMainFile); + } + else + { + generateReductionOpStmt(stmt, isMainFile); + } + } + + void dsl_cpp_generator::addBFSIterKernel(iterateBFS *bfsAbstraction) + { + const char *loopVar = "v"; + char strBuffer[1024]; + statement *body = bfsAbstraction->getBody(); + assert(body->getTypeofNode() == NODE_BLOCKSTMT); + blockStatement *block = (blockStatement *)body; + list statementList = block->returnStatements(); + + main.pushstr_newL("Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> v){for (; v < V; v += NUM_THREADS){"); + sprintf(strBuffer, "if(d_level[%s] == *d_hops_from_source) {", loopVar); + main.pushstr_newL(strBuffer); + + for (statement *stmt : statementList) + { + generateStatement(stmt, false); + } + main.pushstr_newL("} // end if d lvl"); + main.pushstr_newL("}});}).wait(); // kernel end"); + main.NewLine(); + } + + void dsl_cpp_generator::addBFSIterationLoop(iterateBFS *bfsAbstraction) + { + main.pushstr_newL("finished = true;"); // there vars are BFS specific + generateMemCpyStr("d_finished", "&finished", "bool", "1"); + main.NewLine(); + main.pushstr_newL("//Kernel LAUNCH"); + + addBFSIterKernel(bfsAbstraction); // KERNEL BODY!!! + + main.pushstr_newL("Q.submit([&](handler &h){ h.single_task([=](){ *d_hops_from_source += 1; }); }).wait();"); + main.pushstr_newL("++hops_from_source; // updating the level to process in the next iteration"); + } + + void dsl_cpp_generator::addRevBFSIterationLoop(iterateBFS *bfsAbstraction) + { + main.NewLine(); + main.pushstr_newL("hops_from_source--;"); + generateMemCpyStr("d_hops_from_source", "&hops_from_source", "int", "1"); + main.NewLine(); + } + + void dsl_cpp_generator::addRevBFSIterKernel(list &statementList) + { + const char *loopVar = "v"; + char strBuffer[1024]; + + main.pushstr_newL("Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> v){for (; v < V; v += NUM_THREADS){"); + sprintf(strBuffer, "if(d_level[%s] == *d_hops_from_source-1) {", loopVar); + main.pushstr_newL(strBuffer); + + for (statement *stmt : statementList) + { + generateStatement(stmt, false); // false. All these stmts should be inside kernel + } + + main.pushstr_newL("} // end if d lvl"); + main.pushstr_newL(" }});}).wait(); // kernel end"); + main.NewLine(); + } + + void dsl_cpp_generator::generatePropParams(list paramList, bool isNeedType = true, bool isMainFile = true) + { + main.pushstr_newL("// generatePropParams"); + } + + Function *dsl_cpp_generator::getCurrentFunc() + { + return currentFunc; + } + + void dsl_cpp_generator::generateBFSAbstraction(iterateBFS *bfsAbstraction, bool isMainFile) + { + char strBuffer[1024]; + statement *body = bfsAbstraction->getBody(); + assert(body->getTypeofNode() == NODE_BLOCKSTMT); + blockStatement *block = (blockStatement *)body; + list statementList = block->returnStatements(); + + main.NewLine(); + main.pushstr_newL("//EXTRA vars for ITBFS AND REVBFS"); // NOT IN DSL so hardcode is fine + main.pushstr_newL("bool finished;"); + main.pushstr_newL("int hops_from_source=0;"); + + main.pushstr_newL("bool* d_finished; d_finished = malloc_device(1, Q);"); + main.pushstr_newL("int* d_hops_from_source; d_hops_from_source = malloc_device(1, Q);"); + main.pushstr_newL("Q.submit([&](handler &h){ h.single_task([=](){ *d_hops_from_source = 0; }); }).wait();"); + main.pushstr_newL("int* d_level; d_level = malloc_device(V, Q);"); + + main.NewLine(); + main.pushstr_newL("//EXTRA vars INITIALIZATION"); + + generateInitkernelStr("int", "d_level", "-1"); + + main.pushstr_newL("Q.submit([&](handler &h){ h.single_task([=](){"); + sprintf(strBuffer, "d_level[%s] = 0;", bfsAbstraction->getRootNode()->getIdentifier()); + main.pushstr_newL(strBuffer); + main.pushstr_newL("}); }).wait();"); + main.NewLine(); + + main.pushstr_newL("// long k =0 ;// For DEBUG"); + main.pushstr_newL("do {"); + + addBFSIterationLoop(bfsAbstraction); // ADDS BODY OF ITERBFS + KERNEL LAUNCH + + main.NewLine(); + + generateMemCpyStr("&finished", "d_finished", "bool", "1"); + + main.pushstr_newL("}while(!finished);"); + + blockStatement * + revBlock = (blockStatement *)bfsAbstraction->getRBFS()->getBody(); + list revStmtList = revBlock->returnStatements(); + addRevBFSIterationLoop(bfsAbstraction); + + main.pushstr_newL("//BACKWARD PASS"); + main.pushstr_newL("while(hops_from_source > 1) {"); + + main.NewLine(); + main.pushstr_newL("//KERNEL Launch"); + + main.NewLine(); + addRevBFSIterKernel(revStmtList); // KERNEL BODY + + main.pushstr_newL("hops_from_source--;"); + generateMemCpyStr("d_hops_from_source", "&hops_from_source", "int", "1"); + + main.pushstr_newL("}"); + } + + void dsl_cpp_generator::generateInitkernel1(assignment *assign, bool isMainFile, bool isPropEdge = false) + { + main.pushstr_newL("Q.submit([&](handler &h){ h.parallel_for(NUM_THREADS, [=](id<1> i){"); + + char strBuffer[1024]; + + Identifier *inId = assign->getId(); + Expression *exprAssigned = assign->getExpr(); + + const char *inVarType = + convertToCppType(inId->getSymbolInfo()->getType()->getInnerTargetType()); + const char *inVarName = inId->getIdentifier(); + + if (isPropEdge) + sprintf(strBuffer, "for (; i < E; i += stride) d_%s[i] = (%s)", inVarName, inVarType); + else + sprintf(strBuffer, "for (; i < V; i += stride) d_%s[i] = (%s)", inVarName, inVarType); + + main.pushString(strBuffer); + + std::cout << "varName:" << inVarName << '\n'; + generateExpr(exprAssigned, isMainFile); // asssuming int/float const literal // OUTPUTS INIT VALUE + + main.pushstr_newL(";});"); + main.pushstr_newL("}).wait();"); + main.NewLine(); + } + + void dsl_cpp_generator::generateProcCall(proc_callStmt *proc_callStmt, bool isMainFile) + { + proc_callExpr *procedure = proc_callStmt->getProcCallExpr(); + string methodID(procedure->getMethodId()->getIdentifier()); + string IDCoded("attachNodeProperty"); + int x = methodID.compare(IDCoded); + + if (x == 0) + { + list argList = procedure->getArgList(); + list::iterator itr; + + for (itr = argList.begin(); itr != argList.end(); itr++) + { + assignment *assign = (*itr)->getAssignExpr(); + + if (argList.size() == 1) + { + generateInitkernel1(assign, isMainFile); + } + else if (argList.size() == 2) + { + generateInitkernel1(assign, isMainFile); + } + } + } + string IDCoded1("attachEdgeProperty"); + int x1 = methodID.compare(IDCoded1); + + if (x1 == 0) + { + list argList = procedure->getArgList(); + list::iterator itr; + + for (itr = argList.begin(); itr != argList.end(); itr++) + { + assignment *assign = (*itr)->getAssignExpr(); + bool isPropEdge = true; + generateInitkernel1(assign, isMainFile, isPropEdge); + } + } + } + + void dsl_cpp_generator::generateTransferStmt(varTransferStmt *stmt) + { + main.pushstr_newL("// Generate transfer statement"); + } + + void dsl_cpp_generator::generateStatement(statement *stmt, bool isMainFile) + { + if (stmt->getTypeofNode() == NODE_BLOCKSTMT) + { + generateBlock((blockStatement *)stmt, false, isMainFile); + } + + if (stmt->getTypeofNode() == NODE_DECL) + { + generateVariableDecl((declaration *)stmt, isMainFile); + } + + if (stmt->getTypeofNode() == NODE_ASSIGN) + { + // generateAssignmentStmt((assignment*)stmt); + assignment *asst = (assignment *)stmt; + if (asst->isDeviceAssignment()) + generateDeviceAssignmentStmt(asst, isMainFile); + else // atomic or normal asmt + generateAtomicDeviceAssignmentStmt(asst, isMainFile); + } + + if (stmt->getTypeofNode() == NODE_WHILESTMT) + { + // generateWhileStmt((whileStmt*) stmt); + } + + if (stmt->getTypeofNode() == NODE_IFSTMT) + { + generateIfStmt((ifStmt *)stmt, isMainFile); + } + + if (stmt->getTypeofNode() == NODE_DOWHILESTMT) + { + generateDoWhileStmt((dowhileStmt *)stmt, isMainFile); + } + + if (stmt->getTypeofNode() == NODE_FORALLSTMT) + { + std::cout << "STMT: For" << '\n'; + printf("isMainFile val %d\n", isMainFile); + generateForAll((forallStmt *)stmt, isMainFile); + } + + if (stmt->getTypeofNode() == NODE_FIXEDPTSTMT) + { + generateFixedPoint((fixedPointStmt *)stmt, isMainFile); + } + if (stmt->getTypeofNode() == NODE_REDUCTIONCALLSTMT) + { + generateReductionStmt((reductionCallStmt *)stmt, isMainFile); + } + if (stmt->getTypeofNode() == NODE_ITRBFS) + { + generateBFSAbstraction((iterateBFS *)stmt, isMainFile); + } + if (stmt->getTypeofNode() == NODE_PROCCALLSTMT) + { + generateProcCall((proc_callStmt *)stmt, isMainFile); + } + if (stmt->getTypeofNode() == NODE_UNARYSTMT) + { + unary_stmt *unaryStmt = (unary_stmt *)stmt; + generateExpr(unaryStmt->getUnaryExpr(), isMainFile); + main.pushstr_newL(";"); + } + if (isOptimized && (stmt->getTypeofNode() == NODE_TRANSFERSTMT)) + { + varTransferStmt *transferStmt = (varTransferStmt *)stmt; + generateTransferStmt(transferStmt); + } + } + + void dsl_cpp_generator::generateBlock(blockStatement *blockStmt, bool includeBrace, bool isMainFile) + { + usedVariables usedVars = getDeclaredPropertyVariablesOfBlock(blockStmt); + list vars = usedVars.getVariables(); + std::cout << "\t==VARSIZE:" << vars.size() << '\n'; + + list stmtList = blockStmt->returnStatements(); + list::iterator itr; + if (includeBrace) + { + main.pushstr_newL("{"); + } + + for (itr = stmtList.begin(); itr != stmtList.end(); itr++) + { + statement *stmt = *itr; + generateStatement(stmt, isMainFile); + } + + // FREE memory + char strBuffer[1024]; + + if (vars.size() > 0) + { + main.NewLine(); + main.pushstr_newL("//free up!! all propVars in this BLOCK!"); + } + for (Identifier *iden : vars) + { + sprintf(strBuffer, "free(d_%s, Q);", iden->getIdentifier()); + main.pushstr_newL(strBuffer); + } + main.NewLine(); + + if (includeBrace) + { + main.pushstr_newL("}"); + } + } + + void dsl_cpp_generator::generateMemCpyParams(list paramList) + { + list::iterator itr; + for (itr = paramList.begin(); itr != paramList.end(); itr++) + { + Type *type = (*itr)->getType(); + if (type->isPropType()) + { + if (type->getInnerTargetType()->isPrimitiveType()) + { + const char *sizeofProp = NULL; + if (type->isPropEdgeType()) + sizeofProp = "E"; + else + sizeofProp = "V"; + const char *temp = "d_"; + char *temp1 = (*itr)->getIdentifier()->getIdentifier(); + char *temp2 = (char *)malloc(1 + strlen(temp) + strlen(temp1)); + strcpy(temp2, temp); + strcat(temp2, temp1); + + generateMemCpyStr((*itr)->getIdentifier()->getIdentifier(), temp2, convertToCppType(type->getInnerTargetType()), sizeofProp); + } + } + } + } + + void dsl_cpp_generator::incFuncCount(int funcType) + { + if (funcType == GEN_FUNC) + genFuncCount++; + else if (funcType == STATIC_FUNC) + staticFuncCount++; + else if (funcType == INCREMENTAL_FUNC) + inFuncCount++; + else + decFuncCount++; + } + + void dsl_cpp_generator::generateStopTimer() + { + main.pushstr_newL("std::chrono::steady_clock::time_point toc = std::chrono::steady_clock::now();"); + main.pushstr_newL("std::cout<<\"Time required: \"<(toc - tic).count()<<\"[µs]\"<getParamList()); + + main.NewLine(); + + main.pushstr_newL("//BEGIN DSL PARSING "); + + generateBlock(func->getBlockStatement(), false); + + // Assuming one function! + main.pushstr_newL("//TIMER STOP"); + generateStopTimer(); + main.NewLine(); + + generateMemCpyParams(func->getParamList()); + //~ sprintf(strBuffer, "cudaMemcpy(%s,d_%s , sizeof(%s) * (V), cudaMemcpyDeviceToHost);", outVarName, outVarName, outVarType); + + //~ main.pushstr_newL(strBuffer); + + main.pushstr_newL("} //end FUN"); + + incFuncCount(func->getFuncType()); + + return; + } + + void dsl_cpp_generator::generation_end() + { + main.NewLine(); + main.pushstr_newL("#endif"); + } + + bool dsl_cpp_generator::openFileforOutput() + { + char temp[1024]; + printf("fileName %s\n", fileName); + sprintf(temp, "%s/%s.cpp", "../graphcode/generated_sycl", fileName); + bodyFile = fopen(temp, "w"); + if (bodyFile == NULL) + return false; + main.setOutputFile(bodyFile); + return true; + } + + void dsl_cpp_generator::closeOutputFile() + { + if (bodyFile != NULL) + { + main.outputToFile(); + fclose(bodyFile); + } + + bodyFile = NULL; + } + + const char *dsl_cpp_generator::getOperatorString(int operatorId) + { + switch (operatorId) + { + case OPERATOR_ADD: + return "+"; + case OPERATOR_DIV: + return "/"; + case OPERATOR_MUL: + return "*"; + case OPERATOR_MOD: + return "%"; + case OPERATOR_SUB: + return "-"; + case OPERATOR_EQ: + return "=="; + case OPERATOR_NE: + return "!="; + case OPERATOR_LT: + return "<"; + case OPERATOR_LE: + return "<="; + case OPERATOR_GT: + return ">"; + case OPERATOR_GE: + return ">="; + case OPERATOR_AND: + return "&&"; + case OPERATOR_OR: + return "||"; + case OPERATOR_INC: + return "++"; + case OPERATOR_DEC: + return "--"; + case OPERATOR_ADDASSIGN: + return "+"; + case OPERATOR_ANDASSIGN: + return "&&"; + case OPERATOR_ORASSIGN: + return "||"; + case OPERATOR_MULASSIGN: + return "*"; + case OPERATOR_SUBASSIGN: + return "-"; + default: + return "NA"; + } + } + + bool dsl_cpp_generator::generate() + { + cout << "INSIDE SYCL GENERATOR" << endl; + cout << "FRONTEND VALUES" << frontEndContext.getFuncList().front()->getBlockStatement()->returnStatements().size() << endl; + // //openFileforOutput(); + if (!openFileforOutput()) + return false; + generation_begin(); + + list funcList = frontEndContext.getFuncList(); + for (Function *func : funcList) + { + setCurrentFunc(func); + generateFunc(func); + } + + generation_end(); + + closeOutputFile(); + + return true; + } + + void dsl_cpp_generator::setFileName(char *f) + { + char *token = strtok(f, "/"); + char *prevtoken; + + while (token != NULL) + { + prevtoken = token; + token = strtok(NULL, "/"); + } + fileName = prevtoken; + } +} \ No newline at end of file diff --git a/src/backends/backend_sycl/dsl_cpp_generator.h b/src/backends/backend_sycl/dsl_cpp_generator.h new file mode 100644 index 00000000..f3490781 --- /dev/null +++ b/src/backends/backend_sycl/dsl_cpp_generator.h @@ -0,0 +1,203 @@ +#ifndef SYCL_DSL_CPP_GENERATOR +#define SYCL_DSL_CPP_GENERATOR + +#include +#include +#include "../../ast/ASTNodeTypes.hpp" +#include "../dslCodePad.h" +//~ #include "../../parser/includeHeader.hpp" + +namespace spsycl +{ + class dsl_cpp_generator + { + private: + dslCodePad main; + FILE *bodyFile; + + char *fileName; + + int genFuncCount; + int staticFuncCount; + int inFuncCount; + int decFuncCount; + int curFuncType; + + // added here + bool genCSR; + char *gName; + int kernelCount; + Function *currentFunc; + + bool isHeader; + bool isOptimized; + + public: + dsl_cpp_generator() + { + // added here + genCSR = false; + isHeader = false; + kernelCount = 0; + gName = new char[25]; + + bodyFile = NULL; + fileName = new char[1024]; + currentFunc = NULL; + isOptimized = false; + + genFuncCount = 0; + staticFuncCount = 0; + inFuncCount = 0; + decFuncCount = 0; + } + + void generateParamList(list paramList, dslCodePad &targetFile); + void setCurrentFunc(Function *func); + Function *getCurrentFunc(); + void setFileName(char *f); + bool generate(); + void generation_begin(); + void generation_end(); + bool openFileforOutput(); + void closeOutputFile(); + const char *convertToCppType(Type *type, bool isElementOfProp); + const char *getOperatorString(int operatorId); + void generateFunc(ASTNode *proc); + void generateFuncHeader(Function *proc); + void generateProcCall(proc_callStmt *procCall, bool isMainFile); + void generateVariableDecl(declaration *decl, bool isMainFile); + void generateStatement(statement *stmt, bool isMainFile); + // void generateAssignmentStmt(assignment* assignStmt); + void generateAssignmentStmt(assignment *assignStmt, bool isMainFile); + void generateWhileStmt(whileStmt *whilestmt); + void generateForAll(forallStmt *forAll, bool isMainFile); + void generateFixedPoint(fixedPointStmt *fixedPoint, bool isMainFile); + void generateIfStmt(ifStmt *ifstmt, bool isMainFile); + void generateDoWhileStmt(dowhileStmt *doWhile, bool isMainFile); + void generateBFS(); + void generateBlock(blockStatement *blockStmt, bool includeBrace = true, bool isMainFile = true); + void generateReductionStmt(reductionCallStmt *reductnStmt, bool isMainFile); + void generateBFSAbstraction(iterateBFS *bfsAbstraction, bool isMainFile); + void generateRevBFSAbstraction(iterateBFS *bfsAbstraction, + bool isMainFile); // reverse + + void incFuncCount(int funcType); + int curFuncCount(); + + void generateExpr(Expression *expr, bool isMainFile, bool isAtomic = false); + void generate_exprArL(Expression *expr, bool isMainFile, bool isAtomic = false); + + void generate_exprRelational(Expression *expr, bool isMainFile); + void generate_exprInfinity(Expression *expr, bool isMainFile); + void generate_exprLiteral(Expression *expr, bool isMainFile); + void generate_exprIdentifier(Identifier *id, bool isMainFile); + void generate_exprPropId(PropAccess *propId, bool isMainFile); + void generate_exprProcCall(Expression *expr, bool isMainFile); + + void generateForAll_header(); + void generateForAllSignature(forallStmt *forAll, bool isKernel); + // void includeIfToBlock(forallStmt* forAll); + bool neighbourIteration(char *methodId); + bool allGraphIteration(char *methodId); + blockStatement *includeIfToBlock(forallStmt *forAll); + + void generateId(); + void generateOid(); + void addIncludeToFile(const char *includeName, dslCodePad &file, + bool isCPPLib); + void generatePropertyDefination(Type *type, char *Id, bool isMainFile); + void findTargetGraph(vector graphTypes, Type *type); + void getDefaultValueforTypes(int type); + + void generateInitialization(); + void generateFuncSSSPBody(); + void generateFuncCUDASizeAllocation(); + void generateFuncCudaMalloc(); + void generateBlockForSSSPBody(blockStatement *blockStmt, bool includeBrace); + void generateStatementForSSSPBody(statement *stmt); + void generateCudaMemCpyForSSSPBody(); + void generateFuncPrintingSSSPOutput(); + void generateFuncVariableINITForSSSP(); + void generateFuncTerminatingConditionForSSSP(); + // newly added for cuda speific handlings index + void generateCudaIndex(); + void generateAtomicBlock(bool isMainFile); + void generateVariableDeclForEdge(declaration *declStmt); + void generateLocalInitForID(); + // new + void castIfRequired(Type *type, Identifier *methodID, dslCodePad &main); + void generateReductionCallStmt(reductionCallStmt *stmt, bool isMainFile); + void generateReductionOpStmt(reductionCallStmt *stmt, bool isMainFile); + void generate_exprUnary(Expression *expr, bool isMainFile); + void generateForAll_header(forallStmt *forAll, bool isMainFile); + void generatefixedpt_filter(Expression *filterExpr, bool isMainFile); + void generateTransferStmt(varTransferStmt *stmt); + + bool elementsIteration(char *extractId); + //~ void generateCudaMalloc(Type* type, const char* identifier); + // void generateCudaMalloc(Type* type, const char* identifier, bool + // isMainFile); + void generateCudaMemcpy(const char *dVar, const char *cVar, + const char *typeStr, const char *sizeOfType, + bool isMainFile, const char *from); + + // for algorithm specific function implementation headers + + void generatePrintAnswer(); + void generateGPUTimerStop(); + void generateGPUTimerStart(); + void generateMemCpyStr(const char *, const char *, const char *, const char *); + void generateInitkernel1(assignment *, bool, bool); + + void generateInitkernelStr(const char *inVarType, const char *inVarName, const char *initVal); + + void generateCSRArrays(const char *); + void generateInitkernel(const char *name); + void generateLaunchConfig(); + void generateCudaDeviceSync(); + void generateForKernel(); + void generateForKernel(Identifier *); + void generateCudaIndex(const char *idName); + void generateMemCpySymbol(char *var, const char *typeStr, bool direction); + void generateMallocDevice(Type *type, const char *identifier); + void generateMallocDeviceStr(const char *dVar, const char *type, + const char *sizeOfType); + void generateThreadId(const char *str); + void generateFuncBody(Function *proc); + + void generateStartTimer(); + void generateStopTimer(); + + void addRevBFSIterationLoop(iterateBFS *bfsAbstraction); + void addBFSIterationLoop(iterateBFS *bfsAbstraction); + void generateExtraDeviceVariable(const char *typeStr, const char *dVar, const char *sizeVal); + void addBFSIterKernel(iterateBFS *bfsAbstraction); + void addRevBFSIterKernel(list &revStmtList); + void generateAtomicDeviceAssignmentStmt(assignment *asmt, bool isMainFile); + void generateDeviceAssignmentStmt(assignment *asmt, bool isMainFile); + void addKernel(forallStmt *forAll); + void generateCallList(list paramList, dslCodePad &targetFile); + void generateMallocDeviceParams(list paramList); + void generateMemCpyParams(list paramList); + void generateHeaderDeviceVariable(const char *typeStr, const char *dVar); + void generateExtraDeviceVariableNoD(const char *typeStr, const char *dVar, const char *sizeVal); + void generatePropParams(list paramList, bool isNeedType, bool isMainFile); + //~ void setGenCSR(bool yes = true) { genCSR = yes; } + //~ bool isGenCSR() { return genCSR; } + //~ void setGName(const char* str) { + //~ strlen(str); + //~ strcpy(gName, str); + //~ } + //~ char* getGName() { return gName; } + void IncrementKCount() { kernelCount++; } + int getKCount() { return kernelCount; } + void setOptimized() { isOptimized = true; } + }; + + static const char *INTALLOCATION = "new int"; + static const char *BOOLALLOCATION = "new bool"; + static const char *FLOATALLOCATION = "new float"; + static const char *DOUBLEALLOCATION = "new double"; +} // namespace spsycl +#endif \ No newline at end of file diff --git a/src/backends/backend_sycl/getUsedVars.cpp b/src/backends/backend_sycl/getUsedVars.cpp new file mode 100644 index 00000000..748cb2b5 --- /dev/null +++ b/src/backends/backend_sycl/getUsedVars.cpp @@ -0,0 +1,339 @@ +#include "analyserUtil.cpp" + +usedVariables getVariablesStatement(statement *stmt); +usedVariables getVariablesExpr(Expression *expr) +{ + usedVariables result; + + if (expr->isIdentifierExpr()) + { + Identifier *iden = expr->getId(); + result.addVariable(iden, READ); + } + else if (expr->isPropIdExpr()) + { + PropAccess *propExpr = expr->getPropId(); + result.addVariable(propExpr->getIdentifier1(), READ); + result.addVariable(propExpr->getIdentifier2(), READ); + } + else if (expr->isUnary()) + { + if (expr->getOperatorType() == OPERATOR_NOT) + result = getVariablesExpr(expr->getUnaryExpr()); + else if ((expr->getOperatorType() == OPERATOR_INC) || (expr->getOperatorType() == OPERATOR_DEC)) + { + Expression *uExpr = expr->getUnaryExpr(); + if (uExpr->isIdentifierExpr()) + result.addVariable(uExpr->getId(), READ_WRITE); + else if (uExpr->isPropIdExpr()) + { + PropAccess *propId = uExpr->getPropId(); + result.addVariable(propId->getIdentifier1(), READ); + result.addVariable(propId->getIdentifier2(), READ_WRITE); + } + } + } + else if (expr->isLogical() || expr->isArithmetic() || expr->isRelational()) + { + result = getVariablesExpr(expr->getLeft()); + result.merge(getVariablesExpr(expr->getRight())); + } + return result; +} + +usedVariables getVariablesWhile(whileStmt *stmt) +{ + usedVariables currVars = getVariablesExpr(stmt->getCondition()); + currVars.merge(getVariablesStatement(stmt->getBody())); + + return currVars; +} + +usedVariables getVariablesDoWhile(dowhileStmt *stmt) +{ + usedVariables currVars = getVariablesExpr(stmt->getCondition()); + currVars.merge(getVariablesStatement(stmt->getBody())); + + return currVars; +} + +usedVariables getVariablesAssignment(assignment *stmt) +{ + usedVariables currVars; + if (stmt->lhs_isProp()) + { + PropAccess *propId = stmt->getPropId(); + currVars.addVariable(propId->getIdentifier1(), READ); + currVars.addVariable(propId->getIdentifier2(), WRITE); + } + else if (stmt->lhs_isIdentifier()) + currVars.addVariable(stmt->getId(), WRITE); + + usedVariables exprVars = getVariablesExpr(stmt->getExpr()); + currVars.merge(exprVars); + return currVars; +} + +usedVariables getVariablesIf(ifStmt *stmt) +{ + usedVariables currVars = getVariablesExpr(stmt->getCondition()); + currVars.merge(getVariablesStatement(stmt->getIfBody())); + if (stmt->getElseBody() != NULL) + currVars.merge(getVariablesStatement(stmt->getElseBody())); + + return currVars; +} +/* +// usedVariables getVariablesFixedPoint(fixedPointStmt *stmt) +// { +// usedVariables currVars = getVariablesExpr(stmt->getDependentProp()); +// currVars.addVariable(stmt->getFixedPointId()); +// currVars.merge(getVariablesStatement(stmt->getBody())); +// return currVars; +// } +// // TODO : Handle this atlast +// */ + +usedVariables getVariablesReduction(reductionCallStmt *stmt) +{ + usedVariables currVars; + + auto getVariablesReductionCall = [&currVars](reductionCall *callExpr) -> void + { + for (argument *arg : callExpr->getargList()) + { + if (arg->isExpr()) + currVars.merge(getVariablesExpr(arg->getExpr())); + } + }; + + if (stmt->is_reducCall()) + { + if (stmt->getLhsType() == 1) + { + currVars.addVariable(stmt->getLeftId(), WRITE); + getVariablesReductionCall(stmt->getReducCall()); + } + else if (stmt->getLhsType() == 2) + { + PropAccess *propId = stmt->getPropAccess(); + currVars.addVariable(propId->getIdentifier1(), READ); + currVars.addVariable(propId->getIdentifier2(), WRITE); + + getVariablesReductionCall(stmt->getReducCall()); + } + else if (stmt->getLhsType() == 3) + { + for (ASTNode *node : stmt->getLeftList()) + { + if (node->getTypeofNode() == NODE_ID) + { + Identifier *iden = (Identifier *)node; + currVars.addVariable(iden, WRITE); + } + else if (node->getTypeofNode() == NODE_PROPACCESS) + { + PropAccess *propId = (PropAccess *)node; + currVars.addVariable(propId->getIdentifier1(), READ); + currVars.addVariable(propId->getIdentifier2(), WRITE); + } + } + getVariablesReductionCall(stmt->getReducCall()); + + for (ASTNode *node : stmt->getRightList()) + { + if (node->getTypeofNode() == NODE_ID) + { + Identifier *iden = (Identifier *)node; + currVars.addVariable(iden, WRITE); + } + else if (node->getTypeofNode() == NODE_PROPACCESS) + { + PropAccess *propId = (PropAccess *)node; + currVars.addVariable(propId->getIdentifier1(), READ); + currVars.addVariable(propId->getIdentifier2(), WRITE); + } + } + } + } + else + { + if (stmt->isLeftIdentifier()) + { + currVars.addVariable(stmt->getLeftId(), READ_WRITE); + currVars.merge(getVariablesExpr(stmt->getRightSide())); + } + else + { + PropAccess *propId = stmt->getPropAccess(); + currVars.addVariable(propId->getIdentifier1(), READ); + currVars.addVariable(propId->getIdentifier2(), READ_WRITE); + + currVars.merge(getVariablesExpr(stmt->getRightSide())); + } + } + return currVars; +} + +usedVariables getVariablesUnary(unary_stmt *stmt) +{ + Expression *unaryExpr = stmt->getUnaryExpr(); + Expression *varExpr = unaryExpr->getUnaryExpr(); + + usedVariables currUsed; + if (varExpr->isIdentifierExpr()) + currUsed.addVariable(varExpr->getId(), READ_WRITE); + else if (varExpr->isPropIdExpr()) + { + currUsed.addVariable(varExpr->getPropId()->getIdentifier1(), READ); + currUsed.addVariable(varExpr->getPropId()->getIdentifier2(), WRITE); + } + + return currUsed; +} + +/* +// usedVariables getVariablesBFS(iterateBFS *stmt) +// { +// usedVariables currVars = getVariablesStatement(stmt->getBody()); +// if (stmt->getRBFS() != nullptr) +// { +// iterateReverseBFS *RBFSstmt = stmt->getRBFS(); +// if (RBFSstmt->getBFSFilter() != nullptr) +// currVars.merge(RBFSstmt->getBFSFilter()); +// currVars.merge(RBFSstmt->getBody()); +// } + +// return currVars; +// }*/ + +usedVariables getVariablesForAll(forallStmt *stmt) +{ + usedVariables currVars = getVariablesStatement(stmt->getBody()); + currVars.removeVariable(stmt->getIterator(), READ_WRITE); + + if (stmt->isSourceProcCall()) + { + proc_callExpr *expr = stmt->getExtractElementFunc(); + for (argument *arg : expr->getArgList()) + { + if (arg->getExpr() != nullptr) + currVars.merge(getVariablesExpr(arg->getExpr())); + } + } + else if (!stmt->isSourceField()) + { + Identifier *iden = stmt->getSource(); + currVars.addVariable(iden, READ); + } + else + { + PropAccess *propId = stmt->getPropSource(); + currVars.addVariable(propId->getIdentifier1(), READ); + } + + if (stmt->hasFilterExpr()) + currVars.merge(getVariablesExpr(stmt->getfilterExpr())); + + return currVars; +} + +usedVariables getVariablesBlock(blockStatement *blockStmt) +{ + list stmtList = blockStmt->returnStatements(); + list declVars; + + usedVariables currVars; + for (statement *stmt : stmtList) + { + if (stmt->getTypeofNode() == NODE_DECL) + { + declaration *decl = (declaration *)stmt; + declVars.push_back(decl->getdeclId()); + + if (decl->isInitialized()) + { + usedVariables exprVars = getVariablesExpr(decl->getExpressionAssigned()); + for (Identifier *dVars : declVars) + exprVars.removeVariable(dVars, READ_WRITE); + + currVars.merge(exprVars); + } + } + else + { + usedVariables stmtVars = getVariablesStatement(stmt); + for (Identifier *dVars : declVars) + stmtVars.removeVariable(dVars, READ_WRITE); + + currVars.merge(stmtVars); + } + } + + return currVars; +} +/* Function: getDeclaredPropertyVarsOfBlock + * Return all the Property variables declared in a the block! + * Used for cudaFree those variables + * usedVariables may be a misnomer?! for this function. + * --rajesh + */ +usedVariables getDeclaredPropertyVariablesOfBlock(blockStatement *blockStmt) +{ + list stmtList = blockStmt->returnStatements(); + list declVars; + + usedVariables currVars; + for (statement *stmt : stmtList) + { + if (stmt->getTypeofNode() == NODE_DECL) + { + declaration *decl = (declaration *)stmt; + if (decl->getType()->isPropType()) + { + currVars.addVariable(decl->getdeclId(), READ_WRITE); // 2nd arg may be not used by us + } + } + } + + return currVars; +} + +usedVariables getVariablesStatement(statement *stmt) +{ + switch (stmt->getTypeofNode()) + { + case NODE_BLOCKSTMT: + return getVariablesBlock((blockStatement *)stmt); + + case NODE_ASSIGN: + return getVariablesAssignment((assignment *)stmt); + + case NODE_UNARYSTMT: + return getVariablesUnary((unary_stmt *)stmt); + + case NODE_IFSTMT: + return getVariablesIf((ifStmt *)stmt); + + case NODE_WHILESTMT: + return getVariablesWhile((whileStmt *)stmt); + + case NODE_DOWHILESTMT: + return getVariablesDoWhile((dowhileStmt *)stmt); + + case NODE_FORALLSTMT: + return getVariablesForAll((forallStmt *)stmt); + + case NODE_REDUCTIONCALLSTMT: + return getVariablesReduction((reductionCallStmt *)stmt); + + /*case NODE_ITRBFS: + return getVariablesBFS((iterateBFS *)stmt); + + case NODE_FIXEDPTSTMT: + return getVariablesFixedPoint((fixedPointStmt *)stmt);*/ + default:; // added to fix warning! + } + + return usedVariables(); +} \ No newline at end of file diff --git a/src/opDebug.txt b/src/opDebug.txt new file mode 100644 index 00000000..135c5493 --- /dev/null +++ b/src/opDebug.txt @@ -0,0 +1,120 @@ +fileName ../graphcode/staticDSLCodes/bc_dslV2 +Backend Target cuda +Type: function + +'(' +Graph Type + +','Node Property +'<'Type: float'>' +','Set of Nodes'<''>' + +')'currentFuncType check!!0 +tempID g funccount 0 + +'{''.' +'(' +'=' +')'';'TYPE OF NODE OF STATEMENT1For: for +'(' +Keyword in +')' +'{'Node Property'<'Type: float'>' +';'Node Property'<'Type: float'>' +';''.''(''='')'';'TYPE OF NODE OF STATEMENT1'.''(' +'=' +')'';'TYPE OF NODE OF STATEMENT1'.' +'=' +';'iterateInBFS'(' +Keyword in +'.''('')' +from +')''{'For: for'(' +Keyword in +'.''('')'')''{''.''=''.''+''.'';''}''}'iterateInReverse'('NE_OP')''{'For: for'(' +Keyword in +'.''('')'')''{''.' +'=' +'.' +'+' +'(''.' +'/' +'.'')' +'*' +'(' + +'+' +'.'')'';''}''.' +'=' +'.' +'+' +'.'';''}''}' +'}' +error val 0 +at 1 +FORALL par NAME1:6 +FORALL ParPar NAME2:2 + TO Set DEVICE BOOL + ON: DEV ASST +RET FALSE +ANAME1:6 +ANAME2:18 +FORALL par NAME1:6 +FORALL ParPar NAME2:13 +FORALL ParParPar NAME3:6 +RET FALSE +ANAME1:6 +ANAME2:18 + ON ACC ASST STMT IN REV BFS +FORALL par NAME1:6 +FORALL ParPar NAME2:14 +FORALL ParParPar NAME3:13 + TP SET ACC BC BOOL +RET FALSE +ANAME1:6 +ANAME2:18 +ANAME1:6 +ANAME2:14 +at 2 +fileName bc_dslV2 +param :g +paramD:d_g +========== SET TRUE +param :BC +paramD:d_BC +param :sourceSet +paramD:d_sourceSet +param :g +paramD:d_g +param :BC +paramD:d_BC +param :sourceSet +paramD:d_sourceSet + ==VARSIZE:0 +varName:BC +STMT: For +isMainFile val 1 +GenerateForAllSignature = 0 +FOR ==VARSIZE:2 +varName:delta +varName:sigma + ASST + DEVICE ASST +STMT: For +isMainFile val 0 +GenerateForAllSignature = 0 + ITERATE Neighbour +src:w + ==VARSIZE:0 + ASST +STMT: For +isMainFile val 0 +GenerateForAllSignature = 0 + ITERATE Neighbour +src:w +V?:v + ==VARSIZE:0 + ASST + ASST + RESULT NO BC by 2 ASST +finished successfully diff --git a/src/parser/includeHeader.hpp b/src/parser/includeHeader.hpp index c658cb9b..bbd099e0 100644 --- a/src/parser/includeHeader.hpp +++ b/src/parser/includeHeader.hpp @@ -1,10 +1,9 @@ #ifndef INCLUDEHEADER_H #define INCLUDEHEADER_H - -//#include "../maincontext/MainContext.hpp" +// #include "../maincontext/MainContext.hpp" #include "../maincontext/enum_def.hpp" -//#include "../symbolutil/SymbolTable.hpp" +// #include "../symbolutil/SymbolTable.hpp" /*#include "../ast/ASTNodeTypes.hpp" #include "../ast/ASTNode.hpp" #include "../ast/ASTHelper.cpp"*/ @@ -25,7 +24,9 @@ #include "../symbolutil/SymbolTableBuilder.h" -extern "C" int yyparse (void); +/* UNCOMMENT IT TO GENERATE FOR SYCL BACKEND */ +#include "../backends/backend_sycl/dsl_cpp_generator.h" +extern "C" int yyparse(void); #endif diff --git a/src/parser/lexer.l b/src/parser/lexer.l index d3557c38..92b3107b 100644 --- a/src/parser/lexer.l +++ b/src/parser/lexer.l @@ -92,6 +92,7 @@ NEGATE [-] "+" { printf ( "'+'"); return '+';} "*" { printf ( "'*'"); return '*';} "/" { printf ( "'/'"); return '/';} +"//"[^\n]*"\n" { printf ( "COMMENT" ); } "%" { printf ( "'%%'"); return '%';} "<" { printf ( "'<'"); return '<';} ">" { printf ( "'>'"); return '>';} diff --git a/src/parser/lrparser.y b/src/parser/lrparser.y index 0134f228..137ec5c9 100644 --- a/src/parser/lrparser.y +++ b/src/parser/lrparser.y @@ -538,7 +538,7 @@ int main(int argc,char **argv) } else { - if(!((strcmp(backendTarget,"omp")==0)||(strcmp(backendTarget,"mpi")==0)||(strcmp(backendTarget,"cuda")==0) || (strcmp(backendTarget,"acc")==0))) + if(!((strcmp(backendTarget,"omp")==0)||(strcmp(backendTarget,"mpi")==0)||(strcmp(backendTarget,"cuda")==0) || (strcmp(backendTarget,"acc")==0) || (strcmp(backendTarget,"sycl")==0))) { fprintf(stderr, "Specified backend target is not implemented in the current version!\n"); exit(-1); @@ -635,6 +635,12 @@ int main(int argc,char **argv) } cpp_backend.generate(); } + else if (strcmp(backendTarget, "sycl") == 0) { + std::cout<<"GENERATING SYCL CODE"<getTypeofNode() == NODE_ONADDBLOCK) - { - onAddBlock* onAddStmt = (onAddBlock*)preprocessEnv; - updatesId = onAddStmt->getUpdateId(); - - } - else - { - onDeleteBlock* onDeleteStmt = (onDeleteBlock*)preprocessEnv; - updatesId = onDeleteStmt->getUpdateId(); - - } - Identifier* id1 = expr->getIdentifier1(); - string updatesIdName(updatesId->getIdentifier()); - if(updatesIdName == id1->getIdentifier()) - expr->getIdentifier1()->setUpdateAssociation(updatesId); + Identifier *updatesId = NULL; + if (preprocessEnv->getTypeofNode() == NODE_ONADDBLOCK) + { + onAddBlock *onAddStmt = (onAddBlock *)preprocessEnv; + updatesId = onAddStmt->getUpdateId(); + } + else + { + onDeleteBlock *onDeleteStmt = (onDeleteBlock *)preprocessEnv; + updatesId = onDeleteStmt->getUpdateId(); + } + Identifier *id1 = expr->getIdentifier1(); + string updatesIdName(updatesId->getIdentifier()); + if (updatesIdName == id1->getIdentifier()) + expr->getIdentifier1()->setUpdateAssociation(updatesId); } /* if the filter is on a nested for all statement, the filter is propagated to the parent parallel-for loop */ -void setFilterAssocForForAll(std::vector parallelConstruct, Expression* filterExpr) +void setFilterAssocForForAll(std::vector parallelConstruct, Expression *filterExpr) +{ + forallStmt *forStmt = NULL; + + for (int i = 0; i < parallelConstruct.size(); i++) + { + if (parallelConstruct[i]->getTypeofNode() == NODE_FORALLSTMT) + { + forStmt = (forallStmt *)parallelConstruct[i]; + break; + } + } + + forStmt->setFilterExprAssoc(); + forStmt->setAssocExpr(filterExpr); +} + +bool search_and_connect_toId(SymbolTable *sTab, Identifier *id) { - forallStmt* forStmt = NULL; - - for(int i=0 ; i < parallelConstruct.size() ; i++) - { - if(parallelConstruct[i]->getTypeofNode() == NODE_FORALLSTMT) - { - forStmt = (forallStmt*)parallelConstruct[i]; - break; - } - } - - forStmt->setFilterExprAssoc(); - forStmt->setAssocExpr(filterExpr); + assert(id != NULL); + assert(id->getIdentifier() != NULL); + TableEntry *tableEntry = sTab->findEntryInST(id); + if (tableEntry == NULL) + { + return false; + // to be added. + } + if (id->getSymbolInfo() != NULL) + { + assert(id->getSymbolInfo() == tableEntry); + } + else + id->setSymbolInfo(tableEntry); + + return true; } -bool search_and_connect_toId(SymbolTable* sTab,Identifier* id) - { - assert(id!=NULL); - assert(id->getIdentifier()!=NULL); - TableEntry* tableEntry=sTab->findEntryInST(id); - if(tableEntry==NULL) - { return false; - //to be added. - } - if(id->getSymbolInfo()!=NULL) +void addPropToSymbolTE(SymbolTable *sTab, Identifier *id, std::list argList) +{ + assert(id != NULL); + assert(id->getIdentifier() != NULL); + TableEntry *tableEntry = sTab->findEntryInST(id); + Type *type = tableEntry->getType(); + for (argument *arg : argList) + { + assert(arg->isAssignExpr()); + if (arg->isAssignExpr()) + { + assignment *assign = (assignment *)arg->getAssignExpr(); + type->addToPropList(assign->getId()); + Identifier *TE_id = assign->getId()->getSymbolInfo()->getId(); + TE_id->set_assignedExpr(assign->getExpr()); // added to extract the initialization value. + } + } +} + +declaration *createPropertyDeclaration(Identifier *&id) +{ + + Type *typeNode = Type::createForPrimitive(TYPE_INT, 1); + Type *propType = Type::createForPropertyType(TYPE_PROPNODE, 4, typeNode); + declaration *declNode = declaration::normal_Declaration(propType, id); + return declNode; +} + +argument *createAssignedArg(Identifier *id) +{ + Expression *exprForId = Expression::nodeForIntegerConstant(-1); + assignment *assignmentNode = assignment::id_assignExpr(id, exprForId); + argument *arg = new argument(); + arg->setAssign(assignmentNode); + arg->setAssignFlag(); + return arg; +} + +/*void SymbolTableBuilder::setLockDeclInFunc(ASTNode* node) + { + + ASTNode* parent = node->getParent(); + if(parent!=NULL) { - assert(id->getSymbolInfo()==tableEntry); + if(parent->getTypeofNode()!=NODE_FUNC) + setLockDeclInFunc(parent); + else + { + + Function* func = (Function*) node; + func->setInitialLockDecl(); + } } - else - id->setSymbolInfo(tableEntry); - return true; + }*/ - } +bool create_Symbol(SymbolTable *sTab, Identifier *id, Type *type) +{ + bool checkFine = sTab->check_conflicts_and_add(sTab, id, type); + if (!checkFine) + { + // action to be added. + } + search_and_connect_toId(sTab, id); - void addPropToSymbolTE(SymbolTable* sTab,Identifier* id,std::list argList) - { - assert(id!=NULL); - assert(id->getIdentifier()!=NULL); - TableEntry* tableEntry=sTab->findEntryInST(id); - Type* type = tableEntry->getType(); - for(argument* arg:argList) - { - assert(arg->isAssignExpr()); - if(arg->isAssignExpr()) - { - assignment* assign=(assignment*)arg->getAssignExpr(); - type->addToPropList(assign->getId()); - Identifier* TE_id = assign->getId()->getSymbolInfo()->getId(); - TE_id->set_assignedExpr(assign->getExpr()); // added to extract the initialization value. - } - } - - - } - - declaration* createPropertyDeclaration(Identifier* &id) - { - - Type* typeNode=Type::createForPrimitive(TYPE_INT,1); - Type* propType=Type::createForPropertyType(TYPE_PROPNODE,4,typeNode); - declaration* declNode=declaration::normal_Declaration(propType,id); - return declNode; - } - - argument* createAssignedArg(Identifier* id) - { - Expression* exprForId=Expression::nodeForIntegerConstant(-1); - assignment* assignmentNode=assignment::id_assignExpr(id,exprForId); - argument* arg=new argument(); - arg->setAssign(assignmentNode); - arg->setAssignFlag(); - return arg; + return checkFine; +} + +bool checkInsideBFSIter(std::vector parallelRegions) +{ + int size = parallelRegions.size() - 1; + while (size >= 0) + { + ASTNode *parallelRegion = parallelRegions[size]; + if (parallelRegion->getTypeofNode() == NODE_ITRBFS) + return true; + + size = size - 1; + } - } + return false; +} - /*void SymbolTableBuilder::setLockDeclInFunc(ASTNode* node) +void SymbolTableBuilder::buildForProc(Function *func) +{ + currentFunc = func; + if (func->getFuncType() == STATIC_FUNC) { + Identifier *methodId = func->getIdentifier(); + string methodString(methodId->getIdentifier()); + dynamicLinkedFunc[methodString] = false; + } + init_curr_SymbolTable(func); + list paramList = func->getParamList(); + list::iterator itr; - ASTNode* parent = node->getParent(); - if(parent!=NULL) - { - if(parent->getTypeofNode()!=NODE_FUNC) - setLockDeclInFunc(parent); - else - { - - Function* func = (Function*) node; - func->setInitialLockDecl(); - } - } - - }*/ - - bool create_Symbol(SymbolTable* sTab,Identifier* id,Type* type) - { - bool checkFine=sTab->check_conflicts_and_add(sTab, id,type); - if(!checkFine) - { - //action to be added. - } - search_and_connect_toId(sTab,id); + for (itr = paramList.begin(); itr != paramList.end(); itr++) + { + formalParam *fp = (*itr); + Type *type = fp->getType(); + Identifier *id = fp->getIdentifier(); + SymbolTable *symbTab = type->isPropType() ? currPropSymbT : currVarSymbT; + bool creationFine = create_Symbol(symbTab, id, type); + id->getSymbolInfo()->setArgument(true); + } - return checkFine; - } + buildForStatements(func->getBlockStatement()); + delete_curr_SymbolTable(); +} - bool checkInsideBFSIter(std::vector parallelRegions) +void SymbolTableBuilder::buildForStatements(statement *stmt) +{ + bool searchSuccess = false; + switch (stmt->getTypeofNode()) { - int size = parallelRegions.size() - 1; - while(size >= 0) - { - ASTNode* parallelRegion = parallelRegions[size]; - if(parallelRegion->getTypeofNode() == NODE_ITRBFS) - return true; + case NODE_DECL: + { + declaration *declStmt = (declaration *)stmt; + Type *type = declStmt->getType(); + SymbolTable *symbTab = type->isPropType() ? currPropSymbT : currVarSymbT; + bool creatsFine = create_Symbol(symbTab, declStmt->getdeclId(), type); + + if (parallelConstruct.size() == 0) + { + declStmt->getdeclId()->getSymbolInfo()->setGlobalVariable(); + } - size = size - 1; + if (declStmt->isInitialized()) + { + Expression *exprAssigned = declStmt->getExpressionAssigned(); + checkForExpressions(exprAssigned); + if (type->isPropType()) + { + if (exprAssigned->isIndexExpr()) + { + Expression *mapExpr = exprAssigned->getMapExpr(); + Identifier *mapId = mapExpr->getId(); + Type *mapType = mapId->getSymbolInfo()->getType(); + Type *innerTarget = mapType->getInnerTargetType(); + if (innerTarget->isPropNodeType()) + { + declStmt->setMapPropCopy(); + } + } + else if (exprAssigned->isIdentifierExpr()) + { + Identifier *rhsPropId = exprAssigned->getId(); + if (rhsPropId->getSymbolInfo()->getType()->isPropNodeType()) + declStmt->setPropCopy(); + } + } + } + break; + } + + case NODE_ASSIGN: + { + assignment *assign = (assignment *)stmt; + Expression *exprAssigned = assign->getExpr(); + string backend(backendTarget); + + if (assign->lhs_isIdentifier()) + { + Identifier *id = assign->getId(); + searchSuccess = findSymbolId(id); + if (backend.compare("mpi") == 0 && IdsInsideParallelFilter.find(id->getSymbolInfo()) != IdsInsideParallelFilter.end()) + { + id->getSymbolInfo()->getId()->set_used_inside_forall_filter_and_changed_inside_forall_body(); + } + + // Add MORE DOC : Push all the globalvariables which are modified inside the parallel region + if (backend.compare("mpi") == 0) + { + if (id->getSymbolInfo()->isGlobalVariable()) + { + + if (parallelConstruct.size() > 0) + { + printf("global variable changed here %s \n", id->getIdentifier()); + // Add More DOC (Atharva) + ASTNode *parallel = parallelConstruct.back(); + if (parallel->getTypeofNode() == NODE_FORALLSTMT) + { + + forallStmt *forall = (forallStmt *)parallel; + printf("%s\n", id->getSymbolInfo()->getId()->getIdentifier()); + forall->pushModifiedGlobalVariable(id->getSymbolInfo()); + printf("global var inserted\n"); + } + else if (parallel->getTypeofNode() == NODE_ITRBFS) + { + // iterateBFS* iBFS = (iterateBFS*) parallel; + // iBFS->pushModifiedGlobalVariable(id->getSymbolInfo()); + } + else if (parallel->getTypeofNode() == NODE_ITRRBFS) + { + // iterateReverseBFS* iRBFS = (iterateReverseBFS*) parallel; + // iRBFS->pushModifiedGlobalVariable(id->getSymbolInfo()); + } + else + { + assert(false); // add similar for other parallel constructs like itrbfs if needed + } + } } + } + } + else if (assign->lhs_isProp()) + { + PropAccess *propId = assign->getPropId(); + searchSuccess = findSymbolPropId(propId); + if (backend.compare("mpi") == 0 && IdsInsideParallelFilter.find(propId->getIdentifier2()->getSymbolInfo()) != IdsInsideParallelFilter.end()) + { + propId->getIdentifier2()->getSymbolInfo()->getId()->set_used_inside_forall_filter_and_changed_inside_forall_body(); + } + } + else if (assign->lhs_isIndexAccess()) + { + + Expression *expr = assign->getIndexAccess(); + checkForExpressions(expr); + } + + if ((backend.compare("cuda") == 0 || (backend.compare("sycl") == 0)) && assign->lhs_isProp()) + { // This flags device assingments OUTSIDE for + //~ std::cout<< "varName1: " << assign->getPropId()->getIdentifier1()->getIdentifier() << '\n'; + //~ std::cout<< "varName2: " << assign->getPropId()->getIdentifier2()->getIdentifier() << '\n'; + std::cout << "ANAME1:" << assign->getParent()->getTypeofNode() << '\n'; + std::cout << "ANAME2:" << assign->getParent()->getParent()->getTypeofNode() << '\n'; + //~ std::cout<< "ANAME3:"<< assign->getParent()->getParent()->getParent()->getTypeofNode() << '\n'; + if (assign->getParent()->getParent()->getTypeofNode() == NODE_FUNC || (assign->getParent()->getParent()->getTypeofNode() != NODE_FUNC && assign->getParent()->getParent()->getParent()->getTypeofNode() == NODE_FUNC)) + { + std::cout << "\t\tSetting device bool" << '\n'; + assign->flagAsDeviceVariable(); + } + } - return false; + checkForExpressions(exprAssigned); + if (assign->lhs_isIdentifier()) + { + Identifier *id = assign->getId(); + if (id->getSymbolInfo()->getType()->isPropType()) + { + if (exprAssigned->isIdentifierExpr()) + { + Identifier *rhsPropId = exprAssigned->getId(); + if (id->getSymbolInfo()->getType()->isPropNodeType() && rhsPropId->getSymbolInfo()->getType()->isPropNodeType()) + assign->setPropCopy(); + else if (id->getSymbolInfo()->getType()->isPropEdgeType() && rhsPropId->getSymbolInfo()->getType()->isPropEdgeType()) + assign->setPropCopy(); + } + } + } + break; } + case NODE_FIXEDPTSTMT: + { + fixedPointStmt *fpStmt = (fixedPointStmt *)stmt; + Identifier *fixedPointId = fpStmt->getFixedPointId(); + searchSuccess = findSymbolId(fixedPointId); + checkForExpressions(fpStmt->getDependentProp()); + /* This else portion needs to be generalized to handle expressions of all kinds. + Currently handling dependent expressions that is based on a single node property and is Unary*/ + + if (fpStmt->getDependentProp()->isUnary() || fpStmt->getDependentProp()->isIdentifierExpr()) + { + Identifier *depId; + if (fpStmt->getDependentProp()->isUnary()) + { + depId = fpStmt->getDependentProp()->getUnaryExpr()->getId(); + } + else + { + depId = fpStmt->getDependentProp()->getId(); + } + if (depId->getSymbolInfo() != NULL) + { + Identifier *tableId = depId->getSymbolInfo()->getId(); + printf(tableId->getIdentifier()); + printf("\n"); + tableId->set_redecl(); // explained in the ASTNodeTypes + tableId->set_fpassociation(); // explained in the ASTNodeTypes + tableId->set_fpId(fixedPointId->getIdentifier()); // explained in the ASTNodeTypes + tableId->set_fpIdNode(fixedPointId); // explained in the ASTNodeTypes + tableId->set_dependentExpr(fpStmt->getDependentProp()); + } + } + buildForStatements(fpStmt->getBody()); + + break; + } + + case NODE_FORALLSTMT: + { + forallStmt *forAll = (forallStmt *)stmt; + Identifier *source1 = forAll->isSourceProcCall() ? forAll->getSourceGraph() : NULL; + if (forAll->getSource() != NULL) + source1 = forAll->getSource(); - void SymbolTableBuilder::buildForProc(Function* func) - { - currentFunc = func; - if(func->getFuncType() == STATIC_FUNC) { - Identifier* methodId = func->getIdentifier(); - string methodString(methodId->getIdentifier()); - dynamicLinkedFunc[methodString] = false; - } - init_curr_SymbolTable(func); - list paramList=func->getParamList(); - list::iterator itr; - - for(itr=paramList.begin();itr!=paramList.end();itr++) - { - formalParam* fp=(*itr); - Type* type=fp->getType(); - Identifier* id=fp->getIdentifier(); - SymbolTable* symbTab=type->isPropType()?currPropSymbT:currVarSymbT; - bool creationFine=create_Symbol(symbTab,id,type); - id->getSymbolInfo()->setArgument(true); - - + PropAccess *propId = forAll->isSourceField() ? forAll->getPropSource() : NULL; + Identifier *iterator = forAll->getIterator(); + searchSuccess = checkHeaderSymbols(source1, propId, forAll); + if (forAll->isSourceExpr()) + { + + cout << "Entered here check source " << forAll->getSourceExpr()->getMapExpr()->getId()->getIdentifier() << "\n"; + checkForExpressions(forAll->getSourceExpr()); } - buildForStatements(func->getBlockStatement()); - delete_curr_SymbolTable(); + string backend(backendTarget); + if (forAll->hasFilterExpr()) + { + checkForExpressions(forAll->getfilterExpr()); + } + /* Required for omp backend code generation, + the forall is checked for its existence inside + another forall which is to be generated with + omp parallel pragma, and then disable the parallel loop*/ + if ((backend.compare("omp") == 0) || (backend.compare("cuda") == 0) || (backend.compare("acc") == 0) || (backend.compare("mpi") == 0) || (backend.compare("sycl") == 0)) + { + if (parallelConstruct.size() > 0) + { + forAll->disableForall(); + if (forAll->hasFilterExpr()) + setFilterAssocForForAll(parallelConstruct, forAll->getfilterExpr()); + } + if (forAll->isForall()) + { + parallelConstruct.push_back(forAll); + if (forAll->hasFilterExpr()) + if (backend.compare("mpi") == 0) + getIdsInsideExpression(forAll->getfilterExpr(), IdsInsideParallelFilter); + } + } - } + if (backend.compare("cuda") == 0 || (backend.compare("sycl") == 0)) + { // This flags device assingments INSIDE for + std::cout << "FORALL par NAME1:" << forAll->getParent()->getTypeofNode() << '\n'; + if (forAll->getParent()->getParent()) + std::cout << "FORALL ParPar NAME2:" << forAll->getParent()->getParent()->getTypeofNode() << '\n'; + if (forAll->getParent()->getParent()->getParent()) + std::cout << "FORALL ParParPar NAME3:" << forAll->getParent()->getParent()->getParent()->getTypeofNode() << '\n'; + + if (forAll->getParent()->getParent()->getTypeofNode() == NODE_FUNC) + { // This flags device assingments OUTSIDE for e.g BC + std::cout << "\t\tTO Set DEVICE BOOL" << '\n'; + forAll->addDeviceAssignment(); + } + if (forAll->getParent()->getParent()->getTypeofNode() == NODE_ITRRBFS) + { + std::cout << "\t\tTP SET ACC BC BOOL" << '\n'; + //~ forAll->addDeviceAssignment(); + } + } - void SymbolTableBuilder::buildForStatements(statement* stmt) - { - bool searchSuccess=false; - switch(stmt->getTypeofNode()) + if (checkInsideBFSIter(parallelConstruct)) { - case NODE_DECL: - { - declaration* declStmt=(declaration*)stmt; - Type* type=declStmt->getType(); - SymbolTable* symbTab=type->isPropType()?currPropSymbT:currVarSymbT; - bool creatsFine=create_Symbol(symbTab,declStmt->getdeclId(),type); - - if(parallelConstruct.size()==0) - { - declStmt->getdeclId()->getSymbolInfo()->setGlobalVariable(); - } - - if(declStmt->isInitialized()) - { - Expression* exprAssigned = declStmt->getExpressionAssigned(); - checkForExpressions(exprAssigned); - if(type->isPropType()){ - if(exprAssigned->isIndexExpr()) - { - Expression* mapExpr = exprAssigned->getMapExpr(); - Identifier* mapId = mapExpr->getId(); - Type* mapType = mapId->getSymbolInfo()->getType(); - Type* innerTarget = mapType->getInnerTargetType(); - - if(innerTarget->isPropNodeType()){ - declStmt->setMapPropCopy(); - } - - } - else if(exprAssigned->isIdentifierExpr()) - { - Identifier* rhsPropId = exprAssigned->getId(); - if(rhsPropId->getSymbolInfo()->getType()->isPropNodeType()) - declStmt->setPropCopy() ; - } - } - } - break; - } - - case NODE_ASSIGN: - { - assignment* assign=(assignment*)stmt; - Expression* exprAssigned = assign->getExpr(); - string backend(backendTarget); - - if(assign->lhs_isIdentifier()) - { - Identifier* id=assign->getId(); - searchSuccess=findSymbolId(id); - if(backend.compare("mpi") == 0 && IdsInsideParallelFilter.find(id->getSymbolInfo()) != IdsInsideParallelFilter.end()) { - id->getSymbolInfo()->getId()->set_used_inside_forall_filter_and_changed_inside_forall_body(); - } - - // Add MORE DOC : Push all the globalvariables which are modified inside the parallel region - if(backend.compare("mpi") == 0) - { - if(id->getSymbolInfo()->isGlobalVariable()) - { - - if(parallelConstruct.size()>0) - { printf("global variable changed here %s \n", id->getIdentifier()); - // Add More DOC (Atharva) - ASTNode * parallel = parallelConstruct.back(); - if(parallel->getTypeofNode() == NODE_FORALLSTMT) - { - - forallStmt* forall = (forallStmt*) parallel; - printf("%s\n",id->getSymbolInfo()->getId()->getIdentifier()); - forall->pushModifiedGlobalVariable(id->getSymbolInfo()); - printf("global var inserted\n"); - } - else if(parallel->getTypeofNode() == NODE_ITRBFS) - { - //iterateBFS* iBFS = (iterateBFS*) parallel; - //iBFS->pushModifiedGlobalVariable(id->getSymbolInfo()); - } - else if(parallel->getTypeofNode() == NODE_ITRRBFS) - { - //iterateReverseBFS* iRBFS = (iterateReverseBFS*) parallel; - //iRBFS->pushModifiedGlobalVariable(id->getSymbolInfo()); - } - else - { - assert(false); // add similar for other parallel constructs like itrbfs if needed - } - } - } - } - } - else if(assign->lhs_isProp()) - { - PropAccess* propId = assign->getPropId(); - searchSuccess = findSymbolPropId(propId); - if(backend.compare("mpi") == 0 && IdsInsideParallelFilter.find(propId->getIdentifier2()->getSymbolInfo()) != IdsInsideParallelFilter.end()) { - propId->getIdentifier2()->getSymbolInfo()->getId()->set_used_inside_forall_filter_and_changed_inside_forall_body(); - } - } - else if(assign->lhs_isIndexAccess()){ - - Expression* expr = assign->getIndexAccess(); - checkForExpressions(expr); - - } - - if(backend.compare("cuda")== 0 && assign->lhs_isProp()){ // This flags device assingments OUTSIDE for - //~ std::cout<< "varName1: " << assign->getPropId()->getIdentifier1()->getIdentifier() << '\n'; - //~ std::cout<< "varName2: " << assign->getPropId()->getIdentifier2()->getIdentifier() << '\n'; - std::cout<<"ANAME1:"<< assign->getParent()->getTypeofNode() << '\n'; - std::cout<< "ANAME2:"<< assign->getParent()->getParent()->getTypeofNode() << '\n'; - //~ std::cout<< "ANAME3:"<< assign->getParent()->getParent()->getParent()->getTypeofNode() << '\n'; - if(assign->getParent()->getParent()->getTypeofNode()==NODE_FUNC || (assign->getParent()->getParent()->getTypeofNode()!=NODE_FUNC && assign->getParent()->getParent()->getParent()->getTypeofNode()==NODE_FUNC)){ - std::cout<< "\t\tSetting device bool" << '\n'; - assign->flagAsDeviceVariable(); - } - } - - - checkForExpressions(exprAssigned); - - if(assign->lhs_isIdentifier()) - { - Identifier* id=assign->getId(); - if(id->getSymbolInfo()->getType()->isPropType()) - { - if(exprAssigned->isIdentifierExpr()) - { - Identifier* rhsPropId = exprAssigned->getId(); - if(id->getSymbolInfo()->getType()->isPropNodeType() && rhsPropId->getSymbolInfo()->getType()->isPropNodeType()) - assign->setPropCopy() ; - else if(id->getSymbolInfo()->getType()->isPropEdgeType() && rhsPropId->getSymbolInfo()->getType()->isPropEdgeType()) - assign->setPropCopy() ; - - } - } - - } - - break; - } - case NODE_FIXEDPTSTMT: - { - fixedPointStmt* fpStmt=(fixedPointStmt*)stmt; - Identifier* fixedPointId=fpStmt->getFixedPointId(); - searchSuccess=findSymbolId(fixedPointId); - checkForExpressions(fpStmt->getDependentProp()); - /* This else portion needs to be generalized to handle expressions of all kinds. - Currently handling dependent expressions that is based on a single node property and is Unary*/ - - if(fpStmt->getDependentProp()->isUnary()||fpStmt->getDependentProp()->isIdentifierExpr()) - { - Identifier* depId ; - if(fpStmt->getDependentProp()->isUnary()) - { - depId = fpStmt->getDependentProp()->getUnaryExpr()->getId(); - } - else - { - depId = fpStmt->getDependentProp()->getId(); - } - if(depId->getSymbolInfo()!=NULL) - { - Identifier* tableId = depId->getSymbolInfo()->getId(); - printf(tableId->getIdentifier()); - printf("\n"); - tableId->set_redecl(); //explained in the ASTNodeTypes - tableId->set_fpassociation(); //explained in the ASTNodeTypes - tableId->set_fpId(fixedPointId->getIdentifier()); //explained in the ASTNodeTypes - tableId->set_fpIdNode(fixedPointId); //explained in the ASTNodeTypes - tableId->set_dependentExpr(fpStmt->getDependentProp()); - } - } - buildForStatements(fpStmt->getBody()); - - break; - - } - - case NODE_FORALLSTMT: - { - - forallStmt* forAll=(forallStmt*)stmt; - Identifier* source1 = forAll->isSourceProcCall()?forAll->getSourceGraph():NULL; - - if(forAll->getSource()!=NULL) - source1 = forAll->getSource(); - - PropAccess* propId = forAll->isSourceField()?forAll->getPropSource():NULL; - Identifier* iterator = forAll->getIterator(); - searchSuccess = checkHeaderSymbols(source1,propId,forAll); - - - - - if(forAll->isSourceExpr()){ - - cout<<"Entered here check source "<getSourceExpr()->getMapExpr()->getId()->getIdentifier()<<"\n"; - checkForExpressions(forAll->getSourceExpr()); - } + /* the assignment statements(arithmetic & logical) within the block of a for statement that + is itself within a IterateInBFS abstraction are signaled to become atomic while code + generation. */ + iterateBFS *parent = (iterateBFS *)parallelConstruct[0]; + cout << "parent type: " << parent->getTypeofNode() << endl; + proc_callExpr *extractElem = forAll->getExtractElementFunc(); + if (extractElem != NULL) + { + string methodString(extractElem->getMethodId()->getIdentifier()); + list argList = extractElem->getArgList(); + if (methodString == nbrCall) + { + forAll->addAtomicSignalToStatements(); + parent->setIsMetaUsed(); + currentFunc->setIsMetaUsed(); + parent->setIsDataUsed(); + currentFunc->setIsDataUsed(); + } + else if (methodString == nodesToCall) + { + parent->setIsRevMetaUsed(); + currentFunc->setIsRevMetaUsed(); + parent->setIsSrcUsed(); + currentFunc->setIsSrcUsed(); + } + } + } + else + { // if for all statement has a proc call + proc_callExpr *extractElemFunc = forAll->getExtractElementFunc(); + if (extractElemFunc != NULL && parallelConstruct.size() > 0) + { + forallStmt *parent = (forallStmt *)parallelConstruct.back(); + Identifier *iteratorMethodId = extractElemFunc->getMethodId(); + string iteratorMethodString(iteratorMethodId->getIdentifier()); + if (iteratorMethodString == nodesToCall) + { // if the proc call is nodes_to, d_rev_meta is needed + parent->setIsRevMetaUsed(); + currentFunc->setIsRevMetaUsed(); + parent->setIsSrcUsed(); + currentFunc->setIsSrcUsed(); + } + else if (iteratorMethodString == nbrCall) + { // if the proc call is neighbors, d_data is needed + parent->setIsMetaUsed(); + currentFunc->setIsMetaUsed(); + parent->setIsDataUsed(); + currentFunc->setIsDataUsed(); + } + } + } - string backend(backendTarget); - if(forAll->hasFilterExpr()) - { - checkForExpressions(forAll->getfilterExpr()); - } - /* Required for omp backend code generation, - the forall is checked for its existence inside - another forall which is to be generated with - omp parallel pragma, and then disable the parallel loop*/ - - if( (backend.compare("omp")==0) || (backend.compare("cuda")==0) || (backend.compare("acc")==0) || (backend.compare("mpi")==0) ) - { - if(parallelConstruct.size()>0) - { - forAll->disableForall(); - if(forAll->hasFilterExpr()) - setFilterAssocForForAll(parallelConstruct, forAll->getfilterExpr()); - - } - - if(forAll->isForall()) - { - parallelConstruct.push_back(forAll); - if(forAll->hasFilterExpr()) - if(backend.compare("mpi")==0) - getIdsInsideExpression(forAll->getfilterExpr(),IdsInsideParallelFilter); - - - } - } - - if(backend.compare("cuda")== 0 ){ // This flags device assingments INSIDE for - std::cout<< "FORALL par NAME1:"<< forAll->getParent()->getTypeofNode() << '\n'; - if(forAll->getParent()->getParent()) - std::cout<< "FORALL ParPar NAME2:"<< forAll->getParent()->getParent()->getTypeofNode() << '\n'; - if(forAll->getParent()->getParent()->getParent()) - std::cout<< "FORALL ParParPar NAME3:"<< forAll->getParent()->getParent()->getParent()->getTypeofNode() << '\n'; - - if(forAll->getParent()->getParent()->getTypeofNode()==NODE_FUNC){ // This flags device assingments OUTSIDE for e.g BC - std::cout<< "\t\tTO Set DEVICE BOOL" << '\n'; - forAll->addDeviceAssignment(); - } - if(forAll->getParent()->getParent()->getTypeofNode()==NODE_ITRRBFS ) { - std::cout<< "\t\tTP SET ACC BC BOOL" << '\n'; - //~ forAll->addDeviceAssignment(); - } - } + buildForStatements(forAll->getBody()); - if(checkInsideBFSIter(parallelConstruct)) - { - /* the assignment statements(arithmetic & logical) within the block of a for statement that - is itself within a IterateInBFS abstraction are signaled to become atomic while code - generation. */ - iterateBFS* parent = (iterateBFS*)parallelConstruct[0]; - cout << "parent type: " << parent->getTypeofNode() << endl; - proc_callExpr* extractElem = forAll->getExtractElementFunc(); - if(extractElem!=NULL) - { - string methodString(extractElem->getMethodId()->getIdentifier()); - list argList = extractElem->getArgList(); - if(methodString == nbrCall) - { - forAll->addAtomicSignalToStatements(); - parent->setIsMetaUsed(); - currentFunc->setIsMetaUsed(); - parent->setIsDataUsed(); - currentFunc->setIsDataUsed(); - } - else if(methodString == nodesToCall) - { - parent->setIsRevMetaUsed(); - currentFunc->setIsRevMetaUsed(); - parent->setIsSrcUsed(); - currentFunc->setIsSrcUsed(); - } - } - } - else { // if for all statement has a proc call - proc_callExpr* extractElemFunc = forAll->getExtractElementFunc(); - if(extractElemFunc != NULL && parallelConstruct.size() > 0) { - forallStmt* parent = (forallStmt*) parallelConstruct.back(); - Identifier* iteratorMethodId = extractElemFunc->getMethodId(); - string iteratorMethodString(iteratorMethodId->getIdentifier()); - if(iteratorMethodString == nodesToCall) { // if the proc call is nodes_to, d_rev_meta is needed - parent->setIsRevMetaUsed(); - currentFunc->setIsRevMetaUsed(); - parent->setIsSrcUsed(); - currentFunc->setIsSrcUsed(); - } else if(iteratorMethodString == nbrCall) { // if the proc call is neighbors, d_data is needed - parent->setIsMetaUsed(); - currentFunc->setIsMetaUsed(); - parent->setIsDataUsed(); - currentFunc->setIsDataUsed(); - } - } - } - - buildForStatements(forAll->getBody()); - - //----------------------MERGE CONFLICT OCCURRED HERE (WORKING BRANCH <---- OPENACC)---------------------------------- - //~ if((backend.compare("omp")==0 || backend.compare("acc")==0 ) && forAll->isForall()) - //~ { - //~ parallelConstruct.pop_back(); - //~ } - - //~ delete_curr_SymbolTable(); - - - - if((backend.compare("omp")==0 || backend.compare("cuda")==0 || backend.compare("acc")==0 || backend.compare("mpi")==0) &&forAll->isForall()) - { - if(forAll->isForall()) - { - parallelConstruct.pop_back(); - IdsInsideParallelFilter.clear(); - } - - } - break; - } - case NODE_BLOCKSTMT: - { blockStatement* blockStmt=(blockStatement*)stmt; - init_curr_SymbolTable(blockStmt); - list stmtList=blockStmt->returnStatements(); - list::iterator itr; - int count=0; - int procPos=-1; - int bfsPos=-1; - list::iterator itrIBFS; - list::iterator itrProc; - bool flag=false; - bool callFlag=false; - string backend(backendTarget); - for(itr=stmtList.begin();itr!=stmtList.end();itr++) - { - - if(!callFlag&&(*itr)->getTypeofNode()==NODE_PROCCALLSTMT) - { - proc_callStmt* proc=(proc_callStmt*)(*itr); - char* methodId=proc->getProcCallExpr()->getMethodId()->getIdentifier(); - string IDCoded(attachNodeCall); - int x=IDCoded.compare(IDCoded); - if(x==0) - { - itrProc=itr; - callFlag=true; - procPos=count; - } - } - if((*itr)->getTypeofNode()==NODE_ITRBFS) - { - - itrIBFS=itr; - - flag=true; - bfsPos=count; - } - buildForStatements((*itr)); - count++; - } + //----------------------MERGE CONFLICT OCCURRED HERE (WORKING BRANCH <---- OPENACC)---------------------------------- + //~ if((backend.compare("omp")==0 || backend.compare("acc")==0 ) && forAll->isForall()) + //~ { + //~ parallelConstruct.pop_back(); + //~ } + //~ delete_curr_SymbolTable(); - if(flag&&(backend.compare("omp")==0 || backend.compare("acc")==0 ) ) - - { - iterateBFS* itrbFS=(iterateBFS*)(*itrIBFS); - Identifier* id=Identifier::createIdNode("bfsDist"); - declaration* decl=createPropertyDeclaration(id); - buildForStatements(decl); - blockStmt->insertToBlock(decl,procPos); - argument* arg=createAssignedArg(id); - proc_callStmt* proc=(proc_callStmt*)*itrProc; - proc_callExpr* pExpr=proc->getProcCallExpr(); - pExpr->addToArgList(arg); - PropAccess* propIdNode=PropAccess::createPropAccessNode(itrbFS->getRootNode(),id); - Expression* expr=Expression::nodeForIntegerConstant(0); - assignment* assignmentNode=assignment::prop_assignExpr(propIdNode,expr); - blockStmt->insertToBlock(assignmentNode,bfsPos+1); - - } - - delete_curr_SymbolTable(); - break; - - } - case NODE_WHILESTMT: - { - whileStmt* whilestmt=(whileStmt*)stmt; - checkForExpressions(whilestmt->getCondition()); - Expression* expr = whilestmt->getCondition(); - expr->setTypeofExpr(TYPE_BOOL); - buildForStatements(whilestmt->getBody()); - break; - } - case NODE_IFSTMT: - { - ifStmt* ifstmt=(ifStmt*)stmt; - checkForExpressions(ifstmt->getCondition()); - Expression* expr = ifstmt->getCondition(); - expr->setTypeofExpr(TYPE_BOOL); - buildForStatements(ifstmt->getIfBody()); - if(ifstmt->getElseBody()!=NULL) - buildForStatements(ifstmt->getElseBody()); - break; - } - case NODE_PROCCALLSTMT: - { - proc_callStmt* proc_call = (proc_callStmt*)stmt; - proc_callExpr* pExpr = proc_call->getProcCallExpr(); - int curFuncType = currentFunc->getFuncType(); - char* procId = pExpr->getMethodId()->getIdentifier(); - - checkForExpressions(pExpr); - break; - - } - case NODE_REDUCTIONCALLSTMT: - { - reductionCallStmt* reducStmt=(reductionCallStmt*)stmt; - if(reducStmt->is_reducCall()) - { - list leftList=reducStmt->getLeftList(); - list exprList=reducStmt->getRightList(); - list::iterator itr; - list::iterator itr1; - for(itr=leftList.begin();itr!=leftList.end();itr++) - { - if((*itr)->getTypeofNode()==NODE_ID) - findSymbolId((Identifier*)*itr); - if((*itr)->getTypeofNode()==NODE_PROPACCESS) - { - findSymbolPropId((PropAccess*)*itr); - - } - } - - if(leftList.size() > 2) - { - string backend(backendTarget); - - if(backend.compare("omp") == 0 || backend.compare("acc")) - - { - currentFunc->setInitialLockDecl(); - } - } - - for(itr1=exprList.begin();itr1!=exprList.end();itr1++) - { - checkForExpressions((Expression*)*itr1); - } - - reductionCall* reduceExpr = reducStmt->getReducCall(); - checkReductionExpr(reduceExpr); - - ASTNode* nearest_Parallel=parallelConstruct.back(); - if(nearest_Parallel->getTypeofNode()==NODE_FORALLSTMT) - { - forallStmt* forAll=(forallStmt*)nearest_Parallel; - forAll->setReductionStatement(reducStmt); - } - } - else - { - if(reducStmt->isLeftIdentifier()) - { - findSymbolId(reducStmt->getLeftId()); - ASTNode* nearest_Parallel=parallelConstruct.back(); - if(nearest_Parallel->getTypeofNode()==NODE_FORALLSTMT) - { - forallStmt* forAll=(forallStmt*)nearest_Parallel; - forAll->push_reduction(reducStmt->reduction_op(),reducStmt->getLeftId()); - } - } - else - { - findSymbolPropId(reducStmt->getPropAccess()); - } - checkForExpressions(reducStmt->getRightSide()); - } - break; - } - case NODE_ITRBFS: - { - iterateBFS* iBFS=(iterateBFS*)stmt; - string backend(backendTarget); - - if((backend.compare("omp")==0) || (backend.compare("cuda")==0) || (backend.compare("acc")==0) || (backend.compare("mpi")==0)) - - { - parallelConstruct.push_back(iBFS); - - } - - currentFunc->setIsMetaUsed(); // d_meta is used in itrbfs - iBFS->setIsMetaUsed(); // d_meta is used in itrbfs - currentFunc->setIsDataUsed(); // d_data is used in itrbfs - iBFS->setIsDataUsed(); // d_data is used in itrbfs - currentFunc->setIsWeightUsed(); // d_weight is used in itrbfs - iBFS->setIsWeightUsed(); // d_weight is used in itrbfs - - buildForStatements(iBFS->getBody()); - - - - iterateReverseBFS* iRevBFS = iBFS->getRBFS(); - if(iRevBFS != NULL) - { - iRevBFS->addAccumulateAssignment(); - buildForStatements(iRevBFS->getBody()); - } - if((backend.compare("omp")==0) || (backend.compare("cuda")==0) || (backend.compare("acc")==0) || (backend.compare("mpi")==0)) - - { - parallelConstruct.pop_back(); - - } - - break; - } - case NODE_DOWHILESTMT: - { - dowhileStmt* doStmt=(dowhileStmt*)stmt; - checkForExpressions(doStmt->getCondition()); - buildForStatements(doStmt->getBody()); - break; - } - - case NODE_RETURN: - { - returnStmt* retStmt = (returnStmt*)stmt; - checkForExpressions(retStmt->getReturnExpression()); - currentFunc->flagReturn(); - break; - } - case NODE_BATCHBLOCKSTMT: - { - batchBlock* batchBlckStmt = (batchBlock*)stmt; - checkForExpressions(batchBlckStmt->getBatchSizeExpr()); - batchBlockEnv = batchBlckStmt; - buildForStatements(batchBlckStmt->getStatements()); - batchBlockEnv = NULL; - break; - - } - case NODE_ONADDBLOCK: + if ((backend.compare("omp") == 0 || backend.compare("cuda") == 0 || backend.compare("acc") == 0 || backend.compare("mpi") == 0 || (backend.compare("sycl") == 0)) && forAll->isForall()) + { + if (forAll->isForall()) + { + parallelConstruct.pop_back(); + IdsInsideParallelFilter.clear(); + } + } + break; + } + case NODE_BLOCKSTMT: + { + blockStatement *blockStmt = (blockStatement *)stmt; + init_curr_SymbolTable(blockStmt); + list stmtList = blockStmt->returnStatements(); + list::iterator itr; + int count = 0; + int procPos = -1; + int bfsPos = -1; + list::iterator itrIBFS; + list::iterator itrProc; + bool flag = false; + bool callFlag = false; + string backend(backendTarget); + for (itr = stmtList.begin(); itr != stmtList.end(); itr++) + { + + if (!callFlag && (*itr)->getTypeofNode() == NODE_PROCCALLSTMT) + { + proc_callStmt *proc = (proc_callStmt *)(*itr); + char *methodId = proc->getProcCallExpr()->getMethodId()->getIdentifier(); + string IDCoded(attachNodeCall); + int x = IDCoded.compare(IDCoded); + if (x == 0) { - onAddBlock* onAddStmt = (onAddBlock*)stmt; - findSymbolId(onAddStmt->getUpdateId()); - batchBlock* batchBlockBound = (batchBlock*)batchBlockEnv; - /*if(batchBlockBound->getUpdateId()==NULL) - batchBlockBound->setUpdateId(onAddStmt->getUpdateId());*/ - preprocessEnv = onAddStmt; - buildForStatements(onAddStmt->getStatements()); - preprocessEnv = NULL; - break; + itrProc = itr; + callFlag = true; + procPos = count; + } + } + if ((*itr)->getTypeofNode() == NODE_ITRBFS) + { + itrIBFS = itr; + + flag = true; + bfsPos = count; + } + buildForStatements((*itr)); + count++; + } + + if (flag && (backend.compare("omp") == 0 || backend.compare("acc") == 0)) + + { + iterateBFS *itrbFS = (iterateBFS *)(*itrIBFS); + Identifier *id = Identifier::createIdNode("bfsDist"); + declaration *decl = createPropertyDeclaration(id); + buildForStatements(decl); + blockStmt->insertToBlock(decl, procPos); + argument *arg = createAssignedArg(id); + proc_callStmt *proc = (proc_callStmt *)*itrProc; + proc_callExpr *pExpr = proc->getProcCallExpr(); + pExpr->addToArgList(arg); + PropAccess *propIdNode = PropAccess::createPropAccessNode(itrbFS->getRootNode(), id); + Expression *expr = Expression::nodeForIntegerConstant(0); + assignment *assignmentNode = assignment::prop_assignExpr(propIdNode, expr); + blockStmt->insertToBlock(assignmentNode, bfsPos + 1); + } + + delete_curr_SymbolTable(); + break; + } + case NODE_WHILESTMT: + { + whileStmt *whilestmt = (whileStmt *)stmt; + checkForExpressions(whilestmt->getCondition()); + Expression *expr = whilestmt->getCondition(); + expr->setTypeofExpr(TYPE_BOOL); + buildForStatements(whilestmt->getBody()); + break; + } + case NODE_IFSTMT: + { + ifStmt *ifstmt = (ifStmt *)stmt; + checkForExpressions(ifstmt->getCondition()); + Expression *expr = ifstmt->getCondition(); + expr->setTypeofExpr(TYPE_BOOL); + buildForStatements(ifstmt->getIfBody()); + if (ifstmt->getElseBody() != NULL) + buildForStatements(ifstmt->getElseBody()); + break; + } + case NODE_PROCCALLSTMT: + { + proc_callStmt *proc_call = (proc_callStmt *)stmt; + proc_callExpr *pExpr = proc_call->getProcCallExpr(); + int curFuncType = currentFunc->getFuncType(); + char *procId = pExpr->getMethodId()->getIdentifier(); + + checkForExpressions(pExpr); + break; + } + case NODE_REDUCTIONCALLSTMT: + { + reductionCallStmt *reducStmt = (reductionCallStmt *)stmt; + if (reducStmt->is_reducCall()) + { + list leftList = reducStmt->getLeftList(); + list exprList = reducStmt->getRightList(); + list::iterator itr; + list::iterator itr1; + for (itr = leftList.begin(); itr != leftList.end(); itr++) + { + if ((*itr)->getTypeofNode() == NODE_ID) + findSymbolId((Identifier *)*itr); + if ((*itr)->getTypeofNode() == NODE_PROPACCESS) + { + findSymbolPropId((PropAccess *)*itr); } - case NODE_ONDELETEBLOCK: - { - onDeleteBlock* onDeleteStmt = (onDeleteBlock*)stmt; - findSymbolId(onDeleteStmt->getUpdateId()); - batchBlock* batchBlockBound = (batchBlock*)batchBlockEnv; - /* if(batchBlockBound->getUpdateId()==NULL) - batchBlockBound->setUpdateId(onDeleteStmt->getUpdateId());*/ - preprocessEnv = onDeleteStmt; - buildForStatements(onDeleteStmt->getStatements()); - preprocessEnv = NULL; - break; - - } - - - } - - - } - - void SymbolTableBuilder::checkReductionExpr(reductionCall* reduce) - { - list argList=reduce->getargList(); - list::iterator itr; - for(itr=argList.begin();itr!=argList.end();itr++) - { - argument* arg=(*itr); - if(arg->isAssignExpr()) - buildForStatements(arg->getAssignExpr()); - else - checkForExpressions(arg->getExpr()); + } + + if (leftList.size() > 2) + { + string backend(backendTarget); + + if (backend.compare("omp") == 0 || backend.compare("acc")) + + { + currentFunc->setInitialLockDecl(); + } + } + + for (itr1 = exprList.begin(); itr1 != exprList.end(); itr1++) + { + checkForExpressions((Expression *)*itr1); + } + + reductionCall *reduceExpr = reducStmt->getReducCall(); + checkReductionExpr(reduceExpr); + + ASTNode *nearest_Parallel = parallelConstruct.back(); + if (nearest_Parallel->getTypeofNode() == NODE_FORALLSTMT) + { + forallStmt *forAll = (forallStmt *)nearest_Parallel; + forAll->setReductionStatement(reducStmt); + } + } + else + { + if (reducStmt->isLeftIdentifier()) + { + findSymbolId(reducStmt->getLeftId()); + ASTNode *nearest_Parallel = parallelConstruct.back(); + if (nearest_Parallel->getTypeofNode() == NODE_FORALLSTMT) + { + forallStmt *forAll = (forallStmt *)nearest_Parallel; + forAll->push_reduction(reducStmt->reduction_op(), reducStmt->getLeftId()); + } + } + else + { + findSymbolPropId(reducStmt->getPropAccess()); + } + checkForExpressions(reducStmt->getRightSide()); + } + break; + } + case NODE_ITRBFS: + { + iterateBFS *iBFS = (iterateBFS *)stmt; + string backend(backendTarget); + + if ((backend.compare("omp") == 0) || (backend.compare("cuda") == 0) || (backend.compare("acc") == 0) || (backend.compare("mpi") == 0) || (backend.compare("sycl") == 0)) + + { + parallelConstruct.push_back(iBFS); + } + + currentFunc->setIsMetaUsed(); // d_meta is used in itrbfs + iBFS->setIsMetaUsed(); // d_meta is used in itrbfs + currentFunc->setIsDataUsed(); // d_data is used in itrbfs + iBFS->setIsDataUsed(); // d_data is used in itrbfs + currentFunc->setIsWeightUsed(); // d_weight is used in itrbfs + iBFS->setIsWeightUsed(); // d_weight is used in itrbfs + + buildForStatements(iBFS->getBody()); + + iterateReverseBFS *iRevBFS = iBFS->getRBFS(); + if (iRevBFS != NULL) + { + iRevBFS->addAccumulateAssignment(); + buildForStatements(iRevBFS->getBody()); + } + if ((backend.compare("omp") == 0) || (backend.compare("cuda") == 0) || (backend.compare("acc") == 0) || (backend.compare("mpi") == 0) || (backend.compare("sycl") == 0)) + + { + parallelConstruct.pop_back(); } + break; + } + case NODE_DOWHILESTMT: + { + dowhileStmt *doStmt = (dowhileStmt *)stmt; + checkForExpressions(doStmt->getCondition()); + buildForStatements(doStmt->getBody()); + break; + } - } + case NODE_RETURN: + { + returnStmt *retStmt = (returnStmt *)stmt; + checkForExpressions(retStmt->getReturnExpression()); + currentFunc->flagReturn(); + break; + } + case NODE_BATCHBLOCKSTMT: + { + batchBlock *batchBlckStmt = (batchBlock *)stmt; + checkForExpressions(batchBlckStmt->getBatchSizeExpr()); + batchBlockEnv = batchBlckStmt; + buildForStatements(batchBlckStmt->getStatements()); + batchBlockEnv = NULL; + break; + } + case NODE_ONADDBLOCK: + { + onAddBlock *onAddStmt = (onAddBlock *)stmt; + findSymbolId(onAddStmt->getUpdateId()); + batchBlock *batchBlockBound = (batchBlock *)batchBlockEnv; + /*if(batchBlockBound->getUpdateId()==NULL) + batchBlockBound->setUpdateId(onAddStmt->getUpdateId());*/ + preprocessEnv = onAddStmt; + buildForStatements(onAddStmt->getStatements()); + preprocessEnv = NULL; + break; + } + case NODE_ONDELETEBLOCK: + { + onDeleteBlock *onDeleteStmt = (onDeleteBlock *)stmt; + findSymbolId(onDeleteStmt->getUpdateId()); + batchBlock *batchBlockBound = (batchBlock *)batchBlockEnv; + /* if(batchBlockBound->getUpdateId()==NULL) + batchBlockBound->setUpdateId(onDeleteStmt->getUpdateId());*/ + preprocessEnv = onDeleteStmt; + buildForStatements(onDeleteStmt->getStatements()); + preprocessEnv = NULL; + break; + } + } +} -void SymbolTableBuilder::checkForArguments(list argList) +void SymbolTableBuilder::checkReductionExpr(reductionCall *reduce) { - /* primarly required for situations where we require to create a alias for the - variable for double buffering purposes*/ - for(argument* arg:argList) - { - - if(arg->isAssignExpr()) - { - assignment* assign=(assignment*)arg->getAssignExpr(); - if(assign->lhs_isIdentifier()) - findSymbolId(assign->getId()); - else - findSymbolPropId(assign->getPropId()); - - } - if(arg->isExpr()) - { - checkForExpressions(arg->getExpr()); - } - - } + list argList = reduce->getargList(); + list::iterator itr; + for (itr = argList.begin(); itr != argList.end(); itr++) + { + argument *arg = (*itr); + if (arg->isAssignExpr()) + buildForStatements(arg->getAssignExpr()); + else + checkForExpressions(arg->getExpr()); + } +} +void SymbolTableBuilder::checkForArguments(list argList) +{ + /* primarly required for situations where we require to create a alias for the + variable for double buffering purposes*/ + for (argument *arg : argList) + { + if (arg->isAssignExpr()) + { + assignment *assign = (assignment *)arg->getAssignExpr(); + if (assign->lhs_isIdentifier()) + findSymbolId(assign->getId()); + else + findSymbolPropId(assign->getPropId()); + } + if (arg->isExpr()) + { + checkForExpressions(arg->getExpr()); + } + } } - void SymbolTableBuilder::getIdsInsideExpression(Expression* expr, std::unordered_set& ids) - { - - switch(expr->getExpressionFamily()) +void SymbolTableBuilder::getIdsInsideExpression(Expression *expr, std::unordered_set &ids) +{ + + switch (expr->getExpressionFamily()) + { + case EXPR_ARITHMETIC: + { + getIdsInsideExpression(expr->getLeft(), ids); + getIdsInsideExpression(expr->getRight(), ids); + break; + } + case EXPR_PROCCALL: + { + proc_callExpr *pExpr = (proc_callExpr *)expr; + Identifier *id = pExpr->getId1(); + ids.insert(id->getSymbolInfo()); + + list arglist = pExpr->getArgList(); + for (list::iterator it = arglist.begin(); it != arglist.end(); it++) { - case EXPR_ARITHMETIC: - { - getIdsInsideExpression(expr->getLeft(),ids); - getIdsInsideExpression(expr->getRight(),ids); - break; - } - case EXPR_PROCCALL: - { - proc_callExpr* pExpr=(proc_callExpr*)expr; - Identifier* id=pExpr->getId1(); - ids.insert(id->getSymbolInfo()); - - list arglist= pExpr->getArgList(); - for(list::iterator it = arglist.begin(); it!=arglist.end();it++) - { - if((*it)->isExpr()) - getIdsInsideExpression((*it)->getExpr(), ids); - } - - break; - } - case EXPR_UNARY: - { - - getIdsInsideExpression(expr->getUnaryExpr(),ids); - break; - } - case EXPR_LOGICAL: - { - - getIdsInsideExpression(expr->getLeft(),ids); - getIdsInsideExpression(expr->getRight(),ids); - break; - } - case EXPR_RELATIONAL: - { - getIdsInsideExpression(expr->getLeft(),ids); - getIdsInsideExpression(expr->getRight(),ids); - break; - } - case EXPR_ID: - { - - ids.insert(expr->getId()->getSymbolInfo()); - break; - } - case EXPR_PROPID: - { - - ids.insert(expr->getPropId()->getIdentifier1()->getSymbolInfo()); - ids.insert(expr->getPropId()->getIdentifier2()->getSymbolInfo()); - break; - } - } - } - - void SymbolTableBuilder::checkForExpressions(Expression* expr) - { bool ifFine=false; - switch(expr->getExpressionFamily()) - { - case EXPR_ARITHMETIC: - { - checkForExpressions(expr->getLeft()); - checkForExpressions(expr->getRight()); - break; - } - case EXPR_PROCCALL: - { - proc_callExpr* pExpr = (proc_callExpr*)expr; - Identifier* id = pExpr->getId1(); - Identifier* methodId = pExpr->getMethodId(); - Expression* indexExpr = pExpr->getIndexExpr(); - int curFuncType = currentFunc->getFuncType(); - char* procId = methodId->getIdentifier(); - - string s(methodId->getIdentifier()); - if(id != NULL) - ifFine = findSymbolId(id); - - if(indexExpr != NULL) - checkForExpressions(indexExpr); - - checkForArguments(pExpr->getArgList()); - - if(s.compare(attachNodeCall) == 0) - { - addPropToSymbolTE(currVarSymbT,id,pExpr->getArgList()); - } - if(s.compare(currentBatch) == 0) - { - - batchBlock* currentBlock = (batchBlock*)batchBlockEnv ; - Identifier* updatesId = currentBlock->getUpdateId(); - string updatesString(updatesId->getIdentifier()); - string idString(id->getIdentifier()); - assert(idString.compare(updatesString) == 0); - } - - if(s.compare(isAnEdgeCall) == 0) - { - forallStmt* parentForAll = (forallStmt*)parallelConstruct[0]; - parentForAll->setIsMetaUsed(); - currentFunc->setIsMetaUsed(); - parentForAll->setIsDataUsed(); - currentFunc->setIsDataUsed(); - } - if(s.compare(countOutNbrCall) == 0) - { - forallStmt* parentForAll = (forallStmt*)parallelConstruct[0]; - parentForAll->setIsMetaUsed(); - currentFunc->setIsMetaUsed(); - } - - - /*check if procedure call inside a dynamic func */ - string procIdString(procId); - if(curFuncType == DYNAMIC_FUNC || curFuncType == INCREMENTAL_FUNC || curFuncType == DECREMENTAL_FUNC){ - dynamicLinkedFunc[procIdString] = true; - - } - else { - - char* funcId = currentFunc->getIdentifier()->getIdentifier(); - string funcIdString(funcId); - - if(dynamicLinkedFunc.find(funcIdString) != dynamicLinkedFunc.end() && dynamicLinkedFunc[funcIdString]){ - dynamicLinkedFunc[procIdString] = true; - } - } + if ((*it)->isExpr()) + getIdsInsideExpression((*it)->getExpr(), ids); + } - /* check for deciding on whether the containers need to be localized per thread */ - if(parallelConstruct.size()>0 && s == "push"){ - - ASTNode* parallelEnv = parallelConstruct.back(); - if(pExpr->getIndexExpr() != NULL){ - Expression* indexExpr = pExpr->getIndexExpr(); - Expression* mapExpr = indexExpr->getMapExpr(); - Identifier* mapId = mapExpr->getId(); - - - if(mapId->getSymbolInfo()->getType()->gettypeId() == TYPE_CONTAINER){ - mapId->getSymbolInfo()->getId()->setLocalMapReq(); - - if(parallelEnv->getTypeofNode() == NODE_FORALLSTMT){ - forallStmt* parFor = (forallStmt*)parallelEnv; - cout<<"MMMMMMMMMMMMMMMMMMMMMMMMMMMMM"<<"\n"; - cout<getSymbolInfo()->getId()->getIdentifier()<<"\n"; - cout<getSymbolInfo()->getType()->getArgList().size()<<"\n"; - parFor->pushMapLocals(mapId); - } - - } - } - else { - - Identifier* mapId = pExpr->getId1(); - if(mapId->getSymbolInfo()->getType()->gettypeId() == TYPE_CONTAINER){ - mapId->getSymbolInfo()->getId()->setLocalMapReq(); - - if(parallelEnv->getTypeofNode() == NODE_FORALLSTMT){ - forallStmt* parFor = (forallStmt*)parallelEnv; - parFor->pushMapLocals(mapId); - } - } - } - - } + break; + } + case EXPR_UNARY: + { - break; - } - case EXPR_UNARY: - { - checkForExpressions(expr->getUnaryExpr()); - break; - } - case EXPR_LOGICAL: - { - checkForExpressions(expr->getLeft()); - checkForExpressions(expr->getRight()); - break; - } - case EXPR_RELATIONAL: - { - checkForExpressions(expr->getLeft()); - checkForExpressions(expr->getRight()); - break; - } - case EXPR_ID: - { - ifFine=findSymbolId(expr->getId()); - break; - } - case EXPR_MAPGET: - { - checkForExpressions(expr->getMapExpr()); - //cout<<"check if symboltable "<<(expr->getMapExpr()->getId()->getSymbolInfo()->getType()->gettypeId() == TYPE_CONTAINER)<<"\n"; - checkForExpressions(expr->getIndexExpr()); - break; - } - case EXPR_PROPID: - { - cout<getPropId()->getIdentifier1()->getIdentifier()<<"\n"; - ifFine=findSymbolPropId(expr->getPropId()); - if(preprocessEnv!=NULL && expr->getPropId()->getIdentifier1()->getSymbolInfo()==NULL) { - - performUpdatesAssociation((PropAccess*)expr->getPropId(),preprocessEnv); - } - - break; - } - - - } - } - bool SymbolTableBuilder::findSymbolPropId(PropAccess* propId) - { - bool isFine = true; - Identifier* id1 = propId->getIdentifier1(); - Identifier* id2 = propId->getIdentifier2(); - Expression* indexexpr = propId->getPropExpr(); - search_and_connect_toId(currVarSymbT,id1); - if(propId->isPropertyExpression()) - { - Expression* mapExpr = indexexpr->getMapExpr(); - checkForExpressions(mapExpr); - // search_and_connect_toId(currVarSymbT, propId->get) - - //cout<<"Done for index "<<"\n"; - } - else - search_and_connect_toId(currPropSymbT,id2); //need to change..ideally this should search in prop. - - return isFine; //to be changed! - - - - } - - bool SymbolTableBuilder::findSymbolId(Identifier* id) - { - bool success=search_and_connect_toId(currVarSymbT,id); - if(!success) - search_and_connect_toId(currPropSymbT,id); //need to optimize on whether to call this function or not. - return true; //to be changed! - } - - bool SymbolTableBuilder::checkHeaderSymbols(Identifier* src,PropAccess* propId,forallStmt* forall) - { if(propId!=NULL) + getIdsInsideExpression(expr->getUnaryExpr(), ids); + break; + } + case EXPR_LOGICAL: + { + + getIdsInsideExpression(expr->getLeft(), ids); + getIdsInsideExpression(expr->getRight(), ids); + break; + } + case EXPR_RELATIONAL: + { + getIdsInsideExpression(expr->getLeft(), ids); + getIdsInsideExpression(expr->getRight(), ids); + break; + } + case EXPR_ID: + { + + ids.insert(expr->getId()->getSymbolInfo()); + break; + } + case EXPR_PROPID: + { + + ids.insert(expr->getPropId()->getIdentifier1()->getSymbolInfo()); + ids.insert(expr->getPropId()->getIdentifier2()->getSymbolInfo()); + break; + } + } +} + +void SymbolTableBuilder::checkForExpressions(Expression *expr) +{ + bool ifFine = false; + switch (expr->getExpressionFamily()) + { + case EXPR_ARITHMETIC: + { + checkForExpressions(expr->getLeft()); + checkForExpressions(expr->getRight()); + break; + } + case EXPR_PROCCALL: + { + proc_callExpr *pExpr = (proc_callExpr *)expr; + Identifier *id = pExpr->getId1(); + Identifier *methodId = pExpr->getMethodId(); + Expression *indexExpr = pExpr->getIndexExpr(); + int curFuncType = currentFunc->getFuncType(); + char *procId = methodId->getIdentifier(); + + string s(methodId->getIdentifier()); + if (id != NULL) + ifFine = findSymbolId(id); + + if (indexExpr != NULL) + checkForExpressions(indexExpr); + + checkForArguments(pExpr->getArgList()); + + if (s.compare(attachNodeCall) == 0) { - if(!findSymbolPropId(propId)) - return false; + addPropToSymbolTE(currVarSymbT, id, pExpr->getArgList()); + } + if (s.compare(currentBatch) == 0) + { + + batchBlock *currentBlock = (batchBlock *)batchBlockEnv; + Identifier *updatesId = currentBlock->getUpdateId(); + string updatesString(updatesId->getIdentifier()); + string idString(id->getIdentifier()); + assert(idString.compare(updatesString) == 0); } - if(src!=NULL) + if (s.compare(isAnEdgeCall) == 0) { - if(!findSymbolId(src)) - return false; + forallStmt *parentForAll = (forallStmt *)parallelConstruct[0]; + parentForAll->setIsMetaUsed(); + currentFunc->setIsMetaUsed(); + parentForAll->setIsDataUsed(); + currentFunc->setIsDataUsed(); + } + if (s.compare(countOutNbrCall) == 0) + { + forallStmt *parentForAll = (forallStmt *)parallelConstruct[0]; + parentForAll->setIsMetaUsed(); + currentFunc->setIsMetaUsed(); } - return true; //more checking need to be carried out. - } + /*check if procedure call inside a dynamic func */ + string procIdString(procId); + if (curFuncType == DYNAMIC_FUNC || curFuncType == INCREMENTAL_FUNC || curFuncType == DECREMENTAL_FUNC) + { + dynamicLinkedFunc[procIdString] = true; + } + else + { - void SymbolTableBuilder::init_curr_SymbolTable(ASTNode* node) - { - node->getVarSymbT()->setParent(currVarSymbT); - node->getPropSymbT()->setParent(currPropSymbT); - variableSymbolTables.push_back(currVarSymbT); - propSymbolTables.push_back(currPropSymbT); - currVarSymbT=node->getVarSymbT(); - currPropSymbT=node->getPropSymbT(); + char *funcId = currentFunc->getIdentifier()->getIdentifier(); + string funcIdString(funcId); - } + if (dynamicLinkedFunc.find(funcIdString) != dynamicLinkedFunc.end() && dynamicLinkedFunc[funcIdString]) + { + dynamicLinkedFunc[procIdString] = true; + } + } - void SymbolTableBuilder::delete_curr_SymbolTable() - { - currVarSymbT=variableSymbolTables.back(); - currPropSymbT=propSymbolTables.back(); + /* check for deciding on whether the containers need to be localized per thread */ + if (parallelConstruct.size() > 0 && s == "push") + { - variableSymbolTables.pop_back(); - propSymbolTables.pop_back(); - } + ASTNode *parallelEnv = parallelConstruct.back(); + if (pExpr->getIndexExpr() != NULL) + { + Expression *indexExpr = pExpr->getIndexExpr(); + Expression *mapExpr = indexExpr->getMapExpr(); + Identifier *mapId = mapExpr->getId(); -void SymbolTableBuilder::buildST(list funcList){ + if (mapId->getSymbolInfo()->getType()->gettypeId() == TYPE_CONTAINER) + { + mapId->getSymbolInfo()->getId()->setLocalMapReq(); - cout<<"entered here for symbol table stuff"<<"\n"; - list::iterator itr; - for(itr=funcList.begin();itr!=funcList.end();itr++) - buildForProc((*itr)); + if (parallelEnv->getTypeofNode() == NODE_FORALLSTMT) + { + forallStmt *parFor = (forallStmt *)parallelEnv; + cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMM" + << "\n"; + cout << mapId->getSymbolInfo()->getId()->getIdentifier() << "\n"; + cout << mapId->getSymbolInfo()->getType()->getArgList().size() << "\n"; + parFor->pushMapLocals(mapId); + } + } + } + else + { + Identifier *mapId = pExpr->getId1(); + if (mapId->getSymbolInfo()->getType()->gettypeId() == TYPE_CONTAINER) + { + mapId->getSymbolInfo()->getId()->setLocalMapReq(); -} + if (parallelEnv->getTypeofNode() == NODE_FORALLSTMT) + { + forallStmt *parFor = (forallStmt *)parallelEnv; + parFor->pushMapLocals(mapId); + } + } + } + } -map SymbolTableBuilder::getDynamicLinkedFuncs(){ + break; + } + case EXPR_UNARY: + { + checkForExpressions(expr->getUnaryExpr()); + break; + } + case EXPR_LOGICAL: + { + checkForExpressions(expr->getLeft()); + checkForExpressions(expr->getRight()); + break; + } + case EXPR_RELATIONAL: + { + checkForExpressions(expr->getLeft()); + checkForExpressions(expr->getRight()); + break; + } + case EXPR_ID: + { + ifFine = findSymbolId(expr->getId()); + break; + } + case EXPR_MAPGET: + { + checkForExpressions(expr->getMapExpr()); + // cout<<"check if symboltable "<<(expr->getMapExpr()->getId()->getSymbolInfo()->getType()->gettypeId() == TYPE_CONTAINER)<<"\n"; + checkForExpressions(expr->getIndexExpr()); + break; + } + case EXPR_PROPID: + { + cout << expr->getPropId()->getIdentifier1()->getIdentifier() << "\n"; + ifFine = findSymbolPropId(expr->getPropId()); + if (preprocessEnv != NULL && expr->getPropId()->getIdentifier1()->getSymbolInfo() == NULL) + { - return dynamicLinkedFunc; + performUpdatesAssociation((PropAccess *)expr->getPropId(), preprocessEnv); + } + + break; + } + } +} +bool SymbolTableBuilder::findSymbolPropId(PropAccess *propId) +{ + bool isFine = true; + Identifier *id1 = propId->getIdentifier1(); + Identifier *id2 = propId->getIdentifier2(); + Expression *indexexpr = propId->getPropExpr(); + search_and_connect_toId(currVarSymbT, id1); + if (propId->isPropertyExpression()) + { + Expression *mapExpr = indexexpr->getMapExpr(); + checkForExpressions(mapExpr); + // search_and_connect_toId(currVarSymbT, propId->get) + + // cout<<"Done for index "<<"\n"; + } + else + search_and_connect_toId(currPropSymbT, id2); // need to change..ideally this should search in prop. + + return isFine; // to be changed! +} + +bool SymbolTableBuilder::findSymbolId(Identifier *id) +{ + bool success = search_and_connect_toId(currVarSymbT, id); + if (!success) + search_and_connect_toId(currPropSymbT, id); // need to optimize on whether to call this function or not. + return true; // to be changed! +} + +bool SymbolTableBuilder::checkHeaderSymbols(Identifier *src, PropAccess *propId, forallStmt *forall) +{ + if (propId != NULL) + { + if (!findSymbolPropId(propId)) + return false; + } + if (src != NULL) + { + if (!findSymbolId(src)) + return false; + } + + return true; // more checking need to be carried out. } - - +void SymbolTableBuilder::init_curr_SymbolTable(ASTNode *node) +{ + node->getVarSymbT()->setParent(currVarSymbT); + node->getPropSymbT()->setParent(currPropSymbT); + variableSymbolTables.push_back(currVarSymbT); + propSymbolTables.push_back(currPropSymbT); + currVarSymbT = node->getVarSymbT(); + currPropSymbT = node->getPropSymbT(); +} +void SymbolTableBuilder::delete_curr_SymbolTable() +{ + currVarSymbT = variableSymbolTables.back(); + currPropSymbT = propSymbolTables.back(); + + variableSymbolTables.pop_back(); + propSymbolTables.pop_back(); +} + +void SymbolTableBuilder::buildST(list funcList) +{ + + cout << "entered here for symbol table stuff" + << "\n"; + list::iterator itr; + for (itr = funcList.begin(); itr != funcList.end(); itr++) + buildForProc((*itr)); +} + +map SymbolTableBuilder::getDynamicLinkedFuncs() +{ + + return dynamicLinkedFunc; +}