1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * All rights reserved.                                                      *
4  *                                                                           *
5  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
6  * terms governing use, modification, and redistribution, is contained in    *
7  * the COPYING file, which can be found at the root of the source code       *
8  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
9  * If you do not have access to either file, you may request a copy from     *
10  * help@hdfgroup.org.                                                        *
11  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12 
13 /*
14    This program will test independant and collective reads and writes between
15    selections of different rank that non-the-less are deemed as having the
16    same shape by H5Sselect_shape_same().
17  */
18 
19 #define H5S_FRIEND             /*suppress error about including H5Spkg   */
20 
21 /* Define this macro to indicate that the testing APIs should be available */
22 #define H5S_TESTING
23 
24 
25 #include "H5Spkg.h"             /* Dataspaces                           */
26 #include "testphdf5.h"
27 
28 
29 /* On Lustre (and perhaps other parallel file systems?), we have severe
30  * slow downs if two or more processes attempt to access the same file system
31  * block.  To minimize this problem, we set alignment in the shape same tests
32  * to the default Lustre block size -- which greatly reduces contention in
33  * the chunked dataset case.
34  */
35 
36 #define SHAPE_SAME_TEST_ALIGNMENT    ((hsize_t)(4 * 1024 * 1024))
37 
38 
39 #define PAR_SS_DR_MAX_RANK    5     /* must update code if this changes */
40 
41 struct hs_dr_pio_test_vars_t
42 {
43     int        mpi_size;
44     int         mpi_rank;
45     MPI_Comm    mpi_comm;
46     MPI_Info    mpi_info;
47     int         test_num;
48     int         edge_size;
49     int        checker_edge_size;
50     int         chunk_edge_size;
51     int         small_rank;
52     int         large_rank;
53     hid_t       dset_type;
54     uint32_t  * small_ds_buf_0;
55     uint32_t  * small_ds_buf_1;
56     uint32_t  * small_ds_buf_2;
57     uint32_t  * small_ds_slice_buf;
58     uint32_t  * large_ds_buf_0;
59     uint32_t  * large_ds_buf_1;
60     uint32_t  * large_ds_buf_2;
61     uint32_t  * large_ds_slice_buf;
62     int         small_ds_offset;
63     int         large_ds_offset;
64     hid_t       fid;               /* HDF5 file ID */
65     hid_t    xfer_plist;
66     hid_t       full_mem_small_ds_sid;
67     hid_t       full_file_small_ds_sid;
68     hid_t       mem_small_ds_sid;
69     hid_t       file_small_ds_sid_0;
70     hid_t       file_small_ds_sid_1;
71     hid_t    small_ds_slice_sid;
72     hid_t       full_mem_large_ds_sid;
73     hid_t       full_file_large_ds_sid;
74     hid_t       mem_large_ds_sid;
75     hid_t       file_large_ds_sid_0;
76     hid_t       file_large_ds_sid_1;
77     hid_t       file_large_ds_process_slice_sid;
78     hid_t       mem_large_ds_process_slice_sid;
79     hid_t    large_ds_slice_sid;
80     hid_t       small_dataset;     /* Dataset ID */
81     hid_t       large_dataset;     /* Dataset ID */
82     size_t      small_ds_size;
83     size_t      small_ds_slice_size;
84     size_t      large_ds_size;
85     size_t      large_ds_slice_size;
86     hsize_t     dims[PAR_SS_DR_MAX_RANK];
87     hsize_t     chunk_dims[PAR_SS_DR_MAX_RANK];
88     hsize_t     start[PAR_SS_DR_MAX_RANK];
89     hsize_t     stride[PAR_SS_DR_MAX_RANK];
90     hsize_t     count[PAR_SS_DR_MAX_RANK];
91     hsize_t     block[PAR_SS_DR_MAX_RANK];
92     hsize_t   * start_ptr;
93     hsize_t   * stride_ptr;
94     hsize_t   * count_ptr;
95     hsize_t   * block_ptr;
96     int         skips;
97     int            max_skips;
98     int64_t    total_tests;
99     int64_t    tests_run;
100     int64_t    tests_skipped;
101 };
102 
103 /*-------------------------------------------------------------------------
104  * Function:    hs_dr_pio_test__setup()
105  *
106  * Purpose:    Do setup for tests of I/O to/from hyperslab selections of
107  *         different rank in the parallel case.
108  *
109  * Return:    void
110  *
111  * Programmer:    JRM -- 8/9/11
112  *
113  *-------------------------------------------------------------------------
114  */
115 
116 #define CONTIG_HS_DR_PIO_TEST__SETUP__DEBUG 0
117 
118 static void
hs_dr_pio_test__setup(const int test_num,const int edge_size,const int checker_edge_size,const int chunk_edge_size,const int small_rank,const int large_rank,const hbool_t use_collective_io,const hid_t dset_type,const int express_test,struct hs_dr_pio_test_vars_t * tv_ptr)119 hs_dr_pio_test__setup(const int test_num,
120                       const int edge_size,
121                       const int checker_edge_size,
122                       const int chunk_edge_size,
123                       const int small_rank,
124                       const int large_rank,
125                       const hbool_t use_collective_io,
126                       const hid_t dset_type,
127                       const int express_test,
128                       struct hs_dr_pio_test_vars_t * tv_ptr)
129 {
130 #if CONTIG_HS_DR_PIO_TEST__SETUP__DEBUG
131     const char *fcnName = "hs_dr_pio_test__setup()";
132 #endif /* CONTIG_HS_DR_PIO_TEST__SETUP__DEBUG */
133     const char *filename;
134     hbool_t    mis_match = FALSE;
135     int        i;
136     int         mrc;
137     int        mpi_rank; /* needed by the VRFY macro */
138     uint32_t    expected_value;
139     uint32_t  * ptr_0;
140     uint32_t  * ptr_1;
141     hid_t    acc_tpl;        /* File access templates */
142     hid_t       small_ds_dcpl_id = H5P_DEFAULT;
143     hid_t       large_ds_dcpl_id = H5P_DEFAULT;
144     herr_t    ret;        /* Generic return value */
145 
146     HDassert( edge_size >= 6 );
147     HDassert( edge_size >= chunk_edge_size );
148     HDassert( ( chunk_edge_size == 0 ) || ( chunk_edge_size >= 3 ) );
149     HDassert( 1 < small_rank );
150     HDassert( small_rank < large_rank );
151     HDassert( large_rank <= PAR_SS_DR_MAX_RANK );
152 
153     tv_ptr->test_num = test_num;
154     tv_ptr->edge_size = edge_size;
155     tv_ptr->checker_edge_size = checker_edge_size;
156     tv_ptr->chunk_edge_size = chunk_edge_size;
157     tv_ptr->small_rank = small_rank;
158     tv_ptr->large_rank = large_rank;
159     tv_ptr->dset_type = dset_type;
160 
161     MPI_Comm_size(MPI_COMM_WORLD, &(tv_ptr->mpi_size));
162     MPI_Comm_rank(MPI_COMM_WORLD, &(tv_ptr->mpi_rank));
163     /* the VRFY() macro needs the local variable mpi_rank -- set it up now */
164     mpi_rank = tv_ptr->mpi_rank;
165 
166     HDassert( tv_ptr->mpi_size >= 1 );
167 
168     tv_ptr->mpi_comm = MPI_COMM_WORLD;
169     tv_ptr->mpi_info = MPI_INFO_NULL;
170 
171     for ( i = 0; i < tv_ptr->small_rank - 1; i++ )
172     {
173         tv_ptr->small_ds_size *= (size_t)(tv_ptr->edge_size);
174         tv_ptr->small_ds_slice_size *= (size_t)(tv_ptr->edge_size);
175     }
176     tv_ptr->small_ds_size *= (size_t)(tv_ptr->mpi_size + 1);
177 
178     /* used by checker board tests only */
179     tv_ptr->small_ds_offset = PAR_SS_DR_MAX_RANK - tv_ptr->small_rank;
180 
181     HDassert( 0 < tv_ptr->small_ds_offset );
182     HDassert( tv_ptr->small_ds_offset < PAR_SS_DR_MAX_RANK );
183 
184     for ( i = 0; i < tv_ptr->large_rank - 1; i++ ) {
185 
186         tv_ptr->large_ds_size *= (size_t)(tv_ptr->edge_size);
187         tv_ptr->large_ds_slice_size *= (size_t)(tv_ptr->edge_size);
188     }
189     tv_ptr->large_ds_size *= (size_t)(tv_ptr->mpi_size + 1);
190 
191     /* used by checker board tests only */
192     tv_ptr->large_ds_offset = PAR_SS_DR_MAX_RANK - tv_ptr->large_rank;
193 
194     HDassert( 0 <= tv_ptr->large_ds_offset );
195     HDassert( tv_ptr->large_ds_offset < PAR_SS_DR_MAX_RANK );
196 
197 
198     /* set up the start, stride, count, and block pointers */
199     /* used by contiguous tests only */
200     tv_ptr->start_ptr  = &(tv_ptr->start[PAR_SS_DR_MAX_RANK - tv_ptr->large_rank]);
201     tv_ptr->stride_ptr = &(tv_ptr->stride[PAR_SS_DR_MAX_RANK - tv_ptr->large_rank]);
202     tv_ptr->count_ptr  = &(tv_ptr->count[PAR_SS_DR_MAX_RANK - tv_ptr->large_rank]);
203     tv_ptr->block_ptr  = &(tv_ptr->block[PAR_SS_DR_MAX_RANK - tv_ptr->large_rank]);
204 
205 
206     /* Allocate buffers */
207     tv_ptr->small_ds_buf_0 = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->small_ds_size);
208     VRFY((tv_ptr->small_ds_buf_0 != NULL), "malloc of small_ds_buf_0 succeeded");
209 
210     tv_ptr->small_ds_buf_1 = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->small_ds_size);
211     VRFY((tv_ptr->small_ds_buf_1 != NULL), "malloc of small_ds_buf_1 succeeded");
212 
213     tv_ptr->small_ds_buf_2 = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->small_ds_size);
214     VRFY((tv_ptr->small_ds_buf_2 != NULL), "malloc of small_ds_buf_2 succeeded");
215 
216     tv_ptr->small_ds_slice_buf =
217         (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->small_ds_slice_size);
218     VRFY((tv_ptr->small_ds_slice_buf != NULL), "malloc of small_ds_slice_buf succeeded");
219 
220     tv_ptr->large_ds_buf_0 = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->large_ds_size);
221     VRFY((tv_ptr->large_ds_buf_0 != NULL), "malloc of large_ds_buf_0 succeeded");
222 
223     tv_ptr->large_ds_buf_1 = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->large_ds_size);
224     VRFY((tv_ptr->large_ds_buf_1 != NULL), "malloc of large_ds_buf_1 succeeded");
225 
226     tv_ptr->large_ds_buf_2 = (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->large_ds_size);
227     VRFY((tv_ptr->large_ds_buf_2 != NULL), "malloc of large_ds_buf_2 succeeded");
228 
229     tv_ptr->large_ds_slice_buf =
230         (uint32_t *)HDmalloc(sizeof(uint32_t) * tv_ptr->large_ds_slice_size);
231     VRFY((tv_ptr->large_ds_slice_buf != NULL), "malloc of large_ds_slice_buf succeeded");
232 
233     /* initialize the buffers */
234 
235     ptr_0 = tv_ptr->small_ds_buf_0;
236     for(i = 0; i < (int)(tv_ptr->small_ds_size); i++)
237         *ptr_0++ = (uint32_t)i;
238     HDmemset(tv_ptr->small_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->small_ds_size);
239     HDmemset(tv_ptr->small_ds_buf_2, 0, sizeof(uint32_t) * tv_ptr->small_ds_size);
240 
241     HDmemset(tv_ptr->small_ds_slice_buf, 0, sizeof(uint32_t) * tv_ptr->small_ds_slice_size);
242 
243     ptr_0 = tv_ptr->large_ds_buf_0;
244     for(i = 0; i < (int)(tv_ptr->large_ds_size); i++)
245         *ptr_0++ = (uint32_t)i;
246     HDmemset(tv_ptr->large_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->large_ds_size);
247     HDmemset(tv_ptr->large_ds_buf_2, 0, sizeof(uint32_t) * tv_ptr->large_ds_size);
248 
249     HDmemset(tv_ptr->large_ds_slice_buf, 0, sizeof(uint32_t) * tv_ptr->large_ds_slice_size);
250 
251     filename = (const char *)GetTestParameters();
252     HDassert( filename != NULL );
253 #if CONTIG_HS_DR_PIO_TEST__SETUP__DEBUG
254     if ( MAINPROCESS ) {
255 
256         HDfprintf(stdout, "%d: test num = %d.\n", tv_ptr->mpi_rank, tv_ptr->test_num);
257         HDfprintf(stdout, "%d: mpi_size = %d.\n", tv_ptr->mpi_rank, tv_ptr->mpi_size);
258         HDfprintf(stdout,
259                   "%d: small/large rank = %d/%d, use_collective_io = %d.\n",
260                   tv_ptr->mpi_rank, tv_ptr->small_rank, tv_ptr->large_rank,
261                   (int)use_collective_io);
262         HDfprintf(stdout, "%d: edge_size = %d, chunk_edge_size = %d.\n",
263                   tv_ptr->mpi_rank, tv_ptr->edge_size, tv_ptr->chunk_edge_size);
264         HDfprintf(stdout, "%d: checker_edge_size = %d.\n",
265                   tv_ptr->mpi_rank, tv_ptr->checker_edge_size);
266         HDfprintf(stdout, "%d: small_ds_size = %d, large_ds_size = %d.\n",
267                   tv_ptr->mpi_rank, (int)(tv_ptr->small_ds_size),
268                   (int)(tv_ptr->large_ds_size));
269         HDfprintf(stdout, "%d: filename = %s.\n", tv_ptr->mpi_rank, filename);
270     }
271 #endif /* CONTIG_HS_DR_PIO_TEST__SETUP__DEBUG */
272     /* ----------------------------------------
273      * CREATE AN HDF5 FILE WITH PARALLEL ACCESS
274      * ---------------------------------------*/
275     /* setup file access template */
276     acc_tpl = create_faccess_plist(tv_ptr->mpi_comm, tv_ptr->mpi_info, facc_type);
277     VRFY((acc_tpl >= 0), "create_faccess_plist() succeeded");
278 
279     /* set the alignment -- need it large so that we aren't always hitting the
280      * the same file system block.  Do this only if express_test is greater
281      * than zero.
282      */
283     if ( express_test > 0 ) {
284 
285         ret = H5Pset_alignment(acc_tpl, (hsize_t)0, SHAPE_SAME_TEST_ALIGNMENT);
286         VRFY((ret != FAIL), "H5Pset_alignment() succeeded");
287     }
288 
289     /* create the file collectively */
290     tv_ptr->fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, acc_tpl);
291     VRFY((tv_ptr->fid >= 0), "H5Fcreate succeeded");
292 
293     MESG("File opened.");
294 
295     /* Release file-access template */
296     ret = H5Pclose(acc_tpl);
297     VRFY((ret >= 0), "H5Pclose(acc_tpl) succeeded");
298 
299 
300     /* setup dims: */
301     tv_ptr->dims[0] = (hsize_t)(tv_ptr->mpi_size + 1);
302     tv_ptr->dims[1] = tv_ptr->dims[2] =
303         tv_ptr->dims[3] = tv_ptr->dims[4] = (hsize_t)(tv_ptr->edge_size);
304 
305 
306     /* Create small ds dataspaces */
307     tv_ptr->full_mem_small_ds_sid =
308         H5Screate_simple(tv_ptr->small_rank, tv_ptr->dims, NULL);
309     VRFY((tv_ptr->full_mem_small_ds_sid != 0),
310          "H5Screate_simple() full_mem_small_ds_sid succeeded");
311 
312     tv_ptr->full_file_small_ds_sid =
313         H5Screate_simple(tv_ptr->small_rank, tv_ptr->dims, NULL);
314     VRFY((tv_ptr->full_file_small_ds_sid != 0),
315          "H5Screate_simple() full_file_small_ds_sid succeeded");
316 
317     tv_ptr->mem_small_ds_sid = H5Screate_simple(tv_ptr->small_rank, tv_ptr->dims, NULL);
318     VRFY((tv_ptr->mem_small_ds_sid != 0),
319          "H5Screate_simple() mem_small_ds_sid succeeded");
320 
321     tv_ptr->file_small_ds_sid_0 = H5Screate_simple(tv_ptr->small_rank, tv_ptr->dims, NULL);
322     VRFY((tv_ptr->file_small_ds_sid_0 != 0),
323          "H5Screate_simple() file_small_ds_sid_0 succeeded");
324 
325     /* used by checker board tests only */
326     tv_ptr->file_small_ds_sid_1 = H5Screate_simple(tv_ptr->small_rank, tv_ptr->dims, NULL);
327     VRFY((tv_ptr->file_small_ds_sid_1 != 0),
328          "H5Screate_simple() file_small_ds_sid_1 succeeded");
329 
330     tv_ptr->small_ds_slice_sid =
331         H5Screate_simple(tv_ptr->small_rank - 1, &(tv_ptr->dims[1]), NULL);
332     VRFY((tv_ptr->small_ds_slice_sid != 0),
333          "H5Screate_simple() small_ds_slice_sid succeeded");
334 
335 
336     /* Create large ds dataspaces */
337     tv_ptr->full_mem_large_ds_sid =
338         H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
339     VRFY((tv_ptr->full_mem_large_ds_sid != 0),
340          "H5Screate_simple() full_mem_large_ds_sid succeeded");
341 
342     tv_ptr->full_file_large_ds_sid =
343         H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
344     VRFY((tv_ptr->full_file_large_ds_sid != FAIL),
345          "H5Screate_simple() full_file_large_ds_sid succeeded");
346 
347     tv_ptr->mem_large_ds_sid = H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
348     VRFY((tv_ptr->mem_large_ds_sid != FAIL),
349          "H5Screate_simple() mem_large_ds_sid succeeded");
350 
351     tv_ptr->file_large_ds_sid_0 = H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
352     VRFY((tv_ptr->file_large_ds_sid_0 != FAIL),
353          "H5Screate_simple() file_large_ds_sid_0 succeeded");
354 
355     /* used by checker board tests only */
356     tv_ptr->file_large_ds_sid_1 = H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
357     VRFY((tv_ptr->file_large_ds_sid_1 != FAIL),
358          "H5Screate_simple() file_large_ds_sid_1 succeeded");
359 
360     tv_ptr->mem_large_ds_process_slice_sid =
361         H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
362     VRFY((tv_ptr->mem_large_ds_process_slice_sid != FAIL),
363          "H5Screate_simple() mem_large_ds_process_slice_sid succeeded");
364 
365     tv_ptr->file_large_ds_process_slice_sid =
366         H5Screate_simple(tv_ptr->large_rank, tv_ptr->dims, NULL);
367     VRFY((tv_ptr->file_large_ds_process_slice_sid != FAIL),
368          "H5Screate_simple() file_large_ds_process_slice_sid succeeded");
369 
370 
371     tv_ptr->large_ds_slice_sid =
372         H5Screate_simple(tv_ptr->large_rank - 1, &(tv_ptr->dims[1]), NULL);
373     VRFY((tv_ptr->large_ds_slice_sid != 0),
374          "H5Screate_simple() large_ds_slice_sid succeeded");
375 
376 
377     /* if chunk edge size is greater than zero, set up the small and
378      * large data set creation property lists to specify chunked
379      * datasets.
380      */
381     if ( tv_ptr->chunk_edge_size > 0 ) {
382 
383         /* Under Lustre (and perhaps other parallel file systems?) we get
384          * locking delays when two or more processes attempt to access the
385          * same file system block.
386          *
387          * To minimize this problem, I have changed chunk_dims[0]
388          * from (mpi_size + 1) to just when any sort of express test is
389          * selected.  Given the structure of the test, and assuming we
390          * set the alignment large enough, this avoids the contention
391          * issue by seeing to it that each chunk is only accessed by one
392          * process.
393          *
394          * One can argue as to whether this is a good thing to do in our
395          * tests, but for now it is necessary if we want the test to complete
396          * in a reasonable amount of time.
397          *
398          *                                         JRM -- 9/16/10
399          */
400         if ( express_test == 0 ) {
401 
402             tv_ptr->chunk_dims[0] = 1;
403 
404         } else {
405 
406             tv_ptr->chunk_dims[0] = 1;
407         }
408         tv_ptr->chunk_dims[1] = tv_ptr->chunk_dims[2] =
409                                 tv_ptr->chunk_dims[3] =
410                                 tv_ptr->chunk_dims[4] = (hsize_t)(tv_ptr->chunk_edge_size);
411 
412         small_ds_dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
413         VRFY((ret != FAIL), "H5Pcreate() small_ds_dcpl_id succeeded");
414 
415         ret = H5Pset_layout(small_ds_dcpl_id, H5D_CHUNKED);
416         VRFY((ret != FAIL), "H5Pset_layout() small_ds_dcpl_id succeeded");
417 
418         ret = H5Pset_chunk(small_ds_dcpl_id, tv_ptr->small_rank, tv_ptr->chunk_dims);
419         VRFY((ret != FAIL), "H5Pset_chunk() small_ds_dcpl_id succeeded");
420 
421 
422         large_ds_dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
423         VRFY((ret != FAIL), "H5Pcreate() large_ds_dcpl_id succeeded");
424 
425         ret = H5Pset_layout(large_ds_dcpl_id, H5D_CHUNKED);
426         VRFY((ret != FAIL), "H5Pset_layout() large_ds_dcpl_id succeeded");
427 
428         ret = H5Pset_chunk(large_ds_dcpl_id, tv_ptr->large_rank, tv_ptr->chunk_dims);
429         VRFY((ret != FAIL), "H5Pset_chunk() large_ds_dcpl_id succeeded");
430     }
431 
432     /* create the small dataset */
433     tv_ptr->small_dataset = H5Dcreate2(tv_ptr->fid, "small_dataset", tv_ptr->dset_type,
434                                        tv_ptr->file_small_ds_sid_0, H5P_DEFAULT,
435                                        small_ds_dcpl_id, H5P_DEFAULT);
436     VRFY((ret != FAIL), "H5Dcreate2() small_dataset succeeded");
437 
438     /* create the large dataset */
439     tv_ptr->large_dataset = H5Dcreate2(tv_ptr->fid, "large_dataset", tv_ptr->dset_type,
440                                        tv_ptr->file_large_ds_sid_0, H5P_DEFAULT,
441                                        large_ds_dcpl_id, H5P_DEFAULT);
442     VRFY((ret != FAIL), "H5Dcreate2() large_dataset succeeded");
443 
444 
445     /* setup xfer property list */
446     tv_ptr->xfer_plist = H5Pcreate(H5P_DATASET_XFER);
447     VRFY((tv_ptr->xfer_plist >= 0), "H5Pcreate(H5P_DATASET_XFER) succeeded");
448 
449     if(use_collective_io) {
450         ret = H5Pset_dxpl_mpio(tv_ptr->xfer_plist, H5FD_MPIO_COLLECTIVE);
451         VRFY((ret >= 0), "H5Pset_dxpl_mpio succeeded");
452     }
453 
454     /* setup selection to write initial data to the small and large data sets */
455     tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
456     tv_ptr->stride[0] = (hsize_t)(2 * (tv_ptr->mpi_size + 1));
457     tv_ptr->count[0] = 1;
458     tv_ptr->block[0] = 1;
459 
460     for ( i = 1; i < tv_ptr->large_rank; i++ ) {
461 
462         tv_ptr->start[i] = 0;
463         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
464         tv_ptr->count[i] = 1;
465         tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
466     }
467 
468     /* setup selections for writing initial data to the small data set */
469     ret = H5Sselect_hyperslab(tv_ptr->mem_small_ds_sid,
470                               H5S_SELECT_SET,
471                               tv_ptr->start,
472                               tv_ptr->stride,
473                               tv_ptr->count,
474                               tv_ptr->block);
475     VRFY((ret >= 0), "H5Sselect_hyperslab(mem_small_ds_sid, set) suceeded");
476 
477     ret = H5Sselect_hyperslab(tv_ptr->file_small_ds_sid_0,
478                               H5S_SELECT_SET,
479                               tv_ptr->start,
480                               tv_ptr->stride,
481                               tv_ptr->count,
482                               tv_ptr->block);
483     VRFY((ret >= 0), "H5Sselect_hyperslab(file_small_ds_sid_0, set) suceeded");
484 
485     if ( MAINPROCESS ) { /* add an additional slice to the selections */
486 
487         tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_size);
488 
489         ret = H5Sselect_hyperslab(tv_ptr->mem_small_ds_sid,
490                                   H5S_SELECT_OR,
491                                   tv_ptr->start,
492                                   tv_ptr->stride,
493                                   tv_ptr->count,
494                                   tv_ptr->block);
495         VRFY((ret>= 0), "H5Sselect_hyperslab(mem_small_ds_sid, or) suceeded");
496 
497         ret = H5Sselect_hyperslab(tv_ptr->file_small_ds_sid_0,
498                                   H5S_SELECT_OR,
499                                   tv_ptr->start,
500                                   tv_ptr->stride,
501                                   tv_ptr->count,
502                                   tv_ptr->block);
503         VRFY((ret>= 0), "H5Sselect_hyperslab(file_small_ds_sid_0, or) suceeded");
504     }
505 
506 
507     /* write the initial value of the small data set to file */
508     ret = H5Dwrite(tv_ptr->small_dataset, tv_ptr->dset_type, tv_ptr->mem_small_ds_sid,
509                    tv_ptr->file_small_ds_sid_0, tv_ptr->xfer_plist, tv_ptr->small_ds_buf_0);
510 
511     VRFY((ret >= 0), "H5Dwrite() small_dataset initial write succeeded");
512 
513 
514     /* sync with the other processes before checking data */
515     if ( ! use_collective_io ) {
516 
517         mrc = MPI_Barrier(MPI_COMM_WORLD);
518         VRFY((mrc==MPI_SUCCESS), "Sync after small dataset writes");
519     }
520 
521     /* read the small data set back to verify that it contains the
522      * expected data.  Note that each process reads in the entire
523      * data set and verifies it.
524      */
525     ret = H5Dread(tv_ptr->small_dataset,
526                   H5T_NATIVE_UINT32,
527                   tv_ptr->full_mem_small_ds_sid,
528                   tv_ptr->full_file_small_ds_sid,
529                   tv_ptr->xfer_plist,
530                   tv_ptr->small_ds_buf_1);
531     VRFY((ret >= 0), "H5Dread() small_dataset initial read succeeded");
532 
533 
534     /* verify that the correct data was written to the small data set */
535     expected_value = 0;
536     mis_match = FALSE;
537     ptr_1 = tv_ptr->small_ds_buf_1;
538 
539     i = 0;
540     for ( i = 0; i < (int)(tv_ptr->small_ds_size); i++ ) {
541 
542         if ( *ptr_1 != expected_value ) {
543 
544             mis_match = TRUE;
545         }
546         ptr_1++;
547         expected_value++;
548     }
549     VRFY( (mis_match == FALSE), "small ds init data good.");
550 
551 
552     /* setup selections for writing initial data to the large data set */
553 
554     tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
555 
556     ret = H5Sselect_hyperslab(tv_ptr->mem_large_ds_sid,
557                               H5S_SELECT_SET,
558                               tv_ptr->start,
559                               tv_ptr->stride,
560                               tv_ptr->count,
561                               tv_ptr->block);
562     VRFY((ret >= 0), "H5Sselect_hyperslab(mem_large_ds_sid, set) suceeded");
563 
564     ret = H5Sselect_hyperslab(tv_ptr->file_large_ds_sid_0,
565                               H5S_SELECT_SET,
566                               tv_ptr->start,
567                               tv_ptr->stride,
568                               tv_ptr->count,
569                               tv_ptr->block);
570     VRFY((ret >= 0), "H5Sselect_hyperslab(file_large_ds_sid_0, set) suceeded");
571 
572     /* In passing, setup the process slice dataspaces as well */
573 
574     ret = H5Sselect_hyperslab(tv_ptr->mem_large_ds_process_slice_sid,
575                               H5S_SELECT_SET,
576                               tv_ptr->start,
577                               tv_ptr->stride,
578                               tv_ptr->count,
579                               tv_ptr->block);
580     VRFY((ret >= 0),
581          "H5Sselect_hyperslab(mem_large_ds_process_slice_sid, set) suceeded");
582 
583     ret = H5Sselect_hyperslab(tv_ptr->file_large_ds_process_slice_sid,
584                               H5S_SELECT_SET,
585                               tv_ptr->start,
586                               tv_ptr->stride,
587                               tv_ptr->count,
588                               tv_ptr->block);
589     VRFY((ret >= 0),
590          "H5Sselect_hyperslab(file_large_ds_process_slice_sid, set) suceeded");
591 
592     if ( MAINPROCESS ) { /* add an additional slice to the selections */
593 
594         tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_size);
595 
596         ret = H5Sselect_hyperslab(tv_ptr->mem_large_ds_sid,
597                                   H5S_SELECT_OR,
598                                   tv_ptr->start,
599                                   tv_ptr->stride,
600                                   tv_ptr->count,
601                                   tv_ptr->block);
602         VRFY((ret>= 0), "H5Sselect_hyperslab(mem_large_ds_sid, or) suceeded");
603 
604         ret = H5Sselect_hyperslab(tv_ptr->file_large_ds_sid_0,
605                                   H5S_SELECT_OR,
606                                   tv_ptr->start,
607                                   tv_ptr->stride,
608                                   tv_ptr->count,
609                                   tv_ptr->block);
610         VRFY((ret>= 0), "H5Sselect_hyperslab(file_large_ds_sid_0, or) suceeded");
611     }
612 
613 
614     /* write the initial value of the large data set to file */
615     ret = H5Dwrite(tv_ptr->large_dataset, tv_ptr->dset_type,
616                    tv_ptr->mem_large_ds_sid, tv_ptr->file_large_ds_sid_0,
617                    tv_ptr->xfer_plist, tv_ptr->large_ds_buf_0);
618     if ( ret < 0 ) H5Eprint2(H5E_DEFAULT, stderr);
619     VRFY((ret >= 0), "H5Dwrite() large_dataset initial write succeeded");
620 
621 
622     /* sync with the other processes before checking data */
623     if ( ! use_collective_io ) {
624 
625         mrc = MPI_Barrier(MPI_COMM_WORLD);
626         VRFY((mrc==MPI_SUCCESS), "Sync after large dataset writes");
627     }
628 
629 
630     /* read the large data set back to verify that it contains the
631      * expected data.  Note that each process reads in the entire
632      * data set.
633      */
634     ret = H5Dread(tv_ptr->large_dataset,
635                   H5T_NATIVE_UINT32,
636                   tv_ptr->full_mem_large_ds_sid,
637                   tv_ptr->full_file_large_ds_sid,
638                   tv_ptr->xfer_plist,
639                   tv_ptr->large_ds_buf_1);
640     VRFY((ret >= 0), "H5Dread() large_dataset initial read succeeded");
641 
642 
643     /* verify that the correct data was written to the large data set */
644     expected_value = 0;
645     mis_match = FALSE;
646     ptr_1 = tv_ptr->large_ds_buf_1;
647 
648     i = 0;
649     for ( i = 0; i < (int)(tv_ptr->large_ds_size); i++ ) {
650 
651         if ( *ptr_1 != expected_value ) {
652 
653             mis_match = TRUE;
654         }
655         ptr_1++;
656         expected_value++;
657     }
658     VRFY( (mis_match == FALSE), "large ds init data good.");
659 
660 
661     /* sync with the other processes before changing data */
662 
663     if ( ! use_collective_io ) {
664 
665         mrc = MPI_Barrier(MPI_COMM_WORLD);
666         VRFY((mrc==MPI_SUCCESS), "Sync initial values check");
667     }
668 
669     return;
670 
671 } /* hs_dr_pio_test__setup() */
672 
673 
674 /*-------------------------------------------------------------------------
675  * Function:    hs_dr_pio_test__takedown()
676  *
677  * Purpose:    Do takedown after tests of I/O to/from hyperslab selections
678  *        of different rank in the parallel case.
679  *
680  * Return:    void
681  *
682  * Programmer:    JRM -- 9/18/09
683  *
684  *-------------------------------------------------------------------------
685  */
686 
687 #define HS_DR_PIO_TEST__TAKEDOWN__DEBUG 0
688 
689 static void
hs_dr_pio_test__takedown(struct hs_dr_pio_test_vars_t * tv_ptr)690 hs_dr_pio_test__takedown( struct hs_dr_pio_test_vars_t * tv_ptr)
691 {
692 #if HS_DR_PIO_TEST__TAKEDOWN__DEBUG
693     const char *fcnName = "hs_dr_pio_test__takedown()";
694 #endif /* HS_DR_PIO_TEST__TAKEDOWN__DEBUG */
695     int        mpi_rank;       /* needed by the VRFY macro */
696     herr_t    ret;        /* Generic return value */
697 
698     /* initialize the local copy of mpi_rank */
699     mpi_rank = tv_ptr->mpi_rank;
700 
701     /* Close property lists */
702     if ( tv_ptr->xfer_plist != H5P_DEFAULT ) {
703         ret = H5Pclose(tv_ptr->xfer_plist);
704         VRFY((ret != FAIL), "H5Pclose(xfer_plist) succeeded");
705     }
706 
707     /* Close dataspaces */
708     ret = H5Sclose(tv_ptr->full_mem_small_ds_sid);
709     VRFY((ret != FAIL), "H5Sclose(full_mem_small_ds_sid) succeeded");
710 
711     ret = H5Sclose(tv_ptr->full_file_small_ds_sid);
712     VRFY((ret != FAIL), "H5Sclose(full_file_small_ds_sid) succeeded");
713 
714     ret = H5Sclose(tv_ptr->mem_small_ds_sid);
715     VRFY((ret != FAIL), "H5Sclose(mem_small_ds_sid) succeeded");
716 
717     ret = H5Sclose(tv_ptr->file_small_ds_sid_0);
718     VRFY((ret != FAIL), "H5Sclose(file_small_ds_sid_0) succeeded");
719 
720     ret = H5Sclose(tv_ptr->file_small_ds_sid_1);
721     VRFY((ret != FAIL), "H5Sclose(file_small_ds_sid_1) succeeded");
722 
723     ret = H5Sclose(tv_ptr->small_ds_slice_sid);
724     VRFY((ret != FAIL), "H5Sclose(small_ds_slice_sid) succeeded");
725 
726     ret = H5Sclose(tv_ptr->full_mem_large_ds_sid);
727     VRFY((ret != FAIL), "H5Sclose(full_mem_large_ds_sid) succeeded");
728 
729     ret = H5Sclose(tv_ptr->full_file_large_ds_sid);
730     VRFY((ret != FAIL), "H5Sclose(full_file_large_ds_sid) succeeded");
731 
732     ret = H5Sclose(tv_ptr->mem_large_ds_sid);
733     VRFY((ret != FAIL), "H5Sclose(mem_large_ds_sid) succeeded");
734 
735     ret = H5Sclose(tv_ptr->file_large_ds_sid_0);
736     VRFY((ret != FAIL), "H5Sclose(file_large_ds_sid_0) succeeded");
737 
738     ret = H5Sclose(tv_ptr->file_large_ds_sid_1);
739     VRFY((ret != FAIL), "H5Sclose(file_large_ds_sid_1) succeeded");
740 
741     ret = H5Sclose(tv_ptr->mem_large_ds_process_slice_sid);
742     VRFY((ret != FAIL), "H5Sclose(mem_large_ds_process_slice_sid) succeeded");
743 
744     ret = H5Sclose(tv_ptr->file_large_ds_process_slice_sid);
745     VRFY((ret != FAIL), "H5Sclose(file_large_ds_process_slice_sid) succeeded");
746 
747     ret = H5Sclose(tv_ptr->large_ds_slice_sid);
748     VRFY((ret != FAIL), "H5Sclose(large_ds_slice_sid) succeeded");
749 
750     /* Close Datasets */
751     ret = H5Dclose(tv_ptr->small_dataset);
752     VRFY((ret != FAIL), "H5Dclose(small_dataset) succeeded");
753 
754     ret = H5Dclose(tv_ptr->large_dataset);
755     VRFY((ret != FAIL), "H5Dclose(large_dataset) succeeded");
756 
757     /* close the file collectively */
758     MESG("about to close file.");
759     ret = H5Fclose(tv_ptr->fid);
760     VRFY((ret != FAIL), "file close succeeded");
761 
762     /* Free memory buffers */
763 
764     if ( tv_ptr->small_ds_buf_0 != NULL ) HDfree(tv_ptr->small_ds_buf_0);
765     if ( tv_ptr->small_ds_buf_1 != NULL ) HDfree(tv_ptr->small_ds_buf_1);
766     if ( tv_ptr->small_ds_buf_2 != NULL ) HDfree(tv_ptr->small_ds_buf_2);
767     if ( tv_ptr->small_ds_slice_buf != NULL ) HDfree(tv_ptr->small_ds_slice_buf);
768 
769     if ( tv_ptr->large_ds_buf_0 != NULL ) HDfree(tv_ptr->large_ds_buf_0);
770     if ( tv_ptr->large_ds_buf_1 != NULL ) HDfree(tv_ptr->large_ds_buf_1);
771     if ( tv_ptr->large_ds_buf_2 != NULL ) HDfree(tv_ptr->large_ds_buf_2);
772     if ( tv_ptr->large_ds_slice_buf != NULL ) HDfree(tv_ptr->large_ds_slice_buf);
773 
774     return;
775 
776 } /* hs_dr_pio_test__takedown() */
777 
778 
779 /*-------------------------------------------------------------------------
780  * Function:    contig_hs_dr_pio_test__d2m_l2s()
781  *
782  * Purpose:    Part one of a series of tests of I/O to/from hyperslab
783  *        selections of different rank in the parallel.
784  *
785  *        Verify that we can read from disk correctly using
786  *        selections of different rank that H5S_select_shape_same()
787  *        views as being of the same shape.
788  *
789  *              In this function, we test this by reading small_rank - 1
790  *        slices from the on disk large cube, and verifying that the
791  *        data read is correct.  Verify that H5S_select_shape_same()
792  *        returns true on the memory and file selections.
793  *
794  * Return:    void
795  *
796  * Programmer:    JRM -- 9/10/11
797  *
798  *-------------------------------------------------------------------------
799  */
800 
801 #define CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG 0
802 
803 static void
contig_hs_dr_pio_test__d2m_l2s(struct hs_dr_pio_test_vars_t * tv_ptr)804 contig_hs_dr_pio_test__d2m_l2s(struct hs_dr_pio_test_vars_t * tv_ptr)
805 {
806 #if CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG
807     const char *fcnName = "contig_hs_dr_pio_test__run_test()";
808 #endif /* CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
809     hbool_t    mis_match = FALSE;
810     int        i, j, k, l;
811     size_t    n;
812     int        mpi_rank; /* needed by the VRFY macro */
813     uint32_t    expected_value;
814     uint32_t  * ptr_1;
815     htri_t      check;          /* Shape comparison return value */
816     herr_t    ret;        /* Generic return value */
817 
818     /* initialize the local copy of mpi_rank */
819     mpi_rank = tv_ptr->mpi_rank;
820 
821 
822     /* We have already done a H5Sselect_all() on the dataspace
823      * small_ds_slice_sid in the initialization phase, so no need to
824      * call H5Sselect_all() again.
825      */
826 
827     /* set up start, stride, count, and block -- note that we will
828      * change start[] so as to read slices of the large cube.
829      */
830     for ( i = 0; i < PAR_SS_DR_MAX_RANK; i++ ) {
831 
832         tv_ptr->start[i] = 0;
833         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
834         tv_ptr->count[i] = 1;
835         if ( (PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1) ) {
836 
837             tv_ptr->block[i] = 1;
838 
839         } else {
840 
841             tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
842         }
843     }
844 
845     /* zero out the buffer we will be reading into */
846     HDmemset(tv_ptr->small_ds_slice_buf, 0, sizeof(uint32_t) * tv_ptr->small_ds_slice_size);
847 
848 #if CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG
849     HDfprintf(stdout,
850               "%s reading slices from big cube on disk into small cube slice.\n",
851               fcnName);
852 #endif /* CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
853 
854     /* in serial versions of this test, we loop through all the dimensions
855      * of the large data set.  However, in the parallel version, each
856      * process only works with that slice of the large cube indicated
857      * by its rank -- hence we set the most slowly changing index to
858      * mpi_rank, and don't itterate over it.
859      */
860 
861     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0 ) {
862 
863         i = tv_ptr->mpi_rank;
864 
865     } else {
866 
867         i = 0;
868     }
869 
870     /* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
871      * loop over it -- either we are setting i to mpi_rank, or
872      * we are setting it to zero.  It will not change during the
873      * test.
874      */
875 
876     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1 ) {
877 
878         j = tv_ptr->mpi_rank;
879 
880     } else {
881 
882         j = 0;
883     }
884 
885     do {
886         if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2 ) {
887 
888             k = tv_ptr->mpi_rank;
889 
890         } else {
891 
892             k = 0;
893         }
894 
895         do {
896             /* since small rank >= 2 and large_rank > small_rank, we
897              * have large_rank >= 3.  Since PAR_SS_DR_MAX_RANK == 5
898              * (baring major re-orgaization), this gives us:
899              *
900              *     (PAR_SS_DR_MAX_RANK - large_rank) <= 2
901              *
902              * so no need to repeat the test in the outer loops --
903              * just set l = 0.
904              */
905 
906             l = 0;
907             do {
908                 if ( (tv_ptr->skips)++ < tv_ptr->max_skips ) { /* skip the test */
909 
910             (tv_ptr->tests_skipped)++;
911 
912                 } else { /* run the test */
913 
914                     tv_ptr->skips = 0; /* reset the skips counter */
915 
916                     /* we know that small_rank - 1 >= 1 and that
917                      * large_rank > small_rank by the assertions at the head
918                      * of this function.  Thus no need for another inner loop.
919                      */
920                     tv_ptr->start[0] = (hsize_t)i;
921                     tv_ptr->start[1] = (hsize_t)j;
922                     tv_ptr->start[2] = (hsize_t)k;
923                     tv_ptr->start[3] = (hsize_t)l;
924                     tv_ptr->start[4] = 0;
925 
926                     ret = H5Sselect_hyperslab(tv_ptr->file_large_ds_sid_0,
927                                               H5S_SELECT_SET,
928                                               tv_ptr->start_ptr,
929                                               tv_ptr->stride_ptr,
930                                               tv_ptr->count_ptr,
931                                               tv_ptr->block_ptr);
932                     VRFY((ret != FAIL),
933                          "H5Sselect_hyperslab(file_large_cube_sid) succeeded");
934 
935 
936                     /* verify that H5S_select_shape_same() reports the two
937                      * selections as having the same shape.
938                      */
939                     check = H5S_select_shape_same_test(tv_ptr->small_ds_slice_sid,
940                                                        tv_ptr->file_large_ds_sid_0);
941                     VRFY((check == TRUE), "H5S_select_shape_same_test passed");
942 
943 
944                     /* Read selection from disk */
945 #if CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG
946                     HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n",
947                               fcnName, (int)(tv_ptr->mpi_rank),
948                               (int)(tv_ptr->start[0]), (int)(tv_ptr->start[1]),
949                               (int)(tv_ptr->start[2]), (int)(tv_ptr->start[3]),
950                               (int)(tv_ptr->start[4]));
951                     HDfprintf(stdout, "%s slice/file extent dims = %d/%d.\n",
952                               fcnName,
953                               H5Sget_simple_extent_ndims(tv_ptr->small_ds_slice_sid),
954                               H5Sget_simple_extent_ndims(tv_ptr->file_large_ds_sid_0));
955 #endif /* CONTIG_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
956                     ret = H5Dread(tv_ptr->large_dataset,
957                                   H5T_NATIVE_UINT32,
958                                   tv_ptr->small_ds_slice_sid,
959                                   tv_ptr->file_large_ds_sid_0,
960                                   tv_ptr->xfer_plist,
961                                   tv_ptr->small_ds_slice_buf);
962                     VRFY((ret >= 0), "H5Dread() slice from large ds succeeded.");
963 
964 
965                     /* verify that expected data is retrieved */
966 
967                     mis_match = FALSE;
968                     ptr_1 = tv_ptr->small_ds_slice_buf;
969                     expected_value = (uint32_t)(
970                         (i * tv_ptr->edge_size * tv_ptr->edge_size *
971                              tv_ptr->edge_size * tv_ptr->edge_size) +
972                         (j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
973                         (k * tv_ptr->edge_size * tv_ptr->edge_size) +
974                         (l * tv_ptr->edge_size));
975 
976                     for ( n = 0; n < tv_ptr->small_ds_slice_size; n++ ) {
977 
978                         if ( *ptr_1 != expected_value ) {
979 
980                             mis_match = TRUE;
981                         }
982 
983                         *ptr_1 = 0; /* zero data for next use */
984 
985                         ptr_1++;
986                         expected_value++;
987                     }
988 
989                     VRFY((mis_match == FALSE),
990                          "small slice read from large ds data good.");
991 
992             (tv_ptr->tests_run)++;
993                 }
994 
995                 l++;
996 
997                 (tv_ptr->total_tests)++;
998 
999             } while ( ( tv_ptr->large_rank > 2 ) &&
1000                       ( (tv_ptr->small_rank - 1) <= 1 ) &&
1001                       ( l < tv_ptr->edge_size ) );
1002             k++;
1003         } while ( ( tv_ptr->large_rank > 3 ) &&
1004                   ( (tv_ptr->small_rank - 1) <= 2 ) &&
1005                   ( k < tv_ptr->edge_size ) );
1006         j++;
1007     } while ( ( tv_ptr->large_rank > 4 ) &&
1008               ( (tv_ptr->small_rank - 1) <= 3 ) &&
1009               ( j < tv_ptr->edge_size ) );
1010 
1011     return;
1012 
1013 } /* contig_hs_dr_pio_test__d2m_l2s() */
1014 
1015 
1016 /*-------------------------------------------------------------------------
1017  * Function:    contig_hs_dr_pio_test__d2m_s2l()
1018  *
1019  * Purpose:    Part two of a series of tests of I/O to/from hyperslab
1020  *        selections of different rank in the parallel.
1021  *
1022  *        Verify that we can read from disk correctly using
1023  *        selections of different rank that H5S_select_shape_same()
1024  *        views as being of the same shape.
1025  *
1026  *        In this function, we test this by reading slices of the
1027  *        on disk small data set into slices through the in memory
1028  *        large data set, and verify that the correct data (and
1029  *        only the correct data) is read.
1030  *
1031  * Return:    void
1032  *
1033  * Programmer:    JRM -- 8/10/11
1034  *
1035  *-------------------------------------------------------------------------
1036  */
1037 
1038 #define CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG 0
1039 
1040 static void
contig_hs_dr_pio_test__d2m_s2l(struct hs_dr_pio_test_vars_t * tv_ptr)1041 contig_hs_dr_pio_test__d2m_s2l(struct hs_dr_pio_test_vars_t * tv_ptr)
1042 {
1043 #if CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG
1044     const char *fcnName = "contig_hs_dr_pio_test__d2m_s2l()";
1045 #endif /* CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
1046     hbool_t    mis_match = FALSE;
1047     int        i, j, k, l;
1048     size_t    n;
1049     int        mpi_rank; /* needed by the VRFY macro */
1050     size_t      start_index;
1051     size_t      stop_index;
1052     uint32_t    expected_value;
1053     uint32_t  * ptr_1;
1054     htri_t      check;          /* Shape comparison return value */
1055     herr_t    ret;        /* Generic return value */
1056 
1057     /* initialize the local copy of mpi_rank */
1058     mpi_rank = tv_ptr->mpi_rank;
1059 
1060     /* Read slices of the on disk small data set into slices
1061      * through the in memory large data set, and verify that the correct
1062      * data (and only the correct data) is read.
1063      */
1064 
1065     tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
1066     tv_ptr->stride[0] = (hsize_t)(2 * (tv_ptr->mpi_size + 1));
1067     tv_ptr->count[0] = 1;
1068     tv_ptr->block[0] = 1;
1069 
1070     for ( i = 1; i < tv_ptr->large_rank; i++ ) {
1071 
1072         tv_ptr->start[i] = 0;
1073         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
1074         tv_ptr->count[i] = 1;
1075         tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
1076     }
1077 
1078     ret = H5Sselect_hyperslab(tv_ptr->file_small_ds_sid_0,
1079                               H5S_SELECT_SET,
1080                               tv_ptr->start,
1081                               tv_ptr->stride,
1082                               tv_ptr->count,
1083                               tv_ptr->block);
1084     VRFY((ret >= 0), "H5Sselect_hyperslab(file_small_ds_sid_0, set) suceeded");
1085 
1086 
1087 #if CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG
1088     HDfprintf(stdout,
1089       "%s reading slices of on disk small data set into slices of big data set.\n",
1090               fcnName);
1091 #endif /* CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
1092 
1093     /* zero out the in memory large ds */
1094     HDmemset(tv_ptr->large_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->large_ds_size);
1095 
1096     /* set up start, stride, count, and block -- note that we will
1097      * change start[] so as to read slices of the large cube.
1098      */
1099     for ( i = 0; i < PAR_SS_DR_MAX_RANK; i++ ) {
1100 
1101         tv_ptr->start[i] = 0;
1102         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
1103         tv_ptr->count[i] = 1;
1104         if ( (PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1) ) {
1105 
1106             tv_ptr->block[i] = 1;
1107 
1108         } else {
1109 
1110             tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
1111         }
1112     }
1113 
1114 
1115     /* in serial versions of this test, we loop through all the dimensions
1116      * of the large data set that don't appear in the small data set.
1117      *
1118      * However, in the parallel version, each process only works with that
1119      * slice of the large (and small) data set indicated by its rank -- hence
1120      * we set the most slowly changing index to mpi_rank, and don't itterate
1121      * over it.
1122      */
1123 
1124 
1125     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0 ) {
1126 
1127         i = tv_ptr->mpi_rank;
1128 
1129     } else {
1130 
1131         i = 0;
1132     }
1133 
1134     /* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
1135      * loop over it -- either we are setting i to mpi_rank, or
1136      * we are setting it to zero.  It will not change during the
1137      * test.
1138      */
1139 
1140     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1 ) {
1141 
1142         j = tv_ptr->mpi_rank;
1143 
1144     } else {
1145 
1146         j = 0;
1147     }
1148 
1149     do {
1150         if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2 ) {
1151 
1152             k = tv_ptr->mpi_rank;
1153 
1154         } else {
1155 
1156             k = 0;
1157         }
1158 
1159         do {
1160             /* since small rank >= 2 and large_rank > small_rank, we
1161              * have large_rank >= 3.  Since PAR_SS_DR_MAX_RANK == 5
1162              * (baring major re-orgaization), this gives us:
1163              *
1164              *     (PAR_SS_DR_MAX_RANK - large_rank) <= 2
1165              *
1166              * so no need to repeat the test in the outer loops --
1167              * just set l = 0.
1168              */
1169 
1170             l = 0;
1171             do {
1172                 if ( (tv_ptr->skips)++ < tv_ptr->max_skips ) { /* skip the test */
1173 
1174                     (tv_ptr->tests_skipped)++;
1175 
1176                 } else { /* run the test */
1177 
1178                     tv_ptr->skips = 0; /* reset the skips counter */
1179 
1180                     /* we know that small_rank >= 1 and that large_rank > small_rank
1181                      * by the assertions at the head of this function.  Thus no
1182                      * need for another inner loop.
1183                      */
1184                     tv_ptr->start[0] = (hsize_t)i;
1185                     tv_ptr->start[1] = (hsize_t)j;
1186                     tv_ptr->start[2] = (hsize_t)k;
1187                     tv_ptr->start[3] = (hsize_t)l;
1188                     tv_ptr->start[4] = 0;
1189 
1190                     ret = H5Sselect_hyperslab(tv_ptr->mem_large_ds_sid,
1191                                               H5S_SELECT_SET,
1192                                               tv_ptr->start_ptr,
1193                                               tv_ptr->stride_ptr,
1194                                               tv_ptr->count_ptr,
1195                                               tv_ptr->block_ptr);
1196                     VRFY((ret != FAIL),
1197                          "H5Sselect_hyperslab(mem_large_ds_sid) succeeded");
1198 
1199 
1200                     /* verify that H5S_select_shape_same() reports the two
1201                      * selections as having the same shape.
1202                      */
1203                     check = H5S_select_shape_same_test(tv_ptr->file_small_ds_sid_0,
1204                                                        tv_ptr->mem_large_ds_sid);
1205                     VRFY((check == TRUE), "H5S_select_shape_same_test passed");
1206 
1207 
1208                     /* Read selection from disk */
1209 #if CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG
1210                     HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n",
1211                               fcnName, (int)(tv_ptr->mpi_rank),
1212                               (int)(tv_ptr->start[0]), (int)(tv_ptr->start[1]),
1213                               (int)(tv_ptr->start[2]), (int)(tv_ptr->start[3]),
1214                               (int)(tv_ptr->start[4]));
1215                     HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n",
1216                               fcnName, tv_ptr->mpi_rank,
1217                               H5Sget_simple_extent_ndims(tv_ptr->mem_large_ds_sid),
1218                               H5Sget_simple_extent_ndims(tv_ptr->file_small_ds_sid_0));
1219 #endif /* CONTIG_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
1220                     ret = H5Dread(tv_ptr->small_dataset,
1221                                   H5T_NATIVE_UINT32,
1222                                   tv_ptr->mem_large_ds_sid,
1223                                   tv_ptr->file_small_ds_sid_0,
1224                                   tv_ptr->xfer_plist,
1225                                   tv_ptr->large_ds_buf_1);
1226                     VRFY((ret >= 0), "H5Dread() slice from small ds succeeded.");
1227 
1228                     /* verify that the expected data and only the
1229                      * expected data was read.
1230                      */
1231                     ptr_1 = tv_ptr->large_ds_buf_1;
1232                     expected_value = (uint32_t)
1233                         ((size_t)(tv_ptr->mpi_rank) * tv_ptr->small_ds_slice_size);
1234                     start_index = (size_t)(
1235                         (i * tv_ptr->edge_size * tv_ptr->edge_size *
1236                              tv_ptr->edge_size * tv_ptr->edge_size) +
1237                         (j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
1238                         (k * tv_ptr->edge_size * tv_ptr->edge_size) +
1239                         (l * tv_ptr->edge_size));
1240                     stop_index = start_index + tv_ptr->small_ds_slice_size - 1;
1241 
1242                     HDassert( start_index < stop_index );
1243                     HDassert( stop_index <= tv_ptr->large_ds_size );
1244 
1245                     for ( n = 0; n < tv_ptr->large_ds_size; n++ ) {
1246 
1247                         if ( ( n >= start_index ) && ( n <= stop_index ) ) {
1248 
1249                             if ( *ptr_1 != expected_value ) {
1250 
1251                                 mis_match = TRUE;
1252                             }
1253                             expected_value++;
1254 
1255                         } else {
1256 
1257                             if ( *ptr_1 != 0 ) {
1258 
1259                                 mis_match = TRUE;
1260                             }
1261                         }
1262                         /* zero out the value for the next pass */
1263                         *ptr_1 = 0;
1264 
1265                         ptr_1++;
1266                     }
1267 
1268                     VRFY((mis_match == FALSE),
1269                          "small slice read from large ds data good.");
1270 
1271                     (tv_ptr->tests_run)++;
1272                 }
1273 
1274                 l++;
1275 
1276                 (tv_ptr->total_tests)++;
1277 
1278             } while ( ( tv_ptr->large_rank > 2 ) &&
1279                       ( (tv_ptr->small_rank - 1) <= 1 ) &&
1280                       ( l < tv_ptr->edge_size ) );
1281             k++;
1282         } while ( ( tv_ptr->large_rank > 3 ) &&
1283                   ( (tv_ptr->small_rank - 1) <= 2 ) &&
1284                   ( k < tv_ptr->edge_size ) );
1285         j++;
1286     } while ( ( tv_ptr->large_rank > 4 ) &&
1287               ( (tv_ptr->small_rank - 1) <= 3 ) &&
1288               ( j < tv_ptr->edge_size ) );
1289 
1290     return;
1291 
1292 } /* contig_hs_dr_pio_test__d2m_s2l() */
1293 
1294 
1295 /*-------------------------------------------------------------------------
1296  * Function:    contig_hs_dr_pio_test__m2d_l2s()
1297  *
1298  * Purpose:    Part three of a series of tests of I/O to/from hyperslab
1299  *        selections of different rank in the parallel.
1300  *
1301  *        Verify that we can write from memory to file using
1302  *        selections of different rank that H5S_select_shape_same()
1303  *        views as being of the same shape.
1304  *
1305  *        Do this by writing small_rank - 1 dimensional slices from
1306  *        the in memory large data set to the on disk small cube
1307  *        dataset.  After each write, read the slice of the small
1308  *        dataset back from disk, and verify that it contains
1309  *              the expected data. Verify that H5S_select_shape_same()
1310  *        returns true on the memory and file selections.
1311  *
1312  * Return:    void
1313  *
1314  * Programmer:    JRM -- 8/10/11
1315  *
1316  *-------------------------------------------------------------------------
1317  */
1318 
1319 #define CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG 0
1320 
1321 static void
contig_hs_dr_pio_test__m2d_l2s(struct hs_dr_pio_test_vars_t * tv_ptr)1322 contig_hs_dr_pio_test__m2d_l2s(struct hs_dr_pio_test_vars_t * tv_ptr)
1323 {
1324 #if CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG
1325     const char *fcnName = "contig_hs_dr_pio_test__m2d_l2s()";
1326 #endif /* CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG */
1327     hbool_t    mis_match = FALSE;
1328     int        i, j, k, l;
1329     size_t    n;
1330     int        mpi_rank; /* needed by the VRFY macro */
1331     size_t      start_index;
1332     size_t      stop_index;
1333     uint32_t    expected_value;
1334     uint32_t  * ptr_1;
1335     htri_t      check;          /* Shape comparison return value */
1336     herr_t    ret;        /* Generic return value */
1337 
1338     /* initialize the local copy of mpi_rank */
1339     mpi_rank = tv_ptr->mpi_rank;
1340 
1341 
1342     /* now we go in the opposite direction, verifying that we can write
1343      * from memory to file using selections of different rank that
1344      * H5S_select_shape_same() views as being of the same shape.
1345      *
1346      * Start by writing small_rank - 1 dimensional slices from the in memory large
1347      * data set to the on disk small cube dataset.  After each write, read the
1348      * slice of the small dataset back from disk, and verify that it contains
1349      * the expected data. Verify that H5S_select_shape_same() returns true on
1350      * the memory and file selections.
1351      */
1352 
1353     tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
1354     tv_ptr->stride[0] = (hsize_t)(2 * (tv_ptr->mpi_size + 1));
1355     tv_ptr->count[0] = 1;
1356     tv_ptr->block[0] = 1;
1357 
1358     for ( i = 1; i < tv_ptr->large_rank; i++ ) {
1359 
1360         tv_ptr->start[i] = 0;
1361         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
1362         tv_ptr->count[i] = 1;
1363         tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
1364     }
1365 
1366     ret = H5Sselect_hyperslab(tv_ptr->file_small_ds_sid_0,
1367                               H5S_SELECT_SET,
1368                               tv_ptr->start,
1369                               tv_ptr->stride,
1370                               tv_ptr->count,
1371                               tv_ptr->block);
1372     VRFY((ret >= 0), "H5Sselect_hyperslab(file_small_ds_sid_0, set) suceeded");
1373 
1374     ret = H5Sselect_hyperslab(tv_ptr->mem_small_ds_sid,
1375                               H5S_SELECT_SET,
1376                               tv_ptr->start,
1377                               tv_ptr->stride,
1378                               tv_ptr->count,
1379                               tv_ptr->block);
1380     VRFY((ret >= 0), "H5Sselect_hyperslab(mem_small_ds_sid, set) suceeded");
1381 
1382 
1383     /* set up start, stride, count, and block -- note that we will
1384      * change start[] so as to read slices of the large cube.
1385      */
1386     for ( i = 0; i < PAR_SS_DR_MAX_RANK; i++ ) {
1387 
1388         tv_ptr->start[i] = 0;
1389         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
1390         tv_ptr->count[i] = 1;
1391         if ( (PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1) ) {
1392 
1393             tv_ptr->block[i] = 1;
1394 
1395         } else {
1396 
1397             tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
1398         }
1399     }
1400 
1401     /* zero out the in memory small ds */
1402     HDmemset(tv_ptr->small_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->small_ds_size);
1403 
1404 
1405 #if CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG
1406     HDfprintf(stdout,
1407               "%s writing slices from big ds to slices of small ds on disk.\n",
1408               fcnName);
1409 #endif /* CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG */
1410 
1411     /* in serial versions of this test, we loop through all the dimensions
1412      * of the large data set that don't appear in the small data set.
1413      *
1414      * However, in the parallel version, each process only works with that
1415      * slice of the large (and small) data set indicated by its rank -- hence
1416      * we set the most slowly changing index to mpi_rank, and don't itterate
1417      * over it.
1418      */
1419 
1420 
1421     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0 ) {
1422 
1423         i = tv_ptr->mpi_rank;
1424 
1425     } else {
1426 
1427         i = 0;
1428     }
1429 
1430     /* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
1431      * loop over it -- either we are setting i to mpi_rank, or
1432      * we are setting it to zero.  It will not change during the
1433      * test.
1434      */
1435 
1436     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1 ) {
1437 
1438         j = tv_ptr->mpi_rank;
1439 
1440     } else {
1441 
1442         j = 0;
1443     }
1444 
1445     j = 0;
1446     do {
1447         if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2 ) {
1448 
1449             k = tv_ptr->mpi_rank;
1450 
1451         } else {
1452 
1453             k = 0;
1454         }
1455 
1456         do {
1457             /* since small rank >= 2 and large_rank > small_rank, we
1458              * have large_rank >= 3.  Since PAR_SS_DR_MAX_RANK == 5
1459              * (baring major re-orgaization), this gives us:
1460              *
1461              *     (PAR_SS_DR_MAX_RANK - large_rank) <= 2
1462              *
1463              * so no need to repeat the test in the outer loops --
1464              * just set l = 0.
1465              */
1466 
1467             l = 0;
1468             do {
1469                 if ( (tv_ptr->skips)++ < tv_ptr->max_skips ) { /* skip the test */
1470 
1471                     (tv_ptr->tests_skipped)++;
1472 
1473                 } else { /* run the test */
1474 
1475                     tv_ptr->skips = 0; /* reset the skips counter */
1476 
1477                     /* we know that small_rank >= 1 and that large_rank > small_rank
1478                      * by the assertions at the head of this function.  Thus no
1479                      * need for another inner loop.
1480                      */
1481 
1482                     /* zero out this rank's slice of the on disk small data set */
1483                     ret = H5Dwrite(tv_ptr->small_dataset,
1484                                    H5T_NATIVE_UINT32,
1485                                    tv_ptr->mem_small_ds_sid,
1486                                    tv_ptr->file_small_ds_sid_0,
1487                                    tv_ptr->xfer_plist,
1488                                    tv_ptr->small_ds_buf_2);
1489                     VRFY((ret >= 0), "H5Dwrite() zero slice to small ds succeeded.");
1490 
1491                     /* select the portion of the in memory large cube from which we
1492                      * are going to write data.
1493                      */
1494                     tv_ptr->start[0] = (hsize_t)i;
1495                     tv_ptr->start[1] = (hsize_t)j;
1496                     tv_ptr->start[2] = (hsize_t)k;
1497                     tv_ptr->start[3] = (hsize_t)l;
1498                     tv_ptr->start[4] = 0;
1499 
1500                     ret = H5Sselect_hyperslab(tv_ptr->mem_large_ds_sid,
1501                                               H5S_SELECT_SET,
1502                                               tv_ptr->start_ptr,
1503                                               tv_ptr->stride_ptr,
1504                                               tv_ptr->count_ptr,
1505                                               tv_ptr->block_ptr);
1506                     VRFY((ret >= 0),
1507                          "H5Sselect_hyperslab() mem_large_ds_sid succeeded.");
1508 
1509 
1510                     /* verify that H5S_select_shape_same() reports the in
1511                      * memory slice through the cube selection and the
1512                      * on disk full square selections as having the same shape.
1513                      */
1514                     check = H5S_select_shape_same_test(tv_ptr->file_small_ds_sid_0,
1515                                                        tv_ptr->mem_large_ds_sid);
1516                     VRFY((check == TRUE), "H5S_select_shape_same_test passed.");
1517 
1518 
1519                     /* write the slice from the in memory large data set to the
1520                      * slice of the on disk small dataset. */
1521 #if CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG
1522                     HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n",
1523                               fcnName, (int)(tv_ptr->mpi_rank),
1524                               (int)(tv_ptr->start[0]), (int)(tv_ptr->start[1]),
1525                               (int)(tv_ptr->start[2]), (int)(tv_ptr->start[3]),
1526                               (int)(tv_ptr->start[4]));
1527                     HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n",
1528                               fcnName, tv_ptr->mpi_rank,
1529                               H5Sget_simple_extent_ndims(tv_ptr->mem_large_ds_sid),
1530                               H5Sget_simple_extent_ndims(tv_ptr->file_small_ds_sid_0));
1531 #endif /* CONTIG_HS_DR_PIO_TEST__M2D_L2S__DEBUG */
1532                     ret = H5Dwrite(tv_ptr->small_dataset,
1533                                    H5T_NATIVE_UINT32,
1534                                    tv_ptr->mem_large_ds_sid,
1535                                    tv_ptr->file_small_ds_sid_0,
1536                                    tv_ptr->xfer_plist,
1537                                    tv_ptr->large_ds_buf_0);
1538                     VRFY((ret >= 0), "H5Dwrite() slice to large ds succeeded.");
1539 
1540 
1541                     /* read the on disk square into memory */
1542                     ret = H5Dread(tv_ptr->small_dataset,
1543                                   H5T_NATIVE_UINT32,
1544                                   tv_ptr->mem_small_ds_sid,
1545                                   tv_ptr->file_small_ds_sid_0,
1546                                   tv_ptr->xfer_plist,
1547                                   tv_ptr->small_ds_buf_1);
1548                     VRFY((ret >= 0), "H5Dread() slice from small ds succeeded.");
1549 
1550 
1551                     /* verify that expected data is retrieved */
1552 
1553                     mis_match = FALSE;
1554                     ptr_1 = tv_ptr->small_ds_buf_1;
1555 
1556                     expected_value = (uint32_t)(
1557                         (i * tv_ptr->edge_size * tv_ptr->edge_size *
1558                              tv_ptr->edge_size * tv_ptr->edge_size) +
1559                         (j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
1560                         (k * tv_ptr->edge_size * tv_ptr->edge_size) +
1561                         (l * tv_ptr->edge_size));
1562 
1563                     start_index = (size_t)(tv_ptr->mpi_rank) * tv_ptr->small_ds_slice_size;
1564                     stop_index = start_index + tv_ptr->small_ds_slice_size - 1;
1565 
1566                     HDassert( start_index < stop_index );
1567                     HDassert( stop_index <= tv_ptr->small_ds_size );
1568 
1569                     for ( n = 0; n < tv_ptr->small_ds_size; n++ ) {
1570 
1571                         if ( ( n >= start_index ) && ( n <= stop_index ) ) {
1572 
1573                             if ( *ptr_1 != expected_value ) {
1574 
1575                                 mis_match = TRUE;
1576                             }
1577                             expected_value++;
1578 
1579                         } else {
1580 
1581                             if ( *ptr_1 != 0 ) {
1582 
1583                                 mis_match = TRUE;
1584                             }
1585                         }
1586                         /* zero out the value for the next pass */
1587                         *ptr_1 = 0;
1588 
1589                         ptr_1++;
1590                     }
1591 
1592                     VRFY((mis_match == FALSE),
1593                          "small slice write from large ds data good.");
1594 
1595                     (tv_ptr->tests_run)++;
1596                 }
1597 
1598                 l++;
1599 
1600                (tv_ptr->total_tests)++;
1601 
1602             } while ( ( tv_ptr->large_rank > 2 ) &&
1603                       ( (tv_ptr->small_rank - 1) <= 1 ) &&
1604                       ( l < tv_ptr->edge_size ) );
1605             k++;
1606         } while ( ( tv_ptr->large_rank > 3 ) &&
1607                   ( (tv_ptr->small_rank - 1) <= 2 ) &&
1608                   ( k < tv_ptr->edge_size ) );
1609         j++;
1610     } while ( ( tv_ptr->large_rank > 4 ) &&
1611               ( (tv_ptr->small_rank - 1) <= 3 ) &&
1612               ( j < tv_ptr->edge_size ) );
1613 
1614     return;
1615 
1616 } /* contig_hs_dr_pio_test__m2d_l2s() */
1617 
1618 
1619 /*-------------------------------------------------------------------------
1620  * Function:    contig_hs_dr_pio_test__m2d_s2l()
1621  *
1622  * Purpose:    Part four of a series of tests of I/O to/from hyperslab
1623  *        selections of different rank in the parallel.
1624  *
1625  *        Verify that we can write from memory to file using
1626  *        selections of different rank that H5S_select_shape_same()
1627  *        views as being of the same shape.
1628  *
1629  *        Do this by writing the contents of the process's slice of
1630  *        the in memory small data set to slices of the on disk
1631  *        large data set.  After each write, read the process's
1632  *        slice of the large data set back into memory, and verify
1633  *        that it contains the expected data.
1634  *
1635  *        Verify that H5S_select_shape_same() returns true on the
1636  *        memory and file selections.
1637  *
1638  * Return:    void
1639  *
1640  * Programmer:    JRM -- 8/10/11
1641  *
1642  *-------------------------------------------------------------------------
1643  */
1644 
1645 #define CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG 0
1646 
1647 static void
contig_hs_dr_pio_test__m2d_s2l(struct hs_dr_pio_test_vars_t * tv_ptr)1648 contig_hs_dr_pio_test__m2d_s2l(struct hs_dr_pio_test_vars_t * tv_ptr)
1649 {
1650 #if CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG
1651     const char *fcnName = "contig_hs_dr_pio_test__m2d_s2l()";
1652 #endif /* CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
1653     hbool_t    mis_match = FALSE;
1654     int        i, j, k, l;
1655     size_t    n;
1656     int        mpi_rank; /* needed by the VRFY macro */
1657     size_t      start_index;
1658     size_t      stop_index;
1659     uint32_t    expected_value;
1660     uint32_t  * ptr_1;
1661     htri_t      check;          /* Shape comparison return value */
1662     herr_t    ret;        /* Generic return value */
1663 
1664     /* initialize the local copy of mpi_rank */
1665     mpi_rank = tv_ptr->mpi_rank;
1666 
1667     /* Now write the contents of the process's slice of the in memory
1668      * small data set to slices of the on disk large data set.  After
1669      * each write, read the process's slice of the large data set back
1670      * into memory, and verify that it contains the expected data.
1671      * Verify that H5S_select_shape_same() returns true on the memory
1672      * and file selections.
1673      */
1674 
1675     /* select the slice of the in memory small data set associated with
1676      * the process's mpi rank.
1677      */
1678     tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
1679     tv_ptr->stride[0] = (hsize_t)(2 * (tv_ptr->mpi_size + 1));
1680     tv_ptr->count[0] = 1;
1681     tv_ptr->block[0] = 1;
1682 
1683     for ( i = 1; i < tv_ptr->large_rank; i++ ) {
1684 
1685         tv_ptr->start[i] = 0;
1686         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
1687         tv_ptr->count[i] = 1;
1688         tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
1689     }
1690 
1691     ret = H5Sselect_hyperslab(tv_ptr->mem_small_ds_sid,
1692                               H5S_SELECT_SET,
1693                               tv_ptr->start,
1694                               tv_ptr->stride,
1695                               tv_ptr->count,
1696                               tv_ptr->block);
1697     VRFY((ret >= 0), "H5Sselect_hyperslab(mem_small_ds_sid, set) suceeded");
1698 
1699 
1700     /* set up start, stride, count, and block -- note that we will
1701      * change start[] so as to write slices of the small data set to
1702      * slices of the large data set.
1703      */
1704     for ( i = 0; i < PAR_SS_DR_MAX_RANK; i++ ) {
1705 
1706         tv_ptr->start[i] = 0;
1707         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
1708         tv_ptr->count[i] = 1;
1709         if ( (PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1) ) {
1710 
1711             tv_ptr->block[i] = 1;
1712 
1713         } else {
1714 
1715             tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
1716         }
1717     }
1718 
1719     /* zero out the in memory large ds */
1720     HDmemset(tv_ptr->large_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->large_ds_size);
1721 
1722 #if CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG
1723     HDfprintf(stdout,
1724          "%s writing process slices of small ds to slices of large ds on disk.\n",
1725          fcnName);
1726 #endif /* CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
1727 
1728     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0 ) {
1729 
1730         i = tv_ptr->mpi_rank;
1731 
1732     } else {
1733 
1734         i = 0;
1735     }
1736 
1737     /* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
1738      * loop over it -- either we are setting i to mpi_rank, or
1739      * we are setting it to zero.  It will not change during the
1740      * test.
1741      */
1742 
1743     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1 ) {
1744 
1745         j = tv_ptr->mpi_rank;
1746 
1747     } else {
1748 
1749         j = 0;
1750     }
1751 
1752     do {
1753         if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2 ) {
1754 
1755             k = tv_ptr->mpi_rank;
1756 
1757         } else {
1758 
1759             k = 0;
1760         }
1761 
1762         do {
1763             /* since small rank >= 2 and large_rank > small_rank, we
1764              * have large_rank >= 3.  Since PAR_SS_DR_MAX_RANK == 5
1765              * (baring major re-orgaization), this gives us:
1766              *
1767              *     (PAR_SS_DR_MAX_RANK - large_rank) <= 2
1768              *
1769              * so no need to repeat the test in the outer loops --
1770              * just set l = 0.
1771              */
1772 
1773             l = 0;
1774             do {
1775                 if ( (tv_ptr->skips)++ < tv_ptr->max_skips ) { /* skip the test */
1776 
1777                     (tv_ptr->tests_skipped)++;
1778 
1779 #if CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG
1780                     tv_ptr->start[0] = (hsize_t)i;
1781                     tv_ptr->start[1] = (hsize_t)j;
1782                     tv_ptr->start[2] = (hsize_t)k;
1783                     tv_ptr->start[3] = (hsize_t)l;
1784                     tv_ptr->start[4] = 0;
1785 
1786                     HDfprintf(stdout,
1787                               "%s:%d: skipping test with start = %d %d %d %d %d.\n",
1788                               fcnName, (int)(tv_ptr->mpi_rank),
1789                               (int)(tv_ptr->start[0]), (int)(tv_ptr->start[1]),
1790                               (int)(tv_ptr->start[2]), (int)(tv_ptr->start[3]),
1791                               (int)(tv_ptr->start[4]));
1792                     HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n",
1793                               fcnName, tv_ptr->mpi_rank,
1794                               H5Sget_simple_extent_ndims(tv_ptr->mem_small_ds_sid),
1795                               H5Sget_simple_extent_ndims(tv_ptr->file_large_ds_sid_0));
1796 #endif /* CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
1797                 } else { /* run the test */
1798 
1799                     tv_ptr->skips = 0; /* reset the skips counter */
1800 
1801                     /* we know that small_rank >= 1 and that large_rank > small_rank
1802                      * by the assertions at the head of this function.  Thus no
1803                      * need for another inner loop.
1804                      */
1805 
1806                     /* Zero out this processes slice of the on disk large data set.
1807                      * Note that this will leave one slice with its original data
1808                      * as there is one more slice than processes.
1809                      */
1810                     ret = H5Dwrite(tv_ptr->large_dataset,
1811                                    H5T_NATIVE_UINT32,
1812                                    tv_ptr->large_ds_slice_sid,
1813                                    tv_ptr->file_large_ds_process_slice_sid,
1814                                    tv_ptr->xfer_plist,
1815                                    tv_ptr->large_ds_buf_2);
1816                     VRFY((ret != FAIL), "H5Dwrite() to zero large ds suceeded");
1817 
1818 
1819                     /* select the portion of the in memory large cube to which we
1820                      * are going to write data.
1821                      */
1822                     tv_ptr->start[0] = (hsize_t)i;
1823                     tv_ptr->start[1] = (hsize_t)j;
1824                     tv_ptr->start[2] = (hsize_t)k;
1825                     tv_ptr->start[3] = (hsize_t)l;
1826                     tv_ptr->start[4] = 0;
1827 
1828                     ret = H5Sselect_hyperslab(tv_ptr->file_large_ds_sid_0,
1829                                               H5S_SELECT_SET,
1830                                               tv_ptr->start_ptr,
1831                                               tv_ptr->stride_ptr,
1832                                               tv_ptr->count_ptr,
1833                                               tv_ptr->block_ptr);
1834                     VRFY((ret != FAIL),
1835                          "H5Sselect_hyperslab() target large ds slice succeeded");
1836 
1837 
1838                     /* verify that H5S_select_shape_same() reports the in
1839                      * memory small data set slice selection and the
1840                      * on disk slice through the large data set selection
1841                      * as having the same shape.
1842                      */
1843                     check = H5S_select_shape_same_test(tv_ptr->mem_small_ds_sid,
1844                                                        tv_ptr->file_large_ds_sid_0);
1845                     VRFY((check == TRUE), "H5S_select_shape_same_test passed");
1846 
1847 
1848                     /* write the small data set slice from memory to the
1849                      * target slice of the disk data set
1850                      */
1851 #if CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG
1852                     HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n",
1853                               fcnName, (int)(tv_ptr->mpi_rank),
1854                               (int)(tv_ptr->start[0]), (int)(tv_ptr->start[1]),
1855                               (int)(tv_ptr->start[2]), (int)(tv_ptr->start[3]),
1856                               (int)(tv_ptr->start[4]));
1857                     HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n",
1858                               fcnName, tv_ptr->mpi_rank,
1859                               H5Sget_simple_extent_ndims(tv_ptr->mem_small_ds_sid),
1860                               H5Sget_simple_extent_ndims(tv_ptr->file_large_ds_sid_0));
1861 #endif /* CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
1862                     ret = H5Dwrite(tv_ptr->large_dataset,
1863                                    H5T_NATIVE_UINT32,
1864                                    tv_ptr->mem_small_ds_sid,
1865                                    tv_ptr->file_large_ds_sid_0,
1866                                    tv_ptr->xfer_plist,
1867                                    tv_ptr->small_ds_buf_0);
1868                     VRFY((ret != FAIL),
1869                           "H5Dwrite of small ds slice to large ds succeeded");
1870 
1871 
1872                     /* read this processes slice on the on disk large
1873                      * data set into memory.
1874                      */
1875 
1876                     ret = H5Dread(tv_ptr->large_dataset,
1877                                   H5T_NATIVE_UINT32,
1878                                   tv_ptr->mem_large_ds_process_slice_sid,
1879                                   tv_ptr->file_large_ds_process_slice_sid,
1880                                   tv_ptr->xfer_plist,
1881                                   tv_ptr->large_ds_buf_1);
1882                     VRFY((ret != FAIL),
1883                          "H5Dread() of process slice of large ds succeeded");
1884 
1885 
1886                     /* verify that the expected data and only the
1887                      * expected data was read.
1888                      */
1889                     ptr_1 = tv_ptr->large_ds_buf_1;
1890                     expected_value = (uint32_t)
1891                         ((size_t)(tv_ptr->mpi_rank) * tv_ptr->small_ds_slice_size);
1892 
1893                     start_index = (size_t)
1894                                   ((i * tv_ptr->edge_size * tv_ptr->edge_size *
1895                                         tv_ptr->edge_size * tv_ptr->edge_size) +
1896                                    (j * tv_ptr->edge_size * tv_ptr->edge_size *
1897                                         tv_ptr->edge_size) +
1898                                    (k * tv_ptr->edge_size * tv_ptr->edge_size) +
1899                                    (l * tv_ptr->edge_size));
1900                     stop_index = start_index + tv_ptr->small_ds_slice_size - 1;
1901 
1902                     HDassert( start_index < stop_index );
1903                     HDassert( stop_index < tv_ptr->large_ds_size );
1904 
1905                     for ( n = 0; n < tv_ptr->large_ds_size; n++ ) {
1906 
1907                         if ( ( n >= start_index ) && ( n <= stop_index ) ) {
1908 
1909                             if ( *ptr_1 != expected_value ) {
1910 
1911                                 mis_match = TRUE;
1912                             }
1913 
1914                             expected_value++;
1915 
1916                         } else {
1917 
1918                             if ( *ptr_1 != 0 ) {
1919 
1920                                 mis_match = TRUE;
1921                             }
1922                         }
1923                         /* zero out buffer for next test */
1924                         *ptr_1 = 0;
1925                         ptr_1++;
1926                     }
1927 
1928                     VRFY((mis_match == FALSE),
1929                          "small ds slice write to large ds slice data good.");
1930 
1931                     (tv_ptr->tests_run)++;
1932                 }
1933 
1934                 l++;
1935 
1936                 (tv_ptr->total_tests)++;
1937 
1938             } while ( ( tv_ptr->large_rank > 2 ) &&
1939                       ( (tv_ptr->small_rank - 1) <= 1 ) &&
1940                       ( l < tv_ptr->edge_size ) );
1941             k++;
1942         } while ( ( tv_ptr->large_rank > 3 ) &&
1943                   ( (tv_ptr->small_rank - 1) <= 2 ) &&
1944                   ( k < tv_ptr->edge_size ) );
1945         j++;
1946     } while ( ( tv_ptr->large_rank > 4 ) &&
1947               ( (tv_ptr->small_rank - 1) <= 3 ) &&
1948               ( j < tv_ptr->edge_size ) );
1949 
1950     return;
1951 
1952 } /* contig_hs_dr_pio_test__m2d_s2l() */
1953 
1954 
1955 /*-------------------------------------------------------------------------
1956  * Function:    contig_hs_dr_pio_test__run_test()
1957  *
1958  * Purpose:    Test I/O to/from hyperslab selections of different rank in
1959  *        the parallel.
1960  *
1961  * Return:    void
1962  *
1963  * Programmer:    JRM -- 9/18/09
1964  *
1965  * Modifications:
1966  *
1967  *        JRM -- 9/16/10
1968  *        Added express_test parameter.  Use it to control whether
1969  *        we set up the chunks so that no chunk is shared between
1970  *        processes, and also whether we set an alignment when we
1971  *        create the test file.
1972  *
1973  *        JRM -- 8/11/11
1974  *        Refactored function heavily & broke it into six functions.
1975  *        Added the skips_ptr, max_skips, total_tests_ptr,
1976  *        tests_run_ptr, and tests_skiped_ptr parameters to support
1977  *        skipping portions of the test according to the express
1978  *        test value.
1979  *
1980  *-------------------------------------------------------------------------
1981  */
1982 
1983 #define CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG 0
1984 
1985 static void
contig_hs_dr_pio_test__run_test(const int test_num,const int edge_size,const int chunk_edge_size,const int small_rank,const int large_rank,const hbool_t use_collective_io,const hid_t dset_type,int express_test,int * skips_ptr,int max_skips,int64_t * total_tests_ptr,int64_t * tests_run_ptr,int64_t * tests_skipped_ptr)1986 contig_hs_dr_pio_test__run_test(const int test_num,
1987                                 const int edge_size,
1988                                 const int chunk_edge_size,
1989                                 const int small_rank,
1990                                 const int large_rank,
1991                                 const hbool_t use_collective_io,
1992                                 const hid_t dset_type,
1993                                 int express_test,
1994                                 int * skips_ptr,
1995                                 int max_skips,
1996                                 int64_t * total_tests_ptr,
1997                                 int64_t * tests_run_ptr,
1998                                 int64_t * tests_skipped_ptr)
1999 {
2000 #if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
2001     const char *fcnName = "contig_hs_dr_pio_test__run_test()";
2002 #endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
2003     int        mpi_rank;
2004     struct hs_dr_pio_test_vars_t test_vars =
2005     {
2006         /* int           mpi_size                        = */ -1,
2007         /* int         mpi_rank                        = */ -1,
2008         /* MPI_Comm    mpi_comm                        = */ MPI_COMM_NULL,
2009         /* MPI_Inf     mpi_info                        = */ MPI_INFO_NULL,
2010         /* int         test_num                        = */ -1,
2011         /* int         edge_size                       = */ -1,
2012         /* int         checker_edge_size               = */ -1,
2013         /* int         chunk_edge_size                 = */ -1,
2014         /* int         small_rank                      = */ -1,
2015         /* int         large_rank                      = */ -1,
2016         /* hid_t       dset_type                       = */ -1,
2017         /* uint32_t  * small_ds_buf_0                  = */ NULL,
2018         /* uint32_t  * small_ds_buf_1                  = */ NULL,
2019         /* uint32_t  * small_ds_buf_2                  = */ NULL,
2020         /* uint32_t  * small_ds_slice_buf              = */ NULL,
2021         /* uint32_t  * large_ds_buf_0                  = */ NULL,
2022         /* uint32_t  * large_ds_buf_1                  = */ NULL,
2023         /* uint32_t  * large_ds_buf_2                  = */ NULL,
2024         /* uint32_t  * large_ds_slice_buf              = */ NULL,
2025         /* int         small_ds_offset                 = */ -1,
2026         /* int         large_ds_offset                 = */ -1,
2027         /* hid_t       fid                             = */ -1,  /* HDF5 file ID */
2028         /* hid_t       xfer_plist                      = */ H5P_DEFAULT,
2029         /* hid_t       full_mem_small_ds_sid           = */ -1,
2030         /* hid_t       full_file_small_ds_sid          = */ -1,
2031         /* hid_t       mem_small_ds_sid                = */ -1,
2032         /* hid_t       file_small_ds_sid_0             = */ -1,
2033         /* hid_t       file_small_ds_sid_1             = */ -1,
2034         /* hid_t       small_ds_slice_sid              = */ -1,
2035         /* hid_t       full_mem_large_ds_sid           = */ -1,
2036         /* hid_t       full_file_large_ds_sid          = */ -1,
2037         /* hid_t       mem_large_ds_sid                = */ -1,
2038         /* hid_t       file_large_ds_sid_0             = */ -1,
2039         /* hid_t       file_large_ds_sid_1             = */ -1,
2040         /* hid_t       file_large_ds_process_slice_sid = */ -1,
2041         /* hid_t       mem_large_ds_process_slice_sid  = */ -1,
2042         /* hid_t       large_ds_slice_sid              = */ -1,
2043         /* hid_t       small_dataset                   = */ -1,     /* Dataset ID */
2044         /* hid_t       large_dataset                   = */ -1,     /* Dataset ID */
2045         /* size_t      small_ds_size                   = */ 1,
2046         /* size_t      small_ds_slice_size             = */ 1,
2047         /* size_t      large_ds_size                   = */ 1,
2048         /* size_t      large_ds_slice_size             = */ 1,
2049         /* hsize_t     dims[PAR_SS_DR_MAX_RANK]        = */ {0,0,0,0,0},
2050         /* hsize_t     chunk_dims[PAR_SS_DR_MAX_RANK]  = */ {0,0,0,0,0},
2051         /* hsize_t     start[PAR_SS_DR_MAX_RANK]       = */ {0,0,0,0,0},
2052         /* hsize_t     stride[PAR_SS_DR_MAX_RANK]      = */ {0,0,0,0,0},
2053         /* hsize_t     count[PAR_SS_DR_MAX_RANK]       = */ {0,0,0,0,0},
2054         /* hsize_t     block[PAR_SS_DR_MAX_RANK]       = */ {0,0,0,0,0},
2055         /* hsize_t   * start_ptr                       = */ NULL,
2056         /* hsize_t   * stride_ptr                      = */ NULL,
2057         /* hsize_t   * count_ptr                       = */ NULL,
2058         /* hsize_t   * block_ptr                       = */ NULL,
2059         /* int            skips                           = */ 0,
2060         /* int            max_skips                       = */ 0,
2061         /* int64_t     total_tests                     = */ 0,
2062         /* int64_t     tests_run                       = */ 0,
2063         /* int64_t     tests_skipped                   = */ 0
2064     };
2065     struct hs_dr_pio_test_vars_t * tv_ptr = &test_vars;
2066 
2067     hs_dr_pio_test__setup(test_num, edge_size, -1, chunk_edge_size,
2068                           small_rank, large_rank, use_collective_io,
2069                           dset_type, express_test, tv_ptr);
2070 
2071     /* initialize the local copy of mpi_rank */
2072     mpi_rank = tv_ptr->mpi_rank;
2073 
2074     /* initialize skips & max_skips */
2075     tv_ptr->skips = *skips_ptr;
2076     tv_ptr->max_skips = max_skips;
2077 
2078 #if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
2079     if ( MAINPROCESS ) {
2080         HDfprintf(stdout, "test %d: small rank = %d, large rank = %d.\n",
2081                   test_num, small_rank, large_rank);
2082         HDfprintf(stdout, "test %d: Initialization complete.\n", test_num);
2083     }
2084 #endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
2085 
2086     /* first, verify that we can read from disk correctly using selections
2087      * of different rank that H5S_select_shape_same() views as being of the
2088      * same shape.
2089      *
2090      * Start by reading small_rank - 1 dimensional slice from the on disk
2091      * large cube, and verifying that the data read is correct.  Verify that
2092      * H5S_select_shape_same() returns true on the memory and file selections.
2093      */
2094 
2095 #if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
2096     if ( MAINPROCESS ) {
2097         HDfprintf(stdout, "test %d: running contig_hs_dr_pio_test__d2m_l2s.\n", test_num);
2098     }
2099 #endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
2100     contig_hs_dr_pio_test__d2m_l2s(tv_ptr);
2101 
2102 
2103     /* Second, read slices of the on disk small data set into slices
2104      * through the in memory large data set, and verify that the correct
2105      * data (and only the correct data) is read.
2106      */
2107 
2108 #if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
2109     if ( MAINPROCESS ) {
2110         HDfprintf(stdout, "test %d: running contig_hs_dr_pio_test__d2m_s2l.\n", test_num);
2111     }
2112 #endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
2113     contig_hs_dr_pio_test__d2m_s2l(tv_ptr);
2114 
2115 
2116     /* now we go in the opposite direction, verifying that we can write
2117      * from memory to file using selections of different rank that
2118      * H5S_select_shape_same() views as being of the same shape.
2119      *
2120      * Start by writing small_rank - 1 D slices from the in memory large data
2121      * set to the on disk small cube dataset.  After each write, read the
2122      * slice of the small dataset back from disk, and verify that it contains
2123      * the expected data. Verify that H5S_select_shape_same() returns true on
2124      * the memory and file selections.
2125      */
2126 
2127 #if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
2128     if ( MAINPROCESS ) {
2129         HDfprintf(stdout, "test %d: running contig_hs_dr_pio_test__m2d_l2s.\n", test_num);
2130     }
2131 #endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
2132     contig_hs_dr_pio_test__m2d_l2s(tv_ptr);
2133 
2134 
2135     /* Now write the contents of the process's slice of the in memory
2136      * small data set to slices of the on disk large data set.  After
2137      * each write, read the process's slice of the large data set back
2138      * into memory, and verify that it contains the expected data.
2139      * Verify that H5S_select_shape_same() returns true on the memory
2140      * and file selections.
2141      */
2142 
2143 #if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
2144     if ( MAINPROCESS ) {
2145         HDfprintf(stdout, "test %d: running contig_hs_dr_pio_test__m2d_s2l.\n", test_num);
2146     }
2147 #endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
2148     contig_hs_dr_pio_test__m2d_s2l(tv_ptr);
2149 
2150 #if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
2151     if ( MAINPROCESS ) {
2152         HDfprintf(stdout,
2153             "test %d: Subtests complete -- tests run/skipped/total = %lld/%lld/%lld.\n",
2154              test_num, (long long)(tv_ptr->tests_run), (long long)(tv_ptr->tests_skipped),
2155              (long long)(tv_ptr->total_tests));
2156     }
2157 #endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
2158 
2159     hs_dr_pio_test__takedown(tv_ptr);
2160 
2161 #if CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG
2162     if ( MAINPROCESS ) {
2163         HDfprintf(stdout, "test %d: Takedown complete.\n", test_num);
2164     }
2165 #endif /* CONTIG_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
2166 
2167     *skips_ptr = tv_ptr->skips;
2168     *total_tests_ptr += tv_ptr->total_tests;
2169     *tests_run_ptr += tv_ptr->tests_run;
2170     *tests_skipped_ptr += tv_ptr->tests_skipped;
2171 
2172     return;
2173 
2174 } /* contig_hs_dr_pio_test__run_test() */
2175 
2176 
2177 /*-------------------------------------------------------------------------
2178  * Function:    contig_hs_dr_pio_test(ShapeSameTestMethods sstest_type)
2179  *
2180  * Purpose:    Test I/O to/from hyperslab selections of different rank in
2181  *        the parallel case.
2182  *
2183  * Return:    void
2184  *
2185  * Programmer:    JRM -- 9/18/09
2186  *
2187  * Modifications:
2188  *
2189  *          Modified function to take a sample of the run times
2190  *        of the different tests, and skip some of them if
2191  *        run times are too long.
2192  *
2193  *        We need to do this because Lustre runns very slowly
2194  *        if two or more processes are banging on the same
2195  *        block of memory.
2196  *                        JRM -- 9/10/10
2197  *              Break this one big test into 4 smaller tests according
2198  *              to {independent,collective}x{contigous,chunked} datasets.
2199  *        AKC -- 2010/01/14
2200  *
2201  *-------------------------------------------------------------------------
2202  */
2203 
2204 #define CONTIG_HS_DR_PIO_TEST__DEBUG 0
2205 
2206 static void
contig_hs_dr_pio_test(ShapeSameTestMethods sstest_type)2207 contig_hs_dr_pio_test(ShapeSameTestMethods sstest_type)
2208 {
2209     int         express_test;
2210     int         local_express_test;
2211     int         mpi_rank = -1;
2212     int         mpi_size;
2213     int            test_num = 0;
2214     int        edge_size;
2215     int        chunk_edge_size = 0;
2216     int            small_rank;
2217     int            large_rank;
2218     int        mpi_result;
2219     int        skips = 0;
2220     int        max_skips = 0;
2221     /* The following table list the number of sub-tests skipped between
2222      * each test that is actually executed as a function of the express
2223      * test level.  Note that any value in excess of 4880 will cause all
2224      * sub tests to be skipped.
2225      */
2226     int         max_skips_tbl[4] = {0, 4, 64, 1024};
2227     hid_t    dset_type = H5T_NATIVE_UINT;
2228     int64_t    total_tests = 0;
2229     int64_t    tests_run = 0;
2230     int64_t     tests_skipped = 0;
2231 
2232     HDcompile_assert(sizeof(uint32_t) == sizeof(unsigned));
2233 
2234     MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
2235     MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
2236 
2237     edge_size = (mpi_size > 6 ? mpi_size : 6);
2238 
2239     local_express_test = GetTestExpress();
2240 
2241     mpi_result = MPI_Allreduce((void *)&local_express_test,
2242                                (void *)&express_test,
2243                                1,
2244                                MPI_INT,
2245                                MPI_MAX,
2246                                MPI_COMM_WORLD);
2247 
2248     VRFY((mpi_result == MPI_SUCCESS ), "MPI_Allreduce(0) succeeded");
2249 
2250     if ( local_express_test < 0 ) {
2251         max_skips = max_skips_tbl[0];
2252     } else if ( local_express_test > 3 ) {
2253         max_skips = max_skips_tbl[3];
2254     } else {
2255         max_skips = max_skips_tbl[local_express_test];
2256     }
2257 
2258     for ( large_rank = 3; large_rank <= PAR_SS_DR_MAX_RANK; large_rank++ ) {
2259 
2260         for ( small_rank = 2; small_rank < large_rank; small_rank++ ) {
2261 
2262             switch(sstest_type){
2263                 case IND_CONTIG:
2264                     /* contiguous data set, independent I/O */
2265                     chunk_edge_size = 0;
2266 
2267                     contig_hs_dr_pio_test__run_test(test_num,
2268                                                    edge_size,
2269                                                    chunk_edge_size,
2270                                                    small_rank,
2271                                                    large_rank,
2272                                                    FALSE,
2273                                                    dset_type,
2274                                                    express_test,
2275                                                    &skips,
2276                                                    max_skips,
2277                                                    &total_tests,
2278                                                    &tests_run,
2279                                                    &tests_skipped);
2280                     test_num++;
2281                     break;
2282                     /* end of case IND_CONTIG */
2283 
2284                 case COL_CONTIG:
2285                     /* contiguous data set, collective I/O */
2286                     chunk_edge_size = 0;
2287 
2288                     contig_hs_dr_pio_test__run_test(test_num,
2289                                                    edge_size,
2290                                                    chunk_edge_size,
2291                                                    small_rank,
2292                                                    large_rank,
2293                                                    TRUE,
2294                                                    dset_type,
2295                                                    express_test,
2296                                                    &skips,
2297                                                    max_skips,
2298                                                    &total_tests,
2299                                                    &tests_run,
2300                                                    &tests_skipped);
2301                     test_num++;
2302                     break;
2303                     /* end of case COL_CONTIG */
2304 
2305                 case IND_CHUNKED:
2306                     /* chunked data set, independent I/O */
2307                     chunk_edge_size = 5;
2308 
2309                     contig_hs_dr_pio_test__run_test(test_num,
2310                                                    edge_size,
2311                                                    chunk_edge_size,
2312                                                    small_rank,
2313                                                    large_rank,
2314                                                    FALSE,
2315                                                    dset_type,
2316                                                    express_test,
2317                                                    &skips,
2318                                                    max_skips,
2319                                                    &total_tests,
2320                                                    &tests_run,
2321                                                    &tests_skipped);
2322                     test_num++;
2323                     break;
2324                     /* end of case IND_CHUNKED */
2325 
2326                 case COL_CHUNKED:
2327                     /* chunked data set, collective I/O */
2328                     chunk_edge_size = 5;
2329 
2330                     contig_hs_dr_pio_test__run_test(test_num,
2331                                                    edge_size,
2332                                                    chunk_edge_size,
2333                                                    small_rank,
2334                                                    large_rank,
2335                                                    TRUE,
2336                                                    dset_type,
2337                                                    express_test,
2338                                                    &skips,
2339                                                    max_skips,
2340                                                    &total_tests,
2341                                                    &tests_run,
2342                                                    &tests_skipped);
2343                     test_num++;
2344                     break;
2345                     /* end of case COL_CHUNKED */
2346 
2347                 default:
2348                     VRFY((FALSE), "unknown test type");
2349                     break;
2350 
2351             } /* end of switch(sstest_type) */
2352 #if CONTIG_HS_DR_PIO_TEST__DEBUG
2353             if ( ( MAINPROCESS ) && ( tests_skipped > 0 ) ) {
2354                 HDfprintf(stdout, "    run/skipped/total = %lld/%lld/%lld.\n",
2355                           tests_run, tests_skipped, total_tests);
2356             }
2357 #endif /* CONTIG_HS_DR_PIO_TEST__DEBUG */
2358         }
2359     }
2360 
2361     if ( ( MAINPROCESS ) && ( tests_skipped > 0 ) ) {
2362         HDfprintf(stdout, "    %lld of %lld subtests skipped to expedite testing.\n",
2363                   tests_skipped, total_tests);
2364     }
2365 
2366     return;
2367 
2368 } /* contig_hs_dr_pio_test() */
2369 
2370 
2371 /****************************************************************
2372 **
2373 **  ckrbrd_hs_dr_pio_test__slct_ckrbrd():
2374 **    Given a dataspace of tgt_rank, and dimensions:
2375 **
2376 **        (mpi_size + 1), edge_size, ... , edge_size
2377 **
2378 **    edge_size, and a checker_edge_size, select a checker
2379 **    board selection of a sel_rank (sel_rank < tgt_rank)
2380 **    dimensional slice through the dataspace parallel to the
2381 **      sel_rank fastest changing indicies, with origin (in the
2382 **    higher indicies) as indicated by the start array.
2383 **
2384 **    Note that this function, like all its relatives, is
2385 **    hard coded to presume a maximum dataspace rank of 5.
2386 **    While this maximum is declared as a constant, increasing
2387 **    it will require extensive coding in addition to changing
2388 **      the value of the constant.
2389 **
2390 **                    JRM -- 10/8/09
2391 **
2392 ****************************************************************/
2393 
2394 #define CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG 0
2395 
2396 static void
ckrbrd_hs_dr_pio_test__slct_ckrbrd(const int mpi_rank,const hid_t tgt_sid,const int tgt_rank,const int edge_size,const int checker_edge_size,const int sel_rank,hsize_t sel_start[])2397 ckrbrd_hs_dr_pio_test__slct_ckrbrd(const int mpi_rank,
2398                                    const hid_t tgt_sid,
2399                                    const int tgt_rank,
2400                                    const int edge_size,
2401                                    const int checker_edge_size,
2402                                    const int sel_rank,
2403                                    hsize_t sel_start[])
2404 {
2405 #if CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG
2406     const char *    fcnName = "ckrbrd_hs_dr_pio_test__slct_ckrbrd():";
2407 #endif
2408     hbool_t        first_selection = TRUE;
2409     int                 i, j, k, l, m;
2410     int            n_cube_offset;
2411     int            sel_offset;
2412     const int        test_max_rank = PAR_SS_DR_MAX_RANK;  /* must update code if */
2413                                                              /* this changes        */
2414     hsize_t        base_count;
2415     hsize_t             offset_count;
2416     hsize_t         start[PAR_SS_DR_MAX_RANK];
2417     hsize_t         stride[PAR_SS_DR_MAX_RANK];
2418     hsize_t         count[PAR_SS_DR_MAX_RANK];
2419     hsize_t         block[PAR_SS_DR_MAX_RANK];
2420     herr_t          ret;            /* Generic return value */
2421 
2422     HDassert( edge_size >= 6 );
2423     HDassert( 0 < checker_edge_size );
2424     HDassert( checker_edge_size <= edge_size );
2425     HDassert( 0 < sel_rank );
2426     HDassert( sel_rank <= tgt_rank );
2427     HDassert( tgt_rank <= test_max_rank );
2428     HDassert( test_max_rank <= PAR_SS_DR_MAX_RANK );
2429 
2430     sel_offset = test_max_rank - sel_rank;
2431     HDassert( sel_offset >= 0 );
2432 
2433     n_cube_offset = test_max_rank - tgt_rank;
2434     HDassert( n_cube_offset >= 0 );
2435     HDassert( n_cube_offset <= sel_offset );
2436 
2437 #if CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG
2438     HDfprintf(stdout, "%s:%d: edge_size/checker_edge_size = %d/%d\n",
2439               fcnName, mpi_rank, edge_size, checker_edge_size);
2440     HDfprintf(stdout, "%s:%d: sel_rank/sel_offset = %d/%d.\n",
2441               fcnName, mpi_rank, sel_rank, sel_offset);
2442     HDfprintf(stdout, "%s:%d: tgt_rank/n_cube_offset = %d/%d.\n",
2443               fcnName, mpi_rank, tgt_rank, n_cube_offset);
2444 #endif /* CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG */
2445 
2446     /* First, compute the base count (which assumes start == 0
2447      * for the associated offset) and offset_count (which
2448      * assumes start == checker_edge_size for the associated
2449      * offset).
2450      *
2451      * Note that the following computation depends on the C99
2452      * requirement that integer division discard any fraction
2453      * (truncation towards zero) to function correctly. As we
2454      * now require C99, this shouldn't be a problem, but noting
2455      * it may save us some pain if we are ever obliged to support
2456      * pre-C99 compilers again.
2457      */
2458 
2459     base_count = (hsize_t)(edge_size / (checker_edge_size * 2));
2460 
2461     if ( (edge_size % (checker_edge_size * 2)) > 0 ) {
2462 
2463         base_count++;
2464     }
2465 
2466     offset_count = (hsize_t)((edge_size - checker_edge_size) / (checker_edge_size * 2));
2467 
2468     if ( ((edge_size - checker_edge_size) % (checker_edge_size * 2)) > 0 ) {
2469 
2470         offset_count++;
2471     }
2472 
2473     /* Now set up the stride and block arrays, and portions of the start
2474      * and count arrays that will not be altered during the selection of
2475      * the checker board.
2476      */
2477     i = 0;
2478     while ( i < n_cube_offset ) {
2479 
2480         /* these values should never be used */
2481         start[i] = 0;
2482         stride[i] = 0;
2483         count[i] = 0;
2484         block[i] = 0;
2485 
2486         i++;
2487     }
2488 
2489     while ( i < sel_offset ) {
2490 
2491         start[i] = sel_start[i];
2492         stride[i] = (hsize_t)(2 * edge_size);
2493         count[i] = 1;
2494         block[i] = 1;
2495 
2496         i++;
2497     }
2498 
2499     while ( i < test_max_rank ) {
2500 
2501         stride[i] = (hsize_t)(2 * checker_edge_size);
2502         block[i] = (hsize_t)checker_edge_size;
2503 
2504         i++;
2505     }
2506 
2507     i = 0;
2508     do {
2509         if ( 0 >= sel_offset ) {
2510 
2511             if ( i == 0 ) {
2512 
2513                 start[0] = 0;
2514                 count[0] = base_count;
2515 
2516             } else {
2517 
2518                 start[0] = (hsize_t)checker_edge_size;
2519                 count[0] = offset_count;
2520 
2521             }
2522         }
2523 
2524         j = 0;
2525         do {
2526             if ( 1 >= sel_offset ) {
2527 
2528                 if ( j == 0 ) {
2529 
2530                     start[1] = 0;
2531                     count[1] = base_count;
2532 
2533                 } else {
2534 
2535                     start[1] = (hsize_t)checker_edge_size;
2536                     count[1] = offset_count;
2537 
2538                 }
2539             }
2540 
2541             k = 0;
2542             do {
2543                 if ( 2 >= sel_offset ) {
2544 
2545                     if ( k == 0 ) {
2546 
2547                         start[2] = 0;
2548                         count[2] = base_count;
2549 
2550                     } else {
2551 
2552                         start[2] = (hsize_t)checker_edge_size;
2553                         count[2] = offset_count;
2554 
2555                     }
2556                 }
2557 
2558                 l = 0;
2559                 do {
2560                     if ( 3 >= sel_offset ) {
2561 
2562                         if ( l == 0 ) {
2563 
2564                             start[3] = 0;
2565                             count[3] = base_count;
2566 
2567                         } else {
2568 
2569                             start[3] = (hsize_t)checker_edge_size;
2570                             count[3] = offset_count;
2571 
2572                         }
2573                     }
2574 
2575                     m = 0;
2576                     do {
2577                         if ( 4 >= sel_offset ) {
2578 
2579                             if ( m == 0 ) {
2580 
2581                                 start[4] = 0;
2582                                 count[4] = base_count;
2583 
2584                             } else {
2585 
2586                                 start[4] = (hsize_t)checker_edge_size;
2587                                 count[4] = offset_count;
2588 
2589                             }
2590                         }
2591 
2592                         if ( ((i + j + k + l + m) % 2) == 0 ) {
2593 
2594 #if CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG
2595                             HDfprintf(stdout, "%s%d: *** first_selection = %d ***\n",
2596                                       fcnName, mpi_rank, (int)first_selection);
2597                             HDfprintf(stdout, "%s:%d: i/j/k/l/m = %d/%d/%d/%d/%d\n",
2598                                       fcnName, mpi_rank, i, j, k, l, m);
2599                             HDfprintf(stdout,
2600                                       "%s:%d: start = %d %d %d %d %d.\n",
2601                                       fcnName, mpi_rank, (int)start[0], (int)start[1],
2602                                       (int)start[2], (int)start[3], (int)start[4]);
2603                             HDfprintf(stdout,
2604                                       "%s:%d: stride = %d %d %d %d %d.\n",
2605                                       fcnName, mpi_rank, (int)stride[0], (int)stride[1],
2606                                       (int)stride[2], (int)stride[3], (int)stride[4]);
2607                             HDfprintf(stdout,
2608                                       "%s:%d: count = %d %d %d %d %d.\n",
2609                                       fcnName, mpi_rank, (int)count[0], (int)count[1],
2610                                       (int)count[2], (int)count[3], (int)count[4]);
2611                             HDfprintf(stdout,
2612                                       "%s:%d: block = %d %d %d %d %d.\n",
2613                                       fcnName, mpi_rank, (int)block[0], (int)block[1],
2614                                       (int)block[2], (int)block[3], (int)block[4]);
2615                             HDfprintf(stdout, "%s:%d: n-cube extent dims = %d.\n",
2616                                       fcnName, mpi_rank,
2617                                       H5Sget_simple_extent_ndims(tgt_sid));
2618                             HDfprintf(stdout, "%s:%d: selection rank = %d.\n",
2619                                       fcnName, mpi_rank, sel_rank);
2620 #endif
2621 
2622                             if ( first_selection ) {
2623 
2624                                 first_selection = FALSE;
2625 
2626                                 ret = H5Sselect_hyperslab
2627                                       (
2628                                         tgt_sid,
2629                                         H5S_SELECT_SET,
2630                                         &(start[n_cube_offset]),
2631                                         &(stride[n_cube_offset]),
2632                                         &(count[n_cube_offset]),
2633                                         &(block[n_cube_offset])
2634                                       );
2635 
2636                                 VRFY((ret != FAIL), "H5Sselect_hyperslab(SET) succeeded");
2637 
2638                             } else {
2639 
2640                                 ret = H5Sselect_hyperslab
2641                                       (
2642                                         tgt_sid,
2643                                         H5S_SELECT_OR,
2644                                         &(start[n_cube_offset]),
2645                                         &(stride[n_cube_offset]),
2646                                         &(count[n_cube_offset]),
2647                                         &(block[n_cube_offset])
2648                                       );
2649 
2650                                 VRFY((ret != FAIL), "H5Sselect_hyperslab(OR) succeeded");
2651 
2652                             }
2653                         }
2654 
2655                         m++;
2656 
2657                     } while ( ( m <= 1 ) &&
2658                               ( 4 >= sel_offset ) );
2659 
2660                     l++;
2661 
2662                 } while ( ( l <= 1 ) &&
2663                           ( 3 >= sel_offset ) );
2664 
2665                 k++;
2666 
2667             } while ( ( k <= 1 ) &&
2668                       ( 2 >= sel_offset ) );
2669 
2670             j++;
2671 
2672         } while ( ( j <= 1 ) &&
2673                   ( 1 >= sel_offset ) );
2674 
2675 
2676         i++;
2677 
2678     } while ( ( i <= 1 ) &&
2679               ( 0 >= sel_offset ) );
2680 
2681 #if CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG
2682     HDfprintf(stdout, "%s%d: H5Sget_select_npoints(tgt_sid) = %d.\n",
2683               fcnName, mpi_rank, (int)H5Sget_select_npoints(tgt_sid));
2684 #endif /* CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG */
2685 
2686     /* Clip the selection back to the dataspace proper. */
2687 
2688     for ( i = 0; i < test_max_rank; i++ ) {
2689 
2690         start[i]  = 0;
2691         stride[i] = (hsize_t)edge_size;
2692         count[i]  = 1;
2693         block[i]  = (hsize_t)edge_size;
2694     }
2695 
2696     ret = H5Sselect_hyperslab(tgt_sid, H5S_SELECT_AND,
2697                               start, stride, count, block);
2698 
2699     VRFY((ret != FAIL), "H5Sselect_hyperslab(AND) succeeded");
2700 
2701 #if CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG
2702     HDfprintf(stdout, "%s%d: H5Sget_select_npoints(tgt_sid) = %d.\n",
2703               fcnName, mpi_rank, (int)H5Sget_select_npoints(tgt_sid));
2704     HDfprintf(stdout, "%s%d: done.\n", fcnName, mpi_rank);
2705 #endif /* CKRBRD_HS_DR_PIO_TEST__SELECT_CHECKER_BOARD__DEBUG */
2706 
2707     return;
2708 
2709 } /* ckrbrd_hs_dr_pio_test__slct_ckrbrd() */
2710 
2711 
2712 /****************************************************************
2713 **
2714 **  ckrbrd_hs_dr_pio_test__verify_data():
2715 **
2716 **    Examine the supplied buffer to see if it contains the
2717 **    expected data.  Return TRUE if it does, and FALSE
2718 **      otherwise.
2719 **
2720 **    The supplied buffer is presumed to this process's slice
2721 **    of the target data set.  Each such slice will be an
2722 **    n-cube of rank (rank -1) and the supplied edge_size with
2723 **    origin (mpi_rank, 0, ... , 0) in the target data set.
2724 **
2725 **    Further, the buffer is presumed to be the result of reading
2726 **    or writing a checker board selection of an m (1 <= m <
2727 **      rank) dimensional slice through this processes slice
2728 **    of the target data set.  Also, this slice must be parallel
2729 **    to the fastest changing indicies.
2730 **
2731 **    It is further presumed that the buffer was zeroed before
2732 **    the read/write, and that the full target data set (i.e.
2733 **    the buffer/data set for all processes) was initialized
2734 **      with the natural numbers listed in order from the origin
2735 **    along the fastest changing axis.
2736 **
2737 **      Thus for a 20x10x10 dataset, the value stored in location
2738 **    (x, y, z) (assuming that z is the fastest changing index
2739 **    and x the slowest) is assumed to be:
2740 **
2741 **        (10 * 10 * x) + (10 * y) + z
2742 **
2743 **    Further, supposing that this is process 10, this process's
2744 **    slice of the dataset would be a 10 x 10 2-cube with origin
2745 **    (10, 0, 0) in the data set, and would be initialize (prior
2746 **    to the checkerboard selection) as follows:
2747 **
2748 **        1000, 1001, 1002, ... 1008, 1009
2749 **        1010, 1011, 1012, ... 1018, 1019
2750 **          .     .     .         .     .
2751 **          .     .     .         .     .
2752 **          .     .     .         .     .
2753 **        1090, 1091, 1092, ... 1098, 1099
2754 **
2755 **    In the case of a read from the processors slice of another
2756 **    data set of different rank, the values expected will have
2757 **    to be adjusted accordingly.  This is done via the
2758 **    first_expected_val parameter.
2759 **
2760 **    Finally, the function presumes that the first element
2761 **    of the buffer resides either at the origin of either
2762 **    a selected or an unselected checker.  (Translation:
2763 **    if partial checkers appear in the buffer, they will
2764 **    intersect the edges of the n-cube oposite the origin.)
2765 **
2766 ****************************************************************/
2767 
2768 #define CKRBRD_HS_DR_PIO_TEST__VERIFY_DATA__DEBUG 0
2769 
2770 static hbool_t
ckrbrd_hs_dr_pio_test__verify_data(uint32_t * buf_ptr,const int rank,const int edge_size,const int checker_edge_size,uint32_t first_expected_val,hbool_t buf_starts_in_checker)2771 ckrbrd_hs_dr_pio_test__verify_data(uint32_t * buf_ptr,
2772                                    const int rank,
2773                                    const int edge_size,
2774                                    const int checker_edge_size,
2775                                    uint32_t first_expected_val,
2776                                    hbool_t buf_starts_in_checker)
2777 {
2778 #if CKRBRD_HS_DR_PIO_TEST__VERIFY_DATA__DEBUG
2779     const char *    fcnName = "ckrbrd_hs_dr_pio_test__verify_data():";
2780 #endif
2781     hbool_t good_data = TRUE;
2782     hbool_t in_checker;
2783     hbool_t start_in_checker[5];
2784     uint32_t expected_value;
2785     uint32_t * val_ptr;
2786     int i, j, k, l, m;  /* to track position in n-cube */
2787     int v, w, x, y, z;  /* to track position in checker */
2788     const int test_max_rank = 5; /* code changes needed if this is increased */
2789 
2790     HDassert( buf_ptr != NULL );
2791     HDassert( 0 < rank );
2792     HDassert( rank <= test_max_rank );
2793     HDassert( edge_size >= 6 );
2794     HDassert( 0 < checker_edge_size );
2795     HDassert( checker_edge_size <= edge_size );
2796     HDassert( test_max_rank <= PAR_SS_DR_MAX_RANK );
2797 
2798 #if CKRBRD_HS_DR_PIO_TEST__VERIFY_DATA__DEBUG
2799 
2800     int        mpi_rank;
2801 
2802     MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
2803     HDfprintf(stdout, "%s mpi_rank = %d.\n", fcnName, mpi_rank);
2804     HDfprintf(stdout, "%s rank = %d.\n", fcnName, rank);
2805     HDfprintf(stdout, "%s edge_size = %d.\n", fcnName, edge_size);
2806     HDfprintf(stdout, "%s checker_edge_size = %d.\n", fcnName, checker_edge_size);
2807     HDfprintf(stdout, "%s first_expected_val = %d.\n", fcnName, (int)first_expected_val);
2808     HDfprintf(stdout, "%s starts_in_checker = %d.\n", fcnName, (int)buf_starts_in_checker);
2809 }
2810 #endif
2811 
2812     val_ptr = buf_ptr;
2813     expected_value = first_expected_val;
2814 
2815     i = 0;
2816     v = 0;
2817     start_in_checker[0] = buf_starts_in_checker;
2818     do
2819     {
2820         if ( v >= checker_edge_size ) {
2821 
2822             start_in_checker[0] = ! start_in_checker[0];
2823             v = 0;
2824         }
2825 
2826         j = 0;
2827         w = 0;
2828         start_in_checker[1] = start_in_checker[0];
2829         do
2830         {
2831             if ( w >= checker_edge_size ) {
2832 
2833                 start_in_checker[1] = ! start_in_checker[1];
2834                 w = 0;
2835             }
2836 
2837             k = 0;
2838             x = 0;
2839             start_in_checker[2] = start_in_checker[1];
2840             do
2841             {
2842                 if ( x >= checker_edge_size ) {
2843 
2844                     start_in_checker[2] = ! start_in_checker[2];
2845                     x = 0;
2846                 }
2847 
2848                 l = 0;
2849                 y = 0;
2850                 start_in_checker[3] = start_in_checker[2];
2851                 do
2852                 {
2853                     if ( y >= checker_edge_size ) {
2854 
2855                         start_in_checker[3] = ! start_in_checker[3];
2856                         y = 0;
2857                     }
2858 
2859                     m = 0;
2860                     z = 0;
2861 #if CKRBRD_HS_DR_PIO_TEST__VERIFY_DATA__DEBUG
2862                     HDfprintf(stdout, "%d, %d, %d, %d, %d:", i, j, k, l, m);
2863 #endif
2864                     in_checker = start_in_checker[3];
2865                     do
2866                     {
2867 #if CKRBRD_HS_DR_PIO_TEST__VERIFY_DATA__DEBUG
2868                         HDfprintf(stdout, " %d", (int)(*val_ptr));
2869 #endif
2870                         if ( z >= checker_edge_size ) {
2871 
2872                             in_checker = ! in_checker;
2873                             z = 0;
2874                         }
2875 
2876                         if ( in_checker ) {
2877 
2878                             if ( *val_ptr != expected_value ) {
2879 
2880                                 good_data = FALSE;
2881                             }
2882 
2883                             /* zero out buffer for re-use */
2884                             *val_ptr = 0;
2885 
2886                         } else if ( *val_ptr != 0 ) {
2887 
2888                             good_data = FALSE;
2889 
2890                             /* zero out buffer for re-use */
2891                             *val_ptr = 0;
2892 
2893                         }
2894 
2895                         val_ptr++;
2896                         expected_value++;
2897                         m++;
2898                         z++;
2899 
2900                     } while ( ( rank >= (test_max_rank - 4) ) &&
2901                               ( m < edge_size ) );
2902 #if CKRBRD_HS_DR_PIO_TEST__VERIFY_DATA__DEBUG
2903                     HDfprintf(stdout, "\n");
2904 #endif
2905                     l++;
2906                     y++;
2907                 } while ( ( rank >= (test_max_rank - 3) ) &&
2908                           ( l < edge_size ) );
2909                 k++;
2910                 x++;
2911             } while ( ( rank >= (test_max_rank - 2) ) &&
2912                       ( k < edge_size ) );
2913             j++;
2914             w++;
2915         } while ( ( rank >= (test_max_rank - 1) ) &&
2916                   ( j < edge_size ) );
2917         i++;
2918         v++;
2919     } while ( ( rank >= test_max_rank ) &&
2920               ( i < edge_size ) );
2921 
2922     return(good_data);
2923 
2924 } /* ckrbrd_hs_dr_pio_test__verify_data() */
2925 
2926 
2927 /*-------------------------------------------------------------------------
2928  * Function:    ckrbrd_hs_dr_pio_test__d2m_l2s()
2929  *
2930  * Purpose:    Part one of a series of tests of I/O to/from hyperslab
2931  *        selections of different rank in the parallel.
2932  *
2933  *        Verify that we can read from disk correctly using checker
2934  *        board selections of different rank that
2935  *              H5S_select_shape_same() views as being of the same shape.
2936  *
2937  *        In this function, we test this by reading small_rank - 1
2938  *        checker board slices from the on disk large cube, and
2939  *        verifying that the data read is correct.  Verify that
2940  *        H5S_select_shape_same() returns true on the memory and
2941  *        file selections.
2942  *
2943  * Return:    void
2944  *
2945  * Programmer:    JRM -- 9/15/11
2946  *
2947  *-------------------------------------------------------------------------
2948  */
2949 
2950 #define CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG 0
2951 
2952 static void
2953 ckrbrd_hs_dr_pio_test__d2m_l2s(struct hs_dr_pio_test_vars_t * tv_ptr)
2954 {
2955 #if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG
2956     const char *fcnName = "ckrbrd_hs_dr_pio_test__d2m_l2s()";
2957     uint32_t  * ptr_0;
2958 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
2959     hbool_t    data_ok = FALSE;
2960     int        i, j, k, l;
2961     uint32_t    expected_value;
2962     int        mpi_rank; /* needed by VRFY */
2963     hsize_t     sel_start[PAR_SS_DR_MAX_RANK];
2964     htri_t      check;          /* Shape comparison return value */
2965     herr_t    ret;        /* Generic return value */
2966 
2967     /* initialize the local copy of mpi_rank */
2968     mpi_rank = tv_ptr->mpi_rank;
2969 
2970 
2971     /* first, verify that we can read from disk correctly using selections
2972      * of different rank that H5S_select_shape_same() views as being of the
2973      * same shape.
2974      *
2975      * Start by reading a (small_rank - 1)-D checker board slice from this
2976      * processes slice of the on disk large data set, and verifying that the
2977      * data read is correct.  Verify that H5S_select_shape_same() returns
2978      * true on the memory and file selections.
2979      *
2980      * The first step is to set up the needed checker board selection in the
2981      * in memory small small cube
2982      */
2983 
2984     sel_start[0] = sel_start[1] = sel_start[2] = sel_start[3] = sel_start[4] = 0;
2985     sel_start[tv_ptr->small_ds_offset] = (hsize_t)(tv_ptr->mpi_rank);
2986 
2987     ckrbrd_hs_dr_pio_test__slct_ckrbrd(tv_ptr->mpi_rank,
2988                                        tv_ptr->small_ds_slice_sid,
2989                                        tv_ptr->small_rank - 1,
2990                                        tv_ptr->edge_size,
2991                                        tv_ptr->checker_edge_size,
2992                                        tv_ptr->small_rank - 1,
2993                                        sel_start);
2994 
2995     /* zero out the buffer we will be reading into */
2996     HDmemset(tv_ptr->small_ds_slice_buf, 0, sizeof(uint32_t) * tv_ptr->small_ds_slice_size);
2997 
2998 #if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG
2999     HDfprintf(stdout, "%s:%d: initial small_ds_slice_buf = ",
3000               fcnName, tv_ptr->mpi_rank);
3001     ptr_0 = tv_ptr->small_ds_slice_buf;
3002     for ( i = 0; i < (int)(tv_ptr->small_ds_slice_size); i++ ) {
3003         HDfprintf(stdout, "%d ", (int)(*ptr_0));
3004         ptr_0++;
3005     }
3006     HDfprintf(stdout, "\n");
3007 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
3008 
3009     /* set up start, stride, count, and block -- note that we will
3010      * change start[] so as to read slices of the large cube.
3011      */
3012     for ( i = 0; i < PAR_SS_DR_MAX_RANK; i++ ) {
3013 
3014         tv_ptr->start[i] = 0;
3015         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
3016         tv_ptr->count[i] = 1;
3017         if ( (PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1) ) {
3018 
3019             tv_ptr->block[i] = 1;
3020 
3021         } else {
3022 
3023             tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
3024         }
3025     }
3026 
3027 #if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG
3028     HDfprintf(stdout,
3029               "%s:%d: reading slice from big ds on disk into small ds slice.\n",
3030               fcnName, tv_ptr->mpi_rank);
3031 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
3032     /* in serial versions of this test, we loop through all the dimensions
3033      * of the large data set.  However, in the parallel version, each
3034      * process only works with that slice of the large cube indicated
3035      * by its rank -- hence we set the most slowly changing index to
3036      * mpi_rank, and don't itterate over it.
3037      */
3038 
3039     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0 ) {
3040 
3041         i = tv_ptr->mpi_rank;
3042 
3043     } else {
3044 
3045         i = 0;
3046     }
3047 
3048     /* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
3049      * loop over it -- either we are setting i to mpi_rank, or
3050      * we are setting it to zero.  It will not change during the
3051      * test.
3052      */
3053 
3054     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1 ) {
3055 
3056         j = tv_ptr->mpi_rank;
3057 
3058     } else {
3059 
3060         j = 0;
3061     }
3062 
3063     do {
3064         if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2 ) {
3065 
3066             k = tv_ptr->mpi_rank;
3067 
3068         } else {
3069 
3070             k = 0;
3071         }
3072 
3073         do {
3074             /* since small rank >= 2 and large_rank > small_rank, we
3075              * have large_rank >= 3.  Since PAR_SS_DR_MAX_RANK == 5
3076              * (baring major re-orgaization), this gives us:
3077              *
3078              *     (PAR_SS_DR_MAX_RANK - large_rank) <= 2
3079              *
3080              * so no need to repeat the test in the outer loops --
3081              * just set l = 0.
3082              */
3083 
3084             l = 0;
3085             do {
3086                 if ( (tv_ptr->skips)++ < tv_ptr->max_skips ) { /* skip the test */
3087 
3088                     (tv_ptr->tests_skipped)++;
3089 
3090                 } else { /* run the test */
3091 
3092                     tv_ptr->skips = 0; /* reset the skips counter */
3093 
3094                     /* we know that small_rank - 1 >= 1 and that
3095                      * large_rank > small_rank by the assertions at the head
3096                      * of this function.  Thus no need for another inner loop.
3097                      */
3098                     tv_ptr->start[0] = (hsize_t)i;
3099                     tv_ptr->start[1] = (hsize_t)j;
3100                     tv_ptr->start[2] = (hsize_t)k;
3101                     tv_ptr->start[3] = (hsize_t)l;
3102                     tv_ptr->start[4] = 0;
3103 
3104                     HDassert((tv_ptr->start[0] == 0)||(0 < tv_ptr->small_ds_offset + 1));
3105                     HDassert((tv_ptr->start[1] == 0)||(1 < tv_ptr->small_ds_offset + 1));
3106                     HDassert((tv_ptr->start[2] == 0)||(2 < tv_ptr->small_ds_offset + 1));
3107                     HDassert((tv_ptr->start[3] == 0)||(3 < tv_ptr->small_ds_offset + 1));
3108                     HDassert((tv_ptr->start[4] == 0)||(4 < tv_ptr->small_ds_offset + 1));
3109 
3110                     ckrbrd_hs_dr_pio_test__slct_ckrbrd
3111                     (
3112                       tv_ptr->mpi_rank,
3113                       tv_ptr->file_large_ds_sid_0,
3114                       tv_ptr->large_rank,
3115                       tv_ptr->edge_size,
3116                       tv_ptr->checker_edge_size,
3117                       tv_ptr->small_rank - 1,
3118                       tv_ptr->start
3119                     );
3120 
3121                     /* verify that H5S_select_shape_same() reports the two
3122                      * selections as having the same shape.
3123                      */
3124                     check = H5S_select_shape_same_test(tv_ptr->small_ds_slice_sid,
3125                                                        tv_ptr->file_large_ds_sid_0);
3126                     VRFY((check == TRUE), "H5S_select_shape_same_test passed");
3127 
3128 
3129                     /* Read selection from disk */
3130 #if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG
3131                     HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n", fcnName,
3132                               tv_ptr->mpi_rank, tv_ptr->start[0], tv_ptr->start[1],
3133                               tv_ptr->start[2], tv_ptr->start[3], tv_ptr->start[4]);
3134                     HDfprintf(stdout, "%s slice/file extent dims = %d/%d.\n",
3135                               fcnName,
3136                               H5Sget_simple_extent_ndims(tv_ptr->small_ds_slice_sid),
3137                               H5Sget_simple_extent_ndims(tv_ptr->file_large_ds_sid_0));
3138 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
3139 
3140                     ret = H5Dread(tv_ptr->large_dataset,
3141                                   H5T_NATIVE_UINT32,
3142                                   tv_ptr->small_ds_slice_sid,
3143                                   tv_ptr->file_large_ds_sid_0,
3144                                   tv_ptr->xfer_plist,
3145                                   tv_ptr->small_ds_slice_buf);
3146                     VRFY((ret >= 0), "H5Dread() slice from large ds succeeded.");
3147 
3148 #if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG
3149                     HDfprintf(stdout, "%s:%d: H5Dread() returns.\n",
3150                               fcnName, tv_ptr->mpi_rank);
3151 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_L2S__DEBUG */
3152 
3153                     /* verify that expected data is retrieved */
3154 
3155                     expected_value = (uint32_t)
3156                         ((i * tv_ptr->edge_size * tv_ptr->edge_size *
3157                               tv_ptr->edge_size * tv_ptr->edge_size) +
3158                          (j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
3159                          (k * tv_ptr->edge_size * tv_ptr->edge_size) +
3160                          (l * tv_ptr->edge_size));
3161 
3162                     data_ok = ckrbrd_hs_dr_pio_test__verify_data
3163                               (
3164                                 tv_ptr->small_ds_slice_buf,
3165                                 tv_ptr->small_rank - 1,
3166                                 tv_ptr->edge_size,
3167                                 tv_ptr->checker_edge_size,
3168                                 expected_value,
3169                                 (hbool_t)TRUE
3170                               );
3171 
3172                     VRFY((data_ok == TRUE),
3173                          "small slice read from large ds data good.");
3174 
3175                     (tv_ptr->tests_run)++;
3176                 }
3177 
3178                 l++;
3179 
3180                 (tv_ptr->total_tests)++;
3181 
3182             } while ( ( tv_ptr->large_rank > 2 ) &&
3183                       ( (tv_ptr->small_rank - 1) <= 1 ) &&
3184                       ( l < tv_ptr->edge_size ) );
3185             k++;
3186         } while ( ( tv_ptr->large_rank > 3 ) &&
3187                   ( (tv_ptr->small_rank - 1) <= 2 ) &&
3188                   ( k < tv_ptr->edge_size ) );
3189         j++;
3190     } while ( ( tv_ptr->large_rank > 4 ) &&
3191               ( (tv_ptr->small_rank - 1) <= 3 ) &&
3192               ( j < tv_ptr->edge_size ) );
3193 
3194     return;
3195 
3196 } /* ckrbrd_hs_dr_pio_test__d2m_l2s() */
3197 
3198 
3199 /*-------------------------------------------------------------------------
3200  * Function:    ckrbrd_hs_dr_pio_test__d2m_s2l()
3201  *
3202  * Purpose:    Part two of a series of tests of I/O to/from hyperslab
3203  *        selections of different rank in the parallel.
3204  *
3205  *        Verify that we can read from disk correctly using
3206  *        selections of different rank that H5S_select_shape_same()
3207  *        views as being of the same shape.
3208  *
3209  *        In this function, we test this by reading checker board
3210  *        slices of the on disk small data set into slices through
3211  *        the in memory large data set, and verify that the correct
3212  *        data (and only the correct data) is read.
3213  *
3214  * Return:    void
3215  *
3216  * Programmer:    JRM -- 8/15/11
3217  *
3218  *-------------------------------------------------------------------------
3219  */
3220 
3221 #define CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG 0
3222 
3223 static void
3224 ckrbrd_hs_dr_pio_test__d2m_s2l(struct hs_dr_pio_test_vars_t * tv_ptr)
3225 {
3226 #if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG
3227     const char *fcnName = "ckrbrd_hs_dr_pio_test__d2m_s2l()";
3228 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
3229     hbool_t    data_ok = FALSE;
3230     int        i, j, k, l;
3231     size_t      u;
3232     size_t      start_index;
3233     size_t      stop_index;
3234     uint32_t    expected_value;
3235     uint32_t  * ptr_1;
3236     int        mpi_rank; /* needed by VRFY */
3237     hsize_t     sel_start[PAR_SS_DR_MAX_RANK];
3238     htri_t      check;          /* Shape comparison return value */
3239     herr_t    ret;        /* Generic return value */
3240 
3241     /* initialize the local copy of mpi_rank */
3242     mpi_rank = tv_ptr->mpi_rank;
3243 
3244 
3245     /* similarly, read slices of the on disk small data set into slices
3246      * through the in memory large data set, and verify that the correct
3247      * data (and only the correct data) is read.
3248      */
3249 
3250     sel_start[0] = sel_start[1] = sel_start[2] = sel_start[3] = sel_start[4] = 0;
3251     sel_start[tv_ptr->small_ds_offset] = (hsize_t)(tv_ptr->mpi_rank);
3252 
3253     ckrbrd_hs_dr_pio_test__slct_ckrbrd(tv_ptr->mpi_rank,
3254                                        tv_ptr->file_small_ds_sid_0,
3255                                        tv_ptr->small_rank,
3256                                        tv_ptr->edge_size,
3257                                        tv_ptr->checker_edge_size,
3258                                        tv_ptr->small_rank - 1,
3259                                        sel_start);
3260 
3261 #if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG
3262     HDfprintf(stdout,
3263       "%s reading slices of on disk small data set into slices of big data set.\n",
3264               fcnName);
3265 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
3266 
3267     /* zero out the buffer we will be reading into */
3268     HDmemset(tv_ptr->large_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->large_ds_size);
3269 
3270     /* set up start, stride, count, and block -- note that we will
3271      * change start[] so as to read the slice of the small data set
3272      * into different slices of the process slice of the large data
3273      * set.
3274      */
3275     for ( i = 0; i < PAR_SS_DR_MAX_RANK; i++ ) {
3276 
3277         tv_ptr->start[i] = 0;
3278         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
3279         tv_ptr->count[i] = 1;
3280         if ( (PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1) ) {
3281 
3282             tv_ptr->block[i] = 1;
3283 
3284         } else {
3285 
3286             tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
3287         }
3288     }
3289 
3290     /* in serial versions of this test, we loop through all the dimensions
3291      * of the large data set that don't appear in the small data set.
3292      *
3293      * However, in the parallel version, each process only works with that
3294      * slice of the large (and small) data set indicated by its rank -- hence
3295      * we set the most slowly changing index to mpi_rank, and don't itterate
3296      * over it.
3297      */
3298 
3299 
3300     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0 ) {
3301 
3302         i = tv_ptr->mpi_rank;
3303 
3304     } else {
3305 
3306         i = 0;
3307     }
3308 
3309     /* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
3310      * loop over it -- either we are setting i to mpi_rank, or
3311      * we are setting it to zero.  It will not change during the
3312      * test.
3313      */
3314 
3315     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1 ) {
3316 
3317         j = tv_ptr->mpi_rank;
3318 
3319     } else {
3320 
3321         j = 0;
3322     }
3323 
3324     do {
3325         if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2 ) {
3326 
3327             k = tv_ptr->mpi_rank;
3328 
3329         } else {
3330 
3331             k = 0;
3332         }
3333 
3334         do {
3335             /* since small rank >= 2 and large_rank > small_rank, we
3336              * have large_rank >= 3.  Since PAR_SS_DR_MAX_RANK == 5
3337              * (baring major re-orgaization), this gives us:
3338              *
3339              *     (PAR_SS_DR_MAX_RANK - large_rank) <= 2
3340              *
3341              * so no need to repeat the test in the outer loops --
3342              * just set l = 0.
3343              */
3344 
3345             l = 0;
3346             do {
3347                 if ( (tv_ptr->skips)++ < tv_ptr->max_skips ) { /* skip the test */
3348 
3349                     (tv_ptr->tests_skipped)++;
3350 
3351                 } else { /* run the test */
3352 
3353                     tv_ptr->skips = 0; /* reset the skips counter */
3354 
3355                     /* we know that small_rank >= 1 and that large_rank > small_rank
3356                      * by the assertions at the head of this function.  Thus no
3357                      * need for another inner loop.
3358                      */
3359                     tv_ptr->start[0] = (hsize_t)i;
3360                     tv_ptr->start[1] = (hsize_t)j;
3361                     tv_ptr->start[2] = (hsize_t)k;
3362                     tv_ptr->start[3] = (hsize_t)l;
3363                     tv_ptr->start[4] = 0;
3364 
3365                     HDassert((tv_ptr->start[0] == 0)||(0 < tv_ptr->small_ds_offset + 1));
3366                     HDassert((tv_ptr->start[1] == 0)||(1 < tv_ptr->small_ds_offset + 1));
3367                     HDassert((tv_ptr->start[2] == 0)||(2 < tv_ptr->small_ds_offset + 1));
3368                     HDassert((tv_ptr->start[3] == 0)||(3 < tv_ptr->small_ds_offset + 1));
3369                     HDassert((tv_ptr->start[4] == 0)||(4 < tv_ptr->small_ds_offset + 1));
3370 
3371                     ckrbrd_hs_dr_pio_test__slct_ckrbrd
3372                     (
3373                       tv_ptr->mpi_rank,
3374                       tv_ptr->mem_large_ds_sid,
3375                       tv_ptr->large_rank,
3376                       tv_ptr->edge_size,
3377                       tv_ptr->checker_edge_size,
3378                       tv_ptr->small_rank - 1,
3379                       tv_ptr->start
3380                     );
3381 
3382 
3383                     /* verify that H5S_select_shape_same() reports the two
3384                      * selections as having the same shape.
3385                      */
3386                     check = H5S_select_shape_same_test(tv_ptr->file_small_ds_sid_0,
3387                                                        tv_ptr->mem_large_ds_sid);
3388                     VRFY((check == TRUE), "H5S_select_shape_same_test passed");
3389 
3390 
3391                     /* Read selection from disk */
3392 #if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG
3393                     HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n",
3394                               fcnName, tv_ptr->mpi_rank,
3395                               tv_ptr->start[0], tv_ptr->start[1], tv_ptr->start[2],
3396                               tv_ptr->start[3], tv_ptr->start[4]);
3397                     HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n",
3398                               fcnName, tv_ptr->mpi_rank,
3399                               H5Sget_simple_extent_ndims(tv_ptr->large_ds_slice_sid),
3400                               H5Sget_simple_extent_ndims(tv_ptr->file_small_ds_sid_0));
3401 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
3402                     ret = H5Dread(tv_ptr->small_dataset,
3403                                   H5T_NATIVE_UINT32,
3404                                   tv_ptr->mem_large_ds_sid,
3405                                   tv_ptr->file_small_ds_sid_0,
3406                                   tv_ptr->xfer_plist,
3407                                   tv_ptr->large_ds_buf_1);
3408                     VRFY((ret >= 0), "H5Dread() slice from small ds succeeded.");
3409 
3410                     /* verify that the expected data and only the
3411                      * expected data was read.
3412                      */
3413                     data_ok = TRUE;
3414                     ptr_1 = tv_ptr->large_ds_buf_1;
3415                     expected_value =
3416                        (uint32_t)((size_t)(tv_ptr->mpi_rank) * tv_ptr->small_ds_slice_size);
3417                     start_index = (size_t)(
3418                         (i * tv_ptr->edge_size * tv_ptr->edge_size *
3419                              tv_ptr->edge_size * tv_ptr->edge_size) +
3420                         (j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
3421                         (k * tv_ptr->edge_size * tv_ptr->edge_size) +
3422                         (l * tv_ptr->edge_size));
3423                     stop_index = start_index + tv_ptr->small_ds_slice_size - 1;
3424 
3425 #if CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG
3426                     {
3427                         int m, n;
3428 
3429                         HDfprintf(stdout, "%s:%d: expected_value = %d.\n",
3430                                   fcnName, tv_ptr->mpi_rank, expected_value);
3431                         HDfprintf(stdout, "%s:%d: start/stop index = %d/%d.\n",
3432                                   fcnName, tv_ptr->mpi_rank, start_index, stop_index);
3433                         n = 0;
3434                         for ( m = 0; (unsigned)m < tv_ptr->large_ds_size; m ++ ) {
3435                             HDfprintf(stdout, "%d ", (int)(*ptr_1));
3436                             ptr_1++;
3437                             n++;
3438                             if ( n >= tv_ptr->edge_size ) {
3439                                 HDfprintf(stdout, "\n");
3440                                 n = 0;
3441                             }
3442                         }
3443                         HDfprintf(stdout, "\n");
3444                         ptr_1 = tv_ptr->large_ds_buf_1;
3445                     }
3446 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__D2M_S2L__DEBUG */
3447 
3448                     HDassert( start_index < stop_index );
3449                     HDassert( stop_index <= tv_ptr->large_ds_size );
3450 
3451                     for ( u = 0; u < start_index; u++ ) {
3452 
3453                         if ( *ptr_1 != 0 ) {
3454 
3455                             data_ok = FALSE;
3456                         }
3457 
3458                         /* zero out the value for the next pass */
3459                         *ptr_1 = 0;
3460 
3461                         ptr_1++;
3462                     }
3463 
3464                     VRFY((data_ok == TRUE),
3465                          "slice read from small to large ds data good(1).");
3466 
3467                     data_ok = ckrbrd_hs_dr_pio_test__verify_data
3468                               (
3469                                 ptr_1,
3470                                 tv_ptr->small_rank - 1,
3471                                 tv_ptr->edge_size,
3472                                 tv_ptr->checker_edge_size,
3473                                 expected_value,
3474                                 (hbool_t)TRUE
3475                               );
3476 
3477                     VRFY((data_ok == TRUE),
3478                          "slice read from small to large ds data good(2).");
3479 
3480 
3481                     ptr_1 = tv_ptr->large_ds_buf_1 + stop_index + 1;
3482 
3483                     for ( u = stop_index + 1; u < tv_ptr->large_ds_size; u++ ) {
3484 
3485                         if ( *ptr_1 != 0 ) {
3486 
3487                             data_ok = FALSE;
3488                         }
3489 
3490                         /* zero out the value for the next pass */
3491                         *ptr_1 = 0;
3492 
3493                         ptr_1++;
3494                     }
3495 
3496                     VRFY((data_ok == TRUE),
3497                          "slice read from small to large ds data good(3).");
3498 
3499                     (tv_ptr->tests_run)++;
3500                 }
3501 
3502                 l++;
3503 
3504                 (tv_ptr->total_tests)++;
3505 
3506             } while ( ( tv_ptr->large_rank > 2 ) &&
3507                       ( (tv_ptr->small_rank - 1) <= 1 ) &&
3508                       ( l < tv_ptr->edge_size ) );
3509             k++;
3510         } while ( ( tv_ptr->large_rank > 3 ) &&
3511                   ( (tv_ptr->small_rank - 1) <= 2 ) &&
3512                   ( k < tv_ptr->edge_size ) );
3513         j++;
3514     } while ( ( tv_ptr->large_rank > 4 ) &&
3515               ( (tv_ptr->small_rank - 1) <= 3 ) &&
3516               ( j < tv_ptr->edge_size ) );
3517 
3518     return;
3519 
3520 } /* ckrbrd_hs_dr_pio_test__d2m_s2l() */
3521 
3522 
3523 /*-------------------------------------------------------------------------
3524  * Function:    ckrbrd_hs_dr_pio_test__m2d_l2s()
3525  *
3526  * Purpose:    Part three of a series of tests of I/O to/from checker
3527  *        board hyperslab selections of different rank in the
3528  *        parallel.
3529  *
3530  *        Verify that we can write from memory to file using checker
3531  *        board selections of different rank that
3532  *        H5S_select_shape_same() views as being of the same shape.
3533  *
3534  *        Do this by writing small_rank - 1 dimensional checker
3535  *        board slices from the in memory large data set to the on
3536  *        disk small cube dataset.  After each write, read the
3537  *        slice of the small dataset back from disk, and verify
3538  *        that it contains the expected data. Verify that
3539  *        H5S_select_shape_same() returns true on the memory and
3540  *        file selections.
3541  *
3542  * Return:    void
3543  *
3544  * Programmer:    JRM -- 8/15/11
3545  *
3546  *-------------------------------------------------------------------------
3547  */
3548 
3549 #define CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG 0
3550 
3551 static void
3552 ckrbrd_hs_dr_pio_test__m2d_l2s(struct hs_dr_pio_test_vars_t * tv_ptr)
3553 {
3554 #if CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG
3555     const char *fcnName = "ckrbrd_hs_dr_pio_test__m2d_l2s()";
3556 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG */
3557     hbool_t    data_ok = FALSE;
3558     hbool_t    mis_match = FALSE;
3559     int        i, j, k, l;
3560     size_t      u;
3561     size_t      start_index;
3562     size_t      stop_index;
3563     uint32_t    expected_value;
3564     uint32_t  * ptr_1;
3565     int        mpi_rank; /* needed by VRFY */
3566     hsize_t     sel_start[PAR_SS_DR_MAX_RANK];
3567     htri_t      check;          /* Shape comparison return value */
3568     herr_t    ret;        /* Generic return value */
3569 
3570     /* initialize the local copy of mpi_rank */
3571     mpi_rank = tv_ptr->mpi_rank;
3572 
3573 
3574     /* now we go in the opposite direction, verifying that we can write
3575      * from memory to file using selections of different rank that
3576      * H5S_select_shape_same() views as being of the same shape.
3577      *
3578      * Start by writing small_rank - 1 D slices from the in memory large data
3579      * set to the on disk small dataset.  After each write, read the slice of
3580      * the small dataset back from disk, and verify that it contains the
3581      * expected data. Verify that H5S_select_shape_same() returns true on
3582      * the memory and file selections.
3583      */
3584 
3585     tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
3586     tv_ptr->stride[0] = (hsize_t)(2 * (tv_ptr->mpi_size + 1));
3587     tv_ptr->count[0] = 1;
3588     tv_ptr->block[0] = 1;
3589 
3590     for ( i = 1; i < tv_ptr->large_rank; i++ ) {
3591 
3592         tv_ptr->start[i] = 0;
3593         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
3594         tv_ptr->count[i] = 1;
3595         tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
3596     }
3597 
3598     ret = H5Sselect_hyperslab(tv_ptr->file_small_ds_sid_0,
3599                               H5S_SELECT_SET,
3600                               tv_ptr->start,
3601                               tv_ptr->stride,
3602                               tv_ptr->count,
3603                               tv_ptr->block);
3604     VRFY((ret >= 0), "H5Sselect_hyperslab(file_small_ds_sid_0, set) suceeded");
3605 
3606     ret = H5Sselect_hyperslab(tv_ptr->mem_small_ds_sid,
3607                               H5S_SELECT_SET,
3608                               tv_ptr->start,
3609                               tv_ptr->stride,
3610                               tv_ptr->count,
3611                               tv_ptr->block);
3612     VRFY((ret >= 0), "H5Sselect_hyperslab(mem_small_ds_sid, set) suceeded");
3613 
3614 
3615     sel_start[0] = sel_start[1] = sel_start[2] = sel_start[3] = sel_start[4] = 0;
3616     sel_start[tv_ptr->small_ds_offset] = (hsize_t)(tv_ptr->mpi_rank);
3617 
3618     ckrbrd_hs_dr_pio_test__slct_ckrbrd(tv_ptr->mpi_rank,
3619                                        tv_ptr->file_small_ds_sid_1,
3620                                        tv_ptr->small_rank,
3621                                        tv_ptr->edge_size,
3622                                        tv_ptr->checker_edge_size,
3623                                        tv_ptr->small_rank - 1,
3624                                        sel_start);
3625 
3626 
3627     /* set up start, stride, count, and block -- note that we will
3628      * change start[] so as to read slices of the large cube.
3629      */
3630     for ( i = 0; i < PAR_SS_DR_MAX_RANK; i++ ) {
3631 
3632         tv_ptr->start[i] = 0;
3633         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
3634         tv_ptr->count[i] = 1;
3635         if ( (PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1) ) {
3636 
3637             tv_ptr->block[i] = 1;
3638 
3639         } else {
3640 
3641             tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
3642         }
3643     }
3644 
3645     /* zero out the in memory small ds */
3646     HDmemset(tv_ptr->small_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->small_ds_size);
3647 
3648 
3649 #if CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG
3650     HDfprintf(stdout,
3651     "%s writing checker boards selections of slices from big ds to slices of small ds on disk.\n",
3652     fcnName);
3653 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG */
3654 
3655     /* in serial versions of this test, we loop through all the dimensions
3656      * of the large data set that don't appear in the small data set.
3657      *
3658      * However, in the parallel version, each process only works with that
3659      * slice of the large (and small) data set indicated by its rank -- hence
3660      * we set the most slowly changing index to mpi_rank, and don't itterate
3661      * over it.
3662      */
3663 
3664 
3665     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0 ) {
3666 
3667         i = tv_ptr->mpi_rank;
3668 
3669     } else {
3670 
3671         i = 0;
3672     }
3673 
3674     /* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
3675      * loop over it -- either we are setting i to mpi_rank, or
3676      * we are setting it to zero.  It will not change during the
3677      * test.
3678      */
3679 
3680     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1 ) {
3681 
3682         j = tv_ptr->mpi_rank;
3683 
3684     } else {
3685 
3686         j = 0;
3687     }
3688 
3689     j = 0;
3690     do {
3691         if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2 ) {
3692 
3693             k = tv_ptr->mpi_rank;
3694 
3695         } else {
3696 
3697             k = 0;
3698         }
3699 
3700         do {
3701             /* since small rank >= 2 and large_rank > small_rank, we
3702              * have large_rank >= 3.  Since PAR_SS_DR_MAX_RANK == 5
3703              * (baring major re-orgaization), this gives us:
3704              *
3705              *     (PAR_SS_DR_MAX_RANK - large_rank) <= 2
3706              *
3707              * so no need to repeat the test in the outer loops --
3708              * just set l = 0.
3709              */
3710 
3711             l = 0;
3712             do {
3713                 if ( (tv_ptr->skips)++ < tv_ptr->max_skips ) { /* skip the test */
3714 
3715                     (tv_ptr->tests_skipped)++;
3716 
3717                 } else { /* run the test */
3718 
3719                     tv_ptr->skips = 0; /* reset the skips counter */
3720 
3721                     /* we know that small_rank >= 1 and that large_rank > small_rank
3722                      * by the assertions at the head of this function.  Thus no
3723                      * need for another inner loop.
3724                      */
3725 
3726                     /* zero out this rank's slice of the on disk small data set */
3727                     ret = H5Dwrite(tv_ptr->small_dataset,
3728                                    H5T_NATIVE_UINT32,
3729                                    tv_ptr->mem_small_ds_sid,
3730                                    tv_ptr->file_small_ds_sid_0,
3731                                    tv_ptr->xfer_plist,
3732                                    tv_ptr->small_ds_buf_2);
3733                     VRFY((ret >= 0), "H5Dwrite() zero slice to small ds succeeded.");
3734 
3735                     /* select the portion of the in memory large cube from which we
3736                      * are going to write data.
3737                      */
3738                     tv_ptr->start[0] = (hsize_t)i;
3739                     tv_ptr->start[1] = (hsize_t)j;
3740                     tv_ptr->start[2] = (hsize_t)k;
3741                     tv_ptr->start[3] = (hsize_t)l;
3742                     tv_ptr->start[4] = 0;
3743 
3744                     HDassert((tv_ptr->start[0] == 0)||(0 < tv_ptr->small_ds_offset + 1));
3745                     HDassert((tv_ptr->start[1] == 0)||(1 < tv_ptr->small_ds_offset + 1));
3746                     HDassert((tv_ptr->start[2] == 0)||(2 < tv_ptr->small_ds_offset + 1));
3747                     HDassert((tv_ptr->start[3] == 0)||(3 < tv_ptr->small_ds_offset + 1));
3748                     HDassert((tv_ptr->start[4] == 0)||(4 < tv_ptr->small_ds_offset + 1));
3749 
3750                     ckrbrd_hs_dr_pio_test__slct_ckrbrd
3751                     (
3752                       tv_ptr->mpi_rank,
3753                       tv_ptr->mem_large_ds_sid,
3754                       tv_ptr->large_rank,
3755                       tv_ptr->edge_size,
3756                       tv_ptr->checker_edge_size,
3757                       tv_ptr->small_rank - 1,
3758                       tv_ptr->start
3759                     );
3760 
3761 
3762                     /* verify that H5S_select_shape_same() reports the in
3763                      * memory checkerboard selection of the slice through the
3764                      * large dataset and the checkerboard selection of the process
3765                      * slice of the small data set as having the same shape.
3766                      */
3767                     check = H5S_select_shape_same_test(tv_ptr->file_small_ds_sid_1,
3768                                                        tv_ptr->mem_large_ds_sid);
3769                     VRFY((check == TRUE), "H5S_select_shape_same_test passed.");
3770 
3771 
3772                     /* write the checker board selection of the slice from the in
3773                      * memory large data set to the slice of the on disk small
3774                      * dataset.
3775                      */
3776 #if CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG
3777                     HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n",
3778                               fcnName, tv_ptr->mpi_rank,
3779                               tv_ptr->start[0], tv_ptr->start[1], tv_ptr->start[2],
3780                               tv_ptr->start[3], tv_ptr->start[4]);
3781                     HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n",
3782                               fcnName, tv_ptr->mpi_rank,
3783                               H5Sget_simple_extent_ndims(tv_ptr->mem_large_ds_sid),
3784                               H5Sget_simple_extent_ndims(tv_ptr->file_small_ds_sid_1));
3785 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__M2D_L2S__DEBUG */
3786                     ret = H5Dwrite(tv_ptr->small_dataset,
3787                                    H5T_NATIVE_UINT32,
3788                                    tv_ptr->mem_large_ds_sid,
3789                                    tv_ptr->file_small_ds_sid_1,
3790                                    tv_ptr->xfer_plist,
3791                                    tv_ptr->large_ds_buf_0);
3792                     VRFY((ret >= 0), "H5Dwrite() slice to large ds succeeded.");
3793 
3794 
3795                     /* read the on disk process slice of the small dataset into memory */
3796                     ret = H5Dread(tv_ptr->small_dataset,
3797                                   H5T_NATIVE_UINT32,
3798                                   tv_ptr->mem_small_ds_sid,
3799                                   tv_ptr->file_small_ds_sid_0,
3800                                   tv_ptr->xfer_plist,
3801                                   tv_ptr->small_ds_buf_1);
3802                     VRFY((ret >= 0), "H5Dread() slice from small ds succeeded.");
3803 
3804 
3805                     /* verify that expected data is retrieved */
3806 
3807                     mis_match = FALSE;
3808 
3809                     expected_value = (uint32_t)(
3810                 (i * tv_ptr->edge_size * tv_ptr->edge_size *
3811                                  tv_ptr->edge_size * tv_ptr->edge_size) +
3812                         (j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
3813                         (k * tv_ptr->edge_size * tv_ptr->edge_size) +
3814                         (l * tv_ptr->edge_size));
3815 
3816                     start_index = (size_t)(tv_ptr->mpi_rank) * tv_ptr->small_ds_slice_size;
3817                     stop_index = start_index + tv_ptr->small_ds_slice_size - 1;
3818 
3819                     HDassert( start_index < stop_index );
3820                     HDassert( stop_index <= tv_ptr->small_ds_size );
3821 
3822                     data_ok = TRUE;
3823 
3824                     ptr_1 = tv_ptr->small_ds_buf_1;
3825                     for ( u = 0; u < start_index; u++, ptr_1++ ) {
3826 
3827                         if ( *ptr_1 != 0 ) {
3828 
3829                             data_ok = FALSE;
3830                             *ptr_1 = 0;
3831                         }
3832                     }
3833 
3834                     data_ok &= ckrbrd_hs_dr_pio_test__verify_data
3835                                (
3836                                  tv_ptr->small_ds_buf_1 + start_index,
3837                                  tv_ptr->small_rank - 1,
3838                                  tv_ptr->edge_size,
3839                                  tv_ptr->checker_edge_size,
3840                                  expected_value,
3841                                  (hbool_t)TRUE
3842                                );
3843 
3844 
3845                     ptr_1 = tv_ptr->small_ds_buf_1;
3846                     for ( u = stop_index; u < tv_ptr->small_ds_size; u++, ptr_1++ ) {
3847 
3848                         if ( *ptr_1 != 0 ) {
3849 
3850                             data_ok = FALSE;
3851                             *ptr_1 = 0;
3852                         }
3853                     }
3854 
3855                     VRFY((data_ok == TRUE),
3856                          "large slice write slice to small slice data good.");
3857 
3858                     (tv_ptr->tests_run)++;
3859                 }
3860 
3861                 l++;
3862 
3863                 (tv_ptr->total_tests)++;
3864 
3865             } while ( ( tv_ptr->large_rank > 2 ) &&
3866                       ( (tv_ptr->small_rank - 1) <= 1 ) &&
3867                       ( l < tv_ptr->edge_size ) );
3868             k++;
3869         } while ( ( tv_ptr->large_rank > 3 ) &&
3870                   ( (tv_ptr->small_rank - 1) <= 2 ) &&
3871                   ( k < tv_ptr->edge_size ) );
3872         j++;
3873     } while ( ( tv_ptr->large_rank > 4 ) &&
3874               ( (tv_ptr->small_rank - 1) <= 3 ) &&
3875               ( j < tv_ptr->edge_size ) );
3876 
3877     return;
3878 
3879 } /* ckrbrd_hs_dr_pio_test__m2d_l2s() */
3880 
3881 
3882 /*-------------------------------------------------------------------------
3883  * Function:    ckrbrd_hs_dr_pio_test__m2d_s2l()
3884  *
3885  * Purpose:    Part four of a series of tests of I/O to/from checker
3886  *        board hyperslab selections of different rank in the parallel.
3887  *
3888  *        Verify that we can write from memory to file using
3889  *        selections of different rank that H5S_select_shape_same()
3890  *        views as being of the same shape.
3891  *
3892  *        Do this by writing checker board selections of the contents
3893  *        of the process's slice of the in memory small data set to
3894  *        slices of the on disk large data set.  After each write,
3895  *        read the process's slice of the large data set back into
3896  *        memory, and verify that it contains the expected data.
3897  *
3898  *        Verify that H5S_select_shape_same() returns true on the
3899  *        memory and file selections.
3900  *
3901  * Return:    void
3902  *
3903  * Programmer:    JRM -- 8/15/11
3904  *
3905  *-------------------------------------------------------------------------
3906  */
3907 
3908 #define CHECKER_BOARD_HS_DR_PIO_TEST__M2D_S2L__DEBUG 0
3909 
3910 static void
3911 ckrbrd_hs_dr_pio_test__m2d_s2l(struct hs_dr_pio_test_vars_t * tv_ptr)
3912 {
3913 #if CHECKER_BOARD_HS_DR_PIO_TEST__M2D_S2L__DEBUG
3914     const char *fcnName = "ckrbrd_hs_dr_pio_test__m2d_s2l()";
3915 #endif /* CONTIG_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
3916     hbool_t    data_ok = FALSE;
3917     hbool_t    mis_match = FALSE;
3918     int        i, j, k, l;
3919     size_t      u;
3920     size_t      start_index;
3921     size_t      stop_index;
3922     uint32_t    expected_value;
3923     uint32_t  * ptr_1;
3924     int        mpi_rank; /* needed by VRFY */
3925     hsize_t     sel_start[PAR_SS_DR_MAX_RANK];
3926     htri_t      check;          /* Shape comparison return value */
3927     herr_t    ret;        /* Generic return value */
3928 
3929     /* initialize the local copy of mpi_rank */
3930     mpi_rank = tv_ptr->mpi_rank;
3931 
3932 
3933     /* Now write the contents of the process's slice of the in memory
3934      * small data set to slices of the on disk large data set.  After
3935      * each write, read the process's slice of the large data set back
3936      * into memory, and verify that it contains the expected data.
3937      * Verify that H5S_select_shape_same() returns true on the memory
3938      * and file selections.
3939      */
3940 
3941     tv_ptr->start[0] = (hsize_t)(tv_ptr->mpi_rank);
3942     tv_ptr->stride[0] = (hsize_t)(2 * (tv_ptr->mpi_size + 1));
3943     tv_ptr->count[0] = 1;
3944     tv_ptr->block[0] = 1;
3945 
3946     for ( i = 1; i < tv_ptr->large_rank; i++ ) {
3947 
3948         tv_ptr->start[i] = 0;
3949         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
3950         tv_ptr->count[i] = 1;
3951         tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
3952     }
3953 
3954     ret = H5Sselect_hyperslab(tv_ptr->file_large_ds_sid_0,
3955                               H5S_SELECT_SET,
3956                               tv_ptr->start,
3957                               tv_ptr->stride,
3958                               tv_ptr->count,
3959                               tv_ptr->block);
3960     VRFY((ret >= 0), "H5Sselect_hyperslab(file_large_ds_sid_0, set) suceeded");
3961 
3962     ret = H5Sselect_hyperslab(tv_ptr->mem_large_ds_sid,
3963                               H5S_SELECT_SET,
3964                               tv_ptr->start,
3965                               tv_ptr->stride,
3966                               tv_ptr->count,
3967                               tv_ptr->block);
3968     VRFY((ret >= 0), "H5Sselect_hyperslab(tv_ptr->mem_large_ds_sid, set) suceeded");
3969 
3970     /* setup a checkerboard selection of the slice of the in memory small
3971      * data set associated with the process's mpi rank.
3972      */
3973 
3974     sel_start[0] = sel_start[1] = sel_start[2] = sel_start[3] = sel_start[4] = 0;
3975     sel_start[tv_ptr->small_ds_offset] = (hsize_t)(tv_ptr->mpi_rank);
3976 
3977     ckrbrd_hs_dr_pio_test__slct_ckrbrd(tv_ptr->mpi_rank,
3978                                        tv_ptr->mem_small_ds_sid,
3979                                        tv_ptr->small_rank,
3980                                        tv_ptr->edge_size,
3981                                        tv_ptr->checker_edge_size,
3982                                        tv_ptr->small_rank - 1,
3983                                        sel_start);
3984 
3985     /* set up start, stride, count, and block -- note that we will
3986      * change start[] so as to write checkerboard selections of slices
3987      * of the small data set to slices of the large data set.
3988      */
3989     for ( i = 0; i < PAR_SS_DR_MAX_RANK; i++ ) {
3990 
3991         tv_ptr->start[i] = 0;
3992         tv_ptr->stride[i] = (hsize_t)(2 * tv_ptr->edge_size);
3993         tv_ptr->count[i] = 1;
3994         if ( (PAR_SS_DR_MAX_RANK - i) > (tv_ptr->small_rank - 1) ) {
3995 
3996             tv_ptr->block[i] = 1;
3997 
3998         } else {
3999 
4000             tv_ptr->block[i] = (hsize_t)(tv_ptr->edge_size);
4001         }
4002     }
4003 
4004     /* zero out the in memory large ds */
4005     HDmemset(tv_ptr->large_ds_buf_1, 0, sizeof(uint32_t) * tv_ptr->large_ds_size);
4006 
4007 #if CHECKER_BOARD_HS_DR_PIO_TEST__M2D_S2L__DEBUG
4008     HDfprintf(stdout,
4009          "%s writing process checkerboard selections of slices of small ds to process slices of large ds on disk.\n",
4010          fcnName);
4011 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
4012 
4013     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 0 ) {
4014 
4015         i = tv_ptr->mpi_rank;
4016 
4017     } else {
4018 
4019         i = 0;
4020     }
4021 
4022     /* since large_rank is at most PAR_SS_DR_MAX_RANK, no need to
4023      * loop over it -- either we are setting i to mpi_rank, or
4024      * we are setting it to zero.  It will not change during the
4025      * test.
4026      */
4027 
4028     if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 1 ) {
4029 
4030         j = tv_ptr->mpi_rank;
4031 
4032     } else {
4033 
4034         j = 0;
4035     }
4036 
4037     do {
4038         if ( PAR_SS_DR_MAX_RANK - tv_ptr->large_rank == 2 ) {
4039 
4040             k = tv_ptr->mpi_rank;
4041 
4042         } else {
4043 
4044             k = 0;
4045         }
4046 
4047         do {
4048             /* since small rank >= 2 and large_rank > small_rank, we
4049              * have large_rank >= 3.  Since PAR_SS_DR_MAX_RANK == 5
4050              * (baring major re-orgaization), this gives us:
4051              *
4052              *     (PAR_SS_DR_MAX_RANK - large_rank) <= 2
4053              *
4054              * so no need to repeat the test in the outer loops --
4055              * just set l = 0.
4056              */
4057 
4058             l = 0;
4059             do {
4060                 if ( (tv_ptr->skips)++ < tv_ptr->max_skips ) { /* skip the test */
4061 
4062                     (tv_ptr->tests_skipped)++;
4063 
4064                 } else { /* run the test */
4065 
4066                     tv_ptr->skips = 0; /* reset the skips counter */
4067 
4068                     /* we know that small_rank >= 1 and that large_rank > small_rank
4069                      * by the assertions at the head of this function.  Thus no
4070                      * need for another inner loop.
4071                      */
4072 
4073                     /* Zero out this processes slice of the on disk large data set.
4074                      * Note that this will leave one slice with its original data
4075                      * as there is one more slice than processes.
4076                      */
4077                     ret = H5Dwrite(tv_ptr->large_dataset,
4078                                    H5T_NATIVE_UINT32,
4079                                    tv_ptr->mem_large_ds_sid,
4080                                    tv_ptr->file_large_ds_sid_0,
4081                                    tv_ptr->xfer_plist,
4082                                    tv_ptr->large_ds_buf_2);
4083                     VRFY((ret != FAIL), "H5Dwrite() to zero large ds suceeded");
4084 
4085 
4086                     /* select the portion of the in memory large cube to which we
4087                      * are going to write data.
4088                      */
4089                     tv_ptr->start[0] = (hsize_t)i;
4090                     tv_ptr->start[1] = (hsize_t)j;
4091                     tv_ptr->start[2] = (hsize_t)k;
4092                     tv_ptr->start[3] = (hsize_t)l;
4093                     tv_ptr->start[4] = 0;
4094 
4095                     HDassert((tv_ptr->start[0] == 0)||(0 < tv_ptr->small_ds_offset + 1));
4096                     HDassert((tv_ptr->start[1] == 0)||(1 < tv_ptr->small_ds_offset + 1));
4097                     HDassert((tv_ptr->start[2] == 0)||(2 < tv_ptr->small_ds_offset + 1));
4098                     HDassert((tv_ptr->start[3] == 0)||(3 < tv_ptr->small_ds_offset + 1));
4099                     HDassert((tv_ptr->start[4] == 0)||(4 < tv_ptr->small_ds_offset + 1));
4100 
4101                     ckrbrd_hs_dr_pio_test__slct_ckrbrd
4102                     (
4103                       tv_ptr->mpi_rank,
4104                       tv_ptr->file_large_ds_sid_1,
4105                       tv_ptr->large_rank,
4106                       tv_ptr->edge_size,
4107                       tv_ptr->checker_edge_size,
4108                       tv_ptr->small_rank - 1,
4109                       tv_ptr->start
4110                     );
4111 
4112 
4113                     /* verify that H5S_select_shape_same() reports the in
4114                      * memory small data set slice selection and the
4115                      * on disk slice through the large data set selection
4116                      * as having the same shape.
4117                      */
4118                     check = H5S_select_shape_same_test(tv_ptr->mem_small_ds_sid,
4119                                                        tv_ptr->file_large_ds_sid_1);
4120                     VRFY((check == TRUE), "H5S_select_shape_same_test passed");
4121 
4122 
4123                     /* write the small data set slice from memory to the
4124                      * target slice of the disk data set
4125                      */
4126 #if CHECKER_BOARD_HS_DR_PIO_TEST__M2D_S2L__DEBUG
4127                     HDfprintf(stdout, "%s:%d: start = %d %d %d %d %d.\n",
4128                               fcnName, tv_ptr->mpi_rank,
4129                               tv_ptr->start[0], tv_ptr->start[1], tv_ptr->start[2],
4130                               tv_ptr->start[3], tv_ptr->start[4]);
4131                     HDfprintf(stdout, "%s:%d: mem/file extent dims = %d/%d.\n",
4132                               fcnName, tv_ptr->mpi_rank,
4133                               H5Sget_simple_extent_ndims(tv_ptr->mem_small_ds_sid),
4134                               H5Sget_simple_extent_ndims(tv_ptr->file_large_ds_sid_1));
4135 #endif /* CHECKER_BOARD_HS_DR_PIO_TEST__M2D_S2L__DEBUG */
4136                     ret = H5Dwrite(tv_ptr->large_dataset,
4137                                    H5T_NATIVE_UINT32,
4138                                    tv_ptr->mem_small_ds_sid,
4139                                    tv_ptr->file_large_ds_sid_1,
4140                                    tv_ptr->xfer_plist,
4141                                    tv_ptr->small_ds_buf_0);
4142                     VRFY((ret != FAIL),
4143                          "H5Dwrite of small ds slice to large ds succeeded");
4144 
4145 
4146                     /* read this processes slice on the on disk large
4147                      * data set into memory.
4148                      */
4149 
4150                     ret = H5Dread(tv_ptr->large_dataset,
4151                                   H5T_NATIVE_UINT32,
4152                                   tv_ptr->mem_large_ds_sid,
4153                                   tv_ptr->file_large_ds_sid_0,
4154                                   tv_ptr->xfer_plist,
4155                                   tv_ptr->large_ds_buf_1);
4156                     VRFY((ret != FAIL),
4157                          "H5Dread() of process slice of large ds succeeded");
4158 
4159 
4160                     /* verify that the expected data and only the
4161                      * expected data was read.
4162                      */
4163                     expected_value =
4164                        (uint32_t)((size_t)(tv_ptr->mpi_rank) * tv_ptr->small_ds_slice_size);
4165 
4166                     start_index = (size_t)
4167                         ((i * tv_ptr->edge_size * tv_ptr->edge_size *
4168                               tv_ptr->edge_size * tv_ptr->edge_size) +
4169                          (j * tv_ptr->edge_size * tv_ptr->edge_size * tv_ptr->edge_size) +
4170                          (k * tv_ptr->edge_size * tv_ptr->edge_size) +
4171                          (l * tv_ptr->edge_size));
4172                     stop_index = start_index + tv_ptr->small_ds_slice_size - 1;
4173 
4174                     HDassert( start_index < stop_index );
4175                     HDassert( stop_index < tv_ptr->large_ds_size );
4176 
4177 
4178                     mis_match = FALSE;
4179 
4180                     data_ok = TRUE;
4181 
4182                     ptr_1 = tv_ptr->large_ds_buf_1;
4183                     for ( u = 0; u < start_index; u++, ptr_1++ ) {
4184 
4185                         if ( *ptr_1 != 0 ) {
4186 
4187                             data_ok = FALSE;
4188                             *ptr_1 = 0;
4189                         }
4190                     }
4191 
4192                     data_ok &= ckrbrd_hs_dr_pio_test__verify_data
4193                                (
4194                                  tv_ptr->large_ds_buf_1 + start_index,
4195                                  tv_ptr->small_rank - 1,
4196                                  tv_ptr->edge_size,
4197                                  tv_ptr->checker_edge_size,
4198                                  expected_value,
4199                                  (hbool_t)TRUE
4200                                );
4201 
4202 
4203                     ptr_1 = tv_ptr->large_ds_buf_1;
4204                     for ( u = stop_index; u < tv_ptr->small_ds_size; u++, ptr_1++ ) {
4205 
4206                         if ( *ptr_1 != 0 ) {
4207 
4208                             data_ok = FALSE;
4209                             *ptr_1 = 0;
4210                         }
4211                     }
4212 
4213                     VRFY((data_ok == TRUE),
4214                          "small ds cb slice write to large ds slice data good.");
4215 
4216                     (tv_ptr->tests_run)++;
4217                 }
4218 
4219                 l++;
4220 
4221                 (tv_ptr->total_tests)++;
4222 
4223             } while ( ( tv_ptr->large_rank > 2 ) &&
4224                       ( (tv_ptr->small_rank - 1) <= 1 ) &&
4225                       ( l < tv_ptr->edge_size ) );
4226             k++;
4227         } while ( ( tv_ptr->large_rank > 3 ) &&
4228                   ( (tv_ptr->small_rank - 1) <= 2 ) &&
4229                   ( k < tv_ptr->edge_size ) );
4230         j++;
4231     } while ( ( tv_ptr->large_rank > 4 ) &&
4232               ( (tv_ptr->small_rank - 1) <= 3 ) &&
4233               ( j < tv_ptr->edge_size ) );
4234 
4235     return;
4236 
4237 } /* ckrbrd_hs_dr_pio_test__m2d_s2l() */
4238 
4239 
4240 /*-------------------------------------------------------------------------
4241  * Function:    ckrbrd_hs_dr_pio_test__run_test()
4242  *
4243  * Purpose:    Test I/O to/from checkerboard selections of hyperslabs of
4244  *        different rank in the parallel.
4245  *
4246  * Return:    void
4247  *
4248  * Programmer:    JRM -- 10/10/09
4249  *
4250  * Modifications:
4251  *
4252  *        JRM -- 9/16/10
4253  *        Added the express_test parameter.  Use it to control
4254  *        whether we set an alignment, and whether we allocate
4255  *        chunks such that no two processes will normally touch
4256  *        the same chunk.
4257  *
4258  *-------------------------------------------------------------------------
4259  */
4260 
4261 #define CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG 0
4262 
4263 static void
4264 ckrbrd_hs_dr_pio_test__run_test(const int test_num,
4265                                 const int edge_size,
4266                                 const int checker_edge_size,
4267                                 const int chunk_edge_size,
4268                                 const int small_rank,
4269                                 const int large_rank,
4270                                 const hbool_t use_collective_io,
4271                                 const hid_t dset_type,
4272                                 const int express_test,
4273                                 int * skips_ptr,
4274                                 int max_skips,
4275                                 int64_t * total_tests_ptr,
4276                                 int64_t * tests_run_ptr,
4277                                 int64_t * tests_skipped_ptr)
4278 
4279 {
4280 #if CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG
4281     const char *fcnName = "ckrbrd_hs_dr_pio_test__run_test()";
4282 #endif /* CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
4283     int        mpi_rank; /* needed by VRFY */
4284     struct hs_dr_pio_test_vars_t test_vars =
4285     {
4286         /* int           mpi_size                        = */ -1,
4287         /* int         mpi_rank                        = */ -1,
4288         /* MPI_Comm    mpi_comm                        = */ MPI_COMM_NULL,
4289         /* MPI_Inf     mpi_info                        = */ MPI_INFO_NULL,
4290         /* int         test_num                        = */ -1,
4291         /* int         edge_size                       = */ -1,
4292         /* int         checker_edge_size               = */ -1,
4293         /* int         chunk_edge_size                 = */ -1,
4294         /* int         small_rank                      = */ -1,
4295         /* int         large_rank                      = */ -1,
4296         /* hid_t       dset_type                       = */ -1,
4297         /* uint32_t  * small_ds_buf_0                  = */ NULL,
4298         /* uint32_t  * small_ds_buf_1                  = */ NULL,
4299         /* uint32_t  * small_ds_buf_2                  = */ NULL,
4300         /* uint32_t  * small_ds_slice_buf              = */ NULL,
4301         /* uint32_t  * large_ds_buf_0                  = */ NULL,
4302         /* uint32_t  * large_ds_buf_1                  = */ NULL,
4303         /* uint32_t  * large_ds_buf_2                  = */ NULL,
4304         /* uint32_t  * large_ds_slice_buf              = */ NULL,
4305         /* int         small_ds_offset                 = */ -1,
4306         /* int         large_ds_offset                 = */ -1,
4307         /* hid_t       fid                             = */ -1,  /* HDF5 file ID */
4308         /* hid_t       xfer_plist                      = */ H5P_DEFAULT,
4309         /* hid_t       full_mem_small_ds_sid           = */ -1,
4310         /* hid_t       full_file_small_ds_sid          = */ -1,
4311         /* hid_t       mem_small_ds_sid                = */ -1,
4312         /* hid_t       file_small_ds_sid_0             = */ -1,
4313         /* hid_t       file_small_ds_sid_1             = */ -1,
4314         /* hid_t       small_ds_slice_sid              = */ -1,
4315         /* hid_t       full_mem_large_ds_sid           = */ -1,
4316         /* hid_t       full_file_large_ds_sid          = */ -1,
4317         /* hid_t       mem_large_ds_sid                = */ -1,
4318         /* hid_t       file_large_ds_sid_0             = */ -1,
4319         /* hid_t       file_large_ds_sid_1             = */ -1,
4320         /* hid_t       file_large_ds_process_slice_sid = */ -1,
4321         /* hid_t       mem_large_ds_process_slice_sid  = */ -1,
4322         /* hid_t       large_ds_slice_sid              = */ -1,
4323         /* hid_t       small_dataset                   = */ -1,     /* Dataset ID */
4324         /* hid_t       large_dataset                   = */ -1,     /* Dataset ID */
4325         /* size_t      small_ds_size                   = */ 1,
4326         /* size_t      small_ds_slice_size             = */ 1,
4327         /* size_t      large_ds_size                   = */ 1,
4328         /* size_t      large_ds_slice_size             = */ 1,
4329         /* hsize_t     dims[PAR_SS_DR_MAX_RANK]        = */ {0,0,0,0,0},
4330         /* hsize_t     chunk_dims[PAR_SS_DR_MAX_RANK]  = */ {0,0,0,0,0},
4331         /* hsize_t     start[PAR_SS_DR_MAX_RANK]       = */ {0,0,0,0,0},
4332         /* hsize_t     stride[PAR_SS_DR_MAX_RANK]      = */ {0,0,0,0,0},
4333         /* hsize_t     count[PAR_SS_DR_MAX_RANK]       = */ {0,0,0,0,0},
4334         /* hsize_t     block[PAR_SS_DR_MAX_RANK]       = */ {0,0,0,0,0},
4335         /* hsize_t   * start_ptr                       = */ NULL,
4336         /* hsize_t   * stride_ptr                      = */ NULL,
4337         /* hsize_t   * count_ptr                       = */ NULL,
4338         /* hsize_t   * block_ptr                       = */ NULL,
4339         /* int            skips                           = */ 0,
4340         /* int            max_skips                       = */ 0,
4341         /* int64_t     total_tests                     = */ 0,
4342         /* int64_t     tests_run                       = */ 0,
4343         /* int64_t     tests_skipped                   = */ 0
4344     };
4345     struct hs_dr_pio_test_vars_t * tv_ptr = &test_vars;
4346 
4347     hs_dr_pio_test__setup(test_num, edge_size, checker_edge_size,
4348                           chunk_edge_size, small_rank, large_rank,
4349                           use_collective_io, dset_type, express_test,
4350                           tv_ptr);
4351 
4352 
4353     /* initialize the local copy of mpi_rank */
4354     mpi_rank = tv_ptr->mpi_rank;
4355 
4356 
4357     /* initialize skips & max_skips */
4358     tv_ptr->skips = *skips_ptr;
4359     tv_ptr->max_skips = max_skips;
4360 
4361 
4362 #if CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG
4363     if ( MAINPROCESS ) {
4364         HDfprintf(stdout, "test %d: small rank = %d, large rank = %d.\n",
4365                   test_num, small_rank, large_rank);
4366         HDfprintf(stdout, "test %d: Initialization complete.\n", test_num);
4367     }
4368 #endif /* CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
4369 
4370 
4371     /* first, verify that we can read from disk correctly using selections
4372      * of different rank that H5S_select_shape_same() views as being of the
4373      * same shape.
4374      *
4375      * Start by reading a (small_rank - 1)-D slice from this processes slice
4376      * of the on disk large data set, and verifying that the data read is
4377      * correct.  Verify that H5S_select_shape_same() returns true on the
4378      * memory and file selections.
4379      *
4380      * The first step is to set up the needed checker board selection in the
4381      * in memory small small cube
4382      */
4383 
4384     ckrbrd_hs_dr_pio_test__d2m_l2s(tv_ptr);
4385 
4386 
4387     /* similarly, read slices of the on disk small data set into slices
4388      * through the in memory large data set, and verify that the correct
4389      * data (and only the correct data) is read.
4390      */
4391 
4392     ckrbrd_hs_dr_pio_test__d2m_s2l(tv_ptr);
4393 
4394 
4395     /* now we go in the opposite direction, verifying that we can write
4396      * from memory to file using selections of different rank that
4397      * H5S_select_shape_same() views as being of the same shape.
4398      *
4399      * Start by writing small_rank - 1 D slices from the in memory large data
4400      * set to the on disk small dataset.  After each write, read the slice of
4401      * the small dataset back from disk, and verify that it contains the
4402      * expected data. Verify that H5S_select_shape_same() returns true on
4403      * the memory and file selections.
4404      */
4405 
4406     ckrbrd_hs_dr_pio_test__m2d_l2s(tv_ptr);
4407 
4408 
4409     /* Now write the contents of the process's slice of the in memory
4410      * small data set to slices of the on disk large data set.  After
4411      * each write, read the process's slice of the large data set back
4412      * into memory, and verify that it contains the expected data.
4413      * Verify that H5S_select_shape_same() returns true on the memory
4414      * and file selections.
4415      */
4416 
4417     ckrbrd_hs_dr_pio_test__m2d_s2l(tv_ptr);
4418 
4419 
4420 #if CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG
4421     if ( MAINPROCESS ) {
4422         HDfprintf(stdout,
4423             "test %d: Subtests complete -- tests run/skipped/total = %lld/%lld/%lld.\n",
4424              test_num, (long long)(tv_ptr->tests_run), (long long)(tv_ptr->tests_skipped),
4425              (long long)(tv_ptr->total_tests));
4426     }
4427 #endif /* CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
4428 
4429     hs_dr_pio_test__takedown(tv_ptr);
4430 
4431 #if CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG
4432     if ( MAINPROCESS ) {
4433         HDfprintf(stdout, "test %d: Takedown complete.\n", test_num);
4434     }
4435 #endif /* CKRBRD_HS_DR_PIO_TEST__RUN_TEST__DEBUG */
4436 
4437     *skips_ptr = tv_ptr->skips;
4438     *total_tests_ptr += tv_ptr->total_tests;
4439     *tests_run_ptr += tv_ptr->tests_run;
4440     *tests_skipped_ptr += tv_ptr->tests_skipped;
4441 
4442     return;
4443 
4444 } /* ckrbrd_hs_dr_pio_test__run_test() */
4445 
4446 
4447 /*-------------------------------------------------------------------------
4448  * Function:    ckrbrd_hs_dr_pio_test()
4449  *
4450  * Purpose:    Test I/O to/from hyperslab selections of different rank in
4451  *        the parallel case.
4452  *
4453  * Return:    void
4454  *
4455  * Programmer:    JRM -- 9/18/09
4456  *
4457  * Modifications:
4458  *
4459  *          Modified function to take a sample of the run times
4460  *        of the different tests, and skip some of them if
4461  *        run times are too long.
4462  *
4463  *        We need to do this because Lustre runns very slowly
4464  *        if two or more processes are banging on the same
4465  *        block of memory.
4466  *                        JRM -- 9/10/10
4467  *          Break this one big test into 4 smaller tests according
4468  *          to {independent,collective}x{contigous,chunked} datasets.
4469  *        AKC -- 2010/01/17
4470  *
4471  *-------------------------------------------------------------------------
4472  */
4473 
4474 static void
4475 ckrbrd_hs_dr_pio_test(ShapeSameTestMethods sstest_type)
4476 {
4477     int         express_test;
4478     int         local_express_test;
4479     int            mpi_size = -1;
4480     int         mpi_rank = -1;
4481     int            test_num = 0;
4482     int        edge_size;
4483     int         checker_edge_size = 3;
4484     int        chunk_edge_size = 0;
4485     int            small_rank = 3;
4486     int            large_rank = 4;
4487     int        mpi_result;
4488     hid_t    dset_type = H5T_NATIVE_UINT;
4489     int         skips = 0;
4490     int         max_skips = 0;
4491     /* The following table list the number of sub-tests skipped between
4492      * each test that is actually executed as a function of the express
4493      * test level.  Note that any value in excess of 4880 will cause all
4494      * sub tests to be skipped.
4495      */
4496     int         max_skips_tbl[4] = {0, 4, 64, 1024};
4497     int64_t     total_tests = 0;
4498     int64_t     tests_run = 0;
4499     int64_t     tests_skipped = 0;
4500 
4501     MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
4502     MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
4503 
4504     edge_size = (mpi_size > 6 ? mpi_size : 6);
4505 
4506     local_express_test = GetTestExpress();
4507 
4508     HDcompile_assert(sizeof(uint32_t) == sizeof(unsigned));
4509 
4510     mpi_result = MPI_Allreduce((void *)&local_express_test,
4511                                (void *)&express_test,
4512                                1,
4513                                MPI_INT,
4514                                MPI_MAX,
4515                                MPI_COMM_WORLD);
4516 
4517     VRFY((mpi_result == MPI_SUCCESS ), "MPI_Allreduce(0) succeeded");
4518 
4519     if ( local_express_test < 0 ) {
4520         max_skips = max_skips_tbl[0];
4521     } else if ( local_express_test > 3 ) {
4522         max_skips = max_skips_tbl[3];
4523     } else {
4524         max_skips = max_skips_tbl[local_express_test];
4525     }
4526 
4527 #if 0
4528     {
4529         int DebugWait = 1;
4530 
4531         while (DebugWait) ;
4532     }
4533 #endif
4534 
4535     for ( large_rank = 3; large_rank <= PAR_SS_DR_MAX_RANK; large_rank++ ) {
4536 
4537         for ( small_rank = 2; small_rank < large_rank; small_rank++ ) {
4538             switch(sstest_type){
4539                 case IND_CONTIG:
4540                     /* contiguous data set, independent I/O */
4541                     chunk_edge_size = 0;
4542                     ckrbrd_hs_dr_pio_test__run_test(test_num,
4543                                                     edge_size,
4544                                                     checker_edge_size,
4545                                                     chunk_edge_size,
4546                                                     small_rank,
4547                                                     large_rank,
4548                                                     FALSE,
4549                                                     dset_type,
4550                                                     express_test,
4551                                                     &skips,
4552                                                     max_skips,
4553                                                     &total_tests,
4554                                                     &tests_run,
4555                                                     &tests_skipped);
4556                     test_num++;
4557                     break;
4558                     /* end of case IND_CONTIG */
4559 
4560                  case COL_CONTIG:
4561                     /* contiguous data set, collective I/O */
4562                     chunk_edge_size = 0;
4563                     ckrbrd_hs_dr_pio_test__run_test(test_num,
4564                                                     edge_size,
4565                                                     checker_edge_size,
4566                                                     chunk_edge_size,
4567                                                     small_rank,
4568                                                     large_rank,
4569                                                     TRUE,
4570                                                     dset_type,
4571                                                     express_test,
4572                                                     &skips,
4573                                                     max_skips,
4574                                                     &total_tests,
4575                                                     &tests_run,
4576                                                     &tests_skipped);
4577                     test_num++;
4578                     break;
4579                     /* end of case COL_CONTIG */
4580 
4581                 case IND_CHUNKED:
4582                     /* chunked data set, independent I/O */
4583                     chunk_edge_size = 5;
4584                     ckrbrd_hs_dr_pio_test__run_test(test_num,
4585                                                     edge_size,
4586                                                     checker_edge_size,
4587                                                     chunk_edge_size,
4588                                                     small_rank,
4589                                                     large_rank,
4590                                                     FALSE,
4591                                                     dset_type,
4592                                                     express_test,
4593                                                     &skips,
4594                                                     max_skips,
4595                                                     &total_tests,
4596                                                     &tests_run,
4597                                                     &tests_skipped);
4598                     test_num++;
4599                     break;
4600                     /* end of case IND_CHUNKED */
4601 
4602                 case COL_CHUNKED:
4603                     /* chunked data set, collective I/O */
4604                     chunk_edge_size = 5;
4605                     ckrbrd_hs_dr_pio_test__run_test(test_num,
4606                                                     edge_size,
4607                                                     checker_edge_size,
4608                                                     chunk_edge_size,
4609                                                     small_rank,
4610                                                     large_rank,
4611                                                     TRUE,
4612                                                     dset_type,
4613                                                     express_test,
4614                                                     &skips,
4615                                                     max_skips,
4616                                                     &total_tests,
4617                                                     &tests_run,
4618                                                     &tests_skipped);
4619                     test_num++;
4620                     break;
4621                     /* end of case COL_CHUNKED */
4622 
4623                 default:
4624                     VRFY((FALSE), "unknown test type");
4625                     break;
4626 
4627             } /* end of switch(sstest_type) */
4628 #if CONTIG_HS_DR_PIO_TEST__DEBUG
4629             if ( ( MAINPROCESS ) && ( tests_skipped > 0 ) ) {
4630                 HDfprintf(stdout, "     run/skipped/total = %lld/%lld/%lld.\n",
4631                           tests_run, tests_skipped, total_tests);
4632             }
4633 #endif /* CONTIG_HS_DR_PIO_TEST__DEBUG */
4634         }
4635     }
4636 
4637     if ( ( MAINPROCESS ) && ( tests_skipped > 0 ) ) {
4638         HDfprintf(stdout, "     %lld of %lld subtests skipped to expedite testing.\n",
4639                   tests_skipped, total_tests);
4640     }
4641 
4642     return;
4643 
4644 } /* ckrbrd_hs_dr_pio_test() */
4645 
4646 /* Main Body. Here for now, may have to move them to a separated file later. */
4647 
4648 /*
4649  * Main driver of the Parallel HDF5 tests
4650  */
4651 
4652 #include "testphdf5.h"
4653 
4654 #ifndef PATH_MAX
4655 #define PATH_MAX    512
4656 #endif  /* !PATH_MAX */
4657 
4658 /* global variables */
4659 int dim0;
4660 int dim1;
4661 int chunkdim0;
4662 int chunkdim1;
4663 int nerrors = 0;            /* errors count */
4664 int ndatasets = 300;            /* number of datasets to create*/
4665 int ngroups = 512;                      /* number of groups to create in root
4666                                          * group. */
4667 int facc_type = FACC_MPIO;        /*Test file access type */
4668 int dxfer_coll_type = DXFER_COLLECTIVE_IO;
4669 
4670 H5E_auto2_t old_func;                /* previous error handler */
4671 void *old_client_data;            /* previous error handler arg.*/
4672 
4673 /* other option flags */
4674 
4675 /* FILENAME and filenames must have the same number of names.
4676  * Use PARATESTFILE in general and use a separated filename only if the file
4677  * created in one test is accessed by a different test.
4678  * filenames[0] is reserved as the file name for PARATESTFILE.
4679  */
4680 #define NFILENAME 2
4681 #define PARATESTFILE filenames[0]
4682 const char *FILENAME[NFILENAME]={
4683         "ShapeSameTest",
4684         NULL};
4685 char    filenames[NFILENAME][PATH_MAX];
4686 hid_t    fapl;                /* file access property list */
4687 
4688 #ifdef USE_PAUSE
4689 /* pause the process for a moment to allow debugger to attach if desired. */
4690 /* Will pause more if greenlight file is not persent but will eventually */
4691 /* continue. */
4692 #include <sys/types.h>
4693 #include <sys/stat.h>
4694 
4695 void pause_proc(void)
4696 {
4697 
4698     int pid;
4699     h5_stat_t    statbuf;
4700     char greenlight[] = "go";
4701     int maxloop = 10;
4702     int loops = 0;
4703     int time_int = 10;
4704 
4705     /* mpi variables */
4706     int  mpi_size, mpi_rank;
4707     int  mpi_namelen;
4708     char mpi_name[MPI_MAX_PROCESSOR_NAME];
4709 
4710     pid = getpid();
4711     MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
4712     MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
4713     MPI_Get_processor_name(mpi_name, &mpi_namelen);
4714 
4715     if (MAINPROCESS)
4716     while ((HDstat(greenlight, &statbuf) == -1) && loops < maxloop){
4717         if (!loops++){
4718         HDprintf("Proc %d (%*s, %d): to debug, attach %d\n",
4719             mpi_rank, mpi_namelen, mpi_name, pid, pid);
4720         }
4721         HDprintf("waiting(%ds) for file %s ...\n", time_int, greenlight);
4722         fflush(stdout);
4723             HDsleep(time_int);
4724     }
4725     MPI_Barrier(MPI_COMM_WORLD);
4726 }
4727 
4728 /* Use the Profile feature of MPI to call the pause_proc() */
4729 int MPI_Init(int *argc, char ***argv)
4730 {
4731     int ret_code;
4732     ret_code=PMPI_Init(argc, argv);
4733     pause_proc();
4734     return (ret_code);
4735 }
4736 #endif    /* USE_PAUSE */
4737 
4738 
4739 /*
4740  * Show command usage
4741  */
4742 static void
4743 usage(void)
4744 {
4745     HDprintf("    [-r] [-w] [-m<n_datasets>] [-n<n_groups>] "
4746     "[-o] [-f <prefix>] [-d <dim0> <dim1>]\n");
4747     HDprintf("\t-m<n_datasets>"
4748     "\tset number of datasets for the multiple dataset test\n");
4749     HDprintf("\t-n<n_groups>"
4750         "\tset number of groups for the multiple group test\n");
4751     HDprintf("\t-f <prefix>\tfilename prefix\n");
4752     HDprintf("\t-2\t\tuse Split-file together with MPIO\n");
4753     HDprintf("\t-d <factor0> <factor1>\tdataset dimensions factors. Defaults (%d,%d)\n",
4754     ROW_FACTOR, COL_FACTOR);
4755     HDprintf("\t-c <dim0> <dim1>\tdataset chunk dimensions. Defaults (dim0/10,dim1/10)\n");
4756     HDprintf("\n");
4757 }
4758 
4759 
4760 /*
4761  * parse the command line options
4762  */
4763 static int
4764 parse_options(int argc, char **argv)
4765 {
4766     int mpi_size, mpi_rank;                /* mpi variables */
4767 
4768     MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
4769     MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
4770 
4771     /* setup default chunk-size. Make sure sizes are > 0 */
4772 
4773     chunkdim0 = (dim0+9)/10;
4774     chunkdim1 = (dim1+9)/10;
4775 
4776     while (--argc){
4777     if (**(++argv) != '-'){
4778         break;
4779     }else{
4780         switch(*(*argv+1)){
4781         case 'm':   ndatasets = atoi((*argv+1)+1);
4782                 if (ndatasets < 0){
4783                 nerrors++;
4784                 return(1);
4785                 }
4786                 break;
4787             case 'n':   ngroups = atoi((*argv+1)+1);
4788                     if (ngroups < 0){
4789                                 nerrors++;
4790                                 return(1);
4791                 }
4792                             break;
4793         case 'f':   if (--argc < 1) {
4794                 nerrors++;
4795                 return(1);
4796                 }
4797                 if (**(++argv) == '-') {
4798                 nerrors++;
4799                 return(1);
4800                 }
4801                 paraprefix = *argv;
4802                 break;
4803         case 'i':   /* Collective MPI-IO access with independent IO  */
4804                 dxfer_coll_type = DXFER_INDEPENDENT_IO;
4805                 break;
4806         case '2':   /* Use the split-file driver with MPIO access */
4807                 /* Can use $HDF5_METAPREFIX to define the */
4808                 /* meta-file-prefix. */
4809                 facc_type = FACC_MPIO | FACC_SPLIT;
4810                 break;
4811         case 'd':   /* dimensizes */
4812                 if (--argc < 2){
4813                 nerrors++;
4814                 return(1);
4815                 }
4816                 dim0 = atoi(*(++argv))*mpi_size;
4817                 argc--;
4818                 dim1 = atoi(*(++argv))*mpi_size;
4819                 /* set default chunkdim sizes too */
4820                 chunkdim0 = (dim0+9)/10;
4821                 chunkdim1 = (dim1+9)/10;
4822                 break;
4823         case 'c':   /* chunk dimensions */
4824                 if (--argc < 2){
4825                 nerrors++;
4826                 return(1);
4827                 }
4828                 chunkdim0 = atoi(*(++argv));
4829                 argc--;
4830                 chunkdim1 = atoi(*(++argv));
4831                 break;
4832         case 'h':   /* print help message--return with nerrors set */
4833                 return(1);
4834         default:    HDprintf("Illegal option(%s)\n", *argv);
4835                 nerrors++;
4836                 return(1);
4837         }
4838     }
4839     } /*while*/
4840 
4841     /* check validity of dimension and chunk sizes */
4842     if (dim0 <= 0 || dim1 <= 0){
4843     HDprintf("Illegal dim sizes (%d, %d)\n", dim0, dim1);
4844     nerrors++;
4845     return(1);
4846     }
4847     if (chunkdim0 <= 0 || chunkdim1 <= 0){
4848     HDprintf("Illegal chunkdim sizes (%d, %d)\n", chunkdim0, chunkdim1);
4849     nerrors++;
4850     return(1);
4851     }
4852 
4853     /* Make sure datasets can be divided into equal portions by the processes */
4854     if ((dim0 % mpi_size) || (dim1 % mpi_size)){
4855     if (MAINPROCESS)
4856         HDprintf("dim0(%d) and dim1(%d) must be multiples of processes(%d)\n",
4857             dim0, dim1, mpi_size);
4858     nerrors++;
4859     return(1);
4860     }
4861 
4862     /* compose the test filenames */
4863     {
4864     int i, n;
4865 
4866     n = sizeof(FILENAME)/sizeof(FILENAME[0]) - 1;    /* exclude the NULL */
4867 
4868     for (i=0; i < n; i++)
4869         if (h5_fixname(FILENAME[i],fapl,filenames[i],sizeof(filenames[i]))
4870         == NULL){
4871         HDprintf("h5_fixname failed\n");
4872         nerrors++;
4873         return(1);
4874         }
4875     HDprintf("Test filenames are:\n");
4876     for (i=0; i < n; i++)
4877         HDprintf("    %s\n", filenames[i]);
4878     }
4879 
4880     return(0);
4881 }
4882 
4883 
4884 /*
4885  * Create the appropriate File access property list
4886  */
4887 hid_t
4888 create_faccess_plist(MPI_Comm comm, MPI_Info info, int l_facc_type)
4889 {
4890     hid_t ret_pl = -1;
4891     herr_t ret;                 /* generic return value */
4892     int mpi_rank;        /* mpi variables */
4893 
4894     /* need the rank for error checking macros */
4895     MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
4896 
4897     ret_pl = H5Pcreate (H5P_FILE_ACCESS);
4898     VRFY((ret_pl >= 0), "H5P_FILE_ACCESS");
4899 
4900     if (l_facc_type == FACC_DEFAULT)
4901     return (ret_pl);
4902 
4903     if (l_facc_type == FACC_MPIO){
4904     /* set Parallel access with communicator */
4905     ret = H5Pset_fapl_mpio(ret_pl, comm, info);
4906     VRFY((ret >= 0), "");
4907         ret = H5Pset_all_coll_metadata_ops(ret_pl, TRUE);
4908     VRFY((ret >= 0), "");
4909         ret = H5Pset_coll_metadata_write(ret_pl, TRUE);
4910     VRFY((ret >= 0), "");
4911     return(ret_pl);
4912     }
4913 
4914     if (l_facc_type == (FACC_MPIO | FACC_SPLIT)){
4915     hid_t mpio_pl;
4916 
4917     mpio_pl = H5Pcreate (H5P_FILE_ACCESS);
4918     VRFY((mpio_pl >= 0), "");
4919     /* set Parallel access with communicator */
4920     ret = H5Pset_fapl_mpio(mpio_pl, comm, info);
4921     VRFY((ret >= 0), "");
4922 
4923     /* setup file access template */
4924     ret_pl = H5Pcreate (H5P_FILE_ACCESS);
4925     VRFY((ret_pl >= 0), "");
4926     /* set Parallel access with communicator */
4927     ret = H5Pset_fapl_split(ret_pl, ".meta", mpio_pl, ".raw", mpio_pl);
4928     VRFY((ret >= 0), "H5Pset_fapl_split succeeded");
4929     H5Pclose(mpio_pl);
4930     return(ret_pl);
4931     }
4932 
4933     /* unknown file access types */
4934     return (ret_pl);
4935 }
4936 
4937 
4938 /* Shape Same test using contigous hyperslab using independent IO on contigous datasets */
4939 static void
4940 sscontig1(void)
4941 {
4942     contig_hs_dr_pio_test(IND_CONTIG);
4943 }
4944 
4945 /* Shape Same test using contigous hyperslab using collective IO on contigous datasets */
4946 static void
4947 sscontig2(void)
4948 {
4949     contig_hs_dr_pio_test(COL_CONTIG);
4950 }
4951 
4952 /* Shape Same test using contigous hyperslab using independent IO on chunked datasets */
4953 static void
4954 sscontig3(void)
4955 {
4956     contig_hs_dr_pio_test(IND_CHUNKED);
4957 }
4958 
4959 /* Shape Same test using contigous hyperslab using collective IO on chunked datasets */
4960 static void
4961 sscontig4(void)
4962 {
4963     contig_hs_dr_pio_test(COL_CHUNKED);
4964 }
4965 
4966 
4967 /* Shape Same test using checker hyperslab using independent IO on contigous datasets */
4968 static void
4969 sschecker1(void)
4970 {
4971     ckrbrd_hs_dr_pio_test(IND_CONTIG);
4972 }
4973 
4974 /* Shape Same test using checker hyperslab using collective IO on contigous datasets */
4975 static void
4976 sschecker2(void)
4977 {
4978     ckrbrd_hs_dr_pio_test(COL_CONTIG);
4979 }
4980 
4981 /* Shape Same test using checker hyperslab using independent IO on chunked datasets */
4982 static void
4983 sschecker3(void)
4984 {
4985     ckrbrd_hs_dr_pio_test(IND_CHUNKED);
4986 }
4987 
4988 /* Shape Same test using checker hyperslab using collective IO on chunked datasets */
4989 static void
4990 sschecker4(void)
4991 {
4992     ckrbrd_hs_dr_pio_test(COL_CHUNKED);
4993 }
4994 
4995 
4996 int main(int argc, char **argv)
4997 {
4998     int mpi_size, mpi_rank;                /* mpi variables */
4999 
5000 #ifndef H5_HAVE_WIN32_API
5001     /* Un-buffer the stdout and stderr */
5002     HDsetbuf(stderr, NULL);
5003     HDsetbuf(stdout, NULL);
5004 #endif
5005 
5006     MPI_Init(&argc, &argv);
5007     MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
5008     MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
5009 
5010     dim0 = ROW_FACTOR*mpi_size;
5011     dim1 = COL_FACTOR*mpi_size;
5012 
5013     if (MAINPROCESS){
5014     HDprintf("===================================\n");
5015     HDprintf("Shape Same Tests Start\n");
5016         HDprintf("    express_test = %d.\n", GetTestExpress());
5017     HDprintf("===================================\n");
5018     }
5019 
5020     /* Attempt to turn off atexit post processing so that in case errors
5021      * happen during the test and the process is aborted, it will not get
5022      * hang in the atexit post processing in which it may try to make MPI
5023      * calls.  By then, MPI calls may not work.
5024      */
5025     if (H5dont_atexit() < 0){
5026     HDprintf("%d: Failed to turn off atexit processing. Continue.\n", mpi_rank);
5027     };
5028     H5open();
5029     h5_show_hostname();
5030 
5031     /* Initialize testing framework */
5032     TestInit(argv[0], usage, parse_options);
5033 
5034     /* Shape Same tests using contigous hyperslab */
5035     AddTest("sscontig1", sscontig1, NULL,
5036     "Cntg hslab, ind IO, cntg dsets", PARATESTFILE);
5037     AddTest("sscontig2", sscontig2, NULL,
5038     "Cntg hslab, col IO, cntg dsets", PARATESTFILE);
5039     AddTest("sscontig3", sscontig3, NULL,
5040     "Cntg hslab, ind IO, chnk dsets", PARATESTFILE);
5041     AddTest("sscontig4", sscontig4, NULL,
5042     "Cntg hslab, col IO, chnk dsets", PARATESTFILE);
5043 
5044     /* Shape Same tests using checker board hyperslab */
5045     AddTest("sschecker1", sschecker1, NULL,
5046     "Check hslab, ind IO, cntg dsets", PARATESTFILE);
5047     AddTest("sschecker2", sschecker2, NULL,
5048     "Check hslab, col IO, cntg dsets", PARATESTFILE);
5049     AddTest("sschecker3", sschecker3, NULL,
5050     "Check hslab, ind IO, chnk dsets", PARATESTFILE);
5051     AddTest("sschecker4", sschecker4, NULL,
5052     "Check hslab, col IO, chnk dsets", PARATESTFILE);
5053 
5054     /* Display testing information */
5055     TestInfo(argv[0]);
5056 
5057     /* setup file access property list */
5058     fapl = H5Pcreate (H5P_FILE_ACCESS);
5059     H5Pset_fapl_mpio(fapl, MPI_COMM_WORLD, MPI_INFO_NULL);
5060 
5061     /* Parse command line arguments */
5062     TestParseCmdLine(argc, argv);
5063 
5064     if (dxfer_coll_type == DXFER_INDEPENDENT_IO && MAINPROCESS){
5065     HDprintf("===================================\n"
5066         "   Using Independent I/O with file set view to replace collective I/O \n"
5067         "===================================\n");
5068     }
5069 
5070 
5071     /* Perform requested testing */
5072     PerformTests();
5073 
5074     /* make sure all processes are finished before final report, cleanup
5075      * and exit.
5076      */
5077     MPI_Barrier(MPI_COMM_WORLD);
5078 
5079     /* Display test summary, if requested */
5080     if (MAINPROCESS && GetTestSummary())
5081         TestSummary();
5082 
5083     /* Clean up test files */
5084     h5_clean_files(FILENAME, fapl);
5085 
5086     nerrors += GetTestNumErrs();
5087 
5088     /* Gather errors from all processes */
5089     {
5090         int temp;
5091         MPI_Allreduce(&nerrors, &temp, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
5092     nerrors=temp;
5093     }
5094 
5095     if (MAINPROCESS){        /* only process 0 reports */
5096     HDprintf("===================================\n");
5097     if (nerrors)
5098         HDprintf("***Shape Same tests detected %d errors***\n", nerrors);
5099     else
5100         HDprintf("Shape Same tests finished with no errors\n");
5101     HDprintf("===================================\n");
5102     }
5103 
5104     /* close HDF5 library */
5105     H5close();
5106 
5107     /* Release test infrastructure */
5108     TestShutdown();
5109 
5110     MPI_Finalize();
5111 
5112     /* cannot just return (nerrors) because exit code is limited to 1byte */
5113     return(nerrors!=0);
5114 }
5115 
5116