[Piglit] [PATCH 5/5] gen_conversion: generate tests for 64-bit integers

Nicolai Hähnle nhaehnle at gmail.com
Thu Jan 26 18:59:26 UTC 2017


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

---
 generated_tests/gen_conversion.py                  | 302 ++++++++++++++++++---
 generated_tests/templates/gen_conversion/base.mako |   2 +-
 2 files changed, 264 insertions(+), 40 deletions(-)

diff --git a/generated_tests/gen_conversion.py b/generated_tests/gen_conversion.py
index e261eac..810e0ef 100644
--- a/generated_tests/gen_conversion.py
+++ b/generated_tests/gen_conversion.py
@@ -14,21 +14,21 @@
 # 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.
 
-"""Generate fp64 types conversion tests."""
+"""Generate fp64 and int64 types conversion tests."""
 
 from __future__ import print_function, division, absolute_import
 import abc
 import argparse
 import itertools
 import os
 import struct
 
 import numpy as np
 
@@ -115,20 +115,67 @@ FLOAT_VALUES                = ['0xff7fffff', # Negative maximum normalized
                                #'0x807fffff', # Negative maximum denormalized -- Denormalized may be flushed to 0
                                #'0x80000001', # Negative minimum denormalized -- Denormalized may be flushed to 0
                                #'0x00000001', # Positive minimum denormalized -- Denormalized may be flushed to 0
                                #'0x007fffff', # Positive maximum denormalized -- Denormalized may be flushed to 0
                                '0x00800000', # Positive minimum normalized
                                '0x3ff92e73', # +1.9467300176620483
                                '0x40a00000', # +5.0
                                '0x4b800000', # +16777216.0
                                '0x7f7fffff'] # Positive maximum normalized
 
