[Piglit] [PATCH] Add initial python built-in test generator

Tom Stellard tom at stellard.net
Tue Feb 5 07:32:10 PST 2013


On Mon, Feb 04, 2013 at 01:35:16PM -0600, Aaron Watry wrote:
> Initial version only generates tests for the char data type.

This looks like a good first step, I am impressed with how thorough the tests
are.  I think it is important to try to generate as much stuff as possible,
so whenever there is an opportunity to do this, we should try to take advantage.
I have made a few comments inline.

> ---
>  .../cl/program/execute/builtin/builtin-integer.inc |  291 ++++++++++++++++++++
>  tests/cl/program/execute/builtin/builtins-gen.py   |  272 ++++++++++++++++++
>  2 files changed, 563 insertions(+), 0 deletions(-)
>  create mode 100644 tests/cl/program/execute/builtin/builtin-integer.inc
>  create mode 100755 tests/cl/program/execute/builtin/builtins-gen.py
> 
> diff --git a/tests/cl/program/execute/builtin/builtin-integer.inc b/tests/cl/program/execute/builtin/builtin-integer.inc
> new file mode 100644
> index 0000000..c0d6796
> --- /dev/null
> +++ b/tests/cl/program/execute/builtin/builtin-integer.inc
> @@ -0,0 +1,291 @@
> +typedef T T_TYPE;
> +typedef U U_TYPE;
> +typedef S S_TYPE;
> +
> +/* 
> +   Caveats: 
> +        1) These tests assume that vstore/vload work for the datatype being
> +           tested. There's other tests for this already.

Implementing the vstore / vload builitins are on my TODO list, and I'm hoping
to finish them before the 9.1 release.

> +        2) These tests assume that you're running on a device capable of CL1.1
> +           (e.g. clamp requires 1.1 for int types)
> +*/
> +
> +
> +#define gen_kernel_1_arg(fnName, inType, outType) \
> +kernel void test_##fnName##_scalar(global outType* out, global inType* in){ \
> +  *out = fnName(*in);\
> +} \
> +kernel void test_##fnName##_2(global outType* out, global inType* in){ \
> +  vstore2(fnName(vload2(0, in)), 0, out);\
> +} \
> +kernel void test_##fnName##_4(global outType* out, global inType* in){ \
> +  vstore4(fnName(vload4(0, in)), 0, out);\
> +} \
> +kernel void test_##fnName##_8(global outType* out, global inType* in){ \
> +  vstore8(fnName(vload8(0, in)), 0, out);\
> +} \
> +kernel void test_##fnName##_16(global outType* out, global inType* in){ \
> +  vstore16(fnName(vload16(0, in)), 0, out);\
> +}
> +
> +/* 2 argument kernel with input types that match */
> +
> +#define gen_kernel_2_arg_same_type(fnName, inType, outType) \
> +kernel void test_##fnName##_scalar(global outType* out, global inType* in1, global inType* in2){ \
> +  *out = fnName(*in1, *in2);\
> +} \
> +kernel void test_##fnName##_2(global outType* out, global inType* in1, global inType* in2){ \
> +  vstore2(fnName(vload2(0, in1), vload2(0, in2)), 0, out);\
> +} \
> +kernel void test_##fnName##_4(global outType* out, global inType* in1, global inType* in2){ \
> +  vstore4(fnName(vload4(0, in1), vload4(0, in2)), 0, out);\
> +} \
> +kernel void test_##fnName##_8(global outType* out, global inType* in1, global inType* in2){ \
> +  vstore8(fnName(vload8(0, in1), vload8(0, in2)), 0, out);\
> +} \
> +kernel void test_##fnName##_16(global outType* out, global inType* in1, global inType* in2){ \
> +  vstore16(fnName(vload16(0, in1), vload16(0, in2)), 0, out);\
> +}
> +
> +#define gen_kernel_2_arg_mixed_size(fnName, inType, outType) \
> +kernel void test_##fnName##_tss_2(global outType* out, global inType* in1, global inType* in2){ \
> +  vstore2(fnName(vload2(0, in1), *in2), 0, out);\
> +} \
> +kernel void test_##fnName##_tss_4(global outType* out, global inType* in1, global inType* in2){ \
> +  vstore4(fnName(vload4(0, in1), *in2), 0, out);\
> +} \
> +kernel void test_##fnName##_tss_8(global outType* out, global inType* in1, global inType* in2){ \
> +  vstore8(fnName(vload8(0, in1), *in2), 0, out);\
> +} \
> +kernel void test_##fnName##_tss_16(global outType* out, global inType* in1, global inType* in2){ \
> +  vstore16(fnName(vload16(0, in1), *in2), 0, out);\
> +}
> +
> +
> +/* 3-argument built-in functions */
> +
> +#define gen_kernel_3_arg_same_type(fnName, inType, outType) \
> +kernel void test_##fnName##_scalar(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \
> +  *out = fnName(*in1, *in2, *in3);\
> +} \
> +kernel void test_##fnName##_2(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \
> +  vstore2(fnName(vload2(0, in1), vload2(0, in2), vload2(0, in3)), 0, out);\
> +} \
> +kernel void test_##fnName##_4(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \
> +  vstore4(fnName(vload4(0, in1), vload4(0, in2), vload4(0, in3)), 0, out);\
> +} \
> +kernel void test_##fnName##_8(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \
> +  vstore8(fnName(vload8(0, in1), vload8(0, in2), vload8(0, in3)), 0, out);\
> +} \
> +kernel void test_##fnName##_16(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \
> +  vstore16(fnName(vload16(0, in1), vload16(0, in2), vload16(0, in3)), 0, out);\
> +}
> +
> +#define gen_kernel_3_arg_mixed_size(fnName, inType, outType) \
> +kernel void test_##fnName##_tss_2(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \
> +  vstore2(fnName(vload2(0, in1), vload2(0, in2), vload2(0, in3)), 0, out);\
> +} \
> +kernel void test_##fnName##_tss_4(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \
> +  vstore4(fnName(vload4(0, in1), *in2, *in3), 0, out);\
> +} \
> +kernel void test_##fnName##_tss_8(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \
> +  vstore8(fnName(vload8(0, in1), *in2, *in3), 0, out);\
> +} \
> +kernel void test_##fnName##_tss_16(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \
> +  vstore16(fnName(vload16(0, in1), *in2, *in3), 0, out);\
> +}
> +
> +
> +/*
> +    Actually start defining the kernels for built-in functions
> +*/
> +

