h5_file.c 21.4 KB
Newer Older
1
/*
gsell's avatar
gsell committed
2
  Copyright (c) 2006-2016, The Regents of the University of California,
3 4 5 6 7 8 9 10 11 12
  through Lawrence Berkeley National Laboratory (subject to receipt of any
  required approvals from the U.S. Dept. of Energy) and the Paul Scherrer
  Institut (Switzerland).  All rights reserved.

  License: see file COPYING in top level of source distribution.
*/

#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
gsell's avatar
gsell committed
13
#include <string.h>
14

15
#include "h5core/h5_log.h"
16

17
#include "private/h5_file.h"
gsell's avatar
gsell committed
18
#include "private/h5_hdf5.h"
19

gsell's avatar
gsell committed
20 21 22 23
#include "private/h5_model.h"
#include "private/h5_mpi.h"
#include "private/h5u_io.h"
#include "private/h5b_io.h"
24

25
#include "h5core/h5_err.h"
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
#include "h5core/h5_syscall.h"

/*!
  \ingroup h5_core
  \defgroup h5_core_filehandling
*/

/*!
  \ingroup h5_core_filehandling

  Check whether \c f points to a valid file handle.

  \return	H5_SUCCESS or error code
*/
h5_err_t
h5_check_filehandle (
	const h5_file_t f_               /*!< filehandle  to check validity of */
	) {
        h5_file_p f = (h5_file_p)f_;
Gsell Achim's avatar
* C-API  
Gsell Achim committed
45
	return is_valid_file_handle (f) ? H5_SUCCESS : H5_ERR;
46 47
}

gsell's avatar
gsell committed
48 49 50 51 52 53
hid_t
h5_get_hdf5_file(
	const h5_file_t f_		/*!< file handle		*/
	) {
        h5_file_p f = (h5_file_p)f_;
	H5_CORE_API_ENTER (hid_t, "f=%p", f);
Gsell Achim's avatar
* C-API  
Gsell Achim committed
54
	check_file_handle_is_valid (f);
gsell's avatar
gsell committed
55
	H5_RETURN (f->file);
gsell's avatar
gsell committed
56 57
}

58
/*!
59
  Initialize H5hut
60 61 62 63
*/
static herr_t
hdf5_error_handler (
	hid_t estack_id,
gsell's avatar
gsell committed
64
	void*  __f
65 66
	) {
	UNUSED_ARGUMENT (__f);
Gsell Achim's avatar
* C-API  
Gsell Achim committed
67
	if (h5_get_loglevel() >= 4) {
68 69 70 71 72 73 74 75 76 77
		H5Eprint (estack_id, stderr);
	}
	return 0;
}

