[Mesa-dev,v2,9/9] glsl: Add tests for minmax prune

Submitted by Iago Toral Quiroga on Oct. 1, 2014, 6:35 a.m.

Details

Message ID 1412145345-3974-10-git-send-email-itoral@igalia.com
State New
Headers show

Not browsing as part of any series.

Commit Message

Iago Toral Quiroga Oct. 1, 2014, 6:35 a.m.
From: Petri Latvala <petri.latvala@intel.com>

Original patch by Petri Latvala <petri.latvala@intel.com>:

tests/minmax/create_test_cases.py generates the following tests:

multiple_min*.opt_test:
 Construct a tree of min expressions for all permutations of a var_ref
 and three constants. They should all optimize to a single min with
 the variable and the smallest constant.
multiple_max*.opt_test:
 Same as above, for max.
mid3opt*.opt_test:
 Test that code generated from a mid3() for two constants and a
 var_ref optimizes to a single max and a single min.
mixed_vectors*.opt_test:
 Test that the optimization pass doesn't modify expression trees with
 constant vectors where some components compare as less, some as
 greater.

Signed-off-by: Petri Latvala <petri.latvala@intel.com>

Version 2 by Iago Toral Quiroga <itoral@igalia.com>:

mixed_vectors*.opt_test:
 Rewrite the tests now that we can do some optimization for mixed vectors.
 Specifically, test that we can reduce trees of minmax expressions that
 operate on constant vectors, even when some components compare as less and
 some as greater, to constants.

Remove unnecessary imports, fix single-line strings to single quotes
instead of triple quotes and use enumerate for loop counters.
---
 src/glsl/tests/minmax/.gitignore           |   3 +
 src/glsl/tests/minmax/create_test_cases.py | 142 +++++++++++++++++++++++++++++
 2 files changed, 145 insertions(+)
 create mode 100644 src/glsl/tests/minmax/.gitignore
 create mode 100644 src/glsl/tests/minmax/create_test_cases.py

Patch hide | download patch | download mbox

diff --git a/src/glsl/tests/minmax/.gitignore b/src/glsl/tests/minmax/.gitignore
new file mode 100644
index 0000000..e98df62
--- /dev/null
+++ b/src/glsl/tests/minmax/.gitignore
@@ -0,0 +1,3 @@ 
+*.opt_test
+*.expected
+*.out
diff --git a/src/glsl/tests/minmax/create_test_cases.py b/src/glsl/tests/minmax/create_test_cases.py
new file mode 100644
index 0000000..fb3d152
--- /dev/null
+++ b/src/glsl/tests/minmax/create_test_cases.py
@@ -0,0 +1,142 @@ 
+# coding=utf-8
+#
+# Copyright © 2014 Intel Corporation
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+
+import os
+import sys
+import itertools
+
+sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
+from sexps import *
+from test_case_generator import *
+
+def test_multiple_max():
+    doc_string = "Test that multiple constants in multiple max expressions are reduced to a single max."
+
+    operands = [const_float(1),
+                const_float(2),
+                const_float(3),
+                ['var_ref', 'a']]
+
+    for (c, ops) in enumerate(itertools.permutations(operands), start=1):
+        maxtree1 = reduce(lambda a, b: max_(a, b, 'float'), ops)
+        maxtree2 = reduce(lambda a, b: max_(b, a, 'float'), ops)
+
+        expected = max_(const_float(3), ['var_ref', 'a'], 'float')
+
+        input_sexp = make_test_case('main', 'void', (
+                assign_x('b', maxtree1) +
+                assign_x('c', maxtree2)
+                ))
+        expected_sexp = make_test_case('main', 'void', (
+                assign_x('b', expected) +
+                assign_x('c', expected)
+                ))
+
+        create_test_case(doc_string, input_sexp, expected_sexp, 'multiple_max{0}'.format(c), 'do_minmax_prune')
+
+def test_multiple_min():
+    doc_string = "Test that multiple constants in multiple min expressions are reduced to a single min."
+
+    operands = [const_float(1),
+                const_float(2),
+                const_float(3),
+                ['var_ref', 'a']]
+
+    for (c, ops) in enumerate(itertools.permutations(operands), start=1):
+        mintree1 = reduce(lambda a, b: min_(a, b, 'float'), ops)
+        mintree2 = reduce(lambda a, b: min_(b, a, 'float'), ops)
+
+        expected = min_(const_float(1), ['var_ref', 'a'], 'float')
+
+        input_sexp = make_test_case('main', 'void', (
+                assign_x('b', mintree1) +
+                assign_x('c', mintree2)
+                ))
+        expected_sexp = make_test_case('main', 'void', (
+                assign_x('b', expected) +
+                assign_x('c', expected)
+                ))
+
+        create_test_case(doc_string, input_sexp, expected_sexp, 'multiple_min{0}'.format(c), 'do_minmax_prune')
+
+def test_two_constant_mid3():
+    doc_string = """Test that code generated from a mid3() call with two parameters as constants
+are reduced to a single min and max"""
+
+    operands = [const_float(1),
+                const_float(3),
+                ['var_ref', 'a']]
+
+    # The builtin function call mid3(x, y, z) generates max(min(x, y), max(min(x, z), min(y, z))).
+    # All permutations of these parameters should optimize to max(min(var_ref a, 3), 1)
+
+    for (c, ops) in enumerate(itertools.permutations(operands), start=1):
+        x = ops[0]
+        y = ops[1]
+        z = ops[2]
+
+        exprtree = maxf(minf(x, y), maxf(minf(x, z), minf(y, z)))
+        expected = maxf(minf(['var_ref', 'a'], const_float(3)), const_float(1))
+
+        input_sexp = make_test_case('main', 'void', (
+                assign_x('b', exprtree)
+                ))
+        expect_sexp = make_test_case('main', 'void', (
+                assign_x('b', expected)
+                ))
+
+        create_test_case(doc_string, input_sexp, expect_sexp, 'mid3opt{0}'.format(c), 'do_minmax_prune')
+
+def test_mixed_vectors():
+    doc_string = """Test that a min/max tree of constant vectors can be reduced to a simple constant
+even if some of the vectors have some components less and some greater than the other vectors."""
+
+    operands = [const_vec4(1, 3, 1, 3),
+                const_vec4(3, 1, 3, 1),
+                const_vec4(2, 2, 2, 2)]
+
+    for (c, ops) in enumerate(itertools.permutations(operands), start=1):
+        expected = const_vec4(1, 1, 1, 1)
+
+        input_sexp = make_test_case('main', 'void', (
+                declare('vec4', 'a', 'in') +
+                declare('vec4', 'b', 'out') +
+                declare('vec4', 'c', 'out') +
+                assign('b', 'xyzw', reduce(lambda a, b: min_(a, b, 'vec4'), ops)) +
+                assign('c', 'xyzw', reduce(lambda a, b: min_(b, a, 'vec4'), ops))
+                 ))
+        expected_sexp = make_test_case('main', 'void', (
+                declare('vec4', 'a', 'in') +
+                declare('vec4', 'b', 'out') +
+                declare('vec4', 'c', 'out') +
+                assign('b', 'xyzw', expected) +
+                assign('c', 'xyzw', expected)
+                ))
+
+        create_test_case(doc_string, input_sexp, expected_sexp, 'mixed_vectors{0}'.format(c), 'do_minmax_prune')
+
+if __name__ == '__main__':
+    test_multiple_max()
+    test_multiple_min()
+    test_two_constant_mid3()
+    test_mixed_vectors()