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