10 Clang provides a C/C++ language extension that allows users to directly express
11 fixed-size 2-dimensional matrices as language values and perform arithmetic on
14 This feature is currently experimental, and both its design and its
15 implementation are in flux.
23 A matrix type is a scalar type with an underlying *element type*, a constant
24 number of *rows*, and a constant number of *columns*. Matrix types with the same
25 element type, rows, and columns are the same type. A value of a matrix type
26 includes storage for ``rows * columns`` values of the *element type*. The
27 internal layout, overall size and alignment are implementation-defined.
29 The maximum of the product of the number of rows and columns is
30 implementation-defined. If that implementation-defined limit is exceeded, the
31 program is ill-formed.
33 Currently, the element type of a matrix is only permitted to be one of the
36 * an integer type (as in C2x 6.2.5p19), but excluding enumerated types and ``_Bool``
37 * the standard floating types ``float`` or ``double``
38 * a half-precision floating point type, if one is supported on the target
40 Other types may be supported in the future.
45 Matrix types can be declared by adding the ``matrix_type`` attribute to the
46 declaration of a *typedef* (or a C++ alias declaration). The underlying type
47 of the *typedef* must be a valid matrix element type. The
48 attribute takes two arguments, both of which must be integer constant
49 expressions that evaluate to a value greater than zero. The first specifies the
50 number of rows, and the second specifies the number of columns. The underlying
51 type of the *typedef* becomes a matrix type with the given dimensions and an
52 element type of the former underlying type.
54 If a declaration of a *typedef-name* has a ``matrix_type`` attribute, then all
55 declaration of that *typedef-name* shall have a matrix_type attribute with the
56 same element type, number of rows, and number of columns.
61 The standard conversions are extended as follows. Note that these conversions
62 are intentionally not listed as satisfying the constraints for assignment,
63 which is to say, they are only permitted as explicit casts, not as implicit
66 A value of matrix type can be converted to another matrix type if the number of
67 rows and columns are the same and the value's elements can be converted to the
68 element type of the result type. The result is a matrix where each element is
69 the converted corresponding element.
71 A value of any real type (as in C2x 6.2.5p17) can be converted to a matrix type
72 if it can be converted to the element type of the matrix. The result is a
73 matrix where all elements are the converted original value.
75 If the number of rows or columns differ between the original and resulting
76 type, the program is ill-formed.
79 Arithmetic Conversions
80 ----------------------
82 The usual arithmetic conversions are extended as follows.
86 * If both operands are of matrix type, no arithmetic conversion is performed.
87 * If one operand is of matrix type and the other operand is of a real type,
88 convert the real type operand to the matrix type
89 according to the standard conversion rules.
91 Matrix Type Element Access Operator
92 -----------------------------------
94 An expression of the form ``E1 [E2] [E3]``, where ``E1`` has matrix type ``cv
95 M``, is a matrix element access expression. Let ``T`` be the element type
96 of ``M``, and let ``R`` and ``C`` be the number of rows and columns in ``M``
97 respectively. The index expressions shall have integral or unscoped
98 enumeration type and shall not be uses of the comma operator unless
99 parenthesized. The first index expression shall evaluate to a
100 non-negative value less than ``R``, and the second index expression shall
101 evaluate to a non-negative value less than ``C``, or else the expression has
102 undefined behavior. If ``E1`` is a prvalue, the result is a prvalue with type
103 ``T`` and is the value of the element at the given row and column in the matrix.
104 Otherwise, the result is a glvalue with type ``cv T`` and with the same value
105 category as ``E1`` which refers to the element at the given row and column in
108 Programs containing a single subscript expression into a matrix are ill-formed.
110 **Note**: We considered providing an expression of the form
111 ``postfix-expression [expression]`` to access columns of a matrix. We think
112 that such an expression would be problematic once both column and row major
113 matrixes are supported: depending on the memory layout, either accessing columns
114 or rows can be done efficiently, but not both. Instead, we propose to provide
115 builtins to extract rows and columns from a matrix. This makes the operations
118 Matrix Type Binary Operators
119 ----------------------------
121 Given two matrixes, the ``+`` and ``-`` operators perform element-wise addition
122 and subtraction, while the ``*`` operator performs matrix multiplication.
123 ``+``, ``-``, ``*``, and ``/`` can also be used with a matrix and a scalar
124 value, applying the operation to each element of the matrix.
126 Earlier versions of this extension did not support division by a scalar.
127 You can test for the availability of this feature with
128 ``__has_extension(matrix_types_scalar_division)``.
130 For the expression ``M1 BIN_OP M2`` where
132 * ``BIN_OP`` is one of ``+`` or ``-``, one of ``M1`` and ``M2`` is of matrix
133 type, and the other is of matrix type or real type; or
134 * ``BIN_OP`` is ``*``, one of ``M1`` and ``M2`` is of matrix type, and the
135 other is of a real type; or
136 * ``BIN_OP`` is ``/``, ``M1`` is of matrix type, and ``M2`` is of a real type:
138 * The usual arithmetic conversions are applied to ``M1`` and ``M2``. [ Note: if ``M1`` or
139 ``M2`` are of a real type, they are broadcast to matrices here. — end note ]
140 * ``M1`` and ``M2`` shall be of the same matrix type.
141 * The result is equivalent to Res in the following where col is the number of
142 columns and row is the number of rows in the matrix type:
147 for (int C = 0; C < col; ++C)
148 for (int R = 0; R < row; ++R)
149 Res[R][C] = M1[R][C] BIN_OP M2[R][C];
151 Given the expression ``M1 * M2`` where ``M1`` and ``M2`` are of matrix type:
153 * The usual arithmetic conversions are applied to ``M1`` and ``M2``.
154 * The type of ``M1`` shall have the same number of columns as the type of ``M2`` has
155 rows. The element types of ``M1`` and ``M2`` shall be the same type.
156 * The resulting type, ``MTy``, is a matrix type with the common element type,
157 the number of rows of ``M1`` and the number of columns of ``M2``.
158 * The result is equivalent to ``Res`` in the following where ``EltTy`` is the
159 element type of ``MTy``, ``col`` is the number of columns, ``row`` is the
160 number of rows in ``MTy`` and ``inner`` is the number of columns of ``M1``:
165 for (int C = 0; C < col; ++C) {
166 for (int R = 0; R < row; ++R) {
168 for (int K = 0; K < inner; ++K) {
169 Elt += M1[R][K] * M2[K][C];
174 All operations on matrix types match the behavior of the element type with
175 respect to signed overflows.
177 With respect to floating-point contraction, rounding and environment rules,
178 operations on matrix types match the behavior of the elementwise operations
179 in the corresponding expansions provided above.
181 Operations on floating-point matrices have the same rounding and floating-point
182 environment behavior as ordinary floating-point operations in the expression's
183 context. For the purposes of floating-point contraction, all calculations done
184 as part of a matrix operation are considered intermediate operations, and their
185 results need not be rounded to the format of the element type until the final
186 result in the containing expression. This is subject to the normal restrictions
187 on contraction, such as ``#pragma STDC FP_CONTRACT``.
189 For the ``+=``, ``-=`` and ``*=`` operators the semantics match their expanded
192 Matrix Type Builtin Operations
193 ------------------------------
195 Each matrix type supports a collection of builtin expressions that look like
196 function calls but do not form an overload set. Here they are described as
197 function declarations with rules for how to construct the argument list types
198 and return type and the library description elements from
199 [library.description.structure.specifications]/3 in the C++ standard.
203 * *M*, *M1*, *M2*, *M3* - Matrix types
205 * *row*, *col* - Row and column arguments respectively.
208 ``M2 __builtin_matrix_transpose(M1 matrix)``
210 **Remarks**: The return type is a cv-unqualified matrix type that has the same
211 element type as ``M1`` and has the same number of rows as ``M1`` has columns and
212 the same number of columns as ``M1`` has rows.
214 **Returns**: A matrix ``Res`` equivalent to the code below, where ``col`` refers to the
215 number of columns of ``M``, and ``row`` to the number of rows of ``M``.
217 **Effects**: Equivalent to:
222 for (int C = 0; C < col; ++C)
223 for (int R = 0; R < row; ++R)
224 Res[C][R] = matrix[R][C];
227 ``M __builtin_matrix_column_major_load(T *ptr, size_t row, size_t col, size_t columnStride)``
229 **Mandates**: ``row`` and ``col`` shall be integral constants greater than 0.
231 **Preconditions**: ``columnStride`` is greater than or equal to ``row``.
233 **Remarks**: The return type is a cv-unqualified matrix type with an element
234 type of the cv-unqualified version of ``T`` and a number of rows and columns equal
235 to ``row`` and ``col`` respectively. The parameter ``columnStride`` is optional
236 and if omitted ``row`` is used as ``columnStride``.
238 **Returns**: A matrix ``Res`` equivalent to:
243 for (size_t C = 0; C < col; ++C) {
244 for (size_t R = 0; R < row; ++K)
250 ``void __builtin_matrix_column_major_store(M matrix, T *ptr, size_t columnStride)``
252 **Preconditions**: ``columnStride`` is greater than or equal to the number of rows in ``M``.
254 **Remarks**: The type ``T`` is the const-unqualified version of the matrix
255 argument’s element type. The parameter ``columnStride`` is optional and if
256 omitted, the number of rows of ``M`` is used as ``columnStride``.
258 **Effects**: Equivalent to:
262 for (size_t C = 0; C < columns in M; ++C) {
263 for (size_t R = 0; R < rows in M; ++K)
264 ptr[R] = matrix[R][C];
272 TODO: Does it make sense to allow M::element_type, M::rows, and M::columns
273 where M is a matrix type? We don’t support this anywhere else, but it’s
274 convenient. The alternative is using template deduction to extract this
275 information. Also add spelling for C.
277 Future Work: Initialization syntax.
280 Decisions for the Implementation in Clang
281 =========================================
283 This section details decisions taken for the implementation in Clang and is not
284 part of the draft specification.
286 The elements of a value of a matrix type are laid out in column-major order
289 We propose to provide a Clang option to override this behavior and allow
290 contraction of those operations (e.g. *-ffp-contract=matrix*).
292 TODO: Specify how matrix values are passed to functions.