PaStiX Handbook 6.4.0
Loading...
Searching...
No Matches
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-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
13 * Univ. Bordeaux. All rights reserved.
14 *
15 * @version 6.4.0
16 * @author Xavier Lacoste
17 * @author Pierre Ramet
18 * @author Mathieu Faverge
19 * @author Gregoire Pichon
20 * @author Tony Delarue
21 * @date 2024-07-05
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 *******************************************************************************/
85int
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:251
void pastix_gendirectories(pastix_data_t *pastix_data)
Generate a unique temporary directory to store output files.
Definition api.c:85
FILE * pastix_fopen(const char *filename)
Open a file in the current directory in read only mode.
Definition api.c:298
@ 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.
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.
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.
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.
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:76
pastix_order_t * ordemesh
Definition pastixdata.h:98
pastix_int_t * iparm
Definition pastixdata.h:70
double * dparm
Definition pastixdata.h:71
const spmatrix_t * csc
Definition pastixdata.h:90
pastix_int_t schur_n
Definition pastixdata.h:94
pastix_graph_t * graph
Definition pastixdata.h:92
symbol_matrix_t * symbmtx
Definition pastixdata.h:100
char * dir_global
Definition pastixdata.h:110
pastix_int_t steps
Definition pastixdata.h:73
Main PaStiX data structure.
Definition pastixdata.h:68