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 /* make sure communicator is a PETSc communicator */ 248 ierr = PetscCommDuplicate(comm,&comm,PETSC_NULL);CHKERRQ(ierr); 249 /* has file already been opened into a viewer */ 250 ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr); 251 if (flg) { 252 while (vlink) { 253 ierr = PetscStrcmp(name,((PetscViewer_ASCII*)(vlink->viewer->data))->filename,&eq);CHKERRQ(ierr); 254 if (eq) { 255 ierr = PetscObjectReference((PetscObject)vlink->viewer);CHKERRQ(ierr); 256 *lab = vlink->viewer; 257 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 258 PetscFunctionReturn(0); 259 } 260 vlink = vlink->next; 261 } 262 } 263 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 264 ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr); 265 if (name) { 266 ierr = PetscViewerFileSetName(*lab,name);CHKERRQ(ierr); 267 } 268 /* save viewer into communicator if needed later */ 269 ierr = PetscNew(PetscViewerLink,&nv);CHKERRQ(ierr); 270 nv->viewer = *lab; 271 if (!flg) { 272 ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr); 273 } else { 274 ierr = MPI_Attr_get(comm,Petsc_Viewer_keyval,(void**)&vlink,(PetscMPIInt*)&flg);CHKERRQ(ierr); 275 if (vlink) { 276 while (vlink->next) vlink = vlink->next; 277 vlink->next = nv; 278 } else { 279 ierr = MPI_Attr_put(comm,Petsc_Viewer_keyval,nv);CHKERRQ(ierr); 280 } 281 } 282 ierr = PetscCommDestroy(&comm);CHKERRQ(ierr); 283 PetscFunctionReturn(0); 284 } 285 286 #undef __FUNCT__ 287 #define __FUNCT__ "PetscViewerASCIIOpenWithFILE" 288 /*@C 289 PetscViewerASCIIOpenWithFILE - Given an open file creates an ASCII viewer that prints to it. 290 291 Collective on MPI_Comm 292 293 Input Parameters: 294 + comm - the communicator 295 - fd - the FILE pointer 296 297 Output Parameter: 298 . lab - the PetscViewer to use with the specified file 299 300 Level: beginner 301 302 Notes: 303 This PetscViewer can be destroyed with PetscViewerDestroy(), but the fd will NOT be closed. 304 305 If a multiprocessor communicator is used (such as PETSC_COMM_WORLD), 306 then only the first processor in the group uses the file. All other 307 processors send their data to the first processor to print. 308 309 Concepts: PetscViewerASCII^creating 310 Concepts: printf 311 Concepts: printing 312 Concepts: accessing remote file 313 Concepts: remote file 314 315 .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerBinaryOpen(), 316 PetscViewerASCIIGetPointer(), PetscViewerSetFormat(), PETSC_VIEWER_STDOUT_, PETSC_VIEWER_STDERR_, 317 PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF, PetscViewerASCIIOpen() 318 @*/ 319 PetscErrorCode PetscViewerASCIIOpenWithFILE(MPI_Comm comm,FILE *fd,PetscViewer *lab) 320 { 321 PetscErrorCode ierr; 322 323 PetscFunctionBegin; 324 ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 325 ierr = PetscViewerSetType(*lab,PETSCVIEWERASCII);CHKERRQ(ierr); 326 ierr = PetscViewerASCIISetFILE(*lab,fd);CHKERRQ(ierr); 327 PetscFunctionReturn(0); 328 } 329 330 #undef __FUNCT__ 331 #define __FUNCT__ "PetscViewerASCIISetFILE" 332 PetscErrorCode PetscViewerASCIISetFILE(PetscViewer viewer,FILE *fd) 333 { 334 PetscViewer_ASCII *vascii = (PetscViewer_ASCII*)viewer->data; 335 336 PetscFunctionBegin; 337 vascii->fd = fd; 338 vascii->closefile = PETSC_FALSE; 339 PetscFunctionReturn(0); 340 } 341 342 343 344