PaStiX Handbook  6.2.1
pastix_subtask_order.c
Go to the documentation of this file.
1 /**
2  *
3  * @file pastix_subtask_order.c
4  *
5  * PaStiX ordering task.
6  * Contains wrappers to build a good ordering for sparse direct solvers.
7  * Affected by the compilation time options:
8  * - PASTIX_ORDERING_SCOTCH: Enable Scotch graph partitioning library.
9  * - PASTIX_ORDERING_PTSCOTCH: Enable PT-Scotch graph partitioning library.
10  * - PASTIX_ORDERING_METIS: Enable Metis graph partitioning library.
11  *
12  * @copyright 2015-2021 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
13  * Univ. Bordeaux. All rights reserved.
14  *
15  * @version 6.2.1
16  * @author Xavier Lacoste
17  * @author Pierre Ramet
18  * @author Mathieu Faverge
19  * @author Gregoire Pichon
20  * @author Tony Delarue
21  * @date 2021-06-28
22  *
23  **/
24 #include "common.h"
25 #include <spm.h>
26 #include "graph/graph.h"
27 #include "blend/elimintree.h"
28 #include "order_internal.h"
29 
30 /**
31  *******************************************************************************
32  *
33  * @ingroup pastix_analyze
34  *
35  * @brief Computes the ordering of the given graph in parameters.
36  *
37  * The graph given by the user is used to generate a graph that can be used by
38  * ordering tools and symbolic factorization. This graph is stored in the
39  * pastix_data->graph to be pass over to the symbolic factorization. If it exists
40  * before to call this routine, then the current structure is cleaned and a new
41  * one is created. From this structure, an ordering is computed by the ordering
42  * tool chosen by IPARM_ORDERING and stored in pastix_data->ordemesh. At the end
43  * the full ordering stucture: pemutation, inverse permutation, partition, and
44  * partion tree is generated such that it can be used by any symbolic
45  * factorization algorithm.
46  * The user can get back the permutation generated by providing allocated ordering
47  * structure where the results is stored after computation.
48  *
49  * This routine is affected by the following parameters:
50  * IPARM_VERBOSE, IPARM_ORDERING, IPARM_IO_STRATEGY
51  *
52  *******************************************************************************
53  *
54  * @param[inout] pastix_data
55  * The pastix_data structure that describes the solver instance.
56  * On exit, the field ordemesh is initialize with the result of the
57  * ordering.
58  * - IPARM_ORDERING will determine which ordering tool is used.
59  * - IPARM_IO_STRATEGY:
60  * - If set to PastixIOSave, the results will be written on files on
61  * exit.
62  * - If set to PastixIOLoad and IPARM_ORDERING is set to personal,
63  * then the ordering is loaded from files and no ordering is
64  * called.
65  * - If the function pastix_setSchurUnknownList() function has been
66  * previously called to set the list of vertices to isolate in the
67  * schur complement, those vertices are isolated at the end of the
68  * matrix in a dedicated supernode..
69  * - If the function pastix_setZerosUnknownList() function has been
70  * previously called to set the list of diagonal elements that may
71  * cause problem during the factorization, those vertices are isolated
72  * at the end of the matrix in a dedicated supernode..
73  *
74  * @param[in] spm
75  * The sparse matrix given by the user on which the ordering will be
76  * computed.
77  *
78  *
79  * @param[inout] myorder
80  * On entry, the permutation provide by the user if IPARM_ORDERING
81  * parameter set to PastixOrderPersonal. Not read otherwise.
82  * On exit, if the structure attributs != NULL and IPARM_ORDERING parameter
83  * is not set to PastixOrderPersonal, contains the permutation generated.
84  * Otherwise, it is not referenced.
85  *
86  *******************************************************************************
87  *
88  * @retval PASTIX_SUCCESS on successful exit,
89  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect,
90  * @retval PASTIX_ERR_OUTOFMEMORY if one allocation failed,
91  * @retval PASTIX_ERR_INTEGER_TYPE if Scotch integer type is not the
92  * same size as PaStiX ones,
93  * @retval PASTIX_ERR_INTERNAL if an error occurs internally to Scotch.
94  *
95  *******************************************************************************/
96 int
97 pastix_subtask_order( pastix_data_t *pastix_data,
98  const spmatrix_t *spm,
99  pastix_order_t *myorder )
100 {
101  pastix_int_t n;
102  pastix_int_t schur_n;
103  pastix_int_t *schur_colptr;
104  pastix_int_t *schur_rows;
105  pastix_int_t *schur_perm = NULL;
106  pastix_int_t zeros_n;
107  pastix_int_t *zeros_colptr;
108  pastix_int_t *zeros_rows;
109  pastix_int_t *zeros_perm = NULL;
110  pastix_int_t *iparm;
111  pastix_graph_t subgraph;
112  pastix_graph_t *graph;
113  pastix_order_t *ordemesh;
114  Clock timer;
115  int procnum;
116  int retval = PASTIX_SUCCESS;
117  int retval_rcv;
118  int do_schur = 1;
119  int do_zeros = 1;
120  spmatrix_t *spmg = NULL;
121 
122  /*
123  * Check parameters
124  */
125  if (pastix_data == NULL) {
126  errorPrint("pastix_subtask_order: wrong pastix_data parameter");
128  }
129  if (spm == NULL) {
130  errorPrint("pastix_subtask_order: wrong spm parameter");
132  }
133  if ( !(pastix_data->steps & STEP_INIT) ) {
134  errorPrint("pastix_subtask_order: pastixInit() has to be called before calling this function");
136  }
137 
138  /*
139  * If the spm is distributed, have to gather it for the moment
140  */
141  if ( spm->loc2glob == NULL ) {
142  spmg = (spmatrix_t *)spm;
143  }
144 #if defined(PASTIX_WITH_MPI)
145  else {
146  if( pastix_data->iparm[IPARM_VERBOSE] > PastixVerboseNo ) {
147  pastix_print( pastix_data->procnum, 0, "pastix_subtask_order: the SPM has to be centralized for the moment\n" );
148  }
149  spmg = spmGather( spm, -1 );
150  }
151 #endif
152 
153  iparm = pastix_data->iparm;
154  n = spm->n;
155  /*
156  * Backup flttype from the spm into iparm[IPARM_FLOAT] for later use
157  */
158  iparm[IPARM_FLOAT] = spmg->flttype;
159 
160  if (pastix_data->schur_n > 0)
161  {
162  /*
163  * If ordering is set to PastixOrderPersonal, we consider that the schur
164  * complement is already isolated at the end of permutation array.
165  */
166  if ( iparm[IPARM_ORDERING] == PastixOrderPersonal ) {
167  do_schur = 0;
168  }
169  } else {
170  do_schur = 0;
171  }
172  if (pastix_data->zeros_n > 0)
173  {
174  /*
175  * If ordering is set to PastixOrderPersonal, we consider that the zeros
176  * on diagonal are already isolated at the end of permutation array.
177  */
178  if ( iparm[IPARM_ORDERING] == PastixOrderPersonal ) {
179  do_zeros = 0;
180  }
181  } else {
182  do_zeros = 0;
183  }
184 
185  /*
186  * Clean ordering if it exists
187  */
188  if (pastix_data->ordemesh != NULL) {
189  pastixOrderExit(pastix_data->ordemesh);
190  } else {
191  MALLOC_INTERN( pastix_data->ordemesh, 1, pastix_order_t );
192  }
193 
194  ordemesh = pastix_data->ordemesh;
195  procnum = pastix_data->procnum;
196  pastixOrderAlloc( ordemesh, 0, 0 );
197 
198  if (iparm[IPARM_VERBOSE] > PastixVerboseNot) {
199  pastix_print(procnum, 0, "%s", OUT_STEP_ORDER);
200  }
201 
202  /*
203  * Prepare a copy of user's SPM
204  * Copy the given spm in pastix_data structure and performs basic required
205  * operations as symmetrizing the graph and removing the diagonal
206  * coefficients
207  */
208  graphPrepare( pastix_data, spmg, &(pastix_data->graph) );
209  graphBase( pastix_data->graph, 0 );
210  graph = pastix_data->graph;
211 
212  /*
213  * Isolate Shur elements
214  */
215  if ( do_schur )
216  {
217  assert( graph->loc2glob == NULL );
218  assert( pastix_data->schur_list != NULL );
219  graphIsolate(graph->n,
220  graph->colptr,
221  graph->rowptr,
222  pastix_data->schur_n,
223  pastix_data->schur_list,
224  &schur_colptr,
225  &schur_rows,
226  &schur_perm,
227  NULL);
228 
229  schur_n = graph->n - pastix_data->schur_n;
230  } else {
231  schur_n = graph->n;
232  schur_colptr = graph->colptr;
233  schur_rows = graph->rowptr;
234  }
235 
236  /*
237  * Isolate diagonal elements close to 0.
238  */
239  if ( do_zeros )
240  {
241  assert( graph->loc2glob == NULL );
242  assert( pastix_data->zeros_list != NULL );
243  graphIsolate(schur_n,
244  schur_colptr,
245  schur_rows,
246  pastix_data->zeros_n,
247  pastix_data->zeros_list,
248  &zeros_colptr,
249  &zeros_rows,
250  &zeros_perm,
251  NULL);
252 
253  zeros_n = schur_n - pastix_data->zeros_n;
254  } else {
255  zeros_n = schur_n;
256  zeros_colptr = schur_colptr;
257  zeros_rows = schur_rows;
258  }
259 
260  if (iparm[IPARM_VERBOSE] > PastixVerboseYes) {
261  pastix_print(procnum, 0, "%s", OUT_ORDER_INIT);
262  }
263 
264  clockStart(timer);
265 
266  memcpy( &subgraph, graph, sizeof(pastix_graph_t) );
267  subgraph.n = zeros_n;
268  subgraph.colptr = zeros_colptr;
269  subgraph.rowptr = zeros_rows;
270 
271  /* Select the ordering method chosen by the user */
272  switch (iparm[IPARM_ORDERING]) {
273  /*
274  * Scotch Ordering
275  */
276  case PastixOrderScotch:
277  if (iparm[IPARM_VERBOSE] > PastixVerboseNot) {
278  pastix_print(procnum, 0, OUT_ORDER_METHOD, "Scotch" );
279  }
280 #if defined(PASTIX_ORDERING_SCOTCH)
281  retval = pastixOrderComputeScotch( pastix_data, &subgraph );
282 #else
283  errorPrint("pastix_subtask_order: Ordering with Scotch requires to enable -DPASTIX_ORDERING_SCOTCH option");
284  retval = PASTIX_ERR_BADPARAMETER;
285 #endif
286  break;
287 
288  /*
289  * PT-Scotch Ordering
290  */
291  case PastixOrderPtScotch:
292  if (iparm[IPARM_VERBOSE] > PastixVerboseNot) {
293  pastix_print(procnum, 0, OUT_ORDER_METHOD, "PT-Scotch" );
294  }
295 #if defined(PASTIX_ORDERING_PTSCOTCH)
296  retval = pastixOrderComputePTScotch( pastix_data, &subgraph );
297 #else
298  errorPrint("pastix_subtask_order: Ordering with PT-Scotch requires to enable -DPASTIX_ORDERING_PTSCOTCH option");
299  retval = PASTIX_ERR_BADPARAMETER;
300 #endif
301  break;
302 
303  /*
304  * METIS ordering
305  */
306  case PastixOrderMetis:
307  if (iparm[IPARM_VERBOSE] > PastixVerboseNot) {
308  pastix_print(procnum, 0, OUT_ORDER_METHOD, "Metis" );
309  }
310 #if defined(PASTIX_ORDERING_METIS)
311  retval = pastixOrderComputeMetis( pastix_data, &subgraph );
312  assert( ordemesh->rangtab == NULL );
313 #else
314  errorPrint("pastix_subtask_order: Ordering with Metis requires -DPASTIX_ORDERING_METIS flag at compile time");
315  retval = PASTIX_ERR_BADPARAMETER;
316 #endif
317  break;
318 
319  /*
320  * Personal Ordering
321  */
322  case PastixOrderPersonal:
323  /* Load from file */
324  if ( iparm[IPARM_IO_STRATEGY] & PastixIOLoad ) {
325  if (iparm[IPARM_VERBOSE] > PastixVerboseNot) {
326  pastix_print(procnum, 0, OUT_ORDER_METHOD, "Load" );
327  }
328  retval = pastixOrderLoad( pastix_data, ordemesh );
329  }
330  /* Take input ordering */
331  else
332  {
333  pastix_int_t i, n;
334 
335  n = spm->gN;
336  /* Personal ordering have to be global ordering */
337  assert( spmg->gN == spmg->n );
338 
339  pastixOrderAlloc(ordemesh, n, 0);
340 
341  /* Rebase the Personal ordering to 0 */
342  if ( myorder != NULL ) {
343  assert( myorder != NULL );
344  assert( myorder->vertnbr == n );
345  pastixOrderBase(myorder, 0);
346  }
347 
348  if ( (myorder == NULL) || (myorder->permtab == NULL) ) {
349  if ( (myorder == NULL) || (myorder->peritab == NULL) ) {
350  if (iparm[IPARM_VERBOSE] > PastixVerboseNot) {
351  pastix_print(procnum, 0, OUT_ORDER_METHOD, "Personal (identity)" );
352  }
353  for(i=0; i<n; i++) {
354  ordemesh->permtab[i] = i;
355  ordemesh->peritab[i] = i;
356  }
357  }
358  else {
359  if (iparm[IPARM_VERBOSE] > PastixVerboseNot) {
360  pastix_print(procnum, 0, OUT_ORDER_METHOD, "Personal (from myorder->peritab)" );
361  }
362  /* generate permtab from myorder->peritab */
363  for(i=0;i<n;i++) {
364  ordemesh->permtab[myorder->peritab[i]] = i;
365  }
366  memcpy(ordemesh->peritab, myorder->peritab, n*sizeof(pastix_int_t));
367  }
368  }
369  else {
370  if (myorder->peritab == NULL) {
371  if (iparm[IPARM_VERBOSE] > PastixVerboseNot) {
372  pastix_print(procnum, 0, OUT_ORDER_METHOD, "Personal (from myorder->permtab)" );
373  }
374  /* generate peritab from myorder->permtab */
375  for(i=0;i<n;i++) {
376  ordemesh->peritab[myorder->permtab[i]] = i;
377  }
378  memcpy(ordemesh->permtab, myorder->permtab, n*sizeof(pastix_int_t));
379  }
380  else {
381  if (iparm[IPARM_VERBOSE] > PastixVerboseNot) {
382  pastix_print(procnum, 0, OUT_ORDER_METHOD, "Personal (myorder->permtab/peritab)" );
383  }
384  memcpy(ordemesh->permtab, myorder->permtab, n*sizeof(pastix_int_t));
385  memcpy(ordemesh->peritab, myorder->peritab, n*sizeof(pastix_int_t));
386  }
387  }
388 
389  /* Destroy the rangtab */
390  ordemesh->cblknbr = 0;
391  memFree_null( ordemesh->rangtab );
392  /* Destroy the treetab */
393  memFree_null( ordemesh->treetab );
394 
395  /* If treetab is provided, user must also provide rangtab */
396  if ( myorder != NULL ) {
397  assert( !( (myorder->rangtab == NULL) && (myorder->treetab != NULL) ) );
398  if (myorder->rangtab != NULL )
399  {
400  ordemesh->cblknbr = myorder->cblknbr;
401  MALLOC_INTERN(ordemesh->rangtab, myorder->cblknbr+1, pastix_int_t);
402  memcpy(ordemesh->rangtab, myorder->rangtab, (myorder->cblknbr+1)*sizeof(pastix_int_t));
403  }
404  if (myorder->treetab != NULL )
405  {
406  MALLOC_INTERN(ordemesh->treetab, myorder->cblknbr, pastix_int_t);
407  memcpy(ordemesh->treetab, myorder->treetab, myorder->cblknbr*sizeof(pastix_int_t));
408  }
409  }
410  }
411  break;
412 
413  default:
414  errorPrint( "pastix_subtask_order: Ordering not available (iparm[IPARM_ORDERING]=%d)\n",
415  (int)iparm[IPARM_ORDERING] );
416  retval = PASTIX_ERR_BADPARAMETER;
417  break;
418  }
419 
420  /*
421  * Reduce the error code
422  */
423  MPI_Allreduce( &retval, &retval_rcv, 1, MPI_INT, MPI_MAX,
424  pastix_data->pastix_comm );
425  if (retval_rcv != PASTIX_SUCCESS) {
426 
427  /* Cleanup memory */
428  if ( zeros_colptr != schur_colptr ) { memFree_null( zeros_colptr ); }
429  if ( zeros_rows != schur_rows ) { memFree_null( zeros_rows ); }
430  if ( zeros_perm != NULL ) { memFree_null( zeros_perm ); }
431  if ( schur_colptr != graph->colptr ) { memFree_null( schur_colptr ); }
432  if ( schur_rows != graph->rowptr ) { memFree_null( schur_rows ); }
433  if ( schur_perm != NULL ) { memFree_null( schur_perm ); }
434 
435  if ( spmg != spm ) {
436  spmExit( spmg );
437  memFree_null( spmg );
438  }
439 
440  return retval_rcv;
441  }
442 
443  /* Rebase the ordering to 0 (for orderFindSupernodes) */
444  pastixOrderBase( ordemesh, 0 );
445 
446  /*
447  * If the rangtab or the treetab are not initialized, let's find it ourself
448  */
449  if (( ordemesh->rangtab == NULL ) ||
450  ( ordemesh->treetab == NULL ) )
451  {
452  /* TODO: if rangtab is provided, treetab could be easily calculated */
453  pastixOrderFindSupernodes( &subgraph, ordemesh );
454 
455 #if !defined(NDEBUG) && defined(PASTIX_DEBUG_ORDERING)
456  assert( pastixOrderCheck( ordemesh ) == PASTIX_SUCCESS );
457 #endif
458 
460  iparm[IPARM_INCOMPLETE],
461  iparm[IPARM_LEVEL_OF_FILL],
464  &subgraph,
465  ordemesh,
466  pastix_data->pastix_comm );
467  }
468 
469 #if !defined(NDEBUG) && defined(PASTIX_DEBUG_ORDERING)
470  assert( pastixOrderCheck( ordemesh ) == PASTIX_SUCCESS );
471 #endif
472 
473  /*
474  * Reorder supernodes by level to get a better order for runtime systems,
475  * and for the reordering algorithm
476  */
477  pastixOrderApplyLevelOrder( ordemesh,
478  iparm[IPARM_TASKS2D_LEVEL],
479  iparm[IPARM_TASKS2D_WIDTH] );
480 
481 #if !defined(NDEBUG) && defined(PASTIX_DEBUG_ORDERING)
482  assert( pastixOrderCheck( ordemesh ) == PASTIX_SUCCESS );
483 #endif
484 
485  /*
486  * Add the isolated elements to the ordering structure
487  */
488  if ( do_zeros )
489  {
490  pastixOrderAddIsolate( ordemesh, schur_n, zeros_perm );
491 
492  if ( zeros_colptr != schur_colptr ) { memFree_null( zeros_colptr ); }
493  if ( zeros_rows != schur_rows ) { memFree_null( zeros_rows ); }
494  if ( zeros_perm != NULL ) { memFree_null( zeros_perm ); }
495  }
496 
497  /*
498  * Add the isolated elements to the ordering structure
499  */
500  if ( do_schur )
501  {
502  pastixOrderAddIsolate( ordemesh, n, schur_perm );
503 
504  if ( schur_colptr != graph->colptr ) { memFree_null( schur_colptr ); }
505  if ( schur_rows != graph->rowptr ) { memFree_null( schur_rows ); }
506  if ( schur_perm != NULL ) { memFree_null( schur_perm ); }
507  }
508 
509  /*
510  * Backup of the original supernodes
511  */
512  ordemesh->sndenbr = ordemesh->cblknbr;
513  ordemesh->sndetab = malloc( (ordemesh->sndenbr+1) * sizeof(pastix_int_t) );
514  memcpy( ordemesh->sndetab, ordemesh->rangtab, (ordemesh->sndenbr+1) * sizeof(pastix_int_t) );
515 
516  /*
517  * Block Low-Rank clustering
518  */
519  if ( ( iparm[IPARM_COMPRESS_WHEN] != PastixCompressNever ) &&
521  {
522 #if !defined(PASTIX_ORDERING_SCOTCH)
523  pastix_print_warning( "Clustering is not available yet when Scotch is disabled" );
524 #else
525  EliminTree *etree;
526  pastix_int_t min_cblk = ordemesh->rangtab[ordemesh->cblknbr-1];
527  pastix_int_t ret;
528 
529  graphBase( pastix_data->graph, 0 );
530 
531  etree = pastixOrderBuildEtree( ordemesh );
532 
533  ret = orderSupernodes( pastix_data->graph, ordemesh,
534  etree, iparm, do_schur );
535 
536  eTreeExit( etree );
537 
538  (void)ret;
539  (void)min_cblk;
540 #endif /* !defined(PASTIX_ORDERING_SCOTCH) */
541  }
542 
543 #if defined(PASTIX_ORDER_DRAW_LASTSEP)
544  /*
545  * Draw last separator graph and xyz
546  */
547  orderDraw( pastix_data, NULL, ordemesh->sndenbr-1,
548  orderDrawGraph | orderDrawCoordinates );
549 #endif
550 
551  /* Reduce the error code */
552  MPI_Allreduce(&retval, &retval_rcv, 1, MPI_INT, MPI_MAX,
553  pastix_data->pastix_comm);
554  if (retval_rcv != PASTIX_SUCCESS) {
555  return retval_rcv;
556  }
557 
558  clockStop(timer);
559  pastix_data->dparm[DPARM_ORDER_TIME] = clockVal(timer);
560  if (iparm[IPARM_VERBOSE] > PastixVerboseNot) {
561  pastix_print(procnum, 0, OUT_ORDER_TIME, clockVal(timer));
562  }
563 
564  /*
565  * Save i/o strategy
566  */
567  if ( iparm[IPARM_IO_STRATEGY] & PastixIOSave ) {
568  if (procnum == 0) {
569  retval = pastixOrderSave( pastix_data, ordemesh );
570  }
571 
572  MPI_Allreduce( &retval, &retval_rcv, 1, MPI_INT, MPI_MAX,
573  pastix_data->pastix_comm );
574  if ( retval_rcv != PASTIX_SUCCESS ) {
575  return retval_rcv;
576  }
577  }
578 
579  /*
580  * Return the ordering to user if structure is not NULL
581  * Remark: No need to copy back for personal
582  */
583  if (iparm[IPARM_ORDERING] != PastixOrderPersonal) {
584  if ( spmg->loc2glob == NULL ) {
585  if ( myorder != NULL )
586  {
587  retval = pastixOrderCopy( myorder, ordemesh );
588  MPI_Allreduce( &retval, &retval_rcv, 1, MPI_INT, MPI_MAX,
589  pastix_data->pastix_comm );
590  if ( retval_rcv != PASTIX_SUCCESS ) {
591  return retval_rcv;
592  }
593  }
594  }
595  else {
596  int baseval = graph->colptr[0];
597  /* Should be 0-based ? */
598  assert (baseval == 0);
599 
600  if (myorder->permtab != NULL) {
601  pastix_int_t *permtab = ordemesh->permtab - baseval;
602  pastix_int_t i;
603 
604  for(i=0; i<n; i++) {
605  myorder->permtab[i] = permtab[spmg->loc2glob[i]];
606  }
607  }
608  if (myorder->peritab != NULL) {
609  pastix_int_t *peritab = ordemesh->peritab - baseval;
610  pastix_int_t i;
611 
612  for(i=0; i<n; i++) {
613  myorder->peritab[i] = peritab[spmg->loc2glob[i]];
614  }
615  }
616  /* TODO: Copy also rangtab and treetab ? */
617  }
618  }
619 
620  /*
621  * For now, what the rank 0 has will overwrite what the others have, even if
622  * they all computed something
623  */
624  pastixOrderBcast( pastix_data->ordemesh, 0, pastix_data->pastix_comm );
625 
626 #if !defined(NDEBUG)
627  assert( pastixOrderCheck( pastix_data->ordemesh ) == PASTIX_SUCCESS );
628 #endif
629 
630  /* Backup the spm pointer for further information */
631  pastix_data->csc = spm;
632 
633  /* Free the gathered spm */
634  if ( spmg != spm ) {
635  spmExit( spmg );
636  memFree_null( spmg );
637  }
638 
639  /* Invalidate following steps, and add order step to the ones performed */
640  pastix_data->steps &= ~( STEP_SYMBFACT |
641  STEP_ANALYSE |
642  STEP_CSC2BCSC |
643  STEP_BCSC2CTAB |
644  STEP_NUMFACT |
645  STEP_SOLVE |
646  STEP_REFINE );
647  pastix_data->steps |= STEP_ORDERING;
648 
649  return PASTIX_SUCCESS;
650 }
graphBase
void graphBase(pastix_graph_t *graph, pastix_int_t baseval)
Rebase the graph to the given value.
Definition: graph.c:70
orderDraw
void orderDraw(pastix_data_t *pastix_data, const char *extname, pastix_int_t sndeidx, int dump)
Dump the last separator into an ivview file.
Definition: order_draw.c:50
pastix_order_s::cblknbr
pastix_int_t cblknbr
Definition: order.h:48
pastixOrderSave
int pastixOrderSave(pastix_data_t *pastix_data, const pastix_order_t *ordeptr)
Save an ordering to a file.
Definition: order_io.c:294
etree_s
Elimination tree.
Definition: elimintree.h:39
IPARM_ORDERING
@ IPARM_ORDERING
Definition: api.h:50
pastix_order_s::peritab
pastix_int_t * peritab
Definition: order.h:50
pastix_order_s::permtab
pastix_int_t * permtab
Definition: order.h:49
pastixOrderExit
void pastixOrderExit(pastix_order_t *const ordeptr)
Free the arrays initialized in the order structure.
Definition: order.c:273
IPARM_LEVEL_OF_FILL
@ IPARM_LEVEL_OF_FILL
Definition: api.h:96
pastix_order_s::treetab
pastix_int_t * treetab
Definition: order.h:52
pastix_order_s
Order structure.
Definition: order.h:45
PastixCompressNever
@ PastixCompressNever
Definition: api.h:362
IPARM_TASKS2D_WIDTH
@ IPARM_TASKS2D_WIDTH
Definition: api.h:91
pastixOrderBcast
void pastixOrderBcast(pastix_order_t *ordemesh, int root, PASTIX_Comm pastix_comm)
This routine broadcast the ordemesh structure from node root to all the other nodes.
Definition: order.c:605
PastixIOSave
@ PastixIOSave
Definition: api.h:218
pastixOrderComputeMetis
int pastixOrderComputeMetis(pastix_data_t *pastix_data, pastix_graph_t *graph)
Compute the ordering of the graph given as parameter with Metis library.
Definition: order_compute_metis.c:60
pastix_order_s::vertnbr
pastix_int_t vertnbr
Definition: order.h:47
PastixOrderMetis
@ PastixOrderMetis
Definition: api.h:323
pastixOrderAddIsolate
int pastixOrderAddIsolate(pastix_order_t *ordeptr, pastix_int_t new_n, const pastix_int_t *perm)
This routine combines two permutation arrays when a subset of vertices has been isolated from the ori...
Definition: order_add_isolate.c:56
graphPrepare
int graphPrepare(pastix_data_t *pastix_data, const spmatrix_t *spm, pastix_graph_t **graph)
This routine initializes the graph.
Definition: graph_prepare.c:115
pastixOrderCopy
int pastixOrderCopy(pastix_order_t *const ordedst, const pastix_order_t *const ordesrc)
This routine copy a given ordering in a new one.
Definition: order.c:496
IPARM_AMALGAMATION_LVLCBLK
@ IPARM_AMALGAMATION_LVLCBLK
Definition: api.h:75
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
IPARM_SPLITTING_STRATEGY
@ IPARM_SPLITTING_STRATEGY
Definition: api.h:80
PastixVerboseNot
@ PastixVerboseNot
Definition: api.h:207
PASTIX_SUCCESS
@ PASTIX_SUCCESS
Definition: api.h:344
PastixVerboseNo
@ PastixVerboseNo
Definition: api.h:208
pastixOrderApplyLevelOrder
int pastixOrderApplyLevelOrder(pastix_order_t *ordeptr, pastix_int_t level_tasks2d, pastix_int_t width_tasks2d)
This routine reorder the elimination tree nodes per level.
Definition: order_apply_level_order.c:95
IPARM_COMPRESS_WHEN
@ IPARM_COMPRESS_WHEN
Definition: api.h:128
elimintree.h
PastixOrderPersonal
@ PastixOrderPersonal
Definition: api.h:324
pastixOrderAlloc
int pastixOrderAlloc(pastix_order_t *const ordeptr, pastix_int_t vertnbr, pastix_int_t cblknbr)
Allocate the order structure.
Definition: order.c:55
pastixOrderComputePTScotch
int pastixOrderComputePTScotch(pastix_data_t *pastix_data, pastix_graph_t *graph)
Compute the ordering of the graph given as parameter with PT-Scotch library.
Definition: order_compute_ptscotch.c:60
IPARM_FLOAT
@ IPARM_FLOAT
Definition: api.h:142
eTreeExit
void eTreeExit(EliminTree *)
Free the elimination tree structure.
Definition: elimintree.c:85
pastixOrderAmalgamate
int pastixOrderAmalgamate(int verbose, int ilu, int levelk, int rat_cblk, int rat_blas, pastix_graph_t *graph, pastix_order_t *orderptr, PASTIX_Comm pastix_comm)
Update the order structure with an amalgamation algorithm.
Definition: order_amalgamate.c:82
graphIsolate
int graphIsolate(pastix_int_t n, const pastix_int_t *colptr, const pastix_int_t *rows, pastix_int_t isolate_n, pastix_int_t *isolate_list, pastix_int_t **new_colptr, pastix_int_t **new_rows, pastix_int_t **new_perm, pastix_int_t **new_invp)
Isolate a subset of vertices from a given graph.
Definition: graph_isolate.c:262
graph.h
IPARM_AMALGAMATION_LVLBLAS
@ IPARM_AMALGAMATION_LVLBLAS
Definition: api.h:74
orderSupernodes
pastix_int_t orderSupernodes(const pastix_graph_t *graph, pastix_order_t *order, EliminTree *etree, pastix_int_t *iparm, int do_schur)
Order the supernodes with one of the clustering strategies.
Definition: order_supernodes.c:59
DPARM_ORDER_TIME
@ DPARM_ORDER_TIME
Definition: api.h:157
pastixOrderBuildEtree
EliminTree * pastixOrderBuildEtree(const pastix_order_t *order)
This routine build the elimination tree associated to an ordering.
Definition: order_apply_level_order.c:41
IPARM_VERBOSE
@ IPARM_VERBOSE
Definition: api.h:36
pastix_order_s::rangtab
pastix_int_t * rangtab
Definition: order.h:51
pastixOrderLoad
int pastixOrderLoad(const pastix_data_t *pastix_data, pastix_order_t *ordeptr)
Load an ordering from a file.
Definition: order_io.c:132
PastixSplitNot
@ PastixSplitNot
Definition: api.h:393
PastixOrderScotch
@ PastixOrderScotch
Definition: api.h:322
IPARM_INCOMPLETE
@ IPARM_INCOMPLETE
Definition: api.h:95
IPARM_TASKS2D_LEVEL
@ IPARM_TASKS2D_LEVEL
Definition: api.h:90
pastixOrderFindSupernodes
void pastixOrderFindSupernodes(const pastix_graph_t *graph, pastix_order_t *const ordeptr)
Computes the set of supernodes for a given permutation.
Definition: order_find_supernodes.c:360
PastixIOLoad
@ PastixIOLoad
Definition: api.h:217
pastix_order_s::sndenbr
pastix_int_t sndenbr
Definition: order.h:54
PastixOrderPtScotch
@ PastixOrderPtScotch
Definition: api.h:325
pastix_subtask_order
int pastix_subtask_order(pastix_data_t *pastix_data, const spmatrix_t *spm, pastix_order_t *myorder)
Computes the ordering of the given graph in parameters.
Definition: pastix_subtask_order.c:97
pastixOrderComputeScotch
int pastixOrderComputeScotch(pastix_data_t *pastix_data, pastix_graph_t *graph)
Compute the ordering of the graph given as parameter with Scotch library.
Definition: order_compute_scotch.c:537
pastix_order_s::sndetab
pastix_int_t * sndetab
Definition: order.h:55
IPARM_IO_STRATEGY
@ IPARM_IO_STRATEGY
Definition: api.h:37
PASTIX_ERR_BADPARAMETER
@ PASTIX_ERR_BADPARAMETER
Definition: api.h:351
PastixVerboseYes
@ PastixVerboseYes
Definition: api.h:209