1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
|
/* This is part of the netCDF package.
Copyright 2005 University Corporation for Atmospheric Research/Unidata
See COPYRIGHT file for conditions of use.
Test fix of bug involving creation of a file with PnetCDF APIs,
then opening and modifying the file with netcdf.
Author: Wei-keng Liao.
*/
#include <nc_tests.h>
#include "err_macros.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
#include <netcdf.h>
#include <netcdf_par.h>
#include <assert.h>
#define NVARS 6
#define NX 5
#define FILENAME "tst_pnetcdf.nc"
#define CHK_ERR(e) { \
if (e != NC_NOERR) { \
printf("Error at %s:%d : %s\n", __FILE__,__LINE__, nc_strerror(e)); \
goto fn_exit; \
} \
}
#define EXP_ERR(e, exp) { \
if (e != exp) { \
printf("Error at %s:%d : expect "#exp" but got %d\n", __FILE__,__LINE__, e); \
} \
}
int main(int argc, char* argv[])
{
int i, j, rank, nprocs, ncid, cmode, varid[NVARS], dimid[2], *buf;
int st, nerrs=0;
char str[32];
size_t start[2], count[2];
MPI_Comm comm=MPI_COMM_SELF;
MPI_Info info=MPI_INFO_NULL;
printf("\n*** Testing bug fix with changing PnetCDF variable offsets...");
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (nprocs > 1 && rank == 0)
printf("This test program is intended to run on ONE process\n");
if (rank > 0) goto fn_exit;
/* first, use PnetCDF to create a file with default header/variable alignment */
#ifdef DISABLE_PNETCDF_ALIGNMENT
MPI_Info_create(&info);
MPI_Info_set(info, "nc_header_align_size", "1");
MPI_Info_set(info, "nc_var_align_size", "1");
#endif
cmode = NC_CLOBBER;
st = nc_create_par(FILENAME, cmode, comm, info, &ncid);
#ifdef USE_PNETCDF
CHK_ERR(st)
#else
EXP_ERR(st, NC_ENOTBUILT)
goto fn_exit;
#endif
/* define dimension */
st = nc_def_dim(ncid, "Y", NC_UNLIMITED, &dimid[0]); CHK_ERR(st)
st = nc_def_dim(ncid, "X", NX, &dimid[1]); CHK_ERR(st)
/* Odd numbers are fixed variables, even numbers are record variables */
for (i=0; i<NVARS; i++) {
if (i%2) {
sprintf(str,"fixed_var_%d",i);
st = nc_def_var(ncid, str, NC_INT, 1, dimid+1, &varid[i]); CHK_ERR(st)
}
else {
sprintf(str,"record_var_%d",i);
st = nc_def_var(ncid, str, NC_INT, 2, dimid, &varid[i]); CHK_ERR(st)
}
}
st = nc_enddef(ncid); CHK_ERR(st)
/* Note NC_INDEPENDENT is the default */
st = nc_var_par_access(ncid, NC_GLOBAL, NC_INDEPENDENT); CHK_ERR(st)
/* write all variables */
buf = (int*) malloc(NX * sizeof(int));
for (i=0; i<NVARS; i++) {
for (j=0; j<NX; j++) buf[j] = i*10 + j;
if (i%2) {
start[0] = 0; count[0] = NX;
st = nc_put_vara_int(ncid, varid[i], start, count, buf); CHK_ERR(st)
}
else {
start[0] = 0; start[1] = 0;
count[0] = 1; count[1] = NX;
st = nc_put_vara_int(ncid, varid[i], start, count, buf); CHK_ERR(st)
}
}
st = nc_close(ncid); CHK_ERR(st)
if (info != MPI_INFO_NULL) MPI_Info_free(&info);
/* re-open the file with netCDF (parallel) and enter define mode */
st = nc_open_par(FILENAME, NC_WRITE, comm, info, &ncid); CHK_ERR(st)
st = nc_redef(ncid); CHK_ERR(st)
/* add attributes to make header grow */
for (i=0; i<NVARS; i++) {
sprintf(str, "annotation_for_var_%d",i);
st = nc_put_att_text(ncid, varid[i], "text_attr", strlen(str), str); CHK_ERR(st)
}
st = nc_enddef(ncid); CHK_ERR(st)
/* read variables and check their contents */
for (i=0; i<NVARS; i++) {
for (j=0; j<NX; j++) buf[j] = -1;
if (i%2) {
start[0] = 0; count[0] = NX;
st = nc_get_var_int(ncid, varid[i], buf); CHK_ERR(st)
for (j=0; j<NX; j++)
if (buf[j] != i*10 + j)
printf("unexpected read value var i=%d buf[j=%d]=%d should be %d\n",i,j,buf[j],i*10+j);
}
else {
start[0] = 0; start[1] = 0;
count[0] = 1; count[1] = NX;
st = nc_get_vara_int(ncid, varid[i], start, count, buf); CHK_ERR(st)
for (j=0; j<NX; j++)
if (buf[j] != i*10+j)
printf("unexpected read value var i=%d buf[j=%d]=%d should be %d\n",i,j,buf[j],i*10+j);
}
}
st = nc_close(ncid); CHK_ERR(st)
fn_exit:
MPI_Finalize();
err = nerrs;
SUMMARIZE_ERR;
FINAL_RESULTS;
return (nerrs > 0);
}
/*
Compile:
mpicc -g -o nc_pnc nc_pnc.c -lnetcdf -lcurl -lhdf5_hl -lhdf5 -lpnetcdf -lz -lm
Run:
nc_pnc
Standard Output:
At the time of this test is written, I used the following libraries.
HDF5 version 1.8.10
netCDF version 4.2.1.1 and
PnetCDF version 1.3.1
If macro DISABLE_PNETCDF_ALIGNMENT is defined (i.e. disable PnetCDF
alignment) then there is no standard output.
If macro DISABLE_PNETCDF_ALIGNMENT is NOT defined (i.e. default PnetCDF
alignment) then this test reports unexpected read values below.
unexpected read value var i=1 buf[j=0]=0 should be 10
unexpected read value var i=1 buf[j=1]=0 should be 11
unexpected read value var i=1 buf[j=2]=0 should be 12
unexpected read value var i=1 buf[j=3]=0 should be 13
unexpected read value var i=1 buf[j=4]=0 should be 14
unexpected read value var i=3 buf[j=0]=0 should be 30
unexpected read value var i=3 buf[j=1]=0 should be 31
unexpected read value var i=3 buf[j=2]=0 should be 32
unexpected read value var i=3 buf[j=3]=0 should be 33
unexpected read value var i=3 buf[j=4]=0 should be 34
unexpected read value var i=5 buf[j=0]=0 should be 50
unexpected read value var i=5 buf[j=1]=0 should be 51
unexpected read value var i=5 buf[j=2]=0 should be 52
unexpected read value var i=5 buf[j=3]=0 should be 53
unexpected read value var i=5 buf[j=4]=0 should be 54
*/
|