Browse Source

Fix wave intrinsic prefix test to not assume that lane id is in same order as thread id (#586)

Young Kim 8 years ago
parent
commit
c551a1acac

+ 41 - 19
tools/clang/unittests/HLSL/ExecutionTest.cpp

@@ -434,8 +434,7 @@ static int MaskEveryOther(int i) {
 static int MaskEveryThird(int i) {
   return i % 3 == 0 ? 1 : 0;
 }
-// TODO: It seems there is an issue with WARP with controlling active lanes
-// Add more masks when this is resolved
+
 typedef int(*MaskFunction)(int);
 static MaskFunction MaskFunctionTable[] = {
   MaskAll, MaskEveryOther, MaskEveryThird
@@ -3936,6 +3935,8 @@ TEST_F(ExecutionTest, Msad4Test) {
     }
 }
 
+// A framework for testing individual wave intrinsics tests.
+// This test case is assuming that functions 1) WaveIsFirstLane and 2) WaveGetLaneIndex are correct for all lanes.
 template <class T1, class T2>
 void ExecutionTest::WaveIntrinsicsActivePrefixTest(
     TableParameter *pParameterList, size_t numParameter, bool isPrefix) {
@@ -3943,8 +3944,11 @@ void ExecutionTest::WaveIntrinsicsActivePrefixTest(
 
   // Resource representation for compute shader
   // firstLaneId is used to group different waves
+  // laneIndex is used to identify lane within the wave.
+  // Lane ids are not necessarily in same order as thread ids.
   struct PerThreadData {
       int firstLaneId;
+      int laneIndex;
       int mask;
       T1 input;
       T2 output;
@@ -3978,12 +3982,12 @@ void ExecutionTest::WaveIntrinsicsActivePrefixTest(
 
   // Obtain the list of input lists
   typedef WEX::TestExecution::TestDataArray<T1> DataArray;
-  std::vector<DataArray*> InputList;
+  std::vector<DataArray*> InputDataList;
   for (unsigned int i = 0;
     i < numInputSet; ++i) {
     std::wstring inputName = L"Validation.InputSet";
     inputName.append(std::to_wstring(i + 1));
-    InputList.push_back(handler.GetDataArray<T1>(inputName.data()));
+    InputDataList.push_back(handler.GetDataArray<T1>(inputName.data()));
   }
   CW2A Text(handler.GetTableParamByName(L"ShaderOp.text")->m_str);
 
@@ -4004,9 +4008,11 @@ void ExecutionTest::WaveIntrinsicsActivePrefixTest(
         PerThreadData *pPrimitives = (PerThreadData*)Data.data();
         // 4 different inputs for each operation test
         size_t index = 0;
+        DataArray *IntList = InputDataList[setIndex];
         while (index < ThreadCount) {
           PerThreadData *p = &pPrimitives[index];
-          DataArray *IntList = InputList[setIndex];
+          p->firstLaneId = 0xFFFFBFFF;
+          p->laneIndex = 0xFFFFBFFF;
           p->mask = MaskFunctionTable[maskIndex](index);
           p->input = (*IntList)[index % IntList->GetSize()];
           p->output = 0xFFFFBFFF;
@@ -4048,25 +4054,41 @@ void ExecutionTest::WaveIntrinsicsActivePrefixTest(
         // collect inputs and masks for a given wave
         std::vector<PerThreadData *> *waveData = waves[firstLaneIds.at(i)].get();
         std::vector<T1> inputList(waveData->size());
-        std::vector<int> maskList(waveData->size());
-        std::wstring inputStr = L"Wave Inputs: ";
-        std::wstring maskStr =  L"Wave Mask:   ";
-        for (size_t j = 0; j < waveData->size(); ++j) {
-          inputList.at(j) = (waveData->at(j)->input);
-          maskList.at(j) = (waveData->at(j)->mask);
-          inputStr.append(std::to_wstring(waveData->at(j)->input));
-          inputStr.append(L" ");
-          maskStr.append(std::to_wstring(waveData->at(j)->mask));
+        std::vector<int> maskList(waveData->size(), -1);
+        std::vector<T2> outputList(waveData->size());
+        // sort inputList and masklist by lane id. input for each lane can be computed for its group index
+        for (size_t j = 0, end = waveData->size(); j < end; ++j) {
+          int laneID = waveData->at(j)->laneIndex;
+          // ensure that each lane ID is unique and within the range
+          VERIFY_IS_TRUE(0 <= laneID && laneID < waveData->size());
+          VERIFY_IS_TRUE(maskList.at(laneID) == -1);
+          maskList.at(laneID) = waveData->at(j)->mask;
+          inputList.at(laneID) = waveData->at(j)->input;
+          outputList.at(laneID) = waveData->at(j)->output;
+        }
+        std::wstring inputStr = L"Wave Inputs:  ";
+        std::wstring maskStr =  L"Wave Masks:   ";
+        std::wstring outputStr = L"Wave Outputs: ";
+        // append input string and mask string in lane id order
+        for (size_t j = 0, end = waveData->size(); j < end; ++j) {
+          maskStr.append(std::to_wstring(maskList.at(j)));
           maskStr.append(L" ");
+          inputStr.append(std::to_wstring(inputList.at(j)));
+          inputStr.append(L" ");
+          outputStr.append(std::to_wstring(outputList.at(j)));
+          outputStr.append(L" ");
         }
+
         LogCommentFmt(inputStr.data());
         LogCommentFmt(maskStr.data());
+        LogCommentFmt(outputStr.data());
+        LogCommentFmt(L"\n");
         // Compute expected output for a given inputs, masks, and index
-        for (size_t laneIndex = 0; laneIndex < waveData->size(); ++laneIndex) {
+        for (size_t laneIndex = 0, laneEnd = inputList.size(); laneIndex < laneEnd; ++laneIndex) {
           T2 expected;
           // WaveActive is equivalent to WavePrefix lane # lane count
-          unsigned int index = isPrefix ? laneIndex : waveData->size();
-          if (waveData->at(laneIndex)->mask == 1) {
+          unsigned index = isPrefix ? laneIndex : inputList.size();
+          if (maskList.at(laneIndex) == 1) {
             expected = computeExpectedWithShaderOp<T1, T2>(
               inputList, maskList, 1, index,
               handler.GetTableParamByName(L"ShaderOp.Name")->m_str);
@@ -4077,9 +4099,9 @@ void ExecutionTest::WaveIntrinsicsActivePrefixTest(
               handler.GetTableParamByName(L"ShaderOp.Name")->m_str);
           }
           // TODO: use different comparison for floating point inputs
-          bool equal = waveData->at(laneIndex)->output == expected;
+          bool equal = outputList.at(laneIndex) == expected;
           if (!equal) {
-            LogCommentFmt(L"lane%d: %4d, Expected : %4d", laneIndex, waveData->at(laneIndex)->output, expected);
+            LogCommentFmt(L"lane%d: %4d, Expected : %4d", laneIndex, outputList.at(laneIndex), expected);
           }
           VERIFY_IS_TRUE(equal);
         }

+ 42 - 0
tools/clang/unittests/HLSL/ShaderOpArithTable.xml

@@ -2410,6 +2410,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         int input;
                         int output;
@@ -2419,6 +2420,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveSum(pts.input);
                         }
@@ -2453,6 +2455,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         int input;
                         int output;
@@ -2462,6 +2465,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveProduct(pts.input);
                         }
@@ -2496,6 +2500,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         int input;
                         int output;
@@ -2505,6 +2510,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveCountBits(pts.input > 3);
                         }
@@ -2544,6 +2550,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         int input;
                         int output;
@@ -2553,6 +2560,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveMax(pts.input);
                         }
@@ -2592,6 +2600,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         int input;
                         int output;
@@ -2601,6 +2610,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveMin(pts.input);
                         }
@@ -2646,6 +2656,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         int input;
                         int output;
@@ -2655,6 +2666,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveAllEqual(pts.input);
                         }
@@ -2690,6 +2702,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         bool input;
                         bool output;
@@ -2699,6 +2712,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveAnyTrue(pts.input);
                         }
@@ -2731,6 +2745,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         bool input;
                         bool output;
@@ -2740,6 +2755,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveAllTrue(pts.input);
                         }
@@ -2784,6 +2800,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         uint input;
                         uint output;
@@ -2793,6 +2810,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveSum(pts.input);
                         }
@@ -2827,6 +2845,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         uint input;
                         uint output;
@@ -2836,6 +2855,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveProduct(pts.input);
                         }
@@ -2870,6 +2890,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         uint input;
                         uint output;
@@ -2879,6 +2900,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveMax(pts.input);
                         }
@@ -2913,6 +2935,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         uint input;
                         uint output;
@@ -2922,6 +2945,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveMin(pts.input);
                         }
