Hitmap 1.3
 All Data Structures Namespaces Files Functions Variables Typedefs Friends Macros Groups Pages
luBack.c
Go to the documentation of this file.
1 /*
2 * Hitmap implementation of equation system solver AX = B
3 * using LU factorization and Back substitution
4 *
5 * v0.1: (c) 2010, Carlos de Blas Carton
6 * v0.9: (c) 2012, Arturo Gonzalez-Escribano
7 */
8 
9 /*
10  * <license>
11  *
12  * Hitmap v1.2
13  *
14  * This software is provided to enhance knowledge and encourage progress in the scientific
15  * community. It should be used only for research and educational purposes. Any reproduction
16  * or use for commercial purpose, public redistribution, in source or binary forms, with or
17  * without modifications, is NOT ALLOWED without the previous authorization of the copyright
18  * holder. The origin of this software must not be misrepresented; you must not claim that you
19  * wrote the original software. If you use this software for any purpose (e.g. publication),
20  * a reference to the software package and the authors must be included.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS" AND ANY
23  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
25  * THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * Copyright (c) 2007-2015, Trasgo Group, Universidad de Valladolid.
33  * All rights reserved.
34  *
35  * More information on http://trasgo.infor.uva.es/
36  *
37  * </license>
38 */
39 
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <math.h>
44 #include <sys/time.h>
45 #include <unistd.h>
46 #include <mpi.h>
47 #include <hitmap.h>
48 
49 
50 /*
51  * DECLARE USE OF TILES OF THE PROPER BASETYPE: double
52  */
53 hit_tileNewType(double);
54 
55 /*
56  * PROTOTYPES
57  */
58 void randomMat(HitBlockTile selection, int n1, int n2, int seed, double min, double max);
59 void print(HitBlockTile selection, const char * fileName );
62 
63 /*
64  * HELPER: PRINT USAGE AND EXIT
65  */
67  if ( hit_Rank == 0 ) fprintf(stderr, " \nUsage: lu <matrixSize> <bloqSize>\n\n");
69  exit( EXIT_FAILURE );
70 }
71 
72 
73 /*
74  * MAIN (Timed stages)
75  */
76 int main(int argc, char** argv) {
77  HitClock processTime;
78  HitClock initTime;
79 
80  // 1. INITIALIZE HITMAP COMMUNICATIONS
81  hit_comInit(&argc,&argv);
82 
83  // 2. READ PARAMETERS
84  if ( argc < 2 ) print_help_exit();
85  int n, blockSize;
86  n = atoi(argv[1]);
87  blockSize = atoi(argv[2]);
88  if ( n < 1 || blockSize > n ) print_help_exit();
89 
90  // 3. VIRTUAL TOPOLOGY
91  HitTopology topo;
92  topo = hit_topology(plug_topArray2DComplete);
93 
94  // 4. CREATION OF BLOCK TILE HIERARCHY FOR LOCAL BLOCKS
95  // 4.1. DECLARE THE FULL DOMAINS
96  HitTile_double matrix, vector;
97  hit_tileDomain( &matrix, double, 2, n, n );
98  hit_tileDomain( &vector, double, 2, 1, n );
99 
100  // 4.2. DECLARE THE MULTIBLOCK TILES
101  int blockSizes[2] = { blockSize, blockSize };
102  int blockSizesB[2] = { 1, blockSize };
103  HitBlockTile matrixTiles, vectorTiles;
104  hit_blockTileNew( &matrixTiles, &matrix, blockSizes );
105  hit_blockTileNew( &vectorTiles, &vector, blockSizesB );
106 
107  // 4.3. COMPUTE LAYOUTS
108  HitLayout vectorLayout = hit_layout(plug_layCyclic, topo, hit_tileShape( vectorTiles ), HIT_LAYOUT_NODIM );
109  HitLayout matrixLayout = hit_layout(plug_layCyclic, topo, hit_tileShape( matrixTiles ), HIT_LAYOUT_NODIM );
110  hit_comAllowDims( matrixLayout );
111 
112 
113  // 5. ONLY ACTIVE PROCESSES CONTINUE WITH THE COMPUTATION
114  // OPTIONAL: WARN ABOUT INACTIVE PROCESSORS IN THE LAYOUT
115  //hit_layInactiveWarning( matrixLayout );
116  if ( hit_layImActive( matrixLayout ) ) {
117 
118  // 5.1. DECLARE AND ALLOCATE LAYOUT SELECTIONS
119  HitBlockTile matrixSelection, vectorSelection;
120  hit_blockTileSelect( &matrixSelection, &matrixTiles, hit_layShape( matrixLayout ) );
121  hit_blockTileSelect( &vectorSelection, &vectorTiles, hit_layShape( vectorLayout ) );
122 
123  hit_blockTileAlloc( &matrixSelection, double );
124  hit_blockTileAlloc( &vectorSelection, double );
125 
126  // 5.2. INITIALIZE MATRICES WITH RANDOM VALUES
127  hit_clockStart( initTime );
128  randomMat( matrixSelection, n, n, 0xCAFE, -50.0, 50.0 );
129  // ONLY PROCESSORS IN THE FIRST ROW HAVE PIECES OF THE VECTOR B
130  if ( hit_laySelfRanksDim( matrixLayout, 0 ) == 0 )
131  randomMat( vectorSelection, 1, n, 0xBECA, -50.0, 50.0 );
132  hit_clockStop( initTime );
133 
134 #ifdef WRITE_DATA
135  print( matrixSelection, "A.dtxt" );
136  if ( hit_laySelfRanksDim( matrixLayout, 0 ) == 0 ) print( vectorSelection, "B.dtxt" );
137 #else
138  hit_clockReduce( matrixLayout, initTime );
139  hit_clockPrintMax( initTime );
140 #endif
141 
142  // 5.3. FACTORIZE MATRIX LU = A
143  hit_clockStart( processTime );
144  factorizeMat( matrixLayout, matrixSelection );
145 
146  // 5.4. SOLVE SYSTEM AX = B
147  solveMat( matrixLayout, matrixSelection, vectorSelection );
148  hit_clockStop( processTime );
149 
150 #ifdef WRITE_DATA
151  print( matrixSelection, "LU.dtxt" );
152  if ( hit_laySelfRanksDim( matrixLayout, 0 ) == 0 ) print( vectorSelection, "X.dtxt" );
153 #else
154  hit_clockReduce( matrixLayout, processTime );
155  hit_clockPrintMax( processTime );
156 #endif
157 
158  // 5.5. FREE DATA STRUCTURES
159  hit_blockTileFree( matrixSelection );
160  hit_blockTileFree( vectorSelection );
161 
162  } /* END hit_layImActive */
163 
164  // 6. FREE Hitmap RESOURCES
165  hit_layFree( matrixLayout );
166  hit_layFree( vectorLayout );
167  hit_topFree( topo );
168 
169  // 7. FINALIZE Hitmap USAGE
170  hit_comFinalize();
171  return 0;
172 }
173 
174 
175 /*
176  * MACROS FOR RENAMING DATA ACCESS METHODS
177  * (USED DURING DEBUG, COULD BE FORWARD-SUBSTITUTED)
178  */
179 #define matrixBlockAt(m,i,j) hit_blockTileElemAtNS( m, double, 2, i, j )
180 #define matrixBufferAt(m,i,j) hit_blockTileBufferAtNS( m, double, 2, i, j )
181 #define matrixBlockAtArrayCoords(m,i,j) hit_blockTileElemAtArrayCoords( m, double, 2, i, j )
182 
185 
186 /*
187  * RANDOM DATA INITIALIZATION OF A SELECTED BLOCK TILE
188  */
189 void randomMat(HitBlockTile selection, int n1, int n2, int seed, double min, double max ) {
190  int i;
191 
192  /* 1. CHECK PRECONDITION OF THE RANGE OF RANDOM VALUES */
193  if (min>=max) return;
194 
195  /* 2. INITIALIZE RANDOM SEQUENCE WITH SEED */
196  srand48((long)seed);
197 
198  /* 3. TRAVERSE THE WHOLE ARRAY COORDINATES SPACE, INITIALIZING ONLY THE TILE POSITIONS */
199  int indBlock[2] = { 0, 0 };
200  int ind[2] = { 0, 0 };
201 
202  for (ind[0] = 0; ind[0]<n1; ind[0]++ ) {
203  // COMPUTE THE INDEX OF THE ROW OF BLOCKS, IF I'M NOT THE OWNER, SKIP THE WHOLE ROW
204  indBlock[0] = ind[0] / selection.childSize[0];
205  if ( ! hit_sigIn( hit_tileDimSig( selection, 0 ), indBlock[0] ) ) {
206  for (i=0; i<n2; i++) drand48();
207  continue;
208  }
209 
210  // FOR THE BLOCKS OF THE COLUMNS
211  int numBlocks = (int)ceil( (double)n2 / selection.childSize[1] );
212  for (indBlock[1] = 0; indBlock[1] < numBlocks; indBlock[1]++ ) {
213  // GET THE SIZE WITHOUT PADDING
214  int size;
215  if ( indBlock[1] != numBlocks-1 ) size = selection.childSize[1];
216  else size = ( n2 % selection.childSize[1] == 0 ) ? selection.childSize[1] : n2 % selection.childSize[1];
217 
218  // SKIP IF I'M NOT THE OWNER OF THE BLOCK
219  if ( ! hit_sigIn( hit_tileDimSig( selection, 1 ), indBlock[1] ) ) {
220  for (i=0; i < size; i++) drand48();
221  continue;
222  }
223 
224  // GET BLOCK
225  HitTile_double block = matrixBlockAtArrayCoords( selection, indBlock[0], indBlock[1] );
226 
227  // FILL MY BLOCK (TAKE CARE WITH THE PADDING IN THE LAST BLOCK)
228  int localInd = ind[0] % selection.childSize[0];
229  for (ind[1] = 0; ind[1] < size; ind[1]++)
230  hit_tileElemAtNoStride( block, 2, localInd, ind[1] ) = drand48()*(max-min)+min;
231 
232  }
233 
234  }
235 }
236 
237 
238 /*
239  * PRINT ALL THE BLOCK OF A BLOCK-TILE IN A STREAM
240  */
241 void print( HitBlockTile selection, const char * fileName ) {
242  int ind[2];
243  hit_tileForDimDomain ( selection, 0, ind[0] ) {
244  hit_tileForDimDomain ( selection, 1, ind[1] ) {
245  HitTile_double block = matrixBlockAt( selection, ind[0], ind[1] );
246  hit_tileTextFileWrite( &block, fileName, HIT_FILE_ARRAY, HIT_FILE_DOUBLE, 16, 6 );
247  }
248  }
249 }
250 
251 
252 /*
253  * SEQUENTIAL MATRIX-MATRIX, MATRIX-VECTOR OPERATIONS
254  */
255 
256 /*
257  * SOLVES AX=B' / A MxM matrix, X and B MxN matrices
258  * A is upper triangular
259  * B' is B transposed
260  * Solution in B
261  * Requires m,n>=0
262  */
263 void strsmuv(HitTile_double a, HitTile_double b) {
264  int j,k,i;
265  double temp;
266 
267  int n = hit_tileDimCard( b, 0 );
268  int m = hit_tileDimCard( b, 1 );
269  if (m==0 || n==0) return;
270 
271  for(k=m-1;k>=0;k--) {
272  for(i=m-1;i>k;i--) {
273  if((temp=-hit_tileGetNoStride(a,2,k,i))!=0.0) {
274  for (j=0;j<n;j++) {
275  hit_tileElemAtNoStride(b,2,j,k) += temp * hit_tileGetNoStride(b,2,j,i);
276  }
277  }
278  }
279 
280  temp=hit_tileGetNoStride(a,2,k,k);
281 
282  for(j=0;j<n;j++) {
283  hit_tileSetNoStride(b,2,hit_tileGetNoStride(b,2,j,k)/temp,j,k);
284  }
285  }
286 }
287 
288 /*
289  * SOLVES AX=B' / A MxM matrix, X and B MxN matrices
290  * B' is B transposed (NxM)
291  * A is lower triangular with 1's in the diagonal
292  * Solution in B
293  * Requires m,n>=0
294  */
295 void strsmlv(HitTile_double a, HitTile_double b) {
296  int n = hit_tileDimCard( b, 0 );
297  int m = hit_tileDimCard( b, 1 );
298 
299  int j,k,i;
300  double temp;
301 
302  if (m==0 || n==0) return;
303 
304  for(k=0;k<m;k++) {
305  for(i=0;i<k;i++) {
306  if((temp=-hit_tileGetNoStride(a,2,k,i))!=0.0) {
307  for (j=0;j<n;j++) {
308  hit_tileElemAtNoStride(b,2,j,k) += temp * hit_tileGetNoStride(b,2,j,i);
309  }
310  }
311  }
312  }
313 }
314 
315 /*
316  * SOLVES XA=B / A NxN matrix, X and B MxN matrices
317  * A is lower triangular with 1's in the diagonal
318  * Solution in B
319  * Requires m,n>=0
320  */
321 void strsml2( HitTile_double a, HitTile_double b ) {
322  int j,k,i;
323  double temp;
324 
325  int m = hit_tileDimCard( b, 0 );
326  int n = hit_tileDimCard( b, 1 );
327  if (m==0 || n==0) return;
328 
329  for(k=0;k<n;k++) {
330  for(j=0;j<m;j++) {
331  if ( hit_tileGetNoStride(b,2,j,k) != 0.0 ) {
332  hit_tileElemAtNoStride(b,2,j,k) = hit_tileGetNoStride(b,2,j,k)/hit_tileGetNoStride(a,2,k,k);
333  temp=-hit_tileGetNoStride(b,2,j,k);
334  for(i=k+1;i<n;i++)
335  hit_tileElemAtNoStride(b,2,j,i) += temp * hit_tileGetNoStride(a,2,k,i);
336  }
337  }
338  }
339 }
340 
341 /*
342  * SOLVES C=C-AB / A MxK matrix, B KxN matrix and C MxN matrix
343  * Requires m,n,k>=0
344  */
345 void dgemm ( HitTile_double a, HitTile_double b, HitTile_double c ) {
346  double temp;
347  int i,j,l;
348 
349  int m = hit_tileDimCard( a, 0 );
350  int k = hit_tileDimCard( a, 1 );
351  int n = hit_tileDimCard( b, 1 );
352 
353  if (n==0 || m==0 || k==0) return;
354 
355  for(i=0;i<m;i++) {
356  for(l=0;l<k;l++) {
357  if((temp=-hit_tileGetNoStride(a,2,i,l))!=0.0) {
358  for(j=0;j<n;j++) {
359  hit_tileElemAtNoStride(c,2,i,j) += temp * hit_tileGetNoStride(b,2,l,j);
360  }
361  }
362  }
363  }
364 }
365 
366 /*
367  * SOLVES C'=C'-AB' / A MxK matrix, B KxN matrix and C MxN matrix
368  * B' is B transposed
369  * Requires m,n,k>=0
370  */
371 void dgemmv ( HitTile_double a, HitTile_double b, HitTile_double c ) {
372  int m = hit_tileDimCard( a, 0 );
373  int k = hit_tileDimCard( a, 1 );
374  int n = hit_tileDimCard( b, 0 );
375 
376  double temp;
377  int i,j,l;
378 
379  if (n==0 || m==0 || k==0) return;
380 
381  for(i=0;i<m;i++) {
382  for(l=0;l<k;l++) {
383  if((temp=-hit_tileGetNoStride(a,2,i,l))!=0.0) {
384  for(j=0;j<n;j++) {
385  hit_tileElemAtNoStride(c,2,j,i) += temp * hit_tileGetNoStride(b,2,j,l);
386  }
387  }
388  }
389  }
390 }
391 
392 
393 /*
394  * FACTORIZES MATRIX A = L*U
395  */
397  // stage: INDEX TO ADVANCE IN THE DIAGONAL OF BLOCKS
398  // i,j: INDEXES FOR ROWS/COLUMNS OF BLOCKS
399  // ii,jj: INDEXES FOR ROWS/COLUMNS OF ELEMENTS INSIDE A BLOCK
400  // k: INDEX TO ADVANCE IN THE DIAGONAL INSIDE A BLOCK
401  // block: TEMPORAL BLOCK EXTRACTED FROM BLOCK TILES
402  int stage, i, ii, j, jj, k;
403  HitTile_double block;
404 
405  // GENERIC COMMUNICATIONS (SAME TYPE, ONLY SENDER AND BUFFERS ARE UPDATED)
406  HitTile_double bufferBlock;
407  hit_tileDomainAlloc( &bufferBlock, double, 2, hit_blockTileDimBlockSize( mat, 0 ), hit_blockTileDimBlockSize( mat, 1 ) );
408  comBroadcastDiagonalBlock = hit_comBroadcastDimSelect( layout, 0, HIT_RANK_NULL, &bufferBlock, HIT_SHAPE_WHOLE, HIT_COM_TILECOORDS, HIT_DOUBLE );
409 
410  // BUFFERS FOR ONE ROW AND ONE COLUMN OF THE MATRIX
411  // FOR COMMUNICATIONS ACROSS A DIMENSION
412  // (LAYOUT PROPERTY: ALL PROCS. IN THE SAME DIMENSION INDEX HAVE THE SAME BLOCK SIZES)
413  HitBlockTile bufferStageCol, bufferStageRow;
414  hit_blockTileSelect( &bufferStageCol, &mat, hit_shape( 2, HIT_SIG_WHOLE, hit_sigIndex(0) ) );
415  hit_blockTileSelect( &bufferStageRow, &mat, hit_shape( 2, hit_sigIndex(0), HIT_SIG_WHOLE ) );
416  hit_blockTileAlloc( &bufferStageCol, double );
417  hit_blockTileAlloc( &bufferStageRow, double );
418 
419  // COUNT THE NUMBER OF ASSIGNED BLOCKS ALREADY PROCESSED
420  int processedBlocks[2] = { 0, 0 };
421 
422  // LOOP ACROSS THE DIAGONAL
423  HitBlockTile *domain = hit_blockTileRoot( &mat );
424  int numStages = hit_min( hit_tileDimCard( *domain, 0 ), hit_tileDimCard( *domain, 1 ) );
425  for( stage=0; stage<numStages; stage++ ) {
426 
427  int stageRow = processedBlocks[0];
428  int stageColumn = processedBlocks[1];
429  if ( hit_tileDimHasArrayCoord( mat, 0, stage ) ) processedBlocks[0]++;
430  if ( hit_tileDimHasArrayCoord( mat, 1, stage ) ) processedBlocks[1]++;
431 
432  // CREATE STAGE COMMUNICATIONS FOR THE UNPROCESSED BLOCKS IN THE ROW/COLUMN
433  HitCom combloqfil, combloqfilrcv;
434  if( processedBlocks[1] < hit_tileDimCard( mat, 1 ) ) {
435  combloqfilrcv = hit_comBroadcastDimSelect( layout, 0, hit_layDimOwner( layout, 0, stage ), &bufferStageRow, hit_shape2(hit_sigIndex(0), hit_sig( processedBlocks[1], hit_tileDimCard(mat,1)-1,1)), HIT_COM_TILECOORDS, HIT_DOUBLE );
436 
437  if ( stageRow < hit_tileDimCard( mat, 0 ) )
438  combloqfil = hit_comBroadcastDimSelect( layout, 0, HIT_COM_MYSELF, &mat, hit_shape2( hit_sigIndex(stageRow), hit_sig(processedBlocks[1],hit_tileDimCard(mat,1)-1,1)), HIT_COM_TILECOORDS, HIT_DOUBLE );
439  }
440 
441  HitCom combloqcol, combloqcolrcv;
442  if( processedBlocks[0] < hit_tileDimCard(mat,0) ) {
443  combloqcolrcv = hit_comBroadcastDimSelect( layout, 1, hit_layDimOwner( layout, 1, stage ), &bufferStageCol, hit_shape2( hit_sig( processedBlocks[0], hit_tileDimCard(mat,0)-1,1), hit_sigIndex(0)), HIT_COM_TILECOORDS, HIT_DOUBLE );
444 
445  if ( stageColumn < hit_tileDimCard(mat,1) )
446  combloqcol = hit_comBroadcastDimSelect( layout, 1, HIT_COM_MYSELF, &mat, hit_shape2( hit_sig( processedBlocks[0], hit_tileDimCard(mat,0)-1,1), hit_sigIndex(stageColumn)), HIT_COM_TILECOORDS, HIT_DOUBLE );
447  }
448 
449  //
450  // A. PROCESS WITH DIAGONAL BLOCK
451  //
452  if ( hit_tileHasArrayCoords( mat, 2, stage, stage ) ) {
453  block = matrixBlockAtArrayCoords(mat, stage, stage);
454  int numBlockRows = hit_tileDimCard( block, 0 );
455 
456  // k IS THE INDEX OF THE INSIDE-BLOCK DIAGONAL ELEMENT WE ARE UPDATING
457  for( k=0; k < numBlockRows-1; k++ ) {
458  double diagonalElement = hit_tileGetNoStride( block, 2, k, k );
459  if ( diagonalElement == 0.0 ) fprintf(stderr,"Warning: 0.0 in position %d,%d\n",
460  hit_tileTile2Array( block, 0, k ), hit_tileTile2Array( block, 1, k ) );
461 
462  // LAST ELEMENT DOES NOT NEED TO BE PROCESSED
463  if ( k == numBlockRows-1 ) break;
464 
465  // L MULTIPLIER: UPDATE THE REST OF THIS COLUMN
466  for( ii=k+1; ii < numBlockRows; ii++ ) {
467  // AVOID A TRIVIAL 0.0/x DIVISION WITH A TEST
468  double elem = hit_tileGetNoStride(block,2,ii,k);
469  if ( elem != 0.0 ) hit_tileSetNoStride( block, 2, elem/diagonalElement, ii, k );
470  }
471 
472  // SEND THE UPDATED COLUMN TO OTHER PROCESSES WITH THIS ROW OF BLOCKS
473  HitCom comColBellowDiagonal = hit_comBroadcastDimSelect( layout, 1,
475  &block,
476  hit_shape2( hit_sig( k+1, numBlockRows-1, 1 ), hit_sigIndex(k) ),
478  hit_comDo( &comColBellowDiagonal );
479  hit_comFree( comColBellowDiagonal );
480 
481  // UPDATE TRAILING ROWS
482  for( ii = k+1; ii < numBlockRows; ii++ ) {
483  double elem = - hit_tileGetNoStride( block, 2, ii, k );
484  if( elem !=0.0 ) {
485  // UPDATE IN MY DIAGONAL BLOCK
486  int numBlockColumns = hit_tileDimCard( block, 1 );
487  for( jj=k+1; jj < numBlockColumns; jj++ ) {
488  hit_tileElemAtNoStride( block, 2, ii, jj ) += elem * hit_tileGetNoStride(block,2,k,jj);
489  }
490 
491  // UPDATE OTHER BLOCKS IN THE SAME BLOCKS ROW
492  for( j = processedBlocks[1]; j < hit_tileDimCard(mat,1); j++ ) {
493  HitTile_double updateBlock = matrixBlockAt( mat, stageRow, j );
494  for( jj=0; jj < hit_tileDimCard( updateBlock, 1 ); jj++ ) {
495  hit_tileElemAtNoStride( updateBlock, 2, ii, jj ) += elem * hit_tileGetNoStride(updateBlock,2,k,jj);
496  }
497  }
498  }
499  }
500  }
501 
502  // SEND THE UPDATED BLOCK TO OTHER PROCESSES IN THE COLUMN
503  hit_comUpdateDimSendTo( comBroadcastDiagonalBlock, 0, hit_laySelfRanksDim( layout, 0 ) );
504  hit_comUpdateSendTile( comBroadcastDiagonalBlock, matrixBlockAt( mat, stageRow, stageColumn ) );
505  hit_comDo( &comBroadcastDiagonalBlock );
506 
507  // UPDATE BLOCKS BELOW THE DIAGONAL BLOCK
508  for( j = stageRow+1; j < hit_tileDimCard( mat, 0 ); j++ )
509  strsml2( block, matrixBlockAt( mat, j, stageColumn ) );
510 
511  // SEND THE UPDATED BLOCKS TO OTHER PROCESSES IN THE SAME ROW
512  if( stageColumn+1 < hit_tileDimCard( mat, 1 ) ) hit_comDo( &combloqfil );
513  // SEND THE UPDATED BLOCKS OF MY ROW TO OTHER PROCESSES IN THE SAME COLUMN
514  if( stageRow+1 < hit_tileDimCard( mat, 0 ) ) hit_comDo( &combloqcol );
515 
516  // UPDATE THE REST OF TRAILING BLOCKS (RIGHT/BELLOW THE DIAGONAL BLOCK)
517  for( i = stageRow+1; i < hit_tileDimCard( mat, 0 ); i++)
518  for( j = stageColumn+1; j < hit_tileDimCard( mat, 1 ); j++ )
519  dgemm( matrixBlockAt( mat, i, stageColumn ), matrixBlockAt( mat, stageRow, j ), matrixBlockAt( mat, i, j ) );
520 
521  } // END A. PROCESS WITH DIAGONAL BLOCK
522 
523  //
524  // B. PROCESSES IN THE SAME COLUMN AS THE DIAGONAL
525  //
526  else if ( hit_tileDimHasArrayCoord( mat, 1, stage ) ) {
527  // RECEIVE THE UPDATED DIAGONAL BLOCK
528  hit_comUpdateDimSendTo( comBroadcastDiagonalBlock, 0, hit_layDimOwner( layout, 0, stage ) );
529  hit_comUpdateSendTile( comBroadcastDiagonalBlock, bufferBlock );
530  hit_comDo( &comBroadcastDiagonalBlock );
531 
532  // UPDATE BLOCKS IN THE DIAGONAL COLUMN
533  for( i = processedBlocks[0]; i < hit_tileDimCard( mat, 0 ); i++ ) {
534  strsml2( bufferBlock, matrixBlockAt( mat, i, stageColumn ) );
535  }
536 
537  // RECEIVE THE UPDATED ROW OF BLOCKS
538  if( processedBlocks[1] < hit_tileDimCard( mat, 1 )) {
539  hit_comDo( &combloqfilrcv );
540  }
541 
542  // SEND MY UPDATED COLUMN TO OTHER PROCESSES IN THE SAME ROW
543  if( processedBlocks[0] < hit_tileDimCard( mat, 0 )) {
544  hit_comDo( &combloqcol );
545  }
546 
547  // UPDATE TRAILING BLOCKS (BELLOW/RIGHT THE DIAGONAL)
548  for( i = processedBlocks[0]; i < hit_tileDimCard( mat, 0 ); i++ ) {
549  block = matrixBlockAt( mat, i, stageColumn );
550  for( j = processedBlocks[1]; j < hit_tileDimCard( mat, 1 ); j++) {
551  dgemm( block, matrixBlockAt( bufferStageRow, 0, j ), matrixBlockAt( mat, i, j ) );
552  }
553  }
554  }
555  // END B. PROCESSES IN THE SAME COLUMN AS THE DIAGONAL
556 
557  //
558  // C. PROCESSES IN THE SAME ROW AS THE DIAGONAL
559  //
560  else if ( hit_tileDimHasArrayCoord( mat, 0, stage ) ) {
561  block = matrixBlockAt( bufferStageCol, stageRow, 0 );
562  int numRowsBlock = hit_tileDimCard( block, 0 );
563 
564  for( k=0; k < numRowsBlock-1; k++ ){
565  // RECEIVE AN UPDATED COLUMN OF THE MATRIX FOR THE PROCESS WITH THE DIAGONAL BLOCK
566  int owner = hit_layDimOwner( layout, 1, stage );
567  HitCom comColBellowDiagonal = hit_comBroadcastDimSelect( layout, 1, owner, &block, hit_shape(2, hit_sig( k+1, numRowsBlock-1, 1), hit_sigIndex(0) ), HIT_COM_TILECOORDS, HIT_DOUBLE );
568  hit_comDo( &comColBellowDiagonal );
569  hit_comFree( comColBellowDiagonal );
570 
571  // UPDATE TRAILING BLCOKS IN THE ROW
572  for( ii = k+1; ii < numRowsBlock; ii++ ) {
573  double elem = - hit_tileGetNoStride( block, 2, ii, 0 );
574  if( elem != 0.0 ) {
575  for( j = processedBlocks[1]; j < hit_tileDimCard( mat, 1 ); j++ ) {
576  HitTile_double updateBlock = matrixBlockAt( mat, stageRow, j );
577  for( jj=0; jj < hit_tileDimCard( updateBlock, 1 ); jj++ ) {
578  hit_tileElemAtNoStride( updateBlock, 2, ii, jj ) += elem * hit_tileGetNoStride( updateBlock, 2, k, jj );
579  }
580  }
581  }
582  }
583  }
584 
585  // SEND THE UPDATED ROW TO OTHER PROCESSES IN THE COLUMN
586  if( processedBlocks[1] < hit_tileDimCard(mat,1) ) hit_comDo( &combloqfil );
587 
588  // RECEIVE UPDATED COLUMN BLOCKS FROM THE PROCESS BELLOW THE DIAGONAL
589  if( processedBlocks[0] < hit_tileDimCard(mat,0) ) hit_comDo( &combloqcolrcv );
590 
591  // UPDATE TRAILLING BLOCKS
592  for( i = processedBlocks[0]; i < hit_tileDimCard( mat, 0 ); i++ ) {
593  block = matrixBlockAt( bufferStageCol, i, 0 );
594  for( j = processedBlocks[1]; j < hit_tileDimCard( mat, 1 ); j++) {
595  dgemm( block, matrixBlockAt( mat, stageRow, j ), matrixBlockAt( mat, i, j ) );
596  }
597  }
598  }
599  // END C. PROCESSES IN THE SAME ROW AS THE DIAGONAL
600 
601 
602  //
603  // D. PROCESSES WITH NO BLOCKS IN THE DIAGONAL
604  //
605  else {
606  // RECEIVE ROW OF UPDATED BLOCKS FROM THE PROCESS OF MY COLUMN IN THE DIAGONAL ROW
607  if( processedBlocks[1] < hit_tileDimCard(mat,1) ) hit_comDo( &combloqfilrcv );
608 
609  // RECEIVE COLUMN OF UPDATED BLOCKS FROM THE PROCESS OF MY ROW IN THE DIAGONAL COLUMN
610  if( processedBlocks[0] < hit_tileDimCard(mat,0) ) hit_comDo( &combloqcolrcv );
611 
612  // UPDATE TRAILING MATRIX
613  for( i = processedBlocks[0]; i < hit_tileDimCard( mat, 0 ); i++ ) {
614  block = matrixBufferAt( bufferStageCol, i, 0 );
615  for( j = processedBlocks[1]; j < hit_tileDimCard( mat, 1 ); j++) {
616  dgemm( block, matrixBlockAt( bufferStageRow, 0, j ), matrixBlockAt( mat, i, j ) );
617  }
618  }
619  } // END D. PROCESSES WITH NO BLOCKS IN THE DIAGONAL
620 
621 
622  // ALL PROCESSES CHECK TO FREE GENERIC COMM. RESOURCES FOR THIS STAGE
623  if( processedBlocks[1] < hit_tileDimCard( mat, 1 ) ) {
624  hit_comFree( combloqfilrcv );
625  if ( stageRow < hit_tileDimCard( mat, 0 ) ) hit_comFree( combloqfil );
626  }
627  if( processedBlocks[0] < hit_tileDimCard( mat, 0 ) ) {
628  hit_comFree( combloqcolrcv );
629  if ( stageColumn < hit_tileDimCard( mat, 1 ) ) hit_comFree(combloqcol);
630  }
631  }
632 
633  // FREE Hitmap RESOURCES
634  hit_comFree( comBroadcastDiagonalBlock );
635  hit_tileFree( bufferBlock );
636  hit_blockTileFree( bufferStageCol );
637  hit_blockTileFree( bufferStageRow );
638 }
639 
640 
641 /*
642  * SOLVER: EQUATION SYSTEM Ax=B
643  */
645  // GENERIC COMMUNICATIONS (SAME TYPE, ONLY BUFFERS AND SENDER IDs ARE UPDATED)
646  HitOp suma;
648 
649  HitTile_double bufferVectorBlock;
650  hit_tileDomainAlloc( &bufferVectorBlock, double, 2, 1, hit_blockTileDimBlockSize( matb, 1 ) );
651 
652  if ( hit_laySelfRanksDim( layout, 0 ) == 0 ) comReduceVectorBlock = hit_comReduceDimSelect( layout, 1, HIT_RANKS_NULL, &bufferVectorBlock, HIT_SHAPE_WHOLE, HIT_COM_TILECOORDS, &bufferVectorBlock, HIT_SHAPE_WHOLE, HIT_COM_TILECOORDS, HIT_DOUBLE, suma );
653 
654  // SKIP INACTIVE PROCESSES IN THE LAYOUT
655  if( ! hit_layImActive( layout ) ) return;
656 
657  HitBlockTile bufferStageRow;
658  hit_blockTileSelect( &bufferStageRow, &mat, hit_shape( 2, hit_sigIndex(0), HIT_SIG_WHOLE ) );
659  hit_blockTileAlloc( &bufferStageRow, double );
660 
661  int j, jj;
662  HitTile_double blockA, blockB;
663  HitCom combloqfil,combloqfilrcv;
664 
665  int processedBlocks[2] = { 0, 0 };
666 
667  //
668  // PHASE 1. SOLVE Ly=b
669  //
670  int stage;
671  HitBlockTile *domain = hit_blockTileRoot( &mat );
672  int numStages = hit_min( hit_tileDimCard( *domain, 0 ), hit_tileDimCard( *domain, 1 ) );
673  for( stage=0; stage < numStages; stage++ ) {
674  int stageRow = processedBlocks[0];
675  int stageColumn = processedBlocks[1];
676  if ( hit_tileDimHasArrayCoord( mat, 0, stage ) ) processedBlocks[0]++;
677  if ( hit_tileDimHasArrayCoord( mat, 1, stage ) ) processedBlocks[1]++;
678 
679  // RECEPTION OF DATA TO UPDATE VECTOR BLOCKS (ONLY FIRST ROW PROCESSES)
680  if ( hit_tileDimHasArrayCoord( matb, 0, 0 ) )
681  combloqfilrcv = hit_comRecvSelect( layout, hit_ranks2( hit_layDimOwner( layout, 0, stage ), hit_laySelfRanksDim( layout, 1 ) ), &bufferStageRow, hit_shape2( hit_sigIndex(0), hit_sig( 0, processedBlocks[1]-1, 1 ) ), HIT_COM_TILECOORDS, HIT_DOUBLE);
682 
683  //
684  // PROCESS WITH THE BLOCK OF THE VECTOR INDICATED BY stage
685  //
686  if ( hit_tileHasArrayCoords( matb, 2, 0, stage ) ) {
687  blockB = matrixBlockAt( matb, 0, stageColumn );
688 
689  // BLOCKS OF THE MATRIX IN THIS PROCESS
690  if ( hit_tileDimHasArrayCoord( mat, 0, stage ) ) {
691  for( j = stageColumn-1; j >= 0; j-- ) {
692  dgemmv( matrixBlockAt(mat,stageRow,j), matrixBlockAt(matb,0,j), blockB );
693  }
694  blockA = matrixBlockAt( mat, stageRow, stageColumn );
695  }
696  // BLOCKS OF THE MATRIX IN OTHER PROCESS
697  else {
698  // RECEPTION OF ROW
699  hit_comDo( &combloqfilrcv );
700 
701  for( j = stageColumn-1; j >= 0; j-- ) {
702  dgemmv( matrixBlockAt(bufferStageRow,0,j), matrixBlockAt(matb,0,j), blockB );
703  }
704  blockA = matrixBlockAt( bufferStageRow, 0, stageColumn );
705  }
706 
707  // REDUCTION OF PARTIAL RESULTS
708  for( jj=0; jj < hit_tileDimCard( blockB, 1 ); jj++ )
709  hit_tileElemAtNoStride( bufferVectorBlock, 1, jj ) = hit_tileElemAtNoStride( blockB, 2, 0, jj );
710 
711  hit_comUpdateDimSendTo( comReduceVectorBlock, 1, hit_layDimOwner( layout, 1, stage ) );
712  hit_comUpdateRecvTile( comReduceVectorBlock, blockB );
713  hit_comDo( &comReduceVectorBlock );
714 
715  strsmlv( blockA, blockB );
716  }
717 
718 
719  //
720  // PROCESSES WITH OTHER BLOCKS OF THE VECTOR
721  //
722  else if ( hit_tileDimHasArrayCoord( matb, 0, 0 ) ) {
723  for( j=0; j < hit_tileDimCard( bufferVectorBlock, 1 ); j++ ) hit_tileElemAtNoStride( bufferVectorBlock, 1, j ) = 0.0;
724 
725  // BLOCKS OF THE MATRIX IN THIS PROCESS
726  if ( hit_tileDimHasArrayCoord( mat, 0, stage ) ) {
727  for( j=processedBlocks[1]-1; j >= 0; j-- ) {
728  dgemmv( matrixBlockAt(mat,stageRow,j), matrixBlockAt(matb,0,j), bufferVectorBlock );
729  }
730  }
731  // BLOCKS OF THE MATRIX IN OTHER PROCESS
732  else {
733  // RECEPTION OF ROW
734  if( processedBlocks[1] > 0 ) hit_comDo( &combloqfilrcv );
735 
736  for( j=processedBlocks[1]-1; j >= 0; j-- )
737  dgemmv( matrixBlockAt(bufferStageRow,0,j), matrixBlockAt(matb,0,j), bufferVectorBlock );
738  }
739 
740  // SENDING PARTIAL RESULTS
741  hit_comUpdateDimSendTo( comReduceVectorBlock, 1, hit_layDimOwner( layout, 1, stage ) );
742  hit_comDo( &comReduceVectorBlock );
743  }
744 
745  //
746  // PROCESSES WITH BLOCKS IN THE ROW INDICATED BY stage
747  //
748  else if ( hit_tileDimHasArrayCoord( mat, 0, stage ) ) {
749  if ( processedBlocks[1] > 0 ) {
750  combloqfil = hit_comSendSelect( layout, hit_ranks2( 0, hit_laySelfRanksDim( layout, 1 ) ), &mat, hit_shape2( hit_sigIndex( stageRow ), hit_sig( 0, processedBlocks[1]-1, 1) ), HIT_COM_TILECOORDS, HIT_DOUBLE);
751  hit_comDo( &combloqfil );
752  hit_comFree( combloqfil );
753  }
754  }
755 
756  // FREE COMM. RESOURCES
757  if ( hit_tileDimHasArrayCoord( matb, 0, 0 ) ) hit_comFree( combloqfilrcv );
758  }
759 
760 
761  //
762  // PHASE 1. SOLVE Ux=y
763  //
764  processedBlocks[0] = hit_tileDimCard( mat, 0 )-1;
765  processedBlocks[1] = hit_tileDimCard( mat, 1 )-1;
766  for( stage = numStages-1; stage >= 0; stage-- ) {
767  int stageRow = processedBlocks[0];
768  int stageColumn = processedBlocks[1];
769  if ( hit_tileDimHasArrayCoord( mat, 0, stage ) ) processedBlocks[0]--;
770  if ( hit_tileDimHasArrayCoord( mat, 1, stage ) ) processedBlocks[1]--;
771 
772  if( processedBlocks[1]+1 < hit_tileDimCard( mat, 1 ) ) {
773  if ( hit_tileDimHasArrayCoord( matb, 0, 0 ) )
774  combloqfilrcv = hit_comRecvSelect( layout, hit_ranks2( hit_layDimOwner( layout, 0, stage), hit_laySelfRanksDim( layout, 1 ) ), &bufferStageRow, hit_shape2( hit_sigIndex(0), hit_sig( processedBlocks[1]+1, hit_tileDimCard(mat,1)-1, 1 ) ), HIT_COM_TILECOORDS, HIT_DOUBLE);
775  }
776 
777  //
778  // PROCESS WITH THE BLOCK OF THE VECTOR INDICATED BY stage
779  //
780  if ( hit_tileHasArrayCoords( matb, 2, 0, stage ) ) {
781  blockB = matrixBlockAt( matb, 0, stageColumn );
782 
783  if ( hit_tileDimHasArrayCoord( mat, 0, stage ) ) { //blocks of matrix are also mine
784  for( j = stageColumn+1; j < hit_tileDimCard( matb, 1 ); j++ ) {
785  dgemmv( matrixBlockAt(mat,stageRow,j), matrixBlockAt(matb,0,j), blockB );
786  }
787  blockA = matrixBlockAt( mat, stageRow, stageColumn );
788  }
789  else {
790  hit_comDo( &combloqfilrcv );
791 
792  for( j= stageColumn+1; j <hit_tileDimCard( matb, 1 ); j++ ) {
793  dgemmv( matrixBlockAt(bufferStageRow,0,j), matrixBlockAt(matb,0,j), blockB );
794  }
795  blockA = matrixBlockAt( bufferStageRow, 0, stageColumn );
796  }
797 
798  // REDUCTION OF PARTIAL RESULTS
799  for( jj=0; jj < hit_tileDimCard( blockB, 1 ); jj++ )
800  hit_tileElemAtNoStride( bufferVectorBlock, 1, jj ) = hit_tileElemAtNoStride( blockB, 2, 0, jj );
801 
802  hit_comUpdateDimSendTo( comReduceVectorBlock, 1, hit_layDimOwner( layout, 1, stage ) );
803  hit_comUpdateRecvTile(comReduceVectorBlock, blockB );
804  hit_comDo( &comReduceVectorBlock );
805 
806  strsmuv( blockA, blockB );
807  }
808 
809 
810  //
811  // PROCESSES WITH OTHER BLOCKS OF THE VECTOR
812  //
813  else if ( hit_tileDimHasArrayCoord( matb, 0, 0 ) ) {
814  // INITIALIZE ACCUMULATOR BLOCK WITH 0s
815  for( j=0; j < hit_tileDimCard( bufferVectorBlock, 1 ); j++ ) hit_tileElemAtNoStride( bufferVectorBlock, 1, j ) = 0.0;
816 
817  if ( hit_tileDimHasArrayCoord( mat, 0, stage ) ) {
818  for( j=processedBlocks[1]+1; j < hit_tileDimCard( matb, 1); j++ ) {
819  dgemmv( matrixBlockAt(mat,stageRow,j), matrixBlockAt(matb,0,j), bufferVectorBlock );
820  }
821  }
822  else {
823  if( processedBlocks[1]+1 < hit_tileDimCard( matb, 1 ) ) hit_comDo( &combloqfilrcv );
824  for( j=processedBlocks[1]+1; j < hit_tileDimCard( matb, 1 ); j++ )
825  dgemmv( matrixBlockAt(bufferStageRow,0,j), matrixBlockAt(matb,0,j), bufferVectorBlock );
826  }
827 
828  // SENDING PARTIAL RESULTS
829  hit_comUpdateDimSendTo( comReduceVectorBlock, 1, hit_layDimOwner( layout, 1, stage ) );
830  hit_comDo( &comReduceVectorBlock );
831  }
832 
833  //
834  // PROCESSES WITH BLOCKS IN THE ROW INDICATED BY stage
835  //
836  else if ( hit_tileDimHasArrayCoord( mat, 0, stage ) ) {
837  if ( processedBlocks[1]+1 < hit_tileDimCard( mat, 1 ) ) {
838  combloqfil = hit_comSendSelect( layout, hit_ranks2( 0, hit_laySelfRanksDim( layout, 1 ) ), &mat, hit_shape2( hit_sigIndex( stageRow ), hit_sig( processedBlocks[1]+1, hit_tileDimCard(mat,1)-1, 1) ), HIT_COM_TILECOORDS, HIT_DOUBLE);
839  hit_comDo( &combloqfil );
840  hit_comFree( combloqfil );
841  }
842  }
843  if ( processedBlocks[1]+1 < hit_tileDimCard( mat, 1 ) ) {
844  if ( hit_tileDimHasArrayCoord( matb, 0, 0 ) ) hit_comFree(combloqfilrcv);
845  }
846  }
847 
848  // FREE Hitmap RESOURCES
849  hit_comOpFree(suma);
850  hit_comFree( comReduceVectorBlock );
851  hit_tileFree( bufferVectorBlock );
852  hit_blockTileFree( bufferStageRow );
853 }
#define hit_shape(nd,...)
Definition: hit_sshape.h:175
MPI_Op HitOp
Definition: hit_com.h:118
HitShape block[k_num]
Definition: mg.c:156
#define hit_tileHasArrayCoords(var, ndims,...)
Definition: hit_tile.h:850
#define hit_layShape(lay)
Definition: hit_layout.h:650
int hit_layDimOwner(HitLayout lay, int dim, int ind)
Definition: hit_layout.c:2223
void strsmuv(HitTile_double a, HitTile_double b)
Definition: luBack.c:263
#define hit_tileNewType(baseType)
Definition: hit_tile.h:163
HitCom comReduceVectorBlock
Definition: luBack.c:184
void hit_comOpSumDouble(void *, void *, int *, HitType *)
Definition: hit_com.c:2665
void randomMat(HitBlockTile selection, int n1, int n2, int seed, double min, double max)
Definition: luBack.c:189
#define hit_comOpFree(operation)
Definition: hit_com.h:1048
#define hit_comSendSelect(lay, sendTo, tileP, selection, modeSelect, baseType)
Definition: hit_com.h:442
#define hit_Rank
Definition: hit_com.h:140
void srand48(long)
#define hit_comUpdateDimSendTo(comm, dim, SendTo)
Definition: hit_com.h:550
void hit_comFree(HitCom issue)
Definition: hit_com.c:1995
void hit_comDo(HitCom *issue)
Definition: hit_com.c:2408
#define hit_tileDimSig(var, dim)
Definition: hit_tile.h:776
#define hit_comUpdateSendTile(comm, sendTile)
Definition: hit_com.h:509
#define hit_tileDomainAlloc(newVarP, baseType, numDims,...)
Definition: hit_tile.h:336
HitLayout layout[k_num]
Definition: mg.c:150
HitShape HIT_SHAPE_WHOLE
Definition: hit_shape.c:75
#define hit_comUpdateRecvTile(comm, recvTile)
Definition: hit_com.h:519
#define hit_topology(name,...)
Definition: hit_topology.h:308
HitRanks HIT_RANKS_NULL
Definition: hit_topology.c:68
#define hit_sigIn(sig, ind)
Definition: hit_sig.h:186
int HIT_RANK_NULL
Definition: hit_topology.c:67
#define hit_blockTileSelect(...)
#define HIT_FILE_DOUBLE
Definition: hit_tile.h:189
void print(HitBlockTile selection, const char *fileName)
Definition: luBack.c:241
#define hit_laySelfRanksDim(lay, dim)
Definition: hit_layout.h:857
void print_help_exit()
Definition: luBack.c:66
#define hit_clockPrintMax(c)
Definition: hit_utils.h:175
#define matrixBlockAtArrayCoords(m, i, j)
Definition: luBack.c:181
#define hit_tileDimCard(var, dim)
Definition: hit_tile.h:750
void factorizeMat(HitLayout, HitBlockTile)
Definition: luBack.c:396
#define hit_blockTileDimBlockSize(tile, dim)
HitCom hit_comBroadcastDimSelect(HitLayout lay, int dim, int root, const void *tile, HitShape selection, int modeSelect, HitType baseType)
Definition: hit_com.c:779
void dgemm(HitTile_double a, HitTile_double b, HitTile_double c)
Definition: luBack.c:345
#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 hit_comOp(function, operation)
Definition: hit_com.h:1036
int size[2]
Definition: SWcommon.c:57
HitCom comBroadcastDiagonalBlock
Definition: luBack.c:183
void hit_blockTileFree(HitBlockTile container)
void dgemmv(HitTile_double a, HitTile_double b, HitTile_double c)
Definition: luBack.c:371
#define hit_tileDimHasArrayCoord(var, dim, pos)
Definition: hit_tile.h:836
#define hit_tileTile2Array(var, dim, pos)
Definition: hit_tile.h:864
void hit_comInit(int *pargc, char **pargv[])
Definition: hit_com.c:111
HitSig HIT_SIG_WHOLE
Definition: hit_sig.c:49
#define hit_layImActive(lay)
Definition: hit_layout.h:797
void solveMat(HitLayout, HitBlockTile, HitBlockTile)
Definition: luBack.c:644
#define hit_tileDomain(newVarP, baseType, numDims,...)
Definition: hit_tile.h:286
#define hit_tileElemAtNoStride(var, ndims,...)
Definition: hit_tile.h:558
void hit_layFree(HitLayout lay)
Definition: hit_layout.c:2251
#define HIT_COM_MYSELF
Definition: hit_com.h:135
#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 hit_blockTileAlloc(varP, baseType)
#define HIT_LAYOUT_NODIM
Definition: hit_layout.h:173
#define hit_comRecvSelect(lay, receiveFrom, tileP, selection, modeSelect, baseType)
Definition: hit_com.h:489
#define m(a, b, c)
#define matrixBufferAt(m, i, j)
Definition: luBack.c:180
#define matrixBlockAt(m, i, j)
Definition: luBack.c:179
#define hit_tileForDimDomain(tile, dim, index)
Definition: hit_tile.h:587
HitCom hit_comReduceDimSelect(HitLayout lay, int dim, HitRanks root, const void *tilePSend, HitShape selectionSend, int modeSelectSend, const void *tilePRecv, HitShape selectionRecv, int modeSelectRecv, HitType baseType, HitOp operation)
Definition: hit_com.c:660
#define hit_comAllowDims(lay)
Definition: hit_com.h:587
#define hit_layout(name, topo,...)
Definition: hit_layout.h:415
#define min(a, b)
Definition: refMPIluBack.c:56
#define HIT_COM_TILECOORDS
Definition: hit_com.h:343
#define hit_min(a, b)
Definition: hit_funcop.h:65
void strsmlv(HitTile_double a, HitTile_double b)
Definition: luBack.c:295
#define hit_tileFree(var)
Definition: hit_tile.h:369
void hit_blockTileNew(HitBlockTile *container, void *originalVar, int blockSizes[HIT_MAXDIMS])
Definition: hit_blockTile.c:47
#define max(a, b)
Definition: cannonAsync.c:47
void strsml2(HitTile_double a, HitTile_double b)
Definition: luBack.c:321
#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