16 #include "matrixscalapack.hpp" 30 int use_scalapack = 0;
41 long int GetBlockSize(
long int Msize,
long int nproc) {
42 long int block_size = 16;
43 if(Msize*Msize/nproc > block_size*block_size)
58 long int GetPArrayIndex(
long int i,
long int np,
long int nb) {
72 long int GetLocalIndex(
long int i,
long int np,
long int nb) {
73 return (i/(np*nb))*nb + i%nb;
87 long int GetGlobalIndex(
long int il,
long int p,
long int np,
long int nb){
88 return ((il/nb)*np+p)*nb + il%nb;
103 long int MatToRank(
long int i,
long int j,
long int nprow,
long int npcol,
long int nb){
104 long int iproc, jproc;
105 iproc = GetPArrayIndex(i, nprow, nb);
106 jproc = GetPArrayIndex(j, npcol, nb);
107 return iproc+jproc*nprow;
121 long int GetMatRawInRank(
long int lj,
long int rank,
long int npcol,
long int nb){
122 long int pcol = rank/npcol;
123 return GetGlobalIndex(lj, pcol, npcol, nb);
138 long int *GetMatElementInRank(
long int i,
long int j,
long int nprow,
long int npcol,
long int nb){
140 ij = malloc(2*
sizeof(
int));
141 ij[0] = GetLocalIndex(i, nprow, nb);
142 ij[1] = GetLocalIndex(j, npcol, nb);
157 void DivMat(
long int m,
long int n, std::complex<double> Aorgmn, std::complex<double> *A,
int *desca){
158 long int mp = m+1, np = n+1;
159 pzelset_(A, &mp, &np, desca, &Aorgmn);
173 void GetEigenVector(
long int i,
long int m, std::complex<double> *Z,
int *descZ, std::complex<double> *vec) {
174 std::complex<double> alpha;
177 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
181 pzelget_(
"A",
" ", &alpha, Z, &jp, &ip, descZ);
200 int diag_scalapack_cmp(
long int xNsize, std::complex<double> **A,
201 std::complex<double> *r, std::complex<double> *Z,
int *descZ) {
202 const int i_one=1, i_zero=0;
203 const long int i_negone=-1;
204 const double zero=0.0, one=1.0;
205 long int m, n, mb, nb;
207 int myrow, mycol, info, lld;
210 std::complex<double> *A_distr, *work, *rwork;
213 int rank, size, iam, nprocs;
214 long int lwork, lrwork;
216 long int i, j, ip, jp;
219 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
220 MPI_Comm_size(MPI_COMM_WORLD, &size);
221 MPI_Dims_create(size,2,dims);
222 nprow=dims[0]; npcol=dims[1];
224 blacs_pinfo_(&iam, &nprocs);
225 blacs_get_((
int *)&i_negone, &i_zero, &ictxt);
226 blacs_gridinit_(&ictxt,
"R", &nprow, &npcol);
227 blacs_gridinfo_(&ictxt, &nprow, &npcol, &myrow, &mycol);
229 mb = GetBlockSize(m, size);
230 nb = GetBlockSize(n, size);
232 mp = numroc_(&m, &mb, &myrow, &i_zero, &nprow);
233 nq = numroc_(&n, &nb, &mycol, &i_zero, &npcol);
234 W = malloc(n*
sizeof(
double));
235 A_distr = malloc(mp*nq*
sizeof(std::complex<double>));
237 lld = (mp>0) ? mp : 1;
238 descinit_(descA_distr, &m, &n, &mb, &nb, &i_zero, &i_zero, &ictxt, &lld, &info);
239 descinit_(descZ, &m, &n, &mb, &nb, &i_zero, &i_zero, &ictxt, &lld, &info);
243 DivMat(i, j, A[i][j], A_distr, descA_distr);
247 std::complex<double> wkopt, rwkopt;
248 pzheev_(
"V",
"U", &n, A_distr, &i_one, &i_one, descA_distr, W, Z, &i_one, &i_one, descZ, &wkopt, &i_negone, &rwkopt, &i_negone, &info);
250 lwork = (
long int)wkopt;
251 lrwork = (
long int)rwkopt;
252 work = malloc(lwork*
sizeof(std::complex<double>));
253 rwork = malloc(lrwork*
sizeof(std::complex<double>));
256 pzheev_(
"V",
"U", &n, A_distr, &i_one, &i_one, descA_distr, W, Z, &i_one, &i_one, descZ, work, &lwork, rwork, &lrwork, &info);
int nproc
Number of processors, defined in InitializeMPI()