SIRIUS 7.5.0
Electronic structure library and applications
eigensolver.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2019 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 eigensolver.hpp
21 *
22 * \brief Contains definition of eigensolver factory.
23 */
24
25#ifndef __EIGENSOLVER_HPP__
26#define __EIGENSOLVER_HPP__
27
28#include "SDDK/memory.hpp"
29#include "core/la/dmatrix.hpp"
30
31namespace sirius {
32
33namespace la {
34
35/// Type of eigen-value solver.
36enum class ev_solver_t
37{
38 /// LAPACK
39 lapack,
40
41 /// ScaLAPACK
43
44 /// ELPA solver
45 elpa,
46
47 /// DLA-Future solver
48 dlaf,
49
50 /// MAGMA with CPU pointers
51 magma,
52
53 /// MAGMA with GPU pointers
55
56 /// CUDA eigen-solver
58};
59
60/// Get type of an eigen solver by name (provided as a string).
61inline ev_solver_t get_ev_solver_t(std::string name__)
62{
63 std::transform(name__.begin(), name__.end(), name__.begin(), ::tolower);
64
65 static const std::map<std::string, ev_solver_t> map_to_type = {
66 {"lapack", ev_solver_t::lapack}, {"scalapack", ev_solver_t::scalapack}, {"elpa1", ev_solver_t::elpa},
67 {"elpa2", ev_solver_t::elpa}, {"dlaf", ev_solver_t::dlaf}, {"magma", ev_solver_t::magma}, {"magma_gpu", ev_solver_t::magma_gpu},
68 {"cusolver", ev_solver_t::cusolver}};
69
70 if (map_to_type.count(name__) == 0) {
71 std::stringstream s;
72 s << "wrong label of eigen-solver : " << name__;
73 RTE_THROW(s);
74 }
75
76 return map_to_type.at(name__);
77}
78
79/// Interface to different eigen-solvers.
81{
82 protected:
83 /// Type of the eigen-value solver.
85 /// Common error message.
86 const std::string error_msg_not_implemented = "solver is not implemented";
87 /// True if solver is MPI parallel.
88 bool is_parallel_{false};
89 /// Type of host memory needed for the solver.
90 /** Some solvers, for example MAGMA, require host pilnned memory. */
91 sddk::memory_t host_memory_t_{sddk::memory_t::none};
92 /// Type of input data memory.
93 /** CPU solvers start from host memory, MAGMA can start from host or device memory, cuSolver starts from
94 * device memory. */
95 sddk::memory_t data_memory_t_{sddk::memory_t::none};
96
97 public:
98 /// Constructor.
99 Eigensolver(ev_solver_t type__, bool is_parallel__, sddk::memory_t host_memory_t__,
100 sddk::memory_t data_memory_t__)
101 : ev_solver_type_(type__)
102 , is_parallel_(is_parallel__)
103 , host_memory_t_(host_memory_t__)
104 , data_memory_t_(data_memory_t__)
105 {
106 }
107
108 /// Destructor.
109 virtual ~Eigensolver()
110 {
111 }
112
113 /// Solve a standard eigen-value problem for all eigen-pairs.
114 virtual int solve(ftn_int matrix_size__, dmatrix<double>& A__, double* eval__, dmatrix<double>& Z__)
115 {
116 RTE_THROW(error_msg_not_implemented);
117 return -1;
118 }
119
120 /// Solve a standard eigen-value problem for all eigen-pairs.
121 virtual int solve(ftn_int matrix_size__, dmatrix<std::complex<double>>& A__, double* eval__,
122 dmatrix<std::complex<double>>& Z__)
123 {
124 RTE_THROW(error_msg_not_implemented);
125 return -1;
126 }
127
128 /// Solve a standard eigen-value problem for all eigen-pairs.
129 virtual int solve(ftn_int matrix_size__, dmatrix<float>& A__, float* eval__, dmatrix<float>& Z__)
130 {
131 RTE_THROW(error_msg_not_implemented);
132 return -1;
133 }
134
135 /// Solve a standard eigen-value problem for all eigen-pairs.
136 virtual int solve(ftn_int matrix_size__, dmatrix<std::complex<float>>& A__, float* eval__,
137 dmatrix<std::complex<float>>& Z__)
138 {
139 RTE_THROW(error_msg_not_implemented);
140 return -1;
141 }
142
143 /// Solve a standard eigen-value problem of a sub-matrix for N lowest eigen-pairs
144 virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix<double>& A__, double* eval__, dmatrix<double>& Z__)
145 {
146 RTE_THROW(error_msg_not_implemented);
147 return -1;
148 }
149
150 /// Solve a standard eigen-value problem of a sub-matrix for N lowest eigen-pairs.
151 virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix<std::complex<double>>& A__, double* eval__, dmatrix<std::complex<double>>& Z__)
152 {
153 RTE_THROW(error_msg_not_implemented);
154 return -1;
155 }
156
157 /// Solve a standard eigen-value problem of a sub-matrix for N lowest eigen-pairs
158 virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix<float>& A__, float* eval__, dmatrix<float>& Z__)
159 {
160 RTE_THROW(error_msg_not_implemented);
161 return -1;
162 }
163
164 /// Solve a standard eigen-value problem of a sub-matrix for N lowest eigen-pairs.
165 virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix<std::complex<float>>& A__, float* eval__, dmatrix<std::complex<float>>& Z__)
166 {
167 RTE_THROW(error_msg_not_implemented);
168 return -1;
169 }
170
171 /// Solve a generalized eigen-value problem for all eigen-pairs.
172 virtual int solve(ftn_int matrix_size__, dmatrix<double>& A__, dmatrix<double>& B__, double* eval__,
173 dmatrix<double>& Z__)
174 {
175 RTE_THROW(error_msg_not_implemented);
176 return -1;
177 }
178
179 /// Solve a generalized eigen-value problem for all eigen-pairs.
180 virtual int solve(ftn_int matrix_size__, dmatrix<std::complex<double>>& A__, dmatrix<std::complex<double>>& B__,
181 double* eval__, dmatrix<std::complex<double>>& Z__)
182 {
183 RTE_THROW(error_msg_not_implemented);
184 return -1;
185 }
186
187 /// Solve a generalized eigen-value problem for all eigen-pairs.
188 virtual int solve(ftn_int matrix_size__, dmatrix<float>& A__, dmatrix<float>& B__, float* eval__,
189 dmatrix<float>& Z__)
190 {
191 RTE_THROW(error_msg_not_implemented);
192 return -1;
193 }
194
195 /// Solve a generalized eigen-value problem for all eigen-pairs.
196 virtual int solve(ftn_int matrix_size__, dmatrix<std::complex<float>>& A__, dmatrix<std::complex<float>>& B__,
197 float* eval__, dmatrix<std::complex<float>>& Z__)
198 {
199 RTE_THROW(error_msg_not_implemented);
200 return -1;
201 }
202
203 /// Solve a generalized eigen-value problem for N lowest eigen-pairs.
204 virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix<double>& A__, dmatrix<double>& B__,
205 double* eval__, dmatrix<double>& Z__)
206 {
207 RTE_THROW(error_msg_not_implemented);
208 return -1;
209 }
210
211 /// Solve a generalized eigen-value problem for N lowest eigen-pairs.
212 virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix<std::complex<double>>& A__,
213 dmatrix<std::complex<double>>& B__, double* eval__, dmatrix<std::complex<double>>& Z__)
214 {
215 RTE_THROW(error_msg_not_implemented);
216 return -1;
217 }
218
219 /// Solve a generalized eigen-value problem for N lowest eigen-pairs.
220 virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix<float>& A__, dmatrix<float>& B__,
221 float* eval__, dmatrix<float>& Z__)
222 {
223 RTE_THROW(error_msg_not_implemented);
224 return -1;
225 }
226
227 /// Solve a generalized eigen-value problem for N lowest eigen-pairs.
228 virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix<std::complex<float>>& A__,
229 dmatrix<std::complex<float>>& B__, float* eval__, dmatrix<std::complex<float>>& Z__)
230 {
231 RTE_THROW(error_msg_not_implemented);
232 return -1;
233 }
234
235 /// Parallel or sequential solver.
236 bool is_parallel() const
237 {
238 return is_parallel_;
239 }
240
241 /// Type of host memory, required by the solver.
243 {
244 return host_memory_t_;
245 }
246
247 /// Type of input memory for the solver.
249 {
250 return data_memory_t_;
251 }
252
253 /// Type of eigen-solver.
254 inline ev_solver_t type() const
255 {
256 return ev_solver_type_;
257 }
258};
259
260std::unique_ptr<Eigensolver>
261Eigensolver_factory(std::string name__);
262
263} // namespace
264
265}
266
267#endif
Interface to different eigen-solvers.
Definition: eigensolver.hpp:81
virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix< std::complex< double > > &A__, dmatrix< std::complex< double > > &B__, double *eval__, dmatrix< std::complex< double > > &Z__)
Solve a generalized eigen-value problem for N lowest eigen-pairs.
virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix< std::complex< float > > &A__, float *eval__, dmatrix< std::complex< float > > &Z__)
Solve a standard eigen-value problem of a sub-matrix for N lowest eigen-pairs.
virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix< std::complex< double > > &A__, double *eval__, dmatrix< std::complex< double > > &Z__)
Solve a standard eigen-value problem of a sub-matrix for N lowest eigen-pairs.
virtual int solve(ftn_int matrix_size__, dmatrix< float > &A__, float *eval__, dmatrix< float > &Z__)
Solve a standard eigen-value problem for all eigen-pairs.
const std::string error_msg_not_implemented
Common error message.
Definition: eigensolver.hpp:86
virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix< std::complex< float > > &A__, dmatrix< std::complex< float > > &B__, float *eval__, dmatrix< std::complex< float > > &Z__)
Solve a generalized eigen-value problem for N lowest eigen-pairs.
virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix< double > &A__, dmatrix< double > &B__, double *eval__, dmatrix< double > &Z__)
Solve a generalized eigen-value problem for N lowest eigen-pairs.
ev_solver_t type() const
Type of eigen-solver.
ev_solver_t ev_solver_type_
Type of the eigen-value solver.
Definition: eigensolver.hpp:84
virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix< float > &A__, dmatrix< float > &B__, float *eval__, dmatrix< float > &Z__)
Solve a generalized eigen-value problem for N lowest eigen-pairs.
sddk::memory_t data_memory_t_
Type of input data memory.
Definition: eigensolver.hpp:95
virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix< float > &A__, float *eval__, dmatrix< float > &Z__)
Solve a standard eigen-value problem of a sub-matrix for N lowest eigen-pairs.
virtual int solve(ftn_int matrix_size__, dmatrix< std::complex< float > > &A__, dmatrix< std::complex< float > > &B__, float *eval__, dmatrix< std::complex< float > > &Z__)
Solve a generalized eigen-value problem for all eigen-pairs.
virtual int solve(ftn_int matrix_size__, dmatrix< std::complex< double > > &A__, dmatrix< std::complex< double > > &B__, double *eval__, dmatrix< std::complex< double > > &Z__)
Solve a generalized eigen-value problem for all eigen-pairs.
sddk::memory_t host_memory_t() const
Type of host memory, required by the solver.
virtual int solve(ftn_int matrix_size__, dmatrix< double > &A__, double *eval__, dmatrix< double > &Z__)
Solve a standard eigen-value problem for all eigen-pairs.
sddk::memory_t data_memory_t() const
Type of input memory for the solver.
Eigensolver(ev_solver_t type__, bool is_parallel__, sddk::memory_t host_memory_t__, sddk::memory_t data_memory_t__)
Constructor.
Definition: eigensolver.hpp:99
virtual int solve(ftn_int matrix_size__, dmatrix< float > &A__, dmatrix< float > &B__, float *eval__, dmatrix< float > &Z__)
Solve a generalized eigen-value problem for all eigen-pairs.
sddk::memory_t host_memory_t_
Type of host memory needed for the solver.
Definition: eigensolver.hpp:91
virtual ~Eigensolver()
Destructor.
virtual int solve(ftn_int matrix_size__, dmatrix< std::complex< float > > &A__, float *eval__, dmatrix< std::complex< float > > &Z__)
Solve a standard eigen-value problem for all eigen-pairs.
bool is_parallel_
True if solver is MPI parallel.
Definition: eigensolver.hpp:88
bool is_parallel() const
Parallel or sequential solver.
virtual int solve(ftn_int matrix_size__, dmatrix< std::complex< double > > &A__, double *eval__, dmatrix< std::complex< double > > &Z__)
Solve a standard eigen-value problem for all eigen-pairs.
virtual int solve(ftn_int matrix_size__, ftn_int nev__, dmatrix< double > &A__, double *eval__, dmatrix< double > &Z__)
Solve a standard eigen-value problem of a sub-matrix for N lowest eigen-pairs.
virtual int solve(ftn_int matrix_size__, dmatrix< double > &A__, dmatrix< double > &B__, double *eval__, dmatrix< double > &Z__)
Solve a generalized eigen-value problem for all eigen-pairs.
Distributed matrix.
Definition: dmatrix.hpp:56
Contains definition and implementation of distributed matrix class.
Memory management functions and classes.
memory_t
Memory types where the code can store data.
Definition: memory.hpp:71
ev_solver_t get_ev_solver_t(std::string name__)
Get type of an eigen solver by name (provided as a string).
Definition: eigensolver.hpp:61
ev_solver_t
Type of eigen-value solver.
Definition: eigensolver.hpp:37
@ dlaf
DLA-Future solver.
@ magma_gpu
MAGMA with GPU pointers.
@ cusolver
CUDA eigen-solver.
@ magma
MAGMA with CPU pointers.
std::enable_if_t< std::is_same< T, real_type< F > >::value, void > transform(::spla::Context &spla_ctx__, sddk::memory_t mem__, la::dmatrix< F > const &M__, int irow0__, int jcol0__, real_type< F > alpha__, Wave_functions< T > const &wf_in__, spin_index s_in__, band_range br_in__, real_type< F > beta__, Wave_functions< T > &wf_out__, spin_index s_out__, band_range br_out__)
Apply linear transformation to the wave-functions.
Namespace of the SIRIUS library.
Definition: sirius.f90:5