NumericAL
A header-only C++20 lexer built on REAL
Loading...
Searching...
No Matches
Classes | Functions | Variables
numerical::blas::detail Namespace Reference

Classes

struct  syrk_operands
 The operands of syrk_triangle, which are row-major P = op(A) and Q = op(A)ᵀ (one of them scaled by α), the column-major C and which triangle of it is written. More...
 

Functions

buffer< double > & syrk_operand () noexcept
 The storage of syrk's operand copy this thread keeps between calls.
 
constexpr bool is_operation (char op) noexcept
 Whether op is one of BLAS's N, T or C (either case): no transpose, transpose, conjugate one.
 
constexpr bool transposes (char op) noexcept
 Whether op transposes (T or C: a real matrix's conjugate transpose is its transpose).
 
constexpr bool conjugates (char op) noexcept
 Whether op is BLAS's C: the conjugate transpose (a real matrix's is its transpose).
 
template<typename T >
bool finite (const T &x)
 Whether the real x is finite (an overload per kind of scalar, as conj_of: each one expression).
 
template<typename U >
bool finite (const std::complex< U > &x)
 Whether both parts of the complex x are finite.
 
template<typename T >
void row_major_into (buffer< T > &out, const T *a, std::ptrdiff_t lda, std::ptrdiff_t rows, std::ptrdiff_t cols, T scale, bool conjugate=false)
 The column-major rows × cols a (lda apart) into the row-major out (resized to it), by tiles, each element times scale (conjugated first where conjugate).
 
template<typename T >
buffer< T > row_major (const T *a, std::ptrdiff_t lda, std::ptrdiff_t rows, std::ptrdiff_t cols, T scale, bool conjugate=false)
 rows × cols of the column-major a (lda apart), as a row-major buffer, each element times scale (conjugated first where conjugate).
 
template<typename T >
buffer< T > & kept_storage (std::size_t slot) noexcept
 Row-major storage of the scalar T this thread keeps between calls, in slot (0 for a call's A, 1 for its B): a fresh one of megabytes is mapped anew and faulted in page by page on every call (a solve of order 1000 spent 2.5 ms of its 30 on each).
 
template<typename T >
buffer< T > take_kept (std::size_t slot)
 kept_storage's slot, taken over by the caller (left empty there meanwhile).
 
template<typename T >
void give_back (std::size_t slot, buffer< T > &&storage)
 storage given back to kept_storage's slot, unless past kept_bytes.
 
template<typename T >
bool is_identity (const T *b, std::size_t ldb, std::size_t n)
 Whether the column-major n × n b (ldb apart) is the identity to the bit (a -0 is no zero of it, a solve from it signing zeros of its own): column j against n elements of a unit column of 2n − 1, its one in the middle, from n − 1 − j, a comparison of bytes a column. The first column alone, most other right-hand sides told apart there; the rest by columns on the threads, bound by the memory.
 
template<typename T >
void column_major_into (const T *from, std::size_t rows, std::size_t cols, T *a, std::size_t lda)
 The row-major rows × cols from into the column-major a (lda apart), by tiles.
 
template<typename T >
void column_major_permuted_into (const T *from, std::size_t n, const std::size_t *to, T *a, std::size_t lda)
 column_major_into for the n × n from, its column j written as column to[j] of a.
 
template<typename T >
void product_by_op_a (char transa, std::size_t m, std::size_t n, std::size_t k, const T *l, std::size_t ldl, const T *a, std::size_t lda, T *c, std::size_t ldc)
 C += L op(A)ᵀ (C row-major m × n, L m × k), a the column-major op(A)'s storage (lda apart): op(A)ᵀ is A read in place where transa does not transpose, else a copy of its transpose (an overload per scalar, as conj_of).
 
void product_by_op_a (char transa, std::size_t m, std::size_t n, std::size_t k, const double *l, std::size_t ldl, const double *a, std::size_t lda, double *c, std::size_t ldc)
 product_by_op_a for double: a transposed A read in place too, as op(A)ᵀ's transpose (numerical::detail::gemm_bt, the bits of the product by the copy; NumPy's a @ b.T).
 
