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