static inline h5_err_t
mpi_init (
	const h5_file_p f
	) {
	H5_INLINE_FUNC_ENTER (h5_err_t);
78
#ifdef H5_HAVE_PARALLEL
79 80 81 82 83 84 85 86 87
	TRY (h5priv_mpi_comm_size (f->props->comm, &f->nprocs));
	TRY (h5priv_mpi_comm_rank (f->props->comm, &f->myproc));
	
	/* xfer_prop:  also used for parallel I/O, during actual writes
	   rather than the access_prop which is for file creation. */
	TRY (f->props->xfer_prop = hdf5_create_property(H5P_DATASET_XFER));
	TRY (f->props->access_prop = hdf5_create_property(H5P_FILE_ACCESS));

	/* select the HDF5 VFD */
gsell's avatar
gsell committed
88
#if H5_VERSION_LE(1,8,12)
89
	if ((f->props->flags & H5_VFD_MPIO_POSIX)) {
90 91 92 93 94
		h5_info("Selecting MPI-POSIX VFD");
		hbool_t use_gpfs = 0; // TODO autodetect GPFS?
		TRY (hdf5_set_fapl_mpiposix_property (f->props->access_prop,
                                                     f->props->comm, use_gpfs));

95
        } else if ((f->props->flags & H5_VFD_CORE)) {
96 97 98
		h5_info("Selecting CORE VFD");
                TRY (hdf5_set_fapl_core (f->props->access_prop,
                                         f->props->align, 1));
gsell's avatar
gsell committed
99
        } else if ((f->props->flags & H5_VFD_MPIO_INDEPENDENT)){
100
                h5_info("Selecting MPI-IO VFD, using independent mode");
101 102
		TRY (hdf5_set_fapl_mpio_property (f->props->access_prop,
                                                  f->props->comm, MPI_INFO_NULL));
103 104 105
                TRY (hdf5_set_dxpl_mpio_property (f->props->xfer_prop,
                                                  H5FD_MPIO_INDEPENDENT) );
        } else {
106
                // default is MPI-IO collective mode
107 108 109 110 111
		h5_info("Selecting MPI-IO VFD, using collective mode");
		TRY (hdf5_set_fapl_mpio_property (f->props->access_prop,
                                                  f->props->comm, MPI_INFO_NULL));
                TRY (hdf5_set_dxpl_mpio_property (f->props->xfer_prop,
                                                  H5FD_MPIO_COLLECTIVE) );
112
	}
gsell's avatar
gsell committed
113 114 115 116 117 118 119 120 121 122 123 124 125
#else
	// VFD_MPIO_POSIX has been removed in HDF5 1.8.13
        if ((f->props->flags & H5_VFD_CORE)) {
		h5_info("Selecting CORE VFD");
                TRY (hdf5_set_fapl_core (f->props->access_prop,
                                         f->props->align, 1));
        } else if ((f->props->flags & H5_VFD_MPIO_INDEPENDENT)){
                h5_info("Selecting MPI-IO VFD, using independent mode");
		TRY (hdf5_set_fapl_mpio_property (f->props->access_prop,
                                                  f->props->comm, MPI_INFO_NULL));
                TRY (hdf5_set_dxpl_mpio_property (f->props->xfer_prop,
                                                  H5FD_MPIO_INDEPENDENT) );
        } else {
126
                // default is MPI-IO collective mode
gsell's avatar
gsell committed
127 128 129 130 131 132 133
		h5_info("Selecting MPI-IO VFD, using collective mode");
		TRY (hdf5_set_fapl_mpio_property (f->props->access_prop,
                                                  f->props->comm, MPI_INFO_NULL));
                TRY (hdf5_set_dxpl_mpio_property (f->props->xfer_prop,
                                                  H5FD_MPIO_COLLECTIVE) );
	}
#endif
134 135 136 137 138
#ifdef H5_USE_LUSTRE
	if (f->flags & H5_FS_LUSTRE) {
		TRY (h5_optimize_for_lustre(f, filename));
	}
#endif
139
#endif /* H5_HAVE_PARALLEL */
gsell's avatar
gsell committed
140
	H5_RETURN (H5_SUCCESS);
141 142 143 144 145 146 147 148
}

static inline h5_err_t
set_alignment (
	const h5_file_p f
	) {
	H5_INLINE_FUNC_ENTER (h5_err_t);
	if ( f->props->align != 0 ) {
gsell's avatar
gsell committed
149 150 151 152
		h5_info (
			"Setting HDF5 alignment to %lld bytes "
			"with threshold at half that many bytes.",
			(long long int)f->props->align);
153 154 155 156
		TRY (hdf5_set_alignment_property (
                             f->props->access_prop,
                             f->props->align / 2,
                             f->props->align));
gsell's avatar
gsell committed
157 158 159
		h5_info (
			"Setting HDF5 meta block to %lld bytes",
			(long long int)f->props->align);
160 161
		TRY (H5Pset_meta_block_size (f->props->access_prop, f->props->align));
	}
gsell's avatar
gsell committed
162
	H5_RETURN (H5_SUCCESS);
163 164 165 166
}

static inline h5_err_t
set_default_file_props (
gsell's avatar
gsell committed
167
        h5_prop_file_t* const _props
168 169
        ) {
        H5_INLINE_FUNC_ENTER (h5_err_t);
gsell's avatar
gsell committed
170
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
gsell's avatar
gsell committed
171
        bzero (props, sizeof (*props));
172
        props->class = H5_PROP_FILE;
Gsell Achim's avatar
* C-API  
Gsell Achim committed
173
        TRY (props->prefix_iteration_name = h5_calloc (1, H5_ITERATION_NAME_LEN));
174
        strncpy (
Gsell Achim's avatar
* C-API  
Gsell Achim committed
175 176 177 178
                props->prefix_iteration_name,
                H5_ITERATION_NAME,
                H5_ITERATION_NAME_LEN - 1);
        props->width_iteration_idx = H5_ITERATION_NUM_WIDTH;
179
#ifdef H5_HAVE_PARALLEL
180
        props->comm = MPI_COMM_WORLD;
181
#endif
gsell's avatar
gsell committed
182
        H5_RETURN (H5_SUCCESS);
183 184 185
}

