1c6db04a5SJed Brown #include <../src/vec/pf/pfimpl.h> /*I "petscpf.h" I*/
2292f8084SBarry Smith
3292f8084SBarry Smith /*
4a5b23f4aSJose E. Roman This PF generates a function on the fly and loads it into the running
5292f8084SBarry Smith program.
6292f8084SBarry Smith */
7292f8084SBarry Smith
PFView_String(void * value,PetscViewer viewer)8d71ae5a4SJacob Faibussowitsch static PetscErrorCode PFView_String(void *value, PetscViewer viewer)
9d71ae5a4SJacob Faibussowitsch {
10*9f196a02SMartin Diehl PetscBool isascii;
11292f8084SBarry Smith
12292f8084SBarry Smith PetscFunctionBegin;
13*9f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
14*9f196a02SMartin Diehl if (isascii) PetscCall(PetscViewerASCIIPrintf(viewer, "String = %s\n", (char *)value));
153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
16292f8084SBarry Smith }
17292f8084SBarry Smith
PFDestroy_String(void * value)18d71ae5a4SJacob Faibussowitsch static PetscErrorCode PFDestroy_String(void *value)
19d71ae5a4SJacob Faibussowitsch {
20292f8084SBarry Smith PetscFunctionBegin;
219566063dSJacob Faibussowitsch PetscCall(PetscFree(value));
223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
23292f8084SBarry Smith }
24292f8084SBarry Smith
PFSetFromOptions_String(PF pf,PetscOptionItems PetscOptionsObject)25ce78bad3SBarry Smith static PetscErrorCode PFSetFromOptions_String(PF pf, PetscOptionItems PetscOptionsObject)
26f236b2adSBarry Smith {
27f236b2adSBarry Smith PetscBool flag;
28f236b2adSBarry Smith char value[PETSC_MAX_PATH_LEN];
29292f8084SBarry Smith
30f236b2adSBarry Smith PetscFunctionBegin;
31f236b2adSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "String function options");
32f236b2adSBarry Smith PetscCall(PetscOptionsString("-pf_string", "Enter the function", "PFStringCreateFunction", "", value, sizeof(value), &flag));
33f236b2adSBarry Smith if (flag) PetscCall(PFStringSetFunction(pf, value));
34f236b2adSBarry Smith PetscOptionsHeadEnd();
35f236b2adSBarry Smith PetscFunctionReturn(PETSC_SUCCESS);
36f236b2adSBarry Smith }
37f236b2adSBarry Smith
3838b5cf2dSJacob Faibussowitsch /*@C
39f236b2adSBarry Smith PFStringSetFunction - Creates a function from a string
40f236b2adSBarry Smith
41f236b2adSBarry Smith Collective
42292f8084SBarry Smith
43292f8084SBarry Smith Input Parameters:
44292f8084SBarry Smith + pf - the function object
45292f8084SBarry Smith - string - the string that defines the function
46292f8084SBarry Smith
47e33f79d8SJacob Faibussowitsch Level: intermediate
48e33f79d8SJacob Faibussowitsch
49f236b2adSBarry Smith Developer Notes:
50e33f79d8SJacob Faibussowitsch Currently this can be used only ONCE in a running code. It needs to be fixed to generate a
51e33f79d8SJacob Faibussowitsch new library name for each new function added.
52f236b2adSBarry Smith
53f236b2adSBarry Smith Requires `PETSC_HAVE_POPEN` `PETSC_USE_SHARED_LIBRARIES` `PETSC_HAVE_DYNAMIC_LIBRARIES` to use
54292f8084SBarry Smith
55db781477SPatrick Sanan .seealso: `PFSetFromOptions()`
5638b5cf2dSJacob Faibussowitsch @*/
PFStringSetFunction(PF pf,const char string[])57cc4c1da9SBarry Smith PetscErrorCode PFStringSetFunction(PF pf, const char string[])
58d71ae5a4SJacob Faibussowitsch {
59f236b2adSBarry Smith char task[1024], tmp[PETSC_MAX_PATH_LEN], lib[PETSC_MAX_PATH_LEN];
60ace3abfcSBarry Smith PetscBool tmpshared, wdshared, keeptmpfiles = PETSC_FALSE;
61292f8084SBarry Smith MPI_Comm comm;
62f236b2adSBarry Smith FILE *fd;
63f236b2adSBarry Smith char *data;
64f236b2adSBarry Smith PetscErrorCode (*f)(void *, PetscInt, const PetscScalar *, PetscScalar *);
65292f8084SBarry Smith
66292f8084SBarry Smith PetscFunctionBegin;
67f236b2adSBarry Smith PetscCall(PetscObjectChangeTypeName((PetscObject)pf, PFSTRING));
68292f8084SBarry Smith /* create the new C function and compile it */
699566063dSJacob Faibussowitsch PetscCall(PetscSharedTmp(PetscObjectComm((PetscObject)pf), &tmpshared));
709566063dSJacob Faibussowitsch PetscCall(PetscSharedWorkingDirectory(PetscObjectComm((PetscObject)pf), &wdshared));
71292f8084SBarry Smith if (tmpshared) { /* do it in /tmp since everyone has one */
72a364092eSJacob Faibussowitsch PetscCall(PetscGetTmp(PetscObjectComm((PetscObject)pf), tmp, PETSC_STATIC_ARRAY_LENGTH(tmp)));
739566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)pf, &comm));
74292f8084SBarry Smith } else if (!wdshared) { /* each one does in private /tmp */
75a364092eSJacob Faibussowitsch PetscCall(PetscGetTmp(PetscObjectComm((PetscObject)pf), tmp, PETSC_STATIC_ARRAY_LENGTH(tmp)));
76292f8084SBarry Smith comm = PETSC_COMM_SELF;
77292f8084SBarry Smith } else { /* do it in current directory */
78c6a7a370SJeremy L Thompson PetscCall(PetscStrncpy(tmp, ".", sizeof(tmp)));
799566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)pf, &comm));
80292f8084SBarry Smith }
819566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetBool(((PetscObject)pf)->options, ((PetscObject)pf)->prefix, "-pf_string_keep_files", &keeptmpfiles, NULL));
82887451b3SStefano Zampini 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" : ""));
83f6e5521dSKarl Rupp
849566063dSJacob Faibussowitsch PetscCall(PetscPOpen(comm, NULL, task, "r", &fd));
859566063dSJacob Faibussowitsch PetscCall(PetscPClose(comm, fd));
869566063dSJacob Faibussowitsch PetscCallMPI(MPI_Barrier(comm));
87292f8084SBarry Smith
88292f8084SBarry Smith /* load the apply function from the dynamic library */
89f236b2adSBarry Smith PetscCall(PetscSNPrintf(lib, PETSC_STATIC_ARRAY_LENGTH(lib), "%s/${USERNAME}/libpetscdlib", tmp));
90f236b2adSBarry Smith PetscCall(PetscDLLibrarySym(comm, NULL, lib, "PFApply_String", (void **)&f));
9128b400f6SJacob Faibussowitsch PetscCheck(f, PetscObjectComm((PetscObject)pf), PETSC_ERR_ARG_WRONGSTATE, "Cannot find function %s", lib);
92f236b2adSBarry Smith
93f236b2adSBarry Smith PetscCall(PetscFree(pf->data));
94835f2295SStefano Zampini PetscCall(PetscStrallocpy(string, &data));
95f236b2adSBarry Smith PetscCall(PFSet(pf, f, NULL, PFView_String, PFDestroy_String, data));
96f236b2adSBarry Smith pf->ops->setfromoptions = PFSetFromOptions_String;
973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
98292f8084SBarry Smith }
99292f8084SBarry Smith
PFCreate_String(PF pf,void * value)100da8c939bSJacob Faibussowitsch PETSC_INTERN PetscErrorCode PFCreate_String(PF pf, void *value)
101d71ae5a4SJacob Faibussowitsch {
102292f8084SBarry Smith PetscFunctionBegin;
103f236b2adSBarry Smith PetscCall(PFStringSetFunction(pf, (const char *)value));
1043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS);
105292f8084SBarry Smith }
106