If possible, I think it would be a good idea to try to generate these kernel
definitions too.  This would make it easier to have a separate file for each
builtin, which I suggest in a comment below.


> +//Integer Built-in Functions [6.11.3]
> +//T is type char, charn, uchar, ucharn, short, shortn, ushort, ushortn, int, intn, uint, uintn, long, longn, ulong, or ulongn.
> +//U is the unsigned version of T. S is the scalar version of T.
> +
> +//U abs (T x) | x |
> +gen_kernel_1_arg(abs, T, U)
> +
> +//U abs_diff (T x, T y) | x – y | without modulo overflow
> +gen_kernel_2_arg_same_type(abs_diff, T, U);
> +
> +//T add_sat (T x, T y) x + y and saturates the result
> +gen_kernel_2_arg_same_type(add_sat, T, T);
> +
> +//T hadd (T x, T y) (x + y) >> 1 without mod. overflow
> +gen_kernel_2_arg_same_type(hadd, T, T);
> +
> +//T rhadd (T x, T y) (x + y + 1) >> 1
> +gen_kernel_2_arg_same_type(rhadd, T, T);
> +
> +//T clz (T x) Number of leading 0-bits in x
> +gen_kernel_1_arg(clz, T, T);
> +
> +//T clamp (T x, T min, T max)
> +gen_kernel_3_arg_same_type(clamp, T, T);
> +
> +//T clamp (T x, S min, S max) min(max(x, minval), maxval)
> +gen_kernel_3_arg_mixed_size(clamp, T, T);
> +
> +//T mad_hi (T a, T b, T c) mul_hi(a, b) + c
> +gen_kernel_3_arg_same_type(mad_hi, T, T);
> +
> +//T mad_sat (T a, T b, T c) a * b + c and saturates the result
> +gen_kernel_3_arg_same_type(mad_sat, T, T);
> +
> +//T max (T x, T y)
> +gen_kernel_2_arg_same_type(max, T, T);
> +
> +//T max (T x, S y) y if x < y, otherwise it returns x
> +gen_kernel_2_arg_mixed_size(max, T, T);
> +
> +//T min (T x, T y) y if y < x, otherwise it returns x
> +gen_kernel_2_arg_same_type(min, T, T);
> +
> +//T min (T x, S y) y if y < x, otherwise it returns x
> +gen_kernel_2_arg_mixed_size(min, T, T);
> +
> +//T mul_hi (T x, T y) high half of the product of x and y
> +gen_kernel_2_arg_same_type(mul_hi, T, T);
> +
> +//T rotate (T v, T i) result[indx] = v[indx] << i[indx]
> +gen_kernel_2_arg_same_type(rotate, T, T);
> +
> +//T sub_sat (T x, T y) x - y and saturates the result
> +gen_kernel_2_arg_same_type(sub_sat, T, T);
> +
> +//For upsample, scalar types are permitted for the vector types below.
> +//shortn upsample (charn hi, ucharn lo)
> +//result[i]= ((short)hi[i]<< 8) | lo[i]
> +kernel void test_upsample_char_1(global short* out, global char* in1, global uchar* in2){
> +    *out = upsample(*in1, *in2);
> +}
> +kernel void test_upsample_char_2(global short* out, global char* in1, global uchar* in2){
> +    vstore2(upsample(vload2(0, in1), vload2(0,in2)), 0, out);
> +}
> +kernel void test_upsample_char_4(global short* out, global char* in1, global uchar* in2){
> +    vstore4(upsample(vload4(0, in1), vload4(0,in2)), 0, out);
> +}
> +kernel void test_upsample_char_8(global short* out, global char* in1, global uchar* in2){
> +    vstore8(upsample(vload8(0, in1), vload8(0,in2)), 0, out);
> +}
> +kernel void test_upsample_char_16(global short* out, global char* in1, global uchar* in2){
> +    vstore16(upsample(vload16(0, in1), vload16(0,in2)), 0, out);
> +}
> +
> +//ushortn upsample (ucharn hi, ucharn lo)
> +//result[i]=((ushort)hi[i]<< 8) | lo[i]
> +kernel void test_upsample_uchar_1(global ushort* out, global uchar* in1, global uchar* in2){
> +    *out = upsample(*in1, *in2);
> +}
> +kernel void test_upsample_uchar_2(global ushort* out, global uchar* in1, global uchar* in2){
> +    vstore2(upsample(vload2(0, in1), vload2(0,in2)), 0, out);
> +}
> +kernel void test_upsample_uchar_4(global ushort* out, global uchar* in1, global uchar* in2){
> +    vstore4(upsample(vload4(0, in1), vload4(0,in2)), 0, out);
> +}
> +kernel void test_upsample_uchar_8(global ushort* out, global uchar* in1, global uchar* in2){
> +    vstore8(upsample(vload8(0, in1), vload8(0,in2)), 0, out);
> +}
> +kernel void test_upsample_uchar_16(global ushort* out, global uchar* in1, global uchar* in2){
> +    vstore16(upsample(vload16(0, in1), vload16(0,in2)), 0, out);
> +}
> +
> +//intn upsample (shortn hi, ushortn lo)
> +//result[i]=((int)hi[i]<< 16) | lo[i]
> +kernel void test_upsample_short_1(global int* out, global short* in1, global ushort* in2){
> +    *out = upsample(*in1, *in2);
> +}
> +kernel void test_upsample_short_2(global int* out, global short* in1, global ushort* in2){
> +    vstore2(upsample(vload2(0, in1), vload2(0,in2)), 0, out);
> +}
> +kernel void test_upsample_short_4(global int* out, global short* in1, global ushort* in2){
> +    vstore4(upsample(vload4(0, in1), vload4(0,in2)), 0, out);
> +}
> +kernel void test_upsample_short_8(global int* out, global short* in1, global ushort* in2){
> +    vstore8(upsample(vload8(0, in1), vload8(0,in2)), 0, out);
> +}
> +kernel void test_upsample_short_16(global int* out, global short* in1, global ushort* in2){
> +    vstore16(upsample(vload16(0, in1), vload16(0,in2)), 0, out);
> +}
> +
> +//uintn upsample (ushortn hi, ushortn lo)
> +//result[i]=((uint)hi[i]<< 16) | lo[i]
> +kernel void test_upsample_ushort_1(global uint* out, global ushort* in1, global ushort* in2){
> +    *out = upsample(*in1, *in2);
> +}
> +kernel void test_upsample_ushort_2(global uint* out, global ushort* in1, global ushort* in2){
> +    vstore2(upsample(vload2(0, in1), vload2(0,in2)), 0, out);
> +}
> +kernel void test_upsample_ushort_4(global uint* out, global ushort* in1, global ushort* in2){
> +    vstore4(upsample(vload4(0, in1), vload4(0,in2)), 0, out);
> +}
> +kernel void test_upsample_ushort_8(global uint* out, global ushort* in1, global ushort* in2){
> +    vstore8(upsample(vload8(0, in1), vload8(0,in2)), 0, out);
> +}
> +kernel void test_upsample_ushort_16(global uint* out, global ushort* in1, global ushort* in2){
> +    vstore16(upsample(vload16(0, in1), vload16(0,in2)), 0, out);
> +}
> +
> +//longn upsample (intn hi, uintn lo)
> +//result[i]=((long)hi[i]<< 32) | lo[i]
> +kernel void test_upsample_int_1(global long* out, global int* in1, global uint* in2){
> +    *out = upsample(*in1, *in2);
> +}
> +kernel void test_upsample_int_2(global long* out, global int* in1, global uint* in2){
> +    vstore2(upsample(vload2(0, in1), vload2(0,in2)), 0, out);
> +}
> +kernel void test_upsample_int_4(global long* out, global int* in1, global uint* in2){
> +    vstore4(upsample(vload4(0, in1), vload4(0,in2)), 0, out);
> +}
> +kernel void test_upsample_int_8(global long* out, global int* in1, global uint* in2){
> +    vstore8(upsample(vload8(0, in1), vload8(0,in2)), 0, out);
> +}
> +kernel void test_upsample_int_16(global long* out, global int* in1, global uint* in2){
> +    vstore16(upsample(vload16(0, in1), vload16(0,in2)), 0, out);
> +}
> +
> +//ulongn upsample (uintn hi, uintn lo)
> +//result[i]=((ulong)hi[i]<< 32) | lo[i]
> +kernel void test_upsample_uint_1(global ulong* out, global uint* in1, global uint* in2){
> +    *out = upsample(*in1, *in2);
> +}
> +kernel void test_upsample_uint_2(global ulong* out, global uint* in1, global uint* in2){
> +    vstore2(upsample(vload2(0, in1), vload2(0,in2)), 0, out);
> +}
> +kernel void test_upsample_uint_4(global ulong* out, global uint* in1, global uint* in2){
> +    vstore4(upsample(vload4(0, in1), vload4(0,in2)), 0, out);
> +}
> +kernel void test_upsample_uint_8(global ulong* out, global uint* in1, global uint* in2){
> +    vstore8(upsample(vload8(0, in1), vload8(0,in2)), 0, out);
> +}
> +kernel void test_upsample_uint_16(global ulong* out, global uint* in1, global uint* in2){
> +    vstore16(upsample(vload16(0, in1), vload16(0,in2)), 0, out);
> +}
> +
> +/*
> +//The following fast integer functions optimize the performance
> +//of kernels. In these functions, T is type int, int2, int3, int4, int8, int16, uint, uint2, uint4, uint8 or uint16.
> +
> +//T mad24 (T a, T b, T c) Multiply 24-bit int. values a, b, add 32-bit int. result to 32-bit int. c
> +//gen_kernel_3_arg_same_type(mad24, T, T);
> +
> +//T mul24 (T a, T b) Multiply 24-bit int. values a and b
> +//gen_kernel_2_arg_same_type(mul24, T, T);
> +
> +//TODO:
> +//For the upsample functions, put them in the file responsible for testing the 
> +//first argument type: e.g. shortN upsample(charN hi, ucharN lo) goes in char tests.
> +//shortn upsample (charn hi, ucharn lo)
> +//ushortn upsample (ucharn hi, ucharn lo)
> +//intn upsample (shortn hi, ushortn lo)
> +//uintn upsample (ushortn hi, ushortn lo)
> +//longn upsample (intn hi, uintn lo)
> +//ulongn upsample (uintn hi, uintn lo)
> +
> +//Put these in the signed int test file.
> +//T mad24 (T a, T b, T c) Multiply 24-bit int. values a, b, add 32-bit int. result to 32-bit int. c
> +//T mul24 (T a, T b) Multiply 24-bit int. values a and b
> +
> +*/
> \ No newline at end of file
> diff --git a/tests/cl/program/execute/builtin/builtins-gen.py b/tests/cl/program/execute/builtin/builtins-gen.py
> new file mode 100755
> index 0000000..40b03d1
> --- /dev/null
> +++ b/tests/cl/program/execute/builtin/builtins-gen.py
> @@ -0,0 +1,272 @@
> +#!/usr/bin/python
> +
> +#The following is a data structure of the following:
> +# builtins = {
> +#   '{data_type}': { #data type is any of char, uchar, short, ushort, int, uint, long, ulong

