35template <
class ScalarType>
37 if (block_i == block_j)
return &ilu.d[block_i * nVar * nVar];
38 const auto* __restrict row_ptr = block_j < block_i ? ilu.row_ptr_l : ilu.row_ptr_u;
39 const auto* __restrict col_ind = block_j < block_i ? ilu.col_ind_l : ilu.col_ind_u;
40 auto* __restrict vals = block_j < block_i ? ilu.l : ilu.u;
41 for (
auto k = row_ptr[block_i]; k < row_ptr[block_i + 1]; ++k) {
42 if (col_ind[k] == block_j)
return vals + k * nVar * nVar;
49template <
class T,
bool alpha,
bool beta,
bool transp>
50FORCEINLINE void gemv_impl(
unsigned long n,
unsigned long m,
const T* a,
const T* b, T* c) {
57 for (
auto i = 0ul; i < n; i++) {
58 if (!beta) c[i] = 0.0;
59 for (
auto j = 0ul; j < m; j++) c[i] += (alpha ? 1 : -1) * a[i * m + j] * b[j];
63 for (
auto j = 0ul; j < m; j++) c[j] = 0.0;
64 for (
auto i = 0ul; i < n; i++)
65 for (
auto j = 0ul; j < m; j++) c[j] += (alpha ? 1 : -1) * a[i * n + j] * b[i];
70FORCEINLINE void gemm_impl(
unsigned long n,
const T* a,
const T* b, T* c) {
72 unsigned long i, j, k;
73 for (i = 0; i < n; i++) {
74 for (j = 0; j < n; j++) {
76 for (k = 0; k < n; k++) c[i * n + j] += a[i * n + k] * b[k * n + j];
82#define __MATVECPROD_SIGNATURE__(TYPE, NAME) \
83 FORCEINLINE void CSysMatrix<TYPE>::NAME(const TYPE* matrix, const TYPE* vector, TYPE* product) const
85#define MATVECPROD_SIGNATURE(NAME) \
86 template <class ScalarType> \
87 __MATVECPROD_SIGNATURE__(ScalarType, NAME)
95 gemv_impl<ScalarType, true, false, false>(nVar, nEqn, matrix, vector, product);
99 gemv_impl<ScalarType, true, true, false>(nVar, nEqn, matrix, vector, product);
103 gemv_impl<ScalarType, false, true, false>(nVar, nEqn, matrix, vector, product);
106template <
class ScalarType>
108 ScalarType* product)
const {
109 gemm_impl<ScalarType>(nVar, matrix_a, matrix_b, product);
114 MatrixVectorProductKernelBetaZero(MatrixVectorProductJitterBetaZero,
const_cast<ScalarType*
>(vector),
115 const_cast<ScalarType*
>(matrix), product);
119 MatrixVectorProductKernelBetaOne(MatrixVectorProductJitterBetaOne,
const_cast<ScalarType*
>(vector),
120 const_cast<ScalarType*
>(matrix), product);
124 MatrixVectorProductKernelAlphaMinusOne(MatrixVectorProductJitterAlphaMinusOne,
const_cast<ScalarType*
>(vector),
125 const_cast<ScalarType*
>(matrix), product);
128template <
class ScalarType>
130 ScalarType* product)
const {
131 MatrixMatrixProductKernel(MatrixMatrixProductJitter,
const_cast<ScalarType*
>(matrix_a),
132 const_cast<ScalarType*
>(matrix_b), product);
136#undef MATVECPROD_SIGNATURE
137#undef __MATVECPROD_SIGNATURE__
139template <
class ScalarType>
142 ScalarType block[MAXNVAR * MAXNVAR];
143 MatrixCopy(&mat.d[block_i * nVar * nVar], block);
144 GaussElimination(block, rhs);
147template <
class ScalarType>
149 ScalarType block[MAXNVAR * MAXNVAR];
150 const QuantScaleType* __restrict qs = &q_scale.d[block_i * nVar];
151 const QuantType* __restrict qv = &q_blocks.d[block_i * nVar * nVar];
152 for (
auto r = 0ul; r < nVar; ++r) {
154 for (
auto c = 0ul; c < nVar; ++c) block[r * nVar + c] = static_cast<ScalarType>(qv[r * nVar + c] * row_scale);
156 GaussElimination(block, rhs);
159template <
class ScalarType>
162 ScalarType block[MAXNVAR * MAXNVAR];
163 MatrixCopy(&mat.d[block_i * nVar * nVar], block);
168template <
class ScalarType>
171 auto* Uii = &ilu.d[block_i * nVar * nVar];
172 ScalarType block[MAXNVAR * MAXNVAR];
173 MatrixCopy(Uii, block);
178template <
class ScalarType>
180 const QuantType* __restrict qv,
181 const ScalarType* __restrict vec,
182 ScalarType* __restrict prod)
const {
183 for (
auto r = 0ul; r < nVar; ++r) {
185 auto sum = ScalarType(0);
186 for (
auto c = 0ul; c < nVar; ++c) sum += qv[r * nVar + c] * vec[c];
187 prod[r] += row_scale * sum;
191template <
class ScalarType>
193 ScalarType* prod)
const {
194 for (
auto iVar = 0ul; iVar < nVar; iVar++) prod[iVar] = 0.0;
196 for (
auto k = mat.row_ptr_l[row_i]; k < mat.row_ptr_l[row_i + 1]; k++) {
197 MatrixVectorProductAdd(&mat.l[k * nVar * nEqn], &vec[mat.col_ind_l[k] * nEqn], prod);
199 MatrixVectorProductAdd(&mat.d[row_i * nVar * nEqn], &vec[row_i * nEqn], prod);
201 for (
auto k = mat.row_ptr_u[row_i]; k < mat.row_ptr_u[row_i + 1]; k++) {
202 MatrixVectorProductAdd(&mat.u[k * nVar * nEqn], &vec[mat.col_ind_u[k] * nEqn], prod);
206template <
class ScalarType>
208 unsigned long col_ub, ScalarType* prod)
const {
209 for (
auto iVar = 0ul; iVar < nVar; iVar++) prod[iVar] = 0.0;
211 for (
auto index = mat.row_ptr_u[row_i]; index < mat.row_ptr_u[row_i + 1]; index++) {
212 auto col_j = mat.col_ind_u[index];
214 if (col_j < col_ub || col_j >= nPointDomain) {
215 MatrixVectorProductAdd(&mat.u[index * nVar * nEqn], &vec[col_j * nEqn], prod);
220template <
class ScalarType>
222 unsigned long col_lb, ScalarType* prod)
const {
223 for (
auto iVar = 0ul; iVar < nVar; iVar++) prod[iVar] = 0.0;
225 for (
auto index = mat.row_ptr_l[row_i]; index < mat.row_ptr_l[row_i + 1]; index++) {
226 auto col_j = mat.col_ind_l[index];
227 if (col_j >= col_lb) {
228 MatrixVectorProductAdd(&mat.l[index * nVar * nEqn], &vec[col_j * nEqn], prod);
233template <
class ScalarType>
235 ScalarType* prod)
const {
236 MatrixVectorProduct(&mat.d[row_i * nVar * nEqn], &vec[row_i * nEqn], prod);
239template <
class ScalarType>
241 ScalarType* prod)
const {
242 for (
auto iVar = 0ul; iVar < nVar; iVar++) prod[iVar] = 0.0;
244 for (
auto k = mat.row_ptr_l[row_i]; k < mat.row_ptr_l[row_i + 1]; k++) {
245 QuantizedMatVecAdd(&q_scale.l[k * nVar], &q_blocks.l[k * nVar * nEqn], &vec[mat.col_ind_l[k] * nEqn], prod);
247 QuantizedMatVecAdd(&q_scale.d[row_i * nVar], &q_blocks.d[row_i * nVar * nEqn], &vec[row_i * nEqn], prod);
249 for (
auto k = mat.row_ptr_u[row_i]; k < mat.row_ptr_u[row_i + 1]; k++) {
250 QuantizedMatVecAdd(&q_scale.u[k * nVar], &q_blocks.u[k * nVar * nEqn], &vec[mat.col_ind_u[k] * nEqn], prod);
254template <
class ScalarType>
256 unsigned long col_ub, ScalarType* prod)
const {
257 for (
auto iVar = 0ul; iVar < nVar; iVar++) prod[iVar] = 0.0;
259 for (
auto index = mat.row_ptr_u[row_i]; index < mat.row_ptr_u[row_i + 1]; index++) {
260 auto col_j = mat.col_ind_u[index];
261 if (col_j < col_ub || col_j >= nPointDomain) {
262 QuantizedMatVecAdd(&q_scale.u[index * nVar], &q_blocks.u[index * nVar * nEqn], &vec[col_j * nEqn], prod);
267template <
class ScalarType>
269 unsigned long col_lb, ScalarType* prod)
const {
270 for (
auto iVar = 0ul; iVar < nVar; iVar++) prod[iVar] = 0.0;
272 for (
auto index = mat.row_ptr_l[row_i]; index < mat.row_ptr_l[row_i + 1]; index++) {
273 auto col_j = mat.col_ind_l[index];
274 if (col_j >= col_lb) {
275 QuantizedMatVecAdd(&q_scale.l[index * nVar], &q_blocks.l[index * nVar * nEqn], &vec[col_j * nEqn], prod);
280template <
class ScalarType>
282 unsigned long row_i, ScalarType* prod)
const {
283 for (
auto iVar = 0ul; iVar < nVar; iVar++) prod[iVar] = 0.0;
284 QuantizedMatVecAdd(&q_scale.d[row_i * nVar], &q_blocks.d[row_i * nVar * nEqn], &vec[row_i * nEqn], prod);
Declaration of the block-sparse matrix class. The implemtation is in CSysMatrix.cpp.
float DecodeQuantScale(uint8_t e) noexcept
Reconstruct the float row-scale from a stored uint8 binary exponent. e is stored already biased,...
Definition CSysMatrix.hpp:121
#define MATVECPROD_SIGNATURE(NAME)
Definition CSysMatrix.inl:85
Main class for defining block-compressed-row-storage sparse matrices.
Definition CSysMatrix.hpp:256
Class for holding and manipulating vectors needed by linear solvers.
Definition CSysVector.hpp:195
#define FORCEINLINE
Definition code_config.hpp:44
void MatrixInverse(unsigned long nVar, ScalarType *matrix, ScalarType *inverse)
Invert the nVar by nVar dense matrix matrix into inverse via Gauss-Jordan elimination with partial pi...
Definition CMatrixInverse.hpp:57