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 */ 6afcb2eb5SJed Brown #include <petsc-private/petscimpl.h> /*I "petscsys.h" I*/ 7*665c2dedSJed Brown #include <petscviewer.h> 8e5c89e4eSSatish Balay 9e5c89e4eSSatish Balay #undef __FUNCT__ 10140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListGetPathAndFunction" 11140e18c1SBarry Smith PetscErrorCode PetscFunctionListGetPathAndFunction(const char name[],char *path[],char *function[]) 12e5c89e4eSSatish Balay { 13e5c89e4eSSatish Balay PetscErrorCode ierr; 14e5c89e4eSSatish Balay char work[PETSC_MAX_PATH_LEN],*lfunction; 15e5c89e4eSSatish Balay 16e5c89e4eSSatish Balay PetscFunctionBegin; 178caf3d72SBarry Smith ierr = PetscStrncpy(work,name,sizeof(work));CHKERRQ(ierr); 18a297a907SKarl Rupp 198caf3d72SBarry Smith work[sizeof(work) - 1] = 0; 20a297a907SKarl Rupp 21e5c89e4eSSatish Balay ierr = PetscStrchr(work,':',&lfunction);CHKERRQ(ierr); 22e5c89e4eSSatish Balay if (lfunction != work && lfunction && lfunction[1] != ':') { 23e5c89e4eSSatish Balay lfunction[0] = 0; 24a297a907SKarl Rupp 25e5c89e4eSSatish Balay ierr = PetscStrallocpy(work,path);CHKERRQ(ierr); 26e5c89e4eSSatish Balay ierr = PetscStrallocpy(lfunction+1,function);CHKERRQ(ierr); 27e5c89e4eSSatish Balay } else { 28e5c89e4eSSatish Balay *path = 0; 29e5c89e4eSSatish Balay ierr = PetscStrallocpy(name,function);CHKERRQ(ierr); 30e5c89e4eSSatish Balay } 31e5c89e4eSSatish Balay PetscFunctionReturn(0); 32e5c89e4eSSatish Balay } 33e5c89e4eSSatish Balay 343fa76a5bSLisandro Dalcin /* 353fa76a5bSLisandro Dalcin This is the default list used by PETSc with the PetscDLLibrary register routines 363fa76a5bSLisandro Dalcin */ 37d44a1e48SBarry Smith PetscDLLibrary PetscDLLibrariesLoaded = 0; 383fa76a5bSLisandro Dalcin 39ebd79076SLisandro Dalcin #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 40ebd79076SLisandro Dalcin 41e5c89e4eSSatish Balay #undef __FUNCT__ 42487e5849SBarry Smith #define __FUNCT__ "PetscLoadDynamicLibrary" 437087cfbeSBarry Smith static PetscErrorCode PetscLoadDynamicLibrary(const char *name,PetscBool *found) 44487e5849SBarry Smith { 45487e5849SBarry Smith char libs[PETSC_MAX_PATH_LEN],dlib[PETSC_MAX_PATH_LEN]; 46487e5849SBarry Smith PetscErrorCode ierr; 47487e5849SBarry Smith 48487e5849SBarry Smith PetscFunctionBegin; 49487e5849SBarry Smith ierr = PetscStrcpy(libs,"${PETSC_LIB_DIR}/libpetsc");CHKERRQ(ierr); 50487e5849SBarry Smith ierr = PetscStrcat(libs,name);CHKERRQ(ierr); 51487e5849SBarry Smith ierr = PetscDLLibraryRetrieve(PETSC_COMM_WORLD,libs,dlib,1024,found);CHKERRQ(ierr); 52487e5849SBarry Smith if (*found) { 53d44a1e48SBarry Smith ierr = PetscDLLibraryAppend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,dlib);CHKERRQ(ierr); 54487e5849SBarry Smith } else { 55487e5849SBarry Smith ierr = PetscStrcpy(libs,"${PETSC_DIR}/${PETSC_ARCH}/lib/libpetsc");CHKERRQ(ierr); 56487e5849SBarry Smith ierr = PetscStrcat(libs,name);CHKERRQ(ierr); 57487e5849SBarry Smith ierr = PetscDLLibraryRetrieve(PETSC_COMM_WORLD,libs,dlib,1024,found);CHKERRQ(ierr); 58487e5849SBarry Smith if (*found) { 59d44a1e48SBarry Smith ierr = PetscDLLibraryAppend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,dlib);CHKERRQ(ierr); 60487e5849SBarry Smith } 61487e5849SBarry Smith } 62487e5849SBarry Smith PetscFunctionReturn(0); 63487e5849SBarry Smith } 64487e5849SBarry Smith 653fa76a5bSLisandro Dalcin #endif 663fa76a5bSLisandro Dalcin 67487e5849SBarry Smith #undef __FUNCT__ 68e5c89e4eSSatish Balay #define __FUNCT__ "PetscInitialize_DynamicLibraries" 69e5c89e4eSSatish Balay /* 70e5c89e4eSSatish Balay PetscInitialize_DynamicLibraries - Adds the default dynamic link libraries to the 71e5c89e4eSSatish Balay search path. 72e5c89e4eSSatish Balay */ 737087cfbeSBarry Smith PetscErrorCode PetscInitialize_DynamicLibraries(void) 74e5c89e4eSSatish Balay { 75487e5849SBarry Smith char *libname[32]; 76e5c89e4eSSatish Balay PetscErrorCode ierr; 77e5c89e4eSSatish Balay PetscInt nmax,i; 783fa76a5bSLisandro Dalcin #if defined(PETSC_USE_DYNAMIC_LIBRARIES) 79ace3abfcSBarry Smith PetscBool found; 803fa76a5bSLisandro Dalcin #endif 81e5c89e4eSSatish Balay 8260154eb2SBarry Smith PetscFunctionBegin; 83e5c89e4eSSatish Balay nmax = 32; 840298fd71SBarry Smith ierr = PetscOptionsGetStringArray(NULL,"-dll_prepend",libname,&nmax,NULL);CHKERRQ(ierr); 85e5c89e4eSSatish Balay for (i=0; i<nmax; i++) { 86d44a1e48SBarry Smith ierr = PetscDLLibraryPrepend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,libname[i]);CHKERRQ(ierr); 87e5c89e4eSSatish Balay ierr = PetscFree(libname[i]);CHKERRQ(ierr); 88e5c89e4eSSatish Balay } 89e5c89e4eSSatish Balay 903fa76a5bSLisandro Dalcin #if !defined(PETSC_USE_DYNAMIC_LIBRARIES) 913fa76a5bSLisandro Dalcin /* 923fa76a5bSLisandro Dalcin This just initializes the most basic PETSc stuff. 933fa76a5bSLisandro Dalcin 943fa76a5bSLisandro Dalcin The classes, from PetscDraw to PetscTS, are initialized the first 953fa76a5bSLisandro Dalcin time an XXCreate() is called. 963fa76a5bSLisandro Dalcin */ 970298fd71SBarry Smith ierr = PetscSysInitializePackage(NULL);CHKERRQ(ierr); 983fa76a5bSLisandro Dalcin #else 9960154eb2SBarry Smith #if defined(PETSC_USE_SINGLE_LIBRARY) 100487e5849SBarry Smith ierr = PetscLoadDynamicLibrary("",&found);CHKERRQ(ierr); 101e32f2f54SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc dynamic library \n You cannot move the dynamic libraries!"); 10260154eb2SBarry Smith #else 10360154eb2SBarry Smith ierr = PetscLoadDynamicLibrary("sys",&found);CHKERRQ(ierr); 10460154eb2SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc dynamic library \n You cannot move the dynamic libraries!"); 105487e5849SBarry Smith ierr = PetscLoadDynamicLibrary("vec",&found);CHKERRQ(ierr); 106e32f2f54SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc Vec dynamic library \n You cannot move the dynamic libraries!"); 107487e5849SBarry Smith ierr = PetscLoadDynamicLibrary("mat",&found);CHKERRQ(ierr); 108e32f2f54SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc Mat dynamic library \n You cannot move the dynamic libraries!"); 109487e5849SBarry Smith ierr = PetscLoadDynamicLibrary("dm",&found);CHKERRQ(ierr); 110e32f2f54SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc DM dynamic library \n You cannot move the dynamic libraries!"); 11160154eb2SBarry Smith ierr = PetscLoadDynamicLibrary("characteristic",&found);CHKERRQ(ierr); 11260154eb2SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc Characteristic dynamic library \n You cannot move the dynamic libraries!"); 113487e5849SBarry Smith ierr = PetscLoadDynamicLibrary("ksp",&found);CHKERRQ(ierr); 114e32f2f54SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc KSP dynamic library \n You cannot move the dynamic libraries!"); 115487e5849SBarry Smith ierr = PetscLoadDynamicLibrary("snes",&found);CHKERRQ(ierr); 116e32f2f54SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc SNES dynamic library \n You cannot move the dynamic libraries!"); 117487e5849SBarry Smith ierr = PetscLoadDynamicLibrary("ts",&found);CHKERRQ(ierr); 118e32f2f54SBarry Smith if (!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate PETSc TS dynamic library \n You cannot move the dynamic libraries!"); 119bb84e0fdSBarry Smith #endif 120e5c89e4eSSatish Balay 121487e5849SBarry Smith ierr = PetscLoadDynamicLibrary("mesh",&found);CHKERRQ(ierr); 122487e5849SBarry Smith ierr = PetscLoadDynamicLibrary("contrib",&found);CHKERRQ(ierr); 1233fa76a5bSLisandro Dalcin #endif 124e5c89e4eSSatish Balay 125e5c89e4eSSatish Balay nmax = 32; 1260298fd71SBarry Smith ierr = PetscOptionsGetStringArray(NULL,"-dll_append",libname,&nmax,NULL);CHKERRQ(ierr); 127e5c89e4eSSatish Balay for (i=0; i<nmax; i++) { 128d44a1e48SBarry Smith ierr = PetscDLLibraryAppend(PETSC_COMM_WORLD,&PetscDLLibrariesLoaded,libname[i]);CHKERRQ(ierr); 129e5c89e4eSSatish Balay ierr = PetscFree(libname[i]);CHKERRQ(ierr); 130e5c89e4eSSatish Balay } 131e5c89e4eSSatish Balay PetscFunctionReturn(0); 132e5c89e4eSSatish Balay } 133e5c89e4eSSatish Balay 134e5c89e4eSSatish Balay #undef __FUNCT__ 135e5c89e4eSSatish Balay #define __FUNCT__ "PetscFinalize_DynamicLibraries" 136ebd79076SLisandro Dalcin /* 137ebd79076SLisandro Dalcin PetscFinalize_DynamicLibraries - Closes the opened dynamic libraries. 138ebd79076SLisandro Dalcin */ 139e5c89e4eSSatish Balay PetscErrorCode PetscFinalize_DynamicLibraries(void) 140e5c89e4eSSatish Balay { 141ebd79076SLisandro Dalcin PetscErrorCode ierr; 142ace3abfcSBarry Smith PetscBool flg = PETSC_FALSE; 143e5c89e4eSSatish Balay 144ebd79076SLisandro Dalcin PetscFunctionBegin; 1450298fd71SBarry Smith ierr = PetscOptionsGetBool(NULL,"-dll_view",&flg,NULL);CHKERRQ(ierr); 146d44a1e48SBarry Smith if (flg) { ierr = PetscDLLibraryPrintPath(PetscDLLibrariesLoaded);CHKERRQ(ierr); } 147d44a1e48SBarry Smith ierr = PetscDLLibraryClose(PetscDLLibrariesLoaded);CHKERRQ(ierr); 148a297a907SKarl Rupp 149d44a1e48SBarry Smith PetscDLLibrariesLoaded = 0; 150e5c89e4eSSatish Balay PetscFunctionReturn(0); 151e5c89e4eSSatish Balay } 152e5c89e4eSSatish Balay 153e4d1774bSDmitry Karpeev 154e4d1774bSDmitry Karpeev 155e5c89e4eSSatish Balay /* ------------------------------------------------------------------------------*/ 156140e18c1SBarry Smith struct _n_PetscFunctionList { 157e5c89e4eSSatish Balay void (*routine)(void); /* the routine */ 158e5c89e4eSSatish Balay char *path; /* path of link library containing routine */ 159e5c89e4eSSatish Balay char *name; /* string to identify routine */ 160e5c89e4eSSatish Balay char *rname; /* routine name in dynamic library */ 161140e18c1SBarry Smith PetscFunctionList next; /* next pointer */ 162140e18c1SBarry Smith PetscFunctionList next_list; /* used to maintain list of all lists for freeing */ 163e5c89e4eSSatish Balay }; 164e5c89e4eSSatish Balay 165e5c89e4eSSatish Balay /* 166140e18c1SBarry Smith Keep a linked list of PetscFunctionLists so that we can destroy all the left-over ones. 167e5c89e4eSSatish Balay */ 168140e18c1SBarry Smith static PetscFunctionList dlallhead = 0; 169e5c89e4eSSatish Balay 170e5c89e4eSSatish Balay #undef __FUNCT__ 171140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListAdd" 172e5c89e4eSSatish Balay /*@C 173140e18c1SBarry Smith PetscFunctionListAdd - Given a routine and a string id, saves that routine in the 174e5c89e4eSSatish Balay specified registry. 175e5c89e4eSSatish Balay 1766d75e210SBarry Smith Formally Collective on MPI_Comm 177e5c89e4eSSatish Balay 178e5c89e4eSSatish Balay Input Parameters: 1796d75e210SBarry Smith + comm - the comm where this exists (currently not used) 1806d75e210SBarry Smith . fl - pointer registry 181e5c89e4eSSatish Balay . name - string to identify routine 182e5c89e4eSSatish Balay . rname - routine name in dynamic library 183e5c89e4eSSatish Balay - fnc - function pointer (optional if using dynamic libraries) 184e5c89e4eSSatish Balay 185e5c89e4eSSatish Balay Notes: 1860298fd71SBarry Smith To remove a registered routine, pass in a NULL rname and fnc(). 187e5c89e4eSSatish Balay 188e5c89e4eSSatish Balay Users who wish to register new classes for use by a particular PETSc 189e5c89e4eSSatish Balay component (e.g., SNES) should generally call the registration routine 190e5c89e4eSSatish Balay for that particular component (e.g., SNESRegisterDynamic()) instead of 191140e18c1SBarry Smith calling PetscFunctionListAdd() directly. 192e5c89e4eSSatish Balay 193e5c89e4eSSatish Balay ${PETSC_ARCH}, ${PETSC_DIR}, ${PETSC_LIB_DIR}, or ${any environmental variable} 194e5c89e4eSSatish Balay occuring in pathname will be replaced with appropriate values. 195e5c89e4eSSatish Balay 196e5c89e4eSSatish Balay Level: developer 197e5c89e4eSSatish Balay 198140e18c1SBarry Smith .seealso: PetscFunctionListDestroy(), SNESRegisterDynamic(), KSPRegisterDynamic(), 199140e18c1SBarry Smith PCRegisterDynamic(), TSRegisterDynamic(), PetscFunctionList 200e5c89e4eSSatish Balay @*/ 201140e18c1SBarry Smith PetscErrorCode PetscFunctionListAdd(MPI_Comm comm,PetscFunctionList *fl,const char name[],const char rname[],void (*fnc)(void)) 202e5c89e4eSSatish Balay { 203140e18c1SBarry Smith PetscFunctionList entry,ne; 204e5c89e4eSSatish Balay PetscErrorCode ierr; 205e5c89e4eSSatish Balay char *fpath,*fname; 206e5c89e4eSSatish Balay 207e5c89e4eSSatish Balay PetscFunctionBegin; 208e5c89e4eSSatish Balay if (!*fl) { 209140e18c1SBarry Smith ierr = PetscNew(struct _n_PetscFunctionList,&entry);CHKERRQ(ierr); 210e5c89e4eSSatish Balay ierr = PetscStrallocpy(name,&entry->name);CHKERRQ(ierr); 211140e18c1SBarry Smith ierr = PetscFunctionListGetPathAndFunction(rname,&fpath,&fname);CHKERRQ(ierr); 212e5c89e4eSSatish Balay entry->path = fpath; 213e5c89e4eSSatish Balay entry->rname = fname; 214e5c89e4eSSatish Balay entry->routine = fnc; 215e5c89e4eSSatish Balay entry->next = 0; 216e5c89e4eSSatish Balay *fl = entry; 217e5c89e4eSSatish Balay 218e5c89e4eSSatish Balay /* add this new list to list of all lists */ 219e5c89e4eSSatish Balay if (!dlallhead) { 220e5c89e4eSSatish Balay dlallhead = *fl; 221e5c89e4eSSatish Balay (*fl)->next_list = 0; 222e5c89e4eSSatish Balay } else { 223e5c89e4eSSatish Balay ne = dlallhead; 224e5c89e4eSSatish Balay dlallhead = *fl; 225e5c89e4eSSatish Balay (*fl)->next_list = ne; 226e5c89e4eSSatish Balay } 227e5c89e4eSSatish Balay } else { 228e5c89e4eSSatish Balay /* search list to see if it is already there */ 229e5c89e4eSSatish Balay ne = *fl; 230e5c89e4eSSatish Balay while (ne) { 231ace3abfcSBarry Smith PetscBool founddup; 232e5c89e4eSSatish Balay 233e5c89e4eSSatish Balay ierr = PetscStrcmp(ne->name,name,&founddup);CHKERRQ(ierr); 234e5c89e4eSSatish Balay if (founddup) { /* found duplicate */ 235140e18c1SBarry Smith ierr = PetscFunctionListGetPathAndFunction(rname,&fpath,&fname);CHKERRQ(ierr); 236503cfb0cSBarry Smith ierr = PetscFree(ne->path);CHKERRQ(ierr); 237503cfb0cSBarry Smith ierr = PetscFree(ne->rname);CHKERRQ(ierr); 238a297a907SKarl Rupp 239e5c89e4eSSatish Balay ne->path = fpath; 240e5c89e4eSSatish Balay ne->rname = fname; 241e5c89e4eSSatish Balay ne->routine = fnc; 242e5c89e4eSSatish Balay PetscFunctionReturn(0); 243e5c89e4eSSatish Balay } 244a297a907SKarl Rupp if (ne->next) ne = ne->next; 245a297a907SKarl Rupp else break; 246e5c89e4eSSatish Balay } 247e5c89e4eSSatish Balay /* create new entry and add to end of list */ 248140e18c1SBarry Smith ierr = PetscNew(struct _n_PetscFunctionList,&entry);CHKERRQ(ierr); 249e5c89e4eSSatish Balay ierr = PetscStrallocpy(name,&entry->name);CHKERRQ(ierr); 250140e18c1SBarry Smith ierr = PetscFunctionListGetPathAndFunction(rname,&fpath,&fname);CHKERRQ(ierr); 251e5c89e4eSSatish Balay entry->path = fpath; 252e5c89e4eSSatish Balay entry->rname = fname; 253e5c89e4eSSatish Balay entry->routine = fnc; 254e5c89e4eSSatish Balay entry->next = 0; 255e5c89e4eSSatish Balay ne->next = entry; 256e5c89e4eSSatish Balay } 257e5c89e4eSSatish Balay PetscFunctionReturn(0); 258e5c89e4eSSatish Balay } 259e5c89e4eSSatish Balay 260e5c89e4eSSatish Balay #undef __FUNCT__ 261140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListDestroy" 262e5c89e4eSSatish Balay /*@ 263140e18c1SBarry Smith PetscFunctionListDestroy - Destroys a list of registered routines. 264e5c89e4eSSatish Balay 265e5c89e4eSSatish Balay Input Parameter: 266e5c89e4eSSatish Balay . fl - pointer to list 267e5c89e4eSSatish Balay 268e5c89e4eSSatish Balay Level: developer 269e5c89e4eSSatish Balay 270140e18c1SBarry Smith .seealso: PetscFunctionListAddDynamic(), PetscFunctionList 271e5c89e4eSSatish Balay @*/ 272140e18c1SBarry Smith PetscErrorCode PetscFunctionListDestroy(PetscFunctionList *fl) 273e5c89e4eSSatish Balay { 274140e18c1SBarry Smith PetscFunctionList next,entry,tmp = dlallhead; 275e5c89e4eSSatish Balay PetscErrorCode ierr; 276e5c89e4eSSatish Balay 277e5c89e4eSSatish Balay PetscFunctionBegin; 2781441b1d3SBarry Smith if (!*fl) PetscFunctionReturn(0); 27960154eb2SBarry Smith if (!dlallhead) PetscFunctionReturn(0); 280e5c89e4eSSatish Balay 281e5c89e4eSSatish Balay /* 282e5c89e4eSSatish Balay Remove this entry from the master DL list (if it is in it) 283e5c89e4eSSatish Balay */ 2841441b1d3SBarry Smith if (dlallhead == *fl) { 285a297a907SKarl Rupp if (dlallhead->next_list) dlallhead = dlallhead->next_list; 286a297a907SKarl Rupp else dlallhead = 0; 287e5c89e4eSSatish Balay } else { 2881441b1d3SBarry Smith while (tmp->next_list != *fl) { 289e5c89e4eSSatish Balay tmp = tmp->next_list; 290e5c89e4eSSatish Balay if (!tmp->next_list) break; 291e5c89e4eSSatish Balay } 292e5c89e4eSSatish Balay if (tmp->next_list) tmp->next_list = tmp->next_list->next_list; 293e5c89e4eSSatish Balay } 294e5c89e4eSSatish Balay 295e5c89e4eSSatish Balay /* free this list */ 2961441b1d3SBarry Smith entry = *fl; 297e5c89e4eSSatish Balay while (entry) { 298e5c89e4eSSatish Balay next = entry->next; 299503cfb0cSBarry Smith ierr = PetscFree(entry->path);CHKERRQ(ierr); 300e5c89e4eSSatish Balay ierr = PetscFree(entry->name);CHKERRQ(ierr); 301e5c89e4eSSatish Balay ierr = PetscFree(entry->rname);CHKERRQ(ierr); 302e5c89e4eSSatish Balay ierr = PetscFree(entry);CHKERRQ(ierr); 303e5c89e4eSSatish Balay entry = next; 304e5c89e4eSSatish Balay } 3051441b1d3SBarry Smith *fl = 0; 306e5c89e4eSSatish Balay PetscFunctionReturn(0); 307e5c89e4eSSatish Balay } 308e5c89e4eSSatish Balay 309e5c89e4eSSatish Balay /* 310e5c89e4eSSatish Balay Destroys all the function lists that anyone has every registered, such as KSPList, VecList, etc. 311e5c89e4eSSatish Balay */ 312e5c89e4eSSatish Balay #undef __FUNCT__ 313140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListDestroyAll" 314140e18c1SBarry Smith PetscErrorCode PetscFunctionListDestroyAll(void) 315e5c89e4eSSatish Balay { 316140e18c1SBarry Smith PetscFunctionList tmp2,tmp1 = dlallhead; 317e5c89e4eSSatish Balay PetscErrorCode ierr; 318e5c89e4eSSatish Balay 319e5c89e4eSSatish Balay PetscFunctionBegin; 320e5c89e4eSSatish Balay while (tmp1) { 321e5c89e4eSSatish Balay tmp2 = tmp1->next_list; 322140e18c1SBarry Smith ierr = PetscFunctionListDestroy(&tmp1);CHKERRQ(ierr); 323e5c89e4eSSatish Balay tmp1 = tmp2; 324e5c89e4eSSatish Balay } 325e5c89e4eSSatish Balay dlallhead = 0; 326e5c89e4eSSatish Balay PetscFunctionReturn(0); 327e5c89e4eSSatish Balay } 328e5c89e4eSSatish Balay 329e5c89e4eSSatish Balay #undef __FUNCT__ 330140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListFind" 331e5c89e4eSSatish Balay /*@C 332140e18c1SBarry Smith PetscFunctionListFind - Given a name, finds the matching routine. 333e5c89e4eSSatish Balay 334e5c89e4eSSatish Balay Input Parameters: 3351d280d73SBarry Smith + fl - pointer to list 3361d280d73SBarry Smith . comm - processors looking for routine 3374b91b6eaSBarry Smith . name - name string 3384b91b6eaSBarry Smith - searchlibraries - if not found in the list then search the dynamic libraries and executable for the symbol 339e5c89e4eSSatish Balay 340e5c89e4eSSatish Balay Output Parameters: 341e5c89e4eSSatish Balay . r - the routine 342e5c89e4eSSatish Balay 343e5c89e4eSSatish Balay Level: developer 344e5c89e4eSSatish Balay 345140e18c1SBarry Smith .seealso: PetscFunctionListAddDynamic(), PetscFunctionList 346e5c89e4eSSatish Balay @*/ 347140e18c1SBarry Smith PetscErrorCode PetscFunctionListFind(MPI_Comm comm,PetscFunctionList fl,const char name[],PetscBool searchlibraries,void (**r)(void)) 348e5c89e4eSSatish Balay { 349140e18c1SBarry Smith PetscFunctionList entry = fl; 350e5c89e4eSSatish Balay PetscErrorCode ierr; 351e5c89e4eSSatish Balay char *function,*path; 352ace3abfcSBarry Smith PetscBool flg,f1,f2,f3; 3530598bfebSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) 354e5c89e4eSSatish Balay char *newpath; 355e5c89e4eSSatish Balay #endif 356e5c89e4eSSatish Balay 357e5c89e4eSSatish Balay PetscFunctionBegin; 358e32f2f54SBarry Smith if (!name) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NULL,"Trying to find routine with null name"); 359e5c89e4eSSatish Balay 360e5c89e4eSSatish Balay *r = 0; 361140e18c1SBarry Smith ierr = PetscFunctionListGetPathAndFunction(name,&path,&function);CHKERRQ(ierr); 362e5c89e4eSSatish Balay 363e5c89e4eSSatish Balay /* 364e5c89e4eSSatish Balay If path then append it to search libraries 365e5c89e4eSSatish Balay */ 3660598bfebSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) 367e5c89e4eSSatish Balay if (path) { 368d44a1e48SBarry Smith ierr = PetscDLLibraryAppend(comm,&PetscDLLibrariesLoaded,path);CHKERRQ(ierr); 369e5c89e4eSSatish Balay } 370e5c89e4eSSatish Balay #endif 371e5c89e4eSSatish Balay 372e5c89e4eSSatish Balay while (entry) { 373e5c89e4eSSatish Balay flg = PETSC_FALSE; 374e5c89e4eSSatish Balay if (path && entry->path) { 375e5c89e4eSSatish Balay ierr = PetscStrcmp(path,entry->path,&f1);CHKERRQ(ierr); 376e5c89e4eSSatish Balay ierr = PetscStrcmp(function,entry->rname,&f2);CHKERRQ(ierr); 377e5c89e4eSSatish Balay ierr = PetscStrcmp(function,entry->name,&f3);CHKERRQ(ierr); 378ace3abfcSBarry Smith flg = (PetscBool) ((f1 && f2) || (f1 && f3)); 379e5c89e4eSSatish Balay } else if (!path) { 380e5c89e4eSSatish Balay ierr = PetscStrcmp(function,entry->name,&f1);CHKERRQ(ierr); 381e5c89e4eSSatish Balay ierr = PetscStrcmp(function,entry->rname,&f2);CHKERRQ(ierr); 382ace3abfcSBarry Smith flg = (PetscBool) (f1 || f2); 383e5c89e4eSSatish Balay } else { 384e5c89e4eSSatish Balay ierr = PetscStrcmp(function,entry->name,&flg);CHKERRQ(ierr); 385e5c89e4eSSatish Balay if (flg) { 386e5c89e4eSSatish Balay ierr = PetscFree(function);CHKERRQ(ierr); 387e5c89e4eSSatish Balay ierr = PetscStrallocpy(entry->rname,&function);CHKERRQ(ierr); 388e5c89e4eSSatish Balay } else { 389e5c89e4eSSatish Balay ierr = PetscStrcmp(function,entry->rname,&flg);CHKERRQ(ierr); 390e5c89e4eSSatish Balay } 391e5c89e4eSSatish Balay } 392e5c89e4eSSatish Balay 393e5c89e4eSSatish Balay if (flg) { 394e5c89e4eSSatish Balay if (entry->routine) { 395e5c89e4eSSatish Balay *r = entry->routine; 396503cfb0cSBarry Smith ierr = PetscFree(path);CHKERRQ(ierr); 397e5c89e4eSSatish Balay ierr = PetscFree(function);CHKERRQ(ierr); 398e5c89e4eSSatish Balay PetscFunctionReturn(0); 399e5c89e4eSSatish Balay } 4005629bde7SJed Brown if (!(entry->rname && entry->rname[0])) { /* The entry has been cleared */ 4015629bde7SJed Brown ierr = PetscFree(function);CHKERRQ(ierr); 4025629bde7SJed Brown PetscFunctionReturn(0); 4035629bde7SJed Brown } 404e5c89e4eSSatish Balay if ((path && entry->path && f3) || (!path && f1)) { /* convert name of function (alias) to actual function name */ 405e5c89e4eSSatish Balay ierr = PetscFree(function);CHKERRQ(ierr); 406e5c89e4eSSatish Balay ierr = PetscStrallocpy(entry->rname,&function);CHKERRQ(ierr); 407e5c89e4eSSatish Balay } 408e5c89e4eSSatish Balay 409e5c89e4eSSatish Balay /* it is not yet in memory so load from dynamic library */ 4100598bfebSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) 411e5c89e4eSSatish Balay newpath = path; 412e5c89e4eSSatish Balay if (!path) newpath = entry->path; 413d44a1e48SBarry Smith ierr = PetscDLLibrarySym(comm,&PetscDLLibrariesLoaded,newpath,entry->rname,(void**)r);CHKERRQ(ierr); 414e5c89e4eSSatish Balay if (*r) { 415e5c89e4eSSatish Balay entry->routine = *r; 416a297a907SKarl Rupp 417503cfb0cSBarry Smith ierr = PetscFree(path);CHKERRQ(ierr); 418e5c89e4eSSatish Balay ierr = PetscFree(function);CHKERRQ(ierr); 419e5c89e4eSSatish Balay PetscFunctionReturn(0); 420e5c89e4eSSatish Balay } 421e5c89e4eSSatish Balay #endif 422e5c89e4eSSatish Balay } 423e5c89e4eSSatish Balay entry = entry->next; 424e5c89e4eSSatish Balay } 425e5c89e4eSSatish Balay 4260598bfebSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) 4274b91b6eaSBarry Smith if (searchlibraries) { 428e5c89e4eSSatish Balay /* Function never registered; try for it anyway */ 429d44a1e48SBarry Smith ierr = PetscDLLibrarySym(comm,&PetscDLLibrariesLoaded,path,function,(void**)r);CHKERRQ(ierr); 430503cfb0cSBarry Smith ierr = PetscFree(path);CHKERRQ(ierr); 431e5c89e4eSSatish Balay if (*r) { 432140e18c1SBarry Smith ierr = PetscFunctionListAdd(comm,&fl,name,name,*r);CHKERRQ(ierr); 433e5c89e4eSSatish Balay } 4344b91b6eaSBarry Smith } 435e5c89e4eSSatish Balay #endif 436e5c89e4eSSatish Balay ierr = PetscFree(function);CHKERRQ(ierr); 437e5c89e4eSSatish Balay PetscFunctionReturn(0); 438e5c89e4eSSatish Balay } 439e5c89e4eSSatish Balay 440e5c89e4eSSatish Balay #undef __FUNCT__ 441140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListView" 442e5c89e4eSSatish Balay /*@ 443140e18c1SBarry Smith PetscFunctionListView - prints out contents of an PetscFunctionList 444e5c89e4eSSatish Balay 445e5c89e4eSSatish Balay Collective over MPI_Comm 446e5c89e4eSSatish Balay 447e5c89e4eSSatish Balay Input Parameters: 448e5c89e4eSSatish Balay + list - the list of functions 449e5c89e4eSSatish Balay - viewer - currently ignored 450e5c89e4eSSatish Balay 451e5c89e4eSSatish Balay Level: developer 452e5c89e4eSSatish Balay 453140e18c1SBarry Smith .seealso: PetscFunctionListAddDynamic(), PetscFunctionListPrintTypes(), PetscFunctionList 454e5c89e4eSSatish Balay @*/ 455140e18c1SBarry Smith PetscErrorCode PetscFunctionListView(PetscFunctionList list,PetscViewer viewer) 456e5c89e4eSSatish Balay { 457e5c89e4eSSatish Balay PetscErrorCode ierr; 458ace3abfcSBarry Smith PetscBool iascii; 459e5c89e4eSSatish Balay 460e5c89e4eSSatish Balay PetscFunctionBegin; 461e5c89e4eSSatish Balay if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF; 462e5c89e4eSSatish Balay PetscValidPointer(list,1); 4630700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 464e5c89e4eSSatish Balay 465251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 466e32f2f54SBarry Smith if (!iascii) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only ASCII viewer supported"); 467e5c89e4eSSatish Balay 468e5c89e4eSSatish Balay while (list) { 469e5c89e4eSSatish Balay if (list->path) { 470e5c89e4eSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," %s %s %s\n",list->path,list->name,list->rname);CHKERRQ(ierr); 471e5c89e4eSSatish Balay } else { 472e5c89e4eSSatish Balay ierr = PetscViewerASCIIPrintf(viewer," %s %s\n",list->name,list->rname);CHKERRQ(ierr); 473e5c89e4eSSatish Balay } 474e5c89e4eSSatish Balay list = list->next; 475e5c89e4eSSatish Balay } 476e5c89e4eSSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 477e5c89e4eSSatish Balay PetscFunctionReturn(0); 478e5c89e4eSSatish Balay } 479e5c89e4eSSatish Balay 480e5c89e4eSSatish Balay #undef __FUNCT__ 481140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListGet" 482065533a5SJed Brown /*@C 483140e18c1SBarry Smith PetscFunctionListGet - Gets an array the contains the entries in PetscFunctionList, this is used 484e5c89e4eSSatish Balay by help etc. 485e5c89e4eSSatish Balay 486e5c89e4eSSatish Balay Collective over MPI_Comm 487e5c89e4eSSatish Balay 488e5c89e4eSSatish Balay Input Parameter: 489e5c89e4eSSatish Balay . list - list of types 490e5c89e4eSSatish Balay 491e5c89e4eSSatish Balay Output Parameter: 492e5c89e4eSSatish Balay + array - array of names 493e5c89e4eSSatish Balay - n - length of array 494e5c89e4eSSatish Balay 495e5c89e4eSSatish Balay Notes: 496e5c89e4eSSatish Balay This allocates the array so that must be freed. BUT the individual entries are 497e5c89e4eSSatish Balay not copied so should not be freed. 498e5c89e4eSSatish Balay 499e5c89e4eSSatish Balay Level: developer 500e5c89e4eSSatish Balay 501140e18c1SBarry Smith .seealso: PetscFunctionListAddDynamic(), PetscFunctionList 502e5c89e4eSSatish Balay @*/ 503140e18c1SBarry Smith PetscErrorCode PetscFunctionListGet(PetscFunctionList list,const char ***array,int *n) 504e5c89e4eSSatish Balay { 505e5c89e4eSSatish Balay PetscErrorCode ierr; 506e5c89e4eSSatish Balay PetscInt count = 0; 507140e18c1SBarry Smith PetscFunctionList klist = list; 508e5c89e4eSSatish Balay 509e5c89e4eSSatish Balay PetscFunctionBegin; 510e5c89e4eSSatish Balay while (list) { 511e5c89e4eSSatish Balay list = list->next; 512e5c89e4eSSatish Balay count++; 513e5c89e4eSSatish Balay } 514e5c89e4eSSatish Balay ierr = PetscMalloc((count+1)*sizeof(char*),array);CHKERRQ(ierr); 515e5c89e4eSSatish Balay count = 0; 516e5c89e4eSSatish Balay while (klist) { 517e5c89e4eSSatish Balay (*array)[count] = klist->name; 518e5c89e4eSSatish Balay klist = klist->next; 519e5c89e4eSSatish Balay count++; 520e5c89e4eSSatish Balay } 521e5c89e4eSSatish Balay (*array)[count] = 0; 522e5c89e4eSSatish Balay *n = count+1; 523e5c89e4eSSatish Balay PetscFunctionReturn(0); 524e5c89e4eSSatish Balay } 525e5c89e4eSSatish Balay 526e5c89e4eSSatish Balay 527e5c89e4eSSatish Balay #undef __FUNCT__ 528140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListPrintTypes" 529e5c89e4eSSatish Balay /*@C 530140e18c1SBarry Smith PetscFunctionListPrintTypes - Prints the methods available. 531e5c89e4eSSatish Balay 532e5c89e4eSSatish Balay Collective over MPI_Comm 533e5c89e4eSSatish Balay 534e5c89e4eSSatish Balay Input Parameters: 535e5c89e4eSSatish Balay + comm - the communicator (usually MPI_COMM_WORLD) 536e5c89e4eSSatish Balay . fd - file to print to, usually stdout 537e5c89e4eSSatish Balay . prefix - prefix to prepend to name (optional) 538e5c89e4eSSatish Balay . name - option string (for example, "-ksp_type") 539e5c89e4eSSatish Balay . text - short description of the object (for example, "Krylov solvers") 540e5c89e4eSSatish Balay . man - name of manual page that discusses the object (for example, "KSPCreate") 5413cc1e11dSBarry Smith . list - list of types 5423cc1e11dSBarry Smith - def - default (current) value 543e5c89e4eSSatish Balay 544e5c89e4eSSatish Balay Level: developer 545e5c89e4eSSatish Balay 546140e18c1SBarry Smith .seealso: PetscFunctionListAddDynamic(), PetscFunctionList 547e5c89e4eSSatish Balay @*/ 548140e18c1SBarry Smith PetscErrorCode PetscFunctionListPrintTypes(MPI_Comm comm,FILE *fd,const char prefix[],const char name[],const char text[],const char man[],PetscFunctionList list,const char def[]) 549e5c89e4eSSatish Balay { 550e5c89e4eSSatish Balay PetscErrorCode ierr; 551e5c89e4eSSatish Balay PetscInt count = 0; 552e5c89e4eSSatish Balay char p[64]; 553e5c89e4eSSatish Balay 554e5c89e4eSSatish Balay PetscFunctionBegin; 555da9f1d6bSBarry Smith if (!fd) fd = PETSC_STDOUT; 556e5c89e4eSSatish Balay 557e5c89e4eSSatish Balay ierr = PetscStrcpy(p,"-");CHKERRQ(ierr); 558e5c89e4eSSatish Balay if (prefix) {ierr = PetscStrcat(p,prefix);CHKERRQ(ierr);} 5593cc1e11dSBarry Smith ierr = PetscFPrintf(comm,fd," %s%s <%s>: %s (one of)",p,name+1,def,text);CHKERRQ(ierr); 560e5c89e4eSSatish Balay 561e5c89e4eSSatish Balay while (list) { 562e5c89e4eSSatish Balay ierr = PetscFPrintf(comm,fd," %s",list->name);CHKERRQ(ierr); 563e5c89e4eSSatish Balay list = list->next; 564e5c89e4eSSatish Balay count++; 565e5c89e4eSSatish Balay if (count == 8) {ierr = PetscFPrintf(comm,fd,"\n ");CHKERRQ(ierr);} 566e5c89e4eSSatish Balay } 567e5c89e4eSSatish Balay ierr = PetscFPrintf(comm,fd," (%s)\n",man);CHKERRQ(ierr); 568e5c89e4eSSatish Balay PetscFunctionReturn(0); 569e5c89e4eSSatish Balay } 570e5c89e4eSSatish Balay 571e5c89e4eSSatish Balay #undef __FUNCT__ 572140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListDuplicate" 573e5c89e4eSSatish Balay /*@ 574140e18c1SBarry Smith PetscFunctionListDuplicate - Creates a new list from a given object list. 575e5c89e4eSSatish Balay 576e5c89e4eSSatish Balay Input Parameters: 577e5c89e4eSSatish Balay . fl - pointer to list 578e5c89e4eSSatish Balay 579e5c89e4eSSatish Balay Output Parameters: 580e5c89e4eSSatish Balay . nl - the new list (should point to 0 to start, otherwise appends) 581e5c89e4eSSatish Balay 582e5c89e4eSSatish Balay Level: developer 583e5c89e4eSSatish Balay 584140e18c1SBarry Smith .seealso: PetscFunctionList, PetscFunctionListAdd(), PetscFlistDestroy() 585e5c89e4eSSatish Balay 586e5c89e4eSSatish Balay @*/ 587140e18c1SBarry Smith PetscErrorCode PetscFunctionListDuplicate(PetscFunctionList fl,PetscFunctionList *nl) 588e5c89e4eSSatish Balay { 589e5c89e4eSSatish Balay PetscErrorCode ierr; 590e5c89e4eSSatish Balay char path[PETSC_MAX_PATH_LEN]; 591e5c89e4eSSatish Balay 592e5c89e4eSSatish Balay PetscFunctionBegin; 593e5c89e4eSSatish Balay while (fl) { 594e5c89e4eSSatish Balay /* this is silly, rebuild the complete pathname */ 595e5c89e4eSSatish Balay if (fl->path) { 596e5c89e4eSSatish Balay ierr = PetscStrcpy(path,fl->path);CHKERRQ(ierr); 597e5c89e4eSSatish Balay ierr = PetscStrcat(path,":");CHKERRQ(ierr); 598e5c89e4eSSatish Balay ierr = PetscStrcat(path,fl->name);CHKERRQ(ierr); 599e5c89e4eSSatish Balay } else { 600e5c89e4eSSatish Balay ierr = PetscStrcpy(path,fl->name);CHKERRQ(ierr); 601e5c89e4eSSatish Balay } 602140e18c1SBarry Smith ierr = PetscFunctionListAdd(PETSC_COMM_WORLD,nl,path,fl->rname,fl->routine);CHKERRQ(ierr); 603e5c89e4eSSatish Balay fl = fl->next; 604e5c89e4eSSatish Balay } 605e5c89e4eSSatish Balay PetscFunctionReturn(0); 606e5c89e4eSSatish Balay } 607e5c89e4eSSatish Balay 608e5c89e4eSSatish Balay 609e5c89e4eSSatish Balay #undef __FUNCT__ 610140e18c1SBarry Smith #define __FUNCT__ "PetscFunctionListConcat" 611e5c89e4eSSatish Balay /* 612140e18c1SBarry Smith PetscFunctionListConcat - joins name of a libary, and the path where it is located 613e5c89e4eSSatish Balay into a single string. 614e5c89e4eSSatish Balay 615e5c89e4eSSatish Balay Input Parameters: 616e5c89e4eSSatish Balay . path - path to the library name. 617e5c89e4eSSatish Balay . name - name of the library 618e5c89e4eSSatish Balay 619e5c89e4eSSatish Balay Output Parameters: 620e5c89e4eSSatish Balay . fullname - the name that is the union of the path and the library name, 621e5c89e4eSSatish Balay delimited by a semicolon, i.e., path:name 622e5c89e4eSSatish Balay 623e5c89e4eSSatish Balay Notes: 624e5c89e4eSSatish Balay If the path is NULL, assumes that the name, specified also includes 625e5c89e4eSSatish Balay the path as path:name 626e5c89e4eSSatish Balay 627e5c89e4eSSatish Balay */ 628140e18c1SBarry Smith PetscErrorCode PetscFunctionListConcat(const char path[],const char name[],char fullname[]) 629e5c89e4eSSatish Balay { 630e5c89e4eSSatish Balay PetscErrorCode ierr; 6315fd66863SKarl Rupp 632e5c89e4eSSatish Balay PetscFunctionBegin; 633e5c89e4eSSatish Balay if (path) { 634e5c89e4eSSatish Balay ierr = PetscStrcpy(fullname,path);CHKERRQ(ierr); 635e5c89e4eSSatish Balay ierr = PetscStrcat(fullname,":");CHKERRQ(ierr); 636e5c89e4eSSatish Balay ierr = PetscStrcat(fullname,name);CHKERRQ(ierr); 637e5c89e4eSSatish Balay } else { 638e5c89e4eSSatish Balay ierr = PetscStrcpy(fullname,name);CHKERRQ(ierr); 639e5c89e4eSSatish Balay } 640e5c89e4eSSatish Balay PetscFunctionReturn(0); 641e5c89e4eSSatish Balay } 642