PaStiX Handbook  6.4.0
schur.c
Go to the documentation of this file.
1 /**
2  *
3  * @file sopalin/schur.c
4  *
5  * PaStiX schur interface functions
6  *
7  * @copyright 2017-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  * @date 2024-07-05
15  *
16  * @addtogroup pastix_schur
17  * @{
18  *
19  **/
20 #include "common.h"
21 #include <spm.h>
22 #include <lapacke.h>
23 #include "blend/solver.h"
24 #include "sopalin/coeftab_z.h"
25 #include "sopalin/coeftab_c.h"
26 #include "sopalin/coeftab_d.h"
27 #include "sopalin/coeftab_s.h"
28 
29 /**
30  *******************************************************************************
31  *
32  * @brief Set a list of unknowns that needs to be isolated and pushed at the end
33  * of the ordering before the Schur unknowns if any.
34  *
35  * Remark: This is usually required when some unknowns are disconnected or
36  * zeroes appear on the diagonal.
37  *
38  *******************************************************************************
39  *
40  * @param[inout] pastix_data
41  * The pastix data structure of the solver to store the list of unknowns.
42  *
43  * @param[in] n
44  * The number of unknowns hat needs to be isolated.
45  *
46  * @param[in] list
47  * Array of integer of size n.
48  * The list of unknowns to isolate.
49  *
50  *******************************************************************************/
51 void
53  pastix_int_t n,
54  const pastix_int_t *list )
55 {
56  if ( n > 0 ) {
57  pastix_data->zeros_n = n;
58  pastix_data->zeros_list = (pastix_int_t*)malloc(n * sizeof(pastix_int_t));
59  memcpy( pastix_data->zeros_list, list, n * sizeof(pastix_int_t) );
60  }
61 }
62 
63 /**
64  *******************************************************************************
65  *
66  * @brief Set the list of unknowns that belongs to the schur complement.
67  *
68  *******************************************************************************
69  *
70  * @param[inout] pastix_data
71  * The pastix data structure of the solver to store the list of Schur
72  * unknowns.
73  *
74  * @param[in] n
75  * The number of unknowns in the Schur complement.
76  *
77  * @param[in] list
78  * Array of integer of size n.
79  * The list of unknowns belonging to the Schur complement with the same
80  * baseval as the associated spm.
81  *
82  *******************************************************************************/
83 void
85  pastix_int_t n,
86  const pastix_int_t *list )
87 {
88  if ( n > 0 ) {
89  pastix_data->schur_n = n;
90  pastix_data->schur_list = (pastix_int_t*)malloc(n * sizeof(pastix_int_t));
91  memcpy( pastix_data->schur_list, list, n * sizeof(pastix_int_t) );
92  }
93 }
94 
95 /**
96  *******************************************************************************
97  *
98  * @brief Return the Schur complement.
99  *
100  * The Schur complement is returned in the column major layout used by the
101  * classic linear algebra libraries such as Blas or Lapack.
102  *
103  *******************************************************************************
104  *
105  * @param[in] pastix_data
106  * The pastix data structure of the problem solved.
107  *
108  * @param[inout] S
109  * Array of size spm->n -by- lds of arithmetic spm->flttype, where spm
110  * is the spm of the original problem.
111  * On exit, the array contains the Schur complement of the factorized
112  * matrix.
113  *
114  * @param[in] lds
115  * The leading dimension of the S array.
116  *
117  ********************************************************************************
118  *
119  * @retval PASTIX_SUCCESS on successful exit,
120  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect.
121  *
122  *******************************************************************************/
123 int
124 pastixGetSchur( const pastix_data_t *pastix_data,
125  void *S,
126  pastix_int_t lds )
127 {
128  pastix_int_t *iparm;
129 
130  /*
131  * Check parameters
132  */
133  if (pastix_data == NULL) {
134  pastix_print_error( "pastix_getSchur: wrong pastix_data parameter" );
136  }
137  if (S == NULL) {
138  pastix_print_error( "pastix_getSchur: S parameter" );
140  }
141  if (lds <= 0) {
142  pastix_print_error( "pastix_getSchur: lds parameter" );
144  }
145  if ( !(pastix_data->steps & STEP_NUMFACT) ) {
146  pastix_print_error( "pastix_getSchur: All steps from pastix_task_init() to pastix_task_numfact() have to be called before calling this function" );
148  }
149 #if defined(PASTIX_WITH_MPI)
150  if (pastix_data->inter_node_procnbr > 1) {
151  if ( pastix_data->inter_node_procnum == 0 ) {
152  pastix_print_error( "pastix_getSchur: Schur complement is not available yet with multiple MPI processes\n" );
153  }
154  return -1;
155  }
156 #endif
157 
158  iparm = pastix_data->iparm;
159  switch(iparm[IPARM_FLOAT])
160  {
161  case PastixPattern:
162  break;
163  case PastixFloat:
164  coeftab_sgetschur( pastix_data->solvmatr, S, lds );
165  break;
166  case PastixComplex32:
167  coeftab_cgetschur( pastix_data->solvmatr, S, lds );
168  break;
169  case PastixComplex64:
170  coeftab_zgetschur( pastix_data->solvmatr, S, lds );
171  break;
172  case PastixDouble:
173  default:
174  coeftab_dgetschur( pastix_data->solvmatr, S, lds );
175  }
176  return PASTIX_SUCCESS;
177 }
178 
179 /**
180  *******************************************************************************
181  *
182  * @ingroup pastix_solve
183  *
184  * @brief Get the vector in an RHS data structure.
185  *
186  *******************************************************************************
187  *
188  * @param[in] pastix_data
189  * TODO
190  *
191  * @param[in] m
192  * The number of rows of the vector b, must be equal to the number of
193  * unknowns in the Schur complement.
194  *
195  * @param[in] n
196  * The number of columns of the vector b.
197  *
198  * @param[in] rhsB
199  * The pastix_rhs_t data structure used to solve the system.
200  *
201  * @param[inout] B
202  * On entry, a vector of size ldb-by-n.
203  * On exit, the m-by-n leading part contains the right hand side
204  * related to the Schur part.
205  *
206  * @param[in] ldb
207  * The leading dimension of the vector b.
208  *
209  *******************************************************************************
210  *
211  * @retval PASTIX_SUCCESS on successful exit,
212  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect.
213  *
214  *******************************************************************************/
215 int
216 pastixRhsSchurGet( const pastix_data_t *pastix_data,
217  pastix_int_t m,
218  pastix_int_t n,
219  pastix_rhs_t rhsB,
220  void *B,
221  pastix_int_t ldb )
222 {
223  const SolverMatrix *solvmtx;
224  const SolverCblk *cblk;
225  pastix_int_t mschur;
226  void *bptr;
227  int rc;
228 
229  if ( pastix_data == NULL ) {
230  pastix_print_error( "pastixRhsSchurGet: wrong pastix_data parameter" );
232  }
233  if ( rhsB == NULL ) {
234  pastix_print_error( "pastixRhsSchurGet: wrong rhsB parameter" );
236  }
237  if ( B == NULL ) {
238  pastix_print_error( "pastixRhsSchurGet: wrong b parameter" );
240  }
241 
242  solvmtx = pastix_data->solvmatr;
243  cblk = solvmtx->cblktab + solvmtx->cblkschur;
244  mschur = solvmtx->nodenbr - cblk->fcolnum;
245 
246  if ( m != mschur ) {
247  pastix_print_error( "pastixRhsSchurGet: wrong m parameter expecting %ld but was %ld\n",
248  (long)mschur, (long)m );
250  }
251  if ( n != rhsB->n ) {
252  pastix_print_error( "pastixRhsSchurGet: wrong n parameter expecting %ld but was %ld\n",
253  (long)rhsB->n, (long)n );
255  }
256  if ( ldb < m ) {
257  pastix_print_error( "pastixRhsSchurGet: wrong ldb parameter\n" );
259  }
260 
261  bptr = ((char *)rhsB->b) + cblk->lcolidx * pastix_size_of( rhsB->flttype );
262 
263  switch( rhsB->flttype ) {
264  case SpmComplex64:
265  rc = LAPACKE_zlacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, (pastix_complex64_t *)bptr, rhsB->ld, B, ldb );
266  break;
267  case SpmComplex32:
268  rc = LAPACKE_clacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, (pastix_complex32_t *)bptr, rhsB->ld, B, ldb );
269  break;
270  case SpmDouble:
271  rc = LAPACKE_dlacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, (double *)bptr, rhsB->ld, B, ldb );
272  break;
273  case SpmFloat:
274  rc = LAPACKE_slacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, (float *)bptr, rhsB->ld, B, ldb );
275  break;
276  default:
277  pastix_print_error( "pastixRhsSchurGet: unknown flttype\n" );
279  }
280 
281  return rc;
282 }
283 
284 /**
285  *******************************************************************************
286  *
287  * @ingroup pastix_solve
288  *
289  * @brief Set the vector in an RHS data structure.
290  *
291  *******************************************************************************
292  *
293  * @param[in] pastix_data
294  * TODO
295  *
296  * @param[in] m
297  * The number of rows of the vector b.
298  *
299  * @param[in] n
300  * The number of columns of the vector b.
301  *
302  * @param[in] B
303  * The vector b.
304  *
305  * @param[in] ldb
306  * The leading dimension of the vector b.
307  *
308  * @param[out] rhsB
309  * The pastix_rhs_t data structure which contains the vector b.
310  *
311  *******************************************************************************
312  *
313  * @retval PASTIX_SUCCESS on successful exit,
314  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect.
315  *
316  *******************************************************************************/
317 int
318 pastixRhsSchurSet( const pastix_data_t *pastix_data,
319  pastix_int_t m,
320  pastix_int_t n,
321  void *B,
322  pastix_int_t ldb,
323  pastix_rhs_t rhsB )
324 {
325  const SolverMatrix *solvmtx;
326  const SolverCblk *cblk;
327  pastix_int_t mschur;
328  void *bptr;
329  int rc;
330 
331  if ( pastix_data == NULL ) {
332  pastix_print_error( "pastixRhsSchurSet: wrong pastix_data parameter" );
334  }
335  if ( rhsB == NULL ) {
336  pastix_print_error( "pastixRhsSchurSet: wrong rhsB parameter" );
338  }
339  if ( B == NULL ) {
340  pastix_print_error( "pastixRhsSchurSet: wrong b parameter" );
342  }
343 
344  solvmtx = pastix_data->solvmatr;
345  cblk = solvmtx->cblktab + solvmtx->cblkschur;
346  mschur = solvmtx->nodenbr - cblk->fcolnum;
347 
348  if ( m != mschur ) {
349  pastix_print_error( "pastixRhsSchurSet: wrong m parameter expecting %ld but was %ld\n",
350  (long)mschur, (long)m );
352  }
353  if ( n != rhsB->n ) {
354  pastix_print_error( "pastixRhsSchurSet: wrong n parameter expecting %ld but was %ld\n",
355  (long)rhsB->n, (long)n );
357  }
358  if ( ldb < m ) {
359  pastix_print_error( "pastixRhsSchurSet: wrong ldb parameter\n" );
361  }
362 
363  bptr = ((char *)rhsB->b) + cblk->lcolidx * pastix_size_of( rhsB->flttype );
364 
365  switch( rhsB->flttype ) {
366  case SpmComplex64:
367  rc = LAPACKE_zlacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, B, ldb, (pastix_complex64_t *)bptr, rhsB->ld );
368  break;
369  case SpmComplex32:
370  rc = LAPACKE_clacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, B, ldb, (pastix_complex32_t *)bptr, rhsB->ld );
371  break;
372  case SpmDouble:
373  rc = LAPACKE_dlacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, B, ldb, (double *)bptr, rhsB->ld );
374  break;
375  case SpmFloat:
376  rc = LAPACKE_slacpy_work( LAPACK_COL_MAJOR, 'A', mschur, n, B, ldb, (float *)bptr, rhsB->ld );
377  break;
378  default:
379  pastix_print_error( "pastixRhsSchurSet: unknown flttype\n" );
381  }
382 
383  return rc;
384 }
385 
386 /**
387  * @}
388  */
BEGIN_C_DECLS typedef int pastix_int_t
Definition: datatypes.h:51
float _Complex pastix_complex32_t
Definition: datatypes.h:76
void coeftab_sgetschur(const SolverMatrix *solvmtx, float *S, pastix_int_t lds)
Extract the Schur complement.
Definition: coeftab_s.c:607
void coeftab_dgetschur(const SolverMatrix *solvmtx, double *S, pastix_int_t lds)
Extract the Schur complement.
Definition: coeftab_d.c:607
void coeftab_zgetschur(const SolverMatrix *solvmtx, pastix_complex64_t *S, pastix_int_t lds)
Extract the Schur complement.
Definition: coeftab_z.c:607
void coeftab_cgetschur(const SolverMatrix *solvmtx, pastix_complex32_t *S, pastix_int_t lds)
Extract the Schur complement.
Definition: coeftab_c.c:607
@ IPARM_FLOAT
Definition: api.h:149
@ PASTIX_SUCCESS
Definition: api.h:367
@ PASTIX_ERR_BADPARAMETER
Definition: api.h:374
void pastixSetSchurUnknownList(pastix_data_t *pastix_data, pastix_int_t n, const pastix_int_t *list)
Set the list of unknowns that belongs to the schur complement.
Definition: schur.c:84
int pastixGetSchur(const pastix_data_t *pastix_data, void *S, pastix_int_t lds)
Return the Schur complement.
Definition: schur.c:124
void pastixIsolateUnknowns(pastix_data_t *pastix_data, pastix_int_t n, const pastix_int_t *list)
Set a list of unknowns that needs to be isolated and pushed at the end of the ordering before the Sch...
Definition: schur.c:52
int pastixRhsSchurSet(const pastix_data_t *pastix_data, pastix_int_t m, pastix_int_t n, void *B, pastix_int_t ldb, pastix_rhs_t rhsB)
Set the vector in an RHS data structure.
Definition: schur.c:318
int pastixRhsSchurGet(const pastix_data_t *pastix_data, pastix_int_t m, pastix_int_t n, pastix_rhs_t rhsB, void *B, pastix_int_t ldb)
Get the vector in an RHS data structure.
Definition: schur.c:216
int inter_node_procnum
Definition: pastixdata.h:84
SolverMatrix * solvmatr
Definition: pastixdata.h:103
int inter_node_procnbr
Definition: pastixdata.h:83
pastix_int_t zeros_n
Definition: pastixdata.h:96
pastix_int_t * iparm
Definition: pastixdata.h:70
pastix_int_t ld
Definition: pastixdata.h:160
pastix_coeftype_t flttype
Definition: pastixdata.h:157
pastix_int_t schur_n
Definition: pastixdata.h:94
pastix_int_t * schur_list
Definition: pastixdata.h:95
pastix_int_t * zeros_list
Definition: pastixdata.h:97
pastix_int_t steps
Definition: pastixdata.h:73
pastix_int_t n
Definition: pastixdata.h:159
Main PaStiX data structure.
Definition: pastixdata.h:68
Main PaStiX RHS structure.
Definition: pastixdata.h:155
pastix_int_t nodenbr
Definition: solver.h:208
pastix_int_t lcolidx
Definition: solver.h:170
SolverCblk *restrict cblktab
Definition: solver.h:228
pastix_int_t cblkschur
Definition: solver.h:221
pastix_int_t fcolnum
Definition: solver.h:166
Solver column block structure.
Definition: solver.h:161
Solver column block structure.
Definition: solver.h:203