FlexBox - A Flexible Primal-Dual ToolBox
tools.h
Go to the documentation of this file.
1 #ifndef flexTools_H
2 #define flexTools_H
3 
4 #include <vector>
5 #include <numeric>
6 #include <string>
7 #include <functional>
8 #include <algorithm>
9 #include <cmath>
10 #include <iostream>
11 #include <chrono>
12 #include <iostream>
13 #include <fstream>
14 #include <sstream>
15 
16 #define VERBOSE 0
17 
18 #ifdef _OPENMP
19  #include <omp.h>
20 #endif
21 
22 #ifdef __CUDACC__
23  #include <thrust/device_vector.h>
24  #include <thrust/transform.h>
25  #include <thrust/sequence.h>
26  #include <thrust/copy.h>
27  #include <thrust/fill.h>
28  #include <thrust/replace.h>
29  #include <thrust/functional.h>
30  #include <thrust/iterator/zip_iterator.h>
31  #include <thrust/tuple.h>
32  #include <thrust/for_each.h>
33  #include <thrust/transform_reduce.h>
34  #include <thrust/extrema.h>
35 #endif
36 
37 
38 using std::cerr;
39 using std::cout;
40 using std::endl;
41 using std::string;
42 
47 static const int SIGN_PLUS = 0;
48 static const int SIGN_MINUS = 1;
49 static const int SIGN_EQUALS = 2;
50 
51 // Could be any number, but the whole array should fit into shared memory
52 #define CONST_ARRAY_SIZE 512
53 #define BLOCK_SIZE (64)
54 
56 enum mySign
57 {
58  PLUS,
59  MINUS,
60  EQUALS,
61  COMPOSE
62 };
63 
65 enum prox
66 {
67  primalEmptyProx,
68  dualL1AnisoProx,
69  dualL1IsoProx,
70  dualL2Prox,
71  dualLInfProx,
72  dualFrobeniusProx,
73  dualHuberProx,
74  dualL2DataProx,
75  dualL1DataProx,
76  dualLInfDataProx,
77  dualKLDataProx,
78  dualBoxConstraintProx,
79  dualInnerProductProx
80 };
81 
83 enum linOp
84 {
85  linearOp,
86  diagonalOp,
87  gradientOp,
88  identityOp,
89  matrixOp,
90  matrixGPUOp,
91  zeroOp,
92  superpixelOp,
93  concatOp
94 };
95 
98 {
99  forward,
100  backward,
101  central
102 };
103 
104 template < typename T >
105 T myAbs(T x)
106 {
107  return x > 0 ? x : -x;
108 }
109 
110 template < typename T >
111 T myMin(T a, T b)
112 {
113  return a > b ? b : a;
114 }
115 
116 template < typename T >
117 T myMax(T a, T b)
118 {
119  return a < b ? b : a;
120 }
121 
122 double pow2(double x)
123 {
124  return x * x;
125 }
126 float pow2(float x)
127 {
128  return x * x;
129 }
130 
131 template < typename T >
132 T vectorProduct(const std::vector<T> &v)
133 {
134  return std::accumulate(v.begin(), v.end(), 1, std::multiplies<T>());
135 }
136 
137 
138 
139 template < typename T >
140 T vectorSum(const std::vector<T> &v)
141 {
142  return std::accumulate(v.begin(), v.end(), (T)0);
143 }
144 
145 template < typename T >
146 float vectorMax(std::vector<T> &v)
147 {
148  return *std::max_element(v.begin(), v.end());
149 }
150 
151 template < typename T >
152 void vectorScalarProduct(std::vector<T> &v,T scalarValue)
153 {
154  std::transform(v.begin(), v.end(), v.begin(), [scalarValue](T x) {return scalarValue*x;});
155 }
156 
157 template < typename T >
158 void vectorScalarSet(std::vector<T> &v, const T scalarValue)
159 {
160  std::fill(v.begin(), v.end(), scalarValue);
161 }
162 
163 template < typename T >
164 void vectorPlus(std::vector<T> &v1, std::vector<T> &v2)
165 {
166  std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(), std::plus<T>());
167 }
168 
169 template < typename T >
170 void vectorMinus(std::vector<T> &v1, std::vector<T> &v2)
171 {
172  std::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(), std::minus<T>());
173 }
174 
175 template < typename T >
176 void vectorAbs(std::vector<T> &v)
177 {
178  std::transform(v.begin(), v.end(), v.begin(), [](T x) { return std::abs(x); });
179 }
180 
181 
182 template < typename T >
183 void doOverrelaxation(std::vector<T> &x, std::vector<T> &xOld, std::vector<T> &xBar)
184 {
185  std::transform(x.begin(), x.end(), xOld.begin(), xBar.begin(), [](T x, T y) { return x + x - y; });
186 }
187 
188 template < typename T >
189 void vectorPow2(std::vector<T> &v)
190 {
191  std::transform(v.begin(), v.end(), v.begin(), [](T x) { return x *x ; });
192 }
193 
194 template < typename T >
195 void vectorAddVectorTimesVector(std::vector<T> &result, const std::vector<T> &v1, const std::vector<T> &v2, const int signRule)
196 {
197  switch (signRule)
198  {
199  case SIGN_PLUS:
200  {
201  int numElements = (int)result.size();
202  for (int i = 0; i < numElements; ++i)
203  {
204  result[i] += v1[i] * v2[i];
205  }
206  break;
207  }
208  case SIGN_MINUS:
209  {
210  int numElements = (int)result.size();
211  for (int i = 0; i < numElements; ++i)
212  {
213  result[i] -= v1[i] * v2[i];
214  }
215  break;
216  }
217  case SIGN_EQUALS:
218  {
219  int numElements = (int)result.size();
220  for (int i = 0; i < numElements; ++i)
221  {
222  result[i] = v1[i] * v2[i];
223  }
224  break;
225  }
226  }
227 }
228 
230 
235 class Timer
236 {
237 public:
238  Timer() : t_begin(std::chrono::system_clock::now()), isStopped(false)
239  {
240  };
241 
243  void reset()
244  {
245 #ifdef __CUDACC__
246  cudaDeviceSynchronize();
247  #endif
248  t_begin = std::chrono::system_clock::now();
249  isStopped = false;
250  }
251 
253  void end()
254  {
255 #ifdef __CUDACC__
256  cudaDeviceSynchronize();
257  #endif
258  t_end = std::chrono::system_clock::now();
259  isStopped = true;
260  }
261 
263 
267  double elapsed() const
268  {
269  if(isStopped)
270  {
271  std::chrono::duration<double> diff = t_end - t_begin;
272  return diff.count();
273  }
274  return 0.0;
275 
276  }
277 
278 private:
279  bool isStopped;
280  std::chrono::system_clock::time_point t_begin;
281  std::chrono::system_clock::time_point t_end;
282 };
283 
284 
285 
286 
287 
288 #ifdef __CUDACC__
289 
290  template < typename T >
291  void calculateXYError(thrust::device_vector<T> &x, thrust::device_vector<T> &xOld, thrust::device_vector<T> &xError, T tau)
292  {
293  thrust::transform(x.begin(), x.end(), xOld.begin(), xError.begin(), (thrust::placeholders::_1 - thrust::placeholders::_2) / tau);
294  }
295 
296  template < typename T >
297  __host__ __device__
298  T myPow2GPU(T x)
299  {
300  return x * x;
301  }
302 
304  template < typename T >
305  struct myAbsGPU
306  {
307  __host__ __device__
308  myAbsGPU() {}
309 
310  __host__ __device__
311  T operator()(T x) const { return abs(x); }
312  };
313 
314  template < typename T >
315  void vectorAbs(thrust::device_vector<T> &v)
316  {
317  thrust::transform(v.begin(), v.end(), v.begin(), myAbsGPU<T>());
318  }
319 
320  template < typename T >
321  __host__ __device__
322  T myMinGPU(T a, T b)
323  {
324  return a > b ? b : a;
325  }
326 
327  __device__ float myMinGPUf(float a,float b)
328  {
329  return a > b ? b : a;
330  }
331 
332  __device__ float myMaxGPUf(float a,float b)
333  {
334  return a > b ? a : b;
335  }
336 
337  template < typename T >
338  __host__ __device__
339  T myMaxGPU(T a, T b)
340  {
341  return a < b ? b : a;
342  }
343 
344  template < typename T >
345  T vectorSum(thrust::device_vector<T> &v)
346  {
347  return thrust::reduce(v.begin(), v.end(), (T)0, thrust::plus<T>());
348  }
349 
350  /*sets all elements in a vector to scalarValue*/
351  template < typename T >
352  void vectorScalarSet(thrust::device_vector<T> &v, T scalarValue)
353  {
354  thrust::fill(v.begin(), v.end(), scalarValue);
355  }
356 
357  template < typename T >
358  void vectorScalarProduct(thrust::device_vector<T> &v, const T scalarValue)
359  {
360  thrust::transform(v.begin(), v.end(), v.begin(), scalarValue * thrust::placeholders::_1);
361  }
362 
363  template < typename T >
364  void vectorMinus(thrust::device_vector<T> &v1, thrust::device_vector<T> &v2)
365  {
366  thrust::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(), thrust::minus<T>());
367  }
368 
369  template < typename T >
370  void vectorAddSquared(thrust::device_vector<T> &v1, thrust::device_vector<T> &v2)
371  {
372  thrust::transform(v1.begin(), v1.end(), v2.begin(), v1.begin(), thrust::placeholders::_1 + thrust::placeholders::_2*thrust::placeholders::_2);
373  }
374 
377  {
378  __host__ __device__
379  vectorAddVectorTimesVectorGPU(const int signRule) : signRule(signRule){}
380 
381  template <typename Tuple>
382  __host__ __device__
383  void operator()(Tuple t)
384  {
385  switch (signRule)
386  {
387  case SIGN_PLUS:
388  {
389  thrust::get<0>(t) += thrust::get<1>(t) * thrust::get<2>(t);
390  break;
391  }
392  case SIGN_MINUS:
393  {
394  thrust::get<0>(t) -= thrust::get<1>(t) * thrust::get<2>(t);
395  break;
396  }
397  case SIGN_EQUALS:
398  {
399  thrust::get<0>(t) = thrust::get<1>(t) * thrust::get<2>(t);
400  break;
401  }
402  }
403  }
404 
405  const int signRule;
406  };
407 
408  template < typename T >
409  void vectorAddVectorTimesVector(thrust::device_vector<T> &result, const thrust::device_vector<T> &v1, const thrust::device_vector<T> &v2, const int signRule)
410  {
411  thrust::for_each(
412  thrust::make_zip_iterator(thrust::make_tuple(result.begin(), v1.begin(), v2.begin())),
413  thrust::make_zip_iterator(thrust::make_tuple(result.end(), v1.end(), v2.end())),
415  }
416 
417 
418  template < typename T >
419  __host__ __device__
420  T sqrtGPU(T x)
421  {
422  return sqrt(x);
423  }
424 
425  template < typename T >
426  void vectorSqrt(thrust::device_vector<T> &v1)
427  {
428  thrust::transform(v1.begin(), v1.end(), v1.begin(), sqrtGPU<T>());
429  }
430 
431  template < typename T >
432  float vectorMax(thrust::device_vector<T> &v)
433  {
434  return *thrust::max_element(v.begin(), v.end());
435  }
436 
437 
438 
439 
440 #endif
441 
442 
443  //kernels for CUDA operators
444 
445 #ifdef __CUDACC__
446 /*
447 // cuda error checking
448 std::string prev_file = "";
449 int prev_line = 0;
450 void cuda_check(std::string file, int line)
451 {
452  cudaError_t e = cudaGetLastError();
453  if (e != cudaSuccess)
454  {
455  std::ofstream out("output.txt");
456  out << endl << file << ", line " << line << ": " << cudaGetErrorString(e) << " (" << e << ")" << endl;
457  if (prev_line>0) out << "Previous CUDA call:" << endl << prev_file << ", line " << prev_line << endl;
458  out.close();
459 
460  cout << endl << file << ", line " << line << ": " << cudaGetErrorString(e) << " (" << e << ")" << endl;
461  if (prev_line>0) cout << "Previous CUDA call:" << endl << prev_file << ", line " << prev_line << endl;
462  system("pause");
463  exit(1);
464  }
465  prev_file = file;
466  prev_line = line;
467 }
468 
469 void writeOutput(char* writeString)
470 {
471 
472  std::ofstream out("log.txt");
473  out << endl << writeString << endl;
474  out.close();
475 }
476 
477 #define CUDA_CHECK cuda_check(__FILE__,__LINE__)
478 //#if DO_CUDA_CHECK
479 // #define CUDA_CHECK cuda_check(__FILE__,__LINE__)
480 //#else
481 // #define CUDA_CHECK 0
482 //#endif
483 */
484 
485 #endif
486 
487 
488 
489 #endif
thrust functor for elemntwise multiplication of two vectors following a summation of the result on a ...
Definition: tools.h:376
class for timing execution times
Definition: tools.h:235
thrust functor for calculating the absolute value of vector
Definition: tools.h:305
void end()
ends the timer
Definition: tools.h:253
mySign
enum representing the type of concatenation
Definition: tools.h:56
gradientType
enum representing the type of gradient
Definition: tools.h:97
prox
enum representing the type of prox
Definition: tools.h:65
double elapsed() const
returns the duration
Definition: tools.h:267
void reset()
resets or starts the timer
Definition: tools.h:243
linOp
enum representing the type of a linear operator
Definition: tools.h:83