1 #include <blas_magma.h>
5 #include <quda_internal.h>
12 #define _cU MagmaUpper
13 #define _cR MagmaRight
15 #define _cC MagmaConjTrans
16 #define _cN MagmaNoTrans
17 #define _cNV MagmaNoVec
24 template<typename magmaFloat> void magma_gesv(void *sol, const int ldn, const int n, void *Mat, const int ldm)
26 cudaPointerAttributes ptr_attr;
27 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");
30 magma_int_t err, info;
32 magma_imalloc_pinned(&ipiv, n);
36 magma_malloc_pinned((void**)&tmp, ldm*n*sizeof(magmaFloat));
37 memcpy(tmp, Mat, ldm*n*sizeof(magmaFloat));
39 if ( ptr_attr.memoryType == cudaMemoryTypeDevice ) {
40 if(sizeof(magmaFloat) == sizeof(magmaFloatComplex))
42 err = magma_cgesv_gpu(n, 1, static_cast<magmaFloatComplex* >(tmp), ldm, ipiv, static_cast<magmaFloatComplex* >(sol), ldn, &info);
43 if(err != 0) errorQuda("\nError in SolveGPUProjMatrix (magma_cgesv_gpu), exit ...\n");
47 err = magma_zgesv_gpu(n, 1, static_cast<magmaDoubleComplex*>(tmp), ldm, ipiv, static_cast<magmaDoubleComplex*>(sol), ldn, &info);
48 if(err != 0) errorQuda("\nError in SolveGPUProjMatrix (magma_zgesv_gpu), exit ...\n");
50 } else if ( ptr_attr.memoryType == cudaMemoryTypeHost ) {
52 if(sizeof(magmaFloat) == sizeof(magmaFloatComplex))
54 err = magma_cgesv(n, 1, static_cast<magmaFloatComplex* >(tmp), ldm, ipiv, static_cast<magmaFloatComplex* >(sol), ldn, &info);
55 if(err != 0) errorQuda("\nError in SolveGPUProjMatrix (magma_cgesv), exit ...\n");
59 err = magma_zgesv(n, 1, static_cast<magmaDoubleComplex*>(tmp), ldm, ipiv, static_cast<magmaDoubleComplex*>(sol), ldn, &info);
60 if(err != 0) errorQuda("\nError in SolveGPUProjMatrix (magma_zgesv), exit ...\n");
64 magma_free_pinned(ipiv);
65 magma_free_pinned(tmp);
73 template<typename magmaFloat> void magma_geev(void *Mat, const int m, const int ldm, void *vr, void *evalues, const int ldv)
75 cudaPointerAttributes ptr_attr;
76 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");
78 magma_int_t err, info;
80 void *work_ = nullptr, *rwork_ = nullptr;
82 if ( ptr_attr.memoryType == cudaMemoryTypeDevice ) {
83 errorQuda("\nGPU version is not supported.\n");
84 } else if ( ptr_attr.memoryType == cudaMemoryTypeHost ) {
86 if(sizeof(magmaFloat) == sizeof(magmaFloatComplex))
88 magmaFloatComplex qwork;
90 magmaFloatComplex *work = static_cast<magmaFloatComplex*>(work_);
91 float *rwork = static_cast<float*>(rwork_);
93 err = magma_cgeev(_cNV, _cV, m, nullptr, ldm, nullptr, nullptr, ldv, nullptr, ldv, &qwork, -1, nullptr, &info);
94 if( err != 0 ) errorQuda( "Error: CGEEVX, info %d\n",info);
96 magma_int_t lwork = static_cast<magma_int_t>( MAGMA_C_REAL(qwork));
98 magma_smalloc_pinned(&rwork, 2*m);
99 magma_cmalloc_pinned(&work, lwork);
101 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);
102 if( err != 0 ) errorQuda( "Error: CGEEVX, info %d\n",info);
107 magmaDoubleComplex qwork;
109 magmaDoubleComplex *work = static_cast<magmaDoubleComplex*>(work_);
110 double *rwork = static_cast<double*>(rwork_);
111 err = magma_zgeev(_cNV, _cV, m, nullptr, ldm, nullptr, nullptr, ldv, nullptr, ldv, &qwork, -1, nullptr, &info);
112 if( err != 0 ) errorQuda( "Error: ZGEEVX, info %d\n",info);
114 magma_int_t lwork = static_cast<magma_int_t>( MAGMA_Z_REAL(qwork));
116 magma_dmalloc_pinned(&rwork, 2*m);
117 magma_zmalloc_pinned(&work, lwork);
119 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);
120 if( err != 0 ) errorQuda( "Error: ZGEEVX, info %d\n",info);
124 if(rwork_) magma_free_pinned(rwork_);
125 if(work_ ) magma_free_pinned(work_);
133 template<typename magmaFloat> void magma_gels(void *Mat, void *c, int rows, int cols, int ldm)
135 cudaPointerAttributes ptr_attr;
136 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");
138 magma_int_t err, info, lwork;
139 void *hwork_ = nullptr;
141 if ( ptr_attr.memoryType == cudaMemoryTypeDevice )
143 if(sizeof(magmaFloat) == sizeof(magmaFloatComplex))
145 magma_int_t nb = magma_get_cgeqrf_nb( rows, cols );
146 lwork = std::max( cols*nb, 2*nb*nb );
148 magmaFloatComplex *hwork = static_cast<magmaFloatComplex*>(hwork_);
149 magma_cmalloc_cpu( &hwork, lwork);
151 err = magma_cgels_gpu( _cN, rows, cols, 1, static_cast<magmaFloatComplex*>(Mat), ldm, static_cast<magmaFloatComplex*>(c),
152 ldm, hwork, lwork, &info );
153 if (err != 0) errorQuda("\nError in magma_cgels_gpu, %d, exit ...\n", info);
155 magma_int_t nb = magma_get_zgeqrf_nb( rows, cols );
157 lwork = std::max( cols*nb, 2*nb*nb );
158 magmaDoubleComplex *hwork = static_cast<magmaDoubleComplex*>(hwork_);
159 magma_zmalloc_cpu( &hwork, lwork);
161 err = magma_zgels_gpu( _cN, rows, cols, 1, static_cast<magmaDoubleComplex*>(Mat), ldm, static_cast<magmaDoubleComplex*>(c),
162 ldm, hwork, lwork, &info );
163 if (err != 0) errorQuda("\nError in magma_zgels_gpu, %d, exit ...\n", info);
165 } else if ( ptr_attr.memoryType == cudaMemoryTypeHost ) {
168 if(sizeof(magmaFloat) == sizeof(magmaFloatComplex))
170 magma_int_t nb = magma_get_cgeqrf_nb( rows, cols );
172 lwork = std::max( cols*nb, 2*nb*nb );
173 magmaFloatComplex *hwork = static_cast<magmaFloatComplex*>(hwork_);
174 magma_cmalloc_cpu( &hwork, lwork);
176 err = magma_cgels( _cN, rows, cols, 1, static_cast<magmaFloatComplex*>(Mat), ldm, static_cast<magmaFloatComplex*>(c),
177 ldm, hwork, lwork, &info );
178 if (err != 0) errorQuda("\nError in magma_cgels_cpu, %d, exit ...\n", info);
180 magma_int_t nb = magma_get_zgeqrf_nb( rows, cols );
182 lwork = std::max( cols*nb, 2*nb*nb );
183 magmaDoubleComplex *hwork = static_cast<magmaDoubleComplex*>(hwork_);
184 magma_zmalloc_cpu( &hwork, lwork);
186 err = magma_zgels( _cN, rows, cols, 1, static_cast<magmaDoubleComplex*>(Mat), ldm, static_cast<magmaDoubleComplex*>(c),
187 ldm, hwork, lwork, &info );
188 if (err != 0) errorQuda("\nError in magma_zgels_cpu, %d, exit ...\n", info);
192 if(hwork_) magma_free_cpu(hwork_);
198 template<typename magmaFloat> void magma_heev(void *Mat, const int m, const int ldm, void *evalues)
200 cudaPointerAttributes ptr_attr;
201 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");
203 magma_int_t err, info;
205 void *work_ = nullptr, *rwork_ = nullptr;
206 int *iwork = nullptr;
209 if ( ptr_attr.memoryType == cudaMemoryTypeDevice ) {
210 errorQuda("\nGPU version is not supported.\n");
211 } else if ( ptr_attr.memoryType == cudaMemoryTypeHost ) {
212 if(sizeof(magmaFloat) == sizeof(magmaFloatComplex))
214 magmaFloatComplex qwork;
217 magmaFloatComplex *work = static_cast<magmaFloatComplex*>(work_);
218 float *rwork = static_cast<float*>(rwork_);
220 err = magma_cheevd(_cV, _cU, m, nullptr, ldm, nullptr, &qwork, -1, &qrwork, -1, &qiwork, -1, &info);
221 if( err != 0 ) errorQuda( "Error: CHEEVD, info %d\n",info);
223 magma_int_t lwork = static_cast<magma_int_t>( MAGMA_C_REAL(qwork));
224 magma_int_t lrwork = static_cast<magma_int_t>( qrwork );
225 magma_int_t liwork = static_cast<magma_int_t>( qiwork );
227 magma_cmalloc_pinned(&work, lwork);
228 magma_smalloc_pinned(&rwork, lrwork);
229 magma_imalloc_pinned(&iwork, liwork);
231 err = magma_cheevd(_cV, _cU, m, static_cast<magmaFloatComplex*>(Mat), ldm, static_cast<float*>(evalues), work, lwork, rwork, lrwork, iwork, liwork, &info);
232 if( err != 0 ) errorQuda( "Error: CHEEVD, info %d\n",info);
234 magmaDoubleComplex qwork;
237 magmaDoubleComplex *work = static_cast<magmaDoubleComplex*>(work_);
238 double *rwork = static_cast<double*>(rwork_);
240 err = magma_zheevd(_cV, _cU, m, nullptr, ldm, nullptr, &qwork, -1, &qrwork, -1, &qiwork, -1, &info);
241 if( err != 0 ) errorQuda( "Error: ZHEEVD, info %d\n",info);
243 magma_int_t lwork = static_cast<magma_int_t>( MAGMA_Z_REAL(qwork));
244 magma_int_t lrwork = static_cast<magma_int_t>( qrwork );
245 magma_int_t liwork = static_cast<magma_int_t>( qiwork );
247 magma_zmalloc_pinned(&work, lwork);
248 magma_dmalloc_pinned(&rwork, lrwork);
249 magma_imalloc_pinned(&iwork, liwork);
251 err = magma_zheevd(_cV, _cU, m, static_cast<magmaDoubleComplex*>(Mat), ldm, static_cast<double*>(evalues), work, lwork, rwork, lrwork, iwork, liwork, &info);
252 if( err != 0 ) errorQuda( "Error: ZHEEVD, info %d\n",info);
256 if(rwork_) magma_free_pinned(rwork_);
257 if(work_ ) magma_free_pinned(work_);
258 if(iwork ) magma_free_pinned(iwork);
265 void magma_Xgesv(void* sol, const int ldn, const int n, void* Mat, const int ldm, const int prec)
268 if (prec == sizeof(std::complex< double >)) magma_gesv<magmaDoubleComplex>(sol, ldn, n, Mat, ldm);
269 else if (prec == sizeof(std::complex< float >)) magma_gesv<magmaFloatComplex >(sol, ldn, n, Mat, ldm);
270 else errorQuda("\nPrecision is not supported.\n");
275 void magma_Xgeev(void *Mat, const int m, const int ldm, void *vr, void *evalues, const int ldv, const int prec)
278 if (prec == sizeof(std::complex< double >)) magma_geev<magmaDoubleComplex>(Mat, m, ldm, vr, evalues, ldv);
279 else if (prec == sizeof(std::complex< float >)) magma_geev<magmaFloatComplex >(Mat, m, ldm, vr, evalues, ldv);
280 else errorQuda("\nPrecision is not supported.\n");
286 void magma_Xgels(void *Mat, void *c, int rows, int cols, int ldm, const int prec)
289 if (prec == sizeof(std::complex< double >)) magma_gels<magmaDoubleComplex>(Mat, c, rows, cols, ldm);
290 else if (prec == sizeof(std::complex< float >)) magma_gels<magmaFloatComplex >(Mat, c, rows, cols, ldm);
291 else errorQuda("\nPrecision is not supported.\n");
296 void magma_Xheev(void *Mat, const int m, const int ldm, void *evalues, const int prec)
299 if (prec == sizeof(std::complex< double >)) magma_heev<magmaDoubleComplex>(Mat, m, ldm, evalues);
300 else if (prec == sizeof(std::complex< float >)) magma_heev<magmaFloatComplex >(Mat, m, ldm, evalues);
301 else errorQuda("\nPrecision is not supported.\n");
309 magma_int_t err = magma_init();
311 if(err != MAGMA_SUCCESS) errorQuda("\nError: cannot initialize MAGMA library\n");
313 int major, minor, micro;
315 magma_version( &major, &minor, µ);
316 if (getVerbosity() >= QUDA_VERBOSE) printfQuda("\nMAGMA library version: %d.%d\n\n", major, minor);
318 errorQuda("\nError: MAGMA library was not compiled, check your compilation options...\n");
325 if(magma_finalize() != MAGMA_SUCCESS) errorQuda("\nError: cannot close MAGMA library\n");
327 errorQuda("\nError: MAGMA library was not compiled, check your compilation options...\n");