Document #: | P2812 |
Date: | 2023/02/10 |
Project: | Programming Language C++ LEWG |
Reply-to: |
Mark Hoemmen <mhoemmen@nvidia.com> Christian Trott <crtrott@sandia.gov> Damien Lebrun-Grandie <lebrungrandt@ornl.gov> Nevin Liber <nliber@anl.gov> |
This paper is nonnormative. It is the presentation that P1673R11 coauthors gave to LEWG at the Issaquah WG21 meeting on 2023/02/10.
mdspan
(C++23) as multidimensional array view
…ExecutionPolicy&&
)using vector_t = mdspan<double, dextents<int, 1>>;
using matrix_t = mdspan<double, dextents<int, 2>>;
// ... allocate and fill ...
= /* ... */;
vector_t x = /* ... */;
vector_t y = /* ... */;
matrix_t A
// compute y = Ax
(y, A, x);
matrix_vector_multiply
// compute norm2 of y
double val = vector_norm2(y);
// mixed precision, different layout
<float, dextents<int, 2>, layout_left> A_f =
mdspan/* allocate and fill */;
(y, A_f, x);
matrix_vector_multiplydouble val2 = vector_norm2(y);
Implements LEWG’s Kona 2022/11/10 request to
explore expressing constraints with concepts instead of named type requirements.
template<class in_vector_t,
class in_matrix_t,
class out_vector_t>
void matrix_vector_product(in_matrix_t A,
in_vector_t x,); out_vector_t y
C++98-style named-based requirements on template parameters
Imitating [algorithms.requirements] 4: “Throughout this Clause, where the template parameters are not constrained, the names of template parameters are used to express type requirements.”
Defined in [linalg.algs.reqs] in P1673R10
“in_vector*_t
is a rank-1 mdspan
with a
potentially const
element type and a unique layout. If the
algorithm accesses the object, it will do so in read-only
fashion.”
“out_vector*_t
is a rank-1 mdspan
with
a non-const element type, and whose layout is always unique
(layout_type::is_always_unique()
equals true
).
If the algorithm accesses the object, it will do so in write-only
fashion.”
For multiple parameters: in_matrix_1_t
,
in_matrix_2_t
, etc.
template<in-matrix InMat,
in-vector InVec,>
out-vector OutVecvoid matrix_vector_product(InMat A,
InVec x,); OutVec y
template<class T>
struct is-mdspan : false_type {}; // exposition only
template<class ElementType, class Extents, class Layout, class Accessor>
struct is-mdspan<mdspan<ElementType, Extents, Layout, Accessor>> // exposition only
: true_type {};
template<class T>
concept in-vector = // exposition only
<T>::value &&
is-mdspan::rank() == 1;
T
template<class T>
concept out-vector = // exposition only
<T>::value &&
is-mdspan::rank() == 1 &&
T<remove_const_t<typename T::element_type>, typename T::element_type> &&
is_same_v::is_always_unique();
T
// ...
template<class T>
concept in-matrix = // exposition only
<T>::value &&
is-mdspan::rank() == 2; T
Entirely syntactic, except for:
2 If an algorithm in [linalg.algs] accesses the elements of an
in-vector
,in-matrix
, orin-object
, it will do so in read-only fashion.
Follows LEWG guidance to simplify Effects and Constraints.
This is our interpretation of the “hand wavy do math” poll option that received a majority of votes at Kona on 2022/11/10.
float16_t
), bigfloatsP1673 (or anything like it) generalizes
std::reduce
GENERALIZED_SUM
[numerics.defns]Constraining value types with concepts is not a good fit
Before | After |
---|---|
For i in the domain of y and N
equal to A.extent(1) , the mathematical expression for the
algorithm is y[i] = the sum of A[i,j] * x[j]
for all j such that i,j is in the domain of
A .
|
Effects: Computes y such that y = Ax. |
P1673R10 defined “Mathematical expression for the algorithm” as:
Each algorithm or method using the type has one or more associated mathematical expressions that defines the algorithm’s or method’s behavior. For each algorithm or method, its mathematical expression(s) are either explicitly stated as such, or are implicitly stated in the algorithm’s or method’s description. The requirements below will refer to those mathematical expression(s).
P1673R11’s Effects reference the mathematical definition of matrix-vector multiplication. Compare to wording for the mathematical special functions [sf.cmath], which uses math-font integrals, derivatives, and infinite sums. [linalg.reqs.val] is much shorter.
__cpp_lib_linalg