PaStiX Handbook 6.4.0
Loading...
Searching...
No Matches
pastix_task_refine.c
Go to the documentation of this file.
1/**
2 *
3 * @file pastix_task_refine.c
4 *
5 * PaStiX refinement functions implementations.
6 *
7 * @copyright 2015-2024 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 Pierre Ramet
13 * @author Xavier Lacoste
14 * @author Gregoire Pichon
15 * @author Tony Delarue
16 * @author Alycia Lisito
17 * @date 2024-07-05
18 *
19 **/
20#include "common.h"
21#include "bcsc/bcsc.h"
26#include "pastix/order.h"
27
28/**
29 *******************************************************************************
30 *
31 * @ingroup pastix_dev_refine
32 *
33 * @brief Select the refinement function to call depending on the matrix type
34 * and the precision
35 *
36 *******************************************************************************/
38
39#ifndef DOXYGEN_SHOULD_SKIP_THIS
40static refine_fct_t sopalinRefine[4][4] =
41{
42 /* PastixRefineGMRES */
43 {
48 },
49 /* PastixRefineCG */
50 {
55 },
56 /* PastixRefineSR */
57 {
62 },
63 /* PastixRefineBiCGSTAB */
64 {
69 }
70};
71#endif /* DOXYGEN_SHOULD_SKIP_THIS */
72
73/**
74 *******************************************************************************
75 *
76 * @ingroup pastix_refine
77 *
78 * @brief Perform the iterative refinement without apply the permutations.
79 *
80 * This routine is affected by the following parameters:
81 * IPARM_REFINEMENT, DPARM_EPSILON_REFINEMENT
82 *
83 *******************************************************************************
84 *
85 * @param[in] pastix_data
86 * The PaStiX data structure that describes the solver instance.
87 *
88 * @param[inout] Bp
89 * The right hand side matrix of size ldb-by-nrhs.
90 * B is noted as inout, as permutation might be performed on the
91 * matrix. On exit, the matrix is restored as it was on entry.
92 *
93 * @param[inout] Xp
94 * The matrix x of size ldx-by-nrhs.
95 * On entry, the initial guess x0 for the refinement step, that may be
96 * the solution returned by the solve step or any other initial guess.
97 * On exit, contains the final solution after the iterative refinement.
98 *
99 *******************************************************************************
100 *
101 * @retval PASTIX_SUCCESS on successful exit,
102 * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect,
103 *
104 *******************************************************************************/
105int
107 pastix_rhs_t Bp,
108 pastix_rhs_t Xp )
109{
110 pastix_int_t *iparm = pastix_data->iparm;
111 pastix_bcsc_t *bcsc = pastix_data->bcsc;
112 double timer;
113 pastix_int_t n = Bp->m;
114 pastix_int_t nrhs = Bp->n;
115 pastix_int_t ldb = Bp->ld;
116 pastix_int_t ldx = Xp->ld;
117 const void *b = Bp->b;
118 void *x = Xp->b;
119 int prevnt;
120
121 if (nrhs > 1)
122 {
123 pastix_print_warning( "Refinement works only with 1 rhs, We will iterate on each RHS one by one\n" );
124 }
125
126 if ( (pastix_data->schur_n > 0) && (iparm[IPARM_SCHUR_SOLV_MODE] != PastixSolvModeLocal))
127 {
128 fprintf(stderr, "Refinement is not available with Schur complement when non local solve is required\n");
130 }
131
132 /* Prepare the refinement threshold, if not set by the user */
133 if ( pastix_data->dparm[DPARM_EPSILON_REFINEMENT] < 0. ) {
134 int isDouble = (bcsc->flttype == PastixDouble) || (bcsc->flttype == PastixComplex64);
135 if ( (!isDouble) ) {
136 pastix_data->dparm[DPARM_EPSILON_REFINEMENT] = 1e-6;
137 }
138 else {
139 pastix_data->dparm[DPARM_EPSILON_REFINEMENT] = 1e-12;
140 }
141 }
142
144
145 clockSyncStart( timer, pastix_data->inter_node_comm );
146 {
147 refine_fct_t refinefct = sopalinRefine[iparm[IPARM_REFINEMENT]][pastix_data->bcsc->flttype -2];
148 char *xptr = (char *)x;
149 char *bptr = (char *)b;
150 size_t shiftx, shiftb;
151 int i;
152
153 shiftx = ldx * pastix_size_of( Xp->flttype );
154 shiftb = ldb * pastix_size_of( Bp->flttype );
155 Bp->n = 1;
156 Xp->n = 1;
157
158 for(i=0; i<nrhs; i++, xptr += shiftx, bptr += shiftb ) {
159 pastix_int_t it;
160 Bp->b = bptr;
161 Xp->b = xptr;
162 it = refinefct( pastix_data, Xp, Bp );
163 pastix_data->iparm[IPARM_NBITER] = pastix_imax( it, pastix_data->iparm[IPARM_NBITER] );
164 }
165
166 Bp->n = nrhs;
167 Bp->b = (void*)b;
168 Xp->n = nrhs;
169 Xp->b = (void*)x;
170 }
171 clockSyncStop( timer, pastix_data->inter_node_comm );
172
173 pastixBlasSetNumThreads( prevnt );
174
175 pastix_data->dparm[DPARM_REFINE_TIME] = clockVal(timer);
176 if ( iparm[IPARM_VERBOSE] > PastixVerboseNot ) {
177 pastix_print( pastix_data->inter_node_procnum,
178 0, OUT_TIME_REFINE,
179 pastix_data->dparm[DPARM_REFINE_TIME] );
180 }
181
182 (void)n;
183 return PASTIX_SUCCESS;
184}
185
186/**
187 *******************************************************************************
188 *
189 * @ingroup pastix_users
190 *
191 * @brief Perform iterative refinement.
192 *
193 * This routine performs the permutation of x, and b before and after the
194 * iterative refinement solution. To prevent extra permuation to happen, see
195 * pastix_subtask_refine().
196 * This routine is affected by the following parameters:
197 * IPARM_REFINEMENT, DPARM_EPSILON_REFINEMENT
198 *
199 *******************************************************************************
200 *
201 * @param[in] pastix_data
202 * The PaStiX data structure that describes the solver instance.
203 *
204 * @param[in] m
205 * The size of system to solve, and the number of rows of both
206 * matrices b and x.
207 *
208 * @param[in] nrhs
209 * The number of right hand side members, and the number of columns of
210 * b and x.
211 *
212 * @param[inout] b
213 * The right hand side matrix of size ldb-by-nrhs.
214 * B is noted as inout, as permutation might be performed on the
215 * matrix. On exit, the matrix is restored as it was on entry.
216 *
217 * @param[in] ldb
218 * The leading dimension of the matrix b. ldb >= n.
219 *
220 * @param[inout] x
221 * The matrix x of size ldx-by-nrhs.
222 * On entry, the initial guess x0 for the refinement step, that may be
223 * the solution returned by the solve step or any other initial guess.
224 * On exit, contains the final solution after the iterative refinement.
225 *
226 * @param[in] ldx
227 * The leading dimension of the matrix x. ldx >= n.
228 *
229 *******************************************************************************
230 *
231 * @retval PASTIX_SUCCESS on successful exit,
232 * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect,
233 *
234 *******************************************************************************/
235int
237 pastix_int_t m,
238 pastix_int_t nrhs,
239 void *b,
240 pastix_int_t ldb,
241 void *x,
242 pastix_int_t ldx )
243{
244 pastix_int_t *iparm = pastix_data->iparm;
245 pastix_rhs_t Bp, Xp;
246 int rc;
247
248 if ( (pastix_data->schur_n > 0) && (iparm[IPARM_SCHUR_SOLV_MODE] != PastixSolvModeLocal))
249 {
250 fprintf(stderr, "Refinement is not available with Schur complement when non local solve is required\n");
252 }
253
254 /* Compute P * b */
255 rc = pastixRhsInit( &Bp );
256 if( rc != PASTIX_SUCCESS ) {
257 return rc;
258 }
259
260 rc = pastix_subtask_applyorder( pastix_data, PastixDirForward, m, nrhs, b, ldb, Bp );
261 if( rc != PASTIX_SUCCESS ) {
262 return rc;
263 }
264
265 /* Compute P * x */
266 rc = pastixRhsInit( &Xp );
267 if( rc != PASTIX_SUCCESS ) {
268 return rc;
269 }
270
271 rc = pastix_subtask_applyorder( pastix_data, PastixDirForward, m, nrhs, x, ldx, Xp );
272 if( rc != PASTIX_SUCCESS ) {
273 return rc;
274 }
275
276 /* Performe the iterative refinement */
277 rc = pastix_subtask_refine( pastix_data, Bp, Xp );
278 if( rc != PASTIX_SUCCESS ) {
279 return rc;
280 }
281
282 /* Compute P * b */
283 rc = pastix_subtask_applyorder( pastix_data, PastixDirBackward, m, nrhs, b, ldb, Bp );
284 if( rc != PASTIX_SUCCESS ) {
285 return rc;
286 }
287 rc = pastixRhsFinalize( Bp );
288 if( rc != PASTIX_SUCCESS ) {
289 return rc;
290 }
291
292 /* Compute P * x */
293 rc = pastix_subtask_applyorder( pastix_data, PastixDirBackward, m, nrhs, x, ldx, Xp );
294 if( rc != PASTIX_SUCCESS ) {
295 return rc;
296 }
297
298 rc = pastixRhsFinalize( Xp );
299 if( rc != PASTIX_SUCCESS ) {
300 return rc;
301 }
302
303 (void)m;
304 return rc;
305}
306
307/**
308 *******************************************************************************
309 *
310 * @ingroup pastix_users
311 *
312 * @brief Performs solve and iterative refinement without unnecessary
313 * permutations.
314 *
315 * This routine performs the permutation of x and b before and after the solve
316 * and iterative refinement solution. This prevent the permutation of x at
317 * the end of the solve and the permutations of x and b at the beginnning of the
318 * refinement when the user wants to perfom both solve and refinement.
319 * This routine is affected by the following parameters:
320 * IPARM_REFINEMENT, DPARM_EPSILON_REFINEMENT, IPARM_VERBOSE,
321 * IPARM_FACTORIZATION, IPARM_TRANSPOSE_SOLVE
322 *
323 *******************************************************************************
324 *
325 * @param[in] pastix_data
326 * The PaStiX data structure that describes the solver instance.
327 *
328 * @param[in] m
329 * The size of system to solve, and the number of rows of both
330 * matrices b and x.
331 *
332 * @param[in] nrhs
333 * The number of right hand side members, and the number of columns of
334 * b and x.
335 *
336 * @param[inout] b
337 * The right hand side matrix of size ldb-by-nrhs.
338 * B is noted as inout, as permutation might be performed on the
339 * matrix. On exit, the matrix is restored as it was on entry.
340 *
341 * @param[in] ldb
342 * The leading dimension of the matrix b. ldb >= n.
343 *
344 * @param[inout] x
345 * The matrix x of size ldx-by-nrhs.
346 * On entry, a copy of b.
347 * On exit, contains the final solution after the iterative refinement.
348 *
349 * @param[in] ldx
350 * The leading dimension of the matrix x. ldx >= n.
351 *
352 *******************************************************************************
353 *
354 * @retval PASTIX_SUCCESS on successful exit,
355 * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect,
356 *
357 *******************************************************************************/
358int
360 pastix_int_t m,
361 pastix_int_t nrhs,
362 void *b,
363 pastix_int_t ldb,
364 void *x,
365 pastix_int_t ldx )
366{
367 pastix_int_t *iparm;
368 pastix_rhs_t Bp, Xp;
369 int rc;
370
371 /*
372 * Checks parameters
373 */
374 if (pastix_data == NULL) {
375 pastix_print_error( "pastix_task_solve_and_refine: wrong pastix_data parameter" );
377 }
378 iparm = pastix_data->iparm;
379
380 if ( !(pastix_data->steps & STEP_NUMFACT) ) {
381 pastix_print_error( "pastix_task_solve_and_refine: Numerical factorization hasn't been done." );
383 }
384
385 if ( (pastix_data->schur_n > 0) && (iparm[IPARM_SCHUR_SOLV_MODE] != PastixSolvModeLocal))
386 {
387 fprintf(stderr, "Refinement is not available with Schur complement when non local solve is required\n");
389 }
390
391
392 /* Computes P * b */
393 rc = pastixRhsInit( &Bp );
394 if( rc != PASTIX_SUCCESS ) {
395 return rc;
396 }
397
398 rc = pastix_subtask_applyorder( pastix_data, PastixDirForward, m, nrhs, b, ldb, Bp );
399 if( rc != PASTIX_SUCCESS ) {
400 return rc;
401 }
402
403 /* Computes P * x */
404 rc = pastixRhsInit( &Xp );
405 if( rc != PASTIX_SUCCESS ) {
406 return rc;
407 }
408
409 rc = pastix_subtask_applyorder( pastix_data, PastixDirForward, m, nrhs, x, ldx, Xp );
410 if( rc != PASTIX_SUCCESS ) {
411 return rc;
412 }
413
414 /* Solves A x = b */
415 rc = pastix_subtask_solve( pastix_data, Xp );
416 if( rc != PASTIX_SUCCESS ) {
417 return rc;
418 }
419
420 /* Performs the iterative refinement */
421 rc = pastix_subtask_refine( pastix_data, Bp, Xp );
422 if( rc != PASTIX_SUCCESS ) {
423 return rc;
424 }
425
426 /* Computes P^t * P * b */
427 rc = pastix_subtask_applyorder( pastix_data, PastixDirBackward, m, nrhs, b, ldb, Bp );
428 if( rc != PASTIX_SUCCESS ) {
429 return rc;
430 }
431 rc = pastixRhsFinalize( Bp );
432 if( rc != PASTIX_SUCCESS ) {
433 return rc;
434 }
435
436 /* Computes P^t * P * x */
437 rc = pastix_subtask_applyorder( pastix_data, PastixDirBackward, m, nrhs, x, ldx, Xp );
438 if( rc != PASTIX_SUCCESS ) {
439 return rc;
440 }
441
442 rc = pastixRhsFinalize( Xp );
443 if( rc != PASTIX_SUCCESS ) {
444 return rc;
445 }
446
447 (void)m;
448 return rc;
449}
BEGIN_C_DECLS typedef int pastix_int_t
Definition datatypes.h:51
int pastixRhsInit(pastix_rhs_t *rhs)
Initialize an RHS data structure.
Definition pastix_rhs.c:44
int pastixRhsFinalize(pastix_rhs_t rhs)
Cleanup an RHS data structure.
Definition pastix_rhs.c:92
int pastixBlasSetNumThreadsOne(void)
Set the number of threads for blas calls (BLIS, MKL, OpenBLAS) to 1 and return the previous number of...
Definition api.c:1179
int pastixBlasSetNumThreads(int nt)
Set the number of threads for blas calls (BLIS, MKL, OpenBLAS) and return the previous number of blas...
Definition api.c:1147
@ PastixDirForward
Definition api.h:513
@ PastixDirBackward
Definition api.h:514
@ DPARM_REFINE_TIME
Definition api.h:182
@ DPARM_EPSILON_REFINEMENT
Definition api.h:161
@ IPARM_REFINEMENT
Definition api.h:111
@ IPARM_VERBOSE
Definition api.h:36
@ IPARM_NBITER
Definition api.h:112
@ IPARM_SCHUR_SOLV_MODE
Definition api.h:107
@ PastixVerboseNot
Definition api.h:220
@ PASTIX_SUCCESS
Definition api.h:367
@ PASTIX_ERR_BADPARAMETER
Definition api.h:374
pastix_int_t d_gmres_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t c_gmres_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t s_grad_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t s_gmres_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t d_pivot_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t s_pivot_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t z_grad_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t c_bicgstab_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t c_grad_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t c_pivot_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t z_bicgstab_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t z_pivot_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t z_gmres_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t s_bicgstab_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t(* refine_fct_t)(pastix_data_t *, pastix_rhs_t, pastix_rhs_t)
Select the refinement function to call depending on the matrix type and the precision.
pastix_int_t d_bicgstab_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t d_grad_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
int pastix_subtask_refine(pastix_data_t *pastix_data, pastix_rhs_t Bp, pastix_rhs_t Xp)
Perform the iterative refinement without apply the permutations.
int pastix_subtask_applyorder(pastix_data_t *pastix_data, pastix_dir_t dir, pastix_int_t m, pastix_int_t n, void *B, pastix_int_t ldb, pastix_rhs_t Bp)
Apply a permutation on the right-and-side vector before the solve step.
int pastix_subtask_solve(pastix_data_t *pastix_data, pastix_rhs_t b)
Solve the given problem without applying the permutation.
int inter_node_procnum
Definition pastixdata.h:84
pastix_int_t * iparm
Definition pastixdata.h:70
pastix_int_t ld
Definition pastixdata.h:160
double * dparm
Definition pastixdata.h:71
pastix_coeftype_t flttype
Definition pastixdata.h:157
pastix_int_t schur_n
Definition pastixdata.h:94
PASTIX_Comm inter_node_comm
Definition pastixdata.h:78
pastix_int_t m
Definition pastixdata.h:158
pastix_bcsc_t * bcsc
Definition pastixdata.h:102
pastix_int_t steps
Definition pastixdata.h:73
pastix_int_t n
Definition pastixdata.h:159
int pastix_task_refine(pastix_data_t *pastix_data, pastix_int_t m, pastix_int_t nrhs, void *b, pastix_int_t ldb, void *x, pastix_int_t ldx)
Perform iterative refinement.
int pastix_task_solve_and_refine(pastix_data_t *pastix_data, pastix_int_t m, pastix_int_t nrhs, void *b, pastix_int_t ldb, void *x, pastix_int_t ldx)
Performs solve and iterative refinement without unnecessary permutations.
Main PaStiX data structure.
Definition pastixdata.h:68
Main PaStiX RHS structure.
Definition pastixdata.h:155