예제 #1
0
/*
    PFStringCreateFunction - Creates a function from a string

   Collective over PF

  Input Parameters:
+    pf - the function object
-    string - the string that defines the function

  Output Parameter:
.    f - the function pointer.

.seealso: PFSetFromOptions()

*/
PetscErrorCode PETSCVEC_DLLEXPORT PFStringCreateFunction(PF pf,char *string,void **f)
{
#if defined(PETSC_USE_DYNAMIC_LIBRARIES)
  PetscErrorCode ierr;
  char       task[1024],tmp[256],lib[PETSC_MAX_PATH_LEN],username[64];
  FILE       *fd;
  PetscTruth tmpshared,wdshared,keeptmpfiles = PETSC_FALSE;
  MPI_Comm   comm;
#endif

  PetscFunctionBegin;
#if defined(PETSC_USE_DYNAMIC_LIBRARIES)
  ierr = PetscStrfree(pf->data);CHKERRQ(ierr);
  ierr = PetscStrallocpy(string,(char**)&pf->data);CHKERRQ(ierr);

  /* create the new C function and compile it */
  ierr = PetscSharedTmp(((PetscObject)pf)->comm,&tmpshared);CHKERRQ(ierr);
  ierr = PetscSharedWorkingDirectory(((PetscObject)pf)->comm,&wdshared);CHKERRQ(ierr);
  if (tmpshared) {  /* do it in /tmp since everyone has one */
    ierr = PetscGetTmp(((PetscObject)pf)->comm,tmp,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
    comm = ((PetscObject)pf)->comm;
  } else if (!wdshared) {  /* each one does in private /tmp */
    ierr = PetscGetTmp(((PetscObject)pf)->comm,tmp,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
    comm = PETSC_COMM_SELF;
  } else { /* do it in current directory */
    ierr = PetscStrcpy(tmp,".");CHKERRQ(ierr);
    comm = ((PetscObject)pf)->comm;
  } 
  ierr = PetscOptionsGetTruth(((PetscObject)pf)->prefix,"-pf_string_keep_files",&keeptmpfiles,PETSC_NULL);CHKERRQ(ierr);
  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);
  } 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);
  }
#if defined(PETSC_HAVE_POPEN)
  ierr = PetscPOpen(comm,PETSC_NULL,task,"r",&fd);CHKERRQ(ierr);
  ierr = PetscPClose(comm,fd);CHKERRQ(ierr);
#else
  SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
#endif

  ierr = MPI_Barrier(comm);CHKERRQ(ierr);

  /* load the apply function from the dynamic library */
  ierr = PetscGetUserName(username,64);CHKERRQ(ierr);
  sprintf(lib,"%s/%s/libpetscdlib",tmp,username);
  ierr = PetscDLLibrarySym(comm,PETSC_NULL,lib,"PFApply_String",f);CHKERRQ(ierr);
