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 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,NULL);CHKERRMPI(ierr); 41 } 42 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Stdout_keyval,(void**)viewer,(PetscMPIInt*)&flg);CHKERRMPI(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);CHKERRMPI(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 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(NULL);} 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 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,NULL);CHKERRMPI(ierr); 121 } 122 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Stderr_keyval,(void**)viewer,(PetscMPIInt*)&flg);CHKERRMPI(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);CHKERRMPI(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 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(NULL);} 160 PetscFunctionReturn(viewer); 161 } 162 163 PetscMPIInt Petsc_Viewer_keyval = MPI_KEYVAL_INVALID; 164 /* 165 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 166 PetscObjectDestroyRegisterAll(). PetscViewerASCIIGetStdout() registers the viewer with PetscObjectDestroyRegister() to be destroyed when PetscFinalize() is called. 167 168 This is called by MPI, not by users. 169 170 */ 171 PETSC_EXTERN PetscMPIInt MPIAPI Petsc_DelViewer(MPI_Comm comm,PetscMPIInt keyval,void *attr_val,void *extra_state) 172 { 173 PetscErrorCode ierr; 174 175 PetscFunctionBegin; 176 ierr = PetscInfo(NULL,"Removing viewer data attribute in an MPI_Comm %ld\n",(long)comm);CHKERRMPI(ierr); 177 PetscFunctionReturn(MPI_SUCCESS); 178 } 179 180 /*@C 181 PetscViewerASCIIOpen - Opens an ASCII file for writing as a PetscViewer. 182 183 Collective 184 185 Input Parameters: 186 + comm - the communicator 187 - name - the file name 188 189 Output Parameter: 190 . lab - the PetscViewer to use with the specified file 191 192 Level: beginner 193 194 Notes: 195 To open a ASCII file as a viewer for reading one must use the sequence 196 $ PetscViewerCreate(comm,&lab); 197 $ PetscViewerSetType(lab,PETSCVIEWERASCII); 198 $ PetscViewerFileSetMode(lab,FILE_MODE_READ); 199 $ PetscViewerFileSetName(lab,name); 200 201 This PetscViewer can be destroyed with PetscViewerDestroy(). 202 203 The MPI communicator used here must match that used by the object one is viewing. For example if the 204 Mat was created with a PETSC_COMM_WORLD, then the Viewer must be created with PETSC_COMM_WORLD 205 206 As shown below, PetscViewerASCIIOpen() is useful in conjunction with 207 MatView() and VecView() 208 .vb 209 PetscViewerASCIIOpen(PETSC_COMM_WORLD,"mat.output",&viewer); 210 MatView(matrix,viewer); 211 .ve 212 213 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(), PetscViewerASCIIRead() 214 PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_, 215 PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, 216 @*/ 217 PetscErrorCode PetscViewerASCIIOpen(MPI_Comm comm,const char name[],PetscViewer *lab) 218 { 219 PetscErrorCode ierr; 220 PetscViewerLink *vlink,*nv; 221 PetscBool flg,eq; 222 size_t len; 223 224 PetscFunctionBegin; 225 ierr = PetscStrlen(name,&len);CHKERRQ(ierr); 226 if (!len) { 227 ierr = PetscViewerASCIIGetStdout(comm,lab);CHKERRQ(ierr); 228 ierr = PetscObjectReference((PetscObject)*lab);CHKERRQ(ierr); 229 PetscFunctionReturn(0); 230 } 231 ierr = PetscSpinlockLock(&PetscViewerASCIISpinLockOpen);CHKERRQ(ierr); 232 if (Petsc_Viewer_keyval == MPI_KEYVAL_INVALID) { 233 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,Petsc_DelViewer,&Petsc_Viewer_keyval,(void*)0);CHKERRMPI(ierr); 234 } 235 /* 236 It would be better to move this code to PetscFileSetName() but since it must return a preexiting communicator 237 we cannot do that, since PetscFileSetName() takes a communicator that already exists. 238 239 Plus if the original communicator that created the file has since been close this will not detect the old 240 communictor and hence will overwrite the old data. It may be better to simply remove all this code 241 */ 242 /* make sure communicator is a PETSc communicator */ 243 ierr = PetscCommDuplicate(comm,&comm,NULL);CHKERRQ(ierr); 244 /* has file already been opened into a viewer */ 245 ierr = MPI_Comm_get_attr(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRMPI(ierr); 246 if (flg) { 247 while (vlink) { 248 ierr = PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);CHKERRQ(ierr); 249 if (eq) { 250 ierr = PetscObjectReference((PetscObject)vlink->viewer);CHKERRQ(ierr); 251 *lab = vlink->viewer; 252 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 253 ierr = PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);CHKERRQ(ierr); 254 PetscFunctionReturn(0); 255 } 256 vlink = vlink->next; 257 } 258 } 259 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 260 ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr); 261 if (name) { 262 ierr = PetscViewerFileSetName(*lab,name);CHKERRQ(ierr); 263 } 264 /* save viewer into communicator if needed later */ 265 ierr = PetscNew(&nv);CHKERRQ(ierr); 266 nv->viewer = *lab; 267 if (!flg) { 268 ierr = MPI_Comm_set_attr(comm,Petsc_Viewer_keyval,nv);CHKERRMPI(ierr); 269 } else { 270 ierr = MPI_Comm_get_attr(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRMPI(ierr); 271 if (vlink) { 272 while (vlink->next) vlink = vlink->next; 273 vlink->next = nv; 274 } else { 275 ierr = MPI_Comm_set_attr(comm,Petsc_Viewer_keyval,nv);CHKERRMPI(ierr); 276 } 277 } 278 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 279 ierr = PetscSpinlockUnlock(&PetscViewerASCIISpinLockOpen);CHKERRQ(ierr); 280 PetscFunctionReturn(0); 281 } 282 283 /*@C 284 PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it. 285 286 Collective 287 288 Input Parameters: 289 + comm - the communicator 290 - fd - the FILE pointer 291 292 Output Parameter: 293 . lab - the PetscViewer to use with the specified file 294 295 Level: beginner 296 297 Notes: 298 This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed. 299 300 If a multiprocessor communicator is used (such as PETSC_COMM_WORLD), 301 then only the first processor in the group uses the file. All other 302 processors send their data to the first processor to print. 303 304 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(), 305 PetscViewerASCIIGetPointer(), PetscViewerPushFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_, 306 PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen() 307 @*/ 308 PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab) 309 { 310 PetscErrorCode ierr; 311 312 PetscFunctionBegin; 313 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 314 ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr); 315 ierr = PetscViewerASCIISetFILE(*lab,fd);CHKERRQ(ierr); 316 PetscFunctionReturn(0); 317 } 318 319 PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd) 320 { 321 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 322 323 PetscFunctionBegin; 324 vascii->fd = fd; 325 vascii->closefile = PETSC_FALSE; 326 PetscFunctionReturn(0); 327 } 328