h5_err_t
186 187
h5_set_prop_file_mpio_collective (
        h5_prop_t _props,
188 189
        MPI_Comm* comm
        ) {
gsell's avatar
gsell committed
190
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
191
        H5_CORE_API_ENTER (h5_err_t, "props=%p, comm=%p", props, comm);
192
        
193
        if (props->class != H5_PROP_FILE) {
194 195 196 197
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
198
        }
199
#ifdef H5_HAVE_PARALLEL
200 201 202
        props->flags &= ~(H5_VFD_MPIO_POSIX | H5_VFD_MPIO_INDEPENDENT | H5_VFD_CORE);
        props->flags |= H5_VFD_MPIO_COLLECTIVE;
        props->comm = *comm;
203 204 205 206
	if (props->throttle > 0) {
		h5_warn ("Throttling is not permitted with collective VFD. Reset throttling.");
		props->throttle = 0;
	}
207 208 209
#else
	h5_info ("Setting MPIO collective property ignored in serial H5hut");
#endif
gsell's avatar
gsell committed
210
        H5_RETURN (H5_SUCCESS);
211 212 213 214 215 216 217
}

h5_err_t
h5_set_prop_file_mpio_independent (
        h5_prop_t _props,
        MPI_Comm* comm
        ) {
gsell's avatar
gsell committed
218
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
219 220 221
        H5_CORE_API_ENTER (h5_err_t, "props=%p, comm=%p", props, comm);
        
        if (props->class != H5_PROP_FILE) {
222 223 224 225
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
226
        }
227
#ifdef H5_HAVE_PARALLEL
228 229 230
        props->flags &= ~(H5_VFD_MPIO_COLLECTIVE | H5_VFD_MPIO_POSIX | H5_VFD_CORE);
        props->flags |= H5_VFD_MPIO_INDEPENDENT;
        props->comm = *comm;
231 232 233
#else
	h5_info ("Setting MPIO independent property ignored in serial H5hut");
#endif
gsell's avatar
gsell committed
234
        H5_RETURN (H5_SUCCESS);
235 236
}

237
#if H5_VERSION_LE(1,8,12)
238 239 240 241 242
h5_err_t
h5_set_prop_file_mpio_posix (
        h5_prop_t _props,
        MPI_Comm* comm
        ) {
gsell's avatar
gsell committed
243
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
244 245 246
        H5_CORE_API_ENTER (h5_err_t, "props=%p, comm=%p", props, comm);
        
        if (props->class != H5_PROP_FILE) {
247 248 249 250
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
251
        }
252
#ifdef H5_HAVE_PARALLEL
253 254 255
        props->flags &= ~(H5_VFD_MPIO_COLLECTIVE | H5_VFD_MPIO_POSIX | H5_VFD_CORE);
        props->flags |= H5_VFD_MPIO_INDEPENDENT;
        props->comm = *comm;
256 257 258
#else
	h5_info ("Setting MPIO POSIX property ignored in serial H5hut");
#endif
gsell's avatar
gsell committed
259
        H5_RETURN (H5_SUCCESS);
260
}
261
#endif
262 263 264

h5_err_t
h5_set_prop_file_core_vfd (
265
        h5_prop_t _props,
gsell's avatar
gsell committed
266
	const h5_int64_t increment
267
        ) {
gsell's avatar
gsell committed
268
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
Gsell Achim's avatar
* C-API  
Gsell Achim committed
269 270
        H5_CORE_API_ENTER (h5_err_t, "props=%p, increment=%lld",
			   props, (long long int)increment);
271 272
        
        if (props->class != H5_PROP_FILE) {
273 274 275 276
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
277
        }
278
#ifdef H5_HAVE_PARALLEL
Gsell Achim's avatar
* C-API  
Gsell Achim committed
279 280 281
        props->flags &= ~(H5_VFD_MPIO_COLLECTIVE |
			  H5_VFD_MPIO_INDEPENDENT |
			  H5_VFD_MPIO_POSIX);
282 283
        props->flags |= H5_VFD_MPIO_INDEPENDENT;
        props->comm = MPI_COMM_SELF;
284
	props->increment = increment;
285
	if (props->throttle > 0) {
gsell's avatar
gsell committed
286
		h5_warn ("Throttling is not permitted with core VFD. Reset throttling.");
287 288
		props->throttle = 0;
	}
289 290 291
#else
	h5_info ("Setting MPIO core property ignored in serial H5hut");
#endif
gsell's avatar
gsell committed
292
        H5_RETURN (H5_SUCCESS);
293 294
}