+FLOAT_INT64_VALUES          = ['0xcf800000', # -4294967296.0
+                               '0xcb800000', # -16777216.0
+                               '0xc0a00000', # -5.0
+                               '0xbff92e73', # -1.9467300176620483
+                               '0x80800000', # Negative minimum normalized
+                               '0x807fffff', # Negative maximum denormalized
+                               '0x80000001', # Negative minimum denormalized
+                               '0x00000001', # Positive minimum denormalized
+                               '0x007fffff', # Positive maximum denormalized
+                               '0x00800000', # Positive minimum normalized
+                               '0x3ff92e73', # +1.9467300176620483
+                               '0x40a00000', # +5.0
+                               '0x4b800000', # +16777216.0
+                               '0x4f800000'] # +4294967296.0
+
+FLOAT_UINT64_VALUES         = ['0x00000001', # Positive minimum denormalized
+                               '0x007fffff', # Positive maximum denormalized
+                               '0x00800000', # Positive minimum normalized
+                               '0x3ff92e73', # +1.9467300176620483
+                               '0x40a00000', # +5.0
+                               '0x4b800000', # +16777216.0
+                               '0x4f800000'] # +4294967296.0
+
+UINT64_VALUES               = ['0', # Minimum
+                               '5',
+                               '2147483647', # Signed int32 low frontier
+                               '2147483648', # Signed int32 up frontier
+                               '4294967295', # Maximum unsigned int32
+                               '4294967296',
+                               '9223372036854775807', # Signed int64 low frontier
+                               '9223372036854775808', # Signed int64 up frontier
+                               '18446744073709551615'] # Maximum
+
+INT64_VALUES                = ['-9223372036854775808', # Minimum
+                               '-2147483649',
+                               '-2147483648',
+                               '-5',
+                               '-1',
+                               '0',
+                               '1',
+                               '5',
+                               '2147483647', # Signed int32 low frontier
+                               '2147483648', # Signed int32 up frontier
+                               '4294967295', # Maximum unsigned int32
+                               '4294967296',
+                               '9223372036854775807'] # Maximum
+
 UINT_VALUES                 = ['0', # Minimum
                                '5',
                                '2147483647', # Signed int low frontier
                                '2147483648', # Signed int up frontier
                                '4294967295'] # Maximum
 
 INT_VALUES                  = ['-2147483648', # Minimum
                                '-5',
                                '-1',
                                '0',
@@ -199,26 +246,109 @@ class TestTuple(object):
     def float_hex_to_inv_double_hex(hstr):
         """Returns the inverted float64 hexadecimal representation from a
            float32 hexadecimal representation.
         """
         assert isinstance(hstr, str)
         temp = TestTuple.hex_to_float(hstr)
         double_value = np.divide(1.0, temp)
         return TestTuple.double_to_hex(double_value)
 
     @staticmethod
+    def float_hex_to_int64_str(hstr):
+        """Returns the int64 string representation from a float32
+           hexadecimal representation.
+        """
+        assert isinstance(hstr, str)
+        x = TestTuple.hex_to_float(hstr)
+        if x > np.iinfo(np.dtype('int64')).max:
+            return str(np.iinfo(np.dtype('int64')).max)
+        if x < np.iinfo(np.dtype('int64')).min:
+            return str(np.iinfo(np.dtype('int64')).min)
+        return str(int(x))
+
+    @staticmethod
+    def float_hex_to_uint64_str(hstr):
+        """Returns the uint64 string representation from a float32
+           hexadecimal representation.
+        """
+        assert isinstance(hstr, str)
+        x = TestTuple.hex_to_float(hstr)
+        if x > np.iinfo(np.dtype('uint64')).max:
+            return str(np.iinfo(np.dtype('uint64')).max)
+        if x < np.iinfo(np.dtype('uint64')).min:
+            return str(np.iinfo(np.dtype('uint64')).min)
+        return str(int(x))
+
+    @staticmethod
+    def int_str_to_bool_str(istr):
+        """Returns a bool/integer string from an (arbitrary size) integet string."""
+        assert isinstance(istr, str)
+        return str(int(bool(int(istr))))
+
+    @staticmethod
+    def int_str_to_float_hex(istr):
+        """Returns a float32 hexadecimal representation from an (arbitrary size) integer string."""
+        assert isinstance(istr, str)
+        return TestTuple.float_to_hex(np.float32(int(istr)))
+
+    @staticmethod
+    def int_str_to_double_hex(istr):
+        """Returns a float64 hexadecimal representation from an (arbitrary size) integer string."""
+        assert isinstance(istr, str)
+        return TestTuple.double_to_hex(float(istr))
+
+    @staticmethod
     def int_str_to_double_str(istr):
-        """Returns a float64 string from an int32 string."""
+        """Returns a float64 string from an (arbitrary size) integer string."""
         assert isinstance(istr, str)
         return str(float(istr))
 
     @staticmethod
+    def int_str_to_int32_str(istr):
+        """Returns an int32 string from an (arbitrary size) integer string."""
+        x = int(istr) & (2**32 - 1)
+        if x >= 2**31:
+            x -= 2**32
+        return str(x)
+
+    @staticmethod
+    def int_str_to_uint32_str(istr):
+        """Returns an uint32 string from an (arbitrary size) integer string."""
+        x = int(istr) & (2**32 - 1)
+        return str(x)
+
+    @staticmethod
+    def int_str_to_int64_str(istr):
+        """Returns an int64 string from an (arbitrary size) integer string."""
+        x = int(istr) & (2**64 - 1)
+        if x >= 2**63:
+            x -= 2**64
+        return str(x)
+
+    @staticmethod
+    def int_str_to_uint64_str(istr):
+        """Returns an uint64 string from an (arbitrary size) integer string."""
+        x = int(istr) & (2**64 - 1)
+        return str(x)
+
+    @staticmethod
+    def int_str_to_type_str(target_type):
+        """Returns a function for converting an int string to a string for the given type."""
+        assert target_type in ('d', 'i64', 'u64')
+        if target_type == 'd':
+            return TestTuple.int_str_to_double_str
+        elif target_type == 'i64':
+            return TestTuple.int_str_to_int64_str
+        elif target_type == 'u64':
+            return TestTuple.int_str_to_uint64_str
+
+    @staticmethod
     def double_hex_to_bool_str(hstr):
         """Returns a bool string from a float64 hexadecimal representation."""
         assert isinstance(hstr, str)
         bool_double = TestTuple.hex_to_double(hstr)
         return '1' if bool_double != 0.0 else '0'
 
     @staticmethod
     def double_hex_to_int_str(hstr):
         """Returns an int32 string from a float64 hexadecimal
            representation.
@@ -256,20 +386,46 @@ class TestTuple(object):
     @staticmethod
     def double_hex_to_inv_float_hex(hstr):
         """Returns the inverted float32 hexadecimal representation from a
            float64 hexadecimal representation.
         """
         assert isinstance(hstr, str)
         temp = np.divide(1.0, TestTuple.hex_to_double(hstr))
         float_double = np.float32(temp)
         return TestTuple.float_to_hex(float_double)
 
+    @staticmethod
+    def double_hex_to_int64_str(hstr):
+        """Returns the int64 string representation from a float64
+           hexadecimal representation.
+        """
+        assert isinstance(hstr, str)
+        x = TestTuple.hex_to_double(hstr)
+        if x > np.iinfo(np.dtype('int64')).max:
+            return str(np.iinfo(np.dtype('int64')).max)
+        if x < np.iinfo(np.dtype('int64')).min:
+            return str(np.iinfo(np.dtype('int64')).min)
+        return str(int(x))
+
+    @staticmethod
+    def double_hex_to_uint64_str(hstr):
+        """Returns the uint64 string representation from a float64
+           hexadecimal representation.
+        """
+        assert isinstance(hstr, str)
+        x = TestTuple.hex_to_double(hstr)
+        if x > np.iinfo(np.dtype('uint64')).max:
+            return str(np.iinfo(np.dtype('uint64')).max)
+        if x < np.iinfo(np.dtype('uint64')).min:
+            return str(np.iinfo(np.dtype('uint64')).min)
+        return str(int(x))
+
     def __init__(self, ver, stage,
                  first_dimension, second_dimension,
                  basic_type, target_type, names_only):
         assert stage in ('vert', 'geom', 'frag')
         assert first_dimension in ('1', '2', '3', '4')
         assert second_dimension in ('1', '2', '3', '4')
         assert isinstance(names_only, bool)
 
         self._ver = ver
         self._stage = stage
@@ -279,50 +435,63 @@ class TestTuple(object):
         self._target_full_type = ''
         self._conversion_type = ''
         self._uniform_type = ''
         self._amount = int(first_dimension) * int(second_dimension)
         self._filenames = []
         self._extensions = []
 
         if ver.startswith('GL_'):
             if basic_type == 'd' or target_type == 'd':
                 self._extensions.append('GL_ARB_gpu_shader_fp64')
+            if basic_type in ('i64', 'u64') or target_type in ('i64', 'u64'):
+                self._extensions.append('GL_ARB_gpu_shader_int64')
 
         if first_dimension != '1':
             dimensional_type = 'mat' + first_dimension
             if first_dimension != second_dimension:
                 dimensional_type += 'x' + second_dimension
         elif second_dimension != '1':
             dimensional_type = 'vec' + second_dimension
         else:
             dimensional_type = ''
 
         if dimensional_type == '':
             if basic_type == 'b':
                 self._conversion_type = 'bool'
                 self._uniform_type = 'int'
             elif basic_type == 'i':
                 self._conversion_type = 'int'
             elif basic_type == 'u':
                 self._conversion_type = 'uint'
             elif basic_type == 'f':
                 self._conversion_type = 'float'
-            self._target_full_type = 'double'
+            elif basic_type == 'd':
+                self._conversion_type = 'double'
+            elif basic_type == 'i64':
+                self._conversion_type = 'int64_t'
+            elif basic_type == 'u64':
+                self._conversion_type = 'uint64_t'
             if self._uniform_type == '':
                 self._uniform_type = self._conversion_type
+            if target_type == 'd':
+                self._target_full_type = 'double'
+            elif target_type == 'i64':
+                self._target_full_type = 'int64_t'
+            elif target_type == 'u64':
+                self._target_full_type = 'uint64_t'
         else:
             self._conversion_type = (basic_type if basic_type != 'f' else '') + dimensional_type
             if basic_type == 'b':
                 self._uniform_type = 'i' + dimensional_type
             else:
                 self._uniform_type = self._conversion_type
-            self._target_full_type = 'd' + dimensional_type
+            self._target_full_type = target_type + dimensional_type
 
     @abc.abstractmethod
     def _gen_to_target(self):
         """Generates the test files for conversions to float64."""
 
     @abc.abstractmethod
     def _gen_from_target(self):
         """Generates the test files for conversions from float64."""
 
     @property
@@ -348,49 +517,53 @@ class RegularTestTuple(TestTuple):
        edges of the used types.
     """
 
     @staticmethod
     def all_tests(names_only):
         """Returns all the possible contained conversion test instances."""
 
         assert isinstance(names_only, bool)
         stages = ['vert', 'geom', 'frag']
         dimensions = ['1', '2', '3', '4']
-        basic_types = ['b', 'u', 'i', 'f']
-        target_types = ['d']
-        glsl_ver = ['GL_ARB_gpu_shader_fp64', '400']
+        basic_types = ['b', 'u', 'i', 'f', 'd', 'i64', 'u64']
+        target_types = ['d', 'i64', 'u64']
+        glsl_ver = ['GL_ARB_gpu_shader_int64', 'GL_ARB_gpu_shader_fp64', '400']
 
         if not names_only:
             test_types = ['compiler', 'execution']
             for ver, test_type in itertools.product(glsl_ver, test_types):
                 utils.safe_makedirs(get_dir_name(ver, test_type))
 
         for ver, stage, first_dimension, second_dimension, basic_type, target_type in itertools.product(
                 glsl_ver,
                 stages,
                 dimensions,
                 dimensions,
                 basic_types,
                 target_types):
-            if (not (first_dimension != '1' and (second_dimension == '1' or basic_type != 'f')) and
-                (basic_type not in target_types or basic_type < target_type)):
+            has_int64 = basic_type in ('i64', 'u64') or target_type in ('i64', 'u64')
+            if (not (first_dimension != '1' and
+                     (second_dimension == '1' or basic_type not in ('f', 'd') or target_type != 'd')) and
+                (basic_type not in target_types or basic_type < target_type) and
+                ((ver == 'GL_ARB_gpu_shader_int64') == has_int64)):
                 yield RegularTestTuple(ver, stage,
                                        first_dimension, second_dimension,
                                        basic_type, target_type, names_only)
 
     def __init__(self, ver, stage,
                  first_dimension, second_dimension,
                  basic_type, target_type, names_only):
-        assert ver in ('GL_ARB_gpu_shader_fp64', '400')
-        assert basic_type in ('b', 'u', 'i', 'f')
-        assert target_type in ('d')
-        assert not (first_dimension != '1' and (second_dimension == '1' or basic_type != 'f'))
+        assert ver in ('GL_ARB_gpu_shader_int64', 'GL_ARB_gpu_shader_fp64', '400')
+        assert basic_type in ('b', 'u', 'i', 'f', 'd', 'i64', 'u64')
+        assert target_type in ('d', 'i64', 'u64')
+        assert not (first_dimension != '1' and
+                    (second_dimension == '1' or basic_type not in ('f', 'd') or target_type != 'd'))
         super(RegularTestTuple, self).__init__(ver, stage,
                                                first_dimension, second_dimension,
                                                basic_type, target_type, names_only)
 
     def _gen_comp_test(self, from_type, to_type, converted_from):
         filename = os.path.join(
             get_dir_name(self._ver, 'compiler'),
             '{}-conversion-implicit-{}-{}-bad.{}'.format(self._stage, from_type, to_type,
                                                          self._stage))
 
@@ -428,69 +601,120 @@ class RegularTestTuple(TestTuple):
                         converted_from=converted_from,
                         uniform_from_type=uniform_from_type,
                         uniform_to_type=uniform_to_type,
                         conversions=conversions))
 
     def _gen_to_target(self):
         converted_from = 'from'
         explicit = 'implicit'
 
         if self._basic_type == 'b':
