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 PetscBool flg; 120 MPI_Comm ncomm; 121 122 PetscFunctionBegin; 123 ierr = PetscSpinlockLock(&PetscViewerASCIISpinLock);CHKERRQ(ierr); 124 ierr = PetscCommDuplicate(comm,&ncomm,NULL);CHKERRQ(ierr); 125 if (Petsc_Viewer_Stderr_keyval == MPI_KEYVAL_INVALID) { 126 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Stderr_keyval,0);CHKERRQ(ierr); 127 } 128 ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Stderr_keyval,(void**)viewer,(PetscMPIInt*)&flg);CHKERRQ(ierr); 129 if (!flg) { /* PetscViewer not yet created */ 130 ierr = PetscViewerASCIIOpen(ncomm,"stderr",viewer);CHKERRQ(ierr); 131 ierr = PetscObjectRegisterDestroy((PetscObject)*viewer);CHKERRQ(ierr); 132 ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Stderr_keyval,(void*)*viewer);CHKERRQ(ierr); 133 } 134 ierr = PetscCommDestroy(&ncomm);CHKERRQ(ierr); 135 ierr = PetscSpinlockUnlock(&PetscViewerASCIISpinLock);CHKERRQ(ierr); 136 PetscFunctionReturn(0); 137 } 138 139 #undef __FUNCT__ 140 #define __FUNCT__ "PETSC_VIEWER_STDERR_" 141 /*@C 142 PETSC_VIEWER_STDERR_ - Creates a ASCII PetscViewer shared by all processors 143 in a communicator. 144 145 Collective on MPI_Comm 146 147 Input Parameter: 148 . comm - the MPI communicator to share the PetscViewer 149 150 Level: beginner 151 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)); 156 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 { 162 PetscErrorCode ierr; 163 PetscViewer viewer; 164 165 PetscFunctionBegin; 166 ierr = PetscViewerASCIIGetStderr(comm,&viewer); 167 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_STDERR_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," "); PetscFunctionReturn(0);} 168 PetscFunctionReturn(viewer); 169 } 170 171 172 PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID; 173 #undef __FUNCT__ 174 #define __FUNCT__ "Petsc_DelViewer" 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. 178 179 This is called by MPI, not by users. 180 181 */ 182 PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state) 183 { 184 PetscErrorCode ierr; 185 186 PetscFunctionBegin; 187 ierr = PetscInfo1(0,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr); 188 PetscFunctionReturn(MPI_SUCCESS); 189 } 190 191 #undef __FUNCT__ 192 #define __FUNCT__ "PetscViewerASCIIOpen" 193 /*@C 194 PetscViewerASCIIOpen - Opens an ASCII file as a PetscViewer. 195 196 Collective on MPI_Comm 197 198 Input Parameters: 199 + comm - the communicator 200 - name - the file name 201 202 Output Parameter: 203 . lab - the PetscViewer to use with the specified file 204 205 Level: beginner 206 207 Notes: 208 This PetscViewer can be destroyed with PetscViewerDestroy(). 209 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 212 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 219 220 Concepts: PetscViewerASCII^creating 221 Concepts: printf 222 Concepts: printing 223 Concepts: accessing remote file 224 Concepts: remote file 225 226 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(), 227 PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), 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; 236 237 PetscFunctionBegin; 238 ierr = PetscStrlen(name,&len);CHKERRQ(ierr); 239 if (!len) { 240 ierr = PetscViewerASCIIGetStdout(comm,lab);CHKERRQ(ierr); 241 ierr = PetscObjectReference((PetscObject)*lab);CHKERRQ(ierr); 242 PetscFunctionReturn(0); 243 } 244 ierr = PetscSpinlockLock(&PetscViewerASCIISpinLock);CHKERRQ(ierr); 245 if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) { 246 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr); 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. 251 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 ierr = PetscCommDuplicate(comm,&comm,NULL);CHKERRQ(ierr); 257 /* has file already been opened into a viewer */ 258 ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr); 259 if (flg) { 260 while (vlink) { 261 ierr = PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);CHKERRQ(ierr); 262 if (eq) { 263 ierr = PetscObjectReference((PetscObject)vlink->viewer);CHKERRQ(ierr); 264 *lab = vlink->viewer; 265 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 266 ierr = PetscSpinlockUnlock(&PetscViewerASCIISpinLock);CHKERRQ(ierr); 267 PetscFunctionReturn(0); 268 } 269 vlink = vlink->next; 270 } 271 } 272 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 273 ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr); 274 if (name) { 275 ierr = PetscViewerFileSetName(*lab,name);CHKERRQ(ierr); 276 } 277 /* save viewer into communicator if needed later */ 278 ierr = PetscNew(&nv);CHKERRQ(ierr); 279 nv->viewer = *lab; 280 if (!flg) { 281 ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr); 282 } else { 283 ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr); 284 if (vlink) { 285 while (vlink->next) vlink = vlink->next; 286 vlink->next = nv; 287 } else { 288 ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr); 289 } 290 } 291 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 292 ierr = PetscSpinlockUnlock(&PetscViewerASCIISpinLock);CHKERRQ(ierr); 293 PetscFunctionReturn(0); 294 } 295 296 #undef __FUNCT__ 297 #define __FUNCT__ "PetscViewerASCIIOpenWithFILE" 298 /*@C 299 PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it. 300 301 Collective on MPI_Comm 302 303 Input Parameters: 304 + comm - the communicator 305 - fd - the FILE pointer 306 307 Output Parameter: 308 . lab - the PetscViewer to use with the specified file 309 310 Level: beginner 311 312 Notes: 313 This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed. 314 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. 318 319 Concepts: PetscViewerASCII^creating 320 Concepts: printf 321 Concepts: printing 322 Concepts: accessing remote file 323 Concepts: remote file 324 325 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(), 326 PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), 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 { 331 PetscErrorCode ierr; 332 333 PetscFunctionBegin; 334 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 335 ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr); 336 ierr = PetscViewerASCIISetFILE(*lab,fd);CHKERRQ(ierr); 337 PetscFunctionReturn(0); 338 } 339 340 #undef __FUNCT__ 341 #define __FUNCT__ "PetscViewerASCIISetFILE" 342 PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd) 343 { 344 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 345 346 PetscFunctionBegin; 347 vascii->fd = fd; 348 vascii->closefile = PETSC_FALSE; 349 PetscFunctionReturn(0); 350 } 351 352 353 354