Quincey's fixes for NCF-250, netCDF-4 parallel independent access with

unlimited dimension hanging.  Extending the size of an unlimited
dimension in HDF5 must be a collective operation, so now an error is
returned if trying to extend in independent access mode.

Quincey's bug fixes for parallel build portability, particularly
OpenMPI on MacOS-X.
This commit is contained in:
Russ Rew 2013-07-08 21:31:13 +00:00
parent 145f4c4b99
commit 6cd8fca60d
12 changed files with 68 additions and 78 deletions

View File

@ -21,11 +21,8 @@
#ifdef USE_PARALLEL
#include <netcdf_par.h>
#else
#define MPI_Info int
#define MPI_Comm int
#include <netcdf.h>
#endif /* USE_PARALLEL */
#include <netcdf.h>
#include <netcdf_f.h>
/* Always needed */

View File

@ -109,19 +109,12 @@ extern int nc_put_vara_ulonglong(int ncid, int varid,
/* Define an alias for int to indicate an error return */
typedef int NCerror;
/* WARNING: this must match libsrc4/netcdf.h */
#ifndef MPI_Comm
#define MPI_Comm int
#endif
#ifndef MPI_Info
#define MPI_Info int
#endif
#ifndef MPI_COMM_WORLD
#ifndef USE_PARALLEL
typedef int MPI_Comm;
typedef int MPI_Info;
#define MPI_COMM_WORLD 0
#endif
#ifndef MPI_INFO_NULL
#define MPI_INFO_NULL 0
#endif
#endif /* USE_PARALLEL */
/* Define a struct to hold the MPI info so it can be passed down the
* call stack. This is used internally by the netCDF library. It

View File

@ -378,8 +378,9 @@ by the desired type. */
#define NC_EBADCHUNK (-127) /**< Bad chunksize. */
#define NC_ENOTBUILT (-128) /**< Attempt to use feature that was not turned on when netCDF was built. */
#define NC_EDISKLESS (-129) /**< Error in using diskless access. */
#define NC_ECANTEXTEND (-130) /**< Attempt to extend dataset during ind. I/O operation. */
#define NC4_LAST_ERROR (-129)
#define NC4_LAST_ERROR (-130)
/* This is used in netCDF-4 files for dimensions without coordinate
* vars. */

View File

@ -11,7 +11,6 @@
#define NETCDF_PAR_H 1
#include <mpi.h>
#include <netcdf.h>
#if defined(__cplusplus)
extern "C" {

View File

@ -101,14 +101,14 @@ NC_check_file_type(const char *path, int use_parallel, void *mpi_info,
/* Get the 4-byte magic from the beginning of the file. Don't use posix
* for parallel, use the MPI functions instead. */
#ifdef USE_PARALLEL_MPIO
#ifdef USE_PARALLEL
if (use_parallel)
{
MPI_File fh;
MPI_Status status;
int retval;
MPI_Comm comm = 0;
MPI_Info info = 0;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
if(mpi_info != NULL) {
comm = ((NC_MPI_INFO*)mpi_info)->comm;

View File

@ -8,7 +8,7 @@ Research/Unidata. See COPYRIGHT file for more info.
#include "config.h"
#ifdef USE_PARALLEL
#include "netcdf_f.h"
#endif
#endif /* USE_PARALLEL */
#include "ncdispatch.h"
/* This function creates a file for use with parallel I/O. */
@ -20,8 +20,6 @@ nc_create_par(const char *path, int cmode, MPI_Comm comm,
return NC_ENOPAR;
#else
NC_MPI_INFO data;
MPI_Comm comm_c = 0;
MPI_Info info_c = 0;
/* One of these two parallel IO modes must be chosen by the user,
* or else pnetcdf must be in use. */
@ -29,11 +27,8 @@ nc_create_par(const char *path, int cmode, MPI_Comm comm,
!(cmode & NC_PNETCDF))
return NC_EINVAL;
comm_c = (MPI_Comm)comm;
info_c = (MPI_Info)info;
data.comm = comm_c;
data.info = info_c;
data.comm = comm;
data.info = info;
return NC_create(path, cmode, 0, 0, NULL, 1, &data, ncidp);
#endif /* USE_PARALLEL */
}
@ -72,9 +67,8 @@ nc_open_par_fortran(const char *path, int mode, int comm,
#ifndef USE_PARALLEL
return NC_ENOPAR;
#else
MPI_Comm comm_c = 0;
MPI_Info info_c = 0;
MPI_Comm comm_c;
MPI_Info info_c;
/* Convert fortran comm and info to C comm and info, if there is a
* function to do so. Otherwise just pass them. */
@ -117,9 +111,11 @@ nc_create_par_fortran(const char *path, int cmode, int comm,
#ifndef USE_PARALLEL
return NC_ENOPAR;
#else
MPI_Comm comm_c = 0;
MPI_Info info_c = 0;
#ifdef USE_PARALLEL
MPI_Comm comm_c;
MPI_Info info_c;
/* Convert fortran comm and info to C comm and info, if there is a
* function to do so. Otherwise just pass them. */
#ifdef HAVE_MPI_COMM_F2C
comm_c = MPI_Comm_f2c(comm);
info_c = MPI_Info_f2c(info);
@ -127,7 +123,7 @@ nc_create_par_fortran(const char *path, int cmode, int comm,
comm_c = (MPI_Comm)comm;
info_c = (MPI_Info)info;
#endif
#endif
return nc_create_par(path, cmode, comm_c, info_c, ncidp);
#endif
}

View File

@ -9,10 +9,8 @@
#include "nc.h"
#ifndef MPI_INCLUDED
#define MPI_Comm int
#define MPI_Info int
#define MPI_COMM_WORLD 0
#define MPI_INFO_NULL 0
typedef int MPI_Comm;
typedef int MPI_Info;
#endif
int

View File

@ -7,8 +7,8 @@
#define _NC3STUB_H
#ifndef MPI_INCLUDED
#define MPI_Comm int
#define MPI_Info int
typedef int MPI_Comm;
typedef int MPI_Info;
#endif
#if defined(__cplusplus)

View File

@ -390,12 +390,8 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe,
size_t *chunksizehintp, int use_parallel, void *mpidata,
NC_Dispatch *dispatch, NC* nc_file)
{
#ifdef USE_PARALLEL
MPI_Comm comm = 0;
MPI_Info info = 0;
#else
int comm = 0, info = 0;
#endif /* USE_PARALLEL */
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
int res;
assert(nc_file && path);
@ -2769,12 +2765,8 @@ NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp,
int use_parallel, void *mpidata, NC_Dispatch *dispatch, NC *nc_file)
{
int hdf_file = 0;
#ifdef USE_PARALLEL
MPI_Comm comm = 0;
MPI_Info info = 0;
#else
int comm = 0, info = 0;
#endif /* USE_PARALLEL */
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
int res;
assert(nc_file && path);
@ -2785,8 +2777,8 @@ NC4_open(const char *path, int mode, int basepe, size_t *chunksizehintp,
#ifdef USE_PARALLEL
if (mpidata)
{
NC_MPI_INFO *nmi = (NC_MPI_INFO *)mpidata;
comm = nmi->comm; info = nmi->info;
comm = ((NC_MPI_INFO *)mpidata)->comm;
info = ((NC_MPI_INFO *)mpidata)->info;
}
#endif /* USE_PARALLEL */

View File

@ -762,6 +762,10 @@ nc4_put_vara(NC *nc, int ncid, int varid, const size_t *startp,
if (need_to_extend)
{
LOG((4, "extending dataset"));
#ifdef USE_PARALLEL
if (h5->parallel && NC_COLLECTIVE != var->parallel_access)
BAIL(NC_ECANTEXTEND);
#endif /* USE_PARALLEL */
if (H5Dset_extent(var->hdf_datasetid, xtend_size) < 0)
BAIL(NC_EHDFERR);
if (file_spaceid > 0 && H5Sclose(file_spaceid) < 0)

View File

@ -44,8 +44,8 @@ NC5_create(const char *path, int cmode,
{
int res;
NC5_INFO* nc5;
MPI_Comm comm = 0;
MPI_Info info = 0;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
/* Check the cmode for only valid flags*/
if(cmode & ~LEGAL_CREATE_FLAGS)
@ -98,8 +98,8 @@ NC5_open(const char *path, int cmode,
{
int res;
NC5_INFO* nc5;
MPI_Comm comm = 0;
MPI_Info info = 0;
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
/* Check the cmode for only valid flags*/
if(cmode & ~LEGAL_OPEN_FLAGS)

View File

@ -271,7 +271,14 @@ int test_pio(int flag)
}
/* Write slabs of phoney data. */
if (nc_put_vara_int(ncid, uvid, ustart, ucount, udata)) ERR;
if (NC_INDEPENDENT == flag) {
int res;
res = nc_put_vara_int(ncid, uvid, ustart, ucount, udata);
if(res != NC_ECANTEXTEND) ERR;
}
else {
if (nc_put_vara_int(ncid, uvid, ustart, ucount, udata)) ERR;
}
free(udata);
/* Close the netcdf file. */
@ -319,28 +326,31 @@ int test_pio(int flag)
ucount[3] = DIMSIZE/mpi_size;
/* Inquiry the data */
if (nc_inq_varid(ncid, "uv1", &rvid)) ERR;
/* Access the parallel */
if (nc_var_par_access(ncid, rvid, flag)) ERR;
/* (NOTE: This variable isn't written out, when access is independent) */
if (NC_INDEPENDENT != flag) {
if (nc_inq_varid(ncid, "uv1", &rvid)) ERR;
/* Access the parallel */
if (nc_var_par_access(ncid, rvid, flag)) ERR;
if (!(rudata = malloc(ucount[0]*ucount[1]*ucount[2]*ucount[3]*sizeof(int)))) ERR;
temprudata = rudata;
if (!(rudata = malloc(ucount[0]*ucount[1]*ucount[2]*ucount[3]*sizeof(int)))) ERR;
temprudata = rudata;
/* Read data */
if (nc_get_vara_int(ncid, rvid, ustart, ucount, rudata)) ERR;
/* Read data */
if (nc_get_vara_int(ncid, rvid, ustart, ucount, rudata)) ERR;
for(m = 0; m < ucount[0]; m++)
for(k = 0; k < ucount[1]; k++)
for(j = 0; j < ucount[2]; j++)
for(i = 0; i < ucount[3]; i++)
{
if(*temprudata != (1+mpi_rank)*2*(j+1)*(k+1)*(m+1))
ERR_RET;
temprudata++;
}
for(m = 0; m < ucount[0]; m++)
for(k = 0; k < ucount[1]; k++)
for(j = 0; j < ucount[2]; j++)
for(i = 0; i < ucount[3]; i++)
{
if(*temprudata != (1+mpi_rank)*2*(j+1)*(k+1)*(m+1))
ERR_RET;
temprudata++;
}
free(rudata);
free(rudata);
}
/* Close the netcdf file. */
if (nc_close(ncid)) ERR;