QUDA  0.9.0
blas_magma.cu
Go to the documentation of this file.
1 #include <blas_magma.h>
2 #include <string.h>
3 
4 #include <vector>
5 #include <algorithm>
6 
7 #include <util_quda.h>
8 #include <quda_internal.h>
9 
10 #ifdef MAGMA_LIB
11 
12 #include <magma.h>
13 
14 #define _cV MagmaVec
15 #define _cU MagmaUpper
16 #define _cR MagmaRight
17 #define _cL MagmaLeft
18 #define _cC MagmaConjTrans
19 #define _cN MagmaNoTrans
20 #define _cNV MagmaNoVec
21 
22 #endif
23 
24 #ifdef MAGMA_LIB
25 
26 
27  template<typename magmaFloat> void magma_gesv(void *sol, const int ldn, const int n, void *Mat, const int ldm)
28  {
29  cudaPointerAttributes ptr_attr;
30  if(cudaPointerGetAttributes(&ptr_attr, Mat) == cudaErrorInvalidValue) errorQuda("In magma_gesv, a pointer was not allocated in, mapped by or registered with current CUDA context.\n");
31 
32  magma_int_t *ipiv;
33  magma_int_t err, info;
34 
35  magma_imalloc_pinned(&ipiv, n);
36 
37  void *tmp;
38 
39  magma_malloc_pinned((void**)&tmp, ldm*n*sizeof(magmaFloat));
40  memcpy(tmp, Mat, ldm*n*sizeof(magmaFloat));
41 
42  if ( ptr_attr.memoryType == cudaMemoryTypeDevice ) {
43  if(sizeof(magmaFloat) == sizeof(magmaFloatComplex))
44  {
45  err = magma_cgesv_gpu(n, 1, static_cast<magmaFloatComplex* >(tmp), ldm, ipiv, static_cast<magmaFloatComplex* >(sol), ldn, &info);
46  if(err != 0) errorQuda("\nError in SolveGPUProjMatrix (magma_cgesv_gpu), exit ...\n");
47  }
48  else
49  {
50  err = magma_zgesv_gpu(n, 1, static_cast<magmaDoubleComplex*>(tmp), ldm, ipiv, static_cast<magmaDoubleComplex*>(sol), ldn, &info);
51  if(err != 0) errorQuda("\nError in SolveGPUProjMatrix (magma_zgesv_gpu), exit ...\n");
52  }
53  } else if ( ptr_attr.memoryType == cudaMemoryTypeHost ) {
54 
55  if(sizeof(magmaFloat) == sizeof(magmaFloatComplex))
56  {
57  err = magma_cgesv(n, 1, static_cast<magmaFloatComplex* >(tmp), ldm, ipiv, static_cast<magmaFloatComplex* >(sol), ldn, &info);
58  if(err != 0) errorQuda("\nError in SolveGPUProjMatrix (magma_cgesv), exit ...\n");
59  }
60  else
61  {
62  err = magma_zgesv(n, 1, static_cast<magmaDoubleComplex*>(tmp), ldm, ipiv, static_cast<magmaDoubleComplex*>(sol), ldn, &info);
63  if(err != 0) errorQuda("\nError in SolveGPUProjMatrix (magma_zgesv), exit ...\n");
64  }
65  }
66 
67  magma_free_pinned(ipiv);
68  magma_free_pinned(tmp);
69 
70  return;
71  }
72 
73 
75 
76  template<typename magmaFloat> void magma_geev(void *Mat, const int m, const int ldm, void *vr, void *evalues, const int ldv)
77  {
78  cudaPointerAttributes ptr_attr;
79  if(cudaPointerGetAttributes(&ptr_attr, Mat) == cudaErrorInvalidValue) errorQuda("In magma_geev, a pointer was not allocated in, mapped by or registered with current CUDA context.\n");
80 
81  magma_int_t err, info;
82 
83  void *work_ = nullptr, *rwork_ = nullptr;
84 
85  if ( ptr_attr.memoryType == cudaMemoryTypeDevice ) {
86  errorQuda("\nGPU version is not supported.\n");
87  } else if ( ptr_attr.memoryType == cudaMemoryTypeHost ) {
88 
89  if(sizeof(magmaFloat) == sizeof(magmaFloatComplex))
90  {
91  magmaFloatComplex qwork;
92 
93  magmaFloatComplex *work = static_cast<magmaFloatComplex*>(work_);
94  float *rwork = static_cast<float*>(rwork_);
95 
96  err = magma_cgeev(_cNV, _cV, m, nullptr, ldm, nullptr, nullptr, ldv, nullptr, ldv, &qwork, -1, nullptr, &info);
97  if( err != 0 ) errorQuda( "Error: CGEEVX, info %d\n",info);
98 
99  magma_int_t lwork = static_cast<magma_int_t>( MAGMA_C_REAL(qwork));
100 
101  magma_smalloc_pinned(&rwork, 2*m);
102  magma_cmalloc_pinned(&work, lwork);
103 
104  err = magma_cgeev(_cNV, _cV, m, static_cast<magmaFloatComplex*>(Mat), ldm, static_cast<magmaFloatComplex*>(evalues), nullptr, ldv, static_cast<magmaFloatComplex*>(vr), ldv, work, lwork, rwork, &info);
105  if( err != 0 ) errorQuda( "Error: CGEEVX, info %d\n",info);
106 
107  }
108  else
109  {
110  magmaDoubleComplex qwork;
111 
112  magmaDoubleComplex *work = static_cast<magmaDoubleComplex*>(work_);
113  double *rwork = static_cast<double*>(rwork_);
114  err = magma_zgeev(_cNV, _cV, m, nullptr, ldm, nullptr, nullptr, ldv, nullptr, ldv, &qwork, -1, nullptr, &info);
115  if( err != 0 ) errorQuda( "Error: ZGEEVX, info %d\n",info);
116 
117  magma_int_t lwork = static_cast<magma_int_t>( MAGMA_Z_REAL(qwork));
118 
119  magma_dmalloc_pinned(&rwork, 2*m);
120  magma_zmalloc_pinned(&work, lwork);
121 
122  err = magma_zgeev(_cNV, _cV, m, static_cast<magmaDoubleComplex*>(Mat), ldm, static_cast<magmaDoubleComplex*>(evalues), nullptr, ldv, static_cast<magmaDoubleComplex*>(vr), ldv, work, lwork, rwork, &info);
123  if( err != 0 ) errorQuda( "Error: ZGEEVX, info %d\n",info);
124  }
125  }
126 
127  if(rwork_) magma_free_pinned(rwork_);
128  if(work_ ) magma_free_pinned(work_);
129 
130  return;
131  }
132 
133 
135 
136  template<typename magmaFloat> void magma_gels(void *Mat, void *c, int rows, int cols, int ldm)
137  {
138  cudaPointerAttributes ptr_attr;
139  if(cudaPointerGetAttributes(&ptr_attr, Mat) == cudaErrorInvalidValue) errorQuda("In magma_gels, a pointer was not allocated in, mapped by or registered with current CUDA context.\n");
140 
141  magma_int_t err, info, lwork;
142  void *hwork_ = nullptr;
143 
144  if ( ptr_attr.memoryType == cudaMemoryTypeDevice )
145  {
146  if(sizeof(magmaFloat) == sizeof(magmaFloatComplex))
147  {
148  magma_int_t nb = magma_get_cgeqrf_nb( rows, cols );
149  lwork = std::max( cols*nb, 2*nb*nb );
150 
151  magmaFloatComplex *hwork = static_cast<magmaFloatComplex*>(hwork_);
152  magma_cmalloc_cpu( &hwork, lwork);
153 
154  err = magma_cgels_gpu( _cN, rows, cols, 1, static_cast<magmaFloatComplex*>(Mat), ldm, static_cast<magmaFloatComplex*>(c),
155  ldm, hwork, lwork, &info );
156  if (err != 0) errorQuda("\nError in magma_cgels_gpu, %d, exit ...\n", info);
157  } else {
158  magma_int_t nb = magma_get_zgeqrf_nb( rows, cols );
159 
160  lwork = std::max( cols*nb, 2*nb*nb );
161  magmaDoubleComplex *hwork = static_cast<magmaDoubleComplex*>(hwork_);
162  magma_zmalloc_cpu( &hwork, lwork);
163 
164  err = magma_zgels_gpu( _cN, rows, cols, 1, static_cast<magmaDoubleComplex*>(Mat), ldm, static_cast<magmaDoubleComplex*>(c),
165  ldm, hwork, lwork, &info );
166  if (err != 0) errorQuda("\nError in magma_zgels_gpu, %d, exit ...\n", info);
167  }
168  } else if ( ptr_attr.memoryType == cudaMemoryTypeHost ) {
169 
170 
171  if(sizeof(magmaFloat) == sizeof(magmaFloatComplex))
172  {
173  magma_int_t nb = magma_get_cgeqrf_nb( rows, cols );
174 
175  lwork = std::max( cols*nb, 2*nb*nb );
176  magmaFloatComplex *hwork = static_cast<magmaFloatComplex*>(hwork_);
177  magma_cmalloc_cpu( &hwork, lwork);
178 
179  err = magma_cgels( _cN, rows, cols, 1, static_cast<magmaFloatComplex*>(Mat), ldm, static_cast<magmaFloatComplex*>(c),
180  ldm, hwork, lwork, &info );
181  if (err != 0) errorQuda("\nError in magma_cgels_cpu, %d, exit ...\n", info);
182  } else {
183  magma_int_t nb = magma_get_zgeqrf_nb( rows, cols );
184 
185  lwork = std::max( cols*nb, 2*nb*nb );
186  magmaDoubleComplex *hwork = static_cast<magmaDoubleComplex*>(hwork_);
187  magma_zmalloc_cpu( &hwork, lwork);
188 
189  err = magma_zgels( _cN, rows, cols, 1, static_cast<magmaDoubleComplex*>(Mat), ldm, static_cast<magmaDoubleComplex*>(c),
190  ldm, hwork, lwork, &info );
191  if (err != 0) errorQuda("\nError in magma_zgels_cpu, %d, exit ...\n", info);
192  }
193  }
194 
195  if(hwork_) magma_free_cpu(hwork_);
196 
197  return;
198  }
199 
200 
201  template<typename magmaFloat> void magma_heev(void *Mat, const int m, const int ldm, void *evalues)
202  {
203  cudaPointerAttributes ptr_attr;
204  if(cudaPointerGetAttributes(&ptr_attr, Mat) == cudaErrorInvalidValue) errorQuda("In magma_heev, a pointer was not allocated in, mapped by or registered with current CUDA context.\n");
205 
206  magma_int_t err, info;
207 
208  void *work_ = nullptr, *rwork_ = nullptr;
209  int *iwork = nullptr;
210  int qiwork;
211 
212  if ( ptr_attr.memoryType == cudaMemoryTypeDevice ) {
213  errorQuda("\nGPU version is not supported.\n");
214  } else if ( ptr_attr.memoryType == cudaMemoryTypeHost ) {
215  if(sizeof(magmaFloat) == sizeof(magmaFloatComplex))
216  {
217  magmaFloatComplex qwork;
218  float qrwork;
219 
220  magmaFloatComplex *work = static_cast<magmaFloatComplex*>(work_);
221  float *rwork = static_cast<float*>(rwork_);
222 
223  err = magma_cheevd(_cV, _cU, m, nullptr, ldm, nullptr, &qwork, -1, &qrwork, -1, &qiwork, -1, &info);
224  if( err != 0 ) errorQuda( "Error: CHEEVD, info %d\n",info);
225 
226  magma_int_t lwork = static_cast<magma_int_t>( MAGMA_C_REAL(qwork));
227  magma_int_t lrwork = static_cast<magma_int_t>( qrwork );
228  magma_int_t liwork = static_cast<magma_int_t>( qiwork );
229 
230  magma_cmalloc_pinned(&work, lwork);
231  magma_smalloc_pinned(&rwork, lrwork);
232  magma_imalloc_pinned(&iwork, liwork);
233 
234  err = magma_cheevd(_cV, _cU, m, static_cast<magmaFloatComplex*>(Mat), ldm, static_cast<float*>(evalues), work, lwork, rwork, lrwork, iwork, liwork, &info);
235  if( err != 0 ) errorQuda( "Error: CHEEVD, info %d\n",info);
236  } else {
237  magmaDoubleComplex qwork;
238  double qrwork;
239 
240  magmaDoubleComplex *work = static_cast<magmaDoubleComplex*>(work_);
241  double *rwork = static_cast<double*>(rwork_);
242 
243  err = magma_zheevd(_cV, _cU, m, nullptr, ldm, nullptr, &qwork, -1, &qrwork, -1, &qiwork, -1, &info);
244  if( err != 0 ) errorQuda( "Error: ZHEEVD, info %d\n",info);
245 
246  magma_int_t lwork = static_cast<magma_int_t>( MAGMA_Z_REAL(qwork));
247  magma_int_t lrwork = static_cast<magma_int_t>( qrwork );
248  magma_int_t liwork = static_cast<magma_int_t>( qiwork );
249 
250  magma_zmalloc_pinned(&work, lwork);
251  magma_dmalloc_pinned(&rwork, lrwork);
252  magma_imalloc_pinned(&iwork, liwork);
253 
254  err = magma_zheevd(_cV, _cU, m, static_cast<magmaDoubleComplex*>(Mat), ldm, static_cast<double*>(evalues), work, lwork, rwork, lrwork, iwork, liwork, &info);
255  if( err != 0 ) errorQuda( "Error: ZHEEVD, info %d\n",info);
256  }
257  }
258 
259  if(rwork_) magma_free_pinned(rwork_);
260  if(work_ ) magma_free_pinned(work_);
261  if(iwork ) magma_free_pinned(iwork);
262 
263  return;
264  }
265 
266 #endif // MAGMA_LIB
267 
268  void magma_Xgesv(void* sol, const int ldn, const int n, void* Mat, const int ldm, const int prec)
269  {
270 #ifdef MAGMA_LIB
271  if (prec == sizeof(std::complex< double >)) magma_gesv<magmaDoubleComplex>(sol, ldn, n, Mat, ldm);
272  else if (prec == sizeof(std::complex< float >)) magma_gesv<magmaFloatComplex >(sol, ldn, n, Mat, ldm);
273  else errorQuda("\nPrecision is not supported.\n");
274 #endif
275  return;
276  }
277 
278  void magma_Xgeev(void *Mat, const int m, const int ldm, void *vr, void *evalues, const int ldv, const int prec)
279  {
280 #ifdef MAGMA_LIB
281  if (prec == sizeof(std::complex< double >)) magma_geev<magmaDoubleComplex>(Mat, m, ldm, vr, evalues, ldv);
282  else if (prec == sizeof(std::complex< float >)) magma_geev<magmaFloatComplex >(Mat, m, ldm, vr, evalues, ldv);
283  else errorQuda("\nPrecision is not supported.\n");
284 #endif
285  return;
286  }
287 
288 
289  void magma_Xgels(void *Mat, void *c, int rows, int cols, int ldm, const int prec)
290  {
291 #ifdef MAGMA_LIB
292  if (prec == sizeof(std::complex< double >)) magma_gels<magmaDoubleComplex>(Mat, c, rows, cols, ldm);
293  else if (prec == sizeof(std::complex< float >)) magma_gels<magmaFloatComplex >(Mat, c, rows, cols, ldm);
294  else errorQuda("\nPrecision is not supported.\n");
295 #endif
296  return;
297  }
298 
299  void magma_Xheev(void *Mat, const int m, const int ldm, void *evalues, const int prec)
300  {
301 #ifdef MAGMA_LIB
302  if (prec == sizeof(std::complex< double >)) magma_heev<magmaDoubleComplex>(Mat, m, ldm, evalues);
303  else if (prec == sizeof(std::complex< float >)) magma_heev<magmaFloatComplex >(Mat, m, ldm, evalues);
304  else errorQuda("\nPrecision is not supported.\n");
305 #endif
306  return;
307  }
308 
309 
310  void OpenMagma(){
311 #ifdef MAGMA_LIB
312  magma_int_t err = magma_init();
313 
314  if(err != MAGMA_SUCCESS) errorQuda("\nError: cannot initialize MAGMA library\n");
315 
316  int major, minor, micro;
317 
318  magma_version( &major, &minor, &micro);
319  printfQuda("\nMAGMA library version: %d.%d\n\n", major, minor);
320 #else
321  errorQuda("\nError: MAGMA library was not compiled, check your compilation options...\n");
322 #endif
323  return;
324  }
325 
326  void CloseMagma(){
327 #ifdef MAGMA_LIB
328  if(magma_finalize() != MAGMA_SUCCESS) errorQuda("\nError: cannot close MAGMA library\n");
329 #else
330  errorQuda("\nError: MAGMA library was not compiled, check your compilation options...\n");
331 #endif
332  return;
333  }
334 
335 
336 #ifdef MAGMA_LIB
337 
338 #undef _cV
339 #undef _cU
340 #undef _cR
341 #undef _cL
342 #undef _cC
343 #undef _cN
344 #undef _cNV
345 
346 #endif
#define errorQuda(...)
Definition: util_quda.h:90
cudaColorSpinorField * tmp
Definition: covdev_test.cpp:44
void magma_Xgesv(void *sol, const int ldn, const int n, void *Mat, const int ldm, const int prec)
Definition: blas_magma.cu:268
void Mat(sFloat *out, gFloat **link, sFloat *in, int daggerBit, int mu)
void magma_Xgels(void *Mat, void *c, int rows, int cols, int ldm, const int prec)
Definition: blas_magma.cu:289
void CloseMagma()
Definition: blas_magma.cu:326
cudaError_t err
void magma_Xgeev(void *Mat, const int m, const int ldm, void *vr, void *evalues, const int ldv, const int prec)
Definition: blas_magma.cu:278
void * memcpy(void *__dst, const void *__src, size_t __n)
void OpenMagma()
Definition: blas_magma.cu:310
void magma_Xheev(void *Mat, const int m, const int ldm, void *evalues, const int prec)
Definition: blas_magma.cu:299
#define printfQuda(...)
Definition: util_quda.h:84
const void * c
QudaPrecision prec
Definition: test_util.cpp:1615