<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8">
</head>
<body>
<div style="font-family:sans-serif"><div style="white-space:normal">
<p dir="auto">On 26 Mar 2020, at 18:21, Florian Hahn wrote:</p>
</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><p dir="auto">Thank you very much for your comments John! Responses inline and I’ve also updated<br>
<br>
On Mar 25, 2020, at 20:39, John McCall <rjmccall@apple.com> wrote:</p>
<blockquote style="border-left:2px solid #777; color:#999; margin:0 0 5px; padding-left:5px; border-left-color:#999"><p dir="auto">You should require the element type to be unqualified and then apply qualifiers “outside” of the matrix type. That is, you can have a const float4x4, but not a const_float4x4.</p>
</blockquote><p dir="auto">Agreed, thanks! I’ve added<br>
<br>
"The element type must be unqualified and qualifiers are applied to the matrix type directly.”</p>
</blockquote></div>
<div style="white-space:normal">
<p dir="auto">Sounds good.</p>
</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><blockquote style="border-left:2px solid #777; color:#999; margin:0 0 5px; padding-left:5px; border-left-color:#999"><p dir="auto">Why do you want to guarantee the same alignment as the element type? Isn’t that going to be seriously performance-limiting for most matrix types?<br>
<br>
If your goal is to make it easy to load / store matrices from an existing buffer, I would recommend adding separate operations to do that instead of (I assume) expecting users to simply cast those buffers to a pointer-to-matrix type and dereference. That will also allow you to use non-packed representations for matrices. Furthermore, you can parameterize the operation by the row/column-major-ness of the buffer and then simply use a canonical representation for matrix types.</p>
</blockquote><p dir="auto">The main reason was allowing users to cast between element type/matrix pointers to load/store matrixes from buffers. But I think it would indeed be better to disallow such casts and not limit ourselves to the element type alignment. There already are the builtin_matrix_column_load/builtin_matrix_column_store which can be used instead of going through casts. In the future, similar builtins could be added to load data in row-major layouts.<br>
<br>
I think initially it would be best to go with implementation defined alignment. What do you think? (I’ve reworded the sentence to "A matrix type is a *scalar type* and its alignment is implementation defined.”)</p>
</blockquote></div>
<div style="white-space:normal">
<p dir="auto">Yeah, making the size and alignment implementation-defined is the right spec-ese.</p>
</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><blockquote style="border-left:2px solid #777; color:#999; margin:0 0 5px; padding-left:5px; border-left-color:#999"><p dir="auto">TODO: Allow reinterpret_cast from pointer to element type. Make aliasing work.<br>
<br>
This seems like an anti-goal. Maybe you want a reinterpret_cast between matrix types with the same total storage size, though? Not sure if that’s a good idea.</p>
</blockquote><p dir="auto">Agreed, now that we cannot cast element type pointers to matrix pointer I think we should disallow it here. It should simply be enough to drop the TODO, right?</p>
</blockquote></div>
<div style="white-space:normal">
<p dir="auto">Yeah, that would be fine.</p>
</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><blockquote style="border-left:2px solid #777; color:#999; margin:0 0 5px; padding-left:5px; border-left-color:#999"><p dir="auto">Standard Conversions<br>
<br>
The standard conversions are extended as follows.<br>
<br>
For integral promotions, floating-point promotion, integral conversions, floating-point conversions, and floating-integral conversions: apply the rules to the underlying type of the matrix type. The resulting type is a matrix type with that underlying element type. The resulting value is as follows:<br>
<br>
* If the original value was of matrix type, each element is converted element by element.<br>
* If the original value was not of matrix type, each element takes the value of the original value.<br>
<br>
This isn’t sufficient; you need to describe what happens if the element counts don’t match. I assume this is ill-formed.</p>
</blockquote><p dir="auto">Yes, the dimension should match.<br>
<br>
I’ve added "If the number of rows or columns differ between the original and resulting type, the program is ill-formed. Otherwise the resulting value is as follows:"</p>
</blockquote></div>
<div style="white-space:normal">
<p dir="auto">Sounds good.</p>
</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><blockquote style="border-left:2px solid #777; color:#999; margin:0 0 5px; padding-left:5px; border-left-color:#999"><p dir="auto">Arithmetic Conversions<br>
<br>
The usual arithmetic conversions are extended as follows.<br>
<br>
Insert at the start:<br>
<br>
* If either operand is of matrix type, apply the usual arithmetic conversions using its underlying element type. The resulting type is a matrix type with that underlying element type.<br>
<br>
This seems like a mistake, mostly because of the integer promotions. You really want short_matrix + short_matrix to yield an int_matrix, or -short_matrix to be an int_matrix? I would recommend that you specify this as working without integer promotion, so that the result of an operation two integer operations just has (1) the greater rank and (2) is unsigned if there’s a signedness mismatch and the signed type can’t express the full range of the unsigned type.</p>
</blockquote><p dir="auto">The intention of choosing the rules for the underlying type was consistency with the existing behavior, but maybe it would be beneficial to forbid them. I think with both there might be source for confusion, but it might be simpler to not allow promotion.</p>
</blockquote></div>
<div style="white-space:normal">
<p dir="auto">It’s an interesting question. In a totally different language, I would say that you shouldn’t allow mis-matched binary operations or implicit conversions, but that explicit casts should be able to do arbitrary element-wise conversions. That’s not really consistent with C’s normal behavior, though. It also might be really pedantic around e.g. scalar multiplication by a literal: would you have to write <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">short4x4 * (short) 2</code>? On the other hand, presumably you wouldn’t want <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">float4x4 * 2.0</code> to yield a <code style="background-color:#F7F7F7; border-radius:3px; margin:0; padding:0 0.4em" bgcolor="#F7F7F7">double4x4</code>.</p>
</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><blockquote style="border-left:2px solid #777; color:#999; margin:0 0 5px; padding-left:5px; border-left-color:#999"><p dir="auto">You also need to specify what happens if you pass a matrix as a variadic argument.<br>
</p>
</blockquote><p dir="auto">Initially they would be passed similar to ext_vector values, but we should spell the rules out correctly here. I’ll add a TODO.</p>
</blockquote></div>
<div style="white-space:normal">
<p dir="auto">Yeah, this is definitely a long-term question.</p>
</div>
<div style="white-space:normal"><blockquote style="border-left:2px solid #777; color:#777; margin:0 0 5px; padding-left:5px"><blockquote style="border-left:2px solid #777; color:#999; margin:0 0 5px; padding-left:5px; border-left-color:#999"><p dir="auto">Matrix Type Element Access Operator<br>
<br>
An expression of the form `postfix-expression [expression][expression]` where the postfix-expression is of matrix type is a matrix element access expression. expression shall not be a comma expression, and shall be a prvalue of unscoped enumeration or integral type. Given the expression E1[E2][E3], the result is an lvalue of the same type as the underlying element type of the matrix that refers to the value at E2 row and E3 column in the matrix. The expression E1 is sequenced before E2 and E3. The expressions E2 and E3 are unsequenced.<br>
<br>
Note: We thought about providing an expression of the form `postfix-expression [expression]` to access columns of a matrix. We think that such an expression would be problematic once both column and row major matrixes are supported: depending on the memory layout, either accessing columns or rows can be done efficiently, but not both. Instead, we propose to provide builtins to extract rows and columns from a matrix. This makes the operations more explicit.<br>
<br>
Okay, so what happens if you do write matrix[0]?<br>
</p>
</blockquote><p dir="auto">That is not supported. We should probably state explicitly that single index operators on matrix values are ill-defined or something like that?</p>
</blockquote></div>
<div style="white-space:normal">
<p dir="auto">Yeah, you can say that incomplete subscripts can only be used as the base operand of another subscript. There’s a similar rule with member-function accesses in C++, which can only be the function operand of a call. You can enforce that rule reliably in Clang with a placeholder type.</p>
<p dir="auto">John.</p>
</div>
</div>
</body>
</html>