source: tests/array-container/array-md-sbscr-cases.cfa @ 21a99cc

ADTast-experimentalenumforall-pointer-decaypthread-emulationqualifiedEnum
Last change on this file since 21a99cc was 1d71208, checked in by Michael Brooks <mlbrooks@…>, 3 years ago

Implementing new-array subscripting syntax, in which a[x,y,z] now means the same as ax,y,z?.

This behaviour immediately replaces a syntax error that prohibits the -[-,-,-] syntax. The prior state showed that the C programs we compile don't use the C-compatible meaning of commas in subscripts.

This behaviour ultimately replaces the C-compatible interpretation in which a[x,y,z] means a[(x,y,z)] or, roughly, ({ x; y; a[z]; }).

  • Property mode set to 100644
File size: 9.2 KB
Line 
1#include <containers/array.hfa>
2
3#include <assert.h>
4
5float getMagicNumber( ptrdiff_t w, ptrdiff_t x, ptrdiff_t y, ptrdiff_t z ) {
6
7    assert( 0 <= w && w < 3 );
8    assert( 0 <= x && x < 4 );
9    assert( 0 <= y && y < 5 );
10    assert( 0 <= z && z < 6 );
11
12    float ww = (2.0f \ w) / 1.0f;
13    float xx = (2.0f \ x) / 100.0f;
14    float yy = (2.0f \ y) / 10000.0f;
15    float Nz = (2.0f \ z) / 1000000.0f;
16
17    return ww+xx+yy+Nz;
18}
19
20forall( [Nw], [Nx], [Ny], [Nz] )
21void fillHelloData( array( float, Nw, Nx, Ny, Nz ) & wxyz ) {
22    for (w; Nw)
23    for (x; Nx)
24    for (y; Ny)
25    for (z; Nz)
26        wxyz[w][x][y][z] = getMagicNumber(w, x, y, z);
27}
28
29// Work around a compiler optimization that can lead to false failures.
30// Think of `valExpected` as a constant local to each test function.
31// When implemented that way, an optimization, run on some hardware, makes
32// its value be off-by-a-little, compared with the values that have been
33// stored-loaded (in the array under test).  This effect has been observed
34// on x86-32 with -O3.  Declaring it as below forces the expected value
35// to be stored-loaded too, which keeps the (admittedly lazily done)
36// `assert(f1 == f2)` checks passing, when the intended <w,x,y,z> location
37// is recovered, which is the point of all these tests.
38volatile float valExpected = 0.0;
39
40// Tests all the ways to split dimensions into CFA-supported chunks, by the only order that C supports: coarsest to finest stride.
41forall( [Nw], [Nx], [Ny], [Nz] )
42void test_inOrderSplits( tag(Nw), tag(Nx), tag(Ny), tag(Nz) ) {
43
44    array( float, Nw, Nx, Ny, Nz ) wxyz;
45    fillHelloData(wxyz);
46
47    ptrdiff_t iw = 2, ix = 3, iy=4, iz=5;
48
49    valExpected = getMagicNumber(iw, ix, iy, iz);
50    float valGot = wxyz[iw][ix][iy][iz];
51    assert( valGot == valExpected );
52
53    // order wxyz, natural split (4-0 or 0-4, no intermediate to declare)
54
55    assert(( wxyz[iw, ix, iy, iz] == valExpected ));
56
57    // order wxyz, unnatural split 1-3  (three ways declared)
58
59    typeof( wxyz[iw] ) xyz1 = wxyz[iw];
60    assert(( xyz1[ix, iy, iz]  == valExpected ));
61
62    typeof( wxyz[iw] ) xyz2;
63    &xyz2 = &wxyz[iw];
64    assert(( xyz2[ix, iy, iz] == valExpected ));
65
66    assert(( wxyz[iw][ix, iy, iz] == valExpected ));
67
68    // order wxyz, unnatural split 2-2  (three ways declared)
69
70    typeof( wxyz[iw, ix] ) yz1 = wxyz[iw,ix];
71    assert(( yz1[iy, iz]  == valExpected ));
72
73    typeof( wxyz[iw, ix] ) yz2;
74    &yz2 = &wxyz[iw, ix];
75    assert(( yz2[iy, iz]  == valExpected ));
76
77    assert(( wxyz[iw, ix][iy, iz] == valExpected ));
78
79    // order wxyz, unnatural split 3-1  (three ways declared)
80
81    typeof( wxyz[iw, ix, iy] ) z1 = wxyz[iw, ix, iy];
82    assert(( z1[iz]  == valExpected ));
83
84    typeof( wxyz[iw, ix, iy] ) z2;
85    &z2 = &wxyz[iw, ix, iy];
86    assert(( z2[iz] == valExpected ));
87
88    assert(( wxyz[iw, ix, iy][iz] == valExpected ));
89}
90
91// All orders that skip a single dimension, each in its most natural split.
92forall( [Nw], [Nx], [Ny], [Nz] )
93void test_skipSingle( tag(Nw), tag(Nx), tag(Ny), tag(Nz) ) {
94
95    array( float, Nw, Nx, Ny, Nz ) wxyz;
96    fillHelloData(wxyz);
97
98    ptrdiff_t iw = 2, ix = 3, iy=4, iz=5;
99
100    valExpected = getMagicNumber(iw, ix, iy, iz);
101    assert( wxyz[iw][ix][iy][iz] == valExpected );
102
103
104    // order wxyz (no intermediates to declare)
105
106    assert(( wxyz[iw  , ix  , iy  , iz  ]       == valExpected ));
107    assert(( wxyz[iw-1, ix  , iy  , iz  ]       != valExpected ));
108
109    // order xyzw: *xyz, w
110
111    assert(( wxyz[all , ix  , iy  , iz  ][iw  ] == valExpected ));
112    assert(( wxyz[all , ix-1, iy  , iz  ][iw  ] != valExpected ));
113    assert(( wxyz[all , ix  , iy  , iz  ][iw-1] != valExpected ));
114
115    // order wyzx: w*yz, x
116
117    assert(( wxyz[iw  , all , iy  , iz  ][ix  ] == valExpected ));
118    assert(( wxyz[iw  , all , iy-1, iz  ][ix  ] != valExpected ));
119    assert(( wxyz[iw  , all , iy  , iz  ][ix-1] != valExpected ));
120
121    // order wxzy: wx*z, y
122  #if 0
123    // not working on 32-bit
124    assert(( wxyz[iw  , ix  , all , iz  ][iy  ] == valExpected ));
125    assert(( wxyz[iw  , ix  , all , iz-1][iy  ] != valExpected ));
126    assert(( wxyz[iw  , ix  , all , iz  ][iy-1] != valExpected ));
127  #endif
128}
129
130
131// The comments specify a covering set of orders, each in its most natural split.
132// Covering means that each edge on the lattice of dimesnions-provided is used.
133// Natural split means the arity of every -[-,...] tuple equals the dimensionality of its "this" operand, then that the fewest "all" subscripts are given.
134// The commented-out test code shows cases that don't work.  We wish all the comment-coverd cases worked.
135forall( [Nw], [Nx], [Ny], [Nz] )
136void test_latticeCoverage( tag(Nw), tag(Nx), tag(Ny), tag(Nz) ) {
137
138    array( float, Nw, Nx, Ny, Nz ) wxyz;
139    fillHelloData(wxyz);
140
141    ptrdiff_t iw = 2, ix = 3, iy=4, iz=5;
142
143    valExpected = getMagicNumber(iw, ix, iy, iz);
144    assert( wxyz[iw][ix][iy][iz] == valExpected );
145
146
147    // order wxyz (no intermediates to declare)
148
149    assert(( wxyz[iw, ix, iy, iz] == valExpected ));
150
151    {
152        // order wyxz: w*y*, xz
153        assert( wxyz[iw][all][iy][all] [ix][iz] == valExpected );
154
155        typeof( wxyz[iw, all, iy, all] ) xz1 = wxyz[iw, all, iy, all];
156        assert(( xz1[ix, iz]  == valExpected ));
157
158        typeof( wxyz[iw, all, iy, all] ) xz2;
159        &xz2 = &wxyz[iw, all, iy, all];
160        assert(( xz2[ix, iz]  == valExpected ));
161
162        assert(( wxyz[iw  , all, iy  , all][ix  , iz  ] == valExpected ));
163        assert(( wxyz[iw-1, all, iy  , all][ix  , iz  ] != valExpected ));
164        assert(( wxyz[iw  , all, iy-1, all][ix  , iz  ] != valExpected ));
165        assert(( wxyz[iw  , all, iy  , all][ix-1, iz  ] != valExpected ));
166        assert(( wxyz[iw  , all, iy  , all][ix  , iz-1] != valExpected ));
167    }
168    {
169        // order wzxy: w**z, xy
170        assert( wxyz[iw][all][all][iz] [ix][iy] == valExpected );
171
172        // typeof( wxyz[iw, all, all, iz] ) xy1 = wxyz[iw, all, all, iz];
173        // assert(( xy1[ix, iy]  == valExpected ));
174
175        // typeof(  wxyz[iw, all, all, iz] ) xy2;
176        // &xy2 = &wxyz[iw, all, all, iz];
177        // assert(( xy2[ix, iy]  == valExpected ));
178
179        // assert(( wxyz[iw  , all, all, iz  ][ix  , iy  ] == valExpected ));
180        // assert(( wxyz[iw-1, all, all, iz  ][ix  , iy  ] != valExpected ));
181        // assert(( wxyz[iw  , all, all, iz-1][ix  , iy  ] != valExpected ));
182        // assert(( wxyz[iw  , all, all, iz  ][ix-1, iy  ] != valExpected ));
183        // assert(( wxyz[iw  , all, all, iz  ][ix  , iy-1] != valExpected ));
184    }
185    {
186        // order xywz: *xy*, wz
187        assert( wxyz[all][ix][iy][all] [iw][iz] == valExpected );
188
189        typeof( wxyz[all, ix, iy, all] ) wz1 = wxyz[all, ix, iy, all];
190        assert(( wz1[iw, iz]  == valExpected ));
191
192        assert(( wxyz[all  , ix, iy  , all][iw  , iz  ] == valExpected ));
193    }
194    {
195        // order xzwy: *x*z, wy
196        assert( wxyz[all][ix][all][iz] [iw][iy] == valExpected );
197
198        // assert(( wxyz[all , ix  , all , iz  ][iw  , iy  ] == valExpected ));
199    }
200    {
201        // order yzwx: **yz, wx
202        assert( wxyz[all][all][iy][iz] [iw][ix] == valExpected );
203
204        // assert(( wxyz[all , all , iy  , iz  ][iw  , ix  ] == valExpected ));
205    }
206    {
207        // order xwzy: *x**, w*z, y
208        assert( wxyz[all][ix][all][all] [iw][all][iz] [iy] == valExpected );
209
210        typeof( wxyz[all][ix][all][all] ) wyz_workaround = wxyz[all , ix , all  , all  ];
211        typeof( wyz_workaround[iw][all][iz] ) y_workaround = wyz_workaround[iw , all , iz  ];
212        assert( y_workaround[iy] == valExpected );
213
214        // assert(( wxyz[all , ix , all  , all  ][iw  , all , iz  ][iy  ] == valExpected ));
215    }
216    {
217        // order ywzx: **y*, w*z, x
218    }
219    {
220        // order zwyx: ***z, w*y, x
221    }
222    {
223        // order yxzw: **y*, *xz, w
224    }
225    {
226        // order zxyw: ***z, *xy, w
227    }
228    {
229        // order zyxw: ***z, **y, *x, w
230    }
231}
232
233forall( [Nw], [Nx], [Ny], [Nz] )
234void test_numSubscrTypeCompatibility( tag(Nw), tag(Nx), tag(Ny), tag(Nz) ) {
235
236    array( float, Nw, Nx, Ny, Nz ) wxyz;
237    fillHelloData(wxyz);
238
239    valExpected = getMagicNumber(2, 3, 4, 5);
240    assert(( wxyz [2] [3] [4] [5]  == valExpected ));
241    assert(( wxyz[2,  3][4] [5]  == valExpected ));
242    assert(( wxyz [2][3,  4][5]  == valExpected ));
243    assert(( wxyz [2] [3][4,  5] == valExpected ));
244    assert(( wxyz[2,  3,  4][5]  == valExpected ));
245    assert(( wxyz [2][3,  4,  5] == valExpected ));
246    assert(( wxyz[2,  3,  4,  5] == valExpected ));
247
248    for ( i; Nw ) {
249        assert(( wxyz[ i, 3, 4, 5 ] == getMagicNumber(i, 3, 4, 5) ));
250    }
251
252    for ( i; Nx ) {
253        assert(( wxyz[ 2, i, 4, 5 ] == getMagicNumber(2, i, 4, 5) ));
254    }
255
256    for ( i; Ny ) {
257        assert(( wxyz[ 2, 3, i, 5 ] == getMagicNumber(2, 3, i, 5) ));
258    }
259
260    for ( i; Nz ) {
261        assert(( wxyz[ 2, 3, 4, i ] == getMagicNumber(2, 3, 4, i) ));
262    }
263
264    for ( i; Nw ) {
265        assert(( wxyz[ i, all, 4, 5 ][3] == getMagicNumber(i, 3, 4, 5) ));
266    }
267
268    for ( i; Nw ) {
269        assert(( wxyz[ all, 3, 4, 5 ][i] == getMagicNumber(i, 3, 4, 5) ));
270    }
271}
272
273const size_t  KW = 3,  KX = 4,  KY = 5,  KZ = 6;
274
275int main() {
276
277    test_inOrderSplits  ( ztag(KW), ztag(KX), ztag(KY), ztag(KZ) );
278    test_skipSingle     ( ztag(KW), ztag(KX), ztag(KY), ztag(KZ) );
279    test_latticeCoverage( ztag(KW), ztag(KX), ztag(KY), ztag(KZ) );
280    test_numSubscrTypeCompatibility( ztag(KW), ztag(KX), ztag(KY), ztag(KZ) );
281    printf("done\n");
282}
Note: See TracBrowser for help on using the repository browser.