PaStiX Handbook  6.2.1
pastix_subtask_symbfact.c
Go to the documentation of this file.
1 /**
2  *
3  * @file pastix_subtask_symbfact.c
4  *
5  * PaStiX symbolic factorizations task.
6  * Contains wrappers to the symbolic factorization step.
7  * Affetcted by the compilation time options:
8  * - PASTIX_SYMBOL_DUMP_SYMBMTX: Dump the symbol matrix in a postscript file.
9  * - COMPACT_SMX: Optimization for solve step (TODO: check if not obsolete)
10  * - FORGET_PARTITION: Force to forget the precomputed partition
11  *
12  * @copyright 2015-2021 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
13  * Univ. Bordeaux. All rights reserved.
14  *
15  * @version 6.2.0
16  * @author Xavier Lacoste
17  * @author Pierre Ramet
18  * @author Mathieu Faverge
19  * @author Gregoire Pichon
20  * @author Tony Delarue
21  * @date 2021-01-25
22  *
23  **/
24 #include "common.h"
25 #include <spm.h>
26 #include "graph/graph.h"
27 #include "pastix/order.h"
28 #include "symbol/symbol.h"
29 
30 /**
31  *******************************************************************************
32  *
33  * @ingroup pastix_analyze
34  *
35  * @brief Computes the symbolic factorization step.
36  *
37  * Computes the symbolic matrix structure and if required the amalgamated
38  * supernode partition.
39  *
40  * The function is a *centralized* algorithm to generate the symbol matrix
41  * structure associated to the problem. It takes as input the ordemesh structure
42  * (permutation array, inverse permutation array, and optionnal supernodes
43  * array) and returns the modified ordemesh structure if changed, and the
44  * symbolic structure.
45  * - If a direct factorization is performed, the structure is generated with
46  * pastixSymbolFaxDirect() thanks to the information provided by the ordering
47  * steps (permutation, partition, and elimination tree).
48  * - If an ILU(k) factorization is performed, pastixSymbolFaxILUk() is used to
49  * generate the symbol matrix structure. It requires an intermediate step to
50  * generate the csr graph of L with incomplete factorization.
51  *
52  * Both algorithms are working with a centralized version of the graph and are
53  * replicated on every nodes. If a distributed graph has been used, it is
54  * gathered on each node to compute the symbol matrix.
55  *
56  * This routine is affected by the following parameters:
57  * IPARM_VERBOSE, IPARM_INCOMPLETE, IPARM_LEVEL_OF_FILL,
58  * IPARM_IO_STRATEGY, IPARM_FLOAT, IPARM_FACTORIZATION
59  *
60  * On exit, the following parameters are set:
61  * IPARM_NNZEROS, DPARM_FACT_THFLOPS, DPARM_FACT_RLFLOPS
62  *
63  *******************************************************************************
64  *
65  * @param[inout] pastix_data
66  * The pastix_data structure that describes the solver instance.
67  * On exit, the field symbmtx is initialized with the symbol matrix,
68  * and the field ordemesh is updated if the supernode partition is
69  * computed.
70  * - IPARM_INCOMPLETE switches the factorization mode from direct to ILU(k).
71  * - IPARM_LEVEL_OF_FILL defines the level of incomplete factorization
72  * if IPARM_INCOMPLETE == 1. If IPARM_LEVEL_OF_FILL < 0, the
73  * full pattern is generated as for direct factorization.
74  * - IPARM_IO_STRATEGY will enable to load/store the result to files.
75  * If set to PastixIOSave, the symbmtx and the generated ordemesh is
76  * dump to file.
77  * If set to PastixIOLoad, the symbmtx (only) is loaded from the files.
78  *
79  *******************************************************************************
80  *
81  * @retval PASTIX_SUCCESS on successful exit
82  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect.
83  * @retval PASTIX_ERR_OUTOFMEMORY if one allocation failed.
84  * @retval PASTIX_ERR_INTEGER_TYPE if Scotch integer type is not the
85  * same size as PaStiX ones.
86  * @retval PASTIX_ERR_INTERNAL if an error occurs internally to Scotch.
87  *
88  *******************************************************************************/
89 int
90 pastix_subtask_symbfact( pastix_data_t *pastix_data )
91 {
92  pastix_int_t *iparm;
93  double *dparm;
94  pastix_graph_t *graph;
95  pastix_order_t *ordemesh;
96  int procnum;
97  Clock timer;
98 
99 #if defined( PASTIX_DISTRIBUTED )
100  pastix_int_t *PTS_perm = NULL;
101  pastix_int_t *PTS_rev_perm = NULL;
102  pastix_int_t *tmpperm = NULL;
103  pastix_int_t *tmpperi = NULL;
104  pastix_int_t gN;
105  pastix_int_t i;
106 #endif
107 
108  /*
109  * Check parameters
110  */
111  if ( pastix_data == NULL ) {
112  errorPrint( "pastix_subtask_symbfact: wrong pastix_data parameter" );
114  }
115  iparm = pastix_data->iparm;
116  dparm = pastix_data->dparm;
117 
118  if ( !( pastix_data->steps & STEP_ORDERING ) ) {
119  errorPrint( "pastix_subtask_symbfact: pastix_subtask_order() has to be called before "
120  "calling this function" );
122  }
123 
124  procnum = pastix_data->procnum;
125  graph = pastix_data->graph;
126  ordemesh = pastix_data->ordemesh;
127 
128  if ( graph == NULL ) {
129  errorPrint( "pastix_subtask_symbfact: the pastix_data->graph field has not been "
130  "initialized, pastix_subtask_order should be called first" );
132  }
133  if ( ordemesh == NULL ) {
134  errorPrint( "pastix_subtask_symbfact: the pastix_data->ordemesh field has not been "
135  "initialized, pastix_subtask_order should be called first" );
137  }
138 
139  clockStart( timer );
140 
141  /* Make sure they are both 0-based */
142  pastixOrderBase( ordemesh, 0 );
143  graphBase( graph, 0 );
144 
145  if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
146  pastix_print( procnum, 0, OUT_STEP_FAX );
147  }
148 
149  /* Allocate the symbol matrix structure */
150  if ( pastix_data->symbmtx == NULL ) {
151  MALLOC_INTERN( pastix_data->symbmtx, 1, symbol_matrix_t );
152  }
153  else {
154  pastixSymbolExit( pastix_data->symbmtx );
155  }
156 
157  /*Symbol matrix loaded from file */
158  if ( iparm[IPARM_IO_STRATEGY] & PastixIOLoad ) {
159  FILE *stream = NULL;
160  stream = pastix_fopen( "symbname" );
161  if ( stream ) {
162  pastixSymbolLoad( pastix_data->symbmtx, stream );
163  fclose( stream );
164  }
165  }
166  /* Symbol matrix computed through Fax (Direct or ILU(k)) */
167  else {
168  pastix_int_t nfax;
169  pastix_int_t *colptrfax;
170  pastix_int_t *rowfax;
171 
172  /* Check correctness of parameters */
173  if ( iparm[IPARM_INCOMPLETE] == 0 ) {
174 #if defined( COMPACT_SMX )
175  if ( procnum == 0 )
176  errorPrintW( "COMPACT_SMX only works with incomplete factorization, force ILU(%d) "
177  "factorization.",
178  iparm[IPARM_LEVEL_OF_FILL] );
179  iparm[IPARM_INCOMPLETE] = 1;
180 #endif
181  }
182  /* End of parameters check */
183 
184  /*
185  * Fax works with centralized interface, we convert the cscd to csc if required
186  */
187 #if defined( PASTIX_DISTRIBUTED )
188  if ( graph->loc2glob != NULL ) {
189  cscd2csc_int( graph->n,
190  graph->colptr,
191  graph->rowptr,
192  NULL,
193  NULL,
194  NULL,
195  NULL,
196  &nfax,
197  &colptrfax,
198  &rowfax,
199  NULL,
200  NULL,
201  NULL,
202  NULL,
203  graph->loc2glob,
204  pastix_data->pastix_comm,
205  iparm[IPARM_DOF_NBR],
206  1 );
207  }
208  else
209 #endif
210  {
211  nfax = graph->n;
212  colptrfax = graph->colptr;
213  rowfax = graph->rowptr;
214  }
215 
216  pastixSymbolInit( graph, ordemesh, pastix_data->symbmtx );
217 
218  /*
219  * The amalgamate supernodes partition has been found with (PT-)Scotch,
220  * we use it to generate the symbol matrix structure.
221  * This works only if direct factorization will be performed.
222  */
223  if ( !iparm[IPARM_INCOMPLETE] || ( iparm[IPARM_LEVEL_OF_FILL] == -1 ) ) {
224  if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
225  pastix_print( procnum, 0, OUT_FAX_METHOD, "Fax Direct" );
226  }
227 
228  pastixSymbolFaxDirect( pastix_data->symbmtx, /* Symbol Matrix */
229  graph,
230  ordemesh );
231  }
232  else {
233  if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
234  pastix_print( procnum, 0, OUT_FAX_METHOD, "Fax ILU(k)" );
235  }
236 
237  pastixSymbolFaxILUk( pastix_data->symbmtx, /* Symbol Matrix */
238  iparm[IPARM_LEVEL_OF_FILL],
239  graph,
240  ordemesh );
241  }
242 
243  /* Set the beginning of the Schur complement */
244  pastix_data->symbmtx->schurfcol =
245  nfax - pastix_data->schur_n + pastix_data->symbmtx->baseval;
246 
247  if ( graph->loc2glob != NULL ) {
248  memFree_null( colptrfax );
249  memFree_null( rowfax );
250  }
251  } /* not PastixIOLoad */
252 
253  /* Rebase to 0 */
254  pastixSymbolBase( pastix_data->symbmtx, 0 );
255 
256  /* Build the browtabs and Realign data structure */
257  pastixSymbolBuildRowtab( pastix_data->symbmtx );
258  pastixSymbolRealloc( pastix_data->symbmtx );
259 
260  if ( ordemesh->selevtx != NULL ) {
261  symbol_matrix_t *symbmtx = pastix_data->symbmtx;
262  symbol_cblk_t *cblk = symbmtx->cblktab;
263  int8_t *selevtx = ordemesh->selevtx;
264  pastix_int_t i;
265 
266  for(i=0; i<symbmtx->cblknbr; i++, cblk++, selevtx++ ) {
267  cblk->selevtx = *selevtx;
268  }
269  }
270 
271 #if !defined( NDEBUG )
272  if ( pastixOrderCheck( ordemesh ) != 0 ) {
273  errorPrint( "pastix_subtask_symbfact: pastixOrderCheck on final ordering after symbolic "
274  "factorization failed !!!" );
275  assert( 0 );
276  }
277  if ( pastixSymbolCheck( pastix_data->symbmtx ) != 0 ) {
278  errorPrint( "pastix_subtask_symbfact: symbolCheck on final symbol matrix failed !!!" );
279  assert( 0 );
280  }
281 #endif
282 
283  /*
284  * Save the symbolic factorization
285  */
286  if ( iparm[IPARM_IO_STRATEGY] & PastixIOSave ) {
287  pastix_gendirectories( pastix_data );
288  if ( procnum == 0 ) {
289  FILE *stream = NULL;
290  stream = pastix_fopenw( pastix_data->dir_global, "symbgen", "w" );
291  if ( stream ) {
292  pastixSymbolSave( pastix_data->symbmtx, stream );
293  fclose( stream );
294  }
295  }
296  }
297 
298  /*
299  * Dump an eps file of the symbolic factorization
300  */
301 #if defined( PASTIX_SYMBOL_DUMP_SYMBMTX )
302  {
303  pastix_gendirectories( pastix_data );
304  if ( procnum == 0 ) {
305  FILE *stream = NULL;
306  stream = pastix_fopenw( pastix_data->dir_global, "symbol.eps", "w" );
307  if ( stream ) {
308  pastixSymbolDraw( pastix_data->symbmtx, stream );
309  fclose( stream );
310  }
311  }
312  }
313 #endif
314 
315  /*
316  * Computes statistics and print informations
317  */
318  iparm[IPARM_NNZEROS] = pastixSymbolGetNNZ( pastix_data->symbmtx );
319  pastixSymbolGetFlops( pastix_data->symbmtx,
320  iparm[IPARM_FLOAT],
321  iparm[IPARM_FACTORIZATION],
322  &( dparm[DPARM_FACT_THFLOPS] ),
323  &( dparm[DPARM_FACT_RLFLOPS] ) );
324 
325  clockStop( timer );
326 
327  /* Warning: the timer will be overwritten by the call in reordering step */
328  pastix_data->dparm[DPARM_SYMBFACT_TIME] = clockVal(timer);
329 
330  if ( procnum == 0 ) {
331  if ( iparm[IPARM_VERBOSE] > PastixVerboseNo )
332  pastixSymbolPrintStats( pastix_data->symbmtx );
333 
334  if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
335  double fillin =
336  (double)( iparm[IPARM_NNZEROS] ) / (double)( ( pastix_data->csc )->gnnz );
337 
338  pastix_print( procnum, 0, OUT_FAX_SUMMARY,
339  (long)iparm[IPARM_NNZEROS],
340  fillin, clockVal(timer) );
341  }
342  }
343 
344  /* Invalidate following steps, and add order step to the ones performed */
345  pastix_data->steps &= ~( STEP_ANALYSE |
346  STEP_CSC2BCSC |
347  STEP_BCSC2CTAB |
348  STEP_NUMFACT |
349  STEP_SOLVE |
350  STEP_REFINE );
351  pastix_data->steps |= STEP_SYMBFACT;
352 
353  return PASTIX_SUCCESS;
354 }
graphBase
void graphBase(pastix_graph_t *graph, pastix_int_t baseval)
Rebase the graph to the given value.
Definition: graph.c:70
symbol_matrix_s
Symbol matrix structure.
Definition: symbol.h:75
pastixSymbolLoad
int pastixSymbolLoad(symbol_matrix_t *symbptr, FILE *stream)
Load the given block matrix structure from the given stream.
Definition: symbol_io.c:51
pastixSymbolSave
int pastixSymbolSave(const symbol_matrix_t *symbptr, FILE *stream)
Save the given block matrix structure to the given stream.
Definition: symbol_io.c:147
pastixSymbolGetNNZ
pastix_int_t pastixSymbolGetNNZ(const symbol_matrix_t *symbptr)
Computes the number of non-zero elements in L.
Definition: symbol_cost.c:327
DPARM_SYMBFACT_TIME
@ DPARM_SYMBFACT_TIME
Definition: api.h:158
pastixSymbolExit
void pastixSymbolExit(symbol_matrix_t *symbptr)
Free the content of symbolic matrix.
Definition: symbol.c:140
IPARM_LEVEL_OF_FILL
@ IPARM_LEVEL_OF_FILL
Definition: api.h:96
pastix_gendirectories
void pastix_gendirectories(pastix_data_t *pastix_data)
Generate a unique temporary directory to store output files.
Definition: api.c:69
pastix_order_s
Order structure.
Definition: order.h:45
pastixSymbolFaxILUk
int pastixSymbolFaxILUk(symbol_matrix_t *symbptr, pastix_int_t levelk, const pastix_graph_t *graphA, const pastix_order_t *ordeptr)
Create the symbol matrix from the graph of the non zero pattern of the factorized matrix and the supe...
Definition: symbol_fax_iluk.c:55
pastix_order_s::selevtx
int8_t * selevtx
Definition: order.h:53
pastixSymbolBase
void pastixSymbolBase(symbol_matrix_t *symbptr, const pastix_int_t baseval)
Sets the base of the given symbol matrix structure to the given base value.
Definition: symbol_base.c:37
PastixIOSave
@ PastixIOSave
Definition: api.h:218
symbol_matrix_s::cblknbr
pastix_int_t cblknbr
Definition: symbol.h:77
IPARM_NNZEROS
@ IPARM_NNZEROS
Definition: api.h:40
pastix_subtask_symbfact
int pastix_subtask_symbfact(pastix_data_t *pastix_data)
Computes the symbolic factorization step.
Definition: pastix_subtask_symbfact.c:90
pastixSymbolDraw
int pastixSymbolDraw(const symbol_matrix_t *symbptr, FILE *stream)
Export the symbol structure in a PostScript format.
Definition: symbol_draw.c:248
DPARM_FACT_THFLOPS
@ DPARM_FACT_THFLOPS
Definition: api.h:165
pastixOrderCheck
int pastixOrderCheck(const pastix_order_t *const ordeptr)
This routine checks the correctness of the ordering structure.
Definition: order_check.c:39
pastixOrderBase
void pastixOrderBase(pastix_order_t *const ordeptr, pastix_int_t baseval)
This routine sets the base of the given ordering structure to the given base value.
Definition: order.c:319
pastixSymbolRealloc
void pastixSymbolRealloc(symbol_matrix_t *symbptr)
Reallocate the data structure to optimize the memory alignment.
Definition: symbol.c:173
pastixSymbolGetFlops
void pastixSymbolGetFlops(const symbol_matrix_t *symbmtx, pastix_coeftype_t flttype, pastix_factotype_t factotype, double *thflops, double *rlflops)
Computes the number of theoretical and real flops.
Definition: symbol_cost.c:424
PastixVerboseNot
@ PastixVerboseNot
Definition: api.h:207
PASTIX_SUCCESS
@ PASTIX_SUCCESS
Definition: api.h:344
PastixVerboseNo
@ PastixVerboseNo
Definition: api.h:208
pastix_fopenw
FILE * pastix_fopenw(const char *dirname, const char *filename, const char *mode)
Open a file in the unique directory of the pastix instance.
Definition: api.c:232
symbol.h
pastixSymbolCheck
int pastixSymbolCheck(const symbol_matrix_t *symbptr)
Checks the consistency of the given symbolic block matrix.
Definition: symbol_check.c:47
IPARM_FLOAT
@ IPARM_FLOAT
Definition: api.h:142
graph.h
symbol_matrix_s::cblktab
symbol_cblk_t * cblktab
Definition: symbol.h:81
IPARM_VERBOSE
@ IPARM_VERBOSE
Definition: api.h:36
pastixSymbolBuildRowtab
void pastixSymbolBuildRowtab(symbol_matrix_t *symbptr)
Construct the browtab array that stores the blocks in a CSR way.
Definition: symbol.c:305
order.h
symbol_cblk_s
Symbol column block structure.
Definition: symbol.h:43
IPARM_INCOMPLETE
@ IPARM_INCOMPLETE
Definition: api.h:95
IPARM_DOF_NBR
@ IPARM_DOF_NBR
Definition: api.h:144
DPARM_FACT_RLFLOPS
@ DPARM_FACT_RLFLOPS
Definition: api.h:166
PastixIOLoad
@ PastixIOLoad
Definition: api.h:217
pastixSymbolPrintStats
void pastixSymbolPrintStats(const symbol_matrix_t *symbptr)
Print statistical information about the symbolic matrix structure.
Definition: symbol.c:392
IPARM_IO_STRATEGY
@ IPARM_IO_STRATEGY
Definition: api.h:37
pastix_fopen
FILE * pastix_fopen(const char *filename)
Open a file in the current directory in read only mode.
Definition: api.c:279
PASTIX_ERR_BADPARAMETER
@ PASTIX_ERR_BADPARAMETER
Definition: api.h:351
pastixSymbolFaxDirect
int pastixSymbolFaxDirect(symbol_matrix_t *symbptr, const pastix_graph_t *graphA, const pastix_order_t *ordeptr)
Compute the block symbolic factorization of the given matrix graph according to the given vertex orde...
Definition: symbol_fax_direct.c:77
IPARM_FACTORIZATION
@ IPARM_FACTORIZATION
Definition: api.h:99