PaStiX Handbook  6.2.1
coeftab_zinit.c
Go to the documentation of this file.
1 /**
2  *
3  * @file coeftab_zinit.c
4  *
5  * Precision dependent coeficient array initialization routines.
6  *
7  * @copyright 2015-2021 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8  * Univ. Bordeaux. All rights reserved.
9  *
10  * @version 6.2.1
11  * @author Xavier Lacoste
12  * @author Pierre Ramet
13  * @author Mathieu Faverge
14  * @author Esragul Korkmaz
15  * @date 2021-05-05
16  *
17  * @generated from /builds/solverstack/pastix/sopalin/coeftab_zinit.c, normal z -> z, Tue Jul 27 19:17:35 2021
18  *
19  **/
20 #define _GNU_SOURCE 1
21 #include "common.h"
22 #include "blend/solver.h"
23 #include "bcsc/bcsc.h"
24 #include "sopalin/coeftab_z.h"
25 #include "pastix_zcores.h"
26 
27 /**
28  *******************************************************************************
29  *
30  * @brief Dump a single column block into a FILE in a human readale format.
31  *
32  * All non-zeroes coefficients are dumped in the format:
33  * i j val
34  * with one value per row.
35  *
36  *******************************************************************************
37  *
38  * @param[in] side
39  * Define which side of the cblk must be printed.
40  * @arg PastixLCoef if lower part only
41  * @arg PastixUCoef if upper part only
42  *
43  * @param[in] cblk
44  * The column block to dump into the file.
45  *
46  * @param[inout] stream
47  * The FILE structure opened in write mode.
48  *
49  *******************************************************************************/
50 void
52  const SolverCblk *cblk,
53  FILE *stream )
54 {
55  const pastix_complex64_t *coeftab = side == PastixUCoef ? cblk->ucoeftab : cblk->lcoeftab;
56  SolverBlok *blok;
57  pastix_int_t itercol;
58  pastix_int_t iterrow;
59  pastix_int_t coefindx;
60 
61  /* We don't know how to dump the compressed block for now */
62  if ( cblk->cblktype & CBLK_COMPRESSED ) {
63  fprintf(stderr, "coeftab_zcblkdump: Can't dump a compressed cblk\n");
64  return;
65  }
66 
67  for (itercol = cblk->fcolnum;
68  itercol <= cblk->lcolnum;
69  itercol++)
70  {
71  /* Diagonal Block */
72  blok = cblk->fblokptr;
73  coefindx = blok->coefind;
74  if (cblk->cblktype & CBLK_LAYOUT_2D) {
75  coefindx += (itercol - cblk->fcolnum) * blok_rownbr( blok );
76  }
77  else {
78  coefindx += (itercol - cblk->fcolnum) * cblk->stride;
79  }
80 
81  for (iterrow = blok->frownum;
82  iterrow <= blok->lrownum;
83  iterrow++, coefindx++)
84  {
85  if ((cabs( coeftab[coefindx] ) > 0.) &&
86  (itercol <= iterrow))
87  {
88  if ( side == PastixUCoef ) {
89 #if defined(PRECISION_z) || defined(PRECISION_c)
90  fprintf(stream, "%ld %ld (%13e,%13e) [U]\n",
91  (long)itercol, (long)iterrow,
92  creal(coeftab[coefindx]), cimag(coeftab[coefindx]));
93 #else
94  fprintf(stream, "%ld %ld %13e [U]\n",
95  (long)itercol, (long)iterrow,
96  coeftab[coefindx]);
97 #endif
98  }
99  else {
100 #if defined(PRECISION_z) || defined(PRECISION_c)
101  fprintf(stream, "%ld %ld (%13e,%13e) [L]\n",
102  (long)iterrow, (long)itercol,
103  creal(coeftab[coefindx]), cimag(coeftab[coefindx]));
104 #else
105  fprintf(stream, "%ld %ld %13e [L]\n",
106  (long)iterrow, (long)itercol,
107  coeftab[coefindx]);
108 #endif
109  }
110  }
111  }
112 
113  /* Off diagonal blocks */
114  blok++;
115  while( blok < (cblk+1)->fblokptr )
116  {
117  coefindx = blok->coefind;
118  if (cblk->cblktype & CBLK_LAYOUT_2D) {
119  coefindx += (itercol - cblk->fcolnum) * blok_rownbr( blok );
120  }
121  else {
122  coefindx += (itercol - cblk->fcolnum) * cblk->stride;
123  }
124 
125  for (iterrow = blok->frownum;
126  iterrow <= blok->lrownum;
127  iterrow++, coefindx++)
128  {
129  if (cabs( coeftab[coefindx]) > 0.)
130  {
131  if ( side == PastixUCoef ) {
132 #if defined(PRECISION_z) || defined(PRECISION_c)
133  fprintf(stream, "%ld %ld (%13e,%13e) [U]\n",
134  (long)itercol, (long)iterrow,
135  creal(coeftab[coefindx]), cimag(coeftab[coefindx]));
136 #else
137  fprintf(stream, "%ld %ld %13e [U]\n",
138  (long)itercol, (long)iterrow,
139  coeftab[coefindx]);
140 #endif
141  }
142  else {
143 #if defined(PRECISION_z) || defined(PRECISION_c)
144  fprintf(stream, "%ld %ld (%13e,%13e) [L]\n",
145  (long)iterrow, (long)itercol,
146  creal(coeftab[coefindx]), cimag(coeftab[coefindx]));
147 #else
148  fprintf(stream, "%ld %ld %13e [L]\n",
149  (long)iterrow, (long)itercol,
150  coeftab[coefindx]);
151 #endif
152  }
153  }
154  }
155  blok++;
156  }
157  }
158 }
159 
160 void coeftab_zcblkComputeILULevels( const SolverMatrix *solvmtx, SolverCblk *cblk )
161 {
162  /* If there are off diagonal supernodes in the column */
163  SolverBlok *blokB = cblk->fblokptr + 1; /* this diagonal block */
164  SolverBlok *lblkB = cblk[1].fblokptr; /* the next diagonal block */
165 
166  for (; blokB<lblkB; blokB++) {
167  SolverCblk *fcblk = solvmtx->cblktab + blokB->fcblknm;
168  SolverBlok *blokC = fcblk->fblokptr;
169  SolverBlok *blokA;
170 
171  /* If there are off-diagonal supernodes in the column*/
172  for (blokA=blokB; blokA<lblkB; blokA++) {
173  int lvl_AB;
174 
175  /* Find the facing block */
176  while ( !is_block_inside_fblock(blokA, blokC) ) {
177  blokC++;
178  assert( blokC < fcblk[1].fblokptr );
179  }
180 
181  /* Compute the level k of the block */
182  if ( (blokA->iluklvl == INT_MAX) ||
183  (blokB->iluklvl == INT_MAX) )
184  {
185  lvl_AB = INT_MAX;
186  }
187  else {
188  lvl_AB = blokA->iluklvl + blokB->iluklvl + 1;
189  }
190 
191  pastix_cblk_lock( fcblk );
192  blokC->iluklvl = pastix_imin( blokC->iluklvl,
193  lvl_AB );
194  assert( blokC->iluklvl >= 0 );
195  pastix_cblk_unlock( fcblk );
196  }
197 
198  pastix_atomic_dec_32b( &(fcblk->ctrbcnt) );
199  }
200 }
201 
202 void coeftab_zcblkComputePreselect( const SolverMatrix *solvmtx, SolverCblk *cblk )
203 {
204  /* If there are off diagonal supernodes in the column */
205  SolverBlok *blok = cblk->fblokptr + 1; /* this diagonal block */
206  SolverBlok *lblk = cblk[1].fblokptr; /* the next diagonal block */
207 
208  for (; blok<lblk; blok++) {
209  SolverCblk *fcblk = solvmtx->cblktab + blok->fcblknm;
210  int is_preselected = blok_is_preselected( cblk, blok, fcblk );
211 
212  if ( is_preselected ) {
213  blok->iluklvl = -1;
214  }
215  else {
216  blok->iluklvl = INT_MAX;
217  }
218  }
219 }
220 
221 /**
222  *******************************************************************************
223  *
224  * @brief Fully initialize a single cblk.
225  *
226  * The cblk is allocated, intialized from the bcsc, and compressed if necessary.
227  *
228  *******************************************************************************
229  *
230  * @param[in] side
231  * Define which side of the matrix must be initialized.
232  * @arg PastixLCoef if lower part only
233  * @arg PastixUCoef if upper part only
234  * @arg PastixLUCoef if both sides.
235  *
236  * @param[in] solvmtx
237  * The solver matrix data structure.
238  *
239  * @param[in] bcsc
240  * The internal block CSC structure to fill-in the matrix.
241  *
242  * @param[in] itercblk
243  * The index of the cblk to initialize.
244  *
245  * @param[inout] directory
246  * The pointer to the temporary directory where to store the output
247  * files. Used only if PASTIX_DEBUG_DUMP_COEFTAB is defined.
248  *
249  *******************************************************************************/
250 void
252  const SolverMatrix *solvmtx,
253  const pastix_bcsc_t *bcsc,
254  pastix_int_t itercblk,
255  const char *directory )
256 {
257  SolverCblk *cblk = solvmtx->cblktab + itercblk;
258  int ilukmax = solvmtx->lowrank.ilu_lvl;
259 
260  cpucblk_zalloc( side, cblk );
261  cpucblk_zfillin( side, solvmtx, bcsc, itercblk );
262 
263 #if defined(PASTIX_DEBUG_DUMP_COEFTAB)
264  /*
265  * Rk: This function is not in the kernel directory to avoid the double
266  * dependency with the pastix library due to pastix_fopenw()
267  */
268  {
269  FILE *f = NULL;
270  char *filename;
271  int rc;
272 
273  /* Lower part */
274  if ( side != PastixUCoef )
275  {
276  rc = asprintf( &filename, "Lcblk%05ld_init.txt", itercblk );
277  f = pastix_fopenw( directory, filename, "w" );
278  if ( f != NULL ) {
279  cpucblk_zdump( PastixLCoef, cblk, f );
280  fclose( f );
281  }
282  free( filename );
283  }
284 
285  /* Upper part */
286  if ( side != PastixLCoef )
287  {
288  rc = asprintf( &filename, "Ucblk%05ld_init.txt", itercblk );
289  f = pastix_fopenw( directory, filename, "w" );
290  if ( f != NULL ) {
291  cpucblk_zdump( PastixUCoef, cblk, f );
292  fclose( f );
293  }
294  free( filename );
295  }
296  (void)rc;
297  }
298 #endif /* defined(PASTIX_DEBUG_DUMP_COEFTAB) */
299 
300  /* Update ILU levels if needed */
301  if ( (ilukmax > 0) && (ilukmax < INT_MAX) ) {
302 #if defined(PASTIX_WITH_MPI)
303  /* For now, we can't compute ILU(k) levels in distributed */
304  if ( solvmtx->clustnbr == 1 )
305 #endif
306  {
307  do {} while( cblk->ctrbcnt > 0 );
308  coeftab_zcblkComputeILULevels( solvmtx, cblk );
309  }
310  }
311 
312  /**
313  * Try to compress the cblk if needs to be compressed
314  */
315  if ( (cblk->cblktype & CBLK_COMPRESSED) &&
316  (ilukmax < INT_MAX) )
317  {
318  cpucblk_zcompress( solvmtx, side, ilukmax, cblk );
319  }
320 
321  (void)directory;
322 }
solver_blok_s::frownum
pastix_int_t frownum
Definition: solver.h:112
solver.h
blok_rownbr
static pastix_int_t blok_rownbr(const SolverBlok *blok)
Compute the number of rows of a block.
Definition: solver.h:271
cpucblk_zfillin
void cpucblk_zfillin(pastix_coefside_t side, const SolverMatrix *solvmtx, const pastix_bcsc_t *bcsc, pastix_int_t itercblk)
Initialize the coeftab structure from the internal bcsc.
Definition: cpucblk_zinit.c:509
solver_cblk_s::fblokptr
SolverBlok * fblokptr
Definition: solver.h:134
cpucblk_zinit
void cpucblk_zinit(pastix_coefside_t side, const SolverMatrix *solvmtx, const pastix_bcsc_t *bcsc, pastix_int_t itercblk, const char *directory)
Fully initialize a single cblk.
Definition: coeftab_zinit.c:251
pastix_bcsc_s
Internal column block distributed CSC matrix.
Definition: bcsc.h:37
solver_cblk_s::stride
pastix_int_t stride
Definition: solver.h:135
solver_cblk_s
Solver column block structure.
Definition: solver.h:127
pastix_coefside_t
enum pastix_coefside_e pastix_coefside_t
Data blocks used in the kernel.
solver_blok_s
Solver block structure.
Definition: solver.h:107
pastix_zcores.h
solver_cblk_s::ctrbcnt
volatile uint32_t ctrbcnt
Definition: solver.h:129
solver_cblk_s::ucoeftab
void * ucoeftab
Definition: solver.h:143
is_block_inside_fblock
static int is_block_inside_fblock(const SolverBlok *blok, const SolverBlok *fblok)
Check if a block is included inside another one.
Definition: solver.h:384
solver_blok_s::iluklvl
int iluklvl
Definition: solver.h:118
bcsc.h
cpucblk_zdump
void cpucblk_zdump(pastix_coefside_t side, const SolverCblk *cblk, FILE *stream)
Dump a single column block into a FILE in a human readale format.
Definition: coeftab_zinit.c:51
solver_cblk_s::lcoeftab
void * lcoeftab
Definition: solver.h:142
blok_is_preselected
static int blok_is_preselected(const SolverCblk *cblk, const SolverBlok *blok, const SolverCblk *fcbk)
Return if a block is preselected as either part of the projection, or as a sub-diagonal block.
Definition: solver.h:308
PastixUCoef
@ PastixUCoef
Definition: api.h:455
pastix_fopenw
FILE * pastix_fopenw(const char *dirname, const char *filename, const char *mode)
Open a file in the unique directory of the pastix instance.
Definition: api.c:232
PastixLCoef
@ PastixLCoef
Definition: api.h:454
solver_blok_s::coefind
pastix_int_t coefind
Definition: solver.h:114
cpucblk_zalloc
void cpucblk_zalloc(pastix_coefside_t side, SolverCblk *cblk)
Allocate the cblk structure to store the coefficient.
Definition: cpucblk_zinit.c:170
solver_cblk_s::cblktype
int8_t cblktype
Definition: solver.h:130
coeftab_z.h
solver_cblk_s::fcolnum
pastix_int_t fcolnum
Definition: solver.h:132
cpucblk_zcompress
pastix_int_t cpucblk_zcompress(const SolverMatrix *solvmtx, pastix_coefside_t side, int max_ilulvl, SolverCblk *cblk)
Compress a single column block from full-rank to low-rank format.
Definition: cpucblk_zcompress.c:116
solver_blok_s::fcblknm
pastix_int_t fcblknm
Definition: solver.h:110