1292f8084SBarry Smith 2c6db04a5SJed Brown #include <../src/vec/pf/pfimpl.h> /*I "petscpf.h" I*/ 3292f8084SBarry Smith 4292f8084SBarry Smith /* 5a5b23f4aSJose E. Roman This PF generates a function on the fly and loads it into the running 6292f8084SBarry Smith program. 7292f8084SBarry Smith */ 8292f8084SBarry Smith 9d71ae5a4SJacob Faibussowitsch static PetscErrorCode PFView_String(void *value, PetscViewer viewer) 10d71ae5a4SJacob Faibussowitsch { 11ace3abfcSBarry Smith PetscBool iascii; 12292f8084SBarry Smith 13292f8084SBarry Smith PetscFunctionBegin; 149566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 1548a46eb9SPierre Jolivet if (iascii) PetscCall(PetscViewerASCIIPrintf(viewer, "String = %s\n", (char *)value)); 163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17292f8084SBarry Smith } 18292f8084SBarry Smith 19d71ae5a4SJacob Faibussowitsch static PetscErrorCode PFDestroy_String(void *value) 20d71ae5a4SJacob Faibussowitsch { 21292f8084SBarry Smith PetscFunctionBegin; 229566063dSJacob Faibussowitsch PetscCall(PetscFree(value)); 233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24292f8084SBarry Smith } 25292f8084SBarry Smith 26*f236b2adSBarry Smith static PetscErrorCode PFSetFromOptions_String(PF pf, PetscOptionItems *PetscOptionsObject) 27*f236b2adSBarry Smith { 28*f236b2adSBarry Smith PetscBool flag; 29*f236b2adSBarry Smith char value[PETSC_MAX_PATH_LEN]; 30292f8084SBarry Smith 31*f236b2adSBarry Smith PetscFunctionBegin; 32*f236b2adSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "String function options"); 33*f236b2adSBarry Smith PetscCall(PetscOptionsString("-pf_string", "Enter the function", "PFStringCreateFunction", "", value, sizeof(value), &flag)); 34*f236b2adSBarry Smith if (flag) PetscCall(PFStringSetFunction(pf, value)); 35*f236b2adSBarry Smith PetscOptionsHeadEnd(); 36*f236b2adSBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 37*f236b2adSBarry Smith } 38*f236b2adSBarry Smith 39*f236b2adSBarry Smith /* 40*f236b2adSBarry Smith PFStringSetFunction - Creates a function from a string 41*f236b2adSBarry Smith 42*f236b2adSBarry Smith Collective 43292f8084SBarry Smith 44292f8084SBarry Smith Input Parameters: 45292f8084SBarry Smith + pf - the function object 46292f8084SBarry Smith - string - the string that defines the function 47292f8084SBarry Smith 48*f236b2adSBarry Smith Developer Notes: 49*f236b2adSBarry Smith Currently this can be used only ONCE in a running code. It needs to be fixed to generate a new library name for each new function added. 50*f236b2adSBarry Smith 51*f236b2adSBarry Smith Requires `PETSC_HAVE_POPEN` `PETSC_USE_SHARED_LIBRARIES` `PETSC_HAVE_DYNAMIC_LIBRARIES` to use 52292f8084SBarry Smith 53db781477SPatrick Sanan .seealso: `PFSetFromOptions()` 54292f8084SBarry Smith */ 55*f236b2adSBarry Smith PetscErrorCode PFStringSetFunction(PF pf, const char *string) 56d71ae5a4SJacob Faibussowitsch { 57*f236b2adSBarry Smith char task[1024], tmp[PETSC_MAX_PATH_LEN], lib[PETSC_MAX_PATH_LEN]; 58ace3abfcSBarry Smith PetscBool tmpshared, wdshared, keeptmpfiles = PETSC_FALSE; 59292f8084SBarry Smith MPI_Comm comm; 60*f236b2adSBarry Smith FILE *fd; 61*f236b2adSBarry Smith char *data; 62*f236b2adSBarry Smith PetscErrorCode (*f)(void *, PetscInt, const PetscScalar *, PetscScalar *); 63292f8084SBarry Smith 64292f8084SBarry Smith PetscFunctionBegin; 65*f236b2adSBarry Smith PetscCall(PetscObjectChangeTypeName((PetscObject)pf, PFSTRING)); 66292f8084SBarry Smith /* create the new C function and compile it */ 679566063dSJacob Faibussowitsch PetscCall(PetscSharedTmp(PetscObjectComm((PetscObject)pf), &tmpshared)); 689566063dSJacob Faibussowitsch PetscCall(PetscSharedWorkingDirectory(PetscObjectComm((PetscObject)pf), &wdshared)); 69292f8084SBarry Smith if (tmpshared) { /* do it in /tmp since everyone has one */ 70a364092eSJacob Faibussowitsch PetscCall(PetscGetTmp(PetscObjectComm((PetscObject)pf), tmp, PETSC_STATIC_ARRAY_LENGTH(tmp))); 719566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)pf, &comm)); 72292f8084SBarry Smith } else if (!wdshared) { /* each one does in private /tmp */ 73a364092eSJacob Faibussowitsch PetscCall(PetscGetTmp(PetscObjectComm((PetscObject)pf), tmp, PETSC_STATIC_ARRAY_LENGTH(tmp))); 74292f8084SBarry Smith comm = PETSC_COMM_SELF; 75292f8084SBarry Smith } else { /* do it in current directory */ 76c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(tmp, ".", sizeof(tmp))); 779566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)pf, &comm)); 78292f8084SBarry Smith } 799566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(((PetscObject)pf)->options, ((PetscObject)pf)->prefix, "-pf_string_keep_files", &keeptmpfiles, NULL)); 80*f236b2adSBarry Smith PetscCall(PetscSNPrintf(task, PETSC_STATIC_ARRAY_LENGTH(task), "cd %s ; if [ ! -d ${USERNAME} ]; then mkdir ${USERNAME}; fi ; cd ${USERNAME} ; rm -f makefile petscdlib.* ; cp -f ${PETSC_DIR}/src/vec/pf/impls/string/makefile ./makefile ; ${PETSC_MAKE} NIN=%" PetscInt_FMT " NOUT=%" PetscInt_FMT " -f makefile libpetscdlib STRINGFUNCTION=\"%s\" %s ; sync\n", tmp, pf->dimin, pf->dimout, string, keeptmpfiles ? "; rm -f makefile petscdlib.c" : "")); 81f6e5521dSKarl Rupp 829566063dSJacob Faibussowitsch PetscCall(PetscPOpen(comm, NULL, task, "r", &fd)); 839566063dSJacob Faibussowitsch PetscCall(PetscPClose(comm, fd)); 849566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(comm)); 85292f8084SBarry Smith 86292f8084SBarry Smith /* load the apply function from the dynamic library */ 87*f236b2adSBarry Smith PetscCall(PetscSNPrintf(lib, PETSC_STATIC_ARRAY_LENGTH(lib), "%s/${USERNAME}/libpetscdlib", tmp)); 88*f236b2adSBarry Smith PetscCall(PetscDLLibrarySym(comm, NULL, lib, "PFApply_String", (void **)&f)); 8928b400f6SJacob Faibussowitsch PetscCheck(f, PetscObjectComm((PetscObject)pf), PETSC_ERR_ARG_WRONGSTATE, "Cannot find function %s", lib); 90*f236b2adSBarry Smith 91*f236b2adSBarry Smith PetscCall(PetscFree(pf->data)); 92*f236b2adSBarry Smith PetscCall(PetscStrallocpy(string, (char **)&data)); 93*f236b2adSBarry Smith PetscCall(PFSet(pf, f, NULL, PFView_String, PFDestroy_String, data)); 94*f236b2adSBarry Smith pf->ops->setfromoptions = PFSetFromOptions_String; 953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 96292f8084SBarry Smith } 97292f8084SBarry Smith 98d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PFCreate_String(PF pf, void *value) 99d71ae5a4SJacob Faibussowitsch { 100292f8084SBarry Smith PetscFunctionBegin; 101*f236b2adSBarry Smith PetscCall(PFStringSetFunction(pf, (const char *)value)); 1023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 103292f8084SBarry Smith } 104