SpM Handbook 1.2.4
Loading...
Searching...
No Matches
z_spm_rhs.c
Go to the documentation of this file.
1/**
2 *
3 * @file z_spm_rhs.c
4 *
5 * SParse Matrix package right hand side precision dependant routines.
6 *
7 * @copyright 2020-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8 * Univ. Bordeaux. All rights reserved.
9 *
10 * @version 1.2.4
11 * @author Mathieu Faverge
12 * @author Tony Delarue
13 * @author Alycia Lisito
14 * @date 2024-06-25
15 *
16 * @generated from /builds/2mk6rsew/0/fpruvost/spm/src/z_spm_rhs.c, normal z -> z, Fri Nov 29 11:34:31 2024
17 *
18 * @ingroup spm_dev_rhs
19 * @{
20 *
21 **/
22#include "common.h"
23
24/**
25 *******************************************************************************
26 *
27 * @brief Stores the local values of a global RHS in the local one.
28 *
29 *******************************************************************************
30 *
31 * @param[in] nrhs
32 * Number of rhs vectors.
33 *
34 * @param[in] spm
35 * The sparse matrix spm
36 *
37 * @param[inout] bglob
38 * The global RHS.
39 *
40 * @param[in] ldbg
41 * Leading dimension of the global bglob matrix.
42 *
43 * @param[inout] bloc
44 * Local rhs matrix.
45 *
46 * @param[in] ldbl
47 * Leading dimension of the local bloc vector.
48 *
49 *******************************************************************************/
50void
52 const spmatrix_t *spm,
53 const spm_complex64_t *bglob,
54 spm_int_t ldbg,
55 spm_complex64_t *bloc,
56 spm_int_t ldbl )
57{
58 spm_complex64_t *rhs = bloc;
59 spm_int_t *loc2glob;
60 spm_int_t i, ig, row, dofi;
61 spm_int_t m, k, baseval;
62
63 assert( !spm->replicated );
64 baseval = spm->baseval;
65 loc2glob = spm->loc2glob;
66 for( i=0; i<spm->n; i++, loc2glob++ )
67 {
68 ig = *loc2glob - baseval;
69 dofi = ( spm->dof > 0 ) ? spm->dof : spm->dofs[ig+1] - spm->dofs[ig];
70 row = ( spm->dof > 0 ) ? spm->dof * ig : spm->dofs[ig] - baseval;
71 for( m=0; m<nrhs; m++ )
72 {
73 for ( k=0; k<dofi; k++)
74 {
75 rhs[ m * ldbl + k ] = bglob[ m * ldbg + row + k ];
76 }
77 }
78 rhs += dofi;
79 }
80}
81
82/**
83 *******************************************************************************
84 *
85 * @brief Reduce all the global coefficients of a rhs and store the local ones
86 *
87 *******************************************************************************
88 *
89 * @param[in] nrhs
90 * Number of rhs vectors.
91 *
92 * @param[in] spm
93 * The sparse matrix spm
94 *
95 * @param[inout] bglob
96 * The global rhs to reduce.
97 *
98 * @param[in] ldbg
99 * Leading dimension of the global bglob matrix.
100 *
101 * @param[inout] bloc
102 * Local rhs matrix.
103 *
104 * @param[in] ldbl
105 * Leading dimension of the local bloc matrix.
106 *
107 *******************************************************************************/
108void
110 const spmatrix_t *spm,
111 spm_complex64_t *bglob,
112 spm_int_t ldbg,
113 spm_complex64_t *bloc,
114 spm_int_t ldbl )
115{
116
117 if ( spm->replicated ) {
118 assert( ldbl == ldbg );
119 memcpy( bloc, bglob, spm->gNexp * nrhs * sizeof( spm_complex64_t ) );
120 }
121#if defined(SPM_WITH_MPI)
122 else {
123 /* Reduce all the globals RHS */
124 MPI_Allreduce( MPI_IN_PLACE, bglob, ldbg * nrhs, SPM_MPI_COMPLEX64, MPI_SUM, spm->comm );
125
126 /* Get the local values of bglob in bloc */
127 z_spmExtractLocalRHS( nrhs, spm, bglob, ldbg, bloc, ldbl );
128 }
129#endif
130 (void)ldbg;
131 (void)ldbl;
132}
133
134/**
135 *******************************************************************************
136 *
137 * @brief Gather all the global C coefficients and store the good ones in local
138 *
139 *******************************************************************************
140 *
141 * @param[in] spm
142 * The sparse matrix spm
143 *
144 * @param[in] nrhs
145 * Number of rhs vectors.
146 *
147 * @param[in] b
148 * The local RHS array of size ldb-by-nrhs.
149 *
150 * @param[in] ldb
151 * The leading dimension of the b array. ldb >= max(1, spm->nexp)
152 *
153 * @param[in] root
154 * Clustnum where the complete vector will be gathered.
155 * -1 if you want to gather the data on all nodes.
156 *
157 * @param[inout] bg
158 * On entry, the allocated ldbg-by-nrhs array to store the gathered RHS.
159 *
160 * @param[in] ldbg
161 * The leading dimension of the bg array. ldbg >= max(1, spm->gNexp)
162 *
163 *******************************************************************************/
164void
166 const spmatrix_t *spm,
167 const spm_complex64_t *b,
168 spm_int_t ldb,
169 int root,
170 spm_complex64_t *bg,
171 spm_int_t ldbg )
172{
173 /* We do not handle cases where ldb is different from spm->n */
174 assert( (spm->nexp == 0) || (ldb == spm->nexp) );
175
176 /* We do not handle cases where ldbg is different from spm->gN */
177 assert( (spm->gNexp == 0) || (ldbg == spm->gNexp) );
178
179 if ( spm->replicated ) {
180 if ( ( root == -1 ) || ( root == spm->clustnum ) ) {
181 memcpy( bg, b, spm->gNexp * nrhs * sizeof( spm_complex64_t ) );
182 }
183 (void)ldb;
184 (void)ldbg;
185 return;
186 }
187
188#if defined(SPM_WITH_MPI)
189 int c;
190 int n, nmax = 0;
191 int nexp, nexpmax = 0;
192 spm_complex64_t *tmp_out, *current_out, *outptr;
193 spm_int_t *tmp_l2g, *current_l2g;
194 spm_int_t current_n, current_nexp;
195 spm_int_t i, j, k, ig, dofi, row;
196 spm_int_t baseval = spm->baseval;
197
198 n = spm->n;
199 nexp = spm->nexp;
200 if ( root == -1 ) {
201 MPI_Allreduce( &n, &nmax, 1, MPI_INT, MPI_MAX, spm->comm );
202 MPI_Allreduce( &nexp, &nexpmax, 1, MPI_INT, MPI_MAX, spm->comm );
203 }
204 else {
205 MPI_Reduce( &n, &nmax, 1, MPI_INT, MPI_MAX, root, spm->comm );
206 MPI_Reduce( &nexp, &nexpmax, 1, MPI_INT, MPI_MAX, root, spm->comm );
207 }
208
209 if ( ( root == -1 ) || ( root == spm->clustnum ) ) {
210 tmp_out = malloc( nexpmax * nrhs * sizeof( spm_complex64_t ) );
211 tmp_l2g = malloc( nmax * sizeof( spm_int_t ) );
212
213 for ( c=0; c<spm->clustnbr; c++ ) {
214 MPI_Status status;
215
216 if ( c == spm->clustnum ) {
217 current_n = spm->n;
218 current_nexp = spm->nexp;
219 current_l2g = spm->loc2glob;
220 current_out = (spm_complex64_t *)b;
221 }
222 else {
223 current_n = 0;
224 current_nexp = 0;
225 current_l2g = tmp_l2g;
226 current_out = tmp_out;
227 }
228
229 if ( root == -1 ) {
230 MPI_Bcast( &current_n, 1, SPM_MPI_INT, c, spm->comm );
231 MPI_Bcast( &current_nexp, 1, SPM_MPI_INT, c, spm->comm );
232 if ( current_n > 0 ) {
233 MPI_Bcast( current_l2g, current_n, SPM_MPI_INT, c, spm->comm );
234 MPI_Bcast( current_out, current_nexp * nrhs, SPM_MPI_COMPLEX64, c, spm->comm );
235 }
236 }
237 else if ( root != c ) { /* No communication if c == root */
238 assert( root == spm->clustnum );
239 MPI_Recv( &current_n, 1, SPM_MPI_INT, c, 0, spm->comm, &status );
240 MPI_Recv( &current_nexp, 1, SPM_MPI_INT, c, 1, spm->comm, &status );
241 if ( current_n > 0 ) {
242 MPI_Recv( current_l2g, current_n, SPM_MPI_INT, c, 2, spm->comm, &status );
243 MPI_Recv( current_out, current_nexp * nrhs, SPM_MPI_COMPLEX64, c, 3, spm->comm, &status );
244 }
245 }
246
247 outptr = bg;
248 for ( i=0; i<current_n; i++, current_l2g++ ) {
249 ig = *current_l2g - baseval;
250 dofi = ( spm->dof > 0 ) ? spm->dof : spm->dofs[ig+1] - spm->dofs[ig];
251 row = ( spm->dof > 0 ) ? spm->dof * ig : spm->dofs[ig] - baseval;
252 for ( j=0; j<nrhs; j++ ) {
253 for ( k=0; k<dofi; k++ ) {
254 outptr[ row + j * spm->gNexp + k ] = current_out[ j * current_nexp + k ];
255 }
256 }
257 current_out += dofi;
258 }
259 }
260
261 free( tmp_out );
262 free( tmp_l2g );
263 }
264 else {
265 current_n = spm->n;
266 current_nexp = spm->nexp;
267 current_l2g = spm->loc2glob;
268 current_out = (spm_complex64_t*)b;
269
270 MPI_Send( &current_n, 1, SPM_MPI_INT, root, 0, spm->comm );
271 MPI_Send( &current_nexp, 1, SPM_MPI_INT, root, 1, spm->comm );
272 if ( current_n > 0 ) {
273 MPI_Send( current_l2g, current_n, SPM_MPI_INT, root, 2, spm->comm );
274 MPI_Send( current_out, current_nexp * nrhs, SPM_MPI_COMPLEX64, root, 3, spm->comm );
275 }
276 }
277#endif
278 return;
279}
280
281/**
282 * @}
283 */
void z_spmReduceRHS(int nrhs, const spmatrix_t *spm, spm_complex64_t *bglob, spm_int_t ldbg, spm_complex64_t *bloc, spm_int_t ldbl)
Reduce all the global coefficients of a rhs and store the local ones.
Definition z_spm_rhs.c:109
void z_spmGatherRHS(int nrhs, const spmatrix_t *spm, const spm_complex64_t *b, spm_int_t ldb, int root, spm_complex64_t *bg, spm_int_t ldbg)
Gather all the global C coefficients and store the good ones in local.
Definition z_spm_rhs.c:165
void z_spmExtractLocalRHS(int nrhs, const spmatrix_t *spm, const spm_complex64_t *bglob, spm_int_t ldbg, spm_complex64_t *bloc, spm_int_t ldbl)
Stores the local values of a global RHS in the local one.
Definition z_spm_rhs.c:51
spm_int_t * dofs
Definition spm.h:85
spm_int_t nexp
Definition spm.h:78
int clustnbr
Definition spm.h:96
spm_int_t dof
Definition spm.h:82
spm_int_t n
Definition spm.h:73
spm_int_t * loc2glob
Definition spm.h:91
SPM_Comm comm
Definition spm.h:97
spm_int_t baseval
Definition spm.h:71
spm_int_t gNexp
Definition spm.h:77
int clustnum
Definition spm.h:95
int replicated
Definition spm.h:98
#define SPM_MPI_INT
The MPI type associated to spm_int_t.
Definition datatypes.h:72
int spm_int_t
The main integer datatype used in spm arrays.
Definition datatypes.h:70
The sparse matrix data structure.
Definition spm.h:64