MFEM  v4.6.0
Finite element discretization library
hypre_parcsr.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010-2023, Lawrence Livermore National Security, LLC. Produced
2 // at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3 // LICENSE and NOTICE for details. LLNL-CODE-806117.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability visit https://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the BSD-3 license. We welcome feedback and contributions, see file
10 // CONTRIBUTING.md for details.
11 
12 #ifndef MFEM_HYPRE_PARCSR_HPP
13 #define MFEM_HYPRE_PARCSR_HPP
14 
15 #include "../config/config.hpp"
16 
17 #ifdef MFEM_USE_MPI
18 
19 // Enable internal hypre timing routines
20 #define HYPRE_TIMING
21 
22 #include "../general/mem_manager.hpp"
23 #include "_hypre_parcsr_mv.h"
24 
25 // Older hypre versions do not define HYPRE_BigInt and HYPRE_MPI_BIG_INT, so we
26 // define them here for backward compatibility.
27 #if MFEM_HYPRE_VERSION < 21600
28 typedef HYPRE_Int HYPRE_BigInt;
29 #define HYPRE_MPI_BIG_INT HYPRE_MPI_INT
30 #endif
31 
32 // Define macro wrappers for hypre_TAlloc, hypre_CTAlloc and hypre_TFree:
33 // mfem_hypre_TAlloc, mfem_hypre_CTAlloc, and mfem_hypre_TFree, respectively.
34 // Note: these macros are used in hypre.cpp, hypre_parcsr.cpp, and perhaps
35 // other locations in the future.
36 #if MFEM_HYPRE_VERSION < 21400
37 
38 #define mfem_hypre_TAlloc(type, size) hypre_TAlloc(type, size)
39 #define mfem_hypre_CTAlloc(type, size) hypre_CTAlloc(type, size)
40 #define mfem_hypre_TFree(ptr) hypre_TFree(ptr)
41 
42 #define mfem_hypre_TAlloc_host(type, size) hypre_TAlloc(type, size)
43 #define mfem_hypre_CTAlloc_host(type, size) hypre_CTAlloc(type, size)
44 #define mfem_hypre_TFree_host(ptr) hypre_TFree(ptr)
45 
46 #else // MFEM_HYPRE_VERSION >= 21400
47 
48 #define mfem_hypre_TAlloc(type, size) \
49  hypre_TAlloc(type, size, HYPRE_MEMORY_DEVICE)
50 #define mfem_hypre_CTAlloc(type, size) \
51  hypre_CTAlloc(type, size, HYPRE_MEMORY_DEVICE)
52 #define mfem_hypre_TFree(ptr) hypre_TFree(ptr, HYPRE_MEMORY_DEVICE)
53 
54 #define mfem_hypre_TAlloc_host(type, size) \
55  hypre_TAlloc(type, size, HYPRE_MEMORY_HOST)
56 #define mfem_hypre_CTAlloc_host(type, size) \
57  hypre_CTAlloc(type, size, HYPRE_MEMORY_HOST)
58 #define mfem_hypre_TFree_host(ptr) hypre_TFree(ptr, HYPRE_MEMORY_HOST)
59 
60 // Notes regarding allocation and deallocation of hypre objects in 2.14.0
61 //-----------------------------------------------------------------------
62 //
63 // 1. hypre_CSRMatrix: i, j, data, and rownnz use HYPRE_MEMORY_SHARED while the
64 // hypre_CSRMatrix structure uses HYPRE_MEMORY_HOST.
65 //
66 // Note: the function HYPRE_CSRMatrixCreate creates the i array using
67 // HYPRE_MEMORY_HOST!
68 // Note: the functions hypre_CSRMatrixAdd and hypre_CSRMatrixMultiply create
69 // C_i using HYPRE_MEMORY_HOST!
70 //
71 // 2. hypre_Vector: data uses HYPRE_MEMORY_SHARED while the hypre_Vector
72 // structure uses HYPRE_MEMORY_HOST.
73 //
74 // 3. hypre_ParVector: the structure hypre_ParVector uses HYPRE_MEMORY_HOST;
75 // partitioning uses HYPRE_MEMORY_HOST.
76 //
77 // 4. hypre_ParCSRMatrix: the structure hypre_ParCSRMatrix uses
78 // HYPRE_MEMORY_HOST; col_map_offd, row_starts, col_starts, rowindices,
79 // rowvalues also use HYPRE_MEMORY_HOST.
80 //
81 // Note: the function hypre_ParCSRMatrixToCSRMatrixAll allocates matrix_i
82 // using HYPRE_MEMORY_HOST!
83 //
84 // 5. The goal for the MFEM wrappers of hypre objects is to support only the
85 // standard hypre build case, i.e. when hypre is build without device support
86 // and all memory types correspond to host memory. In this case memory
87 // allocated with operator new can be used by hypre but (as usual) it must
88 // not be owned by hypre.
89 
90 #endif // #if MFEM_HYPRE_VERSION < 21400
91 
92 namespace mfem
93 {
94 
95 // This module contains functions that are logically part of HYPRE, and might
96 // become part of HYPRE at some point. In the meantime the module can be
97 // thought of as an extension of HYPRE.
98 
100 {
103 };
104 
105 namespace internal
106 {
107 
108 /** Parallel essential BC elimination from the system A*X = B.
109  (Adapted from hypre_ParCSRMatrixEliminateRowsCols.) */
110 void hypre_ParCSRMatrixEliminateAXB(hypre_ParCSRMatrix *A,
111  HYPRE_Int num_rowscols_to_elim,
112  HYPRE_Int *rowscols_to_elim,
113  hypre_ParVector *X,
114  hypre_ParVector *B);
115 
116 /** Parallel essential BC elimination from matrix A only. The eliminated
117  elements are stored in a new matrix Ae, so that (A + Ae) equals the original
118  matrix A. */
119 void hypre_ParCSRMatrixEliminateAAe(hypre_ParCSRMatrix *A,
120  hypre_ParCSRMatrix **Ae,
121  HYPRE_Int num_rowscols_to_elim,
122  HYPRE_Int *rowscols_to_elim,
123  int ignore_rows = 0);
124 
125 /** Eliminate rows from a hypre ParCSRMatrix, setting all entries in the listed
126  rows of the matrix to zero. */
127 void hypre_ParCSRMatrixEliminateRows(hypre_ParCSRMatrix *A,
128  HYPRE_Int num_rows_to_elim,
129  const HYPRE_Int *rows_to_elim);
130 
131 /** Split matrix 'A' into nr x nc blocks, return nr x nc pointers to
132  new parallel matrices. The array 'blocks' needs to be preallocated to hold
133  nr x nc pointers. If 'interleaved' == 0 the matrix is split into contiguous
134  blocks (AAABBBCCC) otherwise the blocks are interleaved (ABCABCABC).
135  The local number of rows of A must be divisible by nr. The local number of
136  columns of A must be divisible by nc. */
137 void hypre_ParCSRMatrixSplit(hypre_ParCSRMatrix *A,
138  HYPRE_Int nr, HYPRE_Int nc,
139  hypre_ParCSRMatrix **blocks,
140  int interleaved_rows, int interleaved_cols);
141 
142 typedef int HYPRE_Bool;
143 #define HYPRE_MPI_BOOL MPI_INT
144 
145 /// Computes y = alpha * |A| * x + beta * y, using entry-wise absolute values of matrix A
146 void hypre_CSRMatrixAbsMatvec(hypre_CSRMatrix *A,
147  HYPRE_Real alpha,
148  HYPRE_Real *x,
149  HYPRE_Real beta,
150  HYPRE_Real *y);
151 
152 /// Computes y = alpha * |At| * x + beta * y, using entry-wise absolute values of the transpose of matrix A
153 void hypre_CSRMatrixAbsMatvecT(hypre_CSRMatrix *A,
154  HYPRE_Real alpha,
155  HYPRE_Real *x,
156  HYPRE_Real beta,
157  HYPRE_Real *y);
158 
159 /// Computes y = alpha * |A| * x + beta * y, using entry-wise absolute values of matrix A
160 void hypre_ParCSRMatrixAbsMatvec(hypre_ParCSRMatrix *A,
161  HYPRE_Real alpha,
162  HYPRE_Real *x,
163  HYPRE_Real beta,
164  HYPRE_Real *y);
165 
166 /// Computes y = alpha * |At| * x + beta * y, using entry-wise absolute values of the transpose of matrix A
167 void hypre_ParCSRMatrixAbsMatvecT(hypre_ParCSRMatrix *A,
168  HYPRE_Real alpha,
169  HYPRE_Real *x,
170  HYPRE_Real beta,
171  HYPRE_Real *y);
172 
173 /** The "Boolean" analog of y = alpha * A * x + beta * y, where elements in the
174  sparsity pattern of the CSR matrix A are treated as "true". */
175 void hypre_CSRMatrixBooleanMatvec(hypre_CSRMatrix *A,
176  HYPRE_Bool alpha,
177  HYPRE_Bool *x,
178  HYPRE_Bool beta,
179  HYPRE_Bool *y);
180 
181 /** The "Boolean" analog of y = alpha * A^T * x + beta * y, where elements in
182  the sparsity pattern of the CSR matrix A are treated as "true". */
183 void hypre_CSRMatrixBooleanMatvecT(hypre_CSRMatrix *A,
184  HYPRE_Bool alpha,
185  HYPRE_Bool *x,
186  HYPRE_Bool beta,
187  HYPRE_Bool *y);
188 
189 hypre_ParCSRCommHandle *
190 hypre_ParCSRCommHandleCreate_bool(HYPRE_Int job,
191  hypre_ParCSRCommPkg *comm_pkg,
192  HYPRE_Bool *send_data,
193  HYPRE_Bool *recv_data);
194 
195 /** The "Boolean" analog of y = alpha * A * x + beta * y, where elements in the
196  sparsity pattern of the ParCSR matrix A are treated as "true". */
197 void hypre_ParCSRMatrixBooleanMatvec(hypre_ParCSRMatrix *A,
198  HYPRE_Bool alpha,
199  HYPRE_Bool *x,
200  HYPRE_Bool beta,
201  HYPRE_Bool *y);
202 
203 /** The "Boolean" analog of y = alpha * A^T * x + beta * y, where elements in
204  the sparsity pattern of the ParCSR matrix A are treated as "true". */
205 void hypre_ParCSRMatrixBooleanMatvecT(hypre_ParCSRMatrix *A,
206  HYPRE_Bool alpha,
207  HYPRE_Bool *x,
208  HYPRE_Bool beta,
209  HYPRE_Bool *y);
210 
211 /** Perform the operation A += beta*B, assuming that the sparsity pattern of A
212  contains that of B. */
213 HYPRE_Int
214 hypre_CSRMatrixSum(hypre_CSRMatrix *A,
215  HYPRE_Complex beta,
216  hypre_CSRMatrix *B);
217 
218 #if MFEM_HYPRE_VERSION >= 22200
219 /** Provide an overloaded function for code consistency between HYPRE API
220  versions. */
221 inline hypre_CSRMatrix *hypre_CSRMatrixAdd(hypre_CSRMatrix *A,
222  hypre_CSRMatrix *B)
223 {
224  return ::hypre_CSRMatrixAdd(1.0, A, 1.0, B);
225 }
226 #endif
227 
228 /** Return a new matrix containing the sum of A and B, assuming that both
229  matrices use the same row and column partitions. The col_map_offd do not
230  need to be the same, but a more efficient algorithm is used if that's the
231  case. */
232 hypre_ParCSRMatrix *
233 hypre_ParCSRMatrixAdd(hypre_ParCSRMatrix *A,
234  hypre_ParCSRMatrix *B);
235 
236 /** Perform the operation A += beta*B, assuming that both matrices use the same
237  row and column partitions and the same col_map_offd arrays, or B has an empty
238  off-diagonal block. We also assume that the sparsity pattern of A contains
239  that of B. */
240 HYPRE_Int
241 hypre_ParCSRMatrixSum(hypre_ParCSRMatrix *A,
242  HYPRE_Complex beta,
243  hypre_ParCSRMatrix *B);
244 
245 /** Initialize all entries of A with value. */
246 HYPRE_Int
247 hypre_CSRMatrixSetConstantValues(hypre_CSRMatrix *A,
248  HYPRE_Complex value);
249 
250 /** Initialize all entries of A with value. */
251 HYPRE_Int
252 hypre_ParCSRMatrixSetConstantValues(hypre_ParCSRMatrix *A,
253  HYPRE_Complex value);
254 
255 } // namespace mfem::internal
256 
257 } // namespace mfem
258 
259 #endif // MFEM_USE_MPI
260 
261 #endif
Memory< HYPRE_Int > I
Memory< double > data
Vector beta
Memory< HYPRE_Int > J
HYPRE_Int HYPRE_BigInt
const double alpha
Definition: ex15.cpp:369