-
Notifications
You must be signed in to change notification settings - Fork 4
/
conn.cu
310 lines (269 loc) · 6.66 KB
/
conn.cu
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
/****************************************************************************************
* CONNECTED COMPONENTS ON THE GPU
* ==============================
*
*
*
* Copyright (c) 2010 International Institute of Information Technology,
* Hyderabad.
* All rights reserved.
*
* Permission to use, copy, modify and distribute this software and its
* documentation for research purpose is hereby granted without fee,
* provided that the above copyright notice and this permission notice appear
* in all copies of this software and that you do not sell the software.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTY OF ANY KIND,
* EXPRESS, IMPLIED OR OTHERWISE.
*
* Please report any issues to Jyothish Soman ([email protected])
*
* Please cite following paper, if you use this software for research purpose
*
* "Fast GPU Algorithms for Graph Connectivity, Jyothish Soman, K. Kothapalli,
* and P. J. Narayanan, in Proc. of Large Scale Parallel Processing,
* IPDPS Workshops, 2010.
*
*
*
*
* Created by Jyothish Soman
*
****************************************************************************************/
/*
*
* Function to speedup the selection process in the first iteration
* The ancestor tree is initialized to the add the edge from larger edge to its smaller neighbour in this method.
* The process is random and each edge performs this task independently.
* select_winner_init
*
*/
struct ed{
long long int x;
};
typedef struct ed edge;
struct grp{
int num_e,num_n;
int**neigh,*deg;
};
typedef struct grp my_graph;
__global__
void select_winner_init(int* an,edge *ed_list,int num_e,int num_n,int*flag,char*mark){
int a,b,x,y,mn,mx;
long long int t;
a=blockIdx.y*gridDim.x+blockIdx.x;
b=threadIdx.x;
a=a*512+b;
if(a<num_e){
t=ed_list[a].x;
x=(int)t & 0xFFFFFFFF;
y=(int)(t>>32);
mx=x>y?x:y;
mn=x+y-mx;
an[mx]=mn;
}
return;
}
/*
Function to hook from higher valued tree to lower valued tree. For details, read the PPL Paper or LSPP paper or my master's thesis.
Following greener's algorithm, there are two iterations, one from lower valued edges to higher values edges
and the second iteration goes vice versa. The performance of this is largely related to the input.
*/
__global__
void select_winner2(int* an,edge *ed_list,int num_e,int num_n,int*flag,char*mark){
int a,b,x,y,a_x,a_y,mn,mx;
long long int t;
a=blockIdx.y*gridDim.x+blockIdx.x;
b=threadIdx.x;
__shared__ int s_flag;
a=a*512+b;
if(b==1)
s_flag=0;
__syncthreads();
if(a<num_e){
if(mark[a]==0){
t=ed_list[a].x;
x=(int)t & 0xFFFFFFFF;
y=(int)(t>>32);
a_x=an[x];
a_y=an[y];
mx=a_x>a_y?a_x:a_y;
mn=a_x+a_y-mx;
if(mn==mx){
mark[a]=-1;
}
else{
an[mn]=mx;
s_flag=1;
}
}
}
__syncthreads();
if(b==1){
if(s_flag==1){
*flag=1;
}
}
return;
}
/*
Function to hook from lower valued to higher valued trees.
*/
__global__
void select_winner(int* an,edge *ed_list,int num_e,int num_n,int*flag,char*mark){
int a,b,x,y,a_x,a_y,mn,mx;
long long int t;
a=blockIdx.y*gridDim.x+blockIdx.x;
b=threadIdx.x;
__shared__ int s_flag;
a=a*512+b;
if(b==1)
s_flag=0;
__syncthreads();
if(a<num_e){
if(mark[a]==0){
t=ed_list[a].x;
x=(int)t & 0xFFFFFFFF;
y=(int)(t>>32);
a_x=an[x];
a_y=an[y];
mx=a_x>a_y?a_x:a_y;
mn=a_x+a_y-mx;
if(mn==mx){
mark[a]=-1;
}
else{
an[mx]=mn;
s_flag=1;
}
}
}
__syncthreads();
if(b==1){
if(s_flag==1){
*flag=1;
}
}
return;
}
__global__
void p_jump(int num_n,int* an,int *flag){
int a,b,x,y;
a=blockIdx.y*gridDim.x+blockIdx.x;
b=threadIdx.x;
a=a*512+b;
__shared__ int s_f;
if(a>=num_n)
return;
if(b==1){
s_f=0;
}
__syncthreads();
if(a<num_n){
y=an[a];
x=an[y];
if(x!=y){
s_f=1;
an[a]=x;
}
}
if(b==1){
if(s_f==1){
*flag=1;
}
}
}
/*
Function to do a masked jump
Nodes are either root nodes or leaf nodes. Leaf nodes are directly connected to the root nodes, hence do not
need to jump itertively. Once root nodes have reascertained the new root nodes, the leaf nodes can just jump once
*/
__global__
void p_jump_masked(int num_n,int* an,int *flag,char*mask){
int a,b,x,y;
a=blockIdx.y*gridDim.x+blockIdx.x;
b=threadIdx.x;
a=a*512+b;
__shared__ int s_f;
if(a>=num_n)
return;
if(b==1){
s_f=0;
}
__syncthreads();
if(mask[a]==0){
y=an[a];
x=an[y];
if(x!=y){
s_f=1;
an[a]=x;
}
else{
mask[a]=-1;
}
}
if(b==1){
if(s_f==1){
*flag=1;
}
}
}
/*
Function for pointer jumping in the tree, the tree height is shortened by this method.
Here the assumption is that all the nodes are root nodes, or not known whether they are leaf nodes.
Works well in the early iterations
*/
__global__
void p_jump_unmasked(int num_n,int* an,char *mask){
int a,b,x,y;
a=blockIdx.y*gridDim.x+blockIdx.x;
b=threadIdx.x;
a=a*512+b;
if(a>=num_n)
return;
__syncthreads();
if(mask[a]==1){
y=an[a];
x=an[y];
an[a]=x;
}
}
/*
Function to create self pointing tree.
*/
__global__
void update_an(int*an,int num_n){
int a,b;
a=blockIdx.y*gridDim.x+blockIdx.x;
b=threadIdx.x;
a=a*512+b;
if(a>=num_n)
return;
an[a]=a;
return;
}
/*
Function to initialize each edge as a clean copy.
*/
__global__
void update_mark(char *mark,int num_e){
int j;
j=blockIdx.y*gridDim.x+blockIdx.x;
j=j*512+threadIdx.x;
if(j>=num_e)
return;
mark[j]=0;
}
/*
Function to check if each node is the parent of itself or not and to update it as a leaf or root node
*/
__global__
void update_mask(char *mask,int n,int *an){
int j;
j=blockIdx.y*gridDim.x+blockIdx.x;
j=j*512+threadIdx.x;
if(j>=n)
return;
mask[j]=an[j]==j?0:1;
return;
}