template<typename T >
void lower_triangle_rows (T *a, std::size_t lda, std::size_t n, T *rows, bool in)
 The lower triangle of the column-major n × n a (lda apart) into that of the row-major rows (n apart) where in, out of it back into a otherwise, by tiles, bands of them on the threads; the other triangles untouched.
 
template<typename T >
buffer< T > columns_as_rows (const T *a, std::ptrdiff_t lda, std::ptrdiff_t rows, std::ptrdiff_t cols, T scale)
 The cols columns of rows elements of the column-major a (lda apart) as the rows of a row-major buffer, each element times scale: aᵀ, row-major.
 
template<typename T >
void product_of_ops (char transa, char transb, T alpha, std::size_t m, std::size_t n, std::size_t k, const T *a, std::size_t lda, const T *b, std::size_t ldb, T *c, std::size_t ldc)
 C += α op(B)ᵀ op(A)ᵀ, row-major C (m × n, ldc apart), the column-major C of BLAS's gemm as its transpose. A column-major matrix is row-major as its transpose, so op(B)ᵀ is B read in place when B is not transposed (unless α scales a copy), and op(A)ᵀ is A read in place when A is not; a transposed one is copied (an overload per scalar, as conj_of).
 
void product_of_ops (char transa, char transb, double alpha, std::size_t m, std::size_t n, std::size_t k, const double *a, std::size_t lda, const double *b, std::size_t ldb, double *c, std::size_t ldc)
 product_of_ops for double: with α = 1 a transposed B is read in place too, as op(B)ᵀ's transpose (numerical::detail::gemm_at, or numerical::detail::gemm_atbt with a transposed A: the bits of the products by the copies; NumPy's a.T @ b).
 
template<typename Index >
void interchanges (const std::vector< std::size_t > &pivots, Index *ipiv)
 The permutation pivots (row i of P A is row pivots[i] of A) as LAPACK's successive row interchanges, 1-based, in ipiv: at step i, row i was interchanged with row ipiv[i].
 
template<typename T , typename Index >
int rectangular_lu (std::size_t m, std::size_t n, T *a, std::size_t lda, Index *ipiv)
 The LU factorisation with partial pivoting of a rectangular column-major A in place, as LAPACK's dgetf2, column by column: NumericAL's blocked LU takes square matrices.
 
constexpr std::size_t strided (std::size_t i, std::size_t length, std::ptrdiff_t inc) noexcept
 Index of element i of a BLAS vector of length elements inc apart: from the last one where inc is negative, as the reference walks it.
 
template<typename T >
T real_dot (std::ptrdiff_t n, const T *x, std::ptrdiff_t incx, const T *y, std::ptrdiff_t incy)
 numerical::blas::dot of the real scalar T.
 
void syrk_product (const syrk_operands &operands, std::size_t c0, std::size_t cols, std::size_t r0, std::size_t rows, double *out, std::size_t ldo)
 P(c0…) Q(…, r0…) added to the cols × rows row-major block at out (ldo apart): numerical::detail::gemm, or, where Q is Pᵀ, numerical::detail::gemm_bt from P's rows (the same bits, no copy of Q).
 
void syrk_triangle (syrk_operands operands, std::size_t j0, std::size_t w)
 Adds P Q to the triangle of the diagonal block [j0, j0 + w) of C: halved until it is a block of syrk_block columns or fewer, formed whole aside; above that, the off-diagonal half is one product of (w / 2)² entries, which the matrix product kernel runs on every core. A block of C (rows r0…, columns c0…), column-major, is row-major Cᵀ: it adds P(c0…) Q(…, r0…).
 
void syrk_all (const syrk_operands &operands, std::size_t n)
 The whole triangle of C (order n) from operands: a product the matrix product kernel packs runs in one pass over the triangle's tiles (numerical::detail::gemm_triangle; each operand read where it lies, as syrk_product reads it), a smaller one by halves (syrk_triangle). Column-major C is row-major Cᵀ = P Q, so its upper triangle is the product's lower one.
 
