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