How about adding a 'generic' data type that is used to generate tests
for all types?  This would allow to specify one test that could be run
on all data types and then you can add type-specific tests as needed.
You might even be able to use this for testing edge cases, by creating
a MAX_INT / MIN_INT value that is understood by the script to mean
substitute the maximum /minimum value for this type.

> +#       '{builtin_function_name}': {
> +#           'arg_types': ['{data_type}', '{data_type}', ...],
> +#           'function_type': 'ttt'|'tss',
> +#                           #ttt = all arguments are same-length vectors
> +#                           #tss = all arguments are either same-length vectors, or a vector followed by scalars
> +#           'values': [
> +#               [array of test output (arg0) values],
> +#               [array of arg1 values],
> +#               [array of arg2 values],
> +#               ...
> +#           ]
> +#       },
> +#       '{next_function}': {...},
> +#       ...
> +#   },
> +#   '{next_type}': {...},
> +#   ...
> +# }
> +
> +# Need to create an outer associative array
> +# Will need several sets for vector/scalar input types (ttt/tss function)
> +builtins = {
> +    'char': {
> +        'abs': {
> +            'arg_types': ['uchar', 'char'],
> +            'function_type': 'ttt',
> +            'values': [
> +              [0,  1, 2,  3, 4,  5, 6,  7, 8,  9, 10,  11, 12,  13,  128, 127], 
> +              [0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, -128, 127]

I think some of these tests are redundant.  It should be sufficient
to test the edge cases (i.e. for abs() -1, 0, 1, MAX_INT, MIN_INT)
plus one generic cases for each class of inputs (for abs() this would
be one positive integer and one negative integer).  Actually for abs()
it is probably debatable whether or not -1 and 1 are edge cases and I
think that abs(MIN_INT) so maybe there can be less edge cases.

> +            ]
> +        },
> +        'abs_diff': {
> +            'arg_types': ['uchar','char','char'],
> +            'function_type': 'ttt',
> +            'values': [
> +               [15, 13, 11, 10,  8,  5,  3,  1,  1,  3,  5,  7,  9, 11,  255,  255],
> +               [-8, -7, -6, -6, -5, -3, -2, -1,  0,  1,  2,  3,  4,  5, -128,  127],
> +               [ 7,  6,  5,  4,  3,  2,  1,  0, -1, -2, -3, -4, -5, -6,  127, -128]
> +            ]
> +        },
> +        'add_sat': {
> +            'arg_types': ['char','char','char'],
> +            'function_type': 'ttt',
> +            'values': [
> +               [  0, -2, 13,  64, -128, 127, 127, -128,   0, -2, 13,  64, -128, 127, 127, -128],
> +               [ 32, -8, -7, 127, -120, 127, 100, -100,  32, -8, -7, 127, -120, 127, 100, -100],
> +               [-32,  6, 20, -63,  -12,  64,  50,  -50, -32,  6, 20, -63,  -12,  64,  50,  -50]
> +            ]
> +        },
> +        'hadd': {
> +            'arg_types': ['char','char','char'],
> +            'function_type': 'ttt',
> +            'values': [
> +                [32, 0, -33, 10, 32, 0, -33, 10, 32, 0, -33, 10, 32, 0, -33, 10],
> +                [32, 1, -33, 12, 32, 1, -33, 12, 32, 1, -33, 12, 32, 1, -33, 12],
> +                [33, 0, -32,  8, 33, 0, -32,  8, 33, 0, -32,  8, 33, 0, -32,  8]
> +            ]
> +        },
> +        'rhadd': {
> +            'arg_types': ['char','char','char'],
> +            'function_type': 'ttt',
> +            'values': [
> +                [33, 1, -32, 10, 33, 1, -32, 10, 33, 1, -32, 10, 33, 1, -32, 10],
> +                [32, 1, -33, 12, 32, 1, -33, 12, 32, 1, -33, 12, 32, 1, -33, 12],
> +                [33, 0, -32,  8, 33, 0, -32,  8, 33, 0, -32,  8, 33, 0, -32,  8]
> +            ]
> +        },
> +        'clz': {
> +            'arg_types': ['char', 'char'],
> +            'function_type': 'ttt',
> +            'values': [
> +                [ 2,  1, 8,  0,  2,  1, 8,  0,  2,  1, 8,  0,  2,  1, 8,  0],
> +                [32, 64, 0, -1, 32, 64, 0, -1, 32, 64, 0, -1, 32, 64, 0, -1]
> +            ]
> +        },
> +        'clamp': {
> +            'arg_types': ['char','char','char','char'],
> +            'function_type': 'ttt',
> +            'values': [
> +                [64,  -64,  1,  0, 64,  -64,  1,  0, 64,  -64,  1,  0, 64,  -64,  1,  0],
> +                [92, -128, 64, -1, 92, -128, 64, -1, 92, -128, 64, -1, 92, -128, 64, -1],
> +                [ 0,  -64,  0,  0,  0,  -64,  0,  0,  0,  -64,  0,  0,  0,  -64,  0,  0],
> +                [64,    0,  1,  1, 64,    0,  1,  1, 64,    0,  1,  1, 64,    0,  1,  1]
> +            ]
> +        },
> +        'mad_hi': {
> +            'arg_types': ['char','char','char','char'],
> +            'function_type': 'ttt',
> +            'values': [
> +                [ 0, -128,  1,    1,  4,   1,    0, -66,  -64,   63,  1, 0, 2,   -2, 0, 0],
> +                [92,   -1, 64, -128, 12, 127, -128, 127, -128, -128, 92, 0, 127,  1, 0, 0],
> +                [ 2, -128,  1,    2,  4,   1,    1, 127, -128,  127,  1, 0, 2,   -1, 0, 0],
> +                [ 0, -128,  1,    2,  4,   1,    1, 127, -128,  127,  1, 0, 2,   -1, 0, 0]
> +            ]
> +        },
> +        'mad_sat': {
> +            'arg_types': ['char','char','char','char'],
> +            'function_type': 'ttt',
> +            'values': [
> +                [127,    0, 65, -128, 52, 127, -128, 127,  127, -128, 93, 0, 127, -2, -128, 127],
> +                [ 92,   -1, 64, -128, 12, 127, -128, 127, -128, -128, 92, 0, 127,  1, -128, 127],
> +                [  2, -128,  1,    2,  4,   1,    1, 127, -128,  127,  1, 0,   2, -1,    1, 127],
> +                [  0, -128,  1,    2,  4,   1,   -1, 127, -128,  127,  1, 0,   2, -1,   -1, 127]
> +            ]
> +        },
> +        'max': {
> +            'arg_types': ['char', 'char', 'char'],
> +            'function_type': 'tss',
> +            'values': [
> +                [92,   -1, 64,    2, 12, 127,    1, 127, -128,  127, 92, 0, 127,  1,    1, 127],
> +                [92,   -1, 64,    2, 12, 127, -128, 127, -128, -128, 92, 0, 127,  1, -128, 127],
> +                [ 2, -128,  1, -128,  4,   1,    1, 127, -128,  127,  1, 0,   2, -1,    1, 127]         
> +            ]
> +        },
> +        'min': {
> +            'arg_types': ['char', 'char', 'char'],
> +            'function_type': 'tss',
> +            'values': [
> +                [ 2, -128,  1, -128,  4,   1, -128, 127, -128, -128,  1, 0,   2, -1, -128, 127],
> +                [92,   -1, 64,    2, 12, 127, -128, 127, -128, -128, 92, 0, 127,  1, -128, 127],
> +                [ 2, -128,  1, -128,  4,   1,    1, 127, -128,  127,  1, 0,   2, -1,    1, 127]
> +            ]
> +        },
> +        'mul_hi': {
> +            'arg_types': ['char','char','char'],
> +            'function_type': 'ttt',
> +            'values': [
> +                [ 0,    0,  0,   -1,  0,   0,   -1,  63,   64,  -64,  0, 0,   0, -1, 0, 0],
> +                [92,   -1, 64, -128, 12, 127, -128, 127, -128, -128, 92, 0, 127,  1, 0, 0],
> +                [ 2, -128,  1,    2,  4,   1,    1, 127, -128,  127,  1, 0,   2, -1, 0, 0]
> +            ]
> +        },
> +        'rotate': {
> +            'arg_types': ['char','char','char'],
> +            'function_type': 'ttt',
> +            'values': [
> +                [1, 2, 4, 8, 16, 32, 64, -128, 1, 2,  4,  8, 16, 32, 64,  1, 1, -128, 64, 32, 16,  8,  4,  2,  1,  -128,  64,  32,  16,   8,   4,   1],
> +                [1, 1, 1, 1,  1,  1,  1,    1, 1, 1,  1,  1,  1,  1,  1,  1, 1,    1,  1,  1,  1,  1,  1,  1,  1,     1,   1,   1,   1,   1,   1,   1],
> +                [0, 1, 2, 3,  4,  5,  6,    7, 8, 9, 10, 11, 12, 13, 14, 80, 0,   -1, -2, -3, -4, -5, -6, -7, -8,    -9, -10, -11, -12, -13, -14, -80]
> +            ]
> +        },
> +        'sub_sat': {
> +            'arg_types': ['char','char','char'],
> +            'function_type': 'ttt',
> +            'values': [
> +                [1,  2,  3, -128, 127,  127,  7,  8,  9, 10,  11,  12,  13,  14,  15,  81],
> +                [1,  1,  1,  -64, 120,  127,  1,  1,  1,  1,   1,   1,   1,   1,   1,   1],
> +                [0, -1, -2,   64, -32, -128, -6, -7, -8, -9, -10, -11, -12, -13, -14, -80]
> +            ]
> +        },
> +        'upsample': {
> +            'arg_types': ['short','char','uchar'],
> +            'function_type': 'ttt',
> +            'values': [
> +                [256, 257,  -1, 32767, 0, 127, -256, 263, 264, 265, 266, 11, 268, 269, 270, 336],
> +                [  1,   1,  -1,   127, 0,   0,   -1,   1,   1,   1,   1,  0,   1,   1,   1,   1],
> +                [  0,   1, 255,   255, 0, 127,    0,   7,   8,   9,  10, 11,  12,  13,  14,  80]
> +            ]
> +        }
> +    } #End of char tests
> +}
> +
> +#By default, let's just test what is part of the CL1.1 stock spec, leave vec3 for later
> +#vector_widths = (2, 3, 4, 8, 16)
> +vector_widths = (2, 4, 8, 16)
> +
> +#### Define helper functions ####
> +
> +def print_test(f, fnName, fnSuffix, argType, argCount, tests, testIdx, vecSize):
> +    f.write('[test]\n' + \
> +        'name: ' + fnName + ' ' + argType + str(vecSize) + '\n' + \
> +        'kernel_name: test_' + fnName + '_' + fnSuffix + \
> +        '\n'
> +    )
> +
> +    for arg in range(0, argCount):
> +        argInOut = ''
> +        if arg == 0:
> +            argInOut = 'arg_out: '
> +        else:
> +            argInOut = 'arg_in: '
> +        argVal = str(tests[arg][testIdx])
> +        f.write(argInOut + str(arg) + ' buffer ' + argTypes[arg] + \
> +            '[' + str(vecSize) + '] ' + \
> +            ' '.join([argVal]*vecSize) + \
> +            '\n'
> +        )
> +
> +    #Blank line between tests for formatting clarity
> +    f.write('\n')
> +
> +
> +#Print a test with both all-vector inputs/outputs, and mixed vector/scalar args
> +def print_test_tss(f, fnName, fnSuffix, argType, argCount, tests, testIdx, vecSize):
> +    #Print test using all vector inputs
> +    print_test(f, fnName, fnSuffix, argType, argCount, tests, testIdx, vecSize)
> +    
> +    #Print test using mixed vector/scalar inputs
> +    f.write('[test]\n' + \
> +        'name: ' + fnName + ' ' + argType + str(vecSize) + '\n' + \
> +        'kernel_name: test_' + fnName + '_tss_' + fnSuffix + \
> +        '\n'
> +    )
> +
> +    for arg in range(0, argCount):
> +        argInOut = ''
> +        argVal = str(tests[arg][testIdx])
> +        if arg == 0:
> +            argInOut = 'arg_out: '
> +            f.write(argInOut + str(arg) + ' buffer ' + argTypes[arg] + \
> +                '[' + str(vecSize) + '] ' + \
> +                ' '.join([argVal]*vecSize) + \
> +                '\n'
> +            )
> +        else:
> +            argInOut = 'arg_in: '
> +            f.write(argInOut + str(arg) + ' buffer ' + argTypes[arg] + \
> +                '[1] ' + argVal + '\n'
> +            )
> +
> +    #Blank line between tests for formatting reasons
> +    f.write('\n')
> +
> +
> +#### Main logic start ####
> +
> +#Loop over all data types being tested. Create one output file per data type
> +for argType in builtins.keys():
> +    functions = builtins[argType]
> +    filename = 'builtin-' + argType +'-1.1.python_generated.program_test'

