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  pastix_print_error( "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  pastix_print_error( "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  pastix_print_error( "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  pastix_print_error( "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  graphGatherInPlace( graph );
145 
146  if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
147  pastix_print( procnum, 0, OUT_STEP_FAX );
148  }
149 
150  /* Allocate the symbol matrix structure */
151  if ( pastix_data->symbmtx == NULL ) {
152  MALLOC_INTERN( pastix_data->symbmtx, 1, symbol_matrix_t );
153  }
154  else {
155  pastixSymbolExit( pastix_data->symbmtx );
156  }
157 
158  /*Symbol matrix loaded from file */
159  if ( iparm[IPARM_IO_STRATEGY] & PastixIOLoad ) {
160  FILE *stream = NULL;
161  stream = pastix_fopen( "symbname" );
162  if ( stream ) {
163  pastixSymbolLoad( pastix_data->symbmtx, stream );
164  fclose( stream );
165  }
166  }
167  /* Symbol matrix computed through Fax (Direct or ILU(k)) */
168  else {
169  pastix_int_t nfax;
170 
171  /* Check correctness of parameters */
172  if ( iparm[IPARM_INCOMPLETE] == 0 ) {
173 #if defined( COMPACT_SMX )
174  if ( procnum == 0 )
175  pastix_print_warning( "COMPACT_SMX only works with incomplete factorization, force ILU(%d) "
176  "factorization.",
177  iparm[IPARM_LEVEL_OF_FILL] );
178  iparm[IPARM_INCOMPLETE] = 1;
179 #endif
180  }
181  /* End of parameters check */
182 
183  /*
184  * Fax works with centralized interface, we convert the cscd to csc if required
185  */
186 #if defined( PASTIX_DISTRIBUTED )
187  if ( graph->loc2glob != NULL ) {
188  cscd2csc_int( graph->n,
189  graph->colptr,
190  graph->rowptr,
191  NULL,
192  NULL,
193  NULL,
194  NULL,
195  &nfax,
196  &colptrfax,
197  &rowfax,
198  NULL,
199  NULL,
200  NULL,
201  NULL,
202  graph->loc2glob,
203  pastix_data->pastix_comm,
204  iparm[IPARM_DOF_NBR],
205  1 );
206  }
207  else
208 #endif
209  {
210  nfax = graph->gN;
211  }
212 
213  pastixSymbolInit( graph, ordemesh, pastix_data->symbmtx );
214 
215  /*
216  * The amalgamate supernodes partition has been found with (PT-)Scotch,
217  * we use it to generate the symbol matrix structure.
218  * This works only if direct factorization will be performed.
219  */
220  if ( !iparm[IPARM_INCOMPLETE] || ( iparm[IPARM_LEVEL_OF_FILL] == -1 ) ) {
221  if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
222  pastix_print( procnum, 0, OUT_FAX_METHOD, "Fax Direct" );
223  }
224 
225  pastixSymbolFaxDirect( pastix_data->symbmtx, /* Symbol Matrix */
226  graph,
227  ordemesh );
228  }
229  else {
230  if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
231  pastix_print( procnum, 0, OUT_FAX_METHOD, "Fax ILU(k)" );
232  }
233 
234  pastixSymbolFaxILUk( pastix_data->symbmtx, /* Symbol Matrix */
235  iparm[IPARM_LEVEL_OF_FILL],
236  graph,
237  ordemesh );
238  }
239 
240  /* Set the beginning of the Schur complement */
241  pastix_data->symbmtx->schurfcol =
242  nfax - pastix_data->schur_n + pastix_data->symbmtx->baseval;
243  } /* not PastixIOLoad */
244 
245  /* Rebase to 0 */
246  pastixSymbolBase( pastix_data->symbmtx, 0 );
247 
248  /* Build the browtabs and Realign data structure */
249  pastixSymbolBuildRowtab( pastix_data->symbmtx );
250  pastixSymbolRealloc( pastix_data->symbmtx );
251 
252  if ( ordemesh->selevtx != NULL ) {
253  symbol_matrix_t *symbmtx = pastix_data->symbmtx;
254  symbol_cblk_t *cblk = symbmtx->cblktab;
255  int8_t *selevtx = ordemesh->selevtx;
256  pastix_int_t i;
257 
258  for(i=0; i<symbmtx->cblknbr; i++, cblk++, selevtx++ ) {
259  cblk->selevtx = *selevtx;
260  }
261  }
262 
263 #if !defined( NDEBUG )
264  if ( pastixOrderCheck( ordemesh ) != 0 ) {
265  pastix_print_error( "pastix_subtask_symbfact: pastixOrderCheck on final ordering after symbolic "
266  "factorization failed !!!" );
267  assert( 0 );
268  }
269  if ( pastixSymbolCheck( pastix_data->symbmtx ) != 0 ) {
270  pastix_print_error( "pastix_subtask_symbfact: symbolCheck on final symbol matrix failed !!!" );
271  assert( 0 );
272  }
273 #endif
274 
275  /*
276  * Save the symbolic factorization
277  */
278  if ( iparm[IPARM_IO_STRATEGY] & PastixIOSave ) {
279  pastix_gendirectories( pastix_data );
280  if ( procnum == 0 ) {
281  FILE *stream = NULL;
282  stream = pastix_fopenw( pastix_data->dir_global, "symbgen", "w" );
283  if ( stream ) {
284  pastixSymbolSave( pastix_data->symbmtx, stream );
285  fclose( stream );
286  }
287  }
288  }
289 
290  /*
291  * Dump an eps file of the symbolic factorization
292  */
293 #if defined( PASTIX_SYMBOL_DUMP_SYMBMTX )
294  {
295  pastix_gendirectories( pastix_data );
296  if ( procnum == 0 ) {
297  FILE *stream = NULL;
298  stream = pastix_fopenw( pastix_data->dir_global, "symbol.eps", "w" );
299  if ( stream ) {
300  pastixSymbolDraw( pastix_data->symbmtx, stream );
301  fclose( stream );
302  }
303  }
304  }
305 #endif
306 
307  /*
308  * Computes statistics and print informations
309  */
310  iparm[IPARM_NNZEROS] = pastixSymbolGetNNZ( pastix_data->symbmtx );
311  pastixSymbolGetFlops( pastix_data->symbmtx,
312  iparm[IPARM_FLOAT],
313  iparm[IPARM_FACTORIZATION],
314  &( dparm[DPARM_FACT_THFLOPS] ),
315  &( dparm[DPARM_FACT_RLFLOPS] ) );
316 
317  clockStop( timer );
318 
319  /* Warning: the timer will be overwritten by the call in reordering step */
320  pastix_data->dparm[DPARM_SYMBFACT_TIME] = clockVal(timer);
321 
322  if ( procnum == 0 ) {
323  if ( iparm[IPARM_VERBOSE] > PastixVerboseNo )
324  pastixSymbolPrintStats( pastix_data->symbmtx );
325 
326  if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
327  double fillin =
328  (double)( iparm[IPARM_NNZEROS] ) / (double)( ( pastix_data->csc )->gnnz );
329 
330  pastix_print( procnum, 0, OUT_FAX_SUMMARY,
331  (long)iparm[IPARM_NNZEROS],
332  fillin, clockVal(timer) );
333  }
334  }
335 
336  /* Invalidate following steps, and add order step to the ones performed */
337  pastix_data->steps &= ~( STEP_ANALYSE |
338  STEP_CSC2BCSC |
339  STEP_BCSC2CTAB |
340  STEP_NUMFACT |
341  STEP_SOLVE |
342  STEP_REFINE );
343  pastix_data->steps |= STEP_SYMBFACT;
344 
345  return PASTIX_SUCCESS;
346 }
graphBase
void graphBase(pastix_graph_t *graph, pastix_int_t baseval)
Rebase the graph to the given value.
Definition: graph.c:100
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:220
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 *ordeptr)
This routine checks the correctness of the ordering structure.
Definition: order_check.c:39
pastixOrderBase
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: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:209
PASTIX_SUCCESS
@ PASTIX_SUCCESS
Definition: api.h:346
PastixVerboseNo
@ PastixVerboseNo
Definition: api.h:210
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
graphGatherInPlace
int graphGatherInPlace(pastix_graph_t *graph)
This routine gather a distributed graph on each note in place.
Definition: graph.c:240
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:219
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:353
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