1 2 #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I "petscsys.h" I*/ 3 4 /* ---------------------------------------------------------------------*/ 5 6 #undef __FUNCT__ 7 #define __FUNCT__ "PetscViewerASCIIGetStdout" 8 /*@C 9 PetscViewerASCIIGetStdout - Creates a ASCII PetscViewer shared by all processors 10 in a communicator. Error returning version of PETSC_VIEWER_STDOUT_() 11 12 Collective on MPI_Comm 13 14 Input Parameter: 15 . comm - the MPI communicator to share the PetscViewer 16 17 Level: beginner 18 19 Notes: 20 This should be used in all PETSc source code instead of PETSC_VIEWER_STDOUT_() 21 22 .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD, 23 PETSC_VIEWER_STDOUT_SELF 24 25 @*/ 26 PetscErrorCode PetscViewerASCIIGetStdout(MPI_Comm comm,PetscViewer *viewer) 27 { 28 PetscErrorCode ierr; 29 30 PetscFunctionBegin; 31 ierr = PetscViewerASCIIOpen(comm,"stdout",viewer);CHKERRQ(ierr); 32 PetscFunctionReturn(0); 33 } 34 35 #undef __FUNCT__ 36 #define __FUNCT__ "PETSC_VIEWER_STDOUT_" 37 /*@C 38 PETSC_VIEWER_STDOUT_ - Creates a ASCII PetscViewer shared by all processors 39 in a communicator. 40 41 Collective on MPI_Comm 42 43 Input Parameter: 44 . comm - the MPI communicator to share the PetscViewer 45 46 Level: beginner 47 48 Notes: 49 Unlike almost all other PETSc routines, this does not return 50 an error code. Usually used in the form 51 $ XXXView(XXX object,PETSC_VIEWER_STDOUT_(comm)); 52 53 .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD, 54 PETSC_VIEWER_STDOUT_SELF 55 56 @*/ 57 PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm comm) 58 { 59 PetscErrorCode ierr; 60 PetscViewer viewer; 61 62 PetscFunctionBegin; 63 ierr = PetscViewerASCIIGetStdout(comm,&viewer); 64 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); PetscFunctionReturn(0);} 65 PetscFunctionReturn(viewer); 66 } 67 68 /* ---------------------------------------------------------------------*/ 69 70 #undef __FUNCT__ 71 #define __FUNCT__ "PetscViewerASCIIGetStderr" 72 /*@C 73 PetscViewerASCIIGetStderr - Creates a ASCII PetscViewer shared by all processors 74 in a communicator. Error returning version of PETSC_VIEWER_STDERR_() 75 76 Collective on MPI_Comm 77 78 Input Parameter: 79 . comm - the MPI communicator to share the PetscViewer 80 81 Level: beginner 82 83 Notes: 84 This should be used in all PETSc source code instead of PETSC_VIEWER_STDERR_() 85 86 .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDERR_WORLD, 87 PETSC_VIEWER_STDERR_SELF 88 89 @*/ 90 PetscErrorCode PetscViewerASCIIGetStderr(MPI_Comm comm,PetscViewer *viewer) 91 { 92 PetscErrorCode ierr; 93 94 PetscFunctionBegin; 95 ierr = PetscViewerASCIIOpen(comm,"stderr",viewer);CHKERRQ(ierr); 96 PetscFunctionReturn(0); 97 } 98 99 #undef __FUNCT__ 100 #define __FUNCT__ "PETSC_VIEWER_STDERR_" 101 /*@C 102 PETSC_VIEWER_STDERR_ - Creates a ASCII PetscViewer shared by all processors 103 in a communicator. 104 105 Collective on MPI_Comm 106 107 Input Parameter: 108 . comm - the MPI communicator to share the PetscViewer 109 110 Level: beginner 111 112 Note: 113 Unlike almost all other PETSc routines, this does not return 114 an error code. Usually used in the form 115 $ XXXView(XXX object,PETSC_VIEWER_STDERR_(comm)); 116 117 .seealso: PETSC_VIEWER_DRAW_, PetscViewerASCIIOpen(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDOUT_WORLD, 118 PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDERR_WORLD, PETSC_VIEWER_STDERR_SELF 119 @*/ 120 PetscViewer PETSC_VIEWER_STDERR_(MPI_Comm comm) 121 { 122 PetscErrorCode ierr; 123 PetscViewer viewer; 124 125 PetscFunctionBegin; 126 ierr = PetscViewerASCIIGetStderr(comm,&viewer); 127 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDERR_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); PetscFunctionReturn(0);} 128 PetscFunctionReturn(viewer); 129 } 130 131 132 PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID; 133 #undef __FUNCT__ 134 #define __FUNCT__ "Petsc_DelViewer" 135 /* 136 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 137 PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called. 138 139 This is called by MPI, not by users. 140 141 */ 142 PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state) 143 { 144 PetscErrorCode ierr; 145 146 PetscFunctionBegin; 147 ierr = PetscInfo1(0,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr); 148 PetscFunctionReturn(MPI_SUCCESS); 149 } 150 151 #undef __FUNCT__ 152 #define __FUNCT__ "PetscViewerASCIIOpen" 153 /*@C 154 PetscViewerASCIIOpen - Opens an ASCII file as a PetscViewer. 155 156 Collective on MPI_Comm 157 158 Input Parameters: 159 + comm - the communicator 160 - name - the file name 161 162 Output Parameter: 163 . lab - the PetscViewer to use with the specified file 164 165 Level: beginner 166 167 Notes: 168 This PetscViewer can be destroyed with PetscViewerDestroy(). 169 170 The MPI communicator used here must match that used by the object one is viewing. For example if the 171 Mat was created with a PETSC_COMM_WORLD, then the Viewer must be created with PETSC_COMM_WORLD 172 173 As shown below, PetscViewerASCIIOpen() is useful in conjunction with 174 MatView() and VecView() 175 .vb 176 PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer); 177 MatView(matrix,viewer); 178 .ve 179 180 Concepts: PetscViewerASCII^creating 181 Concepts: printf 182 Concepts: printing 183 Concepts: accessing remote file 184 Concepts: remote file 185 186 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(), 187 PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_, 188 PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, 189 @*/ 190 PetscErrorCode PetscViewerASCIIOpen(MPI_Comm comm,const char name[],PetscViewer *lab) 191 { 192 PetscErrorCode ierr; 193 PetscViewerLink *vlink,*nv; 194 PetscBool flg,eq; 195 size_t len; 196 197 PetscFunctionBegin; 198 ierr = PetscStrlen(name,&len);CHKERRQ(ierr); 199 if (!len) { 200 ierr = PetscViewerASCIIGetStdout(comm,lab);CHKERRQ(ierr); 201 ierr = PetscObjectReference((PetscObject)*lab);CHKERRQ(ierr); 202 PetscFunctionReturn(0); 203 } 204 ierr = PetscSpinlockLock(&PetscViewerASCIISpinLock);CHKERRQ(ierr); 205 if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) { 206 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr); 207 } 208 /* 209 It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator 210 we cannot do that, since PetscFileSetName() takes a communicator that already exists. 211 212 Plus if the original communicator that created the file has since been close this will not detect the old 213 communictor and hence will overwrite the old data. It may be better to simply remove all this code 214 */ 215 /* make sure communicator is a PETSc communicator */ 216 ierr = PetscCommDuplicate(comm,&comm,NULL);CHKERRQ(ierr); 217 /* has file already been opened into a viewer */ 218 ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr); 219 if (flg) { 220 while (vlink) { 221 ierr = PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);CHKERRQ(ierr); 222 if (eq) { 223 ierr = PetscObjectReference((PetscObject)vlink->viewer);CHKERRQ(ierr); 224 *lab = vlink->viewer; 225 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 226 ierr = PetscSpinlockUnlock(&PetscViewerASCIISpinLock);CHKERRQ(ierr); 227 PetscFunctionReturn(0); 228 } 229 vlink = vlink->next; 230 } 231 } 232 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 233 ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr); 234 if (name) { 235 ierr = PetscViewerFileSetName(*lab,name);CHKERRQ(ierr); 236 } 237 /* save viewer into communicator if needed later */ 238 ierr = PetscNew(&nv);CHKERRQ(ierr); 239 nv->viewer = *lab; 240 if (!flg) { 241 ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr); 242 } else { 243 ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr); 244 if (vlink) { 245 while (vlink->next) vlink = vlink->next; 246 vlink->next = nv; 247 } else { 248 ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr); 249 } 250 } 251 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 252 ierr = PetscSpinlockUnlock(&PetscViewerASCIISpinLock);CHKERRQ(ierr); 253 PetscFunctionReturn(0); 254 } 255 256 #undef __FUNCT__ 257 #define __FUNCT__ "PetscViewerASCIIOpenWithFILE" 258 /*@C 259 PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it. 260 261 Collective on MPI_Comm 262 263 Input Parameters: 264 + comm - the communicator 265 - fd - the FILE pointer 266 267 Output Parameter: 268 . lab - the PetscViewer to use with the specified file 269 270 Level: beginner 271 272 Notes: 273 This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed. 274 275 If a multiprocessor communicator is used (such as PETSC_COMM_WORLD), 276 then only the first processor in the group uses the file. All other 277 processors send their data to the first processor to print. 278 279 Concepts: PetscViewerASCII^creating 280 Concepts: printf 281 Concepts: printing 282 Concepts: accessing remote file 283 Concepts: remote file 284 285 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(), 286 PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_, 287 PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen() 288 @*/ 289 PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab) 290 { 291 PetscErrorCode ierr; 292 293 PetscFunctionBegin; 294 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 295 ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr); 296 ierr = PetscViewerASCIISetFILE(*lab,fd);CHKERRQ(ierr); 297 PetscFunctionReturn(0); 298 } 299 300 #undef __FUNCT__ 301 #define __FUNCT__ "PetscViewerASCIISetFILE" 302 PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd) 303 { 304 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 305 306 PetscFunctionBegin; 307 vascii->fd = fd; 308 vascii->closefile = PETSC_FALSE; 309 PetscFunctionReturn(0); 310 } 311 312 313 314