18 fprintf(fp,
"(w=%d m=%d)",((
mpath*)a)[0].
w,((
mpath*)a)[0].m);
22 fprintf(fp,
"(w=%d m=%f c=%lf)",((
cpath*)a)[0].
w,((
cpath*)a)[0].m,((
cpath*)a)[0].c);
36 assert(sp_B || !sp_C);
48 for (
int ib=0; ib<n && (nbatches == 0 || ib/b<nbatches); ib+=
b){
49 int k = std::min(b, n-ib);
57 if (sp_C) atr_C = atr_C |
SP;
68 double sbl = MPI_Wtime();
70 all_B[
"ij"] = B[
"ij"];
71 for (
int i=0; i<n; i++, nbl++){
77 if (C.
nnz_tot == 0){ nbl--;
break; }
81 (*Bellman)(A[
"ik"],C[
"kj"],B[
"ij"]);
87 all_B[
"ij"] += B[
"ij"];
92 if (num_changed.
get_val() == 0)
break;
97 all_B[
"ij"] += ispeye[
"ij"];
100 double tbl = MPI_Wtime() - sbl;
111 double sbr = MPI_Wtime();
115 for (
int i=0; i<n; i++, nbr++){
120 if (C.
nnz_tot == 0){ nbr--;
break; }
125 cB[
"ij"] += (*Brandes)(A[
"ki"],C[
"kj"]);
133 all_cB[
"ij"] += cB[
"ij"];
139 if (num_changed.
get_val() == 0)
break;
145 double tbr = MPI_Wtime() - sbr;
147 printf(
"(%d, %d) iter (%lf, %lf) sec\n", nbl, nbr, tbl, tbr);
174 P[
"ij"] = setw(A[
"ij"]);
182 for (
int i=0; i<n; i++){
184 P[
"ij"] = Pi[
"ik"]*P[
"kj"];
188 int lenn[3] = {n,n,n};
200 if (c.w<INT_MAX/2 && a.w+b.w == c.w){ c.c = ((double)a.m*b.m)/c.m; }
203 )(P[
"ij"],P[
"jk"],postv[
"ijk"]);
221 [](
int a,
int b){
return std::min(a,b); },
224 [](
int a,
int b){
return a+
b; });
232 int64_t nmy = ((int64_t)std::max((int64_t)(n*sp),(int64_t)1))*((int64_t)((n+dw.
np-1)/dw.
np));
236 for (int64_t row=dw.
rank*n/dw.
np; row<(int64_t)(dw.
rank+1)*n/dw.
np; row++){
237 int64_t cols[std::max((int64_t)(n*sp),(int64_t)1)];
238 for (int64_t col=0; col<std::max((int64_t)(n*sp),(int64_t)1); col++){
241 cols[col] = rand()%n;
243 for (int64_t c=0; c<col; c++){
244 if (cols[c] == cols[col]) is_rep = 1;
247 inds[i] = cols[col]*n+row;
248 vals[i] = (rand()%std::min(n*n,20))+1;
252 A.write(i,inds,vals);
264 double st_time = MPI_Wtime();
275 int pass = v1.
norm2() <= n*1.E-6;
278 MPI_Reduce(MPI_IN_PLACE, &pass, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
280 printf(
"{ betweenness centrality } passed \n");
282 printf(
"{ betweenness centrality } failed \n");
284 MPI_Reduce(&pass, MPI_IN_PLACE, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
288 printf(
"Executing warm-up batch\n");
291 printf(
"Starting benchmarking\n");
297 if (nbatches == 0) printf(
"Completed all batches in time %lf sec, projected total %lf sec.\n", MPI_Wtime()-st_time, MPI_Wtime()-st_time);
298 else printf(
"Completed %d batches in time %lf sec, projected total %lf sec.\n", nbatches, MPI_Wtime()-st_time, (n/(bsize*nbatches))*(MPI_Wtime()-st_time));
309 char ** itr = std::find(begin, end, option);
310 if (itr != end && ++itr != end){
317 int main(
int argc,
char ** argv){
318 int rank,
np, n, pass, bsize, nbatches, test;
321 int const in_num = argc;
322 char ** input_str = argv;
324 MPI_Init(&argc, &argv);
325 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
326 MPI_Comm_size(MPI_COMM_WORLD, &np);
329 n = atoi(
getCmdOption(input_str, input_str+in_num,
"-n"));
334 sp = atof(
getCmdOption(input_str, input_str+in_num,
"-sp"));
337 if (
getCmdOption(input_str, input_str+in_num,
"-bsize")){
338 bsize = atoi(
getCmdOption(input_str, input_str+in_num,
"-bsize"));
339 if (bsize < 0) bsize = 2;
341 if (
getCmdOption(input_str, input_str+in_num,
"-nbatches")){
342 nbatches = atoi(
getCmdOption(input_str, input_str+in_num,
"-nbatches"));
343 if (nbatches < 0) nbatches = 1;
345 if (
getCmdOption(input_str, input_str+in_num,
"-test")){
346 test = atoi(
getCmdOption(input_str, input_str+in_num,
"-test"));
347 if (test < 0) test = 0;
349 if (
getCmdOption(input_str, input_str+in_num,
"-sp_B")){
350 sp_B = (bool)atoi(
getCmdOption(input_str, input_str+in_num,
"-sp_B"));
352 if (
getCmdOption(input_str, input_str+in_num,
"-sp_C")){
353 sp_C = (bool)atoi(
getCmdOption(input_str, input_str+in_num,
"-sp_C"));
359 World dw(argc, argv);
362 printf(
"Computing betweenness centrality for graph with %d nodes, with %lf percent sparsity, and batch size %d, second operand sparsity set to %d, output sparsity set to %d\n",n,sp,bsize,sp_B,sp_C);
364 pass =
btwn_cnt(n, dw, sp, bsize, nbatches, test, sp_B, sp_C);
Matrix class which encapsulates a 2D tensor.
Tensor< dtype > slice(int const *offsets, int const *ends) const
cuts out a slice (block) of this tensor A[offsets,ends) result will always be fully nonsymmetric ...
dtype get_val()
returns scalar value
local process walltime measurement
int main(int argc, char **argv)
Semiring is a Monoid with an addition multiplicaton function addition must have an identity and be as...
Vector class which encapsulates a 1D tensor.
custom bivariate function on two tensors: e.g. C["ij"] = f(A["ik"],B["kj"])
int btwn_cnt(int n, World &dw, double sp=.20, int bsize=2, int nbatches=1, int test=0, bool sp_B=1, bool sp_C=1)
an instance of the CTF library (world) on a MPI communicator
CTF::Monoid< cpath > get_cpath_monoid()
dtype norm2()
computes the frobenius norm of the tensor (needs sqrt()!)
CTF::World * wrld
distributed processor context on which tensor is defined
Scalar class which encapsulates a 0D tensor.
int rank
rank of local processor
void btwn_cnt_naive(Matrix< int > &A, Vector< double > &v)
naive algorithm for betweenness centrality using 3D tensor of counts
void print(char const *a, FILE *fp=stdout) const
prints the value
void sparsify()
reduce tensor to sparse format, storing only nonzero data, or data above a specified threshold...
void btwn_cnt_fast(Matrix< int > A, int b, Vector< double > &v, int nbatches=0, bool sp_B=true, bool sp_C=true)
fast algorithm for betweenness centrality using Bellman Ford
CTF::Bivar_Function< int, cpath, cpath > * get_Brandes_kernel()
int64_t nnz_tot
maximum number of local nonzero elements over all procs
epoch during which to measure timers
int speye(int n, int order, World &dw)
int set_zero()
elects a mapping and sets tensor data to zero
char * getCmdOption(char **begin, char **end, const std::string &option)
A Monoid is a Set equipped with a binary addition operator '+' or a custom function addition must hav...
an instance of a tensor within a CTF world
CTF::Bivar_Function< int, mpath, mpath > * get_Bellman_kernel()
int np
number of processors
CTF::Semiring< mpath > get_mpath_semiring()