1 2 #include <../src/vec/pf/pfimpl.h> /*I "petscpf.h" I*/ 3 4 /* 5 Ths PF generates a function on the fly and loads it into the running 6 program. 7 */ 8 9 static PetscErrorCode PFView_String(void *value,PetscViewer viewer) 10 { 11 PetscErrorCode ierr; 12 PetscBool iascii; 13 14 PetscFunctionBegin; 15 ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 16 if (iascii) { 17 ierr = PetscViewerASCIIPrintf(viewer,"String = %s\n",(char*)value);CHKERRQ(ierr); 18 } 19 PetscFunctionReturn(0); 20 } 21 22 static PetscErrorCode PFDestroy_String(void *value) 23 { 24 PetscErrorCode ierr; 25 26 PetscFunctionBegin; 27 ierr = PetscFree(value);CHKERRQ(ierr); 28 PetscFunctionReturn(0); 29 } 30 31 /* 32 PFStringCreateFunction - Creates a function from a string 33 34 Collective over PF 35 36 Input Parameters: 37 + pf - the function object 38 - string - the string that defines the function 39 40 Output Parameter: 41 . f - the function pointer. 42 43 .seealso: PFSetFromOptions() 44 45 */ 46 PetscErrorCode PFStringCreateFunction(PF pf,char *string,void **f) 47 { 48 #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) 49 PetscErrorCode ierr; 50 char task[1024],tmp[256],lib[PETSC_MAX_PATH_LEN],username[64]; 51 FILE *fd; 52 PetscBool tmpshared,wdshared,keeptmpfiles = PETSC_FALSE; 53 MPI_Comm comm; 54 #endif 55 56 PetscFunctionBegin; 57 #if defined(PETSC_HAVE_DYNAMIC_LIBRARIES) 58 ierr = PetscFree(pf->data);CHKERRQ(ierr); 59 ierr = PetscStrallocpy(string,(char**)&pf->data);CHKERRQ(ierr); 60 61 /* create the new C function and compile it */ 62 ierr = PetscSharedTmp(PetscObjectComm((PetscObject)pf),&tmpshared);CHKERRQ(ierr); 63 ierr = PetscSharedWorkingDirectory(PetscObjectComm((PetscObject)pf),&wdshared);CHKERRQ(ierr); 64 if (tmpshared) { /* do it in /tmp since everyone has one */ 65 ierr = PetscGetTmp(PetscObjectComm((PetscObject)pf),tmp,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 66 ierr = PetscObjectGetComm((PetscObject)pf,&comm);CHKERRQ(ierr); 67 } else if (!wdshared) { /* each one does in private /tmp */ 68 ierr = PetscGetTmp(PetscObjectComm((PetscObject)pf),tmp,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 69 comm = PETSC_COMM_SELF; 70 } else { /* do it in current directory */ 71 ierr = PetscStrcpy(tmp,".");CHKERRQ(ierr); 72 ierr = PetscObjectGetComm((PetscObject)pf,&comm);CHKERRQ(ierr); 73 } 74 ierr = PetscOptionsGetBool(((PetscObject)pf)->options,((PetscObject)pf)->prefix,"-pf_string_keep_files",&keeptmpfiles,NULL);CHKERRQ(ierr); 75 if (keeptmpfiles) 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); 76 else 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,(int)pf->dimin,(int)pf->dimout,string); 77 78 #if defined(PETSC_HAVE_POPEN) 79 ierr = PetscPOpen(comm,NULL,task,"r",&fd);CHKERRQ(ierr); 80 ierr = PetscPClose(comm,fd);CHKERRQ(ierr); 81 #else 82 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine"); 83 #endif 84 85 ierr = MPI_Barrier(comm);CHKERRMPI(ierr); 86 87 /* load the apply function from the dynamic library */ 88 ierr = PetscGetUserName(username,64);CHKERRQ(ierr); 89 sprintf(lib,"%s/%s/libpetscdlib",tmp,username); 90 ierr = PetscDLLibrarySym(comm,NULL,lib,"PFApply_String",f);CHKERRQ(ierr); 91 if (!f) SETERRQ1(PetscObjectComm((PetscObject)pf),PETSC_ERR_ARG_WRONGSTATE,"Cannot find function %s",lib); 92 #endif 93 PetscFunctionReturn(0); 94 } 95 96 static PetscErrorCode PFSetFromOptions_String(PetscOptionItems *PetscOptionsObject,PF pf) 97 { 98 PetscErrorCode ierr; 99 PetscBool flag; 100 char value[PETSC_MAX_PATH_LEN]; 101 PetscErrorCode (*f)(void*,PetscInt,const PetscScalar*,PetscScalar*) = NULL; 102 103 PetscFunctionBegin; 104 ierr = PetscOptionsHead(PetscOptionsObject,"String function options");CHKERRQ(ierr); 105 ierr = PetscOptionsString("-pf_string","Enter the function","PFStringCreateFunction","",value,sizeof(value),&flag);CHKERRQ(ierr); 106 if (flag) { 107 ierr = PFStringCreateFunction(pf,value,(void**)&f);CHKERRQ(ierr); 108 pf->ops->apply = f; 109 } 110 ierr = PetscOptionsTail();CHKERRQ(ierr); 111 PetscFunctionReturn(0); 112 } 113 114 typedef PetscErrorCode (*FCN)(void*,PetscInt,const PetscScalar*,PetscScalar*); /* force argument to next function to not be extern C*/ 115 116 PETSC_EXTERN PetscErrorCode PFCreate_String(PF pf,void *value) 117 { 118 PetscErrorCode ierr; 119 FCN f = NULL; 120 121 PetscFunctionBegin; 122 if (value) { 123 ierr = PFStringCreateFunction(pf,(char*)value,(void**)&f);CHKERRQ(ierr); 124 } 125 ierr = PFSet(pf,f,NULL,PFView_String,PFDestroy_String,NULL);CHKERRQ(ierr); 126 pf->ops->setfromoptions = PFSetFromOptions_String; 127 PetscFunctionReturn(0); 128 } 129 130