merge latest trunk changes into my branch

This commit is contained in:
Russ Rew 2010-10-10 21:20:42 +00:00
commit 23226e5101
20 changed files with 298 additions and 261 deletions

View File

@ -29,6 +29,11 @@ int total_err = 0, err = 0;
char *format_name[] = {"", "classic", "64-bit offset", "netCDF-4",
"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
* test program. */
#define ERR do { \

View File

@ -63,6 +63,8 @@ extern "C" {
#define NC_UINT64 11 /* unsigned 8-byte int */
#define NC_STRING 12 /* string */
#define NC_MAX_ATOMIC_TYPE NC_STRING
/* The following are use internally in support of user-defines
* types. They are also the class returned by nc_inq_user_type. */
#define NC_VLEN 13 /* used internally for vlen types */

View File

@ -13,22 +13,28 @@
/* Compare two netcdf types for equality. Must have the ncids as well,
to find user-defined types. */
static int
NC_compare_nc_types(int ncid1, int typeid1,
int ncid2, int typeid2, int *equalp)
NC_compare_nc_types(int ncid1, int typeid1, int ncid2, int typeid2,
int *equalp)
{
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
exit with NC_NOERR and we're done. */
*equalp = 0;
/* Atomic types are so easy! */
if (typeid1 <= ATOMICTYPEMAX) {
if (typeid2 != typeid1) return NC_NOERR;
if (typeid1 <= NC_MAX_ATOMIC_TYPE)
{
if (typeid2 != typeid1)
return NC_NOERR;
*equalp = 1;
}
else {
else
{
int i, ret, equal1;
char name1[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 dimsizes2[NC_MAX_VAR_DIMS];
ret = nc_inq_user_type(ncid1,typeid1,name1,&size1,&base1,&nelems1,&class1);
if(ret) return ret;
ret = nc_inq_user_type(ncid2,typeid2,name2,&size2,&base2,&nelems2,&class2);
if(ret) return ret;
/* Find out about the two types. */
if ((ret = nc_inq_user_type(ncid1, typeid1, name1, &size1,
&base1, &nelems1, &class1)))
return ret;
if ((ret = nc_inq_user_type(ncid2, typeid2, name2, &size2,
&base2, &nelems2, &class2)))
return ret;
/* Check the obvious. */
if(size1 != size2 || class1 != class2 || strcmp(name1,name2))
return NC_NOERR;
/* Check user-defined types in detail. */
switch(class1) {
switch(class1)
{
case NC_VLEN:
if(base1 <= NC_STRING) {
if(base1 != base2) return NC_NOERR;
} else {
/* User defined type in VLEN! */
if((ret = NC_compare_nc_types(ncid1,base1,ncid2,base1,&equal1)))
return ret;
if(!equal1) return NC_NOERR;
}
if((ret = NC_compare_nc_types(ncid1, base1, ncid2,
base1, &equal1)))
return ret;
if(!equal1)
return NC_NOERR;
break;
case NC_OPAQUE:
/* Already checked size above. */
break;
case NC_ENUM:
if(base1 != base2 || nelems1 != nelems2) return NC_NOERR;
value1 = malloc(size1);
value2 = malloc(size2);
for(i=0;i<nelems1;i++) {
ret = nc_inq_enum_member(ncid1,typeid1,i,name1,value1);
if(ret) return ret;
ret = nc_inq_enum_member(ncid2,typeid2,i,name2,value2);
if(ret) goto enumdone;
if(strcmp(name1,name2) != 0
|| memcmp(value1,value2,size1) != 0)
return NC_NOERR;
if (!(value1 = malloc(size1)))
return NC_ENOMEM;
if (!(value2 = malloc(size2)))
return NC_ENOMEM;
for(i = 0; i < nelems1; i++)
{
if ((ret = nc_inq_enum_member(ncid1, typeid1, i, name1,
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(value2);
free(value1);
free(value2);
break;
case NC_COMPOUND:
if(nelems1 != nelems2) return NC_NOERR;
if(nelems1 != nelems2)
return NC_NOERR;
/* Compare each field. Each must be equal! */
for(i=0;i<nelems1;i++) {
for(i = 0; i < nelems1; i++)
{
int j;
ret = nc_inq_compound_field(ncid1,typeid1,i,name1,&offset1,&ftype1,&ndims1,dimsizes1);
if(ret) return ret;
ret = nc_inq_compound_field(ncid2,typeid2,i,name2,&offset2,&ftype2,&ndims2,dimsizes2);
if(ret) return ret;
if(ndims1 != ndims2) return NC_NOERR;
for(j=0;j<ndims1;j++) {
if(dimsizes1[j] != dimsizes2[j]) return NC_NOERR;
}
/* Handle atomic types. */
if(ftype1 <= NC_STRING) {
if(ftype1 != ftype2) return NC_NOERR;
} else { /* Dang! *More* user-defined types!
Look up the field types in each file. */
/* Compare user-defined field types. */
if((ret = NC_compare_nc_types(ncid1,ftype1,ncid2,ftype2,&equal1)))
return ret;
if(!equal1) return NC_NOERR;
}
if ((ret = nc_inq_compound_field(ncid1, typeid1, i, name1, &offset1,
&ftype1, &ndims1, dimsizes1)))
return ret;
if ((ret = nc_inq_compound_field(ncid2, typeid2, i, name2, &offset2,
&ftype2, &ndims2, dimsizes2)))
return ret;
if(ndims1 != ndims2)
return NC_NOERR;
for(j = 0; j < ndims1;j++)
if(dimsizes1[j] != dimsizes2[j])
return NC_NOERR;
/* Compare user-defined field types. */
if((ret = NC_compare_nc_types(ncid1, ftype1, ncid2, ftype2,
&equal1)))
return ret;
if(!equal1)
return NC_NOERR;
}
break;
default:
@ -158,15 +176,19 @@ NC_rec_find_nc_type(int ncid1, nc_type tid1, int ncid2, nc_type* tid2)
return ret;
if (nids)
{
if (!(ids = (int*)malloc(nids*sizeof(int))))
if (!(ids = (int *)malloc(nids * sizeof(int))))
return NC_ENOMEM;
if ((ret = nc_inq_grps(ncid1,&nids,ids)))
if ((ret = nc_inq_grps(ncid1, &nids, ids)))
{
free(ids);
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);
if(ret && ret != NC_EBADTYPE) break;
if(tid2 && *tid2 != 0) /* found */
if (ret && ret != NC_EBADTYPE)
break;
if (tid2 && *tid2 != 0) /* found */
{
free(ids);
return NC_NOERR;
@ -183,11 +205,16 @@ static int
NC_find_equal_type(int ncid1, nc_type xtype1, int ncid2, nc_type *xtype2)
{
int ret = NC_NOERR;
/* Check input */
if(xtype1 <= NC_NAT) return NC_EINVAL;
if(xtype1 <= NC_NAT)
return NC_EINVAL;
/* Handle atomic types. */
if (xtype1 <= ATOMICTYPEMAX) {
if(xtype2) *xtype2 = xtype1;
if (xtype1 <= NC_MAX_ATOMIC_TYPE)
{
if(xtype2)
*xtype2 = xtype1;
return NC_NOERR;
}
@ -438,28 +465,26 @@ nc_copy_att(int ncid_in, int varid_in, const char *name,
size_t len;
void *data=NULL;
int res;
#ifdef USE_NETCDF4
LOG((2, "nc_copy_att: ncid_in 0x%x varid_in %d name %s",
ncid_in, varid_in, name));
#endif
/* Find out about the attribute and allocate memory for the
data. */
if ((res = nc_inq_att(ncid_in, varid_in, name, &xtype, &len)))
return res;
/* Can't copy to same var in same file. */
if (ncid_in == ncid_out && varid_in == varid_out)
return NC_NOERR;
#ifndef USE_NETCDF4
if (xtype <= NC_DOUBLE) {
if (xtype < NC_STRING)
{
/* Handle atomic types. */
if (len) {
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,
@ -467,20 +492,9 @@ nc_copy_att(int ncid_in, int varid_in, const char *name,
if (len)
free(data);
}
#else /*!USE_NETCDF4*/
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) {
#ifdef USE_NETCDF4
else if (xtype == NC_STRING)
{
/* Copy string attributes. */
char **str_data;
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);
nc_free_string(len, str_data);
free(str_data);
} else/*x*/ {
}
else
{
/* Copy user-defined type attributes. */
int class;
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 */
if ((res = NC_find_equal_type(ncid_in, xtype, ncid_out, &xtype_out)))
return res;
if(xtype_out != 0) {
if (xtype_out)
{
/* 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)))
return res;
if(class == NC_VLEN) { /* VLENs are different... */
if (class == NC_VLEN) /* VLENs are different... */
{
nc_vlen_t *vldata;
int i;
if(!(vldata = malloc(sizeof(nc_vlen_t) * len)))
if (!(vldata = malloc(sizeof(nc_vlen_t) * len)))
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;
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)))
return res;
for(i=0;i<len;i++) {
if((res = nc_free_vlen(&vldata[i]))) return res;
}
for (i = 0; i < len; i++)
if((res = nc_free_vlen(&vldata[i])))
return res;
free(vldata);
} else {/* not VLEN */
if(!(data = malloc(size * len)))
}
else /* not VLEN */
{
if (!(data = malloc(size * len)))
return NC_ENOMEM;
if((res = nc_get_att(ncid_in, varid_in, name, data)))
return res;
if((res = nc_put_att(ncid_out, varid_out, name, xtype_out,
len, data)))
return res;
res = nc_get_att(ncid_in, varid_in, name, data);
if (!res)
res = nc_put_att(ncid_out, varid_out, name, xtype_out, len, data);
free(data);
}
}

View File

@ -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_dimscales3 tst_h_files2 tst_h_compounds '\
'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_vars3 tst_xplatform tst_dims '\
'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
# tst_h_strings tst_h_atts3 tst_h_vars2 tst_vars tst_fills tst_chunks
# tst_coords tst_xplatform2
# These don't work yet: tst_h_atts3 tst_fills tst_xplatform2
for tst in $list; do
echo ""

View File

@ -61,17 +61,18 @@ main(int argc, char **argv)
if (strcmp(data_in[i], "")) 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;
/* Now re-open file, read data, and check values again. */
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 (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;
free(data_in);
free(data_in);
}
SUMMARIZE_ERR;

View File

@ -295,6 +295,7 @@ main(int argc, char **argv)
nc_vlen_t vlen_of_comp_out[DIM1_LEN];
struct s2 comp_array_of_comp_out[DIM2_LEN];
struct s3 comp_array_of_vlen_of_comp_out[DIM3_LEN];
char zero = 0;
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
* different platforms - our old friend struct s1. */
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;
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;
/* Now make a new type: a vlen of our compound type. */
if (nc_def_vlen(ncid, VLEN_NAME, s1_typeid, &vlen_typeid)) ERR;
/* 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;
/* How does it look? */
@ -379,7 +380,7 @@ main(int argc, char **argv)
{
strcat(file_in, getenv("srcdir"));
strcat(file_in, "/");
}
}
strcat(file_in, REF_FILE_NAME_1);
/* 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, "/");
}
}
strcat(file_in, REF_FILE_NAME_2);
/* Check out the same file, generated on buddy and included with

View File

@ -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.)
NC4_TEST_PROGS = t_type cdm_sea_soundings tst_camrun tst_vl tst_atts \
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)
TESTS = $(NC4_TEST_PROGS)
@ -28,16 +26,11 @@ TESTS += tst_v2
endif # BUILD_V2
if LARGE_FILE_TESTS
tst_large_SOURCES = tst_large.c tests.h
check_PROGRAMS += tst_large
TESTS += tst_large
endif # LARGE_FILE_TESTS
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 \
tst_ar4_3d tst_ar4_4d
TESTS += tst_ar4_3d tst_create_files run_bm_test1.sh run_bm_elena.sh \

View File

@ -7,7 +7,7 @@
$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 DIM_NAME "Sounding"

View File

@ -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_ */

View File

@ -18,6 +18,70 @@ int
main(int argc, char **argv)
{
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...");
{
#define ATT_NAME "Irish_Leader"
@ -138,70 +202,6 @@ main(int argc, char **argv)
if (nc_close(ncid[1])) 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...");
{
#define DIM_LEN_10 10

View File

@ -7,7 +7,7 @@
$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>
#define FILE "tst_mpi_parallel.bin"

View File

@ -9,7 +9,7 @@ Dennis Nadeau.
$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 NDIMS1 2

View File

@ -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. */
/*#define USE_MPE 1*/
#include "tests.h"
#include <nc_tests.h>
#include <mpi.h>
#ifdef USE_MPE
#include <mpe.h>

View File

@ -9,7 +9,7 @@
* clog2TOslog2) and then used in the analysis program jumpshot. */
/*#define USE_MPE 1*/
#include "tests.h"
#include <nc_tests.h>
#include <mpi.h>
#include <pnetcdf.h>

View File

@ -18,7 +18,7 @@
*
*/
#include "tests.h"
#include <nc_tests.h>
#define FILE_NAME "tst_parallel3.nc"

View File

@ -9,7 +9,7 @@
* clog2TOslog2) and then used in the analysis program jumpshot. */
/*#define USE_MPE 1*/
#include "tests.h"
#include <nc_tests.h>
#include <mpi.h>
#ifdef USE_MPE
#include <mpe.h>
@ -171,7 +171,7 @@ main(int argc, char **argv)
if ((ret = nc_open_par(file_name, NC_NOWRITE, comm, info, &ncid)))
{
printf("ret = %d\n", ret);
ERR;
ERR_RET;
}
if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
if (ndims_in != NDIMS || nvars_in != 1 || natts_in != 1 ||

View File

@ -148,11 +148,13 @@ endif #BUILD_BENCHMARKS
# Test parallel I/O.
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_SOURCES = f90tst_parallel.f90
f90tst_parallel2_SOURCES = f90tst_parallel2.f90
f90tst_parallel3_SOURCES = f90tst_parallel3.f90
f90tst_nc4_par_SOURCES = f90tst_nc4_par.f90
#f90tst_parallel_fill_SOURCES = f90tst_parallel_fill.f90
TESTS += run_f90_par_test.sh
CLEANFILES += f90tst_parallel*.nc

View 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

View File

@ -22,10 +22,9 @@
integer NUM_PROC
parameter (NUM_PROC = 4)
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 mode_flag
integer nvars, ngatts, ndims, unlimdimid, file_format
integer x, y, retval
integer p, my_rank, ierr
integer start(MAX_DIMS), count(MAX_DIMS)

View File

@ -4,5 +4,7 @@ sleep 2
mpiexec -n 4 ./f90tst_parallel
mpiexec -n 4 ./f90tst_parallel2
mpiexec -n 4 ./f90tst_parallel3
mpiexec -n 8 ./f90tst_nc4_par1
mpiexec -n 8 ./f90tst_nc4_par
#mpiexec -n 4 ./f90tst_parallel_fill