xref: /petsc/src/vec/pf/impls/string/cstring.c (revision 9371c9d470a9602b6d10a8bf50c9b2280a79e45a)
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 
9*9371c9d4SSatish Balay static PetscErrorCode PFView_String(void *value, PetscViewer viewer) {
10ace3abfcSBarry Smith   PetscBool iascii;
11292f8084SBarry Smith 
12292f8084SBarry Smith   PetscFunctionBegin;
139566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
14*9371c9d4SSatish Balay   if (iascii) { PetscCall(PetscViewerASCIIPrintf(viewer, "String = %s\n", (char *)value)); }
15292f8084SBarry Smith   PetscFunctionReturn(0);
16292f8084SBarry Smith }
17292f8084SBarry Smith 
18*9371c9d4SSatish Balay static PetscErrorCode PFDestroy_String(void *value) {
19292f8084SBarry Smith   PetscFunctionBegin;
209566063dSJacob Faibussowitsch   PetscCall(PetscFree(value));
21292f8084SBarry Smith   PetscFunctionReturn(0);
22292f8084SBarry Smith }
23292f8084SBarry Smith 
24292f8084SBarry Smith /*
25292f8084SBarry Smith     PFStringCreateFunction - Creates a function from a string
26292f8084SBarry Smith 
27292f8084SBarry Smith    Collective over PF
28292f8084SBarry Smith 
29292f8084SBarry Smith   Input Parameters:
30292f8084SBarry Smith +    pf - the function object
31292f8084SBarry Smith -    string - the string that defines the function
32292f8084SBarry Smith 
33292f8084SBarry Smith   Output Parameter:
34292f8084SBarry Smith .    f - the function pointer.
35292f8084SBarry Smith 
36db781477SPatrick Sanan .seealso: `PFSetFromOptions()`
37292f8084SBarry Smith 
38292f8084SBarry Smith */
39*9371c9d4SSatish Balay PetscErrorCode PFStringCreateFunction(PF pf, char *string, void **f) {
400598bfebSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
41292f8084SBarry Smith   char      task[1024], tmp[256], lib[PETSC_MAX_PATH_LEN], username[64];
42292f8084SBarry Smith   FILE     *fd;
43ace3abfcSBarry Smith   PetscBool tmpshared, wdshared, keeptmpfiles = PETSC_FALSE;
44292f8084SBarry Smith   MPI_Comm  comm;
45292f8084SBarry Smith #endif
46292f8084SBarry Smith 
47292f8084SBarry Smith   PetscFunctionBegin;
480598bfebSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
499566063dSJacob Faibussowitsch   PetscCall(PetscFree(pf->data));
509566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(string, (char **)&pf->data));
51292f8084SBarry Smith 
52292f8084SBarry Smith   /* create the new C function and compile it */
539566063dSJacob Faibussowitsch   PetscCall(PetscSharedTmp(PetscObjectComm((PetscObject)pf), &tmpshared));
549566063dSJacob Faibussowitsch   PetscCall(PetscSharedWorkingDirectory(PetscObjectComm((PetscObject)pf), &wdshared));
55292f8084SBarry Smith   if (tmpshared) { /* do it in /tmp since everyone has one */
569566063dSJacob Faibussowitsch     PetscCall(PetscGetTmp(PetscObjectComm((PetscObject)pf), tmp, PETSC_MAX_PATH_LEN));
579566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetComm((PetscObject)pf, &comm));
58292f8084SBarry Smith   } else if (!wdshared) { /* each one does in private /tmp */
599566063dSJacob Faibussowitsch     PetscCall(PetscGetTmp(PetscObjectComm((PetscObject)pf), tmp, PETSC_MAX_PATH_LEN));
60292f8084SBarry Smith     comm = PETSC_COMM_SELF;
61292f8084SBarry Smith   } else { /* do it in current directory */
629566063dSJacob Faibussowitsch     PetscCall(PetscStrcpy(tmp, "."));
639566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetComm((PetscObject)pf, &comm));
64292f8084SBarry Smith   }
659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)pf)->options, ((PetscObject)pf)->prefix, "-pf_string_keep_files", &keeptmpfiles, NULL));
66*9371c9d4SSatish Balay   if (keeptmpfiles)
67*9371c9d4SSatish Balay     sprintf(task, "cd %s ; mkdir ${USERNAME} ; cd ${USERNAME} ; \\cp -f ${PETSC_DIR}/src/pf/impls/string/makefile ./makefile ; ke  MIN=%d NOUT=%d petscdlib STRINGFUNCTION=\"%s\" ; sync\n", tmp, (int)pf->dimin, (int)pf->dimout, string);
68*9371c9d4SSatish Balay   else
69*9371c9d4SSatish Balay     sprintf(task, "cd %s ; mkdir ${USERNAME} ; cd ${USERNAME} ; \\cp -f ${PETSC_DIR}/src/pf/impls/string/makefile ./makefile ; make  MIN=%d NOUT=%d -f makefile petscdlib STRINGFUNCTION=\"%s\" ; \\rm -f makefile petscdlib.c libpetscdlib.a ;  sync\n", tmp,
70*9371c9d4SSatish Balay             (int)pf->dimin, (int)pf->dimout, string);
71f6e5521dSKarl Rupp 
727cfd0b05SBarry Smith #if defined(PETSC_HAVE_POPEN)
739566063dSJacob Faibussowitsch   PetscCall(PetscPOpen(comm, NULL, task, "r", &fd));
749566063dSJacob Faibussowitsch   PetscCall(PetscPClose(comm, fd));
757cfd0b05SBarry Smith #else
76e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot run external programs on this machine");
777cfd0b05SBarry Smith #endif
78292f8084SBarry Smith 
799566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Barrier(comm));
80292f8084SBarry Smith 
81292f8084SBarry Smith   /* load the apply function from the dynamic library */
829566063dSJacob Faibussowitsch   PetscCall(PetscGetUserName(username, 64));
83292f8084SBarry Smith   sprintf(lib, "%s/%s/libpetscdlib", tmp, username);
849566063dSJacob Faibussowitsch   PetscCall(PetscDLLibrarySym(comm, NULL, lib, "PFApply_String", f));
8528b400f6SJacob Faibussowitsch   PetscCheck(f, PetscObjectComm((PetscObject)pf), PETSC_ERR_ARG_WRONGSTATE, "Cannot find function %s", lib);
86292f8084SBarry Smith #endif
87292f8084SBarry Smith   PetscFunctionReturn(0);
88292f8084SBarry Smith }
89292f8084SBarry Smith 
90*9371c9d4SSatish Balay static PetscErrorCode PFSetFromOptions_String(PF pf, PetscOptionItems *PetscOptionsObject) {
91ace3abfcSBarry Smith   PetscBool flag;
92292f8084SBarry Smith   char      value[PETSC_MAX_PATH_LEN];
934c8fdceaSLisandro Dalcin   PetscErrorCode (*f)(void *, PetscInt, const PetscScalar *, PetscScalar *) = NULL;
94292f8084SBarry Smith 
95292f8084SBarry Smith   PetscFunctionBegin;
96d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "String function options");
979566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-pf_string", "Enter the function", "PFStringCreateFunction", "", value, sizeof(value), &flag));
98292f8084SBarry Smith   if (flag) {
999566063dSJacob Faibussowitsch     PetscCall(PFStringCreateFunction(pf, value, (void **)&f));
100292f8084SBarry Smith     pf->ops->apply = f;
101292f8084SBarry Smith   }
102d0609cedSBarry Smith   PetscOptionsHeadEnd();
103292f8084SBarry Smith   PetscFunctionReturn(0);
104292f8084SBarry Smith }
105292f8084SBarry Smith 
10626e7fa26SJed Brown typedef PetscErrorCode (*FCN)(void *, PetscInt, const PetscScalar *, PetscScalar *); /* force argument to next function to not be extern C*/
1076ac5842eSBarry Smith 
108*9371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PFCreate_String(PF pf, void *value) {
1094c8fdceaSLisandro Dalcin   FCN f = NULL;
110292f8084SBarry Smith 
111292f8084SBarry Smith   PetscFunctionBegin;
112*9371c9d4SSatish Balay   if (value) { PetscCall(PFStringCreateFunction(pf, (char *)value, (void **)&f)); }
1139566063dSJacob Faibussowitsch   PetscCall(PFSet(pf, f, NULL, PFView_String, PFDestroy_String, NULL));
114292f8084SBarry Smith   pf->ops->setfromoptions = PFSetFromOptions_String;
115292f8084SBarry Smith   PetscFunctionReturn(0);
116292f8084SBarry Smith }
117