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

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since 1b64344 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
RevLine 
[63a4b92]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
[b9dae14c]20forall( [Nw], [Nx], [Ny], [Nz] )
[63a4b92]21void fillHelloData( array( float, Nw, Nx, Ny, Nz ) & wxyz ) {
[6e50a6b]22    for (w; Nw)
23    for (x; Nx)
24    for (y; Ny)
25    for (z; Nz)
[63a4b92]26        wxyz[w][x][y][z] = getMagicNumber(w, x, y, z);
27}
28
[938885d3]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
[63a4b92]40// Tests all the ways to split dimensions into CFA-supported chunks, by the only order that C supports: coarsest to finest stride.
[b9dae14c]41forall( [Nw], [Nx], [Ny], [Nz] )
[63a4b92]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
[938885d3]49    valExpected = getMagicNumber(iw, ix, iy, iz);
50    float valGot = wxyz[iw][ix][iy][iz];
51    assert( valGot == valExpected );
[63a4b92]52
53    // order wxyz, natural split (4-0 or 0-4, no intermediate to declare)
54
[1d71208]55    assert(( wxyz[iw, ix, iy, iz] == valExpected ));
[63a4b92]56
57    // order wxyz, unnatural split 1-3  (three ways declared)
58
59    typeof( wxyz[iw] ) xyz1 = wxyz[iw];
[1d71208]60    assert(( xyz1[ix, iy, iz]  == valExpected ));
[63a4b92]61
62    typeof( wxyz[iw] ) xyz2;
63    &xyz2 = &wxyz[iw];
[1d71208]64    assert(( xyz2[ix, iy, iz] == valExpected ));
[63a4b92]65
[1d71208]66    assert(( wxyz[iw][ix, iy, iz] == valExpected ));
[63a4b92]67
68    // order wxyz, unnatural split 2-2  (three ways declared)
69
[1d71208]70    typeof( wxyz[iw, ix] ) yz1 = wxyz[iw,ix];
71    assert(( yz1[iy, iz]  == valExpected ));
[63a4b92]72
[1d71208]73    typeof( wxyz[iw, ix] ) yz2;
74    &yz2 = &wxyz[iw, ix];
75    assert(( yz2[iy, iz]  == valExpected ));
[63a4b92]76
[1d71208]77    assert(( wxyz[iw, ix][iy, iz] == valExpected ));
[63a4b92]78
79    // order wxyz, unnatural split 3-1  (three ways declared)
80
[1d71208]81    typeof( wxyz[iw, ix, iy] ) z1 = wxyz[iw, ix, iy];
[63a4b92]82    assert(( z1[iz]  == valExpected ));
83
[1d71208]84    typeof( wxyz[iw, ix, iy] ) z2;
85    &z2 = &wxyz[iw, ix, iy];
[63a4b92]86    assert(( z2[iz] == valExpected ));
87
[1d71208]88    assert(( wxyz[iw, ix, iy][iz] == valExpected ));
[63a4b92]89}
90
91// All orders that skip a single dimension, each in its most natural split.
[b9dae14c]92forall( [Nw], [Nx], [Ny], [Nz] )
[63a4b92]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
[938885d3]100    valExpected = getMagicNumber(iw, ix, iy, iz);
[63a4b92]101    assert( wxyz[iw][ix][iy][iz] == valExpected );
102
103
104    // order wxyz (no intermediates to declare)
105
[1d71208]106    assert(( wxyz[iw  , ix  , iy  , iz  ]       == valExpected ));
107    assert(( wxyz[iw-1, ix  , iy  , iz  ]       != valExpected ));
[63a4b92]108
109    // order xyzw: *xyz, w
110
[1d71208]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 ));
[63a4b92]114
115    // order wyzx: w*yz, x
116
[1d71208]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 ));
[63a4b92]120
121    // order wxzy: wx*z, y
[d653faf]122  #if 0
123    // not working on 32-bit
[1d71208]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 ));
[d653faf]127  #endif
[63a4b92]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.
[1d71208]133// Natural split means the arity of every -[-,...] tuple equals the dimensionality of its "this" operand, then that the fewest "all" subscripts are given.
[63a4b92]134// The commented-out test code shows cases that don't work.  We wish all the comment-coverd cases worked.
[b9dae14c]135forall( [Nw], [Nx], [Ny], [Nz] )
[63a4b92]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
[938885d3]143    valExpected = getMagicNumber(iw, ix, iy, iz);
[63a4b92]144    assert( wxyz[iw][ix][iy][iz] == valExpected );
145
146
147    // order wxyz (no intermediates to declare)
148
[1d71208]149    assert(( wxyz[iw, ix, iy, iz] == valExpected ));
[63a4b92]150
151    {
152        // order wyxz: w*y*, xz
153        assert( wxyz[iw][all][iy][all] [ix][iz] == valExpected );
154
[1d71208]155        typeof( wxyz[iw, all, iy, all] ) xz1 = wxyz[iw, all, iy, all];
156        assert(( xz1[ix, iz]  == valExpected ));
[63a4b92]157
[1d71208]158        typeof( wxyz[iw, all, iy, all] ) xz2;
159        &xz2 = &wxyz[iw, all, iy, all];
160        assert(( xz2[ix, iz]  == valExpected ));
[63a4b92]161
[1d71208]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 ));
[63a4b92]167    }
168    {
169        // order wzxy: w**z, xy
170        assert( wxyz[iw][all][all][iz] [ix][iy] == valExpected );
171
[1d71208]172        // typeof( wxyz[iw, all, all, iz] ) xy1 = wxyz[iw, all, all, iz];
173        // assert(( xy1[ix, iy]  == valExpected ));
[63a4b92]174
[1d71208]175        // typeof(  wxyz[iw, all, all, iz] ) xy2;
176        // &xy2 = &wxyz[iw, all, all, iz];
177        // assert(( xy2[ix, iy]  == valExpected ));
[63a4b92]178
[1d71208]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 ));
[63a4b92]184    }
185    {
186        // order xywz: *xy*, wz
187        assert( wxyz[all][ix][iy][all] [iw][iz] == valExpected );
188
[1d71208]189        typeof( wxyz[all, ix, iy, all] ) wz1 = wxyz[all, ix, iy, all];
190        assert(( wz1[iw, iz]  == valExpected ));
[63a4b92]191
[1d71208]192        assert(( wxyz[all  , ix, iy  , all][iw  , iz  ] == valExpected ));
[63a4b92]193    }
194    {
195        // order xzwy: *x*z, wy
196        assert( wxyz[all][ix][all][iz] [iw][iy] == valExpected );
197
[1d71208]198        // assert(( wxyz[all , ix  , all , iz  ][iw  , iy  ] == valExpected ));
[63a4b92]199    }
200    {
201        // order yzwx: **yz, wx
202        assert( wxyz[all][all][iy][iz] [iw][ix] == valExpected );
203
[1d71208]204        // assert(( wxyz[all , all , iy  , iz  ][iw  , ix  ] == valExpected ));
[63a4b92]205    }
206    {
207        // order xwzy: *x**, w*z, y
208        assert( wxyz[all][ix][all][all] [iw][all][iz] [iy] == valExpected );
209
[1d71208]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  ];
[63a4b92]212        assert( y_workaround[iy] == valExpected );
213
[1d71208]214        // assert(( wxyz[all , ix , all  , all  ][iw  , all , iz  ][iy  ] == valExpected ));
[63a4b92]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
[b9dae14c]233forall( [Nw], [Nx], [Ny], [Nz] )
[63a4b92]234void test_numSubscrTypeCompatibility( tag(Nw), tag(Nx), tag(Ny), tag(Nz) ) {
235
236    array( float, Nw, Nx, Ny, Nz ) wxyz;
237    fillHelloData(wxyz);
238
[938885d3]239    valExpected = getMagicNumber(2, 3, 4, 5);
[63a4b92]240    assert(( wxyz [2] [3] [4] [5]  == valExpected ));
[1d71208]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 ));
[63a4b92]247
[6e50a6b]248    for ( i; Nw ) {
[1d71208]249        assert(( wxyz[ i, 3, 4, 5 ] == getMagicNumber(i, 3, 4, 5) ));
[63a4b92]250    }
251
[6e50a6b]252    for ( i; Nx ) {
[1d71208]253        assert(( wxyz[ 2, i, 4, 5 ] == getMagicNumber(2, i, 4, 5) ));
[63a4b92]254    }
255
[6e50a6b]256    for ( i; Ny ) {
[1d71208]257        assert(( wxyz[ 2, 3, i, 5 ] == getMagicNumber(2, 3, i, 5) ));
[63a4b92]258    }
259
[6e50a6b]260    for ( i; Nz ) {
[1d71208]261        assert(( wxyz[ 2, 3, 4, i ] == getMagicNumber(2, 3, 4, i) ));
[63a4b92]262    }
263
[6e50a6b]264    for ( i; Nw ) {
[1d71208]265        assert(( wxyz[ i, all, 4, 5 ][3] == getMagicNumber(i, 3, 4, 5) ));
[63a4b92]266    }
267
[6e50a6b]268    for ( i; Nw ) {
[1d71208]269        assert(( wxyz[ all, 3, 4, 5 ][i] == getMagicNumber(i, 3, 4, 5) ));
[63a4b92]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) );
[b9dae14c]280    test_numSubscrTypeCompatibility( ztag(KW), ztag(KX), ztag(KY), ztag(KZ) );
[63a4b92]281    printf("done\n");
282}
Note: See TracBrowser for help on using the repository browser.