euclidean layer update
[jacinto-ai/caffe-jacinto.git] / src / caffe / util / math_functions.cpp
1 // Copyright 2013 Yangqing Jia
3 #include <mkl.h>
4 #include <cublas_v2.h>
5 #include "caffe/common.hpp"
6 #include "caffe/util/math_functions.hpp"
8 namespace caffe {
10 template<>
11 void caffe_cpu_gemm<float>(const CBLAS_TRANSPOSE TransA,
12     const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K,
13     const float alpha, const float* A, const float* B, const float beta,
14     float* C) {
15   int lda = (TransA == CblasNoTrans) ? K : M;
16   int ldb = (TransB == CblasNoTrans) ? N : K;
17   cblas_sgemm(CblasRowMajor, TransA, TransB, M, N, K, alpha, A, lda, B,
18       ldb, beta, C, N);
19 }
21 template<>
22 void caffe_cpu_gemm<double>(const CBLAS_TRANSPOSE TransA,
23     const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K,
24     const double alpha, const double* A, const double* B, const double beta,
25     double* C) {
26   int lda = (TransA == CblasNoTrans) ? K : M;
27   int ldb = (TransB == CblasNoTrans) ? N : K;
28   cblas_dgemm(CblasRowMajor, TransA, TransB, M, N, K, alpha, A, lda, B,
29       ldb, beta, C, N);
30 }
32 template <>
33 void caffe_gpu_gemm<float>(const CBLAS_TRANSPOSE TransA,
34     const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K,
35     const float alpha, const float* A, const float* B, const float beta,
36     float* C) {
37   // Note that cublas follows fortran order.
38   int lda = (TransA == CblasNoTrans) ? K : M;
39   int ldb = (TransB == CblasNoTrans) ? N : K;
40   cublasOperation_t cuTransA =
41       (TransA == CblasNoTrans) ? CUBLAS_OP_N : CUBLAS_OP_T;
42   cublasOperation_t cuTransB =
43       (TransB == CblasNoTrans) ? CUBLAS_OP_N : CUBLAS_OP_T;
44   CUBLAS_CHECK(cublasSgemm(Caffe::cublas_handle(), cuTransB, cuTransA,
45       N, M, K, &alpha, B, ldb, A, lda, &beta, C, N));
46 }
48 template <>
49 void caffe_gpu_gemm<double>(const CBLAS_TRANSPOSE TransA,
50     const CBLAS_TRANSPOSE TransB, const int M, const int N, const int K,
51     const double alpha, const double* A, const double* B, const double beta,
52     double* C) {
53   // Note that cublas follows fortran order.
54   int lda = (TransA == CblasNoTrans) ? K : M;
55   int ldb = (TransB == CblasNoTrans) ? N : K;
56   cublasOperation_t cuTransA =
57       (TransA == CblasNoTrans) ? CUBLAS_OP_N : CUBLAS_OP_T;
58   cublasOperation_t cuTransB =
59       (TransB == CblasNoTrans) ? CUBLAS_OP_N : CUBLAS_OP_T;
60   CUBLAS_CHECK(cublasDgemm(Caffe::cublas_handle(), cuTransB, cuTransA,
61       N, M, K, &alpha, B, ldb, A, lda, &beta, C, N));
62 }
64 template <>
65 void caffe_cpu_gemv<float>(const CBLAS_TRANSPOSE TransA, const int M,
66     const int N, const float alpha, const float* A, const float* x,
67     const float beta, float* y) {
68   cblas_sgemv(CblasRowMajor, TransA, M, N, alpha, A, N, x, 1, beta, y, 1);
69 }
71 template <>
72 void caffe_cpu_gemv<double>(const CBLAS_TRANSPOSE TransA, const int M,
73     const int N, const double alpha, const double* A, const double* x,
74     const double beta, double* y) {
75   cblas_dgemv(CblasRowMajor, TransA, M, N, alpha, A, N, x, 1, beta, y, 1);
76 }
78 template <>
79 void caffe_gpu_gemv<float>(const CBLAS_TRANSPOSE TransA, const int M,
80     const int N, const float alpha, const float* A, const float* x,
81     const float beta, float* y) {
82   cublasOperation_t cuTransA =
83       (TransA == CblasNoTrans) ? CUBLAS_OP_T : CUBLAS_OP_N;
84   CUBLAS_CHECK(cublasSgemv(Caffe::cublas_handle(), cuTransA, N, M, &alpha,
85       A, N, x, 1, &beta, y, 1));
86 }
88 template <>
89 void caffe_gpu_gemv<double>(const CBLAS_TRANSPOSE TransA, const int M,
90     const int N, const double alpha, const double* A, const double* x,
91     const double beta, double* y) {
92   cublasOperation_t cuTransA =
93       (TransA == CblasNoTrans) ? CUBLAS_OP_T : CUBLAS_OP_N;
94   CUBLAS_CHECK(cublasDgemv(Caffe::cublas_handle(), cuTransA, N, M, &alpha,
95       A, N, x, 1, &beta, y, 1));
96 }
98 template <>
99 void caffe_axpy<float>(const int N, const float alpha, const float* X,
100     float* Y) { cblas_saxpy(N, alpha, X, 1, Y, 1); }
102 template <>
103 void caffe_axpy<double>(const int N, const double alpha, const double* X,
104     double* Y) { cblas_daxpy(N, alpha, X, 1, Y, 1); }
106 template <>
107 void caffe_axpby<float>(const int N, const float alpha, const float* X,
108     const float beta, float* Y) {
109   cblas_saxpby(N, alpha, X, 1, beta, Y, 1);
112 template <>
113 void caffe_axpby<double>(const int N, const double alpha, const double* X,
114     const double beta, double* Y) {
115   cblas_daxpby(N, alpha, X, 1, beta, Y, 1);
118 template <>
119 void caffe_copy<float>(const int N, const float* X, float* Y) {
120   cblas_scopy(N, X, 1, Y, 1);
123 template <>
124 void caffe_copy<double>(const int N, const double* X, double* Y) {
125   cblas_dcopy(N, X, 1, Y, 1);
128 template <>
129 void caffe_scal<float>(const int N, const float alpha, float *X) {
130   cblas_sscal(N, alpha, X, 1);
133 template <>
134 void caffe_scal<double>(const int N, const double alpha, double *X) {
135   cblas_dscal(N, alpha, X, 1);
138 template <>
139 void caffe_gpu_scal<float>(const int N, const float alpha, float *X) {
140   CUBLAS_CHECK(cublasSscal(Caffe::cublas_handle(), N, &alpha, X, 1));
143 template <>
144 void caffe_gpu_scal<double>(const int N, const double alpha, double *X) {
145   CUBLAS_CHECK(cublasDscal(Caffe::cublas_handle(), N, &alpha, X, 1));
148 template <>
149 void caffe_sqr<float>(const int n, const float* a, float* y) {
150   vsSqr(n, a, y);
153 template <>
154 void caffe_sqr<double>(const int n, const double* a, double* y) {
155   vdSqr(n, a, y);
158 template <>
159 void caffe_add<float>(const int n, const float* a, const float* b,
160     float* y) { vsAdd(n, a, b, y); }
162 template <>
163 void caffe_add<double>(const int n, const double* a, const double* b,
164     double* y) { vdAdd(n, a, b, y); }
166 template <>
167 void caffe_sub<float>(const int n, const float* a, const float* b,
168     float* y) { vsSub(n, a, b, y); }
170 template <>
171 void caffe_sub<double>(const int n, const double* a, const double* b,
172     double* y) { vdSub(n, a, b, y); }
174 template <>
175 void caffe_mul<float>(const int n, const float* a, const float* b,
176     float* y) { vsMul(n, a, b, y); }
178 template <>
179 void caffe_mul<double>(const int n, const double* a, const double* b,
180     double* y) { vdMul(n, a, b, y); }
182 template <>
183 void caffe_div<float>(const int n, const float* a, const float* b,
184     float* y) { vsDiv(n, a, b, y); }
186 template <>
187 void caffe_div<double>(const int n, const double* a, const double* b,
188     double* y) { vdDiv(n, a, b, y); }
190 template <>
191 void caffe_powx<float>(const int n, const float* a, const float b,
192     float* y) { vsPowx(n, a, b, y); }
194 template <>
195 void caffe_powx<double>(const int n, const double* a, const double b,
196     double* y) { vdPowx(n, a, b, y); }
198 template <>
199 void caffe_vRngUniform<float>(const int n, float* r,
200     const float a, const float b) {
201   VSL_CHECK(vsRngUniform(VSL_RNG_METHOD_UNIFORM_STD, Caffe::vsl_stream(),
202       n, r, a, b));
205 template <>
206 void caffe_vRngUniform<double>(const int n, double* r,
207     const double a, const double b) {
208   VSL_CHECK(vdRngUniform(VSL_RNG_METHOD_UNIFORM_STD, Caffe::vsl_stream(),
209       n, r, a, b));
212 template <>
213 void caffe_vRngGaussian<float>(const int n, float* r, const float a,
214     const float sigma) {
215   VSL_CHECK(vsRngGaussian(VSL_RNG_METHOD_GAUSSIAN_BOXMULLER,
216       Caffe::vsl_stream(), n, r, a, sigma));
220 template <>
221 void caffe_vRngGaussian<double>(const int n, double* r, const double a,
222     const double sigma) {
223   VSL_CHECK(vdRngGaussian(VSL_RNG_METHOD_GAUSSIAN_BOXMULLER,
224       Caffe::vsl_stream(), n, r, a, sigma));
227 template <>
228 void caffe_exp<float>(const int n, const float* a, float* y) {
229   vsExp(n, a, y);
232 template <>
233 void caffe_exp<double>(const int n, const double* a, double* y) {
234   vdExp(n, a, y);
237 template <>
238 float caffe_cpu_dot<float>(const int n, const float* x, const float* y) {
239   return cblas_sdot(n, x, 1, y, 1);
242 template <>
243 double caffe_cpu_dot<double>(const int n, const double* x, const double* y) {
244   return cblas_ddot(n, x, 1, y, 1);
247 }  // namespace caffe