h5_file.c 20 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 45 46 47 48 49 50 51 52
#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_;
	if (f == NULL || f_ == H5_FAILURE || f->file < 0 || f->u == NULL || f->b == NULL) {
		return h5_error (
			H5_ERR_BADF,
			"Called with bad filehandle.");
	}
	return H5_SUCCESS;
}

gsell's avatar
gsell committed
53 54 55 56 57 58
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's avatar
gsell committed
59
	H5_RETURN (f->file);
gsell's avatar
gsell committed
60 61
}

62
/*!
63
  Initialize H5hut
64 65 66 67
*/
static herr_t
hdf5_error_handler (
	hid_t estack_id,
gsell's avatar
gsell committed
68
	void*  __f
69 70
	) {
	UNUSED_ARGUMENT (__f);
71
	if (h5_get_loglevel() >= 5) {
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
		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);
#ifdef PARALLEL_IO
	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
92
#if H5_VERSION_LE(1,8,12)
93
	if ((f->props->flags & H5_VFD_MPIO_POSIX)) {
94 95 96 97 98
		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));

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

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
153 154 155 156
		h5_info (
			"Setting HDF5 alignment to %lld bytes "
			"with threshold at half that many bytes.",
			(long long int)f->props->align);
157 158 159 160
		TRY (hdf5_set_alignment_property (
                             f->props->access_prop,
                             f->props->align / 2,
                             f->props->align));
gsell's avatar
gsell committed
161 162 163
		h5_info (
			"Setting HDF5 meta block to %lld bytes",
			(long long int)f->props->align);
164 165
		TRY (H5Pset_meta_block_size (f->props->access_prop, f->props->align));
	}
gsell's avatar
gsell committed
166
	H5_RETURN (H5_SUCCESS);
167 168 169 170
}

static inline h5_err_t
set_default_file_props (
gsell's avatar
gsell committed
171
        h5_prop_file_t* const _props
172 173
        ) {
        H5_INLINE_FUNC_ENTER (h5_err_t);
gsell's avatar
gsell committed
174
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
gsell's avatar
gsell committed
175
        bzero (props, sizeof (*props));
176 177
        props->class = H5_PROP_FILE;
        TRY (props->prefix_step_name = h5_calloc (1, H5_STEPNAME_LEN));
178
        strncpy (
179
                props->prefix_step_name,
180 181
                H5_STEPNAME,
                H5_STEPNAME_LEN - 1);
182 183
        props->width_step_idx = H5_STEPWIDTH;
        props->comm = MPI_COMM_WORLD;
gsell's avatar
gsell committed
184
        H5_RETURN (H5_SUCCESS);
185 186 187
}

h5_err_t
188 189
h5_set_prop_file_mpio_collective (
        h5_prop_t _props,
190 191
        MPI_Comm* comm
        ) {
gsell's avatar
gsell committed
192
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
193
        H5_CORE_API_ENTER (h5_err_t, "props=%p, comm=%p", props, comm);
194
        
195
        if (props->class != H5_PROP_FILE) {
196 197 198 199
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
200 201 202 203
        }
        props->flags &= ~(H5_VFD_MPIO_POSIX | H5_VFD_MPIO_INDEPENDENT | H5_VFD_CORE);
        props->flags |= H5_VFD_MPIO_COLLECTIVE;
        props->comm = *comm;
204 205 206 207 208
	if (props->throttle > 0) {
		h5_warn ("Throttling is not permitted with collective VFD. Reset throttling.");
		props->throttle = 0;
	}

gsell's avatar
gsell committed
209
        H5_RETURN (H5_SUCCESS);
210 211 212 213 214 215 216
}

h5_err_t
h5_set_prop_file_mpio_independent (
        h5_prop_t _props,
        MPI_Comm* comm
        ) {
gsell's avatar
gsell committed
217
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
218 219 220
        H5_CORE_API_ENTER (h5_err_t, "props=%p, comm=%p", props, comm);
        
        if (props->class != H5_PROP_FILE) {
221 222 223 224
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
225 226 227 228
        }
        props->flags &= ~(H5_VFD_MPIO_COLLECTIVE | H5_VFD_MPIO_POSIX | H5_VFD_CORE);
        props->flags |= H5_VFD_MPIO_INDEPENDENT;
        props->comm = *comm;
gsell's avatar
gsell committed
229
        H5_RETURN (H5_SUCCESS);
230 231
}

