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