1 2 #include <../src/sys/classes/viewer/impls/ascii/asciiimpl.h> /*I "petscviewer.h" I*/ 3 4 /* ---------------------------------------------------------------------*/ 5 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; 11 12 /*@ 13 PetscViewerASCIIGetStdout - Creates a ASCII PetscViewer shared by all processors 14 in a communicator. Error returning version of PETSC_VIEWER_STDOUT_() 15 16 Collective on MPI_Comm 17 18 Input Parameter: 19 . comm - the MPI communicator to share the PetscViewer 20 21 Level: beginner 22 23 Notes: 24 This should be used in all PETSc source code instead of PETSC_VIEWER_STDOUT_() 25 26 .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD, 27 PETSC_VIEWER_STDOUT_SELF 28 29 @*/ 30 PetscErrorCode PetscViewerASCIIGetStdout(MPI_Comm comm,PetscViewer *viewer) 31 { 32 PetscErrorCode ierr; 33 PetscBool flg; 34 MPI_Comm ncomm; 35 36 PetscFunctionBegin; 37 ierr = PetscSpinlockLock(&PetscViewerASCIISpinLockStdout);CHKERRQ(ierr); 38 ierr = PetscCommDuplicate(comm,&ncomm,NULL);CHKERRQ(ierr); 39 if (Petsc_Viewer_Stdout_keyval == MPI_KEYVAL_INVALID) { 40 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Stdout_keyval,0);CHKERRQ(ierr); 41 } 42 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Stdout_keyval,(void**)viewer,(PetscMPIInt*)&flg);CHKERRQ(ierr); 43 if (!flg) { /* PetscViewer not yet created */ 44 ierr = PetscViewerASCIIOpen(ncomm,"stdout",viewer);CHKERRQ(ierr); 45 ierr = PetscObjectRegisterDestroy((PetscObject)*viewer);CHKERRQ(ierr); 46 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_Stdout_keyval,(void*)*viewer);CHKERRQ(ierr); 47 } 48 ierr = PetscCommDestroy(&ncomm);CHKERRQ(ierr); 49 ierr = PetscSpinlockUnlock(&PetscViewerASCIISpinLockStdout);CHKERRQ(ierr); 50 PetscFunctionReturn(0); 51 } 52 53 /*@C 54 PETSC_VIEWER_STDOUT_ - Creates a ASCII PetscViewer shared by all processors 55 in a communicator. 56 57 Collective on MPI_Comm 58 59 Input Parameter: 60 . comm - the MPI communicator to share the PetscViewer 61 62 Level: beginner 63 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)); 68 69 .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDOUT_WORLD, 70 PETSC_VIEWER_STDOUT_SELF 71 72 @*/ 73 PetscViewer PETSC_VIEWER_STDOUT_(MPI_Comm comm) 74 { 75 PetscErrorCode ierr; 76 PetscViewer viewer; 77 78 PetscFunctionBegin; 79 ierr = PetscViewerASCIIGetStdout(comm,&viewer); 80 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDOUT_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); PetscFunctionReturn(0);} 81 PetscFunctionReturn(viewer); 82 } 83 84 /* ---------------------------------------------------------------------*/ 85 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; 91 92 /*@ 93 PetscViewerASCIIGetStderr - Creates a ASCII PetscViewer shared by all processors 94 in a communicator. Error returning version of PETSC_VIEWER_STDERR_() 95 96 Collective on MPI_Comm 97 98 Input Parameter: 99 . comm - the MPI communicator to share the PetscViewer 100 101 Level: beginner 102 103 Notes: 104 This should be used in all PETSc source code instead of PETSC_VIEWER_STDERR_() 105 106 .seealso: PETSC_VIEWER_DRAW_(), PetscViewerASCIIOpen(), PETSC_VIEWER_STDERR_, PETSC_VIEWER_STDERR_WORLD, 107 PETSC_VIEWER_STDERR_SELF 108 109 @*/ 110 PetscErrorCode PetscViewerASCIIGetStderr(MPI_Comm comm,PetscViewer *viewer) 111 { 112 PetscErrorCode ierr; 113 PetscBool flg; 114 MPI_Comm ncomm; 115 116 PetscFunctionBegin; 117 ierr = PetscSpinlockLock(&PetscViewerASCIISpinLockStderr);CHKERRQ(ierr); 118 ierr = PetscCommDuplicate(comm,&ncomm,NULL);CHKERRQ(ierr); 119 if (Petsc_Viewer_Stderr_keyval == MPI_KEYVAL_INVALID) { 120 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Stderr_keyval,0);CHKERRQ(ierr); 121 } 122 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Stderr_keyval,(void**)viewer,(PetscMPIInt*)&flg);CHKERRQ(ierr); 123 if (!flg) { /* PetscViewer not yet created */ 124 ierr = PetscViewerASCIIOpen(ncomm,"stderr",viewer);CHKERRQ(ierr); 125 ierr = PetscObjectRegisterDestroy((PetscObject)*viewer);CHKERRQ(ierr); 126 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_Stderr_keyval,(void*)*viewer);CHKERRQ(ierr); 127 } 128 ierr = PetscCommDestroy(&ncomm);CHKERRQ(ierr); 129 ierr = PetscSpinlockUnlock(&PetscViewerASCIISpinLockStderr);CHKERRQ(ierr); 130 PetscFunctionReturn(0); 131 } 132 133 /*@C 134 PETSC_VIEWER_STDERR_ - Creates a ASCII PetscViewer shared by all processors 135 in a communicator. 136 137 Collective on MPI_Comm 138 139 Input Parameter: 140 . comm - the MPI communicator to share the PetscViewer 141 142 Level: beginner 143 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)); 148 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 { 154 PetscErrorCode ierr; 155 PetscViewer viewer; 156 157 PetscFunctionBegin; 158 ierr = PetscViewerASCIIGetStderr(comm,&viewer); 159 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDERR_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); PetscFunctionReturn(0);} 160 PetscFunctionReturn(viewer); 161 } 162 163 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. 168 169 This is called by MPI, not by users. 170 171 */ 172 PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state) 173 { 174 PetscErrorCode ierr; 175 176 PetscFunctionBegin; 177 ierr = PetscInfo1(0,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);CHKERRMPI(ierr); 178 PetscFunctionReturn(MPI_SUCCESS); 179 } 180 181 /*@C 182 PetscViewerASCIIOpen - Opens an ASCII file for writing as a PetscViewer. 183 184 Collective on MPI_Comm 185 186 Input Parameters: 187 + comm - the communicator 188 - name - the file name 189 190 Output Parameter: 191 . lab - the PetscViewer to use with the specified file 192 193 Level: beginner 194 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); 201 202 This PetscViewer can be destroyed with PetscViewerDestroy(). 203 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 206 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 213 214 Concepts: PetscViewerASCII^creating 215 Concepts: printf 216 Concepts: printing 217 Concepts: accessing remote file 218 Concepts: remote file 219 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; 230 231 PetscFunctionBegin; 232 ierr = PetscStrlen(name,&len);CHKERRQ(ierr); 233 if (!len) { 234 ierr = PetscViewerASCIIGetStdout(comm,lab);CHKERRQ(ierr); 235 ierr = PetscObjectReference((PetscObject)*lab);CHKERRQ(ierr); 236 PetscFunctionReturn(0); 237 } 238 ierr = PetscSpinlockLock(&PetscViewerASCIISpinLockOpen);CHKERRQ(ierr); 239 if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) { 240 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr); 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. 245 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 ierr = PetscCommDuplicate(comm,&comm,NULL);CHKERRQ(ierr); 251 /* has file already been opened into a viewer */ 252 ierr = MPI_Comm_get_attr(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr); 253 if (flg) { 254 while (vlink) { 255 ierr = PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);CHKERRQ(ierr); 256 if (eq) { 257 ierr = PetscObjectReference((PetscObject)vlink->viewer);CHKERRQ(ierr); 258 *lab = vlink->viewer; 259 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 260 ierr = PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);CHKERRQ(ierr); 261 PetscFunctionReturn(0); 262 } 263 vlink = vlink->next; 264 } 265 } 266 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 267 ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr); 268 if (name) { 269 ierr = PetscViewerFileSetName(*lab,name);CHKERRQ(ierr); 270 } 271 /* save viewer into communicator if needed later */ 272 ierr = PetscNew(&nv);CHKERRQ(ierr); 273 nv->viewer = *lab; 274 if (!flg) { 275 ierr = MPI_Comm_set_attr(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr); 276 } else { 277 ierr = MPI_Comm_get_attr(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr); 278 if (vlink) { 279 while (vlink->next) vlink = vlink->next; 280 vlink->next = nv; 281 } else { 282 ierr = MPI_Comm_set_attr(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr); 283 } 284 } 285 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 286 ierr = PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);CHKERRQ(ierr); 287 PetscFunctionReturn(0); 288 } 289 290 /*@C 291 PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it. 292 293 Collective on MPI_Comm 294 295 Input Parameters: 296 + comm - the communicator 297 - fd - the FILE pointer 298 299 Output Parameter: 300 . lab - the PetscViewer to use with the specified file 301 302 Level: beginner 303 304 Notes: 305 This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed. 306 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. 310 311 Concepts: PetscViewerASCII^creating 312 Concepts: printf 313 Concepts: printing 314 Concepts: accessing remote file 315 Concepts: remote file 316 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 { 323 PetscErrorCode ierr; 324 325 PetscFunctionBegin; 326 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 327 ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr); 328 ierr = PetscViewerASCIISetFILE(*lab,fd);CHKERRQ(ierr); 329 PetscFunctionReturn(0); 330 } 331 332 PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd) 333 { 334 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 335 336 PetscFunctionBegin; 337 vascii->fd = fd; 338 vascii->closefile = PETSC_FALSE; 339 PetscFunctionReturn(0); 340 } 341 342 343 344