PaStiX Handbook 6.4.0
Loading...
Searching...
No Matches
d_refine_bicgstab.c
Go to the documentation of this file.
1/**
2 *
3 * @file d_refine_bicgstab.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 Theophile Terraz
15 * @author Gregoire Pichon
16 * @author Vincent Bridonneau
17 * @date 2024-07-05
18 * @generated from /builds/2mk6rsew/0/solverstack/pastix/refinement/z_refine_bicgstab.c, normal z -> d, Tue Feb 25 14:36:03 2025
19 *
20 **/
21#include "common.h"
22#include "bcsc/bcsc.h"
23#include "d_refine_functions.h"
24
25/**
26 *******************************************************************************
27 *
28 * @ingroup pastix_refine
29 *
30 * d_bicgstab_smp - Function computing bicgstab iterative refinement.
31 *
32 *******************************************************************************
33 *
34 * @param[in] pastix_data
35 * The PaStiX data structure that describes the solver instance.
36 *
37 * @param[out] xp
38 * The solution vector.
39 *
40 * @param[in] bp
41 * The right hand side member (only one).
42 *
43 *******************************************************************************
44 *
45 * @return Number of iterations
46 *
47 *******************************************************************************/
50 pastix_rhs_t xp,
51 pastix_rhs_t bp )
52{
53 struct d_solver solver;
55 Clock refine_clk;
56 pastix_fixdbl_t t0 = 0;
57 pastix_fixdbl_t t3 = 0;
58 int itermax;
59 int nb_iter = 0;
60 int precond = 1;
61 double *x = (double*)(xp->b);
62 double *b = (double*)(bp->b);
63 double *gradr; /* Current solution */
64 double *gradr2;
65 double *gradp;
66 double *grady;
67 double *gradv;
68 double *grads;
69 double *gradz;
70 double *gradt;
71 double *grad2;
72 double *grad3;
73 float *sgrad = NULL;
74 double v1, v2, w;
75 double normb, normx, normr, alpha, beta;
76 double resid_b, eps;
77
78 memset( &solver, 0, sizeof(struct d_solver) );
79 d_refine_init( &solver, pastix_data );
80
81 if ( !(pastix_data->steps & STEP_NUMFACT) ) {
82 precond = 0;
83 }
84
85 n = pastix_data->bcsc->n;
86 itermax = pastix_data->iparm[IPARM_ITERMAX];
87 eps = pastix_data->dparm[DPARM_EPSILON_REFINEMENT];
88
89 gradr = (double *)solver.malloc(n * sizeof(double));
90 gradr2 = (double *)solver.malloc(n * sizeof(double));
91 gradp = (double *)solver.malloc(n * sizeof(double));
92 grady = (double *)solver.malloc(n * sizeof(double));
93 gradv = (double *)solver.malloc(n * sizeof(double));
94 grads = (double *)solver.malloc(n * sizeof(double));
95 gradz = (double *)solver.malloc(n * sizeof(double));
96 gradt = (double *)solver.malloc(n * sizeof(double));
97 grad2 = (double *)solver.malloc(n * sizeof(double));
98 grad3 = (double *)solver.malloc(n * sizeof(double));
99
100 /* Allocating a vector at half-precision, NULL pointer otherwise */
101 if ( pastix_data->iparm[IPARM_MIXED] )
102 {
103 sgrad = solver.malloc( n * sizeof(float) );
104 }
105
106 clockInit(refine_clk);clockStart(refine_clk);
107
108 normb = solver.norm( pastix_data, n, b );
109 if ( normb == 0. ) {
110 normb = 1;
111 }
112 normx = solver.norm( pastix_data, n, x );
113
114 /* r = b - Ax */
115 solver.copy( pastix_data, n, b, gradr );
116 if ( normx > 0. ) {
117 solver.spmv( pastix_data, PastixNoTrans, -1., x, 1., gradr );
118 }
119 normr = solver.norm( pastix_data, n, gradr );
120
121 /* r2 = r */
122 solver.copy( pastix_data, n, gradr, gradr2 );
123 /* p = r */
124 solver.copy( pastix_data, n, gradr, gradp );
125
126 /* resid_b = ||r|| / ||b|| */
127 resid_b = normr / normb;
128
129 while ((resid_b > eps) && (nb_iter < itermax))
130 {
131 clockStop((refine_clk));
132 t0 = clockGet();
133 nb_iter++;
134
135 /* y = M-1 * p */
136 solver.copy( pastix_data, n, gradp, grady );
137 if ( precond ) {
138 solver.spsv( pastix_data, grady, sgrad );
139 }
140
141 /* v = Ay */
142 solver.spmv( pastix_data, PastixNoTrans, 1.0, grady, 0., gradv );
143
144 /* alpha = (r, r2) / (v, r2) */
145 alpha = solver.dot( pastix_data, n, gradv, gradr2 );
146 beta = solver.dot( pastix_data, n, gradr, gradr2 );
147 alpha = beta / alpha;
148
149 /* s = r - alpha * v */
150 solver.copy( pastix_data, n, gradr, grads );
151 solver.axpy( pastix_data, n, -alpha, gradv, grads );
152
153 /* z = M^{-1} s */
154 solver.copy( pastix_data, n, grads, gradz );
155 if ( precond ) {
156 solver.spsv( pastix_data, gradz, sgrad );
157 }
158
159 /* t = Az */
160 solver.spmv( pastix_data, PastixNoTrans, 1.0, gradz, 0., gradt );
161
162 /* w = (M-1t, M-1s) / (M-1t, M-1t) */
163 /* grad2 = M-1t */
164 solver.copy( pastix_data, n, gradt, grad2 );
165 if ( precond ) {
166 solver.spsv( pastix_data, grad2, sgrad );
167 }
168
169 /* v1 = (M-1t, M-1s) */
170 /* v2 = (M-1t, M-1t) */
171 v1 = solver.dot( pastix_data, n, grad2, gradz );
172 v2 = solver.dot( pastix_data, n, grad2, grad2 );
173 w = v1 / v2;
174
175 /* x = x + alpha * y + w * z */
176 /* x = x + alpha * y */
177 solver.axpy( pastix_data, n, alpha, grady, x );
178
179 /* x = x + w * z */
180 solver.axpy( pastix_data, n, w, gradz, x );
181
182 /* r = s - w * t*/
183 solver.copy( pastix_data, n, grads, gradr );
184 solver.axpy( pastix_data, n, -w, gradt, gradr );
185
186 /* beta = (r', r2) / (r, r2) * (alpha / w) */
187 /* v1 = (r', r2) */
188 v1 = solver.dot( pastix_data, n, gradr, gradr2 );
189 v2 = alpha / w;
190
191 beta = v1 / beta;
192 beta = beta * v2;
193
194 /* p = r + beta * (p - w * v) */
195 /* p = p - w * v */
196 solver.axpy( pastix_data, n, -w, gradv, gradp );
197
198 /* p = r + beta * p */
199 solver.scal( pastix_data, n, beta, gradp );
200 solver.axpy( pastix_data, n, 1., gradr, gradp );
201
202 normr = solver.norm( pastix_data, n, gradr );
203 resid_b = normr / normb;
204
205 clockStop((refine_clk));
206 t3 = clockGet();
207 if ( ( pastix_data->iparm[IPARM_VERBOSE] > PastixVerboseNot ) &&
208 ( pastix_data->procnum == 0 ) ) {
209 solver.output_oneiter( t0, t3, resid_b, nb_iter );
210 }
211 }
212
213 solver.output_final(pastix_data, resid_b, nb_iter, t3, x, x);
214
215 solver.free((void*) gradr);
216 solver.free((void*) gradr2);
217 solver.free((void*) gradp);
218 solver.free((void*) grady);
219 solver.free((void*) gradv);
220 solver.free((void*) grads);
221 solver.free((void*) gradz);
222 solver.free((void*) gradt);
223 solver.free((void*) grad2);
224 solver.free((void*) grad3);
225 solver.free((void*) sgrad);
226
227 return nb_iter;
228}
BEGIN_C_DECLS typedef int pastix_int_t
Definition datatypes.h:51
double pastix_fixdbl_t
Definition datatypes.h:65
@ DPARM_EPSILON_REFINEMENT
Definition api.h:161
@ IPARM_MIXED
Definition api.h:139
@ IPARM_ITERMAX
Definition api.h:113
@ IPARM_VERBOSE
Definition api.h:36
@ PastixNoTrans
Definition api.h:445
@ PastixVerboseNot
Definition api.h:220
void d_refine_init(struct d_solver *, pastix_data_t *)
Initiate functions pointers to define basic operations.
pastix_int_t d_bicgstab_smp(pastix_data_t *pastix_data, pastix_rhs_t xp, pastix_rhs_t bp)
pastix_int_t * iparm
Definition pastixdata.h:70
double * dparm
Definition pastixdata.h:71
pastix_bcsc_t * bcsc
Definition pastixdata.h:102
pastix_int_t steps
Definition pastixdata.h:73
Main PaStiX data structure.
Definition pastixdata.h:68
Main PaStiX RHS structure.
Definition pastixdata.h:155