Ensign
Low-rank framework for multi-core CPUs and GPUs
Loading...
Searching...
No Matches
lr.hpp
Go to the documentation of this file.
1
6#pragma once
7
8#include <generic/common.hpp>
9#include <generic/storage.hpp>
10#include <generic/kernels.hpp>
11#include <generic/matrix.hpp>
12
13namespace Ensign {
14
15/* Class to store the low-rank factors (X, S, V) that are used in the computation.
16*
17* The low-rank factors can reside either on the host (CPU) or the device (GPU)
18* depending on the value of stloc (either stloc::host or stloc::device).
19*/
20template<class T>
21struct lr2 {
25
26 lr2(stloc sl=stloc::host) : S(sl), X(sl), V(sl) {}
27
28 lr2(Index r, array<Index,2> N, stloc sl=stloc::host) : S({r,r},sl), X({N[0],r},sl), V({N[1],r},sl) {}
29
30 lr2(Index r, Index r_max, array<Index,2> N, stloc sl=stloc::host) : S({r,r},sl), X({N[0],r_max},{N[0],r},sl), V({N[1],r_max},{N[1],r},sl) {}
31
32 void resize(Index r, array<Index,2> N) {
33 S.resize({r,r});
34 X.resize({N[0],r});
35 V.resize({N[1],r});
36 }
37
39 X.update_shape({X.shape()[0],r});
40 S.resize({r,r});
41 V.update_shape({V.shape()[0],r});
42 }
43
44 Index size_X() const {
45 return X.shape()[0];
46 }
47 Index size_V() const {
48 return V.shape()[0];
49 }
50 Index rank() const {
51 return S.shape()[0];
52 }
53
54 void set_zero() {
55 S.set_zero();
56 }
57
58 /* Computes the full matrix (can be very expensive and should not be used in production code)
59 */
62 blas.matmul(X, S, K);
64 blas.matmul_transb(K, V, out);
65 return out;
66 }
67};
68
69/* Add two low-rank representations together.
70*
71* Note that no truncation is performed by this function. To do that call lr_truncate.
72*/
73template<class T, class IP>
74void lr_add(T alpha, const lr2<T>& A, T beta, const lr2<T>& B, lr2<T>& out,
75 IP inner_product_X,
76 IP inner_product_V,
77 const Ensign::Matrix::blas_ops& blas);
78
79/* Add three low-rank representations together.
80*
81* Note that no truncation is performed by this function. To do that call lr_truncate.
82*/
83template<class T, class IP>
84void lr_add(T alpha, const lr2<T>& A, T beta, const lr2<T>& B,
85 T gamma, const lr2<T>& C, lr2<T>& out,
86 IP inner_product_X,
87 IP inner_product_V,
88 const Ensign::Matrix::blas_ops& blas);
89
90
91/* Multiplies two low-rank representations together.
92*
93* Note that no truncation is performed by this function. To do that call lr_truncate.
94*/
95template<class T, class IP>
96void lr_mul(const lr2<T>& A, const lr2<T>& B, lr2<T>& out,
97 IP inner_product_X,
98 IP inner_product_V,
99 const Ensign::Matrix::blas_ops& blas);
100
101/* Truncate a low-rank representation inplace to a fixed rank r.
102*
103* The rank is determined by the size of out.
104*/
105template<class T>
106void lr_truncate(const lr2<T>& in, lr2<T>& out, const Ensign::Matrix::blas_ops& blas);
107
108
109/* Computes the inner product of two low-rank representations.
110*
111* Computes the inner product of two low-rank representations.
112*/
113template<class T>
114double lr_inner_product(const lr2<T>& A, const lr2<T>&B, T w, const Ensign::Matrix::blas_ops& blas);
115
116
117/* Computes the norm of a low-rank representations.
118*
119* This assumes that X and V are orthogonalized. Thus, no inner product needs
120* to be passed to this function. The function simply computes
121* \f$\sum_{ij} S_{ij}^2\f$
122*/
123template<class T>
124double lr_norm_sq(const lr2<T>& A, const Ensign::Matrix::blas_ops& blas);
125
126
127
128
129/* Initializes (an already allocated) lr2 to \f$\sum_i X_i V_i\f$.
130*
131* The rank r is taken from the initialized lr. If X.size() and V.size() are smaller
132* than r, the remaining basis functions are initialized in a random manner (subject
133* (to the orthogonality condition).
134* X.size() == V.size() is required.
135*/
136template<class T, class IP>
137void initialize(lr2<T>& lr, vector<const T*> X, vector<const T*> V,
138 IP inner_product_X,
139 IP inner_product_V,
140 const Ensign::Matrix::blas_ops& blas);
141
142template<class T>
143void initialize(lr2<T>& lr, vector<const T*> X, vector<const T*> V,
144 array<double,3> h_xx, array<double,3> h_vv,
145 const Ensign::Matrix::blas_ops& blas);
146
147/* Return an inner product function object for use in, e.g., in gram_schmidt.
148*/
149template<class T>
150std::function<T(T*,T*)> inner_product_from_const_weight(T w, Index N);
151
152/* Return an inner product function object for use in, e.g., in gram_schmidt.
153*
154*/
155template<class T>
156std::function<T(T*,T*)> inner_product_from_weight(const T* w, Index N);
157
158
159/* Orthogonalizes Q and returns the corresponding upper triangular matrix R.
160*
161* Note that the inputs are overwritten.
162*/
163
165
168
169 void operator()(multi_array<double,2>& Q, multi_array<double,2>& R, std::function<double(double*,double*)> inner_product);
172
173 // Forces the use of Gram Schmidt.
174 // This guarantees that if the first number of basis functions are already orthonormal, they are not changed.
175 void gram_schmidt(multi_array<double,2>& Q, multi_array<double,2>& R, std::function<double(double*,double*)> inner_product);
177
178private:
179 const Ensign::Matrix::blas_ops* blas;
180 #ifdef __CUDA__
181 curandGenerator_t gen;
182 #endif
183};
184
185} // namespace Ensign
Provides shared types, platform headers, and basic definitions.
ptrdiff_t Index
Definition common.hpp:83
stloc
Definition common.hpp:84
Declares CUDA kernels for elementwise operations and numerical updates.
Declares dense matrix and vector operations, including BLAS wrappers.
Core namespace for Ensign's numerical algorithms and data structures.
Definition common.hpp:96
std::function< T(T *, T *)> inner_product_from_weight(const T *w, Index N)
Return an inner product function object for use in, e.g., in gram_schmidt.
double lr_inner_product(const lr2< T > &A, const lr2< T > &B, T w, const Ensign::Matrix::blas_ops &blas)
Computes the inner product of two low-rank representations.
void initialize(lr2< T > &lr, vector< const T * > X, vector< const T * > V, IP inner_product_X, IP inner_product_V, const Ensign::Matrix::blas_ops &blas)
Initializes (an already allocated) lr2 to .
void lr_mul(const lr2< T > &A, const lr2< T > &B, lr2< T > &out, IP inner_product_X, IP inner_product_V, const Ensign::Matrix::blas_ops &blas)
Multiplies two low-rank representations together.
void lr_add(T alpha, const lr2< T > &A, T beta, const lr2< T > &B, lr2< T > &out, IP inner_product_X, IP inner_product_V, const Ensign::Matrix::blas_ops &blas)
Add two low-rank representations together.
std::function< T(T *, T *)> inner_product_from_const_weight(T w, Index N)
Return an inner product function object for use in, e.g., in gram_schmidt.
void lr_truncate(const lr2< T > &in, lr2< T > &out, const Ensign::Matrix::blas_ops &blas)
Truncate a low-rank representation inplace to a fixed rank r.
double lr_norm_sq(const lr2< T > &A, const Ensign::Matrix::blas_ops &blas)
Computes the norm of a low-rank representations.
Provides contiguous multidimensional arrays for CPU and GPU storage.
Provides matrix and vector operations with optional GPU execution.
Definition matrix.hpp:47
void matmul(const multi_array< T, 2 > &a, const multi_array< T, 2 > &b, multi_array< T, 2 > &c) const
Matrix multiplication (computes c = a b)
void matmul_transb(const multi_array< T, 2 > &a, const multi_array< T, 2 > &b, multi_array< T, 2 > &c) const
Matrix multiplication with second matrix transposed (computes c = a b^T)
Class to store the low-rank factors (X, S, V) that are used in the computation.
Definition lr.hpp:21
multi_array< T, 2 > full(const Ensign::Matrix::blas_ops &blas) const
Computes the full matrix (can be very expensive and should not be used in production code)
Definition lr.hpp:60
multi_array< T, 2 > X
Definition lr.hpp:23
Index size_X() const
Definition lr.hpp:44
multi_array< T, 2 > V
Definition lr.hpp:24
Index rank() const
Definition lr.hpp:50
Index size_V() const
Definition lr.hpp:47
void set_zero()
Definition lr.hpp:54
lr2(stloc sl=stloc::host)
Definition lr.hpp:26
multi_array< T, 2 > S
Definition lr.hpp:22
lr2(Index r, array< Index, 2 > N, stloc sl=stloc::host)
Definition lr.hpp:28
lr2(Index r, Index r_max, array< Index, 2 > N, stloc sl=stloc::host)
Definition lr.hpp:30
void update_info(Index r)
Definition lr.hpp:38
void resize(Index r, array< Index, 2 > N)
Definition lr.hpp:32
Dense d-dimensional array stored contiguously in column-major order (i.e.
Definition storage.hpp:24
array< Index, d > shape() const
Definition storage.hpp:244
void update_shape(array< Index, d > _e)
Definition storage.hpp:154
void resize(array< Index, d > _e)
Definition storage.hpp:94
Orthogonalizes Q and returns the corresponding upper triangular matrix R.
Definition lr.hpp:164
void gram_schmidt(multi_array< double, 2 > &Q, multi_array< double, 2 > &R, double w)
void operator()(multi_array< double, 2 > &Q, multi_array< double, 2 > &R, double *w)
void operator()(multi_array< double, 2 > &Q, multi_array< double, 2 > &R, std::function< double(double *, double *)> inner_product)
void operator()(multi_array< double, 2 > &Q, multi_array< double, 2 > &R, double w)
void gram_schmidt(multi_array< double, 2 > &Q, multi_array< double, 2 > &R, std::function< double(double *, double *)> inner_product)
orthogonalize(const Ensign::Matrix::blas_ops *_blas)