PaStiX Handbook  6.2.1
order_check.c
Go to the documentation of this file.
1 /**
2  *
3  * @file order_check.c
4  *
5  * PaStiX order function to check correctness of a ordering structure.
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  * @date 2020-03-02
15  *
16  **/
17 #include "common.h"
18 #include "order/order_internal.h"
19 
20 /**
21  *******************************************************************************
22  *
23  * @ingroup pastix_order
24  *
25  * @brief This routine checks the correctness of the ordering structure.
26  *
27  *******************************************************************************
28  *
29  * @param[in] ordeptr
30  * The ordering structure to check.
31  *
32  *******************************************************************************
33  *
34  * @retval PASTIX_SUCCESS on successful exit,
35  * @retval PASTIX_ERR_BADPARAMETER if the ordering structure is incorrect.
36  *
37  *******************************************************************************/
38 int
39 pastixOrderCheck (const pastix_order_t * const ordeptr)
40 {
41  pastix_int_t baseval; /* Node base value */
42  pastix_int_t cblkmax; /* Maximum supernode value */
43  pastix_int_t vnodmax; /* Maximum node value */
44  pastix_int_t vnodnum; /* Number of current node */
45  pastix_int_t rangnum; /* Current column block index */
46  const pastix_int_t * peritax; /* Based access to peritab */
47  const pastix_int_t * permtax; /* Based access to permtab */
48 
49  /* Parameter checks */
50  if (ordeptr == NULL) {
51  pastix_print_error( "pastixOrderCheck: invalid ordeptr pointer" );
53  }
54 
55  if ( (ordeptr->cblknbr < 0) || (ordeptr->vertnbr < 0) ) {
56  pastix_print_error( "pastixOrderCheck: invalid number of vertices and/or column blocks" );
58  }
59 
60  baseval = ordeptr->baseval;
61  if (baseval < 0) {
62  pastix_print_error( "pastixOrderCheck: invalid vertex node base number" );
64  }
65 
66  if ( ordeptr->vertnbr == 0 ) {
67  /* Nothing to check */
68  assert( ordeptr->cblknbr == 0 );
69  return PASTIX_SUCCESS;
70  }
71  assert( ordeptr->cblknbr > 0 );
72 
73  if ( ordeptr->permtab == NULL ) {
74  pastix_print_error( "pastixOrderCheck: permtab array is missing" );
76  }
77  if ( ordeptr->peritab == NULL ) {
78  pastix_print_error( "pastixOrderCheck: peritab array is missing" );
80  }
81  if ( ordeptr->rangtab == NULL ) {
82  pastix_print_error( "pastixOrderCheck: rangtab array is missing" );
84  }
85  if ( ordeptr->treetab == NULL ) {
86  pastix_print_error( "pastixOrderCheck: treetab array is missing" );
88  }
89 
90  assert(baseval == ordeptr->rangtab[0]);
91 
92  peritax = ordeptr->peritab - baseval; /* Set based accesses */
93  vnodmax = ordeptr->rangtab[ordeptr->cblknbr] - 1;
94 
95  assert((ordeptr->rangtab[ordeptr->cblknbr] - baseval) == ordeptr->vertnbr);
96 
97  /*
98  * Check the values in rangtab
99  */
100  for (rangnum = 0; rangnum < ordeptr->cblknbr; rangnum ++)
101  {
102  if ((ordeptr->rangtab[rangnum] < baseval) ||
103  (ordeptr->rangtab[rangnum] > vnodmax) ||
104  (ordeptr->rangtab[rangnum] >= ordeptr->rangtab[rangnum + 1]))
105  {
106  pastix_print_error( "pastixOrderCheck: invalid range array" );
108  }
109  }
110 
111  permtax = ordeptr->permtab - baseval;
112 
113  /*
114  * Check perm and invp, as well as the symmetry between the two
115  */
116  for (vnodnum = baseval;
117  vnodnum <= vnodmax; vnodnum ++)
118  {
119  pastix_int_t vnodold;
120 
121  vnodold = peritax[vnodnum];
122  if ((vnodold < baseval) ||
123  (vnodold > vnodmax) ||
124  (permtax[vnodold] != vnodnum))
125  {
126  pastix_print_error( "pastixOrderCheck: invalid permutation arrays" );
128  }
129  }
130 
131  /*
132  * Check the treetab
133  */
134  cblkmax = ordeptr->cblknbr - baseval;
135  for (rangnum = 0; rangnum < ordeptr->cblknbr-1; rangnum ++)
136  {
137  if ((ordeptr->treetab[rangnum] > cblkmax ) ||
138  ((ordeptr->treetab[rangnum] != -1) &&
139  (ordeptr->treetab[rangnum] < (baseval+rangnum)) ) )
140  {
141  pastix_print_error( "pastixOrderCheck: invalid range array in treetab" );
143  }
144  }
145  if ((rangnum > 0) && (ordeptr->treetab[rangnum] != (baseval-1)))
146  {
147  pastix_print_error( "pastixOrderCheck: invalid father for cblknbr-1 node" );
149  }
150 
151  return PASTIX_SUCCESS;
152 }
pastix_order_s::cblknbr
pastix_int_t cblknbr
Definition: order.h:48
pastix_order_s::peritab
pastix_int_t * peritab
Definition: order.h:50
pastix_order_s::permtab
pastix_int_t * permtab
Definition: order.h:49
pastix_order_s::treetab
pastix_int_t * treetab
Definition: order.h:52
pastix_order_s
Order structure.
Definition: order.h:45
pastix_order_s::vertnbr
pastix_int_t vertnbr
Definition: order.h:47
pastixOrderCheck
int pastixOrderCheck(const pastix_order_t *ordeptr)
This routine checks the correctness of the ordering structure.
Definition: order_check.c:39
PASTIX_SUCCESS
@ PASTIX_SUCCESS
Definition: api.h:346
pastix_order_s::baseval
pastix_int_t baseval
Definition: order.h:46
pastix_order_s::rangtab
pastix_int_t * rangtab
Definition: order.h:51
PASTIX_ERR_BADPARAMETER
@ PASTIX_ERR_BADPARAMETER
Definition: api.h:353