void triangular_solve (bool lower, bool unit, std::size_t k, std::size_t n, const double *a, std::size_t lda, double *b, std::size_t ldb)
 A X = B in place for the column-major triangular k × k a (lower or upper, a unit diagonal not read) and k × n b: by blocks of trsm_block rows, from the top (lower) or the bottom (upper); a block's diagonal triangle column by column of B, the columns in parallel, then its terms out of the rows still to solve through gemm.
 
template<typename T >
int column_cholesky (bool lower, std::size_t size, T *a, std::size_t ld)
 The Cholesky factor of the column-major order-size A in place, column by column as the reference's dpotf2 computes it (lower: L below the diagonal, else U above it, as conjugates for a complex A): where it holds a NaN or an infinity, which NumericAL's Cholesky refuses, the NaN carried through.
 
void real_form (const matrix< std::complex< double > > &v, const vector< std::complex< double > > &values, const std::vector< std::size_t > &column_of, bool conjugate, double *out, std::size_t ld)
 The eigenvectors v (columns, complex) in dgeev's real form, into the column-major out: column j of a real eigenvalue its vector; of a pair λ_j, λ_{j+1} = conj(λ_j) (positive imaginary part first) the real and imaginary parts of λ_j's vector; conjugated where conjugate (the left vectors).
 

Variables

constexpr std::size_t transpose_tile {32}
 The tile side of the transposing copies between column-major arguments and row-major storage: a tile's rows and columns both stay in the cache, where a whole column read across rows lda apart misses on every element (a 1000 × 1000 copy took several milliseconds).
 
constexpr std::size_t transpose_weight {4}
 The weight of an element of the transposing copies against a multiply-add: bound by the memory, a copy spreads over threads from a few hundred thousand elements (an inverse of order 1000 on six AVX2 cores spent a fifth of its time in its four copies on one thread). The bands capture their bounds by value: by reference, the stores might have changed them, and each was read again (order 100: 5.9 → 10 µs).
 
constexpr std::size_t kept_bytes {std::size_t {32} << 20U}
 The most bytes a thread keeps in each of kept_storage's slots between calls (32 MiB).
 

Function Documentation

◆ column_cholesky()

template<typename T >
int numerical::blas::detail::column_cholesky ( bool  lower,
std::size_t  size,
T *  a,
std::size_t  ld 
)

The Cholesky factor of the column-major order-size A in place, column by column as the reference's dpotf2 computes it (lower: L below the diagonal, else U above it, as conjugates for a complex A): where it holds a NaN or an infinity, which NumericAL's Cholesky refuses, the NaN carried through.

Returns
INFO as dpotf2's: 0, or j where the diagonal's j-th term is not positive (or NaN), left in it.

Definition at line 1158 of file blas.hpp.

◆ column_major_into()

template<typename T >
void numerical::blas::detail::column_major_into ( const T *  from,
std::size_t  rows,
std::size_t  cols,
T *  a,
std::size_t  lda 
)

The row-major rows × cols from into the column-major a (lda apart), by tiles.

Definition at line 205 of file blas.hpp.

◆ column_major_permuted_into()

template<typename T >
void numerical::blas::detail::column_major_permuted_into ( const T *  from,
std::size_t  n,
const std::size_t *  to,
T *  a,
std::size_t  lda 
)

column_major_into for the n × n from, its column j written as column to[j] of a.

Definition at line 225 of file blas.hpp.

◆ columns_as_rows()

template<typename T >
buffer< T > numerical::blas::detail::columns_as_rows ( const T *  a,
std::ptrdiff_t  lda,
std::ptrdiff_t  rows,
std::ptrdiff_t  cols,
T  scale 
)

The cols columns of rows elements of the column-major a (lda apart) as the rows of a row-major buffer, each element times scale: aᵀ, row-major.

Definition at line 316 of file blas.hpp.

◆ conjugates()

constexpr bool numerical::blas::detail::conjugates ( char  op)
constexprnoexcept

Whether op is BLAS's C: the conjugate transpose (a real matrix's is its transpose).

