Skip to content

Commit 9618a81

Browse files
authored
Implement basic AsType tests for long vectors. (#7668)
This PR adds test cases for most of the 'AsType' HLSL intrinsics. It introduces changes to facilitate testing an HLSL intrinsic with an output type that does not match the input type. This functionality required some changes to the TestConfig object as well as the addition of a 'VariantVector' alias to store the expected output. Verified locally by running new and all existing long vector exec test cases against WARP. Resolves #7473
1 parent c8b18bc commit 9618a81

File tree

5 files changed

+550
-143
lines changed

5 files changed

+550
-143
lines changed

tools/clang/unittests/HLSLExec/LongVectorOpTable.xml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,11 +555,35 @@
555555
<Parameter Name="OpTypeEnum">UnaryOpType_Initialize</Parameter>
556556
<Parameter Name="DataType">int16</Parameter>
557557
</Row>
558+
<Row Name="AsFloat16_int16">
559+
<Parameter Name="OpTypeEnum">UnaryOpType_AsFloat16</Parameter>
560+
<Parameter Name="DataType">int16</Parameter>
561+
</Row>
562+
<Row Name="AsInt16_int16">
563+
<Parameter Name="OpTypeEnum">UnaryOpType_AsInt16</Parameter>
564+
<Parameter Name="DataType">int16</Parameter>
565+
</Row>
566+
<Row Name="AsUint16_int16">
567+
<Parameter Name="OpTypeEnum">UnaryOpType_AsUint16</Parameter>
568+
<Parameter Name="DataType">int16</Parameter>
569+
</Row>
558570
<!-- LongVectorUnaryOpTypeTable DataType: int32 -->
559571
<Row Name="Initialize_int32">
560572
<Parameter Name="OpTypeEnum">UnaryOpType_Initialize</Parameter>
561573
<Parameter Name="DataType">int32</Parameter>
562574
</Row>
575+
<Row Name="AsFloat_int32">
576+
<Parameter Name="OpTypeEnum">UnaryOpType_AsFloat</Parameter>
577+
<Parameter Name="DataType">int32</Parameter>
578+
</Row>
579+
<Row Name="AsInt_int32">
580+
<Parameter Name="OpTypeEnum">UnaryOpType_AsInt</Parameter>
581+
<Parameter Name="DataType">int32</Parameter>
582+
</Row>
583+
<Row Name="AsUint_int32">
584+
<Parameter Name="OpTypeEnum">UnaryOpType_AsUint</Parameter>
585+
<Parameter Name="DataType">int32</Parameter>
586+
</Row>
563587
<!-- LongVectorUnaryOpTypeTable DataType: int64 -->
564588
<Row Name="Initialize_int64">
565589
<Parameter Name="OpTypeEnum">UnaryOpType_Initialize</Parameter>
@@ -570,11 +594,35 @@
570594
<Parameter Name="OpTypeEnum">UnaryOpType_Initialize</Parameter>
571595
<Parameter Name="DataType">uint16</Parameter>
572596
</Row>
597+
<Row Name="AsFloat16_uint16">
598+
<Parameter Name="OpTypeEnum">UnaryOpType_AsFloat16</Parameter>
599+
<Parameter Name="DataType">uint16</Parameter>
600+
</Row>
601+
<Row Name="AsInt16_uint16">
602+
<Parameter Name="OpTypeEnum">UnaryOpType_AsInt16</Parameter>
603+
<Parameter Name="DataType">uint16</Parameter>
604+
</Row>
605+
<Row Name="AsUint16_uint16">
606+
<Parameter Name="OpTypeEnum">UnaryOpType_AsUint16</Parameter>
607+
<Parameter Name="DataType">uint16</Parameter>
608+
</Row>
573609
<!-- LongVectorUnaryOpTypeTable DataType: uint32 -->
574610
<Row Name="Initialize_uint32">
575611
<Parameter Name="OpTypeEnum">UnaryOpType_Initialize</Parameter>
576612
<Parameter Name="DataType">uint32</Parameter>
577613
</Row>
614+
<Row Name="AsFloat_uint32">
615+
<Parameter Name="OpTypeEnum">UnaryOpType_AsFloat</Parameter>
616+
<Parameter Name="DataType">uint32</Parameter>
617+
</Row>
618+
<Row Name="AsInt_uint32">
619+
<Parameter Name="OpTypeEnum">UnaryOpType_AsInt</Parameter>
620+
<Parameter Name="DataType">uint32</Parameter>
621+
</Row>
622+
<Row Name="AsUint_uint32">
623+
<Parameter Name="OpTypeEnum">UnaryOpType_AsUint</Parameter>
624+
<Parameter Name="DataType">uint32</Parameter>
625+
</Row>
578626
<!-- LongVectorUnaryOpTypeTable DataType: uint64 -->
579627
<Row Name="Initialize_uint64">
580628
<Parameter Name="OpTypeEnum">UnaryOpType_Initialize</Parameter>
@@ -585,6 +633,18 @@
585633
<Parameter Name="OpTypeEnum">UnaryOpType_Initialize</Parameter>
586634
<Parameter Name="DataType">float16</Parameter>
587635
</Row>
636+
<Row Name="AsFloat16_float16">
637+
<Parameter Name="OpTypeEnum">UnaryOpType_AsFloat16</Parameter>
638+
<Parameter Name="DataType">float16</Parameter>
639+
</Row>
640+
<Row Name="AsInt16_float16">
641+
<Parameter Name="OpTypeEnum">UnaryOpType_AsInt16</Parameter>
642+
<Parameter Name="DataType">float16</Parameter>
643+
</Row>
644+
<Row Name="AsUint16_float16">
645+
<Parameter Name="OpTypeEnum">UnaryOpType_AsUint16</Parameter>
646+
<Parameter Name="DataType">float16</Parameter>
647+
</Row>
588648
<!-- LongVectorUnaryOpTypeTable DataType: float32 -->
589649
<Row Name="Initialize_float32">
590650
<Parameter Name="OpTypeEnum">UnaryOpType_Initialize</Parameter>

tools/clang/unittests/HLSLExec/LongVectors.cpp

Lines changed: 44 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -132,32 +132,32 @@ void LongVector::OpTest::dispatchTestByDataType(
132132
using namespace WEX::Common;
133133

134134
if (DataType == L"bool")
135-
dispatchTestByVectorSize<HLSLBool_t>(OpType, Handler);
135+
dispatchTestByVectorLength<HLSLBool_t>(OpType, Handler);
136136
else if (DataType == L"int16")
137-
dispatchTestByVectorSize<int16_t>(OpType, Handler);
137+
dispatchTestByVectorLength<int16_t>(OpType, Handler);
138138
else if (DataType == L"int32")
139-
dispatchTestByVectorSize<int32_t>(OpType, Handler);
139+
dispatchTestByVectorLength<int32_t>(OpType, Handler);
140140
else if (DataType == L"int64")
141-
dispatchTestByVectorSize<int64_t>(OpType, Handler);
141+
dispatchTestByVectorLength<int64_t>(OpType, Handler);
142142
else if (DataType == L"uint16")
143-
dispatchTestByVectorSize<uint16_t>(OpType, Handler);
143+
dispatchTestByVectorLength<uint16_t>(OpType, Handler);
144144
else if (DataType == L"uint32")
145-
dispatchTestByVectorSize<uint32_t>(OpType, Handler);
145+
dispatchTestByVectorLength<uint32_t>(OpType, Handler);
146146
else if (DataType == L"uint64")
147-
dispatchTestByVectorSize<uint64_t>(OpType, Handler);
147+
dispatchTestByVectorLength<uint64_t>(OpType, Handler);
148148
else if (DataType == L"float16")
149-
dispatchTestByVectorSize<HLSLHalf_t>(OpType, Handler);
149+
dispatchTestByVectorLength<HLSLHalf_t>(OpType, Handler);
150150
else if (DataType == L"float32")
151-
dispatchTestByVectorSize<float>(OpType, Handler);
151+
dispatchTestByVectorLength<float>(OpType, Handler);
152152
else if (DataType == L"float64")
153-
dispatchTestByVectorSize<double>(OpType, Handler);
153+
dispatchTestByVectorLength<double>(OpType, Handler);
154154
else
155155
VERIFY_FAIL(
156156
String().Format(L"DataType: %s is not recognized.", DataType.c_str()));
157157
}
158158

159159
template <typename DataTypeT, typename LongVectorOpTypeT>
160-
void LongVector::OpTest::dispatchTestByVectorSize(
160+
void LongVector::OpTest::dispatchTestByVectorLength(
161161
LongVectorOpTypeT opType, TableParameterHandler &Handler) {
162162
WEX::TestExecution::SetVerifyOutput verifySettings(
163163
WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
@@ -180,21 +180,36 @@ void LongVector::OpTest::dispatchTestByVectorSize(
180180
TestConfig.setInputValueSet2(InputValueSet2);
181181
}
182182

183-
std::vector<size_t> InputVectorSizes = {3, 4, 5, 16, 17, 35, 100, 256, 1024};
183+
// Manual override to test a specific vector size. Convenient for debugging
184+
// issues.
185+
size_t InputSizeToTestOverride = 0;
186+
WEX::TestExecution::RuntimeParameters::TryGetValue(L"LongVectorInputSize",
187+
InputSizeToTestOverride);
188+
189+
std::vector<size_t> InputVectorSizes;
190+
if (InputSizeToTestOverride)
191+
InputVectorSizes.push_back(InputSizeToTestOverride);
192+
else
193+
InputVectorSizes = {3, 4, 5, 16, 17, 35, 100, 256, 1024};
194+
184195
for (auto SizeToTest : InputVectorSizes) {
185-
testBaseMethod<DataTypeT, LongVectorOpTypeT>(TestConfig, SizeToTest);
196+
// We could create a new config for each test case with the new length, but
197+
// that feels wasteful. Instead, we just update the length to test.
198+
TestConfig.setLengthToTest(SizeToTest);
199+
testBaseMethod<DataTypeT, LongVectorOpTypeT>(TestConfig);
186200
}
187201
}
188202

189203
template <typename DataTypeT, typename LongVectorOpTypeT>
190204
void LongVector::OpTest::testBaseMethod(
191-
LongVector::TestConfig<DataTypeT, LongVectorOpTypeT> &TestConfig,
192-
size_t VectorSizeToTest) {
205+
LongVector::TestConfig<DataTypeT, LongVectorOpTypeT> &TestConfig) {
193206
WEX::TestExecution::SetVerifyOutput verifySettings(
194207
WEX::TestExecution::VerifyOutputSettings::LogOnlyFailures);
195208

209+
const size_t VectorLengthToTest = TestConfig.getLengthToTest();
210+
196211
hlsl_test::LogCommentFmt(L"Running LongVectorOpTestBase<%S, %zu>",
197-
typeid(DataTypeT).name(), VectorSizeToTest);
212+
typeid(DataTypeT).name(), VectorLengthToTest);
198213

199214
bool LogInputs = false;
200215
WEX::TestExecution::RuntimeParameters::TryGetValue(L"LongVectorLogInputs",
@@ -214,9 +229,9 @@ void LongVector::OpTest::testBaseMethod(
214229
}
215230

216231
std::vector<DataTypeT> InputVector1;
217-
InputVector1.reserve(VectorSizeToTest);
232+
InputVector1.reserve(VectorLengthToTest);
218233
std::vector<DataTypeT> InputVector2; // May be unused, but must be defined.
219-
InputVector2.reserve(VectorSizeToTest);
234+
InputVector2.reserve(VectorLengthToTest);
220235
std::vector<DataTypeT> ScalarInput; // May be unused, but must be defined.
221236
const bool IsVectorBinaryOp =
222237
TestConfig.isBinaryOp() && !TestConfig.isScalarOp();
@@ -233,7 +248,7 @@ void LongVector::OpTest::testBaseMethod(
233248

234249
// Fill the input vectors with values from the value set. Repeat the values
235250
// when we reach the end of the value set.
236-
for (size_t Index = 0; Index < VectorSizeToTest; Index++) {
251+
for (size_t Index = 0; Index < VectorLengthToTest; Index++) {
237252
InputVector1.push_back(
238253
InputVector1ValueSet[Index % InputVector1ValueSet.size()]);
239254

@@ -242,16 +257,12 @@ void LongVector::OpTest::testBaseMethod(
242257
InputVector2ValueSet[Index % InputVector2ValueSet.size()]);
243258
}
244259

245-
std::vector<DataTypeT> ExpectedVector;
246-
ExpectedVector.reserve(VectorSizeToTest);
247260
if (IsVectorBinaryOp)
248-
ExpectedVector =
249-
computeExpectedValues(InputVector1, InputVector2, TestConfig);
261+
computeExpectedValues(InputVector1, InputVector2, TestConfig);
250262
else if (TestConfig.isScalarOp())
251-
ExpectedVector =
252-
computeExpectedValues(InputVector1, ScalarInput[0], TestConfig);
263+
computeExpectedValues(InputVector1, ScalarInput[0], TestConfig);
253264
else // Must be a unary op
254-
ExpectedVector = computeExpectedValues(InputVector1, TestConfig);
265+
computeExpectedValues(InputVector1, TestConfig);
255266

256267
if (LogInputs) {
257268
logLongVector<DataTypeT>(InputVector1, L"InputVector1");
@@ -264,8 +275,7 @@ void LongVector::OpTest::testBaseMethod(
264275

265276
// We have to construct the string outside of the lambda. Otherwise it's
266277
// cleaned up when the lambda finishes executing but before the shader runs.
267-
std::string CompilerOptionsString =
268-
TestConfig.getCompilerOptionsString(VectorSizeToTest);
278+
std::string CompilerOptionsString = TestConfig.getCompilerOptionsString();
269279

270280
// The name of the shader we want to use in ShaderOpArith.xml. Could also add
271281
// logic to set this name in ShaderOpArithTable.xml so we can use different
@@ -331,11 +341,10 @@ void LongVector::OpTest::testBaseMethod(
331341
MappedData ShaderOutData;
332342
TestResult->Test->GetReadBackData("OutputVector", &ShaderOutData);
333343

334-
std::vector<DataTypeT> OutputVector;
335-
fillLongVectorDataFromShaderBuffer<DataTypeT>(ShaderOutData, OutputVector,
336-
VectorSizeToTest);
337-
338-
VERIFY_SUCCEEDED(doVectorsMatch<DataTypeT>(OutputVector, ExpectedVector,
339-
TestConfig.getTolerance(),
340-
TestConfig.getValidationType()));
344+
// The TestConfig object help handles more complicated verification cases. We
345+
// pass in the MappedData instead of the typed data because the TestConfig may
346+
// need to resolve the output type for test cases where the return type of the
347+
// intrinsic being tested does not match the input type, such as the AsType*
348+
// intrinsics (AsInt, AsInt16, AsFloat, ... etc).
349+
VERIFY_SUCCEEDED(TestConfig.verifyOutput(ShaderOutData));
341350
}

0 commit comments

Comments
 (0)