1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /* Programmer:  John Mainzer
15  *              7/13/15
16  *
17  *              This file contains tests specific to the cache image
18  *        feature implemented in H5C.c
19  */
20 #include "testphdf5.h"
21 
22 #include "cache_common.h"
23 #include "genall5.h"
24 
25 #define TEST_FILES_TO_CONSTRUCT 2
26 #define CHUNK_SIZE              10
27 #define DSET_SIZE               (40 * CHUNK_SIZE)
28 #define MAX_NUM_DSETS           256
29 #define PAR_NUM_DSETS           32
30 #define PAGE_SIZE        (4 * 1024)
31 #define PB_SIZE                 (64 * PAGE_SIZE)
32 
33 /* global variable declarations: */
34 
35 
36 const char *FILENAMES[] = {
37         "t_cache_image_00",
38         "t_cache_image_01",
39         "t_cache_image_02",
40         NULL
41 };
42 
43 /* local utility function declarations */
44 
45 static void create_data_sets(hid_t file_id, int min_dset, int max_dset);
46 #if 0 /* keep pending full parallel cache image */
47 static void delete_data_sets(hid_t file_id, int min_dset, int max_dset);
48 #endif
49 
50 static void open_hdf5_file(const hbool_t create_file,
51     const hbool_t mdci_sbem_expected,
52     const hbool_t read_only,
53     const hbool_t set_mdci_fapl,
54     const hbool_t config_fsm,
55     const hbool_t enable_page_buffer,
56     const char * hdf_file_name,
57     const unsigned cache_image_flags,
58     hid_t * file_id_ptr,
59     H5F_t ** file_ptr_ptr,
60     H5C_t ** cache_ptr_ptr,
61     MPI_Comm comm,
62     MPI_Info info,
63    int l_facc_type,
64    const hbool_t all_coll_metadata_ops,
65    const hbool_t coll_metadata_write,
66    const int md_write_strat);
67 
68 static void verify_data_sets(hid_t file_id, int min_dset, int max_dset);
69 
70 /* local test function declarations */
71 
72 static hbool_t parse_flags(int argc, char * argv[], hbool_t * setup_ptr,
73     hbool_t * ici_ptr, int * file_idx_ptr, int * mpi_size_ptr, hbool_t display);
74 static void usage(void);
75 static unsigned construct_test_file(int test_file_index);
76 static void par_create_dataset(int dset_num, hid_t file_id, int mpi_rank,
77     int mpi_size);
78 static void par_delete_dataset(int dset_num, hid_t file_id, int mpi_rank);
79 static void par_verify_dataset(int dset_num, hid_t file_id, int mpi_rank);
80 
81 static hbool_t serial_insert_cache_image(int file_name_idx, int mpi_size);
82 static void serial_verify_dataset(int dset_num, hid_t file_id, int mpi_size);
83 
84 /* top level test function declarations */
85 static unsigned verify_cache_image_RO(int file_name_id,
86     int md_write_strat, int mpi_rank);
87 static unsigned verify_cache_image_RW(int file_name_id,
88     int md_write_strat, int mpi_rank);
89 
90 static hbool_t smoke_check_1(MPI_Comm mpi_comm, MPI_Info mpi_info,
91     int mpi_rank, int mpi_size);
92 
93 
94 /****************************************************************************/
95 /***************************** Utility Functions ****************************/
96 /****************************************************************************/
97 
98 /*-------------------------------------------------------------------------
99  * Function:    construct_test_file()
100  *
101  * Purpose:     This function attempts to mimic the typical "poor man's
102  *        parallel use case in which the file is passed between
103  *        processes, each of which open the file, write some data,
104  *        close the file, and then pass control on to the next
105  *        process.
106  *
107  *        In this case, we create one group for each process, and
108  *        populate it with a "zoo" of HDF5 objects selected to
109  *        (ideally) exercise all HDF5 on disk data structures.
110  *
111  *        The end result is a test file used verify that PHDF5
112  *        can open a file with a cache image.
113  *
114  *        Cycle of operation
115  *
116  *        1) Create a HDF5 file with the cache image FAPL entry.
117  *
118  *           Verify that the cache is informed of the cache image
119  *           FAPL entry.
120  *
121  *           Set all cache image flags, forcing full functionality.
122  *
123  *        2) Create a data set in the file.
124  *
125  *        3) Close the file.
126  *
127  *        4) Open the file.
128  *
129  *           Verify that the metadata cache is instructed to load
130  *                 the metadata cache image.
131  *
132  *        5) Create a data set in the file.
133  *
134  *        6) Close the file.  If enough datasets have been created
135  *                 goto 7.  Otherwise return to 4.
136  *
137  *        7) Open the file R/O.
138  *
139  *                 Verify that the file contains a metadata cache image
140  *                 superblock extension message.
141  *
142  *        8) Verify all data sets.
143  *
144  *           Verify that the cache image has been loaded.
145  *
146  *            9) close the file.
147  *
148  * Return:      void
149  *
150  * Programmer:  John Mainzer
151  *              1/25/17
152  *
153  * Modifications:
154  *
155  *        None.
156  *
157  *-------------------------------------------------------------------------
158  */
159 
160 static unsigned
construct_test_file(int test_file_index)161 construct_test_file(int test_file_index)
162 {
163     const char * fcn_name = "construct_test_file()";
164     char filename[512];
165     hbool_t show_progress = FALSE;
166     hid_t file_id = -1;
167     H5F_t *file_ptr = NULL;
168     H5C_t *cache_ptr = NULL;
169     int cp = 0;
170     int min_dset = 0;
171     int max_dset = 0;
172     MPI_Comm dummy_comm = MPI_COMM_WORLD;
173     MPI_Info dummy_info = MPI_INFO_NULL;
174 
175     pass = TRUE;
176 
177     if ( show_progress )
178         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
179 
180 
181     /* setup the file name */
182     if ( pass ) {
183 
184         HDassert(FILENAMES[test_file_index]);
185 
186         if ( h5_fixname(FILENAMES[test_file_index], H5P_DEFAULT,
187                                   filename, sizeof(filename))
188             == NULL ) {
189 
190             pass = FALSE;
191             failure_mssg = "h5_fixname() failed.\n";
192         }
193     }
194 
195     if ( show_progress )
196         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
197 
198 
199     /* 1) Create a HDF5 file with the cache image FAPL entry.
200      *
201      *      Verify that the cache is informed of the cache image FAPL entry.
202      *
203      *    Set flags forcing full function of the cache image feature.
204      */
205 
206     if ( pass ) {
207 
208         open_hdf5_file(/* create_file           */ TRUE,
209                        /* mdci_sbem_expected    */ FALSE,
210                        /* read_only             */ FALSE,
211                        /* set_mdci_fapl         */ TRUE,
212             /* config_fsm            */ TRUE,
213                        /* enable_page_buffer    */ FALSE,
214                        /* hdf_file_name         */ filename,
215                        /* cache_image_flags     */ H5C_CI__ALL_FLAGS,
216                        /* file_id_ptr           */ &file_id,
217                        /* file_ptr_ptr          */ &file_ptr,
218                        /* cache_ptr_ptr         */ &cache_ptr,
219                        /* comm                  */ dummy_comm,
220                        /* info                  */ dummy_info,
221                        /* l_facc_type           */ 0,
222                        /* all_coll_metadata_ops */ FALSE,
223                        /* coll_metadata_write   */ FALSE,
224                        /* md_write_strat        */ 0);
225     }
226 
227     if ( show_progress )
228         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
229 
230 
231     /* 2) Create a data set in the file. */
232 
233     if ( pass ) {
234 
235         create_data_sets(file_id, min_dset++, max_dset++);
236     }
237 
238 #if H5C_COLLECT_CACHE_STATS
239     if ( pass ) {
240 
241         if ( cache_ptr->images_loaded != 0 ) {
242 
243             pass = FALSE;
244             failure_mssg = "metadata cache image block loaded(1).";
245         }
246     }
247 #endif /* H5C_COLLECT_CACHE_STATS */
248 
249     if ( show_progress )
250         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
251 
252 
253     /* 3) Close the file. */
254 
255     if ( pass ) {
256 
257         if ( H5Fclose(file_id) < 0  ) {
258 
259             pass = FALSE;
260             failure_mssg = "H5Fclose() failed.\n";
261 
262         }
263     }
264 
265     if ( show_progress )
266         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
267 
268 
269     while ( ( pass ) && ( max_dset < MAX_NUM_DSETS ) )
270     {
271 
272         /* 4) Open the file.
273          *
274          *    Verify that the metadata cache is instructed to load the
275          *    metadata cache image.
276          */
277 
278         if ( pass ) {
279 
280             open_hdf5_file(/* create_file           */ FALSE,
281                            /* mdci_sbem_expected    */ TRUE,
282                            /* read_only             */ FALSE,
283                            /* set_mdci_fapl         */ TRUE,
284                 /* config_fsm            */ FALSE,
285                            /* enable_page_buffer    */ FALSE,
286                            /* hdf_file_name         */ filename,
287                            /* cache_image_flags     */ H5C_CI__ALL_FLAGS,
288                            /* file_id_ptr           */ &file_id,
289                            /* file_ptr_ptr          */ &file_ptr,
290                            /* cache_ptr_ptr         */ &cache_ptr,
291                            /* comm                  */ dummy_comm,
292                            /* info                  */ dummy_info,
293                            /* l_facc_type           */ 0,
294                            /* all_coll_metadata_ops */ FALSE,
295                            /* coll_metadata_write   */ FALSE,
296                            /* md_write_strat        */ 0);
297         }
298 
299         if ( show_progress )
300             HDfprintf(stdout, "%s:L1 cp = %d, max_dset = %d, pass = %d.\n",
301                       fcn_name, cp, max_dset, pass);
302 
303 
304         /* 5) Create a data set in the file. */
305 
306         if ( pass ) {
307 
308             create_data_sets(file_id, min_dset++, max_dset++);
309         }
310 
311 #if H5C_COLLECT_CACHE_STATS
312         if ( pass ) {
313 
314             if ( cache_ptr->images_loaded == 0 ) {
315 
316                 pass = FALSE;
317                 failure_mssg = "metadata cache image block not loaded(1).";
318             }
319         }
320 #endif /* H5C_COLLECT_CACHE_STATS */
321 
322         if ( show_progress )
323             HDfprintf(stdout, "%s:L2 cp = %d, max_dset = %d, pass = %d.\n",
324                       fcn_name, cp + 1, max_dset, pass);
325 
326 
327         /* 6) Close the file. */
328 
329         if ( pass ) {
330 
331             if ( H5Fclose(file_id) < 0  ) {
332 
333                 pass = FALSE;
334                 failure_mssg = "H5Fclose() failed.\n";
335 
336             }
337         }
338 
339         if ( show_progress )
340             HDfprintf(stdout, "%s:L3 cp = %d, max_dset = %d, pass = %d.\n",
341                       fcn_name, cp + 2, max_dset, pass);
342     } /* end while */
343     cp += 3;
344 
345 
346     /* 7) Open the file R/O.
347      *
348      *    Verify that the file contains a metadata cache image
349      *    superblock extension message.
350      */
351 
352     if ( pass ) {
353 
354         open_hdf5_file(/* create_file           */ FALSE,
355                        /* mdci_sbem_expected    */ TRUE,
356                        /* read_only             */ TRUE,
357                        /* set_mdci_fapl         */ FALSE,
358                 /* config_fsm            */ FALSE,
359                        /* enable_page_buffer    */ FALSE,
360                        /* hdf_file_name         */ filename,
361                        /* cache_image_flags     */ H5C_CI__ALL_FLAGS,
362                        /* file_id_ptr           */ &file_id,
363                        /* file_ptr_ptr          */ &file_ptr,
364                        /* cache_ptr_ptr         */ &cache_ptr,
365                        /* comm                  */ dummy_comm,
366                        /* info                  */ dummy_info,
367                        /* l_facc_type           */ 0,
368                        /* all_coll_metadata_ops */ FALSE,
369                        /* coll_metadata_write   */ FALSE,
370                        /* md_write_strat        */ 0);
371     }
372 
373     if ( show_progress )
374         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
375 
376 
377     /* 8) Open and close all data sets.
378      *
379      *    Verify that the cache image has been loaded.
380      */
381 
382     if ( pass ) {
383 
384        verify_data_sets(file_id, 0, max_dset - 1);
385     }
386 
387 #if H5C_COLLECT_CACHE_STATS
388     if ( pass ) {
389 
390         if ( cache_ptr->images_loaded == 0 ) {
391 
392             pass = FALSE;
393             failure_mssg = "metadata cache image block not loaded(2).";
394         }
395     }
396 #endif /* H5C_COLLECT_CACHE_STATS */
397 
398     if ( show_progress )
399         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
400 
401     /* 9) Close the file. */
402 
403     if ( pass ) {
404 
405         if ( H5Fclose(file_id) < 0  ) {
406 
407             pass = FALSE;
408             failure_mssg = "H5Fclose() failed.\n";
409         }
410     }
411 
412     return !pass;
413 
414 } /* construct_test_file() */
415 
416 
417 /*-------------------------------------------------------------------------
418  * Function:    create_data_sets()
419  *
420  * Purpose:     If pass is TRUE on entry, create the specified data sets
421  *        in the indicated file.
422  *
423  *        Data sets and their contents must be well know, as we
424  *        will verify that they contain the expected data later.
425  *
426  *              On failure, set pass to FALSE, and set failure_mssg
427  *              to point to an appropriate failure message.
428  *
429  *              Do nothing if pass is FALSE on entry.
430  *
431  * Return:      void
432  *
433  * Programmer:  John Mainzer
434  *              7/15/15
435  *
436  * Modifications:
437  *
438  *              Added min_dset and max_dset parameters and supporting
439  *        code.  This allows the caller to specify a range of
440  *        datasets to create.
441  *                        JRM -- 8/20/15
442  *
443  *-------------------------------------------------------------------------
444  */
445 
446 static void
create_data_sets(hid_t file_id,int min_dset,int max_dset)447 create_data_sets(hid_t file_id, int min_dset, int max_dset)
448 {
449     const char * fcn_name = "create_data_sets()";
450     char dset_name[64];
451     hbool_t show_progress = FALSE;
452     hbool_t valid_chunk;
453     hbool_t verbose = FALSE;
454     int cp = 0;
455     int i, j, k, l, m;
456     int data_chunk[CHUNK_SIZE][CHUNK_SIZE];
457     herr_t status;
458     hid_t dataspace_id = -1;
459     hid_t filespace_ids[MAX_NUM_DSETS];
460     hid_t memspace_id = -1;
461     hid_t dataset_ids[MAX_NUM_DSETS];
462     hid_t properties = -1;
463     hsize_t dims[2];
464     hsize_t a_size[2];
465     hsize_t offset[2];
466     hsize_t chunk_size[2];
467 
468     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
469 
470     HDassert(0 <= min_dset);
471     HDassert(min_dset <= max_dset);
472     HDassert(max_dset < MAX_NUM_DSETS);
473 
474     /* create the datasets */
475 
476     if ( pass ) {
477 
478         i = min_dset;
479 
480         while ( ( pass ) && ( i <= max_dset ) )
481         {
482             /* create a dataspace for the chunked dataset */
483             dims[0] = DSET_SIZE;
484             dims[1] = DSET_SIZE;
485             dataspace_id = H5Screate_simple(2, dims, NULL);
486 
487             if ( dataspace_id < 0 ) {
488 
489                 pass = FALSE;
490                 failure_mssg = "H5Screate_simple() failed.";
491             }
492 
493             /* set the dataset creation plist to specify that the raw data is
494              * to be partioned into 10X10 element chunks.
495              */
496 
497             if ( pass ) {
498 
499                 chunk_size[0] = CHUNK_SIZE;
500                 chunk_size[1] = CHUNK_SIZE;
501                 properties = H5Pcreate(H5P_DATASET_CREATE);
502 
503                 if ( properties < 0 ) {
504 
505                     pass = FALSE;
506                     failure_mssg = "H5Pcreate() failed.";
507                 }
508             }
509 
510             if ( pass ) {
511 
512                 if ( H5Pset_chunk(properties, 2, chunk_size) < 0 ) {
513 
514                     pass = FALSE;
515                     failure_mssg = "H5Pset_chunk() failed.";
516                 }
517             }
518 
519             /* create the dataset */
520             if ( pass ) {
521 
522                 HDsprintf(dset_name, "/dset%03d", i);
523                 dataset_ids[i] = H5Dcreate2(file_id, dset_name, H5T_STD_I32BE,
524                                             dataspace_id, H5P_DEFAULT,
525                                             properties, H5P_DEFAULT);
526 
527                 if ( dataset_ids[i] < 0 ) {
528 
529                     pass = FALSE;
530                     failure_mssg = "H5Dcreate() failed.";
531                 }
532             }
533 
534             /* get the file space ID */
535             if ( pass ) {
536 
537                 filespace_ids[i] = H5Dget_space(dataset_ids[i]);
538 
539                 if ( filespace_ids[i] < 0 ) {
540 
541                     pass = FALSE;
542                     failure_mssg = "H5Dget_space() failed.";
543                 }
544             }
545 
546             i++;
547         }
548     }
549 
550     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
551 
552     /* create the mem space to be used to read and write chunks */
553     if ( pass ) {
554 
555         dims[0] = CHUNK_SIZE;
556         dims[1] = CHUNK_SIZE;
557         memspace_id = H5Screate_simple(2, dims, NULL);
558 
559         if ( memspace_id < 0 ) {
560 
561             pass = FALSE;
562             failure_mssg = "H5Screate_simple() failed.";
563         }
564     }
565 
566     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
567 
568     /* select in memory hyperslab */
569     if ( pass ) {
570 
571         offset[0] = 0;  /*offset of hyperslab in memory*/
572         offset[1] = 0;
573         a_size[0] = CHUNK_SIZE;  /*size of hyperslab*/
574         a_size[1] = CHUNK_SIZE;
575         status = H5Sselect_hyperslab(memspace_id, H5S_SELECT_SET, offset, NULL,
576                                      a_size, NULL);
577 
578         if ( status < 0 ) {
579 
580             pass = FALSE;
581             failure_mssg = "H5Sselect_hyperslab() failed.";
582         }
583     }
584 
585     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
586 
587     /* initialize all datasets on a round robin basis */
588     i = 0;
589     while ( ( pass ) && ( i < DSET_SIZE ) )
590     {
591         j = 0;
592         while ( ( pass ) && ( j < DSET_SIZE ) )
593         {
594             m = min_dset;
595             while ( ( pass ) && ( m <= max_dset ) )
596             {
597                 /* initialize the slab */
598                 for ( k = 0; k < CHUNK_SIZE; k++ )
599                 {
600                     for ( l = 0; l < CHUNK_SIZE; l++ )
601                     {
602                         data_chunk[k][l] = (DSET_SIZE * DSET_SIZE * m) +
603                                            (DSET_SIZE * (i + k)) + j + l;
604                     }
605                 }
606 
607                 /* select on disk hyperslab */
608                 offset[0] = (hsize_t)i; /*offset of hyperslab in file*/
609                 offset[1] = (hsize_t)j;
610                 a_size[0] = CHUNK_SIZE;   /*size of hyperslab*/
611                 a_size[1] = CHUNK_SIZE;
612                 status = H5Sselect_hyperslab(filespace_ids[m], H5S_SELECT_SET,
613                                              offset, NULL, a_size, NULL);
614 
615                 if ( status < 0 ) {
616 
617                     pass = FALSE;
618                     failure_mssg = "disk H5Sselect_hyperslab() failed.";
619                 }
620 
621                 /* write the chunk to file */
622                 status = H5Dwrite(dataset_ids[m], H5T_NATIVE_INT, memspace_id,
623                                   filespace_ids[m], H5P_DEFAULT, data_chunk);
624 
625                 if ( status < 0 ) {
626 
627                     pass = FALSE;
628                     failure_mssg = "H5Dwrite() failed.";
629                 }
630                 m++;
631             }
632             j += CHUNK_SIZE;
633         }
634 
635         i += CHUNK_SIZE;
636     }
637 
638     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
639 
640     /* read data from data sets and validate it */
641     i = 0;
642     while ( ( pass ) && ( i < DSET_SIZE ) )
643     {
644         j = 0;
645         while ( ( pass ) && ( j < DSET_SIZE ) )
646         {
647             m = min_dset;
648             while ( ( pass ) && ( m <= max_dset ) )
649             {
650 
651                 /* select on disk hyperslab */
652                 offset[0] = (hsize_t)i; /* offset of hyperslab in file */
653                 offset[1] = (hsize_t)j;
654                 a_size[0] = CHUNK_SIZE; /* size of hyperslab */
655                 a_size[1] = CHUNK_SIZE;
656                 status = H5Sselect_hyperslab(filespace_ids[m], H5S_SELECT_SET,
657                                              offset, NULL, a_size, NULL);
658 
659                 if ( status < 0 ) {
660 
661                    pass = FALSE;
662                    failure_mssg = "disk hyperslab create failed.";
663                 }
664 
665                 /* read the chunk from file */
666                 if ( pass ) {
667 
668                     status = H5Dread(dataset_ids[m], H5T_NATIVE_INT,
669                                      memspace_id, filespace_ids[m],
670                                      H5P_DEFAULT, data_chunk);
671 
672                     if ( status < 0 ) {
673 
674                        pass = FALSE;
675                        failure_mssg = "disk hyperslab create failed.";
676                     }
677                 }
678 
679                 /* validate the slab */
680                 if ( pass ) {
681 
682                     valid_chunk = TRUE;
683                     for ( k = 0; k < CHUNK_SIZE; k++ )
684                     {
685                         for ( l = 0; l < CHUNK_SIZE; l++ )
686                         {
687                             if ( data_chunk[k][l]
688                                  !=
689                                  ((DSET_SIZE * DSET_SIZE * m) +
690                                   (DSET_SIZE * (i + k)) + j + l) ) {
691 
692                                 valid_chunk = FALSE;
693 
694                 if ( verbose ) {
695 
696                                     HDfprintf(stdout,
697                                     "data_chunk[%0d][%0d] = %0d, expect %0d.\n",
698                                     k, l, data_chunk[k][l],
699                                     ((DSET_SIZE * DSET_SIZE * m) +
700                                      (DSET_SIZE * (i + k)) + j + l));
701                                     HDfprintf(stdout,
702                                     "m = %d, i = %d, j = %d, k = %d, l = %d\n",
703                                     m, i, j, k, l);
704                 }
705                             }
706                         }
707                     }
708 
709                     if ( ! valid_chunk ) {
710 
711                         pass = FALSE;
712                         failure_mssg = "slab validation failed.";
713 
714             if ( verbose ) {
715 
716                 HDfprintf(stdout,
717                                   "Chunk (%0d, %0d) in /dset%03d is invalid.\n",
718                                   i, j, m);
719             }
720                     }
721                 }
722                 m++;
723             }
724             j += CHUNK_SIZE;
725         }
726         i += CHUNK_SIZE;
727     }
728 
729     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
730 
731     /* close the file spaces */
732     i = min_dset;
733     while ( ( pass ) && ( i <= max_dset ) )
734     {
735         if ( H5Sclose(filespace_ids[i]) < 0 ) {
736 
737             pass = FALSE;
738             failure_mssg = "H5Sclose() failed.";
739         }
740         i++;
741     }
742 
743 
744     /* close the datasets */
745     i = min_dset;
746     while ( ( pass ) && ( i <= max_dset ) )
747     {
748         if ( H5Dclose(dataset_ids[i]) < 0 ) {
749 
750             pass = FALSE;
751             failure_mssg = "H5Dclose() failed.";
752         }
753         i++;
754     }
755 
756     /* close the mem space */
757     if ( pass ) {
758 
759         if ( H5Sclose(memspace_id) < 0 ) {
760 
761             pass = FALSE;
762             failure_mssg = "H5Sclose(memspace_id) failed.";
763         }
764     }
765 
766     return;
767 
768 } /* create_data_sets() */
769 
770 
771 /*-------------------------------------------------------------------------
772  * Function:    delete_data_sets()
773  *
774  * Purpose:     If pass is TRUE on entry, verify and then delete the
775  *        dataset(s) indicated by min_dset and max_dset in the
776  *        indicated file.
777  *
778  *        Data sets and their contents must be well know, as we
779  *        will verify that they contain the expected data later.
780  *
781  *              On failure, set pass to FALSE, and set failure_mssg
782  *              to point to an appropriate failure message.
783  *
784  *              Do nothing if pass is FALSE on entry.
785  *
786  * Return:      void
787  *
788  * Programmer:  John Mainzer
789  *              10/31/16
790  *
791  * Modifications:
792  *
793  *              None.
794  *                        JRM -- 8/20/15
795  *
796  *-------------------------------------------------------------------------
797  */
798 #if 0
799 /* this code will be needed to test full support of cache image
800  * in parallel -- keep it around against that day.
801  *
802  *                                      -- JRM
803  */
804 static void
805 delete_data_sets(hid_t file_id, int min_dset, int max_dset)
806 {
807     const char * fcn_name = "delete_data_sets()";
808     char dset_name[64];
809     hbool_t show_progress = FALSE;
810     int cp = 0;
811     int i;
812 
813     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
814 
815     HDassert(0 <= min_dset);
816     HDassert(min_dset <= max_dset);
817     HDassert(max_dset < MAX_NUM_DSETS);
818 
819     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
820 
821     /* first, verify the contents of the target dataset(s) */
822     verify_data_sets(file_id, min_dset, max_dset);
823 
824     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
825 
826     /* now delete the target datasets */
827     if ( pass ) {
828 
829         i = min_dset;
830 
831         while ( ( pass ) && ( i <= max_dset ) )
832         {
833             HDsprintf(dset_name, "/dset%03d", i);
834 
835         if ( H5Ldelete(file_id, dset_name, H5P_DEFAULT) < 0) {
836 
837                 pass = FALSE;
838                 failure_mssg = "H5Ldelete() failed.";
839         }
840 
841             i++;
842         }
843     }
844 
845     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
846 
847     return;
848 
849 } /* delete_data_sets() */
850 #endif
851 
852 
853 /*-------------------------------------------------------------------------
854  * Function:    open_hdf5_file()
855  *
856  * Purpose:     If pass is true on entry, create or open the specified HDF5
857  *        and test to see if it has a metadata cache image superblock
858  *        extension message.
859  *
860  *        Set pass to FALSE and issue a suitable failure
861  *        message if either the file contains a metadata cache image
862  *        superblock extension and mdci_sbem_expected is TRUE, or
863  *        vise versa.
864  *
865  *        If mdci_sbem_expected is TRUE, also verify that the metadata
866  *        cache has been advised of this.
867  *
868  *        If read_only is TRUE, open the file read only.  Otherwise
869  *        open the file read/write.
870  *
871  *        If set_mdci_fapl is TRUE, set the metadata cache image
872  *        FAPL entry when opening the file, and verify that the
873  *        metadata cache is notified.
874  *
875  *        If config_fsm is TRUE, setup the persistant free space
876  *        manager.  Note that this flag may only be set if
877  *        create_file is also TRUE.
878  *
879  *              Return pointers to the cache data structure and file data
880  *              structures.
881  *
882  *              On failure, set pass to FALSE, and set failure_mssg
883  *              to point to an appropriate failure message.
884  *
885  *              Do nothing if pass is FALSE on entry.
886  *
887  * Return:      void
888  *
889  * Programmer:  John Mainzer
890  *              7/14/15
891  *
892  * Modifications:
893  *
894  *              Modified function to handle parallel file creates / opens.
895  *
896  *                                                 JRM -- 2/1/17
897  *
898  *              Modified function to handle
899  *
900  *-------------------------------------------------------------------------
901  */
902 
903 static void
open_hdf5_file(const hbool_t create_file,const hbool_t mdci_sbem_expected,const hbool_t read_only,const hbool_t set_mdci_fapl,const hbool_t config_fsm,const hbool_t enable_page_buffer,const char * hdf_file_name,const unsigned cache_image_flags,hid_t * file_id_ptr,H5F_t ** file_ptr_ptr,H5C_t ** cache_ptr_ptr,MPI_Comm comm,MPI_Info info,int l_facc_type,const hbool_t all_coll_metadata_ops,const hbool_t coll_metadata_write,const int md_write_strat)904 open_hdf5_file(const hbool_t create_file,
905                const hbool_t mdci_sbem_expected,
906         const hbool_t read_only,
907         const hbool_t set_mdci_fapl,
908         const hbool_t config_fsm,
909                const hbool_t enable_page_buffer,
910         const char * hdf_file_name,
911                const unsigned cache_image_flags,
912                hid_t * file_id_ptr,
913                H5F_t ** file_ptr_ptr,
914                H5C_t ** cache_ptr_ptr,
915                MPI_Comm comm,
916                MPI_Info info,
917                int l_facc_type,
918                const hbool_t all_coll_metadata_ops,
919                const hbool_t coll_metadata_write,
920                const int md_write_strat)
921 {
922     const char * fcn_name = "open_hdf5_file()";
923     hbool_t show_progress = FALSE;
924     hbool_t verbose = FALSE;
925     int cp = 0;
926     hid_t fapl_id = -1;
927     hid_t fcpl_id = -1;
928     hid_t file_id = -1;
929     herr_t result;
930     H5F_t * file_ptr = NULL;
931     H5C_t * cache_ptr = NULL;
932     H5C_cache_image_ctl_t image_ctl;
933     H5AC_cache_image_config_t cache_image_config = {
934         H5AC__CURR_CACHE_IMAGE_CONFIG_VERSION,
935         TRUE,
936         FALSE,
937         H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE};
938 
939     HDassert(!create_file || config_fsm);
940 
941     if ( pass )
942     {
943     /* opening the file both read only and with a cache image
944          * requested is a contradiction.  We resolve it by ignoring
945          * the cache image request silently.
946          */
947         if ( ( create_file && mdci_sbem_expected ) ||
948              ( create_file && read_only ) ||
949              ( config_fsm && !create_file ) ||
950              ( create_file && enable_page_buffer && ! config_fsm ) ||
951              ( hdf_file_name == NULL ) ||
952              ( ( set_mdci_fapl ) && ( cache_image_flags == 0 ) ) ||
953              ( ( set_mdci_fapl ) &&
954                ( (cache_image_flags & ~H5C_CI__ALL_FLAGS) != 0 ) ) ||
955              ( file_id_ptr == NULL ) ||
956              ( file_ptr_ptr == NULL ) ||
957              ( cache_ptr_ptr == NULL ) ||
958              ( l_facc_type != (l_facc_type & (FACC_MPIO)) ) ) {
959 
960             failure_mssg =
961                "Bad param(s) on entry to open_hdf5_file().\n";
962 
963             pass = FALSE;
964         } else  if ( verbose ) {
965 
966             HDfprintf(stdout, "%s: HDF file name = \"%s\".\n",
967                       fcn_name, hdf_file_name);
968         }
969     }
970 
971     if ( show_progress )
972         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
973 
974     /* create a file access propertly list. */
975     if ( pass ) {
976 
977         fapl_id = H5Pcreate(H5P_FILE_ACCESS);
978 
979         if ( fapl_id < 0 ) {
980 
981             pass = FALSE;
982             failure_mssg = "H5Pcreate() failed.\n";
983         }
984     }
985 
986     if ( show_progress )
987         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
988 
989     /* call H5Pset_libver_bounds() on the fapl_id */
990     if ( pass ) {
991 
992         if ( H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST)
993                 < 0 ) {
994 
995             pass = FALSE;
996             failure_mssg = "H5Pset_libver_bounds() failed.\n";
997         }
998     }
999 
1000     if ( show_progress )
1001         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1002 
1003     /* get metadata cache image config -- verify that it is the default */
1004     if ( pass ) {
1005 
1006         result = H5Pget_mdc_image_config(fapl_id, &cache_image_config);
1007 
1008         if ( result < 0 ) {
1009 
1010             pass = FALSE;
1011             failure_mssg = "H5Pget_mdc_image_config() failed.\n";
1012         }
1013 
1014         if ( ( cache_image_config.version !=
1015                H5AC__CURR_CACHE_IMAGE_CONFIG_VERSION ) ||
1016              ( cache_image_config.generate_image != FALSE ) ||
1017              ( cache_image_config.save_resize_status != FALSE ) ||
1018              ( cache_image_config.entry_ageout !=
1019                H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE ) ) {
1020 
1021             pass = FALSE;
1022             failure_mssg = "Unexpected default cache image config.\n";
1023         }
1024     }
1025 
1026     if ( show_progress )
1027         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1028 
1029     /* set metadata cache image fapl entry if indicated */
1030     if ( ( pass ) && ( set_mdci_fapl ) ) {
1031 
1032         /* set cache image config fields to taste */
1033         cache_image_config.generate_image = TRUE;
1034         cache_image_config.save_resize_status = FALSE;
1035         cache_image_config.entry_ageout = H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE;
1036 
1037         result = H5Pset_mdc_image_config(fapl_id, &cache_image_config);
1038 
1039         if ( result < 0 ) {
1040 
1041             pass = FALSE;
1042             failure_mssg = "H5Pset_mdc_image_config() failed.\n";
1043         }
1044     }
1045 
1046     if ( show_progress )
1047         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1048 
1049     /* setup the persistant free space manager if indicated */
1050     if ( ( pass ) && ( config_fsm ) ) {
1051 
1052     fcpl_id = H5Pcreate(H5P_FILE_CREATE);
1053 
1054     if ( fcpl_id <= 0 ) {
1055 
1056         pass = FALSE;
1057         failure_mssg = "H5Pcreate(H5P_FILE_CREATE) failed.";
1058     }
1059     }
1060 
1061     if ( ( pass ) && ( config_fsm ) ) {
1062 
1063         if ( H5Pset_file_space_strategy(fcpl_id, H5F_FSPACE_STRATEGY_PAGE,
1064                                         TRUE, (hsize_t)1) == FAIL ) {
1065             pass = FALSE;
1066             failure_mssg = "H5Pset_file_space_strategy() failed.\n";
1067         }
1068     }
1069 
1070     if ( ( pass ) && ( config_fsm ) ) {
1071 
1072         if ( H5Pset_file_space_page_size(fcpl_id, PAGE_SIZE) == FAIL ) {
1073 
1074             pass = FALSE;
1075             failure_mssg = "H5Pset_file_space_page_size() failed.\n";
1076         }
1077     }
1078 
1079     if ( show_progress )
1080         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1081 
1082     /* setup the page buffer if indicated */
1083     if ( ( pass ) && ( enable_page_buffer ) ) {
1084 
1085         if ( H5Pset_page_buffer_size(fapl_id, PB_SIZE, 0, 0) < 0 ) {
1086 
1087             pass = FALSE;
1088             failure_mssg = "H5Pset_page_buffer_size() failed.\n";
1089         }
1090     }
1091 
1092     if ( show_progress )
1093         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1094 
1095 
1096     if ( ( pass ) && ( l_facc_type == FACC_MPIO ) ) {
1097 
1098         /* set Parallel access with communicator */
1099         if ( H5Pset_fapl_mpio(fapl_id, comm, info) < 0 ) {
1100 
1101             pass = FALSE;
1102             failure_mssg = "H5Pset_fapl_mpio() failed.\n";
1103         }
1104     }
1105 
1106     if ( show_progress )
1107         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1108 
1109     if ( ( pass ) && ( l_facc_type == FACC_MPIO ) ) {
1110 
1111         if (H5Pset_all_coll_metadata_ops(fapl_id, all_coll_metadata_ops) < 0) {
1112 
1113             pass = FALSE;
1114             failure_mssg = "H5Pset_all_coll_metadata_ops() failed.\n";
1115         }
1116     }
1117 
1118     if ( show_progress )
1119         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1120 
1121     if ( ( pass ) && ( l_facc_type == FACC_MPIO ) ) {
1122 
1123         if ( H5Pset_coll_metadata_write(fapl_id, coll_metadata_write) < 0 ) {
1124 
1125             pass = FALSE;
1126             failure_mssg = "H5Pset_coll_metadata_write() failed.\n";
1127         }
1128     }
1129 
1130     if ( show_progress )
1131         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1132 
1133     if ( ( pass ) && ( l_facc_type == FACC_MPIO ) ) {
1134 
1135         /* set the desired parallel metadata write strategy */
1136         H5AC_cache_config_t mdc_config;
1137 
1138         mdc_config.version = H5C__CURR_AUTO_SIZE_CTL_VER;
1139 
1140         if ( H5Pget_mdc_config(fapl_id, &mdc_config) < 0 ) {
1141 
1142             pass = FALSE;
1143             failure_mssg = "H5Pget_mdc_config() failed.\n";
1144         }
1145 
1146         mdc_config.metadata_write_strategy = md_write_strat;
1147 
1148         if ( H5Pset_mdc_config(fapl_id, &mdc_config) < 0 ) {
1149 
1150             pass = FALSE;
1151             failure_mssg = "H5Pset_mdc_config() failed.\n";
1152         }
1153     }
1154 
1155     if ( show_progress )
1156         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1157 
1158     /* open the file */
1159     if ( pass ) {
1160 
1161         if ( create_file ) {
1162 
1163         if ( fcpl_id != -1 )
1164 
1165                 file_id = H5Fcreate(hdf_file_name, H5F_ACC_TRUNC,
1166                     fcpl_id, fapl_id);
1167         else
1168 
1169         file_id = H5Fcreate(hdf_file_name, H5F_ACC_TRUNC,
1170                                     H5P_DEFAULT, fapl_id);
1171 
1172         } else {
1173 
1174             if ( read_only )
1175 
1176                 file_id = H5Fopen(hdf_file_name, H5F_ACC_RDONLY, fapl_id);
1177 
1178             else
1179 
1180                 file_id = H5Fopen(hdf_file_name, H5F_ACC_RDWR, fapl_id);
1181         }
1182 
1183         if ( file_id < 0 ) {
1184 
1185             pass = FALSE;
1186             failure_mssg = "H5Fcreate() or H5Fopen() failed.\n";
1187 
1188         } else {
1189 
1190             file_ptr = (struct H5F_t *)H5I_object_verify(file_id, H5I_FILE);
1191 
1192             if ( file_ptr == NULL ) {
1193 
1194                 pass = FALSE;
1195                 failure_mssg = "Can't get file_ptr.";
1196 
1197                 if ( verbose ) {
1198                     HDfprintf(stdout, "%s: Can't get file_ptr.\n", fcn_name);
1199                 }
1200             }
1201         }
1202     }
1203 
1204     if ( show_progress )
1205         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1206 
1207     /* get a pointer to the files internal data structure and then
1208      * to the cache structure
1209      */
1210     if ( pass ) {
1211 
1212         if ( file_ptr->shared->cache == NULL ) {
1213 
1214             pass = FALSE;
1215             failure_mssg = "can't get cache pointer(1).\n";
1216 
1217         } else {
1218 
1219             cache_ptr = file_ptr->shared->cache;
1220         }
1221     }
1222 
1223     if ( show_progress )
1224         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1225 
1226 
1227     /* verify expected page buffer status.  At present, page buffering
1228      * must be disabled in parallel -- hopefully this will change in the
1229      * future.
1230      */
1231     if ( pass ) {
1232 
1233         if ( ( file_ptr->shared->page_buf ) &&
1234              ( ( ! enable_page_buffer ) || ( l_facc_type == FACC_MPIO ) ) ) {
1235 
1236             pass = FALSE;
1237             failure_mssg = "page buffer unexepectedly enabled.";
1238 
1239         } else if ( ( file_ptr->shared->page_buf != NULL ) &&
1240              ( ( enable_page_buffer ) || ( l_facc_type != FACC_MPIO ) ) ) {
1241 
1242             pass = FALSE;
1243             failure_mssg = "page buffer unexepectedly disabled.";
1244         }
1245     }
1246 
1247     if ( show_progress )
1248         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1249 
1250 
1251     /* verify expected metadata cache status */
1252 
1253     /* get the cache image control structure from the cache, and verify
1254      * that it contains the expected values.
1255      *
1256      * Then set the flags in this structure to the specified value.
1257      */
1258     if ( pass ) {
1259 
1260         if ( H5C_get_cache_image_config(cache_ptr, &image_ctl) < 0 ) {
1261 
1262             pass = FALSE;
1263             failure_mssg = "error returned by H5C_get_cache_image_config().";
1264         }
1265     }
1266 
1267     if ( show_progress )
1268         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1269 
1270 
1271     if ( pass ) {
1272 
1273         if ( set_mdci_fapl ) {
1274 
1275         if ( read_only ) {
1276 
1277                 if ( ( image_ctl.version !=
1278                        H5AC__CURR_CACHE_IMAGE_CONFIG_VERSION ) ||
1279                      ( image_ctl.generate_image != FALSE ) ||
1280                      ( image_ctl.save_resize_status != FALSE ) ||
1281                      ( image_ctl.entry_ageout !=
1282                        H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE ) ||
1283                      ( image_ctl.flags != H5C_CI__ALL_FLAGS ) ) {
1284 
1285                     pass = FALSE;
1286                     failure_mssg = "Unexpected image_ctl values(1).\n";
1287                 }
1288         } else {
1289 
1290                 if ( ( image_ctl.version !=
1291                        H5AC__CURR_CACHE_IMAGE_CONFIG_VERSION ) ||
1292                      ( image_ctl.generate_image != TRUE ) ||
1293                      ( image_ctl.save_resize_status != FALSE ) ||
1294                      ( image_ctl.entry_ageout !=
1295                        H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE ) ||
1296                      ( image_ctl.flags != H5C_CI__ALL_FLAGS ) ) {
1297 
1298                     pass = FALSE;
1299                     failure_mssg = "Unexpected image_ctl values(2).\n";
1300                 }
1301             }
1302         } else {
1303 
1304             if ( ( image_ctl.version !=
1305                    H5AC__CURR_CACHE_IMAGE_CONFIG_VERSION ) ||
1306                  ( image_ctl.generate_image != FALSE ) ||
1307                  ( image_ctl.save_resize_status != FALSE ) ||
1308                  ( image_ctl.entry_ageout !=
1309                    H5AC__CACHE_IMAGE__ENTRY_AGEOUT__NONE ) ||
1310                  ( image_ctl.flags != H5C_CI__ALL_FLAGS ) ) {
1311 
1312                 pass = FALSE;
1313                 failure_mssg = "Unexpected image_ctl values(3).\n";
1314             }
1315         }
1316     }
1317 
1318     if ( show_progress )
1319         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1320 
1321     if ( ( pass ) && ( set_mdci_fapl ) ) {
1322 
1323         image_ctl.flags = cache_image_flags;
1324 
1325         if ( H5C_set_cache_image_config(file_ptr, cache_ptr, &image_ctl) < 0 ) {
1326 
1327             pass = FALSE;
1328             failure_mssg = "error returned by H5C_set_cache_image_config().";
1329         }
1330     }
1331 
1332     if ( show_progress )
1333         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1334 
1335     if ( pass ) {
1336 
1337         if ( cache_ptr->close_warning_received == TRUE ) {
1338 
1339             pass = FALSE;
1340             failure_mssg = "Unexpected value of close_warning_received.\n";
1341         }
1342 
1343         if ( mdci_sbem_expected ) {
1344 
1345             if ( read_only ) {
1346 
1347                 if ( ( cache_ptr->load_image != TRUE ) ||
1348                      ( cache_ptr->delete_image != FALSE ) ) {
1349 
1350                     pass = FALSE;
1351                     failure_mssg = "mdci sb extension message not present?\n";
1352                 }
1353             } else {
1354 
1355                 if ( ( cache_ptr->load_image != TRUE ) ||
1356                      ( cache_ptr->delete_image != TRUE ) ) {
1357 
1358                     pass = FALSE;
1359                     failure_mssg = "mdci sb extension message not present?\n";
1360                 }
1361         }
1362         } else {
1363 
1364         if ( ( cache_ptr->load_image == TRUE ) ||
1365                  ( cache_ptr->delete_image == TRUE ) ) {
1366 
1367                 pass = FALSE;
1368                 failure_mssg = "mdci sb extension message present?\n";
1369         }
1370         }
1371     }
1372 
1373     if ( show_progress )
1374         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1375 
1376     if ( pass ) {
1377 
1378         *file_id_ptr = file_id;
1379         *file_ptr_ptr = file_ptr;
1380         *cache_ptr_ptr = cache_ptr;
1381     }
1382 
1383     if ( show_progress ) {
1384         HDfprintf(stdout, "%s: cp = %d, pass = %d -- exiting.\n",
1385                   fcn_name, cp++, pass);
1386 
1387         if ( ! pass )
1388             HDfprintf(stdout, "%s: failure_mssg = %s\n",
1389                       fcn_name, failure_mssg);
1390     }
1391 
1392     return;
1393 
1394 } /* open_hdf5_file() */
1395 
1396 
1397 /*-------------------------------------------------------------------------
1398  * Function:    par_create_dataset()
1399  *
1400  * Purpose:     Collectively create a chunked dataset, and fill it with
1401  *              known values.
1402  *
1403  *              On failure, set pass to FALSE, and set failure_mssg
1404  *              to point to an appropriate failure message.
1405  *
1406  *              Do nothing if pass is FALSE on entry.
1407  *
1408  * Return:      void
1409  *
1410  * Programmer:  John Mainzer
1411  *              3/4/17
1412  *
1413  * Modifications:
1414  *
1415  *              None.
1416  *
1417  *-------------------------------------------------------------------------
1418  */
1419 
1420 static void
par_create_dataset(int dset_num,hid_t file_id,int mpi_rank,int mpi_size)1421 par_create_dataset(int dset_num,
1422                    hid_t file_id,
1423                    int mpi_rank,
1424                    int mpi_size)
1425 {
1426     const char * fcn_name = "par_create_dataset()";
1427     char dset_name[256];
1428     hbool_t show_progress = FALSE;
1429     hbool_t valid_chunk;
1430     hbool_t verbose = FALSE;
1431     int cp = 0;
1432     int i, j, k, l;
1433     int data_chunk[1][CHUNK_SIZE][CHUNK_SIZE];
1434     hsize_t dims[3];
1435     hsize_t a_size[3];
1436     hsize_t offset[3];
1437     hsize_t chunk_size[3];
1438     hid_t status;
1439     hid_t dataspace_id = -1;
1440     hid_t memspace_id = -1;
1441     hid_t dset_id = -1;
1442     hid_t filespace_id = -1;
1443     hid_t dcpl_id = -1;
1444     hid_t dxpl_id = -1;
1445 
1446     show_progress = (show_progress && (mpi_rank == 0));
1447     verbose       = (verbose && (mpi_rank == 0));
1448 
1449     HDsprintf(dset_name, "/dset%03d", dset_num);
1450 
1451     if ( show_progress ) {
1452         HDfprintf(stdout, "%s: dset name = \"%s\".\n", fcn_name, dset_name);
1453         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1454     }
1455 
1456     if ( pass ) {
1457 
1458         /* create a dataspace for the chunked dataset */
1459         dims[0] = (hsize_t)mpi_size;
1460         dims[1] = DSET_SIZE;
1461         dims[2] = DSET_SIZE;
1462         dataspace_id = H5Screate_simple(3, dims, NULL);
1463 
1464         if ( dataspace_id < 0 ) {
1465 
1466             pass = FALSE;
1467             failure_mssg = "H5Screate_simple() failed.";
1468         }
1469     }
1470 
1471     if ( show_progress )
1472         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1473 
1474     /* set the dataset creation plist to specify that the raw data is
1475      * to be partioned into 1X10X10 element chunks.
1476      */
1477 
1478     if ( pass ) {
1479 
1480         dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
1481 
1482         if ( dcpl_id < 0 ) {
1483 
1484             pass = FALSE;
1485             failure_mssg = "H5Pcreate(H5P_DATASET_CREATE) failed.";
1486         }
1487     }
1488 
1489     if ( show_progress )
1490         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1491 
1492     if ( pass ) {
1493 
1494         chunk_size[0] = 1;
1495         chunk_size[1] = CHUNK_SIZE;
1496         chunk_size[2] = CHUNK_SIZE;
1497 
1498         if ( H5Pset_chunk(dcpl_id, 3, chunk_size) < 0 ) {
1499 
1500             pass = FALSE;
1501             failure_mssg = "H5Pset_chunk() failed.";
1502         }
1503     }
1504 
1505     if ( show_progress )
1506         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1507 
1508     /* create the dataset */
1509     if ( pass ) {
1510 
1511         dset_id = H5Dcreate2(file_id, dset_name, H5T_STD_I32BE,
1512                              dataspace_id, H5P_DEFAULT,
1513                              dcpl_id, H5P_DEFAULT);
1514 
1515         if ( dset_id < 0 ) {
1516 
1517             pass = FALSE;
1518             failure_mssg = "H5Dcreate() failed.";
1519         }
1520     }
1521 
1522     if ( show_progress )
1523         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1524 
1525     /* get the file space ID */
1526     if ( pass ) {
1527 
1528         filespace_id = H5Dget_space(dset_id);
1529 
1530         if ( filespace_id < 0 ) {
1531 
1532             pass = FALSE;
1533             failure_mssg = "H5Dget_space() failed.";
1534         }
1535     }
1536 
1537     if ( show_progress )
1538         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1539 
1540     /* create the mem space to be used to read and write chunks */
1541     if ( pass ) {
1542 
1543         dims[0] = 1;
1544         dims[1] = CHUNK_SIZE;
1545         dims[2] = CHUNK_SIZE;
1546         memspace_id = H5Screate_simple(3, dims, NULL);
1547 
1548         if ( memspace_id < 0 ) {
1549 
1550             pass = FALSE;
1551             failure_mssg = "H5Screate_simple() failed.";
1552         }
1553     }
1554 
1555     if ( show_progress )
1556         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1557 
1558     /* select in memory hyperslab */
1559     if ( pass ) {
1560 
1561         offset[0] = 0;                  /* offset of hyperslab in memory */
1562         offset[1] = 0;
1563         offset[2] = 0;
1564         a_size[0] = 1;                  /* size of hyperslab */
1565         a_size[1] = CHUNK_SIZE;
1566         a_size[2] = CHUNK_SIZE;
1567         status = H5Sselect_hyperslab(memspace_id, H5S_SELECT_SET, offset, NULL,
1568                                      a_size, NULL);
1569 
1570         if ( status < 0 ) {
1571 
1572             pass = FALSE;
1573             failure_mssg = "H5Sselect_hyperslab() failed.";
1574         }
1575     }
1576 
1577     if ( show_progress )
1578         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1579 
1580     /* setup the DXPL for collective I/O */
1581     if ( pass ) {
1582 
1583         dxpl_id = H5Pcreate(H5P_DATASET_XFER);
1584 
1585         if ( dxpl_id < 0 ) {
1586 
1587             pass = FALSE;
1588             failure_mssg = "H5Pcreate(H5P_DATASET_XFER) failed.";
1589         }
1590     }
1591 
1592     if ( show_progress )
1593         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1594 
1595     if ( pass ) {
1596 
1597         if ( H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) < 0 ) {
1598 
1599             pass = FALSE;
1600             failure_mssg = "H5Pset_dxpl_mpio() failed.";
1601         }
1602     }
1603 
1604     if ( show_progress )
1605         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1606 
1607     /* initialize the dataset with collective writes */
1608     i = 0;
1609     while ( ( pass ) && ( i < DSET_SIZE ) )
1610     {
1611         j = 0;
1612         while ( ( pass ) && ( j < DSET_SIZE ) )
1613         {
1614 
1615             if ( show_progress )
1616                 HDfprintf(stdout, "%s: cp = %d.0, pass = %d.\n",
1617                           fcn_name, cp, pass);
1618 
1619             /* initialize the slab */
1620             for ( k = 0; k < CHUNK_SIZE; k++ )
1621             {
1622                 for ( l = 0; l < CHUNK_SIZE; l++ )
1623                 {
1624                     data_chunk[0][k][l] = (DSET_SIZE * DSET_SIZE * mpi_rank) +
1625                                           (DSET_SIZE * (i + k)) + j + l +
1626                                           dset_num;
1627                 }
1628             }
1629 
1630             if ( show_progress )
1631                 HDfprintf(stdout, "%s: cp = %d.1, pass = %d.\n",
1632                           fcn_name, cp, pass);
1633 
1634             /* select on disk hyperslab */
1635             offset[0] = (hsize_t)mpi_rank; /* offset of hyperslab in file */
1636             offset[1] = (hsize_t)i;
1637             offset[2] = (hsize_t)j;
1638             a_size[0] = (hsize_t)1;        /* size of hyperslab */
1639             a_size[1] = CHUNK_SIZE;
1640             a_size[2] = CHUNK_SIZE;
1641             status = H5Sselect_hyperslab(filespace_id, H5S_SELECT_SET,
1642                                          offset, NULL, a_size, NULL);
1643 
1644             if ( status < 0 ) {
1645 
1646                 pass = FALSE;
1647                 failure_mssg = "disk H5Sselect_hyperslab() failed.";
1648             }
1649 
1650             if ( show_progress )
1651                 HDfprintf(stdout, "%s: cp = %d.2, pass = %d.\n",
1652                           fcn_name, cp, pass);
1653 
1654             /* write the chunk to file */
1655             status = H5Dwrite(dset_id, H5T_NATIVE_INT, memspace_id,
1656                               filespace_id, dxpl_id, data_chunk);
1657 
1658             if ( status < 0 ) {
1659 
1660                 pass = FALSE;
1661                 failure_mssg = "H5Dwrite() failed.";
1662             }
1663 
1664             if ( show_progress )
1665                 HDfprintf(stdout, "%s: cp = %d.3, pass = %d.\n",
1666                           fcn_name, cp, pass);
1667 
1668             j += CHUNK_SIZE;
1669         }
1670 
1671         i += CHUNK_SIZE;
1672     }
1673 
1674     cp++;
1675     if ( show_progress )
1676         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1677 
1678     /* read data from data sets and validate it */
1679     i = 0;
1680     while ( ( pass ) && ( i < DSET_SIZE ) )
1681     {
1682         j = 0;
1683         while ( ( pass ) && ( j < DSET_SIZE ) )
1684         {
1685             /* select on disk hyperslab */
1686             offset[0] = (hsize_t)mpi_rank;
1687             offset[1] = (hsize_t)i; /* offset of hyperslab in file */
1688             offset[2] = (hsize_t)j;
1689             a_size[0] = (hsize_t)1;
1690             a_size[1] = CHUNK_SIZE; /* size of hyperslab */
1691             a_size[2] = CHUNK_SIZE;
1692 
1693             status = H5Sselect_hyperslab(filespace_id, H5S_SELECT_SET,
1694                                          offset, NULL, a_size, NULL);
1695 
1696             if ( status < 0 ) {
1697 
1698                pass = FALSE;
1699                failure_mssg = "disk hyperslab create failed.";
1700             }
1701 
1702             /* read the chunk from file */
1703             if ( pass ) {
1704 
1705                 status = H5Dread(dset_id, H5T_NATIVE_INT,
1706                                  memspace_id, filespace_id,
1707                                  dxpl_id, data_chunk);
1708 
1709                 if ( status < 0 ) {
1710 
1711                    pass = FALSE;
1712                    failure_mssg = "chunk read failed.";
1713                 }
1714             }
1715 
1716             /* validate the slab */
1717             if ( pass ) {
1718 
1719                 valid_chunk = TRUE;
1720                 for ( k = 0; k < CHUNK_SIZE; k++ )
1721                 {
1722                     for ( l = 0; l < CHUNK_SIZE; l++ )
1723                     {
1724                         if ( data_chunk[0][k][l]
1725                              !=
1726                              ((DSET_SIZE * DSET_SIZE * mpi_rank) +
1727                               (DSET_SIZE * (i + k)) + j + l + dset_num) ) {
1728 
1729                             valid_chunk = FALSE;
1730 
1731                             if ( verbose ) {
1732 
1733                                 HDfprintf(stdout,
1734                                     "data_chunk[%0d][%0d] = %0d, expect %0d.\n",
1735                                     k, l, data_chunk[0][k][l],
1736                                     ((DSET_SIZE * DSET_SIZE * mpi_rank) +
1737                                      (DSET_SIZE * (i + k)) + j + l + dset_num));
1738                                     HDfprintf(stdout,
1739                                     "dset_num = %d, i = %d, j = %d, k = %d, l = %d\n",
1740                                     dset_num, i, j, k, l);
1741                             }
1742                         }
1743                     }
1744                 }
1745 
1746                 if ( ! valid_chunk ) {
1747 
1748                     pass = FALSE;
1749                     failure_mssg = "slab validation failed.";
1750 
1751                     if ( verbose ) {
1752 
1753                         HDfprintf(stdout,
1754                                 "Chunk (%0d, %0d) in /dset%03d is invalid.\n",
1755                                 i, j, dset_num);
1756                     }
1757                 }
1758             }
1759             j += CHUNK_SIZE;
1760         }
1761         i += CHUNK_SIZE;
1762     }
1763 
1764     if ( show_progress )
1765         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1766 
1767     /* close the data space */
1768     if ( ( pass ) && ( H5Sclose(dataspace_id) < 0 ) ) {
1769 
1770         pass = FALSE;
1771         failure_mssg = "H5Sclose(dataspace_id) failed.";
1772     }
1773 
1774     /* close the file space */
1775     if ( ( pass ) && ( H5Sclose(filespace_id) < 0 ) ) {
1776 
1777         pass = FALSE;
1778         failure_mssg = "H5Sclose(filespace_id) failed.";
1779     }
1780 
1781     /* close the dataset */
1782     if ( ( pass ) && ( H5Dclose(dset_id) < 0 ) )  {
1783 
1784         pass = FALSE;
1785         failure_mssg = "H5Dclose(dset_id) failed.";
1786     }
1787 
1788     /* close the mem space */
1789     if ( ( pass ) && ( H5Sclose(memspace_id) < 0 ) ) {
1790 
1791         pass = FALSE;
1792         failure_mssg = "H5Sclose(memspace_id) failed.";
1793     }
1794 
1795     /* close the dataset creation property list */
1796     if ( ( pass ) && ( H5Pclose(dcpl_id) < 0 ) ) {
1797 
1798         pass = FALSE;
1799         failure_mssg = "H5Pclose(dcpl) failed.";
1800     }
1801 
1802     /* close the data access property list */
1803     if ( ( pass ) && ( H5Pclose(dxpl_id) < 0 ) ) {
1804 
1805         pass = FALSE;
1806         failure_mssg = "H5Pclose(dxpl) failed.";
1807     }
1808 
1809     if ( show_progress )
1810         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1811 
1812     return;
1813 
1814 } /* par_create_dataset() */
1815 
1816 
1817 /*-------------------------------------------------------------------------
1818  * Function:    par_delete_dataset()
1819  *
1820  * Purpose:     Collectively delete the specified dataset.
1821  *
1822  *              On failure, set pass to FALSE, and set failure_mssg
1823  *              to point to an appropriate failure message.
1824  *
1825  *              Do nothing if pass is FALSE on entry.
1826  *
1827  * Return:      void
1828  *
1829  * Programmer:  John Mainzer
1830  *              3/6/17
1831  *
1832  * Modifications:
1833  *
1834  *              None.
1835  *
1836  *-------------------------------------------------------------------------
1837  */
1838 
1839 static void
par_delete_dataset(int dset_num,hid_t file_id,int mpi_rank)1840 par_delete_dataset(int dset_num,
1841                    hid_t file_id,
1842                    int mpi_rank)
1843 {
1844     const char * fcn_name = "par_delete_dataset()";
1845     char dset_name[256];
1846     hbool_t show_progress = FALSE;
1847     int cp = 0;
1848 
1849     show_progress = (show_progress && (mpi_rank == 0));
1850 
1851     HDsprintf(dset_name, "/dset%03d", dset_num);
1852 
1853     if ( show_progress ) {
1854         HDfprintf(stdout, "%s: dset name = \"%s\".\n", fcn_name, dset_name);
1855         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1856     }
1857 
1858     /* verify the target dataset */
1859     if ( pass ) {
1860 
1861         par_verify_dataset(dset_num, file_id, mpi_rank);
1862     }
1863 
1864     if ( show_progress )
1865         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1866 
1867     /* delete the target dataset */
1868     if ( pass ) {
1869 
1870         if ( H5Ldelete(file_id, dset_name, H5P_DEFAULT) < 0) {
1871 
1872             pass = FALSE;
1873             failure_mssg = "H5Ldelete() failed.";
1874         }
1875     }
1876 
1877     if ( show_progress )
1878         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
1879 
1880     return;
1881 
1882 } /* par_delete_dataset() */
1883 
1884 
1885 /* This test uses many POSIX things that are not available on
1886  * Windows. We're using a check for fork(2) here as a proxy for
1887  * all POSIX/Unix/Linux things until this test can be made
1888  * more platform-independent.
1889  */
1890 #ifdef H5_HAVE_FORK
1891 
1892 
1893 /*-------------------------------------------------------------------------
1894  * Function:    par_insert_cache_image()
1895  *
1896  * Purpose:     Insert a cache image in the supplied file.
1897  *
1898  *              At present, cache image is not enabled in the parallel
1899  *              so we have to insert the cache image with a serial
1900  *              process.  Do this via a fork and an execv from process 0.
1901  *              All processes wait until the child process completes, and
1902  *              then return.
1903  *
1904  *              On failure, set pass to FALSE, and set failure_mssg
1905  *              to point to an appropriate failure message.
1906  *
1907  *              Do nothing if pass is FALSE on entry.
1908  *
1909  * Return:      void
1910  *
1911  * Programmer:  John Mainzer
1912  *              3/8/17
1913  *
1914  * Modifications:
1915  *
1916  *              None.
1917  *
1918  *-------------------------------------------------------------------------
1919  */
1920 
1921 static void
par_insert_cache_image(int file_name_idx,int mpi_rank,int mpi_size)1922 par_insert_cache_image(int file_name_idx, int mpi_rank, int mpi_size )
1923 {
1924     hbool_t show_progress = FALSE;
1925 
1926     if ( pass ) {
1927 
1928         if ( mpi_rank == 0 ) { /* insert cache image in supplied test file */
1929 
1930             char file_name_idx_str[32];
1931             char mpi_size_str[32];
1932             int child_status;
1933             pid_t child_pid;
1934 
1935             HDsprintf(file_name_idx_str, "%d", file_name_idx);
1936             HDsprintf(mpi_size_str, "%d", mpi_size);
1937 
1938             child_pid = fork();
1939 
1940             if ( child_pid == 0 ) { /* this is the child process */
1941 
1942                 /* fun and games to shutup the compiler */
1943                 char param0[32] = "t_cache_image";
1944                 char param1[32] = "ici";
1945                 char * child_argv[] = {param0,
1946                                        param1,
1947                                        file_name_idx_str,
1948                                        mpi_size_str,
1949                                        NULL};
1950 
1951                 /* we may need to play with the path here */
1952                 if ( execv("t_cache_image", child_argv) == -1 ) {
1953 
1954                     HDfprintf(stdout,
1955                              "execl() of ici process failed. errno = %d(%s)\n",
1956                              errno, strerror(errno));
1957                     HDexit(1);
1958                 }
1959 
1960             } else if ( child_pid != -1 ) {
1961                 /* this is the parent process -- wait until child is done */
1962                 if ( -1 == waitpid(child_pid, &child_status, WUNTRACED)) {
1963 
1964                     HDfprintf(stdout, "can't wait on ici process.\n");
1965                     pass = FALSE;
1966 
1967                 } else if ( ! WIFEXITED(child_status) ) {
1968 
1969                     HDfprintf(stdout, "ici process hasn't exitied.\n");
1970                     pass = FALSE;
1971 
1972                 } else if ( WEXITSTATUS(child_status) != 0 ) {
1973 
1974                     HDfprintf(stdout, "ici process reports failure.\n");
1975                     pass = FALSE;
1976 
1977                 } else if ( show_progress ) {
1978 
1979                     HDfprintf(stdout, "cache image insertion complete.\n");
1980                 }
1981             } else { /* fork failed */
1982 
1983                 HDfprintf(stdout,
1984                           "can't create process to insert cache image.\n");
1985                 pass = FALSE;
1986             }
1987         }
1988     }
1989 
1990     if ( pass ) {
1991 
1992         /* make sure insertion of the cache image is complete
1993          * before proceeding
1994          */
1995         MPI_Barrier(MPI_COMM_WORLD);
1996     }
1997 
1998     return;
1999 
2000 } /* par_insert_cache_image() */
2001 #else /* H5_HAVE_FORK */
2002 
2003 static void
par_insert_cache_image(int file_name_idx,int mpi_rank,int mpi_size)2004 par_insert_cache_image(int file_name_idx, int mpi_rank, int mpi_size )
2005 {
2006     return;
2007 } /* par_insert_cache_image() */
2008 
2009 #endif /* H5_HAVE_FORK */
2010 
2011 
2012 /*-------------------------------------------------------------------------
2013  * Function:    par_verify_dataset()
2014  *
2015  * Purpose:     Collectively verify the contents of a chunked dataset.
2016  *
2017  *              On failure, set pass to FALSE, and set failure_mssg
2018  *              to point to an appropriate failure message.
2019  *
2020  *              Do nothing if pass is FALSE on entry.
2021  *
2022  * Return:      void
2023  *
2024  * Programmer:  John Mainzer
2025  *              3/6/17
2026  *
2027  * Modifications:
2028  *
2029  *              None.
2030  *
2031  *-------------------------------------------------------------------------
2032  */
2033 
2034 static void
par_verify_dataset(int dset_num,hid_t file_id,int mpi_rank)2035 par_verify_dataset(int dset_num,
2036                    hid_t file_id,
2037                    int mpi_rank)
2038 {
2039     const char * fcn_name = "par_verify_dataset()";
2040     char dset_name[256];
2041     hbool_t show_progress = FALSE;
2042     hbool_t valid_chunk;
2043     hbool_t verbose = FALSE;
2044     int cp = 0;
2045     int i, j, k, l;
2046     int data_chunk[1][CHUNK_SIZE][CHUNK_SIZE];
2047     hsize_t dims[3];
2048     hsize_t a_size[3];
2049     hsize_t offset[3];
2050     hid_t status;
2051     hid_t memspace_id = -1;
2052     hid_t dset_id = -1;
2053     hid_t filespace_id = -1;
2054     hid_t dxpl_id = -1;
2055 
2056     show_progress = (show_progress && (mpi_rank == 0));
2057     verbose       = (verbose && (mpi_rank == 0));
2058 
2059     HDsprintf(dset_name, "/dset%03d", dset_num);
2060 
2061     if ( show_progress ) {
2062         HDfprintf(stdout, "%s: dset name = \"%s\".\n", fcn_name, dset_name);
2063         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2064     }
2065 
2066     if ( pass ) {
2067 
2068         /* open the dataset */
2069 
2070         dset_id = H5Dopen2(file_id, dset_name, H5P_DEFAULT);
2071 
2072         if ( dset_id < 0 ) {
2073 
2074             pass = FALSE;
2075             failure_mssg = "H5Dopen2() failed.";
2076         }
2077     }
2078 
2079     /* get the file space ID */
2080     if ( pass ) {
2081 
2082         filespace_id = H5Dget_space(dset_id);
2083 
2084         if ( filespace_id < 0 ) {
2085 
2086             pass = FALSE;
2087             failure_mssg = "H5Dget_space() failed.";
2088         }
2089     }
2090 
2091     if ( show_progress )
2092         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2093 
2094     /* create the mem space to be used to read */
2095     if ( pass ) {
2096 
2097         dims[0] = 1;
2098         dims[1] = CHUNK_SIZE;
2099         dims[2] = CHUNK_SIZE;
2100         memspace_id = H5Screate_simple(3, dims, NULL);
2101 
2102         if ( memspace_id < 0 ) {
2103 
2104             pass = FALSE;
2105             failure_mssg = "H5Screate_simple() failed.";
2106         }
2107     }
2108 
2109     if ( show_progress )
2110         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2111 
2112     /* select in memory hyperslab */
2113     if ( pass ) {
2114 
2115         offset[0] = 0;                  /* offset of hyperslab in memory */
2116         offset[1] = 0;
2117         offset[2] = 0;
2118         a_size[0] = 1;                  /* size of hyperslab */
2119         a_size[1] = CHUNK_SIZE;
2120         a_size[2] = CHUNK_SIZE;
2121         status = H5Sselect_hyperslab(memspace_id, H5S_SELECT_SET, offset, NULL,
2122                                      a_size, NULL);
2123 
2124         if ( status < 0 ) {
2125 
2126             pass = FALSE;
2127             failure_mssg = "H5Sselect_hyperslab() failed.";
2128         }
2129     }
2130 
2131     if ( show_progress )
2132         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2133 
2134     /* setup the DXPL for collective I/O */
2135     if ( pass ) {
2136 
2137         dxpl_id = H5Pcreate(H5P_DATASET_XFER);
2138 
2139         if ( dxpl_id < 0 ) {
2140 
2141             pass = FALSE;
2142             failure_mssg = "H5Pcreate(H5P_DATASET_XFER) failed.";
2143         }
2144     }
2145 
2146     if ( show_progress )
2147         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2148 
2149     if ( pass ) {
2150 
2151         if ( H5Pset_dxpl_mpio(dxpl_id, H5FD_MPIO_COLLECTIVE) < 0 ) {
2152 
2153             pass = FALSE;
2154             failure_mssg = "H5Pset_dxpl_mpio() failed.";
2155         }
2156     }
2157 
2158     if ( show_progress )
2159         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2160 
2161     /* read data from data sets and validate it */
2162     i = 0;
2163     while ( ( pass ) && ( i < DSET_SIZE ) )
2164     {
2165         j = 0;
2166         while ( ( pass ) && ( j < DSET_SIZE ) )
2167         {
2168             /* select on disk hyperslab */
2169             offset[0] = (hsize_t)mpi_rank;
2170             offset[1] = (hsize_t)i; /* offset of hyperslab in file */
2171             offset[2] = (hsize_t)j;
2172             a_size[0] = (hsize_t)1;
2173             a_size[1] = CHUNK_SIZE; /* size of hyperslab */
2174             a_size[2] = CHUNK_SIZE;
2175 
2176             status = H5Sselect_hyperslab(filespace_id, H5S_SELECT_SET,
2177                                          offset, NULL, a_size, NULL);
2178 
2179             if ( status < 0 ) {
2180 
2181                pass = FALSE;
2182                failure_mssg = "disk hyperslab create failed.";
2183             }
2184 
2185             /* read the chunk from file */
2186             if ( pass ) {
2187 
2188                 status = H5Dread(dset_id, H5T_NATIVE_INT,
2189                                  memspace_id, filespace_id,
2190                                  dxpl_id, data_chunk);
2191 
2192                 if ( status < 0 ) {
2193 
2194                    pass = FALSE;
2195                    failure_mssg = "chunk read failed.";
2196                 }
2197             }
2198 
2199             /* validate the slab */
2200             if ( pass ) {
2201 
2202                 valid_chunk = TRUE;
2203                 for ( k = 0; k < CHUNK_SIZE; k++ )
2204                 {
2205                     for ( l = 0; l < CHUNK_SIZE; l++ )
2206                     {
2207                         if ( data_chunk[0][k][l]
2208                              !=
2209                              ((DSET_SIZE * DSET_SIZE * mpi_rank) +
2210                               (DSET_SIZE * (i + k)) + j + l + dset_num) ) {
2211 
2212                             valid_chunk = FALSE;
2213 
2214                             if ( verbose ) {
2215 
2216                                 HDfprintf(stdout,
2217                                     "data_chunk[%0d][%0d] = %0d, expect %0d.\n",
2218                                     k, l, data_chunk[0][k][l],
2219                                     ((DSET_SIZE * DSET_SIZE * mpi_rank) +
2220                                      (DSET_SIZE * (i + k)) + j + l + dset_num));
2221                                     HDfprintf(stdout,
2222                                     "dset_num = %d, i = %d, j = %d, k = %d, l = %d\n",
2223                                     dset_num, i, j, k, l);
2224                             }
2225                         }
2226                     }
2227                 }
2228 
2229                 if ( ! valid_chunk ) {
2230 
2231                     pass = FALSE;
2232                     failure_mssg = "slab validation failed.";
2233 
2234                     if ( verbose ) {
2235 
2236                         HDfprintf(stdout,
2237                                 "Chunk (%0d, %0d) in /dset%03d is invalid.\n",
2238                                 i, j, dset_num);
2239                     }
2240                 }
2241             }
2242             j += CHUNK_SIZE;
2243         }
2244         i += CHUNK_SIZE;
2245     }
2246 
2247     if ( show_progress )
2248         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2249 
2250     /* close the file space */
2251     if ( ( pass ) && ( H5Sclose(filespace_id) < 0 ) ) {
2252 
2253         pass = FALSE;
2254         failure_mssg = "H5Sclose(filespace_id) failed.";
2255     }
2256 
2257     /* close the dataset */
2258     if ( ( pass ) && ( H5Dclose(dset_id) < 0 ) )  {
2259 
2260         pass = FALSE;
2261         failure_mssg = "H5Dclose(dset_id) failed.";
2262     }
2263 
2264     /* close the mem space */
2265     if ( ( pass ) && ( H5Sclose(memspace_id) < 0 ) ) {
2266 
2267         pass = FALSE;
2268         failure_mssg = "H5Sclose(memspace_id) failed.";
2269     }
2270 
2271     /* close the data access property list */
2272     if ( ( pass ) && ( H5Pclose(dxpl_id) < 0 ) ) {
2273 
2274         pass = FALSE;
2275         failure_mssg = "H5Pclose(dxpl) failed.";
2276     }
2277 
2278     if ( show_progress )
2279         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2280 
2281     return;
2282 
2283 } /* par_verify_dataset() */
2284 
2285 
2286 /*-------------------------------------------------------------------------
2287  * Function:    serial_insert_cache_image()
2288  *
2289  * Purpose:     Insert a cache image in the supplied file.
2290  *
2291  *         To populate the cache image, validate the contents
2292  *         of the file before closing.
2293  *
2294  *              On failure, print an appropriate error message and
2295  *              return FALSE.
2296  *
2297  * Return:      TRUE if succussful, FALSE otherwise.
2298  *
2299  * Programmer:  John Mainzer
2300  *              3/8/17
2301  *
2302  * Modifications:
2303  *
2304  *              None.
2305  *
2306  *-------------------------------------------------------------------------
2307  */
2308 
2309 static hbool_t
serial_insert_cache_image(int file_name_idx,int mpi_size)2310 serial_insert_cache_image(int file_name_idx, int mpi_size )
2311 {
2312     const char * fcn_name = "serial_insert_cache_image()";
2313     char filename[512];
2314     hbool_t show_progress = FALSE;
2315     int cp = 0;
2316     int i;
2317     int num_dsets = PAR_NUM_DSETS;
2318     hid_t file_id = -1;
2319     H5F_t *file_ptr = NULL;
2320     H5C_t *cache_ptr = NULL;
2321     MPI_Comm dummy_comm = MPI_COMM_WORLD;
2322     MPI_Info dummy_info = MPI_INFO_NULL;
2323 
2324     pass = TRUE;
2325 
2326     if ( show_progress )
2327         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2328 
2329 
2330     /* 1) setup the file name */
2331     if ( pass ) {
2332 
2333         HDassert(FILENAMES[file_name_idx]);
2334 
2335         if ( h5_fixname(FILENAMES[file_name_idx], H5P_DEFAULT,
2336                                   filename, sizeof(filename))
2337             == NULL ) {
2338 
2339             pass = FALSE;
2340             HDfprintf(stdout, "h5_fixname() failed.\n");
2341         }
2342     }
2343 
2344     if ( show_progress )
2345         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2346 
2347 
2348     /* 2) Open the PHDF5 file with the cache image FAPL entry.
2349      */
2350 
2351     if ( pass ) {
2352 
2353         open_hdf5_file(/* create_file           */ FALSE,
2354                        /* mdci_sbem_expected    */ FALSE,
2355                        /* read_only             */ FALSE,
2356                        /* set_mdci_fapl         */ TRUE,
2357                        /* config_fsm            */ FALSE,
2358                        /* enable_page_buffer    */ FALSE,
2359                        /* hdf_file_name         */ filename,
2360                        /* cache_image_flags     */ H5C_CI__ALL_FLAGS,
2361                        /* file_id_ptr           */ &file_id,
2362                        /* file_ptr_ptr          */ &file_ptr,
2363                        /* cache_ptr_ptr         */ &cache_ptr,
2364                        /* comm                  */ dummy_comm,
2365                        /* info                  */ dummy_info,
2366                        /* l_facc_type           */ 0,
2367                        /* all_coll_metadata_ops */ FALSE,
2368                        /* coll_metadata_write   */ FALSE,
2369                        /* md_write_strat        */ 1);
2370     }
2371 
2372     if ( show_progress )
2373         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2374 
2375 
2376     /* 3) Validate contents of the file */
2377 
2378     i = 0;
2379     while ( ( pass ) && ( i < num_dsets ) ) {
2380 
2381         serial_verify_dataset(i, file_id, mpi_size);
2382         i++;
2383     }
2384 
2385     if ( show_progress )
2386         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2387 
2388 
2389     /* 4) Close the file */
2390 
2391     if ( pass ) {
2392 
2393         if ( H5Fclose(file_id) < 0  ) {
2394 
2395             pass = FALSE;
2396             failure_mssg = "H5Fclose() failed.\n";
2397         }
2398     }
2399 
2400     if ( show_progress )
2401         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2402 
2403     return pass;
2404 
2405 } /* serial_insert_cache_image() */
2406 
2407 
2408 /*-------------------------------------------------------------------------
2409  * Function:    serial_verify_dataset()
2410  *
2411  * Purpose:     Verify the contents of a chunked dataset.
2412  *
2413  *              On failure, set pass to FALSE, and set failure_mssg
2414  *              to point to an appropriate failure message.
2415  *
2416  *              Do nothing if pass is FALSE on entry.
2417  *
2418  * Return:      void
2419  *
2420  * Programmer:  John Mainzer
2421  *              3/6/17
2422  *
2423  * Modifications:
2424  *
2425  *              None.
2426  *
2427  *-------------------------------------------------------------------------
2428  */
2429 
2430 static void
serial_verify_dataset(int dset_num,hid_t file_id,int mpi_size)2431 serial_verify_dataset(int dset_num,
2432                       hid_t file_id,
2433                       int mpi_size)
2434 {
2435     const char * fcn_name = "serial_verify_dataset()";
2436     char dset_name[256];
2437     hbool_t show_progress = FALSE;
2438     hbool_t valid_chunk;
2439     hbool_t verbose = FALSE;
2440     int cp = 0;
2441     int i, j, k, l, m;
2442     int data_chunk[1][CHUNK_SIZE][CHUNK_SIZE];
2443     hsize_t dims[3];
2444     hsize_t a_size[3];
2445     hsize_t offset[3];
2446     hid_t status;
2447     hid_t memspace_id = -1;
2448     hid_t dset_id = -1;
2449     hid_t filespace_id = -1;
2450 
2451     HDsprintf(dset_name, "/dset%03d", dset_num);
2452 
2453     if ( show_progress ) {
2454         HDfprintf(stdout, "%s: dset name = \"%s\".\n", fcn_name, dset_name);
2455         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2456     }
2457 
2458     if ( pass ) {
2459 
2460         /* open the dataset */
2461 
2462         dset_id = H5Dopen2(file_id, dset_name, H5P_DEFAULT);
2463 
2464         if ( dset_id < 0 ) {
2465 
2466             pass = FALSE;
2467             failure_mssg = "H5Dopen2() failed.";
2468         }
2469     }
2470 
2471     /* get the file space ID */
2472     if ( pass ) {
2473 
2474         filespace_id = H5Dget_space(dset_id);
2475 
2476         if ( filespace_id < 0 ) {
2477 
2478             pass = FALSE;
2479             failure_mssg = "H5Dget_space() failed.";
2480         }
2481     }
2482 
2483     if ( show_progress )
2484         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2485 
2486     /* create the mem space to be used to read */
2487     if ( pass ) {
2488 
2489         dims[0] = 1;
2490         dims[1] = CHUNK_SIZE;
2491         dims[2] = CHUNK_SIZE;
2492         memspace_id = H5Screate_simple(3, dims, NULL);
2493 
2494         if ( memspace_id < 0 ) {
2495 
2496             pass = FALSE;
2497             failure_mssg = "H5Screate_simple() failed.";
2498         }
2499     }
2500 
2501     if ( show_progress )
2502         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2503 
2504     /* select in memory hyperslab */
2505     if ( pass ) {
2506 
2507         offset[0] = 0;                  /* offset of hyperslab in memory */
2508         offset[1] = 0;
2509         offset[2] = 0;
2510         a_size[0] = 1;                  /* size of hyperslab */
2511         a_size[1] = CHUNK_SIZE;
2512         a_size[2] = CHUNK_SIZE;
2513         status = H5Sselect_hyperslab(memspace_id, H5S_SELECT_SET, offset, NULL,
2514                                      a_size, NULL);
2515 
2516         if ( status < 0 ) {
2517 
2518             pass = FALSE;
2519             failure_mssg = "H5Sselect_hyperslab() failed.";
2520         }
2521     }
2522 
2523     if ( show_progress )
2524         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2525 
2526 
2527     /* read data from data sets and validate it */
2528     i = 0;
2529     while ( ( pass ) && ( i < mpi_size ) )
2530     {
2531         j = 0;
2532         while ( ( pass ) && ( j < DSET_SIZE ) )
2533         {
2534             k = 0;
2535             while ( ( pass ) && ( k < DSET_SIZE ) )
2536             {
2537                 /* select on disk hyperslab */
2538                 offset[0] = (hsize_t)i; /* offset of hyperslab in file */
2539                 offset[1] = (hsize_t)j; /* offset of hyperslab in file */
2540                 offset[2] = (hsize_t)k;
2541                 a_size[0] = (hsize_t)1;
2542                 a_size[1] = CHUNK_SIZE; /* size of hyperslab */
2543                 a_size[2] = CHUNK_SIZE;
2544 
2545                 status = H5Sselect_hyperslab(filespace_id, H5S_SELECT_SET,
2546                                              offset, NULL, a_size, NULL);
2547 
2548                 if ( status < 0 ) {
2549 
2550                    pass = FALSE;
2551                    failure_mssg = "disk hyperslab create failed.";
2552                 }
2553 
2554                 /* read the chunk from file */
2555                 if ( pass ) {
2556 
2557                     status = H5Dread(dset_id, H5T_NATIVE_INT,
2558                                      memspace_id, filespace_id,
2559                                      H5P_DEFAULT, data_chunk);
2560 
2561                     if ( status < 0 ) {
2562 
2563                        pass = FALSE;
2564                        failure_mssg = "chunk read failed.";
2565                     }
2566                 }
2567 
2568                 /* validate the slab */
2569                 if ( pass ) {
2570 
2571                     valid_chunk = TRUE;
2572 
2573                     for ( l = 0; l < CHUNK_SIZE; l++ )
2574                     {
2575                         for ( m = 0; m < CHUNK_SIZE; m++ )
2576                         {
2577                             if ( data_chunk[0][l][m]
2578                                  !=
2579                                  ((DSET_SIZE * DSET_SIZE * i) +
2580                                   (DSET_SIZE * (j + l)) + k + m + dset_num) ) {
2581 
2582                                 valid_chunk = FALSE;
2583 
2584                                 if ( verbose ) {
2585 
2586                                     HDfprintf(stdout,
2587                                     "data_chunk[%0d][%0d] = %0d, expect %0d.\n",
2588                                     j, k, data_chunk[0][j][k],
2589                                     ((DSET_SIZE * DSET_SIZE * i) +
2590                                      (DSET_SIZE * (j + l)) + k + m + dset_num));
2591                                     HDfprintf(stdout,
2592                                     "dset_num = %d, i = %d, j = %d, k = %d, l = %d, m = %d\n",
2593                                     dset_num, i, j, k, l, m);
2594                                 }
2595                             }
2596                         }
2597                     }
2598 
2599                     if ( ! valid_chunk ) {
2600 
2601                         pass = FALSE;
2602                         failure_mssg = "slab validation failed.";
2603 
2604                         if ( verbose ) {
2605 
2606                             HDfprintf(stdout,
2607                                   "Chunk (%0d, %0d) in /dset%03d is invalid.\n",
2608                                    j, k, dset_num);
2609                         }
2610                     }
2611                 }
2612                 k += CHUNK_SIZE;
2613             }
2614             j += CHUNK_SIZE;
2615         }
2616         i++;
2617     }
2618 
2619 
2620     if ( show_progress )
2621         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2622 
2623     /* close the file space */
2624     if ( ( pass ) && ( H5Sclose(filespace_id) < 0 ) ) {
2625 
2626         pass = FALSE;
2627         failure_mssg = "H5Sclose(filespace_id) failed.";
2628     }
2629 
2630     /* close the dataset */
2631     if ( ( pass ) && ( H5Dclose(dset_id) < 0 ) )  {
2632 
2633         pass = FALSE;
2634         failure_mssg = "H5Dclose(dset_id) failed.";
2635     }
2636 
2637     /* close the mem space */
2638     if ( ( pass ) && ( H5Sclose(memspace_id) < 0 ) ) {
2639 
2640         pass = FALSE;
2641         failure_mssg = "H5Sclose(memspace_id) failed.";
2642     }
2643 
2644     if ( show_progress )
2645         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
2646 
2647     return;
2648 
2649 } /* serial_verify_dataset() */
2650 
2651 
2652 /*-------------------------------------------------------------------------
2653  * Function:    parse_flags
2654  *
2655  * Purpose:     Parse the flags passed to this program, and load the
2656  *              values into the supplied field.
2657  *
2658  * Return:      Success:        1
2659  *              Failure:        0
2660  *
2661  * Programmer:  J Mainzer
2662  *              4/28/11
2663  *
2664  *-------------------------------------------------------------------------
2665  */
2666 static hbool_t
parse_flags(int argc,char * argv[],hbool_t * setup_ptr,hbool_t * ici_ptr,int * file_idx_ptr,int * mpi_size_ptr,hbool_t display)2667 parse_flags(int argc, char * argv[], hbool_t * setup_ptr,
2668     hbool_t * ici_ptr, int * file_idx_ptr, int * mpi_size_ptr, hbool_t display)
2669 {
2670     const char * fcn_name = "parse_flags()";
2671     const char * (ops[]) = {"setup", "ici"};
2672     int success = TRUE;
2673 
2674     HDassert(setup_ptr);
2675     HDassert(*setup_ptr == FALSE);
2676     HDassert(ici_ptr);
2677     HDassert(*ici_ptr == FALSE);
2678     HDassert(file_idx_ptr);
2679     HDassert(mpi_size_ptr);
2680 
2681     if ( setup_ptr == NULL ) {
2682 
2683         success = FALSE;
2684         HDfprintf(stdout, "%s: bad arg(s) on entry.\n", fcn_name);
2685     }
2686 
2687 
2688     if ( ( success ) &&
2689          ( ( argc != 1 ) && ( argc != 2 ) && ( argc != 4 ) ) ) {
2690 
2691         success = FALSE;
2692         usage();
2693     }
2694 
2695 
2696     if ( ( success ) && ( argc >= 2 ) ) {
2697 
2698         if ( strcmp(argv[1], ops[0]) == 0 ) {
2699 
2700             if ( argc != 2 ) {
2701 
2702                 success = FALSE;
2703                 usage();
2704 
2705             } else {
2706 
2707                 *setup_ptr = TRUE;
2708 
2709             }
2710         } else if ( strcmp(argv[1], ops[1]) == 0 ) {
2711 
2712             if ( argc != 4 ) {
2713 
2714                 success = FALSE;
2715                 usage();
2716 
2717             } else {
2718 
2719                 *ici_ptr = TRUE;
2720                 *file_idx_ptr = atoi(argv[2]);
2721                 *mpi_size_ptr = atoi(argv[3]);
2722 
2723             }
2724         }
2725     }
2726 
2727     if ( ( success ) && ( display ) ) {
2728 
2729         if ( *setup_ptr )
2730 
2731             HDfprintf(stdout, "t_cache_image setup\n");
2732 
2733         else if ( *ici_ptr )
2734 
2735             HDfprintf(stdout, "t_cache_image ici %d %d\n",
2736                       *file_idx_ptr, *mpi_size_ptr);
2737 
2738         else
2739 
2740             HDfprintf(stdout, "t_cache_image\n");
2741     }
2742 
2743     return(success);
2744 
2745 } /* parse_flags() */
2746 
2747 
2748 /*-------------------------------------------------------------------------
2749  * Function:    usage
2750  *
2751  * Purpose:     Display a brief message describing the purpose and use
2752  *              of the program.
2753  *
2754  * Return:      void
2755  *
2756  * Programmer:  John Mainzer
2757  *              4/28/11
2758  *
2759  * Modifications:
2760  *
2761  *-------------------------------------------------------------------------
2762  */
2763 void
usage(void)2764 usage(void)
2765 {
2766     const char * s[] =
2767     {
2768         "\n",
2769         "t_cache_image:\n",
2770         "\n",
2771         "Run the parallel cache image tests.  \n"
2772         "\n"
2773         "In general, this program is run via MPI.  However, at present, files\n"
2774         "with cache images can only be constructed by serial processes.\n",
2775         "\n",
2776         "To square this circle, one process in the parallel computation \n"
2777         "forks a serial version of the test program to handle this detail.\n",
2778         "The \"setup\" parameter indicates that t_cache_image is being \n",
2779         "invokde for this purpose.\n",
2780         "\n",
2781         "Similarly, only a serial process can add a cache image to an\n",
2782         "existing file.\n",
2783         "\n",
2784         "Here again, one process forks a serial version of the test program\n",
2785         "with the \"ici\" parameter.\n"
2786         "\n",
2787         "usage: t_cache_image [setup|ici m n]\n",
2788         "\n",
2789         "where:\n",
2790         "\n",
2791         "       setup parameter forces creation of test file\n",
2792         "\n",
2793         "       ici parameter forces insertion of a cache image into the \n",
2794         "       m   th test file, created by a parallel computation with .\n",
2795         "       n   processes\n",
2796         "\n",
2797         "Returns 0 on success, 1 on failure.\n",
2798         "\n",
2799         NULL,
2800     };
2801     int i = 0;
2802 
2803     while(s[i] != NULL) {
2804         HDfprintf(stdout, "%s", s[i]);
2805         i++;
2806     }
2807 
2808     return;
2809 } /* usage() */
2810 
2811 
2812 /*-------------------------------------------------------------------------
2813  * Function:    verify_data_sets()
2814  *
2815  * Purpose:     If pass is TRUE on entry, verify that the data sets in the
2816  *        file exist and contain the expected data.
2817  *
2818  *        Note that these data sets were created by
2819  *        create_data_sets() above.  Thus any changes in that
2820  *        function must be reflected in this function, and
2821  *        vise-versa.
2822  *
2823  *              On failure, set pass to FALSE, and set failure_mssg
2824  *              to point to an appropriate failure message.
2825  *
2826  *              Do nothing if pass is FALSE on entry.
2827  *
2828  * Return:      void
2829  *
2830  * Programmer:  John Mainzer
2831  *              7/15/15
2832  *
2833  * Modifications:
2834  *
2835  *              Added min_dset and max_dset parameters and supporting
2836  *        code.  This allows the caller to specify a range of
2837  *        datasets to verify.
2838  *                        JRM -- 8/20/15
2839  *
2840  *-------------------------------------------------------------------------
2841  */
2842 
2843 static void
verify_data_sets(hid_t file_id,int min_dset,int max_dset)2844 verify_data_sets(hid_t file_id, int min_dset, int max_dset)
2845 {
2846     const char * fcn_name = "verify_data_sets()";
2847     char dset_name[64];
2848     hbool_t show_progress = FALSE;
2849     hbool_t valid_chunk;
2850     hbool_t verbose = FALSE;
2851     int cp = 0;
2852     int i, j, k, l, m;
2853     int data_chunk[CHUNK_SIZE][CHUNK_SIZE];
2854     herr_t status;
2855     hid_t filespace_ids[MAX_NUM_DSETS];
2856     hid_t memspace_id = -1;
2857     hid_t dataset_ids[MAX_NUM_DSETS];
2858     hsize_t dims[2];
2859     hsize_t a_size[2];
2860     hsize_t offset[2];
2861 
2862     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
2863 
2864     HDassert(0 <= min_dset);
2865     HDassert(min_dset <= max_dset);
2866     HDassert(max_dset < MAX_NUM_DSETS);
2867 
2868     /* open the datasets */
2869 
2870     if ( pass ) {
2871 
2872         i = min_dset;
2873 
2874         while ( ( pass ) && ( i <= max_dset ) )
2875         {
2876             /* open the dataset */
2877             if ( pass ) {
2878 
2879                 HDsprintf(dset_name, "/dset%03d", i);
2880                 dataset_ids[i] = H5Dopen2(file_id, dset_name, H5P_DEFAULT);
2881 
2882                 if ( dataset_ids[i] < 0 ) {
2883 
2884                     pass = FALSE;
2885                     failure_mssg = "H5Dopen2() failed.";
2886                 }
2887             }
2888 
2889             /* get the file space ID */
2890             if ( pass ) {
2891 
2892                 filespace_ids[i] = H5Dget_space(dataset_ids[i]);
2893 
2894                 if ( filespace_ids[i] < 0 ) {
2895 
2896                     pass = FALSE;
2897                     failure_mssg = "H5Dget_space() failed.";
2898                 }
2899             }
2900 
2901             i++;
2902         }
2903     }
2904 
2905     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
2906 
2907     /* create the mem space to be used to read and write chunks */
2908     if ( pass ) {
2909 
2910         dims[0] = CHUNK_SIZE;
2911         dims[1] = CHUNK_SIZE;
2912         memspace_id = H5Screate_simple(2, dims, NULL);
2913 
2914         if ( memspace_id < 0 ) {
2915 
2916             pass = FALSE;
2917             failure_mssg = "H5Screate_simple() failed.";
2918         }
2919     }
2920 
2921     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
2922 
2923     /* select in memory hyperslab */
2924     if ( pass ) {
2925 
2926         offset[0] = 0;  /*offset of hyperslab in memory*/
2927         offset[1] = 0;
2928         a_size[0] = CHUNK_SIZE;  /*size of hyperslab*/
2929         a_size[1] = CHUNK_SIZE;
2930         status = H5Sselect_hyperslab(memspace_id, H5S_SELECT_SET, offset, NULL,
2931                                      a_size, NULL);
2932 
2933         if ( status < 0 ) {
2934 
2935             pass = FALSE;
2936             failure_mssg = "H5Sselect_hyperslab() failed.";
2937         }
2938     }
2939 
2940     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
2941 
2942 
2943     /* read data from data sets and validate it */
2944     i = 0;
2945     while ( ( pass ) && ( i < DSET_SIZE ) )
2946     {
2947         j = 0;
2948         while ( ( pass ) && ( j < DSET_SIZE ) )
2949         {
2950             m = min_dset;
2951             while ( ( pass ) && ( m <= max_dset ) )
2952             {
2953 
2954                 /* select on disk hyperslab */
2955                 offset[0] = (hsize_t)i; /* offset of hyperslab in file */
2956                 offset[1] = (hsize_t)j;
2957                 a_size[0] = CHUNK_SIZE; /* size of hyperslab */
2958                 a_size[1] = CHUNK_SIZE;
2959                 status = H5Sselect_hyperslab(filespace_ids[m], H5S_SELECT_SET,
2960                                              offset, NULL, a_size, NULL);
2961 
2962                 if ( status < 0 ) {
2963 
2964                    pass = FALSE;
2965                    failure_mssg = "disk hyperslab create failed.";
2966                 }
2967 
2968                 /* read the chunk from file */
2969                 if ( pass ) {
2970 
2971                     status = H5Dread(dataset_ids[m], H5T_NATIVE_INT,
2972                                      memspace_id, filespace_ids[m],
2973                                      H5P_DEFAULT, data_chunk);
2974 
2975                     if ( status < 0 ) {
2976 
2977                        pass = FALSE;
2978                        failure_mssg = "disk hyperslab create failed.";
2979                     }
2980                 }
2981 
2982                 /* validate the slab */
2983                 if ( pass ) {
2984 
2985                     valid_chunk = TRUE;
2986                     for ( k = 0; k < CHUNK_SIZE; k++ )
2987                     {
2988                         for ( l = 0; l < CHUNK_SIZE; l++ )
2989                         {
2990                             if ( data_chunk[k][l]
2991                                  !=
2992                                  ((DSET_SIZE * DSET_SIZE * m) +
2993                                   (DSET_SIZE * (i + k)) + j + l) ) {
2994 
2995                                 valid_chunk = FALSE;
2996 
2997                 if ( verbose ) {
2998 
2999                                     HDfprintf(stdout,
3000                                     "data_chunk[%0d][%0d] = %0d, expect %0d.\n",
3001                                     k, l, data_chunk[k][l],
3002                                     ((DSET_SIZE * DSET_SIZE * m) +
3003                                      (DSET_SIZE * (i + k)) + j + l));
3004                                     HDfprintf(stdout,
3005                                      "m = %d, i = %d, j = %d, k = %d, l = %d\n",
3006                                      m, i, j, k, l);
3007                 }
3008                             }
3009                         }
3010                     }
3011 
3012                     if ( ! valid_chunk ) {
3013 
3014                         pass = FALSE;
3015                         failure_mssg = "slab validation failed.";
3016 
3017             if ( verbose ) {
3018 
3019                 HDfprintf(stdout,
3020                                   "Chunk (%0d, %0d) in /dset%03d is invalid.\n",
3021                                   i, j, m);
3022             }
3023                     }
3024                 }
3025                 m++;
3026             }
3027             j += CHUNK_SIZE;
3028         }
3029         i += CHUNK_SIZE;
3030     }
3031 
3032     if ( show_progress ) HDfprintf(stdout, "%s: cp = %d.\n", fcn_name, cp++);
3033 
3034     /* close the file spaces */
3035     i = min_dset;
3036     while ( ( pass ) && ( i <= max_dset ) )
3037     {
3038         if ( H5Sclose(filespace_ids[i]) < 0 ) {
3039 
3040             pass = FALSE;
3041             failure_mssg = "H5Sclose() failed.";
3042         }
3043         i++;
3044     }
3045 
3046 
3047     /* close the datasets */
3048     i = min_dset;
3049     while ( ( pass ) && ( i <= max_dset ) )
3050     {
3051         if ( H5Dclose(dataset_ids[i]) < 0 ) {
3052 
3053             pass = FALSE;
3054             failure_mssg = "H5Dclose() failed.";
3055         }
3056         i++;
3057     }
3058 
3059     /* close the mem space */
3060     if ( pass ) {
3061 
3062         if ( H5Sclose(memspace_id) < 0 ) {
3063 
3064             pass = FALSE;
3065             failure_mssg = "H5Sclose(memspace_id) failed.";
3066         }
3067     }
3068 
3069     return;
3070 
3071 } /* verify_data_sets() */
3072 
3073 
3074 /****************************************************************************/
3075 /******************************* Test Functions *****************************/
3076 /****************************************************************************/
3077 
3078 /*-------------------------------------------------------------------------
3079  * Function:    verify_cache_image_RO()
3080  *
3081  * Purpose:     Verify that a HDF5 file containing a cache image is
3082  *              opened R/O and read correctly by PHDF5 with the specified
3083  *              metadata write strategy.
3084  *
3085  *              Basic cycle of operation is as follows:
3086  *
3087  *        1) Open the test file created at the beginning of this
3088  *           test read only.
3089  *
3090  *           Verify that the file contains a cache image.
3091  *
3092  *           Verify that only process 0 reads the cache image.
3093  *
3094  *           Verify that all other processes receive the cache
3095  *           image block from process 0.
3096  *
3097  *              2) Verify that the file contains the expected data.
3098  *
3099  *              3) Close the file.
3100  *
3101  *              4) Open the file R/O, and verify that it still contains
3102  *                 a cache image.
3103  *
3104  *              5) Verify that the file contains the expected data.
3105  *
3106  *              6) Close the file.
3107  *
3108  * Return:      void
3109  *
3110  * Programmer:  John Mainzer
3111  *              3/11/17
3112  *
3113  * Modifications:
3114  *
3115  *        None.
3116  *
3117  *-------------------------------------------------------------------------
3118  */
3119 
3120 static unsigned
verify_cache_image_RO(int file_name_id,int md_write_strat,int mpi_rank)3121 verify_cache_image_RO(int file_name_id, int md_write_strat, int mpi_rank)
3122 {
3123     const char * fcn_name = "verify_cache_image_RO()";
3124     char filename[512];
3125     hbool_t show_progress = FALSE;
3126     hid_t file_id = -1;
3127     H5F_t *file_ptr = NULL;
3128     H5C_t *cache_ptr = NULL;
3129     int cp = 0;
3130 
3131     pass = TRUE;
3132 
3133     if ( mpi_rank == 0 ) {
3134 
3135         switch(md_write_strat) {
3136 
3137             case H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY:
3138                 TESTING("parallel CI load test -- proc0 md write -- R/O");
3139                 break;
3140 
3141             case H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED:
3142                 TESTING("parallel CI load test -- dist md write -- R/O");
3143                 break;
3144 
3145             default:
3146                 TESTING("parallel CI load test -- unknown md write -- R/o");
3147                 pass = FALSE;
3148                 break;
3149         }
3150     }
3151 
3152     show_progress = ( ( show_progress ) && ( mpi_rank == 0 ) );
3153 
3154     if ( show_progress )
3155         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3156 
3157 
3158     /* setup the file name */
3159     if ( pass ) {
3160 
3161         if ( h5_fixname(FILENAMES[file_name_id], H5P_DEFAULT,
3162                         filename, sizeof(filename)) == NULL ) {
3163 
3164             pass = FALSE;
3165             failure_mssg = "h5_fixname() failed.\n";
3166         }
3167     }
3168 
3169     if ( show_progress )
3170         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3171 
3172 
3173     /* 1) Open the test file created at the beginning of this test.
3174      *
3175      *    Verify that the file contains a cache image.
3176      */
3177 
3178     if ( pass ) {
3179 
3180         open_hdf5_file(/* create_file           */ FALSE,
3181                        /* mdci_sbem_expected    */ TRUE,
3182                        /* read_only             */ TRUE,
3183                        /* set_mdci_fapl         */ FALSE,
3184             /* config_fsm            */ FALSE,
3185                        /* enable_page_buffer    */ FALSE,
3186                        /* hdf_file_name         */ filename,
3187                        /* cache_image_flags     */ H5C_CI__ALL_FLAGS,
3188                        /* file_id_ptr           */ &file_id,
3189                        /* file_ptr_ptr          */ &file_ptr,
3190                        /* cache_ptr_ptr         */ &cache_ptr,
3191                        /* comm                  */ MPI_COMM_WORLD,
3192                        /* info                  */ MPI_INFO_NULL,
3193                        /* l_facc_type           */ FACC_MPIO,
3194                        /* all_coll_metadata_ops */ FALSE,
3195                        /* coll_metadata_write   */ FALSE,
3196                        /* md_write_strat        */ md_write_strat);
3197     }
3198 
3199     if ( show_progress )
3200         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3201 
3202 
3203     /* 2) Verify that the file contains the expected data.
3204      *
3205      *    Verify that only process 0 reads the cache image.
3206      *
3207      *    Verify that all other processes receive the cache
3208      *    image block from process 0.
3209      */
3210 
3211     if ( pass ) {
3212 
3213        verify_data_sets(file_id, 0, MAX_NUM_DSETS - 1);
3214     }
3215 
3216     /* Verify that only process 0 reads the cache image. */
3217 #if H5C_COLLECT_CACHE_STATS
3218     if ( pass ) {
3219 
3220         if ( ( ( mpi_rank == 0 ) && ( cache_ptr->images_read != 1 ) ) ||
3221              ( ( mpi_rank > 0 )  && ( cache_ptr->images_read != 0 ) ) ) {
3222 
3223             pass = FALSE;
3224             failure_mssg = "unexpected images_read.";
3225         }
3226     }
3227 #endif /* H5C_COLLECT_CACHE_STATS */
3228 
3229     if ( show_progress )
3230         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3231 
3232     /* Verify that all other processes receive the cache image block
3233      * from process 0.
3234      *
3235      * Since we have alread verified that only process 0 has read the
3236      * image, it is sufficient to verify that the image was loaded on
3237      * all processes.
3238      */
3239 #if H5C_COLLECT_CACHE_STATS
3240     if ( pass ) {
3241 
3242         if ( cache_ptr->images_loaded != 1 ) {
3243 
3244             pass = FALSE;
3245             failure_mssg = "Image not loaded?.";
3246         }
3247     }
3248 #endif /* H5C_COLLECT_CACHE_STATS */
3249 
3250     if ( show_progress )
3251         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3252 
3253 
3254     /* 3) Close the file. */
3255 
3256     if ( pass ) {
3257 
3258         if ( H5Fclose(file_id) < 0  ) {
3259 
3260             pass = FALSE;
3261             failure_mssg = "H5Fclose() failed.\n";
3262 
3263         }
3264     }
3265 
3266     if ( show_progress )
3267         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3268 
3269 
3270     /* 4) Open the file, and verify that it doesn't contain a cache image. */
3271 
3272     if ( pass ) {
3273 
3274         open_hdf5_file(/* create_file           */ FALSE,
3275                        /* mdci_sbem_expected    */ TRUE,
3276                        /* read_only             */ TRUE,
3277                        /* set_mdci_fapl         */ FALSE,
3278             /* config_fsm            */ FALSE,
3279                        /* enable_page_buffer    */ FALSE,
3280                        /* hdf_file_name         */ filename,
3281                        /* cache_image_flags     */ H5C_CI__ALL_FLAGS,
3282                        /* file_id_ptr           */ &file_id,
3283                        /* file_ptr_ptr          */ &file_ptr,
3284                        /* cache_ptr_ptr         */ &cache_ptr,
3285                        /* comm                  */ MPI_COMM_WORLD,
3286                        /* info                  */ MPI_INFO_NULL,
3287                        /* l_facc_type           */ FACC_MPIO,
3288                        /* all_coll_metadata_ops */ FALSE,
3289                        /* coll_metadata_write   */ FALSE,
3290                        /* md_write_strat        */ md_write_strat);
3291     }
3292 
3293     if ( show_progress )
3294         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3295 
3296 
3297     /* 5) Verify that the file contains the expected data. */
3298 
3299     if ( pass ) {
3300 
3301        verify_data_sets(file_id, 0, MAX_NUM_DSETS - 1);
3302     }
3303 
3304 #if H5C_COLLECT_CACHE_STATS
3305     if ( pass ) {
3306 
3307         if ( cache_ptr->images_loaded != 1 ) {
3308 
3309             pass = FALSE;
3310             failure_mssg = "metadata cache image block not loaded(2).";
3311         }
3312     }
3313 #endif /* H5C_COLLECT_CACHE_STATS */
3314 
3315 
3316     /* 6) Close the file. */
3317 
3318     if ( pass ) {
3319 
3320         if ( H5Fclose(file_id) < 0  ) {
3321 
3322             pass = FALSE;
3323             failure_mssg = "H5Fclose() failed.\n";
3324 
3325         }
3326     }
3327 
3328     if ( show_progress )
3329         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3330 
3331 
3332     /* report results */
3333     if ( mpi_rank == 0 ) {
3334 
3335         if ( pass ) {
3336 
3337             PASSED();
3338 
3339         } else {
3340 
3341             H5_FAILED();
3342 
3343             if ( show_progress )
3344                 HDfprintf(stdout, "%s: failure_mssg = \"%s\"\n", failure_mssg);
3345         }
3346     }
3347 
3348 
3349     return !pass;
3350 
3351 } /* verify_cache_image_RO() */
3352 
3353 
3354 /*-------------------------------------------------------------------------
3355  * Function:    verify_cache_image_RW()
3356  *
3357  * Purpose:     Verify that a HDF5 file containing a cache image is
3358  *              opened and read correctly by PHDF5 with the specified
3359  *              metadata write strategy.
3360  *
3361  *              Basic cycle of operation is as follows:
3362  *
3363  *        1) Open the test file created at the beginning of this
3364  *           test.
3365  *
3366  *           Verify that the file contains a cache image.
3367  *
3368  *              2) Verify that the file contains the expected data.
3369  *
3370  *           Verify that only process 0 reads the cache image.
3371  *
3372  *           Verify that all other processes receive the cache
3373  *           image block from process 0.
3374  *
3375  *
3376  *              3) Close the file.
3377  *
3378  *              4) Open the file, and verify that it doesn't contain
3379  *                 a cache image.
3380  *
3381  *              5) Verify that the file contains the expected data.
3382  *
3383  *              6) Close the file.
3384  *
3385  *              7) Delete the file.
3386  *
3387  * Return:      void
3388  *
3389  * Programmer:  John Mainzer
3390  *              1/25/17
3391  *
3392  * Modifications:
3393  *
3394  *        None.
3395  *
3396  *-------------------------------------------------------------------------
3397  */
3398 
3399 static unsigned
verify_cache_image_RW(int file_name_id,int md_write_strat,int mpi_rank)3400 verify_cache_image_RW(int file_name_id, int md_write_strat, int mpi_rank)
3401 {
3402     const char * fcn_name = "verify_cache_imageRW()";
3403     char filename[512];
3404     hbool_t show_progress = FALSE;
3405     hid_t file_id = -1;
3406     H5F_t *file_ptr = NULL;
3407     H5C_t *cache_ptr = NULL;
3408     int cp = 0;
3409 
3410     pass = TRUE;
3411 
3412     if ( mpi_rank == 0 ) {
3413 
3414         switch(md_write_strat) {
3415 
3416             case H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY:
3417                 TESTING("parallel CI load test -- proc0 md write -- R/W");
3418                 break;
3419 
3420             case H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED:
3421                 TESTING("parallel CI load test -- dist md write -- R/W");
3422                 break;
3423 
3424             default:
3425                 TESTING("parallel CI load test -- unknown md write -- R/W");
3426                 pass = FALSE;
3427                 break;
3428         }
3429     }
3430 
3431     show_progress = ( ( show_progress ) && ( mpi_rank == 0 ) );
3432 
3433     if ( show_progress )
3434         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3435 
3436 
3437     /* setup the file name */
3438     if ( pass ) {
3439 
3440         if ( h5_fixname(FILENAMES[file_name_id], H5P_DEFAULT,
3441                         filename, sizeof(filename)) == NULL ) {
3442 
3443             pass = FALSE;
3444             failure_mssg = "h5_fixname() failed.\n";
3445         }
3446     }
3447 
3448     if ( show_progress )
3449         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3450 
3451 
3452     /* 1) Open the test file created at the beginning of this test.
3453      *
3454      *    Verify that the file contains a cache image.
3455      *
3456      *    Verify that only process 0 reads the cache image.
3457      *
3458      *    Verify that all other processes receive the cache
3459      *    image block from process 0.
3460      */
3461 
3462     if ( pass ) {
3463 
3464         open_hdf5_file(/* create_file           */ FALSE,
3465                        /* mdci_sbem_expected    */ TRUE,
3466                        /* read_only             */ FALSE,
3467                        /* set_mdci_fapl         */ FALSE,
3468             /* config_fsm            */ FALSE,
3469                        /* enable_page_buffer    */ FALSE,
3470                        /* hdf_file_name         */ filename,
3471                        /* cache_image_flags     */ H5C_CI__ALL_FLAGS,
3472                        /* file_id_ptr           */ &file_id,
3473                        /* file_ptr_ptr          */ &file_ptr,
3474                        /* cache_ptr_ptr         */ &cache_ptr,
3475                        /* comm                  */ MPI_COMM_WORLD,
3476                        /* info                  */ MPI_INFO_NULL,
3477                        /* l_facc_type           */ FACC_MPIO,
3478                        /* all_coll_metadata_ops */ FALSE,
3479                        /* coll_metadata_write   */ FALSE,
3480                        /* md_write_strat        */ md_write_strat);
3481     }
3482 
3483     if ( show_progress )
3484         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3485 
3486 
3487     /* 2) Verify that the file contains the expected data.
3488      *
3489      *    Verify that only process 0 reads the cache image.
3490      *
3491      *    Verify that all other processes receive the cache
3492      *    image block from process 0.
3493      */
3494     if ( pass ) {
3495 
3496        verify_data_sets(file_id, 0, MAX_NUM_DSETS - 1);
3497     }
3498 
3499     /* Verify that only process 0 reads the cache image. */
3500 #if H5C_COLLECT_CACHE_STATS
3501     if ( pass ) {
3502 
3503         if ( ( ( mpi_rank == 0 ) && ( cache_ptr->images_read != 1 ) ) ||
3504              ( ( mpi_rank > 0 )  && ( cache_ptr->images_read != 0 ) ) ) {
3505 
3506             pass = FALSE;
3507             failure_mssg = "unexpected images_read.";
3508         }
3509     }
3510 #endif /* H5C_COLLECT_CACHE_STATS */
3511 
3512     if ( show_progress )
3513         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3514 
3515     /* Verify that all other processes receive the cache image block
3516      * from process 0.
3517      *
3518      * Since we have alread verified that only process 0 has read the
3519      * image, it is sufficient to verify that the image was loaded on
3520      * all processes.
3521      */
3522 #if H5C_COLLECT_CACHE_STATS
3523     if ( pass ) {
3524 
3525         if ( cache_ptr->images_loaded != 1 ) {
3526 
3527             pass = FALSE;
3528             failure_mssg = "Image not loaded?.";
3529         }
3530     }
3531 #endif /* H5C_COLLECT_CACHE_STATS */
3532 
3533     if ( show_progress )
3534         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3535 
3536 
3537     /* 3) Close the file. */
3538 
3539     if ( pass ) {
3540 
3541         if ( H5Fclose(file_id) < 0  ) {
3542 
3543             pass = FALSE;
3544             failure_mssg = "H5Fclose() failed.\n";
3545 
3546         }
3547     }
3548 
3549     if ( show_progress )
3550         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3551 
3552 
3553     /* 4) Open the file, and verify that it doesn't contain a cache image. */
3554 
3555     if ( pass ) {
3556 
3557         open_hdf5_file(/* create_file           */ FALSE,
3558                        /* mdci_sbem_expected    */ FALSE,
3559                        /* read_only             */ FALSE,
3560                        /* set_mdci_fapl         */ FALSE,
3561             /* config_fsm            */ FALSE,
3562                        /* enable_page_buffer    */ FALSE,
3563                        /* hdf_file_name         */ filename,
3564                        /* cache_image_flags     */ H5C_CI__ALL_FLAGS,
3565                        /* file_id_ptr           */ &file_id,
3566                        /* file_ptr_ptr          */ &file_ptr,
3567                        /* cache_ptr_ptr         */ &cache_ptr,
3568                        /* comm                  */ MPI_COMM_WORLD,
3569                        /* info                  */ MPI_INFO_NULL,
3570                        /* l_facc_type           */ FACC_MPIO,
3571                        /* all_coll_metadata_ops */ FALSE,
3572                        /* coll_metadata_write   */ FALSE,
3573                        /* md_write_strat        */ md_write_strat);
3574     }
3575 
3576     if ( show_progress )
3577         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3578 
3579 
3580     /* 5) Verify that the file contains the expected data. */
3581 
3582     if ( pass ) {
3583 
3584        verify_data_sets(file_id, 0, MAX_NUM_DSETS - 1);
3585     }
3586 
3587 #if H5C_COLLECT_CACHE_STATS
3588     if ( pass ) {
3589 
3590         if ( cache_ptr->images_loaded != 0 ) {
3591 
3592             pass = FALSE;
3593             failure_mssg = "metadata cache image block loaded(1).";
3594         }
3595     }
3596 #endif /* H5C_COLLECT_CACHE_STATS */
3597 
3598 
3599     /* 6) Close the file. */
3600 
3601     if ( pass ) {
3602 
3603         if ( H5Fclose(file_id) < 0  ) {
3604 
3605             pass = FALSE;
3606             failure_mssg = "H5Fclose() failed.\n";
3607 
3608         }
3609     }
3610 
3611     if ( show_progress )
3612         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3613 
3614 
3615     /* 7) Delete the file. */
3616 
3617     if ( pass ) {
3618 
3619         /* wait for everyone to close the file */
3620         MPI_Barrier(MPI_COMM_WORLD);
3621 
3622         if ( ( mpi_rank == 0 ) && ( HDremove(filename) < 0 ) ) {
3623 
3624             pass = FALSE;
3625             failure_mssg = "HDremove() failed.\n";
3626         }
3627     }
3628 
3629 
3630     /* report results */
3631     if ( mpi_rank == 0 ) {
3632 
3633         if ( pass ) {
3634 
3635             PASSED();
3636 
3637         } else {
3638 
3639             H5_FAILED();
3640 
3641             if ( show_progress )
3642                 HDfprintf(stdout, "%s: failure_mssg = \"%s\"\n", failure_mssg);
3643         }
3644     }
3645 
3646 
3647     return !pass;
3648 
3649 } /* verify_cache_imageRW() */
3650 
3651 
3652 /*****************************************************************************
3653  *
3654  * Function:    smoke_check_1()
3655  *
3656  * Purpose:     Initial smoke check to verify correct behaviour of cache
3657  *              image in combination with parallel.
3658  *
3659  *              As cache image is currently disabled in the parallel case,
3660  *              we construct a test file in parallel, verify it in serial
3661  *              and generate a cache image in passing, and then verify
3662  *              it again in parallel.
3663  *
3664  *              In passing, also verify that page buffering is silently
3665  *              disabled in the parallel case.  Needless to say, this part
3666  *              of the test will have to be re-worked when and if page
3667  *              buffering is supported in parallel.
3668  *
3669  * Return:      Success:        TRUE
3670  *
3671  *              Failure:        FALSE
3672  *
3673  * Programmer:  JRM -- 3/6/17
3674  *
3675  *****************************************************************************/
3676 static hbool_t
smoke_check_1(MPI_Comm mpi_comm,MPI_Info mpi_info,int mpi_rank,int mpi_size)3677 smoke_check_1(MPI_Comm mpi_comm, MPI_Info mpi_info, int mpi_rank, int mpi_size)
3678 {
3679     const char * fcn_name = "smoke_check_1()";
3680     char filename[512];
3681     hbool_t show_progress = FALSE;
3682     hid_t file_id = -1;
3683     H5F_t *file_ptr = NULL;
3684     H5C_t *cache_ptr = NULL;
3685     int cp = 0;
3686     int i;
3687     int num_dsets = PAR_NUM_DSETS;
3688     int test_file_index = 2;
3689     h5_stat_size_t file_size;
3690 
3691     pass = TRUE;
3692 
3693     if ( mpi_rank == 0 ) {
3694 
3695         TESTING("parallel cache image smoke check 1");
3696     }
3697 
3698     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3699         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3700 
3701     /* setup the file name */
3702     if ( pass ) {
3703 
3704         HDassert(FILENAMES[test_file_index]);
3705 
3706         if ( h5_fixname(FILENAMES[test_file_index], H5P_DEFAULT,
3707                                   filename, sizeof(filename))
3708             == NULL ) {
3709 
3710             pass = FALSE;
3711             failure_mssg = "h5_fixname() failed.\n";
3712         }
3713     }
3714 
3715     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3716         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3717 
3718 
3719     /* 1) Create a PHDF5 file without the cache image FAPL entry.
3720      *
3721      *    Verify that a cache image is not requested
3722      */
3723 
3724     if ( pass ) {
3725 
3726         open_hdf5_file(/* create_file           */ TRUE,
3727                        /* mdci_sbem_expected    */ FALSE,
3728                        /* read_only             */ FALSE,
3729                        /* set_mdci_fapl         */ FALSE,
3730                        /* config_fsm            */ TRUE,
3731                        /* enable_page_buffer    */ FALSE,
3732                        /* hdf_file_name         */ filename,
3733                        /* cache_image_flags     */ H5C_CI__ALL_FLAGS,
3734                        /* file_id_ptr           */ &file_id,
3735                        /* file_ptr_ptr          */ &file_ptr,
3736                        /* cache_ptr_ptr         */ &cache_ptr,
3737                        /* comm                  */ mpi_comm,
3738                        /* info                  */ mpi_info,
3739                        /* l_facc_type           */ FACC_MPIO,
3740                        /* all_coll_metadata_ops */ FALSE,
3741                        /* coll_metadata_write   */ TRUE,
3742                        /* md_write_strat        */ 1);
3743     }
3744 
3745     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3746         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3747 
3748 
3749     /* 2) Create datasets in the file */
3750 
3751     i = 0;
3752     while ( ( pass ) && ( i < num_dsets ) ) {
3753 
3754         par_create_dataset(i, file_id, mpi_rank, mpi_size);
3755         i++;
3756     }
3757 
3758     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3759         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3760 
3761 
3762     /* 3) Verify the datasets in the file */
3763 
3764     i = 0;
3765     while ( ( pass ) && ( i < num_dsets ) ) {
3766 
3767         par_verify_dataset(i, file_id, mpi_rank);
3768         i++;
3769     }
3770 
3771 
3772     /* 4) Close the file */
3773 
3774     if ( pass ) {
3775 
3776         if ( H5Fclose(file_id) < 0  ) {
3777 
3778             pass = FALSE;
3779             failure_mssg = "H5Fclose() failed.\n";
3780 
3781         }
3782     }
3783 
3784     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3785         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3786 
3787 
3788     /* 5 Insert a cache image into the file */
3789 
3790     if ( pass ) {
3791 
3792         par_insert_cache_image(test_file_index, mpi_rank,  mpi_size);
3793     }
3794 
3795     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3796         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3797 
3798 
3799     /* 6) Open the file R/O */
3800 
3801     if ( pass ) {
3802 
3803         open_hdf5_file(/* create_file           */ FALSE,
3804                        /* mdci_sbem_expected    */ TRUE,
3805                        /* read_only             */ TRUE,
3806                        /* set_mdci_fapl         */ FALSE,
3807                        /* config_fsm            */ FALSE,
3808                        /* enable_page_buffer    */ FALSE,
3809                        /* hdf_file_name         */ filename,
3810                        /* cache_image_flags     */ H5C_CI__ALL_FLAGS,
3811                        /* file_id_ptr           */ &file_id,
3812                        /* file_ptr_ptr          */ &file_ptr,
3813                        /* cache_ptr_ptr         */ &cache_ptr,
3814                        /* comm                  */ mpi_comm,
3815                        /* info                  */ mpi_info,
3816                        /* l_facc_type           */ FACC_MPIO,
3817                        /* all_coll_metadata_ops */ FALSE,
3818                        /* coll_metadata_write   */ TRUE,
3819                        /* md_write_strat        */ 1);
3820     }
3821 
3822     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3823         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3824 
3825 
3826     /* 7) Verify the datasets in the file backwards
3827      *
3828      *    Verify that only process 0 reads the cache image.
3829      *
3830      *    Verify that all other processes receive the cache
3831      *    image block from process 0.
3832      */
3833 
3834     i = num_dsets - 1;
3835     while ( ( pass ) && ( i >= 0 ) ) {
3836 
3837         par_verify_dataset(i, file_id, mpi_rank);
3838         i--;
3839     }
3840 
3841     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3842         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3843 
3844     /* Verify that only process 0 reads the cache image. */
3845 #if H5C_COLLECT_CACHE_STATS
3846     if ( pass ) {
3847 
3848         if ( ( ( mpi_rank == 0 ) && ( cache_ptr->images_read != 1 ) ) ||
3849              ( ( mpi_rank > 0 )  && ( cache_ptr->images_read != 0 ) ) ) {
3850 
3851             pass = FALSE;
3852             failure_mssg = "unexpected images_read.";
3853         }
3854     }
3855 #endif /* H5C_COLLECT_CACHE_STATS */
3856 
3857     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3858         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3859 
3860     /* Verify that all other processes receive the cache image block
3861      * from process 0.
3862      *
3863      * Since we have alread verified that only process 0 has read the
3864      * image, it is sufficient to verify that the image was loaded on
3865      * all processes.
3866      */
3867 #if H5C_COLLECT_CACHE_STATS
3868     if ( pass ) {
3869 
3870         if ( cache_ptr->images_loaded != 1 ) {
3871 
3872             pass = FALSE;
3873             failure_mssg = "Image not loaded?.";
3874         }
3875     }
3876 #endif /* H5C_COLLECT_CACHE_STATS */
3877 
3878     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3879         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3880 
3881 
3882     /* 8) Close the file */
3883 
3884     if ( pass ) {
3885 
3886         if ( H5Fclose(file_id) < 0  ) {
3887 
3888             pass = FALSE;
3889             failure_mssg = "H5Fclose() failed.";
3890 
3891         }
3892     }
3893 
3894     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3895         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3896 
3897 
3898     /* 9) Open the file */
3899 
3900     if ( pass ) {
3901 
3902         open_hdf5_file(/* create_file           */ FALSE,
3903                        /* mdci_sbem_expected    */ TRUE,
3904                        /* read_only             */ FALSE,
3905                        /* set_mdci_fapl         */ FALSE,
3906                        /* config_fsm            */ FALSE,
3907                        /* enable_page_buffer    */ FALSE,
3908                        /* hdf_file_name         */ filename,
3909                        /* cache_image_flags     */ H5C_CI__ALL_FLAGS,
3910                        /* file_id_ptr           */ &file_id,
3911                        /* file_ptr_ptr          */ &file_ptr,
3912                        /* cache_ptr_ptr         */ &cache_ptr,
3913                        /* comm                  */ mpi_comm,
3914                        /* info                  */ mpi_info,
3915                        /* l_facc_type           */ FACC_MPIO,
3916                        /* all_coll_metadata_ops */ FALSE,
3917                        /* coll_metadata_write   */ TRUE,
3918                        /* md_write_strat        */ 1);
3919     }
3920 
3921     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3922         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3923 
3924 
3925     /* 10) Verify the datasets in the file
3926      *
3927      *     Verify that only process 0 reads the cache image.
3928      *
3929      *     Verify that all other processes receive the cache
3930      *     image block from process 0.
3931      */
3932 
3933     i = 0;
3934     while ( ( pass ) && ( i < num_dsets ) ) {
3935 
3936         par_verify_dataset(i, file_id, mpi_rank);
3937         i++;
3938     }
3939 
3940     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3941         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3942 
3943     /* Verify that only process 0 reads the cache image. */
3944 #if H5C_COLLECT_CACHE_STATS
3945     if ( pass ) {
3946 
3947         if ( ( ( mpi_rank == 0 ) && ( cache_ptr->images_read != 1 ) ) ||
3948              ( ( mpi_rank > 0 )  && ( cache_ptr->images_read != 0 ) ) ) {
3949 
3950             pass = FALSE;
3951             failure_mssg = "unexpected images_read.";
3952         }
3953     }
3954 #endif /* H5C_COLLECT_CACHE_STATS */
3955 
3956     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3957         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3958 
3959     /* Verify that all other processes receive the cache image block
3960      * from process 0.
3961      *
3962      * Since we have alread verified that only process 0 has read the
3963      * image, it is sufficient to verify that the image was loaded on
3964      * all processes.
3965      */
3966 #if H5C_COLLECT_CACHE_STATS
3967     if ( pass ) {
3968 
3969         if ( cache_ptr->images_loaded != 1 ) {
3970 
3971             pass = FALSE;
3972             failure_mssg = "Image not loaded?.";
3973         }
3974     }
3975 #endif /* H5C_COLLECT_CACHE_STATS */
3976 
3977     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3978         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3979 
3980 
3981     /* 11) Delete the datasets in the file */
3982 
3983     i = 0;
3984     while ( ( pass ) && ( i < num_dsets ) ) {
3985 
3986         par_delete_dataset(i, file_id, mpi_rank);
3987         i++;
3988     }
3989 
3990     if ( ( mpi_rank == 0 ) && ( show_progress ) )
3991         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
3992 
3993 
3994     /* 12) Close the file */
3995 
3996     if ( pass ) {
3997 
3998         if ( H5Fclose(file_id) < 0  ) {
3999 
4000             pass = FALSE;
4001             failure_mssg = "H5Fclose() failed.";
4002 
4003         }
4004     }
4005 
4006     if ( ( mpi_rank == 0 ) && ( show_progress ) )
4007         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
4008 
4009 
4010     /* 13) Get the size of the file.  Verify that it is less
4011      *     than 20 KB.  Without deletions and persistant free
4012      *     space managers, size size is about 30 MB, so this
4013      *     is sufficient to verify that the persistant free
4014      *     space managers are more or less doing their job.
4015      *
4016      *     Note that this test will have to change if we use
4017      *     a larger page size.
4018      */
4019     if ( pass ) {
4020 
4021         if ( ( file_size = h5_get_file_size(filename, H5P_DEFAULT) ) < 0 ) {
4022 
4023             pass = FALSE;
4024             failure_mssg = "h5_get_file_size() failed.";
4025 
4026         } else if ( file_size > 20 * 1024 ) {
4027 
4028             pass = FALSE;
4029             failure_mssg = "unexpectedly large file size.";
4030         }
4031     }
4032 
4033     if ( ( mpi_rank == 0 ) && ( show_progress ) )
4034         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
4035 
4036 
4037     /* 14) Delete the file */
4038 
4039     if ( pass ) {
4040 
4041         /* wait for everyone to close the file */
4042         MPI_Barrier(MPI_COMM_WORLD);
4043 
4044         if ( ( mpi_rank == 0 ) && ( HDremove(filename) < 0 ) ) {
4045 
4046             pass = FALSE;
4047             failure_mssg = "HDremove() failed.\n";
4048         }
4049     }
4050 
4051     if ( ( mpi_rank == 0 ) && ( show_progress ) )
4052         HDfprintf(stdout, "%s: cp = %d, pass = %d.\n", fcn_name, cp++, pass);
4053 
4054 
4055     /* report results */
4056     if ( mpi_rank == 0 ) {
4057 
4058         if ( pass ) {
4059 
4060             PASSED();
4061 
4062         } else {
4063 
4064             H5_FAILED();
4065 
4066             HDfprintf(stdout, "%s: failure_mssg = \"%s\"\n",
4067                       fcn_name, failure_mssg);
4068         }
4069     }
4070 
4071     return !pass;
4072 
4073 } /* smoke_check_1() */
4074 
4075 
4076 /* This test uses many POSIX things that are not available on
4077  * Windows. We're using a check for fork(2) here as a proxy for
4078  * all POSIX/Unix/Linux things until this test can be made
4079  * more platform-independent.
4080  */
4081 #ifdef H5_HAVE_FORK
4082 
4083 /*-------------------------------------------------------------------------
4084  * Function:    main
4085  *
4086  * Purpose:     Run parallel tests on the cache image feature.
4087  *
4088  *              At present, cache image is disabled in parallel, and
4089  *              thus these tests are restructed to verifying that a
4090  *              file with a cache image can be opened in the parallel
4091  *              case, and verifying that instructions to create a
4092  *              cache image are ignored in the parallel case.
4093  *
4094  *              WARNING: This test uses fork() and execve(), and
4095  *                       therefore will not run on Windows.
4096  *
4097  * Return:      Success: 0
4098  *
4099  *              Failure: 1
4100  *
4101  * Programmer:  John Mainzer
4102  *              1/25/17
4103  *
4104  * Modifications:
4105  *
4106  *-------------------------------------------------------------------------
4107  */
4108 
4109 int
main(int argc,char ** argv)4110 main(int argc, char **argv)
4111 {
4112     hbool_t setup = FALSE;
4113     hbool_t ici = FALSE;
4114     unsigned nerrs = 0;
4115     MPI_Comm comm = MPI_COMM_WORLD;
4116     MPI_Info info = MPI_INFO_NULL;
4117     int file_idx;
4118     int i;
4119     int mpi_size;
4120     int mpi_rank;
4121 
4122     if ( ! parse_flags(argc, argv, &setup, &ici, &file_idx, &mpi_size, FALSE) )
4123         exit(1);  /* exit now if unable to parse flags */
4124 
4125     if ( setup ) { /* construct test files and exit */
4126 
4127         H5open();
4128         HDfprintf(stdout, "Constructing test files: \n");
4129         HDfflush(stdout);
4130 
4131         i = 0;
4132         while ( ( FILENAMES[i] != NULL ) && ( i < TEST_FILES_TO_CONSTRUCT ) ) {
4133 
4134             HDfprintf(stdout, "   writing %s ... ", FILENAMES[i]);
4135             HDfflush(stdout);
4136             construct_test_file(i);
4137 
4138             if ( pass ) {
4139 
4140                 HDprintf("done.\n");
4141                 HDfflush(stdout);
4142 
4143             } else {
4144 
4145                 HDprintf("failed.\n");
4146                 HDexit(1);
4147             }
4148             i++;
4149         }
4150 
4151         HDfprintf(stdout, "Test file construction complete.\n");
4152         HDexit(0);
4153 
4154     } else if ( ici ) {
4155 
4156         if ( serial_insert_cache_image(file_idx, mpi_size) ) {
4157 
4158             HDexit(0);
4159 
4160         } else {
4161 
4162             HDfprintf(stderr, "\n\nCache image insertion failed.\n");
4163             HDfprintf(stderr, "  failure mssg = \"%s\"\n", failure_mssg);
4164             HDexit(1);
4165         }
4166     }
4167 
4168     HDassert(!setup);
4169     HDassert(!ici);
4170 
4171     MPI_Init(&argc, &argv);
4172     MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
4173     MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
4174 
4175     /* Attempt to turn off atexit post processing so that in case errors
4176      * happen during the test and the process is aborted, it will not get
4177      * hang in the atexit post processing in which it may try to make MPI
4178      * calls.  By then, MPI calls may not work.
4179      */
4180     if (H5dont_atexit() < 0){
4181         HDprintf("%d:Failed to turn off atexit processing. Continue.\n",
4182                mpi_rank);
4183     };
4184 
4185     H5open();
4186 
4187     if ( mpi_rank == 0 ) {
4188         HDprintf("===================================\n");
4189         HDprintf("Parallel metadata cache image tests\n");
4190         HDprintf("        mpi_size     = %d\n", mpi_size);
4191         HDprintf("===================================\n");
4192     }
4193 
4194     if ( mpi_size < 2 ) {
4195 
4196         if ( mpi_rank == 0 ) {
4197 
4198             HDprintf("    Need at least 2 processes.  Exiting.\n");
4199         }
4200         goto finish;
4201     }
4202 
4203     if ( mpi_rank == 0 ) { /* create test files */
4204 
4205         int child_status;
4206         pid_t child_pid;
4207 
4208         child_pid = fork();
4209 
4210         if ( child_pid == 0 ) { /* this is the child process */
4211 
4212             /* fun and games to shutup the compiler */
4213             char param0[32] = "t_cache_image";
4214             char param1[32] = "setup";
4215             char * child_argv[] = {param0, param1, NULL};
4216 
4217             /* we may need to play with the path here */
4218             if ( execv("t_cache_image", child_argv) == -1 ) {
4219 
4220                 HDfprintf(stdout,
4221                           "execl() of setup process failed. errno = %d(%s)\n",
4222                           errno, strerror(errno));
4223                 HDexit(1);
4224             }
4225 
4226         } else if ( child_pid != -1 ) {
4227             /* this is the parent process -- wait until child is done */
4228             if ( -1 == waitpid(child_pid, &child_status, WUNTRACED)) {
4229 
4230                 HDfprintf(stdout, "can't wait on setup process.\n");
4231 
4232             } else if ( ! WIFEXITED(child_status) ) {
4233 
4234                 HDfprintf(stdout, "setup process hasn't exitied.\n");
4235 
4236             } else if ( WEXITSTATUS(child_status) != 0 ) {
4237 
4238                 HDfprintf(stdout, "setup process reports failure.\n");
4239 
4240             } else {
4241 
4242                 HDfprintf(stdout,
4243                  "testfile construction complete -- proceeding with tests.\n");
4244             }
4245         } else { /* fork failed */
4246 
4247             HDfprintf(stdout, "can't create process to construct test file.\n");
4248         }
4249     }
4250 
4251     /* can't start test until test files exist */
4252     MPI_Barrier(MPI_COMM_WORLD);
4253 
4254 
4255     nerrs += verify_cache_image_RO(0,
4256                      H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY, mpi_rank);
4257 #if 1
4258     nerrs += verify_cache_image_RO(1,
4259                      H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED, mpi_rank);
4260     nerrs += verify_cache_image_RW(0,
4261                      H5AC_METADATA_WRITE_STRATEGY__PROCESS_0_ONLY, mpi_rank);
4262     nerrs += verify_cache_image_RW(1,
4263                      H5AC_METADATA_WRITE_STRATEGY__DISTRIBUTED, mpi_rank);
4264     nerrs += smoke_check_1(comm, info, mpi_rank, mpi_size);
4265 #endif
4266 finish:
4267 
4268     /* make sure all processes are finished before final report, cleanup
4269      * and exit.
4270      */
4271     MPI_Barrier(MPI_COMM_WORLD);
4272 
4273     if ( mpi_rank == 0 ) {           /* only process 0 reports */
4274         HDsleep(10);
4275         HDprintf("===================================\n");
4276         if ( nerrs > 0 ) {
4277             HDprintf("***metadata cache image tests detected %d failures***\n",
4278                    nerrs);
4279         }
4280         else {
4281             HDprintf("metadata cache image tests finished with no failures\n");
4282         }
4283         HDprintf("===================================\n");
4284     }
4285 
4286     /* takedown_derived_types(); */
4287 
4288     /* close HDF5 library */
4289     H5close();
4290 
4291     /* MPI_Finalize must be called AFTER H5close which may use MPI calls */
4292     MPI_Finalize();
4293 
4294     /* cannot just return (nerrs) because exit code is limited to 1byte */
4295     return(nerrs > 0);
4296 
4297 } /* main() */
4298 #else /* H5_HAVE_FORK */
4299 
4300 int
main(void)4301 main(void)
4302 {
4303     HDfprintf(stderr, "Non-POSIX platform. Skipping.\n");
4304     return EXIT_SUCCESS;
4305 } /* end main() */
4306 
4307 #endif /* H5_HAVE_FORK */
4308 
4309