Skip to content

Commit adffd31

Browse files
Implement HLSL Diagnostics for LinAlg operations (#7430)
This PR implements checks to validate the linalg builtin functions: __builtin_MatVecMul, __builtin_MatVecMulAdd, __builtin_OuterProductAccumulate and __builtin_VectorAccumulate. This includes: - verify valid types for input and output vectors - const checks for compile-time const parameters - value checks for interpretation and layout (enum) parameters - min/max checks for matrix dimensions - verify input-output vector are the right dimensions for the given matrix (dimM and dimK) : packed and unpacked cases - verify matrix layout, transpose and stride rules - incorrect shader model warning Adds tests for all the above error checks. Implements #7336
1 parent f9c2d5d commit adffd31

21 files changed

+4271
-126
lines changed

include/dxc/dxcapi.internal.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,15 @@ enum LEGAL_INTRINSIC_COMPTYPES {
133133
LICOMPTYPE_HIT_OBJECT = 51,
134134
LICOMPTYPE_RAY_QUERY = 52,
135135

136+
LICOMPTYPE_LINALG = 53, // f32, partial-precision-f32, f16,
137+
// i32, i16, u32, u16,
138+
// int8_4packed, uint8_4packed
139+
136140
#ifdef ENABLE_SPIRV_CODEGEN
137-
LICOMPTYPE_VK_BUFFER_POINTER = 53,
138-
LICOMPTYPE_COUNT = 54
141+
LICOMPTYPE_VK_BUFFER_POINTER = 54,
142+
LICOMPTYPE_COUNT = 55
139143
#else
140-
LICOMPTYPE_COUNT = 53
144+
LICOMPTYPE_COUNT = 54
141145
#endif
142146
};
143147

tools/clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8018,6 +8018,43 @@ def err_hlsl_reorder_unsupported_stage : Error<
80188018
"dx::MaybeReorderThread is unavailable in shader stage '%0' (requires 'raygeneration')">;
80198019
def err_hlsl_hitobject_unsupported_stage : Error<
80208020
"dx::HitObject is unavailable in shader stage '%0' (requires 'raygeneration', 'closesthit' or 'miss')">;
8021+
8022+
// Linear Algebra Operations
8023+
def err_hlsl_linalg_isunsigned_incorrect_for_given_type : Error<
8024+
"%0 must be %select{false|true}1 for vector of "
8025+
"%select{floating point|signed integer|unsigned integer}2 type">;
8026+
def err_hlsl_linalg_interpretation_value_incorrect : Error<
8027+
"%0 is an invalid %select{memory|register}1 interpretation value">;
8028+
def err_hlsl_linalg_matrix_layout_is_not_transposable : Error<
8029+
"RowMajor and ColumnMajor matrices are not transposable">;
8030+
def err_hlsl_linalg_optimal_matrix_layout_matrix_stride_must_be_zero : Error<
8031+
"for optimal matrix layout, matrix stride must be 0">;
8032+
def err_hlsl_linalg_matrix_dim_must_be_greater_than_zero: Error<
8033+
"matrix dimension must be greater than 0">;
8034+
def err_hlsl_linalg_matrix_layout_invalid : Error<
8035+
"matrix layout %0 is not valid, must be in the range [%1, %2]">;
8036+
8037+
def err_hlsl_linalg_mul_muladd_output_vector_size_not_equal_to_matrix_M : Error<
8038+
"output vector length must be equal to Matrix M dimension in a linalg Mul/MulAdd operation">;
8039+
def err_hlsl_linalg_mul_muladd_unpacked_input_vector_size_not_equal_to_matrix_K : Error<
8040+
"unpacked input vector length must be equal to Matrix K dimension in a linalg Mul/MulAdd operation">;
8041+
def err_hlsl_linalg_mul_muladd_packed_input_vector_size_incorrect : Error<
8042+
"packed input vector length must be the smallest number that can hold matrix dim K values of the "
8043+
"packed(smaller) type in linalg mul/muladd operations">;
8044+
def err_hlsl_linalg_mul_muladd_isUnsigned_for_packed_input_must_be_true : Error<
8045+
"IsInputUnsigned must be true for packed input interpretations in linalg mul/muladd operations">;
8046+
def err_hlsl_linalg_mul_muladd_packed_input_vector_must_be_uint : Error<
8047+
"packed input vector type must be a 32-bit unsigned int type in linalg mul/muladd operations">;
8048+
def err_hlsl_linalg_mul_muladd_invalid_dim: Error<
8049+
"matrix dimension %select{M|K when using unpacked input vectors|K "
8050+
"when using packed input vectors}0 must be less than %1, in a linalg "
8051+
"Mul/MulAdd operation">;
8052+
8053+
def err_hlsl_linalg_outer_prod_acc_vector_type_mismatch : Error<
8054+
"input vectors of outerproductaccumulate must have the same element type">;
8055+
def err_hlsl_linalg_outer_prod_acc_matrix_layout_must_be_outer_prod_acc_optimal : Error<
8056+
"matrix layout for outerproductaccumulate must be %0">;
8057+
80218058
// HLSL Change Ends
80228059

80238060
// SPIRV Change Starts

tools/clang/lib/Headers/hlsl/dx/linalg.h

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,30 @@ enum MatrixLayout {
4343
// Helper for signedness
4444
//
4545
namespace details {
46-
template <typename T> bool IsUnsigned() { return false; }
46+
47+
template <typename T> struct IsUnsigned {};
48+
49+
#define _SPECIALIZE_ISUNSIGNED(type, value) \
50+
template <> struct IsUnsigned<type> { \
51+
static const bool Value = value; \
52+
}
53+
54+
_SPECIALIZE_ISUNSIGNED(uint8_t4_packed, true);
55+
_SPECIALIZE_ISUNSIGNED(int8_t4_packed, true);
56+
_SPECIALIZE_ISUNSIGNED(uint32_t, true);
57+
_SPECIALIZE_ISUNSIGNED(int32_t, false);
58+
_SPECIALIZE_ISUNSIGNED(float32_t, false);
4759

4860
#ifdef __HLSL_ENABLE_16_BIT
49-
template <> bool IsUnsigned<uint16_t>() { return true; }
50-
#endif
61+
_SPECIALIZE_ISUNSIGNED(uint16_t, true);
62+
_SPECIALIZE_ISUNSIGNED(int16_t, false);
63+
_SPECIALIZE_ISUNSIGNED(float16_t, false);
64+
#else // //__HLSL_ENABLE_16_BIT
65+
_SPECIALIZE_ISUNSIGNED(half, false);
66+
#endif //__HLSL_ENABLE_16_BIT
67+
68+
#undef _SPECIALIZE_ISUNSIGNED
5169

52-
template <> bool IsUnsigned<uint32_t>() { return true; }
53-
template <> bool IsUnsigned<uint64_t>() { return true; }
5470
} // namespace details
5571

5672
//
@@ -116,10 +132,10 @@ Mul(MatrixRefImpl<MatrixBufferTy, MatrixDT, MatrixM, MatrixK, MatrixLayout,
116132
vector<OutputElTy, MatrixM> OutputVector;
117133

118134
__builtin_MatVecMul(
119-
/*out*/ OutputVector, details::IsUnsigned<OutputElTy>(), InputVector.Data,
120-
details::IsUnsigned<InputElTy>(), InputDT, Matrix.Buffer,
121-
Matrix.StartOffset, MatrixDT, MatrixM, MatrixK, MatrixLayout,
122-
MatrixTranspose, Matrix.Stride);
135+
/*out*/ OutputVector, details::IsUnsigned<OutputElTy>::Value,
136+
InputVector.Data, details::IsUnsigned<InputElTy>::Value, InputDT,
137+
Matrix.Buffer, Matrix.StartOffset, MatrixDT, MatrixM, MatrixK,
138+
MatrixLayout, MatrixTranspose, Matrix.Stride);
123139

124140
return OutputVector;
125141
}
@@ -143,11 +159,11 @@ MulAdd(MatrixRefImpl<MatrixBufferTy, MatrixDT, MatrixM, MatrixK, MatrixLayout,
143159
vector<OutputElTy, MatrixM> OutputVector;
144160

145161
__builtin_MatVecMulAdd(
146-
/*out*/ OutputVector, details::IsUnsigned<OutputElTy>(), InputVector.Data,
147-
details::IsUnsigned<InputElTy>(), InputDT, Matrix.Buffer,
148-
Matrix.StartOffset, MatrixDT, MatrixM, MatrixK, MatrixLayout,
149-
MatrixTranspose, Matrix.Stride, BiasVector.Buffer, BiasVector.StartOffset,
150-
BiasVectorDT);
162+
/*out*/ OutputVector, details::IsUnsigned<OutputElTy>::Value,
163+
InputVector.Data, details::IsUnsigned<InputElTy>::Value, InputDT,
164+
Matrix.Buffer, Matrix.StartOffset, MatrixDT, MatrixM, MatrixK,
165+
MatrixLayout, MatrixTranspose, Matrix.Stride, BiasVector.Buffer,
166+
BiasVector.StartOffset, BiasVectorDT);
151167

152168
return OutputVector;
153169
}

0 commit comments

Comments
 (0)