PaStiX Handbook  6.3.2
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-2023 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
13  * Univ. Bordeaux. All rights reserved.
14  *
15  * @version 6.3.2
16  * @author Xavier Lacoste
17  * @author Pierre Ramet
18  * @author Mathieu Faverge
19  * @author Gregoire Pichon
20  * @author Tony Delarue
21  * @date 2023-07-21
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  *
84  *******************************************************************************/
85 int
87 {
88  pastix_int_t *iparm;
89  double *dparm;
90  pastix_graph_t *graph;
91  pastix_order_t *ordemesh;
92  int procnum;
93  Clock timer;
94  size_t nnz;
95 
96 #if defined( PASTIX_DISTRIBUTED )
97  pastix_int_t *PTS_perm = NULL;
98  pastix_int_t *PTS_rev_perm = NULL;
99  pastix_int_t *tmpperm = NULL;
100  pastix_int_t *tmpperi = NULL;
101  pastix_int_t gN;
102  pastix_int_t i;
103 #endif
104 
105  /*
106  * Check parameters
107  */
108  if ( pastix_data == NULL ) {
109  pastix_print_error( "pastix_subtask_symbfact: wrong pastix_data parameter" );
111  }
112  iparm = pastix_data->iparm;
113  dparm = pastix_data->dparm;
114 
115  if ( !( pastix_data->steps & STEP_ORDERING ) ) {
116  pastix_print_error( "pastix_subtask_symbfact: pastix_subtask_order() has to be called before "
117  "calling this function" );
119  }
120 
121  procnum = pastix_data->procnum;
122  graph = pastix_data->graph;
123  ordemesh = pastix_data->ordemesh;
124 
125  if ( graph == NULL ) {
126  pastix_print_error( "pastix_subtask_symbfact: the pastix_data->graph field has not been "
127  "initialized, pastix_subtask_order should be called first" );
129  }
130  if ( ordemesh == NULL ) {
131  pastix_print_error( "pastix_subtask_symbfact: the pastix_data->ordemesh field has not been "
132  "initialized, pastix_subtask_order should be called first" );
134  }
135 
136  clockStart( timer );
137 
138  /* Make sure they are both 0-based */
139  pastixOrderBase( ordemesh, 0 );
140  graphBase( graph, 0 );
141  graphGatherInPlace( graph );
142 
143  if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
144  pastix_print( procnum, 0, OUT_STEP_FAX );
145  }
146 
147  /* Allocate the symbol matrix structure */
148  if ( pastix_data->symbmtx == NULL ) {
149  MALLOC_INTERN( pastix_data->symbmtx, 1, symbol_matrix_t );
150  }
151  else {
152  pastixSymbolExit( pastix_data->symbmtx );
153  }
154 
155  /*Symbol matrix loaded from file */
156  if ( iparm[IPARM_IO_STRATEGY] & PastixIOLoad ) {
157  FILE *stream = NULL;
158  stream = pastix_fopen( "symbname" );
159  if ( stream ) {
160  pastixSymbolLoad( pastix_data->symbmtx, stream );
161  fclose( stream );
162  }
163  }
164  /* Symbol matrix computed through Fax (Direct or ILU(k)) */
165  else {
166  pastix_int_t nfax;
167 
168  /* Check correctness of parameters */
169  if ( iparm[IPARM_INCOMPLETE] == 0 ) {
170 #if defined( COMPACT_SMX )
171  if ( procnum == 0 )
172  pastix_print_warning( "COMPACT_SMX only works with incomplete factorization, force ILU(%d) "
173  "factorization.",
174  iparm[IPARM_LEVEL_OF_FILL] );
175  iparm[IPARM_INCOMPLETE] = 1;
176 #endif
177  }
178  /* End of parameters check */
179 
180  /*
181  * Fax works with centralized interface, we convert the cscd to csc if required
182  */
183 #if defined( PASTIX_DISTRIBUTED )
184  if ( graph->loc2glob != NULL ) {
185  cscd2csc_int( graph->n,
186  graph->colptr,
187  graph->rowptr,
188  NULL,
189  NULL,
190  NULL,
191  NULL,
192  &nfax,
193  &colptrfax,
194  &rowfax,
195  NULL,
196  NULL,
197  NULL,
198  NULL,
199  graph->loc2glob,
200  pastix_data->pastix_comm,
201  iparm[IPARM_DOF_NBR],
202  1 );
203  }
204  else
205 #endif
206  {
207  nfax = graph->gN;
208  }
209 
210  pastixSymbolInit( graph, ordemesh, pastix_data->symbmtx );
211 
212  /*
213  * The amalgamate supernodes partition has been found with (PT-)Scotch,
214  * we use it to generate the symbol matrix structure.
215  * This works only if direct factorization will be performed.
216  */
217  if ( !iparm[IPARM_INCOMPLETE] || ( iparm[IPARM_LEVEL_OF_FILL] == -1 ) ) {
218  if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
219  pastix_print( procnum, 0, OUT_FAX_METHOD, "Fax Direct" );
220  }
221 
222  pastixSymbolFaxDirect( pastix_data->symbmtx, /* Symbol Matrix */
223  graph,
224  ordemesh );
225  }
226  else {
227  if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
228  pastix_print( procnum, 0, OUT_FAX_METHOD, "Fax ILU(k)" );
229  }
230 
231  pastixSymbolFaxILUk( pastix_data->symbmtx, /* Symbol Matrix */
232  iparm[IPARM_LEVEL_OF_FILL],
233  graph,
234  ordemesh );
235  }
236 
237  /* Set the beginning of the Schur complement */
238  pastix_data->symbmtx->schurfcol =
239  nfax - pastix_data->schur_n + pastix_data->symbmtx->baseval;
240  } /* not PastixIOLoad */
241 
242  /* Rebase to 0 */
243  pastixSymbolBase( pastix_data->symbmtx, 0 );
244 
245  /* Build the browtabs and Realign data structure */
246  pastixSymbolBuildRowtab( pastix_data->symbmtx );
247  pastixSymbolRealloc( pastix_data->symbmtx );
248 
249  if ( ordemesh->selevtx != NULL ) {
250  symbol_matrix_t *symbmtx = pastix_data->symbmtx;
251  symbol_cblk_t *cblk = symbmtx->cblktab;
252  int8_t *selevtx = ordemesh->selevtx;
253  pastix_int_t i;
254 
255  for(i=0; i<symbmtx->cblknbr; i++, cblk++, selevtx++ ) {
256  cblk->selevtx = *selevtx;
257  }
258  }
259 
260 #if !defined( NDEBUG )
261  if ( pastixOrderCheck( ordemesh ) != 0 ) {
262  pastix_print_error( "pastix_subtask_symbfact: pastixOrderCheck on final ordering after symbolic "
263  "factorization failed !!!" );
264  assert( 0 );
265  }
266  if ( pastixSymbolCheck( pastix_data->symbmtx ) != 0 ) {
267  pastix_print_error( "pastix_subtask_symbfact: symbolCheck on final symbol matrix failed !!!" );
268  assert( 0 );
269  }
270 #endif
271 
272  /*
273  * Save the symbolic factorization
274  */
275  if ( iparm[IPARM_IO_STRATEGY] & PastixIOSave ) {
276  pastix_gendirectories( pastix_data );
277  if ( procnum == 0 ) {
278  FILE *stream = NULL;
279  stream = pastix_fopenw( pastix_data->dir_global, "symbgen", "w" );
280  if ( stream ) {
281  pastixSymbolSave( pastix_data->symbmtx, stream );
282  fclose( stream );
283  }
284  }
285  }
286 
287  /*
288  * Dump an eps file of the symbolic factorization
289  */
290 #if defined( PASTIX_SYMBOL_DUMP_SYMBMTX )
291  {
292  pastix_gendirectories( pastix_data );
293  if ( procnum == 0 ) {
294  FILE *stream = NULL;
295  stream = pastix_fopenw( pastix_data->dir_global, "symbol.eps", "w" );
296  if ( stream ) {
297  pastixSymbolDraw( pastix_data->symbmtx, stream );
298  fclose( stream );
299  }
300  }
301  }
302 #endif
303 
304  /*
305  * Computes statistics and print informations
306  */
307  nnz = pastixSymbolGetNNZ( pastix_data->symbmtx );
308  pastixSymbolGetFlops( pastix_data->symbmtx,
309  iparm[IPARM_FLOAT],
310  iparm[IPARM_FACTORIZATION],
311  &( dparm[DPARM_FACT_THFLOPS] ),
312  &( dparm[DPARM_FACT_RLFLOPS] ) );
313 
314  clockStop( timer );
315 
316  /* Warning: the timer will be overwritten by the call in reordering step */
317  pastix_data->dparm[DPARM_SYMBFACT_TIME] = clockVal(timer);
318 
319  if ( procnum == 0 ) {
320  if ( iparm[IPARM_VERBOSE] > PastixVerboseNo )
321  pastixSymbolPrintStats( pastix_data->symbmtx );
322 
323  if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
324  double fillin =
325  (double)( nnz ) / (double)( ( pastix_data->csc )->gnnz );
326 
327  pastix_print( procnum, 0, OUT_FAX_SUMMARY,
328  nnz, fillin, clockVal(timer) );
329  }
330  }
331  iparm[IPARM_NNZEROS] = nnz;
332 
333  /* Invalidate following steps, and add order step to the ones performed */
334  pastix_data->steps &= ~( STEP_ANALYSE |
335  STEP_CSC2BCSC |
336  STEP_BCSC2CTAB |
337  STEP_NUMFACT |
338  STEP_SOLVE |
339  STEP_REFINE );
340  pastix_data->steps |= STEP_SYMBFACT;
341 
342  return PASTIX_SUCCESS;
343 }
BEGIN_C_DECLS typedef int pastix_int_t
Definition: datatypes.h:51
int pastix_subtask_symbfact(pastix_data_t *pastix_data)
Computes the symbolic factorization step.
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:242
FILE * pastix_fopen(const char *filename)
Open a file in the current directory in read only mode.
Definition: api.c:289
void pastix_gendirectories(pastix_data_t *pastix_data)
Generate a unique temporary directory to store output files.
Definition: api.c:76
@ PastixIOSave
Definition: api.h:231
@ PastixIOLoad
Definition: api.h:230
@ DPARM_FACT_THFLOPS
Definition: api.h:172
@ DPARM_FACT_RLFLOPS
Definition: api.h:173
@ DPARM_SYMBFACT_TIME
Definition: api.h:165
@ IPARM_FACTORIZATION
Definition: api.h:99
@ IPARM_DOF_NBR
Definition: api.h:151
@ IPARM_FLOAT
Definition: api.h:149
@ IPARM_VERBOSE
Definition: api.h:36
@ IPARM_NNZEROS
Definition: api.h:40
@ IPARM_IO_STRATEGY
Definition: api.h:37
@ IPARM_LEVEL_OF_FILL
Definition: api.h:96
@ IPARM_INCOMPLETE
Definition: api.h:95
@ PastixVerboseNot
Definition: api.h:220
@ PastixVerboseNo
Definition: api.h:221
@ PASTIX_SUCCESS
Definition: api.h:367
@ PASTIX_ERR_BADPARAMETER
Definition: api.h:374
int graphGatherInPlace(pastix_graph_t *graph)
This routine gather a distributed graph on each node in place.
Definition: graph.c:239
void graphBase(pastix_graph_t *graph, pastix_int_t baseval)
Rebase the graph to the given value.
Definition: graph.c:102
int8_t * selevtx
Definition: order.h:55
void pastixOrderBase(pastix_order_t *ordeptr, pastix_int_t baseval)
This routine sets the base of the given ordering structure to the given base value.
Definition: order.c:322
int pastixOrderCheck(const pastix_order_t *ordeptr)
This routine checks the correctness of the ordering structure.
Definition: order_check.c:39
Order structure.
Definition: order.h:47
pastix_int_t baseval
Definition: symbol.h:78
symbol_cblk_t * cblktab
Definition: symbol.h:83
pastix_int_t schurfcol
Definition: symbol.h:82
pastix_int_t cblknbr
Definition: symbol.h:79
void pastixSymbolRealloc(symbol_matrix_t *symbptr)
Reallocate the data structure to optimize the memory alignment.
Definition: symbol.c:170
void pastixSymbolInit(const pastix_graph_t *graph, const pastix_order_t *order, symbol_matrix_t *symbptr)
Initialize the symbol structure.
Definition: symbol.c:105
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
void pastixSymbolPrintStats(const symbol_matrix_t *symbptr)
Print statistical information about the symbolic matrix structure.
Definition: symbol.c:389
int pastixSymbolDraw(const symbol_matrix_t *symbptr, FILE *stream)
Export the symbol structure in a PostScript format.
Definition: symbol_draw.c:248
void pastixSymbolBuildRowtab(symbol_matrix_t *symbptr)
Construct the browtab array that stores the blocks in a CSR way.
Definition: symbol.c:302
size_t pastixSymbolGetNNZ(const symbol_matrix_t *symbptr)
Computes the number of non-zero elements in L.
Definition: symbol_cost.c:325
int pastixSymbolSave(const symbol_matrix_t *symbptr, FILE *stream)
Save the given block matrix structure to the given stream.
Definition: symbol_io.c:147
int pastixSymbolLoad(symbol_matrix_t *symbptr, FILE *stream)
Load the given block matrix structure from the given stream.
Definition: symbol_io.c:51
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:422
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...
void pastixSymbolExit(symbol_matrix_t *symbptr)
Free the content of symbolic matrix.
Definition: symbol.c:137
int pastixSymbolCheck(const symbol_matrix_t *symbptr)
Checks the consistency of the given symbolic block matrix.
Definition: symbol_check.c:47
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...
Symbol column block structure.
Definition: symbol.h:45
Symbol matrix structure.
Definition: symbol.h:77
PASTIX_Comm pastix_comm
Definition: pastixdata.h:75
pastix_order_t * ordemesh
Definition: pastixdata.h:97
pastix_int_t * iparm
Definition: pastixdata.h:69
double * dparm
Definition: pastixdata.h:70
const spmatrix_t * csc
Definition: pastixdata.h:89
pastix_int_t schur_n
Definition: pastixdata.h:93
pastix_graph_t * graph
Definition: pastixdata.h:91
symbol_matrix_t * symbmtx
Definition: pastixdata.h:99
char * dir_global
Definition: pastixdata.h:109
pastix_int_t steps
Definition: pastixdata.h:72
Main PaStiX data structure.
Definition: pastixdata.h:67