mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-02-17 16:50:18 +08:00
merge latest trunk changes into my branch
This commit is contained in:
commit
23226e5101
include
libdispatch
libsrc4
nc_test4
Makefile.amcdm_sea_soundings.ctests.htst_atts2.ctst_mpi_parallel.ctst_nc4perf.ctst_parallel.ctst_parallel2.ctst_parallel3.ctst_parallel4.c
nf_test
@ -29,6 +29,11 @@ int total_err = 0, err = 0;
|
|||||||
char *format_name[] = {"", "classic", "64-bit offset", "netCDF-4",
|
char *format_name[] = {"", "classic", "64-bit offset", "netCDF-4",
|
||||||
"netCDF-4 classic model"};
|
"netCDF-4 classic model"};
|
||||||
|
|
||||||
|
#define BAIL(e) do { \
|
||||||
|
printf ("Bailing out in file %s, line %d, error:%s.\n", __FILE__, __LINE__, nc_strerror(e)); \
|
||||||
|
return -1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/* This macro prints an error message with line number and name of
|
/* This macro prints an error message with line number and name of
|
||||||
* test program. */
|
* test program. */
|
||||||
#define ERR do { \
|
#define ERR do { \
|
||||||
|
@ -63,6 +63,8 @@ extern "C" {
|
|||||||
#define NC_UINT64 11 /* unsigned 8-byte int */
|
#define NC_UINT64 11 /* unsigned 8-byte int */
|
||||||
#define NC_STRING 12 /* string */
|
#define NC_STRING 12 /* string */
|
||||||
|
|
||||||
|
#define NC_MAX_ATOMIC_TYPE NC_STRING
|
||||||
|
|
||||||
/* The following are use internally in support of user-defines
|
/* The following are use internally in support of user-defines
|
||||||
* types. They are also the class returned by nc_inq_user_type. */
|
* types. They are also the class returned by nc_inq_user_type. */
|
||||||
#define NC_VLEN 13 /* used internally for vlen types */
|
#define NC_VLEN 13 /* used internally for vlen types */
|
||||||
|
@ -13,22 +13,28 @@
|
|||||||
/* Compare two netcdf types for equality. Must have the ncids as well,
|
/* Compare two netcdf types for equality. Must have the ncids as well,
|
||||||
to find user-defined types. */
|
to find user-defined types. */
|
||||||
static int
|
static int
|
||||||
NC_compare_nc_types(int ncid1, int typeid1,
|
NC_compare_nc_types(int ncid1, int typeid1, int ncid2, int typeid2,
|
||||||
int ncid2, int typeid2, int *equalp)
|
int *equalp)
|
||||||
{
|
{
|
||||||
int ret = NC_NOERR;
|
int ret = NC_NOERR;
|
||||||
if(equalp == NULL) return NC_NOERR;
|
|
||||||
|
/* If you don't care about the answer, neither do I! */
|
||||||
|
if(equalp == NULL)
|
||||||
|
return NC_NOERR;
|
||||||
|
|
||||||
/* Assume the types are not equal. If we find any inequality, then
|
/* Assume the types are not equal. If we find any inequality, then
|
||||||
exit with NC_NOERR and we're done. */
|
exit with NC_NOERR and we're done. */
|
||||||
*equalp = 0;
|
*equalp = 0;
|
||||||
|
|
||||||
/* Atomic types are so easy! */
|
/* Atomic types are so easy! */
|
||||||
if (typeid1 <= ATOMICTYPEMAX) {
|
if (typeid1 <= NC_MAX_ATOMIC_TYPE)
|
||||||
if (typeid2 != typeid1) return NC_NOERR;
|
{
|
||||||
|
if (typeid2 != typeid1)
|
||||||
|
return NC_NOERR;
|
||||||
*equalp = 1;
|
*equalp = 1;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
int i, ret, equal1;
|
int i, ret, equal1;
|
||||||
char name1[NC_MAX_NAME];
|
char name1[NC_MAX_NAME];
|
||||||
char name2[NC_MAX_NAME];
|
char name2[NC_MAX_NAME];
|
||||||
@ -44,69 +50,81 @@ NC_compare_nc_types(int ncid1, int typeid1,
|
|||||||
int dimsizes1[NC_MAX_VAR_DIMS];
|
int dimsizes1[NC_MAX_VAR_DIMS];
|
||||||
int dimsizes2[NC_MAX_VAR_DIMS];
|
int dimsizes2[NC_MAX_VAR_DIMS];
|
||||||
|
|
||||||
ret = nc_inq_user_type(ncid1,typeid1,name1,&size1,&base1,&nelems1,&class1);
|
/* Find out about the two types. */
|
||||||
if(ret) return ret;
|
if ((ret = nc_inq_user_type(ncid1, typeid1, name1, &size1,
|
||||||
ret = nc_inq_user_type(ncid2,typeid2,name2,&size2,&base2,&nelems2,&class2);
|
&base1, &nelems1, &class1)))
|
||||||
if(ret) return ret;
|
return ret;
|
||||||
|
if ((ret = nc_inq_user_type(ncid2, typeid2, name2, &size2,
|
||||||
|
&base2, &nelems2, &class2)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* Check the obvious. */
|
/* Check the obvious. */
|
||||||
if(size1 != size2 || class1 != class2 || strcmp(name1,name2))
|
if(size1 != size2 || class1 != class2 || strcmp(name1,name2))
|
||||||
return NC_NOERR;
|
return NC_NOERR;
|
||||||
|
|
||||||
/* Check user-defined types in detail. */
|
/* Check user-defined types in detail. */
|
||||||
switch(class1) {
|
switch(class1)
|
||||||
|
{
|
||||||
case NC_VLEN:
|
case NC_VLEN:
|
||||||
if(base1 <= NC_STRING) {
|
if((ret = NC_compare_nc_types(ncid1, base1, ncid2,
|
||||||
if(base1 != base2) return NC_NOERR;
|
base1, &equal1)))
|
||||||
} else {
|
return ret;
|
||||||
/* User defined type in VLEN! */
|
if(!equal1)
|
||||||
if((ret = NC_compare_nc_types(ncid1,base1,ncid2,base1,&equal1)))
|
return NC_NOERR;
|
||||||
return ret;
|
|
||||||
if(!equal1) return NC_NOERR;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case NC_OPAQUE:
|
case NC_OPAQUE:
|
||||||
/* Already checked size above. */
|
/* Already checked size above. */
|
||||||
break;
|
break;
|
||||||
case NC_ENUM:
|
case NC_ENUM:
|
||||||
if(base1 != base2 || nelems1 != nelems2) return NC_NOERR;
|
if(base1 != base2 || nelems1 != nelems2) return NC_NOERR;
|
||||||
value1 = malloc(size1);
|
|
||||||
value2 = malloc(size2);
|
if (!(value1 = malloc(size1)))
|
||||||
for(i=0;i<nelems1;i++) {
|
return NC_ENOMEM;
|
||||||
ret = nc_inq_enum_member(ncid1,typeid1,i,name1,value1);
|
if (!(value2 = malloc(size2)))
|
||||||
if(ret) return ret;
|
return NC_ENOMEM;
|
||||||
ret = nc_inq_enum_member(ncid2,typeid2,i,name2,value2);
|
|
||||||
if(ret) goto enumdone;
|
for(i = 0; i < nelems1; i++)
|
||||||
if(strcmp(name1,name2) != 0
|
{
|
||||||
|| memcmp(value1,value2,size1) != 0)
|
if ((ret = nc_inq_enum_member(ncid1, typeid1, i, name1,
|
||||||
return NC_NOERR;
|
value1)) ||
|
||||||
|
(ret = nc_inq_enum_member(ncid2, typeid2, i, name2,
|
||||||
|
value2)) ||
|
||||||
|
strcmp(name1, name2) || memcmp(value1, value2, size1))
|
||||||
|
{
|
||||||
|
free(value1);
|
||||||
|
free(value2);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
enumdone:
|
free(value1);
|
||||||
free(value1); free(value2);
|
free(value2);
|
||||||
break;
|
break;
|
||||||
case NC_COMPOUND:
|
case NC_COMPOUND:
|
||||||
if(nelems1 != nelems2) return NC_NOERR;
|
if(nelems1 != nelems2)
|
||||||
|
return NC_NOERR;
|
||||||
|
|
||||||
/* Compare each field. Each must be equal! */
|
/* Compare each field. Each must be equal! */
|
||||||
for(i=0;i<nelems1;i++) {
|
for(i = 0; i < nelems1; i++)
|
||||||
|
{
|
||||||
int j;
|
int j;
|
||||||
ret = nc_inq_compound_field(ncid1,typeid1,i,name1,&offset1,&ftype1,&ndims1,dimsizes1);
|
if ((ret = nc_inq_compound_field(ncid1, typeid1, i, name1, &offset1,
|
||||||
if(ret) return ret;
|
&ftype1, &ndims1, dimsizes1)))
|
||||||
ret = nc_inq_compound_field(ncid2,typeid2,i,name2,&offset2,&ftype2,&ndims2,dimsizes2);
|
return ret;
|
||||||
if(ret) return ret;
|
if ((ret = nc_inq_compound_field(ncid2, typeid2, i, name2, &offset2,
|
||||||
if(ndims1 != ndims2) return NC_NOERR;
|
&ftype2, &ndims2, dimsizes2)))
|
||||||
for(j=0;j<ndims1;j++) {
|
return ret;
|
||||||
if(dimsizes1[j] != dimsizes2[j]) return NC_NOERR;
|
if(ndims1 != ndims2)
|
||||||
}
|
return NC_NOERR;
|
||||||
/* Handle atomic types. */
|
for(j = 0; j < ndims1;j++)
|
||||||
if(ftype1 <= NC_STRING) {
|
if(dimsizes1[j] != dimsizes2[j])
|
||||||
if(ftype1 != ftype2) return NC_NOERR;
|
return NC_NOERR;
|
||||||
} else { /* Dang! *More* user-defined types!
|
|
||||||
Look up the field types in each file. */
|
/* Compare user-defined field types. */
|
||||||
/* Compare user-defined field types. */
|
if((ret = NC_compare_nc_types(ncid1, ftype1, ncid2, ftype2,
|
||||||
if((ret = NC_compare_nc_types(ncid1,ftype1,ncid2,ftype2,&equal1)))
|
&equal1)))
|
||||||
return ret;
|
return ret;
|
||||||
if(!equal1) return NC_NOERR;
|
if(!equal1)
|
||||||
}
|
return NC_NOERR;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -158,15 +176,19 @@ NC_rec_find_nc_type(int ncid1, nc_type tid1, int ncid2, nc_type* tid2)
|
|||||||
return ret;
|
return ret;
|
||||||
if (nids)
|
if (nids)
|
||||||
{
|
{
|
||||||
if (!(ids = (int*)malloc(nids*sizeof(int))))
|
if (!(ids = (int *)malloc(nids * sizeof(int))))
|
||||||
return NC_ENOMEM;
|
return NC_ENOMEM;
|
||||||
if ((ret = nc_inq_grps(ncid1,&nids,ids)))
|
if ((ret = nc_inq_grps(ncid1, &nids, ids)))
|
||||||
|
{
|
||||||
|
free(ids);
|
||||||
return ret;
|
return ret;
|
||||||
for(i = 0; i < nids; i++)
|
}
|
||||||
|
for (i = 0; i < nids; i++)
|
||||||
{
|
{
|
||||||
ret = NC_rec_find_nc_type(ncid1, tid1, ids[i], tid2);
|
ret = NC_rec_find_nc_type(ncid1, tid1, ids[i], tid2);
|
||||||
if(ret && ret != NC_EBADTYPE) break;
|
if (ret && ret != NC_EBADTYPE)
|
||||||
if(tid2 && *tid2 != 0) /* found */
|
break;
|
||||||
|
if (tid2 && *tid2 != 0) /* found */
|
||||||
{
|
{
|
||||||
free(ids);
|
free(ids);
|
||||||
return NC_NOERR;
|
return NC_NOERR;
|
||||||
@ -183,11 +205,16 @@ static int
|
|||||||
NC_find_equal_type(int ncid1, nc_type xtype1, int ncid2, nc_type *xtype2)
|
NC_find_equal_type(int ncid1, nc_type xtype1, int ncid2, nc_type *xtype2)
|
||||||
{
|
{
|
||||||
int ret = NC_NOERR;
|
int ret = NC_NOERR;
|
||||||
|
|
||||||
/* Check input */
|
/* Check input */
|
||||||
if(xtype1 <= NC_NAT) return NC_EINVAL;
|
if(xtype1 <= NC_NAT)
|
||||||
|
return NC_EINVAL;
|
||||||
|
|
||||||
/* Handle atomic types. */
|
/* Handle atomic types. */
|
||||||
if (xtype1 <= ATOMICTYPEMAX) {
|
if (xtype1 <= NC_MAX_ATOMIC_TYPE)
|
||||||
if(xtype2) *xtype2 = xtype1;
|
{
|
||||||
|
if(xtype2)
|
||||||
|
*xtype2 = xtype1;
|
||||||
return NC_NOERR;
|
return NC_NOERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,28 +465,26 @@ nc_copy_att(int ncid_in, int varid_in, const char *name,
|
|||||||
size_t len;
|
size_t len;
|
||||||
void *data=NULL;
|
void *data=NULL;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
#ifdef USE_NETCDF4
|
|
||||||
LOG((2, "nc_copy_att: ncid_in 0x%x varid_in %d name %s",
|
LOG((2, "nc_copy_att: ncid_in 0x%x varid_in %d name %s",
|
||||||
ncid_in, varid_in, name));
|
ncid_in, varid_in, name));
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Find out about the attribute and allocate memory for the
|
/* Find out about the attribute and allocate memory for the
|
||||||
data. */
|
data. */
|
||||||
if ((res = nc_inq_att(ncid_in, varid_in, name, &xtype, &len)))
|
if ((res = nc_inq_att(ncid_in, varid_in, name, &xtype, &len)))
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
/* Can't copy to same var in same file. */
|
/* Can't copy to same var in same file. */
|
||||||
if (ncid_in == ncid_out && varid_in == varid_out)
|
if (ncid_in == ncid_out && varid_in == varid_out)
|
||||||
return NC_NOERR;
|
return NC_NOERR;
|
||||||
|
|
||||||
#ifndef USE_NETCDF4
|
if (xtype < NC_STRING)
|
||||||
if (xtype <= NC_DOUBLE) {
|
{
|
||||||
/* Handle atomic types. */
|
/* Handle atomic types. */
|
||||||
if (len) {
|
if (len)
|
||||||
if (!(data = malloc(len * NC_atomictypelen(xtype))))
|
if (!(data = malloc(len * NC_atomictypelen(xtype))))
|
||||||
return NC_ENOMEM;
|
return NC_ENOMEM;
|
||||||
}
|
|
||||||
res = nc_get_att(ncid_in, varid_in, name, data);
|
res = nc_get_att(ncid_in, varid_in, name, data);
|
||||||
if (!res)
|
if (!res)
|
||||||
res = nc_put_att(ncid_out, varid_out, name, xtype,
|
res = nc_put_att(ncid_out, varid_out, name, xtype,
|
||||||
@ -467,20 +492,9 @@ nc_copy_att(int ncid_in, int varid_in, const char *name,
|
|||||||
if (len)
|
if (len)
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
#else /*!USE_NETCDF4*/
|
#ifdef USE_NETCDF4
|
||||||
if(xtype < NC_STRING) {
|
else if (xtype == NC_STRING)
|
||||||
/* Handle atomic types. */
|
{
|
||||||
if (len)
|
|
||||||
if (!(data = malloc(len * NC_atomictypelen(xtype))))
|
|
||||||
return NC_ENOMEM;
|
|
||||||
|
|
||||||
res = nc_get_att(ncid_in, varid_in, name, data);
|
|
||||||
if (!res)
|
|
||||||
res = nc_put_att(ncid_out, varid_out, name, xtype,
|
|
||||||
len, data);
|
|
||||||
if (len)
|
|
||||||
free(data);
|
|
||||||
} else if (xtype == NC_STRING) {
|
|
||||||
/* Copy string attributes. */
|
/* Copy string attributes. */
|
||||||
char **str_data;
|
char **str_data;
|
||||||
if (!(str_data = malloc(sizeof(char *) * len)))
|
if (!(str_data = malloc(sizeof(char *) * len)))
|
||||||
@ -491,7 +505,9 @@ nc_copy_att(int ncid_in, int varid_in, const char *name,
|
|||||||
(const char **)str_data);
|
(const char **)str_data);
|
||||||
nc_free_string(len, str_data);
|
nc_free_string(len, str_data);
|
||||||
free(str_data);
|
free(str_data);
|
||||||
} else/*x*/ {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* Copy user-defined type attributes. */
|
/* Copy user-defined type attributes. */
|
||||||
int class;
|
int class;
|
||||||
size_t size;
|
size_t size;
|
||||||
@ -503,33 +519,35 @@ nc_copy_att(int ncid_in, int varid_in, const char *name,
|
|||||||
which we had to "duplicate" here */
|
which we had to "duplicate" here */
|
||||||
if ((res = NC_find_equal_type(ncid_in, xtype, ncid_out, &xtype_out)))
|
if ((res = NC_find_equal_type(ncid_in, xtype, ncid_out, &xtype_out)))
|
||||||
return res;
|
return res;
|
||||||
if(xtype_out != 0) {
|
if (xtype_out)
|
||||||
|
{
|
||||||
/* We found an equal type! */
|
/* We found an equal type! */
|
||||||
if((res = nc_inq_user_type(ncid_in, xtype, NULL, &size,
|
if ((res = nc_inq_user_type(ncid_in, xtype, NULL, &size,
|
||||||
NULL, NULL, &class)))
|
NULL, NULL, &class)))
|
||||||
return res;
|
return res;
|
||||||
if(class == NC_VLEN) { /* VLENs are different... */
|
if (class == NC_VLEN) /* VLENs are different... */
|
||||||
|
{
|
||||||
nc_vlen_t *vldata;
|
nc_vlen_t *vldata;
|
||||||
int i;
|
int i;
|
||||||
if(!(vldata = malloc(sizeof(nc_vlen_t) * len)))
|
if (!(vldata = malloc(sizeof(nc_vlen_t) * len)))
|
||||||
return NC_ENOMEM;
|
return NC_ENOMEM;
|
||||||
if((res = nc_get_att(ncid_in, varid_in, name, vldata)))
|
if ((res = nc_get_att(ncid_in, varid_in, name, vldata)))
|
||||||
return res;
|
return res;
|
||||||
if((res = nc_put_att(ncid_out, varid_out, name, xtype_out,
|
if ((res = nc_put_att(ncid_out, varid_out, name, xtype_out,
|
||||||
len, vldata)))
|
len, vldata)))
|
||||||
return res;
|
return res;
|
||||||
for(i=0;i<len;i++) {
|
for (i = 0; i < len; i++)
|
||||||
if((res = nc_free_vlen(&vldata[i]))) return res;
|
if((res = nc_free_vlen(&vldata[i])))
|
||||||
}
|
return res;
|
||||||
free(vldata);
|
free(vldata);
|
||||||
} else {/* not VLEN */
|
}
|
||||||
if(!(data = malloc(size * len)))
|
else /* not VLEN */
|
||||||
|
{
|
||||||
|
if (!(data = malloc(size * len)))
|
||||||
return NC_ENOMEM;
|
return NC_ENOMEM;
|
||||||
if((res = nc_get_att(ncid_in, varid_in, name, data)))
|
res = nc_get_att(ncid_in, varid_in, name, data);
|
||||||
return res;
|
if (!res)
|
||||||
if((res = nc_put_att(ncid_out, varid_out, name, xtype_out,
|
res = nc_put_att(ncid_out, varid_out, name, xtype_out, len, data);
|
||||||
len, data)))
|
|
||||||
return res;
|
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,15 +14,13 @@ list='tst_h_dimscales tst_h_files '\
|
|||||||
'tst_h_grps tst_h_wrt_cmp tst_h_rd_cmp tst_h_vl tst_h_atts '\
|
'tst_h_grps tst_h_wrt_cmp tst_h_rd_cmp tst_h_vl tst_h_atts '\
|
||||||
'tst_h_dimscales3 tst_h_files2 tst_h_compounds '\
|
'tst_h_dimscales3 tst_h_files2 tst_h_compounds '\
|
||||||
'tst_h_vars tst_h_opaques tst_h_compounds2 '\
|
'tst_h_vars tst_h_opaques tst_h_compounds2 '\
|
||||||
'tst_compounds '\
|
'tst_h_vars2 tst_h_vars3 tst_h_strings tst_compounds '\
|
||||||
'tst_files tst_utf8 tst_fillbug '\
|
'tst_files tst_utf8 tst_fillbug '\
|
||||||
'tst_vars3 tst_xplatform tst_dims '\
|
'tst_vars3 tst_xplatform tst_dims '\
|
||||||
'tst_dims2 tst_dims3 tst_varms tst_unlim_vars '\
|
'tst_dims2 tst_dims3 tst_varms tst_unlim_vars '\
|
||||||
'tst_endian_fill tst_compounds2'
|
'tst_endian_fill tst_compounds2 tst_chunks tst_coords tst_vars'
|
||||||
|
|
||||||
# These don't work yet: tst_h_vars3
|
# These don't work yet: tst_h_atts3 tst_fills tst_xplatform2
|
||||||
# tst_h_strings tst_h_atts3 tst_h_vars2 tst_vars tst_fills tst_chunks
|
|
||||||
# tst_coords tst_xplatform2
|
|
||||||
|
|
||||||
for tst in $list; do
|
for tst in $list; do
|
||||||
echo ""
|
echo ""
|
||||||
|
@ -61,17 +61,18 @@ main(int argc, char **argv)
|
|||||||
if (strcmp(data_in[i], "")) ERR;
|
if (strcmp(data_in[i], "")) ERR;
|
||||||
if (strcmp(data_in[DATA_START], data_out[0])) ERR;
|
if (strcmp(data_in[DATA_START], data_out[0])) ERR;
|
||||||
|
|
||||||
/* Close everything up. */
|
/* Close everything up. Don't forget to free the string! */
|
||||||
|
if (nc_free_string(DATA_START + 1, data_in)) ERR;
|
||||||
if (nc_close(ncid)) ERR;
|
if (nc_close(ncid)) ERR;
|
||||||
|
|
||||||
/* Now re-open file, read data, and check values again. */
|
/* Now re-open file, read data, and check values again. */
|
||||||
if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
|
if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
|
||||||
if (nc_inq_varid(ncid, STRING_VAR_NAME, &varid_in)) ERR;
|
if (nc_inq_varid(ncid, STRING_VAR_NAME, &varid_in)) ERR;
|
||||||
if (nc_get_att_string(ncid, varid_in, "_FillValue", (char **)missing_val_in)) ERR;
|
if (nc_get_att_string(ncid, varid_in, "_FillValue", (char **)missing_val_in)) ERR;
|
||||||
if (strcmp(missing_val[0], missing_val_in[0])) ERR;
|
if (strcmp(missing_val[0], missing_val_in[0])) ERR;
|
||||||
if (nc_free_string(FILLVALUE_LEN, (char **)missing_val_in)) ERR;
|
/*if (nc_free_string(FILLVALUE_LEN, (char **)missing_val_in[0])) ERR;*/
|
||||||
if (nc_close(ncid)) ERR;
|
if (nc_close(ncid)) ERR;
|
||||||
free(data_in);
|
free(data_in);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUMMARIZE_ERR;
|
SUMMARIZE_ERR;
|
||||||
|
@ -295,6 +295,7 @@ main(int argc, char **argv)
|
|||||||
nc_vlen_t vlen_of_comp_out[DIM1_LEN];
|
nc_vlen_t vlen_of_comp_out[DIM1_LEN];
|
||||||
struct s2 comp_array_of_comp_out[DIM2_LEN];
|
struct s2 comp_array_of_comp_out[DIM2_LEN];
|
||||||
struct s3 comp_array_of_vlen_of_comp_out[DIM3_LEN];
|
struct s3 comp_array_of_vlen_of_comp_out[DIM3_LEN];
|
||||||
|
char zero = 0;
|
||||||
|
|
||||||
printf("\nTesting nested types across platforms.\n");
|
printf("\nTesting nested types across platforms.\n");
|
||||||
|
|
||||||
@ -346,16 +347,16 @@ main(int argc, char **argv)
|
|||||||
/* Create a simple compound type which has different sizes on
|
/* Create a simple compound type which has different sizes on
|
||||||
* different platforms - our old friend struct s1. */
|
* different platforms - our old friend struct s1. */
|
||||||
if (nc_def_compound(ncid, sizeof(struct s1), S1_TYPE_NAME, &s1_typeid)) ERR;
|
if (nc_def_compound(ncid, sizeof(struct s1), S1_TYPE_NAME, &s1_typeid)) ERR;
|
||||||
if (nc_insert_compound(ncid, s1_typeid, X_NAME,
|
if (nc_insert_compound(ncid, s1_typeid, X_NAME,
|
||||||
NC_COMPOUND_OFFSET(struct s1, x), NC_FLOAT)) ERR;
|
NC_COMPOUND_OFFSET(struct s1, x), NC_FLOAT)) ERR;
|
||||||
if (nc_insert_compound(ncid, s1_typeid, Y_NAME,
|
if (nc_insert_compound(ncid, s1_typeid, Y_NAME,
|
||||||
NC_COMPOUND_OFFSET(struct s1, y), NC_DOUBLE)) ERR;
|
NC_COMPOUND_OFFSET(struct s1, y), NC_DOUBLE)) ERR;
|
||||||
|
|
||||||
/* Now make a new type: a vlen of our compound type. */
|
/* Now make a new type: a vlen of our compound type. */
|
||||||
if (nc_def_vlen(ncid, VLEN_NAME, s1_typeid, &vlen_typeid)) ERR;
|
if (nc_def_vlen(ncid, VLEN_NAME, s1_typeid, &vlen_typeid)) ERR;
|
||||||
|
|
||||||
/* Write the output data as an attribute. */
|
/* Write the output data as an attribute. */
|
||||||
if (nc_put_att(ncid, NC_GLOBAL, VLEN_ATT_NAME, vlen_typeid,
|
if (nc_put_att(ncid, NC_GLOBAL, VLEN_ATT_NAME, vlen_typeid,
|
||||||
DIM1_LEN, vlen_of_comp_out)) ERR;
|
DIM1_LEN, vlen_of_comp_out)) ERR;
|
||||||
|
|
||||||
/* How does it look? */
|
/* How does it look? */
|
||||||
@ -379,7 +380,7 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
strcat(file_in, getenv("srcdir"));
|
strcat(file_in, getenv("srcdir"));
|
||||||
strcat(file_in, "/");
|
strcat(file_in, "/");
|
||||||
}
|
}
|
||||||
strcat(file_in, REF_FILE_NAME_1);
|
strcat(file_in, REF_FILE_NAME_1);
|
||||||
|
|
||||||
/* Check out the same file, generated on buddy and included with
|
/* Check out the same file, generated on buddy and included with
|
||||||
@ -438,7 +439,7 @@ main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
strcat(file_in, getenv("srcdir"));
|
strcat(file_in, getenv("srcdir"));
|
||||||
strcat(file_in, "/");
|
strcat(file_in, "/");
|
||||||
}
|
}
|
||||||
strcat(file_in, REF_FILE_NAME_2);
|
strcat(file_in, REF_FILE_NAME_2);
|
||||||
|
|
||||||
/* Check out the same file, generated on buddy and included with
|
/* Check out the same file, generated on buddy and included with
|
||||||
|
@ -16,8 +16,6 @@ AM_CPPFLAGS += -I$(top_srcdir)/libsrc4 -I$(top_srcdir)/libsrc
|
|||||||
# Our test programs and sources. (tst_h_vl2 must come after tst_vl.)
|
# Our test programs and sources. (tst_h_vl2 must come after tst_vl.)
|
||||||
NC4_TEST_PROGS = t_type cdm_sea_soundings tst_camrun tst_vl tst_atts \
|
NC4_TEST_PROGS = t_type cdm_sea_soundings tst_camrun tst_vl tst_atts \
|
||||||
tst_atts2 tst_vars2 tst_files tst_files2
|
tst_atts2 tst_vars2 tst_files tst_files2
|
||||||
cdm_sea_soundings_SOURCES = cdm_sea_soundings.c tests.h
|
|
||||||
tst_camrun_SOURCES = tst_camrun.c tests.h
|
|
||||||
|
|
||||||
check_PROGRAMS = $(NC4_TEST_PROGS)
|
check_PROGRAMS = $(NC4_TEST_PROGS)
|
||||||
TESTS = $(NC4_TEST_PROGS)
|
TESTS = $(NC4_TEST_PROGS)
|
||||||
@ -28,16 +26,11 @@ TESTS += tst_v2
|
|||||||
endif # BUILD_V2
|
endif # BUILD_V2
|
||||||
|
|
||||||
if LARGE_FILE_TESTS
|
if LARGE_FILE_TESTS
|
||||||
tst_large_SOURCES = tst_large.c tests.h
|
|
||||||
check_PROGRAMS += tst_large
|
check_PROGRAMS += tst_large
|
||||||
TESTS += tst_large
|
TESTS += tst_large
|
||||||
endif # LARGE_FILE_TESTS
|
endif # LARGE_FILE_TESTS
|
||||||
|
|
||||||
if BUILD_BENCHMARKS
|
if BUILD_BENCHMARKS
|
||||||
bm_file_SOURCES = bm_file.c tests.h
|
|
||||||
tst_create_files_SOURCES = tst_create_files.c tests.h
|
|
||||||
tst_ar4_SOURCES = tst_ar4.c tests.h
|
|
||||||
tst_chunks_SOURCES = tst_chunks.c tests.h
|
|
||||||
check_PROGRAMS += tst_create_files bm_file tst_chunks tst_ar4 \
|
check_PROGRAMS += tst_create_files bm_file tst_chunks tst_ar4 \
|
||||||
tst_ar4_3d tst_ar4_4d
|
tst_ar4_3d tst_ar4_4d
|
||||||
TESTS += tst_ar4_3d tst_create_files run_bm_test1.sh run_bm_elena.sh \
|
TESTS += tst_ar4_3d tst_create_files run_bm_test1.sh run_bm_elena.sh \
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
$Id: cdm_sea_soundings.c,v 1.5 2010/05/25 13:53:04 ed Exp $
|
$Id: cdm_sea_soundings.c,v 1.5 2010/05/25 13:53:04 ed Exp $
|
||||||
*/
|
*/
|
||||||
#include <tests.h>
|
#include <nc_tests.h>
|
||||||
|
|
||||||
#define FILE_NAME "cdm_sea_soundings.nc"
|
#define FILE_NAME "cdm_sea_soundings.nc"
|
||||||
#define DIM_NAME "Sounding"
|
#define DIM_NAME "Sounding"
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
/* This is part of the netCDF package.
|
|
||||||
Copyright 2005 University Corporation for Atmospheric Research/Unidata
|
|
||||||
See COPYRIGHT file for conditions of use.
|
|
||||||
|
|
||||||
Common includes, defines, etc., for test code in the nc_test4
|
|
||||||
directory.
|
|
||||||
|
|
||||||
$Id: tests.h,v 1.6 2010/05/25 13:53:04 ed Exp $
|
|
||||||
*/
|
|
||||||
#ifndef _NC_TEST4_TESTS_
|
|
||||||
#define _NC_TEST4_TESTS_
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifdef USE_PARALLEL
|
|
||||||
#include <netcdf_par.h>
|
|
||||||
#include <mpi.h>
|
|
||||||
#ifndef MPI_FILE_NULL /*MPIO may be defined in mpi.h already */
|
|
||||||
#include <mpio.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#include <netcdf.h>
|
|
||||||
|
|
||||||
int total_err = 0, err = 0;
|
|
||||||
|
|
||||||
/* This is handy for print statements. */
|
|
||||||
char *format_name[] = {"", "classic", "64-bit offset", "netCDF-4", "netCDF-4 strict NC3"};
|
|
||||||
|
|
||||||
#define BAIL(e) do { \
|
|
||||||
printf ("Bailing out in file %s, line %d, error:%s.\n", __FILE__, __LINE__, nc_strerror(e)); \
|
|
||||||
return -1; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define ERR do { \
|
|
||||||
fflush(stdout); /* Make sure our stdout is synced with stderr. */ \
|
|
||||||
err++; \
|
|
||||||
fprintf(stderr, "unexpected result, %s, line: %d\n", __FILE__, __LINE__); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define SUMMARIZE_ERR do { \
|
|
||||||
if (err) \
|
|
||||||
{ \
|
|
||||||
printf("%d failures\n", err); \
|
|
||||||
total_err += err; \
|
|
||||||
err = 0; \
|
|
||||||
} \
|
|
||||||
else \
|
|
||||||
printf("ok.\n"); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
/* Print out our number of errors, if any, and exit badly. */
|
|
||||||
#define FINAL_RESULTS do { \
|
|
||||||
if (total_err) \
|
|
||||||
{ \
|
|
||||||
printf("%d errors detected! Sorry!\n", total_err); \
|
|
||||||
return 2; \
|
|
||||||
} \
|
|
||||||
printf("*** Tests successful!\n"); \
|
|
||||||
return 0; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#endif /* _NC_TEST4_TESTS_ */
|
|
@ -18,6 +18,70 @@ int
|
|||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
printf("\n*** Testing netcdf-4 attribute copies.\n");
|
printf("\n*** Testing netcdf-4 attribute copies.\n");
|
||||||
|
printf("*** testing compound attribute copy to different type of same name...");
|
||||||
|
{
|
||||||
|
#define CMP_NAME1 "Ireland"
|
||||||
|
#define I1_NAME "Cork"
|
||||||
|
#define I2_NAME "Dublin"
|
||||||
|
#define DIM_LEN 3
|
||||||
|
#define ATT_NAME3 "Rain"
|
||||||
|
#define NUM_FILES 2
|
||||||
|
|
||||||
|
int ncid[NUM_FILES], typeid;
|
||||||
|
char file_name[NUM_FILES][NC_MAX_NAME + 1] = {FILE_NAME1, FILE_NAME2};
|
||||||
|
int i;
|
||||||
|
struct s1
|
||||||
|
{
|
||||||
|
int i1;
|
||||||
|
int i2;
|
||||||
|
};
|
||||||
|
struct s1 data[DIM_LEN];
|
||||||
|
struct s2
|
||||||
|
{
|
||||||
|
short i1;
|
||||||
|
int i2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Create some phony data. */
|
||||||
|
for (i = 0; i < DIM_LEN; i++)
|
||||||
|
{
|
||||||
|
data[i].i1 = 32768;
|
||||||
|
data[i].i2 = 32767;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create two files with different compound types of the same name. */
|
||||||
|
for (i = 0; i < NUM_FILES; i++)
|
||||||
|
if (nc_create(file_name[i], NC_NETCDF4, &ncid[i])) ERR;
|
||||||
|
|
||||||
|
/* Define s1 in file 1. */
|
||||||
|
if (nc_def_compound(ncid[0], sizeof(struct s1), CMP_NAME1, &typeid)) ERR;
|
||||||
|
if (nc_insert_compound(ncid[0], typeid, I1_NAME,
|
||||||
|
NC_COMPOUND_OFFSET(struct s1, i1), NC_INT)) ERR;
|
||||||
|
if (nc_insert_compound(ncid[0], typeid, I2_NAME,
|
||||||
|
NC_COMPOUND_OFFSET(struct s1, i2), NC_INT)) ERR;
|
||||||
|
|
||||||
|
/* Define s2 in file 2, but named the same as s1. */
|
||||||
|
if (nc_def_compound(ncid[1], sizeof(struct s2), CMP_NAME1, &typeid)) ERR;
|
||||||
|
if (nc_insert_compound(ncid[1], typeid, I1_NAME,
|
||||||
|
NC_COMPOUND_OFFSET(struct s2, i1), NC_SHORT)) ERR;
|
||||||
|
if (nc_insert_compound(ncid[1], typeid, I2_NAME,
|
||||||
|
NC_COMPOUND_OFFSET(struct s2, i2), NC_INT)) ERR;
|
||||||
|
|
||||||
|
|
||||||
|
/* Write an att in one file. */
|
||||||
|
if (nc_put_att(ncid[0], NC_GLOBAL, ATT_NAME3, typeid, DIM_LEN,
|
||||||
|
data)) ERR;
|
||||||
|
|
||||||
|
/* Try to copy. It must fail, because the two types are not the
|
||||||
|
* same. */
|
||||||
|
if (nc_copy_att(ncid[0], NC_GLOBAL, ATT_NAME3, ncid[1],
|
||||||
|
NC_GLOBAL) != NC_EBADTYPE) ERR;
|
||||||
|
|
||||||
|
/* Close the files. */
|
||||||
|
for (i = 0; i < NUM_FILES; i++)
|
||||||
|
if (nc_close(ncid[i])) ERR;
|
||||||
|
}
|
||||||
|
SUMMARIZE_ERR;
|
||||||
printf("*** testing string attribute copy...");
|
printf("*** testing string attribute copy...");
|
||||||
{
|
{
|
||||||
#define ATT_NAME "Irish_Leader"
|
#define ATT_NAME "Irish_Leader"
|
||||||
@ -138,70 +202,6 @@ main(int argc, char **argv)
|
|||||||
if (nc_close(ncid[1])) ERR;
|
if (nc_close(ncid[1])) ERR;
|
||||||
}
|
}
|
||||||
SUMMARIZE_ERR;
|
SUMMARIZE_ERR;
|
||||||
printf("*** testing compound attribute copy to different type of same name...");
|
|
||||||
{
|
|
||||||
#define CMP_NAME1 "Ireland"
|
|
||||||
#define I1_NAME "Cork"
|
|
||||||
#define I2_NAME "Dublin"
|
|
||||||
#define DIM_LEN 3
|
|
||||||
#define ATT_NAME3 "Rain"
|
|
||||||
#define NUM_FILES 2
|
|
||||||
|
|
||||||
int ncid[NUM_FILES], typeid;
|
|
||||||
char file_name[NUM_FILES][NC_MAX_NAME + 1] = {FILE_NAME1, FILE_NAME2};
|
|
||||||
int i;
|
|
||||||
struct s1
|
|
||||||
{
|
|
||||||
int i1;
|
|
||||||
int i2;
|
|
||||||
};
|
|
||||||
struct s1 data[DIM_LEN];
|
|
||||||
struct s2
|
|
||||||
{
|
|
||||||
short i1;
|
|
||||||
int i2;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Create some phony data. */
|
|
||||||
for (i = 0; i < DIM_LEN; i++)
|
|
||||||
{
|
|
||||||
data[i].i1 = 32768;
|
|
||||||
data[i].i2 = 32767;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create two files with different compound types of the same name. */
|
|
||||||
for (i = 0; i < NUM_FILES; i++)
|
|
||||||
if (nc_create(file_name[i], NC_NETCDF4, &ncid[i])) ERR;
|
|
||||||
|
|
||||||
/* Define s1 in file 1. */
|
|
||||||
if (nc_def_compound(ncid[0], sizeof(struct s1), CMP_NAME1, &typeid)) ERR;
|
|
||||||
if (nc_insert_compound(ncid[0], typeid, I1_NAME,
|
|
||||||
NC_COMPOUND_OFFSET(struct s1, i1), NC_INT)) ERR;
|
|
||||||
if (nc_insert_compound(ncid[0], typeid, I2_NAME,
|
|
||||||
NC_COMPOUND_OFFSET(struct s1, i2), NC_INT)) ERR;
|
|
||||||
|
|
||||||
/* Define s2 in file 2, but named the same as s1. */
|
|
||||||
if (nc_def_compound(ncid[1], sizeof(struct s2), CMP_NAME1, &typeid)) ERR;
|
|
||||||
if (nc_insert_compound(ncid[1], typeid, I1_NAME,
|
|
||||||
NC_COMPOUND_OFFSET(struct s2, i1), NC_SHORT)) ERR;
|
|
||||||
if (nc_insert_compound(ncid[1], typeid, I2_NAME,
|
|
||||||
NC_COMPOUND_OFFSET(struct s2, i2), NC_INT)) ERR;
|
|
||||||
|
|
||||||
|
|
||||||
/* Write an att in one file. */
|
|
||||||
if (nc_put_att(ncid[0], NC_GLOBAL, ATT_NAME3, typeid, DIM_LEN,
|
|
||||||
data)) ERR;
|
|
||||||
|
|
||||||
/* Try to copy. It must fail, because the two types are not the
|
|
||||||
* same. */
|
|
||||||
if (nc_copy_att(ncid[0], NC_GLOBAL, ATT_NAME3, ncid[1],
|
|
||||||
NC_GLOBAL) != NC_EBADTYPE) ERR;
|
|
||||||
|
|
||||||
/* Close the files. */
|
|
||||||
for (i = 0; i < NUM_FILES; i++)
|
|
||||||
if (nc_close(ncid[i])) ERR;
|
|
||||||
}
|
|
||||||
SUMMARIZE_ERR;
|
|
||||||
printf("*** testing simple enum attribute copy...");
|
printf("*** testing simple enum attribute copy...");
|
||||||
{
|
{
|
||||||
#define DIM_LEN_10 10
|
#define DIM_LEN_10 10
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
$Id: tst_mpi_parallel.c,v 1.2 2009/08/19 15:58:57 ed Exp $
|
$Id: tst_mpi_parallel.c,v 1.2 2009/08/19 15:58:57 ed Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tests.h"
|
#include <nc_tests.h>
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
|
|
||||||
#define FILE "tst_mpi_parallel.bin"
|
#define FILE "tst_mpi_parallel.bin"
|
||||||
|
@ -9,7 +9,7 @@ Dennis Nadeau.
|
|||||||
$Id: tst_nc4perf.c,v 1.4 2009/08/19 15:58:57 ed Exp $
|
$Id: tst_nc4perf.c,v 1.4 2009/08/19 15:58:57 ed Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tests.h"
|
#include "nc_tests.h"
|
||||||
|
|
||||||
#define FILENAME "tst_nc4perf.nc"
|
#define FILENAME "tst_nc4perf.nc"
|
||||||
#define NDIMS1 2
|
#define NDIMS1 2
|
||||||
|
@ -13,7 +13,7 @@ $Id: tst_parallel.c,v 1.7 2009/08/19 15:58:57 ed Exp $
|
|||||||
* clog2TOslog2) and then used in the analysis program jumpshot. */
|
* clog2TOslog2) and then used in the analysis program jumpshot. */
|
||||||
/*#define USE_MPE 1*/
|
/*#define USE_MPE 1*/
|
||||||
|
|
||||||
#include "tests.h"
|
#include <nc_tests.h>
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
#ifdef USE_MPE
|
#ifdef USE_MPE
|
||||||
#include <mpe.h>
|
#include <mpe.h>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* clog2TOslog2) and then used in the analysis program jumpshot. */
|
* clog2TOslog2) and then used in the analysis program jumpshot. */
|
||||||
/*#define USE_MPE 1*/
|
/*#define USE_MPE 1*/
|
||||||
|
|
||||||
#include "tests.h"
|
#include <nc_tests.h>
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
#include <pnetcdf.h>
|
#include <pnetcdf.h>
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tests.h"
|
#include <nc_tests.h>
|
||||||
|
|
||||||
#define FILE_NAME "tst_parallel3.nc"
|
#define FILE_NAME "tst_parallel3.nc"
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* clog2TOslog2) and then used in the analysis program jumpshot. */
|
* clog2TOslog2) and then used in the analysis program jumpshot. */
|
||||||
/*#define USE_MPE 1*/
|
/*#define USE_MPE 1*/
|
||||||
|
|
||||||
#include "tests.h"
|
#include <nc_tests.h>
|
||||||
#include <mpi.h>
|
#include <mpi.h>
|
||||||
#ifdef USE_MPE
|
#ifdef USE_MPE
|
||||||
#include <mpe.h>
|
#include <mpe.h>
|
||||||
@ -171,7 +171,7 @@ main(int argc, char **argv)
|
|||||||
if ((ret = nc_open_par(file_name, NC_NOWRITE, comm, info, &ncid)))
|
if ((ret = nc_open_par(file_name, NC_NOWRITE, comm, info, &ncid)))
|
||||||
{
|
{
|
||||||
printf("ret = %d\n", ret);
|
printf("ret = %d\n", ret);
|
||||||
ERR;
|
ERR_RET;
|
||||||
}
|
}
|
||||||
if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
|
if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
|
||||||
if (ndims_in != NDIMS || nvars_in != 1 || natts_in != 1 ||
|
if (ndims_in != NDIMS || nvars_in != 1 || natts_in != 1 ||
|
||||||
|
@ -148,11 +148,13 @@ endif #BUILD_BENCHMARKS
|
|||||||
|
|
||||||
# Test parallel I/O.
|
# Test parallel I/O.
|
||||||
if TEST_PARALLEL
|
if TEST_PARALLEL
|
||||||
check_PROGRAMS += f90tst_parallel f90tst_parallel2 f90tst_parallel3
|
check_PROGRAMS += f90tst_parallel f90tst_parallel2 f90tst_parallel3 \
|
||||||
|
f90tst_nc4_par
|
||||||
#f90tst_parallel_fill
|
#f90tst_parallel_fill
|
||||||
f90tst_parallel_SOURCES = f90tst_parallel.f90
|
f90tst_parallel_SOURCES = f90tst_parallel.f90
|
||||||
f90tst_parallel2_SOURCES = f90tst_parallel2.f90
|
f90tst_parallel2_SOURCES = f90tst_parallel2.f90
|
||||||
f90tst_parallel3_SOURCES = f90tst_parallel3.f90
|
f90tst_parallel3_SOURCES = f90tst_parallel3.f90
|
||||||
|
f90tst_nc4_par_SOURCES = f90tst_nc4_par.f90
|
||||||
#f90tst_parallel_fill_SOURCES = f90tst_parallel_fill.f90
|
#f90tst_parallel_fill_SOURCES = f90tst_parallel_fill.f90
|
||||||
TESTS += run_f90_par_test.sh
|
TESTS += run_f90_par_test.sh
|
||||||
CLEANFILES += f90tst_parallel*.nc
|
CLEANFILES += f90tst_parallel*.nc
|
||||||
|
82
nf_test/f90tst_nc4_par.f90
Normal file
82
nf_test/f90tst_nc4_par.f90
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
! This parallel test was contributed by Jim Edwards at UCAR. Thanks Jim!
|
||||||
|
program f90tst_nc4_par
|
||||||
|
use netcdf
|
||||||
|
use mpi
|
||||||
|
implicit none
|
||||||
|
|
||||||
|
character (len = *), parameter :: FILE_NAME = "f90tst_nc4_par.nc"
|
||||||
|
integer :: nmode, ierr, fh, my_task, nprocs, i, varid
|
||||||
|
integer :: dimid(3), start(3), count(3)
|
||||||
|
real :: f(3)
|
||||||
|
|
||||||
|
|
||||||
|
call MPI_INIT(ierr)
|
||||||
|
call MPI_COMM_RANK(MPI_COMM_WORLD, my_task, ierr)
|
||||||
|
call MPI_COMM_SIZE(MPI_COMM_WORLD, nprocs, ierr)
|
||||||
|
|
||||||
|
if(nprocs/=8)then
|
||||||
|
stop 'requires 8 tasks'
|
||||||
|
end if
|
||||||
|
|
||||||
|
|
||||||
|
nmode = ior(NF90_CLOBBER,NF90_NETCDF4)
|
||||||
|
nmode = IOR(nmode, nf90_mpiio)
|
||||||
|
|
||||||
|
call handle_err(nf90_create(FILE_NAME, nmode, fh, &
|
||||||
|
comm = MPI_COMM_WORLD, info = MPI_INFO_NULL))
|
||||||
|
|
||||||
|
call handle_err(nf90_set_fill(fh, NF90_NOFILL, nmode))
|
||||||
|
|
||||||
|
|
||||||
|
call handle_err(nf90_def_dim(fh, 'dim1', 6, dimid(1)))
|
||||||
|
call handle_err(nf90_def_dim(fh, 'dim2', 4, dimid(2)))
|
||||||
|
call handle_err(nf90_def_dim(fh, 'dim3', 1, dimid(3)))
|
||||||
|
|
||||||
|
|
||||||
|
call handle_err(nf90_def_var(fh, 'var1', NF90_DOUBLE, dimid, varid))
|
||||||
|
call handle_err(nf90_enddef(fh))
|
||||||
|
|
||||||
|
|
||||||
|
do i=1,3
|
||||||
|
f(i) = my_task*3+i
|
||||||
|
end do
|
||||||
|
|
||||||
|
count = (/3,1,1/)
|
||||||
|
start(1) = mod(my_task,2)*3+1
|
||||||
|
start(2) = my_task/2+1
|
||||||
|
start(3) = 1
|
||||||
|
|
||||||
|
print *,my_task, start, count, f
|
||||||
|
|
||||||
|
call handle_err(nf90_put_var(fh, varid, f,start=start,count=count))
|
||||||
|
|
||||||
|
call handle_err(nf90_close(fh))
|
||||||
|
|
||||||
|
! Reopen the file and check it.
|
||||||
|
call handle_err(nf90_open(FILE_NAME, NF90_MPIIO, fh, &
|
||||||
|
comm = MPI_COMM_WORLD, info = MPI_INFO_NULL))
|
||||||
|
|
||||||
|
call handle_err(nf90_get_var(fh, varid, f, start=start, count=count))
|
||||||
|
do i=1,3
|
||||||
|
if (f(i) .ne. my_task*3+i) stop 3
|
||||||
|
end do
|
||||||
|
|
||||||
|
call handle_err(nf90_close(fh))
|
||||||
|
call MPI_Finalize(ierr)
|
||||||
|
|
||||||
|
contains
|
||||||
|
! This subroutine handles errors by printing an error message and
|
||||||
|
! exiting with a non-zero status.
|
||||||
|
subroutine handle_err(errcode)
|
||||||
|
use netcdf
|
||||||
|
implicit none
|
||||||
|
integer, intent(in) :: errcode
|
||||||
|
|
||||||
|
if(errcode /= nf90_noerr) then
|
||||||
|
print *, 'Error: ', trim(nf90_strerror(errcode))
|
||||||
|
stop 2
|
||||||
|
endif
|
||||||
|
end subroutine handle_err
|
||||||
|
|
||||||
|
end program f90tst_nc4_par
|
||||||
|
|
@ -22,10 +22,9 @@
|
|||||||
integer NUM_PROC
|
integer NUM_PROC
|
||||||
parameter (NUM_PROC = 4)
|
parameter (NUM_PROC = 4)
|
||||||
integer ncid, varid, dimids(MAX_DIMS)
|
integer ncid, varid, dimids(MAX_DIMS)
|
||||||
integer x_dimid, y_dimid, contig
|
integer x_dimid, y_dimid
|
||||||
integer data_out(NY / 2, NX / 2), data_in(NY / 2, NX / 2)
|
integer data_out(NY / 2, NX / 2), data_in(NY / 2, NX / 2)
|
||||||
integer mode_flag
|
integer mode_flag
|
||||||
integer nvars, ngatts, ndims, unlimdimid, file_format
|
|
||||||
integer x, y, retval
|
integer x, y, retval
|
||||||
integer p, my_rank, ierr
|
integer p, my_rank, ierr
|
||||||
integer start(MAX_DIMS), count(MAX_DIMS)
|
integer start(MAX_DIMS), count(MAX_DIMS)
|
||||||
|
@ -4,5 +4,7 @@ sleep 2
|
|||||||
mpiexec -n 4 ./f90tst_parallel
|
mpiexec -n 4 ./f90tst_parallel
|
||||||
mpiexec -n 4 ./f90tst_parallel2
|
mpiexec -n 4 ./f90tst_parallel2
|
||||||
mpiexec -n 4 ./f90tst_parallel3
|
mpiexec -n 4 ./f90tst_parallel3
|
||||||
|
mpiexec -n 8 ./f90tst_nc4_par1
|
||||||
|
mpiexec -n 8 ./f90tst_nc4_par
|
||||||
#mpiexec -n 4 ./f90tst_parallel_fill
|
#mpiexec -n 4 ./f90tst_parallel_fill
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user