1e5c89e4eSSatish Balay /*
2e5c89e4eSSatish Balay Provides a general mechanism to allow one to register new routines in
3e5c89e4eSSatish Balay dynamic libraries for many of the PETSc objects (including, e.g., KSP and PC).
4e5c89e4eSSatish Balay */
5af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/
6665c2dedSJed Brown #include <petscviewer.h>
7e5c89e4eSSatish Balay
8ed170139SJacob Faibussowitsch #include <petsc/private/hashmap.h>
93fa76a5bSLisandro Dalcin /*
103fa76a5bSLisandro Dalcin This is the default list used by PETSc with the PetscDLLibrary register routines
113fa76a5bSLisandro Dalcin */
1202c9f0b5SLisandro Dalcin PetscDLLibrary PetscDLLibrariesLoaded = NULL;
133fa76a5bSLisandro Dalcin
14cbd104e6SBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES)
15ebd79076SLisandro Dalcin
PetscLoadDynamicLibrary(const char * name,PetscBool * found)16d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscLoadDynamicLibrary(const char *name, PetscBool *found)
17d71ae5a4SJacob Faibussowitsch {
18487e5849SBarry Smith char libs[PETSC_MAX_PATH_LEN], dlib[PETSC_MAX_PATH_LEN];
19487e5849SBarry Smith
20487e5849SBarry Smith PetscFunctionBegin;
219566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(libs, "${PETSC_LIB_DIR}/libpetsc", sizeof(libs)));
229566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(libs, name, sizeof(libs)));
23859f1752SFrancesco Ballarin #if defined(PETSC_LIB_NAME_SUFFIX)
24859f1752SFrancesco Ballarin PetscCall(PetscStrlcat(libs, PETSC_LIB_NAME_SUFFIX, sizeof(libs)));
25859f1752SFrancesco Ballarin #endif
269566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryRetrieve(PETSC_COMM_WORLD, libs, dlib, 1024, found));
27487e5849SBarry Smith if (*found) {
289566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, dlib));
29487e5849SBarry Smith } else {
309566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(libs, "${PETSC_DIR}/${PETSC_ARCH}/lib/libpetsc", sizeof(libs)));
319566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(libs, name, sizeof(libs)));
32859f1752SFrancesco Ballarin #if defined(PETSC_LIB_NAME_SUFFIX)
33859f1752SFrancesco Ballarin PetscCall(PetscStrlcat(libs, PETSC_LIB_NAME_SUFFIX, sizeof(libs)));
34859f1752SFrancesco Ballarin #endif
359566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryRetrieve(PETSC_COMM_WORLD, libs, dlib, 1024, found));
3648a46eb9SPierre Jolivet if (*found) PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, dlib));
37487e5849SBarry Smith }
383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
39487e5849SBarry Smith }
403fa76a5bSLisandro Dalcin #endif
413fa76a5bSLisandro Dalcin
4260da17ecSBarry Smith #if defined(PETSC_USE_SINGLE_LIBRARY) && !(defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES))
4395c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode AOInitializePackage(void);
4495c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscSFInitializePackage(void);
457da51e29SSatish Balay #if !defined(PETSC_USE_COMPLEX)
4695c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode CharacteristicInitializePackage(void);
477da51e29SSatish Balay #endif
4895c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode ISInitializePackage(void);
4995c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode VecInitializePackage(void);
5095c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode MatInitializePackage(void);
5195c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode DMInitializePackage(void);
5295c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PCInitializePackage(void);
5395c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode KSPInitializePackage(void);
5495c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode SNESInitializePackage(void);
5595c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode TSInitializePackage(void);
5660da17ecSBarry Smith PETSC_EXTERN PetscErrorCode TaoInitializePackage(void);
5760da17ecSBarry Smith #endif
58acff04ddSBarry Smith
59e5c89e4eSSatish Balay /*
60e5c89e4eSSatish Balay PetscInitialize_DynamicLibraries - Adds the default dynamic link libraries to the
61e5c89e4eSSatish Balay search path.
62e5c89e4eSSatish Balay */
PetscInitialize_DynamicLibraries(void)63d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscInitialize_DynamicLibraries(void)
64d71ae5a4SJacob Faibussowitsch {
65487e5849SBarry Smith char *libname[32];
66e5c89e4eSSatish Balay PetscInt nmax, i;
6760da17ecSBarry Smith PetscBool preload = PETSC_FALSE;
68540e20f2SPierre Jolivet #if defined(PETSC_HAVE_ELEMENTAL)
69540e20f2SPierre Jolivet PetscBool PetscInitialized = PetscInitializeCalled;
70540e20f2SPierre Jolivet #endif
71e5c89e4eSSatish Balay
7260154eb2SBarry Smith PetscFunctionBegin;
7360da17ecSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY)
7460da17ecSBarry Smith /* These must be all initialized here because it is not safe for individual threads to call these initialize routines */
7560da17ecSBarry Smith preload = PETSC_TRUE;
7660da17ecSBarry Smith #endif
7760da17ecSBarry Smith
78e5c89e4eSSatish Balay nmax = 32;
799566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetStringArray(NULL, NULL, "-dll_prepend", libname, &nmax, NULL));
80e5c89e4eSSatish Balay for (i = 0; i < nmax; i++) {
819566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryPrepend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, libname[i]));
829566063dSJacob Faibussowitsch PetscCall(PetscFree(libname[i]));
83e5c89e4eSSatish Balay }
84e5c89e4eSSatish Balay
859566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-library_preload", &preload, NULL));
8660da17ecSBarry Smith if (!preload) {
879566063dSJacob Faibussowitsch PetscCall(PetscSysInitializePackage());
8860da17ecSBarry Smith } else {
8960da17ecSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES)
90aa2d57e9SJed Brown PetscBool found;
9160154eb2SBarry Smith #if defined(PETSC_USE_SINGLE_LIBRARY)
929566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("", &found));
9300045ab3SPierre Jolivet PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc dynamic library. You cannot move the dynamic libraries!");
9460154eb2SBarry Smith #else
959566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("sys", &found));
9600045ab3SPierre Jolivet PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc Sys dynamic library. You cannot move the dynamic libraries!");
979566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("vec", &found));
9800045ab3SPierre Jolivet PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc Vec dynamic library. You cannot move the dynamic libraries!");
999566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("mat", &found));
10000045ab3SPierre Jolivet PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc Mat dynamic library. You cannot move the dynamic libraries!");
1019566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("dm", &found));
10200045ab3SPierre Jolivet PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc DM dynamic library. You cannot move the dynamic libraries!");
1039566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("ksp", &found));
10400045ab3SPierre Jolivet PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc KSP dynamic library. You cannot move the dynamic libraries!");
1059566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("snes", &found));
10600045ab3SPierre Jolivet PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc SNES dynamic library. You cannot move the dynamic libraries!");
1079566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("ts", &found));
10800045ab3SPierre Jolivet PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc TS dynamic library. You cannot move the dynamic libraries!");
1099566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("tao", &found));
11000045ab3SPierre Jolivet PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate Tao dynamic library. You cannot move the dynamic libraries!");
111bb84e0fdSBarry Smith #endif
11260da17ecSBarry Smith #else /* defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) */
11360da17ecSBarry Smith #if defined(PETSC_USE_SINGLE_LIBRARY)
1149566063dSJacob Faibussowitsch PetscCall(AOInitializePackage());
1159566063dSJacob Faibussowitsch PetscCall(PetscSFInitializePackage());
1167da51e29SSatish Balay #if !defined(PETSC_USE_COMPLEX)
1179566063dSJacob Faibussowitsch PetscCall(CharacteristicInitializePackage());
1187da51e29SSatish Balay #endif
1199566063dSJacob Faibussowitsch PetscCall(ISInitializePackage());
1209566063dSJacob Faibussowitsch PetscCall(VecInitializePackage());
1219566063dSJacob Faibussowitsch PetscCall(MatInitializePackage());
1229566063dSJacob Faibussowitsch PetscCall(DMInitializePackage());
1239566063dSJacob Faibussowitsch PetscCall(PCInitializePackage());
1249566063dSJacob Faibussowitsch PetscCall(KSPInitializePackage());
1259566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage());
1269566063dSJacob Faibussowitsch PetscCall(TSInitializePackage());
1279566063dSJacob Faibussowitsch PetscCall(TaoInitializePackage());
12860da17ecSBarry Smith #else
12960da17ecSBarry Smith SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "Cannot use -library_preload with multiple static PETSc libraries");
13060da17ecSBarry Smith #endif
13160da17ecSBarry Smith #endif /* defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) */
13260da17ecSBarry Smith }
13360da17ecSBarry Smith
13460da17ecSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) && defined(PETSC_HAVE_BAMG)
13560da17ecSBarry Smith {
13660da17ecSBarry Smith PetscBool found;
1379566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("bamg", &found));
13800045ab3SPierre Jolivet PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc BAMG dynamic library. You cannot move the dynamic libraries!");
13960da17ecSBarry Smith }
14060da17ecSBarry Smith #endif
141*54606e8bSsdargavi #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) && defined(PETSC_HAVE_PFLARE)
142*54606e8bSsdargavi {
143*54606e8bSsdargavi PetscBool found;
144*54606e8bSsdargavi PetscCall(PetscLoadDynamicLibrary("pflare", &found));
145*54606e8bSsdargavi PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PFLARE dynamic library. You cannot move the dynamic libraries!");
146*54606e8bSsdargavi }
147*54606e8bSsdargavi #endif
14860da17ecSBarry Smith
14960da17ecSBarry Smith nmax = 32;
1509566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetStringArray(NULL, NULL, "-dll_append", libname, &nmax, NULL));
15160da17ecSBarry Smith for (i = 0; i < nmax; i++) {
1529566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, libname[i]));
1539566063dSJacob Faibussowitsch PetscCall(PetscFree(libname[i]));
15460da17ecSBarry Smith }
15560da17ecSBarry Smith
156540e20f2SPierre Jolivet #if defined(PETSC_HAVE_ELEMENTAL)
157540e20f2SPierre Jolivet /* in Fortran, PetscInitializeCalled is set to PETSC_TRUE before PetscInitialize_DynamicLibraries() */
158540e20f2SPierre Jolivet /* in C, it is not the case, but the value is forced to PETSC_TRUE so that PetscRegisterFinalize() is called */
159540e20f2SPierre Jolivet PetscInitializeCalled = PETSC_TRUE;
1609566063dSJacob Faibussowitsch PetscCall(PetscElementalInitializePackage());
161540e20f2SPierre Jolivet PetscInitializeCalled = PetscInitialized;
162540e20f2SPierre Jolivet #endif
1633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
164e5c89e4eSSatish Balay }
165e5c89e4eSSatish Balay
166ebd79076SLisandro Dalcin /*
167ebd79076SLisandro Dalcin PetscFinalize_DynamicLibraries - Closes the opened dynamic libraries.
168ebd79076SLisandro Dalcin */
PetscFinalize_DynamicLibraries(void)169d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscFinalize_DynamicLibraries(void)
170d71ae5a4SJacob Faibussowitsch {
171ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE;
172e5c89e4eSSatish Balay
173ebd79076SLisandro Dalcin PetscFunctionBegin;
1749566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-dll_view", &flg, NULL));
1759566063dSJacob Faibussowitsch if (flg) PetscCall(PetscDLLibraryPrintPath(PetscDLLibrariesLoaded));
1769566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryClose(PetscDLLibrariesLoaded));
17702c9f0b5SLisandro Dalcin PetscDLLibrariesLoaded = NULL;
1783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
179e5c89e4eSSatish Balay }
180e5c89e4eSSatish Balay
18157d50842SBarry Smith PETSC_HASH_MAP(HMapFunc, const char *, PetscErrorCodeFn *, kh_str_hash_func, kh_str_hash_equal, NULL)
182ed170139SJacob Faibussowitsch
183140e18c1SBarry Smith struct _n_PetscFunctionList {
184ed170139SJacob Faibussowitsch PetscHMapFunc map;
185e5c89e4eSSatish Balay };
186e5c89e4eSSatish Balay
187ed170139SJacob Faibussowitsch /* Keep a linked list of PetscFunctionLists so that we can destroy all the left-over ones. */
188ed170139SJacob Faibussowitsch typedef struct n_PetscFunctionListDLAll *PetscFunctionListDLAll;
189ed170139SJacob Faibussowitsch struct n_PetscFunctionListDLAll {
190ed170139SJacob Faibussowitsch PetscFunctionList data;
191ed170139SJacob Faibussowitsch PetscFunctionListDLAll next;
192ed170139SJacob Faibussowitsch };
193e5c89e4eSSatish Balay
194ed170139SJacob Faibussowitsch static PetscFunctionListDLAll dlallhead = NULL;
195ed170139SJacob Faibussowitsch
PetscFunctionListDLAllPush_Private(PetscFunctionList fl)196ed170139SJacob Faibussowitsch static PetscErrorCode PetscFunctionListDLAllPush_Private(PetscFunctionList fl)
197d71ae5a4SJacob Faibussowitsch {
1980e6b6b59SJacob Faibussowitsch PetscFunctionBegin;
199ed170139SJacob Faibussowitsch if (PetscDefined(USE_DEBUG) && !PetscDefined(HAVE_THREADSAFETY)) {
200ed170139SJacob Faibussowitsch PetscFunctionListDLAll head;
201ed170139SJacob Faibussowitsch
202ed170139SJacob Faibussowitsch PetscCall(PetscNew(&head));
203ed170139SJacob Faibussowitsch head->data = fl;
204ed170139SJacob Faibussowitsch head->next = dlallhead;
205ed170139SJacob Faibussowitsch dlallhead = head;
206ed170139SJacob Faibussowitsch }
2073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
208ed170139SJacob Faibussowitsch }
209ed170139SJacob Faibussowitsch
PetscFunctionListDLAllPop_Private(PetscFunctionList fl)210ed170139SJacob Faibussowitsch static PetscErrorCode PetscFunctionListDLAllPop_Private(PetscFunctionList fl)
211ed170139SJacob Faibussowitsch {
212ed170139SJacob Faibussowitsch PetscFunctionBegin;
213ed170139SJacob Faibussowitsch if (PetscDefined(USE_DEBUG) && !PetscDefined(HAVE_THREADSAFETY)) {
214ed170139SJacob Faibussowitsch PetscFunctionListDLAll current = dlallhead, prev = NULL;
215ed170139SJacob Faibussowitsch
216ed170139SJacob Faibussowitsch /* Remove this entry from the main DL list (if it is in it) */
217ed170139SJacob Faibussowitsch while (current) {
218ed170139SJacob Faibussowitsch const PetscFunctionListDLAll next = current->next;
219ed170139SJacob Faibussowitsch
220ed170139SJacob Faibussowitsch if (current->data == fl) {
221ed170139SJacob Faibussowitsch if (prev) {
222ed170139SJacob Faibussowitsch // somewhere in the middle (or end) of the list
223ed170139SJacob Faibussowitsch prev->next = next;
224ed170139SJacob Faibussowitsch } else {
225ed170139SJacob Faibussowitsch // prev = NULL implies current = dlallhead, so front of list
226ed170139SJacob Faibussowitsch dlallhead = next;
227ed170139SJacob Faibussowitsch }
228ed170139SJacob Faibussowitsch PetscCall(PetscFree(current));
229ed170139SJacob Faibussowitsch break;
230ed170139SJacob Faibussowitsch }
231ed170139SJacob Faibussowitsch prev = current;
232ed170139SJacob Faibussowitsch current = next;
233ed170139SJacob Faibussowitsch }
234ed170139SJacob Faibussowitsch }
2353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
236ed170139SJacob Faibussowitsch }
237ed170139SJacob Faibussowitsch
PetscHMapFuncInsert_Private(PetscHMapFunc map,const char name[],PetscErrorCodeFn * fnc)23857d50842SBarry Smith static PetscErrorCode PetscHMapFuncInsert_Private(PetscHMapFunc map, const char name[], PetscErrorCodeFn *fnc)
239ed170139SJacob Faibussowitsch {
240ed170139SJacob Faibussowitsch PetscHashIter it;
241ed170139SJacob Faibussowitsch PetscBool found;
242ed170139SJacob Faibussowitsch
243ed170139SJacob Faibussowitsch PetscFunctionBegin;
2444f572ea9SToby Isaac PetscAssertPointer(name, 2);
245ed170139SJacob Faibussowitsch if (fnc) PetscValidFunction(fnc, 3);
246ed170139SJacob Faibussowitsch PetscCall(PetscHMapFuncFind(map, name, &it, &found));
247ed170139SJacob Faibussowitsch if (fnc) {
248ed170139SJacob Faibussowitsch if (found) {
249ed170139SJacob Faibussowitsch PetscCall(PetscHMapFuncIterSet(map, it, fnc));
250ed170139SJacob Faibussowitsch } else {
251ed170139SJacob Faibussowitsch char *tmp_name;
252ed170139SJacob Faibussowitsch
253ed170139SJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &tmp_name));
254ed170139SJacob Faibussowitsch PetscCall(PetscHMapFuncSet(map, tmp_name, fnc));
255ed170139SJacob Faibussowitsch }
256ed170139SJacob Faibussowitsch } else if (found) {
257ed170139SJacob Faibussowitsch const char *tmp_name;
258ed170139SJacob Faibussowitsch
259ed170139SJacob Faibussowitsch PetscHashIterGetKey(map, it, tmp_name);
260ed170139SJacob Faibussowitsch PetscCall(PetscFree(tmp_name));
261ed170139SJacob Faibussowitsch PetscCall(PetscHMapFuncIterDel(map, it));
262ed170139SJacob Faibussowitsch }
2633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
264ed170139SJacob Faibussowitsch }
265ed170139SJacob Faibussowitsch
PetscFunctionListCreate_Private(PetscInt size,PetscFunctionList * fl)266ed170139SJacob Faibussowitsch static PetscErrorCode PetscFunctionListCreate_Private(PetscInt size, PetscFunctionList *fl)
267ed170139SJacob Faibussowitsch {
268ed170139SJacob Faibussowitsch PetscFunctionBegin;
2693ba16761SJacob Faibussowitsch if (*fl) PetscFunctionReturn(PETSC_SUCCESS);
270ed170139SJacob Faibussowitsch PetscCall(PetscNew(fl));
271ed170139SJacob Faibussowitsch PetscCall(PetscHMapFuncCreateWithSize(size, &(*fl)->map));
272ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListDLAllPush_Private(*fl));
2733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
2740e6b6b59SJacob Faibussowitsch }
2750e6b6b59SJacob Faibussowitsch
276a240a19fSJed Brown /*MC
277140e18c1SBarry Smith PetscFunctionListAdd - Given a routine and a string id, saves that routine in the
278e5c89e4eSSatish Balay specified registry.
279e5c89e4eSSatish Balay
280a240a19fSJed Brown Synopsis:
281aaa7dc30SBarry Smith #include <petscsys.h>
28257d50842SBarry Smith PetscErrorCode PetscFunctionListAdd(PetscFunctionList *flist, const char name[], PetscErrorCodeFn *fptr)
283a240a19fSJed Brown
284d4349b43SBarry Smith Not Collective
285e5c89e4eSSatish Balay
286e5c89e4eSSatish Balay Input Parameters:
28710450e9eSJacob Faibussowitsch + fl - pointer to function list object
288e5c89e4eSSatish Balay . name - string to identify routine
289a240a19fSJed Brown - fptr - function pointer
290e5c89e4eSSatish Balay
29121532e8aSBarry Smith Level: developer
29221532e8aSBarry Smith
293e5c89e4eSSatish Balay Notes:
29421532e8aSBarry Smith To remove a registered routine, pass in a `NULL` `fptr`.
295e5c89e4eSSatish Balay
296e5c89e4eSSatish Balay Users who wish to register new classes for use by a particular PETSc
297811af0c4SBarry Smith component (e.g., `SNES`) should generally call the registration routine
298811af0c4SBarry Smith for that particular component (e.g., `SNESRegister()`) instead of
299811af0c4SBarry Smith calling `PetscFunctionListAdd()` directly.
300e5c89e4eSSatish Balay
30121532e8aSBarry Smith .seealso: `PetscFunctionListDestroy()`, `SNESRegister()`, `KSPRegister()`,`PetscFunctionListDuplicate()`
302db781477SPatrick Sanan `PCRegister()`, `TSRegister()`, `PetscFunctionList`, `PetscObjectComposeFunction()`
303a240a19fSJed Brown M*/
PetscFunctionListAdd_Private(PetscFunctionList * fl,const char name[],PetscErrorCodeFn * fptr)30457d50842SBarry Smith PetscErrorCode PetscFunctionListAdd_Private(PetscFunctionList *fl, const char name[], PetscErrorCodeFn *fptr)
305d71ae5a4SJacob Faibussowitsch {
306e5c89e4eSSatish Balay PetscFunctionBegin;
3074f572ea9SToby Isaac PetscAssertPointer(fl, 1);
3084f572ea9SToby Isaac if (name) PetscAssertPointer(name, 2);
30910450e9eSJacob Faibussowitsch if (fptr) PetscValidFunction(fptr, 3);
310ebd2f95aSStefano Zampini if (!fptr && !*fl) PetscFunctionReturn(PETSC_SUCCESS);
311ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListCreate_Private(0, fl));
31210450e9eSJacob Faibussowitsch PetscCall(PetscHMapFuncInsert_Private((*fl)->map, name, fptr));
3133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
314e5c89e4eSSatish Balay }
315e5c89e4eSSatish Balay
316ffeef943SBarry Smith /*@C
317140e18c1SBarry Smith PetscFunctionListDestroy - Destroys a list of registered routines.
318e5c89e4eSSatish Balay
319e5c89e4eSSatish Balay Input Parameter:
320e5c89e4eSSatish Balay . fl - pointer to list
321e5c89e4eSSatish Balay
322e5c89e4eSSatish Balay Level: developer
323e5c89e4eSSatish Balay
3240e6b6b59SJacob Faibussowitsch .seealso: `PetscFunctionListAdd()`, `PetscFunctionList`, `PetscFunctionListClear()`
325e5c89e4eSSatish Balay @*/
PetscFunctionListDestroy(PetscFunctionList * fl)326d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFunctionListDestroy(PetscFunctionList *fl)
327d71ae5a4SJacob Faibussowitsch {
328e5c89e4eSSatish Balay PetscFunctionBegin;
3293ba16761SJacob Faibussowitsch if (!*fl) PetscFunctionReturn(PETSC_SUCCESS);
330ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListDLAllPop_Private(*fl));
331e5c89e4eSSatish Balay /* free this list */
332ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListClear(*fl));
333ed170139SJacob Faibussowitsch PetscCall(PetscHMapFuncDestroy(&(*fl)->map));
334ed170139SJacob Faibussowitsch PetscCall(PetscFree(*fl));
3353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
336e5c89e4eSSatish Balay }
337e5c89e4eSSatish Balay
338ed170139SJacob Faibussowitsch #define PetscHMapFuncForEach(__func_list__, __key_name__, __val_name__, ...) \
339ed170139SJacob Faibussowitsch do { \
340ed170139SJacob Faibussowitsch const PetscHMapFunc phmfi_map_ = (__func_list__)->map; \
341ed170139SJacob Faibussowitsch PetscHashIter phmfi_iter_; \
342ed170139SJacob Faibussowitsch \
343ed170139SJacob Faibussowitsch PetscHashIterBegin(phmfi_map_, phmfi_iter_); \
344ed170139SJacob Faibussowitsch while (!PetscHashIterAtEnd(phmfi_map_, phmfi_iter_)) { \
345ed170139SJacob Faibussowitsch const char *PETSC_UNUSED __key_name__; \
34657d50842SBarry Smith PetscErrorCodeFn *PETSC_UNUSED __val_name__; \
347ed170139SJacob Faibussowitsch \
348ed170139SJacob Faibussowitsch PetscHashIterGetKey(phmfi_map_, phmfi_iter_, __key_name__); \
349ed170139SJacob Faibussowitsch PetscHashIterGetVal(phmfi_map_, phmfi_iter_, __val_name__); \
350ed170139SJacob Faibussowitsch { \
351ed170139SJacob Faibussowitsch __VA_ARGS__; \
352ed170139SJacob Faibussowitsch } \
353ed170139SJacob Faibussowitsch PetscHashIterNext(phmfi_map_, phmfi_iter_); \
354ed170139SJacob Faibussowitsch } /* end while */ \
355ed170139SJacob Faibussowitsch } while (0)
356ed170139SJacob Faibussowitsch
357ffeef943SBarry Smith /*@C
3580e6b6b59SJacob Faibussowitsch PetscFunctionListClear - Clear a `PetscFunctionList`
3590e6b6b59SJacob Faibussowitsch
3600e6b6b59SJacob Faibussowitsch Not Collective
3610e6b6b59SJacob Faibussowitsch
3620e6b6b59SJacob Faibussowitsch Input Parameter:
3630e6b6b59SJacob Faibussowitsch . fl - The `PetscFunctionList` to clear
3640e6b6b59SJacob Faibussowitsch
36521532e8aSBarry Smith Level: developer
36621532e8aSBarry Smith
3670e6b6b59SJacob Faibussowitsch Notes:
3680e6b6b59SJacob Faibussowitsch This clears the contents of `fl` but does not deallocate the entries themselves.
3690e6b6b59SJacob Faibussowitsch
3700e6b6b59SJacob Faibussowitsch .seealso: `PetscFunctionList`, `PetscFunctionListDestroy()`, `PetscFunctionListAdd()`
3710e6b6b59SJacob Faibussowitsch @*/
PetscFunctionListClear(PetscFunctionList fl)372d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFunctionListClear(PetscFunctionList fl)
373d71ae5a4SJacob Faibussowitsch {
3740e6b6b59SJacob Faibussowitsch PetscFunctionBegin;
375ed170139SJacob Faibussowitsch if (fl) {
376ed170139SJacob Faibussowitsch PetscHMapFuncForEach(fl, name, func, PetscCall(PetscFree(name)));
377ed170139SJacob Faibussowitsch PetscCall(PetscHMapFuncClear(fl->map));
3780e6b6b59SJacob Faibussowitsch }
3793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
3800e6b6b59SJacob Faibussowitsch }
3810e6b6b59SJacob Faibussowitsch
382e5c89e4eSSatish Balay /*
3832e956fe4SStefano Zampini Print registered PetscFunctionLists
384e5c89e4eSSatish Balay */
PetscFunctionListPrintAll(void)385d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFunctionListPrintAll(void)
386d71ae5a4SJacob Faibussowitsch {
387ed170139SJacob Faibussowitsch PetscFunctionListDLAll current = dlallhead;
388e5c89e4eSSatish Balay
389e5c89e4eSSatish Balay PetscFunctionBegin;
390ed170139SJacob Faibussowitsch if (current) PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Registered PetscFunctionLists\n", PetscGlobalRank));
391ed170139SJacob Faibussowitsch while (current) {
392ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListPrintNonEmpty(current->data));
393ed170139SJacob Faibussowitsch current = current->next;
39437e93019SBarry Smith }
3953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
396e5c89e4eSSatish Balay }
397e5c89e4eSSatish Balay
39810450e9eSJacob Faibussowitsch /*@C
39910450e9eSJacob Faibussowitsch PetscFunctionListPrintNonEmpty - Print composed names for non `NULL` function pointers
4002e956fe4SStefano Zampini
401cc4c1da9SBarry Smith Logically Collective, No Fortran Support
402cc4c1da9SBarry Smith
4032e956fe4SStefano Zampini Input Parameter:
40410450e9eSJacob Faibussowitsch . fl - the function list
4052e956fe4SStefano Zampini
4062e956fe4SStefano Zampini Level: developer
4072e956fe4SStefano Zampini
4082e956fe4SStefano Zampini .seealso: `PetscFunctionListAdd()`, `PetscFunctionList`, `PetscObjectQueryFunction()`
40910450e9eSJacob Faibussowitsch @*/
PetscFunctionListPrintNonEmpty(PetscFunctionList fl)410d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFunctionListPrintNonEmpty(PetscFunctionList fl)
411d71ae5a4SJacob Faibussowitsch {
4122e956fe4SStefano Zampini PetscFunctionBegin;
413ed170139SJacob Faibussowitsch if (fl) {
414ed170139SJacob Faibussowitsch // clang-format off
415ed170139SJacob Faibussowitsch PetscHMapFuncForEach(
416ed170139SJacob Faibussowitsch fl,
417ed170139SJacob Faibussowitsch name, func,
418ed170139SJacob Faibussowitsch PetscCall(PetscFPrintf(PETSC_COMM_SELF, PETSC_STDOUT, "[%d] function name: %s\n", PetscGlobalRank, name));
419ed170139SJacob Faibussowitsch );
420ed170139SJacob Faibussowitsch // clang-format on
4212e956fe4SStefano Zampini }
4223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
4232e956fe4SStefano Zampini }
4242e956fe4SStefano Zampini
4252e956fe4SStefano Zampini /*MC
4261c9cd337SJed Brown PetscFunctionListFind - Find function registered under given name
4271c9cd337SJed Brown
428cc4c1da9SBarry Smith Not Collective, No Fortran Support
429cc4c1da9SBarry Smith
4301c9cd337SJed Brown Synopsis:
431aaa7dc30SBarry Smith #include <petscsys.h>
43257d50842SBarry Smith PetscErrorCode PetscFunctionListFind(PetscFunctionList flist, const char name[], PetscErrorCodeFn **fptr)
433e5c89e4eSSatish Balay
434e5c89e4eSSatish Balay Input Parameters:
43510450e9eSJacob Faibussowitsch + fl - the function list
4361c9cd337SJed Brown - name - name registered for the function
437e5c89e4eSSatish Balay
4382fe279fdSBarry Smith Output Parameter:
43921532e8aSBarry Smith . fptr - the function pointer if name was found, else `NULL`
440e5c89e4eSSatish Balay
441e5c89e4eSSatish Balay Level: developer
442e5c89e4eSSatish Balay
44321532e8aSBarry Smith .seealso: `PetscFunctionListAdd()`, `PetscFunctionList`, `PetscObjectQueryFunction()`, `PetscFunctionListDuplicate()`
4441c9cd337SJed Brown M*/
PetscFunctionListFind_Private(PetscFunctionList fl,const char name[],PetscErrorCodeFn ** fptr)44557d50842SBarry Smith PetscErrorCode PetscFunctionListFind_Private(PetscFunctionList fl, const char name[], PetscErrorCodeFn **fptr)
446d71ae5a4SJacob Faibussowitsch {
447e5c89e4eSSatish Balay PetscFunctionBegin;
4484f572ea9SToby Isaac PetscAssertPointer(name, 2);
4494f572ea9SToby Isaac PetscAssertPointer(fptr, 3);
45010450e9eSJacob Faibussowitsch *fptr = NULL;
45110450e9eSJacob Faibussowitsch if (fl) PetscCall(PetscHMapFuncGet(fl->map, name, fptr));
4523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
453e5c89e4eSSatish Balay }
454e5c89e4eSSatish Balay
455ffeef943SBarry Smith /*@C
45620f4b53cSBarry Smith PetscFunctionListView - prints out contents of a `PetscFunctionList`
457e5c89e4eSSatish Balay
45820f4b53cSBarry Smith Collective
459e5c89e4eSSatish Balay
460e5c89e4eSSatish Balay Input Parameters:
461e5c89e4eSSatish Balay + list - the list of functions
46220f4b53cSBarry Smith - viewer - the `PetscViewer` used to view the `PetscFunctionList`
463e5c89e4eSSatish Balay
464e5c89e4eSSatish Balay Level: developer
465e5c89e4eSSatish Balay
466db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionListPrintTypes()`, `PetscFunctionList`
467e5c89e4eSSatish Balay @*/
PetscFunctionListView(PetscFunctionList list,PetscViewer viewer)468d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFunctionListView(PetscFunctionList list, PetscViewer viewer)
469d71ae5a4SJacob Faibussowitsch {
4709f196a02SMartin Diehl PetscBool isascii;
471e5c89e4eSSatish Balay
472e5c89e4eSSatish Balay PetscFunctionBegin;
4734f572ea9SToby Isaac PetscAssertPointer(list, 1);
474ed170139SJacob Faibussowitsch if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PETSC_COMM_SELF, &viewer));
4750700a824SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
476e5c89e4eSSatish Balay
4779f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
4789f196a02SMartin Diehl PetscCheck(isascii, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only ASCII viewer supported");
479ed170139SJacob Faibussowitsch {
480ed170139SJacob Faibussowitsch PetscInt size;
481e5c89e4eSSatish Balay
482ed170139SJacob Faibussowitsch PetscCall(PetscHMapFuncGetSize(list->map, &size));
483ed170139SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "PetscFunctionList Object:\n"));
484ed170139SJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer));
485ed170139SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "size: %" PetscInt_FMT "\n", size));
486ed170139SJacob Faibussowitsch if (size) {
487ed170139SJacob Faibussowitsch PetscInt count = 0;
488ed170139SJacob Faibussowitsch
489ed170139SJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "functions:\n"));
490ed170139SJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer));
491ed170139SJacob Faibussowitsch PetscHMapFuncForEach(list, name, func, PetscCall(PetscViewerASCIIPrintf(viewer, "%" PetscInt_FMT ": %s\n", ++count, name)));
492ed170139SJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer));
493e5c89e4eSSatish Balay }
494ed170139SJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer));
495ed170139SJacob Faibussowitsch }
4963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
497e5c89e4eSSatish Balay }
498e5c89e4eSSatish Balay
499065533a5SJed Brown /*@C
500811af0c4SBarry Smith PetscFunctionListGet - Gets an array the contains the entries in `PetscFunctionList`, this is used
501e5c89e4eSSatish Balay by help etc.
502e5c89e4eSSatish Balay
503cc4c1da9SBarry Smith Not Collective, No Fortran Support
504e5c89e4eSSatish Balay
505e5c89e4eSSatish Balay Input Parameter:
506e5c89e4eSSatish Balay . list - list of types
507e5c89e4eSSatish Balay
508d8d19677SJose E. Roman Output Parameters:
509e5c89e4eSSatish Balay + array - array of names
51021532e8aSBarry Smith - n - length of `array`
51121532e8aSBarry Smith
51221532e8aSBarry Smith Level: developer
513e5c89e4eSSatish Balay
514811af0c4SBarry Smith Note:
515a3b724e8SBarry Smith This allocates the array so that must be freed with `PetscFree()`. BUT the individual entries should not be freed.
516e5c89e4eSSatish Balay
517db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionList`
518e5c89e4eSSatish Balay @*/
PetscFunctionListGet(PetscFunctionList list,const char *** array,int * n)519d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFunctionListGet(PetscFunctionList list, const char ***array, int *n)
520d71ae5a4SJacob Faibussowitsch {
521ed170139SJacob Faibussowitsch PetscInt size = 0;
522e5c89e4eSSatish Balay
523e5c89e4eSSatish Balay PetscFunctionBegin;
5244f572ea9SToby Isaac PetscAssertPointer(array, 2);
525ed170139SJacob Faibussowitsch *array = NULL;
526ed170139SJacob Faibussowitsch if (list) {
527ed170139SJacob Faibussowitsch const PetscHMapFunc map = list->map;
528ed170139SJacob Faibussowitsch PetscInt off = 0;
529ed170139SJacob Faibussowitsch
530ed170139SJacob Faibussowitsch PetscCall(PetscHMapFuncGetSize(map, &size));
531ed170139SJacob Faibussowitsch PetscCall(PetscMalloc1(size, (char ***)array));
532ed170139SJacob Faibussowitsch PetscCall(PetscHMapFuncGetKeys(map, &off, *array));
533e5c89e4eSSatish Balay }
534835f2295SStefano Zampini PetscCall(PetscCIntCast(size, n));
5353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
536e5c89e4eSSatish Balay }
537e5c89e4eSSatish Balay
538e5c89e4eSSatish Balay /*@C
539811af0c4SBarry Smith PetscFunctionListPrintTypes - Prints the methods available in a list of functions
540e5c89e4eSSatish Balay
541cc4c1da9SBarry Smith Collective, No Fortran Support
542e5c89e4eSSatish Balay
543e5c89e4eSSatish Balay Input Parameters:
544811af0c4SBarry Smith + comm - the communicator (usually `MPI_COMM_WORLD`)
54521532e8aSBarry Smith . fd - file to print to, usually `stdout`
546e5c89e4eSSatish Balay . prefix - prefix to prepend to name (optional)
54721532e8aSBarry Smith . name - option string (for example, `-ksp_type`)
548e5c89e4eSSatish Balay . text - short description of the object (for example, "Krylov solvers")
54921532e8aSBarry Smith . man - name of manual page that discusses the object (for example, `KSPCreate`)
5503cc1e11dSBarry Smith . list - list of types
55144ef3d73SBarry Smith . def - default (current) value
55244ef3d73SBarry Smith - newv - new value
553e5c89e4eSSatish Balay
554e5c89e4eSSatish Balay Level: developer
555e5c89e4eSSatish Balay
556db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionList`
557e5c89e4eSSatish Balay @*/
PetscFunctionListPrintTypes(MPI_Comm comm,FILE * fd,const char prefix[],const char name[],const char text[],const char man[],PetscFunctionList list,const char def[],const char newv[])558d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFunctionListPrintTypes(MPI_Comm comm, FILE *fd, const char prefix[], const char name[], const char text[], const char man[], PetscFunctionList list, const char def[], const char newv[])
559d71ae5a4SJacob Faibussowitsch {
560e5c89e4eSSatish Balay char p[64];
561e5c89e4eSSatish Balay
562e5c89e4eSSatish Balay PetscFunctionBegin;
563ed170139SJacob Faibussowitsch (void)fd;
5649566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(p, "-", sizeof(p)));
5659566063dSJacob Faibussowitsch if (prefix) PetscCall(PetscStrlcat(p, prefix, sizeof(p)));
566ed170139SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " %s%s <now %s : formerly %s>: %s (one of)", p, name + 1, newv, def, text));
567e5c89e4eSSatish Balay
5688c7e48aeSJacob Faibussowitsch if (list) PetscHMapFuncForEach(list, name, func, PetscCall((*PetscHelpPrintf)(comm, " %s", name)));
569ed170139SJacob Faibussowitsch PetscCall((*PetscHelpPrintf)(comm, " (%s)\n", man));
5703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
571e5c89e4eSSatish Balay }
572e5c89e4eSSatish Balay
573ffeef943SBarry Smith /*@C
57421532e8aSBarry Smith PetscFunctionListDuplicate - Creates a new list from a given function list `PetscFunctionList`.
575e5c89e4eSSatish Balay
5762fe279fdSBarry Smith Input Parameter:
577e5c89e4eSSatish Balay . fl - pointer to list
578e5c89e4eSSatish Balay
5792fe279fdSBarry Smith Output Parameter:
58021532e8aSBarry Smith . nl - the new list (should point to `NULL` to start, otherwise appends)
581e5c89e4eSSatish Balay
582e5c89e4eSSatish Balay Level: developer
583e5c89e4eSSatish Balay
584db781477SPatrick Sanan .seealso: `PetscFunctionList`, `PetscFunctionListAdd()`, `PetscFlistDestroy()`
585e5c89e4eSSatish Balay @*/
PetscFunctionListDuplicate(PetscFunctionList fl,PetscFunctionList * nl)586d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscFunctionListDuplicate(PetscFunctionList fl, PetscFunctionList *nl)
587d71ae5a4SJacob Faibussowitsch {
588e5c89e4eSSatish Balay PetscFunctionBegin;
589ed170139SJacob Faibussowitsch if (fl) {
590ed170139SJacob Faibussowitsch PetscHMapFunc dup_map;
591ed170139SJacob Faibussowitsch
592ed170139SJacob Faibussowitsch if (!*nl) {
593ed170139SJacob Faibussowitsch PetscInt n;
594ed170139SJacob Faibussowitsch
595ed170139SJacob Faibussowitsch PetscCall(PetscHMapFuncGetSize(fl->map, &n));
596ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListCreate_Private(n, nl));
597ed170139SJacob Faibussowitsch }
598ed170139SJacob Faibussowitsch dup_map = (*nl)->map;
599ed170139SJacob Faibussowitsch PetscHMapFuncForEach(fl, name, func, PetscCall(PetscHMapFuncInsert_Private(dup_map, name, func)));
600e5c89e4eSSatish Balay }
6013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
602e5c89e4eSSatish Balay }
603