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