Nektar++
GsLib.hpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: GsLib.hpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: wrapper of functions around GSLib routines
32//
33///////////////////////////////////////////////////////////////////////////////
34
35#ifndef NEKTAR_LIB_UTILITIES_COMMUNICATION_GSLIB_HPP
36#define NEKTAR_LIB_UTILITIES_COMMUNICATION_GSLIB_HPP
37
38#include <iostream>
39
42#ifdef NEKTAR_USE_MPI
44#endif
45
46namespace Gs
47{
48using namespace Nektar;
49
50typedef enum
51{
58typedef enum
59{
68typedef enum
69{
75
76typedef struct
77{
78 void *ptr;
79 size_t n, max;
80} array;
81typedef array buffer;
82#ifdef NEKTAR_USE_MPI
83typedef MPI_Comm comm_ext;
84typedef MPI_Request comm_req;
85#else
86typedef int comm_ext;
87typedef int comm_req;
88#endif
89
90struct comm
91{
92 unsigned int id;
93 unsigned int np;
95};
96
97typedef struct
98{
99 unsigned int n; /* number of messages */
100 unsigned int *p; /* message source/dest proc */
101 unsigned int *size; /* size of message */
102 unsigned int total; /* sum of message sizes */
104
105typedef struct
106{
108 const unsigned int *map[2];
110 unsigned int buffer_size;
111} pw_data;
112
113typedef struct
114{
115 const unsigned int *scatter_map, *gather_map;
116 unsigned int size_r, size_r1, size_r2;
117 unsigned int size_sk, size_s, size_total;
118 unsigned int p1, p2;
119 unsigned int nrecvn;
120} cr_stage;
121
122typedef struct
123{
124 cr_stage *stage[2];
125 unsigned int nstages;
126 unsigned int buffer_size, stage_buffer_size;
127} cr_data;
128
129typedef struct
130{
131 const unsigned int *map_to_buf[2], *map_from_buf[2];
132 unsigned int buffer_size;
134
135typedef void exec_fun(void *data, gs_mode mode, unsigned vn, gs_dom dom,
136 gs_op op, unsigned transpose, const void *execdata,
137 const struct comm *comm, char *buf);
138typedef void fin_fun(void *data);
139
140typedef struct
141{
142 unsigned int buffer_size, mem_size;
143 void *data;
146} gs_remote;
147
148typedef struct
149{
150 struct comm comm;
151 const unsigned int *map_local[2]; /* 0=unflagged, 1=all */
152 const unsigned int *flagged_primaries;
154 unsigned int handle_size;
155} gs_data;
156
157typedef enum
158{
164
165extern "C"
166{
167 void nektar_gs(void *u, gs_dom dom, gs_op op, unsigned transpose,
168 gs_data *gsh, buffer *buf);
169 gs_data *nektar_gs_setup(const long *id, unsigned int n,
170 const struct comm *comm, int unique,
171 gs_method method, int verbose);
173 void nektar_gs_unique(const long *id, unsigned int n,
174 const struct comm *comm);
175}
176
177/**
178 * @brief Initialise Gather-Scatter map.
179 *
180 * On each process an array of IDs for each global degree of freedom is
181 * supplied which corresponds to a unique numbering of universal degrees of
182 * freedom. This is used to initialise the GSLib mapping between process-
183 * boundary degrees of freedom on different processes.
184 * @param pId Array of integers providing universal IDs for each
185 * global DOF on the process.
186 * @param pComm Communication object used for inter-process
187 * communication.
188 * @return GSLib data structure containing mapping information.
189 */
190static inline gs_data *Init(
191 [[maybe_unused]] const Nektar::Array<OneD, long> pId,
192 [[maybe_unused]] const LibUtilities::CommSharedPtr &pComm,
193 [[maybe_unused]] bool verbose = true)
194{
195#ifdef NEKTAR_USE_MPI
196 if (pComm->IsSerial())
197 {
198 return nullptr;
199 }
201 std::dynamic_pointer_cast<LibUtilities::CommMpi>(pComm);
202 ASSERTL1(vCommMpi, "Failed to cast MPI Comm object.");
203 comm vComm;
204 MPI_Comm_dup(vCommMpi->GetComm(), &vComm.c);
205 vComm.id = vCommMpi->GetRank();
206 vComm.np = vCommMpi->GetSize();
207 gs_data *result = nektar_gs_setup(pId.get(), pId.size(), &vComm, 0, gs_auto,
208 (int)verbose);
209 MPI_Comm_free(&vComm.c);
210 return result;
211#else
212 return 0;
213#endif
214}
215
216/**
217 * @brief Updates pId to negate all-but-one references to each universal ID.
218 *
219 * The array of universal IDs corresponding to the process-local DOF are
220 * updated such that the ID of only one instance of each universal ID
221 * remains positive. This allows the consistent formulation of universally
222 * -distributed dot products, for which the contributions of each DOF must
223 * be included only once.
224 */
225static inline void Unique(
226 [[maybe_unused]] const Nektar::Array<OneD, long> pId,
227 [[maybe_unused]] const LibUtilities::CommSharedPtr &pComm)
228{
229#ifdef NEKTAR_USE_MPI
230 if (pComm->IsSerial())
231 {
232 return;
233 }
235 std::dynamic_pointer_cast<LibUtilities::CommMpi>(pComm);
236 ASSERTL1(vCommMpi, "Failed to cast MPI Comm object.");
237 comm vComm;
238 vComm.c = vCommMpi->GetComm();
239 vComm.id = vCommMpi->GetRank();
240 vComm.np = vCommMpi->GetSize();
241 nektar_gs_unique(pId.get(), pId.size(), &vComm);
242#endif
243}
244
245/**
246 * @brief Deallocates the GSLib mapping data.
247 */
248static inline void Finalise([[maybe_unused]] gs_data *pGsh)
249{
250#ifdef NEKTAR_USE_MPI
251 int finalized;
252 MPI_Finalized(&finalized);
253 if (pGsh && !finalized)
254 {
255 nektar_gs_free(pGsh);
256 }
257#endif
258}
259
260/**
261 * @brief Deallocates GSLib mapping data without finalising MPI.
262 */
263static inline void Free([[maybe_unused]] gs_data *pGsh)
264{
265#ifdef NEKTAR_USE_MPI
266 if (pGsh)
267 {
268 nektar_gs_free(pGsh);
269 }
270#endif
271}
272
273/**
274 * @brief Performs a gather-scatter operation of the provided values.
275 *
276 * The
277 */
278static inline void Gather([[maybe_unused]] Nektar::Array<OneD, NekDouble> pU,
279 [[maybe_unused]] gs_op pOp,
280 [[maybe_unused]] gs_data *pGsh,
281 [[maybe_unused]] Nektar::Array<OneD, NekDouble>
282 pBuffer = NullNekDouble1DArray)
283{
284#ifdef NEKTAR_USE_MPI
285 if (!pGsh)
286 {
287 return;
288 }
289 if (pBuffer.size() == 0)
290 {
291 nektar_gs(pU.get(), gs_double, pOp, false, pGsh, nullptr);
292 }
293 else
294 {
295 array buf;
296 buf.ptr = &pBuffer[0];
297 buf.n = pBuffer.size();
298 nektar_gs(pU.get(), gs_double, pOp, false, pGsh, &buf);
299 }
300#endif
301}
302} // namespace Gs
303
304#endif
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
Definition: GsLib.hpp:47
gs_dom
Definition: GsLib.hpp:51
@ gs_dom_n
Definition: GsLib.hpp:56
@ gs_int
Definition: GsLib.hpp:54
@ gs_double
Definition: GsLib.hpp:52
@ gs_long
Definition: GsLib.hpp:55
@ gs_float
Definition: GsLib.hpp:53
gs_data * nektar_gs_setup(const long *id, unsigned int n, const struct comm *comm, int unique, gs_method method, int verbose)
static void Gather(Nektar::Array< OneD, NekDouble > pU, gs_op pOp, gs_data *pGsh, Nektar::Array< OneD, NekDouble > pBuffer=NullNekDouble1DArray)
Performs a gather-scatter operation of the provided values.
Definition: GsLib.hpp:278
int comm_req
Definition: GsLib.hpp:87
static gs_data * Init(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm, bool verbose=true)
Initialise Gather-Scatter map.
Definition: GsLib.hpp:190
gs_op
Definition: GsLib.hpp:59
@ gs_amax
Definition: GsLib.hpp:64
@ gs_add
Definition: GsLib.hpp:60
@ gs_max
Definition: GsLib.hpp:63
@ gs_bpr
Definition: GsLib.hpp:65
@ gs_min
Definition: GsLib.hpp:62
@ gs_op_n
Definition: GsLib.hpp:66
@ gs_mul
Definition: GsLib.hpp:61
void fin_fun(void *data)
Definition: GsLib.hpp:138
static void Finalise(gs_data *pGsh)
Deallocates the GSLib mapping data.
Definition: GsLib.hpp:248
static void Free(gs_data *pGsh)
Deallocates GSLib mapping data without finalising MPI.
Definition: GsLib.hpp:263
void nektar_gs_unique(const long *id, unsigned int n, const struct comm *comm)
void nektar_gs(void *u, gs_dom dom, gs_op op, unsigned transpose, gs_data *gsh, buffer *buf)
array buffer
Definition: GsLib.hpp:81
int comm_ext
Definition: GsLib.hpp:86
gs_method
Definition: GsLib.hpp:158
@ gs_all_reduce
Definition: GsLib.hpp:162
@ gs_pairwise
Definition: GsLib.hpp:160
@ gs_crystal_router
Definition: GsLib.hpp:161
@ gs_auto
Definition: GsLib.hpp:159
void exec_fun(void *data, gs_mode mode, unsigned vn, gs_dom dom, gs_op op, unsigned transpose, const void *execdata, const struct comm *comm, char *buf)
Definition: GsLib.hpp:135
gs_mode
Definition: GsLib.hpp:69
@ mode_vec
Definition: GsLib.hpp:71
@ mode_plain
Definition: GsLib.hpp:70
@ mode_dry_run
Definition: GsLib.hpp:73
@ mode_many
Definition: GsLib.hpp:72
static void Unique(const Nektar::Array< OneD, long > pId, const LibUtilities::CommSharedPtr &pComm)
Updates pId to negate all-but-one references to each universal ID.
Definition: GsLib.hpp:225
void nektar_gs_free(gs_data *gsh)
std::shared_ptr< CommMpi > CommMpiSharedPtr
Pointer to a Communicator object.
Definition: CommMpi.h:56
std::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:55
static Array< OneD, NekDouble > NullNekDouble1DArray
unsigned int buffer_size
Definition: GsLib.hpp:132
size_t max
Definition: GsLib.hpp:79
void * ptr
Definition: GsLib.hpp:78
comm_ext c
Definition: GsLib.hpp:94
unsigned int np
Definition: GsLib.hpp:93
unsigned int id
Definition: GsLib.hpp:92
unsigned int buffer_size
Definition: GsLib.hpp:126
unsigned int nstages
Definition: GsLib.hpp:125
unsigned int size_s
Definition: GsLib.hpp:117
unsigned int size_r
Definition: GsLib.hpp:116
unsigned int p1
Definition: GsLib.hpp:118
const unsigned int * gather_map
Definition: GsLib.hpp:115
unsigned int nrecvn
Definition: GsLib.hpp:119
unsigned int handle_size
Definition: GsLib.hpp:154
gs_remote r
Definition: GsLib.hpp:153
const unsigned int * flagged_primaries
Definition: GsLib.hpp:152
exec_fun * exec
Definition: GsLib.hpp:144
unsigned int buffer_size
Definition: GsLib.hpp:142
void * data
Definition: GsLib.hpp:143
fin_fun * fin
Definition: GsLib.hpp:145
unsigned int n
Definition: GsLib.hpp:99
unsigned int * size
Definition: GsLib.hpp:101
unsigned int total
Definition: GsLib.hpp:102
unsigned int * p
Definition: GsLib.hpp:100
comm_req * req
Definition: GsLib.hpp:109
unsigned int buffer_size
Definition: GsLib.hpp:110