Definition at line 71 of file blas.hpp.

◆ finite() [1/2]

template<typename U >
bool numerical::blas::detail::finite ( const std::complex< U > &  x)

Whether both parts of the complex x are finite.

Definition at line 85 of file blas.hpp.

◆ finite() [2/2]

template<typename T >
bool numerical::blas::detail::finite ( const T &  x)

Whether the real x is finite (an overload per kind of scalar, as conj_of: each one expression).

Definition at line 78 of file blas.hpp.

◆ give_back()

template<typename T >
void numerical::blas::detail::give_back ( std::size_t  slot,
buffer< T > &&  storage 
)

storage given back to kept_storage's slot, unless past kept_bytes.

Definition at line 169 of file blas.hpp.

◆ interchanges()

template<typename Index >
void numerical::blas::detail::interchanges ( const std::vector< std::size_t > &  pivots,
Index *  ipiv 
)

The permutation pivots (row i of P A is row pivots[i] of A) as LAPACK's successive row interchanges, 1-based, in ipiv: at step i, row i was interchanged with row ipiv[i].

Definition at line 398 of file blas.hpp.

◆ is_identity()

template<typename T >
bool numerical::blas::detail::is_identity ( const T *  b,
std::size_t  ldb,
std::size_t  n 
)

Whether the column-major n × n b (ldb apart) is the identity to the bit (a -0 is no zero of it, a solve from it signing zeros of its own): column j against n elements of a unit column of 2n − 1, its one in the middle, from n − 1 − j, a comparison of bytes a column. The first column alone, most other right-hand sides told apart there; the rest by columns on the threads, bound by the memory.

Definition at line 184 of file blas.hpp.

◆ is_operation()

constexpr bool numerical::blas::detail::is_operation ( char  op)
constexprnoexcept

Whether op is one of BLAS's N, T or C (either case): no transpose, transpose, conjugate one.

Definition at line 59 of file blas.hpp.

◆ kept_storage()

template<typename T >
buffer< T > & numerical::blas::detail::kept_storage ( std::size_t  slot)
noexcept

Row-major storage of the scalar T this thread keeps between calls, in slot (0 for a call's A, 1 for its B): a fresh one of megabytes is mapped anew and faulted in page by page on every call (a solve of order 1000 spent 2.5 ms of its 30 on each).

Definition at line 154 of file blas.hpp.

◆ lower_triangle_rows()

template<typename T >
void numerical::blas::detail::lower_triangle_rows ( T *  a,
std::size_t  lda,
std::size_t  n,
T *  rows,
bool  in 
)

The lower triangle of the column-major n × n a (lda apart) into that of the row-major rows (n apart) where in, out of it back into a otherwise, by tiles, bands of them on the threads; the other triangles untouched.

Definition at line 290 of file blas.hpp.

◆ product_by_op_a() [1/2]

void numerical::blas::detail::product_by_op_a ( char  transa,
std::size_t  m,
std::size_t  n,
std::size_t  k,
const double *  l,
std::size_t  ldl,
const double *  a,
std::size_t  lda,
double *  c,
std::size_t  ldc 
)
inline

product_by_op_a for double: a transposed A read in place too, as op(A)ᵀ's transpose (numerical::detail::gemm_bt, the bits of the product by the copy; NumPy's a @ b.T).

Definition at line 268 of file blas.hpp.

◆ product_by_op_a() [2/2]

template<typename T >
void numerical::blas::detail::product_by_op_a ( char  transa,
std::size_t  m,
std::size_t  n,
std::size_t  k,
const T *  l,
std::size_t  ldl,
const T *  a,
std::size_t  lda,
T *  c,
std::size_t  ldc 
)

C += L op(A)ᵀ (C row-major m × n, L m × k), a the column-major op(A)'s storage (lda apart): op(A)ᵀ is A read in place where transa does not transpose, else a copy of its transpose (an overload per scalar, as conj_of).

Definition at line 249 of file blas.hpp.

◆ product_of_ops() [1/2]