-            explicit = 'explicit'
-            self._gen_comp_test(self._conversion_type, self._target_full_type,
-                                converted_from)
-            converted_from = self._target_full_type + '(from)'
             conversion_values = BOOL_VALUES
-            conversion_function = TestTuple.int_str_to_double_str
+            conversion_function = TestTuple.int_str_to_type_str(self._target_type)
         elif self._basic_type == 'i':
             conversion_values = INT_VALUES
-            conversion_function = TestTuple.int_str_to_double_str
+            conversion_function = TestTuple.int_str_to_type_str(self._target_type)
         elif self._basic_type == 'u':
             conversion_values = UINT_VALUES
-            conversion_function = TestTuple.int_str_to_double_str
+            conversion_function = TestTuple.int_str_to_type_str(self._target_type)
         elif self._basic_type == 'f':
-            conversion_values = FLOAT_INFS + FLOAT_NEG_ZERO + FLOAT_POS_ZERO + FLOAT_VALUES
-            conversion_function = TestTuple.float_hex_to_double_hex
+            if self._target_type == 'd':
+                conversion_values = FLOAT_INFS + FLOAT_NEG_ZERO + FLOAT_POS_ZERO + FLOAT_VALUES
+                conversion_function = TestTuple.float_hex_to_double_hex
+            elif self._target_type == 'i64':
+                conversion_values = FLOAT_POS_ZERO + FLOAT_INT64_VALUES
+                conversion_function = TestTuple.float_hex_to_int64_str
+            elif self._target_type == 'u64':
+                conversion_values = FLOAT_POS_ZERO + FLOAT_UINT64_VALUES
+                conversion_function = TestTuple.float_hex_to_uint64_str
+        elif self._basic_type == 'd':
+            if self._target_type == 'i64':
+                conversion_values = DOUBLE_DENORMAL_VALUES + DOUBLE_NORMAL_VALUES + DOUBLE_INT_VALUES
+                conversion_function = TestTuple.double_hex_to_int64_str
+            elif self._target_type == 'u64':
+                conversion_values = DOUBLE_DENORMAL_VALUES + DOUBLE_NORMAL_VALUES + DOUBLE_UINT_VALUES
+                conversion_function = TestTuple.double_hex_to_uint64_str
+        elif self._basic_type in ('i64', 'u64'):
+            if self._basic_type == 'i64':
+                conversion_values = INT64_VALUES
+            else:
+                conversion_values = UINT64_VALUES
+            conversion_function = TestTuple.int_str_to_type_str(self._target_type)
+
+        if (self._basic_type == 'b' or
+            (self._basic_type in ('f', 'd') and self._target_type in ('i64', 'u64')) or
+            (self._basic_type == 'u' and self._target_type == 'i64')):
+            explicit = 'explicit'
+            self._gen_comp_test(self._conversion_type, self._target_full_type,
+                                converted_from)
+            converted_from = self._target_full_type + '(from)'
 
         conversions = []
         for value in conversion_values:
             to_value = conversion_function(value)
             item = {'from': value, 'to': to_value}
             conversions.append(item)
 
         self._gen_exec_test(self._conversion_type, self._target_full_type,
                             self._uniform_type, self._target_full_type,
                             explicit, converted_from, conversions)
 
     def _gen_from_target(self):
         converted_from = 'from'
