COMBINATORIAL_BLAS  1.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Semirings.h
Go to the documentation of this file.
1 
2 #ifndef _SEMIRINGS_H_
3 #define _SEMIRINGS_H_
4 
5 #include <utility>
6 #include <climits>
7 #include <cmath>
8 #include "promote.h"
9 
10 template <typename T>
11 struct inf_plus{
12  T operator()(const T& a, const T& b) const {
13  T inf = std::numeric_limits<T>::max();
14  if (a == inf || b == inf){
15  return inf;
16  }
17  return a + b;
18  }
19 };
20 
21 // This semiring is used in indexing (SpParMat::operator())
22 template <class OUT>
24 {
25  static OUT id() { return OUT(); }
26  static bool returnedSAID() { return false; }
27  static OUT add(const OUT & arg1, const OUT & arg2)
28  {
29  cout << "Add should not happen (BoolCopy2ndSRing)!" << endl;
30  throw std::string("Add should not happen!");
31  std::exit(1);
32  return arg2;
33  }
34  static const OUT& multiply(bool arg1, const OUT & arg2)
35  {
36  return arg2;
37  }
38  static void axpy(bool a, const OUT & x, OUT & y)
39  {
40  y = multiply(a, x);
41  }
42 
43  static MPI_Op mpi_op()
44  {
45  static MPI_Op mpiop;
46  static bool exists = false;
47  if (exists)
48  return mpiop;
49  else
50  {
51  MPI_Op_create(MPI_func, true, &mpiop);
52  exists = true;
53  return mpiop;
54  }
55  }
56 
57  static void MPI_func(void * invec, void * inoutvec, int * len, MPI_Datatype *datatype)
58  {
59  if (*len > 0)
60  {
61  cout << "MPI Add should not happen (BoolCopy2ndSRing)!" << endl;
62  std::exit(1);
63  }
64  }
65 };
66 
67 // This semiring is used in indexing (SpParMat::operator())
68 template <class OUT>
70 {
71  static OUT id() { return OUT(); }
72  static bool returnedSAID() { return false; }
73  static OUT add(const OUT & arg1, const OUT & arg2)
74  {
75  cout << "Add should not happen (BoolCopy1stSRing)!" << endl;
76  throw std::string("Add should not happen!");
77  std::exit(1);
78  return arg2;
79  }
80  static const OUT& multiply(const OUT & arg1, bool arg2)
81  {
82  return arg1;
83  }
84  static void axpy(const OUT& a, bool x, OUT & y)
85  {
86  y = multiply(a, x);
87  }
88 
89  static MPI_Op mpi_op()
90  {
91  static MPI_Op mpiop;
92  static bool exists = false;
93  if (exists)
94  return mpiop;
95  else
96  {
97  MPI_Op_create(MPI_func, true, &mpiop);
98  exists = true;
99  return mpiop;
100  }
101  }
102 
103  static void MPI_func(void * invec, void * inoutvec, int * len, MPI_Datatype *datatype)
104  {
105  if (*len > 0)
106  {
107  cout << "MPI Add should not happen (BoolCopy1stSRing)!" << endl;
108  std::exit(1);
109  }
110  }
111 };
112 
113 
114 
115 template <class T1, class T2, class OUT>
117 {
118  static OUT id() { return OUT(); }
119  static bool returnedSAID() { return false; }
120  static MPI_Op mpi_op() { return MPI_MAX; };
121  static OUT add(const OUT & arg1, const OUT & arg2)
122  {
123  return arg2;
124  }
125  static OUT multiply(const T1 & arg1, const T2 & arg2)
126  {
127  // fragile since it wouldn't work with y <- x*A
128  return static_cast<OUT>(arg2);
129  }
130  static void axpy(T1 a, const T2 & x, OUT & y)
131  {
132  //y = add(y, multiply(a, x));
133  y = multiply(a, x);
134  }
135 };
136 
137 template <class T1, class T2>
139 {
141  static T_promote id() { return -1; };
142  static bool returnedSAID() { return false; }
143  static MPI_Op mpi_op() { return MPI_MAX; };
144  static T_promote add(const T_promote & arg1, const T_promote & arg2)
145  {
146  return std::max(arg1, arg2);
147  }
148  static T_promote multiply(const T1 & arg1, const T2 & arg2)
149  {
150  // we could have just returned arg2 but it would be
151  // fragile since it wouldn't work with y <- x*A
152  return (static_cast<T_promote>(arg1) *
153  static_cast<T_promote>(arg2) );
154  }
155  static void axpy(T1 a, const T2 & x, T_promote & y)
156  {
157  y = std::max(y, static_cast<T_promote>(a*x));
158  }
159 };
160 
161 
162 // This one is used for BFS iteration
163 template <class T2>
164 struct SelectMaxSRing<bool, T2>
165 {
166  typedef T2 T_promote;
167  static T_promote id(){ return -1; };
168  static bool returnedSAID() { return false; }
169  static MPI_Op mpi_op() { return MPI_MAX; };
170  static T_promote add(const T_promote & arg1, const T_promote & arg2)
171  {
172  return std::max(arg1, arg2);
173  }
174  static T_promote multiply(const bool & arg1, const T2 & arg2)
175  {
176  return arg2;
177  }
178  static void axpy(bool a, const T2 & x, T_promote & y)
179  {
180  y = std::max(y, x);
181  }
182 };
183 
184 template <class T1, class T2>
186 {
188  static T_promote id(){ return 0; }
189  static bool returnedSAID() { return false; }
190  static MPI_Op mpi_op() { return MPI_SUM; };
191  static T_promote add(const T_promote & arg1, const T_promote & arg2)
192  {
193  return arg1+arg2;
194  }
195  static T_promote multiply(const T1 & arg1, const T2 & arg2)
196  {
197  return (static_cast<T_promote>(arg1) *
198  static_cast<T_promote>(arg2) );
199  }
200  static void axpy(T1 a, const T2 & x, T_promote & y)
201  {
202  y += a*x;
203  }
204 };
205 
206 
207 template <class T1, class T2>
209 {
211  static T_promote id() { return std::numeric_limits<T_promote>::max(); };
212  static bool returnedSAID() { return false; }
213  static MPI_Op mpi_op() { return MPI_MIN; };
214  static T_promote add(const T_promote & arg1, const T_promote & arg2)
215  {
216  return std::min(arg1, arg2);
217  }
218  static T_promote multiply(const T1 & arg1, const T2 & arg2)
219  {
220  return inf_plus< T_promote >
221  (static_cast<T_promote>(arg1), static_cast<T_promote>(arg2));
222  }
223  static void axpy(T1 a, const T2 & x, T_promote & y)
224  {
225  y = std::min(y, multiply(a, x));
226  }
227 };
228 
229 
230 #endif