295

296 297
h5_err_t
h5_set_prop_file_align (
298
        h5_prop_t _props,
gsell's avatar
gsell committed
299
        const h5_int64_t align
300
        ) {
gsell's avatar
gsell committed
301
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
gsell's avatar
gsell committed
302 303
        H5_CORE_API_ENTER (
		h5_err_t,
304 305 306
		"props=%p, align=%lld",
		props, (long long int)align);
        if (props->class != H5_PROP_FILE) {
307 308 309 310
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
311
        }
312
        props->align = align;
gsell's avatar
gsell committed
313
        H5_RETURN (H5_SUCCESS);
314 315
}

gsell's avatar
gsell committed
316
h5_err_t
Gsell Achim's avatar
* C-API  
Gsell Achim committed
317
h5_set_prop_file_flush_after_write (
gsell's avatar
gsell committed
318 319 320 321 322
        h5_prop_t _props
        ) {
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
        H5_CORE_API_ENTER (
		h5_err_t,
Gsell Achim's avatar
* C-API  
Gsell Achim committed
323 324
		"props=%p",
		props);
gsell's avatar
gsell committed
325 326 327 328 329 330
        if (props->class != H5_PROP_FILE) {
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
        }
Gsell Achim's avatar
* C-API  
Gsell Achim committed
331
        props->flush = 1;
gsell's avatar
gsell committed
332 333 334
        H5_RETURN (H5_SUCCESS);
}

335 336
h5_err_t
h5_set_prop_file_throttle (
337
        h5_prop_t _props,
gsell's avatar
gsell committed
338
        const h5_int64_t throttle
339
        ) {
gsell's avatar
gsell committed
340
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
gsell's avatar
gsell committed
341 342
        H5_CORE_API_ENTER (
		h5_err_t,
343 344 345
		"props=%p, throttle=%lld",
		props, (long long int)throttle);
        if (props->class != H5_PROP_FILE) {
346 347 348 349
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
350
        }
351
#ifdef H5_HAVE_PARALLEL
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
	// throttle only if VFD is MPIO independent od POSIX
	h5_int64_t mask = H5_VFD_MPIO_INDEPENDENT;
#if H5_VERSION_LE(1,8,12)
	mask |= H5_VFD_MPIO_POSIX;
#endif
	if (! (props->flags & mask)) {
#if H5_VERSION_LE(1,8,12)
		h5_warn (
			"Throttling is only permitted with the MPI-POSIX "
			"or MPI-IO Independent VFD. Property ignored." );
#else
		h5_warn (
			"Throttling is only permitted with "
			"the MPI-IO Independent VFD. Property ignored.");
#endif
		props->throttle = 0;
	}

370
        props->throttle = throttle;
371 372 373
#else
	h5_info ("Setting the throttle property in serial H5hut");
#endif
gsell's avatar
gsell committed
374
        H5_RETURN (H5_SUCCESS);
375 376 377 378 379
}


h5_prop_t
h5_create_prop (
gsell's avatar
gsell committed
380
        const h5_int64_t class
381
        ) {
gsell's avatar
gsell committed
382 383 384 385
        H5_CORE_API_ENTER (
		h5_prop_t,
		"class=%lld",
		(long long int)class);
386 387 388 389 390 391 392
        h5_prop_t* prop;
        switch (class) {
        case H5_PROP_FILE:
                TRY (prop = h5_calloc (1, sizeof (h5_prop_file_t)));
                set_default_file_props ((h5_prop_file_t*)prop);
                break;
        default:
393 394 395 396
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)class);
397
        }
gsell's avatar
gsell committed
398
        H5_RETURN ((h5_prop_t)prop);
399 400 401 402 403 404 405 406 407 408 409
}

