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