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

ADT ast-experimental
Last change on this file since cca034e was 1d71208, checked in by Michael Brooks <mlbrooks@…>, 4 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.