├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── apps ├── apsp │ ├── Makefile │ ├── README.md │ └── apsp.cc ├── bc │ ├── Makefile │ ├── README.md │ ├── bc.cc │ └── bc_non_partitioned.cc ├── bfs │ ├── Makefile │ ├── README.md │ ├── bfs.cc │ ├── bfs_atomic.cc │ └── sample.txt ├── community │ ├── Makefile │ ├── README.md │ ├── community_atomic.cc │ ├── community_lock.cc │ └── sample.txt ├── connected_components │ ├── Makefile │ ├── README.md │ ├── connected_components_atomic.cc │ ├── connected_components_lock.cc │ └── sample.txt ├── dfs │ ├── Makefile │ ├── README.md │ ├── dfs.cc │ └── sample.txt ├── pagerank │ ├── Makefile │ ├── README.md │ ├── pagerank.cc │ ├── pagerank_lock.cc │ └── sample.txt ├── sssp │ ├── Makefile │ ├── README.md │ ├── sample.txt │ ├── sssp.cc │ ├── sssp_outer.cc │ └── sssp_outer_atomic.cc ├── triangle_counting │ ├── Makefile │ ├── README.md │ ├── sample.txt │ ├── sorted_neighbors_tri_lock.cc │ ├── triangle_counting_atomic.cc │ └── triangle_counting_lock.cc └── tsp │ ├── Makefile │ ├── README.md │ └── tsp.cc ├── common ├── barrier.h └── mtx.h └── docs └── Graphite ├── Makefile └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | before_script: 2 | - sudo apt-get update -qq 3 | - sudo apt-get install libboost-thread-dev libboost-system-dev libboost-test-dev libboost-program-options-dev 4 | install: 5 | - sudo apt-get update -qq 6 | - sudo apt-get install -y libboost-graph-dev 7 | - sudo apt-get install -y libboost-regex-dev 8 | - sudo apt-get install -y libz-dev 9 | - sudo apt-get install -y libpthread-stubs0-dev 10 | env: 11 | - CRONO_HOME=$PWD BOOST_ROOT=/usr/include/boost 12 | language: c++ 13 | compiler: 14 | - g++ 15 | script: 16 | - make 17 | notifications: 18 | email: 19 | on_success: never 20 | on_failure: always 21 | recipients: 22 | - masab.ahmad@uconn.edu 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Masab Ahmad 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SUBDIRS= apsp bc sssp community connected_components dfs bfs pagerank triangle_counting tsp 2 | 3 | CRONO_DIR=$(PWD) 4 | 5 | all: 6 | for dir in $(SUBDIRS); do \ 7 | $(MAKE) -C $(CRONO_DIR)/apps/$$dir; \ 8 | done 9 | 10 | clean: 11 | for dir in $(SUBDIRS); do \ 12 | $(MAKE) clean -C $(CRONO_DIR)/apps/$$dir; \ 13 | done 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | CRONO v0.9 : A Benchmark Suite for Multithreaded Graph Algorithms Executing on Futuristic Multicores 3 | ==================================================================== 4 | 5 | [![build status](https://travis-ci.org/masabahmad/CRONO.svg?branch=master)](https://travis-ci.org/masabahmad/CRONO) 6 | 7 | This is a pre-release repository containing 10 graph analytic benchmarks. 8 | An in-built synthetic graph generater can be included by statically configuring certain benchmarks. 9 | These benchmarks can run on real multicore machines as well as the Graphite Multicore Simulator. 10 | 11 | If you use these benchmarks, please cite: 12 | 13 | CRONO : A Benchmark Suite for Multithreaded Graph Algorithms Executing on Futuristic Multicores, Masab Ahmad, Farrukh Hijaz, Qingchuan Shi, Omer Khan, IEEE International Symposium on Workload Characteriz 14 | ation (IISWC), Oct 2015, Atlanta, Georgia, USA. 15 | 16 | Paper pdf is located at: 17 | http://www.engr.uconn.edu/~omer.khan/pubs/crono-iiswc15.pdf 18 | 19 | Requirements 20 | ============ 21 | 22 | 1. Linux (Tested on Ubuntu 14.04) 23 | 2. g++ 4.6 (Tested with g++ 4.7) 24 | 3. The ```pthread``` Library 25 | 26 | Features 27 | ======== 28 | 1. Ubiquitous graph based search, planning, and clustering algorithms 29 | 2. Benchmarks use adjacency list representation for input graphs 30 | 3. Most benchmarks scale to 256 threads, some scale upto 1024 threads as well 31 | 4. Easy to compile and use 32 | 5. The input graphs are generic, i.e., the benchmarks do not assume any pre-processing or optimizations, such as graph compression and vertex/edge reordering 33 | 34 | Getting Started 35 | =============== 36 | 37 | Checkout the Repo: 38 | ```git clone https://github.com/masabahmad/CRONO``` 39 | 40 | To generate the executable for a benchmark, run ```make``` inside the CRONO directory, then execute each benchmark using the syntax specified by the individual README.md. 41 | 42 | External Users 43 | ============== 44 | 45 | 1. "Profile-Guided Temporal Prefetching", M. Li (HKUST), Y. Gao (Intel), et. al., ISCA '25, 52th Annual International Symposium on Computer Architecture, 2025. 46 | 47 | 2. "Lease/release: architectural support for scaling contended data structures", SK Haider (Microsoft Research), W Hasenplaugh (MIT), D Alistarh (Microsoft Research), PPoPP '16 Proceedings of the 21st ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming. 48 | 49 | 3. "Dictionary Sharing: An Efficient Cache Compression Scheme for Compressed Caches", B Panda (INRIA), A Seznec (INRIA/IRISA), MICRO '16, 49th Annual IEEE/ACM International Symposium on Microarchitecture, 2016. 50 | 51 | 4. "BoDNoC: Providing bandwidth-on-demand interconnection for multi-granularity memory systems", S Lian, Y Wang, Y Han, X Li (Chinese Academy of Sciences), ASP-DAC '17, 22nd Asia and South Pacific Design Automation Conference, 2017. 52 | 53 | 5. "Redundant Memory Array Architecture for Efficient Selective Protection", R Zheng, MC Huang (University of Rochester), ISCA '17, 44th Annual International Symposium on Computer Architecture, 2017. 54 | 55 | Contact 56 | ======= 57 | 58 | masab.ahmad@uconn.edu 59 | masabahmad13@gmail.com 60 | -------------------------------------------------------------------------------- /apps/apsp/Makefile: -------------------------------------------------------------------------------- 1 | 2 | TRGS = apsp 3 | 4 | LIBS += -lpthread -lrt 5 | 6 | ##BOOST_PATH = /run/pkg/boost-/1.53.0-gcc_4.7.3 7 | 8 | ##BOOST_FLAGS = -I$(BOOST_PATH)/include -L$(BOOST_PATH)/lib -lboost_graph 9 | 10 | CXXFLAGS = -g --std=c++0x -O3 11 | CXXFLAGS += -Wall -Werror 12 | 13 | all: $(TRGS) 14 | 15 | apsp: apsp.cc 16 | 17 | ##boost_dijk_real: boost_dijk_real.cc 18 | 19 | clean: 20 | rm -f $(TRGS) *.o *.dot 21 | 22 | %: %.cc ; 23 | $(CXX) $(CXXFLAGS) $< -o $@ $(LIBS) 24 | -------------------------------------------------------------------------------- /apps/apsp/README.md: -------------------------------------------------------------------------------- 1 | All Pairs Shortest Path 2 | ======================= 3 | 4 | Run ```make``` to generate the required executables, then run using the syntax explained below 5 | 6 | To execute with P number of threads, N vertices, and DEG edges per vertex 7 | ```./apsp P N DEG``` 8 | 9 | e.g. 10 | ```./apsp 2 16384 16``` 11 | 12 | **Notes** 13 | 14 | The executable outputs the time in seconds that the program took to run. 15 | -------------------------------------------------------------------------------- /apps/apsp/apsp.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Program adopted from Parallel MiBench 3 | */ 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | //#include "carbon_user.h" /*For the Graphite Simulator*/ 10 | #include 11 | #include 12 | 13 | #define MAX 100000000 14 | #define INT_MAX 100000000 15 | #define BILLION 1E9 16 | 17 | //Thread Argument Structure 18 | typedef struct 19 | { 20 | int* local_min; 21 | int* global_min; 22 | int* Q; 23 | int* D; 24 | int** W; 25 | int** W_index; 26 | int* d_count; 27 | int tid; 28 | int P; 29 | int N; 30 | int DEG; 31 | pthread_barrier_t* barrier_total; 32 | pthread_barrier_t* barrier; 33 | } thread_arg_t; 34 | 35 | //Function Declarations 36 | int initialize_single_source(int* D, int* Q, int source, int N); 37 | void relax(int u, int i, volatile int* D, int** W, int** W_index, int N); 38 | int get_local_min(volatile int* Q, volatile int* D, int start, int stop, int N, int** W_index, int** W, int u); 39 | void init_weights(int N, int DEG, int** W, int** W_index); 40 | 41 | //Global Variables 42 | int min = INT_MAX; //For local mins 43 | int min_index = 0; 44 | pthread_mutex_t lock; 45 | pthread_mutex_t locks[4194304]; //unused 46 | int u = 0; //next best vertex 47 | int local_min_buffer[1024]; 48 | int global_min_buffer; 49 | int start = 64; 50 | int P_global = 256; 51 | thread_arg_t thread_arg[1024]; 52 | pthread_t thread_handle[1024]; //MAX threads and pthread handlers 53 | 54 | //Primary Parallel Function 55 | void* do_work(void* args) 56 | { 57 | volatile thread_arg_t* arg = (thread_arg_t*) args; 58 | 59 | //volatile int* Q = arg->Q; 60 | //int* D = arg->D; 61 | int** W = arg->W; //Graph weights 62 | int** W_index = arg->W_index; //Graph connections 63 | const int N = arg->N; //Total Vertices 64 | const int DEG = arg->DEG; //Edges per Vertex 65 | int v = 0; //current vertex 66 | P_global = start; 67 | 68 | int node = 0; 69 | 70 | pthread_barrier_wait(arg->barrier_total); 71 | 72 | while(node (D[v] + W[v][i]))) 96 | D[W_index[v][i]] = D[v] + W[v][i]; 97 | 98 | Q[v]=0; //Current vertex checked 99 | } 100 | } 101 | 102 | pthread_mutex_lock(&lock); //Vertex Capture 103 | node++; 104 | pthread_mutex_unlock(&lock); 105 | } 106 | 107 | pthread_barrier_wait(arg->barrier_total); 108 | return NULL; 109 | } 110 | 111 | int main(int argc, char** argv) 112 | { 113 | //Input arguments 114 | const int P1 = atoi(argv[1]); 115 | const int N = atoi(argv[2]); 116 | const int DEG = atoi(argv[3]); 117 | 118 | int P = 256; 119 | start = P1; 120 | P = P1; 121 | 122 | 123 | if (DEG > N) 124 | { 125 | fprintf(stderr, "Degree of graph cannot be grater than number of Vertices\n"); 126 | exit(EXIT_FAILURE); 127 | } 128 | 129 | //int* D; 130 | //int* Q; 131 | //posix_memalign((void**) &D, 64, N * sizeof(int)); 132 | //posix_memalign((void**) &Q, 64, N * sizeof(int)); 133 | int d_count = N; 134 | pthread_barrier_t barrier_total; 135 | pthread_barrier_t barrier; 136 | 137 | //Memory allocations for the input graph 138 | int** W = (int**) malloc(N*sizeof(int*)); 139 | int** W_index = (int**) malloc(N*sizeof(int*)); 140 | for(int i = 0; i < N; i++) 141 | { 142 | //W[i] = (int *)malloc(sizeof(int)*N); 143 | int ret = posix_memalign((void**) &W[i], 64, DEG*sizeof(int)); 144 | int re1 = posix_memalign((void**) &W_index[i], 64, DEG*sizeof(int)); 145 | if (ret != 0 || re1!=0) 146 | { 147 | fprintf(stderr, "Could not allocate memory\n"); 148 | exit(EXIT_FAILURE); 149 | } 150 | } 151 | 152 | //Initialize random graph 153 | init_weights(N, DEG, W, W_index); 154 | 155 | //Synchronization Variables' Initialization 156 | pthread_barrier_init(&barrier_total, NULL, P1); 157 | pthread_barrier_init(&barrier, NULL, P1); 158 | pthread_mutex_init(&lock, NULL); 159 | for(int i=0; i<2097152; i++) 160 | pthread_mutex_init(&locks[i], NULL); 161 | 162 | //Thread Arguments 163 | for(int j = 0; j < P1; j++) { 164 | thread_arg[j].local_min = local_min_buffer; 165 | thread_arg[j].global_min = &global_min_buffer; 166 | //thread_arg[j].Q = Q; 167 | //thread_arg[j].D = D; 168 | thread_arg[j].W = W; 169 | thread_arg[j].W_index = W_index; 170 | thread_arg[j].d_count = &d_count; 171 | thread_arg[j].tid = j; 172 | thread_arg[j].P = P; 173 | thread_arg[j].N = N; 174 | thread_arg[j].DEG = DEG; 175 | thread_arg[j].barrier_total = &barrier_total; 176 | thread_arg[j].barrier = &barrier; 177 | } 178 | 179 | //Measure CPU time 180 | struct timespec requestStart, requestEnd; 181 | clock_gettime(CLOCK_REALTIME, &requestStart); 182 | 183 | // Enable Graphite performance and energy models 184 | //CarbonEnableModels(); 185 | 186 | //Spawn Threads 187 | for(int j = 1; j < P1; j++) { 188 | pthread_create(thread_handle+j, 189 | NULL, 190 | do_work, 191 | (void*)&thread_arg[j]); 192 | } 193 | do_work((void*) &thread_arg[0]); 194 | 195 | printf("\nThreads Returned!"); 196 | 197 | //Join Threads 198 | for(int j = 1; j < P1; j++) { //mul = mul*2; 199 | pthread_join(thread_handle[j],NULL); 200 | } 201 | 202 | // Disable Graphite performance and energy models 203 | //CarbonDisableModels(); 204 | 205 | printf("\nThreads Joined!"); 206 | 207 | clock_gettime(CLOCK_REALTIME, &requestEnd); 208 | double accum = ( requestEnd.tv_sec - requestStart.tv_sec ) + ( requestEnd.tv_nsec - requestStart.tv_nsec ) / BILLION; 209 | printf( "\nTime: %lf seconds\n", accum ); 210 | 211 | /*for(int i = 0; i < N; i++) { 212 | printf(" %d ", D[i]); 213 | } 214 | printf("\n"); 215 | */ 216 | return 0; 217 | } 218 | 219 | //Distance initializations 220 | int initialize_single_source(int* D, 221 | int* Q, 222 | int source, 223 | int N) 224 | { 225 | for(int i = 0; i < N; i++) 226 | { 227 | D[i] = INT_MAX; //all distances infinite 228 | Q[i] = 1; 229 | } 230 | 231 | D[source] = 0; //source distance 0 232 | return 0; 233 | } 234 | 235 | //Get local min vertex to jump to in the next iteration 236 | int get_local_min(volatile int* Q, volatile int* D, int start, int stop, int N, int** W_index, int** W, int u) 237 | { 238 | int min = INT_MAX; 239 | int min_index = N; 240 | 241 | for(int i = start; i < stop; i++) 242 | { 243 | if(D[i] < min && Q[i]) //if current edge has the smallest distance 244 | { 245 | min = D[i]; 246 | min_index = W_index[u][i]; 247 | } 248 | } 249 | return min_index; //return smallest edge 250 | } 251 | 252 | //Relax : updates distance based on the current vertex 253 | void relax(int u, int i, volatile int* D, int** W, int** W_index, int N) 254 | { 255 | if((D[W_index[u][i]] > (D[u] + W[u][i]) && (W_index[u][i]!=-1 && W_index[u][i] last) 277 | { 278 | W_index[i][j] = neighbor; 279 | last = W_index[i][j]; 280 | } 281 | else 282 | { 283 | if(last < (N-1)) 284 | { 285 | W_index[i][j] = (last + 1); 286 | last = W_index[i][j]; 287 | } 288 | } 289 | } 290 | else 291 | { 292 | last = W_index[i][j]; 293 | } 294 | if(W_index[i][j]>=N) 295 | { 296 | W_index[i][j] = N-1; 297 | } 298 | } 299 | } 300 | 301 | // Populate Cost Array 302 | for(int i = 0; i < N; i++) 303 | { 304 | for(int j = 0; j < DEG; j++) 305 | { 306 | double v = drand48(); 307 | /*if(v > 0.8 || W_index[i][j] == -1) 308 | { W[i][j] = MAX; 309 | W_index[i][j] = -1; 310 | } 311 | 312 | else*/ if(W_index[i][j] == i) 313 | W[i][j] = 0; 314 | 315 | else 316 | W[i][j] = (int) (v*100) + 1; 317 | //printf(" %d ",W_index[i][j]); 318 | } 319 | //printf("\n"); 320 | } 321 | } -------------------------------------------------------------------------------- /apps/bc/Makefile: -------------------------------------------------------------------------------- 1 | 2 | TRGS = bc bc_non_partitioned 3 | 4 | LIBS += -lpthread -lrt 5 | 6 | ##BOOST_PATH = /run/pkg/boost-/1.53.0-gcc_4.7.3 7 | 8 | ##BOOST_FLAGS = -I$(BOOST_PATH)/include -L$(BOOST_PATH)/lib -lboost_graph 9 | 10 | CXXFLAGS = -g --std=c++0x -O3 11 | CXXFLAGS += -Wall -Werror 12 | 13 | all: $(TRGS) 14 | 15 | bc: bc.cc 16 | bc_non_partitioned: bc_non_partitioned.cc 17 | 18 | ##boost_dijk_real: boost_dijk_real.cc 19 | 20 | clean: 21 | rm -f $(TRGS) *.o *.dot 22 | 23 | %: %.cc ; 24 | $(CXX) $(CXXFLAGS) $< -o $@ $(LIBS) 25 | -------------------------------------------------------------------------------- /apps/bc/README.md: -------------------------------------------------------------------------------- 1 | Betweenness Centrality 2 | ====================== 3 | 4 | Run ```make``` to generate the required executables, then run using the syntax below 5 | 6 | To run with P number of threads, N vertices, and DEG edges per vertex 7 | ```./bc P N DEG``` 8 | 9 | e.g. 10 | ```./bc 2 16384 16``` 11 | 12 | **Notes** 13 | 14 | The executable outputs the time in seconds that the program took to run. 15 | 16 | bc_non_partitioned.cc contains a variant of the parallelization that updates sigma values via locks. This removes the need to initialize a sigma array for each thread separately. However the original partitioned version mostly has better performance. 17 | -------------------------------------------------------------------------------- /apps/bc/bc.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Program adopted from Parallel MiBench All Pairs Shortest Path 3 | Assumption : An entity (UAV) using this program practically needs shortest paths before making a decision. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | //#include "carbon_user.h" /*For the Graphite Simulator*/ 11 | #include 12 | #include 13 | 14 | #define MAX 100000000 15 | #define INT_MAX 100000000 16 | #define BILLION 1E9 17 | 18 | //Thread Argument Structure 19 | typedef struct 20 | { 21 | int* local_min; 22 | int* global_min; 23 | int* Q; 24 | int* D; 25 | int** W; 26 | int** W_index; 27 | int** sigma; 28 | int* d_count; 29 | int tid; 30 | int P; 31 | int N; 32 | int DEG; 33 | pthread_barrier_t* barrier_total; 34 | pthread_barrier_t* barrier; 35 | } thread_arg_t; 36 | 37 | //Function Declarations 38 | int initialize_single_source(int* D, int* Q, int source, int N); 39 | void relax(int u, int i, volatile int* D, int** W, int** W_index, int N); 40 | int get_local_min(volatile int* Q, volatile int* D, int start, int stop, int N, int** W_index, int** W, int u); 41 | void init_weights(int N, int DEG, int** W, int** W_index); 42 | 43 | //Global Variables 44 | int min = INT_MAX; 45 | int min_index = 0; //For local mins 46 | pthread_mutex_t lock; 47 | pthread_mutex_t locks[4194304]; 48 | int u = 0; //next best vertex 49 | int local_min_buffer[1024]; 50 | int global_min_buffer; 51 | int start = 64; 52 | int P_global = 256; 53 | 54 | int* avg; //avg shortest paths passing 55 | double* delta; //centralities 56 | 57 | thread_arg_t thread_arg[1024]; 58 | pthread_t thread_handle[1024]; //MAX threads and pthread handlers 59 | 60 | //Primary Parallel Function 61 | void* do_work(void* args) 62 | { 63 | volatile thread_arg_t* arg = (thread_arg_t*) args; 64 | 65 | int tid = arg->tid; 66 | int P = arg->P; 67 | //volatile int* Q = arg->Q; 68 | //int* D = arg->D; 69 | int** W = arg->W; //Graph weights 70 | int** W_index = arg->W_index; //Graph connections 71 | const int N = arg->N; //Total Vertices 72 | const int DEG = arg->DEG; //Edges per Vertex 73 | int v = 0; //current vertex 74 | int** sigma = arg->sigma; //shortest paths passing 75 | P_global = start; 76 | double tid_d = tid; 77 | double P_d = arg->P; 78 | double N_d = N; 79 | 80 | /*int* D; 81 | int* Q; 82 | 83 | int p0 = posix_memalign((void**) &D, 64, N * sizeof(int)); 84 | int p1 = posix_memalign((void**) &Q, 64, N * sizeof(int)); 85 | 86 | for(int i=0;iP); 97 | int i_stop = stop_d;//(tid+1) * N / (arg->P); 98 | int node = 0; 99 | 100 | pthread_barrier_wait(arg->barrier_total); 101 | 102 | //all_pairs shortest path first here 103 | while(node (D[v] + W[v][i]))) 126 | { 127 | int neighbor = W_index[v][i]; 128 | D[neighbor] = D[v] + W[v][i]; 129 | sigma[tid][neighbor]++; 130 | //printf(" %d ",sigma[tid][neighbor]); 131 | } 132 | Q[v]=0; 133 | } 134 | } 135 | 136 | //vertex capture 137 | pthread_mutex_lock(&lock); 138 | node++; 139 | //printf("\n %d",next_source); 140 | pthread_mutex_unlock(&lock); 141 | } 142 | 143 | pthread_barrier_wait(arg->barrier_total); 144 | //Betweenness centrality stuff here 145 | //Sum dependencies and then avg for approx 146 | 147 | for(int j=i_start;jN) 155 | avg[j]=1; 156 | //printf(" %d ",avg[j]); 157 | } 158 | pthread_barrier_wait(arg->barrier_total); 159 | 160 | //Master thread reduces centralities 161 | if(tid==0) 162 | { 163 | for(int j=0;jbarrier_total); 173 | 174 | return NULL; 175 | } 176 | 177 | 178 | int main(int argc, char** argv) 179 | { 180 | //Input arguments 181 | const int P1 = atoi(argv[1]); 182 | const int N = atoi(argv[2]); 183 | const int DEG = atoi(argv[3]); 184 | 185 | int P = 256; 186 | start = P1; 187 | P = P1; 188 | 189 | 190 | if (DEG > N) 191 | { 192 | fprintf(stderr, "Degree of graph cannot be grater than number of Vertices\n"); 193 | exit(EXIT_FAILURE); 194 | } 195 | 196 | //int* D; 197 | //int* Q; 198 | //posix_memalign((void**) &D, 64, N * sizeof(int)); 199 | //posix_memalign((void**) &Q, 64, N * sizeof(int)); 200 | 201 | //Memory allocations for the input graph 202 | if(posix_memalign((void**) &avg, 64, N * sizeof(int))) 203 | { 204 | fprintf(stderr, "Allocation of memory failed\n"); 205 | exit(EXIT_FAILURE); 206 | } 207 | if(posix_memalign((void**) &delta, 64, N * sizeof(double))) 208 | { 209 | fprintf(stderr, "Allocation of memory failed\n"); 210 | exit(EXIT_FAILURE); 211 | } 212 | 213 | int d_count = N; 214 | pthread_barrier_t barrier_total; 215 | pthread_barrier_t barrier; 216 | 217 | //Memory allocations for the input graph 218 | int** W = (int**) malloc(N*sizeof(int*)); 219 | int** W_index = (int**) malloc(N*sizeof(int*)); 220 | int** sigma = (int**) malloc(P*sizeof(int*)); 221 | for(int i = 0; i < N; i++) 222 | { 223 | //W[i] = (int *)malloc(sizeof(int)*N); 224 | delta[i]=0; 225 | avg[i]=0; 226 | int ret = posix_memalign((void**) &W[i], 64, DEG*sizeof(int)); 227 | int re1 = posix_memalign((void**) &W_index[i], 64, DEG*sizeof(int)); 228 | if (ret != 0 || re1!=0) 229 | { 230 | fprintf(stderr, "Could not allocate memory\n"); 231 | exit(EXIT_FAILURE); 232 | } 233 | } 234 | 235 | // The new sigma memory allocation loop 236 | for(int i = 0; i < P; i++) 237 | { 238 | int re2 = posix_memalign((void**) &sigma[i], 64, N*sizeof(int)); 239 | if (re2!=0) 240 | { 241 | fprintf(stderr, "Could not allocate memory\n"); 242 | exit(EXIT_FAILURE); 243 | } 244 | } 245 | 246 | //Initialize random graph 247 | init_weights(N, DEG, W, W_index); 248 | for(int i = 0;i (D[u] + W[u][i]) && (W_index[u][i]!=-1 && W_index[u][i] last) 386 | { 387 | W_index[i][j] = neighbor; 388 | last = W_index[i][j]; 389 | } 390 | else 391 | { 392 | if(last < (N-1)) 393 | { 394 | W_index[i][j] = (last + 1); 395 | last = W_index[i][j]; 396 | } 397 | } 398 | } 399 | else 400 | { 401 | last = W_index[i][j]; 402 | } 403 | if(W_index[i][j]>=N) 404 | { 405 | W_index[i][j] = N-1; 406 | } 407 | } 408 | } 409 | 410 | // Populate Cost Array 411 | for(int i = 0; i < N; i++) 412 | { 413 | for(int j = 0; j < DEG; j++) 414 | { 415 | double v = drand48(); 416 | /*if(v > 0.8 || W_index[i][j] == -1) 417 | { W[i][j] = MAX; 418 | W_index[i][j] = -1; 419 | } 420 | 421 | else*/ if(W_index[i][j] == i) 422 | W[i][j] = 0; 423 | 424 | else 425 | W[i][j] = (int) (v*10) + 1; 426 | //printf(" %d ",W[i][j]); 427 | } 428 | //printf("\n"); 429 | } 430 | } 431 | -------------------------------------------------------------------------------- /apps/bc/bc_non_partitioned.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Program adopted from Parallel MiBench All Pairs Shortest Path 3 | Assumption : An entity (UAV) using this program practically needs shortest paths before making a decision. 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | //#include "carbon_user.h" /*For the Graphite Simulator*/ 11 | #include 12 | #include 13 | 14 | #define MAX 100000000 15 | #define INT_MAX 100000000 16 | #define BILLION 1E9 17 | 18 | //Thread Argument Structure 19 | typedef struct 20 | { 21 | int* local_min; 22 | int* global_min; 23 | int* Q; 24 | int* D; 25 | int** W; 26 | int** W_index; 27 | int* sigma; 28 | int* d_count; 29 | int tid; 30 | int P; 31 | int N; 32 | int DEG; 33 | pthread_barrier_t* barrier_total; 34 | pthread_barrier_t* barrier; 35 | } thread_arg_t; 36 | 37 | //Function Declarations 38 | int initialize_single_source(int* D, int* Q, int source, int N); 39 | void relax(int u, int i, volatile int* D, int** W, int** W_index, int N); 40 | int get_local_min(volatile int* Q, volatile int* D, int start, int stop, int N, int** W_index, int** W, int u); 41 | void init_weights(int N, int DEG, int** W, int** W_index); 42 | 43 | //Global Variables 44 | int min = INT_MAX; 45 | int min_index = 0; //For local mins 46 | pthread_mutex_t lock; 47 | pthread_mutex_t *locks; 48 | int u = 0; //next best vertex 49 | int local_min_buffer[1024]; 50 | int global_min_buffer; 51 | int start = 64; 52 | int P_global = 256; 53 | 54 | int* avg; //avg shortest paths passing 55 | double* delta; //centralities 56 | 57 | thread_arg_t thread_arg[1024]; 58 | pthread_t thread_handle[1024]; //MAX threads and pthread handlers 59 | 60 | //Primary Parallel Function 61 | void* do_work(void* args) 62 | { 63 | volatile thread_arg_t* arg = (thread_arg_t*) args; 64 | 65 | int tid = arg->tid; 66 | int P = arg->P; 67 | //volatile int* Q = arg->Q; 68 | //int* D = arg->D; 69 | int** W = arg->W; //Graph weights 70 | int** W_index = arg->W_index; //Graph connections 71 | const int N = arg->N; //Total Vertices 72 | const int DEG = arg->DEG; //Edges per Vertex 73 | int v = 0; //current vertex 74 | int* sigma = arg->sigma; //shortest paths passing 75 | P_global = start; 76 | double tid_d = tid; 77 | double P_d = P; 78 | double N_d = N; 79 | 80 | /*int* D; 81 | int* Q; 82 | 83 | int p0 = posix_memalign((void**) &D, 64, N * sizeof(int)); 84 | int p1 = posix_memalign((void**) &Q, 64, N * sizeof(int)); 85 | 86 | for(int i=0;iP); 97 | int i_stop = stop_d;//(tid+1) * N / (arg->P); 98 | int node = 0; 99 | 100 | pthread_barrier_wait(arg->barrier_total); 101 | 102 | //all_pairs shortest path first here 103 | while(node (D[v] + W[v][i]))) 126 | { 127 | int neighbor = W_index[v][i]; 128 | D[neighbor] = D[v] + W[v][i]; 129 | pthread_mutex_lock(&locks[neighbor]); 130 | sigma[neighbor]++; 131 | pthread_mutex_unlock(&locks[neighbor]); 132 | //printf(" %d ",sigma[tid][neighbor]); 133 | } 134 | Q[v]=0; 135 | } 136 | } 137 | 138 | //vertex capture 139 | pthread_mutex_lock(&lock); 140 | node++; 141 | //printf("\n %d",next_source); 142 | pthread_mutex_unlock(&lock); 143 | } 144 | 145 | pthread_barrier_wait(arg->barrier_total); 146 | //Betweenness centrality stuff here 147 | //Sum dependencies and then avg for approx 148 | 149 | for(int j=i_start;jN) 157 | avg[j]=1; 158 | //printf(" %d ",avg[j]); 159 | } 160 | pthread_barrier_wait(arg->barrier_total); 161 | 162 | //Master thread reduces centralities 163 | if(tid==0) 164 | { 165 | for(int j=0;jbarrier_total); 176 | 177 | return NULL; 178 | } 179 | 180 | 181 | int main(int argc, char** argv) 182 | { 183 | //Input arguments 184 | const int P1 = atoi(argv[1]); 185 | const int N = atoi(argv[2]); 186 | const int DEG = atoi(argv[3]); 187 | 188 | int P = 256; 189 | start = P1; 190 | P = P1; 191 | 192 | 193 | if (DEG > N) 194 | { 195 | fprintf(stderr, "Degree of graph cannot be grater than number of Vertices\n"); 196 | exit(EXIT_FAILURE); 197 | } 198 | 199 | int* sigma; 200 | //int* D; 201 | //int* Q; 202 | //posix_memalign((void**) &D, 64, N * sizeof(int)); 203 | //posix_memalign((void**) &Q, 64, N * sizeof(int)); 204 | 205 | //Memory allocations for the input graph 206 | if(posix_memalign((void**) &avg, 64, N * sizeof(int))) 207 | { 208 | fprintf(stderr, "Allocation of memory failed\n"); 209 | exit(EXIT_FAILURE); 210 | } 211 | if(posix_memalign((void**) &delta, 64, N * sizeof(double))) 212 | { 213 | fprintf(stderr, "Allocation of memory failed\n"); 214 | exit(EXIT_FAILURE); 215 | } 216 | if(posix_memalign((void**) &sigma, 64, N * sizeof(int))) 217 | { 218 | fprintf(stderr, "Allocation of memory failed\n"); 219 | exit(EXIT_FAILURE); 220 | } 221 | 222 | int d_count = N; 223 | pthread_barrier_t barrier_total; 224 | pthread_barrier_t barrier; 225 | 226 | //Memory allocations for the input graph 227 | int** W = (int**) malloc(N*sizeof(int*)); 228 | int** W_index = (int**) malloc(N*sizeof(int*)); 229 | //int** sigma = (int**) malloc(P*sizeof(int*)); 230 | for(int i = 0; i < N; i++) 231 | { 232 | //W[i] = (int *)malloc(sizeof(int)*N); 233 | delta[i]=0; 234 | avg[i]=0; 235 | int ret = posix_memalign((void**) &W[i], 64, DEG*sizeof(int)); 236 | int re1 = posix_memalign((void**) &W_index[i], 64, DEG*sizeof(int)); 237 | //int re2 = posix_memalign((void**) &sigma[i], 64, N*sizeof(int)); 238 | if (ret != 0 || re1!=0) 239 | { 240 | fprintf(stderr, "Could not allocate memory\n"); 241 | exit(EXIT_FAILURE); 242 | } 243 | } 244 | 245 | //Initialize random graph 246 | init_weights(N, DEG, W, W_index); 247 | for(int i = 0;i<1;i++) 248 | { 249 | for(int j = 0;j (D[u] + W[u][i]) && (W_index[u][i]!=-1 && W_index[u][i] last) 386 | { 387 | W_index[i][j] = neighbor; 388 | last = W_index[i][j]; 389 | } 390 | else 391 | { 392 | if(last < (N-1)) 393 | { 394 | W_index[i][j] = (last + 1); 395 | last = W_index[i][j]; 396 | } 397 | } 398 | } 399 | else 400 | { 401 | last = W_index[i][j]; 402 | } 403 | if(W_index[i][j]>=N) 404 | { 405 | W_index[i][j] = N-1; 406 | } 407 | } 408 | } 409 | 410 | // Populate Cost Array 411 | for(int i = 0; i < N; i++) 412 | { 413 | for(int j = 0; j < DEG; j++) 414 | { 415 | double v = drand48(); 416 | /*if(v > 0.8 || W_index[i][j] == -1) 417 | { W[i][j] = MAX; 418 | W_index[i][j] = -1; 419 | } 420 | 421 | else*/ if(W_index[i][j] == i) 422 | W[i][j] = 0; 423 | 424 | else 425 | W[i][j] = (int) (v*10) + 1; 426 | //printf(" %d ",W[i][j]); 427 | } 428 | //printf("\n"); 429 | } 430 | } 431 | -------------------------------------------------------------------------------- /apps/bfs/Makefile: -------------------------------------------------------------------------------- 1 | 2 | TRGS = bfs bfs_atomic 3 | 4 | LIBS += -lpthread -lrt 5 | 6 | CXXFLAGS = -g --std=c++0x -O3 7 | CXXFLAGS += -Wall 8 | 9 | all: $(TRGS) 10 | 11 | bfs: bfs.cc 12 | bfs_atomic: bfs_atomic.cc 13 | 14 | clean: 15 | rm -f $(TRGS) *.o *.dot 16 | rm -f myfile.txt 17 | 18 | %: %.cc ; 19 | $(CXX) $(CXXFLAGS) $< -o $@ $(LIBS) 20 | -------------------------------------------------------------------------------- /apps/bfs/README.md: -------------------------------------------------------------------------------- 1 | Breadth First Search 2 | ================== 3 | 4 | Run ```make``` to generate the required executables, the run using the syntax explained below. 5 | 6 | The first argument to the executable specifies whether you want to read the graph from a file (1), or generate a synthetic one internally (0). 7 | 8 | **Input Graph from File** 9 | 10 | To run with P number of threads, and an input file 11 | ```./bfs 1 P ``` 12 | 13 | The input file can be used as: sample.txt OR any other file such as road networks from the SNAP datasets (e.g. A FaceBook Graph) https://snap.stanford.edu/data/ 14 | 15 | **Generate and Input using the Synthetic Graph Generator** 16 | 17 | To run with P number of threads, N vertices, and DEG edges per vertex 18 | ```./bfs 0 P N DEG``` 19 | 20 | **Notes** 21 | 22 | The executable outputs the time in seconds that the program took to run. 23 | -------------------------------------------------------------------------------- /apps/bfs/bfs.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Distributed Under the MIT license 3 | Uses vertex coloring to distinguish searches 4 | Programs by Masab Ahmad (UConn) 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | //#include "carbon_user.h" /* For the Graphite Simulator*/ 11 | #include 12 | #include 13 | 14 | #define MAX 100000000 15 | #define INT_MAX 100000000 16 | // #define DEBUG 1 17 | #define BILLION 1E9 18 | 19 | //Thread Argument Structure 20 | typedef struct 21 | { 22 | int* local_min; 23 | int* global_min; 24 | int* Q; 25 | int* D; 26 | //int** W; 27 | int** W_index; 28 | int* d_count; 29 | int tid; 30 | int P; 31 | int N; 32 | int DEG; 33 | pthread_barrier_t* barrier_total; 34 | pthread_barrier_t* barrier; 35 | } thread_arg_t; 36 | 37 | //Function Initializers 38 | int initialize_single_source(int* D, int* Q, int source, int N); 39 | void init_weights(int N, int DEG, int** W, int** W_index); 40 | 41 | //Global Variables 42 | pthread_mutex_t lock; //single lock 43 | //pthread_mutex_t locks[4194304]; //locks for each vertes, upper limit 44 | pthread_mutex_t *locks; 45 | int local_min_buffer[1024]; 46 | int global_min_buffer; 47 | int Total = 0; 48 | int terminate = 0; //work termination 49 | int P_global = 256; 50 | int *edges; //deg of a given vertex 51 | int *exist; //whether vertex in graph 52 | int *temporary; 53 | int largest=0; 54 | thread_arg_t thread_arg[1024]; 55 | pthread_t thread_handle[1024]; 56 | 57 | //Primary Parallel Function 58 | void* do_work(void* args) 59 | { 60 | //Thread variables and arguments 61 | volatile thread_arg_t* arg = (thread_arg_t*) args; 62 | int tid = arg->tid; //thread id 63 | int P = arg->P; //Max threads 64 | volatile int* Q = arg->Q; //set/unset array 65 | int* D = arg->D; //coloring array 66 | //int** W = arg->W; 67 | int** W_index = arg->W_index; //graph structure 68 | int v = 0; 69 | int iter = 0; 70 | 71 | //For precision work allocation 72 | double P_d = P; 73 | double tid_d = tid; 74 | double largest_d = largest+1.0; 75 | 76 | int start = 0; //tid * DEG / (arg->P); 77 | int stop = 0; //(tid+1) * DEG / (arg->P); 78 | 79 | //Partition data into threads 80 | double start_d = (tid_d) * (largest_d/P_d); 81 | double stop_d = (tid_d+1.0) * (largest_d/P_d); 82 | start = start_d; //tid * (largest+1) / (P); 83 | stop = stop_d; //(tid+1) * (largest+1) / (P); 84 | 85 | //printf("\n tid:%d %d %d",tid,start,stop); 86 | 87 | pthread_barrier_wait(arg->barrier_total); 88 | 89 | while(terminate==0) 90 | { 91 | for(v=start;vbarrier_total); 118 | 119 | //Update colors 120 | for(v=start;v=Total) 130 | terminate=1; 131 | iter++; 132 | pthread_barrier_wait(arg->barrier_total); 133 | } 134 | //printf("\n %d %d",tid,terminate); 135 | pthread_barrier_wait(arg->barrier_total); 136 | 137 | return NULL; 138 | } 139 | 140 | //Main 141 | int main(int argc, char** argv) 142 | { 143 | FILE *file0 = NULL; 144 | int N = 0; 145 | int DEG = 0; 146 | //whether read from file or generate synthetic 147 | const int select = atoi(argv[1]); 148 | 149 | //if reading from file 150 | if(select==1) 151 | { 152 | const char *filename = argv[3]; 153 | //printf("Please Enter The Name Of The File You Would Like To Fetch\n"); 154 | //scanf("%s", filename); 155 | file0 = fopen(filename,"r"); 156 | } 157 | 158 | int lines_to_check=0; 159 | char c; 160 | int number0; 161 | int number1; 162 | int inter = -1; 163 | 164 | if(select==1) 165 | { 166 | N = 2097152; //can be read from file if needed, this is a default upper limit 167 | DEG = 16; //also can be reda from file if needed, upper limit here again 168 | } 169 | 170 | //Max input threads 171 | const int P1 = atoi(argv[2]); 172 | 173 | int P = P1; 174 | P_global = P1; 175 | 176 | //If generating a uniform random graph 177 | if(select==0) 178 | { 179 | N = atoi(argv[3]); 180 | DEG = atoi(argv[4]); 181 | printf("\nGraph with Parameters: N:%d DEG:%d\n",N,DEG); 182 | } 183 | 184 | if (DEG > N) 185 | { 186 | fprintf(stderr, "Degree of graph cannot be grater than number of Vertices\n"); 187 | exit(EXIT_FAILURE); 188 | } 189 | 190 | //Memory Allocations 191 | int* D; 192 | int* Q; 193 | if(posix_memalign((void**) &D, 64, N * sizeof(int))) 194 | { 195 | fprintf(stderr, "Allocation of memory failed\n"); 196 | exit(EXIT_FAILURE); 197 | } 198 | if(posix_memalign((void**) &Q, 64, N * sizeof(int))) 199 | { 200 | fprintf(stderr, "Allocation of memory failed\n"); 201 | exit(EXIT_FAILURE); 202 | } 203 | if(posix_memalign((void**) &edges, 64, N * sizeof(int))) 204 | { 205 | fprintf(stderr, "Allocation of memory failed\n"); 206 | exit(EXIT_FAILURE); 207 | } 208 | if(posix_memalign((void**) &exist, 64, N * sizeof(int))) 209 | { 210 | fprintf(stderr, "Allocation of memory failed\n"); 211 | exit(EXIT_FAILURE); 212 | } 213 | if(posix_memalign((void**) &temporary, 64, N * sizeof(int))) 214 | { 215 | fprintf(stderr, "Allocation of memory failed\n"); 216 | exit(EXIT_FAILURE); 217 | } 218 | int d_count = N; 219 | pthread_barrier_t barrier_total; 220 | pthread_barrier_t barrier; 221 | 222 | int** W = (int**) malloc(N*sizeof(int*)); 223 | int** W_index = (int**) malloc(N*sizeof(int*)); 224 | for(int i = 0; i < N; i++) 225 | { 226 | //W[i] = (int *)malloc(sizeof(int)*N); 227 | if(posix_memalign((void**) &W[i], 64, DEG*sizeof(int))) 228 | { 229 | fprintf(stderr, "Allocation of memory failed\n"); 230 | exit(EXIT_FAILURE); 231 | } 232 | if(posix_memalign((void**) &W_index[i], 64, DEG*sizeof(int))) 233 | { 234 | fprintf(stderr, "Allocation of memory failed\n"); 235 | exit(EXIT_FAILURE); 236 | } 237 | } 238 | 239 | //Memory initialization 240 | for(int i=0;i3) 261 | { 262 | int f0 = fscanf(file0, "%d %d", &number0,&number1); 263 | if(f0 != 2 && f0 != EOF) 264 | { 265 | printf ("Error: Read %d values, expected 2. Parsing failed.\n",f0); 266 | exit (EXIT_FAILURE); 267 | } 268 | //printf("\n%d %d",number0,number1); 269 | if(number0>largest) 270 | largest=number0; 271 | if(number1>largest) 272 | largest=number1; 273 | inter = edges[number0]; 274 | 275 | //W[number0][inter] = drand48(); 276 | W_index[number0][inter] = number1; 277 | //previous_node = number0; 278 | edges[number0]++; 279 | exist[number0]=1; exist[number1]=1; 280 | } 281 | } 282 | //printf("\n%d deg:%d",test[0]); 283 | printf("\nFile Read, Largest Vertex:%d",largest); 284 | } 285 | 286 | //Generate Random graph 287 | if(select==0) 288 | { 289 | init_weights(N, DEG, W, W_index); 290 | largest = N-1; //largest vertex id 291 | } 292 | 293 | //Synchronization variables 294 | pthread_barrier_init(&barrier_total, NULL, P); 295 | pthread_barrier_init(&barrier, NULL, P); 296 | locks = (pthread_mutex_t*) malloc((largest+16) * sizeof(pthread_mutex_t)); 297 | pthread_mutex_init(&lock, NULL); 298 | 299 | for(int i=0; i last) 414 | { 415 | W_index[i][j] = neighbor; 416 | last = W_index[i][j]; 417 | } 418 | else 419 | { 420 | if(last < (N-1)) 421 | { 422 | W_index[i][j] = (last + 1); 423 | last = W_index[i][j]; 424 | } 425 | } 426 | } 427 | else 428 | { 429 | last = W_index[i][j]; 430 | } 431 | if(W_index[i][j]>=N) 432 | { 433 | W_index[i][j] = N-1; 434 | } 435 | } 436 | } 437 | 438 | // Populate Cost Array 439 | for(int i = 0; i < N; i++) 440 | { 441 | for(int j = 0; j < DEG; j++) 442 | { 443 | double v = drand48(); 444 | /*if(v > 0.8 || W_index[i][j] == -1) 445 | { W[i][j] = MAX; 446 | W_index[i][j] = -1; 447 | } 448 | 449 | else*/ if(W_index[i][j] == i) 450 | W[i][j] = 0; 451 | 452 | else 453 | W[i][j] = (int) (v*100) + 1; 454 | //printf(" %d ",W_index[i][j]); 455 | } 456 | //printf("\n"); 457 | } 458 | } 459 | -------------------------------------------------------------------------------- /apps/bfs/bfs_atomic.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Distributed Under the MIT license 3 | Uses vertex coloring to distinguish searches 4 | Programs by Masab Ahmad (UConn) 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | //#include "carbon_user.h" /* For the Graphite Simulator*/ 11 | #include 12 | #include 13 | #include "../../common/barrier.h" 14 | 15 | #define MAX 100000000 16 | #define INT_MAX 100000000 17 | // #define DEBUG 1 18 | #define BILLION 1E9 19 | 20 | //Thread Argument Structure 21 | typedef struct 22 | { 23 | int* local_min; 24 | int* global_min; 25 | int* Q; 26 | int* D; 27 | //int** W; 28 | int** W_index; 29 | int* d_count; 30 | int tid; 31 | int P; 32 | int N; 33 | int DEG; 34 | pthread_barrier_t* barrier_total; 35 | pthread_barrier_t* barrier; 36 | } thread_arg_t; 37 | 38 | //Function Initializers 39 | int initialize_single_source(int* D, int* Q, int source, int N); 40 | void init_weights(int N, int DEG, int** W, int** W_index); 41 | 42 | //Global Variables 43 | pthread_mutex_t lock; //single lock 44 | //pthread_mutex_t locks[4194304]; //locks for each vertes, upper limit 45 | int local_min_buffer[1024]; 46 | int global_min_buffer; 47 | int Total = 0; 48 | int terminate = 0; //work termination 49 | int P_global = 256; 50 | int *edges; //deg of a given vertex 51 | int *exist; //whether vertex in graph 52 | int *temporary; 53 | int largest=0; 54 | thread_arg_t thread_arg[1024]; 55 | pthread_t thread_handle[1024]; 56 | 57 | //Primary Parallel Function 58 | void* do_work(void* args) 59 | { 60 | //Thread variables and arguments 61 | volatile thread_arg_t* arg = (thread_arg_t*) args; 62 | int tid = arg->tid; //thread id 63 | int P = arg->P; //Max threads 64 | volatile int* Q = arg->Q; //set/unset array 65 | int* D = arg->D; //coloring array 66 | //int** W = arg->W; 67 | int** W_index = arg->W_index; //graph structure 68 | int v = 0; 69 | int iter = 0; 70 | 71 | //For precision work allocation 72 | double P_d = P; 73 | double tid_d = tid; 74 | double largest_d = largest+1.0; 75 | 76 | int start = 0; //tid * DEG / (arg->P); 77 | int stop = 0; //(tid+1) * DEG / (arg->P); 78 | 79 | //Partition data into threads 80 | double start_d = (tid_d) * (largest_d/P_d); 81 | double stop_d = (tid_d+1.0) * (largest_d/P_d); 82 | start = start_d; //tid * (largest+1) / (P); 83 | stop = stop_d; //(tid+1) * (largest+1) / (P); 84 | 85 | //printf("\n tid:%d %d %d",tid,start,stop); 86 | 87 | //pthread_barrier_wait(arg->barrier_total); 88 | barrier_wait(); 89 | 90 | while(terminate==0) 91 | { 92 | for(v=start;vbarrier_total); 130 | barrier_wait(); 131 | 132 | //Update colors 133 | for(v=start;v=Total) 143 | terminate=1; 144 | iter++; 145 | //pthread_barrier_wait(arg->barrier_total); 146 | barrier_wait(); 147 | } 148 | //printf("\n %d %d",tid,terminate); 149 | //pthread_barrier_wait(arg->barrier_total); 150 | barrier_wait(); 151 | 152 | return NULL; 153 | } 154 | 155 | //Main 156 | int main(int argc, char** argv) 157 | { 158 | FILE *file0 = NULL; 159 | int N = 0; 160 | int DEG = 0; 161 | //whether read from file or generate synthetic 162 | const int select = atoi(argv[1]); 163 | 164 | //if reading from file 165 | if(select==1) 166 | { 167 | const char *filename = argv[3]; 168 | //printf("Please Enter The Name Of The File You Would Like To Fetch\n"); 169 | //scanf("%s", filename); 170 | file0 = fopen(filename,"r"); 171 | } 172 | 173 | int lines_to_check=0; 174 | char c; 175 | int number0; 176 | int number1; 177 | int inter = -1; 178 | 179 | if(select==1) 180 | { 181 | N = 2097152; //can be read from file if needed, this is a default upper limit 182 | DEG = 16; //also can be reda from file if needed, upper limit here again 183 | } 184 | 185 | //Max input threads 186 | const int P1 = atoi(argv[2]); 187 | 188 | int P = P1; 189 | P_global = P1; 190 | 191 | //If generating a uniform random graph 192 | if(select==0) 193 | { 194 | N = atoi(argv[3]); 195 | DEG = atoi(argv[4]); 196 | printf("\nGraph with Parameters: N:%d DEG:%d\n",N,DEG); 197 | } 198 | 199 | if (DEG > N) 200 | { 201 | fprintf(stderr, "Degree of graph cannot be grater than number of Vertices\n"); 202 | exit(EXIT_FAILURE); 203 | } 204 | 205 | //Memory Allocations 206 | int* D; 207 | int* Q; 208 | if(posix_memalign((void**) &D, 64, N * sizeof(int))) 209 | { 210 | fprintf(stderr, "Allocation of memory failed\n"); 211 | exit(EXIT_FAILURE); 212 | } 213 | if(posix_memalign((void**) &Q, 64, N * sizeof(int))) 214 | { 215 | fprintf(stderr, "Allocation of memory failed\n"); 216 | exit(EXIT_FAILURE); 217 | } 218 | if(posix_memalign((void**) &edges, 64, N * sizeof(int))) 219 | { 220 | fprintf(stderr, "Allocation of memory failed\n"); 221 | exit(EXIT_FAILURE); 222 | } 223 | if(posix_memalign((void**) &exist, 64, N * sizeof(int))) 224 | { 225 | fprintf(stderr, "Allocation of memory failed\n"); 226 | exit(EXIT_FAILURE); 227 | } 228 | if(posix_memalign((void**) &temporary, 64, N * sizeof(int))) 229 | { 230 | fprintf(stderr, "Allocation of memory failed\n"); 231 | exit(EXIT_FAILURE); 232 | } 233 | int d_count = N; 234 | pthread_barrier_t barrier_total; 235 | pthread_barrier_t barrier; 236 | 237 | int** W = (int**) malloc(N*sizeof(int*)); 238 | int** W_index = (int**) malloc(N*sizeof(int*)); 239 | for(int i = 0; i < N; i++) 240 | { 241 | //W[i] = (int *)malloc(sizeof(int)*N); 242 | if(posix_memalign((void**) &W[i], 64, DEG*sizeof(int))) 243 | { 244 | fprintf(stderr, "Allocation of memory failed\n"); 245 | exit(EXIT_FAILURE); 246 | } 247 | if(posix_memalign((void**) &W_index[i], 64, DEG*sizeof(int))) 248 | { 249 | fprintf(stderr, "Allocation of memory failed\n"); 250 | exit(EXIT_FAILURE); 251 | } 252 | } 253 | 254 | //Memory initialization 255 | for(int i=0;i3) 276 | { 277 | int f0 = fscanf(file0, "%d %d", &number0,&number1); 278 | if(f0 != 2 && f0 != EOF) 279 | { 280 | printf ("Error: Read %d values, expected 2. Parsing failed.\n",f0); 281 | exit (EXIT_FAILURE); 282 | } 283 | //printf("\n%d %d",number0,number1); 284 | if(number0>largest) 285 | largest=number0; 286 | if(number1>largest) 287 | largest=number1; 288 | inter = edges[number0]; 289 | 290 | //W[number0][inter] = drand48(); 291 | W_index[number0][inter] = number1; 292 | //previous_node = number0; 293 | edges[number0]++; 294 | exist[number0]=1; exist[number1]=1; 295 | } 296 | } 297 | //printf("\n%d deg:%d",test[0]); 298 | printf("\nFile Read, Largest Vertex:%d",largest); 299 | } 300 | 301 | //Generate Random graph 302 | if(select==0) 303 | { 304 | init_weights(N, DEG, W, W_index); 305 | largest = N-1; //largest vertex id 306 | } 307 | 308 | //Synchronization variables 309 | pthread_barrier_init(&barrier_total, NULL, P); 310 | pthread_barrier_init(&barrier, NULL, P); 311 | 312 | pthread_mutex_init(&lock, NULL); 313 | 314 | for(int i=0; i last) 431 | { 432 | W_index[i][j] = neighbor; 433 | last = W_index[i][j]; 434 | } 435 | else 436 | { 437 | if(last < (N-1)) 438 | { 439 | W_index[i][j] = (last + 1); 440 | last = W_index[i][j]; 441 | } 442 | } 443 | } 444 | else 445 | { 446 | last = W_index[i][j]; 447 | } 448 | if(W_index[i][j]>=N) 449 | { 450 | W_index[i][j] = N-1; 451 | } 452 | } 453 | } 454 | 455 | // Populate Cost Array 456 | for(int i = 0; i < N; i++) 457 | { 458 | for(int j = 0; j < DEG; j++) 459 | { 460 | double v = drand48(); 461 | /*if(v > 0.8 || W_index[i][j] == -1) 462 | { W[i][j] = MAX; 463 | W_index[i][j] = -1; 464 | } 465 | 466 | else*/ if(W_index[i][j] == i) 467 | W[i][j] = 0; 468 | 469 | else 470 | W[i][j] = (int) (v*100) + 1; 471 | //printf(" %d ",W_index[i][j]); 472 | } 473 | //printf("\n"); 474 | } 475 | } 476 | -------------------------------------------------------------------------------- /apps/bfs/sample.txt: -------------------------------------------------------------------------------- 1 | # Directed graph (each unordered pair of nodes is saved once): roadNet-CA.txt 2 | # Sample California road network 3 | # Nodes: 1965206 Edges: 5533214 4 | # FromNodeId ToNodeId 5 | 0 1 6 | 0 2 7 | 0 469 8 | 1 0 9 | 1 6 10 | 1 385 11 | 2 0 12 | 2 3 13 | 469 0 14 | 469 380 15 | 469 37415 16 | 6 1 17 | 6 5 18 | 385 1 19 | 385 384 20 | 385 386 21 | 3 2 22 | 3 4 23 | 3 419 24 | 3 422 25 | 4 3 26 | 4 5 27 | 4 98 28 | 4 420 29 | 419 3 30 | 419 420 31 | 419 35698 32 | 422 3 33 | 422 183 34 | 422 423 35 | 422 37415 36 | 5 4 37 | 5 6 38 | 5 98 39 | 98 4 40 | 98 5 41 | 98 470 42 | 98 35729 43 | 420 4 44 | 420 419 45 | 420 35709 46 | 7 8 47 | 7 9 48 | 7 79 49 | 8 7 50 | 8 33 51 | 9 7 52 | 9 10 53 | 9 84 54 | 79 7 55 | 79 78 56 | 79 119 57 | 33 8 58 | 33 32 59 | 33 34 60 | 10 9 61 | 10 11 62 | 10 84 63 | 10 110 64 | 84 9 65 | 84 10 66 | 84 83 67 | 84 85 68 | 11 10 69 | 11 12 70 | 11 110 71 | 110 10 72 | 110 11 73 | 110 111 74 | 110 112 75 | 12 11 76 | 12 13 77 | 12 95 78 | 12 108 79 | 13 12 80 | 13 14 81 | 13 94 82 | 13 95 83 | 108 12 84 | 108 109 85 | 108 113 86 | 108 123 87 | 95 12 88 | 95 13 89 | 95 96 90 | 14 13 91 | 14 15 92 | 14 16 93 | 14 77 94 | 94 13 95 | 94 77 96 | 94 93 97 | 15 14 98 | 16 14 99 | 16 17 100 | 77 14 101 | 77 17 102 | 77 94 103 | 17 16 104 | 17 18 105 | 17 77 106 | 17 3254 107 | 18 17 108 | 18 19 109 | 18 3254 110 | 3254 17 111 | 3254 18 112 | 3254 3255 113 | 3254 36971 114 | 19 18 115 | 19 20 116 | 19 23 117 | 20 19 118 | 20 21 119 | 20 22 120 | 23 19 121 | 23 24 122 | 23 25 123 | 21 20 124 | 22 20 125 | 24 23 126 | 25 23 127 | 25 26 128 | 25 27 129 | 26 25 130 | 27 25 131 | 27 28 132 | 27 29 133 | 28 27 134 | 29 27 135 | 29 30 136 | 29 3255 137 | 30 29 138 | 30 31 139 | 30 3247 140 | 30 3253 141 | 3255 29 142 | 3255 3253 143 | 3255 3254 144 | 3255 35943 145 | 31 30 146 | 31 32 147 | 31 3246 148 | 3247 30 149 | 3247 3248 150 | 3247 3249 151 | 3253 30 152 | 3253 3204 153 | 3253 3255 154 | 3253 35950 155 | 32 31 156 | 32 33 157 | 32 2203 158 | 3246 31 159 | 3246 2203 160 | 3246 3252 161 | 3246 3257 162 | 2203 32 163 | 2203 2146 164 | 2203 2204 165 | 2203 3246 166 | 34 33 167 | 35 36 168 | 35 50 169 | 35 1199 170 | 36 35 171 | 36 37 172 | 36 35885 173 | 50 35 174 | 50 49 175 | 50 185 176 | 1199 35 177 | 1199 1198 178 | 1199 1205 179 | 37 36 180 | 37 38 181 | 35885 36 182 | 35885 35884 183 | 38 37 184 | 38 39 185 | 39 38 186 | 39 40 187 | 40 39 188 | 40 41 189 | 41 40 190 | 41 42 191 | 42 41 192 | 42 43 193 | 43 42 194 | 43 44 195 | 44 43 196 | 44 45 197 | 45 44 198 | 45 46 199 | 45 1154 200 | 46 45 201 | 46 47 202 | 46 27108 203 | 46 27325 204 | 1154 45 205 | 1154 1153 206 | 1154 1155 207 | 47 46 208 | 47 48 209 | 47 27325 210 | 27108 46 211 | 27108 27107 212 | 27108 27250 213 | 27325 46 214 | 27325 47 215 | 27325 27323 216 | 27325 27335 217 | 48 47 218 | 48 49 219 | 48 27343 220 | 49 48 221 | 49 50 222 | 49 184 223 | 27343 48 224 | 27343 27342 225 | 27343 35887 226 | -------------------------------------------------------------------------------- /apps/community/Makefile: -------------------------------------------------------------------------------- 1 | 2 | TRGS = community_lock community_atomic 3 | 4 | LIBS += -lpthread -lrt 5 | 6 | CXXFLAGS = -g --std=c++0x -O3 7 | CXXFLAGS += -Wall -Werror 8 | 9 | all: $(TRGS) 10 | 11 | community_lock: community_lock.cc 12 | community_atomic: community_atomic.cc 13 | 14 | clean: 15 | rm -f $(TRGS) *.o *.dot 16 | 17 | %: %.cc ; 18 | $(CXX) $(CXXFLAGS) $< -o $@ $(LIBS) 19 | -------------------------------------------------------------------------------- /apps/community/README.md: -------------------------------------------------------------------------------- 1 | Community Detection 2 | ======================= 3 | 4 | Run ```make``` to generate the required executable, then run using the syntax below. 5 | 6 | The first argument to the executable specifies whether you want to read the graph from a file (1), or generate a synthetic one internally (0). 7 | 8 | **Input Graph from File** 9 | 10 | To run with P number of threads, I iterations, and an input file 11 | ```./community_lock 1 P I ``` 12 | 13 | To run a matrix format file (.mtx) 14 | ```./community_lock 2 P I ``` 15 | 16 | For the input file, use sample.txt 17 | OR any other file such as road networks from the SNAP datasets (e.g. roadNet-CA) 18 | https://snap.stanford.edu/data/#road 19 | 20 | **Generate and Input using the Synthetic Graph Generator** 21 | 22 | To run with P number of threads, I iterations, N vertices, and DEG edges per vertex 23 | ```./community_lock 0 P I N DEG``` 24 | 25 | **Notes** 26 | 27 | Number of iterations required comes from the approximate louvian algorithm, more iterations means higher accuracy of detection. 28 | 29 | The executable outputs the time in seconds that the program took to run. 30 | 31 | The file utilizing atomic instructions has the same arguments as specified above. Although the weights type is converted from float to int. 32 | -------------------------------------------------------------------------------- /apps/community/sample.txt: -------------------------------------------------------------------------------- 1 | # Directed graph (each unordered pair of nodes is saved once): roadNet-CA.txt 2 | # Sample California road network 3 | # Nodes: 1965206 Edges: 5533214 4 | # FromNodeId ToNodeId 5 | 0 1 6 | 0 2 7 | 0 469 8 | 1 0 9 | 1 6 10 | 1 385 11 | 2 0 12 | 2 3 13 | 469 0 14 | 469 380 15 | 469 37415 16 | 6 1 17 | 6 5 18 | 385 1 19 | 385 384 20 | 385 386 21 | 3 2 22 | 3 4 23 | 3 419 24 | 3 422 25 | 4 3 26 | 4 5 27 | 4 98 28 | 4 420 29 | 419 3 30 | 419 420 31 | 419 35698 32 | 422 3 33 | 422 183 34 | 422 423 35 | 422 37415 36 | 5 4 37 | 5 6 38 | 5 98 39 | 98 4 40 | 98 5 41 | 98 470 42 | 98 35729 43 | 420 4 44 | 420 419 45 | 420 35709 46 | 7 8 47 | 7 9 48 | 7 79 49 | 8 7 50 | 8 33 51 | 9 7 52 | 9 10 53 | 9 84 54 | 79 7 55 | 79 78 56 | 79 119 57 | 33 8 58 | 33 32 59 | 33 34 60 | 10 9 61 | 10 11 62 | 10 84 63 | 10 110 64 | 84 9 65 | 84 10 66 | 84 83 67 | 84 85 68 | 11 10 69 | 11 12 70 | 11 110 71 | 110 10 72 | 110 11 73 | 110 111 74 | 110 112 75 | 12 11 76 | 12 13 77 | 12 95 78 | 12 108 79 | 13 12 80 | 13 14 81 | 13 94 82 | 13 95 83 | 108 12 84 | 108 109 85 | 108 113 86 | 108 123 87 | 95 12 88 | 95 13 89 | 95 96 90 | 14 13 91 | 14 15 92 | 14 16 93 | 14 77 94 | 94 13 95 | 94 77 96 | 94 93 97 | 15 14 98 | 16 14 99 | 16 17 100 | 77 14 101 | 77 17 102 | 77 94 103 | 17 16 104 | 17 18 105 | 17 77 106 | 17 3254 107 | 18 17 108 | 18 19 109 | 18 3254 110 | 3254 17 111 | 3254 18 112 | 3254 3255 113 | 3254 36971 114 | 19 18 115 | 19 20 116 | 19 23 117 | 20 19 118 | 20 21 119 | 20 22 120 | 23 19 121 | 23 24 122 | 23 25 123 | 21 20 124 | 22 20 125 | 24 23 126 | 25 23 127 | 25 26 128 | 25 27 129 | 26 25 130 | 27 25 131 | 27 28 132 | 27 29 133 | 28 27 134 | 29 27 135 | 29 30 136 | 29 3255 137 | 30 29 138 | 30 31 139 | 30 3247 140 | 30 3253 141 | 3255 29 142 | 3255 3253 143 | 3255 3254 144 | 3255 35943 145 | 31 30 146 | 31 32 147 | 31 3246 148 | 3247 30 149 | 3247 3248 150 | 3247 3249 151 | 3253 30 152 | 3253 3204 153 | 3253 3255 154 | 3253 35950 155 | 32 31 156 | 32 33 157 | 32 2203 158 | 3246 31 159 | 3246 2203 160 | 3246 3252 161 | 3246 3257 162 | 2203 32 163 | 2203 2146 164 | 2203 2204 165 | 2203 3246 166 | 34 33 167 | 35 36 168 | 35 50 169 | 35 1199 170 | 36 35 171 | 36 37 172 | 36 35885 173 | 36 1645159 174 | 50 35 175 | 50 49 176 | 50 185 177 | 1199 35 178 | 1199 1198 179 | 1199 1205 180 | 37 36 181 | 37 38 182 | 37 1641586 183 | 35885 36 184 | 35885 35884 185 | 35885 1645157 186 | 1645159 36 187 | 1645159 1645156 188 | 1645159 1645157 189 | 1645159 1648644 190 | 38 37 191 | 38 39 192 | 38 1641586 193 | 1641586 37 194 | 1641586 38 195 | 1641586 1633418 196 | 39 38 197 | 39 40 198 | 39 1641587 199 | 40 39 200 | 40 41 201 | 40 1641577 202 | 1641587 39 203 | 1641587 1633418 204 | 1641587 1641576 205 | 1641587 1641606 206 | 41 40 207 | 41 42 208 | 41 1641355 209 | 1641577 40 210 | 1641577 1641363 211 | 1641577 1641576 212 | 42 41 213 | 42 43 214 | 42 1639779 215 | 1641355 41 216 | 1641355 1628954 217 | 1641355 1639780 218 | 1641355 1641363 219 | 43 42 220 | 43 44 221 | 43 1639779 222 | 1639779 42 223 | 1639779 43 224 | 1639779 1639780 225 | 44 43 226 | 44 45 227 | 44 1542024 228 | 45 44 229 | 45 46 230 | 45 1154 231 | 45 1538392 232 | 1542024 44 233 | 1542024 1542023 234 | 1542024 1639781 235 | 46 45 236 | 46 47 237 | 46 27108 238 | 46 27325 239 | 1154 45 240 | 1154 1153 241 | 1154 1155 242 | 1538392 45 243 | 1538392 1538362 244 | 1538392 1538390 245 | 1538392 1538391 246 | 47 46 247 | 47 48 248 | 47 27325 249 | 27108 46 250 | 27108 27107 251 | 27108 27250 252 | 27325 46 253 | 27325 47 254 | 27325 27323 255 | 27325 27335 256 | 48 47 257 | 48 49 258 | 48 27343 259 | 49 48 260 | 49 50 261 | 49 184 262 | 27343 48 263 | 27343 27342 264 | 27343 35887 265 | 27343 39411 266 | 184 49 267 | 184 185 268 | 184 35886 269 | 185 50 270 | 185 184 271 | 185 1198 272 | 52 53 273 | 52 54 274 | 52 4152 275 | 53 52 276 | 53 54 277 | 53 223 278 | 53 225 279 | 54 52 280 | 54 53 281 | 54 4120 282 | 4152 52 283 | 4152 4148 284 | 4152 4153 285 | 4152 4156 286 | 223 53 287 | 223 224 288 | 223 3937 289 | 223 4113 290 | 225 53 291 | 225 224 292 | 225 4114 293 | 225 4148 294 | 4120 54 295 | 4120 3937 296 | 4120 4153 297 | 4120 4154 298 | 55 56 299 | 55 57 300 | 55 1068 301 | 55 1099 302 | 56 55 303 | 56 76 304 | 56 1069 305 | 57 55 306 | 57 58 307 | 57 1071 308 | 57 1072 309 | 1068 55 310 | 1068 1069 311 | 1068 1096 312 | 1068 1116 313 | 1068 36235 314 | 1099 55 315 | 76 56 316 | 76 74 317 | 76 1075 318 | 1069 56 319 | 1069 1068 320 | 1069 1116 321 | 58 57 322 | 58 59 323 | 58 1089 324 | 58 32419 325 | 1072 57 326 | 1072 1070 327 | 1072 32419 328 | 1071 57 329 | 1071 1070 330 | 1071 1098 331 | 1071 1110 332 | 59 58 333 | 59 60 334 | 59 61 335 | 59 62 336 | 1089 58 337 | 1089 62 338 | 1089 171 339 | 1089 172 340 | 32419 58 341 | 32419 1072 342 | 60 59 343 | 61 59 344 | 62 59 345 | 62 63 346 | 62 1089 347 | 63 62 348 | 63 64 349 | 63 339 350 | 64 63 351 | 64 65 352 | 64 2220 353 | 339 63 354 | 339 338 355 | 339 341 356 | 339 36187 357 | 65 64 358 | 65 66 359 | 65 2155 360 | 65 2157 361 | 2220 64 362 | 2220 2219 363 | 2220 2221 364 | 66 65 365 | 66 67 366 | 66 68 367 | 66 2254 368 | 2155 65 369 | 2155 2156 370 | 2155 2254 371 | 2157 65 372 | 2157 2158 373 | 2157 2161 374 | 2157 2219 375 | 67 66 376 | 68 66 377 | 68 69 378 | 68 70 379 | 68 2251 380 | 2254 66 381 | 2254 2155 382 | 2254 2252 383 | 69 68 384 | 70 68 385 | 70 71 386 | 70 1052 387 | 70 2251 388 | 2251 68 389 | 2251 70 390 | 2251 2252 391 | 71 70 392 | 71 72 393 | 71 1049 394 | 1052 70 395 | 1052 1050 396 | 1052 2256 397 | 1052 2258 398 | 72 71 399 | 72 73 400 | 72 74 401 | -------------------------------------------------------------------------------- /apps/connected_components/Makefile: -------------------------------------------------------------------------------- 1 | 2 | TRGS = connected_components_lock connected_components_atomic 3 | 4 | LIBS += -lpthread -lrt 5 | 6 | CXXFLAGS = -g --std=c++0x -O3 7 | CXXFLAGS += -Wall -Werror 8 | 9 | all: $(TRGS) 10 | 11 | connected_components_lock: connected_components_lock.cc 12 | connected_components_atomic: connected_components_atomic.cc 13 | 14 | clean: 15 | rm -f $(TRGS) *.o *.dot 16 | 17 | %: %.cc ; 18 | $(CXX) $(CXXFLAGS) $< -o $@ $(LIBS) 19 | -------------------------------------------------------------------------------- /apps/connected_components/README.md: -------------------------------------------------------------------------------- 1 | Connected Components 2 | ======================= 3 | 4 | Run ```make``` to generate the required executable, then run using the syntax explained below 5 | 6 | The first argument to the executable specifies whether you want to read the graph from a file (1), or generate a synthetic one internally (0). 7 | 8 | **Input Graph from File** 9 | 10 | To run with P number of threads, and an input file of .gr format, 11 | ```./connected_components_lock 1 P ``` 12 | 13 | To run a matrix format file (.mtx) 14 | ```./connected_components_lock 2 P ``` 15 | 16 | The input file can be used as: 17 | sample.txt 18 | OR any other file such as road networks from the SNAP datasets (e.g. A FaceBook Graph) https://snap.stanford.edu/data/ 19 | 20 | **Generate and Input using the Synthetic Graph Generator** 21 | 22 | To run with P number of threads, N vertices, and DEG edges per vertex 23 | ```./connected_components_lock 0 P N DEG``` 24 | 25 | **Notes** 26 | 27 | The executable outputs the time in seconds that the program took to run. 28 | 29 | The file utilizing atomic instructions has the same arguments as specified above. 30 | 31 | A small code snippet getting the total number of unique components is also included. 32 | -------------------------------------------------------------------------------- /apps/connected_components/sample.txt: -------------------------------------------------------------------------------- 1 | # Directed graph (each unordered pair of nodes is saved once): roadNet-CA.txt 2 | # Sample California road network 3 | # Nodes: 1965206 Edges: 5533214 4 | # FromNodeId ToNodeId 5 | 0 1 6 | 0 2 7 | 0 469 8 | 1 0 9 | 1 6 10 | 1 385 11 | 2 0 12 | 2 3 13 | 469 0 14 | 469 380 15 | 469 37415 16 | 6 1 17 | 6 5 18 | 385 1 19 | 385 384 20 | 385 386 21 | 3 2 22 | 3 4 23 | 3 419 24 | 3 422 25 | 4 3 26 | 4 5 27 | 4 98 28 | 4 420 29 | 419 3 30 | 419 420 31 | 419 35698 32 | 422 3 33 | 422 183 34 | 422 423 35 | 422 37415 36 | 5 4 37 | 5 6 38 | 5 98 39 | 98 4 40 | 98 5 41 | 98 470 42 | 98 35729 43 | 420 4 44 | 420 419 45 | 420 35709 46 | 7 8 47 | 7 9 48 | 7 79 49 | 8 7 50 | 8 33 51 | 9 7 52 | 9 10 53 | 9 84 54 | 79 7 55 | 79 78 56 | 79 119 57 | 33 8 58 | 33 32 59 | 33 34 60 | 10 9 61 | 10 11 62 | 10 84 63 | 10 110 64 | 84 9 65 | 84 10 66 | 84 83 67 | 84 85 68 | 11 10 69 | 11 12 70 | 11 110 71 | 110 10 72 | 110 11 73 | 110 111 74 | 110 112 75 | 12 11 76 | 12 13 77 | 12 95 78 | 12 108 79 | 13 12 80 | 13 14 81 | 13 94 82 | 13 95 83 | 108 12 84 | 108 109 85 | 108 113 86 | 108 123 87 | 95 12 88 | 95 13 89 | 95 96 90 | 14 13 91 | 14 15 92 | 14 16 93 | 14 77 94 | 94 13 95 | 94 77 96 | 94 93 97 | 15 14 98 | 16 14 99 | 16 17 100 | 77 14 101 | 77 17 102 | 77 94 103 | 17 16 104 | 17 18 105 | 17 77 106 | 17 3254 107 | 18 17 108 | 18 19 109 | 18 3254 110 | 3254 17 111 | 3254 18 112 | 3254 3255 113 | 3254 36971 114 | 19 18 115 | 19 20 116 | 19 23 117 | 20 19 118 | 20 21 119 | 20 22 120 | 23 19 121 | 23 24 122 | 23 25 123 | 21 20 124 | 22 20 125 | 24 23 126 | 25 23 127 | 25 26 128 | 25 27 129 | 26 25 130 | 27 25 131 | 27 28 132 | 27 29 133 | 28 27 134 | 29 27 135 | 29 30 136 | 29 3255 137 | 30 29 138 | 30 31 139 | 30 3247 140 | 30 3253 141 | 3255 29 142 | 3255 3253 143 | 3255 3254 144 | 3255 35943 145 | 31 30 146 | 31 32 147 | 31 3246 148 | 3247 30 149 | 3247 3248 150 | 3247 3249 151 | 3253 30 152 | 3253 3204 153 | 3253 3255 154 | 3253 35950 155 | 32 31 156 | 32 33 157 | 32 2203 158 | 3246 31 159 | 3246 2203 160 | 3246 3252 161 | 3246 3257 162 | 2203 32 163 | 2203 2146 164 | 2203 2204 165 | 2203 3246 166 | 34 33 167 | 35 36 168 | 35 50 169 | 35 1199 170 | 36 35 171 | 36 37 172 | 36 35885 173 | 36 1645159 174 | 50 35 175 | 50 49 176 | 50 185 177 | 1199 35 178 | 1199 1198 179 | 1199 1205 180 | 37 36 181 | 37 38 182 | 37 1641586 183 | 35885 36 184 | 35885 35884 185 | 35885 1645157 186 | 1645159 36 187 | 1645159 1645156 188 | 1645159 1645157 189 | 1645159 1648644 190 | 38 37 191 | 38 39 192 | 38 1641586 193 | 1641586 37 194 | 1641586 38 195 | 1641586 1633418 196 | 39 38 197 | 39 40 198 | 39 1641587 199 | 40 39 200 | 40 41 201 | 40 1641577 202 | 1641587 39 203 | 1641587 1633418 204 | 1641587 1641576 205 | 1641587 1641606 206 | 41 40 207 | 41 42 208 | 41 1641355 209 | 1641577 40 210 | 1641577 1641363 211 | 1641577 1641576 212 | 42 41 213 | 42 43 214 | 42 1639779 215 | 1641355 41 216 | 1641355 1628954 217 | 1641355 1639780 218 | 1641355 1641363 219 | 43 42 220 | 43 44 221 | 43 1639779 222 | 1639779 42 223 | 1639779 43 224 | 1639779 1639780 225 | 44 43 226 | 44 45 227 | 44 1542024 228 | 45 44 229 | 45 46 230 | 45 1154 231 | 45 1538392 232 | 1542024 44 233 | 1542024 1542023 234 | 1542024 1639781 235 | 46 45 236 | 46 47 237 | 46 27108 238 | 46 27325 239 | 1154 45 240 | 1154 1153 241 | 1154 1155 242 | 1538392 45 243 | 1538392 1538362 244 | 1538392 1538390 245 | 1538392 1538391 246 | 47 46 247 | 47 48 248 | 47 27325 249 | 27108 46 250 | 27108 27107 251 | 27108 27250 252 | 27325 46 253 | 27325 47 254 | 27325 27323 255 | 27325 27335 256 | 48 47 257 | 48 49 258 | 48 27343 259 | 49 48 260 | 49 50 261 | 49 184 262 | 27343 48 263 | 27343 27342 264 | 27343 35887 265 | 27343 39411 266 | 184 49 267 | 184 185 268 | 184 35886 269 | 185 50 270 | 185 184 271 | 185 1198 272 | 52 53 273 | 52 54 274 | 52 4152 275 | 53 52 276 | 53 54 277 | 53 223 278 | 53 225 279 | 54 52 280 | 54 53 281 | 54 4120 282 | 4152 52 283 | 4152 4148 284 | 4152 4153 285 | 4152 4156 286 | 223 53 287 | 223 224 288 | 223 3937 289 | 223 4113 290 | 225 53 291 | 225 224 292 | 225 4114 293 | 225 4148 294 | 4120 54 295 | 4120 3937 296 | 4120 4153 297 | 4120 4154 298 | 55 56 299 | 55 57 300 | 55 1068 301 | 55 1099 302 | 56 55 303 | 56 76 304 | 56 1069 305 | 57 55 306 | 57 58 307 | 57 1071 308 | 57 1072 309 | 1068 55 310 | 1068 1069 311 | 1068 1096 312 | 1068 1116 313 | 1068 36235 314 | 1099 55 315 | 76 56 316 | 76 74 317 | 76 1075 318 | 1069 56 319 | 1069 1068 320 | 1069 1116 321 | 58 57 322 | 58 59 323 | 58 1089 324 | 58 32419 325 | 1072 57 326 | 1072 1070 327 | 1072 32419 328 | 1071 57 329 | 1071 1070 330 | 1071 1098 331 | 1071 1110 332 | 59 58 333 | 59 60 334 | 59 61 335 | 59 62 336 | 1089 58 337 | 1089 62 338 | 1089 171 339 | 1089 172 340 | 32419 58 341 | 32419 1072 342 | 60 59 343 | 61 59 344 | 62 59 345 | 62 63 346 | 62 1089 347 | 63 62 348 | 63 64 349 | 63 339 350 | 64 63 351 | 64 65 352 | 64 2220 353 | 339 63 354 | 339 338 355 | 339 341 356 | 339 36187 357 | 65 64 358 | 65 66 359 | 65 2155 360 | 65 2157 361 | 2220 64 362 | 2220 2219 363 | 2220 2221 364 | 66 65 365 | 66 67 366 | 66 68 367 | 66 2254 368 | 2155 65 369 | 2155 2156 370 | 2155 2254 371 | 2157 65 372 | 2157 2158 373 | 2157 2161 374 | 2157 2219 375 | 67 66 376 | 68 66 377 | 68 69 378 | 68 70 379 | 68 2251 380 | 2254 66 381 | 2254 2155 382 | 2254 2252 383 | 69 68 384 | 70 68 385 | 70 71 386 | 70 1052 387 | 70 2251 388 | 2251 68 389 | 2251 70 390 | 2251 2252 391 | 71 70 392 | 71 72 393 | 71 1049 394 | 1052 70 395 | 1052 1050 396 | 1052 2256 397 | 1052 2258 398 | 72 71 399 | 72 73 400 | 72 74 401 | -------------------------------------------------------------------------------- /apps/dfs/Makefile: -------------------------------------------------------------------------------- 1 | 2 | TRGS = dfs 3 | 4 | LIBS += -lpthread -lrt 5 | 6 | CXXFLAGS = -g --std=c++0x -O3 7 | CXXFLAGS += -Wall -Werror 8 | 9 | all: $(TRGS) 10 | 11 | dfs: dfs.cc 12 | 13 | clean: 14 | rm -f $(TRGS) *.o *.dot 15 | 16 | %: %.cc ; 17 | $(CXX) $(CXXFLAGS) $< -o $@ $(LIBS) 18 | -------------------------------------------------------------------------------- /apps/dfs/README.md: -------------------------------------------------------------------------------- 1 | Depth First Search 2 | ================== 3 | 4 | Run ```make``` to generate the required executable, then run using the syntax explained below 5 | 6 | To run with P number of threads, and an input file 7 | ```./dfs P ``` 8 | 9 | The input file can be used as: 10 | sample.txt 11 | OR any other file such as road networks from the SNAP datasets (e.g. A FaceBook Graph) 12 | https://snap.stanford.edu/data/ 13 | 14 | **Notes** 15 | 16 | The executable then outputs the time in seconds that the program took to run. 17 | -------------------------------------------------------------------------------- /apps/dfs/dfs.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Distributed Under the MIT license 3 | Uses vertex coloring to distinguish searches 4 | Programs by Masab Ahmad (UConn) 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | //#include "carbon_user.h" /* For the Graphite Simulator*/ 11 | #include 12 | #include 13 | 14 | #define MAX 100000000 15 | #define INT_MAX 100000000 16 | // #define DEBUG 1 17 | #define BILLION 1E9 18 | 19 | //Thread Argument Structure 20 | typedef struct 21 | { 22 | int* local_min; 23 | int* global_min; 24 | int* Q; 25 | //int* D; 26 | //int** W; 27 | int** W_index; 28 | int* d_count; 29 | int tid; 30 | int P; 31 | int N; 32 | int DEG; 33 | pthread_barrier_t* barrier_total; 34 | pthread_barrier_t* barrier; 35 | } thread_arg_t; 36 | 37 | //Function Initializers 38 | int initialize_single_source(int* D, int* Q, int source, int N); 39 | void init_weights(int N, int DEG, int** W, int** W_index); 40 | 41 | //Global Variables 42 | pthread_mutex_t lock; //single lock 43 | pthread_mutex_t locks[4194304]; //locks for each vertes, upper limit 44 | int local_min_buffer[1024]; 45 | int global_min_buffer; 46 | int Total = 0; 47 | int terminate = 0; //work termination 48 | int P_global = 256; 49 | int *edges; //deg of a given vertex 50 | int *exist; //whether vertex in graph 51 | int *temporary; 52 | int largest=0; 53 | int avg_deg = 0; 54 | thread_arg_t thread_arg[1024]; 55 | pthread_t thread_handle[1024]; 56 | 57 | //Primary Parallel Function 58 | void* do_work(void* args) 59 | { 60 | //Thread variables and arguments 61 | volatile thread_arg_t* arg = (thread_arg_t*) args; 62 | int tid = arg->tid; //thread id 63 | int P = arg->P; //Max threads 64 | volatile int* Q = arg->Q; //set/unset array 65 | //int* D = arg->D; //coloring array 66 | //int** W = arg->W; 67 | int** W_index = arg->W_index; //graph structure 68 | int v = 0; 69 | int vv=0; 70 | //int iter = 0; 71 | int ptr=0; //ptr for the disjoint stack 72 | double P_d = P; 73 | double tid_d = tid; 74 | double largest_d = largest+1.0; 75 | 76 | int start = 0; //tid * DEG / (arg->P); 77 | int stop = 0; //(tid+1) * DEG / (arg->P); 78 | 79 | //Partition data into threads via double precision 80 | double start_d = (tid_d) * (largest_d/P_d); 81 | double stop_d = (tid_d+1.0) * (largest_d/P_d); 82 | start = start_d; //tid * (largest+1) / (P); 83 | stop = stop_d; //(tid+1) * (largest+1) / (P); 84 | //printf("\n tid:%d %d %d",tid,start,stop); 85 | 86 | int *stack; 87 | if(posix_memalign((void**) &stack, 64, (((largest+1)/P) + 1) * sizeof(int))) 88 | { 89 | fprintf(stderr, "Allocation of memory failed\n"); 90 | exit(EXIT_FAILURE); 91 | } 92 | //int a = posix_memalign((void**) &stack, 64, (largest+1/P) * sizeof(int)); 93 | stack[ptr] = start; 94 | int disjoint = start; 95 | ptr++; 96 | 97 | //pthread_barrier_wait(arg->barrier_total); 98 | 99 | for(vv=start;vv0) 102 | { 103 | ptr--; 104 | v = stack[ptr]; 105 | } 106 | else 107 | { 108 | disjoint++; 109 | v = disjoint; 110 | }//printf("\n %d",v); 111 | 112 | if(exist[v]==0) 113 | continue; //if not in graph 114 | pthread_mutex_lock(&locks[v]); 115 | if(Q[v]==1) //if unset then set 116 | Q[v]=0; 117 | pthread_mutex_unlock(&locks[v]); 118 | 119 | for(int i = 0; i < edges[v]; i++) 120 | { 121 | int neighbor = W_index[v][i]; 122 | 123 | if(Q[neighbor]==0) 124 | continue; 125 | 126 | stack[ptr] = neighbor; 127 | if(ptr<((largest+1)/P)) 128 | ptr++; 129 | } 130 | } 131 | //pthread_barrier_wait(arg->barrier_total); 132 | 133 | return NULL; 134 | } 135 | 136 | //Main 137 | int main(int argc, char** argv) 138 | { 139 | FILE *file0 = NULL; 140 | int N = 0; 141 | int DEG = 0; 142 | //whether read from file or generate synthetic 143 | const int select = atoi(argv[1]); 144 | 145 | //if reading from file 146 | if(select==1) 147 | { 148 | const char *filename = argv[3]; 149 | //printf("Please Enter The Name Of The File You Would Like To Fetch\n"); 150 | //scanf("%s", filename); 151 | file0 = fopen(filename,"r"); 152 | } 153 | 154 | int lines_to_check=0; 155 | char c; 156 | int number0; 157 | int number1; 158 | int inter = -1; 159 | 160 | if(select==1) 161 | { 162 | N = 2097152; //can be read from file if needed, this is a default upper limit 163 | DEG = 16; //also can be reda from file if needed, upper limit here again 164 | } 165 | 166 | //Max input threads 167 | const int P1 = atoi(argv[2]); 168 | 169 | int P = P1; 170 | P_global = P1; 171 | 172 | //If generating a uniform random graph 173 | if(select==0) 174 | { 175 | N = atoi(argv[3]); 176 | DEG = atoi(argv[4]); avg_deg = DEG; 177 | printf("\nGraph with Parameters: N:%d DEG:%d\n",N,DEG); 178 | } 179 | 180 | if (DEG > N) 181 | { 182 | fprintf(stderr, "Degree of graph cannot be grater than number of Vertices\n"); 183 | exit(EXIT_FAILURE); 184 | } 185 | 186 | //Memory Allocations 187 | int* D; 188 | int* Q; 189 | if(posix_memalign((void**) &D, 64, N * sizeof(int))) 190 | { 191 | fprintf(stderr, "Allocation of memory failed\n"); 192 | exit(EXIT_FAILURE); 193 | } 194 | if(posix_memalign((void**) &Q, 64, N * sizeof(int))) 195 | { 196 | fprintf(stderr, "Allocation of memory failed\n"); 197 | exit(EXIT_FAILURE); 198 | } 199 | if(posix_memalign((void**) &edges, 64, N * sizeof(int))) 200 | { 201 | fprintf(stderr, "Allocation of memory failed\n"); 202 | exit(EXIT_FAILURE); 203 | } 204 | if(posix_memalign((void**) &exist, 64, N * sizeof(int))) 205 | { 206 | fprintf(stderr, "Allocation of memory failed\n"); 207 | exit(EXIT_FAILURE); 208 | } 209 | if(posix_memalign((void**) &temporary, 64, N * sizeof(int))) 210 | { 211 | fprintf(stderr, "Allocation of memory failed\n"); 212 | exit(EXIT_FAILURE); 213 | } 214 | int d_count = N; 215 | pthread_barrier_t barrier_total; 216 | pthread_barrier_t barrier; 217 | 218 | int** W = (int**) malloc(N*sizeof(int*)); 219 | int** W_index = (int**) malloc(N*sizeof(int*)); 220 | for(int i = 0; i < N; i++) 221 | { 222 | //W[i] = (int *)malloc(sizeof(int)*N); 223 | if(posix_memalign((void**) &W[i], 64, DEG*sizeof(int))) 224 | { 225 | fprintf(stderr, "Allocation of memory failed\n"); 226 | exit(EXIT_FAILURE); 227 | } 228 | if(posix_memalign((void**) &W_index[i], 64, DEG*sizeof(int))) 229 | { 230 | fprintf(stderr, "Allocation of memory failed\n"); 231 | exit(EXIT_FAILURE); 232 | } 233 | } 234 | 235 | //Memory initialization 236 | for(int i=0;i3) 257 | { 258 | int f0 = fscanf(file0, "%d %d", &number0,&number1); 259 | if(f0 != 2 && f0 != EOF) 260 | { 261 | printf ("Error: Read %d values, expected 2. Parsing failed.\n",f0); 262 | exit (EXIT_FAILURE); 263 | } 264 | //printf("\n%d %d",number0,number1); 265 | if(number0>largest) 266 | largest=number0; 267 | if(number1>largest) 268 | largest=number1; 269 | inter = edges[number0]; 270 | 271 | //W[number0][inter] = drand48(); 272 | W_index[number0][inter] = number1; 273 | //previous_node = number0; 274 | edges[number0]++; 275 | exist[number0]=1; exist[number1]=1; 276 | } 277 | } 278 | //printf("\n%d deg:%d",test[0]); 279 | printf("\nFile Read, Largest Vertex:%d",largest); 280 | } 281 | 282 | //Generate Random graph 283 | if(select==0) 284 | { 285 | init_weights(N, DEG, W, W_index); 286 | largest = N-1; //largest vertex id 287 | } 288 | 289 | //Synchronization variables 290 | pthread_barrier_init(&barrier_total, NULL, P); 291 | pthread_barrier_init(&barrier, NULL, P); 292 | 293 | pthread_mutex_init(&lock, NULL); 294 | 295 | for(int i=0; i last) 404 | { 405 | W_index[i][j] = neighbor; 406 | last = W_index[i][j]; 407 | } 408 | else 409 | { 410 | if(last < (N-1)) 411 | { 412 | W_index[i][j] = (last + 1); 413 | last = W_index[i][j]; 414 | } 415 | }*/ 416 | } 417 | /*else 418 | { 419 | last = W_index[i][j]; 420 | }*/ 421 | if(W_index[i][j]>=N) 422 | { 423 | W_index[i][j] = N-1; 424 | } 425 | } 426 | } 427 | 428 | // Populate Cost Array 429 | for(int i = 0; i < N; i++) 430 | { 431 | for(int j = 0; j < DEG; j++) 432 | { 433 | double v = drand48(); 434 | /*if(v > 0.8 || W_index[i][j] == -1) 435 | { W[i][j] = MAX; 436 | W_index[i][j] = -1; 437 | } 438 | 439 | else*/ if(W_index[i][j] == i) 440 | W[i][j] = 0; 441 | 442 | else 443 | W[i][j] = (int) (v*100) + 1; 444 | //printf(" %d ",W_index[i][j]); 445 | } 446 | //printf("\n"); 447 | } 448 | } 449 | -------------------------------------------------------------------------------- /apps/dfs/sample.txt: -------------------------------------------------------------------------------- 1 | # Directed graph (each unordered pair of nodes is saved once): roadNet-CA.txt 2 | # Sample California road network 3 | # Nodes: 1965206 Edges: 5533214 4 | # FromNodeId ToNodeId 5 | 0 1 6 | 0 2 7 | 0 469 8 | 1 0 9 | 1 6 10 | 1 385 11 | 2 0 12 | 2 3 13 | 469 0 14 | 469 380 15 | 469 37415 16 | 6 1 17 | 6 5 18 | 385 1 19 | 385 384 20 | 385 386 21 | 3 2 22 | 3 4 23 | 3 419 24 | 3 422 25 | 4 3 26 | 4 5 27 | 4 98 28 | 4 420 29 | 419 3 30 | 419 420 31 | 419 35698 32 | 422 3 33 | 422 183 34 | 422 423 35 | 422 37415 36 | 5 4 37 | 5 6 38 | 5 98 39 | 98 4 40 | 98 5 41 | 98 470 42 | 98 35729 43 | 420 4 44 | 420 419 45 | 420 35709 46 | 7 8 47 | 7 9 48 | 7 79 49 | 8 7 50 | 8 33 51 | 9 7 52 | 9 10 53 | 9 84 54 | 79 7 55 | 79 78 56 | 79 119 57 | 33 8 58 | 33 32 59 | 33 34 60 | 10 9 61 | 10 11 62 | 10 84 63 | 10 110 64 | 84 9 65 | 84 10 66 | 84 83 67 | 84 85 68 | 11 10 69 | 11 12 70 | 11 110 71 | 110 10 72 | 110 11 73 | 110 111 74 | 110 112 75 | 12 11 76 | 12 13 77 | 12 95 78 | 12 108 79 | 13 12 80 | 13 14 81 | 13 94 82 | 13 95 83 | 108 12 84 | 108 109 85 | 108 113 86 | 108 123 87 | 95 12 88 | 95 13 89 | 95 96 90 | 14 13 91 | 14 15 92 | 14 16 93 | 14 77 94 | 94 13 95 | 94 77 96 | 94 93 97 | 15 14 98 | 16 14 99 | 16 17 100 | 77 14 101 | 77 17 102 | 77 94 103 | 17 16 104 | 17 18 105 | 17 77 106 | 17 3254 107 | 18 17 108 | 18 19 109 | 18 3254 110 | 3254 17 111 | 3254 18 112 | 3254 3255 113 | 3254 36971 114 | 19 18 115 | 19 20 116 | 19 23 117 | 20 19 118 | 20 21 119 | 20 22 120 | 23 19 121 | 23 24 122 | 23 25 123 | 21 20 124 | 22 20 125 | 24 23 126 | 25 23 127 | 25 26 128 | 25 27 129 | 26 25 130 | 27 25 131 | 27 28 132 | 27 29 133 | 28 27 134 | 29 27 135 | 29 30 136 | 29 3255 137 | 30 29 138 | 30 31 139 | 30 3247 140 | 30 3253 141 | 3255 29 142 | 3255 3253 143 | 3255 3254 144 | 3255 35943 145 | 31 30 146 | 31 32 147 | 31 3246 148 | 3247 30 149 | 3247 3248 150 | 3247 3249 151 | 3253 30 152 | 3253 3204 153 | 3253 3255 154 | 3253 35950 155 | 32 31 156 | 32 33 157 | 32 2203 158 | 3246 31 159 | 3246 2203 160 | 3246 3252 161 | 3246 3257 162 | 2203 32 163 | 2203 2146 164 | 2203 2204 165 | 2203 3246 166 | 34 33 167 | 35 36 168 | 35 50 169 | 35 1199 170 | 36 35 171 | 36 37 172 | 36 35885 173 | 36 1645159 174 | 50 35 175 | 50 49 176 | 50 185 177 | 1199 35 178 | 1199 1198 179 | 1199 1205 180 | 37 36 181 | 37 38 182 | 37 1641586 183 | 35885 36 184 | 35885 35884 185 | 35885 1645157 186 | 1645159 36 187 | 1645159 1645156 188 | 1645159 1645157 189 | 1645159 1648644 190 | 38 37 191 | 38 39 192 | 38 1641586 193 | 1641586 37 194 | 1641586 38 195 | 1641586 1633418 196 | 39 38 197 | 39 40 198 | 39 1641587 199 | 40 39 200 | 40 41 201 | 40 1641577 202 | 1641587 39 203 | 1641587 1633418 204 | 1641587 1641576 205 | 1641587 1641606 206 | 41 40 207 | 41 42 208 | 41 1641355 209 | 1641577 40 210 | 1641577 1641363 211 | 1641577 1641576 212 | 42 41 213 | 42 43 214 | 42 1639779 215 | 1641355 41 216 | 1641355 1628954 217 | 1641355 1639780 218 | 1641355 1641363 219 | 43 42 220 | 43 44 221 | 43 1639779 222 | 1639779 42 223 | 1639779 43 224 | 1639779 1639780 225 | 44 43 226 | 44 45 227 | 44 1542024 228 | 45 44 229 | 45 46 230 | 45 1154 231 | 45 1538392 232 | 1542024 44 233 | 1542024 1542023 234 | 1542024 1639781 235 | 46 45 236 | 46 47 237 | 46 27108 238 | 46 27325 239 | 1154 45 240 | 1154 1153 241 | 1154 1155 242 | 1538392 45 243 | 1538392 1538362 244 | 1538392 1538390 245 | 1538392 1538391 246 | 47 46 247 | 47 48 248 | 47 27325 249 | 27108 46 250 | 27108 27107 251 | 27108 27250 252 | 27325 46 253 | 27325 47 254 | 27325 27323 255 | 27325 27335 256 | 48 47 257 | 48 49 258 | 48 27343 259 | 49 48 260 | 49 50 261 | 49 184 262 | 27343 48 263 | 27343 27342 264 | 27343 35887 265 | 27343 39411 266 | 184 49 267 | 184 185 268 | 184 35886 269 | 185 50 270 | 185 184 271 | 185 1198 272 | 52 53 273 | 52 54 274 | 52 4152 275 | 53 52 276 | 53 54 277 | 53 223 278 | 53 225 279 | 54 52 280 | 54 53 281 | 54 4120 282 | 4152 52 283 | 4152 4148 284 | 4152 4153 285 | 4152 4156 286 | 223 53 287 | 223 224 288 | 223 3937 289 | 223 4113 290 | 225 53 291 | 225 224 292 | 225 4114 293 | 225 4148 294 | 4120 54 295 | 4120 3937 296 | 4120 4153 297 | 4120 4154 298 | 55 56 299 | 55 57 300 | 55 1068 301 | 55 1099 302 | 56 55 303 | 56 76 304 | 56 1069 305 | 57 55 306 | 57 58 307 | 57 1071 308 | 57 1072 309 | 1068 55 310 | 1068 1069 311 | 1068 1096 312 | 1068 1116 313 | 1068 36235 314 | 1099 55 315 | 76 56 316 | 76 74 317 | 76 1075 318 | 1069 56 319 | 1069 1068 320 | 1069 1116 321 | 58 57 322 | 58 59 323 | 58 1089 324 | 58 32419 325 | 1072 57 326 | 1072 1070 327 | 1072 32419 328 | 1071 57 329 | 1071 1070 330 | 1071 1098 331 | 1071 1110 332 | 59 58 333 | 59 60 334 | 59 61 335 | 59 62 336 | 1089 58 337 | 1089 62 338 | 1089 171 339 | 1089 172 340 | 32419 58 341 | 32419 1072 342 | 60 59 343 | 61 59 344 | 62 59 345 | 62 63 346 | 62 1089 347 | 63 62 348 | 63 64 349 | 63 339 350 | 64 63 351 | 64 65 352 | 64 2220 353 | 339 63 354 | 339 338 355 | 339 341 356 | 339 36187 357 | 65 64 358 | 65 66 359 | 65 2155 360 | 65 2157 361 | 2220 64 362 | 2220 2219 363 | 2220 2221 364 | 66 65 365 | 66 67 366 | 66 68 367 | 66 2254 368 | 2155 65 369 | 2155 2156 370 | 2155 2254 371 | 2157 65 372 | 2157 2158 373 | 2157 2161 374 | 2157 2219 375 | 67 66 376 | 68 66 377 | 68 69 378 | 68 70 379 | 68 2251 380 | 2254 66 381 | 2254 2155 382 | 2254 2252 383 | 69 68 384 | 70 68 385 | 70 71 386 | 70 1052 387 | 70 2251 388 | 2251 68 389 | 2251 70 390 | 2251 2252 391 | 71 70 392 | 71 72 393 | 71 1049 394 | 1052 70 395 | 1052 1050 396 | 1052 2256 397 | 1052 2258 398 | 72 71 399 | 72 73 400 | 72 74 401 | -------------------------------------------------------------------------------- /apps/pagerank/Makefile: -------------------------------------------------------------------------------- 1 | 2 | TRGS = pagerank pagerank_lock 3 | 4 | LIBS += -lpthread -lrt 5 | 6 | CXXFLAGS = -g --std=c++0x -O3 7 | CXXFLAGS += -Wall -Werror 8 | 9 | all: $(TRGS) 10 | 11 | pagerank: pagerank.cc 12 | pagerank_lock: pagerank_lock.cc 13 | 14 | clean: 15 | rm -f $(TRGS) *.o *.dot 16 | rm -f file.txt 17 | 18 | %: %.cc ; 19 | $(CXX) $(CXXFLAGS) $< -o $@ $(LIBS) 20 | -------------------------------------------------------------------------------- /apps/pagerank/README.md: -------------------------------------------------------------------------------- 1 | PageRank 2 | ======== 3 | 4 | Run ```make``` to generate executables, then use the syntax explained below 5 | 6 | The first argument to the executable specifies whether you want to read the graph from a file (1), or generate a synthetic one internally (0). 7 | 8 | **Input Graph from File** 9 | 10 | To run with P number of threads, and an input file, 11 | ```./pagerank 1 P ``` 12 | 13 | It will then ask for the input file, enter: 14 | sample.txt 15 | OR any other file such as road networks from the SNAP datasets (e.g. A FaceBook Graph) 16 | https://snap.stanford.edu/data/ 17 | 18 | **Generate and Input using the Synthetic Graph Generator** 19 | 20 | To run with P number of threads, N vertices, and DEG edges per vertex 21 | ```./pagerank 0 P N DEG``` 22 | 23 | **Notes** 24 | 25 | The executable then outputs the time in seconds that the program took to run. 26 | It also outputs a file that contains the pageranks (normalized to 1). 27 | 28 | ```pagerank_lock.cc``` updates dangling page values via locks instead of using a distributed data structure. This is meant for architectural simulation works trying to improve lock accesses. 29 | 30 | Some very small differences in pageranks might occur due to floating point round offs within the program. 31 | -------------------------------------------------------------------------------- /apps/pagerank/pagerank.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | //#include "carbon_user.h" /*For the Graphite Simulator*/ 5 | #include 6 | #include 7 | #include 8 | 9 | #define MAX 100000000 10 | #define INT_MAX 100000000 11 | #define BILLION 1E9 12 | 13 | //Thread Structure 14 | typedef struct 15 | { 16 | int* local_min; 17 | int* global_min; 18 | int* Q; 19 | double* PR; 20 | double** W; 21 | int** W_index; 22 | int tid; 23 | int P; 24 | int N; 25 | int DEG; 26 | pthread_barrier_t* barrier; 27 | } thread_arg_t; 28 | 29 | //Global Variables 30 | pthread_mutex_t lock; //single lock 31 | pthread_mutex_t locks[4194304]; //upper limit for locks, can be increased 32 | int local_min_buffer[1024]; 33 | double dp_tid[1024]; //dangling pages for each thread, reduced later by locks 34 | int global_min_buffer; 35 | int terminate = 0; //terminate variable 36 | int *test; //test variable arrays for graph storage 37 | int *exist; 38 | int *test2; 39 | int *dangling; 40 | int *outlinks; //array for outlinks 41 | double dp = 0; //dangling pointer variable 42 | double *pgtmp; //temporary pageranks 43 | int nodecount = 0; 44 | thread_arg_t thread_arg[1024]; //MAX threads 45 | pthread_t thread_handle[1024]; //pthread handlers 46 | 47 | //Function declarations 48 | int initialize_single_source(double* PR, int* Q, int source, int N, double initial_rank); 49 | void init_weights(int N, int DEG, double** W, int** W_index); 50 | 51 | //Primary Parallel Function 52 | void* do_work(void* args) 53 | { 54 | volatile thread_arg_t* arg = (thread_arg_t*) args; 55 | int tid = arg->tid; 56 | double* PR = arg->PR; 57 | int** W_index = arg->W_index; 58 | const int N = arg->N; 59 | int v = 0; //variable for current vertex 60 | double r = 0.15; //damping coefficient 61 | double d = 0.85; //damping coefficient 62 | double N_real = N; 63 | double tid_d = tid; 64 | double P_d = arg->P; 65 | 66 | //Allocate work among threads 67 | double start_d = (tid_d) * (N_real/P_d); 68 | double stop_d = (tid_d+1.0) * (N_real/P_d); 69 | int i_start = start_d;// tid * N / (arg->P); 70 | int i_stop = stop_d;// (tid+1) * N / (arg->P); 71 | 72 | //Pagerank iteration count 73 | int iterations = 1; 74 | 75 | //Barrier before starting work 76 | pthread_barrier_wait(arg->barrier); 77 | 78 | while(iterations>0) 79 | { 80 | if(tid==0) 81 | dp=0; 82 | pthread_barrier_wait(arg->barrier); 83 | 84 | //for no outlinks, dangling pages calculation 85 | for(v=i_start;vbarrier); 99 | 100 | v=0; 101 | 102 | //Calculate Pageranks 103 | for(v=i_start;v=1.0) 117 | pgtmp[v] = 1.0; 118 | } 119 | //printf("\n Ranks done"); 120 | 121 | pthread_barrier_wait(arg->barrier); 122 | 123 | //Put temporary pageranks into final pageranks 124 | for(v=i_start;vbarrier); 134 | iterations--; 135 | } 136 | 137 | //printf("\n %d %d",tid,terminate); 138 | return NULL; 139 | } 140 | 141 | 142 | //Main 143 | int main(int argc, char** argv) 144 | { 145 | 146 | FILE *file0 = NULL; 147 | FILE *f = NULL; 148 | int N = 0; //Total vertices 149 | int DEG = 0; //Edges per vertex 150 | const int select = atoi(argv[1]); //0 for synthetic, 1 for file read 151 | char filename[100]; 152 | 153 | //For graph through file input 154 | if(select==1) 155 | { 156 | //printf("Please Enter The Name Of The File You Would Like To Fetch\n"); 157 | //scanf("%s", filename); 158 | strcpy(filename,argv[3]); 159 | //filename = argv[2]; 160 | f = fopen(filename,"r"); 161 | } 162 | 163 | int lines_to_check=0; //file processing variables 164 | char c; 165 | int number0; 166 | int number1; 167 | int inter = -1; 168 | 169 | //For graph through file input, upper limits 170 | if(select==1) 171 | { 172 | N = 2097152; //4194304; //can be read from file if needed, this is a default upper limit 173 | DEG = 16; //also can be reda from file if needed, upper limit here again 174 | } 175 | 176 | const int P = atoi(argv[2]); //number of threads 177 | if(select==0) 178 | { 179 | N = atoi(argv[3]); 180 | DEG = atoi(argv[4]); 181 | printf("\nGraph with Parameters: N:%d DEG:%d\n",N,DEG); 182 | } 183 | 184 | if (DEG > N) 185 | { 186 | fprintf(stderr, "Degree of graph cannot be grater than number of Vertices\n"); 187 | exit(EXIT_FAILURE); 188 | } 189 | 190 | //Memory allocations 191 | double* PR; 192 | int* Q; 193 | if(posix_memalign((void**) &PR, 64, N * sizeof(double))) 194 | { 195 | fprintf(stderr, "Allocation of memory failed\n"); 196 | exit(EXIT_FAILURE); 197 | } 198 | if(posix_memalign((void**) &Q, 64, N * sizeof(int))) 199 | { 200 | fprintf(stderr, "Allocation of memory failed\n"); 201 | exit(EXIT_FAILURE); 202 | } 203 | if(posix_memalign((void**) &test, 64, N * sizeof(int))) 204 | { 205 | fprintf(stderr, "Allocation of memory failed\n"); 206 | exit(EXIT_FAILURE); 207 | } 208 | if(posix_memalign((void**) &exist, 64, N * sizeof(int))) 209 | { 210 | fprintf(stderr, "Allocation of memory failed\n"); 211 | exit(EXIT_FAILURE); 212 | } 213 | if(posix_memalign((void**) &test2, 64, N * sizeof(int))) 214 | { 215 | fprintf(stderr, "Allocation of memory failed\n"); 216 | exit(EXIT_FAILURE); 217 | } 218 | if(posix_memalign((void**) &dangling, 64, N * sizeof(int))) 219 | { 220 | fprintf(stderr, "Allocation of memory failed\n"); 221 | exit(EXIT_FAILURE); 222 | } 223 | if(posix_memalign((void**) &pgtmp, 64, N * sizeof(double))) 224 | { 225 | fprintf(stderr, "Allocation of memory failed\n"); 226 | exit(EXIT_FAILURE); 227 | } 228 | if(posix_memalign((void**) &outlinks, 64, N * sizeof(int))) 229 | { 230 | fprintf(stderr, "Allocation of memory failed\n"); 231 | exit(EXIT_FAILURE); 232 | } 233 | pthread_barrier_t barrier; 234 | 235 | double** W = (double**) malloc(N*sizeof(double*)); 236 | int** W_index = (int**) malloc(N*sizeof(int*)); 237 | for(int i = 0; i < N; i++) 238 | { 239 | //W[i] = (int *)malloc(sizeof(int)*N); 240 | int ret = posix_memalign((void**) &W[i], 64, DEG*sizeof(double)); 241 | int re1 = posix_memalign((void**) &W_index[i], 64, DEG*sizeof(int)); 242 | if (ret != 0 || re1!=0) 243 | { 244 | fprintf(stderr, "Could not allocate memory\n"); 245 | exit(EXIT_FAILURE); 246 | } 247 | } 248 | 249 | //Memory initialization 250 | for(int i=0;i3 && lines_to_check nodecount) 301 | nodecount = number0; 302 | if(number1 > nodecount) 303 | nodecount = number1; 304 | } 305 | } 306 | nodecount++; 307 | for(int i=0;i=N) 329 | div = DEG; 330 | init_weights(N, DEG, W, W_index); 331 | for(int i=0;i=N) 462 | { 463 | W_index[i][j] = N-1; 464 | } 465 | } 466 | } 467 | 468 | // Populate Cost Array 469 | for(int i = 0; i < N; i++) 470 | { 471 | for(int j = 0; j < DEG; j++) 472 | { 473 | /*if(v > 0.8 || W_index[i][j] == -1) 474 | { W[i][j] = MAX; 475 | W_index[i][j] = -1; 476 | } 477 | 478 | else*/ if(W_index[i][j] == i) 479 | W[i][j] = 0; 480 | 481 | else 482 | W[i][j] = 0;//(double) (v) + 1; 483 | } 484 | } 485 | } 486 | -------------------------------------------------------------------------------- /apps/pagerank/pagerank_lock.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | //#include "carbon_user.h" /*For the Graphite Simulator*/ 5 | #include 6 | #include 7 | #include 8 | 9 | #define MAX 100000000 10 | #define INT_MAX 100000000 11 | #define BILLION 1E9 12 | 13 | //Thread Structure 14 | typedef struct 15 | { 16 | double* PR; 17 | double** W; 18 | int** W_index; 19 | int tid; 20 | int P; 21 | int N; 22 | int DEG; 23 | pthread_barrier_t* barrier; 24 | } thread_arg_t; 25 | 26 | //Global Variables 27 | pthread_mutex_t lock; //single lock 28 | double dp_tid[1024]; //dangling pages for each thread, reduced later by locks 29 | int terminate = 0; //terminate variable 30 | int *test; //test variable arrays for graph storage 31 | int *exist; 32 | int *test2; 33 | int *dangling; 34 | int *outlinks; //array for outlinks 35 | double dp = 0; //dangling pointer variable 36 | double *pgtmp; //temporary pageranks 37 | thread_arg_t thread_arg[1024]; //MAX threads 38 | pthread_t thread_handle[1024]; //pthread handlers 39 | 40 | //Function declarations 41 | int initialize_single_source(double* PR, int source, int N, double initial_rank); 42 | void init_weights(int N, int DEG, double** W, int** W_index); 43 | 44 | //Primary Parallel Function 45 | void* do_work(void* args) 46 | { 47 | volatile thread_arg_t* arg = (thread_arg_t*) args; 48 | int tid = arg->tid; 49 | double* PR = arg->PR; 50 | int** W_index = arg->W_index; 51 | const int N = arg->N; 52 | int v = 0; //variable for current vertex 53 | double r = 0.15; //damping coefficient 54 | double d = 0.85; //damping coefficient 55 | double N_real = N; 56 | int DEG = arg->DEG; 57 | //double tid_d = tid; 58 | int P = arg->P; 59 | 60 | //Allocate work among threads 61 | //double start_d = (tid_d) * (N_real/P_d); 62 | //double stop_d = (tid_d+1.0) * (N_real/P_d); 63 | int i_start = (double)tid * (double)(N)/(double)P; 64 | int i_stop = (double)(tid+1) * (double)(N)/(double)P; 65 | //printf("\n TID: %d %d %d",tid, i_start, i_stop); 66 | 67 | //Pagerank iteration count 68 | int iterations = 1; 69 | 70 | //Barrier before starting work 71 | pthread_barrier_wait(arg->barrier); 72 | 73 | while(iterations>0) 74 | { 75 | if(tid==0) 76 | dp=d; 77 | pthread_barrier_wait(arg->barrier); 78 | 79 | //for no outlinks, dangling pages calculation 80 | for(v=i_start;vbarrier); 95 | 96 | //if(tid==0) 97 | // printf("\n Outlinks Done %f",dp); 98 | 99 | pthread_barrier_wait(arg->barrier); 100 | 101 | v=0; 102 | 103 | //Calculate Pageranks 104 | for(v=i_start;vN) 113 | break; 114 | //if inlink 115 | //printf("\nuu:%d id:%d",uu,W_index[uu][j]); 116 | pgtmp[v] = pgtmp[v] + (dp*PR[W_index[v][j]]/outlinks[W_index[v][j]]); //replace d with dp if dangling PRs required 117 | } 118 | } 119 | if(pgtmp[v]>=1.0) 120 | pgtmp[v] = 1.0; 121 | } 122 | //printf("\n Ranks done"); 123 | 124 | pthread_barrier_wait(arg->barrier); 125 | 126 | //Put temporary pageranks into final pageranks 127 | for(v=i_start;vbarrier); 137 | iterations--; 138 | } 139 | 140 | //printf("\n %d %d",tid,terminate); 141 | return NULL; 142 | } 143 | 144 | 145 | //Main 146 | int main(int argc, char** argv) 147 | { 148 | 149 | FILE *file0 = NULL; 150 | int N = 0; //Total vertices 151 | int DEG = 0; //Edges per vertex 152 | const int select = atoi(argv[1]); //0 for synthetic, 1 for file read 153 | char filename[100]; 154 | 155 | //For graph through file input 156 | if(select==1) 157 | { 158 | strcpy(filename,argv[3]); 159 | file0 = fopen(filename,"r"); 160 | } 161 | 162 | int lines_to_check=0; //file processing variables 163 | char c; 164 | int number0; 165 | int number1; 166 | 167 | //Read Max Vertices and Edges 168 | if(select==1) 169 | { 170 | N = 0;//2097152; //can be read from file if needed, this is a default upper limit 171 | DEG = 0;//26; //also can be reda from file if needed, upper limit here again 172 | FILE *file_gr = NULL; 173 | const char *filename0 = argv[3]; 174 | file_gr = fopen(filename0,"r"); 175 | char ch0; 176 | int number_of_lines0 = 0; 177 | while(EOF != (ch0=getc(file_gr))) 178 | { 179 | if(ch0=='\n') 180 | number_of_lines0++; 181 | if(number_of_lines0>3) 182 | { 183 | int f0 = fscanf(file_gr, "%d %d", &number0, &number1); 184 | if(f0 != 2 && f0 !=EOF) 185 | { 186 | printf ("Error: Read %d values, expected 2. Parsing failed.\n",f0); 187 | exit (EXIT_FAILURE); 188 | } 189 | if(number0>N) 190 | N = number0; 191 | if(number1>N) 192 | N = number1; 193 | } 194 | } 195 | fclose(file_gr); //Now N has the largest Vertex ID 196 | N++; 197 | 198 | int *temp; 199 | number_of_lines0 = 0; 200 | if(posix_memalign((void**) &temp, 64, N * sizeof(int))) 201 | { 202 | fprintf(stderr, "Allocation of memory failed\n"); 203 | exit(EXIT_FAILURE); 204 | } 205 | for(int i=0;i3) 213 | { 214 | int f0 = fscanf(file_gr, "%d %d", &number0, &number1); 215 | if(f0 != 2 && f0 !=EOF) 216 | { 217 | printf ("Error: Read %d values, expected 2. Parsing failed.\n",f0); 218 | exit (EXIT_FAILURE); 219 | } 220 | temp[number0]++; 221 | } 222 | } 223 | fclose(file_gr); 224 | for(int i=0;iDEG) 227 | DEG = temp[i]; 228 | } 229 | free(temp); 230 | printf("\n.gr graph with parameters: Vertices:%d Degree:%d LinesInFile:%d",N,DEG,number_of_lines0); 231 | } 232 | 233 | const int P = atoi(argv[2]); //number of threads 234 | 235 | if(select==0) 236 | { 237 | N = atoi(argv[3]); 238 | DEG = atoi(argv[4]); 239 | printf("\nUniform Random Graph with Parameters: N:%d DEG:%d\n",N,DEG); 240 | } 241 | 242 | //Memory allocations 243 | double* PR; 244 | if(posix_memalign((void**) &PR, 64, (N+1) * sizeof(double))) 245 | { 246 | fprintf(stderr, "Allocation of memory failed\n"); 247 | exit(EXIT_FAILURE); 248 | } 249 | if(posix_memalign((void**) &test, 64, (N+10) * sizeof(int))) 250 | { 251 | fprintf(stderr, "Allocation of memory failed\n"); 252 | exit(EXIT_FAILURE); 253 | } 254 | if(posix_memalign((void**) &exist, 64, (N+1) * sizeof(int))) 255 | { 256 | fprintf(stderr, "Allocation of memory failed\n"); 257 | exit(EXIT_FAILURE); 258 | } 259 | if(posix_memalign((void**) &test2, 64, (N+1) * sizeof(int))) 260 | { 261 | fprintf(stderr, "Allocation of memory failed\n"); 262 | exit(EXIT_FAILURE); 263 | } 264 | if(posix_memalign((void**) &dangling, 64, (N+1) * sizeof(int))) 265 | { 266 | fprintf(stderr, "Allocation of memory failed\n"); 267 | exit(EXIT_FAILURE); 268 | } 269 | if(posix_memalign((void**) &pgtmp, 64, (N+1) * sizeof(double))) 270 | { 271 | fprintf(stderr, "Allocation of memory failed\n"); 272 | exit(EXIT_FAILURE); 273 | } 274 | if(posix_memalign((void**) &outlinks, 64, (N+1) * sizeof(int))) 275 | { 276 | fprintf(stderr, "Allocation of memory failed\n"); 277 | exit(EXIT_FAILURE); 278 | } 279 | pthread_barrier_t barrier; 280 | 281 | double** W = (double**) malloc((N+1)*sizeof(double*)); 282 | int** W_index = (int**) malloc((N+1)*sizeof(int*)); 283 | for(int i = 0; i <= N; i++) 284 | { 285 | //W[i] = (int *)malloc(sizeof(int)*N); 286 | int ret = posix_memalign((void**) &W[i], 64, (DEG+1)*sizeof(double)); 287 | int re1 = posix_memalign((void**) &W_index[i], 64, (DEG+1)*sizeof(int)); 288 | if (ret != 0 || re1!=0) 289 | { 290 | fprintf(stderr, "Could not allocate memory\n"); 291 | exit(EXIT_FAILURE); 292 | } 293 | } 294 | 295 | //Memory initialization 296 | for(int i=0;i<=N;i++) 297 | { 298 | for(int j=0;j<=DEG;j++) 299 | { 300 | W[i][j] = 1000000000; 301 | W_index[i][j] = INT_MAX; 302 | } 303 | test[i]=0; 304 | exist[i]=0; 305 | test2[i]=0; 306 | dangling[i]=0; 307 | outlinks[i]=0; 308 | } 309 | printf("\nMemory Initialized"); 310 | 311 | //If graph read from file 312 | if(select==1) 313 | { 314 | for(c=getc(file0); c!=EOF; c=getc(file0)) 315 | { 316 | if(c=='\n') 317 | lines_to_check++; 318 | 319 | if(lines_to_check>3) 320 | { 321 | int f0 = fscanf(file0, "%d %d", &number0,&number1); 322 | if(f0 != 2 && f0 != EOF) 323 | { 324 | printf ("Error: Read %d values, expected 2. Parsing failed.\n",f0); 325 | exit (EXIT_FAILURE); 326 | } 327 | 328 | //inter = 1;//test[number1]; 329 | //if(lines_to_check>5532000) 330 | //printf("\n%d\n",number0); 331 | W[number0][test[number1]] = 0; //drand48(); 332 | W_index[number1][test[number1]] = number0; 333 | //test[number1]++; 334 | outlinks[number0]++; 335 | exist[number0]=1; exist[number1]=1; 336 | test2[number0]=1; 337 | dangling[number1]=1; 338 | 339 | } 340 | } 341 | free(test); 342 | printf("\nFile Read"); 343 | for(int i=0;i<=N;i++) 344 | { 345 | if(test2[i]==1 && dangling[i]==1) 346 | dangling[i]=0; 347 | } 348 | printf("\nLargest Vertex: %d",N); 349 | } 350 | 351 | //If graph to be generated synthetically 352 | if(select==0) 353 | { 354 | int div = N; 355 | if(DEG>=N) 356 | div = DEG; 357 | init_weights(N, DEG, W, W_index); 358 | for(int i=0;i<=N;i++) 359 | { 360 | outlinks[i] = rand()%(div); //random outlinks 361 | if(outlinks[i]==0) 362 | outlinks[i] = N; 363 | } 364 | } 365 | 366 | //Synchronization parameters 367 | pthread_barrier_init(&barrier, NULL, P); 368 | pthread_mutex_init(&lock, NULL); 369 | 370 | for(int i=0; i<=N; i++) 371 | { 372 | if(select==0) 373 | { 374 | exist[i]=1; 375 | if(i%100==0) 376 | { 377 | dangling[i]=1; 378 | } 379 | //test[i] = DEG; 380 | } 381 | //pthread_mutex_init(&locks[i], NULL); 382 | } 383 | 384 | //Initialize PageRanks 385 | initialize_single_source(PR, 0, N, 0.15); 386 | printf("\nInitialization Done"); 387 | 388 | //Thread arguments 389 | for(int j = 0; j < P; j++) { 390 | thread_arg[j].PR = PR; 391 | thread_arg[j].W = W; 392 | thread_arg[j].W_index = W_index; 393 | thread_arg[j].tid = j; 394 | thread_arg[j].P = P; 395 | thread_arg[j].N = N; 396 | thread_arg[j].DEG = DEG; 397 | thread_arg[j].barrier = &barrier; 398 | } 399 | 400 | //Start CPU clock 401 | struct timespec requestStart, requestEnd; 402 | clock_gettime(CLOCK_REALTIME, &requestStart); 403 | 404 | // Enable Graphite performance and energy models 405 | //CarbonEnableModels(); 406 | 407 | //Spawn Threads 408 | for(int j = 1; j < P; j++) { 409 | pthread_create(thread_handle+j, 410 | NULL, 411 | do_work, 412 | (void*)&thread_arg[j]); 413 | } 414 | do_work((void*) &thread_arg[0]); //Spawn main 415 | 416 | //Join threads 417 | for(int j = 1; j < P; j++) { //mul = mul*2; 418 | pthread_join(thread_handle[j],NULL); 419 | } 420 | 421 | // Disable Graphite performance and energy models 422 | //CarbonDisableModels(); 423 | 424 | //Read clock and print time 425 | clock_gettime(CLOCK_REALTIME, &requestEnd); 426 | double accum = ( requestEnd.tv_sec - requestStart.tv_sec ) + ( requestEnd.tv_nsec - requestStart.tv_nsec ) / BILLION; 427 | printf( "\nTime:%lf seconds\n", accum ); 428 | 429 | //printf("\ndistance:%d \n",D[N-1]); 430 | 431 | //Print pageranks to file 432 | FILE *f1 = fopen("file.txt", "w"); 433 | 434 | for(int i = 0; i <= N; i++) { 435 | if(exist[i]==1) 436 | fprintf(f1,"pr(%d) = %f\n", i,PR[i]); 437 | } 438 | printf("\n"); 439 | fclose(f1); 440 | 441 | return 0; 442 | } 443 | 444 | int initialize_single_source(double* PR, 445 | int source, 446 | int N, 447 | double initial_rank) 448 | { 449 | for(int i = 0; i <= N; i++) 450 | { 451 | PR[i] = 0.15;//initial_rank; 452 | pgtmp[i] = 0.15;//initial_rank; 453 | } 454 | 455 | // D[source] = 0; 456 | return 0; 457 | } 458 | 459 | void init_weights(int N, int DEG, double** W, int** W_index) 460 | { 461 | // Initialize to -1 462 | for(int i = 0; i <= N; i++) 463 | for(int j = 0; j < DEG; j++) 464 | W_index[i][j]= -1; 465 | 466 | // Populate Index Array 467 | for(int i = 0; i <= N; i++) 468 | { 469 | int max = DEG; 470 | for(int j = 0; j < DEG; j++) 471 | { 472 | if(W_index[i][j] == -1) 473 | { 474 | int neighbor = rand()%(i+max*2); 475 | if(neighborN) 484 | { 485 | W_index[i][j] = N; 486 | } 487 | } 488 | } 489 | 490 | // Populate Cost Array 491 | for(int i = 0; i <= N; i++) 492 | { 493 | for(int j = 0; j < DEG; j++) 494 | { 495 | /*if(v > 0.8 || W_index[i][j] == -1) 496 | { W[i][j] = MAX; 497 | W_index[i][j] = -1; 498 | } 499 | 500 | else*/ if(W_index[i][j] == i) 501 | W[i][j] = 0; 502 | 503 | else 504 | W[i][j] = 0;//(double) (v) + 1; 505 | } 506 | } 507 | } 508 | -------------------------------------------------------------------------------- /apps/pagerank/sample.txt: -------------------------------------------------------------------------------- 1 | # Directed graph (each unordered pair of nodes is saved once): roadNet-CA.txt 2 | # Sample California road network 3 | # Nodes: 1965206 Edges: 5533214 4 | # FromNodeId ToNodeId 5 | 0 1 6 | 0 2 7 | 0 469 8 | 1 0 9 | 1 6 10 | 1 385 11 | 2 0 12 | 2 3 13 | 469 0 14 | 469 380 15 | 469 37415 16 | 6 1 17 | 6 5 18 | 385 1 19 | 385 384 20 | 385 386 21 | 3 2 22 | 3 4 23 | 3 419 24 | 3 422 25 | 4 3 26 | 4 5 27 | 4 98 28 | 4 420 29 | 419 3 30 | 419 420 31 | 419 35698 32 | 422 3 33 | 422 183 34 | 422 423 35 | 422 37415 36 | 5 4 37 | 5 6 38 | 5 98 39 | 98 4 40 | 98 5 41 | 98 470 42 | 98 35729 43 | 420 4 44 | 420 419 45 | 420 35709 46 | 7 8 47 | 7 9 48 | 7 79 49 | 8 7 50 | 8 33 51 | 9 7 52 | 9 10 53 | 9 84 54 | 79 7 55 | 79 78 56 | 79 119 57 | 33 8 58 | 33 32 59 | 33 34 60 | 10 9 61 | 10 11 62 | 10 84 63 | 10 110 64 | 84 9 65 | 84 10 66 | 84 83 67 | 84 85 68 | 11 10 69 | 11 12 70 | 11 110 71 | 110 10 72 | 110 11 73 | 110 111 74 | 110 112 75 | 12 11 76 | 12 13 77 | 12 95 78 | 12 108 79 | 13 12 80 | 13 14 81 | 13 94 82 | 13 95 83 | 108 12 84 | 108 109 85 | 108 113 86 | 108 123 87 | 95 12 88 | 95 13 89 | 95 96 90 | 14 13 91 | 14 15 92 | 14 16 93 | 14 77 94 | 94 13 95 | 94 77 96 | 94 93 97 | 15 14 98 | 16 14 99 | 16 17 100 | 77 14 101 | 77 17 102 | 77 94 103 | 17 16 104 | 17 18 105 | 17 77 106 | 17 3254 107 | 18 17 108 | 18 19 109 | 18 3254 110 | 3254 17 111 | 3254 18 112 | 3254 3255 113 | 3254 36971 114 | 19 18 115 | 19 20 116 | 19 23 117 | 20 19 118 | 20 21 119 | 20 22 120 | 23 19 121 | 23 24 122 | 23 25 123 | 21 20 124 | 22 20 125 | 24 23 126 | 25 23 127 | 25 26 128 | 25 27 129 | 26 25 130 | 27 25 131 | 27 28 132 | 27 29 133 | 28 27 134 | 29 27 135 | 29 30 136 | 29 3255 137 | 30 29 138 | 30 31 139 | 30 3247 140 | 30 3253 141 | 3255 29 142 | 3255 3253 143 | 3255 3254 144 | 3255 35943 145 | 31 30 146 | 31 32 147 | 31 3246 148 | 3247 30 149 | 3247 3248 150 | 3247 3249 151 | 3253 30 152 | 3253 3204 153 | 3253 3255 154 | 3253 35950 155 | 32 31 156 | 32 33 157 | 32 2203 158 | 3246 31 159 | 3246 2203 160 | 3246 3252 161 | 3246 3257 162 | 2203 32 163 | 2203 2146 164 | 2203 2204 165 | 2203 3246 166 | 34 33 167 | 35 36 168 | 35 50 169 | 35 1199 170 | 36 35 171 | 36 37 172 | 36 35885 173 | 36 1645159 174 | 50 35 175 | 50 49 176 | 50 185 177 | 1199 35 178 | 1199 1198 179 | 1199 1205 180 | 37 36 181 | 37 38 182 | 37 1641586 183 | 35885 36 184 | 35885 35884 185 | 35885 1645157 186 | 1645159 36 187 | 1645159 1645156 188 | 1645159 1645157 189 | 1645159 1648644 190 | 38 37 191 | 38 39 192 | 38 1641586 193 | 1641586 37 194 | 1641586 38 195 | 1641586 1633418 196 | 39 38 197 | 39 40 198 | 39 1641587 199 | 40 39 200 | 40 41 201 | 40 1641577 202 | 1641587 39 203 | 1641587 1633418 204 | 1641587 1641576 205 | 1641587 1641606 206 | 41 40 207 | 41 42 208 | 41 1641355 209 | 1641577 40 210 | 1641577 1641363 211 | 1641577 1641576 212 | 42 41 213 | 42 43 214 | 42 1639779 215 | 1641355 41 216 | 1641355 1628954 217 | 1641355 1639780 218 | 1641355 1641363 219 | 43 42 220 | 43 44 221 | 43 1639779 222 | 1639779 42 223 | 1639779 43 224 | 1639779 1639780 225 | 44 43 226 | 44 45 227 | 44 1542024 228 | 45 44 229 | 45 46 230 | 45 1154 231 | 45 1538392 232 | 1542024 44 233 | 1542024 1542023 234 | 1542024 1639781 235 | 46 45 236 | 46 47 237 | 46 27108 238 | 46 27325 239 | 1154 45 240 | 1154 1153 241 | 1154 1155 242 | 1538392 45 243 | 1538392 1538362 244 | 1538392 1538390 245 | 1538392 1538391 246 | 47 46 247 | 47 48 248 | 47 27325 249 | 27108 46 250 | 27108 27107 251 | 27108 27250 252 | 27325 46 253 | 27325 47 254 | 27325 27323 255 | 27325 27335 256 | 48 47 257 | 48 49 258 | 48 27343 259 | 49 48 260 | 49 50 261 | 49 184 262 | 27343 48 263 | 27343 27342 264 | 27343 35887 265 | 27343 39411 266 | 184 49 267 | 184 185 268 | 184 35886 269 | 185 50 270 | 185 184 271 | 185 1198 272 | 52 53 273 | 52 54 274 | 52 4152 275 | 53 52 276 | 53 54 277 | 53 223 278 | 53 225 279 | 54 52 280 | 54 53 281 | 54 4120 282 | 4152 52 283 | 4152 4148 284 | 4152 4153 285 | 4152 4156 286 | 223 53 287 | 223 224 288 | 223 3937 289 | 223 4113 290 | 225 53 291 | 225 224 292 | 225 4114 293 | 225 4148 294 | 4120 54 295 | 4120 3937 296 | 4120 4153 297 | 4120 4154 298 | 55 56 299 | 55 57 300 | 55 1068 301 | 55 1099 302 | 56 55 303 | 56 76 304 | 56 1069 305 | 57 55 306 | 57 58 307 | 57 1071 308 | 57 1072 309 | 1068 55 310 | 1068 1069 311 | 1068 1096 312 | 1068 1116 313 | 1068 36235 314 | 1099 55 315 | 76 56 316 | 76 74 317 | 76 1075 318 | 1069 56 319 | 1069 1068 320 | 1069 1116 321 | 58 57 322 | 58 59 323 | 58 1089 324 | 58 32419 325 | 1072 57 326 | 1072 1070 327 | 1072 32419 328 | 1071 57 329 | 1071 1070 330 | 1071 1098 331 | 1071 1110 332 | 59 58 333 | 59 60 334 | 59 61 335 | 59 62 336 | 1089 58 337 | 1089 62 338 | 1089 171 339 | 1089 172 340 | 32419 58 341 | 32419 1072 342 | 60 59 343 | 61 59 344 | 62 59 345 | 62 63 346 | 62 1089 347 | 63 62 348 | 63 64 349 | 63 339 350 | 64 63 351 | 64 65 352 | 64 2220 353 | 339 63 354 | 339 338 355 | 339 341 356 | 339 36187 357 | 65 64 358 | 65 66 359 | 65 2155 360 | 65 2157 361 | 2220 64 362 | 2220 2219 363 | 2220 2221 364 | 66 65 365 | 66 67 366 | 66 68 367 | 66 2254 368 | 2155 65 369 | 2155 2156 370 | 2155 2254 371 | 2157 65 372 | 2157 2158 373 | 2157 2161 374 | 2157 2219 375 | 67 66 376 | 68 66 377 | 68 69 378 | 68 70 379 | 68 2251 380 | 2254 66 381 | 2254 2155 382 | 2254 2252 383 | 69 68 384 | 70 68 385 | 70 71 386 | 70 1052 387 | 70 2251 388 | 2251 68 389 | 2251 70 390 | 2251 2252 391 | 71 70 392 | 71 72 393 | 71 1049 394 | 1052 70 395 | 1052 1050 396 | 1052 2256 397 | 1052 2258 398 | 72 71 399 | 72 73 400 | 72 74 401 | -------------------------------------------------------------------------------- /apps/sssp/Makefile: -------------------------------------------------------------------------------- 1 | 2 | TRGS = sssp sssp_outer sssp_outer_atomic 3 | 4 | LIBS += -lpthread -lrt 5 | 6 | ##BOOST_PATH = /run/pkg/boost-/1.53.0-gcc_4.7.3 7 | 8 | ##BOOST_FLAGS = -I$(BOOST_PATH)/include -L$(BOOST_PATH)/lib -lboost_graph 9 | 10 | CXXFLAGS = -g --std=c++0x -O3 11 | CXXFLAGS += -Wall -Werror 12 | 13 | all: $(TRGS) 14 | 15 | sssp: sssp.cc 16 | sssp_outer: sssp_outer.cc 17 | sssp_outer_atomic: sssp_outer_atomic.cc 18 | 19 | clean: 20 | rm -f $(TRGS) *.o *.dot 21 | 22 | %: %.cc ; 23 | $(CXX) $(CXXFLAGS) $< -o $@ $(LIBS) 24 | -------------------------------------------------------------------------------- /apps/sssp/README.md: -------------------------------------------------------------------------------- 1 | Single Source Shortest Path 2 | =========================== 3 | 4 | You can run ```make``` to create executables for each program or use the following commands below 5 | 6 | The first argument to the executable specifies whether you want to read the graph from a file (1), or generate a synthetic one internally (0). 7 | 8 | **Input Graph from a File** 9 | 10 | To run with P number of threads 11 | ```./sssp 1 P ``` 12 | 13 | It will then ask for the input file, enter: 14 | sample.txt 15 | OR any other file such as road networks from the SNAP datasets (e.g. roadNet-CA) 16 | https://snap.stanford.edu/data/#road 17 | 18 | **Generate and Input using the Synthetic Graph Generator** 19 | 20 | To run with P number of threads, N vertices, and DEG edges per vertex 21 | ```./sssp 0 P N DEG``` 22 | 23 | **Notes** 24 | 25 | This version of sssp parallelizes the O(V^2) version of Dijkstra's Algorithm, given by Yen's Optimization. 26 | Paper: J.Y.Yen, "An algorithm for finding shortest routes from all source nodes to a given destination in general networks", Quarterly of Applied Mathematics 01/1970. 27 | 28 | SSSP has a parameter P_max that is specified by ```cuberoot(N)*3```, which represents the number of iterations for the outer loop. 29 | 30 | The executable then outputs the time in seconds that the program took to run. 31 | 32 | ```sssp_outer.cc``` implemented a conventional parallelization of the bellman-ford algorithm. This is an iterative algorithm generally used in GPU implementations. ```sssp_outer_atomic.cc``` just replaces pthread_barriers with atomic barriers. 33 | -------------------------------------------------------------------------------- /apps/sssp/sample.txt: -------------------------------------------------------------------------------- 1 | # Directed graph (each unordered pair of nodes is saved once): roadNet-CA.txt 2 | # Sample California road network 3 | # Nodes: 1965206 Edges: 5533214 4 | # FromNodeId ToNodeId 5 | 0 1 6 | 0 2 7 | 0 469 8 | 1 0 9 | 1 6 10 | 1 385 11 | 2 0 12 | 2 3 13 | 469 0 14 | 469 380 15 | 469 37415 16 | 6 1 17 | 6 5 18 | 385 1 19 | 385 384 20 | 385 386 21 | 3 2 22 | 3 4 23 | 3 419 24 | 3 422 25 | 4 3 26 | 4 5 27 | 4 98 28 | 4 420 29 | 419 3 30 | 419 420 31 | 419 35698 32 | 422 3 33 | 422 183 34 | 422 423 35 | 422 37415 36 | 5 4 37 | 5 6 38 | 5 98 39 | 98 4 40 | 98 5 41 | 98 470 42 | 98 35729 43 | 420 4 44 | 420 419 45 | 420 35709 46 | 7 8 47 | 7 9 48 | 7 79 49 | 8 7 50 | 8 33 51 | 9 7 52 | 9 10 53 | 9 84 54 | 79 7 55 | 79 78 56 | 79 119 57 | 33 8 58 | 33 32 59 | 33 34 60 | 10 9 61 | 10 11 62 | 10 84 63 | 10 110 64 | 84 9 65 | 84 10 66 | 84 83 67 | 84 85 68 | 11 10 69 | 11 12 70 | 11 110 71 | 110 10 72 | 110 11 73 | 110 111 74 | 110 112 75 | 12 11 76 | 12 13 77 | 12 95 78 | 12 108 79 | 13 12 80 | 13 14 81 | 13 94 82 | 13 95 83 | 108 12 84 | 108 109 85 | 108 113 86 | 108 123 87 | 95 12 88 | 95 13 89 | 95 96 90 | 14 13 91 | 14 15 92 | 14 16 93 | 14 77 94 | 94 13 95 | 94 77 96 | 94 93 97 | 15 14 98 | 16 14 99 | 16 17 100 | 77 14 101 | 77 17 102 | 77 94 103 | 17 16 104 | 17 18 105 | 17 77 106 | 17 3254 107 | 18 17 108 | 18 19 109 | 18 3254 110 | 3254 17 111 | 3254 18 112 | 3254 3255 113 | 3254 36971 114 | 19 18 115 | 19 20 116 | 19 23 117 | 20 19 118 | 20 21 119 | 20 22 120 | 23 19 121 | 23 24 122 | 23 25 123 | 21 20 124 | 22 20 125 | 24 23 126 | 25 23 127 | 25 26 128 | 25 27 129 | 26 25 130 | 27 25 131 | 27 28 132 | 27 29 133 | 28 27 134 | 29 27 135 | 29 30 136 | 29 3255 137 | 30 29 138 | 30 31 139 | 30 3247 140 | 30 3253 141 | 3255 29 142 | 3255 3253 143 | 3255 3254 144 | 3255 35943 145 | 31 30 146 | 31 32 147 | 31 3246 148 | 3247 30 149 | 3247 3248 150 | 3247 3249 151 | 3253 30 152 | 3253 3204 153 | 3253 3255 154 | 3253 35950 155 | 32 31 156 | 32 33 157 | 32 2203 158 | 3246 31 159 | 3246 2203 160 | 3246 3252 161 | 3246 3257 162 | 2203 32 163 | 2203 2146 164 | 2203 2204 165 | 2203 3246 166 | 34 33 167 | 35 36 168 | 35 50 169 | 35 1199 170 | 36 35 171 | 36 37 172 | 36 35885 173 | 36 1645159 174 | 50 35 175 | 50 49 176 | 50 185 177 | 1199 35 178 | 1199 1198 179 | 1199 1205 180 | 37 36 181 | 37 38 182 | 37 1641586 183 | 35885 36 184 | 35885 35884 185 | 35885 1645157 186 | 1645159 36 187 | 1645159 1645156 188 | 1645159 1645157 189 | 1645159 1648644 190 | 38 37 191 | 38 39 192 | 38 1641586 193 | 1641586 37 194 | 1641586 38 195 | 1641586 1633418 196 | 39 38 197 | 39 40 198 | 39 1641587 199 | 40 39 200 | 40 41 201 | 40 1641577 202 | 1641587 39 203 | 1641587 1633418 204 | 1641587 1641576 205 | 1641587 1641606 206 | 41 40 207 | 41 42 208 | 41 1641355 209 | 1641577 40 210 | 1641577 1641363 211 | 1641577 1641576 212 | 42 41 213 | 42 43 214 | 42 1639779 215 | 1641355 41 216 | 1641355 1628954 217 | 1641355 1639780 218 | 1641355 1641363 219 | 43 42 220 | 43 44 221 | 43 1639779 222 | 1639779 42 223 | 1639779 43 224 | 1639779 1639780 225 | 44 43 226 | 44 45 227 | 44 1542024 228 | 45 44 229 | 45 46 230 | 45 1154 231 | 45 1538392 232 | 1542024 44 233 | 1542024 1542023 234 | 1542024 1639781 235 | 46 45 236 | 46 47 237 | 46 27108 238 | 46 27325 239 | 1154 45 240 | 1154 1153 241 | 1154 1155 242 | 1538392 45 243 | 1538392 1538362 244 | 1538392 1538390 245 | 1538392 1538391 246 | 47 46 247 | 47 48 248 | 47 27325 249 | 27108 46 250 | 27108 27107 251 | 27108 27250 252 | 27325 46 253 | 27325 47 254 | 27325 27323 255 | 27325 27335 256 | 48 47 257 | 48 49 258 | 48 27343 259 | 49 48 260 | 49 50 261 | 49 184 262 | 27343 48 263 | 27343 27342 264 | 27343 35887 265 | 27343 39411 266 | 184 49 267 | 184 185 268 | 184 35886 269 | 185 50 270 | 185 184 271 | 185 1198 272 | 52 53 273 | 52 54 274 | 52 4152 275 | 53 52 276 | 53 54 277 | 53 223 278 | 53 225 279 | 54 52 280 | 54 53 281 | 54 4120 282 | 4152 52 283 | 4152 4148 284 | 4152 4153 285 | 4152 4156 286 | 223 53 287 | 223 224 288 | 223 3937 289 | 223 4113 290 | 225 53 291 | 225 224 292 | 225 4114 293 | 225 4148 294 | 4120 54 295 | 4120 3937 296 | 4120 4153 297 | 4120 4154 298 | 55 56 299 | 55 57 300 | 55 1068 301 | 55 1099 302 | 56 55 303 | 56 76 304 | 56 1069 305 | 57 55 306 | 57 58 307 | 57 1071 308 | 57 1072 309 | 1068 55 310 | 1068 1069 311 | 1068 1096 312 | 1068 1116 313 | 1068 36235 314 | 1099 55 315 | 76 56 316 | 76 74 317 | 76 1075 318 | 1069 56 319 | 1069 1068 320 | 1069 1116 321 | 58 57 322 | 58 59 323 | 58 1089 324 | 58 32419 325 | 1072 57 326 | 1072 1070 327 | 1072 32419 328 | 1071 57 329 | 1071 1070 330 | 1071 1098 331 | 1071 1110 332 | 59 58 333 | 59 60 334 | 59 61 335 | 59 62 336 | 1089 58 337 | 1089 62 338 | 1089 171 339 | 1089 172 340 | 32419 58 341 | 32419 1072 342 | 60 59 343 | 61 59 344 | 62 59 345 | 62 63 346 | 62 1089 347 | 63 62 348 | 63 64 349 | 63 339 350 | 64 63 351 | 64 65 352 | 64 2220 353 | 339 63 354 | 339 338 355 | 339 341 356 | 339 36187 357 | 65 64 358 | 65 66 359 | 65 2155 360 | 65 2157 361 | 2220 64 362 | 2220 2219 363 | 2220 2221 364 | 66 65 365 | 66 67 366 | 66 68 367 | 66 2254 368 | 2155 65 369 | 2155 2156 370 | 2155 2254 371 | 2157 65 372 | 2157 2158 373 | 2157 2161 374 | 2157 2219 375 | 67 66 376 | 68 66 377 | 68 69 378 | 68 70 379 | 68 2251 380 | 2254 66 381 | 2254 2155 382 | 2254 2252 383 | 69 68 384 | 70 68 385 | 70 71 386 | 70 1052 387 | 70 2251 388 | 2251 68 389 | 2251 70 390 | 2251 2252 391 | 71 70 392 | 71 72 393 | 71 1049 394 | 1052 70 395 | 1052 1050 396 | 1052 2256 397 | 1052 2258 398 | 72 71 399 | 72 73 400 | 72 74 401 | -------------------------------------------------------------------------------- /apps/sssp/sssp_outer.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Distributed Under the MIT license 3 | Uses the Bellman-Ford/Dijkstra Algorithm to find shortest path distances 4 | Programs by Masab Ahmad (UConn) 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | //#include "carbon_user.h" /*For the Graphite Simulator*/ 11 | #include 12 | #include 13 | 14 | #define MAX 100000000 15 | #define INT_MAX 100000000 16 | #define BILLION 1E9 17 | 18 | //Thread Argument Structure 19 | typedef struct 20 | { 21 | int* local_min; 22 | int* global_min; 23 | int* Q; 24 | int* D; 25 | int* D_temp; 26 | int** W; 27 | int** W_index; 28 | int* d_count; 29 | int tid; 30 | int P; 31 | int N; 32 | int DEG; 33 | pthread_barrier_t* barrier; 34 | } thread_arg_t; 35 | 36 | //Function Initializers 37 | int initialize_single_source(int* D, int* D_temp, int* Q, int source, int N); 38 | void relax(int u, int i, volatile int* D, int** W, int** W_index, int N); 39 | int get_local_min(volatile int* Q, volatile int* D, int start, int stop, int N, int** W_index, int** W, int u); 40 | void init_weights(int N, int DEG, int** W, int** W_index); 41 | 42 | //Global Variables 43 | int min = INT_MAX; 44 | int min_index = 0; 45 | pthread_mutex_t lock; 46 | pthread_mutex_t locks[2097152]; //change the number of locks to approx or greater N 47 | int u = -1; 48 | int local_min_buffer[1024]; 49 | int global_min_buffer; 50 | int terminate = 0; 51 | int cntr = 0; 52 | int *exist; 53 | int *id; 54 | int P_max=64; 55 | double largest_d; 56 | thread_arg_t thread_arg[1024]; 57 | pthread_t thread_handle[1024]; 58 | 59 | //Primary Parallel Function 60 | void* do_work(void* args) 61 | { 62 | volatile thread_arg_t* arg = (thread_arg_t*) args; 63 | 64 | int tid = arg->tid; //thread id 65 | int P = arg->P; //Max threads 66 | int* D_temp = arg->D_temp; //Temporary Distance Array 67 | int* D = arg->D; //distabces 68 | int** W = arg->W; //edge weights 69 | int** W_index = arg->W_index; //graph structure 70 | const int N = arg->N; //Max vertices 71 | const int DEG = arg->DEG; //edges per vertex 72 | int v = 0; 73 | 74 | int cntr_0 = 0; 75 | int start = 0; 76 | int stop = 1; 77 | int neighbor=0; 78 | 79 | //For precision dynamic work allocation 80 | double P_d = P; 81 | //double range_d = 1.0; 82 | double tid_d = tid; 83 | 84 | double start_d = (tid_d) * (largest_d/P_d); 85 | double stop_d = (tid_d+1.0) * (largest_d/P_d); 86 | start = start_d;//tid * (largest+1) / (P); 87 | stop = stop_d;//(tid+1) * (largest+1) / (P); 88 | 89 | //printf("\n %d %d %d",tid,start,stop); 90 | 91 | pthread_barrier_wait(arg->barrier); 92 | 93 | while(terminate==0) 94 | { 95 | //printf("\n Start:%d",tid); 96 | for(v=start;vbarrier); 102 | 103 | terminate = 1; 104 | 105 | for(v=start;v=N) 117 | break; 118 | 119 | //pthread_mutex_lock(&locks[neighbor]); 120 | 121 | //relax 122 | if((D[W_index[v][i]] > (D[v] + W[v][i]))) //relax, update distance 123 | D_temp[W_index[v][i]] = D[v] + W[v][i]; 124 | //printf("\n %d",D_temp[W_index[v][i]]); 125 | //pthread_mutex_unlock(&locks[neighbor]); 126 | } 127 | } 128 | 129 | pthread_barrier_wait(arg->barrier); 130 | 131 | for(v=start;vbarrier); 140 | cntr_0++; 141 | } 142 | //printf("\n terminate %d",tid); 143 | 144 | if(tid==0) 145 | cntr = cntr_0; 146 | 147 | pthread_barrier_wait(arg->barrier); 148 | 149 | return NULL; 150 | } 151 | 152 | // Create a dotty graph named 'fn'. 153 | void make_dot_graph(int **W,int **W_index,int *exist,int *D,int N,int DEG,const char *fn) 154 | { 155 | FILE *of = fopen(fn,"w"); 156 | if (!of) { 157 | printf ("Unable to open output file %s.\n",fn); 158 | exit (EXIT_FAILURE); 159 | } 160 | 161 | fprintf (of,"digraph D {\n" 162 | " rankdir=LR\n" 163 | " size=\"4,3\"\n" 164 | " ratio=\"fill\"\n" 165 | " edge[style=\"bold\"]\n" 166 | " node[shape=\"circle\",style=\"filled\"]\n"); 167 | 168 | // Write out all edges. 169 | for (int i = 0; i != N; ++i) { 170 | if (exist[i]) { 171 | for (int j = 0; j != DEG; ++j) { 172 | if (W_index[i][j] != INT_MAX) { 173 | fprintf (of,"%d -> %d [label=\"%d\"]\n",i,W_index[i][j],W[i][j]); 174 | } 175 | } 176 | } 177 | } 178 | 179 | # ifdef DISTANCE_LABELS 180 | // We label the vertices with a distance, if there is one. 181 | fprintf (of,"0 [fillcolor=\"red\"]\n"); 182 | for (int i = 0; i != N; ++i) { 183 | if (D[i] != INT_MAX) { 184 | fprintf (of,"%d [label=\"%d (%d)\"]\n",i,i,D[i]); 185 | } 186 | } 187 | # endif 188 | 189 | fprintf (of,"}\n"); 190 | 191 | fclose (of); 192 | } 193 | 194 | int main(int argc, char** argv) 195 | { 196 | if (argc < 3) { 197 | printf ("Usage: %s \n",argv[0]); 198 | return 1; 199 | } 200 | int N = 0; 201 | int DEG = 0; 202 | FILE *file0 = NULL; 203 | 204 | const int select = atoi(argv[1]); 205 | const int P = atoi(argv[2]); 206 | if(select==0) 207 | { 208 | N = atoi(argv[3]); 209 | DEG = atoi(argv[4]); 210 | printf("\nGraph with Parameters: N:%d DEG:%d\n",N,DEG); 211 | } 212 | 213 | if (!P) { 214 | printf ("Error: Thread count must be a valid integer greater than 0."); 215 | return 1; 216 | } 217 | 218 | if(select==1) 219 | { 220 | const char *filename = argv[3]; 221 | file0 = fopen(filename,"r"); 222 | if (!file0) { 223 | printf ("Error: Unable to open input file '%s'\n",filename); 224 | return 1; 225 | } 226 | N = 2000000; //can be read from file if needed, this is a default upper limit 227 | DEG = 16; //also can be reda from file if needed, upper limit here again 228 | } 229 | 230 | int lines_to_check=0; 231 | char c; 232 | int number0; 233 | int number1; 234 | int previous_node = -1; 235 | int inter = -1; 236 | 237 | if (DEG > N) 238 | { 239 | fprintf(stderr, "Degree of graph cannot be grater than number of Vertices\n"); 240 | exit(EXIT_FAILURE); 241 | } 242 | 243 | int* D; 244 | int* D_temp; 245 | int* Q; 246 | 247 | if (posix_memalign((void**) &D, 64, N * sizeof(int))) 248 | { 249 | fprintf(stderr, "Allocation of memory failed\n"); 250 | exit(EXIT_FAILURE); 251 | } 252 | if(posix_memalign((void**) &D_temp, 64, N * sizeof(int))) 253 | { 254 | fprintf(stderr, "Allocation of memory failed\n"); 255 | exit(EXIT_FAILURE); 256 | } 257 | if( posix_memalign((void**) &Q, 64, N * sizeof(int))) 258 | { 259 | fprintf(stderr, "Allocation of memory failed\n"); 260 | exit(EXIT_FAILURE); 261 | } 262 | if( posix_memalign((void**) &exist, 64, N * sizeof(int))) 263 | { 264 | fprintf(stderr, "Allocation of memory failed\n"); 265 | exit(EXIT_FAILURE); 266 | } 267 | if(posix_memalign((void**) &id, 64, N * sizeof(int))) 268 | { 269 | fprintf(stderr, "Allocation of memory failed\n"); 270 | exit(EXIT_FAILURE); 271 | } 272 | int d_count = N; 273 | pthread_barrier_t barrier; 274 | 275 | int** W = (int**) malloc(N*sizeof(int*)); 276 | int** W_index = (int**) malloc(N*sizeof(int*)); 277 | for(int i = 0; i < N; i++) 278 | { 279 | int ret = posix_memalign((void**) &W[i], 64, DEG*sizeof(int)); 280 | int re1 = posix_memalign((void**) &W_index[i], 64, DEG*sizeof(int)); 281 | if (ret != 0 || re1!=0) 282 | { 283 | fprintf(stderr, "Could not allocate memory\n"); 284 | exit(EXIT_FAILURE); 285 | } 286 | } 287 | 288 | for(int i=0;i3) 307 | { 308 | int f0 = fscanf(file0, "%d %d", &number0,&number1); 309 | if(f0 != 2 && f0 != EOF) 310 | { 311 | printf ("Error: Read %d values, expected 2. Parsing failed.\n",f0); 312 | exit (EXIT_FAILURE); 313 | } 314 | //printf("\n%d %d",number0,number1); 315 | 316 | if (number0 >= N) { 317 | printf ("Error: Node %d exceeds maximum graph size of %d.\n",number0,N); 318 | exit (EXIT_FAILURE); 319 | } 320 | 321 | exist[number0] = 1; exist[number1] = 1; 322 | id[number0] = number0; 323 | if(number0==previous_node) { 324 | inter++; 325 | } else { 326 | inter=0; 327 | } 328 | 329 | // Make sure we haven't exceeded our maximum degree. 330 | if (inter >= DEG) { 331 | printf ("Error: Node %d, maximum degree of %d exceeded.\n",number0,DEG); 332 | exit (EXIT_FAILURE); 333 | } 334 | 335 | // We don't support parallel edges, so check for that and ignore. 336 | bool exists = false; 337 | for (int i = 0; i != inter; ++i) { 338 | if (W_index[number0][i] == number1) { 339 | exists = true; 340 | break; 341 | } 342 | } 343 | 344 | if (!exists) { 345 | W[number0][inter] = inter+1; 346 | W_index[number0][inter] = number1; 347 | previous_node = number0; 348 | } 349 | } 350 | } //W[2][0] = -1; 351 | } 352 | 353 | //Generate a uniform random graph 354 | if(select==0) 355 | { 356 | init_weights(N, DEG, W, W_index); 357 | } 358 | 359 | //Synchronization Variables 360 | pthread_barrier_init(&barrier, NULL, P); 361 | pthread_mutex_init(&lock, NULL); 362 | for(int i=0; i (D[u] + W[u][i]) && (W_index[u][i]!=-1 && W_index[u][i] last) 501 | { 502 | W_index[i][j] = neighbor; 503 | last = W_index[i][j]; 504 | } 505 | else 506 | { 507 | if(last < (N-1)) 508 | { 509 | W_index[i][j] = (last + 1); 510 | last = W_index[i][j]; 511 | } 512 | } 513 | } 514 | else 515 | { 516 | last = W_index[i][j]; 517 | } 518 | if(W_index[i][j]>=N) 519 | { 520 | W_index[i][j] = N-1; 521 | } 522 | } 523 | } 524 | 525 | // Populate Cost Array 526 | for(int i = 0; i < N; i++) 527 | { 528 | for(int j = 0; j < DEG; j++) 529 | { 530 | double v = drand48(); 531 | /*if(v > 0.8 || W_index[i][j] == -1) 532 | { W[i][j] = MAX; 533 | W_index[i][j] = -1; 534 | } 535 | 536 | else*/ if(W_index[i][j] == i) 537 | W[i][j] = 0; 538 | 539 | else 540 | W[i][j] = (int) (v*100) + 1; 541 | //printf(" %d ",W_index[i][j]); 542 | } 543 | //printf("\n"); 544 | } 545 | } 546 | -------------------------------------------------------------------------------- /apps/triangle_counting/Makefile: -------------------------------------------------------------------------------- 1 | 2 | TRGS = triangle_counting_lock triangle_counting_atomic sorted_neighbors_tri_lock 3 | 4 | LIBS += -lpthread -lrt 5 | 6 | CXXFLAGS = -g --std=c++0x -O3 7 | CXXFLAGS += #-Wall -Werror 8 | 9 | all: $(TRGS) 10 | 11 | triangle_counting_lock: triangle_counting_lock.cc 12 | triangle_counting_atomic: triangle_counting_atomic.cc 13 | sorted_neighbors_tri_lock: sorted_neighbors_tri_lock.cc 14 | 15 | clean: 16 | rm -f $(TRGS) *.o *.dot 17 | 18 | %: %.cc ; 19 | $(CXX) $(CXXFLAGS) $< -o $@ $(LIBS) 20 | -------------------------------------------------------------------------------- /apps/triangle_counting/README.md: -------------------------------------------------------------------------------- 1 | Triangle Counting 2 | ================= 3 | 4 | Run ```make``` to generate the required executables, then use the syntax below to run the benchmark 5 | 6 | The first argument to the executable specifies whether you want to read the graph from a file (1), or generate a synthetic one internally (0). 7 | 8 | **Input Graph from File** 9 | 10 | To run with P number of threads, and an .gr type (vertex edge) input file, 11 | ```./triangle_counting_lock 1 P ``` 12 | 13 | To run a matrix format file (.mtx) 14 | ```./triangle_counting_lock 2 P ``` 15 | 16 | The input file can be used as: 17 | sample.txt 18 | OR any other file such as road networks from the SNAP datasets (e.g. A FaceBook Graph) 19 | https://snap.stanford.edu/data/ 20 | 21 | **Generate and Input using the Synthetic Graph Generator** 22 | 23 | To run with P number of threads, N vertices, and DEG edges per vertex 24 | ```./triangle_counting_lock 0 P N DEG``` 25 | 26 | **Notes** 27 | 28 | The executable then outputs the time in seconds that the program took to run, as well as the number of triangles counted. 29 | 30 | The file utilizing atomic instructions has the same arguments as specified above. 31 | 32 | The file sorted_neighbors_tri_lock.cc contains a variation of the algorithm that required sorted neighbors. This is run the same way as above, although lines 96 and 97 may need to be commented out to allow graphs having forward progressing triangle connections. 33 | -------------------------------------------------------------------------------- /apps/triangle_counting/sample.txt: -------------------------------------------------------------------------------- 1 | # Directed graph (each unordered pair of nodes is saved once): roadNet-CA.txt 2 | # Sample California road network 3 | # Nodes: 1965206 Edges: 5533214 4 | # FromNodeId ToNodeId 5 | 0 1 6 | 0 2 7 | 0 469 8 | 1 0 9 | 1 6 10 | 1 385 11 | 2 0 12 | 2 3 13 | 469 0 14 | 469 380 15 | 469 37415 16 | 6 1 17 | 6 5 18 | 385 1 19 | 385 384 20 | 385 386 21 | 3 2 22 | 3 4 23 | 3 419 24 | 3 422 25 | 4 3 26 | 4 5 27 | 4 98 28 | 4 420 29 | 419 3 30 | 419 420 31 | 419 35698 32 | 422 3 33 | 422 183 34 | 422 423 35 | 422 37415 36 | 5 4 37 | 5 6 38 | 5 98 39 | 98 4 40 | 98 5 41 | 98 470 42 | 98 35729 43 | 420 4 44 | 420 419 45 | 420 35709 46 | 7 8 47 | 7 9 48 | 7 79 49 | 8 7 50 | 8 33 51 | 9 7 52 | 9 10 53 | 9 84 54 | 79 7 55 | 79 78 56 | 79 119 57 | 33 8 58 | 33 32 59 | 33 34 60 | 10 9 61 | 10 11 62 | 10 84 63 | 10 110 64 | 84 9 65 | 84 10 66 | 84 83 67 | 84 85 68 | 11 10 69 | 11 12 70 | 11 110 71 | 110 10 72 | 110 11 73 | 110 111 74 | 110 112 75 | 12 11 76 | 12 13 77 | 12 95 78 | 12 108 79 | 13 12 80 | 13 14 81 | 13 94 82 | 13 95 83 | 108 12 84 | 108 109 85 | 108 113 86 | 108 123 87 | 95 12 88 | 95 13 89 | 95 96 90 | 14 13 91 | 14 15 92 | 14 16 93 | 14 77 94 | 94 13 95 | 94 77 96 | 94 93 97 | 15 14 98 | 16 14 99 | 16 17 100 | 77 14 101 | 77 17 102 | 77 94 103 | 17 16 104 | 17 18 105 | 17 77 106 | 17 3254 107 | 18 17 108 | 18 19 109 | 18 3254 110 | 3254 17 111 | 3254 18 112 | 3254 3255 113 | 3254 36971 114 | 19 18 115 | 19 20 116 | 19 23 117 | 20 19 118 | 20 21 119 | 20 22 120 | 23 19 121 | 23 24 122 | 23 25 123 | 21 20 124 | 22 20 125 | 24 23 126 | 25 23 127 | 25 26 128 | 25 27 129 | 26 25 130 | 27 25 131 | 27 28 132 | 27 29 133 | 28 27 134 | 29 27 135 | 29 30 136 | 29 3255 137 | 30 29 138 | 30 31 139 | 30 3247 140 | 30 3253 141 | 3255 29 142 | 3255 3253 143 | 3255 3254 144 | 3255 35943 145 | 31 30 146 | 31 32 147 | 31 3246 148 | 3247 30 149 | 3247 3248 150 | 3247 3249 151 | 3253 30 152 | 3253 3204 153 | 3253 3255 154 | 3253 35950 155 | 32 31 156 | 32 33 157 | 32 2203 158 | 3246 31 159 | 3246 2203 160 | 3246 3252 161 | 3246 3257 162 | 2203 32 163 | 2203 2146 164 | 2203 2204 165 | 2203 3246 166 | 34 33 167 | 35 36 168 | 35 50 169 | 35 1199 170 | 36 35 171 | 36 37 172 | 36 35885 173 | 36 1645159 174 | 50 35 175 | 50 49 176 | 50 185 177 | 1199 35 178 | 1199 1198 179 | 1199 1205 180 | 37 36 181 | 37 38 182 | 37 1641586 183 | 35885 36 184 | 35885 35884 185 | 35885 1645157 186 | 1645159 36 187 | 1645159 1645156 188 | 1645159 1645157 189 | 1645159 1648644 190 | 38 37 191 | 38 39 192 | 38 1641586 193 | 1641586 37 194 | 1641586 38 195 | 1641586 1633418 196 | 39 38 197 | 39 40 198 | 39 1641587 199 | 40 39 200 | 40 41 201 | 40 1641577 202 | 1641587 39 203 | 1641587 1633418 204 | 1641587 1641576 205 | 1641587 1641606 206 | 41 40 207 | 41 42 208 | 41 1641355 209 | 1641577 40 210 | 1641577 1641363 211 | 1641577 1641576 212 | 42 41 213 | 42 43 214 | 42 1639779 215 | 1641355 41 216 | 1641355 1628954 217 | 1641355 1639780 218 | 1641355 1641363 219 | 43 42 220 | 43 44 221 | 43 1639779 222 | 1639779 42 223 | 1639779 43 224 | 1639779 1639780 225 | 44 43 226 | 44 45 227 | 44 1542024 228 | 45 44 229 | 45 46 230 | 45 1154 231 | 45 1538392 232 | 1542024 44 233 | 1542024 1542023 234 | 1542024 1639781 235 | 46 45 236 | 46 47 237 | 46 27108 238 | 46 27325 239 | 1154 45 240 | 1154 1153 241 | 1154 1155 242 | 1538392 45 243 | 1538392 1538362 244 | 1538392 1538390 245 | 1538392 1538391 246 | 47 46 247 | 47 48 248 | 47 27325 249 | 27108 46 250 | 27108 27107 251 | 27108 27250 252 | 27325 46 253 | 27325 47 254 | 27325 27323 255 | 27325 27335 256 | 48 47 257 | 48 49 258 | 48 27343 259 | 49 48 260 | 49 50 261 | 49 184 262 | 27343 48 263 | 27343 27342 264 | 27343 35887 265 | 27343 39411 266 | 184 49 267 | 184 185 268 | 184 35886 269 | 185 50 270 | 185 184 271 | 185 1198 272 | 52 53 273 | 52 54 274 | 52 4152 275 | 53 52 276 | 53 54 277 | 53 223 278 | 53 225 279 | 54 52 280 | 54 53 281 | 54 4120 282 | 4152 52 283 | 4152 4148 284 | 4152 4153 285 | 4152 4156 286 | 223 53 287 | 223 224 288 | 223 3937 289 | 223 4113 290 | 225 53 291 | 225 224 292 | 225 4114 293 | 225 4148 294 | 4120 54 295 | 4120 3937 296 | 4120 4153 297 | 4120 4154 298 | 55 56 299 | 55 57 300 | 55 1068 301 | 55 1099 302 | 56 55 303 | 56 76 304 | 56 1069 305 | 57 55 306 | 57 58 307 | 57 1071 308 | 57 1072 309 | 1068 55 310 | 1068 1069 311 | 1068 1096 312 | 1068 1116 313 | 1068 36235 314 | 1099 55 315 | 76 56 316 | 76 74 317 | 76 1075 318 | 1069 56 319 | 1069 1068 320 | 1069 1116 321 | 58 57 322 | 58 59 323 | 58 1089 324 | 58 32419 325 | 1072 57 326 | 1072 1070 327 | 1072 32419 328 | 1071 57 329 | 1071 1070 330 | 1071 1098 331 | 1071 1110 332 | 59 58 333 | 59 60 334 | 59 61 335 | 59 62 336 | 1089 58 337 | 1089 62 338 | 1089 171 339 | 1089 172 340 | 32419 58 341 | 32419 1072 342 | 60 59 343 | 61 59 344 | 62 59 345 | 62 63 346 | 62 1089 347 | 63 62 348 | 63 64 349 | 63 339 350 | 64 63 351 | 64 65 352 | 64 2220 353 | 339 63 354 | 339 338 355 | 339 341 356 | 339 36187 357 | 65 64 358 | 65 66 359 | 65 2155 360 | 65 2157 361 | 2220 64 362 | 2220 2219 363 | 2220 2221 364 | 66 65 365 | 66 67 366 | 66 68 367 | 66 2254 368 | 2155 65 369 | 2155 2156 370 | 2155 2254 371 | 2157 65 372 | 2157 2158 373 | 2157 2161 374 | 2157 2219 375 | 67 66 376 | 68 66 377 | 68 69 378 | 68 70 379 | 68 2251 380 | 2254 66 381 | 2254 2155 382 | 2254 2252 383 | 69 68 384 | 70 68 385 | 70 71 386 | 70 1052 387 | 70 2251 388 | 2251 68 389 | 2251 70 390 | 2251 2252 391 | 71 70 392 | 71 72 393 | 71 1049 394 | 1052 70 395 | 1052 1050 396 | 1052 2256 397 | 1052 2258 398 | 72 71 399 | 72 73 400 | 72 74 401 | -------------------------------------------------------------------------------- /apps/triangle_counting/sorted_neighbors_tri_lock.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | //#include "carbon_user.h" /* For the Graphite Simulator*/ 5 | #include 6 | #include 7 | #include 8 | #include "../../common/mtx.h" 9 | 10 | #define MAX 100000000 11 | #define INT_MAX 100000000 12 | #define BILLION 1E9 13 | 14 | //Thread Argument Structure 15 | typedef struct 16 | { 17 | int* local_min; 18 | int* global_min; 19 | int* Q; 20 | int* D; 21 | //int** W; 22 | int** W_index; 23 | int* d_count; 24 | int tid; 25 | int P; 26 | int N; 27 | int DEG; 28 | pthread_barrier_t* barrier_total; 29 | pthread_barrier_t* barrier; 30 | } thread_arg_t; 31 | 32 | 33 | 34 | //Function Declarations 35 | int initialize_single_source(int* D, int* Q, int source, int N); 36 | void init_weights(int N, int DEG, int** W, int** W_index); 37 | 38 | //Global Variables 39 | pthread_mutex_t lock; 40 | pthread_mutex_t *locks; 41 | //pthread_mutex_t locks[4194304]; //Lock for each vertex 42 | int local_min_buffer[1024]; 43 | int Total_tid[1024] = {0}; //To store triangles per thread 44 | int global_min_buffer; 45 | int P_global = 256; 46 | //int **W; 47 | //int **W_index; 48 | //int *D; 49 | //int *Q; 50 | //int *edges; 51 | //int *exist; 52 | //int *unique; 53 | //int largest=0; 54 | //int degree=0; 55 | int Total_Tri = -1.0; //Stores total triangles 56 | thread_arg_t thread_arg[1024]; //Max threads and pthread handlers 57 | pthread_t thread_handle[1024]; 58 | 59 | //Primary Parallel Function 60 | void* do_work(void* args) 61 | { 62 | //Thread Variables 63 | volatile thread_arg_t* arg = (thread_arg_t*) args; 64 | int tid = arg->tid; 65 | int P = arg->P; 66 | volatile int* Q = arg->Q; 67 | int* D = arg->D; //stores edges 68 | //int** W = arg->W; 69 | int** W_index = arg->W_index; //Graph connections 70 | //const int N = arg->N; 71 | int v = 0; //for each vertex 72 | int local_count = 0;; 73 | double P_d = P; 74 | double tid_d = tid; 75 | double largest_d = largest + 1.0; 76 | 77 | int start = 0; //tid * DEG / (arg->P); 78 | int stop = 0; //(tid+1) * DEG / (arg->P); 79 | 80 | //Chunk work into threads 81 | double start_d = (tid_d) * (largest_d/P_d); 82 | double stop_d = (tid_d+1.0) * (largest_d/P_d); 83 | start = start_d; //tid * (largest) / (P); 84 | stop = stop_d; //(tid+1) * (largest) / (P); 85 | //printf("\n %d %d %d",tid,start,stop); 86 | 87 | pthread_barrier_wait(arg->barrier_total); 88 | 89 | //Look at all edges 90 | for(v=start;v v) 98 | break; 99 | int counter = 0; 100 | 101 | for(int j = 0; j< edges[neighbor]; j++) 102 | { 103 | if(W_index[neighbor][j] > neighbor) 104 | break; 105 | 106 | //printf("\n %d %d %d", neighbor, edges[neighbor], it); 107 | while(W_index[v][counter] < W_index[neighbor][j]) 108 | { 109 | counter++; 110 | } 111 | if(W_index[neighbor][j] == W_index[v][counter]) 112 | Total_tid[tid]++;//local_count++; 113 | } 114 | 115 | //if(neighbor>=largest) 116 | // continue; 117 | //pthread_mutex_lock(&locks[neighbor]); 118 | //D[neighbor]++; //Add edges 119 | //Q[neighbor] = 0; 120 | //pthread_mutex_unlock(&locks[neighbor]); 121 | } 122 | } 123 | } 124 | //Total_tid[tid] = local_count; 125 | 126 | pthread_barrier_wait(arg->barrier_total); 127 | 128 | //The master thread sums up all triangles 129 | if(tid==0) 130 | { 131 | for(int i=0;ibarrier_total); 138 | 139 | return NULL; 140 | } 141 | 142 | 143 | int main(int argc, char** argv) 144 | { 145 | /*int select_opt=0; 146 | int ca; 147 | 148 | while ((ca = getopt(argc, argv, "s:::t::m::")) != -1) 149 | switch(ca) 150 | { 151 | case 's': 152 | select_opt = 0; 153 | break; 154 | case 't': 155 | select_opt = 1; 156 | break; 157 | case 'm': 158 | select_opt = 2; 159 | break; 160 | default: 161 | select_opt = 0; 162 | break; 163 | }*/ 164 | 165 | //char filename[100]; 166 | FILE *file0 = NULL; 167 | int N = 0; 168 | int DEG = 0; 169 | int select = atoi(argv[1]); 170 | 171 | //For reading graph from text file 172 | if(select==1) 173 | { 174 | const char *filename = argv[3]; 175 | //printf("Please Enter The Name Of The File You Would Like To Fetch\n"); 176 | //scanf("%s", filename); 177 | file0 = fopen(filename,"r"); 178 | } 179 | 180 | //Matrix .mtx file 181 | if(select==2) 182 | { 183 | const char *filename = argv[3]; 184 | mtx(filename); 185 | //select = 1; 186 | file0 = fopen(conv_file,"r"); 187 | } 188 | 189 | int lines_to_check=0; 190 | char c; 191 | int number0; 192 | int number1; 193 | int inter = -1; 194 | 195 | if(select==1) 196 | { 197 | N = 0;//2097152; //can be read from file if needed, this is a default upper limit 198 | DEG = 0;//26; //also can be reda from file if needed, upper limit here again 199 | FILE *file_gr = NULL; 200 | const char *filename0 = argv[3]; 201 | file_gr = fopen(filename0,"r"); 202 | char ch0; 203 | int number_of_lines0 = 0; 204 | while(EOF != (ch0=getc(file_gr))) 205 | { 206 | if(ch0=='\n') 207 | number_of_lines0++; 208 | if(number_of_lines0>3) 209 | { 210 | int f0 = fscanf(file_gr, "%d %d", &number0, &number1); 211 | if(f0 != 2 && f0 !=EOF) 212 | { 213 | printf ("Error: Read %d values, expected 2. Parsing failed.\n",f0); 214 | exit (EXIT_FAILURE); 215 | } 216 | if(number0>N) 217 | N = number0; 218 | if(number1>N) 219 | N = number1; 220 | } 221 | } 222 | fclose(file_gr); //Now N has the largest Vertex ID 223 | N++; 224 | 225 | int *temp; 226 | number_of_lines0 = 0; 227 | if(posix_memalign((void**) &temp, 64, N * sizeof(int))) 228 | { 229 | fprintf(stderr, "Allocation of memory failed\n"); 230 | exit(EXIT_FAILURE); 231 | } 232 | for(int i=0;i3) 240 | { 241 | int f0 = fscanf(file_gr, "%d %d", &number0, &number1); 242 | if(f0 != 2 && f0 !=EOF) 243 | { 244 | printf ("Error: Read %d values, expected 2. Parsing failed.\n",f0); 245 | exit (EXIT_FAILURE); 246 | } 247 | temp[number0]++; 248 | } 249 | } 250 | fclose(file_gr); 251 | for(int i=0;iDEG) 254 | DEG = temp[i]; 255 | } 256 | free(temp); 257 | printf("\n .gr graph with parameters: Vertices:%d Degree:%d \n",N,DEG); 258 | } 259 | 260 | 261 | if(select==2) 262 | { 263 | N = largest; 264 | DEG = degree; 265 | select = 1; 266 | } 267 | 268 | const int P1 = atoi(argv[2]); 269 | 270 | int P = P1; 271 | P_global = P1; 272 | 273 | if(select==0) 274 | { 275 | N = atoi(argv[3]); 276 | DEG = atoi(argv[4]); 277 | printf("\nGraph with Parameters: N:%d DEG:%d\n",N,DEG); 278 | } 279 | if (DEG > N) 280 | { 281 | fprintf(stderr, "Degree of graph cannot be grater than number of Vertices\n"); 282 | exit(EXIT_FAILURE); 283 | } 284 | 285 | //Memory Allocations 286 | if(select!=2) { 287 | if(posix_memalign((void**) &edges, 64, (N+2) * sizeof(int))) 288 | { 289 | fprintf(stderr, "Allocation of memory failed\n"); 290 | exit(EXIT_FAILURE); 291 | } 292 | if(posix_memalign((void**) &exist, 64, (N+2) * sizeof(int))) 293 | { 294 | fprintf(stderr, "Allocation of memory failed\n"); 295 | exit(EXIT_FAILURE); 296 | } 297 | } 298 | int *D; int *Q; 299 | if(posix_memalign((void**) &D, 64, N * sizeof(int))) 300 | { 301 | fprintf(stderr, "Allocation of memory failed\n"); 302 | exit(EXIT_FAILURE); 303 | } 304 | if(posix_memalign((void**) &Q, 64, N * sizeof(int))) 305 | { 306 | fprintf(stderr, "Allocation of memory failed\n"); 307 | exit(EXIT_FAILURE); 308 | } 309 | 310 | int d_count = N; 311 | pthread_barrier_t barrier_total; 312 | pthread_barrier_t barrier; 313 | 314 | if(select!=2) { 315 | W = (int**) malloc((N+2)*sizeof(int*)); 316 | W_index = (int**) malloc((N+2)*sizeof(int*)); 317 | for(int i = 0; i < N+2; i++) 318 | { 319 | //W[i] = (int *)malloc(sizeof(int)*N); 320 | if(posix_memalign((void**) &W[i], 64, (DEG+1)*sizeof(int))) 321 | { 322 | fprintf(stderr, "Allocation of memory failed\n"); 323 | exit(EXIT_FAILURE); 324 | } 325 | if(posix_memalign((void**) &W_index[i], 64, (DEG+1)*sizeof(int))) 326 | { 327 | fprintf(stderr, "Allocation of memory failed\n"); 328 | exit(EXIT_FAILURE); 329 | } 330 | } 331 | 332 | for(int i=0;i3) 353 | { 354 | int f0 = fscanf(file0, "%d %d", &number0,&number1); 355 | if(f0 != 2 && f0 != EOF) 356 | { 357 | printf ("Error: Read %d values, expected 2. Parsing failed.\n",f0); 358 | exit (EXIT_FAILURE); 359 | } 360 | //printf("\n%d %d",number0,number1); 361 | if(number0>largest) 362 | largest=number0; 363 | if(number1>largest) 364 | largest=number1; 365 | inter = edges[number0]; 366 | 367 | //W[number0][inter] = drand48(); 368 | W_index[number0][inter] = number1; 369 | //previous_node = number0; 370 | edges[number0]++; 371 | exist[number0]=1; exist[number1]=1; 372 | } 373 | } 374 | printf("\nFile Read, Largest Vertex:%d",largest); 375 | } 376 | 377 | //For synthetic graphs 378 | if(select==0) 379 | { 380 | init_weights(N, DEG, W, W_index); 381 | largest = N; 382 | } 383 | 384 | //Initialize Synchronization Variables 385 | pthread_barrier_init(&barrier_total, NULL, P); 386 | pthread_barrier_init(&barrier, NULL, P); 387 | pthread_mutex_init(&lock, NULL); 388 | locks = (pthread_mutex_t*) malloc((largest+16) * sizeof(pthread_mutex_t)); 389 | 390 | for(int i=0; i last) 511 | { 512 | W_index[i][j] = neighbor; 513 | last = W_index[i][j]; 514 | } 515 | else 516 | { 517 | if(last < (N-1)) 518 | { 519 | W_index[i][j] = (last + 1); 520 | last = W_index[i][j]; 521 | } 522 | } 523 | } 524 | else 525 | { 526 | last = W_index[i][j]; 527 | } 528 | if(W_index[i][j]>=N) 529 | { 530 | W_index[i][j] = N-1; 531 | } 532 | } 533 | } 534 | 535 | // Populate Cost Array 536 | for(int i = 0; i < N; i++) 537 | { 538 | for(int j = 0; j < DEG; j++) 539 | { 540 | double v = drand48(); 541 | /*if(v > 0.8 || W_index[i][j] == -1) 542 | { W[i][j] = MAX; 543 | W_index[i][j] = -1; 544 | } 545 | 546 | else*/ if(W_index[i][j] == i) 547 | W[i][j] = 0; 548 | 549 | else 550 | W[i][j] = (int) (v*100) + 1; 551 | //printf(" %d ",W_index[i][j]); 552 | } 553 | //printf("\n"); 554 | } 555 | } 556 | 557 | -------------------------------------------------------------------------------- /apps/tsp/Makefile: -------------------------------------------------------------------------------- 1 | 2 | TRGS = tsp 3 | 4 | LIBS += -lpthread -lrt 5 | 6 | CXXFLAGS = -g --std=c++0x -O3 7 | CXXFLAGS += -Wall -Werror 8 | 9 | all: $(TRGS) 10 | 11 | tsp: tsp.cc 12 | 13 | clean: 14 | rm -f $(TRGS) *.o *.dot 15 | 16 | %: %.cc ; 17 | $(CXX) $(CXXFLAGS) $< -o $@ $(LIBS) 18 | -------------------------------------------------------------------------------- /apps/tsp/README.md: -------------------------------------------------------------------------------- 1 | Travelling Salesman Problem 2 | =========================== 3 | 4 | Run ```make``` to generate the required executable, then run using the syntax below 5 | 6 | To run with P number of threads, C cities 7 | ```./tsp P C``` 8 | 9 | e.g. 10 | ```./tsp 2 16``` 11 | 12 | **Notes** 13 | 14 | Input threads must be in powers of 2. 15 | 16 | The executable then outputs the time in seconds that the program took to run. 17 | -------------------------------------------------------------------------------- /apps/tsp/tsp.cc: -------------------------------------------------------------------------------- 1 | /* 2 | Travelling Salesman Problem (TSP), Uses Parallel Branch and Bound to find paths with least distances 3 | This program was originally written/modified by george kurian (MIT, Google), Hank Hoffmann (MIT) 4 | Modified later by Masab Ahmad (UConn) 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | using std::vector; 14 | using std::list; 15 | //#include "carbon_user.h" /*For the Graphite Simulator*/ 16 | 17 | // #define DEBUG 1 18 | #define INF 100000000 19 | 20 | //Default graph edge weights 21 | int _WEIGHTS[5][5] = { 22 | { INF, 2, 3, 1, INF }, 23 | { INF, INF, 5, 7, 4 }, 24 | { 3, 1, INF, 6, 1 }, 25 | { 8, 2, 4, INF, 3 }, 26 | { 7, INF, 6, 1, INF } 27 | }; 28 | 29 | //Graph Structure 30 | int** _weights; 31 | 32 | // Globals 33 | int _best_tour_cost ; 34 | int _best_tid; 35 | pthread_mutex_t _lock; 36 | 37 | //Graph Creation 38 | void initCities(int NUM_CITIES) 39 | { 40 | _weights = new int*[NUM_CITIES]; 41 | for (int i = 0; i < NUM_CITIES; i++) 42 | _weights[i] = new int[NUM_CITIES]; 43 | 44 | if(NUM_CITIES == 5) { 45 | for(int i = 0; i < NUM_CITIES; i++) { 46 | for(int j = 0; j < NUM_CITIES; j++) { 47 | _weights[i][j] = _WEIGHTS[i][j]; 48 | } 49 | } 50 | } 51 | else { 52 | for(int i = 0; i < NUM_CITIES; i++) { 53 | _weights[i][i] = INF; 54 | for(int j = i+1; j < NUM_CITIES; j++) { 55 | double v = drand48(); //Uniform Random edge weights 56 | 57 | _weights[i][j] = INF; 58 | if(v < 0.8) { 59 | int length = (int) (v * 100) + 1; 60 | _weights[i][j] = length; 61 | _weights[j][i] = length; 62 | } 63 | } 64 | } 65 | } 66 | } 67 | 68 | class PartialTour 69 | { 70 | public: 71 | PartialTour(int NUM_CITIES, int start_city); 72 | PartialTour(const PartialTour& tour); 73 | ~PartialTour(); 74 | 75 | vector& getPath() { return _path; } 76 | vector& getUnvisited() { return _unvisited; } 77 | const vector& getPath() const { return _path; } 78 | const vector& getUnvisited() const { return _unvisited; } 79 | int getCost() const { return _cost; } 80 | int getLength() const { return _length; } 81 | 82 | void setCost(int cost) { _cost = cost; } 83 | 84 | void addCity(int unvisited_idx); 85 | void print() const; 86 | 87 | private: 88 | vector _path; 89 | vector _unvisited; 90 | int _cost; 91 | int _length; 92 | }; 93 | 94 | PartialTour::PartialTour(int NUM_CITIES, int start_city) 95 | : _cost(0) 96 | , _length(1) 97 | { 98 | _path.push_back(start_city); 99 | for (int i = 0; i < NUM_CITIES; i++) 100 | { 101 | if (i != start_city) 102 | _unvisited.push_back(i); 103 | } 104 | } 105 | 106 | PartialTour::PartialTour(const PartialTour& tour) 107 | : _path(tour.getPath()) 108 | , _unvisited(tour.getUnvisited()) 109 | , _cost(tour.getCost()) 110 | , _length(tour.getLength()) 111 | {} 112 | 113 | PartialTour::~PartialTour() 114 | {} 115 | 116 | void 117 | PartialTour::addCity(int idx) 118 | { 119 | assert (_length >= 1); 120 | 121 | int city = _path.back(); 122 | int new_city = _unvisited[idx]; 123 | 124 | _cost += _weights [city] [new_city]; 125 | _length ++; 126 | _path.push_back(new_city); 127 | _unvisited[idx] = _unvisited.back(); 128 | _unvisited.pop_back(); 129 | } 130 | 131 | void 132 | PartialTour::print() const 133 | { 134 | printf("Cost: %d, Length: %d, Path: [", _cost, _length); 135 | for (vector::const_iterator it = _path.begin(); it != _path.end(); it++) 136 | printf("%d, ", *it); 137 | printf("], Unvisited: ["); 138 | for (vector::const_iterator it = _unvisited.begin(); it != _unvisited.end(); it++) 139 | printf("%d, ", *it); 140 | printf("]\n"); 141 | } 142 | 143 | typedef list WorkQueue; 144 | 145 | //Thread Argument Structure 146 | class ThreadData 147 | { 148 | public: 149 | ThreadData(int tid, WorkQueue& work_queue, int NUM_CITIES); 150 | ~ThreadData(); 151 | 152 | int getTid() const { return _tid; } 153 | WorkQueue& getWorkQueue() { return _work_queue; } 154 | PartialTour* getBestTour() { return _best_tour; } 155 | int getNumCities() const { return _NUM_CITIES; } 156 | 157 | private: 158 | int _tid; 159 | WorkQueue& _work_queue; 160 | PartialTour* _best_tour; 161 | int _NUM_CITIES; 162 | }; 163 | 164 | ThreadData::ThreadData(int tid, WorkQueue& work_queue, int NUM_CITIES) 165 | : _tid(tid) 166 | , _work_queue(work_queue) 167 | , _NUM_CITIES(NUM_CITIES) 168 | { 169 | _best_tour = new PartialTour(NUM_CITIES, 0); 170 | _best_tour->setCost(INF); 171 | } 172 | 173 | ThreadData::~ThreadData() 174 | {} 175 | 176 | //Primary Parallel Function 177 | void 178 | doWork(int tid, WorkQueue& work_queue, PartialTour* tour, PartialTour* best_tour, int NUM_CITIES) 179 | { 180 | int cost = tour->getCost(); 181 | int length = tour->getLength(); 182 | int city = tour->getPath().back(); 183 | 184 | #if DEBUG 185 | printf("Working - Tour: length = %d, cost = %d\n", length, cost); 186 | #endif 187 | 188 | if (length == NUM_CITIES) 189 | { 190 | cost += _weights [city] [0]; 191 | tour->setCost(cost); 192 | 193 | #if DEBUG 194 | printf("Updating best cost, was %d, now %d\n", best_tour->getCost(), cost); 195 | best_tour->print(); 196 | #endif 197 | 198 | if (cost < best_tour->getCost()) 199 | { 200 | *best_tour = *tour; 201 | 202 | pthread_mutex_lock(&_lock); 203 | if (cost < _best_tour_cost) 204 | { 205 | _best_tour_cost = cost; 206 | _best_tid = tid; 207 | #ifdef DEBUG 208 | printf("Best Tour: Cost(%i), Tid(%i)\n", _best_tour_cost, _best_tid); 209 | #endif 210 | } 211 | pthread_mutex_unlock(&_lock); 212 | } 213 | } 214 | 215 | else 216 | { 217 | vector& unvisited = tour->getUnvisited(); 218 | 219 | #if DEBUG 220 | tour->print(); 221 | #endif 222 | 223 | if (cost >= _best_tour_cost) // Pruning 224 | return; 225 | 226 | for (vector::iterator it = unvisited.begin(); it != unvisited.end(); it ++) 227 | { 228 | int new_city = *it; 229 | int new_cost = cost + _weights [city] [new_city]; 230 | 231 | if (new_cost < _best_tour_cost) // Pruning happens here 232 | { 233 | PartialTour* new_tour = new PartialTour(*tour); 234 | #if DEBUG 235 | printf(" Adding city %d to path\n", new_city); 236 | #endif 237 | new_tour->addCity(it - unvisited.begin()); 238 | work_queue.push_front(new_tour); 239 | } 240 | } 241 | } 242 | } 243 | 244 | //Master Parallel Function 245 | void* threadWork(void* targ) 246 | { 247 | ThreadData* arg = (ThreadData*) targ; 248 | int tid = arg->getTid(); 249 | WorkQueue& work_queue = arg->getWorkQueue(); 250 | PartialTour* best_tour = arg->getBestTour(); 251 | int NUM_CITIES = arg->getNumCities(); 252 | 253 | #ifdef DEBUG 254 | printf("Starting Thread: %i\n", tid); 255 | #endif 256 | 257 | int iter = 0; 258 | while (!work_queue.empty()) 259 | { 260 | #if DEBUG 261 | printf("Starting iter %d, queue length = %i\n", iter, (int) work_queue.size()); 262 | #endif 263 | 264 | PartialTour* tour = work_queue.front(); 265 | work_queue.pop_front(); 266 | doWork(tid, work_queue, tour, best_tour, NUM_CITIES); 267 | 268 | delete tour; 269 | 270 | #if DEBUG 271 | printf("Best Tour:\n"); 272 | best_tour->print(); 273 | printf("\n"); 274 | #endif 275 | 276 | iter ++; 277 | } 278 | 279 | #ifdef DEBUG 280 | printf("Ending Thread: %i\n", tid); 281 | #endif 282 | 283 | return NULL; 284 | } 285 | 286 | int 287 | getNumLevels(int NUM_THREADS, int NUM_CITIES) 288 | { 289 | int num_permutations = 1; 290 | for (int i = NUM_CITIES-1; i >= 1; i--) 291 | { 292 | num_permutations *= i; 293 | if (num_permutations >= NUM_THREADS) 294 | return (NUM_CITIES-i); 295 | } 296 | fprintf(stderr, "Too many threads\n"); 297 | return 0; 298 | } 299 | 300 | void 301 | generatePartialTours(PartialTour* tour, int num_levels, vector& partial_tour_vec) 302 | { 303 | int length = tour->getLength(); 304 | if (length <= num_levels) 305 | { 306 | vector& unvisited = tour->getUnvisited(); 307 | for (vector::iterator it = unvisited.begin(); it != unvisited.end(); it++) 308 | { 309 | PartialTour* new_tour = new PartialTour(*tour); 310 | new_tour->addCity(it - unvisited.begin()); 311 | generatePartialTours(new_tour, num_levels, partial_tour_vec); 312 | } 313 | delete tour; 314 | } 315 | else // (length > num_levels) 316 | { 317 | partial_tour_vec.push_back(tour); 318 | } 319 | } 320 | 321 | void 322 | dividePartialTours(const vector& partial_tour_vec, vector& work_queue_vec) 323 | { 324 | int queue_id = 0; 325 | for (vector::const_iterator it = partial_tour_vec.begin(); it != partial_tour_vec.end(); it++) 326 | { 327 | PartialTour* tour = *it; 328 | work_queue_vec[queue_id].push_back(tour); 329 | queue_id = (queue_id + 1) % (work_queue_vec.size()); 330 | } 331 | } 332 | 333 | int main(int argc, char** argv) 334 | { 335 | //Input Arguments 336 | int NUM_THREADS = atoi(argv[1]); 337 | int NUM_CITIES = atoi(argv[2]); 338 | 339 | printf("Starting TSP [Num Threads: %i, Num Cities: %i]\n", NUM_THREADS, NUM_CITIES); 340 | 341 | // Initialize globals 342 | _best_tour_cost = INF; 343 | _best_tid = -1; 344 | //Lock for upper distance bound 345 | pthread_mutex_init(&_lock, NULL); 346 | 347 | //Initialize Graph 348 | initCities(NUM_CITIES); 349 | 350 | vector partial_tour_vec; 351 | vector work_queue_vec(NUM_THREADS); 352 | 353 | int num_levels = getNumLevels(NUM_THREADS, NUM_CITIES); 354 | 355 | #ifdef DEBUG 356 | printf("Num Levels: %d\n\n", num_levels); 357 | #endif 358 | 359 | generatePartialTours(new PartialTour(NUM_CITIES, 0), num_levels, partial_tour_vec); 360 | 361 | #ifdef DEBUG 362 | printf("Partial Tours [START]:\n"); 363 | for (vector::iterator it = partial_tour_vec.begin(); it != partial_tour_vec.end(); it ++) 364 | (*it)->print(); 365 | printf("Partial Tours [END]:\n"); 366 | #endif 367 | 368 | dividePartialTours(partial_tour_vec, work_queue_vec); 369 | 370 | #ifdef DEBUG 371 | for (int i = 0 ; i < NUM_THREADS; i++) 372 | { 373 | printf("\nThread: %i\n", i); 374 | printf("Partial Tours [START]:\n"); 375 | for (WorkQueue::iterator it = work_queue_vec[i].begin(); it != work_queue_vec[i].end(); it ++) 376 | (*it)->print(); 377 | printf("Partial Tours [END]:\n\n"); 378 | } 379 | #endif 380 | 381 | ThreadData* thread_data[NUM_THREADS]; 382 | pthread_t thread_handle[NUM_THREADS]; 383 | 384 | for (int i = 0; i < NUM_THREADS; i++) 385 | thread_data[i] = new ThreadData(i, work_queue_vec[i], NUM_CITIES); 386 | 387 | // Enable Graphite performance and power models 388 | //CarbonEnableModels(); 389 | 390 | //Create threads 391 | for (int i = 1; i < NUM_THREADS; i++) 392 | { 393 | int ret = pthread_create(&thread_handle[i], NULL, threadWork, (void*) thread_data[i]); 394 | if (ret != 0) 395 | { 396 | fprintf(stderr, "Could not spawn thread"); 397 | exit(EXIT_FAILURE); 398 | } 399 | } 400 | threadWork((void*) thread_data[0]); //master thread spawns itself 401 | 402 | //Join threads 403 | for (int i = 1; i < NUM_THREADS; i++) 404 | { 405 | pthread_join(thread_handle[i], NULL); 406 | } 407 | 408 | // Disable Graphite performance and power models 409 | //CarbonDisableModels(); 410 | 411 | //Print TSP Data 412 | for (int i = 0 ; i < NUM_THREADS; i++) 413 | { 414 | printf("Thread: %i, Final Best Tour:\n", i); 415 | thread_data[i]->getBestTour()->print(); 416 | printf("\n"); 417 | } 418 | 419 | printf("Overall Best Tour:\n"); 420 | thread_data[_best_tid]->getBestTour()->print(); 421 | 422 | return 0; 423 | } 424 | -------------------------------------------------------------------------------- /common/barrier.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | volatile int passed = 0; // Number of barriers, passed by all threads. 5 | int bar=0; 6 | int PMAX=0; 7 | 8 | void barrier_wait() 9 | { 10 | int passed_old = passed; // Should be evaluated before incrementing *bar*! 11 | 12 | if(__sync_fetch_and_add(&bar,1) == (PMAX - 1)) 13 | { 14 | // The last thread, faced barrier. 15 | bar = 0; 16 | // *bar* should be reseted strictly before updating of barriers counter. 17 | __sync_synchronize(); 18 | passed++; // Mark barrier as passed. 19 | } 20 | else 21 | { 22 | // Not the last thread. Wait others. 23 | while(passed == passed_old) {}; 24 | // Need to synchronize cache with other threads, passed barrier. 25 | __sync_synchronize(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/mtx.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define MAX 100000000 6 | #define INT_MAX 100000000 7 | #define BILLION 1E9 8 | 9 | //Global Variables 10 | int **W; //Weights 11 | int **W_index; //Edges 12 | //int *D; //Working Array 13 | //int *Q; //Working Array 14 | int *edges; //Edges for each vertex 15 | int *exist; //Wherther the vertex exists in the graph 16 | int *unique; //Unique vertex 17 | int largest=0; //Largest Vertex in graph 18 | int degree=0; //Initialize Maximum Degree 19 | const char *conv_file; 20 | 21 | void mtx(const char* filename) 22 | { 23 | FILE *file_mtx_param = NULL; 24 | FILE *file_mtx_deg = NULL; 25 | FILE *file_mtx = NULL; 26 | //const char *filename = argv[3]; 27 | file_mtx_param = fopen(filename,"r"); 28 | int number_of_lines=0; 29 | int node_count =0; 30 | int intermediate=0; 31 | int edge_count =0; 32 | int first,second; 33 | char ch; 34 | while (EOF != (ch=getc(file_mtx_param))) 35 | { 36 | 37 | if(ch=='\n') 38 | number_of_lines++; 39 | if(number_of_lines==2) 40 | { 41 | int f0 = fscanf(file_mtx_param, "%d %d %d", &node_count,&intermediate,&edge_count); 42 | if(f0 != 3 && f0 != EOF) 43 | { 44 | printf ("Error: Read %d values, expected 2. Parsing failed.\n",f0); 45 | exit (EXIT_FAILURE); 46 | } 47 | break; 48 | } 49 | } 50 | number_of_lines=0; 51 | fclose(file_mtx_param); 52 | largest = node_count; 53 | printf("\nMatrix .mtx graph with Parameters: Vertices:%d Edges:%d",node_count,edge_count); 54 | 55 | if(posix_memalign((void**) &edges, 64, node_count * sizeof(int))) 56 | { 57 | fprintf(stderr, "Allocation of memory failed\n"); 58 | exit(EXIT_FAILURE); 59 | } 60 | if(posix_memalign((void**) &exist, 64, node_count * sizeof(int))) 61 | { 62 | fprintf(stderr, "Allocation of memory failed\n"); 63 | exit(EXIT_FAILURE); 64 | } 65 | for(int i=0;i2) 76 | { 77 | int f0 = fscanf(file_mtx_deg, "%d %d", &first,&second); 78 | if(f0 != 2 && f0 != EOF) 79 | exit (EXIT_FAILURE); 80 | edges[second-1]++; 81 | exist[second-1]=1; exist[first-1]=1; 82 | } 83 | } 84 | fclose(file_mtx_deg); 85 | 86 | degree=edges[0]; 87 | for(int i=1;idegree) 90 | degree = edges[i]; 91 | } 92 | printf("\nLargest Degree:%d\n",degree); 93 | number_of_lines = 0; 94 | ch = 'a'; 95 | 96 | /*if(posix_memalign((void**) &D, 64, node_count * sizeof(int))) 97 | { 98 | fprintf(stderr, "Allocation of memory failed\n"); 99 | exit(EXIT_FAILURE); 100 | } 101 | if(posix_memalign((void**) &Q, 64, node_count * sizeof(int))) 102 | { 103 | fprintf(stderr, "Allocation of memory failed\n"); 104 | exit(EXIT_FAILURE); 105 | }*/ 106 | printf("\nAllocated Working Arrays"); 107 | 108 | //W = (int**) malloc(node_count*sizeof(int*)); 109 | W_index = (int**) malloc(node_count*sizeof(int*)); 110 | for(int i = 0; i < node_count; i++) 111 | { 112 | //W[i] = (int *)malloc(sizeof(int)*N); 113 | /*if(posix_memalign((void**) &W[i], 64, degree*sizeof(int))) 114 | { 115 | fprintf(stderr, "Allocation of memory failed\n"); 116 | exit(EXIT_FAILURE); 117 | }*/ 118 | if(posix_memalign((void**) &W_index[i], 64, degree*sizeof(int))) 119 | { 120 | fprintf(stderr, "Allocation of memory failed\n"); 121 | exit(EXIT_FAILURE); 122 | } 123 | } 124 | printf("\nAllocated Weight/Index Arrays"); 125 | 126 | for(int i=0;i edge_count-100) 148 | // break; 149 | if(number_of_lines>2) 150 | { 151 | int f0 = fscanf(file_mtx, "%d %d", &first,&second); 152 | if(f0 != 2 && f0 != EOF) 153 | exit (EXIT_FAILURE); 154 | //if(number_of_lines >= 132500000) 155 | // printf("\n %d %d %d",first-1,second-1,number_of_lines); 156 | if((first-1 || second-1) > node_count) 157 | continue; 158 | inter = edges[second-1]; 159 | W_index[second-1][inter] = first-1; 160 | edges[second-1]++; 161 | } 162 | } 163 | fclose(file_mtx); 164 | printf("\nDone Allocating and Initializing"); 165 | 166 | //Create .gr file format from .mtx 167 | FILE *file_gr = NULL; 168 | conv_file = "rgg.gr"; 169 | file_gr = fopen(conv_file,"w"); 170 | fprintf(file_gr,"#.\n"); 171 | fprintf(file_gr,"#.\n"); 172 | fprintf(file_gr,"#.\n"); 173 | fprintf(file_gr,"p sp %d %d\n",node_count,edge_count); 174 | for(int i=0;i