void numerical::blas::detail::product_of_ops ( char  transa,
char  transb,
double  alpha,
std::size_t  m,
std::size_t  n,
std::size_t  k,
const double *  a,
std::size_t  lda,
const double *  b,
std::size_t  ldb,
double *  c,
std::size_t  ldc 
)
inline

product_of_ops for double: with α = 1 a transposed B is read in place too, as op(B)ᵀ's transpose (numerical::detail::gemm_at, or numerical::detail::gemm_atbt with a transposed A: the bits of the products by the copies; NumPy's a.T @ b).

Definition at line 368 of file blas.hpp.

◆ product_of_ops() [2/2]

template<typename T >
void numerical::blas::detail::product_of_ops ( char  transa,
char  transb,
T  alpha,
std::size_t  m,
std::size_t  n,
std::size_t  k,
const T *  a,
std::size_t  lda,
const T *  b,
std::size_t  ldb,
T *  c,
std::size_t  ldc 
)

C += α op(B)ᵀ op(A)ᵀ, row-major C (m × n, ldc apart), the column-major C of BLAS's gemm as its transpose. A column-major matrix is row-major as its transpose, so op(B)ᵀ is B read in place when B is not transposed (unless α scales a copy), and op(A)ᵀ is A read in place when A is not; a transposed one is copied (an overload per scalar, as conj_of).

Definition at line 340 of file blas.hpp.

◆ real_dot()

template<typename T >
T numerical::blas::detail::real_dot ( std::ptrdiff_t  n,
const T *  x,
std::ptrdiff_t  incx,
const T *  y,
std::ptrdiff_t  incy 
)

numerical::blas::dot of the real scalar T.

Definition at line 545 of file blas.hpp.

◆ real_form()

void numerical::blas::detail::real_form ( const matrix< std::complex< double > > &  v,
const vector< std::complex< double > > &  values,
const std::vector< std::size_t > &  column_of,
bool  conjugate,
double *  out,
std::size_t  ld 
)
inline

The eigenvectors v (columns, complex) in dgeev's real form, into the column-major out: column j of a real eigenvalue its vector; of a pair λ_j, λ_{j+1} = conj(λ_j) (positive imaginary part first) the real and imaginary parts of λ_j's vector; conjugated where conjugate (the left vectors).

Definition at line 1884 of file blas.hpp.

◆ rectangular_lu()

template<typename T , typename Index >
int numerical::blas::detail::rectangular_lu ( std::size_t  m,
std::size_t  n,
T *  a,
std::size_t  lda,
Index *  ipiv 
)

The LU factorisation with partial pivoting of a rectangular column-major A in place, as LAPACK's dgetf2, column by column: NumericAL's blocked LU takes square matrices.

Returns
INFO as dgetrf's.

Definition at line 422 of file blas.hpp.

◆ row_major()

template<typename T >
buffer< T > numerical::blas::detail::row_major ( const T *  a,
std::ptrdiff_t  lda,
std::ptrdiff_t  rows,
std::ptrdiff_t  cols,
T  scale,
bool  conjugate = false 
)

rows × cols of the column-major a (lda apart), as a row-major buffer, each element times scale (conjugated first where conjugate).

Definition at line 133 of file blas.hpp.

◆ row_major_into()

template<typename T >
void numerical::blas::detail::row_major_into ( buffer< T > &  out,
const T *  a,
std::ptrdiff_t  lda,
std::ptrdiff_t  rows,
std::ptrdiff_t  cols,
T  scale,
bool  conjugate = false 
)

The column-major rows × cols a (lda apart) into the row-major out (resized to it), by tiles, each element times scale (conjugated first where conjugate).

Definition at line 104 of file blas.hpp.

◆ strided()

constexpr std::size_t numerical::blas::detail::strided ( std::size_t  i,
std::size_t  length,
std::ptrdiff_t  inc 
)
constexprnoexcept

Index of element i of a BLAS vector of length elements inc apart: from the last one where inc is negative, as the reference walks it.

Definition at line 536 of file blas.hpp.

◆ syrk_all()

