3 #if (defined (QMP_COMMS) || defined (MPI_COMMS)) 25 template<
typename Float>
void arpack_naupd(
int &ido,
char &bmat,
int &
n,
char *which,
int &
nev, Float &
tol, std::complex<Float> *resid,
int &ncv, std::complex<Float> *v,
int &ldv,
26 int *iparam,
int *ipntr, std::complex<Float> *workd, std::complex<Float> *workl,
int &lworkl, Float *rwork,
int &info,
int *fcomm)
29 if(
sizeof(Float) ==
sizeof(
float))
31 float _tol =
static_cast<float>(
tol);
33 ARPACK(pcnaupd)(fcomm, &ido, &bmat, &
n, which, &
nev, &_tol,
reinterpret_cast<std::complex<float> *
>(resid), &ncv,
reinterpret_cast<std::complex<float> *
>(v),
34 &ldv, iparam, ipntr,
reinterpret_cast<std::complex<float> *
>(workd),
reinterpret_cast<std::complex<float> *
>(workl), &lworkl,
reinterpret_cast<float*
>(rwork), &info);
36 ARPACK(cnaupd)(&ido, &bmat, &
n, which, &
nev, &_tol,
reinterpret_cast<std::complex<float> *
>(resid), &ncv,
reinterpret_cast<std::complex<float> *
>(v),
37 &ldv, iparam, ipntr,
reinterpret_cast<std::complex<float> *
>(workd),
reinterpret_cast<std::complex<float> *
>(workl), &lworkl,
reinterpret_cast<float*
>(rwork), &info);
42 double _tol =
static_cast<double>(
tol);
44 ARPACK(pznaupd)(fcomm, &ido, &bmat, &
n, which, &
nev, &_tol,
reinterpret_cast<std::complex<double> *
>(resid), &ncv,
reinterpret_cast<std::complex<double> *
>(v),
45 &ldv, iparam, ipntr,
reinterpret_cast<std::complex<double> *
>(workd),
reinterpret_cast<std::complex<double> *
>(workl), &lworkl,
reinterpret_cast<double*
>(rwork), &info);
47 ARPACK(znaupd)(&ido, &bmat, &
n, which, &
nev, &_tol,
reinterpret_cast<std::complex<double> *
>(resid), &ncv,
reinterpret_cast<std::complex<double> *
>(v),
48 &ldv, iparam, ipntr,
reinterpret_cast<std::complex<double> *
>(workd),
reinterpret_cast<std::complex<double> *
>(workl), &lworkl,
reinterpret_cast<double*
>(rwork), &info);
55 template<
typename Float>
void arpack_neupd (
int &comp_evecs,
char howmny,
int *select, std::complex<Float>* evals, std::complex<Float>* v,
int &ldv, std::complex<Float> sigma, std::complex<Float>* workev,
56 char bmat,
int &
n,
char *which,
int &
nev, Float
tol, std::complex<Float>* resid,
int &ncv, std::complex<Float>* v1,
int &ldv1,
int *iparam,
int *ipntr,
57 std::complex<Float>* workd, std::complex<Float>* workl,
int &lworkl, Float* rwork,
int &info,
int *fcomm)
60 if(
sizeof(Float) ==
sizeof(
float))
62 float _tol =
static_cast<float>(
tol);
63 std::complex<float> _sigma =
static_cast<std::complex<float>
>(sigma);
65 ARPACK(pcneupd)(fcomm, &comp_evecs, &howmny, select,
reinterpret_cast<std::complex<float> *
>(evals),
66 reinterpret_cast<std::complex<float> *
>(v), &ldv, &_sigma,
reinterpret_cast<std::complex<float> *
>(workev), &bmat, &
n, which,
67 &
nev, &_tol,
reinterpret_cast<std::complex<float> *
>(resid), &ncv,
reinterpret_cast<std::complex<float> *
>(v1),
68 &ldv1, iparam, ipntr,
reinterpret_cast<std::complex<float> *
>(workd),
reinterpret_cast<std::complex<float> *
>(workl),
69 &lworkl, reinterpret_cast<float *>(rwork), &info);
72 ARPACK(cneupd)(&comp_evecs, &howmny, select,
reinterpret_cast<std::complex<float> *
>(evals),
73 reinterpret_cast<std::complex<float> *
>(v), &ldv, &_sigma,
reinterpret_cast<std::complex<float> *
>(workev), &bmat, &
n, which,
74 &
nev, &_tol,
reinterpret_cast<std::complex<float> *
>(resid), &ncv,
reinterpret_cast<std::complex<float> *
>(v1),
75 &ldv1, iparam, ipntr,
reinterpret_cast<std::complex<float> *
>(workd),
reinterpret_cast<std::complex<float> *
>(workl),
76 &lworkl, reinterpret_cast<float *>(rwork), &info);
81 double _tol =
static_cast<double>(
tol);
82 std::complex<double> _sigma =
static_cast<std::complex<double>
>(sigma);
84 ARPACK(pzneupd)(fcomm, &comp_evecs, &howmny, select,
reinterpret_cast<std::complex<double> *
>(evals),
85 reinterpret_cast<std::complex<double> *
>(v), &ldv, &_sigma,
reinterpret_cast<std::complex<double> *
>(workev), &bmat, &
n, which,
86 &
nev, &_tol,
reinterpret_cast<std::complex<double> *
>(resid), &ncv,
reinterpret_cast<std::complex<double> *
>(v1),
87 &ldv1, iparam, ipntr,
reinterpret_cast<std::complex<double> *
>(workd),
reinterpret_cast<std::complex<double> *
>(workl),
88 &lworkl, reinterpret_cast<double *>(rwork), &info);
90 ARPACK(zneupd)(&comp_evecs, &howmny, select,
reinterpret_cast<std::complex<double> *
>(evals),
91 reinterpret_cast<std::complex<double> *
>(v), &ldv, &_sigma,
reinterpret_cast<std::complex<double> *
>(workev), &bmat, &
n, which,
92 &
nev, &_tol,
reinterpret_cast<std::complex<double> *
>(resid), &ncv,
reinterpret_cast<std::complex<double> *
>(v1),
93 &ldv1, iparam, ipntr,
reinterpret_cast<std::complex<double> *
>(workd),
reinterpret_cast<std::complex<double> *
>(workl),
94 &lworkl, reinterpret_cast<double *>(rwork), &info);
138 template<
typename Float>
155 matEigen(*cuda_out, *cuda_in);
157 *cpu_out = *cuda_out;
170 std::vector<ColorSpinorField*> &
evecs ;
188 ArpackArgs(
QudaMatvec<Float> &
matvec, std::vector<ColorSpinorField*> &
evecs, std::complex<Float> *evals,
int nev,
int ncv,
char *which, Float
tol) :
matvec(
matvec),
evecs(
evecs),
w_d_(evals),
nev(
nev),
ncv(
ncv),
lanczos_which(which),
tol(
tol),
info(0)
206 template<
typename Float>
211 std::vector<SortEvals> sorted_evals;
212 sorted_evals.reserve(
nev);
223 std::string arpack_which(lanczos_which);
225 if (arpack_which.compare(std::string(
"SM"))) {
227 }
else if (arpack_which.compare(std::string(
"SI"))) {
228 for(
int e = 0;
e <
nev;
e++) sorted_evals.push_back(
SortEvals(w_d_[
e].imag(),
e));
229 }
else if (arpack_which.compare(std::string(
"SR"))) {
230 for(
int e = 0;
e <
nev;
e++) sorted_evals.push_back(
SortEvals(w_d_[
e].real(),
e));
231 }
else if (arpack_which.compare(std::string(
"LM"))) {
234 }
else if (arpack_which.compare(std::string(
"LI"))) {
235 for(
int e = 0;
e <
nev;
e++) sorted_evals.push_back(
SortEvals(w_d_[
e].imag(),
e));
237 }
else if (arpack_which.compare(std::string(
"LR"))) {
238 for(
int e = 0;
e <
nev;
e++) sorted_evals.push_back(
SortEvals(w_d_[
e].real(),
e));
241 errorQuda(
"\nSorting option is not supported.\n");
250 for(std::vector<ColorSpinorField*>::iterator vec = evecs.begin() ; vec != evecs.end(); ++vec) {
251 int sorted_id = sorted_evals[ev_id++]._idx;
253 printfQuda(
"%d ,Re= %le, Im= %le\n", sorted_id, w_d_[sorted_id].real(), w_d_[sorted_id].imag());
255 std::complex<Float>* tmp_buffer = &w_v_[sorted_id*cldn];
258 csParam.
v =
static_cast<void*
>(tmp_buffer);
261 *curr_nullvec = *cpu_tmp;
269 template<
typename Float>
272 int *fcomm =
nullptr;
274 MPI_Fint mpi_comm_fort = MPI_Comm_c2f(MPI_COMM_WORLD);
275 fcomm =
static_cast<int*
>(&mpi_comm_fort);
289 lworkl_ = (3 * ncv_ * ncv_ + 5 * ncv_),
291 std::complex<Float> sigma_ = 0.0;
294 std::complex<Float> *resid_ =
new std::complex<Float>[cldn];
295 std::complex<Float> *w_workd_ =
new std::complex<Float>[(cldn * 3)];
296 std::complex<Float> *w_workl_ =
new std::complex<Float>[lworkl_];
297 Float *w_rwork_ =
new Float[ncv_];
300 std::complex<Float> *w_workev_ =
new std::complex<Float>[ 2 * ncv_];
301 int *select_ =
new int[ ncv_];
307 iparam_[2] = max_iter;
318 arpack_naupd<Float>(ido_, bmat, n_, lanczos_which, nev_,
tol, resid_, ncv_, w_v_, ldv_, iparam_, ipntr_, w_workd_, w_workl_, lworkl_, w_rwork_, info_, fcomm);
320 if (info_ != 0)
errorQuda(
"\nError in ARPACK CNAUPD (error code %d) , exit.\n", info_);
324 if (ido_ == -1 || ido_ == 1) {
326 matvec(&(w_workd_[(ipntr_[1]-1)]), &(w_workd_[(ipntr_[0]-1)]));
328 if(iter_cnt % 50 == 0)
printfQuda(
"\nIteration : %d\n", iter_cnt);
331 }
while (99 != ido_ && iter_cnt < max_iter);
333 printfQuda(
"Finish: iter=%04d info=%d ido=%d\n", iter_cnt, info_, ido_);
338 arpack_neupd<Float>(rvec_, howmny, select_, w_d_, w_v_, ldv_, sigma_, w_workev_, bmat, n_, lanczos_which,
339 nev_, tol_, resid_, ncv_, w_v_, ldv_, iparam_, ipntr_, w_workd_, w_workl_, lworkl_, w_rwork_, info_, fcomm);
341 if (info_ != 0)
errorQuda(
"\nError in ARPACK CNEUPD (error code %d) , exit.\n", info_);
344 if (w_workl_ !=
nullptr)
delete [] w_workl_;
345 if (w_rwork_ !=
nullptr)
delete [] w_rwork_;
346 if (w_workev_ !=
nullptr)
delete [] w_workev_;
347 if (select_ !=
nullptr)
delete [] select_;
349 if (w_workd_ !=
nullptr)
delete [] w_workd_;
350 if (resid_ !=
nullptr)
delete [] resid_;
356 template<
typename Float>
370 if((
nev <= 0) or (
nev > static_cast<int>(B[0]->Length())))
errorQuda(
"Wrong number of the requested eigenvectors.\n");
371 if(((ncv-
nev) < 2) or (ncv > static_cast<int>(B[0]->Length())))
errorQuda(
"Wrong size of the IRAM work subspace.\n");
373 else arpack_solve<float> (B, evals, matEigen, matPrec, arpackPrec,
tol,
nev , ncv, target);
375 errorQuda(
"Arpack library was not built.\n");
void setPrecision(QudaPrecision precision)
enum QudaPrecision_s QudaPrecision
void operator()(std::complex< Float > *out, std::complex< Float > *in)
__host__ __device__ ValueType norm(const complex< ValueType > &z)
Returns the magnitude of z squared.
std::vector< ColorSpinorField * > & evecs
void arpack_naupd(int &ido, char &bmat, int &n, char *which, int &nev, Float &tol, std::complex< Float > *resid, int &ncv, std::complex< Float > *v, int &ldv, int *iparam, int *ipntr, std::complex< Float > *workd, std::complex< Float > *workl, int &lworkl, Float *rwork, int &info, int *fcomm)
void arpack_solve(std::vector< ColorSpinorField *> &B, void *evals, DiracMatrix &matEigen, QudaPrecision matPrec, QudaPrecision arpackPrec, double tol, int nev, int ncv, char *target)
static ColorSpinorField * Create(const ColorSpinorParam ¶m)
void arpackSolve(std::vector< ColorSpinorField *> &B, void *evals, DiracMatrix &matEigen, QudaPrecision matPrec, QudaPrecision arpackPrec, double tol, int nev, int ncv, char *target)
QudaPrecision matPrecision
ColorSpinorField * cuda_in
static bool SelectLarge(SortEvals v1, SortEvals v2)
ColorSpinorField * cuda_out
void arpack_neupd(int &comp_evecs, char howmny, int *select, std::complex< Float > *evals, std::complex< Float > *v, int &ldv, std::complex< Float > sigma, std::complex< Float > *workev, char bmat, int &n, char *which, int &nev, Float tol, std::complex< Float > *resid, int &ncv, std::complex< Float > *v1, int &ldv1, int *iparam, int *ipntr, std::complex< Float > *workd, std::complex< Float > *workl, int &lworkl, Float *rwork, int &info, int *fcomm)
QudaFieldLocation location
QudaMatvec< Float > & matvec
QudaFieldOrder fieldOrder
std::complex< Float > * w_v_
SortEvals(double val, int idx)
ArpackArgs(QudaMatvec< Float > &matvec, std::vector< ColorSpinorField *> &evecs, std::complex< Float > *evals, int nev, int ncv, char *which, Float tol)
cpuColorSpinorField * out
QudaMatvec(DiracMatrix &matEigen, QudaPrecision prec, ColorSpinorField &meta)
__host__ __device__ ValueType arg(const complex< ValueType > &z)
Returns the phase angle of z.
std::complex< Float > * w_d_
static __inline__ enum cudaRoundMode mode enum cudaRoundMode mode enum cudaRoundMode mode enum cudaRoundMode mode int val
static bool SelectSmall(SortEvals v1, SortEvals v2)