Cyclops Tensor Framework
parallel arithmetic on multidimensional arrays
qinformatics.cxx
Go to the documentation of this file.
1 
10 #include <ctf.hpp>
11 using namespace CTF;
12 
13 char* getCmdOption(char ** begin,
14  char ** end,
15  const std::string & option){
16  char ** itr = std::find(begin, end, option);
17  if (itr != end && ++itr != end){
18  return *itr;
19  }
20  return 0;
21 }
22 
23 
24 int main(int argc, char ** argv){
25  int rank, np, d, L;
26  int const in_num = argc;
27  char ** input_str = argv;
28  double *pairs, *opairs;
29  int64_t *indices, *oindices, npair, onpair;
30 
31  MPI_Init(&argc, &argv);
32  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
33  MPI_Comm_size(MPI_COMM_WORLD, &np);
34 
35  World dw(argc, argv);
36 
37  if (getCmdOption(input_str, input_str+in_num, "-d")){
38  d = atoi(getCmdOption(input_str, input_str+in_num, "-d"));
39  if (d < 0) d = 2;
40  } else d = 2;
41 
42 
43  L = 15;
44 
45  {
46  Matrix<> h(d*d, d*d, NS, dw);
47  h.get_local_data(&npair, &indices, &pairs);
48  for (int i=0; i<npair; i++) {
49  srand48(indices[i]*23);
50  pairs[i] = drand48();
51  }
52  h.write(npair, indices, pairs);
53  delete [] pairs;
54  free(indices);
55 
56  {
57  int size[L/2+1];
58  int shape[L/2+1];
59 
60  for (int i=0; i<L/2; i++) size[i] = d*d;
61  size[L/2] = d;
62  for (int i=0; i<L/2+1; i++) shape[i] = NS;
63  Tensor<> v_in(L/2+1, size, shape, dw);
64 
65  double t_io_start = MPI_Wtime();
66 
67  v_in.get_local_data(&npair, &indices, &pairs);
68  for (int i=0; i<npair; i++) {
69  srand48(indices[i]);
70  pairs[i] = drand48();
71  }
72  v_in.write(npair, indices, pairs);
73  delete [] pairs;
74  free(indices);
75  Tensor<> v_out(L/2+1, size, shape, dw);
76 
77  double t_io_end = MPI_Wtime();
78 
79  double t_start = MPI_Wtime();
80 
81  Timer_epoch ep("folded contractions set 1");
82  ep.begin();
83 
84  v_out["acegikmo"] = h["ax"]*v_in["xcegikmo"];
85  v_out["acegikmo"] += h["cx"]*v_in["axegikmo"];
86  v_out["acegikmo"] += h["ex"]*v_in["acxgikmo"];
87 
88  v_out["acegikmo"] += h["gx"]*v_in["acexikmo"];
89  v_out["acegikmo"] += h["ix"]*v_in["acegxkmo"];
90 
91  v_out["acegikmo"] += h["kx"]*v_in["acegixmo"];
92  v_out["acegikmo"] += h["mx"]*v_in["acegikxo"];
93 
94  ep.end();
95 
96  double t_end = MPI_Wtime();
97  if (rank == 0)
98  printf("First set of folded contractions took %lf sec\n", t_end-t_start);
99 
100  double t_io_start2 = MPI_Wtime();
101 
102  v_in.get_local_data(&npair, &indices, &pairs);
103  v_out.get_local_data(&onpair, &oindices, &opairs);
104 
105  double t_io_end2 = MPI_Wtime();
106  if (rank == 0)
107  printf("IO for first set of folded contractions took %lf sec\n", t_io_end-t_io_start + (t_io_end2-t_io_start2));
108  }
109 
110  {
111  int size[L/2+1];
112  int shape[L/2+1];
113 
114  size[0] = d;
115  for (int i=0; i<L/2; i++) size[i+1] = d*d;
116  for (int i=0; i<L/2+1; i++) shape[i] = NS;
117  Tensor<> v_in(L/2+1, size, shape, dw);
118 
119  double t_io_start = MPI_Wtime();
120  v_in.write(npair, indices, pairs);
121  delete [] pairs;
122  free(indices);
123  Tensor<> v_out(L/2+1, size, shape, dw);
124  v_out.write(onpair, oindices, opairs);
125  double t_io_end = MPI_Wtime();
126 
127  double t_start = MPI_Wtime();
128 
129  Timer_epoch ep("folded contractions set 1");
130  ep.begin();
131 
132  v_out["abdfhjln"] += h["bx"]*v_in["axdfhjln"];
133  v_out["abdfhjln"] += h["dx"]*v_in["abxfhjln"];
134 
135  v_out["abdfhjln"] += h["fx"]*v_in["abdxhjln"];
136  v_out["abdfhjln"] += h["hx"]*v_in["abdfxjln"];
137  v_out["abdfhjln"] += h["jx"]*v_in["abdfhxln"];
138 
139  v_out["abdfhjln"] += h["lx"]*v_in["abdfhjxn"];
140  v_out["abdfhjln"] += h["nx"]*v_in["abdfhjlx"];
141 
142  ep.end();
143 
144  double t_end = MPI_Wtime();
145 
146  double t_norm_start = MPI_Wtime();
147  double norm = v_out.norm2();
148  double t_norm_end = MPI_Wtime();
149  if (rank == 0){
150  printf("second set of folded contractions took %lf seconds\n",t_end-t_start);
151  printf("IO for second set of folded contractions took %lf sec\n", t_io_end-t_io_start);
152  printf("norm of v_out is %lf\n",norm);
153  printf("calculating norm of v_out took %lf sec\n", t_norm_end-t_norm_start);
154  }
155  }
156  }
157 
158  {
159  int size[L];
160  int shape[L];
161 
162  for (int i=0; i<L; i++) size[i] = d;
163  for (int i=0; i<L; i++) shape[i] = NS;
164  Tensor<> v_in(L, size, shape, dw);
165  Tensor<> h(4, size, shape, dw);
166  double t_io_start = MPI_Wtime();
167  v_in.get_local_data(&npair, &indices, &pairs);
168  for (int i=0; i<npair; i++) {
169  srand48(indices[i]);
170  pairs[i] = drand48();
171  }
172  v_in.write(npair, indices, pairs);
173  delete [] pairs;
174  free(indices);
175  h.get_local_data(&npair, &indices, &pairs);
176  for (int i=0; i<npair; i++) {
177  srand48(indices[i]*23);
178  pairs[i] = drand48();
179  }
180  h.write(npair, indices, pairs);
181  delete [] pairs;
182  free(indices);
183  Tensor<> v_out(L, size, shape, dw);
184 
185  double t_io_end = MPI_Wtime();
186 
187  double t_start = MPI_Wtime();
188 
189  Timer_epoch ep("contractions");
190  ep.begin();
191 
192  v_out["abcdefghijklmno"] = h["abxy"]*v_in["xycdefghijklmno"];
193  v_out["abcdefghijklmno"] += h["bcxy"]*v_in["axydefghijklmno"];
194  v_out["abcdefghijklmno"] += h["cdxy"]*v_in["abxyefghijklmno"];
195  v_out["abcdefghijklmno"] += h["dexy"]*v_in["abcxyfghijklmno"];
196  v_out["abcdefghijklmno"] += h["efxy"]*v_in["abcdxyghijklmno"];
197 
198  v_out["abcdefghijklmno"] += h["fgxy"]*v_in["abcdexyhijklmno"];
199  v_out["abcdefghijklmno"] += h["ghxy"]*v_in["abcdefxyijklmno"];
200  v_out["abcdefghijklmno"] += h["hixy"]*v_in["abcdefgxyjklmno"];
201  v_out["abcdefghijklmno"] += h["ijxy"]*v_in["abcdefghxyklmno"];
202  v_out["abcdefghijklmno"] += h["jkxy"]*v_in["abcdefghixylmno"];
203 
204  v_out["abcdefghijklmno"] += h["klxy"]*v_in["abcdefghijxymno"];
205  v_out["abcdefghijklmno"] += h["lmxy"]*v_in["abcdefghijkxyno"];
206  v_out["abcdefghijklmno"] += h["mnxy"]*v_in["abcdefghijklxyo"];
207  v_out["abcdefghijklmno"] += h["noxy"]*v_in["abcdefghijklmxy"];
208  ep.end();
209 
210  double t_end = MPI_Wtime();
211 
212  double t_norm_start = MPI_Wtime();
213  double norm = v_out.norm2();
214  double t_norm_end = MPI_Wtime();
215  if (rank == 0){
216  printf("unfolded contractions took %lf seconds\n", t_end-t_start);
217  printf("unfolded IO took %lf seconds\n", t_io_end-t_io_start);
218  printf("unfolded norm of v_out is %lf\n", norm);
219  printf("calculating norm of v_out took %lf sec\n", t_norm_end-t_norm_start);
220  }
221  }
222  return 0;
223 }
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
Definition: common.h:37
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
epoch during which to measure timers
Definition: timer.h:69
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
int main(int argc, char **argv)
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