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