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