PaStiX Handbook 6.4.0
Loading...
Searching...
No Matches
solver_matrix_gen_utils.c
Go to the documentation of this file.
1/**
2 *
3 * @file solver_matrix_gen_utils.c
4 *
5 * PaStiX solver structure generation functions to factorize
6 * solver_matric_gen.c .
7 *
8 * @copyright 1998-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
9 * Univ. Bordeaux. All rights reserved.
10 *
11 * @version 6.4.0
12 * @author Tony Delarue
13 * @author Pascal Henon
14 * @author Pierre Ramet
15 * @author Xavier Lacoste
16 * @author Mathieu Faverge
17 * @author Alycia Lisito
18 * @author Nolan Bredel
19 * @date 2024-07-05
20 *
21 * @addtogroup blend_dev_solver
22 * @{
23 *
24 **/
25#include "common.h"
26#include "symbol/symbol.h"
27#include "blend/solver.h"
28#include "elimintree.h"
29#include "cost.h"
30#include "cand.h"
31#include "pastix/order.h"
32#include "extendVector.h"
33#include "simu.h"
35
36/**
37 *******************************************************************************
38 *
39 * @brief Fill the local numbering arrays to compress the symbol information
40 * into solver.
41 *
42 *******************************************************************************
43 *
44 * @param[in] symbmtx
45 * The pointer to the symbol matrix structure.
46 *
47 * @param[in] simuctrl
48 * The pointer to the simuctrl structure.
49 *
50 * @param[inout] solvmtx
51 * Pointer to the solver matrix.
52 *
53 * @param[inout] cblklocalnum
54 * Local cblk infos.
55 *
56 * @param[inout] bloklocalnum
57 * Local blok infos.
58 *
59 * @param[inout] tasklocalnum
60 * Local tasks infos.
61 *
62 * @param[inout] ftgttab
63 * Array of fan-in to store the lists of recv/fanin cblk per local cblk.
64 *
65 *******************************************************************************/
66void
68 const SimuCtrl *simuctrl,
69 SolverMatrix *solvmtx,
70 pastix_int_t *cblklocalnum,
71 pastix_int_t *bloklocalnum,
72 pastix_int_t *tasklocalnum,
73 solver_cblk_recv_t **ftgttab,
74 pastix_int_t *faninnbr_tab )
75{
76 pastix_int_t *localindex;
77 symbol_cblk_t *symbcblk;
78 symbol_blok_t *symbblok;
79 pastix_int_t cblknum, brownum, brownbr;
80 pastix_int_t faninnbr, recvnbr, faninbloknbr;
81 pastix_int_t i, j, k, c, fc;
82 pastix_int_t flaglocal;
83 pastix_int_t clustnum = solvmtx->clustnum;
84 pastix_int_t clustnbr = solvmtx->clustnbr;
85
86 /* Initialize the set of cluster candidates for each cblk */
87 MALLOC_INTERN( localindex, clustnbr, pastix_int_t );
88
89 /*
90 * Compute local number of tasks on each cluster
91 */
92 memset( localindex, 0, clustnbr * sizeof(pastix_int_t) );
93 for ( i = 0; i < simuctrl->tasknbr; i++ ) {
94 c = simuctrl->bloktab[ simuctrl->tasktab[i].bloknum ].ownerclust;
95
96 tasklocalnum[i] = localindex[c];
97 localindex[c]++;
98 }
99 solvmtx->tasknbr = localindex[clustnum];
100
101 /*
102 * Compute the local numbering of the fan-in and recv cblks on each cluster
103 */
104 /* Reset the array to compute local informations */
105 memset( localindex, 0, clustnbr * sizeof( pastix_int_t ) );
106
107 cblknum = 0;
108 brownum = 0;
109 recvnbr = 0;
110 faninnbr = 0;
111 faninbloknbr = 0;
112 symbcblk = symbmtx->cblktab;
113 for ( i = 0; i < symbmtx->cblknbr; i++, symbcblk++ ) {
114 brownbr = symbcblk[1].brownum - symbcblk[0].brownum;
115
116 /*
117 * The cblk is considered local if data are local, or if we store a
118 * compressed copy for fanin
119 */
120 flaglocal = ( simuctrl->cblktab[i].owned ) || ( ftgttab[i] != NULL );
121 if ( !flaglocal ) {
122 cblklocalnum[i] = -i - 1;
123#if !defined(NDEBUG)
124 for ( j=symbcblk[0].bloknum; j<symbcblk[1].bloknum; j++ ) {
125 bloklocalnum[j] = -1;
126 assert( simuctrl->bloktab[j].ownerclust != clustnum );
127 }
128#endif
129 continue;
130 }
131
132 /*
133 * The cblk is local.
134 */
135 if ( simuctrl->cblktab[i].owned ) {
136 solver_cblk_recv_t *ftgtcblk;
137
138 /*
139 * The cblk is local. We may receive remote information, let's:
140 * - compute the size of the compressed browtab
141 * - compute the number of remote fanin to be received for the update
142 * - compute the set of remote nodes sending a fanin
143 *
144 * To do that, we work on the incoming edges.
145 */
146 for ( j = symbcblk[0].brownum; j < symbcblk[1].brownum; j++ ) {
147 k = symbmtx->browtab[j];
148 symbblok = symbmtx->bloktab + k;
149 c = simuctrl->bloktab[k].ownerclust;
150
151 assert( i == symbblok->fcblknm );
152
153 /* This is a remote contribution we add it to the ftgt and update the counters */
154 if ( c != clustnum ) {
155 solver_recv_update_recv( ftgttab + i,
156 symbmtx,
157 symbmtx->cblktab + symbblok->lcblknm,
158 symbblok, symbcblk, c );
159 brownbr--;
160 }
161 assert( brownbr >= 0 );
162 }
163
164 /*
165 * Now that all remote contributions have been computed and summarized in ftgttab[i],
166 * let's compute the local information for the indices
167 */
168 ftgtcblk = ftgttab[i];
169 while( ftgtcblk != NULL ) {
170 assert( (ftgtcblk->ownerid != -1) &&
171 (ftgtcblk->ownerid != clustnum) );
172
173 /* Book some space for the reception blocks */
174 localindex[clustnum] += solver_recv_get_bloknbr( ftgtcblk, symbcblk,
175 symbmtx->bloktab + symbcblk->bloknum );
176
177 brownbr++; /* One more blok will be in the browtab */
178 cblknum++; /* Add one cblk */
179 recvnbr++; /* Add one reception count */
180
181 ftgtcblk = ftgtcblk->next;
182 }
183
184 /*
185 * Now, we need to get through the outgoing dependencies to generate
186 * the fanin informations if it needs to be added, and to compute
187 * local block indices.
188 */
189 symbblok = symbmtx->bloktab + symbcblk->bloknum;
190 for ( j=symbcblk[0].bloknum; j<symbcblk[1].bloknum; j++, symbblok++ ) {
191 symbol_cblk_t *symbfcbk;
192 pastix_int_t fcblknum, fbloknum;
193
194 bloklocalnum[j] = localindex[clustnum];
195 localindex[clustnum]++;
196
197 assert( simuctrl->bloktab[j].ownerclust == clustnum );
198
199 fcblknum = symbblok->fcblknm;
200 symbfcbk = symbmtx->cblktab + fcblknum;
201 fbloknum = symbfcbk->bloknum;
202 fc = simuctrl->bloktab[fbloknum].ownerclust;
203
204 /*
205 * If the facing cblk isn't local, we need to have a local copy
206 * of it to store the fan-in
207 */
208 if ( fc != clustnum ) {
209 solver_recv_update_fanin( ftgttab + fcblknum,
210 symbmtx, symbcblk, symbblok, symbfcbk, fc );
211 }
212 }
213 }
214 else {
215 /* If the cblk is not local, it is a fanin */
216
217 /*
218 * First, let's look at incoming dependencies to reduce the brownbr
219 */
220 {
221 for ( j = symbcblk[0].brownum; j < symbcblk[1].brownum; j++ ) {
222 k = symbmtx->browtab[j];
223 c = simuctrl->bloktab[k].ownerclust;
224 if ( c != clustnum ) {
225 brownbr--;
226 }
227 }
228 }
229
230 /*
231 * Second, let's update the localindex counter based on the number of local blocks
232 */
233 {
234 /* Check we have one and only one solver_cblk_recv associated to it */
235 solver_cblk_recv_t *ftgtcblk = ftgttab[i];
236 solver_blok_recv_t *ftgtblok;
237 assert( ftgtcblk != NULL );
238 assert( ftgtcblk->next == NULL );
239
240 symbblok = symbmtx->bloktab + symbcblk->bloknum;
241 faninnbr++;
242 /* Adds a fanin cblk to ftgtcblk->ownerid cblk fanin counter. */
243 faninnbr_tab[2 * ftgtcblk->ownerid]++;
244 ftgtblok = ftgtcblk->bloktab;
245 for ( j=symbcblk[0].bloknum; j<symbcblk[1].bloknum; j++, symbblok++, ftgtblok++ )
246 {
247 assert( simuctrl->bloktab[j].ownerclust != clustnum );
248
249 if ( (ftgtblok->frownum <= ftgtblok->lrownum) &&
250 (ftgtblok->frownum >= symbblok->frownum) &&
251 (ftgtblok->lrownum <= symbblok->lrownum) )
252 {
253 bloklocalnum[j] = localindex[clustnum];
254 localindex[clustnum]++;
255 faninbloknbr++;
256 /* Adds a fanin blok to ftgtcblk->ownerid blok fanin counter. */
257 faninnbr_tab[2 * ftgtcblk->ownerid + 1]++;
258 }
259 else {
260 bloklocalnum[j] = -1;
261 }
262 }
263 }
264 }
265
266 /* Store index of the current cblk */
267 cblklocalnum[i] = cblknum;
268 cblknum++;
269
270 /* Update the brownum index */
271 brownum += brownbr;
272 assert( brownum <= symbcblk[1].brownum );
273 }
274
275 solvmtx->cblknbr = cblknum;
276 solvmtx->bloknbr = localindex[clustnum];
277 solvmtx->brownbr = brownum;
278
279 /* Reallocate recv_sources tab to diminish it's size */
280 solvmtx->recvnbr = recvnbr;
281 solvmtx->faninnbr = faninnbr;
282
283#if defined(PASTIX_WITH_MPI)
284 if ( clustnbr > 1 ) {
285 pastix_int_t fanincnt, fanin_tmp;
286 pastix_int_t faninblokcnt, faninblok_tmp;
287 pastix_int_t gfaninnbr[2];
288 pastix_int_t fanin_tab[4];
289
290 fanin_tab[0] = faninnbr;
291 fanin_tab[1] = faninbloknbr;
292 fanin_tab[2] = 0;
293 fanin_tab[3] = 0;
294
295 if ( clustnum != 0 ) {
296 /* Receives global number of cblk fanin: fanin_tab[2] and blok fanin: fanin_tab[3]. */
297 MPI_Recv( &fanin_tab[2], 2, PASTIX_MPI_INT, clustnum-1, clustnum-1,
298 solvmtx->solv_comm, MPI_STATUS_IGNORE);
299 fanin_tab[0] += fanin_tab[2];
300 fanin_tab[1] += fanin_tab[3];
301 }
302 if ( clustnum != clustnbr - 1 ) {
303 /* Sends global number of cblk fanin: fanin_tab[1] and blok fanin: fanin_tab[2]. */
304 MPI_Send( &fanin_tab[0], 2, PASTIX_MPI_INT, clustnum+1, clustnum,
305 solvmtx->solv_comm );
306 }
307
308 /* Shares the global number of fanin. */
309 gfaninnbr[0] = fanin_tab[0];
310 gfaninnbr[1] = fanin_tab[1];
311 MPI_Bcast( &gfaninnbr, 2, PASTIX_MPI_INT, clustnbr-1, solvmtx->solv_comm );
312 solvmtx->gfanincblknbr = gfaninnbr[0];
313 solvmtx->gfaninbloknbr = gfaninnbr[1];
314
315 fanincnt = fanin_tab[2];
316 faninblokcnt = fanin_tab[3];
317 for ( k = 0; k < clustnbr; k++ ) {
318 if ( faninnbr_tab[2 * k] == 0 ) {
319 /* No fanin cblk for k. */
320 faninnbr_tab[2 * k] = -1;
321 /* No fanin blok for k. */
322 faninnbr_tab[2 * k + 1] = -1;
323 }
324 /* Adds fanin cblk (and blok) indexes for k. */
325 if ( faninnbr_tab[2 * k] != -1 ) {
326 /* Adds fanin cblk index for k. */
327 fanin_tmp = faninnbr_tab[2 * k];
328 faninnbr_tab[ 2 * k] = fanincnt;
329 fanincnt += fanin_tmp;
330 /* Adds fanin blok index for k. */
331 faninblok_tmp = faninnbr_tab[2 * k + 1];
332 faninnbr_tab[ 2 * k + 1] = faninblokcnt;
333 faninblokcnt += faninblok_tmp;
334 }
335 }
336
337 /* Exchanges fanin cblk and blok indexes. */
338 MPI_Alltoall( faninnbr_tab, 2, PASTIX_MPI_INT, faninnbr_tab+2*clustnbr,
339 2, PASTIX_MPI_INT, solvmtx->solv_comm );
340 }
341#endif
342
343 memFree_null( localindex );
344 (void)faninbloknbr;
345}
346
347/**
348 *******************************************************************************
349 *
350 * @brief Reorder the browtab from the symbol structure in a distributed way.
351 * First stock the 1D blocks and then the 2D blocks.
352 *
353 *******************************************************************************
354 *
355 * @param[in] symbmtx
356 * The pointer to the symbol matrix structure.
357 *
358 * @param[in] symbcblk
359 * The pointer to the current symbol cblk.
360 *
361 * @param[inout] solvmtx
362 * Pointer to the solver matrix.
363 *
364 * @param[inout] solvcblk
365 * The pointer to the current solver cblk.
366 *
367 * @param[inout] browtmp
368 * Workspace array used to reorder the local brow information.
369 * Must be of size at least (symbcblk[1].brownum - symbcblk[0].brownum)
370 *
371 * @param[in] cblklocalnum
372 * Local cblk indices.
373 *
374 * @param[in] bloklocalnum
375 * Local blok indices.
376 *
377 * @param[in] brownum
378 * Current brownum.
379 *
380 *******************************************************************************
381 *
382 * @retval TODO
383 *
384 *******************************************************************************/
387 const symbol_cblk_t *symbcblk,
388 SolverMatrix *solvmtx,
389 SolverCblk *solvcblk,
390 pastix_int_t *browtmp,
391 const pastix_int_t *cblklocalnum,
392 const pastix_int_t *bloklocalnum,
393 pastix_int_t brownum )
394{
395 pastix_int_t brownbr;
396 symbol_blok_t *symbblok;
397 SolverBlok *solvblok;
398 SolverCblk *browcblk;
399 pastix_int_t lcblknm, lbloknm;
400 pastix_int_t j2d, j1d, j, jmax;
401 pastix_int_t *b;
402
403 brownbr = symbcblk[1].brownum - symbcblk[0].brownum;
404 solvcblk->brown2d = solvcblk->brownum + brownbr;
405
406 /* Nothing to do here */
407 if ( !brownbr ) {
408 return 0;
409 }
410
411 assert( brownbr <= symbmtx->browmax );
412 memcpy( browtmp,
413 symbmtx->browtab + symbcblk->brownum,
414 brownbr * sizeof(pastix_int_t) );
415
416 /*
417 * j is the index in the local browtab (~ postition of b)
418 * j1d is the number of discovered 1d block in the browtab
419 * j2d if the index of the first 2d block in the original tab
420 * jmax is equal to brownbr
421 * brownbr is updated to store the real number of brow (minus fanin)
422 *
423 * b is a pointer to the temporary copy of the subsection of the browtab
424 * At the end of the first pass, if b[i] is negative, it has already been treated
425 * with if equal to:
426 * -1, the block was a 1D block
427 * -2, the block belonged to a remote cblk
428 * -3, the block belonged to a local fanin (should not happen)
429 * It is is positive, it's a 2D block that need to be pushed to the end of
430 * the browtab in the second pass.
431 */
432 b = browtmp;
433 j2d = -1;
434 jmax = brownbr;
435
436 /* First pass to copy 1D updates */
437 for ( j=0, j1d=0; j < jmax; j++, b++ ) {
438 /* Get the contributing block in the symbol */
439 symbblok = symbmtx->bloktab + (*b);
440
441 lcblknm = ( cblklocalnum == NULL ) ? symbblok->lcblknm : cblklocalnum[ symbblok->lcblknm ];
442
443 /* If distant blok */
444 if ( lcblknm < 0 ) {
445 *b = -2;
446 brownbr--;
447 continue;
448 }
449
450 /* Get the local cblk which owns the block */
451 browcblk = solvmtx->cblktab + lcblknm;
452
453 /* Recv should never appear through cblklocalnum */
454 assert( !(browcblk->cblktype & CBLK_RECV) );
455
456 /* Fanin should not contribute to local data */
457 if( browcblk->cblktype & CBLK_FANIN ) {
458 *b = -3;
459 brownbr--;
460 continue;
461 }
462
463 /* Store the first non 1D index to not rediscover the begining, and skip 2d for now */
464 if ( browcblk->cblktype & CBLK_TASKS_2D ) {
465 j2d = ( j2d == -1 ) ? j : j2d;
466 continue;
467 }
468
469 /* Find the SolvBlok corresponding to the SymbBlok */
470 lbloknm = ( bloklocalnum == NULL ) ? *b : bloklocalnum[ *b ];
471 solvblok = solvmtx->bloktab + lbloknm;
472
473 assert( solvblok->lcblknm == lcblknm );
474#if !defined(NDEBUG)
475 {
476 pastix_int_t frownum, lrownum;
477 symbol_blok_get_rownum( symbmtx, symbblok, &frownum, &lrownum );
478 assert( ( frownum == solvblok->frownum ) &&
479 ( lrownum == solvblok->lrownum ) );
480 }
481#endif
482
483 assert( brownum + j1d < solvmtx->brownbr );
484 solvmtx->browtab[brownum + j1d] = lbloknm;
485 solvblok->browind = brownum + j1d;
486 *b = -1;
487 j1d++;
488 }
489
490 /* Store the index of the first 2D contribution in the array */
491 assert( j1d <= brownbr );
492 solvcblk->brown2d = solvcblk->brownum + j1d;
493
494 /* Second pass to copy 2D updates to the end */
495 if ( j2d != -1 ) {
496 b = browtmp + j2d;
497 for ( j = j2d; j < jmax; j++, b++ ) {
498 symbblok = symbmtx->bloktab + ( *b );
499
500 if ( *b < 0 ) {
501 continue;
502 }
503 lcblknm = ( cblklocalnum == NULL ) ? symbblok->lcblknm : cblklocalnum[ symbblok->lcblknm ];
504 assert( lcblknm >= 0 );
505
506 /* Get the local cblk which owns the block */
507 browcblk = solvmtx->cblktab + lcblknm;
508 assert( (cblklocalnum == NULL) ||
509 (browcblk->ownerid == solvmtx->clustnum) );
510
511 /* Find the SolvBlok corresponding to the SymbBlok */
512 lbloknm = ( bloklocalnum == NULL ) ? *b : bloklocalnum[ *b ];
513 solvblok = solvmtx->bloktab + lbloknm;
514
515 assert( solvblok->lcblknm == lcblknm );
516 assert( ( symbblok->frownum == solvblok->frownum ) &&
517 ( symbblok->lrownum == solvblok->lrownum ) );
518
519 assert( brownum + j1d < solvmtx->brownbr );
520 solvmtx->browtab[brownum + j1d] = lbloknm;
521 solvblok->browind = brownum + j1d;
522 j1d++;
523 }
524 }
525 assert( j1d == brownbr );
526
527 return brownbr;
528}
529
530/**
531 * @brief Structure to pass information to the muti-threaded ttsktab
532 * initialization function.
533 */
534struct args_ttsktab
535{
536 SolverMatrix *solvmtx; /**< Pointer to the solver matrix */
537 const SimuCtrl *simuctrl; /**< Pointer to simulation control structure */
538 const pastix_int_t *tasklocalnum; /**< Array of the local indices of the tasks */
539 pastix_int_t clustnum; /**< Index of the local cluster */
540};
541
542/**
543 *******************************************************************************
544 *
545 * @brief Fill the ttsktab for it's own thread.
546 *
547 *******************************************************************************
548 *
549 * @param[in] ctx
550 * The context of the current thread
551 *
552 * @param[inout] args
553 * The pointer to the args_ttsktab structure that parameterize the
554 * function call.
555 *
556 *******************************************************************************/
557void
558solvMatGen_fill_ttsktab( isched_thread_t *ctx, void *args )
559{
560 struct args_ttsktab *arg = (struct args_ttsktab*)args;
561 SolverMatrix *solvmtx = arg->solvmtx;
562 const SimuCtrl *simuctrl = arg->simuctrl;
563 const pastix_int_t *tasklocalnum = arg->tasklocalnum;
564 pastix_int_t clustnum = arg->clustnum;
565 int rank = ctx->rank;
566 SimuProc *simuproc = simuctrl->proctab
567 + ( simuctrl->clustab[clustnum].fprocnum + rank );
568 pastix_int_t i;
569 pastix_int_t priomin = PASTIX_INT_MAX;
570 pastix_int_t priomax = 0;
571 pastix_int_t ttsknbr = extendint_Size( simuproc->tasktab );
572 pastix_int_t j, jloc;
573
574 solvmtx->ttsknbr[rank] = ttsknbr;
575 if(ttsknbr > 0) {
576 MALLOC_INTERN(solvmtx->ttsktab[rank], ttsknbr, pastix_int_t);
577 }
578 else {
579 solvmtx->ttsktab[rank] = NULL;
580 }
581
582 for(i=0; i<ttsknbr; i++)
583 {
584 j = extendint_Read(simuproc->tasktab, i);
585 if( tasklocalnum != NULL ){
586 jloc = tasklocalnum[j];
587 }
588 else {
589 jloc = j;
590 }
591 /* Only local cblks should appear in the tasktab */
592 assert( !(solvmtx->cblktab[ solvmtx->tasktab[jloc].cblknum ].cblktype & (CBLK_FANIN|CBLK_RECV)) );
593 solvmtx->ttsktab[rank][i] = jloc;
594 solvmtx->cblktab[jloc].threadid = rank;
595
596#if defined(PASTIX_DYNSCHED)
597 solvmtx->tasktab[jloc].threadid = rank;
598#endif
599 priomax = pastix_imax( solvmtx->tasktab[jloc].prionum, priomax );
600 priomin = pastix_imin( solvmtx->tasktab[jloc].prionum, priomin );
601 }
602
603#if defined(PASTIX_DYNSCHED)
604 solvmtx->btree->nodetab[rank].priomin = priomin;
605 solvmtx->btree->nodetab[rank].priomax = priomax;
606#endif
607}
608
609/**
610 *******************************************************************************
611 *
612 * @brief Fill in ttsktab for it's own thread. Only for debugging factorization.
613 *
614 *******************************************************************************
615 *
616 * @param[in] ctx
617 * the context of the current thread
618 *
619 * @param[inout] args
620 * The pointer to the args_ttsktab structure that parameterize the
621 * function call.
622 *
623 *******************************************************************************/
624void
625solvMatGen_fill_ttsktab_dbg( isched_thread_t *ctx, void *args )
626{
627 struct args_ttsktab *arg = (struct args_ttsktab*)args;
628
629 pastix_int_t i, j, size;
630 SolverMatrix *solvmtx = arg->solvmtx;
631 int rank = ctx->rank;
632 int nthread = ctx->global_ctx->world_size;
633 pastix_int_t tasknbr = solvmtx->tasknbr / nthread;
634 pastix_int_t priomin = PASTIX_INT_MAX;
635 pastix_int_t priomax = 0;
636
637 size = (rank == nthread-1) ? (solvmtx->tasknbr - (nthread-1) * tasknbr) : tasknbr;
638 solvmtx->ttsknbr[rank] = size;
639
640 if(size > 0) {
641 MALLOC_INTERN(solvmtx->ttsktab[rank], size, pastix_int_t);
642 }
643 else {
644 solvmtx->ttsktab[rank] = NULL;
645 }
646
647 j = ((solvmtx->tasknbr - (nthread-1) * tasknbr) * rank);
648 for(i=0; i < size; i++)
649 {
650 solvmtx->ttsktab[rank][i] = j;
651
652#if defined(PASTIX_DYNSCHED)
653 solvmtx->tasktab[j].threadid = rank;
654#endif
655 priomax = pastix_imax( solvmtx->tasktab[j].prionum, priomax );
656 priomin = pastix_imin( solvmtx->tasktab[j].prionum, priomin );
657 j++;
658 }
659
660#if defined(PASTIX_DYNSCHED)
661 solvmtx->btree->nodetab[rank].priomin = priomin;
662 solvmtx->btree->nodetab[rank].priomax = priomax;
663#endif
664}
665
666/**
667 *******************************************************************************
668 *
669 * @brief Fill the global tasktab array, as well as the thread ttsktab arrays.
670 *
671 *******************************************************************************
672 *
673 * @param[inout] solvmtx
674 * Pointer to the solver matrix.
675 *
676 * @param[in] isched
677 * The internal context to run multi-threaded functions.
678 *
679 * @param[in] simuctrl
680 * The pointer to the simulation control structure.
681 *
682 * @param[in] tasklocalnum
683 * Array of the local indices of the tasks.
684 *
685 * @param[in] cblklocalnum
686 * Array of the local indices of the cblk.
687 *
688 * @param[in] bloklocalnum
689 * Array of the local indices of the blocks.
690 *
691 * @param[in] clustnum
692 * Rank of the MPI instance.
693 *
694 * @param[in] is_dbg
695 * Enable/disable the ttsktab debug generation.
696 *
697 *******************************************************************************/
698void
700 isched_t *isched,
701 const SimuCtrl *simuctrl,
702 const pastix_int_t *tasklocalnum,
703 const pastix_int_t *cblklocalnum,
704 const pastix_int_t *bloklocalnum,
705 pastix_int_t clustnum,
706 int is_dbg )
707{
708 Task *solvtask;
709 SolverBlok *blok, *lblk;
710 SimuTask *simutask = simuctrl->tasktab;
711 SolverCblk *solvcblk = solvmtx->cblktab;
712 pastix_int_t tasknum = 0;
713 pastix_int_t tasknbr_1dp = 0;
714 pastix_int_t i;
715
716 MALLOC_INTERN( solvmtx->tasktab, solvmtx->tasknbr+1, Task );
717 solvtask = solvmtx->tasktab;
718
719 /* No local indices, this is a global solver */
720 if ( tasklocalnum == NULL )
721 {
722 for(i=0; i<simuctrl->tasknbr; i++, simutask++)
723 {
724 solvtask->taskid = COMP_1D;
725 solvtask->prionum = simutask->prionum;
726 solvtask->cblknum = simutask->cblknum;
727 solvtask->bloknum = simutask->bloknum;
728 solvtask->ctrbcnt = simutask->ctrbcnt;
729
730 solvcblk = solvmtx->cblktab + solvtask->cblknum;
731 solvcblk->priority = solvtask->prionum;
732
733 /* Schur, fanin and recv are counted only in static */
734 if ( solvcblk->cblktype & (CBLK_IN_SCHUR | CBLK_FANIN | CBLK_RECV ) ) {
735 tasknum++; solvtask++;
736 continue;
737 }
738
739 /* Count the number of additional tasks in 1D+ mode */
740 if ( solvcblk->cblktype & CBLK_TASKS_2D )
741 {
742 blok = solvcblk[0].fblokptr + 1; /* first off-diagonal block */
743 lblk = solvcblk[1].fblokptr; /* the next diagonal block */
744
745 /* if there are off-diagonal supernodes in the column */
746 for( ; blok < lblk; blok++ ) {
747 tasknbr_1dp++;
748 /* Skip blocks facing the same cblk */
749 while ( ( blok < lblk ) &&
750 ( blok[0].fcblknm == blok[1].fcblknm ) &&
751 ( blok[0].lcblknm == blok[1].lcblknm ) )
752 {
753 blok++;
754 }
755 }
756 }
757 tasknbr_1dp++;
758 tasknum++; solvtask++;
759 }
760 }
761 else
762 {
763 for(i=0; i<simuctrl->tasknbr; i++, simutask++)
764 {
765 if( simuctrl->bloktab[ simutask->bloknum ].ownerclust != clustnum )
766 {
767 continue;
768 }
769
770 assert( tasknum == tasklocalnum[i] );
771
772 solvtask->taskid = COMP_1D;
773 solvtask->prionum = simutask->prionum;
774 solvtask->cblknum = cblklocalnum[ simutask->cblknum ];
775 solvtask->bloknum = bloklocalnum[ simutask->bloknum ];
776 solvtask->ctrbcnt = simutask->ctrbcnt;
777
778 solvcblk = solvmtx->cblktab + solvtask->cblknum;
779 solvcblk->priority = solvtask->prionum;
780
781 /* Schur, fanin and recv are counted only in static */
782 if ( solvcblk->cblktype & (CBLK_IN_SCHUR | CBLK_FANIN | CBLK_RECV ) ) {
783 tasknum++; solvtask++;
784 continue;
785 }
786
787 /* Count the number of additional tasks in 1D+ mode */
788 if ( solvcblk->cblktype & CBLK_TASKS_2D )
789 {
790 blok = solvcblk[0].fblokptr + 1; /* first off-diagonal block */
791 lblk = solvcblk[1].fblokptr; /* the next diagonal block */
792
793 /* if there are off-diagonal supernodes in the column */
794 for( ; blok < lblk; blok++ ) {
795 tasknbr_1dp++;
796 /* Skip blocks facing the same cblk */
797 while ( ( blok < lblk ) &&
798 ( blok[0].fcblknm == blok[1].fcblknm ) &&
799 ( blok[0].lcblknm == blok[1].lcblknm ) )
800 {
801 blok++;
802 }
803 }
804 }
805
806 tasknbr_1dp++;
807 tasknum++; solvtask++;
808 }
809 }
810 assert(tasknum == solvmtx->tasknbr);
811 solvmtx->tasknbr_1dp = tasknbr_1dp;
812
813 /* One more task to avoid side effect */
814 solvtask->taskid = -1;
815 solvtask->prionum = -1;
816 solvtask->cblknum = solvmtx->cblknbr+1;
817 solvtask->bloknum = solvmtx->bloknbr+1;
818 solvtask->ctrbcnt = 0;
819
820 /* Fill in the ttsktab arrays (one per thread) */
821 MALLOC_INTERN(solvmtx->ttsknbr, solvmtx->bublnbr, pastix_int_t );
822 MALLOC_INTERN(solvmtx->ttsktab, solvmtx->bublnbr, pastix_int_t* );
823
824 if( is_dbg ) {
825 struct args_ttsktab args = { solvmtx, NULL, tasklocalnum, clustnum };
826 isched_parallel_call( isched, solvMatGen_fill_ttsktab_dbg, &args );
827 }
828 else {
829 struct args_ttsktab args = { solvmtx, simuctrl, tasklocalnum, clustnum };
830 isched_parallel_call( isched, solvMatGen_fill_ttsktab, &args );
831 }
832}
833
834/**
835 *******************************************************************************
836 *
837 * @brief Compute the maximum area of the temporary buffers
838 * used during computation
839 *
840 * During this loop, we compute the maximum area that will be used as
841 * temporary buffers, and statistics:
842 * - diagmax: Only for hetrf/sytrf factorization, this the maximum size
843 * of a panel of MAXSIZEOFBLOCKS width in a diagonal block
844 * - gemmmax: For all, this is the maximum area used to compute the
845 * compacted gemm on a CPU.
846 *
847 * Rk: This loop is not merged within the main block loop, since strides have
848 * to be peviously computed.
849 *
850 *******************************************************************************
851 *
852 * @param[inout] solvmtx
853 * Pointer to the solver matrix.
854 *
855 *******************************************************************************/
856void
858{
859 SolverCblk *solvcblk = solvmtx->cblktab;
860 SolverBlok *solvblok = solvmtx->bloktab;
861 pastix_int_t gemmmax = 0;
862 pastix_int_t offdmax = 0;
863 pastix_int_t blokmax = 0;
864 pastix_int_t gemmarea, offdarea, cblk_m, acc_m, i;
865
866 for(i=0; i<solvmtx->cblknbr; i++, solvcblk++)
867 {
868 SolverBlok *lblok = solvcblk[1].fblokptr;
869 pastix_int_t m = solvcblk->stride;
870 pastix_int_t n = cblk_colnbr( solvcblk );
871 pastix_int_t k = blok_rownbr( solvblok );
872
873 m -= n;
874
875 /*
876 * Compute the surface of the off-diagonal block in a panel for
877 * LDL^[th] factorizations
878 */
879 offdarea = m * n;
880 offdmax = pastix_imax( offdmax, offdarea );
881
882 /*
883 * Compute the maximum area for 1d temporary workspace in GEMM
884 */
885 solvblok++;
886 cblk_m = -1;
887 acc_m = 0;
888 for( ; solvblok<lblok; solvblok++ ) {
889 k = blok_rownbr( solvblok );
890
891 /*
892 * Temporary workspace for GEMM
893 * m+1 to store the diagonal in case of GEMDM
894 */
895 if ( !(solvcblk->cblktype & CBLK_LAYOUT_2D) ) {
896 gemmarea = (m+1) * k;
897 gemmmax = pastix_imax( gemmmax, gemmarea );
898 }
899
900 /*
901 * Max size for off-diagonal blocks for 2-terms version of the
902 * 2D LDL
903 */
904 if ( solvcblk->cblktype & (CBLK_TASKS_2D | CBLK_COMPRESSED) ) {
905 if ( solvblok->fcblknm == cblk_m ) {
906 acc_m += k;
907 }
908 else {
909 cblk_m = solvblok->fcblknm;
910 acc_m = k;
911 }
912 /*
913 * acc_m+1 to store the diagonal in case of GEMDM
914 */
915 blokmax = pastix_imax( n * (acc_m+1), blokmax );
916 }
917 m -= k;
918 }
919 }
920
921 solvmtx->offdmax = offdmax;
922 solvmtx->gemmmax = gemmmax;
923 solvmtx->blokmax = blokmax;
924}
925
926/**
927 *******************************************************************************
928 *
929 * @brief Mark blocks if they belong to the last supernode, or if they are
930 * facing it for statistical purpose only.
931 *
932 * TODO : Should be improved by using the brow array in order to cover only the
933 * blocks in front of the last cblk
934 *
935 *******************************************************************************
936 *
937 * @param[inout] solvmtx
938 * Pointer to the solver matrix.
939 *
940 *******************************************************************************/
941void
943{
944#if defined(PASTIX_SUPERNODE_STATS)
945 pastix_int_t i;
946 SolverBlok *solvblok = solvmtx->bloktab;
947
948 for(i=0; i<solvmtx->bloknbr; i++, solvblok++ ) {
949 SolverCblk *fcblk = solvmtx->cblktab + solvblok->fcblknm;
950 SolverCblk *lcblk = solvmtx->cblktab + solvblok->lcblknm;
951 if ( fcblk->cblktype & CBLK_IN_LAST ) {
952 if ( lcblk->cblktype & CBLK_IN_LAST ) {
953 solvblok->inlast = 2;
954 }
955 else {
956 solvblok->inlast = 1;
957 }
958 }
959 }
960#else
961 (void)solvmtx;
962#endif
963}
964
965/**
966 *******************************************************************************
967 *
968 * @brief Register a local cblk from a symbol_cblk_t structure !(Fanin|Recv)
969 *
970 *******************************************************************************
971 *
972 * @param[in] symbmtx
973 * The pointer to the symbol matrix.
974 *
975 * @param[in] candcblk
976 * The cand structure associated to the current cblk to get the type of
977 * the cblk.
978 *
979 * @param[in] cblklocalnum
980 * Array of the local indices of the cblk.
981 *
982 * @param[inout] solvcblk
983 * Pointer to the current cblk to register.
984 *
985 * @param[inout] solvblok
986 * Pointer to the first block of the current cblk.
987 *
988 * @param[in] lcblknm
989 * The local index of the cblk.
990 *
991 * @param[in] brownum
992 * The current index in the browtab.
993 *
994 * @param[in] gcblknm
995 * The global index of the current cblk.
996 *
997 * @param[in] ownerid
998 * The index of the local MPI rank.
999 *
1000 * @return The pointer to the next solver block to register.
1001 *
1002 *******************************************************************************/
1005 const Cand *candcblk,
1006 const pastix_int_t *cblklocalnum,
1007 SolverCblk *solvcblk,
1008 SolverBlok *solvblok,
1009 pastix_int_t lcblknm,
1010 pastix_int_t brownum,
1011 pastix_int_t gcblknm,
1012 pastix_int_t ownerid )
1013{
1014 symbol_cblk_t *symbcblk = symbmtx->cblktab + gcblknm;
1015 symbol_blok_t *symbblok = symbmtx->bloktab + symbcblk->bloknum;
1016 SolverBlok *fblokptr = solvblok;
1017 pastix_int_t stride = 0;
1018 pastix_int_t layout2D = candcblk->cblktype & CBLK_LAYOUT_2D;
1019 pastix_int_t fcolnum, lcolnum, nbcols, j;
1020
1021 assert( solvblok != NULL );
1022 assert( brownum >= 0 );
1023 assert( symbblok->lcblknm == gcblknm );
1024 assert( (cblklocalnum == NULL) || (lcblknm == cblklocalnum[gcblknm]) );
1025
1026 /*
1027 * Compute the number of columns of the fan-in
1028 */
1029 nbcols = symbol_cblk_get_colnum( symbmtx, symbcblk, &fcolnum, &lcolnum );
1030
1031 /*
1032 * Register all the local blocks
1033 */
1034 for ( j=symbcblk[0].bloknum; j<symbcblk[1].bloknum; j++, symbblok++ )
1035 {
1036 pastix_int_t frownum, lrownum, nbrows;
1037
1038 nbrows = symbol_blok_get_rownum( symbmtx, symbblok, &frownum, &lrownum );
1039 assert( nbrows >= 1 );
1040
1041 /* Init the blok */
1042 solvMatGen_init_blok( solvblok, lcblknm,
1043 cblklocalnum == NULL ? symbblok->fcblknm : cblklocalnum[symbblok->fcblknm],
1044 frownum, lrownum, stride, nbcols,
1045 layout2D );
1046 solvblok->gbloknm = j;
1047 stride += nbrows;
1048 solvblok++;
1049 }
1050
1051 solvMatGen_init_cblk( solvcblk, fblokptr, candcblk, symbcblk,
1052 fcolnum, lcolnum, brownum, stride,
1053 gcblknm, ownerid );
1054
1055 solvcblk->lcolidx = fcolnum;
1056
1057 return solvblok;
1058}
1059
1060/**
1061 *******************************************************************************
1062 *
1063 * @brief Register a remote cblk from a solver_recv_cblk_t structure (Fanin|Recv)
1064 *
1065 *******************************************************************************
1066 *
1067 * @param[inout] solvmtx
1068 * The solver matrix.
1069 *
1070 * @param[in] symbmtx
1071 * The pointer to the symbol matrix.
1072 *
1073 * @param[in] recvcblk
1074 * The associated solver_recv_cblk_t structure used to initialize the
1075 * remote cblk.
1076 *
1077 * @param[in] candcblk
1078 * The cand structure associated to the current cblk to get the type of
1079 * the cblk.
1080 *
1081 * @param[in] cblklocalnum
1082 * Array of the local indices of the cblk.
1083 *
1084 * @param[inout] solvcblk
1085 * Pointer to the current cblk to register.
1086 *
1087 * @param[inout] solvblok
1088 * Pointer to the first block of the current cblk.
1089 *
1090 * @param[in] lcblknm
1091 * The local index of the cblk.
1092 *
1093 * @param[in] brownum
1094 * The current index in the browtab.
1095 *
1096 * @param[in] gcblknm
1097 * The global index of the current cblk.
1098 *
1099 * @param[in] faninnbr_tab
1100 * The fanin indexes array.
1101 *
1102 *******************************************************************************
1103 *
1104 * @return The pointer to the next solver block to register.
1105 *
1106 *******************************************************************************/
1109 const symbol_matrix_t *symbmtx,
1110 const solver_cblk_recv_t *recvcblk,
1111 const Cand *candcblk,
1112 const pastix_int_t *cblklocalnum,
1113 SolverCblk *solvcblk,
1114 SolverBlok *solvblok,
1115 pastix_int_t lcblknm,
1116 pastix_int_t brownum,
1117 pastix_int_t gcblknm,
1118 pastix_int_t *faninnbr_tab )
1119{
1120 const solver_blok_recv_t *recvblok = recvcblk->bloktab;
1121 symbol_cblk_t *symbcblk = symbmtx->cblktab + gcblknm;
1122 symbol_blok_t *symbblok = symbmtx->bloktab + symbcblk->bloknum;
1123 SolverBlok *fblokptr = solvblok;
1124 pastix_int_t stride = 0;
1125 pastix_int_t layout2D = candcblk->cblktype & CBLK_LAYOUT_2D;
1126 pastix_int_t clustnbr = solvmtx->clustnbr;
1127 pastix_int_t ownerid = recvcblk->ownerid;
1128 pastix_int_t fcolnum, lcolnum, nbcols, j;
1129
1130 assert( solvblok != NULL );
1131 assert( brownum >= 0 );
1132 assert( symbblok->lcblknm == gcblknm );
1133
1134 /*
1135 * Compute the number of columns of the fan-in
1136 */
1137 if ( symbmtx->dof < 0 ) {
1138 fcolnum = symbmtx->dofs[recvcblk->fcolnum];
1139 lcolnum = symbmtx->dofs[recvcblk->lcolnum + 1] - 1;
1140 }
1141 else {
1142 fcolnum = symbmtx->dof * recvcblk->fcolnum;
1143 lcolnum = symbmtx->dof * ( recvcblk->lcolnum + 1 ) - 1;
1144 }
1145 nbcols = lcolnum - fcolnum + 1;
1146
1147 /*
1148 * Register all the local blocks
1149 */
1150 for ( j=symbcblk[0].bloknum; j<symbcblk[1].bloknum; j++, recvblok++, symbblok++ )
1151 {
1152 pastix_int_t frownum, lrownum, nbrows;
1153
1154 if ( symbmtx->dof < 0 ) {
1155 frownum = symbmtx->dofs[recvblok->frownum];
1156 lrownum = symbmtx->dofs[recvblok->lrownum + 1] - 1;
1157 }
1158 else {
1159 frownum = symbmtx->dof * recvblok->frownum;
1160 lrownum = symbmtx->dof * ( recvblok->lrownum + 1 ) - 1;
1161 }
1162 nbrows = lrownum - frownum + 1;
1163
1164 if ( nbrows < 1 ) {
1165 continue;
1166 }
1167
1168 /* Init the blok */
1169 solvMatGen_init_blok( solvblok,
1170 lcblknm, cblklocalnum[symbblok->fcblknm],
1171 frownum, lrownum, stride, nbcols,
1172 layout2D );
1173 solvblok->gbloknm = j;
1174 stride += nbrows;
1175
1176 if ( solvcblk->cblktype & CBLK_FANIN ) {
1177 assert( faninnbr_tab );
1178 solvblok->gfaninnm = faninnbr_tab[2 * ownerid + 1] + solvmtx->gbloknbr;
1179 faninnbr_tab[2 * ownerid + 1]++;
1180 }
1181 if ( solvcblk->cblktype & CBLK_RECV ) {
1182 assert( faninnbr_tab );
1183 solvblok->gfaninnm = faninnbr_tab[2 * (clustnbr + ownerid) + 1] + solvmtx->gbloknbr;
1184 faninnbr_tab[2 * (clustnbr + ownerid) + 1]++;
1185 }
1186 solvblok++;
1187 }
1188
1189 solvMatGen_init_cblk( solvcblk, fblokptr, candcblk, symbcblk,
1190 fcolnum, lcolnum, brownum, stride,
1191 gcblknm, ownerid );
1192
1193 solvcblk->lcolidx = -1;
1194
1195#if defined(PASTIX_BLEND_FANIN_FR)
1196 if( solvcblk->cblktype & CBLK_COMPRESSED ) {
1197 solvcblk->cblktype &= (~CBLK_COMPRESSED);
1198 }
1199#endif
1200 /* No Schur complement in distributed for the moment */
1201 if( solvcblk->cblktype & CBLK_IN_SCHUR ) {
1202 solvcblk->cblktype &= (~CBLK_IN_SCHUR);
1203 }
1204
1205 return solvblok;
1206}
1207
1208/**
1209 *@}
1210 */
BEGIN_C_DECLS typedef int pastix_int_t
Definition datatypes.h:51
int8_t cblktype
Definition cand.h:36
Processor candidate group to own a column blok.
Definition cand.h:28
pastix_int_t extendint_Size(const ExtendVectorINT *)
Return the number of element stored in the vector.
pastix_int_t extendint_Read(const ExtendVectorINT *, pastix_int_t)
Return the element of index eltnum.
SimuCluster * clustab
Definition simu.h:123
SimuProc * proctab
Definition simu.h:122
int8_t owned
Definition simu.h:80
SimuTask * tasktab
Definition simu.h:121
int ownerclust
Definition simu.h:93
ExtendVectorINT * tasktab
Definition simu.h:60
pastix_int_t ctrbcnt
Definition simu.h:108
pastix_int_t cblknum
Definition simu.h:101
SimuBlok * bloktab
Definition simu.h:126
pastix_int_t fprocnum
Definition simu.h:47
pastix_int_t bloknum
Definition simu.h:102
SimuCblk * cblktab
Definition simu.h:125
pastix_int_t prionum
Definition simu.h:100
pastix_int_t tasknbr
Definition simu.h:119
Thread structure for the simulation.
Definition simu.h:56
Task structure for the simulation.
Definition simu.h:99
Control structure for the simulation.
Definition simu.h:116
SolverBlok * solvMatGen_register_local_cblk(const symbol_matrix_t *symbmtx, const Cand *candcblk, const pastix_int_t *cblklocalnum, SolverCblk *solvcblk, SolverBlok *solvblok, pastix_int_t lcblknm, pastix_int_t brownum, pastix_int_t gcblknm, pastix_int_t ownerid)
Register a local cblk from a symbol_cblk_t structure !(Fanin|Recv)
int solver_recv_get_bloknbr(const solver_cblk_recv_t *ftgtptr, const symbol_cblk_t *symbcblk, const symbol_blok_t *symbblok)
Compute the number of valid blocks in fanin/recv cblk.
SolverBlok * solvMatGen_register_remote_cblk(const SolverMatrix *solvmtx, const symbol_matrix_t *symbmtx, const solver_cblk_recv_t *recvcblk, const Cand *candcblk, const pastix_int_t *cblklocalnum, SolverCblk *solvcblk, SolverBlok *solvblok, pastix_int_t lcblknm, pastix_int_t brownum, pastix_int_t gcblknm, pastix_int_t *faninnbr_tab)
Register a remote cblk from a solver_recv_cblk_t structure (Fanin|Recv)
void solvMatGen_fill_localnums(const symbol_matrix_t *symbmtx, const SimuCtrl *simuctrl, SolverMatrix *solvmtx, pastix_int_t *cblklocalnum, pastix_int_t *bloklocalnum, pastix_int_t *tasklocalnum, solver_cblk_recv_t **ftgttab, pastix_int_t *faninnbr_tab)
Fill the local numbering arrays to compress the symbol information into solver.
void solver_recv_update_fanin(solver_cblk_recv_t **faninptr, const symbol_matrix_t *symbmtx, const symbol_cblk_t *cblk, const symbol_blok_t *blok, const symbol_cblk_t *fcblk, int ownerid)
Register a new contribution to a fanin cblk.
void solver_recv_update_recv(solver_cblk_recv_t **recvptr, const symbol_matrix_t *symbmtx, const symbol_cblk_t *cblk, const symbol_blok_t *blok, const symbol_cblk_t *fcblk, int ownerid)
Register a new contribution to a recv cblk.
static void solvMatGen_init_cblk(SolverCblk *solvcblk, SolverBlok *fblokptr, const Cand *candcblk, const symbol_cblk_t *symbcblk, pastix_int_t fcolnum, pastix_int_t lcolnum, pastix_int_t brownum, pastix_int_t stride, pastix_int_t cblknum, int ownerid)
Initialize a solver cblk.
void solvMatGen_fill_tasktab(SolverMatrix *solvmtx, isched_t *isched, const SimuCtrl *simuctrl, const pastix_int_t *tasklocalnum, const pastix_int_t *cblklocalnum, const pastix_int_t *bloklocalnum, pastix_int_t clustnum, int is_dbg)
Fill the global tasktab array, as well as the thread ttsktab arrays.
void solvMatGen_stats_last(SolverMatrix *solvmtx)
Mark blocks if they belong to the last supernode, or if they are facing it for statistical purpose on...
void solvMatGen_fill_ttsktab(isched_thread_t *ctx, void *args)
Fill the ttsktab for it's own thread.
void solvMatGen_fill_ttsktab_dbg(isched_thread_t *ctx, void *args)
Fill in ttsktab for it's own thread. Only for debugging factorization.
pastix_int_t solvMatGen_reorder_browtab(const symbol_matrix_t *symbmtx, const symbol_cblk_t *symbcblk, SolverMatrix *solvmtx, SolverCblk *solvcblk, pastix_int_t *browtmp, const pastix_int_t *cblklocalnum, const pastix_int_t *bloklocalnum, pastix_int_t brownum)
Reorder the browtab from the symbol structure in a distributed way. First stock the 1D blocks and the...
void solvMatGen_max_buffers(SolverMatrix *solvmtx)
Compute the maximum area of the temporary buffers used during computation.
static void solvMatGen_init_blok(SolverBlok *solvblok, pastix_int_t lcblknm, pastix_int_t fcblknm, pastix_int_t frownum, pastix_int_t lrownum, pastix_int_t stride, pastix_int_t nbcols, pastix_int_t layout2D)
Initialize a solver block.
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 * browtab
Definition symbol.h:85
symbol_cblk_t * cblktab
Definition symbol.h:83
pastix_int_t bloknum
Definition symbol.h:48
pastix_int_t brownum
Definition symbol.h:49
pastix_int_t dof
Definition symbol.h:87
symbol_blok_t * bloktab
Definition symbol.h:84
pastix_int_t lcblknm
Definition symbol.h:62
pastix_int_t * dofs
Definition symbol.h:89
pastix_int_t cblknbr
Definition symbol.h:79
static pastix_int_t symbol_blok_get_rownum(const symbol_matrix_t *symbmtx, symbol_blok_t *symbblok, pastix_int_t *frownum, pastix_int_t *lrownum)
Get the expanded row index of a symbol_blok.
Definition symbol.h:155
static pastix_int_t symbol_cblk_get_colnum(const symbol_matrix_t *symbmtx, symbol_cblk_t *symbcblk, pastix_int_t *fcolnum, pastix_int_t *lcolnum)
Get the expanded column indexes of a symbol_cblk.
Definition symbol.h:116
Symbol block structure.
Definition symbol.h:59
Symbol column block structure.
Definition symbol.h:45
Symbol matrix structure.
Definition symbol.h:77
pastix_int_t lrownum
Definition solver.h:103
pastix_int_t browind
Definition solver.h:150
pastix_int_t gfanincblknbr
Definition solver.h:212
static pastix_int_t blok_rownbr(const SolverBlok *blok)
Compute the number of rows of a block.
Definition solver.h:395
pastix_int_t taskid
Definition solver.h:123
pastix_int_t cblknum
Definition solver.h:125
pastix_int_t gbloknbr
Definition solver.h:225
pastix_int_t lrownum
Definition solver.h:148
pastix_int_t brownum
Definition solver.h:171
pastix_int_t priority
Definition solver.h:183
static pastix_int_t cblk_colnbr(const SolverCblk *cblk)
Compute the number of columns in a column block.
Definition solver.h:329
pastix_int_t brown2d
Definition solver.h:172
pastix_int_t fcblknm
Definition solver.h:144
pastix_int_t frownum
Definition solver.h:102
pastix_int_t gfaninnm
Definition solver.h:146
pastix_int_t cblknbr
Definition solver.h:211
pastix_int_t fcolnum
Definition solver.h:114
SolverBlok *restrict bloktab
Definition solver.h:229
pastix_int_t frownum
Definition solver.h:147
pastix_int_t brownbr
Definition solver.h:227
pastix_int_t gbloknm
Definition solver.h:145
pastix_int_t lcolnum
Definition solver.h:115
pastix_int_t gfaninbloknbr
Definition solver.h:226
pastix_int_t faninnbr
Definition solver.h:213
pastix_int_t prionum
Definition solver.h:124
SolverBlok * fblokptr
Definition solver.h:168
pastix_int_t bloknbr
Definition solver.h:224
pastix_int_t recvnbr
Definition solver.h:216
pastix_int_t *restrict browtab
Definition solver.h:230
pastix_int_t volatile ctrbcnt
Definition solver.h:127
pastix_int_t lcblknm
Definition solver.h:143
solver_blok_recv_t bloktab[1]
Definition solver.h:116
pastix_int_t lcolidx
Definition solver.h:170
int8_t inlast
Definition solver.h:151
SolverCblk *restrict cblktab
Definition solver.h:228
pastix_int_t stride
Definition solver.h:169
int8_t cblktype
Definition solver.h:164
pastix_int_t bloknum
Definition solver.h:126
Solver recv block structure.
Definition solver.h:101
Solver block structure.
Definition solver.h:141
Solver recv column block structure.
Definition solver.h:111
Solver column block structure.
Definition solver.h:161
Solver column block structure.
Definition solver.h:203
The task structure for the numerical factorization.
Definition solver.h:122