1 #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for popen */ 2 /* 3 Some PETSc utilites routines to add simple parallel IO capability 4 */ 5 #include <petscsys.h> 6 7 #undef __FUNCT__ 8 #define __FUNCT__ "PetscFOpen" 9 /*@C 10 PetscFOpen - Has the first process in the communicator open a file; 11 all others do nothing. 12 13 Logically Collective on MPI_Comm 14 15 Input Parameters: 16 + comm - the communicator 17 . name - the filename 18 - mode - the mode for fopen(), usually "w" 19 20 Output Parameter: 21 . fp - the file pointer 22 23 Level: developer 24 25 Notes: 26 NULL (0), "stderr" or "stdout" may be passed in as the filename 27 28 Fortran Note: 29 This routine is not supported in Fortran. 30 31 Concepts: opening ASCII file 32 Concepts: files^opening ASCII 33 34 .seealso: PetscFClose(), PetscSynchronizedFGets(), PetscSynchronizedPrintf(), PetscSynchronizedFlush(), 35 PetscFPrintf() 36 @*/ 37 PetscErrorCode PetscFOpen(MPI_Comm comm,const char name[],const char mode[],FILE **fp) 38 { 39 PetscErrorCode ierr; 40 PetscMPIInt rank; 41 FILE *fd; 42 char fname[PETSC_MAX_PATH_LEN],tname[PETSC_MAX_PATH_LEN]; 43 44 PetscFunctionBegin; 45 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 46 if (!rank) { 47 PetscBool isstdout,isstderr; 48 ierr = PetscStrcmp(name,"stdout",&isstdout);CHKERRQ(ierr); 49 ierr = PetscStrcmp(name,"stderr",&isstderr);CHKERRQ(ierr); 50 if (isstdout || !name) fd = PETSC_STDOUT; 51 else if (isstderr) fd = PETSC_STDERR; 52 else { 53 ierr = PetscStrreplace(PETSC_COMM_SELF,name,tname,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 54 ierr = PetscFixFilename(tname,fname);CHKERRQ(ierr); 55 ierr = PetscInfo1(0,"Opening file %s\n",fname);CHKERRQ(ierr); 56 fd = fopen(fname,mode); 57 if (!fd) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open file %s\n",fname); 58 } 59 } else fd = 0; 60 *fp = fd; 61 PetscFunctionReturn(0); 62 } 63 64 #undef __FUNCT__ 65 #define __FUNCT__ "PetscFClose" 66 /*@ 67 PetscFClose - Has the first processor in the communicator close a 68 file; all others do nothing. 69 70 Logically Collective on MPI_Comm 71 72 Input Parameters: 73 + comm - the communicator 74 - fd - the file, opened with PetscFOpen() 75 76 Level: developer 77 78 Fortran Note: 79 This routine is not supported in Fortran. 80 81 Concepts: files^closing ASCII 82 Concepts: closing file 83 84 .seealso: PetscFOpen() 85 @*/ 86 PetscErrorCode PetscFClose(MPI_Comm comm,FILE *fd) 87 { 88 PetscErrorCode ierr; 89 PetscMPIInt rank; 90 int err; 91 92 PetscFunctionBegin; 93 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 94 if (!rank && fd != PETSC_STDOUT && fd != PETSC_STDERR) { 95 err = fclose(fd); 96 if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file"); 97 } 98 PetscFunctionReturn(0); 99 } 100 101 #if defined(PETSC_HAVE_POPEN) 102 103 #undef __FUNCT__ 104 #define __FUNCT__ "PetscPClose" 105 /*@C 106 PetscPClose - Closes (ends) a program on processor zero run with PetscPOpen() 107 108 Collective on MPI_Comm, but only process 0 runs the command 109 110 Input Parameters: 111 + comm - MPI communicator, only processor zero runs the program 112 - fp - the file pointer where program input or output may be read or NULL if don't care 113 114 Output Parameters: 115 . rval - return value from pclose() or NULL to raise an error on failure 116 117 Level: intermediate 118 119 Notes: 120 Does not work under Windows 121 122 .seealso: PetscFOpen(), PetscFClose(), PetscPOpen() 123 124 @*/ 125 PetscErrorCode PetscPClose(MPI_Comm comm,FILE *fd,PetscInt *rval) 126 { 127 PetscErrorCode ierr; 128 PetscMPIInt rank; 129 int err; 130 131 PetscFunctionBegin; 132 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 133 if (!rank) { 134 char buf[1024]; 135 while (fgets(buf,1024,fd)) ; /* wait till it prints everything */ 136 err = pclose(fd); 137 if (rval) *rval = err; 138 else if (err) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"pclose() failed with error code %D",err); 139 } 140 PetscFunctionReturn(0); 141 } 142 143 144 #undef __FUNCT__ 145 #define __FUNCT__ "PetscPOpen" 146 /*@C 147 PetscPOpen - Runs a program on processor zero and sends either its input or output to 148 a file. 149 150 Logically Collective on MPI_Comm, but only process 0 runs the command 151 152 Input Parameters: 153 + comm - MPI communicator, only processor zero runs the program 154 . machine - machine to run command on or NULL, or string with 0 in first location 155 . program - name of program to run 156 - mode - either r or w 157 158 Output Parameter: 159 . fp - the file pointer where program input or output may be read or NULL if don't care 160 161 Level: intermediate 162 163 Notes: 164 Use PetscPClose() to close the file pointer when you are finished with it 165 Does not work under Windows 166 167 The program string may contain ${DISPLAY}, ${HOMEDIRECTORY} or ${WORKINGDIRECTORY}; these 168 will be replaced with relevent values. 169 170 .seealso: PetscFOpen(), PetscFClose(), PetscPClose() 171 172 @*/ 173 PetscErrorCode PetscPOpen(MPI_Comm comm,const char machine[],const char program[],const char mode[],FILE **fp) 174 { 175 PetscErrorCode ierr; 176 PetscMPIInt rank; 177 size_t i,len,cnt; 178 char commandt[PETSC_MAX_PATH_LEN],command[PETSC_MAX_PATH_LEN]; 179 FILE *fd; 180 181 PetscFunctionBegin; 182 /* all processors have to do the string manipulation because PetscStrreplace() is a collective operation */ 183 if (machine && machine[0]) { 184 ierr = PetscStrcpy(command,"ssh ");CHKERRQ(ierr); 185 ierr = PetscStrcat(command,machine);CHKERRQ(ierr); 186 ierr = PetscStrcat(command," \" export DISPLAY=${DISPLAY}; ");CHKERRQ(ierr); 187 /* 188 Copy program into command but protect the " with a \ in front of it 189 */ 190 ierr = PetscStrlen(command,&cnt);CHKERRQ(ierr); 191 ierr = PetscStrlen(program,&len);CHKERRQ(ierr); 192 for (i=0; i<len; i++) { 193 if (program[i] == '\"') command[cnt++] = '\\'; 194 command[cnt++] = program[i]; 195 } 196 command[cnt] = 0; 197 198 ierr = PetscStrcat(command,"\"");CHKERRQ(ierr); 199 } else { 200 ierr = PetscStrcpy(command,program);CHKERRQ(ierr); 201 } 202 203 ierr = PetscStrreplace(comm,command,commandt,1024);CHKERRQ(ierr); 204 205 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 206 if (!rank) { 207 ierr = PetscInfo1(0,"Running command :%s\n",commandt);CHKERRQ(ierr); 208 if (!(fd = popen(commandt,mode))) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot run command %s",commandt); 209 if (fp) *fp = fd; 210 } 211 PetscFunctionReturn(0); 212 } 213 214 #endif 215