h5_err_t
h5_close_prop (
        h5_prop_t _prop
        ) {
        h5_prop_p prop = (h5_prop_p)_prop;
        H5_CORE_API_ENTER (h5_err_t, "prop=%p", prop);
        switch (prop->class) {
        case H5_PROP_FILE: {
                h5_prop_file_t* file_prop = (h5_prop_file_t*)prop;
Gsell Achim's avatar
* C-API  
Gsell Achim committed
410
                TRY (h5_free (file_prop->prefix_iteration_name));
411 412 413
                break;
        }
        default:
414 415 416 417
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)prop->class);
418
        }
gsell's avatar
gsell committed
419
        H5_RETURN (h5_free (prop));
420 421 422 423 424 425
}

static inline h5_err_t
open_file (
	const h5_file_p f,
	const char* const filename,
gsell's avatar
gsell committed
426
	const h5_int32_t mode
427 428 429 430
	) {
	H5_INLINE_FUNC_ENTER (h5_err_t);
        h5_info ("Opening file %s.", filename);

431
        f->props->flags |= mode;
432 433 434

        f->nprocs = 1; // queried later
        f->myproc = 0; // queried later
Gsell Achim's avatar
* C-API  
Gsell Achim committed
435
        f->iteration_gid = -1;
436

Gsell Achim's avatar
* C-API  
Gsell Achim committed
437
        TRY (f->iteration_name = h5_calloc (2, H5_ITERATION_NAME_LEN));
438
        sprintf (
Gsell Achim's avatar
* C-API  
Gsell Achim committed
439
                f->iteration_name,
440
                "%s#%0*lld",
Gsell Achim's avatar
* C-API  
Gsell Achim committed
441 442
                f->props->prefix_iteration_name,
                f->props->width_iteration_idx, (long long)f->iteration_idx);
443 444 445 446 447 448 449 450

        TRY (hdf5_set_errorhandler (H5E_DEFAULT, hdf5_error_handler, NULL));
        
        f->props->xfer_prop = f->props->access_prop = H5P_DEFAULT;
        TRY (f->props->create_prop = hdf5_create_property (H5P_FILE_CREATE));
	TRY (mpi_init (f));              // noop if serial
	TRY (set_alignment (f));

451
	if (f->props->flags & H5_O_RDONLY) {
452 453
		f->file = H5Fopen (filename, H5F_ACC_RDONLY, f->props->access_prop);
	}
454 455 456 457
	else if (f->props->flags & H5_O_WRONLY){
		f->file = H5Fcreate (
                        filename, H5F_ACC_TRUNC, f->props->create_prop,
                        f->props->access_prop);
458 459
		f->empty = 1;
	}
460
	else if (f->props->flags & H5_O_APPENDONLY || f->props->flags & H5_O_RDWR) {
461 462
		int fd = open (filename, O_RDONLY, 0);
		if ((fd == -1) && (errno == ENOENT)) {
463 464 465
			f->file = H5Fcreate (
                                filename, H5F_ACC_TRUNC,
                                f->props->create_prop, f->props->access_prop);
466 467 468 469 470 471 472 473 474
			f->empty = 1;
		}
		else if (fd != -1) {
			close (fd);
			f->file = H5Fopen (filename, H5F_ACC_RDWR,
					   f->props->access_prop);
		}
	}
	else {
475 476 477 478
		H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid file access mode '%lld'.",
			(long long int)f->props->flags & 0xff);
479 480 481
	}
	
	if (f->file < 0)
482 483 484 485
		H5_RETURN_ERROR (
			H5_ERR_HDF5,
			"Cannot open file '%s' with mode '%s'",
			filename, H5_O_MODES[f->props->flags & 0xff]);
486 487 488 489 490
	TRY (f->root_gid = hdf5_open_group (f->file, "/" ));

	TRY (h5upriv_open_file (f));
	TRY (h5bpriv_open_file (f));

gsell's avatar
gsell committed
491
	H5_RETURN (H5_SUCCESS);
492 493 494 495
}

