From 7adb250b59f572faa38c4c23a178bfc6545d738e Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Mon, 5 Mar 2012 09:50:26 -0800 Subject: [PATCH] Added tests and documentation for soa<> rate qualifier. --- docs/ispc.rst | 236 +++++++------------- docs/perfguide.rst | 77 +++++++ tests/scatter-struct-with-array-member.ispc | 30 +++ tests/soa-1.ispc | 21 ++ tests/soa-10.ispc | 23 ++ tests/soa-11.ispc | 15 ++ tests/soa-12.ispc | 17 ++ tests/soa-13.ispc | 26 +++ tests/soa-14.ispc | 57 +++++ tests/soa-15.ispc | 48 ++++ tests/soa-16.ispc | 48 ++++ tests/soa-17.ispc | 50 +++++ tests/soa-18.ispc | 25 +++ tests/soa-19.ispc | 24 ++ tests/soa-2.ispc | 21 ++ tests/soa-20.ispc | 22 ++ tests/soa-21.ispc | 32 +++ tests/soa-22.ispc | 35 +++ tests/soa-23.ispc | 28 +++ tests/soa-24.ispc | 32 +++ tests/soa-25.ispc | 32 +++ tests/soa-26.ispc | 28 +++ tests/soa-3.ispc | 24 ++ tests/soa-4.ispc | 24 ++ tests/soa-5.ispc | 24 ++ tests/soa-6.ispc | 25 +++ tests/soa-7.ispc | 27 +++ tests/soa-8.ispc | 25 +++ tests/soa-9.ispc | 25 +++ tests_errors/int-ptr-fail.ispc | 5 + tests_errors/new-delete-4.ispc | 2 +- tests_errors/soa-1.ispc | 3 + tests_errors/soa-10.ispc | 25 +++ tests_errors/soa-11.ispc | 25 +++ tests_errors/soa-12.ispc | 25 +++ tests_errors/soa-13.ispc | 25 +++ tests_errors/soa-14.ispc | 25 +++ tests_errors/soa-15.ispc | 25 +++ tests_errors/soa-2.ispc | 6 + tests_errors/soa-3.ispc | 6 + tests_errors/soa-4.ispc | 6 + tests_errors/soa-5.ispc | 6 + tests_errors/soa-6.ispc | 7 + tests_errors/soa-7.ispc | 7 + tests_errors/soa-8.ispc | 5 + tests_errors/soa-9.ispc | 9 + 46 files changed, 1155 insertions(+), 158 deletions(-) create mode 100644 tests/scatter-struct-with-array-member.ispc create mode 100644 tests/soa-1.ispc create mode 100644 tests/soa-10.ispc create mode 100644 tests/soa-11.ispc create mode 100644 tests/soa-12.ispc create mode 100644 tests/soa-13.ispc create mode 100644 tests/soa-14.ispc create mode 100644 tests/soa-15.ispc create mode 100644 tests/soa-16.ispc create mode 100644 tests/soa-17.ispc create mode 100644 tests/soa-18.ispc create mode 100644 tests/soa-19.ispc create mode 100644 tests/soa-2.ispc create mode 100644 tests/soa-20.ispc create mode 100644 tests/soa-21.ispc create mode 100644 tests/soa-22.ispc create mode 100644 tests/soa-23.ispc create mode 100644 tests/soa-24.ispc create mode 100644 tests/soa-25.ispc create mode 100644 tests/soa-26.ispc create mode 100644 tests/soa-3.ispc create mode 100644 tests/soa-4.ispc create mode 100644 tests/soa-5.ispc create mode 100644 tests/soa-6.ispc create mode 100644 tests/soa-7.ispc create mode 100644 tests/soa-8.ispc create mode 100644 tests/soa-9.ispc create mode 100644 tests_errors/int-ptr-fail.ispc create mode 100644 tests_errors/soa-1.ispc create mode 100644 tests_errors/soa-10.ispc create mode 100644 tests_errors/soa-11.ispc create mode 100644 tests_errors/soa-12.ispc create mode 100644 tests_errors/soa-13.ispc create mode 100644 tests_errors/soa-14.ispc create mode 100644 tests_errors/soa-15.ispc create mode 100644 tests_errors/soa-2.ispc create mode 100644 tests_errors/soa-3.ispc create mode 100644 tests_errors/soa-4.ispc create mode 100644 tests_errors/soa-5.ispc create mode 100644 tests_errors/soa-6.ispc create mode 100644 tests_errors/soa-7.ispc create mode 100644 tests_errors/soa-8.ispc create mode 100644 tests_errors/soa-9.ispc diff --git a/docs/ispc.rst b/docs/ispc.rst index aba4104a..f90e9035 100644 --- a/docs/ispc.rst +++ b/docs/ispc.rst @@ -94,6 +94,7 @@ Contents: * `Short Vector Types`_ * `Array Types`_ * `Struct Types`_ + * `Structure of Array Types`_ + `Declarations and Initializers`_ + `Expressions`_ @@ -151,7 +152,6 @@ Contents: + `Data Layout`_ + `Data Alignment and Aliasing`_ + `Restructuring Existing Programs to Use ISPC`_ - + `Understanding How to Interoperate With the Application's Data`_ * `Disclaimer and Legal Information`_ @@ -1950,6 +1950,77 @@ still has only a single ``a`` member, since ``a`` was declared with indexing operation in the last line results in an error. +Structure of Array Types +------------------------ + +If data can be laid out in memory so that the executing program instances +access it via loads and stores of contiguous sections of memory, overall +performance can be improved noticably. One way to improve this memory +access coherence is to lay out structures in "structure of arrays" (SOA) +format in memory; the benefits from SOA layout are discussed in more detail +in the `Use "Structure of Arrays" Layout When Possible`_ section in the +ispc Performance Guide. + +.. _Use "Structure of Arrays" Layout When Possible: perf.html#use-structure-of-arrays-layout-when-possible + +``ispc`` provides two key language-level capabilities for laying out and +accessing data in SOA format: + +* An ``soa`` keyword that transforms a regular ``struct`` into an SOA version + of the struct. +* Array indexing syntax for SOA arrays that transparently handles SOA + indexing. + +As an example, consider a simple struct declaration: + +:: + + struct Point { float x, y, z; }; + +With the ``soa`` rate qualifier, an array of SOA variants of this structure +can be declared: + +:: + + soa<8> Point pts[...]; + +The in-memory layout of the ``Point``s has had the SOA transformation +applied, such that there are 8 ``x`` values in memory followed by 8 ``y`` +values, and so forth. Here is the effective declaration of ``soa<8> +Point``: + +:: + + struct { uniform float x[8], y[8], z[8]; }; + +Given an array of SOA data, array indexing (and pointer arithmetic) is done +so that the appropriate values from the SOA array are accessed. For +example, given: + +:: + + soa<8> Point pts[...]; + uniform float x = pts[10].x; + +The generated code effectively accesses the second 8-wide SOA structure and +then loads the third ``x`` value from it. In general, one can write the +same code to access arrays of SOA elements as one would write to access +them in AOS layout. + +Note that it directly follows from SOA layout that the layout of a single +element of the array isn't contiguous in memory--``pts[1].x`` and +``pts[1].y`` are separated by 7 ``float`` values in the above example. + +There are a few limitations to the current implementation of SOA types in +``ispc``; these may be relaxed in future releases: + +* It's illegal to typecast to ``soa`` data to ``void`` pointers. +* Reference types are illegal in SOA structures +* All members of SOA structures must have no rate qualifiers--specifically, + it's illegal to have an explicitly-qualified ``uniform`` or ``varying`` + member of a structure that has ``soa`` applied to it. + + Declarations and Initializers ----------------------------- @@ -3375,8 +3446,9 @@ Converting Between Array-of-Structures and Structure-of-Arrays Layout Applications often lay data out in memory in "array of structures" form. Though convenient in C/C++ code, this layout can make ``ispc`` programs less efficient than they would be if the data was laid out in "structure of -arrays" form. (See the section `Understanding How to Interoperate With the -Application's Data`_ for extended discussion of this topic.) +arrays" form. (See the section `Use "Structure of Arrays" Layout When +Possible`_ in the performance guide for extended discussion of this topic.) + The standard library does provide a few functions that efficiently convert between these two formats, for cases where it's not possible to change the @@ -3921,9 +3993,9 @@ program instances, ``ispc`` prohibits any varying types from being used in parameters to functions with the ``export`` qualifier. (``ispc`` also prohibits passing structures that themselves have varying types as members, etc.) Thus, all datatypes that is shared with the application must have -the ``uniform`` qualifier applied to them. (See `Understanding How to -Interoperate With the Application's Data`_ for more discussion of how to -load vectors of SoA or AoSoA data from the application.) +the ``uniform`` or ``soa`` rate qualifier applied to them. (See `Use +"Structure of Arrays" Layout When Possible`_ in the Performance Guide for +more discussion of how to load vectors of SOA data from the application.) Similarly, ``struct`` types shared with the application can also have embedded pointers. @@ -3941,7 +4013,7 @@ On the ``ispc`` side, the corresponding ``struct`` declaration is: // ispc struct Foo { - uniform float * uniform foo, * uniform bar; + float * uniform foo, * uniform bar; }; There is one subtlety related to data layout to be aware of: ``ispc`` @@ -4018,156 +4090,6 @@ program instances improves performance. .. _ispc Performance Tuning Guide: http://ispc.github.com/perf.html -Understanding How to Interoperate With the Application's Data -------------------------------------------------------------- - -One of ``ispc``'s key goals is to be able to interoperate with the -application's data, in whatever layout it is stored in. You don't need to -worry about reformatting of data or the overhead of a driver model that -abstracts the data layout. This section illustrates some of the -alternatives with a simple example of computing the length of a large -number of vectors. - -Consider for starters a ``Vector`` data-type, defined in C as: - -:: - - struct Vector { float x, y, z; }; - -We might have (still in C) an array of ``Vector`` s defined like this: - -:: - - Vector vectors[1024]; - -This is called an "array of structures" (AoS) layout. To compute the -lengths of these vectors in parallel, you can write ``ispc`` code like -this: - -:: - - export void length(uniform Vector vectors[1024], uniform float len[]) { - foreach (index = 0 ... 1024) { - float x = vectors[index].x; - float y = vectors[index].y; - float z = vectors[index].z; - float l = sqrt(x*x + y*y + z*z); - len[index] = l; - } - } - -The problem with this implementation is that the indexing into the array of -structures, ``vectors[index].x`` is relatively expensive. On a target -machine that supports four-wide IntelĀ® SSE, this turns into four loads of -single ``float`` values from non-contiguous memory locations, which are -then packed into a four-wide register corresponding to ``float x``. Once the -values are loaded into the local ``x``, ``y``, and ``z`` variables, -SIMD-efficient computation can proceed; getting to that point is -relatively inefficient. - -(As described previously in `Converting Between Array-of-Structures and -Structure-of-Arrays Layout`_, this computation could be written more -efficiently using standard library routines to convert from the AoS layout, -if we were given a flat array of ``float`` values.) - -An alternative data layout would be the "structure of arrays" (SoA). In C, -the data would be declared as: - -:: - - float x[1024], y[1024], z[1024]; - -The ``ispc`` code might be: - -:: - - export void length(uniform float x[1024], uniform float y[1024], - uniform float z[1024], uniform float len[]) { - foreach (index = 0 ... 1024) { - float xx = x[index]; - float yy = y[index]; - float zz = z[index]; - float l = sqrt(xx*xx + yy*yy + zz*zz); - len[index] = l; - } - } - -In this example, the loads into ``xx``, ``yy``, and ``zz`` are single -vector loads of an entire gang's worth of values into the corresponding -registers. This processing is more efficient than the multiple scalar -loads that are required with the AoS layout above. - -A final alternative is "array of structures of arrays" (AoSoA), a hybrid -between these two. A structure is declared that stores a small number of -``x``, ``y``, and ``z`` values in contiguous memory locations: - -:: - - struct Vector16 { - float x[16], y[16], z[16]; - }; - - -The ``ispc`` code has an outer loop over ``Vector16`` elements and -then an inner loop that peels off values from the element members: - -:: - - #define N_VEC (1024/16) - export void length(uniform Vector16 v[N_VEC], uniform float len[]) { - foreach (i = 0 ... N_VEC, j = 0 ... 16) { - float x = v[i].x[j]; - float y = v[i].y[j]; - float z = v[i].z[j]; - float l = sqrt(x*x + y*y + z*z); - len[16*i+j] = l; - } - } - } - -One advantage of the AoSoA layout is that the memory accesses to load -values are to nearby memory locations, where as with SoA, each of the three -loads above is to locations separated by a few thousand bytes. Thus, AoSoA -can be more cache friendly. For structures with many members, this -difference can lead to a substantial improvement. - -With some additional complexity, ``ispc`` can also generate code that -efficiently processes data in AoSoA layout where the inner array length is -less than the machine vector width. For example, consider doing -computation with this AoSoA structure definition on a machine with an -8-wide vector unit (for example, an IntelĀ® AVX target): - -:: - - struct Vector4 { - float x[4], y[4], z[4]; - }; - - -The ``ispc`` code to process this loads elements four at a time from -``Vector4`` instances until it has a full ``programCount`` number of -elements to work with and then proceeds with the computation. - -:: - - #define N_VEC (1024/4) - export void length(uniform Vector4 v[N_VEC], uniform float len[]) { - for (uniform int i = 0; i < N_VEC; i += programCount / 4) { - float x, y, z; - for (uniform int j = 0; j < programCount / 4; ++j) { - if (programIndex >= 4 * j && - programIndex < 4 * (j+1)) { - int index = (programIndex & 0x3); - x = v[i+j].x[index]; - y = v[i+j].y[index]; - z = v[i+j].z[index]; - } - } - float l = sqrt(x*x + y*y + z*z); - len[4*i + programIndex] = l; - } - } - Disclaimer and Legal Information ================================ diff --git a/docs/perfguide.rst b/docs/perfguide.rst index 80c7d8f8..6e8555bf 100644 --- a/docs/perfguide.rst +++ b/docs/perfguide.rst @@ -13,6 +13,7 @@ the most out of ``ispc`` in practice. + `Improving Control Flow Coherence With "foreach_tiled"`_ + `Using Coherent Control Flow Constructs`_ + `Use "uniform" Whenever Appropriate`_ + + `Use "Structure of Arrays" Layout When Possible`_ * `Tips and Techniques`_ @@ -247,6 +248,76 @@ but it's always best to provide the compiler with as much help as possible to understand the actual form of your computation. +Use "Structure of Arrays" Layout When Possible +---------------------------------------------- + +In general, memory access performance (for both reads and writes) is best +when the running program instances access a contiguous region of memory; in +this case efficient vector load and store instructions can often be used +rather than gathers and scatters. As an example of this issue, consider an +array of a simple point datatype laid out and accessed in conventional +"array of structures" (AOS) layout: + +:: + + struct Point { float x, y, z; }; + uniform Point pts[...]; + float v = pts[programIndex].x; + +In the above code, the access to ``pts[programIndex].x`` accesses +non-sequential memory locations, due to the ``y`` and ``z`` values between +the desired ``x`` values in memory. A "gather" is required to get the +value of ``v``, with a corresponding decrease in performance. + +If ``Point`` was defined as a "structure of arrays" (SOA) type, the access +can be much more efficient: + +:: + + struct Point8 { float x[8], y[8], z[8]; }; + uniform Point8 pts8[...]; + int majorIndex = programIndex / 8; + int minorIndex = programIndex % 8; + float v = pts8[majorIndex].x[minorIndex]; + +In this case, each ``Point8`` has 8 ``x`` values contiguous in memory +before 8 ``y`` values and then 8 ``z`` values. If the gang size is 8 or +less, the access for ``v`` will have the same value of ``majorIndex`` for +all program instances and will access consecutive elements of the ``x[8]`` +array with a vector load. (For larger gang sizes, two 8-wide vector loads +would be issues, which is also quite efficient.) + +However, the syntax in the above code is messy; accessing SOA data in this +fashion is much less elegant than the corresponding code for accessing the +data with AOS layout. The ``soa`` qualifier in ``ispc`` can be used to +cause the corresponding transformation to be made to the ``Point`` type, +while preserving the clean syntax for data access that comes with AOS +layout: + +:: + + soa<8> Point pts[...]; + float v = pts[programIndex].x; + +Thanks to having SOA layout a first-class concept in the language's type +system, it's easy to write functions that convert data between the +layouts. For example, the ``aos_to_soa`` function below converts ``count`` +elements of the given ``Point`` type from AOS to 8-wide SOA layout. (It +assumes that the caller has pre-allocated sufficient space in the +``pts_soa`` output array. + +:: + + void aos_to_soa(uniform Point pts_aos[], uniform int count, + soa<8> pts_soa[]) { + foreach (i = 0 ... count) + pts_soa[i] = pts_aos[i]; + } + +Analogously, a function could be written to convert back from SOA to AOS if +needed. + + Tips and Techniques =================== @@ -339,6 +410,12 @@ based on the index, it can be worth doing. See the example ``examples/volume_rendering`` in the ``ispc`` distribution for the use of this technique in an instance where it is beneficial to performance. +Understanding Memory Read Coalescing +------------------------------------ + +XXXX todo + + Avoid 64-bit Addressing Calculations When Possible -------------------------------------------------- diff --git a/tests/scatter-struct-with-array-member.ispc b/tests/scatter-struct-with-array-member.ispc new file mode 100644 index 00000000..081649df --- /dev/null +++ b/tests/scatter-struct-with-array-member.ispc @@ -0,0 +1,30 @@ + +struct Point { float x, y[3], z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + +//CO soa<8> Point pts[10]; + uniform Point pts[80]; + foreach (i = 0 ... 80) { + pts[i].x = b*i; + pts[i].y[0] = 2*b*i; + pts[i].y[1] = 2*b*i+1; + pts[i].y[2] = 2*b*i+2; + pts[i].z = 3*b*i; + } + + a *= -1; + Point vp = { a, { 2*a, 3*a, 4*a }, {5*a} }; + pts[2+programIndex] = vp; + + RET[programIndex] = pts[programIndex].y[2]; +} + +export void result(uniform float RET[]) { + RET[programIndex] = -4 * (programIndex-1); + RET[0] = 2; + RET[1] = 12; +} diff --git a/tests/soa-1.ispc b/tests/soa-1.ispc new file mode 100644 index 00000000..37a8f681 --- /dev/null +++ b/tests/soa-1.ispc @@ -0,0 +1,21 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[10]; + for (uniform int i = 0; i < 8*10; ++i) { + pts[i].x = b*i; + pts[i].y = 2*b*i; + pts[i].z = 3*b*i; + } + + RET[programIndex] = pts[programIndex].y; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 10*programIndex; +} diff --git a/tests/soa-10.ispc b/tests/soa-10.ispc new file mode 100644 index 00000000..2e1c8d30 --- /dev/null +++ b/tests/soa-10.ispc @@ -0,0 +1,23 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[10]; + foreach (i = 0 ... 80) { + pts[i].x = b*i; + pts[i].y = 2*b*i; + pts[i].z = 3*b*i; + } + + uniform Point up = pts[1]; + + RET[programIndex] = up.y; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 10; +} diff --git a/tests/soa-11.ispc b/tests/soa-11.ispc new file mode 100644 index 00000000..c28a02e2 --- /dev/null +++ b/tests/soa-11.ispc @@ -0,0 +1,15 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + soa<4> Point pts[2] = { { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }, + { { 13, 14, 15, 16 }, { 17, 18, 19, 20, }, { 21, 22, 23, 24 } } }; + + RET[programIndex] = pts[1].y; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 6; +} diff --git a/tests/soa-12.ispc b/tests/soa-12.ispc new file mode 100644 index 00000000..6fb43d38 --- /dev/null +++ b/tests/soa-12.ispc @@ -0,0 +1,17 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<4> Point pts[2] = { { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }, + { { 13, 14, 15, 16 }, { 17, 18, 19, 20, }, { 21, 22, 23, 24 } } }; + + RET[programIndex] = pts[programIndex & 1].y; +} + +export void result(uniform float RET[]) { + RET[programIndex] = (programIndex & 1) ? 6 : 5; +} diff --git a/tests/soa-13.ispc b/tests/soa-13.ispc new file mode 100644 index 00000000..d1f7b056 --- /dev/null +++ b/tests/soa-13.ispc @@ -0,0 +1,26 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[10]; + + foreach (i = 0 ... 80) { + pts[i].x = b*i; + pts[i].y = 2*b*i; + pts[i].z = 3*b*i; + } + + uniform Point up = { b, 3, 170 }; + pts[(int64)1] = up; + + RET[programIndex] = pts[(int64)programIndex].z; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 15*programIndex; + RET[1] = 170; +} diff --git a/tests/soa-14.ispc b/tests/soa-14.ispc new file mode 100644 index 00000000..582090cb --- /dev/null +++ b/tests/soa-14.ispc @@ -0,0 +1,57 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +static void p(uniform float *uniform ptr) { +//CO for (uniform int s = 0; s < 1; ++s) { // num to print +//CO for (uniform int i = 0; i < 3; ++i) { // num float in unif struct +//CO for (uniform int j = 0; j < 8; ++j, ++ptr) // soa width +//CO print("% ", *ptr); +//CO print("\n"); +//CO } +//CO print("\n"); +//CO } +} + +soa<8> Point * uniform aossoa(uniform Point aospts[], uniform int count) { + uniform int roundUp = (count + 7) & ~0x7; + uniform int nAlloc = roundUp / 8; + + soa<8> Point * uniform ret = uniform new soa<8> Point[nAlloc]; + foreach (i = 0 ... count) { +//CO varying Point gp = { programIndex+1, 2*programIndex+1, 3*programIndex+1 }; +//CO ret[i] = gp; +//CO ret[i].x = gp.x; +//CO ret[i].y = gp.y; +//CO ret[i].z = gp.z; +//CO print("%: % % %\n", i, gp.x, gp.y, gp.z); + ret[i] = aospts[i]; + } + +//CO p((uniform float * uniform)aospts); +//CO print("----\n"); +//CO p((uniform float * uniform)ret); + + return ret; + +} + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + uniform Point pts[programCount+4]; + foreach (i = 0 ... programCount+4) { + pts[i].x = b*i; + pts[i].y = 2*b*i; + pts[i].z = 3*b*i; + } + + soa<8> Point * uniform soaPts = aossoa(pts, programCount+4); + + RET[programIndex] = soaPts[programIndex+3].z; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 15*(programIndex+3); +} diff --git a/tests/soa-15.ispc b/tests/soa-15.ispc new file mode 100644 index 00000000..8e6bb0ce --- /dev/null +++ b/tests/soa-15.ispc @@ -0,0 +1,48 @@ + +struct Point { float x, y[3], z; }; + +export uniform int width() { return programCount; } + +static void p(uniform float *uniform ptr) { + for (uniform int s = 0; s < 4; ++s) { + for (uniform int i = 0; i < 5; ++i) { + for (uniform int j = 0; j < 4; ++j, ++ptr) + print("% ", *ptr); + print("\n"); + } + print("\n"); + } +} + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + soa<4> Point pts[10]; +//CO uniform Point pts[40]; +//CO foreach (i = 0 ... 40) { + for (uniform int i = 0; i < 40; ++i) { + pts[i].x = b*i; + pts[i].y[0] = 2*b*i; + pts[i].y[1] = 2*b*i+1; + pts[i].y[2] = 2*b*i+2; + pts[i].z = 3*b*i; + } + +//CO p((uniform float * uniform)&pts[0]); + +//CO print("delta %\n", ((uniform float * varying)(&pts[2+programIndex]) - +//CO (uniform float * uniform)&pts[0])); + + float a = aFOO[programIndex]; + a *= -1; + Point vp = { a, { 2*a, 3*a, 4*a }, {5*a} }; + pts[2+programIndex] = vp; + +//CO p((uniform float * uniform)&pts[0]); + + RET[programIndex] = pts[programIndex].y[2]; +} + +export void result(uniform float RET[]) { + RET[programIndex] = -4 * (programIndex-1); + RET[0] = 2; + RET[1] = 12; +} diff --git a/tests/soa-16.ispc b/tests/soa-16.ispc new file mode 100644 index 00000000..0f8c9c1f --- /dev/null +++ b/tests/soa-16.ispc @@ -0,0 +1,48 @@ + +struct Point { double x; double y[3], z; }; + +export uniform int width() { return programCount; } + +static void p(uniform float *uniform ptr) { + for (uniform int s = 0; s < 4; ++s) { + for (uniform int i = 0; i < 5; ++i) { + for (uniform int j = 0; j < 4; ++j, ++ptr) + print("% ", *ptr); + print("\n"); + } + print("\n"); + } +} + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + soa<4> Point pts[10]; +//CO uniform Point pts[40]; +//CO foreach (i = 0 ... 40) { + for (uniform int i = 0; i < 40; ++i) { + pts[i].x = b*i; + pts[i].y[0] = 2*b*i; + pts[i].y[1] = 2*b*i+1; + pts[i].y[2] = 2*b*i+2; + pts[i].z = 3*b*i; + } + +//CO p((uniform float * uniform)&pts[0]); + +//CO print("delta %\n", ((uniform float * varying)(&pts[2+programIndex]) - +//CO (uniform float * uniform)&pts[0])); + + float a = aFOO[programIndex]; + a *= -1; + Point vp = { a, { 2*a, 3*a, 4*a }, {5*a} }; + pts[2+programIndex] = vp; + +//CO p((uniform float * uniform)&pts[0]); + + RET[programIndex] = pts[programIndex].y[2]; +} + +export void result(uniform float RET[]) { + RET[programIndex] = -4 * (programIndex-1); + RET[0] = 2; + RET[1] = 12; +} diff --git a/tests/soa-17.ispc b/tests/soa-17.ispc new file mode 100644 index 00000000..2423cf66 --- /dev/null +++ b/tests/soa-17.ispc @@ -0,0 +1,50 @@ + +struct Point { double x; float y[3], z; }; + +export uniform int width() { return programCount; } + +static void p(uniform float *uniform ptr) { + for (uniform int s = 0; s < 4; ++s) { + + for (uniform int i = 0; i < 5; ++i) { + for (uniform int j = 0; j < 4; ++j, ++ptr) + print("% ", *ptr); + print("\n"); + } + print("\n"); + } +} + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + soa<4> Point pts[10]; +//CO uniform Point pts[40]; +//CO foreach (i = 0 ... 40) { + for (uniform int i = 0; i < 40; ++i) { + pts[i].x = b*i; + pts[i].y[0] = 2*b*i; + pts[i].y[1] = 2*b*i+1; + pts[i].y[2] = 2*b*i+2; + pts[i].z = 3*b*i; + } + +//CO p((uniform float * uniform)&pts[0]); + +//CO print("one size %\n", sizeof(soa<4> Point)); +//CO print("delta %\n", ((uniform int8 * varying)(&pts[2+programIndex]) - +//CO (uniform int8 * uniform)&pts[0])); + + float a = aFOO[programIndex]; + a *= -1; + Point vp = { a, { 2*a, 3*a, 4*a }, {5*a} }; + pts[2+programIndex] = vp; + +//CO p((uniform float * uniform)&pts[0]); + + RET[programIndex] = pts[programIndex].y[2]; +} + +export void result(uniform float RET[]) { + RET[programIndex] = -4 * (programIndex-1); + RET[0] = 2; + RET[1] = 12; +} diff --git a/tests/soa-18.ispc b/tests/soa-18.ispc new file mode 100644 index 00000000..1e8b70f6 --- /dev/null +++ b/tests/soa-18.ispc @@ -0,0 +1,25 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[10]; + foreach (i = 0 ... 80) { + pts[i].x = b*i; + pts[i].y = 2*b*i; + pts[i].z = 3*b*i; + } + + soa<8> Point * ptr = &pts[programIndex]; + ++ptr; + ptr->y = -programIndex; + + RET[programIndex] = pts[1+programIndex].y; +} + +export void result(uniform float RET[]) { + RET[programIndex] = -programIndex; +} diff --git a/tests/soa-19.ispc b/tests/soa-19.ispc new file mode 100644 index 00000000..3b7ad46f --- /dev/null +++ b/tests/soa-19.ispc @@ -0,0 +1,24 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[10]; + foreach (i = 0 ... 80) { + pts[i].x = b*i; + pts[i].y = 2*b*i; + pts[i].z = 3*b*i; + } + + soa<8> Point * ptr = &pts[6+programIndex]; + ptr->y = -programIndex;; + + RET[programIndex] = pts[6+programIndex].y; +} + +export void result(uniform float RET[]) { + RET[programIndex] = -programIndex; +} diff --git a/tests/soa-2.ispc b/tests/soa-2.ispc new file mode 100644 index 00000000..d8ec37e3 --- /dev/null +++ b/tests/soa-2.ispc @@ -0,0 +1,21 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[10]; + foreach (i = 0 ... 80) { + pts[i].x = b*i; + pts[i].y = 2*b*i; + pts[i].z = 3*b*i; + } + + RET[programIndex] = pts[programIndex].z; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 15*programIndex; +} diff --git a/tests/soa-20.ispc b/tests/soa-20.ispc new file mode 100644 index 00000000..f8a1fe6f --- /dev/null +++ b/tests/soa-20.ispc @@ -0,0 +1,22 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[10]; + foreach (i = 0 ... 80) { + pts[i].x = b*i; + pts[i].y = 2*b*i; + pts[i].z = 3*b*i; + } + + soa<8> Point * ptr = &pts[6+programIndex]; + RET[programIndex] = ptr - pts; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 6 + programIndex; +} diff --git a/tests/soa-21.ispc b/tests/soa-21.ispc new file mode 100644 index 00000000..f19ae448 --- /dev/null +++ b/tests/soa-21.ispc @@ -0,0 +1,32 @@ + +struct Point { float x, y, z; }; + +struct Foo { + int x; + Point pts[10]; + int8 z; +}; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Foo * uniform pts = uniform new soa<8> Foo[4]; + foreach (i = 0 ... 32) { + pts[i].x = b*i; + pts[i].z = -b*i; + for (uniform int j = 0; j < 10; ++j) { + pts[i].pts[j].x = j + 100*i; + pts[i].pts[j].y = j + 1000*i; + pts[i].pts[j].z = j + 10000*i; + } + } + + soa<8> Foo * ptr = &pts[7+programIndex]; + RET[programIndex] = ptr->pts[3].z; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 10000 * (7 + programIndex) + 3; +} diff --git a/tests/soa-22.ispc b/tests/soa-22.ispc new file mode 100644 index 00000000..41795c96 --- /dev/null +++ b/tests/soa-22.ispc @@ -0,0 +1,35 @@ + +struct Point { float x, y, z; }; + +struct Foo { + int x; + Point *pts[3]; + int8 z; +}; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Foo * uniform pts = uniform new soa<8> Foo[4]; +//CO uniform Foo pts[32]; + foreach (i = 0 ... 32) { + pts[i].x = b*i; + pts[i].z = -b*i; + for (uniform int j = 0; j < 3; ++j) { + pts[i].pts[j] = new uniform Point[4]; + for (uniform int k = 0; k < 4; ++k) { + pts[i].pts[j][k].x = 100*i+10*j+k; + pts[i].pts[j][k].y = -1234; + pts[i].pts[j][k].z = -(100*i+10*j+k); + } + } + } + + RET[programIndex] = pts[programIndex].pts[programIndex % 3][programIndex % 4].z; +} + +export void result(uniform float RET[]) { + RET[programIndex] = -(100*programIndex+10*(programIndex % 3)+(programIndex % 4)); +} diff --git a/tests/soa-23.ispc b/tests/soa-23.ispc new file mode 100644 index 00000000..24b7b679 --- /dev/null +++ b/tests/soa-23.ispc @@ -0,0 +1,28 @@ + +struct Point { float x, y, z; }; + +struct Foo { + float<3> vec; + int8 z; +}; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Foo * uniform pts = uniform new soa<8> Foo[4]; +//CO uniform Foo pts[32]; + foreach (i = 0 ... 32) { + pts[i].vec.x = b*i; + pts[i].vec.y = -b*i; + pts[i].vec.z = 2*b*i; + pts[i].z = i; + } + + RET[programIndex] = pts[programIndex+2].vec.y; +} + +export void result(uniform float RET[]) { + RET[programIndex] = -(5 * (programIndex+2)); +} diff --git a/tests/soa-24.ispc b/tests/soa-24.ispc new file mode 100644 index 00000000..23835c9c --- /dev/null +++ b/tests/soa-24.ispc @@ -0,0 +1,32 @@ + +struct Point { float x, y, z; }; + +struct Foo { + float<3> vec; + int8 z; +}; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Foo * uniform pts = uniform new soa<8> Foo[4]; +//CO uniform Foo pts[32]; + foreach (i = 0 ... 32) { + pts[i].vec.x = b*i; + pts[i].vec.y = -b*i; + pts[i].vec.z = 2*b*i; + pts[i].z = i; + } + + pts[programIndex+2].vec.z *= -1; + float<3> vl = pts[programIndex].vec; + RET[programIndex] = vl.z; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 10 * programIndex; + if (programIndex >= 2) + RET[programIndex] *= -1; +} diff --git a/tests/soa-25.ispc b/tests/soa-25.ispc new file mode 100644 index 00000000..d3be5253 --- /dev/null +++ b/tests/soa-25.ispc @@ -0,0 +1,32 @@ + +struct Point { float x, y, z; }; + +struct Foo { + float<3> vec; + int8 z; +}; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Foo * uniform pts = uniform new soa<8> Foo[4]; +//CO uniform Foo pts[32]; + foreach (i = 0 ... 32) { + pts[i].vec.x = b*i; + pts[i].vec.y = -b*i; + pts[i].vec.z = 2*b*i; + pts[i].z = i; + } + + pts[2].vec.x *= -1; + float<3> vl = pts[programIndex].vec; + RET[programIndex] = vl.x; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 5 * programIndex; + if (programIndex == 2) + RET[programIndex] *= -1; +} diff --git a/tests/soa-26.ispc b/tests/soa-26.ispc new file mode 100644 index 00000000..b765825a --- /dev/null +++ b/tests/soa-26.ispc @@ -0,0 +1,28 @@ + +struct Point { float x, y, z; }; + +struct Foo { + float<3> vec; + int8 z; +}; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Foo * uniform pts = uniform new soa<8> Foo[4]; +//CO uniform Foo pts[32]; + for (uniform int i = 0; i < 32; ++i) { + pts[i].vec.x = b*i; + pts[i].vec.y = -b*i; + pts[i].vec.z = 2*b*i; + pts[i].z = i; + } + + RET[programIndex] = pts[9].vec.y; +} + +export void result(uniform float RET[]) { + RET[programIndex] = -45; +} diff --git a/tests/soa-3.ispc b/tests/soa-3.ispc new file mode 100644 index 00000000..0eed0bf4 --- /dev/null +++ b/tests/soa-3.ispc @@ -0,0 +1,24 @@ + +struct Point { float x, y[3], z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[10]; +//CO uniform Point pts[80]; + foreach (i = 0 ... 80) { + pts[i].x = b*i; + pts[i].y[0] = 2*b*i; + pts[i].y[1] = 2*b*i+1; + pts[i].y[2] = 2*b*i+2; + pts[i].z = 3*b*i; + } + + RET[programIndex] = pts[programIndex].y[2]; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 10*programIndex + 2; +} diff --git a/tests/soa-4.ispc b/tests/soa-4.ispc new file mode 100644 index 00000000..3af768fb --- /dev/null +++ b/tests/soa-4.ispc @@ -0,0 +1,24 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[8]; + foreach (i = 0 ... 64) { + pts[i].x = 0; + pts[i].y = 0; + pts[i].z = 0; + } + + Point pv = { a, b, -a }; + pts[8+programIndex] = pv; + + RET[programIndex] = pts[8+programIndex].z; +} + +export void result(uniform float RET[]) { + RET[programIndex] = -(1 + programIndex); +} diff --git a/tests/soa-5.ispc b/tests/soa-5.ispc new file mode 100644 index 00000000..ae775c65 --- /dev/null +++ b/tests/soa-5.ispc @@ -0,0 +1,24 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[8]; + foreach (i = 0 ... 64) { + pts[i].x = 0; + pts[i].y = 0; + pts[i].z = 0; + } + + Point pv = { a, b, -a }; + pts[6+programIndex] = pv; + + RET[programIndex] = pts[6+programIndex].x; +} + +export void result(uniform float RET[]) { + RET[programIndex] = (1 + programIndex); +} diff --git a/tests/soa-6.ispc b/tests/soa-6.ispc new file mode 100644 index 00000000..4dd8439e --- /dev/null +++ b/tests/soa-6.ispc @@ -0,0 +1,25 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[8]; + foreach (i = 0 ... 64) { + pts[i].x = -42; + pts[i].y = 0; + pts[i].z = 0; + } + + Point pv = { a, b, -a }; + pts[8+programIndex] = pv; + + RET[programIndex] = pts[6+programIndex].x; +} + +export void result(uniform float RET[]) { + RET[programIndex] = (1 + programIndex - 2); + RET[0] = RET[1] = -42; +} diff --git a/tests/soa-7.ispc b/tests/soa-7.ispc new file mode 100644 index 00000000..042cf3dc --- /dev/null +++ b/tests/soa-7.ispc @@ -0,0 +1,27 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[8]; + foreach (i = 0 ... 64) { + pts[i].x = -42; + pts[i].y = 0; + pts[i].z = 0; + } + + Point pv = { a, b, -a }; + pts[8+programIndex].x = pv.x; + pts[8+programIndex].y = pv.y; + pts[8+programIndex].z = pv.z; + + RET[programIndex] = pts[6+programIndex].x; +} + +export void result(uniform float RET[]) { + RET[programIndex] = (1 + programIndex - 2); + RET[0] = RET[1] = -42; +} diff --git a/tests/soa-8.ispc b/tests/soa-8.ispc new file mode 100644 index 00000000..0235fc2c --- /dev/null +++ b/tests/soa-8.ispc @@ -0,0 +1,25 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[8]; + foreach (i = 0 ... 64) { + pts[i].x = -42; + pts[i].y = 0; + pts[i].z = 0; + } + + Point pv = { a, b, -a }; + pts[7+programIndex] = pv; + + RET[programIndex] = pts[8+programIndex].x; +} + +export void result(uniform float RET[]) { + RET[programIndex] = (2 + programIndex); + RET[programCount-1] = -42; +} diff --git a/tests/soa-9.ispc b/tests/soa-9.ispc new file mode 100644 index 00000000..0249434c --- /dev/null +++ b/tests/soa-9.ispc @@ -0,0 +1,25 @@ + +struct Point { float x, y, z; }; + +export uniform int width() { return programCount; } + +export void f_fu(uniform float RET[], uniform float aFOO[], uniform float b) { + float a = aFOO[programIndex]; + + soa<8> Point pts[10]; + foreach (i = 0 ... 80) { + pts[i].x = b*i; + pts[i].y = 2*b*i; + pts[i].z = 3*b*i; + } + + uniform Point up = { b, 3, 170 }; + pts[1] = up; + + RET[programIndex] = pts[programIndex].z; +} + +export void result(uniform float RET[]) { + RET[programIndex] = 15*programIndex; + RET[1] = 170; +} diff --git a/tests_errors/int-ptr-fail.ispc b/tests_errors/int-ptr-fail.ispc new file mode 100644 index 00000000..0c06bfc8 --- /dev/null +++ b/tests_errors/int-ptr-fail.ispc @@ -0,0 +1,5 @@ +// Type conversion from "const uniform int32" to "uniform int32 * varying" for initializer is not possible + +int voo() { + int * varying foo = 1; +} diff --git a/tests_errors/new-delete-4.ispc b/tests_errors/new-delete-4.ispc index 49fe6214..cc82d91c 100644 --- a/tests_errors/new-delete-4.ispc +++ b/tests_errors/new-delete-4.ispc @@ -1,4 +1,4 @@ -// Type conversion only possible from atomic types +// Type conversion from "varying struct P" to "varying unsigned int32" for item count is not possible struct P { int x; }; diff --git a/tests_errors/soa-1.ispc b/tests_errors/soa-1.ispc new file mode 100644 index 00000000..8068b304 --- /dev/null +++ b/tests_errors/soa-1.ispc @@ -0,0 +1,3 @@ +// Illegal to provide soa<4> qualifier with non-struct type "void" + +soa<4> void foo() { } diff --git a/tests_errors/soa-10.ispc b/tests_errors/soa-10.ispc new file mode 100644 index 00000000..28933bf1 --- /dev/null +++ b/tests_errors/soa-10.ispc @@ -0,0 +1,25 @@ +// Can't convert between types "uniform struct Foo" and "soa<4> struct Foo" with different SOA widths + +struct Pt { float x, y, z; }; + +struct Foo { +//CO uniform int a; +//CO int a; +//CO float *x; +//CO float y[5], z; + double d[5]; + float x, y, z; + //Pt p; +}; + +extern void bar(float); + +uniform Foo uf; +varying Foo vf; + +int index; + +export void x(uniform Foo &x, soa<8> Foo f[]) { + soa<4> Foo xyz; + xyz= uf; +} diff --git a/tests_errors/soa-11.ispc b/tests_errors/soa-11.ispc new file mode 100644 index 00000000..67d814c6 --- /dev/null +++ b/tests_errors/soa-11.ispc @@ -0,0 +1,25 @@ +// Type conversion from "const uniform int32" to "soa<4> struct Foo" for assignment operator is not possible + +struct Pt { float x, y, z; }; + +struct Foo { +//CO uniform int a; +//CO int a; +//CO float *x; +//CO float y[5], z; + double d[5]; + float x, y, z; + //Pt p; +}; + +extern void bar(float); + +uniform Foo uf; +varying Foo vf; + +int index; + +export void x(uniform Foo &x, soa<8> Foo f[]) { + soa<4> Foo xyz; + xyz = 0; +} diff --git a/tests_errors/soa-12.ispc b/tests_errors/soa-12.ispc new file mode 100644 index 00000000..e2cd3242 --- /dev/null +++ b/tests_errors/soa-12.ispc @@ -0,0 +1,25 @@ +// Can't convert between types "const uniform int32" and "soa<4> float" with different SOA widths + +struct Pt { float x, y, z; }; + +struct Foo { +//CO uniform int a; +//CO int a; +//CO float *x; +//CO float y[5], z; + double d[5]; + float x, y, z; + //Pt p; +}; + +extern void bar(float); + +uniform Foo uf; +varying Foo vf; + +int index; + +export void x(uniform Foo &x, soa<8> Foo f[]) { + soa<4> Foo xyz; + xyz.x = 0; +} diff --git a/tests_errors/soa-13.ispc b/tests_errors/soa-13.ispc new file mode 100644 index 00000000..938d00ca --- /dev/null +++ b/tests_errors/soa-13.ispc @@ -0,0 +1,25 @@ +// Can't apply unary operator to SOA type "soa<4> struct Foo" + +struct Pt { float x, y, z; }; + +struct Foo { +//CO uniform int a; +//CO int a; +//CO float *x; +//CO float y[5], z; + double d[5]; + float x, y, z; + //Pt p; +}; + +extern void bar(float); + +uniform Foo uf; +varying Foo vf; + +int index; + +export void x(uniform Foo &x, soa<8> Foo f[]) { + soa<4> Foo xyz; + ++xyz; +} diff --git a/tests_errors/soa-14.ispc b/tests_errors/soa-14.ispc new file mode 100644 index 00000000..07b69f1c --- /dev/null +++ b/tests_errors/soa-14.ispc @@ -0,0 +1,25 @@ +// Can't apply unary operator to SOA type "soa<4> float" + +struct Pt { float x, y, z; }; + +struct Foo { +//CO uniform int a; +//CO int a; +//CO float *x; +//CO float y[5], z; + double d[5]; + float x, y, z; + //Pt p; +}; + +extern void bar(float); + +uniform Foo uf; +varying Foo vf; + +int index; + +export void x(uniform Foo &x, soa<8> Foo f[]) { + soa<4> Foo xyz; + -xyz.x; +} diff --git a/tests_errors/soa-15.ispc b/tests_errors/soa-15.ispc new file mode 100644 index 00000000..c3da34f0 --- /dev/null +++ b/tests_errors/soa-15.ispc @@ -0,0 +1,25 @@ +// Illegal to use binary operator - with SOA type "soa<4> float" + +struct Pt { float x, y, z; }; + +struct Foo { +//CO uniform int a; +//CO int a; +//CO float *x; +//CO float y[5], z; + double d[5]; + float x, y, z; + //Pt p; +}; + +extern void bar(float); + +uniform Foo uf; +varying Foo vf; + +int index; + +export void x(uniform Foo &x, soa<8> Foo f[]) { + soa<4> Foo xyz; + xyz.x = xyz.y-xyz.x; +} diff --git a/tests_errors/soa-2.ispc b/tests_errors/soa-2.ispc new file mode 100644 index 00000000..521d4936 --- /dev/null +++ b/tests_errors/soa-2.ispc @@ -0,0 +1,6 @@ +// soa<3> width illegal. Value must be positive power of two + +struct F { float a, b, c; }; + +soa<3> F farray[10]; + diff --git a/tests_errors/soa-3.ispc b/tests_errors/soa-3.ispc new file mode 100644 index 00000000..b2be1b59 --- /dev/null +++ b/tests_errors/soa-3.ispc @@ -0,0 +1,6 @@ +// syntax error, unexpected '-', expecting int32 constant + +struct F { float a, b, c; }; + +soa<-4> F farray[10]; + diff --git a/tests_errors/soa-4.ispc b/tests_errors/soa-4.ispc new file mode 100644 index 00000000..b2be1b59 --- /dev/null +++ b/tests_errors/soa-4.ispc @@ -0,0 +1,6 @@ +// syntax error, unexpected '-', expecting int32 constant + +struct F { float a, b, c; }; + +soa<-4> F farray[10]; + diff --git a/tests_errors/soa-5.ispc b/tests_errors/soa-5.ispc new file mode 100644 index 00000000..53a1d9cb --- /dev/null +++ b/tests_errors/soa-5.ispc @@ -0,0 +1,6 @@ +// "uniform" qualifier and "soa<4>" qualifier can't both be used + +struct F { float a, b, c; }; + +uniform soa<4> F farray[10]; + diff --git a/tests_errors/soa-6.ispc b/tests_errors/soa-6.ispc new file mode 100644 index 00000000..8bf6b5f7 --- /dev/null +++ b/tests_errors/soa-6.ispc @@ -0,0 +1,7 @@ +// Can't convert between types "uniform struct Point" and "soa<4> struct Point" with different SOA widths + +struct Point { float a, b, c; }; + +void foo(soa<8> Point pts[]) { + soa<4> Point x = pts[0]; +} diff --git a/tests_errors/soa-7.ispc b/tests_errors/soa-7.ispc new file mode 100644 index 00000000..8bf6b5f7 --- /dev/null +++ b/tests_errors/soa-7.ispc @@ -0,0 +1,7 @@ +// Can't convert between types "uniform struct Point" and "soa<4> struct Point" with different SOA widths + +struct Point { float a, b, c; }; + +void foo(soa<8> Point pts[]) { + soa<4> Point x = pts[0]; +} diff --git a/tests_errors/soa-8.ispc b/tests_errors/soa-8.ispc new file mode 100644 index 00000000..fda5c280 --- /dev/null +++ b/tests_errors/soa-8.ispc @@ -0,0 +1,5 @@ +// Unable to apply SOA conversion to struct due to "uniform int32" member "x" with bound "uniform" + +struct Point { uniform int x; float a, b, c; }; + +void foo(soa<8> Point pts[]); diff --git a/tests_errors/soa-9.ispc b/tests_errors/soa-9.ispc new file mode 100644 index 00000000..7c6a1df9 --- /dev/null +++ b/tests_errors/soa-9.ispc @@ -0,0 +1,9 @@ +// Can't convert from pointer to SOA type "soa<8> struct A * uniform" to pointer to non-SOA type "void * varying" + +struct A { float a, b; }; + +soa<8> A as[100]; + +void foo() { + void *ptr = &as[0]; +}