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