PaStiX Handbook  6.2.1
order.c
Go to the documentation of this file.
1 /**
2  *
3  * @file order.c
4  *
5  * PaStiX order structure routines
6  *
7  * @copyright 2004-2021 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8  * Univ. Bordeaux. All rights reserved.
9  *
10  * @version 6.2.0
11  * @author Francois Pellegrini
12  * @author Mathieu Faverge
13  * @author Pierre Ramet
14  * @author Vincent Bridonneau
15  * @date 2021-01-14
16  *
17  **/
18 #include "common.h"
19 #include "pastix/order.h"
20 
21 /**
22  *******************************************************************************
23  *
24  * @ingroup pastix_order
25  *
26  * @brief Allocate the order structure.
27  *
28  * The base value is set to 0 by default.
29  *
30  *******************************************************************************
31  *
32  * @param[inout] ordeptr
33  * The data structure is set to 0 and then initialize.
34  * Need to call pastixOrderExit() to release the memory first if required to
35  * prevent memory leak.
36  *
37  * @param[in] vertnbr
38  * The number of nodes, this is the size of the internal permtab and
39  * peritab arrays.
40  * If vertnbr == 0, permtab and peritab are not allocated.
41  *
42  * @param[in] cblknbr
43  * The number of supernodes. The internal rangtab array is of size
44  * cblknbr+1, and treetab of size cblknbr.
45  * If cblknbr == 0, rangtab and treetab are not allocated.
46  *
47  *******************************************************************************
48  *
49  * @retval PASTIX_SUCCESS on successful exit,
50  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect,
51  * @retval PASTIX_ERR_OUTOFMEMORY if one allocation failed.
52  *
53  *******************************************************************************/
54 int
56  pastix_int_t vertnbr,
57  pastix_int_t cblknbr )
58 {
59  /* Parameter checks */
60  if ( ordeptr == NULL ) {
62  }
63  if ( vertnbr < 0 ) {
65  }
66  if ( cblknbr < 0 ) {
68  }
69  if ( cblknbr > vertnbr ) {
71  }
72 
73  memset( ordeptr, 0, sizeof(pastix_order_t) );
74 
75  ordeptr->vertnbr = vertnbr;
76  ordeptr->cblknbr = cblknbr;
77  ordeptr->sndenbr = cblknbr;
78  ordeptr->sndetab = NULL;
79 
80  if ( vertnbr > 0 ) {
81  MALLOC_INTERN( ordeptr->permtab, vertnbr, pastix_int_t );
82  MALLOC_INTERN( ordeptr->peritab, vertnbr, pastix_int_t );
83  }
84 
85  if ( cblknbr > 0 ) {
86  MALLOC_INTERN( ordeptr->rangtab, cblknbr+1, pastix_int_t );
87  MALLOC_INTERN( ordeptr->treetab, cblknbr, pastix_int_t );
88  }
89 
90  return PASTIX_SUCCESS;
91 }
92 
93 /**
94  *******************************************************************************
95  *
96  * @ingroup pastix_order
97  *
98  * @brief Allocate the order structure for a given number of vertices with no
99  * cblk, and id permutation.
100  *
101  * The base value is set to 0 by default.
102  *
103  *******************************************************************************
104  *
105  * @param[inout] ordeptr
106  * The data structure is set to 0 and then initialize.
107  * Need to call pastixOrderExit() to release the memory first if required to
108  * prevent memory leak.
109  *
110  * @param[in] vertnbr
111  * The number of nodes, this is the size of the internal permtab and
112  * peritab arrays.
113  * If vertnbr == 0, permtab and peritab are not allocated.
114  *
115  *******************************************************************************
116  *
117  * @retval PASTIX_SUCCESS on successful exit,
118  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect,
119  * @retval PASTIX_ERR_OUTOFMEMORY if one allocation failed.
120  *
121  *******************************************************************************/
122 int
124  pastix_int_t vertnbr )
125 {
126  pastix_int_t *perm;
127  pastix_int_t *invp;
128  pastix_int_t i;
129  int rc;
130 
131  rc = pastixOrderAlloc( ordeptr, vertnbr, 1 );
132  if ( rc != PASTIX_SUCCESS ) {
133  return rc;
134  }
135 
136  perm = ordeptr->permtab;
137  invp = ordeptr->peritab;
138 
139  for(i=0; i<vertnbr; i++, perm++, invp++) {
140  *perm = i;
141  *invp = i;
142  }
143 
144  ordeptr->rangtab[0] = 0;
145  ordeptr->rangtab[1] = vertnbr;
146  ordeptr->treetab[0] = -1;
147 
148  return PASTIX_SUCCESS;
149 }
150 
151 /**
152  *******************************************************************************
153  *
154  * @ingroup pastix_order
155  *
156  * @brief Initialize the order structure with the given values.
157  *
158  * The base value is set to 0 by default. This is useful to give a personal
159  * ordering to the pastix_task_order() function.
160  *
161  *******************************************************************************
162  *
163  * @param[inout] ordeptr
164  * The data structure is set to 0 and then initialize.
165  * Need to call orderExit to release the memory first if required to
166  * prevent memory leak.
167  *
168  * @param[in] baseval
169  * The base value used in the given arrays. Usually 0 for C, 1 for
170  * Fortran. Must be >= 0.
171  *
172  * @param[in] vertnbr
173  * The number of nodes, this is the size of the internal permtab and
174  * peritab arrays.
175  *
176  * @param[in] cblknbr
177  * The number of supernodes. The internal rangtab and treetab arrays
178  * are of size cblknbr+1.
179  *
180  * @param[in] permtab
181  * The permutation array which must be of size vertnbr, and based on
182  * baseval value.
183  * If NULL, the permtab field is not initialized.
184  *
185  * @param[in] peritab
186  * The inverse permutation array which must be of size vertnbr, and
187  * based on baseval value.
188  * If NULL, the peritab field is not initialized.
189  *
190  * @param[in] rangtab
191  * The rangtab array that describes the supernodes in the graph. This
192  * array must be of size cblknbr+1, and based on baseval value.
193  * If NULL, the rangtab field is not initialized.
194  *
195  * @param[in] treetab
196  * The treetab array that describes the elimination tree connecting the
197  * supernodes. This array must be defined as follow:
198  * - of size cblknbr;
199  * - based on baseval value;
200  * - each treetab[i] > i, unless i is a root and treetab[i] == -1
201  * - all roots of the tree must have -1 as father
202  * If NULL, the treetab field is not initialized.
203  *
204  *******************************************************************************
205  *
206  * @retval PASTIX_SUCCESS on successful exit
207  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect.
208  * @retval PASTIX_ERR_OUTOFMEMORY if one allocation failed.
209  *
210  *******************************************************************************/
211 int
213  pastix_int_t baseval,
214  pastix_int_t vertnbr,
215  pastix_int_t cblknbr,
216  pastix_int_t * const permtab,
217  pastix_int_t * const peritab,
218  pastix_int_t * const rangtab,
219  pastix_int_t * const treetab )
220 {
221  /* Parameter checks */
222  if ( ordeptr == NULL ) {
224  }
225  if ( vertnbr < 0 ) {
227  }
228  if ( cblknbr < 0 ) {
230  }
231 
232  memset(ordeptr, 0, sizeof(pastix_order_t));
233 
234  ordeptr->baseval = baseval;
235  ordeptr->vertnbr = vertnbr;
236  ordeptr->cblknbr = cblknbr;
237  ordeptr->sndenbr = cblknbr;
238  ordeptr->sndetab = NULL;
239 
240  if ( permtab ) {
241  ordeptr->permtab = permtab;
242  }
243  if ( peritab ) {
244  ordeptr->peritab = peritab;
245  }
246  if ( rangtab ) {
247  ordeptr->rangtab = rangtab;
248  ordeptr->sndetab = malloc( (ordeptr->sndenbr+1) * sizeof(pastix_int_t) );
249  memcpy( ordeptr->sndetab, ordeptr->rangtab, (ordeptr->sndenbr+1) * sizeof(pastix_int_t) );
250  }
251  if ( treetab ) {
252  ordeptr->treetab = treetab;
253  }
254 
255  return PASTIX_SUCCESS;
256 }
257 
258 /**
259  *******************************************************************************
260  *
261  * @ingroup pastix_order
262  *
263  * @brief Free the arrays initialized in the order structure.
264  *
265  *******************************************************************************
266  *
267  * @param[inout] ordeptr
268  * The data structure to clean. All arrays of the structure are freed
269  * and the structure is set to 0.
270  *
271  *******************************************************************************/
272 void
273 pastixOrderExit( pastix_order_t * const ordeptr )
274 {
275  /* Parameter check */
276  if ( ordeptr == NULL ) {
277  return;
278  }
279 
280  if (ordeptr->permtab != NULL) {
281  memFree_null (ordeptr->permtab);
282  }
283  if (ordeptr->peritab != NULL) {
284  memFree_null (ordeptr->peritab);
285  }
286  if (ordeptr->rangtab != NULL) {
287  memFree_null (ordeptr->rangtab);
288  }
289  if (ordeptr->treetab != NULL) {
290  memFree_null (ordeptr->treetab);
291  }
292  if (ordeptr->selevtx != NULL) {
293  memFree_null (ordeptr->selevtx);
294  }
295  if (ordeptr->sndetab != NULL) {
296  memFree_null (ordeptr->sndetab);
297  }
298  memset(ordeptr, 0, sizeof(pastix_order_t) );
299 }
300 
301 /**
302  *******************************************************************************
303  *
304  * @ingroup pastix_order
305  *
306  * @brief This routine sets the base of the given ordering structure to the
307  * given base value.
308  *
309  *******************************************************************************
310  *
311  * @param[inout] ordeptr
312  * The ordering to rebase.
313  *
314  * @param[in] baseval
315  * The base value to be used (needs to be 0 or 1).
316  *
317  *******************************************************************************/
318 void
320  pastix_int_t baseval )
321 {
322  pastix_int_t baseadj; /* Base adjust */
323  pastix_int_t cblknum;
324  pastix_int_t vertnum;
325 
326  /* Parameter checks */
327  if ( ordeptr == NULL ) {
328  errorPrint("pastixOrderBase: ordeptr pointer is NULL");
329  return;
330  }
331  if ( (baseval != 0) &&
332  (baseval != 1) )
333  {
334  errorPrint("pastixOrderBase: baseval is incorrect, must be 0 or 1");
335  return;
336  }
337 
338  baseadj = baseval - ordeptr->baseval; /* Set base adjust */
339  if (baseadj == 0) /* If base already set */
340  return;
341 
342  if (ordeptr->permtab != NULL) {
343  for (vertnum = 0; vertnum < ordeptr->vertnbr; vertnum ++) {
344  ordeptr->permtab[vertnum] += baseadj;
345  }
346  }
347  if (ordeptr->peritab != NULL) {
348  for (vertnum = 0; vertnum < ordeptr->vertnbr; vertnum ++) {
349  ordeptr->peritab[vertnum] += baseadj;
350  }
351  }
352 
353  if (ordeptr->rangtab != NULL) {
354  for (cblknum = 0; cblknum <= ordeptr->cblknbr; cblknum ++) {
355  ordeptr->rangtab[cblknum] += baseadj;
356  }
357  }
358  if (ordeptr->treetab != NULL) {
359  for (cblknum = 0; cblknum < ordeptr->cblknbr; cblknum ++) {
360  ordeptr->treetab[cblknum] += baseadj;
361  }
362  }
363  if (ordeptr->sndetab != NULL) {
364  pastix_int_t sndenum;
365  for (sndenum = 0; sndenum <= ordeptr->sndenbr; sndenum ++) {
366  ordeptr->sndetab[sndenum] += baseadj;
367  }
368  }
369 
370  ordeptr->baseval = baseval;
371 }
372 
373 /**
374  *******************************************************************************
375  *
376  * @ingroup pastix_order
377  *
378  * @brief This routine expand the permutation arrays and the rangtab when the
379  * spm is using multiple dof per unknown.
380  *
381  *******************************************************************************
382  *
383  * @param[inout] ordeptr
384  * The ordering to expand. On entry, the order of the compressed
385  * unknown. On exit, the ordering is 0-based and contains the
386  * permutation for the expanded matrix.
387  *
388  * @param[inout] spm
389  * The sparse matrix structure providing dof information. On exit, the
390  * spm is rebased to 0, if it is not the case on entry.
391  *
392  *******************************************************************************/
393 void pastixOrderExpand( pastix_order_t * const ordeptr,
394  spmatrix_t * const spm )
395 {
396  pastix_int_t *peritab;
397  pastix_int_t i, j, n;
398  pastix_int_t begin, end, sum_rang, sum_snde;
399  pastix_int_t *newperi;
400  pastix_int_t *rangtab;
401  pastix_int_t *sndetab;
402  const pastix_int_t *dofs;
403 
404  spmBase( spm, 0 );
405  pastixOrderBase( ordeptr, 0 );
406 
407  n = spm->nexp;
408 
409  /*
410  * Initialize inverse permutation and rangtab
411  */
412  peritab = ordeptr->peritab;
413  rangtab = ordeptr->rangtab;
414  sndetab = ordeptr->sndetab;
415 
416  MALLOC_INTERN( ordeptr->peritab, n, pastix_int_t );
417  newperi = ordeptr->peritab;
418 
419  dofs = spm->dofs;
420 
421  sum_rang = 0;
422  sum_snde = 0;
423  for (i=0; i<ordeptr->vertnbr; i++)
424  {
425  if ( spm->dof <= 0 ) {
426  begin = dofs[ peritab[i] ];
427  end = dofs[ peritab[i] + 1 ];
428  }
429  else {
430  begin = peritab[i] * spm->dof;
431  end = begin + spm->dof;
432  }
433 
434  if ( i == rangtab[1] ) {
435  rangtab[1] = rangtab[0] + sum_rang;
436  rangtab++;
437  sum_rang = 0;
438  }
439  if ( i == sndetab[1] ) {
440  sndetab[1] = sndetab[0] + sum_snde;
441  sndetab++;
442  sum_snde = 0;
443  }
444 
445  sum_rang += (end - begin);
446  sum_snde += (end - begin);
447 
448  for ( j=begin; j<end; ++j, ++newperi ) {
449  *newperi = j;
450  }
451  }
452  rangtab[1] = rangtab[0] + sum_rang;
453  sndetab[1] = sndetab[0] + sum_snde;
454 
455  ordeptr->vertnbr = n;
456  memFree_null( peritab );
457 
458  /*
459  * Update permtab
460  */
461  memFree_null( ordeptr->permtab );
462  MALLOC_INTERN( ordeptr->permtab, n, pastix_int_t );
463  for( i=0; i<n; i++ ) {
464  j = ordeptr->peritab[i];
465  ordeptr->permtab[j] = i;
466  }
467 }
468 
469 /**
470  *******************************************************************************
471  *
472  * @ingroup pastix_order
473  *
474  * @brief This routine copy a given ordering in a new one.
475  *
476  * This function copies an order structure into another one. If all subpointers
477  * are NULL, then they are all allocated and conatins the original ordesrc
478  * values on exit. If one or more array pointers are not NULL, then, only those
479  * are copied to the ordedst structure.
480  *
481  *******************************************************************************
482  *
483  * @param[inout] ordedst
484  * The destination ordering
485  *
486  * @param[in] ordesrc
487  * The source ordering
488  *
489  *******************************************************************************
490  *
491  * @retval PASTIX_SUCCESS on successful exit
492  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect.
493  *
494  *******************************************************************************/
495 int
497  const pastix_order_t * const ordesrc )
498 {
499  /* Parameter checks */
500  if ( ordedst == NULL ) {
502  }
503  if ( ordesrc == NULL ) {
505  }
506  if ( ordesrc == ordedst ) {
508  }
509 
510  ordedst->baseval = ordesrc->baseval;
511  ordedst->vertnbr = ordesrc->vertnbr;
512  ordedst->cblknbr = ordesrc->cblknbr;
513  ordedst->sndenbr = ordesrc->sndenbr;
514 
515  if ( (ordedst->permtab == NULL) &&
516  (ordedst->peritab == NULL) &&
517  (ordedst->rangtab == NULL) &&
518  (ordedst->treetab == NULL) )
519  {
520  pastixOrderAlloc( ordedst, ordedst->vertnbr, ordedst->cblknbr );
521  }
522 
523  if ( (ordesrc->permtab != NULL) && (ordedst->permtab != NULL) )
524  {
525  memcpy( ordedst->permtab, ordesrc->permtab, ordesrc->vertnbr * sizeof(pastix_int_t) );
526  }
527 
528  if ( (ordesrc->peritab != NULL) && (ordedst->peritab != NULL) )
529  {
530  memcpy( ordedst->peritab, ordesrc->peritab, ordesrc->vertnbr * sizeof(pastix_int_t) );
531  }
532 
533  if ( (ordesrc->rangtab != NULL) && (ordedst->rangtab != NULL) )
534  {
535  memcpy( ordedst->rangtab, ordesrc->rangtab, (ordesrc->cblknbr+1) * sizeof(pastix_int_t) );
536  }
537 
538  if ( (ordesrc->treetab != NULL) && (ordedst->treetab != NULL) )
539  {
540  memcpy( ordedst->treetab, ordesrc->treetab, ordesrc->cblknbr * sizeof(pastix_int_t) );
541  }
542 
543  if ( (ordesrc->sndetab != NULL) && (ordedst->sndetab != NULL) )
544  {
545  memcpy( ordedst->sndetab, ordesrc->sndetab, (ordesrc->sndenbr+1) * sizeof(pastix_int_t) );
546  }
547 
548  return PASTIX_SUCCESS;
549 }
550 
551 /**
552  *******************************************************************************
553  *
554  * @ingroup pastix_order
555  *
556  * @brief This routine returns the pointer to the internal order structure to
557  * access permutation information.
558  *
559  * @warning The data returned by the routines must not be freed or modified by
560  * the user, and are valid as long as no operation on the ordering is performed
561  * (pastix_subtask_order(), pastix_subtask_reordering(), or pastixFinalize()).
562  *
563  *******************************************************************************
564  *
565  * @param[in] pastix_data
566  * The pastix_data structure of the problem
567  *
568  *******************************************************************************
569  *
570  * @return The pointer to the internal ordering structure with permutation
571  * information, or NULL if pastix_data is invalid.
572  *
573  *******************************************************************************/
574 const pastix_order_t *
575 pastixOrderGet( const pastix_data_t * const pastix_data )
576 {
577  /* Parameter checks */
578  if ( pastix_data == NULL ) {
579  return NULL;
580  }
581  return pastix_data->ordemesh;
582 }
583 
584 /**
585  *******************************************************************************
586  *
587  * @ingroup pastix_order
588  *
589  * @brief This routine broadcast the ordemesh structure from node root to all
590  * the other nodes.
591  *
592  *******************************************************************************
593  *
594  * @param[inout] ordemesh
595  * The ordering structure of the problem.
596  *
597  * @param[in] root
598  * The node that will broadcast its ordemesh.
599  *
600  * @param[in] comm
601  * The MPI communicator of the problem.
602  *
603  *******************************************************************************/
604 void
606  int root,
607  PASTIX_Comm pastix_comm )
608 {
609  pastix_int_t vertnbr, cblknbr, sndenbr;
610  int clustnum;
611 
612  MPI_Comm_rank( pastix_comm, &clustnum );
613 
614  /* Free previous order structure */
615  if ( clustnum != root ) {
616  pastixOrderExit( ordemesh );
617  }
618 
619  /* Copy ordemesh datas from node 0 */
620  MPI_Bcast( ordemesh, sizeof(pastix_order_t), MPI_BYTE,
621  root, pastix_comm );
622 
623  vertnbr = ordemesh->vertnbr;
624  cblknbr = ordemesh->cblknbr;
625  sndenbr = ordemesh->sndenbr;
626 
627  if ( ordemesh->permtab ) {
628  if ( clustnum != root ) {
629  MALLOC_INTERN( ordemesh->permtab, vertnbr, pastix_int_t );
630  }
631  MPI_Bcast( ordemesh->permtab, vertnbr, PASTIX_MPI_INT,
632  root, pastix_comm );
633  }
634 
635  if ( ordemesh->peritab ) {
636  if ( clustnum != root ) {
637  MALLOC_INTERN( ordemesh->peritab, vertnbr, pastix_int_t );
638  }
639  MPI_Bcast( ordemesh->peritab, vertnbr, PASTIX_MPI_INT,
640  root, pastix_comm );
641  }
642 
643  if ( ordemesh->rangtab ) {
644  if ( clustnum != root ) {
645  MALLOC_INTERN( ordemesh->rangtab, cblknbr+1, pastix_int_t );
646  }
647  MPI_Bcast( ordemesh->rangtab, cblknbr+1, PASTIX_MPI_INT,
648  root, pastix_comm );
649  }
650 
651  if ( ordemesh->treetab ) {
652  if ( clustnum != root ) {
653  MALLOC_INTERN( ordemesh->treetab, cblknbr, pastix_int_t );
654  }
655  MPI_Bcast( ordemesh->treetab, cblknbr, PASTIX_MPI_INT,
656  root, pastix_comm );
657  }
658 
659  if ( ordemesh->selevtx ) {
660  if ( clustnum != root ) {
661  MALLOC_INTERN( ordemesh->selevtx, cblknbr, int8_t );
662  }
663  MPI_Bcast( ordemesh->selevtx, cblknbr * sizeof(int8_t), MPI_BYTE,
664  root, pastix_comm );
665  }
666 
667  if ( ordemesh->sndetab ) {
668  if ( clustnum != root ) {
669  MALLOC_INTERN( ordemesh->sndetab, sndenbr+1, pastix_int_t );
670  }
671  MPI_Bcast( ordemesh->sndetab, sndenbr+1, PASTIX_MPI_INT,
672  root, pastix_comm );
673  }
674 }
pastix_order_s::cblknbr
pastix_int_t cblknbr
Definition: order.h:48
pastixOrderAllocId
int pastixOrderAllocId(pastix_order_t *const ordeptr, pastix_int_t vertnbr)
Allocate the order structure for a given number of vertices with no cblk, and id permutation.
Definition: order.c:123
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
pastix_order_s::treetab
pastix_int_t * treetab
Definition: order.h:52
pastix_order_s
Order structure.
Definition: order.h:45
pastix_order_s::selevtx
int8_t * selevtx
Definition: order.h:53
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
pastix_order_s::vertnbr
pastix_int_t vertnbr
Definition: order.h:47
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
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
PASTIX_SUCCESS
@ PASTIX_SUCCESS
Definition: api.h:344
pastixOrderAlloc
int pastixOrderAlloc(pastix_order_t *const ordeptr, pastix_int_t vertnbr, pastix_int_t cblknbr)
Allocate the order structure.
Definition: order.c:55
pastix_order_s::baseval
pastix_int_t baseval
Definition: order.h:46
pastixOrderExpand
void pastixOrderExpand(pastix_order_t *const ordeptr, spmatrix_t *const spm)
This routine expand the permutation arrays and the rangtab when the spm is using multiple dof per unk...
Definition: order.c:393
pastixOrderInit
int pastixOrderInit(pastix_order_t *const ordeptr, pastix_int_t baseval, pastix_int_t vertnbr, pastix_int_t cblknbr, pastix_int_t *const perm, pastix_int_t *const invp, pastix_int_t *const rang, pastix_int_t *const tree)
Initialize the order structure with the given values.
Definition: order.c:212
pastix_order_s::rangtab
pastix_int_t * rangtab
Definition: order.h:51
order.h
pastix_order_s::sndenbr
pastix_int_t sndenbr
Definition: order.h:54
pastix_order_s::sndetab
pastix_int_t * sndetab
Definition: order.h:55
pastixOrderGet
const pastix_order_t * pastixOrderGet(const pastix_data_t *const pastix_data)
This routine returns the pointer to the internal order structure to access permutation information.
Definition: order.c:575
PASTIX_ERR_BADPARAMETER
@ PASTIX_ERR_BADPARAMETER
Definition: api.h:351