xref: /petsc/src/vec/pf/impls/string/cstring.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
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*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PFView_String(void *value, PetscViewer viewer)
10*d71ae5a4SJacob 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));
16292f8084SBarry Smith   PetscFunctionReturn(0);
17292f8084SBarry Smith }
18292f8084SBarry Smith 
19*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PFDestroy_String(void *value)
20*d71ae5a4SJacob Faibussowitsch {
21292f8084SBarry Smith   PetscFunctionBegin;
229566063dSJacob Faibussowitsch   PetscCall(PetscFree(value));
23292f8084SBarry Smith   PetscFunctionReturn(0);
24292f8084SBarry Smith }
25292f8084SBarry Smith 
26292f8084SBarry Smith /*
27292f8084SBarry Smith     PFStringCreateFunction - Creates a function from a string
28292f8084SBarry Smith 
29292f8084SBarry Smith    Collective over PF
30292f8084SBarry Smith 
31292f8084SBarry Smith   Input Parameters:
32292f8084SBarry Smith +    pf - the function object
33292f8084SBarry Smith -    string - the string that defines the function
34292f8084SBarry Smith 
35292f8084SBarry Smith   Output Parameter:
36292f8084SBarry Smith .    f - the function pointer.
37292f8084SBarry Smith 
38db781477SPatrick Sanan .seealso: `PFSetFromOptions()`
39292f8084SBarry Smith 
40292f8084SBarry Smith */
41*d71ae5a4SJacob Faibussowitsch PetscErrorCode PFStringCreateFunction(PF pf, char *string, void **f)
42*d71ae5a4SJacob Faibussowitsch {
430598bfebSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
44292f8084SBarry Smith   char      task[1024], tmp[256], lib[PETSC_MAX_PATH_LEN], username[64];
45292f8084SBarry Smith   FILE     *fd;
46ace3abfcSBarry Smith   PetscBool tmpshared, wdshared, keeptmpfiles = PETSC_FALSE;
47292f8084SBarry Smith   MPI_Comm  comm;
48292f8084SBarry Smith #endif
49292f8084SBarry Smith 
50292f8084SBarry Smith   PetscFunctionBegin;
510598bfebSBarry Smith #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES)
529566063dSJacob Faibussowitsch   PetscCall(PetscFree(pf->data));
539566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(string, (char **)&pf->data));
54292f8084SBarry Smith 
55292f8084SBarry Smith   /* create the new C function and compile it */
569566063dSJacob Faibussowitsch   PetscCall(PetscSharedTmp(PetscObjectComm((PetscObject)pf), &tmpshared));
579566063dSJacob Faibussowitsch   PetscCall(PetscSharedWorkingDirectory(PetscObjectComm((PetscObject)pf), &wdshared));
58292f8084SBarry Smith   if (tmpshared) { /* do it in /tmp since everyone has one */
599566063dSJacob Faibussowitsch     PetscCall(PetscGetTmp(PetscObjectComm((PetscObject)pf), tmp, PETSC_MAX_PATH_LEN));
609566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetComm((PetscObject)pf, &comm));
61292f8084SBarry Smith   } else if (!wdshared) { /* each one does in private /tmp */
629566063dSJacob Faibussowitsch     PetscCall(PetscGetTmp(PetscObjectComm((PetscObject)pf), tmp, PETSC_MAX_PATH_LEN));
63292f8084SBarry Smith     comm = PETSC_COMM_SELF;
64292f8084SBarry Smith   } else { /* do it in current directory */
659566063dSJacob Faibussowitsch     PetscCall(PetscStrcpy(tmp, "."));
669566063dSJacob Faibussowitsch     PetscCall(PetscObjectGetComm((PetscObject)pf, &comm));
67292f8084SBarry Smith   }
689566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(((PetscObject)pf)->options, ((PetscObject)pf)->prefix, "-pf_string_keep_files", &keeptmpfiles, NULL));
699371c9d4SSatish Balay   if (keeptmpfiles)
709371c9d4SSatish 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);
719371c9d4SSatish Balay   else
729371c9d4SSatish 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,
739371c9d4SSatish Balay             (int)pf->dimin, (int)pf->dimout, string);
74f6e5521dSKarl Rupp 
757cfd0b05SBarry Smith   #if defined(PETSC_HAVE_POPEN)
769566063dSJacob Faibussowitsch   PetscCall(PetscPOpen(comm, NULL, task, "r", &fd));
779566063dSJacob Faibussowitsch   PetscCall(PetscPClose(comm, fd));
787cfd0b05SBarry Smith   #else
79e32f2f54SBarry Smith   SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP_SYS, "Cannot run external programs on this machine");
807cfd0b05SBarry Smith   #endif
81292f8084SBarry Smith 
829566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Barrier(comm));
83292f8084SBarry Smith 
84292f8084SBarry Smith   /* load the apply function from the dynamic library */
859566063dSJacob Faibussowitsch   PetscCall(PetscGetUserName(username, 64));
86292f8084SBarry Smith   sprintf(lib, "%s/%s/libpetscdlib", tmp, username);
879566063dSJacob Faibussowitsch   PetscCall(PetscDLLibrarySym(comm, NULL, lib, "PFApply_String", f));
8828b400f6SJacob Faibussowitsch   PetscCheck(f, PetscObjectComm((PetscObject)pf), PETSC_ERR_ARG_WRONGSTATE, "Cannot find function %s", lib);
89292f8084SBarry Smith #endif
90292f8084SBarry Smith   PetscFunctionReturn(0);
91292f8084SBarry Smith }
92292f8084SBarry Smith 
93*d71ae5a4SJacob Faibussowitsch static PetscErrorCode PFSetFromOptions_String(PF pf, PetscOptionItems *PetscOptionsObject)
94*d71ae5a4SJacob Faibussowitsch {
95ace3abfcSBarry Smith   PetscBool flag;
96292f8084SBarry Smith   char      value[PETSC_MAX_PATH_LEN];
974c8fdceaSLisandro Dalcin   PetscErrorCode (*f)(void *, PetscInt, const PetscScalar *, PetscScalar *) = NULL;
98292f8084SBarry Smith 
99292f8084SBarry Smith   PetscFunctionBegin;
100d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "String function options");
1019566063dSJacob Faibussowitsch   PetscCall(PetscOptionsString("-pf_string", "Enter the function", "PFStringCreateFunction", "", value, sizeof(value), &flag));
102292f8084SBarry Smith   if (flag) {
1039566063dSJacob Faibussowitsch     PetscCall(PFStringCreateFunction(pf, value, (void **)&f));
104292f8084SBarry Smith     pf->ops->apply = f;
105292f8084SBarry Smith   }
106d0609cedSBarry Smith   PetscOptionsHeadEnd();
107292f8084SBarry Smith   PetscFunctionReturn(0);
108292f8084SBarry Smith }
109292f8084SBarry Smith 
11026e7fa26SJed Brown typedef PetscErrorCode (*FCN)(void *, PetscInt, const PetscScalar *, PetscScalar *); /* force argument to next function to not be extern C*/
1116ac5842eSBarry Smith 
112*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode PFCreate_String(PF pf, void *value)
113*d71ae5a4SJacob Faibussowitsch {
1144c8fdceaSLisandro Dalcin   FCN f = NULL;
115292f8084SBarry Smith 
116292f8084SBarry Smith   PetscFunctionBegin;
11748a46eb9SPierre Jolivet   if (value) PetscCall(PFStringCreateFunction(pf, (char *)value, (void **)&f));
1189566063dSJacob Faibussowitsch   PetscCall(PFSet(pf, f, NULL, PFView_String, PFDestroy_String, NULL));
119292f8084SBarry Smith   pf->ops->setfromoptions = PFSetFromOptions_String;
120292f8084SBarry Smith   PetscFunctionReturn(0);
121292f8084SBarry Smith }
122