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