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

Tom Stellard tom at stellard.net
Fri Feb 15 06:59:01 PST 2013


On Mon, Feb 11, 2013 at 08:17:47PM -0600, Aaron Watry wrote:
> Hi Tom/List,
> 
> I spent most of Saturday working on cleaning this up based on Tom's first
> round of feedback.  It's not quite finished yet, but once again I just want
> to see if I'm headed in the right direction.
> 
> Before I submit a final patch, I'll go through the comments, try to clean
> up the code a bit, and finish converting all of the existing char test
> cases to be generic tests.  I'm also just learning python, so any coding
> style comments are welcome, but be gentle.
> 
> Changes in v2:
> 1) Generate separate output files for each datatype/function combination.
> 2) Define list of generic tests which can be run for all data types
> 3) Define MIN/MAX placeholders and a list of the min/max values for each
> data type.
> 4) Start refactoring existing test cases to use the MIN/MAX placeholders
> instead of hard-coded values
> 5) Remove the builtins-integer.inc include file...  Everything is now
> generated by the python script.
> 6) Define some built-in functions which can be used to do per-type
> calculations so that we can calculate the expected return values in python
> based on the current data type being processed.
> 7) Define SMIN/SMAX/UMIN/UMAX so that the type of the expected output
> values can be forced in python calculations depending on the expected
> output signed/unsigned type.
> 8) Probably more that I've neglected to mention
> 

I really like the improvements you've made in this version, and I'm looking
forward to seeing the final version of the patch.

-Tom
> 
> 
> 
> 
> On Tue, Feb 5, 2013 at 11:32 AM, Tom Stellard <tom at stellard.net> wrote:
> 
> > On Tue, Feb 05, 2013 at 11:26:38AM -0600, Aaron Watry wrote:
> > > On Tue, Feb 5, 2013 at 9:32 AM, Tom Stellard <tom at stellard.net> wrote:
> > >
> > > > 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.
> > > >
> > > >
> > > I had started by hand-writing the char tests for every built-in, and
> > > decided to come up with different test inputs for each part of a char16
> > > input, which made the first set of test cases fairly verbose when I
> > > converted to the test generator.  Before I submit a final version for
> > > inclusion in piglit, I'll trim down the redundant test inputs.
> > >
> > >
> > >
> > > > > ---
> > > > >  .../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.
> > > >
> > > >
> > > I need to fix this comment a bit.  Technically we only have tests for
> > > vstore/vload on 32-bit int data types at the moment (as far as I see).
> > >
> > >
> > > > > +        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.
> > > >
> > > >
> > > Something like a lookup table or other structure that contains the
> > > function names, number of arguments, signedness of each arg, and whether
> > > mixed scalar/vector arguments are allowed?
> > >
> >
> > I don't think my comment here was clear.  I think the macros defined above
> > can all be in the same file, but the kernel definitions below should go
> > in the builtin specific files.
> >
> > -Tom
> >
> > > I'll change the next version to produce a separate file per data
> > > type/function, but we'll see what form the final code takes to get us
> > > there.  Since the version I sent out yesterday, I've made some progress
> > > that should make this easier.
> > >
> > >
> > > > > +//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.
> > > >
> > >
> > > I'll see what I can do.  I definitely agree about adding [MIN|MAX]_{TYPE}
> > > definitions instead of the magic numbers currently in the code. Adding
> > > 'generic' tests will be a little more work, but it should speed up the
> > > process of writing the short/int/long (and unsigned) tests once it's
> > > completed.
> > >
> > >
> > > >
> > > > > +#       '{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.
> > > >
> > > >
> > > They are redundant.  I'll cut this down to a more sane number of tests.
> > > This is an artifact of my having hand-written 16-wide vector tests and
> > not
> > > wanting to just spam the same values across all components.
> > >
> > >
> > > > > +            ]
> > > > > +        },
> > > > > +        '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.
> > > >
> > > >
> > > Agreed. I'll take care of that.  I'll create one file per data type and
> > > function combination.
> > >
> > > --Aaron
> > >
> > >
> > > > > +    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