Compressed Sparse Blocks  1.2
 All Classes Files Functions Variables Typedefs Friends Macros Pages
csb_spmvt_test.cpp
Go to the documentation of this file.
1 #define NOMINMAX
2 #include <iostream>
3 #include <algorithm>
4 #include <functional>
5 #include <fstream>
6 #include <ctime>
7 #include <cmath>
8 #include <string>
9 
10 #include "cilk_util.h"
11 #include "utility.h"
12 
13 #include "triple.h"
14 #include "csc.h"
15 #include "bicsb.h"
16 #include "spvec.h"
17 
18 using namespace std;
19 
20 #define INDEXTYPE uint32_t
21 #define VALUETYPE double
22 
23 /* Alternative native timer (wall-clock):
24  * timeval tim;
25  * gettimeofday(&tim, NULL);
26  * double t1=tim.tv_sec+(tim.tv_usec/1000000.0);
27  */
28 
30 
31 int main(int argc, char* argv[])
32 {
33 #ifndef CILK_STUB
34  int gl_nworkers = __cilkrts_get_nworkers();
35 #else
36  int gl_nworkers = 0;
37 #endif
38  bool syminput = false;
39  bool binary = false;
40  bool iscsc = false;
41  INDEXTYPE m = 0, n = 0, nnz = 0, forcelogbeta = 0;
42  string inputname;
43  if(argc < 2)
44  {
45  cout << "Normal usage: ./parspmvt inputmatrix.mtx sym/nosym binary/text triples/csc" << endl;
46  cout << "Assuming matrix.txt is the input, matrix is unsymmetric, and stored in text(ascii) file" << endl;
47  inputname = "matrix.txt";
48  }
49  else if(argc < 3)
50  {
51  cout << "Normal usage: ./parspmvt inputmatrix.mtx sym/nosym binary/text triples/csc" << endl;
52  cout << "Assuming that the matrix is unsymmetric, and stored in text(ascii) file" << endl;
53  inputname = argv[1];
54  }
55  else if(argc < 4)
56  {
57  cout << "Normal usage: ./parspmvt inputmatrix.mtx sym/nosym binary/text triples/csc" << endl;
58  cout << "Assuming matrix is stored in text(ascii) file" << endl;
59  inputname = argv[1];
60  string issym(argv[2]);
61  if(issym == "sym")
62  syminput = true;
63  else if(issym == "nosym")
64  syminput = false;
65  else
66  cout << "unrecognized option, assuming nosym" << endl;
67  }
68  else
69  {
70  inputname = argv[1];
71  string issym(argv[2]);
72  if(issym == "sym")
73  syminput = true;
74  else if(issym == "nosym")
75  syminput = false;
76  else
77  cout << "unrecognized option, assuming unsymmetric" << endl;
78 
79  string isbinary(argv[3]);
80  if(isbinary == "text")
81  binary = false;
82  else if(isbinary == "binary")
83  binary = true;
84  else
85  cout << "unrecognized option, assuming text file" << endl;
86 
87  if(argc > 4)
88  {
89  string type(argv[4]);
90  if(type == "csc")
91  {
92  iscsc = true;
93  cout << "Processing CSC binary" << endl;
94  }
95  }
96 
97  if(argc == 6)
98  forcelogbeta = atoi(argv[4]);
99  }
100  typedef PTSR<VALUETYPE,VALUETYPE> PTDD;
101  if(binary)
102  {
104  FILE * f = fopen(inputname.c_str(), "r");
105  if(!f)
106  {
107  cerr << "Problem reading binary input file\n";
108  return 1;
109  }
110  if(iscsc)
111  {
112  fread(&n, sizeof(INDEXTYPE), 1, f);
113  fread(&m, sizeof(INDEXTYPE), 1, f);
114  fread(&nnz, sizeof(INDEXTYPE), 1, f);
115  }
116  else
117  {
118  fread(&m, sizeof(INDEXTYPE), 1, f);
119  fread(&n, sizeof(INDEXTYPE), 1, f);
120  fread(&nnz, sizeof(INDEXTYPE), 1, f);
121  }
122  if (m <= 0 || n <= 0 || nnz <= 0)
123  {
124  cerr << "Problem with matrix size in binary input file\n";
125  return 1;
126  }
127  long tstart = cilk_get_time(); // start timer
128  cout << "Reading matrix with dimensions: "<< m << "-by-" << n <<" having "<< nnz << " nonzeros" << endl;
129  INDEXTYPE * rowindices = new INDEXTYPE[nnz];
130  VALUETYPE * vals = new VALUETYPE[nnz];
131  INDEXTYPE * colindices;
132  INDEXTYPE * colpointers;
133  if(iscsc)
134  {
135  colpointers = new INDEXTYPE[n+1];
136  size_t cols = fread(colpointers, sizeof(INDEXTYPE), n+1, f);
137  if(cols != n+1)
138  {
139  cerr << "Problem with FREAD, aborting... " << endl;
140  return -1;
141  }
142  }
143  else
144  {
145  colindices = new INDEXTYPE[nnz];
146  size_t cols = fread(colindices, sizeof(INDEXTYPE), nnz, f);
147  if(cols != nnz)
148  {
149  cerr << "Problem with FREAD, aborting... " << endl;
150  return -1;
151  }
152  }
153  size_t rows = fread(rowindices, sizeof(INDEXTYPE), nnz, f);
154  size_t nums = fread(vals, sizeof(VALUETYPE), nnz, f);
155 
156  if(rows != nnz || nums != nnz)
157  {
158  cerr << "Problem with FREAD, aborting... " << endl;
159  return -1;
160  }
161  long tend = cilk_get_time(); // end timer
162  cout<< "Reading matrix in binary took " << ((VALUETYPE) (tend-tstart)) /1000 << " seconds" <<endl;
163  fclose(f);
164  if(iscsc)
165  {
166  csc = new Csc<VALUETYPE, INDEXTYPE>();
167  csc->SetPointers(colpointers, rowindices, vals , nnz, m, n, true); // do the fortran thing
168  // csc itself will manage the data in this case (shallow copy)
169  }
170  else
171  {
172  csc = new Csc<VALUETYPE, INDEXTYPE>(rowindices, colindices, vals , nnz, m, n);
173  delete [] colindices;
174  delete [] rowindices;
175  delete [] vals;
176  }
177 
178  BiCsb<VALUETYPE, INDEXTYPE> bicsb(*csc, gl_nworkers);
179 
180  flops = 2 * nnz;
181 
182  cout << "# workers: "<< gl_nworkers << endl;
183  cout << "generating vectors... " << endl;
184  cout << "Starting SpMV_T..." << endl;
185  cout << "Col imbalance is: " << ColImbalance(bicsb) << endl;
186 
187 
189  Spvec<VALUETYPE, INDEXTYPE> yt_bicsb(n);
190  Spvec<VALUETYPE, INDEXTYPE> yt_csc (n);
191  yt_csc.fillzero();
192  yt_bicsb.fillzero();
193  xt.fillrandom();
194 
195  bicsb_gespmvt<PTDD>(bicsb, xt.getarr(), yt_bicsb.getarr()); // dummy computation
196 
197  long t0 = cilk_get_time(); // start timer
198  for(int i=0; i < REPEAT; ++i)
199  {
200  bicsb_gespmvt<PTDD>(bicsb, xt.getarr(), yt_bicsb.getarr());
201  }
202  long t1 = cilk_get_time(); // get the wall-clock time
203 
204  long time = (t1-t0)/REPEAT;
205  cout<< "BiCSB Trans" << " time: " << ((double) time) /1000 << " seconds" <<endl;
206  cout<< "BiCSB Trans" << " mflop/sec: " << flops / (1000 * (double) time) <<endl;
207 
208  csc_gaxpy_trans ( *csc, xt.getarr(), yt_csc.getarr());
209  t0 = cilk_get_time();
210  for(int i=0; i < REPEAT; ++i)
211  {
212  csc_gaxpy_trans ( *csc, xt.getarr(), yt_csc.getarr());
213  }
214  t1 = cilk_get_time();
215  time = (t1-t0)/REPEAT;
216  cout <<"Transposed CSC time: " << ((double) time) / 1000 << " seconds" << endl;
217  cout <<"Transposed CSC mflop/sec: " << flops/ (1000 * (double) time) << endl;
218 
219  Verify(yt_csc, yt_bicsb, "BiCSB", n); // inside Spvec.cpp
220 #ifdef STATS
221  ofstream stats("stats.txt");
222  bicsb.PrintStats(stats);
223  stats.close();
224 #endif
225  }
226  else
227  {
228  cout << "reading input matrix in text(ascii)... " << endl;
229  ifstream infile(inputname.c_str());
230  char line[256];
231  char c = infile.get();
232  while(c == '%')
233  {
234  infile.getline(line,256);
235  c = infile.get();
236  }
237  infile.unget();
238  infile >> m >> n >> nnz; // #{rows}-#{cols}-#{nonzeros}
239  flops = 2*nnz;
240 
241  long tstart = cilk_get_time(); // start timer
243 
244  if (infile.is_open())
245  {
246  INDEXTYPE cnz = 0; // current number of nonzeros
247  while (! infile.eof() && cnz < nnz)
248  {
249  infile >> triples[cnz].row >> triples[cnz].col >> triples[cnz].val; // row-col-value
250  triples[cnz].row--;
251  triples[cnz].col--;
252  ++cnz;
253  }
254  assert(cnz == nnz);
255  }
256  long tend = cilk_get_time(); // end timer
257  cout<< "Reading matrix in ascii took " << ((double) (tend-tstart)) /1000 << " seconds" <<endl;
258 
259  cout << "converting to csc and bicsb... " << endl;
260  Csc<VALUETYPE, INDEXTYPE> csc(triples, nnz, m, n);
261  delete [] triples;
262 
263  BiCsb<VALUETYPE, INDEXTYPE> bicsb(csc, gl_nworkers);
264  cout << "# workers: "<< gl_nworkers << endl;
265  cout << "generating vectors... " << endl;
266  cout << "starting matvecs... " << endl;
267 
269  Spvec<VALUETYPE, INDEXTYPE> yt_csc(n);
270  Spvec<VALUETYPE, INDEXTYPE> yt_bicsb(n);
271  yt_csc.fillzero();
272  yt_bicsb.fillzero();
273  xt.fillrandom();
274 
275  csc_gaxpy_trans(csc, xt.getarr(), yt_csc.getarr()); // dummy computation
276 
277  long t0 = cilk_get_time(); // start timer
278  for(int i=0; i < REPEAT; ++i)
279  {
280  csc_gaxpy_trans(csc, xt.getarr(), yt_csc.getarr());
281  }
282  long t1 = cilk_get_time(); // get the wall-clock time
283 
284  long time = (t1-t0)/REPEAT;
285  cout<< "CSC Trans" << " time: " << ((double) time) /1000 << " seconds" <<endl;
286  cout<< "CSC Trans" << " mflop/sec: " << flops / (1000 * (double) time) <<endl;
287 
288  bicsb_gespmvt<PTDD>(bicsb, xt.getarr(), yt_bicsb.getarr()); // dummy computation
289 
290  t0 = cilk_get_time(); // start timer
291  for(int i=0; i < REPEAT; ++i)
292  {
293  bicsb_gespmvt<PTDD>(bicsb, xt.getarr(), yt_bicsb.getarr());
294  }
295  t1 = cilk_get_time(); // get the wall-clock time
296 
297  time = (t1-t0)/REPEAT;
298  cout<< "BiCSB Trans" << " time: " << ((double) time) /1000 << " seconds" <<endl;
299  cout<< "BiCSB Trans" << " mflop/sec: " << flops / (1000 * (double) time) <<endl;
300 
301  Verify(yt_csc, yt_bicsb, "BiCSB", n); // inside Spvec.cpp
302  return 0;
303  }
304 }
305 
#define REPEAT
Definition: utility.h:144
void fillrandom()
Definition: spvec.cpp:117
#define INDEXTYPE
Definition: Semirings.h:24
ITYPE col
Definition: triple.h:14
#define VALUETYPE
int main(int argc, char *argv[])
INDEXTYPE flops
float ColImbalance(const BiCsb< NT, IT > &A)
Definition: friends.h:414
void fillzero()
Definition: spvec.cpp:135
Definition: spvec.h:10
T * getarr()
Definition: spvec.h:42
void Verify(Spvec< NT, IT > &control, Spvec< NT, IT > &test, string name, IT m)
Definition: spvec.cpp:144
int cilk_get_time()
Definition: cilk_util.h:23
ITYPE row
Definition: triple.h:13
Definition: csc.h:12
Definition: csc.h:15
void SetPointers(ITYPE *colpointers, ITYPE *rowindices, T *vals, ITYPE size, ITYPE rows, ITYPE cols, bool fortran)
Definition: csc.h:27
Definition: bicsb.h:19
T val
Definition: triple.h:15
void csc_gaxpy_trans(const Csc< T, ITYPE > &A, T *x, T *y)
Definition: csc.h:121