@@ -2962,6 +2986,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         uint input;
                         uint output;
@@ -2971,6 +2996,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveBitOr(pts.input);
                         }
@@ -3016,6 +3042,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         uint input;
                         uint output;
@@ -3025,6 +3052,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveBitAnd(pts.input);
                         }
@@ -3070,6 +3098,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         uint input;
                         uint output;
@@ -3079,6 +3108,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WaveActiveBitXor(pts.input);
                         }
@@ -3135,6 +3165,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         int input;
                         int output;
@@ -3144,6 +3175,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WavePrefixCountBits(pts.input > 3);
                         }
@@ -3184,6 +3216,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         int input;
                         int output;
@@ -3193,6 +3226,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WavePrefixSum(pts.input);
                         }
@@ -3230,6 +3264,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         int input;
                         int output;
@@ -3239,6 +3274,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WavePrefixProduct(pts.input);
                         }
@@ -3287,6 +3323,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         uint input;
                         uint output;
@@ -3296,6 +3333,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WavePrefixCountBits(pts.input > 3);
                         }
@@ -3333,6 +3371,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         uint input;
                         uint output;
@@ -3342,6 +3381,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WavePrefixSum(pts.input);
                         }
@@ -3378,6 +3418,7 @@
                 <![CDATA[
                     struct PerThreadData {
                         int firstLaneId;
+                        int laneIndex;
                         int mask;
                         uint input;
                         uint output;
@@ -3387,6 +3428,7 @@
                     void main(uint GI : SV_GroupIndex) {
                         PerThreadData pts = g_sb[GI];
                         pts.firstLaneId = WaveReadLaneFirst(GI);
+                        pts.laneIndex = WaveGetLaneIndex();
                         if (pts.mask != 0) {
                             pts.output = WavePrefixProduct(pts.input);
                         }