mptensor v0.5.1
Parallel Library for Tensor Network Methods
Loading...
Searching...
No Matches
matrix_scalapack_impl.hpp
Go to the documentation of this file.
1/*
2 mptensor - Parallel Library for Tensor Network Methods
3
4 Copyright 2016 Satoshi Morita
5
6 mptensor is free software: you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation, either version 3 of the
9 License, or (at your option) any later version.
10
11 mptensor is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with mptensor. If not, see
18 <https://www.gnu.org/licenses/>.
19*/
20
28#ifndef _MATRIX_SCALAPACK_IMPL_HPP_
29#define _MATRIX_SCALAPACK_IMPL_HPP_
30
31#include <algorithm>
32#include <cassert>
33#include <cfloat>
34#include <complex>
35#include <iostream>
36#include <fstream>
37#include <vector>
38#include <string>
39
40#include <mpi.h>
41
44
45/* ---------- PBLAS, SCALAPACK ---------- */
46extern "C" {
47int numroc_(int* M, int* MB, int* prow, int* irsrc, int* nprow);
48void descinit_(int desca[], int* M, int* N, int* MB, int* NB, int* irsrc,
49 int* icsrc, int* ictxt, int* lld, int* info);
50}
51
52namespace mptensor {
53inline namespace matrix {
54
56namespace scalapack {
57
59
63/* ---------- static member variables ---------- */
64template <typename C>
65const size_t Matrix<C>::BLOCK_SIZE = 16;
66
67/* ---------- constructors ---------- */
68
69template <typename C>
71 init(0, 0);
72};
73
74template <typename C>
75Matrix<C>::Matrix(const MPI_Comm& comm) : grid(comm), desc(9) {
76 init(0, 0);
77};
78
79template <typename C>
80Matrix<C>::Matrix(size_t n_row, size_t n_col) : grid(MPI_COMM_WORLD), desc(9) {
82};
83
84template <typename C>
85Matrix<C>::Matrix(const MPI_Comm& comm, size_t n_row, size_t n_col)
86 : grid(comm), desc(9) {
88};
89
90/* ---------- member functions ---------- */
91
92template <typename C>
93inline const C& Matrix<C>::operator[](size_t i) const {
94 return V[i];
95}
96
97template <typename C>
98inline C& Matrix<C>::operator[](size_t i) {
99 return V[i];
100}
101
102template <typename C>
103inline const C* Matrix<C>::head() const {
104 return V.data();
105}
106
107template <typename C>
109 return V.data();
110}
111
112template <typename C>
113inline size_t Matrix<C>::local_size() const {
114 return V.size();
115}
116
117// template <typename C> inline
118// const BlacsGrid& Matrix<C>::get_grid() const { return grid; }
119
120template <typename C>
121inline const MPI_Comm& Matrix<C>::get_comm() const {
122 return grid.comm;
123}
124
125template <typename C>
126inline int Matrix<C>::get_comm_size() const {
127 return grid.mpisize;
128}
129
130template <typename C>
131inline int Matrix<C>::get_comm_rank() const {
132 return grid.myrank;
133}
134
135template <typename C>
136inline const int* Matrix<C>::descriptor() const {
137 return desc.data();
138}
139
140// template <typename C> inline
141// int Matrix<C>::blacs_context() const { return desc[1]; }
142
143template <typename C>
144inline int Matrix<C>::n_row() const {
145 return desc[2];
146}
147
148template <typename C>
149inline int Matrix<C>::n_col() const {
150 return desc[3];
151}
152
153// template <typename C> inline
154// int Matrix<C>::nb_row() const { return desc[4]; }
155
156// template <typename C> inline
157// int Matrix<C>::nb_col() const { return desc[5]; }
158
159template <typename C>
160inline int Matrix<C>::get_lld() const {
161 return desc[8];
162}
163
164template <typename C>
165inline void Matrix<C>::global_index(size_t i, size_t& g_row,
166 size_t& g_col) const {
167 const int lld = get_lld();
168 const size_t l_row = i % lld;
169 const size_t l_col = i / lld;
170 prep_local_to_global();
171 g_row = global_row[l_row];
172 g_col = global_col[l_col];
173};
174
175template <typename C>
176inline bool Matrix<C>::local_index(size_t g_row, size_t g_col,
177 size_t& i) const {
178 const int lld = get_lld();
179 const int nprow = grid.nprow;
180 const int npcol = grid.npcol;
181 const int myprow = grid.myprow;
182 const int mypcol = grid.mypcol;
183
184 size_t b_row = g_row / BLOCK_SIZE;
185 size_t p_row = b_row % nprow;
186 size_t b_col = g_col / BLOCK_SIZE;
187 size_t p_col = b_col % npcol;
188 if (p_row != size_t(myprow) || p_col != size_t(mypcol)) return false;
189
190 size_t l_row = (b_row / nprow) * BLOCK_SIZE + g_row % BLOCK_SIZE;
191 size_t l_col = (b_col / npcol) * BLOCK_SIZE + g_col % BLOCK_SIZE;
192 i = l_row + l_col * lld; // column major
193 return true;
194};
195
196template <typename C>
197inline void Matrix<C>::local_position(size_t g_row, size_t g_col,
198 int& comm_rank, size_t& lindex) const {
199 prep_global_to_local();
200 const int myprow = proc_row[g_row];
201 const int mypcol = proc_col[g_col];
202 comm_rank = grid.mpirank(myprow, mypcol);
203 lindex = local_row[g_row] + local_col[g_col] * lld_list[myprow];
204}
205
206template <typename C>
207inline size_t Matrix<C>::local_row_size() const {
208 return local_row_size_;
209}
210
211template <typename C>
212inline size_t Matrix<C>::local_col_size() const {
213 return local_col_size_;
214}
215
216template <typename C>
217inline size_t Matrix<C>::local_row_index(size_t lindex) const {
218 return lindex % (static_cast<size_t>(get_lld()));
219}
220
221template <typename C>
222inline size_t Matrix<C>::local_col_index(size_t lindex) const {
223 return lindex / (static_cast<size_t>(get_lld()));
224}
225
226template <typename C>
227inline size_t Matrix<C>::global_row_index(size_t l_row) const {
228 return BLOCK_SIZE * ((l_row / BLOCK_SIZE) * grid.nprow + grid.myprow) +
229 (l_row % BLOCK_SIZE);
230}
231
232template <typename C>
233inline size_t Matrix<C>::global_col_index(size_t l_col) const {
234 return BLOCK_SIZE * ((l_col / BLOCK_SIZE) * grid.npcol + grid.mypcol) +
235 (l_col % BLOCK_SIZE);
236}
237
239template <typename C>
241 if (has_local_to_global) return;
242
243 const int nprow = grid.nprow;
244 const int npcol = grid.npcol;
245 const int myprow = grid.myprow;
246 const int mypcol = grid.mypcol;
247 const size_t size_row = get_lld();
248 const size_t size_col = local_size() / size_row;
249 global_row.resize(size_row);
250 global_col.resize(size_col);
251
252#pragma omp parallel default(shared)
253 {
254#pragma omp for
255 for (size_t l_row = 0; l_row < size_row; ++l_row) {
256 global_row[l_row] = BLOCK_SIZE * ((l_row / BLOCK_SIZE) * nprow + myprow) +
257 (l_row % BLOCK_SIZE);
258 }
259#pragma omp for
260 for (size_t l_col = 0; l_col < size_col; ++l_col) {
261 global_col[l_col] = BLOCK_SIZE * ((l_col / BLOCK_SIZE) * npcol + mypcol) +
262 (l_col % BLOCK_SIZE);
263 }
264 }
265
266 has_local_to_global = true;
267}
268
270template <typename C>
272 if (has_global_to_local) return;
273
274 const int nprow = grid.nprow;
275 const int npcol = grid.npcol;
276 const size_t size_row = n_row();
277 const size_t size_col = n_col();
278 const size_t nblocks = size_row / BLOCK_SIZE;
279 const size_t extra_blocks = nblocks % nprow;
280 const size_t locr_offset = (nblocks / nprow) * BLOCK_SIZE;
281
282 local_row.resize(size_row);
283 local_col.resize(size_col);
284 proc_row.resize(size_row);
285 proc_col.resize(size_col);
286 lld_list.resize(nprow);
287
288#pragma omp parallel default(shared)
289 {
290#pragma omp for
291 for (size_t g_row = 0; g_row < size_row; ++g_row) {
292 size_t b_row = g_row / BLOCK_SIZE;
293 proc_row[g_row] = b_row % nprow;
294 local_row[g_row] = (b_row / nprow) * BLOCK_SIZE + g_row % BLOCK_SIZE;
295 }
296
297#pragma omp for
298 for (size_t g_col = 0; g_col < size_col; ++g_col) {
299 size_t b_col = g_col / BLOCK_SIZE;
300 proc_col[g_col] = b_col % npcol;
301 local_col[g_col] = (b_col / npcol) * BLOCK_SIZE + g_col % BLOCK_SIZE;
302 }
303
304#pragma omp for
305 for (size_t myprow = 0; myprow < size_t(nprow); ++myprow) {
306 // inline expansion of numroc_()
307 size_t locr = locr_offset;
308 if (myprow < extra_blocks)
309 locr += BLOCK_SIZE;
310 else if (myprow == extra_blocks)
311 locr += size_row % BLOCK_SIZE;
312
313 lld_list[myprow] = (locr < 1) ? 1 : locr;
314 }
315 }
316
317 has_global_to_local = true;
318};
319
320template <typename C>
321void Matrix<C>::init(size_t n_row, size_t n_col) {
322 int xM = n_row;
323 int xN = n_col;
324 int xMB = BLOCK_SIZE;
325 int xNB = BLOCK_SIZE;
326 int irsrc = 0, icsrc = 0;
327 int locr = numroc_(&xM, &xMB, &(grid.myprow), &irsrc, &(grid.nprow));
328 int locc = numroc_(&xN, &xNB, &(grid.mypcol), &icsrc, &(grid.npcol));
329 int lld = (locr < 1) ? 1 : locr;
330 int info;
331 descinit_(desc.data(), &xM, &xN, &xMB, &xNB, &irsrc, &icsrc, &(grid.ictxt),
332 &lld, &info);
333 V.resize(locr * locc);
334 local_row_size_ = static_cast<size_t>(locr);
335 local_col_size_ = static_cast<size_t>(locc);
336 has_local_to_global = false;
337 has_global_to_local = false;
338};
339
340// template <typename C>
341// void Matrix<C>::set(C (*element)(size_t gi, size_t gj)) {
342// const size_t& length = V.size();
343// for (size_t i=0;i<length;++i) {
344// size_t gi, gj;
345// global_index(i, gi, gj);
346// V[i] = element(gi, gj);
347// }
348// };
349
350template <typename C>
351inline void Matrix<C>::print_info(std::ostream& out) const {
352 out << "Matrix: prow= " << grid.myprow << " pcol= " << grid.mypcol
353 << " local_size= " << local_size() << " lld(locr)= " << get_lld()
354 << " locc= " << local_size() / get_lld() << "\n";
355};
356
357template <typename C>
359 assert(V.size() == rhs.local_size());
360 for (size_t i = 0; i < V.size(); ++i) V[i] += rhs[i];
361 return *this;
362};
363
364template <typename C>
366 assert(V.size() == rhs.local_size());
367 for (size_t i = 0; i < V.size(); ++i) V[i] -= rhs[i];
368 return *this;
369};
370
371template <typename C>
373 for (size_t i = 0; i < V.size(); ++i) V[i] *= rhs;
374 return *this;
375};
376
377template <typename C>
379 for (size_t i = 0; i < V.size(); ++i) V[i] /= rhs;
380 return *this;
381};
382
383template <typename C>
384template <typename UnaryOperation>
386 std::transform(V.begin(), V.end(), V.begin(), op);
387 return *this;
388};
389
390template <typename C>
392 /* new matrix */
393 Matrix<C> M_new(get_comm(), n_col(), n_row());
394
395 /* create lists of local position and destination rank */
396 std::vector<int> dest_rank(local_size());
397 std::vector<size_t> local_position(local_size());
398
399 for (size_t i = 0; i < local_size(); i++) {
400 int dest;
401 size_t pos, g_col, g_row;
402
403 global_index(i, g_row, g_col);
404 M_new.local_position(g_col, g_row, dest, pos);
405
406 local_position[i] = pos;
407 dest_rank[i] = dest;
408 }
409
410 /* exchange data */
411 replace_matrix_data((*this), dest_rank, local_position, M_new);
412
413 return M_new;
414}
415
416template <typename C>
417inline std::vector<C> Matrix<C>::flatten() {
418 const size_t n = n_row() * n_col();
419 const size_t nr = n_row();
420 std::vector<C> vec(n);
421 size_t g_row, g_col;
422 for (size_t i = 0; i < local_size(); ++i) {
423 global_index(i, g_row, g_col);
424 vec[g_row + g_col * nr] = V[i];
425 }
426 return mpi::allreduce_vec(vec, get_comm());
427};
428
429template <typename C>
430inline void Matrix<C>::barrier() const {
431 MPI_Barrier(get_comm());
432}
433
434template <typename C>
436 return mpi::allreduce_sum(value, get_comm());
437}
438
439template <typename C>
440template <typename D>
441inline void Matrix<C>::bcast(D* buffer, int count, int root) const {
442 mpi::bcast(buffer, count, root, get_comm());
443}
444
445template <typename C>
446void Matrix<C>::save_index(const std::string &filename) const {
447 const size_t size_row = get_lld();
448 const size_t size_col = local_size() / size_row;
449 prep_local_to_global();
450 std::ofstream fout(filename);
451 fout << "local_size= " << local_size() << "\n";
452 fout << "local_n_row= " << size_row << "\n";
453 fout << "local_n_col= " << size_col << "\n";
454 fout << "[global_row]\n";
455 for (size_t i = 0; i < size_row; ++i) {
456 fout << " " << global_row[i];
457 if (i % BLOCK_SIZE == BLOCK_SIZE - 1) fout << "\n";
458 }
459 fout << "\n";
460 fout << "[global_col]\n";
461 for (size_t i = 0; i < size_col; ++i) {
462 fout << " " << global_col[i];
463 if (i % BLOCK_SIZE == BLOCK_SIZE - 1) fout << "\n";
464 }
465 fout << "\n";
466 fout.close();
467}
468
469/* ---------- non-member functions ---------- */
470
471template <typename C>
472void replace_matrix_data(const Matrix<C>& M, const std::vector<int>& dest_rank,
473 const std::vector<size_t>& local_position,
474 Matrix<C>& M_new) {
475 const MPI_Comm comm = M.get_comm();
476 const int mpisize = M.get_comm_size();
477 // const int mpirank = M.get_comm_rank();
478 const size_t local_size = M.local_size();
479
480 const C* mat = M.head();
481 C* mat_new = M_new.head();
482
483 // assert(send_size_list.size() == mpisize);
484 assert(dest_rank.size() == local_size);
485 assert(local_position.size() == local_size);
486
487 const int proc_size = mpisize + 1;
488 std::vector<int> send_counts(proc_size, 0);
489 std::vector<int> send_displs(proc_size, 0);
490 std::vector<int> recv_counts(proc_size, 0);
491 std::vector<int> recv_displs(proc_size, 0);
492
493 for (size_t i = 0; i < local_size; ++i) {
494 send_counts[dest_rank[i]] += 1;
495 }
496
497 mpi::alltoall(send_counts.data(), 1, recv_counts.data(), 1, comm);
498
499 for (int rank = 0; rank < mpisize; ++rank) {
500 send_displs[rank + 1] = send_counts[rank] + send_displs[rank];
501 recv_displs[rank + 1] = recv_counts[rank] + recv_displs[rank];
502 }
503
504 const int send_size = local_size; // send_displs[mpisize];
505 const int recv_size = recv_displs[mpisize];
506 std::vector<size_t> send_pos(send_size);
507 std::vector<size_t> recv_pos(recv_size);
508 std::vector<C> send_value(send_size);
509 std::vector<C> recv_value(recv_size);
510
511 /* Pack */
512 {
513 std::vector<int> pack_idx(send_displs);
514 for (size_t i = 0; i < local_size; ++i) {
515 const int rank = dest_rank[i];
516 const int idx = pack_idx[rank];
517 send_value[idx] = mat[i];
518 send_pos[idx] = local_position[i];
519 pack_idx[rank] += 1;
520 }
521 }
522
523 /* Send and Recieve */
524 mpi::alltoallv(send_pos.data(), send_counts.data(), send_displs.data(),
525 recv_pos.data(), recv_counts.data(), recv_displs.data(),
526 comm);
527 mpi::alltoallv(send_value.data(), send_counts.data(), send_displs.data(),
528 recv_value.data(), recv_counts.data(), recv_displs.data(),
529 comm);
530
531 /* Unpack */
532 for (int i = 0; i < recv_size; ++i) {
534 }
535}
536
537template <typename C>
538void replace_matrix_data(const std::vector<C>& V, const std::vector<int>& dest_rank,
539 const std::vector<size_t>& local_position,
540 Matrix<C>& M_new) {
541 const MPI_Comm comm = M_new.get_comm();
542 const int mpisize = M_new.get_comm_size();
543 // const int mpirank = M.get_comm_rank();
544 const size_t local_size = V.size();
545
546 const C* mat = V.data();
547 C* mat_new = M_new.head();
548
549 // assert(send_size_list.size() == mpisize);
550 assert(dest_rank.size() == local_size);
551 assert(local_position.size() == local_size);
552
553 const int proc_size = mpisize + 1;
554 std::vector<int> send_counts(proc_size, 0);
555 std::vector<int> send_displs(proc_size, 0);
556 std::vector<int> recv_counts(proc_size, 0);
557 std::vector<int> recv_displs(proc_size, 0);
558
559 for (size_t i = 0; i < local_size; ++i) {
560 send_counts[dest_rank[i]] += 1;
561 }
562
563 mpi::alltoall(send_counts.data(), 1, recv_counts.data(), 1, comm);
564
565 for (int rank = 0; rank < mpisize; ++rank) {
566 send_displs[rank + 1] = send_counts[rank] + send_displs[rank];
567 recv_displs[rank + 1] = recv_counts[rank] + recv_displs[rank];
568 }
569
570 const int send_size = local_size; // send_displs[mpisize];
571 const int recv_size = recv_displs[mpisize];
572 std::vector<size_t> send_pos(send_size);
573 std::vector<size_t> recv_pos(recv_size);
574 std::vector<C> send_value(send_size);
575 std::vector<C> recv_value(recv_size);
576
577 /* Pack */
578 {
579 std::vector<int> pack_idx(send_displs);
580 for (size_t i = 0; i < local_size; ++i) {
581 const int rank = dest_rank[i];
582 const int idx = pack_idx[rank];
583 send_value[idx] = mat[i];
584 send_pos[idx] = local_position[i];
585 pack_idx[rank] += 1;
586 }
587 }
588
589 /* Send and Recieve */
590 mpi::alltoallv(send_pos.data(), send_counts.data(), send_displs.data(),
591 recv_pos.data(), recv_counts.data(), recv_displs.data(),
592 comm);
593 mpi::alltoallv(send_value.data(), send_counts.data(), send_displs.data(),
594 recv_value.data(), recv_counts.data(), recv_displs.data(),
595 comm);
596
597 /* Unpack */
598 for (int i = 0; i < recv_size; ++i) {
600 }
601}
602
603template <typename C>
604void sum_matrix_data(const Matrix<C>& M, const std::vector<int>& dest_rank,
605 const std::vector<size_t>& local_position,
606 Matrix<C>& M_new) {
607 const MPI_Comm comm = M.get_comm();
608 const int mpisize = M.get_comm_size();
609 const int mpirank = M.get_comm_rank();
610 const size_t local_size = M.local_size();
611
612 // assert(send_size_list.size() == mpisize);
613 assert(dest_rank.size() == local_size);
614 assert(local_position.size() == local_size);
615
616 std::vector<int> send_size_list(mpisize, 0);
617 for (size_t i = 0; i < local_size; ++i) {
618 const int rank = dest_rank[i];
619 if (rank >= 0 && rank < mpisize) send_size_list[dest_rank[i]] += 1;
620 }
621
622 const C* mat = M.head();
623 C* mat_new = M_new.head();
624
625 for (int step = 0; step < mpisize; ++step) {
626 int dest = (mpirank + step) % mpisize;
627 int source = (mpirank + mpisize - step) % mpisize;
628 if (dest == mpirank) {
629 for (size_t i = 0; i < local_size; i++) {
630 if (dest_rank[i] == mpirank) {
631 mat_new[local_position[i]] += mat[i];
632 }
633 }
634 } else {
635 /* Get recv_size */
637 int recv_size;
638 // MPI_Status status;
639 int tag = step;
640 mpi::sendrecv(&send_size, 1, dest, tag, &recv_size, 1, source, tag, comm);
641
642 /* Pack */
643 std::vector<size_t> send_pos(send_size);
644 std::vector<C> send_value(send_size);
645 size_t k = 0;
646 for (size_t i = 0; i < local_size; i++) {
647 if (dest_rank[i] == dest) {
648 send_pos[k] = local_position[i];
649 send_value[k] = mat[i];
650 k += 1;
651 }
652 }
653
654 /* Send and Recieve */
655 std::vector<size_t> recv_pos(recv_size);
656 std::vector<C> recv_value(recv_size);
659 comm);
660
661 /* Unpack */
662 for (int i = 0; i < recv_size; ++i) {
664 }
665 }
666 }
667}
668
669template <typename C>
670double max_abs(const Matrix<C>& a) {
671 const size_t n = a.local_size();
672 double send = 0.0;
673 double recv;
674 for (size_t i = 0; i < n; ++i) {
675 send = std::max(send, std::abs(a[i]));
676 }
678 return recv;
679};
680
681template <typename C>
682double min_abs(const Matrix<C>& a) {
683 const size_t n = a.local_size();
684 double send = DBL_MAX;
685 double recv;
686 for (size_t i = 0; i < n; ++i) {
687 send = std::min(send, std::abs(a[i]));
688 }
690 return recv;
691};
692
693template <typename C>
695 const size_t n = A.local_size();
696 size_t g_row, g_col;
697 C val = 0.0;
698
699 for (size_t i = 0; i < n; ++i) {
700 A.global_index(i, g_row, g_col);
701 if (g_row == g_col) val += A[i];
702 }
703
704 C recv;
705 mpi::allreduce(&val, &recv, 1, MPI_SUM, A.get_comm());
706 return recv;
707};
708
709} // namespace scalapack
710} // inline namespace matrix
711} // namespace mptensor
712
713#endif // _MATRIX_SCALAPACK_IMPL_HPP_
Distributed matrix using ScaLAPACK.
Definition matrix_scalapack.hpp:49
size_t global_row_index(size_t lindex_row) const
Definition matrix_scalapack_impl.hpp:227
Matrix & operator*=(C rhs)
Definition matrix_scalapack_impl.hpp:372
const C * head() const
Definition matrix_scalapack_impl.hpp:103
void global_index(size_t i, size_t &g_row, size_t &g_col) const
Definition matrix_scalapack_impl.hpp:165
Matrix & operator/=(C rhs)
Definition matrix_scalapack_impl.hpp:378
int n_col() const
Definition matrix_scalapack_impl.hpp:149
size_t local_size() const
Definition matrix_scalapack_impl.hpp:113
Matrix()
Definition matrix_scalapack_impl.hpp:70
int get_comm_rank() const
Definition matrix_scalapack_impl.hpp:131
const int * descriptor() const
Definition matrix_scalapack_impl.hpp:136
size_t global_col_index(size_t lindex_col) const
Definition matrix_scalapack_impl.hpp:233
Matrix & operator+=(const Matrix &rhs)
Definition matrix_scalapack_impl.hpp:358
size_t local_row_size() const
Definition matrix_scalapack_impl.hpp:207
const Matrix transpose()
Definition matrix_scalapack_impl.hpp:391
void print_info(std::ostream &) const
Definition matrix_scalapack_impl.hpp:351
void local_position(size_t g_row, size_t g_col, int &comm_rank, size_t &lindex) const
Definition matrix_scalapack_impl.hpp:197
Matrix & map(UnaryOperation op)
size_t local_row_index(size_t lindex) const
Definition matrix_scalapack_impl.hpp:217
void prep_local_to_global() const
Preprocess for fast conversion from local index to global one.
Definition matrix_scalapack_impl.hpp:240
int n_row() const
Definition matrix_scalapack_impl.hpp:144
int get_comm_size() const
Definition matrix_scalapack_impl.hpp:126
void init(size_t n_row, size_t n_col)
Definition matrix_scalapack_impl.hpp:321
void prep_global_to_local() const
Preprocess for fast conversion from global index to local one.
Definition matrix_scalapack_impl.hpp:271
const MPI_Comm & get_comm() const
Definition matrix_scalapack_impl.hpp:121
void save_index(const std::string &filename) const
Definition matrix_scalapack_impl.hpp:446
std::vector< C > flatten()
Definition matrix_scalapack_impl.hpp:417
size_t local_col_size() const
Definition matrix_scalapack_impl.hpp:212
size_t local_col_index(size_t lindex) const
Definition matrix_scalapack_impl.hpp:222
C allreduce_sum(C value) const
Definition matrix_scalapack_impl.hpp:435
bool local_index(size_t g_row, size_t g_col, size_t &i) const
Definition matrix_scalapack_impl.hpp:176
void bcast(D *buffer, int count, int root) const
Definition matrix_scalapack_impl.hpp:441
Matrix & operator-=(const Matrix &rhs)
Definition matrix_scalapack_impl.hpp:365
void barrier() const
Definition matrix_scalapack_impl.hpp:430
const C & operator[](size_t i) const
Definition matrix_scalapack_impl.hpp:93
std::string filename(const std::string &prefix, int proc_size)
Definition common.hpp:32
std::complex< double > complex
Definition complex.hpp:38
mptensor::complex complex
Definition matrix_lapack.cc:36
scalapack::Matrix class
void descinit_(int desca[], int *M, int *N, int *MB, int *NB, int *irsrc, int *icsrc, int *ictxt, int *lld, int *info)
int numroc_(int *M, int *MB, int *prow, int *irsrc, int *nprow)
Wrapper functions of MPI communications.
C matrix_trace(const Matrix< C > &a)
Definition matrix_scalapack_impl.hpp:694
void sum_matrix_data(const Matrix< C > &M, const std::vector< int > &dest_rank, const std::vector< size_t > &local_position, Matrix< C > &M_new)
Definition matrix_scalapack_impl.hpp:604
void replace_matrix_data(const Matrix< C > &M, const std::vector< int > &dest_rank, const std::vector< size_t > &local_position, Matrix< C > &M_new)
Definition matrix_scalapack_impl.hpp:472
double max_abs(const Matrix< C > &a)
Definition matrix_scalapack_impl.hpp:670
double min_abs(const Matrix< C > &a)
Definition matrix_scalapack_impl.hpp:682
void alltoallv(const C *sendbuf, const int *sendcounts, const int *sdispls, C *recvbuf, const int *recvcounts, const int *rdispls, const MPI_Comm &comm)
Wrapper of MPI_Alltoallv.
Definition mpi_wrapper.hpp:185
std::vector< C > allreduce_vec(const std::vector< C > &vec, const MPI_Comm &comm)
Calculate a summation of each element of vector over MPI communicator.
Definition mpi_wrapper.hpp:89
C allreduce_sum(C val, const MPI_Comm &comm)
Calculate a summation over MPI communicator.
Definition mpi_wrapper.hpp:75
void bcast(C *buffer, int count, int root, const MPI_Comm &comm)
Wrapper of MPI_Bcast.
Definition mpi_wrapper.hpp:202
void sendrecv(const C *sendbuf, int sendcount, int dest, int sendtag, C *recvbuf, int recvcount, int source, int recvtag, const MPI_Comm &comm)
Wrapper of MPI_Sendrecv.
Definition mpi_wrapper.hpp:126
void allreduce(const C *sendbuf, C *recvbuf, int count, MPI_Op op, const MPI_Comm &comm)
Wrapper of MPI_Allreduce.
Definition mpi_wrapper.hpp:107
void alltoall(const C *sendbuf, int sendcount, C *recvbuf, int recvcount, const MPI_Comm &comm)
Wrapper of MPI_Alltoall.
Definition mpi_wrapper.hpp:163
Definition complex.hpp:34