h5_file_t
h5_open_file2 (
gsell's avatar
gsell committed
496 497 498
	const char* const filename,
	const h5_int32_t mode,
        const h5_prop_t props_
499
	) {
gsell's avatar
gsell committed
500
        h5_prop_file_t* const props = (h5_prop_file_t*)props_;
501 502 503 504 505 506 507 508 509 510 511
	H5_CORE_API_ENTER (h5_file_t,
			   "filename='%s', mode=%d, props=%p",
			   filename, mode, props);
                
	h5_file_p f = NULL;
	TRY (f = h5_calloc (1, sizeof (*f)));
	
        TRY (f->props = (h5_prop_file_t*)h5_create_prop (H5_PROP_FILE));
                
        if (props != H5_PROP_DEFAULT) {
                if (props->class != H5_PROP_FILE) {
512 513 514 515
                        H5_RETURN_ERROR (
				H5_ERR_INVAL,
				"Invalid property class: %lld.",
				(long long int)props->class);
516
                }
517
#ifdef H5_HAVE_PARALLEL
518
                f->props->comm = props->comm;
519
#endif
520
                f->props->flags = props->flags;
521 522 523 524
                f->props->throttle = props->throttle;
                f->props->align = props->align;

                strncpy (
Gsell Achim's avatar
* C-API  
Gsell Achim committed
525 526 527 528
                        f->props->prefix_iteration_name,
                        props->prefix_iteration_name,
                        H5_ITERATION_NAME_LEN - 1);
                f->props->width_iteration_idx = props->width_iteration_idx;
529 530 531 532
        }

	TRY (open_file (f, filename, mode));

Gsell Achim's avatar
* C-API  
Gsell Achim committed
533 534 535
        TRY (h5_set_iteration_name_fmt ((uintptr_t)f,
					H5_ITERATION_NAME,
					H5_ITERATION_NUM_WIDTH));
gsell's avatar
gsell committed
536

gsell's avatar
gsell committed
537
	H5_RETURN ((h5_file_t)f);
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
}

/*!
  \ingroup h5_core_filehandling
  
  Open file with name \c filename. This function is available in the paralell
  and serial version. In the serial case \c comm may have any value.

  \param[in]	filename	The name of the data file to open.
  \param[in]	flags		The access mode for the file.
  \param[in]	comm		MPI communicator
  \param[in]	align		Number of bytes for setting alignment,
				metadata block size, etc. Set to 0 to disable.

  \return File handle.
  \return H5_ERR  on error.
*/

gsell's avatar
gsell committed
556
h5_file_p
557
h5_open_file1 (
558 559 560
	const char* filename,
	h5_int32_t mode,
	MPI_Comm comm,
gsell's avatar
gsell committed
561
	const h5_size_t align
562
	) {
gsell's avatar
gsell committed
563
	H5_CORE_API_ENTER (
gsell's avatar
gsell committed
564
		h5_file_p,
gsell's avatar
gsell committed
565 566
		"filename='%s', mode=%d, comm=?, align=%llu",
		filename, mode, (long long int)align);
567 568 569
        h5_prop_file_t* props;
        h5_file_t f;
        TRY (props = (h5_prop_file_t*)h5_create_prop (H5_PROP_FILE));
570
        TRY (h5_set_prop_file_mpio_collective ((h5_prop_t)props, &comm));
571 572 573
        TRY (h5_set_prop_file_align ((h5_prop_t)props, align));
        TRY (f = h5_open_file2 (filename, mode, (h5_prop_t)props));
        TRY (h5_close_prop ((h5_prop_t)props));
gsell's avatar
gsell committed
574
	h5_file_p _f = (h5_file_p)f;
gsell's avatar
gsell committed
575
        H5_RETURN (_f);
576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595

}

/*!
  \ingroup h5_core_filehandling

  The h5_close_file() call writes all buffered data to disk, releases 
  all previously allocated memory and terminates access to the associated
  HDF5 file.

  \return	H5_SUCCESS or error code
*/
h5_err_t
h5_close_file (
	const h5_file_t f_              /*!< file handle */
	) {
        h5_file_p f = (h5_file_p)f_;
	H5_CORE_API_ENTER (h5_err_t, "f=%p", f);
	h5_errno = H5_SUCCESS;

Gsell Achim's avatar
* C-API  
Gsell Achim committed
596
	check_file_handle_is_valid (f);
597

Gsell Achim's avatar
* C-API  
Gsell Achim committed
598
	TRY (h5priv_close_iteration (f));
599 600 601 602 603 604 605 606 607
	TRY (h5upriv_close_file (f));
	TRY (h5bpriv_close_file (f));
	TRY (hdf5_close_property (f->props->xfer_prop));
	TRY (hdf5_close_property (f->props->access_prop));
	TRY (hdf5_close_property (f->props->create_prop));
	TRY (hdf5_close_group (f->root_gid));
        TRY (hdf5_flush (f->file, H5F_SCOPE_GLOBAL));
        TRY (h5_close_prop ((h5_prop_t)f->props));
	TRY (hdf5_close_file (f->file));
Gsell Achim's avatar
* C-API  
Gsell Achim committed
608
        TRY (h5_free (f->iteration_name));
609
 	TRY (h5_free (f));
gsell's avatar
gsell committed
610
	H5_RETURN (H5_SUCCESS);
611 612 613
}

