Actual source code: vcreatea.c

petsc-3.7.7 2017-09-25
Report Typos and Errors
  2: #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h>  /*I     "petscsys.h"   I*/

  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: static PetscMPIInt Petsc_Viewer_Stdout_keyval = MPI_KEYVAL_INVALID;

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

 18:    Collective on MPI_Comm

 20:    Input Parameter:
 21: .  comm - the MPI communicator to share the PetscViewer

 23:    Level: beginner

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

 28: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD,
 29:           PETSC_VIEWER_STDOUT_SELF

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

 39:   PetscSpinlockLock(&PetscViewerASCIISpinLockStdout);
 40:   PetscCommDuplicate(comm,&ncomm,NULL);
 41:   if (Petsc_Viewer_Stdout_keyval == MPI_KEYVAL_INVALID) {
 42:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Stdout_keyval,0);
 43:   }
 44:   MPI_Attr_get(ncomm,Petsc_Viewer_Stdout_keyval,(void**)viewer,(PetscMPIInt*)&flg);
 45:   if (!flg) { /* PetscViewer not yet created */
 46:     PetscViewerASCIIOpen(ncomm,"stdout",viewer);
 47:     PetscObjectRegisterDestroy((PetscObject)*viewer);
 48:     MPI_Attr_put(ncomm,Petsc_Viewer_Stdout_keyval,(void*)*viewer);
 49:   }
 50:   PetscCommDestroy(&ncomm);
 51:   PetscSpinlockUnlock(&PetscViewerASCIISpinLockStdout);
 52:   return(0);
 53: }

 57: /*@C
 58:    PETSC_VIEWER_STDOUT_ - Creates a ASCII PetscViewer shared by all processors
 59:                     in a communicator.

 61:    Collective on MPI_Comm

 63:    Input Parameter:
 64: .  comm - the MPI communicator to share the PetscViewer

 66:    Level: beginner

 68:    Notes:
 69:    Unlike almost all other PETSc routines, this does not return
 70:    an error code. Usually used in the form
 71: $      XXXView(XXX object,PETSC_VIEWER_STDOUT_(comm));

 73: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD,
 74:           PETSC_VIEWER_STDOUT_SELF

 76: @*/
 77: PetscViewer  PETSC_VIEWER_STDOUT_(MPI_Comm comm)
 78: {
 80:   PetscViewer    viewer;

 83:   PetscViewerASCIIGetStdout(comm,&viewer);
 84:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); return(0);}
 85:   PetscFunctionReturn(viewer);
 86: }

 88: /* ---------------------------------------------------------------------*/

 90: /*
 91:     The variable Petsc_Viewer_Stderr_keyval is used to indicate an MPI attribute that
 92:   is attached to a communicator, in this case the attribute is a PetscViewer.
 93: */
 94: static PetscMPIInt Petsc_Viewer_Stderr_keyval = MPI_KEYVAL_INVALID;

 98: /*@C
 99:    PetscViewerASCIIGetStderr - Creates a ASCII PetscViewer shared by all processors
100:                     in a communicator. Error returning version of PETSC_VIEWER_STDERR_()

102:    Collective on MPI_Comm

104:    Input Parameter:
105: .  comm - the MPI communicator to share the PetscViewer

107:    Level: beginner

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

112: .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDERR_WORLD,
113:           PETSC_VIEWER_STDERR_SELF

115: @*/
116: PetscErrorCode  PetscViewerASCIIGetStderr(MPI_Comm comm,PetscViewer *viewer)
117: {
119:   PetscBool      flg;
120:   MPI_Comm       ncomm;

123:   PetscSpinlockLock(&PetscViewerASCIISpinLockStderr);
124:   PetscCommDuplicate(comm,&ncomm,NULL);
125:   if (Petsc_Viewer_Stderr_keyval == MPI_KEYVAL_INVALID) {
126:     MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Stderr_keyval,0);
127:   }
128:   MPI_Attr_get(ncomm,Petsc_Viewer_Stderr_keyval,(void**)viewer,(PetscMPIInt*)&flg);
129:   if (!flg) { /* PetscViewer not yet created */
130:     PetscViewerASCIIOpen(ncomm,"stderr",viewer);
131:     PetscObjectRegisterDestroy((PetscObject)*viewer);
132:     MPI_Attr_put(ncomm,Petsc_Viewer_Stderr_keyval,(void*)*viewer);
133:   }
134:   PetscCommDestroy(&ncomm);
135:   PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr);
136:   return(0);
137: }

