HPhi++  3.1.0
matrixlapack_magma.cpp
Go to the documentation of this file.
1 /* HPhi - Quantum Lattice Model Simulator */
2 /* Copyright (C) 2015 The University of Tokyo */
3 
4 /* This program is free software: you can redistribute it and/or modify */
5 /* it under the terms of the GNU General Public License as published by */
6 /* the Free Software Foundation, either version 3 of the License, or */
7 /* (at your option) any later version. */
8 
9 /* This program is distributed in the hope that it will be useful, */
10 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
11 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
12 /* GNU General Public License for more details. */
13 
14 /* You should have received a copy of the GNU General Public License */
15 /* along with this program. If not, see <http://www.gnu.org/licenses/>. */
16 /*-------------------------------------------------------------
17  *[ver.2009.05.25]
18  *-------------------------------------------------------------
19  * Copyright (C) 2007-2009 Daisuke Tahara. All rights reserved.
20  * Copyright (C) 2009- Takahiro Misawa. All rights reserved.
21  * Some functions are added by TM.
22  *-------------------------------------------------------------*/
23 /*=================================================================================================*/
24 
25 #ifdef _MAGMA
26 #include "matrixlapack_magma.hpp"
27 
28 
29 int diag_magma_cmp(int xNsize, std::complex<double> **A,
30  std::complex<double> *r,std::complex<double> **vec, int ngpu){
31 
32  if(ngpu <= 0) {
33  fprintf(stdout, " Error: ngpu is less than or equal to 0. ngpu = %d\n", ngpu);
34  fprintf(stdout, " exit in this function.\n\n");
35  return -1;
36  }
37 
38  magma_init();
39 
40  // local variable
41  int i,j,k;
42  magma_vec_t jobz;
43  magma_uplo_t uplo;
44  magma_int_t n, lda, lwork, lrwork;
45  magma_int_t *iwork, liwork;
46  double *rwork;
47  double *w;
48  magmaDoubleComplex *a, *work;
49  magma_int_t info;
50 
51  {
52  magma_int_t maxngpu = 0;
53  magma_device_t *dummy;
54  magma_getdevices(dummy, 9999, &maxngpu);
55  if(ngpu > maxngpu) {
56  fprintf(stdout, " Warning: ngpu is beyond maxgpu. ngpu = %d, maxngpu = %d\n", ngpu, maxngpu);
57  fprintf(stdout, " MAGMA library executes maxngpu.\n\n");
58  ngpu = maxngpu;
59  }
60  }
61 
62  // auxiliary variable
63  magmaDoubleComplex aux_work[1];
64  double aux_rwork[1];
65  magma_int_t aux_iwork[1];
66 
67  n = lda = xNsize;
68  jobz = MagmaVec;
69  uplo = MagmaUpper;
70 
71  // get optimal work size
72  magma_zheevd(jobz, uplo,
73  n, NULL, lda, NULL, // A, w
74  aux_work, -1,
75  aux_rwork, -1,
76  aux_iwork, -1,
77  &info);
78 
79  lwork = (magma_int_t) MAGMA_Z_REAL(aux_work[0]);
80  lrwork = (magma_int_t) aux_rwork[0];
81  liwork = aux_iwork[0];
82 
83  // allocate
84  magma_zmalloc_cpu(&a, xNsize * xNsize);
85  magma_dmalloc_cpu(&w, xNsize);
86  magma_zmalloc_pinned(&work, lwork);
87  magma_dmalloc_cpu(&rwork, lrwork);
88  magma_imalloc_cpu(&iwork, liwork);
89 
90  k=0;
91  for(j=0;j<xNsize;j++){
92  for(i=0;i<xNsize;i++){
93  MAGMA_Z_REAL(a[k]) = real(A[i][j]);
94  MAGMA_Z_IMAG(a[k]) = imag(A[i][j]);
95  k++;
96  }
97  }
98 
99  // calculation eigen value and eigen vector
100  magma_zheevd_m(ngpu, jobz, uplo,
101  n, a, lda, w,
102  work, lwork,
103  rwork, lrwork,
104  iwork, liwork,
105  &info);
106 
107  magma_free_cpu(iwork);
108  if(info != 0){
109  magma_free_cpu(a);
110  magma_free_cpu(w);
111  magma_free_pinned(work);
112  magma_free_cpu(rwork);
113  return -1;
114  }
115 
116  k=0;
117  for(i=0;i<xNsize;i++){
118  for(j=0;j<xNsize;j++){
119  vec[i][j] = MAGMA_Z_REAL(a[k]) + MAGMA_Z_IMAG(a[k]) * I;
120  k++;
121  }
122  }
123 
124  for(k=0;k<xNsize;k++){
125  r[k] = w[k];
126  }
127 
128  magma_free_cpu(a);
129  magma_free_cpu(w);
130  magma_free_pinned(work);
131  magma_free_cpu(rwork);
132 
133  magma_finalize();
134 
135  return 0;
136 }
137 
138 int diag_magma_real(int xNsize, double **A,
139  double *r, double **vec, int ngpu){
140 
141  if(ngpu <= 0) {
142  fprintf(stdout, " Error: ngpu is less than or equal to 0. ngpu = %d\n", ngpu);
143  fprintf(stdout, " exit in this function.\n\n");
144  return -1;
145  }
146 
147  magma_init();
148 
149  // local variable
150  int i,j,k;
151  magma_vec_t jobz;
152  magma_uplo_t uplo;
153  magma_int_t n, lda, lwork;
154  magma_int_t *iwork, liwork;
155  double *w;
156  double *a, *work;
157  magma_int_t info;
158 
159  {
160  magma_int_t maxngpu = 0;
161  magma_device_t *dummy;
162  magma_getdevices(dummy, 9999, &maxngpu);
163  if(ngpu > maxngpu) {
164  fprintf(stdout, " Warning: ngpu is beyond maxgpu. ngpu = %d, maxngpu = %d\n", ngpu, maxngpu);
165  fprintf(stdout, " MAGMA library executes maxngpu.\n\n");
166  ngpu = maxngpu;
167  }
168  }
169 
170  // auxiliary variable
171  double aux_work[1];
172  magma_int_t aux_iwork[1];
173 
174  n = lda = xNsize;
175  jobz = MagmaVec;
176  uplo = MagmaUpper;
177 
178  // get optimal work size
179  magma_dsyevd(jobz, uplo,
180  n, NULL, lda, NULL, // A, w
181  aux_work, -1,
182  aux_iwork, -1,
183  &info);
184 
185  lwork = (magma_int_t) MAGMA_D_REAL(aux_work[0]);
186  liwork = aux_iwork[0];
187 
188  // allocate
189  magma_dmalloc_cpu(&a, xNsize * xNsize);
190  magma_dmalloc_cpu(&w, xNsize);
191  magma_dmalloc_pinned(&work, lwork);
192  magma_imalloc_cpu(&iwork, liwork);
193 
194  k=0;
195  for(j=0;j<xNsize;j++){
196  for(i=0;i<xNsize;i++){
197  a[k] = A[i][j];
198  k++;
199  }
200  }
201 
202  // calculation eigen value and eigen vector
203  magma_dsyevd_m(ngpu, jobz, uplo,
204  n, a, lda, w,
205  work, lwork,
206  iwork, liwork,
207  &info);
208 
209  magma_free_cpu(iwork);
210  if(info != 0){
211  magma_free_cpu(a);
212  magma_free_cpu(w);
213  magma_free_pinned(work);
214  return -1;
215  }
216 
217  k=0;
218  for(i=0;i<xNsize;i++){
219  for(j=0;j<xNsize;j++){
220  vec[i][j]=a[k];
221  k++;
222  }
223  }
224 
225  for(k=0;k<xNsize;k++){
226  r[k] = w[k];
227  }
228 
229  magma_free_cpu(a);
230  magma_free_cpu(w);
231  magma_free_pinned(work);
232 
233  magma_finalize();
234 
235  return 0;
236 }
237 #endif
std::complex< double > I(0.0, 1.0)