#endif
  PetscFunctionReturn(0);    
}
예제 #2
0
/*@C
    PetscFileRetrieve - Obtains a library from a URL or compressed
        and copies into local disk space as uncompressed.

    Collective on MPI_Comm

    Input Parameter:
+   comm     - processors accessing the library
.   libname  - name of library, including entire URL (with or without .gz)
-   llen     - length of llibname

    Output Parameter:
+   llibname - name of local copy of library
-   found - if found and retrieved the file

    Level: developer

@*/
PetscErrorCode  PetscFileRetrieve(MPI_Comm comm,const char libname[],char llibname[],size_t llen,PetscBool  *found)
{
  char           buf[1024],tmpdir[PETSC_MAX_PATH_LEN],urlget[PETSC_MAX_PATH_LEN],*par;
  const char     *pdir;
  FILE           *fp;
  PetscErrorCode ierr;
  int            i;
  PetscMPIInt    rank;
  size_t         len = 0;
  PetscBool      flg1,flg2,flg3,sharedtmp,exists;
#if defined(PETSC_HAVE_POPEN)
  int            rval;
#endif

  PetscFunctionBegin;
  *found = PETSC_FALSE;

  /* if file does not have an ftp:// or http:// or .gz then need not process file */
  ierr = PetscStrstr(libname,".gz",&par);CHKERRQ(ierr);
  if (par) {ierr = PetscStrlen(par,&len);CHKERRQ(ierr);}

  ierr = PetscStrncmp(libname,"ftp://",6,&flg1);CHKERRQ(ierr);
  ierr = PetscStrncmp(libname,"http://",7,&flg2);CHKERRQ(ierr);
  ierr = PetscStrncmp(libname,"file://",7,&flg3);CHKERRQ(ierr);
  if (!flg1 && !flg2 && !flg3 && (!par || len != 3)) {
    ierr = PetscStrncpy(llibname,libname,llen);CHKERRQ(ierr);
    ierr = PetscTestFile(libname,'r',found);CHKERRQ(ierr);
    if (*found) {
      ierr = PetscInfo1(NULL,"Found file %s\n",libname);CHKERRQ(ierr);
    } else {
      ierr = PetscInfo1(NULL,"Did not find file %s\n",libname);CHKERRQ(ierr);
    }
    PetscFunctionReturn(0);
  }

  if (par && len == 3){
    size_t llen;
    ierr = PetscStrlen(libname,&llen);CHKERRQ(ierr);
    ierr = PetscStrncpy(llibname,libname,llen);CHKERRQ(ierr);
    llibname[llen-len] = 0;
    ierr = PetscTestFile(llibname,'r',found);CHKERRQ(ierr);
    if (*found) {
      ierr = PetscInfo1(NULL,"Found uncompressed version of file %s\n",llibname);CHKERRQ(ierr);
      PetscFunctionReturn(0);
    } else {
      ierr = PetscInfo1(NULL,"Did not find uncompressed version of file %s\n",libname);CHKERRQ(ierr);
    }
  }

  /* Determine if all processors share a common /tmp */
  ierr = PetscSharedTmp(comm,&sharedtmp);CHKERRQ(ierr);
  ierr = PetscOptionsGetenv(comm,"PETSC_TMP",tmpdir,PETSC_MAX_PATH_LEN,&flg1);CHKERRQ(ierr);

  ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
  if (!rank || !sharedtmp) {

    /* Construct the script to get URL file */
    ierr = PetscGetPetscDir(&pdir);CHKERRQ(ierr);
    ierr = PetscStrcpy(urlget,pdir);CHKERRQ(ierr);
    ierr = PetscStrcat(urlget,"/bin/urlget");CHKERRQ(ierr);
    ierr = PetscTestFile(urlget,'r',&exists);CHKERRQ(ierr);
    if (!exists) {
      ierr = PetscTestFile("urlget",'r',&exists);CHKERRQ(ierr);
      if (!exists) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot locate PETSc script urlget in %s or current directory",urlget);
      ierr = PetscStrcpy(urlget,"urlget");CHKERRQ(ierr);
    }
    ierr = PetscStrcat(urlget," ");CHKERRQ(ierr);

    /* are we using an alternative /tmp? */
    if (flg1) {
      ierr = PetscStrcat(urlget,"-tmp ");CHKERRQ(ierr);
      ierr = PetscStrcat(urlget,tmpdir);CHKERRQ(ierr);
      ierr = PetscStrcat(urlget," ");CHKERRQ(ierr);
    }

    ierr = PetscStrcat(urlget,libname);CHKERRQ(ierr);
    ierr = PetscStrcat(urlget," 2>&1 ");CHKERRQ(ierr);

#if defined(PETSC_HAVE_POPEN)
    ierr = PetscPOpen(PETSC_COMM_SELF,NULL,urlget,"r",&fp);CHKERRQ(ierr);
#else
    SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
#endif
    if (!fgets(buf,1024,fp)) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"No output from ${PETSC_DIR}/bin/urlget in getting file %s",libname);
    ierr = PetscInfo1(0,"Message back from urlget: %s\n",buf);CHKERRQ(ierr);

    ierr = PetscStrncmp(buf,"Error",5,&flg1);CHKERRQ(ierr);
    ierr = PetscStrncmp(buf,"Traceback",9,&flg2);CHKERRQ(ierr);
#if defined(PETSC_HAVE_POPEN)
    ierr = PetscPClose(PETSC_COMM_SELF,fp,&rval);CHKERRQ(ierr);
#endif
    if (flg1 || flg2) *found = PETSC_FALSE;
    else {
      *found = PETSC_TRUE;

      /* Check for \n and make it 0 */
      for (i=0; i<1024; i++) {
        if (buf[i] == '\n') {
          buf[i] = 0;
          break;
        }
      }
      ierr = PetscStrncpy(llibname,buf,llen);CHKERRQ(ierr);
    }
  }
  if (sharedtmp) { /* send library name to all processors */
    ierr = MPI_Bcast(found,1,MPIU_BOOL,0,comm);CHKERRQ(ierr);
    if (*found) {
      ierr = MPI_Bcast(llibname,llen,MPI_CHAR,0,comm);CHKERRQ(ierr);
      ierr = MPI_Bcast(found,1,MPIU_BOOL,0,comm);CHKERRQ(ierr);
    }
  }
  PetscFunctionReturn(0);
}