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