-        self._gen_comp_test(self._target_full_type, self._conversion_type,
-                            converted_from)
+        explicit = 'implicit'
 
-        converted_from = self._conversion_type + '(from)'
-        explicit = 'explicit'
+        if self._target_type == 'd':
+            if self._basic_type == 'b':
+                conversion_values = DOUBLE_INFS + DOUBLE_NORMAL_VALUES + DOUBLE_BOOL_VALUES
+                conversion_function = TestTuple.double_hex_to_bool_str
+            elif self._basic_type == 'i':
+                conversion_values = DOUBLE_DENORMAL_VALUES + DOUBLE_NORMAL_VALUES + DOUBLE_INT_VALUES
+                conversion_function = TestTuple.double_hex_to_int_str
+            elif self._basic_type == 'u':
+                conversion_values = DOUBLE_DENORMAL_VALUES + DOUBLE_NORMAL_VALUES + DOUBLE_UINT_VALUES
+                conversion_function = TestTuple.double_hex_to_uint_str
+            elif self._basic_type == 'f':
+                conversion_values = DOUBLE_INFS + DOUBLE_FLOAT_INFS + DOUBLE_FLOAT_VALUES
+                conversion_function = TestTuple.double_hex_to_float_hex
+            conversion_values = DOUBLE_NEG_ZERO + DOUBLE_POS_ZERO + conversion_values
+        elif self._target_type in ('i64', 'u64'):
+            if self._target_type == 'i64':
+                conversion_values = INT64_VALUES
+            elif self._target_type == 'u64':
+                conversion_values = UINT64_VALUES
+
+            if self._basic_type == 'b':
+                conversion_function = TestTuple.int_str_to_bool_str
+            elif self._basic_type == 'i':
+                conversion_function = TestTuple.int_str_to_int32_str
+            elif self._basic_type == 'u':
+                conversion_function = TestTuple.int_str_to_uint32_str
+            elif self._basic_type == 'f':
+                conversion_function = TestTuple.int_str_to_float_hex
+            elif self._basic_type == 'd':
+                conversion_function = TestTuple.int_str_to_double_hex
+            elif self._basic_type == 'i64':
+                conversion_function = TestTuple.int_str_to_int64_str
+            elif self._basic_type == 'i':
+                conversion_function = TestTuple.int_str_to_uint64_str
+
+        if self._basic_type != 'd':
+            self._gen_comp_test(self._target_full_type, self._conversion_type,
+                                converted_from)
 
