Compressed Sparse Blocks  1.2
 All Classes Files Functions Variables Typedefs Friends Macros Pages
spvec.cpp
Go to the documentation of this file.
1 #include "spvec.h"
2 #include "utility.h"
3 #if (__GNUC__ == 4 && (__GNUC_MINOR__ < 7) )
4  #include "randgen.h"
5 #else
6  #include <random>
7 #endif
8 #include <cassert>
9 
10 // constructor that generates a junk dense vector
11 template <class T, class ITYPE>
13 {
14  assert(dim != 0);
15  n = static_cast<ITYPE>(ceil(static_cast<float>(dim)/RBDIM)) * RBDIM;
16  padding = n-dim;
17  if(padding)
18  cout << "Padded vector to size " << n << " for register blocking" << endl;
19  arr = new T[n];
20 }
21 
22 template <class T, class ITYPE>
23 Spvec<T,ITYPE>::Spvec (T * darr, ITYPE dim)
24 {
25  assert(dim != 0);
26 
27  n = static_cast<ITYPE>(ceil(static_cast<float>(dim)/RBDIM)) * RBDIM;
28  padding = n-dim;
29  if(padding)
30  cout << "Padded vector to size " << n << " for register blocking" << endl;
31 
32  arr = new T[n](); // zero initialized PID
33 
34  for(ITYPE i=0; i< n; ++i)
35  {
36  arr[i] = darr[i];
37  }
38 }
39 
40 // copy constructor
41 template <class T, class ITYPE>
42 Spvec<T,ITYPE>::Spvec (const Spvec<T, ITYPE> & rhs): n(rhs.n),padding(rhs.padding)
43 {
44  if(n > 0)
45  {
46  arr = new T[n];
47 
48  for(ITYPE i=0; i< n; ++i)
49  arr[i]= rhs.arr[i];
50  }
51 }
52 
53 template <class T, class ITYPE>
55 {
56  if(this != &rhs)
57  {
58  if(n > 0)
59  {
60  delete [] arr;
61  }
62 
63  n = rhs.n;
64  padding = rhs.padding;
65  if(n > 0)
66  {
67  arr = new T[n];
68  for(ITYPE i=0; i< n; ++i)
69  arr[i]= rhs.arr[i];
70  }
71  }
72  return *this;
73 }
74 
75 
76 template <class T, class ITYPE>
78 {
79  if ( n > 0)
80  {
81  delete [] arr;
82  }
83 }
84 
85 template <class T, class ITYPE>
87 {
88  if((n-padding == matmul.op1.rowsize()) && (matmul.op1.colsize() == matmul.op2.size())) // check compliance
89  {
90  csc_gaxpy(matmul.op1, const_cast< T * >(matmul.op2.arr), arr);
91  }
92  else
93  {
94  cout<< "Detected noncompliant matvec..." << endl;
95  }
96  return *this;
97 }
98 
99 template <class T, class ITYPE>
101 {
102  typedef PTSR< T, T> PTDD;
103  if((n-padding == matmul.op1.rowsize()) && (matmul.op1.colsize() == matmul.op2.size())) // check compliance
104  {
105  bicsb_gespmv<PTDD>(matmul.op1, matmul.op2.arr, arr);
106  }
107  else
108  {
109  cout<< "Detected noncompliant matvec..." << endl;
110  }
111  return *this;
112 }
113 
114 // populate the vector with random entries
115 // currently, only works for T "double" and "float"
116 template <class T, class ITYPE>
118 {
119 #if (__GNUC__ == 4 && (__GNUC_MINOR__ < 7) )
120  RandGen G;
121  for(ITYPE i=0; i< n; ++i)
122  {
123  arr[i] = G.RandReal();
124  }
125 #else
126  std::uniform_real_distribution<T> distribution(0.0f, 1.0f); //Values between 0 and 1
127  std::mt19937 engine; // Mersenne twister MT19937
128  auto generator = std::bind(distribution, engine);
129  std::generate_n(arr, n, generator);
130 #endif
131 }
132 
133 // populate the vector with zeros
134 template <class T, class ITYPE>
136 {
137  for(ITYPE i=0; i< n; ++i)
138  {
139  arr[i] = 0;
140  }
141 }
142 
143 template <typename NT, typename IT>
144 void Verify(Spvec<NT, IT> & control, Spvec<NT, IT> & test, string name, IT m)
145 {
146  vector<NT>error(m);
147  std::transform(&control[0], (&control[0])+m, &test[0], error.begin(), absdiff<NT>());
148  auto maxelement = std::max_element(error.begin(), error.end());
149  cout << "Max error is: " << *maxelement << " on y[" << maxelement-error.begin()<<"]=" << test[maxelement-error.begin()] << endl;
150  NT machEps = machineEpsilon<NT>();
151  cout << "Absolute machine epsilon is: " << machEps <<" and y[" << maxelement-error.begin() << "]*EPSILON becomes "
152  << machEps * test[maxelement-error.begin()] << endl;
153 
154  NT sqrtm = sqrt(static_cast<NT>(m));
155  cout << "sqrt(n) * relative error is: " << abs(machEps * test[maxelement-error.begin()]) * sqrtm << endl;
156  if ( (abs(machEps * test[maxelement-error.begin()]) * sqrtm) < abs(*maxelement))
157  {
158  cout << "*** ATTENTION ***: error is more than sqrt(n) times the relative machine epsilon" << endl;
159  }
160 
161 #ifdef DEBUG
162  cout << "<index, control, test>: \n";
163  for(IT i=0; i<m; ++i)
164  {
165  if(error[i] > abs(sqrtm * machEps * test[i]))
166  {
167  cout << i << "\t" << control[i] << " " << test[i] << "\n";
168  }
169  }
170 #endif
171 }
172 
173 
void fillrandom()
Definition: spvec.cpp:117
Definition: Semirings.h:24
Spvec< T, ITYPE > & operator=(const Spvec< T, ITYPE > &rhs)
Definition: spvec.cpp:54
double RandReal()
Definition: randgen.h:85
#define RBDIM
Definition: utility.h:128
void fillzero()
Definition: spvec.cpp:135
Definition: spvec.h:10
void Verify(Spvec< NT, IT > &control, Spvec< NT, IT > &test, string name, IT m)
Definition: spvec.cpp:144
Spvec()
Definition: spvec.h:13
~Spvec()
Definition: spvec.cpp:77
Spvec< T, ITYPE > & operator+=(const Matmul< Csc< T, ITYPE >, Spvec< T, ITYPE > > &matmul)
Delayed evaluations using compositors for SpMV operation... y <- y + Ax.
Definition: spvec.cpp:86
void csc_gaxpy(const Csc< T, ITYPE > &A, T *x, T *y)
Definition: csc.h:92
Definition: csc.h:15
Definition: bicsb.h:19