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