Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
neural_network.cxx
Go to the documentation of this file.
1 
8 #include <ctf.hpp>
9 using namespace CTF;
10 
13  int64_t * inds_X;
14  double * vals_X;
15  int64_t n_X;
16  //if global index ordering is preserved between the two tensors, we can fold simply
17  X.get_local_data(&n_X, &inds_X, &vals_X);
18  Y.write(n_X, inds_X, vals_X);
19 }
20 
27 int neural(int n,
28  int m,
29  int d,
30  double sp,
31  World & dw){
32  int lens_X[3] = {n, n, m};
33  int lens_W[3] = {d, d, m};
34 
35  Tensor<> X(3, lens_X);
36  Tensor<> W(3, lens_W);
37  Matrix<> Y(n, n);
38 
39  X.fill_sp_random(0.0, 1.0, sp);
40  W.fill_random(0.0, 1.0);
41 
42  //fold first two modes of X into a pair of modes that are n/d-by-d
43  int lens_X5[] = {n/d, d, n/d, d, m};
44  Tensor<> X5(5, lens_X5);
45 
46  fold_unfold(X, X5);
47 
48  int lens_Y4[] = {n/d, d, n/d, d};
49  Tensor<> Y4(4, lens_Y4);
50 
51  //define a matrix that rotates the elements of a vector with wrap around
52  Matrix<> Rd(d, d);
53  if (dw.rank == 0){
54  int64_t inds_Rd[d];
55  double vals_Rd[d];
56  std::fill(vals_Rd, vals_Rd+d, 1.0);
57  for (int i=0; i<d; i++){
58  inds_Rd[i] = ((i+1) % d) + i*d;
59  }
60  Rd.write(d,inds_Rd,vals_Rd);
61  } else Rd.write(0,NULL,NULL);
62 
63  //define a matrix that rotates the elements of a vector of length n with wrap around
64  Matrix<> Rn(n, n);
65  if (dw.rank == 0){
66  int64_t inds_Rn[n];
67  double vals_Rn[n];
68  std::fill(vals_Rn, vals_Rn+n, 1.0);
69  for (int i=0; i<n; i++){
70  inds_Rn[i] = ((i+1) % n) + i*n;
71  }
72  Rn.write(n,inds_Rn,vals_Rn);
73  } else Rn.write(0,NULL,NULL);
74 
75  //fold that vector rotation into a tensor of order 4, to make it act on a vector folded into a n/d-by-d matrix
76  Tensor<> Rn4(4, lens_Y4);
77  fold_unfold(Rn, Rn4);
78 
79  //define a matrix that rotates the elements of a vector of length n by d with wrap around
80  Matrix<> Rnd(n, n);
81  if (dw.rank == 0){
82  int64_t inds_Rnd[n];
83  double vals_Rnd[n];
84  std::fill(vals_Rnd, vals_Rnd+n, 1.0);
85  for (int i=0; i<n; i++){
86  inds_Rnd[i] = ((i+d) % n) + i*n;
87  }
88  Rnd.write(n,inds_Rnd,vals_Rnd);
89  } else Rnd.write(0,NULL,NULL);
90 
91  //fold that vector d-depth rotation into a tensor of order 4, to make it act on a vector folded into a n/d-by-d matrix
92  Tensor<> Rnd4(4, lens_Y4);
93  fold_unfold(Rnd, Rnd4);
94 
95 
96  for (int a=0; a<d; a++){
97  for (int b=0; b<d; b++){
98  //compute k of the kd^2 contributions to the output Y
99  Y4["iajb"] += X5["iajbk"]*W["abk"];
100  //rotate the filter cyclically in the first mode
101  W["abk"] = Rd["bc"]*W["ack"];
102  //rotate Y cyclically in the first mode
103  Y4["iajb"] = Rn4["jbkc"]*Y4["iakc"];
104  }
105  //now rotate Y back by d in the first mode
106  Y4["iajb"] = Rnd4["kcjb"]*Y4["iakc"];
107  //rotate W cyclically in the second mode
108  W["abk"] = Rd["ac"]*W["cbk"];
109  //rotate Y cyclically in the second mode
110  Y4["iajb"] = Rn4["iakc"]*Y4["kcjb"];
111  }
112  //now rotate Y back by d in the second mode
113  Y4["iajb"] = Rnd4["kcia"]*Y4["kcjb"];
114 
115  //unfold output into matrix
116  fold_unfold(Y4, Y);
117 
118  bool pass = Y.norm2() >= 1.E-6;
119 
120  if (dw.rank == 0){
121  if (pass)
122  printf("{ Neural network with sparse X } passed \n");
123  else
124  printf("{ Neural network with sparse X } failed \n");
125  }
126  return pass;
127 }
128 
129 
130 #ifndef TEST_SUITE
131 char* getCmdOption(char ** begin,
132  char ** end,
133  const std::string & option){
134  char ** itr = std::find(begin, end, option);
135  if (itr != end && ++itr != end){
136  return *itr;
137  }
138  return 0;
139 }
140 
141 
142 int main(int argc, char ** argv){
143  int rank, np, n, m, d, pass;
144  double sp;
145  int const in_num = argc;
146  char ** input_str = argv;
147 
148  MPI_Init(&argc, &argv);
149  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
150  MPI_Comm_size(MPI_COMM_WORLD, &np);
151 
152  if (getCmdOption(input_str, input_str+in_num, "-n")){
153  n = atoi(getCmdOption(input_str, input_str+in_num, "-n"));
154  if (n < 0) n = 16;
155  } else n = 16;
156 
157  if (getCmdOption(input_str, input_str+in_num, "-m")){
158  m = atoi(getCmdOption(input_str, input_str+in_num, "-m"));
159  if (m < 0) m = 9;
160  } else m = 9;
161 
162  if (getCmdOption(input_str, input_str+in_num, "-d")){
163  d = atoi(getCmdOption(input_str, input_str+in_num, "-d"));
164  if (d < 0) d = 4;
165  } else d = 4;
166 
167  if (getCmdOption(input_str, input_str+in_num, "-sp")){
168  sp = atof(getCmdOption(input_str, input_str+in_num, "-sp"));
169  if (sp < 0) sp = .2;
170  } else sp = .2;
171 
172  {
173  World dw(argc, argv);
174 
175  if (rank == 0){
176  printf("Running neural network with dimensions %d*%d*%d and sparsity fraction %lf with dense filter of dimensions %d*%d*%d\n",n,n,m,sp,d,d,m);
177  }
178  pass = neural(n, m, d, sp, dw);
179  assert(pass);
180  }
181 
182  MPI_Finalize();
183  return 0;
184 }
190 #endif
char * getCmdOption(char **begin, char **end, const std::string &option)
Matrix class which encapsulates a 2D tensor.
Definition: matrix.h:18
def rank(self)
Definition: core.pyx:312
int neural(int n, int m, int d, double sp, World &dw)
computes a neural network iteration for tensor n*n*m tensor X whose sparsity fraction is sp...
an instance of the CTF library (world) on a MPI communicator
Definition: world.h:19
string
Definition: core.pyx:456
dtype norm2()
computes the frobenius norm of the tensor (needs sqrt()!)
Definition: tensor.h:811
void fill_random(dtype rmin, dtype rmax)
fills local unique tensor elements to random values in the range [min,max] works only for dtype in {f...
Definition: tensor.cxx:928
int rank
rank of local processor
Definition: world.h:24
void fill_sp_random(dtype rmin, dtype rmax, double frac_sp)
generate roughly frac_sp*dense_tensor_size nonzeros between rmin and rmax, works only for dtype in {f...
Definition: tensor.cxx:969
int main(int argc, char **argv)
void get_local_data(int64_t *npair, int64_t **global_idx, dtype **data, bool nonzeros_only=false, bool unpack_sym=false) const
Gives the global indices and values associated with the local data.
Definition: tensor.cxx:159
Definition: apsp.cxx:17
an instance of a tensor within a CTF world
Definition: tensor.h:74
void fold_unfold(Tensor< dtype > &X, Tensor< dtype > &Y)
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