Actual source code: vcreatea.c


  2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>

  4: /* ---------------------------------------------------------------------*/

  6: /*
  7:     The variable Petsc_Viewer_Stdout_keyval is used to indicate an MPI attribute that
  8:   is attached to a communicator, in this case the attribute is a PetscViewer.
  9: */
 10: PetscMPIInt Petsc_Viewer_Stdout_keyval = MPI_KEYVAL_INVALID;

 12: /*@
 13:    PetscViewerASCIIGetStdout - Creates a ASCII PetscViewer shared by all processors
 14:                     in a communicator. Error returning version of PETSC_VIEWER_STDOUT_()

 16:    Collective

 18:    Input Parameter:
 19: .  comm - the MPI communicator to share the PetscViewer

 21:    Level: beginner

 23:    Notes:
 24:      This should be used in all PETSc source code instead of PETSC_VIEWER_STDOUT_()

 26: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD,
 27:           PETSC_VIEWER_STDOUT_SELF

 29: @*/
 30: PetscErrorCode  PetscViewerASCIIGetStdout(MPI_Comm comm,PetscViewer *viewer)
 31: {
 32:   PetscBool      flg;
 33:   MPI_Comm       ncomm;

 35:   PetscSpinlockLock(&PetscViewerASCIISpinLockStdout);
 36:   PetscCommDuplicate(comm,&ncomm,NULL);
 37:   if (Petsc_Viewer_Stdout_keyval == MPI_KEYVAL_INVALID) {
 38:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Stdout_keyval,NULL);
 39:   }
 40:   MPI_Comm_get_attr(ncomm,Petsc_Viewer_Stdout_keyval,(void**)viewer,(PetscMPIInt*)&flg);
 41:   if (!flg) { /* PetscViewer not yet created */
 42:     PetscViewerASCIIOpen(ncomm,"stdout",viewer);
 43:     PetscObjectRegisterDestroy((PetscObject)*viewer);
 44:     MPI_Comm_set_attr(ncomm,Petsc_Viewer_Stdout_keyval,(void*)*viewer);
 45:   }
 46:   PetscCommDestroy(&ncomm);
 47:   PetscSpinlockUnlock(&PetscViewerASCIISpinLockStdout);
 48:   return 0;
 49: }

 51: /*@C
 52:    PETSC_VIEWER_STDOUT_ - Creates a ASCII PetscViewer shared by all processors
 53:                     in a communicator.

 55:    Collective

 57:    Input Parameter:
 58: .  comm - the MPI communicator to share the PetscViewer

 60:    Level: beginner

 62:    Notes:
 63:    Unlike almost all other PETSc routines, this does not return
 64:    an error code. Usually used in the form
 65: $      XXXView(XXX object,PETSC_VIEWER_STDOUT_(comm));

 67: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD,
 68:           PETSC_VIEWER_STDOUT_SELF

 70: @*/
 71: PetscViewer  PETSC_VIEWER_STDOUT_(MPI_Comm comm)
 72: {
 74:   PetscViewer    viewer;

 76:   PetscViewerASCIIGetStdout(comm,&viewer);
 77:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); return NULL;}
 78:   return viewer;
 79: }

 81: /* ---------------------------------------------------------------------*/

 83: /*
 84:     The variable Petsc_Viewer_Stderr_keyval is used to indicate an MPI attribute that
 85:   is attached to a communicator, in this case the attribute is a PetscViewer.
 86: */
 87: PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;

 89: /*@
 90:    PetscViewerASCIIGetStderr - Creates a ASCII PetscViewer shared by all processors
 91:                     in a communicator. Error returning version of PETSC_VIEWER_STDERR_()

 93:    Collective

 95:    Input Parameter:
 96: .  comm - the MPI communicator to share the PetscViewer

 98:    Level: beginner

100:    Notes:
101:      This should be used in all PETSc source code instead of PETSC_VIEWER_STDERR_()

103: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDERR_WORLD,
104:           PETSC_VIEWER_STDERR_SELF

106: @*/
107: PetscErrorCode  PetscViewerASCIIGetStderr(MPI_Comm comm,PetscViewer *viewer)
108: {
109:   PetscBool      flg;
110:   MPI_Comm       ncomm;

112:   PetscSpinlockLock(&PetscViewerASCIISpinLockStderr);
113:   PetscCommDuplicate(comm,&ncomm,NULL);
114:   if (Petsc_Viewer_Stderr_keyval == MPI_KEYVAL_INVALID) {
115:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Stderr_keyval,NULL);
116:   }
117:   MPI_Comm_get_attr(ncomm,Petsc_Viewer_Stderr_keyval,(void**)viewer,(PetscMPIInt*)&flg);
118:   if (!flg) { /* PetscViewer not yet created */
119:     PetscViewerASCIIOpen(ncomm,"stderr",viewer);
120:     PetscObjectRegisterDestroy((PetscObject)*viewer);
121:     MPI_Comm_set_attr(ncomm,Petsc_Viewer_Stderr_keyval,(void*)*viewer);
122:   }
123:   PetscCommDestroy(&ncomm);
124:   PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr);
125:   return 0;
126: }