h5_err_t
gsell's avatar
gsell committed
614
h5_close_h5hut (
615 616 617
        void
        ) {
	H5_CORE_API_ENTER (h5_err_t, "%s", "");
618
	TRY (h5_finalize ());
gsell's avatar
gsell committed
619 620
	TRY (hdf5_close ());
	H5_RETURN (H5_SUCCESS);
621 622 623
}

h5_err_t
Gsell Achim's avatar
* C-API  
Gsell Achim committed
624
h5_flush_iteration (
625 626 627 628
	const h5_file_t f_
	) {
        h5_file_p f = (h5_file_p)f_;
	H5_CORE_API_ENTER (h5_err_t, "f=%p", f);
Gsell Achim's avatar
* C-API  
Gsell Achim committed
629
	check_iteration_is_writable (f);
gsell's avatar
gsell committed
630
	ret_value = H5_SUCCESS;
Gsell Achim's avatar
* C-API  
Gsell Achim committed
631 632
	if (f->iteration_gid >= 0) {
		TRY (ret_value = hdf5_flush (f->iteration_gid, H5F_SCOPE_LOCAL));
gsell's avatar
gsell committed
633
	}
gsell's avatar
gsell committed
634
	H5_RETURN (ret_value);
635 636 637 638 639 640 641 642
}

h5_err_t
h5_flush_file (
	const h5_file_t f_
	) {
        h5_file_p f = (h5_file_p)f_;
	H5_CORE_API_ENTER (h5_err_t, "f=%p", f);
Gsell Achim's avatar
* C-API  
Gsell Achim committed
643
	check_file_is_writable (f);
644
	TRY (ret_value = hdf5_flush (f->file, H5F_SCOPE_GLOBAL));
gsell's avatar
gsell committed
645
	H5_RETURN (ret_value);
646 647 648 649 650 651
}


/*!
  \ingroup h5_core_filehandling

Gsell Achim's avatar
* C-API  
Gsell Achim committed
652
  Define format of the iteration names.
653

Gsell Achim's avatar
* C-API  
Gsell Achim committed
654 655
  Example: ==h5_set_iteration_name_fmt (f, "Step", 6)==
  defines iteration names like ==Step#000042==.
656 657 658 659

  \return \c H5_SUCCESS or error code
*/
h5_err_t
Gsell Achim's avatar
* C-API  
Gsell Achim committed
660
h5_set_iteration_name_fmt (
661 662 663 664 665 666 667 668
	const h5_file_t f_,
	const char* name,
	int width
	) {
        h5_file_p f = (h5_file_p)f_;
	H5_CORE_API_ENTER (h5_err_t,
                           "f=%p, name='%s', width=%d",
                           f, name, width);
Gsell Achim's avatar
* C-API  
Gsell Achim committed
669
	check_file_handle_is_valid (f);
670
	if (width < 0) width = 0;
Gsell Achim's avatar
* C-API  
Gsell Achim committed
671
	else if (width > H5_ITERATION_NAME_LEN - 1) width = H5_ITERATION_NAME_LEN - 1;
672
	strncpy (
Gsell Achim's avatar
* C-API  
Gsell Achim committed
673
		f->props->prefix_iteration_name,
674
		name,
Gsell Achim's avatar
* C-API  
Gsell Achim committed
675 676
		H5_ITERATION_NAME_LEN - 1);
	f->props->width_iteration_idx = width;
677

gsell's avatar
gsell committed
678
	H5_RETURN (H5_SUCCESS);
679 680 681 682 683
}