void numerical::blas::detail::syrk_all ( const syrk_operands &  operands,
std::size_t  n 
)
inline

The whole triangle of C (order n) from operands: a product the matrix product kernel packs runs in one pass over the triangle's tiles (numerical::detail::gemm_triangle; each operand read where it lies, as syrk_product reads it), a smaller one by halves (syrk_triangle). Column-major C is row-major Cᵀ = P Q, so its upper triangle is the product's lower one.

Definition at line 797 of file blas.hpp.

◆ syrk_operand()

buffer< double > & numerical::blas::detail::syrk_operand ( )
inlinenoexcept

The storage of syrk's operand copy this thread keeps between calls.

Definition at line 52 of file blas.hpp.

◆ syrk_product()

void numerical::blas::detail::syrk_product ( const syrk_operands &  operands,
std::size_t  c0,
std::size_t  cols,
std::size_t  r0,
std::size_t  rows,
double *  out,
std::size_t  ldo 
)
inline

P(c0…) Q(…, r0…) added to the cols × rows row-major block at out (ldo apart): numerical::detail::gemm, or, where Q is Pᵀ, numerical::detail::gemm_bt from P's rows (the same bits, no copy of Q).

Definition at line 741 of file blas.hpp.

◆ syrk_triangle()

void numerical::blas::detail::syrk_triangle ( syrk_operands  operands,
std::size_t  j0,
std::size_t  w 
)
inline

Adds P Q to the triangle of the diagonal block [j0, j0 + w) of C: halved until it is a block of syrk_block columns or fewer, formed whole aside; above that, the off-diagonal half is one product of (w / 2)² entries, which the matrix product kernel runs on every core. A block of C (rows r0…, columns c0…), column-major, is row-major Cᵀ: it adds P(c0…) Q(…, r0…).

Definition at line 767 of file blas.hpp.

◆ take_kept()

template<typename T >
buffer< T > numerical::blas::detail::take_kept ( std::size_t  slot)

kept_storage's slot, taken over by the caller (left empty there meanwhile).

Definition at line 162 of file blas.hpp.

◆ transposes()

constexpr bool numerical::blas::detail::transposes ( char  op)
constexprnoexcept

Whether op transposes (T or C: a real matrix's conjugate transpose is its transpose).

Definition at line 65 of file blas.hpp.

◆ triangular_solve()

void numerical::blas::detail::triangular_solve ( bool  lower,
bool  unit,
std::size_t  k,
std::size_t  n,
const double *  a,
std::size_t  lda,
double *  b,
std::size_t  ldb 
)
inline

A X = B in place for the column-major triangular k × k a (lower or upper, a unit diagonal not read) and k × n b: by blocks of trsm_block rows, from the top (lower) or the bottom (upper); a block's diagonal triangle column by column of B, the columns in parallel, then its terms out of the rows still to solve through gemm.

Definition at line 923 of file blas.hpp.

Variable Documentation

◆ kept_bytes

constexpr std::size_t numerical::blas::detail::kept_bytes {std::size_t {32} << 20U}
inlineconstexpr

The most bytes a thread keeps in each of kept_storage's slots between calls (32 MiB).

Definition at line 146 of file blas.hpp.

◆ transpose_tile

constexpr std::size_t numerical::blas::detail::transpose_tile {32}
inlineconstexpr

The tile side of the transposing copies between column-major arguments and row-major storage: a tile's rows and columns both stay in the cache, where a whole column read across rows lda apart misses on every element (a 1000 × 1000 copy took several milliseconds).

Definition at line 93 of file blas.hpp.

◆ transpose_weight

constexpr std::size_t numerical::blas::detail::transpose_weight {4}
inlineconstexpr

The weight of an element of the transposing copies against a multiply-add: bound by the memory, a copy spreads over threads from a few hundred thousand elements (an inverse of order 1000 on six AVX2 cores spent a fifth of its time in its four copies on one thread). The bands capture their bounds by value: by reference, the stores might have changed them, and each was read again (order 100: 5.9 → 10 µs).

Definition at line 99 of file blas.hpp.