-        if self._basic_type == 'b':
-            conversion_values = DOUBLE_INFS + DOUBLE_NORMAL_VALUES + DOUBLE_BOOL_VALUES
-            conversion_function = TestTuple.double_hex_to_bool_str
-        elif self._basic_type == 'i':
-            conversion_values = DOUBLE_DENORMAL_VALUES + DOUBLE_NORMAL_VALUES + DOUBLE_INT_VALUES
-            conversion_function = TestTuple.double_hex_to_int_str
-        elif self._basic_type == 'u':
-            conversion_values = DOUBLE_DENORMAL_VALUES + DOUBLE_NORMAL_VALUES + DOUBLE_UINT_VALUES
-            conversion_function = TestTuple.double_hex_to_uint_str
-        elif self._basic_type == 'f':
-            conversion_values = DOUBLE_INFS + DOUBLE_FLOAT_INFS + DOUBLE_FLOAT_VALUES
-            conversion_function = TestTuple.double_hex_to_float_hex
+            converted_from = self._conversion_type + '(from)'
+            explicit = 'explicit'
+        else:
+            assert self._target_type in ('i64', 'u64')
 
         conversions = []
-        for value in DOUBLE_NEG_ZERO + DOUBLE_POS_ZERO + conversion_values:
+        for value in conversion_values:
             to_value = conversion_function(value)
             item = {'from': value, 'to': to_value}
             conversions.append(item)
 
         self._gen_exec_test(self._target_full_type, self._conversion_type,
                             self._target_full_type, self._uniform_type,
                             explicit, converted_from, conversions)
 
 
 class ZeroSignTestTuple(TestTuple):
diff --git a/generated_tests/templates/gen_conversion/base.mako b/generated_tests/templates/gen_conversion/base.mako
index bcb479f..0dc0819 100644
--- a/generated_tests/templates/gen_conversion/base.mako
+++ b/generated_tests/templates/gen_conversion/base.mako
@@ -1,12 +1,12 @@
 ## coding=utf-8
 <%def name="versioning()"><%
-    if ver == 'GL_ARB_gpu_shader_fp64':
+    if ver == 'GL_ARB_gpu_shader_fp64' or ver == 'GL_ARB_gpu_shader_int64':
         glsl_version_int = '150'
     else:
         glsl_version_int = ver
 
     glsl_version = '{}.{}'.format(glsl_version_int[0], glsl_version_int[1:3])
 
     return (glsl_version, glsl_version_int)
 %></%def>\
 ${next.body()}\
-- 
2.7.4



More information about the Piglit mailing list