Hitmap 1.3
 All Data Structures Namespaces Files Functions Variables Typedefs Friends Macros Groups Pages
cannonAsyncTestPadding.c
Go to the documentation of this file.
1 /*
2 * cannonAsyncTestPadding.c
3 * Hitmap example
4 * Cannon's algorithm for Matrix Multiplication
5 *
6 * Aynchronous communication
7 * Testing padded data structures
8 *
9 * v1.1
10 * (c) 2012, Arturo Gonzalez-Escribano
11 */
12 
13 /*
14  * <license>
15  *
16  * Hitmap v1.2
17  *
18  * This software is provided to enhance knowledge and encourage progress in the scientific
19  * community. It should be used only for research and educational purposes. Any reproduction
20  * or use for commercial purpose, public redistribution, in source or binary forms, with or
21  * without modifications, is NOT ALLOWED without the previous authorization of the copyright
22  * holder. The origin of this software must not be misrepresented; you must not claim that you
23  * wrote the original software. If you use this software for any purpose (e.g. publication),
24  * a reference to the software package and the authors must be included.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND ANY
27  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
28  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29  * THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  * Copyright (c) 2007-2015, Trasgo Group, Universidad de Valladolid.
37  * All rights reserved.
38  *
39  * More information on http://trasgo.infor.uva.es/
40  *
41  * </license>
42 */
43 
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <hitmap.h>
47 
48 hit_tileNewType( double );
49 
50 #define MATRIX_AROWS 10
51 #define MATRIX_ACOLUMNS 20
52 #define MATRIX_BCOLUMNS 10
53 
56 
57 void cannonsMM( int n, int m, int p );
58 
59 
60 /* A. MAIN: INVOCATION OF CANNON'S ALGORITHM */
61 int main(int argc, char *argv[]){
62  hit_comInit( &argc, &argv );
63 
65 
67  return 0;
68 }
69 
70 
71 /* B. FUNCTION TO COMPUTE THE PRODUCT OF TWO LOCAL SUBMATRICES */
72 void matrixBlockProduct( HitTile_double A, HitTile_double B, HitTile_double C ) {
73  int i,j,k;
74 #ifdef OPTIMIZE_PRODUCT
75  double *datas[3] = { C.data, A.data, B.data };
76  int rowSizes[3] ={ C.origAcumCard[1],A.origAcumCard[1],B.origAcumCard[1] };
77 # ifdef OPTIMIZE_LOOPS
78  int loopLimits[3] = { hit_tileDimCard(C,0), hit_tileDimCard(C,1), hit_tileDimCard(A,1) };
79  for (i=0; i<loopLimits[0]; i++) {
80  for (j=0; j<loopLimits[1]; j++) {
81  for (k=0; k<loopLimits[2]; k++) {
82 # else
83  for (i=0; i<hit_tileDimCard(C,0); i++) {
84  for (j=0; j<hit_tileDimCard(C,1); j++) {
85  for (k=0; k<hit_tileDimCard(A,1); k++) {
86 # endif
87 #else
88  int minsize1 = min( hit_tileDimCard(A,0), hit_tileDimCard(C,0) );
89  int minsize2 = min( hit_tileDimCard(B,1), hit_tileDimCard(C,1) );
90  int minsize3 = min( hit_tileDimCard(A,1), hit_tileDimCard(B,0) );
91  //for (i=0; i<hit_tileDimCard(C,0); i++) {
92  for (i=0; i<minsize1; i++) {
93  //for (j=0; j<hit_tileDimCard(C,1); j++) {
94  for (j=0; j<minsize2; j++) {
95  //for (k=0; k<hit_tileDimCard(A,1); k++) {
96  for (k=0; k<minsize3; k++) {
97 #endif
98 
99 #ifdef OPTIMIZE_PRODUCT
100  datas[0][i*rowSizes[0]+j] =
101  datas[0][i*rowSizes[0]+j] + datas[1][i*rowSizes[1]+k] * datas[2][k*rowSizes[2]+j] ;
102 #else
103  hit_tileElemAtNoStride(C,2,i,j) =
104  hit_tileElemAtNoStride(C,2,i,j)
105  + hit_tileElemAtNoStride(A,2,i,k) * hit_tileElemAtNoStride(B,2,k,j);
106 #endif
107  }
108  }
109  }
110 }
111 
112 
113 /* C. INITIALIZE MATRICES */
114 void initMatrices( int m, int p,
115  HitTile_double tileA, HitTile_double tileB, HitTile_double tileC,
116  HitLayout layA, HitLayout layB ) {
117  /* 1. INIT C = 0 */
118  double zero=0;
119  hit_tileFill( &tileA, &zero );
120  hit_tileFill( &tileB, &zero );
121  hit_tileFill( &tileC, &zero );
122 
123 #if defined(READ_AB) || defined(WRITE_AB)
124  HitTile_double realTileA, realTileB;
125  hit_tileSelectArrayCoords( &realTileA, &tileA, hit_layShape( layA ) );
126  hit_tileSelectArrayCoords( &realTileB, &tileB, hit_layShape( layB ) );
127 #endif
128 
129 #ifdef READ_AB
130 #ifdef READ_BIN
131  hit_tileFileRead( &realTileA, "A.in", HIT_FILE_ARRAY );
132  hit_tileFileRead( &realTileB, "B.in", HIT_FILE_ARRAY );
133 #else
134  hit_tileTextFileRead( &realTileA, "A.in.dtxt", HIT_FILE_ARRAY, HIT_FILE_DOUBLE, 14, 4 );
135  hit_tileTextFileRead( &realTileB, "B.in.dtxt", HIT_FILE_ARRAY, HIT_FILE_DOUBLE, 14, 4 );
136 #endif
137 #else
138  int i,j;
139 
140  /* 2. INIT A(i,j) = ( i*numCol + j ) % 1000 */
141  hit_layForDimDomain( layA, 0, i )
142  hit_layForDimDomain( layA, 1, j )
143  hit_tileElemAtArrayCoords( tileA, 2, i,j ) = ( i * m + j ) % 1000;
144 
145  /* 3. INIT B: DIFFERENT COMPILE-TIME OPTIONS */
146 #ifdef B_IDENTITY
147  /* 3.a. INIT B = Identity */
148  hit_layForDimDomain( layB, 0, i )
149  hit_layForDimDomain( layB, 1, j )
150  hit_tileElemAtArrayCoords( tileB, 2, i,j ) = (i==j) ? 1.0 : 0.0;
151 #else
152  /* 3.b. INIT B = Random with seed */
153  srand48( 364543 );
154  for (i=0; i<m; i++) {
155  for (j=0; j<p; j++) {
156  if ( i>=hit_layDimBegin(layB,0) && i<=hit_layDimEnd(layB,0) && j>=hit_layDimBegin(layB,1) && j<=hit_layDimEnd(layB,1) )
157  hit_tileElemAtArrayCoords( tileB, 2, i,j ) = drand48();
158  else drand48();
159  }
160  }
161 #endif
162 #endif
163 #ifdef WRITE_AB
164  /* 4. WRITE A,B ON FILES */
165 #ifdef WRITE_BIN
166  hit_tileFileWrite( &realTileA, "A.out", HIT_FILE_ARRAY );
167  hit_tileFileWrite( &realTileB, "B.out", HIT_FILE_ARRAY );
168 #else
169 #ifdef WRITE_TILE_FILES
170  char name[8];
171  sprintf(name, "A.%d", hit_Rank );
172  hit_tileTextFileWrite( &realTileA, name, HIT_FILE_TILE, HIT_FILE_DOUBLE, 14, 4 );
173  sprintf(name, "B.%d", hit_Rank );
174  hit_tileTextFileWrite( &realTileB, name, HIT_FILE_TILE, HIT_FILE_DOUBLE, 14, 4 );
175 #endif
176  hit_tileTextFileWrite( &realTileA, "A.out.dtxt", HIT_FILE_ARRAY, HIT_FILE_DOUBLE, 14, 4 );
177  hit_tileTextFileWrite( &realTileB, "B.out.dtxt", HIT_FILE_ARRAY, HIT_FILE_DOUBLE, 14, 4 );
178 #endif
179 #endif
180 }
181 
182 
183 /* D. PARALLEL CANNON'S ALGORITHM FOR MATRIX MULTIPLICATION */
184 void cannonsMM( int n, int m, int p ) {
185  /* 0. INIT CLOCKS */
187  hit_clockStart( mainClock );
188  hit_clockReset( productClock );
189 
190  /* 1. CREATE VIRTUAL TOPOLOGY */
191  HitTopology topo = hit_topology( plug_topSquare );
192 
193  /* 2. DECLARE FULL MATRICES WITHOUT MEMORY */
194  HitTile_double A, B, C;
195  hit_tileDomain( &A, double, 2, n, m );
196  hit_tileDomain( &B, double, 2, m, p );
197  hit_tileDomain( &C, double, 2, n, p );
198 
199  /* 3. COMPUTE PARTITIONS */
200 #define LAYOUT_BALANCED
201 #ifdef LAYOUT_BALANCED
202  HitLayout layA = hit_layout(plug_layBlocksBalance, topo, hit_tileShape( A ), 0, 0.8f );
203  HitLayout layC = hit_layout(plug_layBlocksBalance, topo, hit_tileShape( C ), 0, 0.8f );
204 #else
205  HitLayout layA = hit_layout(plug_layBlocks, topo, hit_tileShape( A ) );
206  HitLayout layC = hit_layout(plug_layBlocks, topo, hit_tileShape( C ) );
207 #endif
208  HitLayout layB = hit_layout(plug_layBlocks, topo, hit_tileShape( B ) );
209 
210  hit_layWrapNeighbors( &layA );
211  hit_layWrapNeighbors( &layB );
212 
213  /* 4. CREATE AND ALLOCATE TILES */
214  HitTile_double tileA, tileB, tileC, copyTileA, copyTileB;
215  hit_tileSelectNoBoundary( &tileA, &A, hit_layMaxShape(layA));
216  hit_tileSelectNoBoundary( &tileB, &B, hit_layMaxShape(layB) );
217  hit_tileSelect( &tileC, &C, hit_layShape(layC) );
218  hit_tileAlloc( &tileA ); hit_tileAlloc( &tileB ); hit_tileAlloc( &tileC );
219  hit_tileClone( &copyTileA, &tileA ); hit_tileClone( &copyTileB, &tileB );
220 
221  /* 5. INITIALIZE MATRICES */
222  initMatrices( m, p, tileA, tileB, tileC, layA, layB );
223 
224  /* 6. INITIAL ALIGNMENT PHASE */
225  HitCom commRow, commColumn;
226  commRow = hit_comShiftDim( layA, 1, -hit_laySelfRanksDim(layA,0), &tileA, HIT_DOUBLE );
227  commColumn = hit_comShiftDim( layB, 0, -hit_laySelfRanksDim(layB,1), &tileB, HIT_DOUBLE );
228 
229  hit_comDo( &commRow );
230  hit_comDo( &commColumn );
231  hit_comFree( commRow );
232  hit_comFree( commColumn );
233 
234  /* 7. REPEATED COMM PATTERN */
235  HitPattern shift = hit_pattern( HIT_PAT_UNORDERED );
236  hit_comTagSet( TAG_A, TAG_B );
237  hit_patternAdd( &shift, hit_comShiftDimAsync(layA, 1, 1, &tileA, &copyTileA, HIT_DOUBLE, TAG_A));
238  hit_patternAdd( &shift, hit_comShiftDimAsync(layB, 0, 1, &tileB, &copyTileB, HIT_DOUBLE, TAG_B));
239 
241  HitTile_double tileA_2, tileB_2, tileC_2;
242  HitSig selx, sely;
243 
244  sely = hit_sig( 0, 1535, 1);
245  selx = hit_sig( 0, hit_tileDimCard( tileA, 0 )-1, 1 );
246  hit_tileSelectNoBoundary( &tileA_2, &tileA, hit_shape(2, selx, sely ));
247  hit_tileAlloc( &tileA_2 );
248 
249  selx = hit_sig( 0, hit_tileDimCard( tileB, 0 )-1, 1 );
250  hit_tileSelectNoBoundary( &tileB_2, &tileB, hit_shape(2, selx, sely ));
251  hit_tileAlloc( &tileB_2 );
252 
253  selx = hit_sig( 0, hit_tileDimCard( tileC, 0 )-1, 1 );
254  hit_tileSelectNoBoundary( &tileC_2, &tileC, hit_shape(2, selx, sely ));
255  hit_tileAlloc( &tileC_2 );
256 
257  double zero=0;
258  hit_tileFill( &tileA_2, &zero );
259  hit_tileFill( &tileB_2, &zero );
260  hit_tileFill( &tileC_2, &zero );
261 
262  /* 8. DO COMPUTATION */
263  int loopIndex;
264  int loopLimit = hit_max( layA.numActives[0], layA.numActives[1] );
265  for (loopIndex = 0; loopIndex < loopLimit-1; loopIndex++) {
266  /* 8.1. START COMMUNICATIONS FROM TILES TO REMOTE TILE BUFFERS */
267  hit_patternStartAsync( shift );
268 
269  /* 8.2. CLOCK TO MEASURE SECUENTIAL TIME OF THE PRODUCT */
270  hit_clockContinue( productClock );
271 
273  hit_tileUpdateFromAncestor( &tileA_2 );
274  hit_tileUpdateFromAncestor( &tileB_2 );
275 
276  //matrixBlockProduct( tileA, tileB, tileC );
277  matrixBlockProduct( tileA_2, tileB_2, tileC_2 );
278 
280  hit_tileUpdateToAncestor( &tileC_2 );
281 
282  hit_clockStop( productClock );
283 
284  /* 8.3. END COMMUNICATIONS, MOVE DATA FROM TILE BUFFERS */
285  hit_patternEndAsync( shift );
286  hit_tileUpdateToAncestor( &copyTileA );
287  hit_tileUpdateToAncestor( &copyTileB );
288  }
289  /* 9. LAST ITERATION MULTIPLICATION: NO COMMUNICATION AFTER */
290  hit_clockContinue( productClock );
292  hit_tileUpdateFromAncestor( &tileA_2 );
293  hit_tileUpdateFromAncestor( &tileB_2 );
294  //matrixBlockProduct( tileA, tileB, tileC );
295  matrixBlockProduct( tileA_2, tileB_2, tileC_2 );
297  hit_tileUpdateToAncestor( &tileC_2 );
298  hit_clockStop( productClock );
300  hit_tileFree( tileA_2 );
301  hit_tileFree( tileB_2 );
302  hit_tileFree( tileC_2 );
303 
304  /* 10. CLOCK RESULTS */
305  hit_clockStop( mainClock );
306  hit_clockReduce( layC, mainClock );
307  hit_clockReduce( layC, productClock );
308  hit_clockPrintMax( mainClock );
309  hit_clockPrintMax( productClock );
310 
311  /* 11. WRITE RESULT MATRIX */
312 #ifdef WRITE_RESULT
313 #ifdef WRITE_BIN
314  hit_tileFileWrite( &tileC, "C.out", HIT_FILE_ARRAY );
315 #else
316  hit_tileTextFileWrite( &tileC, "C.dtxt", HIT_FILE_ARRAY, HIT_FILE_DOUBLE, 14, 4 );
317 #endif
318 #endif
319 
320  /* 12. FREE RESOURCES */
321  hit_tileFree( tileA ); hit_tileFree( tileB ); hit_tileFree( tileC );
322  hit_tileFree( copyTileA ); hit_tileFree( copyTileB );
323  hit_patternFree( &shift );
324  hit_layFree( layA ); hit_layFree( layB ); hit_layFree( layC );
325  hit_topFree( topo );
326 }
327 
void hit_patternEndAsync(HitPattern pattern)
Definition: hit_pattern.c:200
#define hit_shape(nd,...)
Definition: hit_sshape.h:175
#define hit_layShape(lay)
Definition: hit_layout.h:650
#define hit_comTagSet(...)
Definition: hit_com.h:909
#define hit_tileNewType(baseType)
Definition: hit_tile.h:163
HitClock productClock
Definition: cannonAsync.c:56
#define A
Definition: mg.c:64
#define hit_tileFileWrite(var, file, coord)
Definition: hit_tile.h:947
#define hit_clockSynchronizeAll()
Definition: hit_utils.h:55
#define hit_tileFill(var, value)
Definition: hit_tile.h:390
void initMatrices(int m, int p, HitTile_double tileA, HitTile_double tileB, HitTile_double tileC, HitLayout layA, HitLayout layB)
Definition: cannonAsync.c:109
#define hit_Rank
Definition: hit_com.h:140
void srand48(long)
#define B
Definition: mg.c:65
void hit_comFree(HitCom issue)
Definition: hit_com.c:1995
void hit_comDo(HitCom *issue)
Definition: hit_com.c:2408
HitShape hit_layMaxShape(HitLayout lay)
Definition: hit_layout.c:1623
#define hit_clockContinue(c)
Definition: hit_utils.h:121
#define MATRIX_AROWS
#define hit_tileAlloc(var)
Definition: hit_tile.h:319
#define hit_topology(name,...)
Definition: hit_topology.h:308
Definition: hit_sig.h:79
#define MATRIX_ACOLUMNS
#define HIT_FILE_DOUBLE
Definition: hit_tile.h:189
HitClock mainClock
Definition: cannonAsync.c:55
#define hit_laySelfRanksDim(lay, dim)
Definition: hit_layout.h:857
#define hit_tileSelect(newVar, oldVar, shape)
Definition: hit_tile.h:453
#define HIT_PAT_UNORDERED
Definition: hit_pattern.h:81
void hit_patternAdd(HitPattern *pattern, HitCom comm)
Definition: hit_pattern.c:61
#define hit_clockPrintMax(c)
Definition: hit_utils.h:175
#define hit_tileDimCard(var, dim)
Definition: hit_tile.h:750
#define hit_tileFileRead(var, file, coord)
Definition: hit_tile.h:974
#define hit_tileUpdateFromAncestor(shadow)
Definition: hit_tile.h:627
#define hit_clockReset(c)
Definition: hit_utils.h:78
#define hit_tileClone(newVar, oldVar)
Definition: hit_tile.h:404
#define MATRIX_BCOLUMNS
#define hit_tileTextFileWrite(var, file, coord, datatype, s1, s2)
Definition: hit_tile.h:1011
void hit_topFree(HitTopology topo)
Definition: hit_topology.c:129
void hit_layWrapNeighbors(HitLayout *lay)
Definition: hit_layout.c:1593
void hit_patternFree(HitPattern *pattern)
Definition: hit_pattern.c:94
void hit_comInit(int *pargc, char **pargv[])
Definition: hit_com.c:111
#define hit_tileTextFileRead(var, file, coord, datatype, s1, s2)
Definition: hit_tile.h:1045
void cannonsMM(int n, int m, int p)
Definition: cannonAsync.c:179
#define hit_comShiftDim(lay, dim, shift, tileP, baseType)
Definition: hit_com.h:646
#define hit_tileDomain(newVarP, baseType, numDims,...)
Definition: hit_tile.h:286
#define HIT_FILE_TILE
Definition: hit_tile.h:196
#define hit_tileElemAtNoStride(var, ndims,...)
Definition: hit_tile.h:558
void hit_layFree(HitLayout lay)
Definition: hit_layout.c:2251
#define hit_clockStop(c)
Definition: hit_utils.h:109
#define HIT_FILE_ARRAY
Definition: hit_tile.h:201
int main(int argc, char *argv[])
Definition: cannonAsync.c:62
#define m(a, b, c)
#define hit_layDimEnd(lay, dim)
Definition: hit_layout.h:700
#define hit_tileSelectArrayCoords(newVar, oldVar, shape)
Definition: hit_tile.h:494
void matrixBlockProduct(HitTile_double A, HitTile_double B, HitTile_double C)
Definition: cannonAsync.c:73
#define hit_tileElemAtArrayCoords(var, ndims,...)
Definition: hit_tile.h:534
#define hit_tileUpdateToAncestor(shadow)
Definition: hit_tile.h:613
#define hit_layDimBegin(lay, dim)
Definition: hit_layout.h:695
#define hit_comShiftDimAsync(lay, dim, shift, tileSend, tileRecv, baseType, tag)
Definition: hit_com.h:661
#define hit_tileSelectNoBoundary(newVar, oldVar, shape)
Definition: hit_tile.h:434
void hit_patternStartAsync(HitPattern pattern)
Definition: hit_pattern.c:187
#define hit_layout(name, topo,...)
Definition: hit_layout.h:415
#define hit_layForDimDomain(lay, dim, index)
Definition: hit_layout.h:837
#define hit_max(a, b)
Definition: hit_funcop.h:59
#define min(a, b)
Definition: refMPIluBack.c:56
int numActives[HIT_MAXDIMS]
Definition: hit_layout.h:257
#define C
Definition: mg.c:66
#define hit_tileFree(var)
Definition: hit_tile.h:369
#define HIT_DOUBLE
Definition: hit_com.h:78
double drand48()
#define hit_tileShape(var)
Definition: hit_tile.h:723
void hit_comFinalize()
Definition: hit_com.c:159
#define hit_clockReduce(lay, c)
Definition: hit_utils.h:139
#define hit_clockStart(c)
Definition: hit_utils.h:87