232
#if H5_VERSION_LE(1,8,12)
233 234 235 236 237
h5_err_t
h5_set_prop_file_mpio_posix (
        h5_prop_t _props,
        MPI_Comm* comm
        ) {
gsell's avatar
gsell committed
238
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
239 240 241
        H5_CORE_API_ENTER (h5_err_t, "props=%p, comm=%p", props, comm);
        
        if (props->class != H5_PROP_FILE) {
242 243 244 245
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
246 247 248 249
        }
        props->flags &= ~(H5_VFD_MPIO_COLLECTIVE | H5_VFD_MPIO_POSIX | H5_VFD_CORE);
        props->flags |= H5_VFD_MPIO_INDEPENDENT;
        props->comm = *comm;
gsell's avatar
gsell committed
250
        H5_RETURN (H5_SUCCESS);
251
}
252
#endif
253 254 255

h5_err_t
h5_set_prop_file_core_vfd (
256
        h5_prop_t _props,
gsell's avatar
gsell committed
257
	const h5_int64_t increment
258
        ) {
gsell's avatar
gsell committed
259
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
260
        H5_CORE_API_ENTER (h5_err_t, "props=%p, increment=%lld", props, (long long int)increment);
261 262
        
        if (props->class != H5_PROP_FILE) {
263 264 265 266
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
267
        }
268 269 270
        props->flags &= ~(H5_VFD_MPIO_COLLECTIVE | H5_VFD_MPIO_INDEPENDENT | H5_VFD_MPIO_POSIX);
        props->flags |= H5_VFD_MPIO_INDEPENDENT;
        props->comm = MPI_COMM_SELF;
271
	props->increment = increment;
272
	if (props->throttle > 0) {
gsell's avatar
gsell committed
273
		h5_warn ("Throttling is not permitted with core VFD. Reset throttling.");
274 275
		props->throttle = 0;
	}
gsell's avatar
gsell committed
276
        H5_RETURN (H5_SUCCESS);
277 278
}

279

280 281
h5_err_t
h5_set_prop_file_align (
282
        h5_prop_t _props,
gsell's avatar
gsell committed
283
        const h5_int64_t align
284
        ) {
gsell's avatar
gsell committed
285
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
gsell's avatar
gsell committed
286 287
        H5_CORE_API_ENTER (
		h5_err_t,
288 289 290
		"props=%p, align=%lld",
		props, (long long int)align);
        if (props->class != H5_PROP_FILE) {
291 292 293 294
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
295
        }
296
        props->align = align;
gsell's avatar
gsell committed
297
        H5_RETURN (H5_SUCCESS);
298 299 300 301
}

h5_err_t
h5_set_prop_file_throttle (
302
        h5_prop_t _props,
gsell's avatar
gsell committed
303
        const h5_int64_t throttle
304
        ) {
gsell's avatar
gsell committed
305
        h5_prop_file_t* props = (h5_prop_file_t*)_props;
gsell's avatar
gsell committed
306 307
        H5_CORE_API_ENTER (
		h5_err_t,
308 309 310
		"props=%p, throttle=%lld",
		props, (long long int)throttle);
        if (props->class != H5_PROP_FILE) {
311 312 313 314
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)props->class);
315
        }
316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
	// 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;
	}

334
        props->throttle = throttle;
gsell's avatar
gsell committed
335
        H5_RETURN (H5_SUCCESS);
336 337 338 339 340
}


h5_prop_t
h5_create_prop (
gsell's avatar
gsell committed
341
        const h5_int64_t class
342
        ) {
gsell's avatar
gsell committed
343 344 345 346
        H5_CORE_API_ENTER (
		h5_prop_t,
		"class=%lld",
		(long long int)class);
347 348 349 350 351 352 353
        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:
354 355 356 357
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)class);
358
        }
gsell's avatar
gsell committed
359
        H5_RETURN ((h5_prop_t)prop);
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
}

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;
                TRY (h5_free (file_prop->prefix_step_name));
                break;
        }
        default:
375 376 377 378
                H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid property class: %lld",
			(long long int)prop->class);
379
        }
gsell's avatar
gsell committed
380
        H5_RETURN (h5_free (prop));
381 382 383 384 385 386
}

static inline h5_err_t
open_file (
	const h5_file_p f,
	const char* const filename,
gsell's avatar
gsell committed
387
	const h5_int32_t mode
388 389 390 391
	) {
	H5_INLINE_FUNC_ENTER (h5_err_t);
        h5_info ("Opening file %s.", filename);

392
        f->props->flags |= mode;
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411

        f->nprocs = 1; // queried later
        f->myproc = 0; // queried later
        f->step_gid = -1;

        TRY (f->step_name = h5_calloc (2, H5_STEPNAME_LEN));
        sprintf (
                f->step_name,
                "%s#%0*lld",
                f->props->prefix_step_name,
                f->props->width_step_idx, (long long)f->step_idx);

        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));

