Actual source code: vcreatea.c

petsc-master 2019-05-24
Report Typos and Errors

  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 on MPI_Comm

 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: {
 33:   PetscBool      flg;
 34:   MPI_Comm       ncomm;

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

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

 57:    Collective on MPI_Comm

 59:    Input Parameter:
 60: .  comm - the MPI communicator to share the PetscViewer

 62:    Level: beginner

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

 69: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD,
 70:           PETSC_VIEWER_STDOUT_SELF

 72: @*/
 73: PetscViewer  PETSC_VIEWER_STDOUT_(MPI_Comm comm)
 74: {
 76:   PetscViewer    viewer;

 79:   PetscViewerASCIIGetStdout(comm,&viewer);
 80:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); return(0);}
 81:   PetscFunctionReturn(viewer);
 82: }

 84: /* ---------------------------------------------------------------------*/

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

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

 96:    Collective on MPI_Comm

 98:    Input Parameter:
 99: .  comm - the MPI communicator to share the PetscViewer

101:    Level: beginner

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

106: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDERR_WORLD,
107:           PETSC_VIEWER_STDERR_SELF

109: @*/
110: PetscErrorCode  PetscViewerASCIIGetStderr(MPI_Comm comm,PetscViewer *viewer)
111: {
113:   PetscBool      flg;
114:   MPI_Comm       ncomm;

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

133: /*@C
134:    PETSC_VIEWER_STDERR_ - Creates a ASCII PetscViewer shared by all processors
135:                     in a communicator.

137:    Collective on MPI_Comm

139:    Input Parameter:
140: .  comm - the MPI communicator to share the PetscViewer

142:    Level: beginner

144:    Note:
145:    Unlike almost all other PETSc routines, this does not return
146:    an error code. Usually used in the form
147: $      XXXView(XXX object,PETSC_VIEWER_STDERR_(comm));

149: .seealso: PETSC_VIEWER_DRAW_, PetscViewerASCIIOpen(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDOUT_WORLD,
150:           PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDERR_WORLD, PETSC_VIEWER_STDERR_SELF
151: @*/
152: PetscViewer  PETSC_VIEWER_STDERR_(MPI_Comm comm)
153: {
155:   PetscViewer    viewer;

158:   PetscViewerASCIIGetStderr(comm,&viewer);
159:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDERR_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); return(0);}
160:   PetscFunctionReturn(viewer);
161: }


164: PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID;
165: /*
166:    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
167:    PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called.

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

171: */
172: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
173: {

177:   PetscInfo1(0,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);CHKERRMPI(ierr);
178:   PetscFunctionReturn(MPI_SUCCESS);
179: }

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

184:    Collective on MPI_Comm

186:    Input Parameters:
187: +  comm - the communicator
188: -  name - the file name

190:    Output Parameter:
191: .  lab - the PetscViewer to use with the specified file

193:    Level: beginner

195:    Notes:
196:    To open a ASCII file as a viewer for reading one must use the sequence
197: $     PetscViewerCreate(comm,&lab);
198: $     PetscViewerSetType(lab,PETSCVIEWERASCII);
199: $     PetscViewerFileSetMode(lab,FILE_MODE_READ);
200: $     PetscViewerFileSetName(lab,name);

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

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

207:    As shown below, PetscViewerASCIIOpen() is useful in conjunction with
208:    MatView() and VecView()
209: .vb
210:      PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
211:      MatView(matrix,viewer);
212: .ve

214:   Concepts: PetscViewerASCII^creating
215:   Concepts: printf
216:   Concepts: printing
217:   Concepts: accessing remote file
218:   Concepts: remote file

220: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(), PetscViewerASCIIRead()
221:           PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
222:           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF,
223: @*/
224: PetscErrorCode  PetscViewerASCIIOpen(MPI_Comm comm,const char name[],PetscViewer *lab)
225: {
226:   PetscErrorCode  ierr;
227:   PetscViewerLink *vlink,*nv;
228:   PetscBool       flg,eq;
229:   size_t          len;

232:   PetscStrlen(name,&len);
233:   if (!len) {
234:     PetscViewerASCIIGetStdout(comm,lab);
235:     PetscObjectReference((PetscObject)*lab);
236:     return(0);
237:   }
238:   PetscSpinlockLock(&PetscViewerASCIISpinLockOpen);
239:   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
240:     MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
241:   }
242:   /*
243:        It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
244:      we cannot do that, since PetscFileSetName() takes a communicator that already exists.

246:       Plus if the original communicator that created the file has since been close this will not detect the old
247:       communictor and hence will overwrite the old data. It may be better to simply remove all this code
248:   */
249:   /* make sure communicator is a PETSc communicator */
250:   PetscCommDuplicate(comm,&comm,NULL);
251:   /* has file already been opened into a viewer */
252:   MPI_Comm_get_attr(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
253:   if (flg) {
254:     while (vlink) {
255:       PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);
256:       if (eq) {
257:         PetscObjectReference((PetscObject)vlink->viewer);
258:         *lab = vlink->viewer;
259:         PetscCommDestroy(&comm);
260:         PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);
261:         return(0);
262:       }
263:       vlink = vlink->next;
264:     }
265:   }
266:   PetscViewerCreate(comm,lab);
267:   PetscViewerSetType(*lab,PETSCVIEWERASCII);
268:   if (name) {
269:     PetscViewerFileSetName(*lab,name);
270:   }
271:   /* save viewer into communicator if needed later */
272:   PetscNew(&nv);
273:   nv->viewer = *lab;
274:   if (!flg) {
275:     MPI_Comm_set_attr(comm,Petsc_Viewer_keyval,nv);
276:   } else {
277:     MPI_Comm_get_attr(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);
278:     if (vlink) {
279:       while (vlink->next) vlink = vlink->next;
280:       vlink->next = nv;
281:     } else {
282:       MPI_Comm_set_attr(comm,Petsc_Viewer_keyval,nv);
283:     }
284:   }
285:   PetscCommDestroy(&comm);
286:   PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);
287:   return(0);
288: }

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

293:    Collective on MPI_Comm

295:    Input Parameters:
296: +  comm - the communicator
297: -  fd - the FILE pointer

299:    Output Parameter:
300: .  lab - the PetscViewer to use with the specified file

302:    Level: beginner

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

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

311:   Concepts: PetscViewerASCII^creating
312:   Concepts: printf
313:   Concepts: printing
314:   Concepts: accessing remote file
315:   Concepts: remote file

317: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
318:           PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
319:           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen()
320: @*/
321: PetscErrorCode  PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab)
322: {

326:   PetscViewerCreate(comm,lab);
327:   PetscViewerSetType(*lab,PETSCVIEWERASCII);
328:   PetscViewerASCIISetFILE(*lab,fd);
329:   return(0);
330: }

332: PetscErrorCode  PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd)
333: {
334:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

337:   vascii->fd        = fd;
338:   vascii->closefile = PETSC_FALSE;
339:   return(0);
340: }