128: /*@C
129:    PETSC_VIEWER_STDERR_ - Creates a ASCII PetscViewer shared by all processors
130:                     in a communicator.

132:    Collective

134:    Input Parameter:
135: .  comm - the MPI communicator to share the PetscViewer

137:    Level: beginner

139:    Note:
140:    Unlike almost all other PETSc routines, this does not return
141:    an error code. Usually used in the form
142: $      XXXView(XXX object,PETSC_VIEWER_STDERR_(comm));

144: .seealso: PETSC_VIEWER_DRAW_, PetscViewerASCIIOpen(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDOUT_WORLD,
145:           PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDERR_WORLD, PETSC_VIEWER_STDERR_SELF
146: @*/
147: PetscViewer  PETSC_VIEWER_STDERR_(MPI_Comm comm)
148: {
150:   PetscViewer    viewer;

152:   PetscViewerASCIIGetStderr(comm,&viewer);
153:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDERR_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); return NULL;}
154:   return viewer;
155: }

157: PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
158: /*
159:    Called with MPI_Comm_free() is called on a communicator that has a viewer as an attribute. The viewer is not actually destroyed because that is managed by
160:    PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.

162:   This is called by MPI, not by users.

164: */
165: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
166: {
167:   PetscInfo(NULL,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);
168:   return MPI_SUCCESS;
169: }

171: /*@C
172:    PetscViewerASCIIOpen - Opens an ASCII file for writing as a PetscViewer.

174:    Collective

176:    Input Parameters:
177: +  comm - the communicator
178: -  name - the file name

180:    Output Parameter:
181: .  lab - the PetscViewer to use with the specified file

183:    Level: beginner

185:    Notes:
186:    To open a ASCII file as a viewer for reading one must use the sequence
187: $     PetscViewerCreate(comm,&lab);
188: $     PetscViewerSetType(lab,PETSCVIEWERASCII);
189: $     PetscViewerFileSetMode(lab,FILE_MODE_READ);
190: $     PetscViewerFileSetName(lab,name);

192:    This PetscViewer can be destroyed with PetscViewerDestroy().

194:    The MPI communicator used here must match that used by the object one is viewing. For example if the
195:    Mat was created with a PETSC_COMM_WORLD, then the Viewer must be created with PETSC_COMM_WORLD

197:    As shown below, PetscViewerASCIIOpen() is useful in conjunction with
198:    MatView() and VecView()
199: .vb
200:      PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
201:      MatView(matrix,viewer);
202: .ve

204: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(), PetscViewerASCIIRead()
205:           PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
206:           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF,
207: @*/
208: PetscErrorCode  PetscViewerASCIIOpen(MPI_Comm comm,const char name[],PetscViewer *lab)
209: {
210:   PetscViewerLink *vlink,*nv;
211:   PetscBool       flg,eq;
212:   size_t          len;

214:   PetscStrlen(name,&len);
215:   if (!len) {
216:     PetscViewerASCIIGetStdout(comm,lab);
217:     PetscObjectReference((PetscObject)*lab);
218:     return 0;
219:   }
220:   PetscSpinlockLock(&PetscViewerASCIISpinLockOpen);
221:   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
222:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
223:   }
224:   /*
225:        It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
226:      we cannot do that, since PetscFileSetName() takes a communicator that already exists.

228:       Plus if the original communicator that created the file has since been close this will not detect the old
229:       communictor and hence will overwrite the old data. It may be better to simply remove all this code
230:   */
231:   /* make sure communicator is a PETSc communicator */
232:   PetscCommDuplicate(comm,&comm,NULL);
233:   /* has file already been opened into a viewer */
234:   MPI_Comm_get_attr(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
235:   if (flg) {
236:     while (vlink) {
237:       PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);
238:       if (eq) {
239:         PetscObjectReference((PetscObject)vlink->viewer);
240:         *lab = vlink->viewer;
241:         PetscCommDestroy(&comm);
242:         PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);
243:         return 0;
244:       }
245:       vlink = vlink->next;
246:     }
247:   }
248:   PetscViewerCreate(comm,lab);
249:   PetscViewerSetType(*lab,PETSCVIEWERASCII);
250:   if (name) {
251:     PetscViewerFileSetName(*lab,name);
252:   }
253:   /* save viewer into communicator if needed later */
254:   PetscNew(&nv);
255:   nv->viewer = *lab;
256:   if (!flg) {
257:     MPI_Comm_set_attr(comm,Petsc_Viewer_keyval,nv);
258:   } else {
259:     MPI_Comm_get_attr(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
260:     if (vlink) {
261:       while (vlink->next) vlink = vlink->next;
262:       vlink->next = nv;
263:     } else {
264:       MPI_Comm_set_attr(comm,Petsc_Viewer_keyval,nv);
265:     }
266:   }
267:   PetscCommDestroy(&comm);
268:   PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);
269:   return 0;
270: }

272: /*@C
273:    PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it.

275:    Collective

277:    Input Parameters:
278: +  comm - the communicator
279: -  fd - the FILE pointer

281:    Output Parameter:
282: .  lab - the PetscViewer to use with the specified file

284:    Level: beginner

286:    Notes:
287:    This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed.

289:    If a multiprocessor communicator is used (such as PETSC_COMM_WORLD),
290:    then only the first processor in the group uses the file.  All other
291:    processors send their data to the first processor to print.

293: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
294:           PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
295:           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen()
296: @*/
297: PetscErrorCode  PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab)
298: {
299:   PetscViewerCreate(comm,lab);
300:   PetscViewerSetType(*lab,PETSCVIEWERASCII);
301:   PetscViewerASCIISetFILE(*lab,fd);
302:   return 0;
303: }

305: PetscErrorCode  PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd)
306: {
307:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

309:   vascii->fd        = fd;
310:   vascii->closefile = PETSC_FALSE;
311:   return 0;
312: }