<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Feb 5, 2013 at 9:32 AM, Tom Stellard <span dir="ltr"><<a href="mailto:tom@stellard.net" target="_blank">tom@stellard.net</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Mon, Feb 04, 2013 at 01:35:16PM -0600, Aaron Watry wrote:<br>
> Initial version only generates tests for the char data type.<br>
<br>
</div>This looks like a good first step, I am impressed with how thorough the tests<br>
are.  I think it is important to try to generate as much stuff as possible,<br>
so whenever there is an opportunity to do this, we should try to take advantage.<br>
I have made a few comments inline.<br>
<div class="im"><br></div></blockquote><div><br></div><div>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.<br>
</div><div><br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
> ---<br>
>  .../cl/program/execute/builtin/builtin-integer.inc |  291 ++++++++++++++++++++<br>
>  tests/cl/program/execute/builtin/builtins-gen.py   |  272 ++++++++++++++++++<br>
>  2 files changed, 563 insertions(+), 0 deletions(-)<br>
>  create mode 100644 tests/cl/program/execute/builtin/builtin-integer.inc<br>
>  create mode 100755 tests/cl/program/execute/builtin/builtins-gen.py<br>
><br>
> diff --git a/tests/cl/program/execute/builtin/builtin-integer.inc b/tests/cl/program/execute/builtin/builtin-integer.inc<br>
> new file mode 100644<br>
> index 0000000..c0d6796<br>
> --- /dev/null<br>
> +++ b/tests/cl/program/execute/builtin/builtin-integer.inc<br>
> @@ -0,0 +1,291 @@<br>
> +typedef T T_TYPE;<br>
> +typedef U U_TYPE;<br>
> +typedef S S_TYPE;<br>
> +<br>
> +/*<br>
> +   Caveats:<br>
> +        1) These tests assume that vstore/vload work for the datatype being<br>
> +           tested. There's other tests for this already.<br>
<br>
</div>Implementing the vstore / vload builitins are on my TODO list, and I'm hoping<br>
to finish them before the 9.1 release.<br>
<div><div class="h5"><br></div></div></blockquote><div><br></div><div>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).<br></div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
> +        2) These tests assume that you're running on a device capable of CL1.1<br>
> +           (e.g. clamp requires 1.1 for int types)<br>
> +*/<br>
> +<br>
> +<br>
> +#define gen_kernel_1_arg(fnName, inType, outType) \<br>
> +kernel void test_##fnName##_scalar(global outType* out, global inType* in){ \<br>
> +  *out = fnName(*in);\<br>
> +} \<br>
> +kernel void test_##fnName##_2(global outType* out, global inType* in){ \<br>
> +  vstore2(fnName(vload2(0, in)), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_4(global outType* out, global inType* in){ \<br>
> +  vstore4(fnName(vload4(0, in)), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_8(global outType* out, global inType* in){ \<br>
> +  vstore8(fnName(vload8(0, in)), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_16(global outType* out, global inType* in){ \<br>
> +  vstore16(fnName(vload16(0, in)), 0, out);\<br>
> +}<br>
> +<br>
> +/* 2 argument kernel with input types that match */<br>
> +<br>
> +#define gen_kernel_2_arg_same_type(fnName, inType, outType) \<br>
> +kernel void test_##fnName##_scalar(global outType* out, global inType* in1, global inType* in2){ \<br>
> +  *out = fnName(*in1, *in2);\<br>
> +} \<br>
> +kernel void test_##fnName##_2(global outType* out, global inType* in1, global inType* in2){ \<br>
> +  vstore2(fnName(vload2(0, in1), vload2(0, in2)), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_4(global outType* out, global inType* in1, global inType* in2){ \<br>
> +  vstore4(fnName(vload4(0, in1), vload4(0, in2)), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_8(global outType* out, global inType* in1, global inType* in2){ \<br>
> +  vstore8(fnName(vload8(0, in1), vload8(0, in2)), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_16(global outType* out, global inType* in1, global inType* in2){ \<br>
> +  vstore16(fnName(vload16(0, in1), vload16(0, in2)), 0, out);\<br>
> +}<br>
> +<br>
> +#define gen_kernel_2_arg_mixed_size(fnName, inType, outType) \<br>
> +kernel void test_##fnName##_tss_2(global outType* out, global inType* in1, global inType* in2){ \<br>
> +  vstore2(fnName(vload2(0, in1), *in2), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_tss_4(global outType* out, global inType* in1, global inType* in2){ \<br>
> +  vstore4(fnName(vload4(0, in1), *in2), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_tss_8(global outType* out, global inType* in1, global inType* in2){ \<br>
> +  vstore8(fnName(vload8(0, in1), *in2), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_tss_16(global outType* out, global inType* in1, global inType* in2){ \<br>
> +  vstore16(fnName(vload16(0, in1), *in2), 0, out);\<br>
> +}<br>
> +<br>
> +<br>
> +/* 3-argument built-in functions */<br>
> +<br>
> +#define gen_kernel_3_arg_same_type(fnName, inType, outType) \<br>
> +kernel void test_##fnName##_scalar(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \<br>
> +  *out = fnName(*in1, *in2, *in3);\<br>
> +} \<br>
> +kernel void test_##fnName##_2(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \<br>
> +  vstore2(fnName(vload2(0, in1), vload2(0, in2), vload2(0, in3)), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_4(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \<br>
> +  vstore4(fnName(vload4(0, in1), vload4(0, in2), vload4(0, in3)), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_8(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \<br>
> +  vstore8(fnName(vload8(0, in1), vload8(0, in2), vload8(0, in3)), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_16(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \<br>
> +  vstore16(fnName(vload16(0, in1), vload16(0, in2), vload16(0, in3)), 0, out);\<br>
> +}<br>
> +<br>
> +#define gen_kernel_3_arg_mixed_size(fnName, inType, outType) \<br>
> +kernel void test_##fnName##_tss_2(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \<br>
> +  vstore2(fnName(vload2(0, in1), vload2(0, in2), vload2(0, in3)), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_tss_4(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \<br>
> +  vstore4(fnName(vload4(0, in1), *in2, *in3), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_tss_8(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \<br>
> +  vstore8(fnName(vload8(0, in1), *in2, *in3), 0, out);\<br>
> +} \<br>
> +kernel void test_##fnName##_tss_16(global outType* out, global inType* in1, global inType* in2, global inType* in3){ \<br>
> +  vstore16(fnName(vload16(0, in1), *in2, *in3), 0, out);\<br>
> +}<br>
> +<br>
> +<br>
> +/*<br>
> +    Actually start defining the kernels for built-in functions<br>
> +*/<br>
> +<br>
<br>
</div></div>If possible, I think it would be a good idea to try to generate these kernel<br>
definitions too.  This would make it easier to have a separate file for each<br>
builtin, which I suggest in a comment below.<br>
<div><div class="h5"><br>
<br></div></div></blockquote><div>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?<br>
<br></div><div>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.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
> +//Integer Built-in Functions [6.11.3]<br>
> +//T is type char, charn, uchar, ucharn, short, shortn, ushort, ushortn, int, intn, uint, uintn, long, longn, ulong, or ulongn.<br>
> +//U is the unsigned version of T. S is the scalar version of T.<br>
> +<br>
> +//U abs (T x) | x |<br>
> +gen_kernel_1_arg(abs, T, U)<br>
> +<br>
> +//U abs_diff (T x, T y) | x – y | without modulo overflow<br>
> +gen_kernel_2_arg_same_type(abs_diff, T, U);<br>
> +<br>
> +//T add_sat (T x, T y) x + y and saturates the result<br>
> +gen_kernel_2_arg_same_type(add_sat, T, T);<br>
> +<br>
> +//T hadd (T x, T y) (x + y) >> 1 without mod. overflow<br>
> +gen_kernel_2_arg_same_type(hadd, T, T);<br>
> +<br>
> +//T rhadd (T x, T y) (x + y + 1) >> 1<br>
> +gen_kernel_2_arg_same_type(rhadd, T, T);<br>
> +<br>
> +//T clz (T x) Number of leading 0-bits in x<br>
> +gen_kernel_1_arg(clz, T, T);<br>
> +<br>
> +//T clamp (T x, T min, T max)<br>
> +gen_kernel_3_arg_same_type(clamp, T, T);<br>
> +<br>
> +//T clamp (T x, S min, S max) min(max(x, minval), maxval)<br>
> +gen_kernel_3_arg_mixed_size(clamp, T, T);<br>
> +<br>
> +//T mad_hi (T a, T b, T c) mul_hi(a, b) + c<br>
> +gen_kernel_3_arg_same_type(mad_hi, T, T);<br>
> +<br>
> +//T mad_sat (T a, T b, T c) a * b + c and saturates the result<br>
> +gen_kernel_3_arg_same_type(mad_sat, T, T);<br>
> +<br>
> +//T max (T x, T y)<br>
> +gen_kernel_2_arg_same_type(max, T, T);<br>
> +<br>
> +//T max (T x, S y) y if x < y, otherwise it returns x<br>
> +gen_kernel_2_arg_mixed_size(max, T, T);<br>
> +<br>
> +//T min (T x, T y) y if y < x, otherwise it returns x<br>
> +gen_kernel_2_arg_same_type(min, T, T);<br>
> +<br>
> +//T min (T x, S y) y if y < x, otherwise it returns x<br>
> +gen_kernel_2_arg_mixed_size(min, T, T);<br>
> +<br>
> +//T mul_hi (T x, T y) high half of the product of x and y<br>
> +gen_kernel_2_arg_same_type(mul_hi, T, T);<br>
> +<br>
> +//T rotate (T v, T i) result[indx] = v[indx] << i[indx]<br>
> +gen_kernel_2_arg_same_type(rotate, T, T);<br>
> +<br>
> +//T sub_sat (T x, T y) x - y and saturates the result<br>
> +gen_kernel_2_arg_same_type(sub_sat, T, T);<br>
> +<br>
> +//For upsample, scalar types are permitted for the vector types below.<br>
> +//shortn upsample (charn hi, ucharn lo)<br>
> +//result[i]= ((short)hi[i]<< 8) | lo[i]<br>
> +kernel void test_upsample_char_1(global short* out, global char* in1, global uchar* in2){<br>
> +    *out = upsample(*in1, *in2);<br>
> +}<br>
> +kernel void test_upsample_char_2(global short* out, global char* in1, global uchar* in2){<br>
> +    vstore2(upsample(vload2(0, in1), vload2(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_char_4(global short* out, global char* in1, global uchar* in2){<br>
> +    vstore4(upsample(vload4(0, in1), vload4(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_char_8(global short* out, global char* in1, global uchar* in2){<br>
> +    vstore8(upsample(vload8(0, in1), vload8(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_char_16(global short* out, global char* in1, global uchar* in2){<br>
> +    vstore16(upsample(vload16(0, in1), vload16(0,in2)), 0, out);<br>
> +}<br>
> +<br>
> +//ushortn upsample (ucharn hi, ucharn lo)<br>
> +//result[i]=((ushort)hi[i]<< 8) | lo[i]<br>
> +kernel void test_upsample_uchar_1(global ushort* out, global uchar* in1, global uchar* in2){<br>
> +    *out = upsample(*in1, *in2);<br>
> +}<br>
> +kernel void test_upsample_uchar_2(global ushort* out, global uchar* in1, global uchar* in2){<br>
> +    vstore2(upsample(vload2(0, in1), vload2(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_uchar_4(global ushort* out, global uchar* in1, global uchar* in2){<br>
> +    vstore4(upsample(vload4(0, in1), vload4(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_uchar_8(global ushort* out, global uchar* in1, global uchar* in2){<br>
> +    vstore8(upsample(vload8(0, in1), vload8(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_uchar_16(global ushort* out, global uchar* in1, global uchar* in2){<br>
> +    vstore16(upsample(vload16(0, in1), vload16(0,in2)), 0, out);<br>
> +}<br>
> +<br>
> +//intn upsample (shortn hi, ushortn lo)<br>
> +//result[i]=((int)hi[i]<< 16) | lo[i]<br>
> +kernel void test_upsample_short_1(global int* out, global short* in1, global ushort* in2){<br>
> +    *out = upsample(*in1, *in2);<br>
> +}<br>
> +kernel void test_upsample_short_2(global int* out, global short* in1, global ushort* in2){<br>
> +    vstore2(upsample(vload2(0, in1), vload2(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_short_4(global int* out, global short* in1, global ushort* in2){<br>
> +    vstore4(upsample(vload4(0, in1), vload4(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_short_8(global int* out, global short* in1, global ushort* in2){<br>
> +    vstore8(upsample(vload8(0, in1), vload8(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_short_16(global int* out, global short* in1, global ushort* in2){<br>
> +    vstore16(upsample(vload16(0, in1), vload16(0,in2)), 0, out);<br>
> +}<br>
> +<br>
> +//uintn upsample (ushortn hi, ushortn lo)<br>
> +//result[i]=((uint)hi[i]<< 16) | lo[i]<br>
> +kernel void test_upsample_ushort_1(global uint* out, global ushort* in1, global ushort* in2){<br>
> +    *out = upsample(*in1, *in2);<br>
> +}<br>
> +kernel void test_upsample_ushort_2(global uint* out, global ushort* in1, global ushort* in2){<br>
> +    vstore2(upsample(vload2(0, in1), vload2(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_ushort_4(global uint* out, global ushort* in1, global ushort* in2){<br>
> +    vstore4(upsample(vload4(0, in1), vload4(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_ushort_8(global uint* out, global ushort* in1, global ushort* in2){<br>
> +    vstore8(upsample(vload8(0, in1), vload8(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_ushort_16(global uint* out, global ushort* in1, global ushort* in2){<br>
> +    vstore16(upsample(vload16(0, in1), vload16(0,in2)), 0, out);<br>
> +}<br>
> +<br>
> +//longn upsample (intn hi, uintn lo)<br>
> +//result[i]=((long)hi[i]<< 32) | lo[i]<br>
> +kernel void test_upsample_int_1(global long* out, global int* in1, global uint* in2){<br>
> +    *out = upsample(*in1, *in2);<br>
> +}<br>
> +kernel void test_upsample_int_2(global long* out, global int* in1, global uint* in2){<br>
> +    vstore2(upsample(vload2(0, in1), vload2(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_int_4(global long* out, global int* in1, global uint* in2){<br>
> +    vstore4(upsample(vload4(0, in1), vload4(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_int_8(global long* out, global int* in1, global uint* in2){<br>
> +    vstore8(upsample(vload8(0, in1), vload8(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_int_16(global long* out, global int* in1, global uint* in2){<br>
> +    vstore16(upsample(vload16(0, in1), vload16(0,in2)), 0, out);<br>
> +}<br>
> +<br>
> +//ulongn upsample (uintn hi, uintn lo)<br>
> +//result[i]=((ulong)hi[i]<< 32) | lo[i]<br>
> +kernel void test_upsample_uint_1(global ulong* out, global uint* in1, global uint* in2){<br>
> +    *out = upsample(*in1, *in2);<br>
> +}<br>
> +kernel void test_upsample_uint_2(global ulong* out, global uint* in1, global uint* in2){<br>
> +    vstore2(upsample(vload2(0, in1), vload2(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_uint_4(global ulong* out, global uint* in1, global uint* in2){<br>
> +    vstore4(upsample(vload4(0, in1), vload4(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_uint_8(global ulong* out, global uint* in1, global uint* in2){<br>
> +    vstore8(upsample(vload8(0, in1), vload8(0,in2)), 0, out);<br>
> +}<br>
> +kernel void test_upsample_uint_16(global ulong* out, global uint* in1, global uint* in2){<br>
> +    vstore16(upsample(vload16(0, in1), vload16(0,in2)), 0, out);<br>
> +}<br>
> +<br>
> +/*<br>
> +//The following fast integer functions optimize the performance<br>
> +//of kernels. In these functions, T is type int, int2, int3, int4, int8, int16, uint, uint2, uint4, uint8 or uint16.<br>
> +<br>
> +//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<br>
> +//gen_kernel_3_arg_same_type(mad24, T, T);<br>
> +<br>
> +//T mul24 (T a, T b) Multiply 24-bit int. values a and b<br>
> +//gen_kernel_2_arg_same_type(mul24, T, T);<br>
> +<br>
> +//TODO:<br>
> +//For the upsample functions, put them in the file responsible for testing the<br>
> +//first argument type: e.g. shortN upsample(charN hi, ucharN lo) goes in char tests.<br>
> +//shortn upsample (charn hi, ucharn lo)<br>
> +//ushortn upsample (ucharn hi, ucharn lo)<br>
> +//intn upsample (shortn hi, ushortn lo)<br>
> +//uintn upsample (ushortn hi, ushortn lo)<br>
> +//longn upsample (intn hi, uintn lo)<br>
> +//ulongn upsample (uintn hi, uintn lo)<br>
> +<br>
> +//Put these in the signed int test file.<br>
> +//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<br>
> +//T mul24 (T a, T b) Multiply 24-bit int. values a and b<br>
> +<br>
> +*/<br>
> \ No newline at end of file<br>
> diff --git a/tests/cl/program/execute/builtin/builtins-gen.py b/tests/cl/program/execute/builtin/builtins-gen.py<br>
> new file mode 100755<br>
> index 0000000..40b03d1<br>
> --- /dev/null<br>
> +++ b/tests/cl/program/execute/builtin/builtins-gen.py<br>
> @@ -0,0 +1,272 @@<br>
> +#!/usr/bin/python<br>
> +<br>
> +#The following is a data structure of the following:<br>
> +# builtins = {<br>
> +#   '{data_type}': { #data type is any of char, uchar, short, ushort, int, uint, long, ulong<br>
<br>
</div></div>How about adding a 'generic' data type that is used to generate tests<br>
for all types?  This would allow to specify one test that could be run<br>
on all data types and then you can add type-specific tests as needed.<br>
You might even be able to use this for testing edge cases, by creating<br>
a MAX_INT / MIN_INT value that is understood by the script to mean<br>
substitute the maximum /minimum value for this type.<br></blockquote><div><br></div><div>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.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5"><br>
> +#       '{builtin_function_name}': {<br>
> +#           'arg_types': ['{data_type}', '{data_type}', ...],<br>
> +#           'function_type': 'ttt'|'tss',<br>
> +#                           #ttt = all arguments are same-length vectors<br>
> +#                           #tss = all arguments are either same-length vectors, or a vector followed by scalars<br>
> +#           'values': [<br>
> +#               [array of test output (arg0) values],<br>
> +#               [array of arg1 values],<br>
> +#               [array of arg2 values],<br>
> +#               ...<br>
> +#           ]<br>
> +#       },<br>
> +#       '{next_function}': {...},<br>
> +#       ...<br>
> +#   },<br>
> +#   '{next_type}': {...},<br>
> +#   ...<br>
> +# }<br>
> +<br>
> +# Need to create an outer associative array<br>
> +# Will need several sets for vector/scalar input types (ttt/tss function)<br>
> +builtins = {<br>
> +    'char': {<br>
> +        'abs': {<br>
> +            'arg_types': ['uchar', 'char'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +              [0,  1, 2,  3, 4,  5, 6,  7, 8,  9, 10,  11, 12,  13,  128, 127],<br>
> +              [0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, -128, 127]<br>
<br>
</div></div>I think some of these tests are redundant.  It should be sufficient<br>
to test the edge cases (i.e. for abs() -1, 0, 1, MAX_INT, MIN_INT)<br>
plus one generic cases for each class of inputs (for abs() this would<br>
be one positive integer and one negative integer).  Actually for abs()<br>
it is probably debatable whether or not -1 and 1 are edge cases and I<br>
think that abs(MIN_INT) so maybe there can be less edge cases.<br>
<div><div class="h5"><br></div></div></blockquote><div><br></div><div>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.<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5">
> +            ]<br>
> +        },<br>
> +        'abs_diff': {<br>
> +            'arg_types': ['uchar','char','char'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +               [15, 13, 11, 10,  8,  5,  3,  1,  1,  3,  5,  7,  9, 11,  255,  255],<br>
> +               [-8, -7, -6, -6, -5, -3, -2, -1,  0,  1,  2,  3,  4,  5, -128,  127],<br>
> +               [ 7,  6,  5,  4,  3,  2,  1,  0, -1, -2, -3, -4, -5, -6,  127, -128]<br>
> +            ]<br>
> +        },<br>
> +        'add_sat': {<br>
> +            'arg_types': ['char','char','char'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +               [  0, -2, 13,  64, -128, 127, 127, -128,   0, -2, 13,  64, -128, 127, 127, -128],<br>
> +               [ 32, -8, -7, 127, -120, 127, 100, -100,  32, -8, -7, 127, -120, 127, 100, -100],<br>
> +               [-32,  6, 20, -63,  -12,  64,  50,  -50, -32,  6, 20, -63,  -12,  64,  50,  -50]<br>
> +            ]<br>
> +        },<br>
> +        'hadd': {<br>
> +            'arg_types': ['char','char','char'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +                [32, 0, -33, 10, 32, 0, -33, 10, 32, 0, -33, 10, 32, 0, -33, 10],<br>
> +                [32, 1, -33, 12, 32, 1, -33, 12, 32, 1, -33, 12, 32, 1, -33, 12],<br>
> +                [33, 0, -32,  8, 33, 0, -32,  8, 33, 0, -32,  8, 33, 0, -32,  8]<br>
> +            ]<br>
> +        },<br>
> +        'rhadd': {<br>
> +            'arg_types': ['char','char','char'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +                [33, 1, -32, 10, 33, 1, -32, 10, 33, 1, -32, 10, 33, 1, -32, 10],<br>
> +                [32, 1, -33, 12, 32, 1, -33, 12, 32, 1, -33, 12, 32, 1, -33, 12],<br>
> +                [33, 0, -32,  8, 33, 0, -32,  8, 33, 0, -32,  8, 33, 0, -32,  8]<br>
> +            ]<br>
> +        },<br>
> +        'clz': {<br>
> +            'arg_types': ['char', 'char'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +                [ 2,  1, 8,  0,  2,  1, 8,  0,  2,  1, 8,  0,  2,  1, 8,  0],<br>
> +                [32, 64, 0, -1, 32, 64, 0, -1, 32, 64, 0, -1, 32, 64, 0, -1]<br>
> +            ]<br>
> +        },<br>
> +        'clamp': {<br>
> +            'arg_types': ['char','char','char','char'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +                [64,  -64,  1,  0, 64,  -64,  1,  0, 64,  -64,  1,  0, 64,  -64,  1,  0],<br>
> +                [92, -128, 64, -1, 92, -128, 64, -1, 92, -128, 64, -1, 92, -128, 64, -1],<br>
> +                [ 0,  -64,  0,  0,  0,  -64,  0,  0,  0,  -64,  0,  0,  0,  -64,  0,  0],<br>
> +                [64,    0,  1,  1, 64,    0,  1,  1, 64,    0,  1,  1, 64,    0,  1,  1]<br>
> +            ]<br>
> +        },<br>
> +        'mad_hi': {<br>
> +            'arg_types': ['char','char','char','char'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +                [ 0, -128,  1,    1,  4,   1,    0, -66,  -64,   63,  1, 0, 2,   -2, 0, 0],<br>
> +                [92,   -1, 64, -128, 12, 127, -128, 127, -128, -128, 92, 0, 127,  1, 0, 0],<br>
> +                [ 2, -128,  1,    2,  4,   1,    1, 127, -128,  127,  1, 0, 2,   -1, 0, 0],<br>
> +                [ 0, -128,  1,    2,  4,   1,    1, 127, -128,  127,  1, 0, 2,   -1, 0, 0]<br>
> +            ]<br>
> +        },<br>
> +        'mad_sat': {<br>
> +            'arg_types': ['char','char','char','char'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +                [127,    0, 65, -128, 52, 127, -128, 127,  127, -128, 93, 0, 127, -2, -128, 127],<br>
> +                [ 92,   -1, 64, -128, 12, 127, -128, 127, -128, -128, 92, 0, 127,  1, -128, 127],<br>
> +                [  2, -128,  1,    2,  4,   1,    1, 127, -128,  127,  1, 0,   2, -1,    1, 127],<br>
> +                [  0, -128,  1,    2,  4,   1,   -1, 127, -128,  127,  1, 0,   2, -1,   -1, 127]<br>
> +            ]<br>
> +        },<br>
> +        'max': {<br>
> +            'arg_types': ['char', 'char', 'char'],<br>
> +            'function_type': 'tss',<br>
> +            'values': [<br>
> +                [92,   -1, 64,    2, 12, 127,    1, 127, -128,  127, 92, 0, 127,  1,    1, 127],<br>
> +                [92,   -1, 64,    2, 12, 127, -128, 127, -128, -128, 92, 0, 127,  1, -128, 127],<br>
> +                [ 2, -128,  1, -128,  4,   1,    1, 127, -128,  127,  1, 0,   2, -1,    1, 127]<br>
> +            ]<br>
> +        },<br>
> +        'min': {<br>
> +            'arg_types': ['char', 'char', 'char'],<br>
> +            'function_type': 'tss',<br>
> +            'values': [<br>
> +                [ 2, -128,  1, -128,  4,   1, -128, 127, -128, -128,  1, 0,   2, -1, -128, 127],<br>
> +                [92,   -1, 64,    2, 12, 127, -128, 127, -128, -128, 92, 0, 127,  1, -128, 127],<br>
> +                [ 2, -128,  1, -128,  4,   1,    1, 127, -128,  127,  1, 0,   2, -1,    1, 127]<br>
> +            ]<br>
> +        },<br>
> +        'mul_hi': {<br>
> +            'arg_types': ['char','char','char'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +                [ 0,    0,  0,   -1,  0,   0,   -1,  63,   64,  -64,  0, 0,   0, -1, 0, 0],<br>
> +                [92,   -1, 64, -128, 12, 127, -128, 127, -128, -128, 92, 0, 127,  1, 0, 0],<br>
> +                [ 2, -128,  1,    2,  4,   1,    1, 127, -128,  127,  1, 0,   2, -1, 0, 0]<br>
> +            ]<br>
> +        },<br>
> +        'rotate': {<br>
> +            'arg_types': ['char','char','char'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +                [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],<br>
> +                [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],<br>
> +                [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]<br>
> +            ]<br>
> +        },<br>
> +        'sub_sat': {<br>
> +            'arg_types': ['char','char','char'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +                [1,  2,  3, -128, 127,  127,  7,  8,  9, 10,  11,  12,  13,  14,  15,  81],<br>
> +                [1,  1,  1,  -64, 120,  127,  1,  1,  1,  1,   1,   1,   1,   1,   1,   1],<br>
> +                [0, -1, -2,   64, -32, -128, -6, -7, -8, -9, -10, -11, -12, -13, -14, -80]<br>
> +            ]<br>
> +        },<br>
> +        'upsample': {<br>
> +            'arg_types': ['short','char','uchar'],<br>
> +            'function_type': 'ttt',<br>
> +            'values': [<br>
> +                [256, 257,  -1, 32767, 0, 127, -256, 263, 264, 265, 266, 11, 268, 269, 270, 336],<br>
> +                [  1,   1,  -1,   127, 0,   0,   -1,   1,   1,   1,   1,  0,   1,   1,   1,   1],<br>
> +                [  0,   1, 255,   255, 0, 127,    0,   7,   8,   9,  10, 11,  12,  13,  14,  80]<br>
> +            ]<br>
> +        }<br>
> +    } #End of char tests<br>
> +}<br>
> +<br>
> +#By default, let's just test what is part of the CL1.1 stock spec, leave vec3 for later<br>
> +#vector_widths = (2, 3, 4, 8, 16)<br>
> +vector_widths = (2, 4, 8, 16)<br>
> +<br>
> +#### Define helper functions ####<br>
> +<br>
> +def print_test(f, fnName, fnSuffix, argType, argCount, tests, testIdx, vecSize):<br>
> +    f.write('[test]\n' + \<br>
> +        'name: ' + fnName + ' ' + argType + str(vecSize) + '\n' + \<br>
> +        'kernel_name: test_' + fnName + '_' + fnSuffix + \<br>
> +        '\n'<br>
> +    )<br>
> +<br>
> +    for arg in range(0, argCount):<br>
> +        argInOut = ''<br>
> +        if arg == 0:<br>
> +            argInOut = 'arg_out: '<br>
> +        else:<br>
> +            argInOut = 'arg_in: '<br>
> +        argVal = str(tests[arg][testIdx])<br>
> +        f.write(argInOut + str(arg) + ' buffer ' + argTypes[arg] + \<br>
> +            '[' + str(vecSize) + '] ' + \<br>
> +            ' '.join([argVal]*vecSize) + \<br>
> +            '\n'<br>
> +        )<br>
> +<br>
> +    #Blank line between tests for formatting clarity<br>
> +    f.write('\n')<br>
> +<br>
> +<br>
> +#Print a test with both all-vector inputs/outputs, and mixed vector/scalar args<br>
> +def print_test_tss(f, fnName, fnSuffix, argType, argCount, tests, testIdx, vecSize):<br>
> +    #Print test using all vector inputs<br>
> +    print_test(f, fnName, fnSuffix, argType, argCount, tests, testIdx, vecSize)<br>
> +<br>
> +    #Print test using mixed vector/scalar inputs<br>
> +    f.write('[test]\n' + \<br>
> +        'name: ' + fnName + ' ' + argType + str(vecSize) + '\n' + \<br>
> +        'kernel_name: test_' + fnName + '_tss_' + fnSuffix + \<br>
> +        '\n'<br>
> +    )<br>
> +<br>
> +    for arg in range(0, argCount):<br>
> +        argInOut = ''<br>
> +        argVal = str(tests[arg][testIdx])<br>
> +        if arg == 0:<br>
> +            argInOut = 'arg_out: '<br>
> +            f.write(argInOut + str(arg) + ' buffer ' + argTypes[arg] + \<br>
> +                '[' + str(vecSize) + '] ' + \<br>
> +                ' '.join([argVal]*vecSize) + \<br>
> +                '\n'<br>
> +            )<br>
> +        else:<br>
> +            argInOut = 'arg_in: '<br>
> +            f.write(argInOut + str(arg) + ' buffer ' + argTypes[arg] + \<br>
> +                '[1] ' + argVal + '\n'<br>
> +            )<br>
> +<br>
> +    #Blank line between tests for formatting reasons<br>
> +    f.write('\n')<br>
> +<br>
> +<br>
> +#### Main logic start ####<br>
> +<br>
> +#Loop over all data types being tested. Create one output file per data type<br>
> +for argType in builtins.keys():<br>
> +    functions = builtins[argType]<br>
> +    filename = 'builtin-' + argType +'-1.1.python_generated.program_test'<br>
<br>
</div></div>As I mentioned above, I think there should be one program_test file per<br>
builtin, or even one file per builtin/argType combination.  This will help keep<br>
things more organized and make it easier to identify and debug failing tests.<br>
<div><div class="h5"><br></div></div></blockquote><div><br></div><div>Agreed. I'll take care of that.  I'll create one file per data type and function combination.<br><br></div><div>--Aaron<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="h5">
> +    f = open(filename, 'w')<br>
> +    #Write the file header<br>
> +    f.write( \<br>
> +        '[config]\n' + \<br>
> +        'name: '+argType+'-based built-in tests for CL 1.1\n'+ \<br>
> +        'clc_version_min: 11\n' + \<br>
> +        'dimensions: 1\n' + \<br>
> +        'global_size: 1 0 0\n' + \<br>
> +        'program_source_file: builtin-integer.inc\n' + \<br>
> +        'build_options: -D U=u'+argType+' -D S='+argType+' -D T='+argType+'\n\n'<br>
> +    )<br>
> +<br>
> +    #Write all tests for each built-in function<br>
> +    for fnName in sorted(functions.keys()):<br>
> +        functionDef = functions[fnName]<br>
> +        tests = functionDef['values']<br>
> +        argCount = len(functionDef['arg_types'])<br>
> +        argTypes = functionDef['arg_types']<br>
> +        fnType = functionDef['function_type']<br>
> +<br>
> +        outputValues = tests[0]<br>
> +        numTests = len(outputValues)<br>
> +<br>
> +        #Handle scalar tests<br>
> +        for testIdx in range(0, numTests):<br>
> +            print_test(f, fnName, 'scalar', argType, argCount, tests, testIdx, 1)<br>
> +<br>
> +        #Handle all available vector widths<br>
> +        for vecSize in sorted(vector_widths):<br>
> +            for testIdx in range(0, numTests):<br>
> +                if fnType == 'tss':<br>
> +                    print_test_tss(f, fnName, str(vecSize), argType, argCount, tests, testIdx, vecSize)<br>
> +                else:<br>
> +                    print_test(f, fnName, str(vecSize), argType, argCount, tests, testIdx, vecSize)<br>
> +<br>
> +    #Hopefully this next part is obvious :)<br>
> +    f.close()<br>
> --<br>
> 1.7.4.4<br>
><br>
</div></div>> _______________________________________________<br>
> Piglit mailing list<br>
> <a href="mailto:Piglit@lists.freedesktop.org">Piglit@lists.freedesktop.org</a><br>
> <a href="http://lists.freedesktop.org/mailman/listinfo/piglit" target="_blank">http://lists.freedesktop.org/mailman/listinfo/piglit</a><br>
</blockquote></div><br></div></div>