1 /******************************************************************************
2 * Copyright 1998-2019 Lawrence Livermore National Security, LLC and other
3 * HYPRE Project Developers. See the top-level COPYRIGHT file for details.
4 *
5 * SPDX-License-Identifier: (Apache-2.0 OR MIT)
6 ******************************************************************************/
7
8 /******************************************************************************
9 *
10 * HYPRE_ParCSRMatrix interface
11 *
12 *****************************************************************************/
13
14 #include "_hypre_parcsr_mv.h"
15
16 /*--------------------------------------------------------------------------
17 * HYPRE_ParCSRMatrixCreate
18 *--------------------------------------------------------------------------*/
19
20 HYPRE_Int
HYPRE_ParCSRMatrixCreate(MPI_Comm comm,HYPRE_BigInt global_num_rows,HYPRE_BigInt global_num_cols,HYPRE_BigInt * row_starts,HYPRE_BigInt * col_starts,HYPRE_Int num_cols_offd,HYPRE_Int num_nonzeros_diag,HYPRE_Int num_nonzeros_offd,HYPRE_ParCSRMatrix * matrix)21 HYPRE_ParCSRMatrixCreate( MPI_Comm comm,
22 HYPRE_BigInt global_num_rows,
23 HYPRE_BigInt global_num_cols,
24 HYPRE_BigInt *row_starts,
25 HYPRE_BigInt *col_starts,
26 HYPRE_Int num_cols_offd,
27 HYPRE_Int num_nonzeros_diag,
28 HYPRE_Int num_nonzeros_offd,
29 HYPRE_ParCSRMatrix *matrix )
30 {
31 if (!matrix)
32 {
33 hypre_error_in_arg(9);
34 return hypre_error_flag;
35 }
36
37 *matrix = (HYPRE_ParCSRMatrix)
38 hypre_ParCSRMatrixCreate(comm, global_num_rows, global_num_cols,
39 row_starts, col_starts, num_cols_offd,
40 num_nonzeros_diag, num_nonzeros_offd);
41
42 return hypre_error_flag;
43 }
44
45 /*--------------------------------------------------------------------------
46 * HYPRE_ParCSRMatrixDestroy
47 *--------------------------------------------------------------------------*/
48
49 HYPRE_Int
HYPRE_ParCSRMatrixDestroy(HYPRE_ParCSRMatrix matrix)50 HYPRE_ParCSRMatrixDestroy( HYPRE_ParCSRMatrix matrix )
51 {
52 return( hypre_ParCSRMatrixDestroy( (hypre_ParCSRMatrix *) matrix ) );
53 }
54
55 /*--------------------------------------------------------------------------
56 * HYPRE_ParCSRMatrixInitialize
57 *--------------------------------------------------------------------------*/
58
59 HYPRE_Int
HYPRE_ParCSRMatrixInitialize(HYPRE_ParCSRMatrix matrix)60 HYPRE_ParCSRMatrixInitialize( HYPRE_ParCSRMatrix matrix )
61 {
62 return ( hypre_ParCSRMatrixInitialize( (hypre_ParCSRMatrix *) matrix ) );
63 }
64
65 /*--------------------------------------------------------------------------
66 * HYPRE_ParCSRMatrixRead
67 *--------------------------------------------------------------------------*/
68
69 HYPRE_Int
HYPRE_ParCSRMatrixRead(MPI_Comm comm,const char * file_name,HYPRE_ParCSRMatrix * matrix)70 HYPRE_ParCSRMatrixRead( MPI_Comm comm,
71 const char *file_name,
72 HYPRE_ParCSRMatrix *matrix)
73 {
74 if (!matrix)
75 {
76 hypre_error_in_arg(3);
77 return hypre_error_flag;
78 }
79 *matrix = (HYPRE_ParCSRMatrix) hypre_ParCSRMatrixRead( comm, file_name );
80 return hypre_error_flag;
81 }
82
83 /*--------------------------------------------------------------------------
84 * HYPRE_ParCSRMatrixPrint
85 *--------------------------------------------------------------------------*/
86
87 HYPRE_Int
HYPRE_ParCSRMatrixPrint(HYPRE_ParCSRMatrix matrix,const char * file_name)88 HYPRE_ParCSRMatrixPrint( HYPRE_ParCSRMatrix matrix,
89 const char *file_name )
90 {
91 hypre_ParCSRMatrixPrint( (hypre_ParCSRMatrix *) matrix,
92 file_name );
93 return hypre_error_flag;
94 }
95
96 /*--------------------------------------------------------------------------
97 * HYPRE_ParCSRMatrixGetComm
98 *--------------------------------------------------------------------------*/
99
100 HYPRE_Int
HYPRE_ParCSRMatrixGetComm(HYPRE_ParCSRMatrix matrix,MPI_Comm * comm)101 HYPRE_ParCSRMatrixGetComm( HYPRE_ParCSRMatrix matrix,
102 MPI_Comm *comm )
103 {
104 if (!matrix)
105 {
106 hypre_error_in_arg(1);
107 return hypre_error_flag;
108 }
109 *comm = hypre_ParCSRMatrixComm((hypre_ParCSRMatrix *) matrix);
110
111 return hypre_error_flag;
112 }
113 /*--------------------------------------------------------------------------
114 * HYPRE_ParCSRMatrixGetDims
115 *--------------------------------------------------------------------------*/
116
117 HYPRE_Int
HYPRE_ParCSRMatrixGetDims(HYPRE_ParCSRMatrix matrix,HYPRE_BigInt * M,HYPRE_BigInt * N)118 HYPRE_ParCSRMatrixGetDims( HYPRE_ParCSRMatrix matrix,
119 HYPRE_BigInt *M,
120 HYPRE_BigInt *N )
121 {
122 if (!matrix)
123 {
124 hypre_error_in_arg(1);
125 return hypre_error_flag;
126 }
127 *M = hypre_ParCSRMatrixGlobalNumRows((hypre_ParCSRMatrix *) matrix);
128 *N = hypre_ParCSRMatrixGlobalNumCols((hypre_ParCSRMatrix *) matrix);
129
130 return hypre_error_flag;
131 }
132
133 /*--------------------------------------------------------------------------
134 * HYPRE_ParCSRMatrixGetRowPartitioning
135 *--------------------------------------------------------------------------*/
136
137 HYPRE_Int
HYPRE_ParCSRMatrixGetRowPartitioning(HYPRE_ParCSRMatrix matrix,HYPRE_BigInt ** row_partitioning_ptr)138 HYPRE_ParCSRMatrixGetRowPartitioning( HYPRE_ParCSRMatrix matrix,
139 HYPRE_BigInt **row_partitioning_ptr )
140 {
141 HYPRE_BigInt *row_partitioning, *row_starts;
142 HYPRE_Int num_procs, i;
143
144 if (!matrix)
145 {
146 hypre_error_in_arg(1);
147 return hypre_error_flag;
148 }
149
150 hypre_MPI_Comm_size(hypre_ParCSRMatrixComm((hypre_ParCSRMatrix *) matrix),
151 &num_procs);
152 row_starts = hypre_ParCSRMatrixRowStarts((hypre_ParCSRMatrix *) matrix);
153 if (!row_starts) return -1;
154 row_partitioning = hypre_CTAlloc(HYPRE_BigInt, num_procs+1, HYPRE_MEMORY_HOST);
155 for (i=0; i < num_procs + 1; i++)
156 row_partitioning[i] = row_starts[i];
157
158 *row_partitioning_ptr = row_partitioning;
159 return hypre_error_flag;
160 }
161
162 /*--------------------------------------------------------------------------
163 * HYPRE_ParCSRMatrixGetGlobalRowPartitioning
164 *--------------------------------------------------------------------------*/
165 HYPRE_Int
HYPRE_ParCSRMatrixGetGlobalRowPartitioning(HYPRE_ParCSRMatrix matrix,HYPRE_Int all_procs,HYPRE_BigInt ** row_partitioning_ptr)166 HYPRE_ParCSRMatrixGetGlobalRowPartitioning( HYPRE_ParCSRMatrix matrix,
167 HYPRE_Int all_procs,
168 HYPRE_BigInt **row_partitioning_ptr )
169 {
170 MPI_Comm comm;
171 HYPRE_Int my_id;
172 HYPRE_BigInt *row_partitioning = NULL;
173
174 if (!matrix)
175 {
176 hypre_error_in_arg(1);
177 return hypre_error_flag;
178 }
179
180 comm = hypre_ParCSRMatrixComm((hypre_ParCSRMatrix *) matrix);
181 hypre_MPI_Comm_rank(comm, &my_id);
182
183 HYPRE_Int num_procs;
184 HYPRE_BigInt row_start;
185
186 hypre_MPI_Comm_size(comm, &num_procs);
187 if (my_id == 0 || all_procs)
188 {
189 row_partitioning = hypre_CTAlloc(HYPRE_BigInt, num_procs+1, HYPRE_MEMORY_HOST);
190 }
191
192 row_start = hypre_ParCSRMatrixFirstRowIndex((hypre_ParCSRMatrix *) matrix);
193 if (all_procs)
194 {
195 hypre_MPI_Allgather(&row_start, 1, HYPRE_MPI_BIG_INT, row_partitioning,
196 1, HYPRE_MPI_BIG_INT, comm);
197 }
198 else
199 {
200 hypre_MPI_Gather(&row_start, 1, HYPRE_MPI_BIG_INT, row_partitioning,
201 1, HYPRE_MPI_BIG_INT, 0, comm);
202 }
203
204 if (my_id == 0 || all_procs)
205 {
206 row_partitioning[num_procs] = hypre_ParCSRMatrixGlobalNumRows((hypre_ParCSRMatrix *) matrix);
207 }
208
209 *row_partitioning_ptr = row_partitioning;
210
211 return hypre_error_flag;
212 }
213
214 /*--------------------------------------------------------------------------
215 * HYPRE_ParCSRMatrixGetColPartitioning
216 *--------------------------------------------------------------------------*/
217
218 HYPRE_Int
HYPRE_ParCSRMatrixGetColPartitioning(HYPRE_ParCSRMatrix matrix,HYPRE_BigInt ** col_partitioning_ptr)219 HYPRE_ParCSRMatrixGetColPartitioning( HYPRE_ParCSRMatrix matrix,
220 HYPRE_BigInt **col_partitioning_ptr )
221 {
222 HYPRE_BigInt *col_partitioning, *col_starts;
223 HYPRE_Int num_procs, i;
224
225 if (!matrix)
226 {
227 hypre_error_in_arg(1);
228 return hypre_error_flag;
229 }
230
231 hypre_MPI_Comm_size(hypre_ParCSRMatrixComm((hypre_ParCSRMatrix *) matrix),
232 &num_procs);
233 col_starts = hypre_ParCSRMatrixColStarts((hypre_ParCSRMatrix *) matrix);
234 if (!col_starts) return -1;
235 col_partitioning = hypre_CTAlloc(HYPRE_BigInt, num_procs+1, HYPRE_MEMORY_HOST);
236 for (i=0; i < num_procs + 1; i++)
237 col_partitioning[i] = col_starts[i];
238
239 *col_partitioning_ptr = col_partitioning;
240 return hypre_error_flag;
241 }
242
243 /*--------------------------------------------------------------------------
244 * HYPRE_ParCSRMatrixGetLocalRange
245 *--------------------------------------------------------------------------*/
246 /**
247 Returns range of rows and columns owned by this processor.
248 Not collective.
249
250 @return integer error code
251 @param HYPRE_ParCSRMatrix matrix [IN]
252 the matrix to be operated on.
253 @param HYPRE_Int *row_start [OUT]
254 the global number of the first row stored on this processor
255 @param HYPRE_Int *row_end [OUT]
256 the global number of the first row stored on this processor
257 @param HYPRE_Int *col_start [OUT]
258 the global number of the first column stored on this processor
259 @param HYPRE_Int *col_end [OUT]
260 the global number of the first column stored on this processor
261 */
262
263 HYPRE_Int
HYPRE_ParCSRMatrixGetLocalRange(HYPRE_ParCSRMatrix matrix,HYPRE_BigInt * row_start,HYPRE_BigInt * row_end,HYPRE_BigInt * col_start,HYPRE_BigInt * col_end)264 HYPRE_ParCSRMatrixGetLocalRange( HYPRE_ParCSRMatrix matrix,
265 HYPRE_BigInt *row_start,
266 HYPRE_BigInt *row_end,
267 HYPRE_BigInt *col_start,
268 HYPRE_BigInt *col_end )
269 {
270 if (!matrix)
271 {
272 hypre_error_in_arg(1);
273 return hypre_error_flag;
274 }
275
276 hypre_ParCSRMatrixGetLocalRange( (hypre_ParCSRMatrix *) matrix,
277 row_start, row_end, col_start, col_end );
278 return hypre_error_flag;
279 }
280
281 /*--------------------------------------------------------------------------
282 * HYPRE_ParCSRMatrixGetRow
283 *--------------------------------------------------------------------------*/
284
285 HYPRE_Int
HYPRE_ParCSRMatrixGetRow(HYPRE_ParCSRMatrix matrix,HYPRE_BigInt row,HYPRE_Int * size,HYPRE_BigInt ** col_ind,HYPRE_Complex ** values)286 HYPRE_ParCSRMatrixGetRow( HYPRE_ParCSRMatrix matrix,
287 HYPRE_BigInt row,
288 HYPRE_Int *size,
289 HYPRE_BigInt **col_ind,
290 HYPRE_Complex **values )
291 {
292 if (!matrix)
293 {
294 hypre_error_in_arg(1);
295 return hypre_error_flag;
296 }
297
298 hypre_ParCSRMatrixGetRow( (hypre_ParCSRMatrix *) matrix,
299 row, size, col_ind, values );
300 return hypre_error_flag;
301 }
302
303 /*--------------------------------------------------------------------------
304 * HYPRE_ParCSRMatrixRestoreRow
305 *--------------------------------------------------------------------------*/
306
307 HYPRE_Int
HYPRE_ParCSRMatrixRestoreRow(HYPRE_ParCSRMatrix matrix,HYPRE_BigInt row,HYPRE_Int * size,HYPRE_BigInt ** col_ind,HYPRE_Complex ** values)308 HYPRE_ParCSRMatrixRestoreRow( HYPRE_ParCSRMatrix matrix,
309 HYPRE_BigInt row,
310 HYPRE_Int *size,
311 HYPRE_BigInt **col_ind,
312 HYPRE_Complex **values )
313 {
314 if (!matrix)
315 {
316 hypre_error_in_arg(1);
317 return hypre_error_flag;
318 }
319
320 hypre_ParCSRMatrixRestoreRow( (hypre_ParCSRMatrix *) matrix,
321 row, size, col_ind, values );
322 return hypre_error_flag;
323 }
324
325 /*--------------------------------------------------------------------------
326 * HYPRE_CSRMatrixToParCSRMatrix
327 * Output argument (fifth argument): a new ParCSRmatrix.
328 * Input arguments: MPI communicator, CSR matrix, and optional partitionings.
329 * If you don't have partitionings, just pass a null pointer for the third
330 * and fourth arguments and they will be computed.
331 * Note that it is not possible to provide a null pointer if this is called
332 * from Fortran code; so you must provide the paritionings from Fortran.
333 *--------------------------------------------------------------------------*/
334
335 HYPRE_Int
HYPRE_CSRMatrixToParCSRMatrix(MPI_Comm comm,HYPRE_CSRMatrix A_CSR,HYPRE_BigInt * row_partitioning,HYPRE_BigInt * col_partitioning,HYPRE_ParCSRMatrix * matrix)336 HYPRE_CSRMatrixToParCSRMatrix( MPI_Comm comm,
337 HYPRE_CSRMatrix A_CSR,
338 HYPRE_BigInt *row_partitioning,
339 HYPRE_BigInt *col_partitioning,
340 HYPRE_ParCSRMatrix *matrix)
341 {
342 if (!matrix)
343 {
344 hypre_error_in_arg(5);
345 return hypre_error_flag;
346 }
347 *matrix = (HYPRE_ParCSRMatrix)
348 hypre_CSRMatrixToParCSRMatrix( comm, (hypre_CSRMatrix *) A_CSR,
349 row_partitioning, col_partitioning) ;
350 return hypre_error_flag;
351 }
352
353 /*--------------------------------------------------------------------------
354 * HYPRE_CSRMatrixToParCSRMatrix_WithNewPartitioning
355 * Output argument (third argument): a new ParCSRmatrix.
356 * Input arguments: MPI communicator, CSR matrix.
357 * Row and column partitionings are computed for the output matrix.
358 *--------------------------------------------------------------------------*/
359
360 HYPRE_Int
HYPRE_CSRMatrixToParCSRMatrix_WithNewPartitioning(MPI_Comm comm,HYPRE_CSRMatrix A_CSR,HYPRE_ParCSRMatrix * matrix)361 HYPRE_CSRMatrixToParCSRMatrix_WithNewPartitioning(
362 MPI_Comm comm,
363 HYPRE_CSRMatrix A_CSR,
364 HYPRE_ParCSRMatrix *matrix )
365 {
366 if (!matrix)
367 {
368 hypre_error_in_arg(3);
369 return hypre_error_flag;
370 }
371 *matrix = (HYPRE_ParCSRMatrix)
372 hypre_CSRMatrixToParCSRMatrix( comm, (hypre_CSRMatrix *) A_CSR, NULL, NULL ) ;
373 return hypre_error_flag;
374 }
375
376 /*--------------------------------------------------------------------------
377 * HYPRE_ParCSRMatrixMatvec
378 *--------------------------------------------------------------------------*/
379
380 HYPRE_Int
HYPRE_ParCSRMatrixMatvec(HYPRE_Complex alpha,HYPRE_ParCSRMatrix A,HYPRE_ParVector x,HYPRE_Complex beta,HYPRE_ParVector y)381 HYPRE_ParCSRMatrixMatvec( HYPRE_Complex alpha,
382 HYPRE_ParCSRMatrix A,
383 HYPRE_ParVector x,
384 HYPRE_Complex beta,
385 HYPRE_ParVector y )
386 {
387 return ( hypre_ParCSRMatrixMatvec(
388 alpha, (hypre_ParCSRMatrix *) A,
389 (hypre_ParVector *) x, beta, (hypre_ParVector *) y) );
390 }
391
392 /*--------------------------------------------------------------------------
393 * HYPRE_ParCSRMatrixMatvecT
394 *--------------------------------------------------------------------------*/
395
396 HYPRE_Int
HYPRE_ParCSRMatrixMatvecT(HYPRE_Complex alpha,HYPRE_ParCSRMatrix A,HYPRE_ParVector x,HYPRE_Complex beta,HYPRE_ParVector y)397 HYPRE_ParCSRMatrixMatvecT( HYPRE_Complex alpha,
398 HYPRE_ParCSRMatrix A,
399 HYPRE_ParVector x,
400 HYPRE_Complex beta,
401 HYPRE_ParVector y )
402 {
403 return ( hypre_ParCSRMatrixMatvecT(
404 alpha, (hypre_ParCSRMatrix *) A,
405 (hypre_ParVector *) x, beta, (hypre_ParVector *) y) );
406 }
407