1 #include <petsc/private/viewerimpl.h> /*I "petscviewer.h" I*/
2
3 typedef struct {
4 int fdes; /* file descriptor, ignored if using MPI IO */
5 #if defined(PETSC_HAVE_MPIIO)
6 PetscBool usempiio;
7 MPI_File mfdes; /* ignored unless using MPI IO */
8 MPI_File mfsub; /* subviewer support */
9 MPI_Offset moff;
10 #endif
11 char *filename; /* file name */
12 PetscFileMode filemode; /* read/write/append mode */
13 FILE *fdes_info; /* optional file containing info on binary file*/
14 PetscBool storecompressed; /* gzip the write binary file when closing it*/
15 char *ogzfilename; /* gzip can be run after the filename has been updated */
16 PetscBool skipinfo; /* Don't create info file for writing; don't use for reading */
17 PetscBool skipoptions; /* don't use PETSc options database when loading */
18 PetscInt flowcontrol; /* allow only <flowcontrol> messages outstanding at a time while doing IO */
19 PetscBool skipheader; /* don't write header, only raw data */
20 PetscBool matlabheaderwritten; /* if format is PETSC_VIEWER_BINARY_MATLAB has the MATLAB .info header been written yet */
21 PetscBool setfromoptionscalled;
22 } PetscViewer_Binary;
23
24 #if defined(PETSC_HAVE_MPIIO)
PetscViewerBinarySyncMPIIO(PetscViewer viewer)25 static PetscErrorCode PetscViewerBinarySyncMPIIO(PetscViewer viewer)
26 {
27 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
28 PetscErrorCode ierr;
29
30 PetscFunctionBegin;
31 if (vbinary->filemode == FILE_MODE_READ) PetscFunctionReturn(0);
32 if (vbinary->mfsub != MPI_FILE_NULL) {
33 ierr = MPI_File_sync(vbinary->mfsub);CHKERRQ(ierr);
34 }
35 if (vbinary->mfdes != MPI_FILE_NULL) {
36 ierr = MPI_Barrier(PetscObjectComm((PetscObject)viewer));CHKERRQ(ierr);
37 ierr = MPI_File_sync(vbinary->mfdes);CHKERRQ(ierr);
38 }
39 PetscFunctionReturn(0);
40 }
41 #endif
42
PetscViewerGetSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer * outviewer)43 static PetscErrorCode PetscViewerGetSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
44 {
45 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
46 PetscMPIInt rank;
47 PetscErrorCode ierr;
48
49 PetscFunctionBegin;
50 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
51
52 /* Return subviewer in process zero */
53 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
54 if (!rank) {
55 PetscMPIInt flg;
56
57 ierr = MPI_Comm_compare(PETSC_COMM_SELF,comm,&flg);CHKERRQ(ierr);
58 if (flg != MPI_IDENT && flg != MPI_CONGRUENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"PetscViewerGetSubViewer() for PETSCVIEWERBINARY requires a singleton MPI_Comm");
59 ierr = PetscViewerCreate(comm,outviewer);CHKERRQ(ierr);
60 ierr = PetscViewerSetType(*outviewer,PETSCVIEWERBINARY);CHKERRQ(ierr);
61 ierr = PetscMemcpy((*outviewer)->data,vbinary,sizeof(PetscViewer_Binary));CHKERRQ(ierr);
62 (*outviewer)->setupcalled = PETSC_TRUE;
63 } else {
64 *outviewer = NULL;
65 }
66
67 #if defined(PETSC_HAVE_MPIIO)
68 if (vbinary->usempiio && *outviewer) {
69 PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
70 /* Parent viewer opens a new MPI file handle on PETSC_COMM_SELF and keeps track of it for future reuse */
71 if (vbinary->mfsub == MPI_FILE_NULL) {
72 int amode;
73 switch (vbinary->filemode) {
74 case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break;
75 case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY; break;
76 case FILE_MODE_APPEND: amode = MPI_MODE_WRONLY; break;
77 default: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vbinary->filemode]);
78 }
79 ierr = MPI_File_open(PETSC_COMM_SELF,vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfsub);CHKERRQ(ierr);
80 }
81 /* Subviewer gets the MPI file handle on PETSC_COMM_SELF */
82 obinary->mfdes = vbinary->mfsub;
83 obinary->mfsub = MPI_FILE_NULL;
84 obinary->moff = vbinary->moff;
85 }
86 #endif
87
88 #if defined(PETSC_HAVE_MPIIO)
89 ierr = PetscViewerBinarySyncMPIIO(viewer);CHKERRQ(ierr);
90 #endif
91 PetscFunctionReturn(0);
92 }
93
PetscViewerRestoreSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer * outviewer)94 static PetscErrorCode PetscViewerRestoreSubViewer_Binary(PetscViewer viewer,MPI_Comm comm,PetscViewer *outviewer)
95 {
96 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
97 PetscMPIInt rank;
98 PetscErrorCode ierr;
99 #if defined(PETSC_HAVE_MPIIO)
100 MPI_Offset moff = 0;
101 #endif
102
103 PetscFunctionBegin;
104 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
105 if (rank && *outviewer) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer");
106
107 #if defined(PETSC_HAVE_MPIIO)
108 if (vbinary->usempiio && *outviewer) {
109 PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
110 if (obinary->mfdes != vbinary->mfsub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer");
111 if (obinary->mfsub != MPI_FILE_NULL) {ierr = MPI_File_close(&obinary->mfsub);CHKERRQ(ierr);}
112 moff = obinary->moff;
113 }
114 #endif
115
116 if (*outviewer) {
117 PetscViewer_Binary *obinary = (PetscViewer_Binary*)(*outviewer)->data;
118 if (obinary->fdes != vbinary->fdes) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Subviewer not obtained from viewer");
119 ierr = PetscFree((*outviewer)->data);CHKERRQ(ierr);
120 ierr = PetscHeaderDestroy(outviewer);CHKERRQ(ierr);
121 }
122
123 #if defined(PETSC_HAVE_MPIIO)
124 if (vbinary->usempiio) {
125 PetscInt64 ioff = (PetscInt64)moff; /* We could use MPI_OFFSET datatype (requires MPI 2.2) */
126 ierr = MPI_Bcast(&ioff,1,MPIU_INT64,0,PetscObjectComm((PetscObject)viewer));CHKERRQ(ierr);
127 vbinary->moff = (MPI_Offset)ioff;
128 }
129 #endif
130
131 #if defined(PETSC_HAVE_MPIIO)
132 ierr = PetscViewerBinarySyncMPIIO(viewer);CHKERRQ(ierr);
133 #endif
134 PetscFunctionReturn(0);
135 }
136
137 #if defined(PETSC_HAVE_MPIIO)
138 /*@C
139 PetscViewerBinaryGetMPIIOOffset - Gets the current global offset that should be passed to MPI_File_set_view() or MPI_File_{write|read}_at[_all]()
140
141 Not Collective
142
143 Input Parameter:
144 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
145
146 Output Parameter:
147 . off - the current global offset
148
149 Level: advanced
150
151 Fortran Note:
152 This routine is not supported in Fortran.
153
154 Use PetscViewerBinaryAddMPIIOOffset() to increase this value after you have written a view.
155
156
157 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryAddMPIIOOffset()
158 @*/
PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset * off)159 PetscErrorCode PetscViewerBinaryGetMPIIOOffset(PetscViewer viewer,MPI_Offset *off)
160 {
161 PetscViewer_Binary *vbinary;
162
163 PetscFunctionBegin;
164 PetscValidHeaderSpecificType(viewer,PETSC_VIEWER_CLASSID,1,PETSCVIEWERBINARY);
165 PetscValidPointer(off,2);
166 vbinary = (PetscViewer_Binary*)viewer->data;
167 *off = vbinary->moff;
168 PetscFunctionReturn(0);
169 }
170
171 /*@C
172 PetscViewerBinaryAddMPIIOOffset - Adds to the current global offset
173
174 Logically Collective
175
176 Input Parameters:
177 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
178 - off - the addition to the global offset
179
180 Level: advanced
181
182 Fortran Note:
183 This routine is not supported in Fortran.
184
185 Use PetscViewerBinaryGetMPIIOOffset() to get the value that you should pass to MPI_File_set_view() or MPI_File_{write|read}_at[_all]()
186
187
188 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
189 @*/
PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)190 PetscErrorCode PetscViewerBinaryAddMPIIOOffset(PetscViewer viewer,MPI_Offset off)
191 {
192 PetscViewer_Binary *vbinary;
193
194 PetscFunctionBegin;
195 PetscValidHeaderSpecificType(viewer,PETSC_VIEWER_CLASSID,1,PETSCVIEWERBINARY);
196 PetscValidLogicalCollectiveInt(viewer,(PetscInt)off,2);
197 vbinary = (PetscViewer_Binary*)viewer->data;
198 vbinary->moff += off;
199 PetscFunctionReturn(0);
200 }
201
202 /*@C
203 PetscViewerBinaryGetMPIIODescriptor - Extracts the MPI IO file descriptor from a PetscViewer.
204
205 Not Collective
206
207 Input Parameter:
208 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
209
210 Output Parameter:
211 . fdes - file descriptor
212
213 Level: advanced
214
215 Fortran Note:
216 This routine is not supported in Fortran.
217
218
219 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
220 @*/
PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File * fdes)221 PetscErrorCode PetscViewerBinaryGetMPIIODescriptor(PetscViewer viewer,MPI_File *fdes)
222 {
223 PetscErrorCode ierr;
224 PetscViewer_Binary *vbinary;
225
226 PetscFunctionBegin;
227 PetscValidHeaderSpecificType(viewer,PETSC_VIEWER_CLASSID,1,PETSCVIEWERBINARY);
228 PetscValidPointer(fdes,2);
229 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
230 vbinary = (PetscViewer_Binary*)viewer->data;
231 *fdes = vbinary->mfdes;
232 PetscFunctionReturn(0);
233 }
234 #endif
235
236 /*@
237 PetscViewerBinarySetUseMPIIO - Sets a binary viewer to use MPI-IO for reading/writing. Must be called
238 before PetscViewerFileSetName()
239
240 Logically Collective on PetscViewer
241
242 Input Parameters:
243 + viewer - the PetscViewer; must be a binary
244 - use - PETSC_TRUE means MPI-IO will be used
245
246 Options Database:
247 -viewer_binary_mpiio : Flag for using MPI-IO
248
249 Level: advanced
250
251 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen(),
252 PetscViewerBinaryGetUseMPIIO()
253
254 @*/
PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool use)255 PetscErrorCode PetscViewerBinarySetUseMPIIO(PetscViewer viewer,PetscBool use)
256 {
257 PetscErrorCode ierr;
258
259 PetscFunctionBegin;
260 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
261 PetscValidLogicalCollectiveBool(viewer,use,2);
262 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetUseMPIIO_C",(PetscViewer,PetscBool),(viewer,use));CHKERRQ(ierr);
263 PetscFunctionReturn(0);
264 }
265
266 #if defined(PETSC_HAVE_MPIIO)
PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool use)267 static PetscErrorCode PetscViewerBinarySetUseMPIIO_Binary(PetscViewer viewer,PetscBool use)
268 {
269 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
270 PetscFunctionBegin;
271 if (viewer->setupcalled && vbinary->usempiio != use) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER,"Cannot change MPIIO to %s after setup",PetscBools[use]);
272 vbinary->usempiio = use;
273 PetscFunctionReturn(0);
274 }
275 #endif
276
277 /*@
278 PetscViewerBinaryGetUseMPIIO - Returns PETSC_TRUE if the binary viewer uses MPI-IO.
279
280 Not Collective
281
282 Input Parameter:
283 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
284
285 Output Parameter:
286 - use - PETSC_TRUE if MPI-IO is being used
287
288 Options Database:
289 -viewer_binary_mpiio : Flag for using MPI-IO
290
291 Level: advanced
292
293 Note:
294 If MPI-IO is not available, this function will always return PETSC_FALSE
295
296 Fortran Note:
297 This routine is not supported in Fortran.
298
299
300 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
301 @*/
PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool * use)302 PetscErrorCode PetscViewerBinaryGetUseMPIIO(PetscViewer viewer,PetscBool *use)
303 {
304 PetscErrorCode ierr;
305
306 PetscFunctionBegin;
307 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
308 PetscValidBoolPointer(use,2);
309 *use = PETSC_FALSE;
310 ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetUseMPIIO_C",(PetscViewer,PetscBool*),(viewer,use));CHKERRQ(ierr);
311 PetscFunctionReturn(0);
312 }
313
314 #if defined(PETSC_HAVE_MPIIO)
PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool * use)315 static PetscErrorCode PetscViewerBinaryGetUseMPIIO_Binary(PetscViewer viewer,PetscBool *use)
316 {
317 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
318
319 PetscFunctionBegin;
320 *use = vbinary->usempiio;
321 PetscFunctionReturn(0);
322 }
323 #endif
324
325 /*@
326 PetscViewerBinarySetFlowControl - Sets how many messages are allowed to outstanding at the same time during parallel IO reads/writes
327
328 Not Collective
329
330 Input Parameter:
331 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
332 - fc - the number of messages, defaults to 256 if this function was not called
333
334 Level: advanced
335
336 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinaryGetFlowControl()
337
338 @*/
PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)339 PetscErrorCode PetscViewerBinarySetFlowControl(PetscViewer viewer,PetscInt fc)
340 {
341 PetscErrorCode ierr;
342
343 PetscFunctionBegin;
344 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
345 PetscValidLogicalCollectiveInt(viewer,fc,2);
346 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetFlowControl_C",(PetscViewer,PetscInt),(viewer,fc));CHKERRQ(ierr);
347 PetscFunctionReturn(0);
348 }
349
PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)350 static PetscErrorCode PetscViewerBinarySetFlowControl_Binary(PetscViewer viewer,PetscInt fc)
351 {
352 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
353
354 PetscFunctionBegin;
355 if (fc <= 1) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ARG_OUTOFRANGE,"Flow control count must be greater than 1, %D was set",fc);
356 vbinary->flowcontrol = fc;
357 PetscFunctionReturn(0);
358 }
359
360 /*@
361 PetscViewerBinaryGetFlowControl - Returns how many messages are allowed to outstanding at the same time during parallel IO reads/writes
362
363 Not Collective
364
365 Input Parameter:
366 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
367
368 Output Parameter:
369 . fc - the number of messages
370
371 Level: advanced
372
373 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer(), PetscViewerBinarySetFlowControl()
374
375 @*/
PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt * fc)376 PetscErrorCode PetscViewerBinaryGetFlowControl(PetscViewer viewer,PetscInt *fc)
377 {
378 PetscErrorCode ierr;
379
380 PetscFunctionBegin;
381 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
382 PetscValidIntPointer(fc,2);
383 ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetFlowControl_C",(PetscViewer,PetscInt*),(viewer,fc));CHKERRQ(ierr);
384 PetscFunctionReturn(0);
385 }
386
PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt * fc)387 static PetscErrorCode PetscViewerBinaryGetFlowControl_Binary(PetscViewer viewer,PetscInt *fc)
388 {
389 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
390
391 PetscFunctionBegin;
392 *fc = vbinary->flowcontrol;
393 PetscFunctionReturn(0);
394 }
395
396 /*@C
397 PetscViewerBinaryGetDescriptor - Extracts the file descriptor from a PetscViewer.
398
399 Collective On PetscViewer
400
401 Input Parameter:
402 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
403
404 Output Parameter:
405 . fdes - file descriptor
406
407 Level: advanced
408
409 Notes:
410 For writable binary PetscViewers, the descriptor will only be valid for the
411 first processor in the communicator that shares the PetscViewer. For readable
412 files it will only be valid on nodes that have the file. If node 0 does not
413 have the file it generates an error even if another node does have the file.
414
415 Fortran Note:
416 This routine is not supported in Fortran.
417
418 Developer Notes:
419 This must be called on all processes because Dave May changed
420 the source code that this may be trigger a PetscViewerSetUp() call if it was not previously triggered.
421
422
423
424 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetInfoPointer()
425 @*/
PetscViewerBinaryGetDescriptor(PetscViewer viewer,int * fdes)426 PetscErrorCode PetscViewerBinaryGetDescriptor(PetscViewer viewer,int *fdes)
427 {
428 PetscErrorCode ierr;
429 PetscViewer_Binary *vbinary;
430
431 PetscFunctionBegin;
432 PetscValidHeaderSpecificType(viewer,PETSC_VIEWER_CLASSID,1,PETSCVIEWERBINARY);
433 PetscValidPointer(fdes,2);
434 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
435 vbinary = (PetscViewer_Binary*)viewer->data;
436 *fdes = vbinary->fdes;
437 PetscFunctionReturn(0);
438 }
439
440 /*@
441 PetscViewerBinarySkipInfo - Binary file will not have .info file created with it
442
443 Not Collective
444
445 Input Parameter:
446 . viewer - PetscViewer context, obtained from PetscViewerCreate()
447
448 Options Database Key:
449 . -viewer_binary_skip_info
450
451 Level: advanced
452
453 Notes:
454 This must be called after PetscViewerSetType(). If you use PetscViewerBinaryOpen() then
455 you can only skip the info file with the -viewer_binary_skip_info flag. To use the function you must open the
456 viewer with PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinarySkipInfo().
457
458 The .info contains meta information about the data in the binary file, for example the block size if it was
459 set for a vector or matrix.
460
461 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
462 PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
463 @*/
PetscViewerBinarySkipInfo(PetscViewer viewer)464 PetscErrorCode PetscViewerBinarySkipInfo(PetscViewer viewer)
465 {
466 PetscErrorCode ierr;
467
468 PetscFunctionBegin;
469 ierr = PetscViewerBinarySetSkipInfo(viewer,PETSC_TRUE);CHKERRQ(ierr);
470 PetscFunctionReturn(0);
471 }
472
473 /*@
474 PetscViewerBinarySetSkipInfo - Binary file will not have .info file created with it
475
476 Not Collective
477
478 Input Parameter:
479 + viewer - PetscViewer context, obtained from PetscViewerCreate()
480 - skip - PETSC_TRUE implies the .info file will not be generated
481
482 Options Database Key:
483 . -viewer_binary_skip_info
484
485 Level: advanced
486
487 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySetSkipOptions(),
488 PetscViewerBinaryGetSkipOptions(), PetscViewerBinaryGetSkipInfo()
489 @*/
PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)490 PetscErrorCode PetscViewerBinarySetSkipInfo(PetscViewer viewer,PetscBool skip)
491 {
492 PetscErrorCode ierr;
493
494 PetscFunctionBegin;
495 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
496 PetscValidLogicalCollectiveBool(viewer,skip,2);
497 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetSkipInfo_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr);
498 PetscFunctionReturn(0);
499 }
500
PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)501 static PetscErrorCode PetscViewerBinarySetSkipInfo_Binary(PetscViewer viewer,PetscBool skip)
502 {
503 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
504
505 PetscFunctionBegin;
506 vbinary->skipinfo = skip;
507 PetscFunctionReturn(0);
508 }
509
510 /*@
511 PetscViewerBinaryGetSkipInfo - check if viewer wrote a .info file
512
513 Not Collective
514
515 Input Parameter:
516 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
517
518 Output Parameter:
519 . skip - PETSC_TRUE implies the .info file was not generated
520
521 Level: advanced
522
523 Notes:
524 This must be called after PetscViewerSetType()
525
526 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
527 PetscViewerBinarySetSkipOptions(), PetscViewerBinarySetSkipInfo()
528 @*/
PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool * skip)529 PetscErrorCode PetscViewerBinaryGetSkipInfo(PetscViewer viewer,PetscBool *skip)
530 {
531 PetscErrorCode ierr;
532
533 PetscFunctionBegin;
534 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
535 PetscValidBoolPointer(skip,2);
536 ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetSkipInfo_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr);
537 PetscFunctionReturn(0);
538 }
539
PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool * skip)540 static PetscErrorCode PetscViewerBinaryGetSkipInfo_Binary(PetscViewer viewer,PetscBool *skip)
541 {
542 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
543
544 PetscFunctionBegin;
545 *skip = vbinary->skipinfo;
546 PetscFunctionReturn(0);
547 }
548
549 /*@
550 PetscViewerBinarySetSkipOptions - do not use the PETSc options database when loading objects
551
552 Not Collective
553
554 Input Parameters:
555 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
556 - skip - PETSC_TRUE means do not use
557
558 Options Database Key:
559 . -viewer_binary_skip_options
560
561 Level: advanced
562
563 Notes:
564 This must be called after PetscViewerSetType()
565
566 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
567 PetscViewerBinaryGetSkipOptions()
568 @*/
PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)569 PetscErrorCode PetscViewerBinarySetSkipOptions(PetscViewer viewer,PetscBool skip)
570 {
571 PetscErrorCode ierr;
572
573 PetscFunctionBegin;
574 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
575 PetscValidLogicalCollectiveBool(viewer,skip,2);
576 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetSkipOptions_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr);
577 PetscFunctionReturn(0);
578 }
579
PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip)580 static PetscErrorCode PetscViewerBinarySetSkipOptions_Binary(PetscViewer viewer,PetscBool skip)
581 {
582 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
583
584 PetscFunctionBegin;
585 vbinary->skipoptions = skip;
586 PetscFunctionReturn(0);
587 }
588
589 /*@
590 PetscViewerBinaryGetSkipOptions - checks if viewer uses the PETSc options database when loading objects
591
592 Not Collective
593
594 Input Parameter:
595 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
596
597 Output Parameter:
598 . skip - PETSC_TRUE means do not use
599
600 Level: advanced
601
602 Notes:
603 This must be called after PetscViewerSetType()
604
605 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
606 PetscViewerBinarySetSkipOptions()
607 @*/
PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool * skip)608 PetscErrorCode PetscViewerBinaryGetSkipOptions(PetscViewer viewer,PetscBool *skip)
609 {
610 PetscErrorCode ierr;
611
612 PetscFunctionBegin;
613 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
614 PetscValidBoolPointer(skip,2);
615 ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetSkipOptions_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr);
616 PetscFunctionReturn(0);
617 }
618
PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool * skip)619 static PetscErrorCode PetscViewerBinaryGetSkipOptions_Binary(PetscViewer viewer,PetscBool *skip)
620 {
621 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
622
623 PetscFunctionBegin;
624 *skip = vbinary->skipoptions;
625 PetscFunctionReturn(0);
626 }
627
628 /*@
629 PetscViewerBinarySetSkipHeader - do not write a header with size information on output, just raw data
630
631 Not Collective
632
633 Input Parameters:
634 + viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
635 - skip - PETSC_TRUE means do not write header
636
637 Options Database Key:
638 . -viewer_binary_skip_header
639
640 Level: advanced
641
642 Notes:
643 This must be called after PetscViewerSetType()
644
645 Can ONLY be called on a binary viewer
646
647 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
648 PetscViewerBinaryGetSkipHeader()
649 @*/
PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)650 PetscErrorCode PetscViewerBinarySetSkipHeader(PetscViewer viewer,PetscBool skip)
651 {
652 PetscErrorCode ierr;
653
654 PetscFunctionBegin;
655 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
656 PetscValidLogicalCollectiveBool(viewer,skip,2);
657 ierr = PetscTryMethod(viewer,"PetscViewerBinarySetSkipHeader_C",(PetscViewer,PetscBool),(viewer,skip));CHKERRQ(ierr);
658 PetscFunctionReturn(0);
659 }
660
PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)661 static PetscErrorCode PetscViewerBinarySetSkipHeader_Binary(PetscViewer viewer,PetscBool skip)
662 {
663 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
664
665 PetscFunctionBegin;
666 vbinary->skipheader = skip;
667 PetscFunctionReturn(0);
668 }
669
670 /*@
671 PetscViewerBinaryGetSkipHeader - checks whether to write a header with size information on output, or just raw data
672
673 Not Collective
674
675 Input Parameter:
676 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
677
678 Output Parameter:
679 . skip - PETSC_TRUE means do not write header
680
681 Level: advanced
682
683 Notes:
684 This must be called after PetscViewerSetType()
685
686 Returns false for PETSCSOCKETVIEWER, you cannot skip the header for it.
687
688 .seealso: PetscViewerBinaryOpen(), PetscViewerBinaryGetDescriptor(), PetscViewerBinarySkipInfo(),
689 PetscViewerBinarySetSkipHeader()
690 @*/
PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool * skip)691 PetscErrorCode PetscViewerBinaryGetSkipHeader(PetscViewer viewer,PetscBool *skip)
692 {
693 PetscErrorCode ierr;
694
695 PetscFunctionBegin;
696 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
697 PetscValidBoolPointer(skip,2);
698 ierr = PetscUseMethod(viewer,"PetscViewerBinaryGetSkipHeader_C",(PetscViewer,PetscBool*),(viewer,skip));CHKERRQ(ierr);
699 PetscFunctionReturn(0);
700 }
701
PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool * skip)702 static PetscErrorCode PetscViewerBinaryGetSkipHeader_Binary(PetscViewer viewer,PetscBool *skip)
703 {
704 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
705
706 PetscFunctionBegin;
707 *skip = vbinary->skipheader;
708 PetscFunctionReturn(0);
709 }
710
711 /*@C
712 PetscViewerBinaryGetInfoPointer - Extracts the file pointer for the ASCII
713 info file associated with a binary file.
714
715 Not Collective
716
717 Input Parameter:
718 . viewer - PetscViewer context, obtained from PetscViewerBinaryOpen()
719
720 Output Parameter:
721 . file - file pointer Always returns NULL if not a binary viewer
722
723 Level: advanced
724
725 Notes:
726 For writable binary PetscViewers, the descriptor will only be valid for the
727 first processor in the communicator that shares the PetscViewer.
728
729 Fortran Note:
730 This routine is not supported in Fortran.
731
732 .seealso: PetscViewerBinaryOpen(),PetscViewerBinaryGetDescriptor()
733 @*/
PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE ** file)734 PetscErrorCode PetscViewerBinaryGetInfoPointer(PetscViewer viewer,FILE **file)
735 {
736 PetscErrorCode ierr;
737
738 PetscFunctionBegin;
739 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
740 PetscValidPointer(file,2);
741 *file = NULL;
742 ierr = PetscTryMethod(viewer,"PetscViewerBinaryGetInfoPointer_C",(PetscViewer,FILE **),(viewer,file));CHKERRQ(ierr);
743 PetscFunctionReturn(0);
744 }
745
PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE ** file)746 static PetscErrorCode PetscViewerBinaryGetInfoPointer_Binary(PetscViewer viewer,FILE **file)
747 {
748 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
749 PetscErrorCode ierr;
750
751 PetscFunctionBegin;
752 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
753 *file = vbinary->fdes_info;
754 if (viewer->format == PETSC_VIEWER_BINARY_MATLAB && !vbinary->matlabheaderwritten) {
755 if (vbinary->fdes_info) {
756 FILE *info = vbinary->fdes_info;
757 ierr = PetscFPrintf(PETSC_COMM_SELF,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr);
758 ierr = PetscFPrintf(PETSC_COMM_SELF,info,"#$$ Set.filename = '%s';\n",vbinary->filename);CHKERRQ(ierr);
759 ierr = PetscFPrintf(PETSC_COMM_SELF,info,"#$$ fd = PetscOpenFile(Set.filename);\n");CHKERRQ(ierr);
760 ierr = PetscFPrintf(PETSC_COMM_SELF,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr);
761 }
762 vbinary->matlabheaderwritten = PETSC_TRUE;
763 }
764 PetscFunctionReturn(0);
765 }
766
767
768 #if defined(PETSC_HAVE_MPIIO)
PetscViewerFileClose_BinaryMPIIO(PetscViewer v)769 static PetscErrorCode PetscViewerFileClose_BinaryMPIIO(PetscViewer v)
770 {
771 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
772 PetscErrorCode ierr;
773
774 PetscFunctionBegin;
775 if (vbinary->mfdes != MPI_FILE_NULL) {
776 ierr = MPI_File_close(&vbinary->mfdes);CHKERRQ(ierr);
777 }
778 if (vbinary->mfsub != MPI_FILE_NULL) {
779 ierr = MPI_File_close(&vbinary->mfsub);CHKERRQ(ierr);
780 }
781 vbinary->moff = 0;
782 PetscFunctionReturn(0);
783 }
784 #endif
785
PetscViewerFileClose_BinarySTDIO(PetscViewer v)786 static PetscErrorCode PetscViewerFileClose_BinarySTDIO(PetscViewer v)
787 {
788 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
789 PetscErrorCode ierr;
790
791 PetscFunctionBegin;
792 if (vbinary->fdes != -1) {
793 ierr = PetscBinaryClose(vbinary->fdes);CHKERRQ(ierr);
794 vbinary->fdes = -1;
795 if (vbinary->storecompressed) {
796 char cmd[8+PETSC_MAX_PATH_LEN],out[64+PETSC_MAX_PATH_LEN] = "";
797 const char *gzfilename = vbinary->ogzfilename ? vbinary->ogzfilename : vbinary->filename;
798 /* compress the file */
799 ierr = PetscStrncpy(cmd,"gzip -f ",sizeof(cmd));CHKERRQ(ierr);
800 ierr = PetscStrlcat(cmd,gzfilename,sizeof(cmd));CHKERRQ(ierr);
801 #if defined(PETSC_HAVE_POPEN)
802 {
803 FILE *fp;
804 ierr = PetscPOpen(PETSC_COMM_SELF,NULL,cmd,"r",&fp);CHKERRQ(ierr);
805 if (fgets(out,(int)(sizeof(out)-1),fp)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error from command %s\n%s",cmd,out);
806 ierr = PetscPClose(PETSC_COMM_SELF,fp);CHKERRQ(ierr);
807 }
808 #endif
809 }
810 }
811 ierr = PetscFree(vbinary->ogzfilename);CHKERRQ(ierr);
812 PetscFunctionReturn(0);
813 }
814
PetscViewerFileClose_BinaryInfo(PetscViewer v)815 static PetscErrorCode PetscViewerFileClose_BinaryInfo(PetscViewer v)
816 {
817 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
818 PetscErrorCode ierr;
819
820 PetscFunctionBegin;
821 if (v->format == PETSC_VIEWER_BINARY_MATLAB && vbinary->matlabheaderwritten) {
822 if (vbinary->fdes_info) {
823 FILE *info = vbinary->fdes_info;
824 ierr = PetscFPrintf(PETSC_COMM_SELF,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr);
825 ierr = PetscFPrintf(PETSC_COMM_SELF,info,"#$$ close(fd);\n");CHKERRQ(ierr);
826 ierr = PetscFPrintf(PETSC_COMM_SELF,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr);
827 }
828 }
829 if (vbinary->fdes_info) {
830 FILE *info = vbinary->fdes_info;
831 vbinary->fdes_info = NULL;
832 if (fclose(info)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fclose() failed on file");
833 }
834 PetscFunctionReturn(0);
835 }
836
PetscViewerFileClose_Binary(PetscViewer v)837 static PetscErrorCode PetscViewerFileClose_Binary(PetscViewer v)
838 {
839 PetscErrorCode ierr;
840
841 PetscFunctionBegin;
842 #if defined(PETSC_HAVE_MPIIO)
843 ierr = PetscViewerFileClose_BinaryMPIIO(v);CHKERRQ(ierr);
844 #endif
845 ierr = PetscViewerFileClose_BinarySTDIO(v);CHKERRQ(ierr);
846 ierr = PetscViewerFileClose_BinaryInfo(v);CHKERRQ(ierr);
847 PetscFunctionReturn(0);
848 }
849
PetscViewerDestroy_Binary(PetscViewer v)850 static PetscErrorCode PetscViewerDestroy_Binary(PetscViewer v)
851 {
852 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
853 PetscErrorCode ierr;
854
855 PetscFunctionBegin;
856 ierr = PetscViewerFileClose_Binary(v);CHKERRQ(ierr);
857 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr);
858 ierr = PetscFree(vbinary);CHKERRQ(ierr);
859
860 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",NULL);CHKERRQ(ierr);
861 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",NULL);CHKERRQ(ierr);
862 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",NULL);CHKERRQ(ierr);
863 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",NULL);CHKERRQ(ierr);
864 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",NULL);CHKERRQ(ierr);
865 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",NULL);CHKERRQ(ierr);
866 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",NULL);CHKERRQ(ierr);
867 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",NULL);CHKERRQ(ierr);
868 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",NULL);CHKERRQ(ierr);
869 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",NULL);CHKERRQ(ierr);
870 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",NULL);CHKERRQ(ierr);
871 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",NULL);CHKERRQ(ierr);
872 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",NULL);CHKERRQ(ierr);
873 #if defined(PETSC_HAVE_MPIIO)
874 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",NULL);CHKERRQ(ierr);
875 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",NULL);CHKERRQ(ierr);
876 #endif
877 PetscFunctionReturn(0);
878 }
879
880 /*@C
881 PetscViewerBinaryOpen - Opens a file for binary input/output.
882
883 Collective
884
885 Input Parameters:
886 + comm - MPI communicator
887 . name - name of file
888 - mode - open mode of file
889 $ FILE_MODE_WRITE - create new file for binary output
890 $ FILE_MODE_READ - open existing file for binary input
891 $ FILE_MODE_APPEND - open existing file for binary output
892
893 Output Parameter:
894 . viewer - PetscViewer for binary input/output to use with the specified file
895
896 Options Database Keys:
897 + -viewer_binary_filename <name> -
898 . -viewer_binary_skip_info -
899 . -viewer_binary_skip_options -
900 . -viewer_binary_skip_header -
901 - -viewer_binary_mpiio -
902
903 Level: beginner
904
905 Note:
906 This PetscViewer should be destroyed with PetscViewerDestroy().
907
908 For reading files, the filename may begin with ftp:// or http:// and/or
909 end with .gz; in this case file is brought over and uncompressed.
910
911 For creating files, if the file name ends with .gz it is automatically
912 compressed when closed.
913
914 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
915 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
916 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead(), PetscViewerBinarySetUseMPIIO(),
917 PetscViewerBinaryGetUseMPIIO(), PetscViewerBinaryGetMPIIOOffset()
918 @*/
PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode mode,PetscViewer * viewer)919 PetscErrorCode PetscViewerBinaryOpen(MPI_Comm comm,const char name[],PetscFileMode mode,PetscViewer *viewer)
920 {
921 PetscErrorCode ierr;
922
923 PetscFunctionBegin;
924 ierr = PetscViewerCreate(comm,viewer);CHKERRQ(ierr);
925 ierr = PetscViewerSetType(*viewer,PETSCVIEWERBINARY);CHKERRQ(ierr);
926 ierr = PetscViewerFileSetMode(*viewer,mode);CHKERRQ(ierr);
927 ierr = PetscViewerFileSetName(*viewer,name);CHKERRQ(ierr);
928 ierr = PetscViewerSetFromOptions(*viewer);CHKERRQ(ierr);
929 PetscFunctionReturn(0);
930 }
931
932 #if defined(PETSC_HAVE_MPIIO)
PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void * data,PetscInt num,PetscInt * count,PetscDataType dtype,PetscBool write)933 static PetscErrorCode PetscViewerBinaryWriteReadMPIIO(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype,PetscBool write)
934 {
935 MPI_Comm comm = PetscObjectComm((PetscObject)viewer);
936 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
937 MPI_File mfdes = vbinary->mfdes;
938 PetscErrorCode ierr;
939 MPI_Datatype mdtype;
940 PetscMPIInt rank,cnt;
941 MPI_Status status;
942 MPI_Aint ul,dsize;
943
944 PetscFunctionBegin;
945 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
946 ierr = PetscMPIIntCast(num,&cnt);CHKERRQ(ierr);
947 ierr = PetscDataTypeToMPIDataType(dtype,&mdtype);CHKERRQ(ierr);
948 if (write) {
949 if (!rank) {
950 ierr = MPIU_File_write_at(mfdes,vbinary->moff,data,cnt,mdtype,&status);CHKERRQ(ierr);
951 }
952 } else {
953 if (!rank) {
954 ierr = MPIU_File_read_at(mfdes,vbinary->moff,data,cnt,mdtype,&status);CHKERRQ(ierr);
955 if (cnt > 0) {ierr = MPI_Get_count(&status,mdtype,&cnt);CHKERRQ(ierr);}
956 }
957 ierr = MPI_Bcast(&cnt,1,MPI_INT,0,comm);CHKERRQ(ierr);
958 ierr = MPI_Bcast(data,cnt,mdtype,0,comm);CHKERRQ(ierr);
959 }
960 ierr = MPI_Type_get_extent(mdtype,&ul,&dsize);CHKERRQ(ierr);
961 vbinary->moff += dsize*cnt;
962 if (count) *count = cnt;
963 PetscFunctionReturn(0);
964 }
965 #endif
966
967 /*@C
968 PetscViewerBinaryRead - Reads from a binary file, all processors get the same result
969
970 Collective
971
972 Input Parameters:
973 + viewer - the binary viewer
974 . data - location of the data to be written
975 . num - number of items of data to read
976 - dtype - type of data to read
977
978 Output Parameters:
979 . count - number of items of data actually read, or NULL.
980
981 Level: beginner
982
983 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
984 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
985 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
986 @*/
PetscViewerBinaryRead(PetscViewer viewer,void * data,PetscInt num,PetscInt * count,PetscDataType dtype)987 PetscErrorCode PetscViewerBinaryRead(PetscViewer viewer,void *data,PetscInt num,PetscInt *count,PetscDataType dtype)
988 {
989 PetscErrorCode ierr;
990 PetscViewer_Binary *vbinary;
991
992 PetscFunctionBegin;
993 PetscValidHeaderSpecificType(viewer,PETSC_VIEWER_CLASSID,1,PETSCVIEWERBINARY);
994 PetscValidLogicalCollectiveInt(viewer,num,3);
995 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
996 vbinary = (PetscViewer_Binary*)viewer->data;
997 #if defined(PETSC_HAVE_MPIIO)
998 if (vbinary->usempiio) {
999 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,data,num,count,dtype,PETSC_FALSE);CHKERRQ(ierr);
1000 } else {
1001 #endif
1002 ierr = PetscBinarySynchronizedRead(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,num,count,dtype);CHKERRQ(ierr);
1003 #if defined(PETSC_HAVE_MPIIO)
1004 }
1005 #endif
1006 PetscFunctionReturn(0);
1007 }
1008
1009 /*@C
1010 PetscViewerBinaryWrite - writes to a binary file, only from the first process
1011
1012 Collective
1013
1014 Input Parameters:
1015 + viewer - the binary viewer
1016 . data - location of data
1017 . count - number of items of data to write
1018 - dtype - type of data to write
1019
1020 Level: beginner
1021
1022 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1023 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(), PetscDataType
1024 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1025 @*/
PetscViewerBinaryWrite(PetscViewer viewer,const void * data,PetscInt count,PetscDataType dtype)1026 PetscErrorCode PetscViewerBinaryWrite(PetscViewer viewer,const void *data,PetscInt count,PetscDataType dtype)
1027 {
1028 PetscErrorCode ierr;
1029 PetscViewer_Binary *vbinary;
1030
1031 PetscFunctionBegin;
1032 PetscValidHeaderSpecificType(viewer,PETSC_VIEWER_CLASSID,1,PETSCVIEWERBINARY);
1033 PetscValidLogicalCollectiveInt(viewer,count,3);
1034 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1035 vbinary = (PetscViewer_Binary*)viewer->data;
1036 #if defined(PETSC_HAVE_MPIIO)
1037 if (vbinary->usempiio) {
1038 ierr = PetscViewerBinaryWriteReadMPIIO(viewer,(void*)data,count,NULL,dtype,PETSC_TRUE);CHKERRQ(ierr);
1039 } else {
1040 #endif
1041 ierr = PetscBinarySynchronizedWrite(PetscObjectComm((PetscObject)viewer),vbinary->fdes,data,count,dtype);CHKERRQ(ierr);
1042 #if defined(PETSC_HAVE_MPIIO)
1043 }
1044 #endif
1045 PetscFunctionReturn(0);
1046 }
1047
PetscViewerBinaryWriteReadAll(PetscViewer viewer,PetscBool write,void * data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)1048 static PetscErrorCode PetscViewerBinaryWriteReadAll(PetscViewer viewer,PetscBool write,void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1049 {
1050 MPI_Comm comm = PetscObjectComm((PetscObject)viewer);
1051 PetscMPIInt size,rank;
1052 MPI_Datatype mdtype;
1053 MPI_Aint lb,dsize;
1054 PetscBool useMPIIO;
1055 PetscErrorCode ierr;
1056
1057 PetscFunctionBegin;
1058 PetscValidHeaderSpecificType(viewer,PETSC_VIEWER_CLASSID,1,PETSCVIEWERBINARY);
1059 PetscValidLogicalCollectiveBool(viewer,((start>=0)||(start==PETSC_DETERMINE)),4);
1060 PetscValidLogicalCollectiveBool(viewer,((total>=0)||(total==PETSC_DETERMINE)),5);
1061 PetscValidLogicalCollectiveInt(viewer,total,5);
1062 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1063
1064 ierr = PetscDataTypeToMPIDataType(dtype,&mdtype);CHKERRQ(ierr);
1065 ierr = MPI_Type_get_extent(mdtype,&lb,&dsize);CHKERRQ(ierr);
1066 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
1067 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1068
1069 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&useMPIIO);CHKERRQ(ierr);
1070 #if defined(PETSC_HAVE_MPIIO)
1071 if (useMPIIO) {
1072 MPI_File mfdes;
1073 MPI_Offset off;
1074 PetscMPIInt cnt;
1075
1076 if (start == PETSC_DETERMINE) {
1077 ierr = MPI_Scan(&count,&start,1,MPIU_INT,MPI_SUM,comm);CHKERRQ(ierr);
1078 start -= count;
1079 }
1080 if (total == PETSC_DETERMINE) {
1081 total = start + count;
1082 ierr = MPI_Bcast(&total,1,MPIU_INT,size-1,comm);CHKERRQ(ierr);
1083 }
1084 ierr = PetscMPIIntCast(count,&cnt);CHKERRQ(ierr);
1085 ierr = PetscViewerBinaryGetMPIIODescriptor(viewer,&mfdes);CHKERRQ(ierr);
1086 ierr = PetscViewerBinaryGetMPIIOOffset(viewer,&off);CHKERRQ(ierr);
1087 off += (MPI_Offset)(start*dsize);
1088 if (write) {
1089 ierr = MPIU_File_write_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);CHKERRQ(ierr);
1090 } else {
1091 ierr = MPIU_File_read_at_all(mfdes,off,data,cnt,mdtype,MPI_STATUS_IGNORE);CHKERRQ(ierr);
1092 }
1093 off = (MPI_Offset)(total*dsize);
1094 ierr = PetscViewerBinaryAddMPIIOOffset(viewer,off);CHKERRQ(ierr);
1095 PetscFunctionReturn(0);
1096 }
1097 #endif
1098 {
1099 int fdes;
1100 char *workbuf = NULL;
1101 PetscInt maxcount=0,message_count,flowcontrolcount;
1102 PetscMPIInt tag,cnt,maxcnt,scnt=0,rcnt=0,j;
1103 MPI_Status status;
1104
1105 ierr = PetscCommGetNewTag(comm,&tag);CHKERRQ(ierr);
1106 ierr = MPI_Reduce(&count,&maxcount,1,MPIU_INT,MPI_MAX,0,comm);CHKERRQ(ierr);
1107 ierr = PetscMPIIntCast(maxcount,&maxcnt);CHKERRQ(ierr);
1108 ierr = PetscMPIIntCast(count,&cnt);CHKERRQ(ierr);
1109
1110 ierr = PetscViewerBinaryGetDescriptor(viewer,&fdes);CHKERRQ(ierr);
1111 ierr = PetscViewerFlowControlStart(viewer,&message_count,&flowcontrolcount);CHKERRQ(ierr);
1112 if (!rank) {
1113 ierr = PetscMalloc(maxcnt*dsize,&workbuf);CHKERRQ(ierr);
1114 if (write) {
1115 ierr = PetscBinaryWrite(fdes,data,cnt,dtype);CHKERRQ(ierr);
1116 } else {
1117 ierr = PetscBinaryRead(fdes,data,cnt,NULL,dtype);CHKERRQ(ierr);
1118 }
1119 for (j=1; j<size; j++) {
1120 ierr = PetscViewerFlowControlStepMaster(viewer,j,&message_count,flowcontrolcount);CHKERRQ(ierr);
1121 if (write) {
1122 ierr = MPI_Recv(workbuf,maxcnt,mdtype,j,tag,comm,&status);CHKERRQ(ierr);
1123 ierr = MPI_Get_count(&status,mdtype,&rcnt);CHKERRQ(ierr);
1124 ierr = PetscBinaryWrite(fdes,workbuf,rcnt,dtype);CHKERRQ(ierr);
1125 } else {
1126 ierr = MPI_Recv(&scnt,1,MPI_INT,j,tag,comm,MPI_STATUS_IGNORE);CHKERRQ(ierr);
1127 ierr = PetscBinaryRead(fdes,workbuf,scnt,NULL,dtype);CHKERRQ(ierr);
1128 ierr = MPI_Send(workbuf,scnt,mdtype,j,tag,comm);CHKERRQ(ierr);
1129 }
1130 }
1131 ierr = PetscFree(workbuf);CHKERRQ(ierr);
1132 ierr = PetscViewerFlowControlEndMaster(viewer,&message_count);CHKERRQ(ierr);
1133 } else {
1134 ierr = PetscViewerFlowControlStepWorker(viewer,rank,&message_count);CHKERRQ(ierr);
1135 if (write) {
1136 ierr = MPI_Send(data,cnt,mdtype,0,tag,comm);CHKERRQ(ierr);
1137 } else {
1138 ierr = MPI_Send(&cnt,1,MPI_INT,0,tag,comm);CHKERRQ(ierr);
1139 ierr = MPI_Recv(data,cnt,mdtype,0,tag,comm,MPI_STATUS_IGNORE);CHKERRQ(ierr);
1140 }
1141 ierr = PetscViewerFlowControlEndWorker(viewer,&message_count);CHKERRQ(ierr);
1142 }
1143 }
1144 PetscFunctionReturn(0);
1145 }
1146
1147 /*@C
1148 PetscViewerBinaryReadAll - reads from a binary file from all processes
1149
1150 Collective
1151
1152 Input Parameters:
1153 + viewer - the binary viewer
1154 . data - location of data
1155 . count - local number of items of data to read
1156 . start - local start, can be PETSC_DETERMINE
1157 . total - global number of items of data to read, can be PETSC_DETERMINE
1158 - dtype - type of data to read
1159
1160 Level: advanced
1161
1162 .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryRead(), PetscViewerBinaryWriteAll()
1163 @*/
PetscViewerBinaryReadAll(PetscViewer viewer,void * data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)1164 PetscErrorCode PetscViewerBinaryReadAll(PetscViewer viewer,void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1165 {
1166 PetscErrorCode ierr;
1167 PetscFunctionBegin;
1168 ierr = PetscViewerBinaryWriteReadAll(viewer,PETSC_FALSE,data,count,start,total,dtype);CHKERRQ(ierr);
1169 PetscFunctionReturn(0);
1170 }
1171
1172 /*@C
1173 PetscViewerBinaryWriteAll - writes to a binary file from all processes
1174
1175 Collective
1176
1177 Input Parameters:
1178 + viewer - the binary viewer
1179 . data - location of data
1180 . count - local number of items of data to write
1181 . start - local start, can be PETSC_DETERMINE
1182 . total - global number of items of data to write, can be PETSC_DETERMINE
1183 - dtype - type of data to write
1184
1185 Level: advanced
1186
1187 .seealso: PetscViewerBinaryOpen(), PetscViewerBinarySetUseMPIIO(), PetscViewerBinaryWriteAll(), PetscViewerBinaryReadAll()
1188 @*/
PetscViewerBinaryWriteAll(PetscViewer viewer,const void * data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)1189 PetscErrorCode PetscViewerBinaryWriteAll(PetscViewer viewer,const void *data,PetscInt count,PetscInt start,PetscInt total,PetscDataType dtype)
1190 {
1191 PetscErrorCode ierr;
1192 PetscFunctionBegin;
1193 ierr = PetscViewerBinaryWriteReadAll(viewer,PETSC_TRUE,(void*)data,count,start,total,dtype);CHKERRQ(ierr);
1194 PetscFunctionReturn(0);
1195 }
1196
1197 /*@C
1198 PetscViewerBinaryWriteStringArray - writes to a binary file, only from the first process an array of strings
1199
1200 Collective
1201
1202 Input Parameters:
1203 + viewer - the binary viewer
1204 - data - location of the array of strings
1205
1206
1207 Level: intermediate
1208
1209 Notes:
1210 array of strings is null terminated
1211
1212 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1213 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1214 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1215 @*/
PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const * data)1216 PetscErrorCode PetscViewerBinaryWriteStringArray(PetscViewer viewer,const char * const *data)
1217 {
1218 PetscErrorCode ierr;
1219 PetscInt i,n = 0,*sizes;
1220 size_t len;
1221
1222 PetscFunctionBegin;
1223 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1224 /* count number of strings */
1225 while (data[n++]);
1226 n--;
1227 ierr = PetscMalloc1(n+1,&sizes);CHKERRQ(ierr);
1228 sizes[0] = n;
1229 for (i=0; i<n; i++) {
1230 ierr = PetscStrlen(data[i],&len);CHKERRQ(ierr);
1231 sizes[i+1] = (PetscInt)len + 1; /* size includes space for the null terminator */
1232 }
1233 ierr = PetscViewerBinaryWrite(viewer,sizes,n+1,PETSC_INT);CHKERRQ(ierr);
1234 for (i=0; i<n; i++) {
1235 ierr = PetscViewerBinaryWrite(viewer,(void*)data[i],sizes[i+1],PETSC_CHAR);CHKERRQ(ierr);
1236 }
1237 ierr = PetscFree(sizes);CHKERRQ(ierr);
1238 PetscFunctionReturn(0);
1239 }
1240
1241 /*@C
1242 PetscViewerBinaryReadStringArray - reads a binary file an array of strings
1243
1244 Collective
1245
1246 Input Parameter:
1247 . viewer - the binary viewer
1248
1249 Output Parameter:
1250 . data - location of the array of strings
1251
1252 Level: intermediate
1253
1254 Notes:
1255 array of strings is null terminated
1256
1257 .seealso: PetscViewerASCIIOpen(), PetscViewerPushFormat(), PetscViewerDestroy(),
1258 VecView(), MatView(), VecLoad(), MatLoad(), PetscViewerBinaryGetDescriptor(),
1259 PetscViewerBinaryGetInfoPointer(), PetscFileMode, PetscViewer, PetscViewerBinaryRead()
1260 @*/
PetscViewerBinaryReadStringArray(PetscViewer viewer,char *** data)1261 PetscErrorCode PetscViewerBinaryReadStringArray(PetscViewer viewer,char ***data)
1262 {
1263 PetscErrorCode ierr;
1264 PetscInt i,n,*sizes,N = 0;
1265
1266 PetscFunctionBegin;
1267 ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr);
1268 /* count number of strings */
1269 ierr = PetscViewerBinaryRead(viewer,&n,1,NULL,PETSC_INT);CHKERRQ(ierr);
1270 ierr = PetscMalloc1(n,&sizes);CHKERRQ(ierr);
1271 ierr = PetscViewerBinaryRead(viewer,sizes,n,NULL,PETSC_INT);CHKERRQ(ierr);
1272 for (i=0; i<n; i++) N += sizes[i];
1273 ierr = PetscMalloc((n+1)*sizeof(char*) + N*sizeof(char),data);CHKERRQ(ierr);
1274 (*data)[0] = (char*)((*data) + n + 1);
1275 for (i=1; i<n; i++) (*data)[i] = (*data)[i-1] + sizes[i-1];
1276 ierr = PetscViewerBinaryRead(viewer,(*data)[0],N,NULL,PETSC_CHAR);CHKERRQ(ierr);
1277 (*data)[n] = NULL;
1278 ierr = PetscFree(sizes);CHKERRQ(ierr);
1279 PetscFunctionReturn(0);
1280 }
1281
1282 /*@C
1283 PetscViewerFileSetMode - Sets the open mode of file
1284
1285 Logically Collective on PetscViewer
1286
1287 Input Parameters:
1288 + viewer - the PetscViewer; must be a a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1289 - mode - open mode of file
1290 $ FILE_MODE_WRITE - create new file for output
1291 $ FILE_MODE_READ - open existing file for input
1292 $ FILE_MODE_APPEND - open existing file for output
1293
1294 Level: advanced
1295
1296 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1297
1298 @*/
PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode mode)1299 PetscErrorCode PetscViewerFileSetMode(PetscViewer viewer,PetscFileMode mode)
1300 {
1301 PetscErrorCode ierr;
1302
1303 PetscFunctionBegin;
1304 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1305 PetscValidLogicalCollectiveEnum(viewer,mode,2);
1306 ierr = PetscTryMethod(viewer,"PetscViewerFileSetMode_C",(PetscViewer,PetscFileMode),(viewer,mode));CHKERRQ(ierr);
1307 PetscFunctionReturn(0);
1308 }
1309
PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode mode)1310 static PetscErrorCode PetscViewerFileSetMode_Binary(PetscViewer viewer,PetscFileMode mode)
1311 {
1312 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1313
1314 PetscFunctionBegin;
1315 if (viewer->setupcalled && vbinary->filemode != mode) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_ORDER,"Cannot change mode to %s after setup",PetscFileModes[mode]);
1316 vbinary->filemode = mode;
1317 PetscFunctionReturn(0);
1318 }
1319
1320 /*@C
1321 PetscViewerFileGetMode - Gets the open mode of file
1322
1323 Not Collective
1324
1325 Input Parameter:
1326 . viewer - the PetscViewer; must be a PETSCVIEWERBINARY, PETSCVIEWERMATLAB, PETSCVIEWERHDF5, or PETSCVIEWERASCII PetscViewer
1327
1328 Output Parameter:
1329 . mode - open mode of file
1330 $ FILE_MODE_WRITE - create new file for binary output
1331 $ FILE_MODE_READ - open existing file for binary input
1332 $ FILE_MODE_APPEND - open existing file for binary output
1333
1334 Level: advanced
1335
1336 .seealso: PetscViewerFileSetMode(), PetscViewerCreate(), PetscViewerSetType(), PetscViewerBinaryOpen()
1337
1338 @*/
PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode * mode)1339 PetscErrorCode PetscViewerFileGetMode(PetscViewer viewer,PetscFileMode *mode)
1340 {
1341 PetscErrorCode ierr;
1342
1343 PetscFunctionBegin;
1344 PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,1);
1345 PetscValidPointer(mode,2);
1346 ierr = PetscUseMethod(viewer,"PetscViewerFileGetMode_C",(PetscViewer,PetscFileMode*),(viewer,mode));CHKERRQ(ierr);
1347 PetscFunctionReturn(0);
1348 }
1349
PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode * mode)1350 static PetscErrorCode PetscViewerFileGetMode_Binary(PetscViewer viewer,PetscFileMode *mode)
1351 {
1352 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1353
1354 PetscFunctionBegin;
1355 *mode = vbinary->filemode;
1356 PetscFunctionReturn(0);
1357 }
1358
PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])1359 static PetscErrorCode PetscViewerFileSetName_Binary(PetscViewer viewer,const char name[])
1360 {
1361 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1362 PetscErrorCode ierr;
1363
1364 PetscFunctionBegin;
1365 if (viewer->setupcalled && vbinary->filename) {
1366 /* gzip can be run after the file with the previous filename has been closed */
1367 ierr = PetscFree(vbinary->ogzfilename);CHKERRQ(ierr);
1368 ierr = PetscStrallocpy(vbinary->filename,&vbinary->ogzfilename);CHKERRQ(ierr);
1369 }
1370 ierr = PetscFree(vbinary->filename);CHKERRQ(ierr);
1371 ierr = PetscStrallocpy(name,&vbinary->filename);CHKERRQ(ierr);
1372 viewer->setupcalled = PETSC_FALSE;
1373 PetscFunctionReturn(0);
1374 }
1375
PetscViewerFileGetName_Binary(PetscViewer viewer,const char ** name)1376 static PetscErrorCode PetscViewerFileGetName_Binary(PetscViewer viewer,const char **name)
1377 {
1378 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1379
1380 PetscFunctionBegin;
1381 *name = vbinary->filename;
1382 PetscFunctionReturn(0);
1383 }
1384
1385 #if defined(PETSC_HAVE_MPIIO)
PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)1386 static PetscErrorCode PetscViewerFileSetUp_BinaryMPIIO(PetscViewer viewer)
1387 {
1388 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1389 int amode;
1390 PetscErrorCode ierr;
1391
1392 PetscFunctionBegin;
1393 vbinary->storecompressed = PETSC_FALSE;
1394
1395 vbinary->moff = 0;
1396 switch (vbinary->filemode) {
1397 case FILE_MODE_READ: amode = MPI_MODE_RDONLY; break;
1398 case FILE_MODE_WRITE: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE; break;
1399 case FILE_MODE_APPEND: amode = MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_APPEND; break;
1400 default: SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"Unsupported file mode %s",PetscFileModes[vbinary->filemode]);
1401 }
1402 ierr = MPI_File_open(PetscObjectComm((PetscObject)viewer),vbinary->filename,amode,MPI_INFO_NULL,&vbinary->mfdes);CHKERRQ(ierr);
1403 /*
1404 The MPI standard does not have MPI_MODE_TRUNCATE. We emulate this behavior by setting the file size to zero.
1405 */
1406 if (vbinary->filemode == FILE_MODE_WRITE) {ierr = MPI_File_set_size(vbinary->mfdes,0);CHKERRQ(ierr);}
1407 /*
1408 Initially, all processes view the file as a linear byte stream. Therefore, for files opened with MPI_MODE_APPEND,
1409 MPI_File_get_position[_shared](fh, &offset) returns the absolute byte position at the end of file.
1410 Otherwise, we would need to call MPI_File_get_byte_offset(fh, offset, &byte_offset) to convert
1411 the offset in etype units to an absolute byte position.
1412 */
1413 if (vbinary->filemode == FILE_MODE_APPEND) {ierr = MPI_File_get_position(vbinary->mfdes,&vbinary->moff);CHKERRQ(ierr);}
1414 PetscFunctionReturn(0);
1415 }
1416 #endif
1417
PetscViewerFileSetUp_BinarySTDIO(PetscViewer viewer)1418 static PetscErrorCode PetscViewerFileSetUp_BinarySTDIO(PetscViewer viewer)
1419 {
1420 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1421 const char *fname;
1422 char bname[PETSC_MAX_PATH_LEN],*gz;
1423 PetscBool found;
1424 PetscMPIInt rank;
1425 PetscErrorCode ierr;
1426
1427 PetscFunctionBegin;
1428 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
1429
1430 /* if file name ends in .gz strip that off and note user wants file compressed */
1431 vbinary->storecompressed = PETSC_FALSE;
1432 if (vbinary->filemode == FILE_MODE_WRITE) {
1433 ierr = PetscStrstr(vbinary->filename,".gz",&gz);CHKERRQ(ierr);
1434 if (gz && gz[3] == 0) {*gz = 0; vbinary->storecompressed = PETSC_TRUE;}
1435 }
1436 #if !defined(PETSC_HAVE_POPEN)
1437 if (vbinary->storecompressed) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP_SYS,"Cannot run gzip on this machine");
1438 #endif
1439
1440
1441 fname = vbinary->filename;
1442 if (vbinary->filemode == FILE_MODE_READ) { /* possibly get the file from remote site or compressed file */
1443 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),fname,bname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr);
1444 if (!found) SETERRQ1(PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_OPEN,"Cannot locate file: %s",fname);
1445 fname = bname;
1446 }
1447
1448 vbinary->fdes = -1;
1449 if (!rank) { /* only first processor opens file*/
1450 PetscFileMode mode = vbinary->filemode;
1451 if (mode == FILE_MODE_APPEND) {
1452 /* check if asked to append to a non-existing file */
1453 ierr = PetscTestFile(fname,'\0',&found);CHKERRQ(ierr);
1454 if (!found) mode = FILE_MODE_WRITE;
1455 }
1456 ierr = PetscBinaryOpen(fname,mode,&vbinary->fdes);CHKERRQ(ierr);
1457 }
1458 PetscFunctionReturn(0);
1459 }
1460
PetscViewerFileSetUp_BinaryInfo(PetscViewer viewer)1461 static PetscErrorCode PetscViewerFileSetUp_BinaryInfo(PetscViewer viewer)
1462 {
1463 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1464 PetscMPIInt rank;
1465 PetscBool found;
1466 PetscErrorCode ierr;
1467
1468 PetscFunctionBegin;
1469 vbinary->fdes_info = NULL;
1470 ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)viewer),&rank);CHKERRQ(ierr);
1471 if (!vbinary->skipinfo && (vbinary->filemode == FILE_MODE_READ || !rank)) {
1472 char infoname[PETSC_MAX_PATH_LEN],iname[PETSC_MAX_PATH_LEN],*gz;
1473
1474 ierr = PetscStrncpy(infoname,vbinary->filename,sizeof(infoname));CHKERRQ(ierr);
1475 /* remove .gz if it ends file name */
1476 ierr = PetscStrstr(infoname,".gz",&gz);CHKERRQ(ierr);
1477 if (gz && gz[3] == 0) *gz = 0;
1478
1479 ierr = PetscStrlcat(infoname,".info",sizeof(infoname));CHKERRQ(ierr);
1480 if (vbinary->filemode == FILE_MODE_READ) {
1481 ierr = PetscFixFilename(infoname,iname);CHKERRQ(ierr);
1482 ierr = PetscFileRetrieve(PetscObjectComm((PetscObject)viewer),iname,infoname,PETSC_MAX_PATH_LEN,&found);CHKERRQ(ierr);
1483 if (found) {ierr = PetscOptionsInsertFile(PetscObjectComm((PetscObject)viewer),((PetscObject)viewer)->options,infoname,PETSC_FALSE);CHKERRQ(ierr);}
1484 } else if (!rank) { /* write or append */
1485 const char *omode = (vbinary->filemode == FILE_MODE_APPEND) ? "a" : "w";
1486 vbinary->fdes_info = fopen(infoname,omode);
1487 if (!vbinary->fdes_info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot open .info file %s for writing",infoname);
1488 }
1489 }
1490 PetscFunctionReturn(0);
1491 }
1492
PetscViewerSetUp_Binary(PetscViewer viewer)1493 static PetscErrorCode PetscViewerSetUp_Binary(PetscViewer viewer)
1494 {
1495 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)viewer->data;
1496 PetscBool usempiio;
1497 PetscErrorCode ierr;
1498
1499 PetscFunctionBegin;
1500 if (!vbinary->setfromoptionscalled) {ierr = PetscViewerSetFromOptions(viewer);CHKERRQ(ierr);}
1501 if (!vbinary->filename) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetName()");
1502 if (vbinary->filemode == (PetscFileMode)-1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ORDER,"Must call PetscViewerFileSetMode()");
1503 ierr = PetscViewerFileClose_Binary(viewer);CHKERRQ(ierr);
1504
1505 ierr = PetscViewerBinaryGetUseMPIIO(viewer,&usempiio);CHKERRQ(ierr);
1506 if (usempiio) {
1507 #if defined(PETSC_HAVE_MPIIO)
1508 ierr = PetscViewerFileSetUp_BinaryMPIIO(viewer);CHKERRQ(ierr);
1509 #endif
1510 } else {
1511 ierr = PetscViewerFileSetUp_BinarySTDIO(viewer);CHKERRQ(ierr);
1512 }
1513 ierr = PetscViewerFileSetUp_BinaryInfo(viewer);CHKERRQ(ierr);
1514
1515 ierr = PetscLogObjectState((PetscObject)viewer,"File: %s",vbinary->filename);CHKERRQ(ierr);
1516 PetscFunctionReturn(0);
1517 }
1518
PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)1519 static PetscErrorCode PetscViewerView_Binary(PetscViewer v,PetscViewer viewer)
1520 {
1521 PetscViewer_Binary *vbinary = (PetscViewer_Binary*)v->data;
1522 const char *fname = vbinary->filename ? vbinary->filename : "not yet set";
1523 const char *fmode = vbinary->filemode != (PetscFileMode) -1 ? PetscFileModes[vbinary->filemode] : "not yet set";
1524 PetscBool usempiio;
1525 PetscErrorCode ierr;
1526
1527 PetscFunctionBegin;
1528 ierr = PetscViewerBinaryGetUseMPIIO(v,&usempiio);CHKERRQ(ierr);
1529 ierr = PetscViewerASCIIPrintf(viewer,"Filename: %s\n",fname);CHKERRQ(ierr);
1530 ierr = PetscViewerASCIIPrintf(viewer,"Mode: %s (%s)\n",fmode,usempiio ? "mpiio" : "stdio");CHKERRQ(ierr);
1531 PetscFunctionReturn(0);
1532 }
1533
PetscViewerSetFromOptions_Binary(PetscOptionItems * PetscOptionsObject,PetscViewer viewer)1534 static PetscErrorCode PetscViewerSetFromOptions_Binary(PetscOptionItems *PetscOptionsObject,PetscViewer viewer)
1535 {
1536 PetscViewer_Binary *binary = (PetscViewer_Binary*)viewer->data;
1537 char defaultname[PETSC_MAX_PATH_LEN];
1538 PetscBool flg;
1539 PetscErrorCode ierr;
1540
1541 PetscFunctionBegin;
1542 if (viewer->setupcalled) PetscFunctionReturn(0);
1543 ierr = PetscOptionsHead(PetscOptionsObject,"Binary PetscViewer Options");CHKERRQ(ierr);
1544 ierr = PetscSNPrintf(defaultname,PETSC_MAX_PATH_LEN-1,"binaryoutput");CHKERRQ(ierr);
1545 ierr = PetscOptionsString("-viewer_binary_filename","Specify filename","PetscViewerFileSetName",defaultname,defaultname,sizeof(defaultname),&flg);CHKERRQ(ierr);
1546 if (flg) { ierr = PetscViewerFileSetName_Binary(viewer,defaultname);CHKERRQ(ierr); }
1547 ierr = PetscOptionsBool("-viewer_binary_skip_info","Skip writing/reading .info file","PetscViewerBinarySetSkipInfo",binary->skipinfo,&binary->skipinfo,NULL);CHKERRQ(ierr);
1548 ierr = PetscOptionsBool("-viewer_binary_skip_options","Skip parsing Vec/Mat load options","PetscViewerBinarySetSkipOptions",binary->skipoptions,&binary->skipoptions,NULL);CHKERRQ(ierr);
1549 ierr = PetscOptionsBool("-viewer_binary_skip_header","Skip writing/reading header information","PetscViewerBinarySetSkipHeader",binary->skipheader,&binary->skipheader,NULL);CHKERRQ(ierr);
1550 #if defined(PETSC_HAVE_MPIIO)
1551 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file","PetscViewerBinarySetUseMPIIO",binary->usempiio,&binary->usempiio,NULL);CHKERRQ(ierr);
1552 #else
1553 ierr = PetscOptionsBool("-viewer_binary_mpiio","Use MPI-IO functionality to write/read binary file (NOT AVAILABLE)","PetscViewerBinarySetUseMPIIO",PETSC_FALSE,NULL,NULL);CHKERRQ(ierr);
1554 #endif
1555 ierr = PetscOptionsTail();CHKERRQ(ierr);
1556 binary->setfromoptionscalled = PETSC_TRUE;
1557 PetscFunctionReturn(0);
1558 }
1559
1560 /*MC
1561 PETSCVIEWERBINARY - A viewer that saves to binary files
1562
1563
1564 .seealso: PetscViewerBinaryOpen(), PETSC_VIEWER_STDOUT_(),PETSC_VIEWER_STDOUT_SELF, PETSC_VIEWER_STDOUT_WORLD, PetscViewerCreate(), PetscViewerASCIIOpen(),
1565 PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, PETSCVIEWERDRAW,
1566 PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType(),
1567 PetscViewerBinaryGetUseMPIIO(), PetscViewerBinarySetUseMPIIO()
1568
1569 Level: beginner
1570
1571 M*/
1572
PetscViewerCreate_Binary(PetscViewer v)1573 PETSC_EXTERN PetscErrorCode PetscViewerCreate_Binary(PetscViewer v)
1574 {
1575 PetscErrorCode ierr;
1576 PetscViewer_Binary *vbinary;
1577
1578 PetscFunctionBegin;
1579 ierr = PetscNewLog(v,&vbinary);CHKERRQ(ierr);
1580 v->data = (void*)vbinary;
1581
1582 v->ops->setfromoptions = PetscViewerSetFromOptions_Binary;
1583 v->ops->destroy = PetscViewerDestroy_Binary;
1584 v->ops->view = PetscViewerView_Binary;
1585 v->ops->setup = PetscViewerSetUp_Binary;
1586 v->ops->flush = NULL; /* Should we support Flush() ? */
1587 v->ops->getsubviewer = PetscViewerGetSubViewer_Binary;
1588 v->ops->restoresubviewer = PetscViewerRestoreSubViewer_Binary;
1589 v->ops->read = PetscViewerBinaryRead;
1590
1591 vbinary->fdes = -1;
1592 #if defined(PETSC_HAVE_MPIIO)
1593 vbinary->usempiio = PETSC_FALSE;
1594 vbinary->mfdes = MPI_FILE_NULL;
1595 vbinary->mfsub = MPI_FILE_NULL;
1596 #endif
1597 vbinary->filename = NULL;
1598 vbinary->filemode = (PetscFileMode)-1;
1599 vbinary->fdes_info = NULL;
1600 vbinary->skipinfo = PETSC_FALSE;
1601 vbinary->skipoptions = PETSC_TRUE;
1602 vbinary->skipheader = PETSC_FALSE;
1603 vbinary->storecompressed = PETSC_FALSE;
1604 vbinary->ogzfilename = NULL;
1605 vbinary->flowcontrol = 256; /* seems a good number for Cray XT-5 */
1606
1607 vbinary->setfromoptionscalled = PETSC_FALSE;
1608
1609 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetFlowControl_C",PetscViewerBinaryGetFlowControl_Binary);CHKERRQ(ierr);
1610 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetFlowControl_C",PetscViewerBinarySetFlowControl_Binary);CHKERRQ(ierr);
1611 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipHeader_C",PetscViewerBinaryGetSkipHeader_Binary);CHKERRQ(ierr);
1612 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipHeader_C",PetscViewerBinarySetSkipHeader_Binary);CHKERRQ(ierr);
1613 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipOptions_C",PetscViewerBinaryGetSkipOptions_Binary);CHKERRQ(ierr);
1614 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipOptions_C",PetscViewerBinarySetSkipOptions_Binary);CHKERRQ(ierr);
1615 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetSkipInfo_C",PetscViewerBinaryGetSkipInfo_Binary);CHKERRQ(ierr);
1616 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetSkipInfo_C",PetscViewerBinarySetSkipInfo_Binary);CHKERRQ(ierr);
1617 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetInfoPointer_C",PetscViewerBinaryGetInfoPointer_Binary);CHKERRQ(ierr);
1618 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetName_C",PetscViewerFileGetName_Binary);CHKERRQ(ierr);
1619 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetName_C",PetscViewerFileSetName_Binary);CHKERRQ(ierr);
1620 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileGetMode_C",PetscViewerFileGetMode_Binary);CHKERRQ(ierr);
1621 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerFileSetMode_C",PetscViewerFileSetMode_Binary);CHKERRQ(ierr);
1622 #if defined(PETSC_HAVE_MPIIO)
1623 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinaryGetUseMPIIO_C",PetscViewerBinaryGetUseMPIIO_Binary);CHKERRQ(ierr);
1624 ierr = PetscObjectComposeFunction((PetscObject)v,"PetscViewerBinarySetUseMPIIO_C",PetscViewerBinarySetUseMPIIO_Binary);CHKERRQ(ierr);
1625 #endif
1626 PetscFunctionReturn(0);
1627 }
1628
1629 /* ---------------------------------------------------------------------*/
1630 /*
1631 The variable Petsc_Viewer_Binary_keyval is used to indicate an MPI attribute that
1632 is attached to a communicator, in this case the attribute is a PetscViewer.
1633 */
1634 PetscMPIInt Petsc_Viewer_Binary_keyval = MPI_KEYVAL_INVALID;
1635
1636 /*@C
1637 PETSC_VIEWER_BINARY_ - Creates a binary PetscViewer shared by all processors
1638 in a communicator.
1639
1640 Collective
1641
1642 Input Parameter:
1643 . comm - the MPI communicator to share the binary PetscViewer
1644
1645 Level: intermediate
1646
1647 Options Database Keys:
1648 + -viewer_binary_filename <name>
1649 . -viewer_binary_skip_info
1650 . -viewer_binary_skip_options
1651 . -viewer_binary_skip_header
1652 - -viewer_binary_mpiio
1653
1654 Environmental variables:
1655 - PETSC_VIEWER_BINARY_FILENAME
1656
1657 Notes:
1658 Unlike almost all other PETSc routines, PETSC_VIEWER_BINARY_ does not return
1659 an error code. The binary PetscViewer is usually used in the form
1660 $ XXXView(XXX object,PETSC_VIEWER_BINARY_(comm));
1661
1662 .seealso: PETSC_VIEWER_BINARY_WORLD, PETSC_VIEWER_BINARY_SELF, PetscViewerBinaryOpen(), PetscViewerCreate(),
1663 PetscViewerDestroy()
1664 @*/
PETSC_VIEWER_BINARY_(MPI_Comm comm)1665 PetscViewer PETSC_VIEWER_BINARY_(MPI_Comm comm)
1666 {
1667 PetscErrorCode ierr;
1668 PetscBool flg;
1669 PetscViewer viewer;
1670 char fname[PETSC_MAX_PATH_LEN];
1671 MPI_Comm ncomm;
1672
1673 PetscFunctionBegin;
1674 ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1675 if (Petsc_Viewer_Binary_keyval == MPI_KEYVAL_INVALID) {
1676 ierr = MPI_Comm_create_keyval(MPI_COMM_NULL_COPY_FN,MPI_COMM_NULL_DELETE_FN,&Petsc_Viewer_Binary_keyval,NULL);
1677 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1678 }
1679 ierr = MPI_Comm_get_attr(ncomm,Petsc_Viewer_Binary_keyval,(void**)&viewer,(int*)&flg);
1680 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1681 if (!flg) { /* PetscViewer not yet created */
1682 ierr = PetscOptionsGetenv(ncomm,"PETSC_VIEWER_BINARY_FILENAME",fname,PETSC_MAX_PATH_LEN,&flg);
1683 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1684 if (!flg) {
1685 ierr = PetscStrcpy(fname,"binaryoutput");
1686 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1687 }
1688 ierr = PetscViewerBinaryOpen(ncomm,fname,FILE_MODE_WRITE,&viewer);
1689 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1690 ierr = PetscObjectRegisterDestroy((PetscObject)viewer);
1691 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1692 ierr = MPI_Comm_set_attr(ncomm,Petsc_Viewer_Binary_keyval,(void*)viewer);
1693 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1694 }
1695 ierr = PetscCommDestroy(&ncomm);
1696 if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_BINARY_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(NULL);}
1697 PetscFunctionReturn(viewer);
1698 }
1699