Caffe
mkl_alternate.hpp
1 #ifndef CAFFE_UTIL_MKL_ALTERNATE_H_
2 #define CAFFE_UTIL_MKL_ALTERNATE_H_
3 
4 #ifdef USE_MKL
5 
6 #include <mkl.h>
7 
8 #else // If use MKL, simply include the MKL header
9 
10 #ifdef USE_ACCELERATE
11 #include <Accelerate/Accelerate.h>
12 #else
13 extern "C" {
14 #include <cblas.h>
15 }
16 #endif // USE_ACCELERATE
17 
18 #include <math.h>
19 
20 // Functions that caffe uses but are not present if MKL is not linked.
21 
22 // A simple way to define the vsl unary functions. The operation should
23 // be in the form e.g. y[i] = sqrt(a[i])
24 #define DEFINE_VSL_UNARY_FUNC(name, operation) \
25  template<typename Dtype> \
26  void v##name(const int n, const Dtype* a, Dtype* y) { \
27  CHECK_GT(n, 0); CHECK(a); CHECK(y); \
28  for (int i = 0; i < n; ++i) { operation; } \
29  } \
30  inline void vs##name( \
31  const int n, const float* a, float* y) { \
32  v##name<float>(n, a, y); \
33  } \
34  inline void vd##name( \
35  const int n, const double* a, double* y) { \
36  v##name<double>(n, a, y); \
37  }
38 
39 DEFINE_VSL_UNARY_FUNC(Sqr, y[i] = a[i] * a[i])
40 DEFINE_VSL_UNARY_FUNC(Sqrt, y[i] = sqrt(a[i]))
41 DEFINE_VSL_UNARY_FUNC(Exp, y[i] = exp(a[i]))
42 DEFINE_VSL_UNARY_FUNC(Ln, y[i] = log(a[i]))
43 DEFINE_VSL_UNARY_FUNC(Abs, y[i] = fabs(a[i]))
44 
45 // A simple way to define the vsl unary functions with singular parameter b.
46 // The operation should be in the form e.g. y[i] = pow(a[i], b)
47 #define DEFINE_VSL_UNARY_FUNC_WITH_PARAM(name, operation) \
48  template<typename Dtype> \
49  void v##name(const int n, const Dtype* a, const Dtype b, Dtype* y) { \
50  CHECK_GT(n, 0); CHECK(a); CHECK(y); \
51  for (int i = 0; i < n; ++i) { operation; } \
52  } \
53  inline void vs##name( \
54  const int n, const float* a, const float b, float* y) { \
55  v##name<float>(n, a, b, y); \
56  } \
57  inline void vd##name( \
58  const int n, const double* a, const float b, double* y) { \
59  v##name<double>(n, a, b, y); \
60  }
61 
62 DEFINE_VSL_UNARY_FUNC_WITH_PARAM(Powx, y[i] = pow(a[i], b))
63 
64 // A simple way to define the vsl binary functions. The operation should
65 // be in the form e.g. y[i] = a[i] + b[i]
66 #define DEFINE_VSL_BINARY_FUNC(name, operation) \
67  template<typename Dtype> \
68  void v##name(const int n, const Dtype* a, const Dtype* b, Dtype* y) { \
69  CHECK_GT(n, 0); CHECK(a); CHECK(b); CHECK(y); \
70  for (int i = 0; i < n; ++i) { operation; } \
71  } \
72  inline void vs##name( \
73  const int n, const float* a, const float* b, float* y) { \
74  v##name<float>(n, a, b, y); \
75  } \
76  inline void vd##name( \
77  const int n, const double* a, const double* b, double* y) { \
78  v##name<double>(n, a, b, y); \
79  }
80 
81 DEFINE_VSL_BINARY_FUNC(Add, y[i] = a[i] + b[i])
82 DEFINE_VSL_BINARY_FUNC(Sub, y[i] = a[i] - b[i])
83 DEFINE_VSL_BINARY_FUNC(Mul, y[i] = a[i] * b[i])
84 DEFINE_VSL_BINARY_FUNC(Div, y[i] = a[i] / b[i])
85 
86 // In addition, MKL comes with an additional function axpby that is not present
87 // in standard blas. We will simply use a two-step (inefficient, of course) way
88 // to mimic that.
89 inline void cblas_saxpby(const int N, const float alpha, const float* X,
90  const int incX, const float beta, float* Y,
91  const int incY) {
92  cblas_sscal(N, beta, Y, incY);
93  cblas_saxpy(N, alpha, X, incX, Y, incY);
94 }
95 inline void cblas_daxpby(const int N, const double alpha, const double* X,
96  const int incX, const double beta, double* Y,
97  const int incY) {
98  cblas_dscal(N, beta, Y, incY);
99  cblas_daxpy(N, alpha, X, incX, Y, incY);
100 }
101 
102 #endif // USE_MKL
103 #endif // CAFFE_UTIL_MKL_ALTERNATE_H_