2 #include "CombBLAS/CombBLAS.h"
44 const uint64_t b[] = {0x2ULL, 0xCULL, 0xF0ULL, 0xFF00ULL, 0xFFFF0000ULL, 0xFFFFFFFF00000000ULL};
45 const unsigned int S[] = {1, 2, 4, 8, 16, 32};
49 for (i = 5; i >= 0; i--)
61 bool from_string(T & t,
const string& s, std::ios_base& (*f)(std::ios_base&))
64 return !(iss >> f >> t).fail();
68 template <
typename PARMAT>
82 struct prunediscovered:
public std::binary_function<int64_t, int64_t, int64_t >
86 return ( y == -1 ) ? x: -1;
90 static void MPI_randuniq(
void * invec,
void * inoutvec,
int * len, MPI_Datatype *datatype)
95 for (
int i=0; i<*len; i++ )
96 inoutveccast[i] = RR(inveccast[i], inoutveccast[i]);
99 int main(
int argc,
char* argv[])
102 MPI_Init(&argc, &argv);
103 MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
104 MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
109 cout <<
"Usage: ./scbfs <Scale>" << endl;
110 cout <<
"Example: mpirun -np 4 ./scbfs 20" << endl;
130 scale =
static_cast<unsigned>(atoi(argv[1]));
132 outs <<
"Forcing scale to : " << scale << endl;
135 double initiator[4] = {.57, .19, .19, .05};
137 double t01 = MPI_Wtime();
141 SpParHelper::Print(
"Generated renamed edge lists\n");
144 tinfo <<
"Generation took " << t02-t01 <<
" seconds" << endl;
145 SpParHelper::Print(tinfo.str());
149 MPI_Barrier(MPI_COMM_WORLD);
150 double t1 = MPI_Wtime();
155 SpParHelper::Print(
"Created Sparse Matrix (with int32 local indices and values)\n");
157 MPI_Barrier(MPI_COMM_WORLD);
158 double redts = MPI_Wtime();
160 MPI_Barrier(MPI_COMM_WORLD);
161 double redtf = MPI_Wtime();
163 ostringstream redtimeinfo;
164 redtimeinfo <<
"Calculated degrees in " << redtf-redts <<
" seconds" << endl;
165 SpParHelper::Print(redtimeinfo.str());
170 ostringstream loopinfo;
171 loopinfo <<
"Converted to Boolean and removed " << removed <<
" loops" << endl;
172 SpParHelper::Print(loopinfo.str());
177 A.Reduce(*ColSums,
Column, plus<int64_t>(),
static_cast<int64_t>(0));
178 A.Reduce(*RowSums,
Row, plus<int64_t>(),
static_cast<int64_t>(0));
179 SpParHelper::Print(
"Reductions done\n");
180 ColSums->
EWiseApply(*RowSums, plus<int64_t>());
182 SpParHelper::Print(
"Intersection of colsums and rowsums found\n");
184 nonisov = ColSums->
FindInds(bind2nd(greater<int64_t>(), 0));
187 SpParHelper::Print(
"Found (and permuted) non-isolated vertices\n");
191 A(nonisov, nonisov,
true);
192 SpParHelper::Print(
"Dropped isolated vertices from input\n");
199 SpParHelper::Print(
"Symmetricized\n");
204 tinfo <<
"Threading activated with " <<
cblas_splits <<
" threads" << endl;
205 SpParHelper::Print(tinfo.str());
210 MPI_Barrier(MPI_COMM_WORLD);
211 double t2=MPI_Wtime();
213 ostringstream k1timeinfo;
214 k1timeinfo << (t2-t1) - (redtf-redts) <<
" seconds elapsed for Kernel #1" << endl;
215 SpParHelper::Print(k1timeinfo.str());
220 outs2 <<
"Load balance: " << balance << endl;
221 SpParHelper::Print(outs2.str());
223 MPI_Barrier(MPI_COMM_WORLD);
227 degrees = degrees(nonisov);
232 double nver = (double) degrees.TotalLength();
239 vector<double> loccands(
ITERS);
240 vector<int64_t> loccandints(
ITERS);
243 for(
int i=0; i<
ITERS; ++i)
244 loccands[i] = M.
rand();
245 copy(loccands.begin(), loccands.end(), ostream_iterator<double>(cout,
" ")); cout << endl;
246 transform(loccands.begin(), loccands.end(), loccands.begin(), bind2nd( multiplies<double>(), nver ));
248 for(
int i=0; i<
ITERS; ++i)
249 loccandints[i] =
static_cast<int64_t>(loccands[i]);
250 copy(loccandints.begin(), loccandints.end(), ostream_iterator<double>(cout,
" ")); cout << endl;
253 for(
int i=0; i<
ITERS; ++i)
257 for(
int i=0; i<
ITERS; ++i)
265 MPI_Barrier(MPI_COMM_WORLD);
266 double t1 = MPI_Wtime();
271 MPI_Op randreducempiop;
272 MPI_Op_create(MPI_randuniq,
true, &randreducempiop);
274 while(fringe.
getnnz() > 0)
277 fringe =
SpMV(Aeff, fringe,optbuf);
281 singlechild.PrintInfo(
"Single child frontier");
286 MPI_Barrier(MPI_COMM_WORLD);
287 double t2 = MPI_Wtime();
295 ostringstream outnew;
296 outnew << i <<
"th starting vertex was " << Cands[i] << endl;
297 outnew <<
"Number iterations: " << iterations << endl;
298 outnew <<
"Number of vertices found: " << parentsp.
Reduce(plus<int64_t>(), (
int64_t) 0) << endl;
299 outnew <<
"Number of edges traversed: " << nedges << endl;
300 outnew <<
"BFS time: " << t2-t1 <<
" seconds" << endl;
301 outnew <<
"MTEPS: " <<
static_cast<double>(nedges) / (t2-t1) / 1000000.0 << endl;
305 MTEPS[i] =
static_cast<double>(nedges) / (t2-t1) / 1000000.0;
306 SpParHelper::Print(outnew.str());
308 SpParHelper::Print(
"Finished\n");
312 sort(EDGES, EDGES+
ITERS);
313 os <<
"--------------------------" << endl;
314 os <<
"Min nedges: " << EDGES[0] << endl;
315 os <<
"First Quartile nedges: " << (EDGES[(
ITERS/4)-1] + EDGES[
ITERS/4])/2 << endl;
316 os <<
"Median nedges: " << (EDGES[(
ITERS/2)-1] + EDGES[
ITERS/2])/2 << endl;
317 os <<
"Third Quartile nedges: " << (EDGES[(3*
ITERS/4) -1 ] + EDGES[3*
ITERS/4])/2 << endl;
318 os <<
"Max nedges: " << EDGES[
ITERS-1] << endl;
319 double mean = accumulate( EDGES, EDGES+
ITERS, 0.0 )/
ITERS;
320 vector<double> zero_mean(
ITERS);
321 transform(EDGES, EDGES+
ITERS, zero_mean.begin(), bind2nd( minus<double>(), mean ));
323 double deviation = inner_product( zero_mean.begin(),zero_mean.end(), zero_mean.begin(), 0.0 );
324 deviation = sqrt( deviation / (
ITERS-1) );
325 os <<
"Mean nedges: " << mean << endl;
326 os <<
"STDDEV nedges: " << deviation << endl;
327 os <<
"--------------------------" << endl;
329 sort(TIMES,TIMES+
ITERS);
330 os <<
"Min time: " << TIMES[0] <<
" seconds" << endl;
331 os <<
"First Quartile time: " << (TIMES[(
ITERS/4)-1] + TIMES[
ITERS/4])/2 <<
" seconds" << endl;
332 os <<
"Median time: " << (TIMES[(
ITERS/2)-1] + TIMES[
ITERS/2])/2 <<
" seconds" << endl;
333 os <<
"Third Quartile time: " << (TIMES[(3*
ITERS/4)-1] + TIMES[3*
ITERS/4])/2 <<
" seconds" << endl;
334 os <<
"Max time: " << TIMES[
ITERS-1] <<
" seconds" << endl;
335 mean = accumulate( TIMES, TIMES+
ITERS, 0.0 )/
ITERS;
336 transform(TIMES, TIMES+
ITERS, zero_mean.begin(), bind2nd( minus<double>(), mean ));
337 deviation = inner_product( zero_mean.begin(),zero_mean.end(), zero_mean.begin(), 0.0 );
338 deviation = sqrt( deviation / (
ITERS-1) );
339 os <<
"Mean time: " << mean <<
" seconds" << endl;
340 os <<
"STDDEV time: " << deviation <<
" seconds" << endl;
341 os <<
"--------------------------" << endl;
343 sort(MTEPS, MTEPS+
ITERS);
344 os <<
"Min MTEPS: " << MTEPS[0] << endl;
345 os <<
"First Quartile MTEPS: " << (MTEPS[(
ITERS/4)-1] + MTEPS[
ITERS/4])/2 << endl;
346 os <<
"Median MTEPS: " << (MTEPS[(
ITERS/2)-1] + MTEPS[
ITERS/2])/2 << endl;
347 os <<
"Third Quartile MTEPS: " << (MTEPS[(3*
ITERS/4)-1] + MTEPS[3*
ITERS/4])/2 << endl;
348 os <<
"Max MTEPS: " << MTEPS[
ITERS-1] << endl;
350 double hteps =
static_cast<double>(
ITERS) / accumulate(INVMTEPS, INVMTEPS+
ITERS, 0.0);
351 os <<
"Harmonic mean of MTEPS: " << hteps << endl;
352 transform(INVMTEPS, INVMTEPS+
ITERS, zero_mean.begin(), bind2nd(minus<double>(), 1/hteps));
353 deviation = inner_product( zero_mean.begin(),zero_mean.end(), zero_mean.begin(), 0.0 );
354 deviation = sqrt( deviation / (
ITERS-1) ) * (hteps*hteps);
355 os <<
"Harmonic standard deviation of MTEPS: " << deviation << endl;
356 SpParHelper::Print(os.str());