412
	if (f->props->flags & H5_O_RDONLY) {
413 414
		f->file = H5Fopen (filename, H5F_ACC_RDONLY, f->props->access_prop);
	}
415 416 417 418
	else if (f->props->flags & H5_O_WRONLY){
		f->file = H5Fcreate (
                        filename, H5F_ACC_TRUNC, f->props->create_prop,
                        f->props->access_prop);
419 420
		f->empty = 1;
	}
421
	else if (f->props->flags & H5_O_APPENDONLY || f->props->flags & H5_O_RDWR) {
422 423
		int fd = open (filename, O_RDONLY, 0);
		if ((fd == -1) && (errno == ENOENT)) {
424 425 426
			f->file = H5Fcreate (
                                filename, H5F_ACC_TRUNC,
                                f->props->create_prop, f->props->access_prop);
427 428 429 430 431 432 433 434 435
			f->empty = 1;
		}
		else if (fd != -1) {
			close (fd);
			f->file = H5Fopen (filename, H5F_ACC_RDWR,
					   f->props->access_prop);
		}
	}
	else {
436 437 438 439
		H5_RETURN_ERROR (
			H5_ERR_INVAL,
			"Invalid file access mode '%lld'.",
			(long long int)f->props->flags & 0xff);
440 441 442
	}
	
	if (f->file < 0)
443 444 445 446
		H5_RETURN_ERROR (
			H5_ERR_HDF5,
			"Cannot open file '%s' with mode '%s'",
			filename, H5_O_MODES[f->props->flags & 0xff]);
447 448 449 450 451
	TRY (f->root_gid = hdf5_open_group (f->file, "/" ));

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

gsell's avatar
gsell committed
452
	H5_RETURN (H5_SUCCESS);
453 454 455 456
}

h5_file_t
h5_open_file2 (
gsell's avatar
gsell committed
457 458 459
	const char* const filename,
	const h5_int32_t mode,
        const h5_prop_t props_
460
	) {
gsell's avatar
gsell committed
461
        h5_prop_file_t* const props = (h5_prop_file_t*)props_;
462 463 464 465 466 467 468 469 470 471 472 473 474
	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));
        TRY (set_default_file_props (f->props));
        TRY (h5_set_stepname_fmt ((uintptr_t)f, H5_STEPNAME, H5_STEPWIDTH));
                
        if (props != H5_PROP_DEFAULT) {
                if (props->class != H5_PROP_FILE) {
475 476 477 478
                        H5_RETURN_ERROR (
				H5_ERR_INVAL,
				"Invalid property class: %lld.",
				(long long int)props->class);
479 480
                }
                f->props->comm = props->comm;
481
                f->props->flags = props->flags;
482 483 484 485 486 487 488 489 490 491 492 493
                f->props->throttle = props->throttle;
                f->props->align = props->align;

                strncpy (
                        f->props->prefix_step_name,
                        props->prefix_step_name,
                        H5_STEPNAME_LEN - 1);
                f->props->width_step_idx = props->width_step_idx;
        }

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

gsell's avatar
gsell committed
494
	H5_RETURN ((h5_file_t)f);
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
}

