xref: /petsc/src/sys/fileio/mpiuopen.c (revision 28b400f66ebc7ae0049166a2294dfcd3df27e64b)
10039db0dSBarry Smith #define PETSC_DESIRE_FEATURE_TEST_MACROS /* for popen() */
2e5c89e4eSSatish Balay /*
34c500f23SPierre Jolivet       Some PETSc utility routines to add simple parallel IO capabilities
4e5c89e4eSSatish Balay */
5c6db04a5SJed Brown #include <petscsys.h>
6e94e781bSJacob Faibussowitsch #include <petsc/private/logimpl.h>
7d0286d30SJed Brown #include <errno.h>
8d0286d30SJed Brown 
9e5c89e4eSSatish Balay /*@C
10e5c89e4eSSatish Balay     PetscFOpen - Has the first process in the communicator open a file;
11e5c89e4eSSatish Balay     all others do nothing.
12e5c89e4eSSatish Balay 
13d083f849SBarry Smith     Logically Collective
14e5c89e4eSSatish Balay 
15e5c89e4eSSatish Balay     Input Parameters:
16e5c89e4eSSatish Balay +   comm - the communicator
17e5c89e4eSSatish Balay .   name - the filename
18e5c89e4eSSatish Balay -   mode - the mode for fopen(), usually "w"
19e5c89e4eSSatish Balay 
20e5c89e4eSSatish Balay     Output Parameter:
21e5c89e4eSSatish Balay .   fp - the file pointer
22e5c89e4eSSatish Balay 
23e5c89e4eSSatish Balay     Level: developer
24e5c89e4eSSatish Balay 
25e5c89e4eSSatish Balay     Notes:
260298fd71SBarry Smith        NULL (0), "stderr" or "stdout" may be passed in as the filename
27e5c89e4eSSatish Balay 
28e5c89e4eSSatish Balay     Fortran Note:
29e5c89e4eSSatish Balay     This routine is not supported in Fortran.
30e5c89e4eSSatish Balay 
31d75a2efbSBarry Smith .seealso: PetscFClose(), PetscSynchronizedFGets(), PetscSynchronizedPrintf(), PetscSynchronizedFlush(),
32d75a2efbSBarry Smith           PetscFPrintf()
33e5c89e4eSSatish Balay @*/
347087cfbeSBarry Smith PetscErrorCode  PetscFOpen(MPI_Comm comm,const char name[],const char mode[],FILE **fp)
35e5c89e4eSSatish Balay {
36e5c89e4eSSatish Balay   PetscMPIInt    rank;
37e5c89e4eSSatish Balay   FILE           *fd;
38e5c89e4eSSatish Balay   char           fname[PETSC_MAX_PATH_LEN],tname[PETSC_MAX_PATH_LEN];
39e5c89e4eSSatish Balay 
40e5c89e4eSSatish Balay   PetscFunctionBegin;
415f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(comm,&rank));
42dd400576SPatrick Sanan   if (rank == 0) {
43ace3abfcSBarry Smith     PetscBool isstdout,isstderr;
445f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcmp(name,"stdout",&isstdout));
455f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcmp(name,"stderr",&isstderr));
46a297a907SKarl Rupp     if (isstdout || !name) fd = PETSC_STDOUT;
47a297a907SKarl Rupp     else if (isstderr) fd = PETSC_STDERR;
48a297a907SKarl Rupp     else {
49b3f259d6SBarry Smith       PetscBool devnull;
505f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscStrreplace(PETSC_COMM_SELF,name,tname,PETSC_MAX_PATH_LEN));
515f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscFixFilename(tname,fname));
525f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscStrbeginswith(fname,"/dev/null",&devnull));
53b3f259d6SBarry Smith       if (devnull) {
545f80ce2aSJacob Faibussowitsch         CHKERRQ(PetscStrcpy(fname,"/dev/null"));
55b3f259d6SBarry Smith       }
565f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscInfo(0,"Opening file %s\n",fname));
57e5c89e4eSSatish Balay       fd   = fopen(fname,mode);
58*28b400f6SJacob Faibussowitsch       PetscCheck(fd,PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to open file %s",fname);
59e5c89e4eSSatish Balay     }
6002c9f0b5SLisandro Dalcin   } else fd = NULL;
61e5c89e4eSSatish Balay   *fp = fd;
62e5c89e4eSSatish Balay   PetscFunctionReturn(0);
63e5c89e4eSSatish Balay }
64e5c89e4eSSatish Balay 
65e8976759SBarry Smith /*@C
66e5c89e4eSSatish Balay     PetscFClose - Has the first processor in the communicator close a
67e5c89e4eSSatish Balay     file; all others do nothing.
68e5c89e4eSSatish Balay 
69d083f849SBarry Smith     Logically Collective
70e5c89e4eSSatish Balay 
71e5c89e4eSSatish Balay     Input Parameters:
72e5c89e4eSSatish Balay +   comm - the communicator
73e5c89e4eSSatish Balay -   fd - the file, opened with PetscFOpen()
74e5c89e4eSSatish Balay 
75e5c89e4eSSatish Balay    Level: developer
76e5c89e4eSSatish Balay 
77e5c89e4eSSatish Balay     Fortran Note:
78e5c89e4eSSatish Balay     This routine is not supported in Fortran.
79e5c89e4eSSatish Balay 
80e5c89e4eSSatish Balay .seealso: PetscFOpen()
81e5c89e4eSSatish Balay @*/
827087cfbeSBarry Smith PetscErrorCode  PetscFClose(MPI_Comm comm,FILE *fd)
83e5c89e4eSSatish Balay {
84e5c89e4eSSatish Balay   PetscMPIInt    rank;
85ed9cf6e9SBarry Smith   int            err;
86e5c89e4eSSatish Balay 
87e5c89e4eSSatish Balay   PetscFunctionBegin;
885f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(comm,&rank));
89dd400576SPatrick Sanan   if (rank == 0 && fd != PETSC_STDOUT && fd != PETSC_STDERR) {
90ed9cf6e9SBarry Smith     err = fclose(fd);
91*28b400f6SJacob Faibussowitsch     PetscCheck(!err,PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
92ed9cf6e9SBarry Smith   }
93e5c89e4eSSatish Balay   PetscFunctionReturn(0);
94e5c89e4eSSatish Balay }
95e5c89e4eSSatish Balay 
96e5c89e4eSSatish Balay #if defined(PETSC_HAVE_POPEN)
9774ba8654SBarry Smith static char PetscPOpenMachine[128] = "";
98e5c89e4eSSatish Balay 
99e5c89e4eSSatish Balay /*@C
100e5c89e4eSSatish Balay       PetscPClose - Closes (ends) a program on processor zero run with PetscPOpen()
101e5c89e4eSSatish Balay 
102d083f849SBarry Smith      Collective, but only process 0 runs the command
103e5c89e4eSSatish Balay 
104e5c89e4eSSatish Balay    Input Parameters:
105e5c89e4eSSatish Balay +   comm - MPI communicator, only processor zero runs the program
1060298fd71SBarry Smith -   fp - the file pointer where program input or output may be read or NULL if don't care
107e5c89e4eSSatish Balay 
108e5c89e4eSSatish Balay    Level: intermediate
109e5c89e4eSSatish Balay 
110e5c89e4eSSatish Balay    Notes:
111e5c89e4eSSatish Balay        Does not work under Windows
112e5c89e4eSSatish Balay 
113e5c89e4eSSatish Balay .seealso: PetscFOpen(), PetscFClose(), PetscPOpen()
114e5c89e4eSSatish Balay 
115e5c89e4eSSatish Balay @*/
116016831caSBarry Smith PetscErrorCode PetscPClose(MPI_Comm comm,FILE *fd)
117e5c89e4eSSatish Balay {
118e5c89e4eSSatish Balay   PetscMPIInt    rank;
119e5c89e4eSSatish Balay 
120e5c89e4eSSatish Balay   PetscFunctionBegin;
1215f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(comm,&rank));
122dd400576SPatrick Sanan   if (rank == 0) {
123e5c89e4eSSatish Balay     char buf[1024];
124a297a907SKarl Rupp     while (fgets(buf,1024,fd)) ; /* wait till it prints everything */
125016831caSBarry Smith     (void) pclose(fd);
126e5c89e4eSSatish Balay   }
127e5c89e4eSSatish Balay   PetscFunctionReturn(0);
128e5c89e4eSSatish Balay }
129e5c89e4eSSatish Balay 
130e5c89e4eSSatish Balay /*@C
131e5c89e4eSSatish Balay       PetscPOpen - Runs a program on processor zero and sends either its input or output to
132e5c89e4eSSatish Balay           a file.
133e5c89e4eSSatish Balay 
134d083f849SBarry Smith      Logically Collective, but only process 0 runs the command
135e5c89e4eSSatish Balay 
136e5c89e4eSSatish Balay    Input Parameters:
137e5c89e4eSSatish Balay +   comm - MPI communicator, only processor zero runs the program
1380298fd71SBarry Smith .   machine - machine to run command on or NULL, or string with 0 in first location
139e5c89e4eSSatish Balay .   program - name of program to run
140e5c89e4eSSatish Balay -   mode - either r or w
141e5c89e4eSSatish Balay 
142e5c89e4eSSatish Balay    Output Parameter:
1430298fd71SBarry Smith .   fp - the file pointer where program input or output may be read or NULL if don't care
144e5c89e4eSSatish Balay 
145e5c89e4eSSatish Balay    Level: intermediate
146e5c89e4eSSatish Balay 
147e5c89e4eSSatish Balay    Notes:
148e5c89e4eSSatish Balay        Use PetscPClose() to close the file pointer when you are finished with it
149e5c89e4eSSatish Balay        Does not work under Windows
150e5c89e4eSSatish Balay 
15174ba8654SBarry Smith        If machine is not provided will use the value set with PetsPOpenSetMachine() if that was provided, otherwise
15274ba8654SBarry Smith        will use the machine running node zero of the communicator
15374ba8654SBarry Smith 
154e5c89e4eSSatish Balay        The program string may contain ${DISPLAY}, ${HOMEDIRECTORY} or ${WORKINGDIRECTORY}; these
155a5b23f4aSJose E. Roman     will be replaced with relevant values.
156e5c89e4eSSatish Balay 
15774ba8654SBarry Smith .seealso: PetscFOpen(), PetscFClose(), PetscPClose(), PetscPOpenSetMachine()
158e5c89e4eSSatish Balay 
159e5c89e4eSSatish Balay @*/
1607087cfbeSBarry Smith PetscErrorCode  PetscPOpen(MPI_Comm comm,const char machine[],const char program[],const char mode[],FILE **fp)
161e5c89e4eSSatish Balay {
162e5c89e4eSSatish Balay   PetscMPIInt    rank;
163e5c89e4eSSatish Balay   size_t         i,len,cnt;
164e5c89e4eSSatish Balay   char           commandt[PETSC_MAX_PATH_LEN],command[PETSC_MAX_PATH_LEN];
165e5c89e4eSSatish Balay   FILE           *fd;
166e5c89e4eSSatish Balay 
167e5c89e4eSSatish Balay   PetscFunctionBegin;
168e5c89e4eSSatish Balay   /* all processors have to do the string manipulation because PetscStrreplace() is a collective operation */
16974ba8654SBarry Smith   if (PetscPOpenMachine[0] || (machine && machine[0])) {
1705f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcpy(command,"ssh "));
17174ba8654SBarry Smith     if (PetscPOpenMachine[0]) {
1725f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscStrcat(command,PetscPOpenMachine));
17374ba8654SBarry Smith     } else {
1745f80ce2aSJacob Faibussowitsch       CHKERRQ(PetscStrcat(command,machine));
17574ba8654SBarry Smith     }
1765f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcat(command," \" export DISPLAY=${DISPLAY}; "));
177e5c89e4eSSatish Balay     /*
178e5c89e4eSSatish Balay         Copy program into command but protect the " with a \ in front of it
179e5c89e4eSSatish Balay     */
1805f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrlen(command,&cnt));
1815f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrlen(program,&len));
182e5c89e4eSSatish Balay     for (i=0; i<len; i++) {
183a297a907SKarl Rupp       if (program[i] == '\"') command[cnt++] = '\\';
184e5c89e4eSSatish Balay       command[cnt++] = program[i];
185e5c89e4eSSatish Balay     }
186e5c89e4eSSatish Balay     command[cnt] = 0;
187a297a907SKarl Rupp 
1885f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcat(command,"\""));
189e5c89e4eSSatish Balay   } else {
1905f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcpy(command,program));
191e5c89e4eSSatish Balay   }
192e5c89e4eSSatish Balay 
1935f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrreplace(comm,command,commandt,1024));
194e5c89e4eSSatish Balay 
1955f80ce2aSJacob Faibussowitsch   CHKERRMPI(MPI_Comm_rank(comm,&rank));
196dd400576SPatrick Sanan   if (rank == 0) {
1975f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscInfo(NULL,"Running command :%s\n",commandt));
1982c71b3e2SJacob Faibussowitsch     PetscCheckFalse(!(fd = popen(commandt,mode)),PETSC_COMM_SELF,PETSC_ERR_LIB,"Cannot run command %s",commandt);
199e5c89e4eSSatish Balay     if (fp) *fp = fd;
200e5c89e4eSSatish Balay   }
201e5c89e4eSSatish Balay   PetscFunctionReturn(0);
202e5c89e4eSSatish Balay }
203e5c89e4eSSatish Balay 
20474ba8654SBarry Smith /*@C
20574ba8654SBarry Smith       PetscPOpenSetMachine - Sets the name of the default machine to run PetscPOpen() calls on
20674ba8654SBarry Smith 
207d083f849SBarry Smith      Logically Collective, but only process 0 runs the command
20874ba8654SBarry Smith 
20974ba8654SBarry Smith    Input Parameter:
21010699b91SBarry Smith .   machine - machine to run command on or NULL for the current machine
21174ba8654SBarry Smith 
21274ba8654SBarry Smith    Options Database:
21310699b91SBarry Smith .   -popen_machine <machine> - run the process on this machine
21474ba8654SBarry Smith 
21574ba8654SBarry Smith    Level: intermediate
21674ba8654SBarry Smith 
21774ba8654SBarry Smith .seealso: PetscFOpen(), PetscFClose(), PetscPClose(), PetscPOpen()
21874ba8654SBarry Smith @*/
21974ba8654SBarry Smith PetscErrorCode  PetscPOpenSetMachine(const char machine[])
22074ba8654SBarry Smith {
22174ba8654SBarry Smith   PetscFunctionBegin;
22274ba8654SBarry Smith   if (machine) {
2235f80ce2aSJacob Faibussowitsch     CHKERRQ(PetscStrcpy(PetscPOpenMachine,machine));
22474ba8654SBarry Smith   } else {
22574ba8654SBarry Smith     PetscPOpenMachine[0] = 0;
22674ba8654SBarry Smith   }
22774ba8654SBarry Smith   PetscFunctionReturn(0);
22874ba8654SBarry Smith }
22974ba8654SBarry Smith 
230e5c89e4eSSatish Balay #endif
231