PaStiX Handbook 6.4.0
Loading...
Searching...
No Matches
extracblk.c
Go to the documentation of this file.
1/**
2 *
3 * @file extracblk.c
4 *
5 * PaStiX analyse headers for extra symbolic structure functions.
6 *
7 * @copyright 1998-2025 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8 * Univ. Bordeaux. All rights reserved.
9 *
10 * @version 6.4.0
11 * @author Mathieu Faverge
12 * @author Gregoire Pichon
13 * @date 2024-07-05
14 *
15 * @addtogroup blend_dev_split
16 * @{
17 *
18 **/
19#include "common.h"
20#include "symbol/symbol.h"
21#include "cost.h"
22#include "elimintree.h"
23#include "cand.h"
24#include "extracblk.h"
25
26/**
27 *******************************************************************************
28 *
29 * @brief Allocate the extracblk structure.
30 *
31 *******************************************************************************
32 *
33 * @param[inout] extracblk
34 * Allocate memory space to store extra cblk when they are created. The
35 * initial number is the one given at extraCblkInit().
36 *
37 *******************************************************************************/
38static inline void
40{
42
43 MALLOC_INTERN( extracblk->sptcblk, extracblk->cblknbr, pastix_int_t );
44 MALLOC_INTERN( extracblk->sptcbnb, extracblk->cblknbr, pastix_int_t );
45
46 /*
47 * Unsplitted cblk will keep sptcblk to -1 and sptcbnb to 1
48 * Splitted cblk will have sptcbnb to the number of cblk replacing the original one,
49 * and sptcblk will contain the cblktab index of the first generated cblk
50 */
51 for(i=0; i<extracblk->cblknbr;i++)
52 {
53 extracblk->sptcblk[i] = -1;
54 extracblk->sptcbnb[i] = 1;
55 }
56
57 /* We choose an arbitrary size for initial allocation of bloktab and cblktab (5%) */
58 extracblk->sizcblk = ( extracblk->cblknbr + 20 ) / 20;
59 MALLOC_INTERN( extracblk->cblktab, extracblk->cblknbr, symbol_cblk_t );
60
61 return;
62}
63
64/**
65 *******************************************************************************
66 *
67 * @brief Increment the number of extra cblk that can be stored.
68 *
69 * If there is not enough space, the structure is reallocated to a larger space.
70 *
71 *******************************************************************************
72 *
73 * @param[inout] extracblk
74 * Allocate memory space to store extra cblk when they are created. The
75 * initial number is the one given at extraCblkInit().
76 *
77 *******************************************************************************
78 *
79 * @return the current index for the next cblk added to the structure.
80 *
81 *******************************************************************************/
82static inline pastix_int_t
84{
85 /* First cblk added */
86 if ( extracblk->sizcblk == 0 ) {
87 extraCblkAlloc( extracblk );
88 }
89
90 extracblk->curcblk++;
91
92 /* Check that we have enough space and make it bigger if required */
93 if( extracblk->curcblk >= extracblk->sizcblk )
94 {
95 /* Add 5% of original cblknbr to the cblktab */
96 pastix_int_t extrasize = (extracblk->cblknbr + 20 ) / 20;
97 symbol_cblk_t *tmp;
98
99 assert( extracblk->curcblk == extracblk->sizcblk);
100 tmp = extracblk->cblktab;
101 extracblk->sizcblk += extrasize;
102
103 MALLOC_INTERN( extracblk->cblktab, extracblk->sizcblk, symbol_cblk_t );
104 memcpy(extracblk->cblktab, tmp, sizeof(symbol_cblk_t)*extracblk->curcblk);
105
106 memFree_null(tmp);
107 }
108
109 return extracblk->curcblk;
110}
111
112/**
113 *******************************************************************************
114 *
115 * @brief Initialize the extracblk structure.
116 *
117 *******************************************************************************
118 *
119 * @param[in] cblknbr
120 * The starting number of cblk that the structure can hold.
121 *
122 * @param[inout] extracblk
123 * Pointer to the allocated extracblk structure to initialize.
124 *
125 *******************************************************************************/
126void
128 ExtraCblk_t *extracblk )
129{
130 extracblk->cblknbr = cblknbr;
131 extracblk->addcblk = 0;
132 extracblk->addblok = 0;
133 extracblk->addblof = 0;
134 extracblk->sptcblk = NULL;
135 extracblk->sptcbnb = NULL;
136 extracblk->curcblk = -1;
137 extracblk->sizcblk = 0;
138 extracblk->cblktab = NULL;
139 return;
140}
141
142/**
143 *******************************************************************************
144 *
145 * @brief Free the extracblk structure.
146 *
147 *******************************************************************************
148 *
149 * @param[inout] extracblk
150 * Pointer to the allocated extracblk structure to free.
151 *
152 *******************************************************************************/
153void
155{
156 if ( extracblk->sizcblk > 0 ) {
157 memFree_null( extracblk->sptcblk );
158 memFree_null( extracblk->sptcbnb );
159 memFree_null( extracblk->cblktab );
160 }
161 extracblk->curcblk = -1;
162 extracblk->sizcblk = 0;
163 return;
164}
165
166/**
167 *******************************************************************************
168 *
169 * @brief Add a new additional cblk defined by its first and last columns.
170 *
171 *******************************************************************************
172 *
173 * @param[inout] extracblk
174 * Pointer to the extracblk structure to add the cblk.
175 *
176 * @param[in] fcolnum
177 * Index of the first column in the new cblk.
178 *
179 * @param[in] lcolnum
180 * Index of the last column in the new cblk.
181 *
182 * @param[in] selevtx
183 * TODO
184 *
185 *******************************************************************************/
186void
188 pastix_int_t fcolnum,
189 pastix_int_t lcolnum,
190 int8_t selevtx )
191{
192 pastix_int_t curcblk = extraCblkInc( extracblk );
193
194 extracblk->cblktab[ curcblk ].fcolnum = fcolnum;
195 extracblk->cblktab[ curcblk ].lcolnum = lcolnum;
196 extracblk->cblktab[ curcblk ].bloknum = -1;
197 extracblk->cblktab[ curcblk ].selevtx = selevtx;
198}
199
200/**
201 *******************************************************************************
202 *
203 * @brief Merge the existing symbol structure with the additional information
204 * from the extracblk structure.
205 *
206 *******************************************************************************
207 *
208 * @param[in] extracblk
209 * Pointer to the extracblk structure that contains information about
210 * splited cblk.
211 *
212 * @param[inout] newsymb
213 * Symbol matrix to update. On exit, the symbol matrix structure is
214 * extended by the splited cblk described in extracblk structure.
215 *
216 * @param[inout] candtab
217 * On entry, the candtab aray associated to the input symbol matrix.
218 * On exit, the updated candtab array with the extended number of cblk.
219 *
220 *******************************************************************************/
221void
222extraCblkMerge( const ExtraCblk_t *extracblk,
223 symbol_matrix_t *newsymb,
224 Cand **candtab )
225{
226 pastix_int_t i, j, k, l;
227 pastix_int_t curbloknum, curcblknum;
228 pastix_int_t lastcblksplit;
229 pastix_int_t addblok = 0;
230 pastix_int_t *newnum = NULL;
231 pastix_int_t *extranewnum = NULL;
232
233 symbol_matrix_t *oldsymb;
234
235#if defined(PASTIX_BLEND_PROPMAP_2STEPS)
236 Cand *oldcand = *candtab;
237 Cand *newcand;
238#else
239 (void)candtab;
240#endif
241
242 symbol_cblk_t *curcblk;
243 symbol_blok_t *curblok;
244
245 /* No splitted cblk: partition remains the same */
246 if( extracblk->addcblk == 0 ) {
247 return;
248 }
249
250 /* Backup the old symbol */
251 MALLOC_INTERN(oldsymb, 1, symbol_matrix_t);
252 memcpy( oldsymb, newsymb, sizeof(symbol_matrix_t) );
253
254 /* Allocate new cblktab */
255 newsymb->cblknbr = oldsymb->cblknbr + extracblk->addcblk;
256 MALLOC_INTERN(newsymb->cblktab, newsymb->cblknbr+1, symbol_cblk_t);
257
258 newsymb->browtab = NULL;
259
260#if defined(PASTIX_BLEND_PROPMAP_2STEPS)
261 /* Allocate new candtab */
262 newcand = candInit( newsymb->cblknbr );
263
264 /* Copy the root cand */
265 newcand[-1] = oldcand[-1];
266#endif
267
268 /*
269 * We use the sptcbnb array to get the new numbering of the former cblk
270 * in the new symbolic matrix
271 * newnum[i+1] becomes the new number of the first cblk generated from the
272 * split of former cblk number i.
273 */
274 MALLOC_INTERN(newnum, oldsymb->cblknbr+1, pastix_int_t);
275 MALLOC_INTERN(extranewnum, extracblk->curcblk+1, pastix_int_t);
276 newnum[0] = 0;
277 memcpy(newnum+1, extracblk->sptcbnb, (oldsymb->cblknbr) * sizeof(pastix_int_t));
278#ifndef NDEBUG
279 memset(extranewnum, 0xff, (extracblk->curcblk+1) * sizeof(pastix_int_t));
280#endif
281
282 /* Compute number of blocks that will be generated,
283 * and copy main information of cblktab and candtab */
284 lastcblksplit = -1;
285 for(i=0; i<oldsymb->cblknbr; i++)
286 {
287 pastix_int_t fbloknum = oldsymb->cblktab[i ].bloknum;
288 pastix_int_t lbloknum = oldsymb->cblktab[i+1].bloknum;
289 pastix_int_t sptcbnbw = extracblk->sptcbnb[i];
290
291 /*
292 * First we compute the number of extra blocks that will be generated
293 */
294
295 /* Diagonal block */
296 addblok += (((sptcbnbw+1) * sptcbnbw) / 2) - 1;
297 for(j=fbloknum+1; j<lbloknum; j++)
298 {
299 pastix_int_t fcblknum = oldsymb->bloktab[j].fcblknm;
300 pastix_int_t sptfcbnb = extracblk->sptcbnb[fcblknum];
301 pastix_int_t sptcbnbh = 0;
302
303 /* If facing cblk is splitted */
304 if ( sptfcbnb > 1 )
305 {
306 symbol_cblk_t *newfcblk = &(extracblk->cblktab[ extracblk->sptcblk[fcblknum] ]);
307 pastix_int_t frownum = oldsymb->bloktab[j].frownum;
308 pastix_int_t lrownum = oldsymb->bloktab[j].lrownum;
309
310 /* Compute how many times the block is splitted horizontally */
311 for(k = 0; k < sptfcbnb; k++, newfcblk++)
312 {
313 /* This block doesn't face this new cblk */
314 if ( frownum > newfcblk->lcolnum ) {
315 continue;
316 }
317
318 /* No more facing cblk will be found */
319 if ( lrownum < newfcblk->fcolnum ) {
320 break;
321 }
322
323 assert( frownum <= lrownum );
324 sptcbnbh++;
325 frownum = newfcblk->lcolnum+1;
326 }
327 }
328 else
329 sptcbnbh = 1;
330
331 /*
332 * The number of extra blocks is the number of times the block
333 * is psplitted horizontally times the number of time the cblk
334 * is splitted vertically minu itself
335 */
336 addblok += sptcbnbw * sptcbnbh - 1;
337 }
338
339 /*
340 * Second, we create newnum/extranewnum arrays and copy information into
341 * cblktab and candtab
342 */
343 {
344 /* This cblk is splitted, we generate new cblktab from extra */
345 pastix_int_t newcblknum = newnum[i];
346 if (sptcbnbw > 1) {
347 pastix_int_t nbcblk2copy = (i - lastcblksplit - 1);
348 pastix_int_t sptcblk = extracblk->sptcblk[i];
349
350 /* Copy the previous unchanged cblks from oldsymb */
351 if ( nbcblk2copy > 0 ) {
352 lastcblksplit++;
353 memcpy( newsymb->cblktab + newnum[ lastcblksplit ],
354 oldsymb->cblktab + lastcblksplit,
355 nbcblk2copy * sizeof(symbol_cblk_t) );
356
357#if defined(PASTIX_BLEND_PROPMAP_2STEPS)
358 memcpy( newcand + newnum[ lastcblksplit ],
359 oldcand + lastcblksplit,
360 nbcblk2copy * sizeof(Cand) );
361#endif
362 }
363
364 /* Copy the new cblk from extracblk */
365 assert( (sptcblk >= 0) && (sptcblk <= extracblk->curcblk) );
366 memcpy( newsymb->cblktab + newcblknum,
367 extracblk->cblktab + sptcblk,
368 sptcbnbw * sizeof(symbol_cblk_t) );
369
370 /* Initialize extranewnum and duplicate the cand for each new cblk */
371 for(j=0; j<sptcbnbw; j++, sptcblk++) {
372 extranewnum[sptcblk] = newcblknum+j;
373
374 assert( (extranewnum[sptcblk] >= 0) &&
375 (extranewnum[sptcblk] < newsymb->cblknbr) );
376
377#if defined(PASTIX_BLEND_PROPMAP_2STEPS)
378 memcpy( newcand + extranewnum[ sptcblk ],
379 oldcand + i, sizeof(Cand) );
380#endif
381 }
382
383 lastcblksplit = i;
384 }
385 /* Update newnum of following cblk (newnum is allocated with one extra space) */
386 newnum[i+1] += newcblknum;
387 }
388 }
389
390 /* Copy last unsplitted block */
391 if ( lastcblksplit < (oldsymb->cblknbr-1) )
392 {
393 pastix_int_t nbcblk2copy = oldsymb->cblknbr - lastcblksplit - 1;
394 lastcblksplit++;
395 memcpy( newsymb->cblktab + newnum[ lastcblksplit ],
396 oldsymb->cblktab + lastcblksplit,
397 nbcblk2copy * sizeof(symbol_cblk_t) );
398
399#if defined(PASTIX_BLEND_PROPMAP_2STEPS)
400 memcpy( newcand + newnum[ lastcblksplit ],
401 oldcand + lastcblksplit,
402 nbcblk2copy * sizeof(Cand) );
403#endif
404 }
405
406#if defined(PASTIX_BLEND_PROPMAP_2STEPS)
407 candExit(oldcand);
408 *candtab = newcand;
409#endif
410
411 /* Allocate new bloktab */
412 newsymb->bloknbr = oldsymb->bloknbr + addblok;
413 MALLOC_INTERN(newsymb->bloktab, newsymb->bloknbr, symbol_blok_t);
414
415 /* Fill in the new symbolic matrix resulting from the splitting of the former one */
416 curbloknum = 0;
417 curcblknum = 0;
418 curcblk = newsymb->cblktab;
419 curblok = newsymb->bloktab;
420
421#if defined(PASTIX_SYMBOL_DUMP_SYMBMTX)
422 symbol_cblk_t *cblk = newsymb->cblktab;
423#endif
424 for(i=0; i<oldsymb->cblknbr; i++)
425 {
426 pastix_int_t fbloknum = oldsymb->cblktab[i ].bloknum;
427 pastix_int_t lbloknum = oldsymb->cblktab[i+1].bloknum;
428 pastix_int_t sptcbnbw = extracblk->sptcbnb[i];
429
430 /* For each new column created by the cblk split */
431 for(j=0; j<sptcbnbw; j++, curcblknum++, curcblk++)
432 {
433 /* Store diagonal bloknum */
434 curcblk->bloknum = curbloknum;
435
436#if defined(PASTIX_SYMBOL_DUMP_SYMBMTX)
437 cblk->split_cblk = sptcbnbw-j-1;
438 cblk++;
439#endif
440
441 /* Create odb due to the splitting of the diag blok */
442 for(k=0; k<(sptcbnbw-j); k++, curbloknum++, curblok++)
443 {
444 curblok->frownum = curcblk[k].fcolnum;
445 curblok->lrownum = curcblk[k].lcolnum;
446 curblok->lcblknm = curcblknum;
447 curblok->fcblknm = curcblknum + k;
448 }
449 /* Next cblk will have one block less on the diagonal */
450
451 /* Create other off diagonal blocks */
452 for(k=fbloknum+1; k<lbloknum; k++)
453 {
454 pastix_int_t frownum = oldsymb->bloktab[k].frownum;
455 pastix_int_t lrownum = oldsymb->bloktab[k].lrownum;
456 pastix_int_t fcblknum = oldsymb->bloktab[k].fcblknm;
457 pastix_int_t sptfcblk = extracblk->sptcblk[fcblknum];
458 pastix_int_t sptfcbnb = extracblk->sptcbnb[fcblknum];
459
460 /* If facing cblk is splitted */
461 if ( sptfcbnb > 1 )
462 {
463 pastix_int_t newfcblknum = extranewnum[ sptfcblk ];
464 symbol_cblk_t *newfcblk = &(extracblk->cblktab[ sptfcblk ]);
465
466 assert( newfcblknum != -1 );
467 assert( newfcblk != NULL );
468
469 /* Create new blocks facing this cblk */
470 for(l=0; l<sptfcbnb; l++, newfcblk++)
471 {
472 /* This block doesn't face this new cblk */
473 if ( frownum > newfcblk->lcolnum ) {
474 continue;
475 }
476
477 /* No more facing cblk will be found */
478 if ( lrownum < newfcblk->fcolnum ) {
479 break;
480 }
481
482 assert( frownum <= lrownum );
483 assert( frownum >= newfcblk->fcolnum );
484
485 curblok->frownum = frownum;
486 curblok->lrownum = pastix_imin( lrownum, newfcblk->lcolnum );
487 curblok->lcblknm = curcblknum;
488 curblok->fcblknm = newfcblknum + l;
489 curblok++; curbloknum++;
490
491 frownum = newfcblk->lcolnum+1;
492 }
493 }
494 else
495 {
496 curblok->frownum = frownum;
497 curblok->lrownum = lrownum;
498 curblok->lcblknm = curcblknum;
499 curblok->fcblknm = newnum[fcblknum];
500 curblok++; curbloknum++;
501 }
502 }
503 }
504 }
505
506 assert(curcblknum == newsymb->cblknbr);
507 assert(curbloknum == newsymb->bloknbr);
508 assert((curcblk - newsymb->cblktab) == newsymb->cblknbr);
509 assert((curblok - newsymb->bloktab) == newsymb->bloknbr);
510
511 /* Free old versions and temporary buffer */
512 pastixSymbolExit(oldsymb);
513 memFree_null(oldsymb);
514 memFree_null(newnum);
515 memFree_null(extranewnum);
516
517 /* Virtual cblk to avoid side effect in the loops on cblk bloks */
518 curcblk[0].fcolnum = curcblk[-1].lcolnum + 1;
519 curcblk[0].lcolnum = curcblk[-1].lcolnum + 1;
520 curcblk[0].bloknum = curbloknum;
521
522 pastixSymbolBuildRowtab( newsymb );
523
524 return;
525}
526
527/**
528 *@}
529 */
BEGIN_C_DECLS typedef int pastix_int_t
Definition datatypes.h:51
Cand * candInit(pastix_int_t cblknbr)
Initialize the candtab array with default values.
Definition cand.c:48
void candExit(Cand *candtab)
Exit and free the candtab structure given.
Definition cand.c:83
Processor candidate group to own a column blok.
Definition cand.h:28
pastix_int_t sizcblk
Definition extracblk.h:35
pastix_int_t addblok
Definition extracblk.h:30
pastix_int_t cblknbr
Definition extracblk.h:28
pastix_int_t addcblk
Definition extracblk.h:29
pastix_int_t addblof
Definition extracblk.h:31
symbol_cblk_t * cblktab
Definition extracblk.h:36
pastix_int_t curcblk
Definition extracblk.h:34
pastix_int_t * sptcbnb
Definition extracblk.h:33
pastix_int_t * sptcblk
Definition extracblk.h:32
void extraCblkAdd(ExtraCblk_t *extracblk, pastix_int_t fcolnum, pastix_int_t lcolnum, int8_t selevtx)
Add a new additional cblk defined by its first and last columns.
Definition extracblk.c:187
static pastix_int_t extraCblkInc(ExtraCblk_t *extracblk)
Increment the number of extra cblk that can be stored.
Definition extracblk.c:83
void extraCblkExit(ExtraCblk_t *extracblk)
Free the extracblk structure.
Definition extracblk.c:154
void extraCblkMerge(const ExtraCblk_t *extracblk, symbol_matrix_t *newsymb, Cand **candtab)
Merge the existing symbol structure with the additional information from the extracblk structure.
Definition extracblk.c:222
void extraCblkInit(pastix_int_t cblknbr, ExtraCblk_t *extracblk)
Initialize the extracblk structure.
Definition extracblk.c:127
static void extraCblkAlloc(ExtraCblk_t *extracblk)
Allocate the extracblk structure.
Definition extracblk.c:39
Extra symbol cblk structure.
Definition extracblk.h:27
pastix_int_t fcblknm
Definition symbol.h:63
pastix_int_t frownum
Definition symbol.h:60
pastix_int_t lrownum
Definition symbol.h:61
pastix_int_t bloknbr
Definition symbol.h:80
pastix_int_t * browtab
Definition symbol.h:85
symbol_cblk_t * cblktab
Definition symbol.h:83
pastix_int_t bloknum
Definition symbol.h:48
pastix_int_t fcolnum
Definition symbol.h:46
pastix_int_t lcolnum
Definition symbol.h:47
symbol_blok_t * bloktab
Definition symbol.h:84
pastix_int_t lcblknm
Definition symbol.h:62
pastix_int_t cblknbr
Definition symbol.h:79
void pastixSymbolBuildRowtab(symbol_matrix_t *symbptr)
Construct the browtab array that stores the blocks in a CSR way.
Definition symbol.c:302
void pastixSymbolExit(symbol_matrix_t *symbptr)
Free the content of symbolic matrix.
Definition symbol.c:137
Symbol block structure.
Definition symbol.h:59
Symbol column block structure.
Definition symbol.h:45
Symbol matrix structure.
Definition symbol.h:77