/*!
  \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
513
h5_file_p
514
h5_open_file1 (
515 516 517
	const char* filename,
	h5_int32_t mode,
	MPI_Comm comm,
gsell's avatar
gsell committed
518
	const h5_size_t align
519
	) {
gsell's avatar
gsell committed
520
	H5_CORE_API_ENTER (
gsell's avatar
gsell committed
521
		h5_file_p,
gsell's avatar
gsell committed
522 523
		"filename='%s', mode=%d, comm=?, align=%llu",
		filename, mode, (long long int)align);
524 525 526
        h5_prop_file_t* props;
        h5_file_t f;
        TRY (props = (h5_prop_file_t*)h5_create_prop (H5_PROP_FILE));
527
        TRY (h5_set_prop_file_mpio_collective ((h5_prop_t)props, &comm));
528 529 530
        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
531
	h5_file_p _f = (h5_file_p)f;
gsell's avatar
gsell committed
532
        H5_RETURN (_f);
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566

}

/*!
  \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;

	CHECK_FILEHANDLE (f);

	TRY (h5priv_close_step (f));
	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));
        TRY (h5_free (f->step_name));
 	TRY (h5_free (f));
gsell's avatar
gsell committed
567
	H5_RETURN (H5_SUCCESS);
568 569 570 571 572 573 574
}

h5_err_t
h5_close_hdf5 (
        void
        ) {
	H5_CORE_API_ENTER (h5_err_t, "%s", "");
575
	TRY (ret_value = hdf5_close ());
gsell's avatar
gsell committed
576
	H5_RETURN (ret_value);
577 578 579 580 581 582 583 584
}

h5_err_t
h5_flush_step (
	const h5_file_t f_
	) {
        h5_file_p f = (h5_file_p)f_;
	H5_CORE_API_ENTER (h5_err_t, "f=%p", f);
585
	TRY (ret_value = hdf5_flush (f->step_gid, H5F_SCOPE_LOCAL));
gsell's avatar
gsell committed
586
	H5_RETURN (ret_value);
587 588 589 590 591 592 593 594
}

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);
595
	TRY (ret_value = hdf5_flush (f->file, H5F_SCOPE_GLOBAL));
gsell's avatar
gsell committed
596
	H5_RETURN (ret_value);
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627
}


/*!
  \ingroup h5_core_filehandling

  Define format of the step names.

  Example: ==H5FedDefineStepNameFormat( f, "Step", 6 )== defines step names 
  like ==Step#000042==.

  \return \c H5_SUCCESS or error code
*/
h5_err_t
h5_set_stepname_fmt (
	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);
	if (width < 0) width = 0;
	else if (width > H5_STEPNAME_LEN - 1) width = H5_STEPNAME_LEN - 1;
	strncpy (
		f->props->prefix_step_name,
		name,
		H5_STEPNAME_LEN - 1);
	f->props->width_step_idx = width;

gsell's avatar
gsell committed
628
	H5_RETURN (H5_SUCCESS);
629 630 631 632 633 634 635 636 637 638 639 640
}

/*!
  \ingroup h5_core_filehandling

  Get format of the step names.

  \return \c H5_SUCCESS or error code
*/
h5_err_t
h5_get_stepname_fmt (
	const h5_file_t f_,		/*!< Handle to file		*/
gsell's avatar
gsell committed
641 642 643
	char* const name,			/*!< OUT: Prefix		*/
	const int l_name,			/*!< length of buffer name	*/
	int* const width			/*!< OUT: Width of the number	*/
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
	) {
        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

  Get current step number.

  \return Current step number or error code
*/
h5_id_t
h5_get_step (
	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's avatar
gsell committed
666
	H5_RETURN (f->step_idx);
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
}

/*!
  \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's avatar
gsell committed
682
	H5_RETURN (f->nprocs);
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697
}

/*!
  \ingroup h5_core_filehandling

  Get number of steps.

  \return Number of steps or error code
*/
h5_ssize_t
h5_get_num_steps(
	const h5_file_t f_		/*!< file handle		*/
	) {
        h5_file_p f = (h5_file_p)f_;
	H5_CORE_API_ENTER (int, "f=%p", f);
698 699 700
	TRY (ret_value = hdf5_get_num_groups_matching_prefix (
		     f->root_gid,
		     f->props->prefix_step_name));
gsell's avatar
gsell committed
701
	H5_RETURN (ret_value);
702 703 704 705 706
}

/*!
  \ingroup h5_core_filehandling

707
  Start traversing steps. 
708 709 710 711 712 713 714 715

  \return \c H5_SUCCESS or error code 
*/
h5_err_t
h5_start_traverse_steps (
	const h5_file_t f_		/*!< file handle		*/
	) {
        h5_file_p f = (h5_file_p)f_;
716 717 718 719 720 721 722 723
	H5_CORE_API_ENTER (int, "f=%p", f);

	/*
	  fast test: Does Step#0 or Step#1 exist?
	  otherwise
	  loop over all steps and get smallest step number
	 */
	
gsell's avatar
gsell committed
724
	H5_RETURN (h5_error_not_implemented ());
725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741
}

/*!
  \ingroup h5_core_filehandling

  Go to next step.

  \return \c H5_SUCCESS or error code 
*/
h5_err_t
h5_traverse_steps (
	const h5_file_t f_		/*!< file handle		*/
	) {
        h5_file_p f = (h5_file_p)f_;
	UNUSED_ARGUMENT (f);
	return h5_error_not_implemented ();
}