Loading...
Searching...
No Matches
blas.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * BLAS declarations for complex double-precision routines.
5 *
6 * These are the standard Fortran BLAS interfaces used by the Davidson
7 * diagonalizer for matrix-matrix and matrix-vector operations. On macOS,
8 * these are provided by the Accelerate framework (same as LAPACK).
9 */
10
11#include <complex>
12
13namespace q3::blas {
14
15extern "C" {
16
17/**
18 * ZGEMM: Complex double-precision general matrix-matrix multiply.
19 * C := alpha * op(A) * op(B) + beta * C
20 */
21void zgemm_(const char* transa,
22 const char* transb,
23 const int* m,
24 const int* n,
25 const int* k,
26 const std::complex<double>* alpha,
27 const std::complex<double>* a,
28 const int* lda,
29 const std::complex<double>* b,
30 const int* ldb,
31 const std::complex<double>* beta,
32 std::complex<double>* c,
33 const int* ldc);
34
35/**
36 * DGEMM: Real double-precision general matrix-matrix multiply.
37 * C := alpha * op(A) * op(B) + beta * C
38 *
39 * Used in gamma-only inner products where the result is real-valued.
40 * Two DGEMM calls on the real and imaginary parts of the complex data
41 * give a 2× FLOP reduction compared to a single ZGEMM.
42 */
43void dgemm_(const char* transa,
44 const char* transb,
45 const int* m,
46 const int* n,
47 const int* k,
48 const double* alpha,
49 const double* a,
50 const int* lda,
51 const double* b,
52 const int* ldb,
53 const double* beta,
54 double* c,
55 const int* ldc);
56
57/**
58 * ZGEMV: Complex double-precision general matrix-vector multiply.
59 * y := alpha * op(A) * x + beta * y
60 */
61void zgemv_(const char* trans,
62 const int* m,
63 const int* n,
64 const std::complex<double>* alpha,
65 const std::complex<double>* a,
66 const int* lda,
67 const std::complex<double>* x,
68 const int* incx,
69 const std::complex<double>* beta,
70 std::complex<double>* y,
71 const int* incy);
72
73/**
74 * DGEMV: Real double-precision general matrix-vector multiply.
75 * y := alpha * op(A) * x + beta * y
76 */
77void dgemv_(const char* trans,
78 const int* m,
79 const int* n,
80 const double* alpha,
81 const double* a,
82 const int* lda,
83 const double* x,
84 const int* incx,
85 const double* beta,
86 double* y,
87 const int* incy);
88
89} // extern "C"
90
91/**
92 * ZDOTC wrapper: Complex double-precision dot product with conjugation.
93 * result := Σ conj(x[element_index]) * y[element_index]
94 *
95 * Uses manual loop to avoid zdotc_ ABI incompatibility on macOS Accelerate
96 * (hidden return-value pointer). BLAS Level-1 operations on vectors of
97 * typical DFT size (~100-1000) are memory-bound, so the manual loop
98 * performs comparably to the BLAS call.
99 */
100inline std::complex<double> q3_complex_conjugate_dot_product(int n,
101 const std::complex<double>* x,
102 const std::complex<double>* y) {
103 std::complex<double> result(0.0, 0.0);
104 for (int element_index = 0; element_index < n; element_index++) {
105 result += std::conj(x[element_index]) * y[element_index];
106 }
107 return result;
108}
109
110extern "C" {
111
112/**
113 * ZAXPY: Complex double-precision vector addition with scalar.
114 * y := alpha * x + y
115 */
116void zaxpy_(const int* n,
117 const std::complex<double>* alpha,
118 const std::complex<double>* x,
119 const int* incx,
120 std::complex<double>* y,
121 const int* incy);
122
123/**
124 * ZDSCAL: Scale a complex double-precision vector by a real scalar.
125 * x := alpha * x
126 */
127void zdscal_(const int* n, const double* alpha, std::complex<double>* x, const int* incx);
128
129/**
130 * DZNRM2: Euclidean norm of a complex double-precision vector.
131 * result := sqrt( Σ |x[i]|² )
132 */
133double dznrm2_(const int* n, const std::complex<double>* x, const int* incx);
134
135/**
136 * DPOTRF: Real double-precision Cholesky factorization.
137 */
138void dpotrf_(const char* uplo, const int* n, double* a, const int* lda, int* info);
139
140/**
141 * ZPOTRF: Complex double-precision Cholesky factorization.
142 */
143void zpotrf_(const char* uplo, const int* n, std::complex<double>* a, const int* lda, int* info);
144
145/**
146 * DTRSM: Real double-precision triangular matrix solve.
147 */
148void dtrsm_(const char* side,
149 const char* uplo,
150 const char* transa,
151 const char* diag,
152 const int* m,
153 const int* n,
154 const double* alpha,
155 const double* a,
156 const int* lda,
157 double* b,
158 const int* ldb);
159
160/**
161 * ZTRSM: Complex double-precision triangular matrix solve.
162 */
163void ztrsm_(const char* side,
164 const char* uplo,
165 const char* transa,
166 const char* diag,
167 const int* m,
168 const int* n,
169 const std::complex<double>* alpha,
170 const std::complex<double>* a,
171 const int* lda,
172 std::complex<double>* b,
173 const int* ldb);
174
175} // extern "C"
176
177} // namespace q3::blas
void dgemm_(const char *transa, const char *transb, const int *m, const int *n, const int *k, const double *alpha, const double *a, const int *lda, const double *b, const int *ldb, const double *beta, double *c, const int *ldc)
void dpotrf_(const char *uplo, const int *n, double *a, const int *lda, int *info)
std::complex< double > q3_complex_conjugate_dot_product(int n, const std::complex< double > *x, const std::complex< double > *y)
Definition blas.hpp:100
void dtrsm_(const char *side, const char *uplo, const char *transa, const char *diag, const int *m, const int *n, const double *alpha, const double *a, const int *lda, double *b, const int *ldb)
void zgemm_(const char *transa, const char *transb, const int *m, const int *n, const int *k, const std::complex< double > *alpha, const std::complex< double > *a, const int *lda, const std::complex< double > *b, const int *ldb, const std::complex< double > *beta, std::complex< double > *c, const int *ldc)
void dgemv_(const char *trans, const int *m, const int *n, const double *alpha, const double *a, const int *lda, const double *x, const int *incx, const double *beta, double *y, const int *incy)
void zpotrf_(const char *uplo, const int *n, std::complex< double > *a, const int *lda, int *info)
void ztrsm_(const char *side, const char *uplo, const char *transa, const char *diag, const int *m, const int *n, const std::complex< double > *alpha, const std::complex< double > *a, const int *lda, std::complex< double > *b, const int *ldb)
void zdscal_(const int *n, const double *alpha, std::complex< double > *x, const int *incx)
void zaxpy_(const int *n, const std::complex< double > *alpha, const std::complex< double > *x, const int *incx, std::complex< double > *y, const int *incy)
double dznrm2_(const int *n, const std::complex< double > *x, const int *incx)
void zgemv_(const char *trans, const int *m, const int *n, const std::complex< double > *alpha, const std::complex< double > *a, const int *lda, const std::complex< double > *x, const int *incx, const std::complex< double > *beta, std::complex< double > *y, const int *incy)