17d0a6c19SBarry Smith 2e5c89e4eSSatish Balay /* 3e5c89e4eSSatish Balay Provides a general mechanism to allow one to register new routines in 4e5c89e4eSSatish Balay dynamic libraries for many of the PETSc objects (including, e.g., KSP and PC). 5e5c89e4eSSatish Balay */ 6af0996ceSBarry Smith #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/ 7665c2dedSJed Brown #include <petscviewer.h> 8e5c89e4eSSatish Balay 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 169371c9d4SSatish Balay static PetscErrorCode PetscLoadDynamicLibrary(const char *name, PetscBool *found) { 17487e5849SBarry Smith char libs[PETSC_MAX_PATH_LEN], dlib[PETSC_MAX_PATH_LEN]; 18487e5849SBarry Smith 19487e5849SBarry Smith PetscFunctionBegin; 209566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(libs, "${PETSC_LIB_DIR}/libpetsc", sizeof(libs))); 219566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(libs, name, sizeof(libs))); 229566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryRetrieve(PETSC_COMM_WORLD, libs, dlib, 1024, found)); 23487e5849SBarry Smith if (*found) { 249566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, dlib)); 25487e5849SBarry Smith } else { 269566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(libs, "${PETSC_DIR}/${PETSC_ARCH}/lib/libpetsc", sizeof(libs))); 279566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(libs, name, sizeof(libs))); 289566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryRetrieve(PETSC_COMM_WORLD, libs, dlib, 1024, found)); 2948a46eb9SPierre Jolivet if (*found) PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, dlib)); 30487e5849SBarry Smith } 31487e5849SBarry Smith PetscFunctionReturn(0); 32487e5849SBarry Smith } 333fa76a5bSLisandro Dalcin #endif 343fa76a5bSLisandro Dalcin 3560da17ecSBarry Smith #if defined(PETSC_USE_SINGLE_LIBRARY) && !(defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES)) 3695c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode AOInitializePackage(void); 3795c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PetscSFInitializePackage(void); 387da51e29SSatish Balay #if !defined(PETSC_USE_COMPLEX) 3995c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode CharacteristicInitializePackage(void); 407da51e29SSatish Balay #endif 4195c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode ISInitializePackage(void); 4295c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode VecInitializePackage(void); 4395c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode MatInitializePackage(void); 4495c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode DMInitializePackage(void); 4595c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode PCInitializePackage(void); 4695c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode KSPInitializePackage(void); 4795c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode SNESInitializePackage(void); 4895c0884eSLisandro Dalcin PETSC_EXTERN PetscErrorCode TSInitializePackage(void); 4960da17ecSBarry Smith PETSC_EXTERN PetscErrorCode TaoInitializePackage(void); 5060da17ecSBarry Smith #endif 5160da17ecSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY) 5222b6d1caSBarry Smith static MPI_Comm PETSC_COMM_WORLD_INNER = 0, PETSC_COMM_SELF_INNER = 0; 53acff04ddSBarry Smith #endif 54acff04ddSBarry Smith 55e5c89e4eSSatish Balay /* 56e5c89e4eSSatish Balay PetscInitialize_DynamicLibraries - Adds the default dynamic link libraries to the 57e5c89e4eSSatish Balay search path. 58e5c89e4eSSatish Balay */ 599371c9d4SSatish Balay PETSC_INTERN PetscErrorCode PetscInitialize_DynamicLibraries(void) { 60487e5849SBarry Smith char *libname[32]; 61e5c89e4eSSatish Balay PetscInt nmax, i; 6260da17ecSBarry Smith PetscBool preload = PETSC_FALSE; 63540e20f2SPierre Jolivet #if defined(PETSC_HAVE_ELEMENTAL) 64540e20f2SPierre Jolivet PetscBool PetscInitialized = PetscInitializeCalled; 65540e20f2SPierre Jolivet #endif 66e5c89e4eSSatish Balay 6760154eb2SBarry Smith PetscFunctionBegin; 6860da17ecSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY) 6960da17ecSBarry Smith /* These must be all initialized here because it is not safe for individual threads to call these initialize routines */ 7060da17ecSBarry Smith preload = PETSC_TRUE; 7160da17ecSBarry Smith #endif 7260da17ecSBarry Smith 73e5c89e4eSSatish Balay nmax = 32; 749566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetStringArray(NULL, NULL, "-dll_prepend", libname, &nmax, NULL)); 75e5c89e4eSSatish Balay for (i = 0; i < nmax; i++) { 769566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryPrepend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, libname[i])); 779566063dSJacob Faibussowitsch PetscCall(PetscFree(libname[i])); 78e5c89e4eSSatish Balay } 79e5c89e4eSSatish Balay 809566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-library_preload", &preload, NULL)); 8160da17ecSBarry Smith if (!preload) { 829566063dSJacob Faibussowitsch PetscCall(PetscSysInitializePackage()); 8360da17ecSBarry Smith } else { 8460da17ecSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) 85aa2d57e9SJed Brown PetscBool found; 8660154eb2SBarry Smith #if defined(PETSC_USE_SINGLE_LIBRARY) 879566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("", &found)); 8828b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc dynamic library \n You cannot move the dynamic libraries!"); 8960154eb2SBarry Smith #else 909566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("sys", &found)); 9128b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc dynamic library \n You cannot move the dynamic libraries!"); 929566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("vec", &found)); 9328b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc Vec dynamic library \n You cannot move the dynamic libraries!"); 949566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("mat", &found)); 9528b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc Mat dynamic library \n You cannot move the dynamic libraries!"); 969566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("dm", &found)); 9728b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc DM dynamic library \n You cannot move the dynamic libraries!"); 989566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("ksp", &found)); 9928b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc KSP dynamic library \n You cannot move the dynamic libraries!"); 1009566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("snes", &found)); 10128b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc SNES dynamic library \n You cannot move the dynamic libraries!"); 1029566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("ts", &found)); 10328b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc TS dynamic library \n You cannot move the dynamic libraries!"); 1049566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("tao", &found)); 10528b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate Tao dynamic library \n You cannot move the dynamic libraries!"); 106bb84e0fdSBarry Smith #endif 10760da17ecSBarry Smith #else /* defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) */ 10860da17ecSBarry Smith #if defined(PETSC_USE_SINGLE_LIBRARY) 1099566063dSJacob Faibussowitsch PetscCall(AOInitializePackage()); 1109566063dSJacob Faibussowitsch PetscCall(PetscSFInitializePackage()); 1117da51e29SSatish Balay #if !defined(PETSC_USE_COMPLEX) 1129566063dSJacob Faibussowitsch PetscCall(CharacteristicInitializePackage()); 1137da51e29SSatish Balay #endif 1149566063dSJacob Faibussowitsch PetscCall(ISInitializePackage()); 1159566063dSJacob Faibussowitsch PetscCall(VecInitializePackage()); 1169566063dSJacob Faibussowitsch PetscCall(MatInitializePackage()); 1179566063dSJacob Faibussowitsch PetscCall(DMInitializePackage()); 1189566063dSJacob Faibussowitsch PetscCall(PCInitializePackage()); 1199566063dSJacob Faibussowitsch PetscCall(KSPInitializePackage()); 1209566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 1219566063dSJacob Faibussowitsch PetscCall(TSInitializePackage()); 1229566063dSJacob Faibussowitsch PetscCall(TaoInitializePackage()); 12360da17ecSBarry Smith #else 12460da17ecSBarry Smith SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP, "Cannot use -library_preload with multiple static PETSc libraries"); 12560da17ecSBarry Smith #endif 12660da17ecSBarry Smith #endif /* defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) */ 12760da17ecSBarry Smith } 12860da17ecSBarry Smith 12960da17ecSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) && defined(PETSC_USE_SHARED_LIBRARIES) && defined(PETSC_HAVE_BAMG) 13060da17ecSBarry Smith { 13160da17ecSBarry Smith PetscBool found; 1329566063dSJacob Faibussowitsch PetscCall(PetscLoadDynamicLibrary("bamg", &found)); 13328b400f6SJacob Faibussowitsch PetscCheck(found, PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN, "Unable to locate PETSc BAMG dynamic library \n You cannot move the dynamic libraries!"); 13460da17ecSBarry Smith } 13560da17ecSBarry Smith #endif 13660da17ecSBarry Smith 13760da17ecSBarry Smith nmax = 32; 1389566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetStringArray(NULL, NULL, "-dll_append", libname, &nmax, NULL)); 13960da17ecSBarry Smith for (i = 0; i < nmax; i++) { 1409566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryAppend(PETSC_COMM_WORLD, &PetscDLLibrariesLoaded, libname[i])); 1419566063dSJacob Faibussowitsch PetscCall(PetscFree(libname[i])); 14260da17ecSBarry Smith } 14360da17ecSBarry Smith 14460da17ecSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY) 1459566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(PETSC_COMM_SELF, &PETSC_COMM_SELF_INNER, NULL)); 1469566063dSJacob Faibussowitsch PetscCall(PetscCommDuplicate(PETSC_COMM_WORLD, &PETSC_COMM_WORLD_INNER, NULL)); 147acff04ddSBarry Smith #endif 148540e20f2SPierre Jolivet #if defined(PETSC_HAVE_ELEMENTAL) 149540e20f2SPierre Jolivet /* in Fortran, PetscInitializeCalled is set to PETSC_TRUE before PetscInitialize_DynamicLibraries() */ 150540e20f2SPierre Jolivet /* in C, it is not the case, but the value is forced to PETSC_TRUE so that PetscRegisterFinalize() is called */ 151540e20f2SPierre Jolivet PetscInitializeCalled = PETSC_TRUE; 1529566063dSJacob Faibussowitsch PetscCall(PetscElementalInitializePackage()); 153540e20f2SPierre Jolivet PetscInitializeCalled = PetscInitialized; 154540e20f2SPierre Jolivet #endif 155e5c89e4eSSatish Balay PetscFunctionReturn(0); 156e5c89e4eSSatish Balay } 157e5c89e4eSSatish Balay 158ebd79076SLisandro Dalcin /* 159ebd79076SLisandro Dalcin PetscFinalize_DynamicLibraries - Closes the opened dynamic libraries. 160ebd79076SLisandro Dalcin */ 1619371c9d4SSatish Balay PETSC_INTERN PetscErrorCode PetscFinalize_DynamicLibraries(void) { 162ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 163e5c89e4eSSatish Balay 164ebd79076SLisandro Dalcin PetscFunctionBegin; 1659566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(NULL, NULL, "-dll_view", &flg, NULL)); 1669566063dSJacob Faibussowitsch if (flg) PetscCall(PetscDLLibraryPrintPath(PetscDLLibrariesLoaded)); 1679566063dSJacob Faibussowitsch PetscCall(PetscDLLibraryClose(PetscDLLibrariesLoaded)); 168a297a907SKarl Rupp 169acff04ddSBarry Smith #if defined(PETSC_HAVE_THREADSAFETY) 1709566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&PETSC_COMM_SELF_INNER)); 1719566063dSJacob Faibussowitsch PetscCall(PetscCommDestroy(&PETSC_COMM_WORLD_INNER)); 172acff04ddSBarry Smith #endif 173acff04ddSBarry Smith 17402c9f0b5SLisandro Dalcin PetscDLLibrariesLoaded = NULL; 175e5c89e4eSSatish Balay PetscFunctionReturn(0); 176e5c89e4eSSatish Balay } 177e5c89e4eSSatish Balay 178e5c89e4eSSatish Balay /* ------------------------------------------------------------------------------*/ 179140e18c1SBarry Smith struct _n_PetscFunctionList { 180e5c89e4eSSatish Balay void (*routine)(void); /* the routine */ 181e5c89e4eSSatish Balay char *name; /* string to identify routine */ 182140e18c1SBarry Smith PetscFunctionList next; /* next pointer */ 183140e18c1SBarry Smith PetscFunctionList next_list; /* used to maintain list of all lists for freeing */ 184e5c89e4eSSatish Balay }; 185e5c89e4eSSatish Balay 186e5c89e4eSSatish Balay /* 187140e18c1SBarry Smith Keep a linked list of PetscFunctionLists so that we can destroy all the left-over ones. 188e5c89e4eSSatish Balay */ 18902c9f0b5SLisandro Dalcin static PetscFunctionList dlallhead = NULL; 190e5c89e4eSSatish Balay 191a240a19fSJed Brown /*MC 192140e18c1SBarry Smith PetscFunctionListAdd - Given a routine and a string id, saves that routine in the 193e5c89e4eSSatish Balay specified registry. 194e5c89e4eSSatish Balay 195a240a19fSJed Brown Synopsis: 196aaa7dc30SBarry Smith #include <petscsys.h> 197b9fb364aSBarry Smith PetscErrorCode PetscFunctionListAdd(PetscFunctionList *flist,const char name[],void (*fptr)(void)) 198a240a19fSJed Brown 199d4349b43SBarry Smith Not Collective 200e5c89e4eSSatish Balay 201e5c89e4eSSatish Balay Input Parameters: 202b9fb364aSBarry Smith + flist - pointer to function list object 203e5c89e4eSSatish Balay . name - string to identify routine 204a240a19fSJed Brown - fptr - function pointer 205e5c89e4eSSatish Balay 206e5c89e4eSSatish Balay Notes: 207a240a19fSJed Brown To remove a registered routine, pass in a NULL fptr. 208e5c89e4eSSatish Balay 209e5c89e4eSSatish Balay Users who wish to register new classes for use by a particular PETSc 210*811af0c4SBarry Smith component (e.g., `SNES`) should generally call the registration routine 211*811af0c4SBarry Smith for that particular component (e.g., `SNESRegister()`) instead of 212*811af0c4SBarry Smith calling `PetscFunctionListAdd()` directly. 213e5c89e4eSSatish Balay 214e5c89e4eSSatish Balay Level: developer 215e5c89e4eSSatish Balay 216db781477SPatrick Sanan .seealso: `PetscFunctionListDestroy()`, `SNESRegister()`, `KSPRegister()`, 217db781477SPatrick Sanan `PCRegister()`, `TSRegister()`, `PetscFunctionList`, `PetscObjectComposeFunction()` 218a240a19fSJed Brown M*/ 2199371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscFunctionListAdd_Private(PetscFunctionList *fl, const char name[], void (*fnc)(void)) { 220140e18c1SBarry Smith PetscFunctionList entry, ne; 221e5c89e4eSSatish Balay 222e5c89e4eSSatish Balay PetscFunctionBegin; 223e5c89e4eSSatish Balay if (!*fl) { 2249566063dSJacob Faibussowitsch PetscCall(PetscNew(&entry)); 2259566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &entry->name)); 226e5c89e4eSSatish Balay entry->routine = fnc; 22702c9f0b5SLisandro Dalcin entry->next = NULL; 228e5c89e4eSSatish Balay *fl = entry; 229e5c89e4eSSatish Balay 23076bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 231e5c89e4eSSatish Balay /* add this new list to list of all lists */ 232e5c89e4eSSatish Balay if (!dlallhead) { 233e5c89e4eSSatish Balay dlallhead = *fl; 23402c9f0b5SLisandro Dalcin (*fl)->next_list = NULL; 235e5c89e4eSSatish Balay } else { 236e5c89e4eSSatish Balay ne = dlallhead; 237e5c89e4eSSatish Balay dlallhead = *fl; 238e5c89e4eSSatish Balay (*fl)->next_list = ne; 239e5c89e4eSSatish Balay } 24076bd3646SJed Brown } 241a8a6328fSBarry Smith 242e5c89e4eSSatish Balay } else { 243e5c89e4eSSatish Balay /* search list to see if it is already there */ 244e5c89e4eSSatish Balay ne = *fl; 245e5c89e4eSSatish Balay while (ne) { 246ace3abfcSBarry Smith PetscBool founddup; 247e5c89e4eSSatish Balay 2489566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(ne->name, name, &founddup)); 249e5c89e4eSSatish Balay if (founddup) { /* found duplicate */ 250e5c89e4eSSatish Balay ne->routine = fnc; 251e5c89e4eSSatish Balay PetscFunctionReturn(0); 252e5c89e4eSSatish Balay } 253a297a907SKarl Rupp if (ne->next) ne = ne->next; 254a297a907SKarl Rupp else break; 255e5c89e4eSSatish Balay } 256e5c89e4eSSatish Balay /* create new entry and add to end of list */ 2579566063dSJacob Faibussowitsch PetscCall(PetscNew(&entry)); 2589566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(name, &entry->name)); 259e5c89e4eSSatish Balay entry->routine = fnc; 26002c9f0b5SLisandro Dalcin entry->next = NULL; 261e5c89e4eSSatish Balay ne->next = entry; 262e5c89e4eSSatish Balay } 263e5c89e4eSSatish Balay PetscFunctionReturn(0); 264e5c89e4eSSatish Balay } 265e5c89e4eSSatish Balay 266e5c89e4eSSatish Balay /*@ 267140e18c1SBarry Smith PetscFunctionListDestroy - Destroys a list of registered routines. 268e5c89e4eSSatish Balay 269e5c89e4eSSatish Balay Input Parameter: 270e5c89e4eSSatish Balay . fl - pointer to list 271e5c89e4eSSatish Balay 272e5c89e4eSSatish Balay Level: developer 273e5c89e4eSSatish Balay 274db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionList` 275e5c89e4eSSatish Balay @*/ 2769371c9d4SSatish Balay PetscErrorCode PetscFunctionListDestroy(PetscFunctionList *fl) { 277140e18c1SBarry Smith PetscFunctionList next, entry, tmp = dlallhead; 278e5c89e4eSSatish Balay 279e5c89e4eSSatish Balay PetscFunctionBegin; 2801441b1d3SBarry Smith if (!*fl) PetscFunctionReturn(0); 281e5c89e4eSSatish Balay 282e5c89e4eSSatish Balay /* 2839dddd249SSatish Balay Remove this entry from the main DL list (if it is in it) 284e5c89e4eSSatish Balay */ 2851441b1d3SBarry Smith if (dlallhead == *fl) { 286a297a907SKarl Rupp if (dlallhead->next_list) dlallhead = dlallhead->next_list; 28737e93019SBarry Smith else dlallhead = NULL; 28837e93019SBarry Smith } else if (tmp) { 2891441b1d3SBarry Smith while (tmp->next_list != *fl) { 290e5c89e4eSSatish Balay tmp = tmp->next_list; 291e5c89e4eSSatish Balay if (!tmp->next_list) break; 292e5c89e4eSSatish Balay } 293e5c89e4eSSatish Balay if (tmp->next_list) tmp->next_list = tmp->next_list->next_list; 294e5c89e4eSSatish Balay } 295e5c89e4eSSatish Balay 296e5c89e4eSSatish Balay /* free this list */ 2971441b1d3SBarry Smith entry = *fl; 298e5c89e4eSSatish Balay while (entry) { 299e5c89e4eSSatish Balay next = entry->next; 3009566063dSJacob Faibussowitsch PetscCall(PetscFree(entry->name)); 3019566063dSJacob Faibussowitsch PetscCall(PetscFree(entry)); 302e5c89e4eSSatish Balay entry = next; 303e5c89e4eSSatish Balay } 30402c9f0b5SLisandro Dalcin *fl = NULL; 305e5c89e4eSSatish Balay PetscFunctionReturn(0); 306e5c89e4eSSatish Balay } 307e5c89e4eSSatish Balay 308e5c89e4eSSatish Balay /* 3092e956fe4SStefano Zampini Print registered PetscFunctionLists 310e5c89e4eSSatish Balay */ 3119371c9d4SSatish Balay PetscErrorCode PetscFunctionListPrintAll(void) { 31237e93019SBarry Smith PetscFunctionList tmp = dlallhead; 313e5c89e4eSSatish Balay 314e5c89e4eSSatish Balay PetscFunctionBegin; 3152e956fe4SStefano Zampini if (tmp) PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] Registered PetscFunctionLists\n", PetscGlobalRank)); 31637e93019SBarry Smith while (tmp) { 3172e956fe4SStefano Zampini PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] %s\n", PetscGlobalRank, tmp->name)); 31837e93019SBarry Smith tmp = tmp->next_list; 31937e93019SBarry Smith } 320e5c89e4eSSatish Balay PetscFunctionReturn(0); 321e5c89e4eSSatish Balay } 322e5c89e4eSSatish Balay 3231c9cd337SJed Brown /*MC 3242e956fe4SStefano Zampini PetscFunctionListNonEmpty - Print composed names for non null function pointers 3252e956fe4SStefano Zampini 3262e956fe4SStefano Zampini Input Parameter: 3272e956fe4SStefano Zampini . flist - pointer to list 3282e956fe4SStefano Zampini 3292e956fe4SStefano Zampini Level: developer 3302e956fe4SStefano Zampini 3312e956fe4SStefano Zampini .seealso: `PetscFunctionListAdd()`, `PetscFunctionList`, `PetscObjectQueryFunction()` 3322e956fe4SStefano Zampini M*/ 3339371c9d4SSatish Balay PetscErrorCode PetscFunctionListPrintNonEmpty(PetscFunctionList fl) { 3342e956fe4SStefano Zampini PetscFunctionBegin; 3352e956fe4SStefano Zampini while (fl) { 3362e956fe4SStefano Zampini PetscFunctionList next = fl->next; 3372e956fe4SStefano Zampini if (fl->routine) PetscCall(PetscPrintf(PETSC_COMM_SELF, "[%d] function name: %s\n", PetscGlobalRank, fl->name)); 3382e956fe4SStefano Zampini fl = next; 3392e956fe4SStefano Zampini } 3402e956fe4SStefano Zampini PetscFunctionReturn(0); 3412e956fe4SStefano Zampini } 3422e956fe4SStefano Zampini 3432e956fe4SStefano Zampini /*MC 3441c9cd337SJed Brown PetscFunctionListFind - Find function registered under given name 3451c9cd337SJed Brown 3461c9cd337SJed Brown Synopsis: 347aaa7dc30SBarry Smith #include <petscsys.h> 3481c9cd337SJed Brown PetscErrorCode PetscFunctionListFind(PetscFunctionList flist,const char name[],void (**fptr)(void)) 349e5c89e4eSSatish Balay 350e5c89e4eSSatish Balay Input Parameters: 3511c9cd337SJed Brown + flist - pointer to list 3521c9cd337SJed Brown - name - name registered for the function 353e5c89e4eSSatish Balay 354e5c89e4eSSatish Balay Output Parameters: 3551c9cd337SJed Brown . fptr - the function pointer if name was found, else NULL 356e5c89e4eSSatish Balay 357e5c89e4eSSatish Balay Level: developer 358e5c89e4eSSatish Balay 359db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionList`, `PetscObjectQueryFunction()` 3601c9cd337SJed Brown M*/ 3619371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PetscFunctionListFind_Private(PetscFunctionList fl, const char name[], void (**r)(void)) { 362140e18c1SBarry Smith PetscFunctionList entry = fl; 363bdf89e91SBarry Smith PetscBool flg; 364e5c89e4eSSatish Balay 365e5c89e4eSSatish Balay PetscFunctionBegin; 36628b400f6SJacob Faibussowitsch PetscCheck(name, PETSC_COMM_SELF, PETSC_ERR_ARG_NULL, "Trying to find routine with null name"); 367e5c89e4eSSatish Balay 36802c9f0b5SLisandro Dalcin *r = NULL; 369e5c89e4eSSatish Balay while (entry) { 3709566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(name, entry->name, &flg)); 371bdf89e91SBarry Smith if (flg) { 372e5c89e4eSSatish Balay *r = entry->routine; 373e5c89e4eSSatish Balay PetscFunctionReturn(0); 374e5c89e4eSSatish Balay } 375e5c89e4eSSatish Balay entry = entry->next; 376e5c89e4eSSatish Balay } 377e5c89e4eSSatish Balay PetscFunctionReturn(0); 378e5c89e4eSSatish Balay } 379e5c89e4eSSatish Balay 380e5c89e4eSSatish Balay /*@ 381140e18c1SBarry Smith PetscFunctionListView - prints out contents of an PetscFunctionList 382e5c89e4eSSatish Balay 383*811af0c4SBarry Smith Collective over viewer 384e5c89e4eSSatish Balay 385e5c89e4eSSatish Balay Input Parameters: 386e5c89e4eSSatish Balay + list - the list of functions 387e5c89e4eSSatish Balay - viewer - currently ignored 388e5c89e4eSSatish Balay 389e5c89e4eSSatish Balay Level: developer 390e5c89e4eSSatish Balay 391db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionListPrintTypes()`, `PetscFunctionList` 392e5c89e4eSSatish Balay @*/ 3939371c9d4SSatish Balay PetscErrorCode PetscFunctionListView(PetscFunctionList list, PetscViewer viewer) { 394ace3abfcSBarry Smith PetscBool iascii; 395e5c89e4eSSatish Balay 396e5c89e4eSSatish Balay PetscFunctionBegin; 397e5c89e4eSSatish Balay if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 398e5c89e4eSSatish Balay PetscValidPointer(list, 1); 3990700a824SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 400e5c89e4eSSatish Balay 4019566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 40228b400f6SJacob Faibussowitsch PetscCheck(iascii, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only ASCII viewer supported"); 403e5c89e4eSSatish Balay 404e5c89e4eSSatish Balay while (list) { 4059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %s\n", list->name)); 406e5c89e4eSSatish Balay list = list->next; 407e5c89e4eSSatish Balay } 4089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 409e5c89e4eSSatish Balay PetscFunctionReturn(0); 410e5c89e4eSSatish Balay } 411e5c89e4eSSatish Balay 412065533a5SJed Brown /*@C 413*811af0c4SBarry Smith PetscFunctionListGet - Gets an array the contains the entries in `PetscFunctionList`, this is used 414e5c89e4eSSatish Balay by help etc. 415e5c89e4eSSatish Balay 416d4349b43SBarry Smith Not Collective 417e5c89e4eSSatish Balay 418e5c89e4eSSatish Balay Input Parameter: 419e5c89e4eSSatish Balay . list - list of types 420e5c89e4eSSatish Balay 421d8d19677SJose E. Roman Output Parameters: 422e5c89e4eSSatish Balay + array - array of names 423e5c89e4eSSatish Balay - n - length of array 424e5c89e4eSSatish Balay 425*811af0c4SBarry Smith Note: 426e5c89e4eSSatish Balay This allocates the array so that must be freed. BUT the individual entries are 427e5c89e4eSSatish Balay not copied so should not be freed. 428e5c89e4eSSatish Balay 429e5c89e4eSSatish Balay Level: developer 430e5c89e4eSSatish Balay 431db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionList` 432e5c89e4eSSatish Balay @*/ 4339371c9d4SSatish Balay PetscErrorCode PetscFunctionListGet(PetscFunctionList list, const char ***array, int *n) { 434e5c89e4eSSatish Balay PetscInt count = 0; 435140e18c1SBarry Smith PetscFunctionList klist = list; 436e5c89e4eSSatish Balay 437e5c89e4eSSatish Balay PetscFunctionBegin; 438e5c89e4eSSatish Balay while (list) { 439e5c89e4eSSatish Balay list = list->next; 440e5c89e4eSSatish Balay count++; 441e5c89e4eSSatish Balay } 4429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(count + 1, (char ***)array)); 443e5c89e4eSSatish Balay count = 0; 444e5c89e4eSSatish Balay while (klist) { 445e5c89e4eSSatish Balay (*array)[count] = klist->name; 446e5c89e4eSSatish Balay klist = klist->next; 447e5c89e4eSSatish Balay count++; 448e5c89e4eSSatish Balay } 44902c9f0b5SLisandro Dalcin (*array)[count] = NULL; 450e5c89e4eSSatish Balay *n = count + 1; 451e5c89e4eSSatish Balay PetscFunctionReturn(0); 452e5c89e4eSSatish Balay } 453e5c89e4eSSatish Balay 454e5c89e4eSSatish Balay /*@C 455*811af0c4SBarry Smith PetscFunctionListPrintTypes - Prints the methods available in a list of functions 456e5c89e4eSSatish Balay 457e5c89e4eSSatish Balay Collective over MPI_Comm 458e5c89e4eSSatish Balay 459e5c89e4eSSatish Balay Input Parameters: 460*811af0c4SBarry Smith + comm - the communicator (usually `MPI_COMM_WORLD`) 461e5c89e4eSSatish Balay . fd - file to print to, usually stdout 462e5c89e4eSSatish Balay . prefix - prefix to prepend to name (optional) 463e5c89e4eSSatish Balay . name - option string (for example, "-ksp_type") 464e5c89e4eSSatish Balay . text - short description of the object (for example, "Krylov solvers") 465e5c89e4eSSatish Balay . man - name of manual page that discusses the object (for example, "KSPCreate") 4663cc1e11dSBarry Smith . list - list of types 46744ef3d73SBarry Smith . def - default (current) value 46844ef3d73SBarry Smith - newv - new value 469e5c89e4eSSatish Balay 470e5c89e4eSSatish Balay Level: developer 471e5c89e4eSSatish Balay 472db781477SPatrick Sanan .seealso: `PetscFunctionListAdd()`, `PetscFunctionList` 473e5c89e4eSSatish Balay @*/ 4749371c9d4SSatish Balay 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[]) { 475e5c89e4eSSatish Balay char p[64]; 476e5c89e4eSSatish Balay 477e5c89e4eSSatish Balay PetscFunctionBegin; 478da9f1d6bSBarry Smith if (!fd) fd = PETSC_STDOUT; 479e5c89e4eSSatish Balay 4809566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(p, "-", sizeof(p))); 4819566063dSJacob Faibussowitsch if (prefix) PetscCall(PetscStrlcat(p, prefix, sizeof(p))); 4829566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, " %s%s <now %s : formerly %s>: %s (one of)", p, name + 1, newv, def, text)); 483e5c89e4eSSatish Balay 484e5c89e4eSSatish Balay while (list) { 4859566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, " %s", list->name)); 486e5c89e4eSSatish Balay list = list->next; 487e5c89e4eSSatish Balay } 4889566063dSJacob Faibussowitsch PetscCall(PetscFPrintf(comm, fd, " (%s)\n", man)); 489e5c89e4eSSatish Balay PetscFunctionReturn(0); 490e5c89e4eSSatish Balay } 491e5c89e4eSSatish Balay 492e5c89e4eSSatish Balay /*@ 493140e18c1SBarry Smith PetscFunctionListDuplicate - Creates a new list from a given object list. 494e5c89e4eSSatish Balay 495e5c89e4eSSatish Balay Input Parameters: 496e5c89e4eSSatish Balay . fl - pointer to list 497e5c89e4eSSatish Balay 498e5c89e4eSSatish Balay Output Parameters: 499e5c89e4eSSatish Balay . nl - the new list (should point to 0 to start, otherwise appends) 500e5c89e4eSSatish Balay 501e5c89e4eSSatish Balay Level: developer 502e5c89e4eSSatish Balay 503db781477SPatrick Sanan .seealso: `PetscFunctionList`, `PetscFunctionListAdd()`, `PetscFlistDestroy()` 504e5c89e4eSSatish Balay @*/ 5059371c9d4SSatish Balay PetscErrorCode PetscFunctionListDuplicate(PetscFunctionList fl, PetscFunctionList *nl) { 506e5c89e4eSSatish Balay PetscFunctionBegin; 507e5c89e4eSSatish Balay while (fl) { 5089566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(nl, fl->name, fl->routine)); 509e5c89e4eSSatish Balay fl = fl->next; 510e5c89e4eSSatish Balay } 511e5c89e4eSSatish Balay PetscFunctionReturn(0); 512e5c89e4eSSatish Balay } 513