Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
sssp.cxx
Go to the documentation of this file.
1 
8 #include <ctf.hpp>
9 #include <float.h>
10 using namespace CTF;
11 
12 
13 // return false if there are negative cycles, true otherwise
14 template <typename t>
15 bool Bellman_Ford(Matrix<t> A, Vector<t> P, int n){
16  Vector<t> Q(P);
17  int r = 0;
18  int new_tot_wht = P["ij"];
19  int tot_wht;
20  do {
21  if (r == n+1) return false; // exit if we did not converge in n iterations
22  else r++;
23  Q["i"] = P["i"]; // save old distances
24  P["i"] += A["ij"]*P["j"]; // update distances
25  tot_wht = new_tot_wht;
26  new_tot_wht = P["ij"];
27  assert(new_tot_wht <= tot_wht);
28  } while (new_tot_wht < tot_wht); // continue so long as some distance got shorter
29  return true;
30 }
31 
32 // calculate SSSP on a graph of n nodes distributed on World (communicator) dw
33 int sssp(int n,
34  World & dw){
35 
36  //tropical semiring, define additive identity to be n*n (max weight) to prevent integer overflow
37  Semiring<int> s(n*n,
38  [](int a, int b){ return std::min(a,b); },
39  MPI_MIN,
40  0,
41  [](int a, int b){ return a+b; });
42 
43  //random adjacency matrix
44  Matrix<int> A(n, n, dw, s);
45  srand(dw.rank);
46  A.fill_random(0, n*n);
47 
48  A["ii"] = n*n;
49 
50  A.sparsify([=](int a){ return a<5*n; });
51 
52  Vector<int> v(n, dw, s);
53  if (dw.rank == 0){
54  int64_t idx = 0;
55  int val = 0;
56  v.write(1, &idx, &val);
57  } else v.write(0, NULL, NULL);
58 
59  //make sure we converged
60  int pass = Bellman_Ford(A, v, n);
61  if (n>=3){
62  v["i"] = n*n;
63  if (dw.rank == 0){
64  int64_t idx = 0;
65  int val = 0;
66  v.write(1, &idx, &val);
67  } else v.write(0, NULL, NULL);
68 
69 
70  // add a negative cycle to A
71  if (dw.rank == 0){
72  int64_t idx[] = {1,n+2,2*n+0};
73  int val[] = {1, -1, -1};
74  A.write(3, idx, val);
75  } else A.write(0, NULL, NULL);
76  //make sure we did not converge
77  int pass2 = Bellman_Ford(A, v, n);
78  pass = pass & !pass2;
79  }
80 
81  if (dw.rank == 0){
82  MPI_Reduce(MPI_IN_PLACE, &pass, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
83  if (pass)
84  printf("{ negative cycle check via Bellman-Ford } passed \n");
85  else
86  printf("{ negative cycle check via Bellman-Ford } failed \n");
87  } else
88  MPI_Reduce(&pass, MPI_IN_PLACE, 1, MPI_INT, MPI_MIN, 0, MPI_COMM_WORLD);
89  return pass;
90 }
91 
92 
93 #ifndef TEST_SUITE
94 char* getCmdOption(char ** begin,
95  char ** end,
96  const std::string & option){
97  char ** itr = std::find(begin, end, option);
98  if (itr != end && ++itr != end){
99  return *itr;
100  }
101  return 0;
102 }
103 
104 
105 int main(int argc, char ** argv){
106  int rank, np, n, pass;
107  int const in_num = argc;
108  char ** input_str = argv;
109 
110  MPI_Init(&argc, &argv);
111  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
112  MPI_Comm_size(MPI_COMM_WORLD, &np);
113 
114  if (getCmdOption(input_str, input_str+in_num, "-n")){
115  n = atoi(getCmdOption(input_str, input_str+in_num, "-n"));
116  if (n < 0) n = 7;
117  } else n = 7;
118 
119  {
120  World dw(argc, argv);
121 
122  if (rank == 0){
123  printf("Computing SSSP on sparse graph with %d nodes using the Bellman-Ford algorithm\n",n);
124  }
125  pass = sssp(n, dw);
126  assert(pass);
127  }
128 
129  MPI_Finalize();
130  return 0;
131 }
137 #endif
Matrix class which encapsulates a 2D tensor.
Definition: matrix.h:18
def rank(self)
Definition: core.pyx:312
Semiring is a Monoid with an addition multiplicaton function addition must have an identity and be as...
Definition: semiring.h:359
Vector class which encapsulates a 1D tensor.
Definition: vector.h:14
an instance of the CTF library (world) on a MPI communicator
Definition: world.h:19
string
Definition: core.pyx:456
int rank
rank of local processor
Definition: world.h:24
bool Bellman_Ford(Matrix< t > A, Vector< t > P, int n)
Definition: sssp.cxx:15
int sssp(int n, World &dw)
Definition: sssp.cxx:33
int main(int argc, char **argv)
Definition: sssp.cxx:105
Definition: apsp.cxx:17
char * getCmdOption(char **begin, char **end, const std::string &option)
Definition: sssp.cxx:94
void write(int64_t npair, int64_t const *global_idx, dtype const *data)
writes in values associated with any set of indices The sparse data is defined in coordinate format...
Definition: tensor.cxx:264
def np(self)
Definition: core.pyx:315