SIRIUS 7.5.0
Electronic structure library and applications
dmatrix.cpp
Go to the documentation of this file.
1// Copyright (c) 2013-2017 Anton Kozhevnikov, Thomas Schulthess
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
5// the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8// following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
10// and the following disclaimer in the documentation and/or other materials provided with the distribution.
11//
12// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
13// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
15// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
17// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
18// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
20/** \file dmatrix.cpp
21 *
22 * \brief Definitions.
23 *
24 */
25#include "dmatrix.hpp"
26
27namespace sirius {
28
29namespace la {
30
31template <typename T>
32dmatrix<T>::dmatrix(int num_rows__, int num_cols__, BLACS_grid const& blacs_grid__, int bs_row__, int bs_col__,
33 sddk::memory_t mem_type__)
34 : sddk::matrix<T>(splindex_block_cyclic<>(num_rows__, n_blocks(blacs_grid__.num_ranks_row()),
35 block_id(blacs_grid__.rank_row()), bs_row__).local_size(),
36 splindex_block_cyclic<>(num_cols__, n_blocks(blacs_grid__.num_ranks_col()),
37 block_id(blacs_grid__.rank_col()), bs_col__).local_size(), mem_type__)
38 , num_rows_(num_rows__)
39 , num_cols_(num_cols__)
40 , bs_row_(bs_row__)
41 , bs_col_(bs_col__)
42 , blacs_grid_(&blacs_grid__)
43 , spl_row_(num_rows_, n_blocks(blacs_grid__.num_ranks_row()), block_id(blacs_grid__.rank_row()), bs_row_)
44 , spl_col_(num_cols_, n_blocks(blacs_grid__.num_ranks_col()), block_id(blacs_grid__.rank_col()), bs_col_)
45 , spla_dist_(spla::MatrixDistribution::create_blacs_block_cyclic_from_mapping(
46 blacs_grid__.comm().native(), blacs_grid__.rank_map().data(), blacs_grid__.num_ranks_row(),
47 blacs_grid__.num_ranks_col(), bs_row__,bs_col__))
48{
49 init();
50}
51
52template <typename T>
53dmatrix<T>::dmatrix(T* ptr__, int num_rows__, int num_cols__, BLACS_grid const& blacs_grid__, int bs_row__,
54 int bs_col__)
55 : sddk::matrix<T>(ptr__,
56 splindex_block_cyclic<>(num_rows__, n_blocks(blacs_grid__.num_ranks_row()),
57 block_id(blacs_grid__.rank_row()), bs_row__).local_size(),
58 splindex_block_cyclic<>(num_cols__, n_blocks(blacs_grid__.num_ranks_col()),
59 block_id(blacs_grid__.rank_col()), bs_col__).local_size())
60 , num_rows_(num_rows__)
61 , num_cols_(num_cols__)
62 , bs_row_(bs_row__)
63 , bs_col_(bs_col__)
64 , blacs_grid_(&blacs_grid__)
65 , spl_row_(num_rows_, n_blocks(blacs_grid__.num_ranks_row()), block_id(blacs_grid__.rank_row()), bs_row_)
66 , spl_col_(num_cols_, n_blocks(blacs_grid__.num_ranks_col()), block_id(blacs_grid__.rank_col()), bs_col_)
67 , spla_dist_(spla::MatrixDistribution::create_blacs_block_cyclic_from_mapping(
68 blacs_grid__.comm().native(), blacs_grid__.rank_map().data(), blacs_grid__.num_ranks_row(),
69 blacs_grid__.num_ranks_col(), bs_row__, bs_col__))
70{
71 init();
72}
73
74template <typename T>
75dmatrix<T>::dmatrix(int num_rows__, int num_cols__, sddk::memory_t mem_type__)
76 : sddk::matrix<T>(num_rows__, num_cols__, mem_type__)
77 , num_rows_(num_rows__)
78 , num_cols_(num_cols__)
79 , bs_row_(1)
80 , bs_col_(1)
81 , spl_row_(num_rows_, n_blocks(1), block_id(0), bs_row_)
82 , spl_col_(num_cols_, n_blocks(1), block_id(0), bs_col_)
83{
84}
85
86template <typename T>
87dmatrix<T>::dmatrix(int num_rows__, int num_cols__, sddk::memory_pool& mp__, std::string const& label__)
88 : sddk::matrix<T>(num_rows__, num_cols__, mp__, label__)
89 , num_rows_(num_rows__)
90 , num_cols_(num_cols__)
91 , bs_row_(1)
92 , bs_col_(1)
93 , spl_row_(num_rows_, n_blocks(1), block_id(0), bs_row_)
94 , spl_col_(num_cols_, n_blocks(1), block_id(0), bs_col_)
95{
96}
97
98
99template <typename T>
100dmatrix<T>::dmatrix(T* ptr__, int num_rows__, int num_cols__)
101 : sddk::matrix<T>(ptr__, num_rows__, num_cols__)
102 , num_rows_(num_rows__)
103 , num_cols_(num_cols__)
104 , bs_row_(1)
105 , bs_col_(1)
106 , spl_row_(num_rows_, n_blocks(1), block_id(0), bs_row_)
107 , spl_col_(num_cols_, n_blocks(1), block_id(0), bs_col_)
108{
109 init();
110}
111
112template <typename T>
113dmatrix<T>::dmatrix(int num_rows__, int num_cols__, BLACS_grid const& blacs_grid__, int bs_row__, int bs_col__,
114 sddk::memory_pool& mp__)
115 : sddk::matrix<T>(splindex_block_cyclic<>(num_rows__, n_blocks(blacs_grid__.num_ranks_row()),
116 block_id(blacs_grid__.rank_row()), bs_row__).local_size(),
117 splindex_block_cyclic<>(num_cols__, n_blocks(blacs_grid__.num_ranks_col()),
118 block_id(blacs_grid__.rank_col()), bs_col__).local_size(), mp__)
119 , num_rows_(num_rows__)
120 , num_cols_(num_cols__)
121 , bs_row_(bs_row__)
122 , bs_col_(bs_col__)
123 , blacs_grid_(&blacs_grid__)
124 , spl_row_(num_rows_, n_blocks(blacs_grid__.num_ranks_row()), block_id(blacs_grid__.rank_row()), bs_row_)
125 , spl_col_(num_cols_, n_blocks(blacs_grid__.num_ranks_col()), block_id(blacs_grid__.rank_col()), bs_col_)
126 , spla_dist_(spla::MatrixDistribution::create_blacs_block_cyclic_from_mapping(
127 blacs_grid__.comm().native(), blacs_grid__.rank_map().data(), blacs_grid__.num_ranks_row(),
128 blacs_grid__.num_ranks_col(), bs_row__, bs_col__))
129{
130 init();
131}
132
133template <typename T>
134void dmatrix<T>::set(int ir0__, int jc0__, int mr__, int nc__, T* ptr__, int ld__)
135{
136 splindex_block_cyclic<> spl_r0(ir0__, n_blocks(blacs_grid().num_ranks_row()),
137 block_id(blacs_grid().rank_row()), bs_row_);
138 splindex_block_cyclic<> spl_r1(ir0__ + mr__, n_blocks(blacs_grid().num_ranks_row()),
139 block_id(blacs_grid().rank_row()), bs_row_);
140
141 splindex_block_cyclic<> spl_c0(jc0__, n_blocks(blacs_grid().num_ranks_col()),
142 block_id(blacs_grid().rank_col()), bs_col_);
143 splindex_block_cyclic<> spl_c1(jc0__ + nc__, n_blocks(blacs_grid().num_ranks_col()),
144 block_id(blacs_grid().rank_col()), bs_col_);
145
146 int m0 = spl_r0.local_size();
147 int m1 = spl_r1.local_size();
148 int n0 = spl_c0.local_size();
149 int n1 = spl_c1.local_size();
150 std::vector<int> map_row(m1 - m0);
151 std::vector<int> map_col(n1 - n0);
152
153 for (int i = 0; i < m1 - m0; i++) {
154 map_row[i] = spl_r1.global_index(m0 + i) - ir0__;
155 }
156 for (int j = 0; j < n1 - n0; j++) {
157 map_col[j] = spl_c1.global_index(n0 + j) - jc0__;
158 }
159
160 //#pragma omp parallel for
161 for (int j = 0; j < n1 - n0; j++) {
162 for (int i = 0; i < m1 - m0; i++) {
163 (*this)(m0 + i, n0 + j) = ptr__[map_row[i] + ld__ * map_col[j]];
164 }
165 }
166}
167
168template <typename T>
169void dmatrix<T>::set(const int irow_glob, const int icol_glob, T val)
170{
171 if (blacs_grid_) {
172 auto r = spl_row_.location(irow_glob);
173 if (blacs_grid_->rank_row() == r.ib) {
174 auto c = spl_col_.location(icol_glob);
175 if (blacs_grid_->rank_col() == c.ib) {
176 (*this)(r.index_local, c.index_local) = val;
177 }
178 }
179 } else {
180 (*this)(irow_glob, icol_glob) = val;
181 }
182}
183
184template <typename T>
185void dmatrix<T>::add(const int irow_glob, const int icol_glob, T val)
186{
187 auto r = spl_row_.location(irow_glob);
188 if (blacs_grid_->rank_row() == r.ib) {
189 auto c = spl_col_.location(icol_glob);
190 if (blacs_grid_->rank_col() == c.ib) {
191 (*this)(r.index_local, c.index_local) += val;
192 }
193 }
194}
195
196template <typename T>
197void dmatrix<T>::add(real_type<T> beta__, const int irow_glob, const int icol_glob, T val)
198{
199 auto r = spl_row_.location(irow_glob);
200 if (blacs_grid_->rank_row() == r.ib) {
201 auto c = spl_col_.location(icol_glob);
202 if (blacs_grid_->rank_col() == c.ib) {
203 (*this)(r.index_local, c.index_local) = (*this)(r.index_local, c.index_local) * beta__ + val;
204 }
205 }
206}
207
208template <typename T>
209void dmatrix<T>::make_real_diag(int n__)
210{
211 for (int i = 0; i < n__; i++) {
212 auto r = spl_row_.location(i);
213 if (blacs_grid_->rank_row() == r.ib) {
214 auto c = spl_col_.location(i);
215 if (blacs_grid_->rank_col() == c.ib) {
216 T v = (*this)(r.index_local, c.index_local);
217 (*this)(r.index_local, c.index_local) = std::real(v);
218 }
219 }
220 }
221}
222
223template <typename T>
224sddk::mdarray<T, 1> dmatrix<T>::get_diag(int n__)
225{
226 sddk::mdarray<T, 1> d(n__);
227 d.zero();
228
229 for (int i = 0; i < n__; i++) {
230 auto r = spl_row_.location(i);
231 if (blacs_grid_->rank_row() == r.ib) {
232 auto c = spl_col_.location(i);
233 if (blacs_grid_->rank_col() == c.ib) {
234 d[i] = (*this)(r.index_local, c.index_local);
235 }
236 }
237 }
238 blacs_grid_->comm().allreduce(d.template at(sddk::memory_t::host), n__);
239 return d;
240}
241
242template <typename T>
243void dmatrix<T>::save_to_hdf5(std::string name__, int m__, int n__)
244{
245 sddk::mdarray<T, 2> full_mtrx(m__, n__);
246 full_mtrx.zero();
247
248 for (int j = 0; j < this->num_cols_local(); j++) {
249 for (int i = 0; i < this->num_rows_local(); i++) {
250 if (this->irow(i) < m__ && this->icol(j) < n__) {
251 full_mtrx(this->irow(i), this->icol(j)) = (*this)(i, j);
252 }
253 }
254 }
255 this->comm().allreduce(full_mtrx.template at(sddk::memory_t::host), static_cast<int>(full_mtrx.size()));
256
257 if (this->blacs_grid().comm().rank() == 0) {
258 sirius::HDF5_tree h5(name__, sirius::hdf5_access_t::truncate);
259 h5.write("nrow", m__);
260 h5.write("ncol", n__);
261 h5.write("mtrx", full_mtrx);
262 }
263}
264
265// instantiate for required types
266template class dmatrix<double>;
267template class dmatrix<std::complex<double>>;
268#ifdef SIRIUS_USE_FP32
269template class dmatrix<float>;
270template class dmatrix<std::complex<float>>;
271#endif
272
273} // namespace
274
275} // namespace sirius
Interface to the HDF5 library.
Definition: hdf5_tree.hpp:86
Contains definition and implementation of distributed matrix class.
@ spla
SPLA library. Can take CPU and device pointers.
Namespace of the SIRIUS library.
Definition: sirius.f90:5
strong_type< int, struct __block_id_tag > block_id
ID of the block.
Definition: splindex.hpp:108
strong_type< int, struct __n_blocks_tag > n_blocks
Number of blocks to which the global index is split.
Definition: splindex.hpp:105