PaStiX Handbook  6.3.2
solver_check.c
Go to the documentation of this file.
1 /**
2  *
3  * @file solver_check.c
4  *
5  * PaStiX check function fo rthe solver structure.
6  *
7  * @copyright 2004-2023 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8  * Univ. Bordeaux. All rights reserved.
9  *
10  * @version 6.3.2
11  * @author Pascal Henon
12  * @author Mathieu Faverge
13  * @author Tony Delarue
14  * @date 2023-07-21
15  *
16  **/
17 #include <stdio.h>
18 #include <assert.h>
19 
20 #include "common.h"
21 #include "symbol/symbol.h"
22 #include "queue.h"
23 #include "blend/solver.h"
24 #include "elimintree.h"
25 #include "cost.h"
26 #include "cand.h"
27 #include "extendVector.h"
28 #include "blendctrl.h"
29 #include "simu.h"
30 #include "pastix_zcores.h"
31 #include "pastix_ccores.h"
32 #include "pastix_dcores.h"
33 #include "pastix_scores.h"
34 
35 /**
36  *******************************************************************************
37  *
38  * @ingroup blend_dev_solver
39  *
40  * @brief Checks the consistency of the given solver matrix structure.
41  *
42  *******************************************************************************
43  *
44  * @param[in] solvmtx
45  * The solver matrix structure to check.
46  *
47  *******************************************************************************
48  *
49  * @retval 0 if the structure is correct
50  * @retval 1 if incorrect
51  *
52  *******************************************************************************/
53 int
54 solverCheck( const SolverMatrix *solvmtx )
55 {
56  int i, j, browtype, cblktype;
57  SolverBlok *blok, *fblok;
58  SolverCblk *cblk, *fcblk;
59  pastix_int_t bloknum;
60 
61  assert( (solvmtx->cblknbr - solvmtx->recvnbr - solvmtx->faninnbr ) <= solvmtx->gcblknbr );
62 
63  cblk = solvmtx->cblktab;
64 
65  for ( i = 0; i < solvmtx->cblknbr; i++, cblk++ ) {
66  /* Make sure the lock is initialized correctly */
67  assert( cblk->lock == PASTIX_ATOMIC_UNLOCKED );
68 
69  /* Check dimensions */
70  assert( cblk->fcolnum <= cblk->lcolnum );
71  assert( cblk->stride >= cblk_colnbr( cblk ) );
72 
73  /* Check the range of value for the ownerid */
74  assert( (cblk->ownerid >= 0) && (cblk->ownerid < solvmtx->clustnbr) );
75  assert( (cblk->threadid >= -1) && (cblk->threadid < solvmtx->thrdnbr ) );
76 
77  /* Check that pointers have been initialized to null */
78  assert( cblk->lcoeftab == NULL );
79  assert( cblk->ucoeftab == NULL );
80 
81  /* Check that we have at least one block */
82  assert( (cblk[1].fblokptr - cblk[0].fblokptr) >= 1 );
83 
84  fblok = cblk->fblokptr;
85  fcblk = solvmtx->cblktab + fblok->fcblknm;
86 
87  if ( cblk->cblktype & CBLK_RECV ) {
88  /*
89  * Check the redundancy of information, the facing cblk of the first
90  * block should match the index of the local cblk which refers to
91  * the local non recv version of this cblk.
92  */
93  assert( fcblk->lcolidx <= cblk->lcolidx );
94  assert( fcblk->sndeidx == cblk->sndeidx );
95  assert( fcblk->gcblknum == cblk->gcblknum );
96  assert( fcblk->fblokptr->lcblknm == fblok->fcblknm );
97  assert( i < fcblk->fblokptr->lcblknm );
98 
99  /* It has to be remote */
100  assert( cblk->ownerid != solvmtx->clustnum );
101 
102  /* No index in the bcsctab */
103  assert( cblk->bcscnum < 0 );
104 
105  /* It has to be included in the destination */
106  assert( cblk->fcolnum >= fcblk->fcolnum );
107  assert( cblk->lcolnum <= fcblk->lcolnum );
108 
109  /* It has no input contributions */
110  assert( ( cblk[0].brownum == cblk[0].brown2d ) &&
111  ( cblk[0].brown2d == cblk[1].brownum ) );
112 
113  /* Check that reception blocks are included within local reception blocks */
114  {
115  SolverBlok *rblok;
116  blok = fblok;
117  rblok = fcblk->fblokptr;
118  for ( ; blok < cblk[1].fblokptr; blok++ ) {
119  while( !is_block_inside_fblock( blok, rblok ) ) {
120  rblok++;
121  assert( rblok->lcblknm == (fcblk - solvmtx->cblktab) );
122  }
123  }
124  assert( rblok->lcblknm == (fcblk - solvmtx->cblktab) );
125  }
126  }
127  else {
128  /* It has to be included in the destination */
129  assert( cblk[0].lcolnum < cblk[1].fcolnum );
130 
131  /* Check that we have none or some contributions */
132  assert( cblk[1].brownum >= cblk[0].brownum );
133  assert( ( cblk[0].brownum <= cblk[0].brown2d ) &&
134  ( cblk[0].brown2d <= cblk[1].brownum ) );
135 
136  /* First diagonal block should not appear in the browtab */
137  assert( fblok->browind == -1 );
138 
139  if ( cblk->cblktype & CBLK_FANIN ) {
140  assert( cblk->bcscnum < 0 );
141 
142  /* It has to be remote */
143  assert( cblk->ownerid != solvmtx->clustnum );
144 
145  /* Fanin targets do not contribute locally so we don't know the target */
146  assert( fblok->fcblknm == -1 );
147  assert( cblk->lcolidx == -1 );
148  }
149  else {
150  /* Check that first diagonal block belongs to ourself */
151  assert( fblok->fcblknm == fblok->lcblknm );
152 
153  assert( cblk->bcscnum >= 0 );
154 
155  /* It has to be local */
156  assert( (solvmtx->gcbl2loc == NULL) ||
157  (cblk->ownerid == solvmtx->clustnum) );
158 
159  /* Check if possible that the right hand side index are in increasing order */
160  assert( (cblk[1].cblktype & CBLK_FANIN) ||
161  (!(cblk[1].cblktype & CBLK_FANIN) && (cblk[0].lcolidx < cblk[1].lcolidx)) );
162  }
163  }
164 
165  /* Check bloks in the current cblk */
166  blok = fblok;
167  for ( ; blok < cblk[1].fblokptr; blok++ ) {
168  assert( blok->lcblknm == i );
169  assert( blok->frownum <= blok->lrownum );
170 
171  /* Next block in the same cblk must be after */
172  assert( (blok[1].lcblknm != blok[0].lcblknm) ||
173  ((blok[1].lcblknm == blok[0].lcblknm) && (blok[0].lrownum < blok[1].frownum)) );
174 
175  if ( cblk->cblktype & CBLK_FANIN ) {
176  assert( blok->fcblknm == -1 );
177  }
178  else if ( cblk->cblktype & CBLK_RECV ) {
179  if ( blok == cblk->fblokptr ) {
180  assert( blok->fcblknm != -1 );
181  assert( blok->browind != -1 );
182  assert( blok->lcblknm < blok->fcblknm );
183  }
184  else {
185  assert( blok->fcblknm == -1 );
186  assert( blok->browind == -1 );
187  }
188  }
189  else {
190  fcblk = solvmtx->cblktab + blok->fcblknm;
191  fblok = fcblk->fblokptr;
192 
193  assert( ((blok == cblk->fblokptr) && (blok->lcblknm == blok->fcblknm)) ||
194  (blok->lcblknm < blok->fcblknm) );
195  assert( blok->frownum >= fblok->frownum );
196  assert( blok->lrownum <= fblok->lrownum );
197 
198  (void)fblok;
199  }
200  }
201 
202  /* Check previous bloks in row */
203  browtype = 0;
204  cblktype = 0;
205  for ( j = cblk[0].brownum; j < cblk[1].brownum; j++ ) {
206  bloknum = solvmtx->browtab[j];
207  blok = solvmtx->bloktab + bloknum;
208  fcblk = solvmtx->cblktab + blok->lcblknm;
209 
210  assert( blok->browind == j );
211  assert( blok->fcblknm == i );
212 
213  /* Blocks in Fanin sould never appear in the browtab */
214  assert( !(fcblk->cblktype & CBLK_FANIN) );
215 
216  /* The contribution comes from a RECV cblk */
217  if ( fcblk->cblktype & CBLK_RECV ) {
218  assert( fcblk->ownerid != solvmtx->clustnum );
219 
220  /* It can come only from the diagonal block */
221  assert( blok == fcblk->fblokptr );
222  }
223  else {
224  assert( (solvmtx->gcbl2loc == NULL) || (fcblk->ownerid == solvmtx->clustnum) );
225  }
226 
227  /* Check that the brow is sorted correctly (1D, 2D, RECV) */
228  cblktype = fcblk->cblktype & ( CBLK_TASKS_2D | CBLK_RECV );
229  assert( cblktype >= browtype );
230  browtype = browtype | cblktype; /* Take the max for the next step */
231  }
232  }
233 
234  return 0;
235 }
236 
BEGIN_C_DECLS typedef int pastix_int_t
Definition: datatypes.h:51
int solverCheck(const SolverMatrix *solvmtx)
Checks the consistency of the given solver matrix structure.
Definition: solver_check.c:54
pastix_int_t browind
Definition: solver.h:145
void * ucoeftab
Definition: solver.h:172
pastix_int_t lrownum
Definition: solver.h:143
pastix_int_t gcblknbr
Definition: solver.h:207
pastix_int_t brownum
Definition: solver.h:166
static pastix_int_t cblk_colnbr(const SolverCblk *cblk)
Compute the number of columns in a column block.
Definition: solver.h:324
pastix_int_t fcblknm
Definition: solver.h:140
static int is_block_inside_fblock(const SolverBlok *blok, const SolverBlok *fblok)
Check if a block is included inside another one.
Definition: solver.h:499
pastix_int_t sndeidx
Definition: solver.h:168
pastix_int_t cblknbr
Definition: solver.h:208
pastix_int_t * gcbl2loc
Definition: solver.h:228
SolverBlok *restrict bloktab
Definition: solver.h:223
pastix_int_t frownum
Definition: solver.h:142
pastix_int_t faninnbr
Definition: solver.h:209
pastix_atomic_lock_t lock
Definition: solver.h:157
SolverBlok * fblokptr
Definition: solver.h:163
pastix_int_t recvnbr
Definition: solver.h:212
pastix_int_t *restrict browtab
Definition: solver.h:224
pastix_int_t lcblknm
Definition: solver.h:139
pastix_int_t gcblknum
Definition: solver.h:169
int threadid
Definition: solver.h:176
pastix_int_t lcolidx
Definition: solver.h:165
pastix_int_t bcscnum
Definition: solver.h:170
SolverCblk *restrict cblktab
Definition: solver.h:222
pastix_int_t stride
Definition: solver.h:164
int8_t cblktype
Definition: solver.h:159
int ownerid
Definition: solver.h:175
pastix_int_t lcolnum
Definition: solver.h:162
void * lcoeftab
Definition: solver.h:171
pastix_int_t fcolnum
Definition: solver.h:161
Solver block structure.
Definition: solver.h:137
Solver column block structure.
Definition: solver.h:156
Solver column block structure.
Definition: solver.h:200