Add more allowed 'dot' alternatives
authorAlexander Galazin <alexander.galazin@arm.com>
Thu, 17 Aug 2017 14:16:09 +0000 (16:16 +0200)
committerAlexander Galazin <alexander.galazin@arm.com>
Mon, 21 Aug 2017 09:34:31 +0000 (11:34 +0200)
Expanded dot may be re-associated in multiple ways.
Add all possible alternatives to prevent precision failures.

Components: Vulkan

VK-GL-CTS issue: 634

Affects:
dEQP-VK.glsl.builtin.precision.dot.*
dEQP-VK.glsl.builtin.precision.reflect.*

Change-Id: I7fecbfa1cde04eab95bb3d418972631727d6d6af

external/vulkancts/modules/vulkan/shaderexecutor/vktShaderBuiltinPrecisionTests.cpp

index f9b2d77..4e406d8 100644 (file)
@@ -2903,12 +2903,32 @@ public:
 protected:
        ExprP<float>    doExpand        (ExpandContext&, const ArgExprs& args) const
        {
-               ExprP<float> val = args.a[0] * args.b[0];
+               ExprP<float> op[Size];
+               // Precompute all products.
+               for (int ndx = 0; ndx < Size; ++ndx)
+                       op[ndx] = args.a[ndx] * args.b[ndx];
 
-               for (int ndx = 1; ndx < Size; ++ndx)
-                       val = val + args.a[ndx] * args.b[ndx];
+               int idx[Size];
+               //Prepare an array of indices.
+               for (int ndx = 0; ndx < Size; ++ndx)
+                       idx[ndx] = ndx;
 
-               return val;
+               ExprP<float> res = op[0];
+               // Compute the first dot alternative: SUM(a[i]*b[i]), i = 0 .. Size-1
+               for (int ndx = 1; ndx < Size; ++ndx)
+                       res = res + op[ndx];
+
+               // Generate all permutations of indices and
+               // using a permutation compute a dot alternative.
+               // Generates all possible variants fo summation of products in the dot product expansion expression.
+               do {
+                       ExprP<float> alt = constant(0.0f);
+                       for (int ndx = 0; ndx < Size; ++ndx)
+                               alt = alt + op[idx[ndx]];
+                       res = alternatives(res, alt);
+               } while (std::next_permutation(idx, idx + Size));
+
+               return res;
        }
 };