source: tests/array-container/array-md-sbscr-cases.cfa @ 029cbc0

ADTast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 029cbc0 was 938885d3, checked in by Michael Brooks <mlbrooks@…>, 4 years ago

Fixing a false failure of the new array test on x86-32 -O3.

  • Property mode set to 100644
File size: 9.4 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; z(Nw))
23    for (x; z(Nx))
24    for (y; z(Ny))
25    for (z; 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; z(Nw) ) {
249        assert(( wxyz[[ i, 3, 4, 5 ]] == getMagicNumber(i, 3, 4, 5) ));
250    }
251
252    for ( i; z(Nx) ) {
253        assert(( wxyz[[ 2, i, 4, 5 ]] == getMagicNumber(2, i, 4, 5) ));
254    }
255
256    for ( i; z(Ny) ) {
257        assert(( wxyz[[ 2, 3, i, 5 ]] == getMagicNumber(2, 3, i, 5) ));
258    }
259
260    for ( i; z(Nz) ) {
261        assert(( wxyz[[ 2, 3, 4, i ]] == getMagicNumber(2, 3, 4, i) ));
262    }
263
264    for ( i; z(Nw) ) {
265        assert(( wxyz[[ i, all, 4, 5 ]][3] == getMagicNumber(i, 3, 4, 5) ));
266    }
267
268    for ( i; z(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.