1 2 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/ 3 #if defined(PETSC_HAVE_SAWS) 4 #include <petscviewersaws.h> 5 #endif 6 7 PetscFunctionList PetscViewerList = 0; 8 9 /* 10 A standard run of an implicit TS generated 60 help message hashes, 11 thus we reserve room for 5 combinations of prefixes. If that is not 12 enough then any additional help messages will be printed multiple times. 13 */ 14 #define PETSCSTRINGHASHSIZE 300 15 typedef struct { 16 int cnt; 17 unsigned long hashes[PETSCSTRINGHASHSIZE]; 18 } PetscStrHash; 19 20 #include "../src/sys/utils/hash.h" 21 22 KHASH_SET_INIT_STR(PetscOptionsGetViewerPrinted) 23 static khash_t(PetscOptionsGetViewerPrinted) *PrintedOptions = NULL; 24 static PetscSegBuffer strings = NULL; 25 26 static PetscErrorCode PetscOptionsGetViewerPrintedDestroy(void) 27 { 28 PetscErrorCode ierr; 29 kh_destroy(PetscOptionsGetViewerPrinted,PrintedOptions); 30 ierr = PetscSegBufferDestroy(&strings);CHKERRQ(ierr); 31 return 0; 32 } 33 34 #undef __FUNCT__ 35 #define __FUNCT__ "PetscOptionsGetViewer" 36 /*@C 37 PetscOptionsGetViewer - Gets a viewer appropriate for the type indicated by the user 38 39 Collective on MPI_Comm 40 41 Input Parameters: 42 + comm - the communicator to own the viewer 43 . pre - the string to prepend to the name or NULL 44 - name - the option one is seeking 45 46 Output Parameter: 47 + viewer - the viewer, pass NULL if not needed 48 . format - the PetscViewerFormat requested by the user, pass NULL if not needed 49 - set - PETSC_TRUE if found, else PETSC_FALSE 50 51 Level: intermediate 52 53 Notes: If no value is provided ascii:stdout is used 54 $ ascii[:[filename][:[format][:append]]] defaults to stdout - format can be one of ascii_info, ascii_info_detail, or ascii_matlab, 55 for example ascii::ascii_info prints just the information about the object not all details 56 unless :append is given filename opens in write mode, overwriting what was already there 57 $ binary[:[filename][:[format][:append]]] defaults to the file binaryoutput 58 $ draw[:drawtype] for example, draw:tikz or draw:x 59 $ socket[:port] defaults to the standard output port 60 $ saws[:communicatorname] publishes object to the Scientific Application Webserver (SAWs) 61 62 Use PetscViewerDestroy() after using the viewer, otherwise a memory leak will occur 63 64 If PETSc is configured with --with-viewfromoptions=0 this function always returns with *set of PETSC_FALSE 65 66 .seealso: PetscOptionsGetReal(), PetscOptionsHasName(), PetscOptionsGetString(), 67 PetscOptionsGetIntArray(), PetscOptionsGetRealArray(), PetscOptionsBool() 68 PetscOptionsInt(), PetscOptionsString(), PetscOptionsReal(), PetscOptionsBool(), 69 PetscOptionsName(), PetscOptionsBegin(), PetscOptionsEnd(), PetscOptionsHead(), 70 PetscOptionsStringArray(),PetscOptionsRealArray(), PetscOptionsScalar(), 71 PetscOptionsBoolGroupBegin(), PetscOptionsBoolGroup(), PetscOptionsBoolGroupEnd(), 72 PetscOptionsFList(), PetscOptionsEList() 73 @*/ 74 PetscErrorCode PetscOptionsGetViewer(MPI_Comm comm,const char pre[],const char name[],PetscViewer *viewer,PetscViewerFormat *format,PetscBool *set) 75 { 76 char *value; 77 PetscErrorCode ierr; 78 PetscBool flag,hashelp; 79 80 PetscFunctionBegin; 81 PetscValidCharPointer(name,3); 82 83 if (set) *set = PETSC_FALSE; 84 #if defined(PETSC_SKIP_VIEWFROMOPTIONS) 85 PetscFunctionReturn(0); 86 #endif 87 88 ierr = PetscOptionsHasName(NULL,NULL,"-help",&hashelp);CHKERRQ(ierr); 89 if (hashelp) { 90 khint_t newitem; 91 if (!PrintedOptions) { 92 PrintedOptions = kh_init(PetscOptionsGetViewerPrinted); 93 ierr = PetscSegBufferCreate(sizeof(char),10000,&strings);CHKERRQ(ierr); 94 ierr = PetscRegisterFinalize(PetscOptionsGetViewerPrintedDestroy);CHKERRQ(ierr); 95 } 96 if (!pre) { 97 kh_put(PetscOptionsGetViewerPrinted,PrintedOptions,name+1,&newitem); 98 } else { 99 size_t l1,l2; 100 char *both; 101 102 ierr = PetscStrlen(pre,&l1);CHKERRQ(ierr); 103 ierr = PetscStrlen(name+1,&l2);CHKERRQ(ierr); 104 ierr = PetscSegBufferGet(strings,l1+l2+1,&both);CHKERRQ(ierr); 105 ierr = PetscStrcpy(both,pre);CHKERRQ(ierr); 106 ierr = PetscStrcat(both,name+1);CHKERRQ(ierr); 107 kh_put(PetscOptionsGetViewerPrinted,PrintedOptions,both,&newitem); 108 } 109 if (newitem) { 110 if (viewer) { 111 ierr = (*PetscHelpPrintf)(comm,"\n -%s%s ascii[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Prints object to stdout or ASCII file","PetscOptionsGetViewer");CHKERRQ(ierr); 112 ierr = (*PetscHelpPrintf)(comm," -%s%s binary[:[filename][:[format][:append]]]: %s (%s)\n",pre ? pre : "",name+1,"Saves object to a binary file","PetscOptionsGetViewer");CHKERRQ(ierr); 113 ierr = (*PetscHelpPrintf)(comm," -%s%s draw[:drawtype]: %s (%s)\n",pre ? pre : "",name+1,"Draws object","PetscOptionsGetViewer");CHKERRQ(ierr); 114 ierr = (*PetscHelpPrintf)(comm," -%s%s socket[:port]: %s (%s)\n",pre ? pre : "",name+1,"Pushes object to a Unix socket","PetscOptionsGetViewer");CHKERRQ(ierr); 115 ierr = (*PetscHelpPrintf)(comm," -%s%s saws[:communicatorname]: %s (%s)\n\n",pre ? pre : "",name+1,"Publishes object to SAWs","PetscOptionsGetViewer");CHKERRQ(ierr); 116 } else { 117 ierr = (*PetscHelpPrintf)(comm," -%s%s\n",pre ? pre : "",name+1);CHKERRQ(ierr); 118 } 119 } 120 } 121 122 if (format) *format = PETSC_VIEWER_DEFAULT; 123 ierr = PetscOptionsFindPair_Private(NULL,pre,name,&value,&flag);CHKERRQ(ierr); 124 if (flag) { 125 if (set) *set = PETSC_TRUE; 126 if (!value) { 127 if (viewer) { 128 ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr); 129 ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr); 130 } 131 } else { 132 char *loc0_vtype,*loc1_fname,*loc2_fmt = NULL,*loc3_fmode = NULL; 133 PetscInt cnt; 134 const char *viewers[] = {PETSCVIEWERASCII,PETSCVIEWERBINARY,PETSCVIEWERDRAW,PETSCVIEWERSOCKET,PETSCVIEWERMATLAB,PETSCVIEWERSAWS,PETSCVIEWERVTK,PETSCVIEWERHDF5,0}; 135 136 ierr = PetscStrallocpy(value,&loc0_vtype);CHKERRQ(ierr); 137 ierr = PetscStrchr(loc0_vtype,':',&loc1_fname);CHKERRQ(ierr); 138 if (loc1_fname) { 139 *loc1_fname++ = 0; 140 ierr = PetscStrchr(loc1_fname,':',&loc2_fmt);CHKERRQ(ierr); 141 } 142 if (loc2_fmt) { 143 *loc2_fmt++ = 0; 144 ierr = PetscStrchr(loc2_fmt,':',&loc3_fmode);CHKERRQ(ierr); 145 } 146 if (loc3_fmode) *loc3_fmode++ = 0; 147 ierr = PetscStrendswithwhich(*loc0_vtype ? loc0_vtype : "ascii",viewers,&cnt);CHKERRQ(ierr); 148 if (cnt > (PetscInt) sizeof(viewers)-1) SETERRQ1(comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown viewer type: %s",loc0_vtype); 149 if (viewer) { 150 if (!loc1_fname) { 151 switch (cnt) { 152 case 0: 153 ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr); 154 break; 155 case 1: 156 if (!(*viewer = PETSC_VIEWER_BINARY_(comm))) CHKERRQ(PETSC_ERR_PLIB); 157 break; 158 case 2: 159 if (!(*viewer = PETSC_VIEWER_DRAW_(comm))) CHKERRQ(PETSC_ERR_PLIB); 160 break; 161 #if defined(PETSC_USE_SOCKET_VIEWER) 162 case 3: 163 if (!(*viewer = PETSC_VIEWER_SOCKET_(comm))) CHKERRQ(PETSC_ERR_PLIB); 164 break; 165 #endif 166 #if defined(PETSC_HAVE_MATLAB_ENGINE) 167 case 4: 168 if (!(*viewer = PETSC_VIEWER_MATLAB_(comm))) CHKERRQ(PETSC_ERR_PLIB); 169 break; 170 #endif 171 #if defined(PETSC_HAVE_SAWS) 172 case 5: 173 if (!(*viewer = PETSC_VIEWER_SAWS_(comm))) CHKERRQ(PETSC_ERR_PLIB); 174 break; 175 #endif 176 #if defined(PETSC_HAVE_HDF5) 177 case 7: 178 if (!(*viewer = PETSC_VIEWER_HDF5_(comm))) CHKERRQ(PETSC_ERR_PLIB); 179 break; 180 #endif 181 default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported viewer %s",loc0_vtype); 182 } 183 ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr); 184 } else { 185 if (loc2_fmt && !*loc1_fname && (cnt == 0)) { /* ASCII format without file name */ 186 ierr = PetscViewerASCIIGetStdout(comm,viewer);CHKERRQ(ierr); 187 ierr = PetscObjectReference((PetscObject)*viewer);CHKERRQ(ierr); 188 } else { 189 PetscFileMode fmode; 190 ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr); 191 ierr = PetscViewerSetType(*viewer,*loc0_vtype ? loc0_vtype : "ascii");CHKERRQ(ierr); 192 fmode = FILE_MODE_WRITE; 193 if (loc3_fmode && *loc3_fmode) { /* Has non-empty file mode ("write" or "append") */ 194 ierr = PetscEnumFind(PetscFileModes,loc3_fmode,(PetscEnum*)&fmode,&flag);CHKERRQ(ierr); 195 if (!flag) SETERRQ1(comm,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown file mode: %s",loc3_fmode); 196 } 197 ierr = PetscViewerFileSetMode(*viewer,flag?fmode:FILE_MODE_WRITE);CHKERRQ(ierr); 198 ierr = PetscViewerFileSetName(*viewer,loc1_fname);CHKERRQ(ierr); 199 ierr = PetscViewerDrawSetDrawType(*viewer,loc1_fname);CHKERRQ(ierr); 200 } 201 } 202 } 203 if (viewer) { 204 ierr = PetscViewerSetUp(*viewer);CHKERRQ(ierr); 205 } 206 if (loc2_fmt && *loc2_fmt) { 207 ierr = PetscEnumFind(PetscViewerFormats,loc2_fmt,(PetscEnum*)format,&flag);CHKERRQ(ierr); 208 if (!flag) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unknown viewer format %s",loc2_fmt);CHKERRQ(ierr); 209 } 210 ierr = PetscFree(loc0_vtype);CHKERRQ(ierr); 211 } 212 } 213 PetscFunctionReturn(0); 214 } 215 216 #undef __FUNCT__ 217 #define __FUNCT__ "PetscViewerCreate" 218 /*@ 219 PetscViewerCreate - Creates a viewing context 220 221 Collective on MPI_Comm 222 223 Input Parameter: 224 . comm - MPI communicator 225 226 Output Parameter: 227 . inviewer - location to put the PetscViewer context 228 229 Level: advanced 230 231 Concepts: graphics^creating PetscViewer 232 Concepts: file input/output^creating PetscViewer 233 Concepts: sockets^creating PetscViewer 234 235 .seealso: PetscViewerDestroy(), PetscViewerSetType(), PetscViewerType 236 237 @*/ 238 PetscErrorCode PetscViewerCreate(MPI_Comm comm,PetscViewer *inviewer) 239 { 240 PetscViewer viewer; 241 PetscErrorCode ierr; 242 243 PetscFunctionBegin; 244 *inviewer = 0; 245 ierr = PetscViewerInitializePackage();CHKERRQ(ierr); 246 ierr = PetscHeaderCreate(viewer,PETSC_VIEWER_CLASSID,"PetscViewer","PetscViewer","Viewer",comm,PetscViewerDestroy,NULL);CHKERRQ(ierr); 247 *inviewer = viewer; 248 viewer->data = 0; 249 PetscFunctionReturn(0); 250 } 251 252 #undef __FUNCT__ 253 #define __FUNCT__ "PetscViewerSetType" 254 /*@C 255 PetscViewerSetType - Builds PetscViewer for a particular implementation. 256 257 Collective on PetscViewer 258 259 Input Parameter: 260 + viewer - the PetscViewer context 261 - type - for example, PETSCVIEWERASCII 262 263 Options Database Command: 264 . -draw_type <type> - Sets the type; use -help for a list 265 of available methods (for instance, ascii) 266 267 Level: advanced 268 269 Notes: 270 See "include/petscviewer.h" for available methods (for instance, 271 PETSCVIEWERSOCKET) 272 273 .seealso: PetscViewerCreate(), PetscViewerGetType(), PetscViewerType, PetscViewerPushFormat() 274 @*/ 275 PetscErrorCode PetscViewerSetType(PetscViewer viewer,PetscViewerType type) 276 { 277 PetscErrorCode ierr,(*r)(PetscViewer); 278 PetscBool match; 279 280 PetscFunctionBegin; 281 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 282 PetscValidCharPointer(type,2); 283 ierr = PetscObjectTypeCompare((PetscObject)viewer,type,&match);CHKERRQ(ierr); 284 if (match) PetscFunctionReturn(0); 285 286 /* cleanup any old type that may be there */ 287 if (viewer->data) { 288 ierr = (*viewer->ops->destroy)(viewer);CHKERRQ(ierr); 289 290 viewer->ops->destroy = NULL; 291 viewer->data = 0; 292 } 293 ierr = PetscMemzero(viewer->ops,sizeof(struct _PetscViewerOps));CHKERRQ(ierr); 294 295 ierr = PetscFunctionListFind(PetscViewerList,type,&r);CHKERRQ(ierr); 296 if (!r) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unknown PetscViewer type given: %s",type); 297 298 ierr = PetscObjectChangeTypeName((PetscObject)viewer,type);CHKERRQ(ierr); 299 ierr = (*r)(viewer);CHKERRQ(ierr); 300 PetscFunctionReturn(0); 301 } 302 303 #undef __FUNCT__ 304 #define __FUNCT__ "PetscViewerRegister" 305 /*@C 306 PetscViewerRegister - Adds a viewer 307 308 Not Collective 309 310 Input Parameters: 311 + name_solver - name of a new user-defined viewer 312 - routine_create - routine to create method context 313 314 Level: developer 315 Notes: 316 PetscViewerRegister() may be called multiple times to add several user-defined viewers. 317 318 Sample usage: 319 .vb 320 PetscViewerRegister("my_viewer_type",MyViewerCreate); 321 .ve 322 323 Then, your solver can be chosen with the procedural interface via 324 $ PetscViewerSetType(viewer,"my_viewer_type") 325 or at runtime via the option 326 $ -viewer_type my_viewer_type 327 328 Concepts: registering^Viewers 329 330 .seealso: PetscViewerRegisterAll(), PetscViewerRegisterDestroy() 331 @*/ 332 PetscErrorCode PetscViewerRegister(const char *sname,PetscErrorCode (*function)(PetscViewer)) 333 { 334 PetscErrorCode ierr; 335 336 PetscFunctionBegin; 337 ierr = PetscFunctionListAdd(&PetscViewerList,sname,function);CHKERRQ(ierr); 338 PetscFunctionReturn(0); 339 } 340 341 #undef __FUNCT__ 342 #define __FUNCT__ "PetscViewerSetFromOptions" 343 /*@C 344 PetscViewerSetFromOptions - Sets the graphics type from the options database. 345 Defaults to a PETSc X windows graphics. 346 347 Collective on PetscViewer 348 349 Input Parameter: 350 . PetscViewer - the graphics context 351 352 Level: intermediate 353 354 Notes: 355 Must be called after PetscViewerCreate() before the PetscViewer is used. 356 357 Concepts: PetscViewer^setting options 358 359 .seealso: PetscViewerCreate(), PetscViewerSetType(), PetscViewerType 360 361 @*/ 362 PetscErrorCode PetscViewerSetFromOptions(PetscViewer viewer) 363 { 364 PetscErrorCode ierr; 365 char vtype[256]; 366 PetscBool flg; 367 368 PetscFunctionBegin; 369 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1); 370 371 if (!PetscViewerList) { 372 ierr = PetscViewerRegisterAll();CHKERRQ(ierr); 373 } 374 ierr = PetscObjectOptionsBegin((PetscObject)viewer);CHKERRQ(ierr); 375 ierr = PetscOptionsFList("-viewer_type","Type of PetscViewer","None",PetscViewerList,(char*)(((PetscObject)viewer)->type_name ? ((PetscObject)viewer)->type_name : PETSCVIEWERASCII),vtype,256,&flg);CHKERRQ(ierr); 376 if (flg) { 377 ierr = PetscViewerSetType(viewer,vtype);CHKERRQ(ierr); 378 } 379 /* type has not been set? */ 380 if (!((PetscObject)viewer)->type_name) { 381 ierr = PetscViewerSetType(viewer,PETSCVIEWERASCII);CHKERRQ(ierr); 382 } 383 if (viewer->ops->setfromoptions) { 384 ierr = (*viewer->ops->setfromoptions)(PetscOptionsObject,viewer);CHKERRQ(ierr); 385 } 386 387 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 388 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)viewer);CHKERRQ(ierr); 389 ierr = PetscViewerViewFromOptions(viewer,NULL,"-viewer_view");CHKERRQ(ierr); 390 ierr = PetscOptionsEnd();CHKERRQ(ierr); 391 PetscFunctionReturn(0); 392 } 393 394 #undef __FUNCT__ 395 #define __FUNCT__ "PetscViewerFlowControlStart" 396 PetscErrorCode PetscViewerFlowControlStart(PetscViewer viewer,PetscInt *mcnt,PetscInt *cnt) 397 { 398 PetscErrorCode ierr; 399 PetscFunctionBegin; 400 ierr = PetscViewerBinaryGetFlowControl(viewer,mcnt);CHKERRQ(ierr); 401 ierr = PetscViewerBinaryGetFlowControl(viewer,cnt);CHKERRQ(ierr); 402 PetscFunctionReturn(0); 403 } 404 405 #undef __FUNCT__ 406 #define __FUNCT__ "PetscViewerFlowControlStepMaster" 407 PetscErrorCode PetscViewerFlowControlStepMaster(PetscViewer viewer,PetscInt i,PetscInt *mcnt,PetscInt cnt) 408 { 409 PetscErrorCode ierr; 410 MPI_Comm comm; 411 412 PetscFunctionBegin; 413 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 414 if (i >= *mcnt) { 415 *mcnt += cnt; 416 ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr); 417 } 418 PetscFunctionReturn(0); 419 } 420 421 #undef __FUNCT__ 422 #define __FUNCT__ "PetscViewerFlowControlEndMaster" 423 PetscErrorCode PetscViewerFlowControlEndMaster(PetscViewer viewer,PetscInt *mcnt) 424 { 425 PetscErrorCode ierr; 426 MPI_Comm comm; 427 PetscFunctionBegin; 428 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 429 *mcnt = 0; 430 ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr); 431 PetscFunctionReturn(0); 432 } 433 434 #undef __FUNCT__ 435 #define __FUNCT__ "PetscViewerFlowControlStepWorker" 436 PetscErrorCode PetscViewerFlowControlStepWorker(PetscViewer viewer,PetscMPIInt rank,PetscInt *mcnt) 437 { 438 PetscErrorCode ierr; 439 MPI_Comm comm; 440 PetscFunctionBegin; 441 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 442 while (PETSC_TRUE) { 443 if (rank < *mcnt) break; 444 ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr); 445 } 446 PetscFunctionReturn(0); 447 } 448 449 #undef __FUNCT__ 450 #define __FUNCT__ "PetscViewerFlowControlEndWorker" 451 PetscErrorCode PetscViewerFlowControlEndWorker(PetscViewer viewer,PetscInt *mcnt) 452 { 453 PetscErrorCode ierr; 454 MPI_Comm comm; 455 PetscFunctionBegin; 456 ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 457 while (PETSC_TRUE) { 458 ierr = MPI_Bcast(mcnt,1,MPIU_INT,0,comm);CHKERRQ(ierr); 459 if (!*mcnt) break; 460 } 461 PetscFunctionReturn(0); 462 } 463