/*!
  \ingroup h5_core_filehandling

Gsell Achim's avatar
* C-API  
Gsell Achim committed
684
  Get format of the iteration names.
685 686 687 688

  \return \c H5_SUCCESS or error code
*/
h5_err_t
Gsell Achim's avatar
* C-API  
Gsell Achim committed
689
h5_get_iteration_name_fmt (
690
	const h5_file_t f_,		/*!< Handle to file		*/
Gsell Achim's avatar
* C-API  
Gsell Achim committed
691 692 693
	char* const name,		/*!< OUT: Prefix		*/
	const int l_name,		/*!< length of buffer name	*/
	int* const width		/*!< OUT: Width of the number	*/
694 695 696 697 698 699 700 701 702 703 704 705
	) {
        h5_file_p f = (h5_file_p)f_;
	UNUSED_ARGUMENT (f);
	UNUSED_ARGUMENT (name);
	UNUSED_ARGUMENT (l_name);
	UNUSED_ARGUMENT (width);
	return h5_error_not_implemented ();
}

/*!
  \ingroup h5_core_filehandling

Gsell Achim's avatar
* C-API  
Gsell Achim committed
706
  Get current iteration number.
707

Gsell Achim's avatar
* C-API  
Gsell Achim committed
708
  \return Current iteration number or error code
709 710
*/
h5_id_t
Gsell Achim's avatar
* C-API  
Gsell Achim committed
711
h5_get_iteration (
712 713 714 715
	const h5_file_t f_		/*!< file handle		*/
	) {
        h5_file_p f = (h5_file_p)f_;
	H5_CORE_API_ENTER (h5_id_t, "f=%p", f);
Gsell Achim's avatar
* C-API  
Gsell Achim committed
716 717
	check_iteration_is_readable (f);
	H5_RETURN (f->iteration_idx);
718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
}

/*!
  \ingroup h5_core_filehandling

  Get number of processes.

  \return Number of processes or error code
*/
int
h5_get_num_procs (
	const h5_file_t f_		/*!< file handle		*/
	) {
        h5_file_p f = (h5_file_p)f_;
	H5_CORE_API_ENTER (int, "f=%p", f);
Gsell Achim's avatar
* C-API  
Gsell Achim committed
733
	check_file_handle_is_valid (f);
gsell's avatar
gsell committed
734
	H5_RETURN (f->nprocs);
735 736 737 738 739
}

/*!
  \ingroup h5_core_filehandling

Gsell Achim's avatar
* C-API  
Gsell Achim committed
740
  Get number of iterations.
741

Gsell Achim's avatar
* C-API  
Gsell Achim committed
742
  \return Number of iterations or error code
743 744
*/
h5_ssize_t
Gsell Achim's avatar
* C-API  
Gsell Achim committed
745
h5_get_num_iterations (
746 747 748 749
	const h5_file_t f_		/*!< file handle		*/
	) {
        h5_file_p f = (h5_file_p)f_;
	H5_CORE_API_ENTER (int, "f=%p", f);
Gsell Achim's avatar
* C-API  
Gsell Achim committed
750
	check_file_handle_is_valid (f);
751 752
	TRY (ret_value = hdf5_get_num_groups_matching_prefix (
		     f->root_gid,
Gsell Achim's avatar
* C-API  
Gsell Achim committed
753
		     f->props->prefix_iteration_name));
gsell's avatar
gsell committed
754
	H5_RETURN (ret_value);
755 756 757 758 759
}

/*!
  \ingroup h5_core_filehandling

Gsell Achim's avatar
* C-API  
Gsell Achim committed
760
  Start traversing iterations.
761 762 763 764

  \return \c H5_SUCCESS or error code 
*/
h5_err_t
Gsell Achim's avatar
* C-API  
Gsell Achim committed
765
h5_start_traverse_iterations (
766 767
	const h5_file_t f_		/*!< file handle		*/
	) {
768
	H5_CORE_API_ENTER (int, "f=%p", (void*)f_);
769 770 771 772 773 774 775

	/*
	  fast test: Does Step#0 or Step#1 exist?
	  otherwise
	  loop over all steps and get smallest step number
	 */
	
gsell's avatar
gsell committed
776
	H5_RETURN (h5_error_not_implemented ());
777 778 779 780 781
}

/*!
  \ingroup h5_core_filehandling

Gsell Achim's avatar
* C-API  
Gsell Achim committed
782
  Go to next iteration.
783 784 785 786

  \return \c H5_SUCCESS or error code 
*/
h5_err_t
Gsell Achim's avatar
* C-API  
Gsell Achim committed
787
h5_traverse_iterations (
788 789 790 791 792 793
	const h5_file_t f_		/*!< file handle		*/
	) {
        h5_file_p f = (h5_file_p)f_;
	UNUSED_ARGUMENT (f);
	return h5_error_not_implemented ();
}