141: /*@C
142:    PETSC_VIEWER_STDERR_ - Creates a ASCII PetscViewer shared by all processors
143:                     in a communicator.

145:    Collective on MPI_Comm

147:    Input Parameter:
148: .  comm - the MPI communicator to share the PetscViewer

150:    Level: beginner

152:    Note:
153:    Unlike almost all other PETSc routines, this does not return
154:    an error code. Usually used in the form
155: $      XXXView(XXX object,PETSC_VIEWER_STDERR_(comm));

157: .seealso: PETSC_VIEWER_DRAW_, PetscViewerASCIIOpen(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDOUT_WORLD,
158:           PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDERR_WORLD, PETSC_VIEWER_STDERR_SELF
159: @*/
160: PetscViewer  PETSC_VIEWER_STDERR_(MPI_Comm comm)
161: {
163:   PetscViewer    viewer;

166:   PetscViewerASCIIGetStderr(comm,&viewer);
167:   if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDERR_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); return(0);}
168:   PetscFunctionReturn(viewer);
169: }


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

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

181: */
182: PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state)
183: {

187:   PetscInfo1(0,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr);
188:   PetscFunctionReturn(MPI_SUCCESS);
189: }

193: /*@C
194:    PetscViewerASCIIOpen - Opens an ASCII file as a PetscViewer.

196:    Collective on MPI_Comm

198:    Input Parameters:
199: +  comm - the communicator
200: -  name - the file name

202:    Output Parameter:
203: .  lab - the PetscViewer to use with the specified file

205:    Level: beginner

207:    Notes:
208:    This PetscViewer can be destroyed with PetscViewerDestroy().

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

213:    As shown below, PetscViewerASCIIOpen() is useful in conjunction with
214:    MatView() and VecView()
215: .vb
216:      PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer);
217:      MatView(matrix,viewer);
218: .ve

220:   Concepts: PetscViewerASCII^creating
221:   Concepts: printf
222:   Concepts: printing
223:   Concepts: accessing remote file
224:   Concepts: remote file

226: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
227:           PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
228:           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF,
229: @*/
230: PetscErrorCode  PetscViewerASCIIOpen(MPI_Comm comm,const char name[],PetscViewer *lab)
231: {
232:   PetscErrorCode  ierr;
233:   PetscViewerLink *vlink,*nv;
234:   PetscBool       flg,eq;
235:   size_t          len;

238:   PetscStrlen(name,&len);
239:   if (!len) {
240:     PetscViewerASCIIGetStdout(comm,lab);
241:     PetscObjectReference((PetscObject)*lab);
242:     return(0);
243:   }
244:   PetscSpinlockLock(&PetscViewerASCIISpinLockOpen);
245:   if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) {
246:     MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);
247:   }
248:   /*
249:        It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator
250:      we cannot do that, since PetscFileSetName() takes a communicator that already exists.

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

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

301:    Collective on MPI_Comm

303:    Input Parameters:
304: +  comm - the communicator
305: -  fd - the FILE pointer

307:    Output Parameter:
308: .  lab - the PetscViewer to use with the specified file

310:    Level: beginner

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

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

319:   Concepts: PetscViewerASCII^creating
320:   Concepts: printf
321:   Concepts: printing
322:   Concepts: accessing remote file
323:   Concepts: remote file

325: .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(),
326:           PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_,
327:           PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen()
328: @*/
329: PetscErrorCode  PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab)
330: {

334:   PetscViewerCreate(comm,lab);
335:   PetscViewerSetType(*lab,PETSCVIEWERASCII);
336:   PetscViewerASCIISetFILE(*lab,fd);
337:   return(0);
338: }

342: PetscErrorCode  PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd)
343: {
344:   PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data;

347:   vascii->fd        = fd;
348:   vascii->closefile = PETSC_FALSE;
349:   return(0);
350: }