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,PETSC_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,PETSC_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 EXTERN_C_BEGIN 168 #undef __FUNCT__ 169 #define __FUNCT__ "Petsc_DelViewer" 170 /* 171 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 172 PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called. 173 174 This is called by MPI, not by users. 175 176 */ 177 PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state) 178 { 179 PetscErrorCode ierr; 180 181 PetscFunctionBegin; 182 ierr = PetscInfo1(0,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);if (ierr) PetscFunctionReturn((PetscMPIInt)ierr); 183 PetscFunctionReturn(MPI_SUCCESS); 184 } 185 EXTERN_C_END 186 187 #undef __FUNCT__ 188 #define __FUNCT__ "PetscViewerASCIIOpen" 189 /*@C 190 PetscViewerASCIIOpen - Opens an ASCII file as a PetscViewer. 191 192 Collective on MPI_Comm 193 194 Input Parameters: 195 + comm - the communicator 196 - name - the file name 197 198 Output Parameter: 199 . lab - the PetscViewer to use with the specified file 200 201 Level: beginner 202 203 Notes: 204 This PetscViewer can be destroyed with PetscViewerDestroy(). 205 206 If a multiprocessor communicator is used (such as PETSC_COMM_WORLD), 207 then only the first processor in the group opens the file. All other 208 processors send their data to the first processor to print. 209 210 Each processor can instead write its own independent output by 211 specifying the communicator PETSC_COMM_SELF. 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 if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) { 245 ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRQ(ierr); 246 } 247 /* 248 It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator 249 we cannot do that, since PetscFileSetName() takes a communicator that already exists. 250 251 Plus if the original communicator that created the file has since been close this will not detect the old 252 communictor and hence will overwrite the old data. It may be better to simply remove all this code 253 */ 254 /* make sure communicator is a PETSc communicator */ 255 ierr = PetscCommDuplicate(comm,&comm,PETSC_NULL);CHKERRQ(ierr); 256 /* has file already been opened into a viewer */ 257 ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr); 258 if (flg) { 259 while (vlink) { 260 ierr = PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);CHKERRQ(ierr); 261 if (eq) { 262 ierr = PetscObjectReference((PetscObject)vlink->viewer);CHKERRQ(ierr); 263 *lab = vlink->viewer; 264 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 265 PetscFunctionReturn(0); 266 } 267 vlink = vlink->next; 268 } 269 } 270 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 271 ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr); 272 if (name) { 273 ierr = PetscViewerFileSetName(*lab,name);CHKERRQ(ierr); 274 } 275 /* save viewer into communicator if needed later */ 276 ierr = PetscNew(PetscViewerLink,&nv);CHKERRQ(ierr); 277 nv->viewer = *lab; 278 if (!flg) { 279 ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr); 280 } else { 281 ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr); 282 if (vlink) { 283 while (vlink->next) vlink = vlink->next; 284 vlink->next = nv; 285 } else { 286 ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr); 287 } 288 } 289 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 290 PetscFunctionReturn(0); 291 } 292 293 #undef __FUNCT__ 294 #define __FUNCT__ "PetscViewerASCIIOpenWithFILE" 295 /*@C 296 PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it. 297 298 Collective on MPI_Comm 299 300 Input Parameters: 301 + comm - the communicator 302 - fd - the FILE pointer 303 304 Output Parameter: 305 . lab - the PetscViewer to use with the specified file 306 307 Level: beginner 308 309 Notes: 310 This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed. 311 312 If a multiprocessor communicator is used (such as PETSC_COMM_WORLD), 313 then only the first processor in the group uses the file. All other 314 processors send their data to the first processor to print. 315 316 Concepts: PetscViewerASCII^creating 317 Concepts: printf 318 Concepts: printing 319 Concepts: accessing remote file 320 Concepts: remote file 321 322 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(), 323 PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_, 324 PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen() 325 @*/ 326 PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab) 327 { 328 PetscErrorCode ierr; 329 330 PetscFunctionBegin; 331 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 332 ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr); 333 ierr = PetscViewerASCIISetFILE(*lab,fd);CHKERRQ(ierr); 334 PetscFunctionReturn(0); 335 } 336 337 #undef __FUNCT__ 338 #define __FUNCT__ "PetscViewerASCIISetFILE" 339 PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd) 340 { 341 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 342 343 PetscFunctionBegin; 344 vascii->fd = fd; 345 vascii->closefile = PETSC_FALSE; 346 PetscFunctionReturn(0); 347 } 348 349 350 351