As I mentioned above, I think there should be one program_test file per
builtin, or even one file per builtin/argType combination.  This will help keep
things more organized and make it easier to identify and debug failing tests.

> +    f = open(filename, 'w')
> +    #Write the file header
> +    f.write( \
> +        '[config]\n' + \
> +        'name: '+argType+'-based built-in tests for CL 1.1\n'+ \
> +        'clc_version_min: 11\n' + \
> +        'dimensions: 1\n' + \
> +        'global_size: 1 0 0\n' + \
> +        'program_source_file: builtin-integer.inc\n' + \
> +        'build_options: -D U=u'+argType+' -D S='+argType+' -D T='+argType+'\n\n'
> +    )
> +
> +    #Write all tests for each built-in function
> +    for fnName in sorted(functions.keys()):
> +        functionDef = functions[fnName]
> +        tests = functionDef['values']
> +        argCount = len(functionDef['arg_types'])
> +        argTypes = functionDef['arg_types']
> +        fnType = functionDef['function_type']
> +        
> +        outputValues = tests[0]
> +        numTests = len(outputValues)
> +
> +        #Handle scalar tests
> +        for testIdx in range(0, numTests):
> +            print_test(f, fnName, 'scalar', argType, argCount, tests, testIdx, 1)
> +        
> +        #Handle all available vector widths
> +        for vecSize in sorted(vector_widths):            
> +            for testIdx in range(0, numTests):
> +                if fnType == 'tss':
> +                    print_test_tss(f, fnName, str(vecSize), argType, argCount, tests, testIdx, vecSize)
> +                else:
> +                    print_test(f, fnName, str(vecSize), argType, argCount, tests, testIdx, vecSize)
> +    
> +    #Hopefully this next part is obvious :)
> +    f.close()
> -- 
> 1.7.4.4
> 
> _______________________________________________
> Piglit mailing list
> Piglit at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/piglit


More information about the Piglit mailing list