Views

Views map memory the caller owns as tfel::math objects. A contiguous view resolves the internal residency, a strided view the external one, and the stride is read from the view.

A view on a pointer

map on a plain pointer, and on a const pointer for a read-only operand.

\[\begin{split} A = \left(\begin{array}{ccc|c} 4 & 1 & 0 & 2 \\ 1 & 5 & 1 & 0 \\ 0 & 1 & 6 & 1 \\ \hline 2 & 0 & 1 & 7 \end{array}\right), \quad b = \begin{pmatrix} 14 \\ 14 \\ 24 \\ 33 \end{pmatrix}, \quad x = \begin{pmatrix} 1 \\ 2 \\ 3 \\ 4 \end{pmatrix} \end{split}\]
// a view on a plain pointer, a read-only one on a const pointer: internal residency
auto A = tfel::math::map<tfel::math::tmatrix<4, 4, double>>(raw_A);
auto b = tfel::math::map<const tfel::math::tvector<4, double>>(raw_b);

tfel::math::tvector<4, double> x;
tfel::math::fsarray<4, int> piv;

const bool ok = tdls::solve(A, piv, b, x);

A strided view over an SoA batch

map_strided on system 1 of a batch of three systems stored structure-of-arrays: element k of system s sits at index 3 k + s.

\[\begin{split} A^{(1)} = A + I, \quad b^{(1)} = b + x, \quad A = \left(\begin{array}{ccc|c} 4 & 1 & 0 & 2 \\ 1 & 5 & 1 & 0 \\ 0 & 1 & 6 & 1 \\ \hline 2 & 0 & 1 & 7 \end{array}\right), \quad b = \begin{pmatrix} 14 \\ 14 \\ 24 \\ 33 \end{pmatrix}, \quad x = \begin{pmatrix} 1 \\ 2 \\ 3 \\ 4 \end{pmatrix} \end{split}\]
// system 1 of the batch, stride 3: a strided view resolves the external residency
auto A = tfel::math::map_strided<tfel::math::tmatrix<4, 4, double>>(soa_A + 1, 3);
auto y = tfel::math::map_strided<tfel::math::tvector<4, double>>(soa_y + 1, 3);

tfel::math::fsarray<4, int> piv;

const bool ok = tdls::solve_inplace(A, piv, y);

Elements of a views array

map_array maps contiguous objects as an array of views. Each element is a view, accepted on its own.

\[\begin{split} A = \left(\begin{array}{ccc|c} 4 & 1 & 0 & 2 \\ 1 & 5 & 1 & 0 \\ 0 & 1 & 6 & 1 \\ \hline 2 & 0 & 1 & 7 \end{array}\right), \quad B = \begin{pmatrix} 14 & 7 & 8 \\ 14 & 7 & 3 \\ 24 & 8 & 6 \\ 33 & 10 & 5 \end{pmatrix}, \quad X = \begin{pmatrix} 1 & 1 & 2 \\ 2 & 1 & 0 \\ 3 & 1 & 1 \\ 4 & 1 & 0 \end{pmatrix} \end{split}\]
tfel::math::tmatrix<4, 4, double> A{4, 1, 0, 2, 1, 5, 1, 0, 0, 1, 6, 1, 2, 0, 1, 7};
tfel::math::fsarray<4, int> piv;

if (!tdls::factorize(A, piv)) return 1;

// an array of views on three contiguous right-hand sides, each passed on its own
auto views = tfel::math::map_array<tfel::math::tvector<3, tfel::math::tvector<4, double>>>(aos);
for (int s = 0; s < 3; ++s) {
    auto y = views[s];
    tdls::substitute_inplace(A, piv, y);
}

Mixed placements

A strided view for the matrix, plain objects for the pivot and the right-hand side: one residency per argument.

\[\begin{split} A^{(2)} = A + 2\,I, \quad b^{(2)} = b + 2\,x, \quad A = \left(\begin{array}{ccc|c} 4 & 1 & 0 & 2 \\ 1 & 5 & 1 & 0 \\ 0 & 1 & 6 & 1 \\ \hline 2 & 0 & 1 & 7 \end{array}\right), \quad b = \begin{pmatrix} 14 \\ 14 \\ 24 \\ 33 \end{pmatrix}, \quad x = \begin{pmatrix} 1 \\ 2 \\ 3 \\ 4 \end{pmatrix} \end{split}\]
// the matrix stays in the batch, the pivot and the right-hand side are plain objects
auto A = tfel::math::map_strided<tfel::math::tmatrix<4, 4, double>>(soa_A + 2, 3);
tfel::math::tvector<4, double> y{16, 18, 30, 41};
tfel::math::fsarray<4, int> piv;

const bool ok = tdls::solve_inplace(A, piv, y);