Beispiel #1
0
static int ex_write_object_names(int exoid, const char *type, const char *dimension_name,
                                 int dimension_var, int string_dimension, int count)
{
  int  dim[2];
  int  status;
  int  varid;
  char errmsg[MAX_ERR_LENGTH];
#if NC_HAS_HDF5
  int fill = NC_FILL_CHAR;
#endif

  if (count > 0) {
    dim[0] = dimension_var;
    dim[1] = string_dimension;

    if ((status = nc_def_var(exoid, dimension_name, NC_CHAR, 2, dim, &varid)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define %s name array in file id %d", type,
               exoid);
      ex_err(__func__, errmsg, status);
      return (status); /* exit define mode and return */
    }
#if NC_HAS_HDF5
    nc_def_var_fill(exoid, varid, 0, &fill);
#endif
  }
  return (NC_NOERR);
}
Beispiel #2
0
/***********************************************************************
 *
 * HANDLE_NC_DEF_VAR_FILL:
 *
 * EXTERNL int
 * nc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value);
 **********************************************************************/
void handle_nc_def_var_fill ( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[], op *nc_op ) {

    int ncid, varid, no_fill;
    void *fill_value;
	
    /*
     * Pointer shortcut to matrix data.
     * */
    double *pr;

    int      status;

    /*
     * Make sure that the inputs are the right type.
     * */
    check_numeric_argument_type ( prhs, nc_op->opname, 1 );
    check_numeric_argument_type ( prhs, nc_op->opname, 2 );
    check_numeric_argument_type ( prhs, nc_op->opname, 3 );
    check_numeric_argument_type ( prhs, nc_op->opname, 4 );

    pr = mxGetData ( prhs[1] );
    ncid = (int)(pr[0]);
    pr = mxGetData ( prhs[2] );
    varid = (int)(pr[0]);
    pr = mxGetData ( prhs[3] );
    no_fill = (int)(pr[0]);

    fill_value = mxGetData(prhs[4]);

	status = nc_def_var_fill(ncid,varid,no_fill,fill_value);
    plhs[0] = mexncCreateDoubleScalar ( status );

    return;
}
static int define_variable_name_variable(int exoid, const char *VARIABLE, int dimension,
                                         const char *label)
{
  char errmsg[MAX_ERR_LENGTH];
  int  dims[2];
  int  variable;
  int  status;
  int  fill = NC_FILL_CHAR;

  dims[0] = dimension;
  (void)nc_inq_dimid(exoid, DIM_STR_NAME, &dims[1]); /* Checked earlier, so known to exist */

  if ((status = nc_def_var(exoid, VARIABLE, NC_CHAR, 2, dims, &variable)) != NC_NOERR) {
    if (status == NC_ENAMEINUSE) {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: %s variable names are already defined in file id %d",
               label, exoid);
      ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
    }
    else {
      exerrval = status;
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to define %s variable names in file id %d",
               label, exoid);
      ex_err("ex_put_all_var_param_ext", errmsg, exerrval);
    }
  }
  nc_def_var_fill(exoid, variable, 0, &fill);
  return status;
}
Beispiel #4
0
static void
genbin_definespecialattributes(Symbol* var)
{
    int stat;
    Specialdata* special = &var->var.special;
    if(special->flags & _STORAGE_FLAG) {
        int storage = special->_Storage;
        size_t* chunks = special->_ChunkSizes;
        if(special->nchunks == 0 || chunks == NULL) chunks = NULL;
        stat = nc_def_var_chunking(var->container->ncid,
                                   var->ncid,
                                   (storage == NC_CONTIGUOUS?NC_CONTIGUOUS
                                                            :NC_CHUNKED),
                                   chunks);
        check_err(stat,__LINE__,__FILE__);
    }
    if(special->flags & _FLETCHER32_FLAG) {
        stat = nc_def_var_fletcher32(var->container->ncid,
                                     var->ncid,
                                     special->_Fletcher32);
        check_err(stat,__LINE__,__FILE__);
    }
    if(special->flags & (_DEFLATE_FLAG | _SHUFFLE_FLAG)) {
        stat = nc_def_var_deflate(var->container->ncid,
                                  var->ncid,
                                  (special->_Shuffle == 1?1:0),
                                  (special->_DeflateLevel >= 0?1:0),
                                  (special->_DeflateLevel >= 0?special->_DeflateLevel
                                                              :0));
        check_err(stat,__LINE__,__FILE__);
    }
    if(special->flags & _ENDIAN_FLAG) {
        stat = nc_def_var_endian(var->container->ncid,
                                 var->ncid,
                                 (special->_Endianness == NC_ENDIAN_LITTLE?
                                        NC_ENDIAN_LITTLE
                                       :NC_ENDIAN_BIG));
        check_err(stat,__LINE__,__FILE__);
    }
    if(special->flags & _NOFILL_FLAG) {
        stat = nc_def_var_fill(var->container->ncid,
                                 var->ncid,
		                 (special->_Fill?NC_FILL:NC_NOFILL),
                                 NULL);
        check_err(stat,__LINE__,__FILE__);
    }
}
/*!
This function makes a request to netcdf with a ncid, to set the fill parameters for a variable,
given variable id and type of fill
\param [in] ncid Id groupd(or File Id)
\param [in] varId Id of the variable
\param [in] noFill turn on/off nofill mode on a variable
\param [in/out] fillValue
\return Status code
*/
int CNetCdfInterface::defVarFill(int ncid, int varId, int noFill, void* fillValue)
{
  int status = nc_def_var_fill(ncid, varId, noFill, fillValue);
  if (NC_NOERR != status)
  {
    StdString errormsg(nc_strerror(status));
    StdStringStream sstr;

    sstr << "Error when calling function nc_def_var_fill(ncid, varId, noFill, fillValue)" << std::endl;
    sstr << errormsg << std::endl;
    sstr << "Unable to set fill parameters of the variable with id: " << varId
      << " and fill option " << noFill << std::endl;
    StdString e = sstr.str();
    throw CNetCdfException(e);
  }

  return status;
}
Beispiel #6
0
int ex_put_map_param(int exoid, int num_node_maps, int num_elem_maps)
{
  int  dim[2], dimid, strdim, varid, status;
  int  var_nm_id, var_em_id;
  int  i;
  char errmsg[MAX_ERR_LENGTH];
  int  id_type  = NC_INT;
  int  int_type = NC_INT;
#if NC_HAS_HDF5
  int fill = NC_FILL_CHAR;
#endif

  EX_FUNC_ENTER();
  ex_check_valid_file_id(exoid, __func__);

  if (ex_int64_status(exoid) & EX_IDS_INT64_DB) {
    id_type = NC_INT64;
  }
  if (ex_int64_status(exoid) & EX_BULK_INT64_DB) {
    int_type = NC_INT64;
  }

  /* return if these have been defined before */
  if ((num_node_maps > 0 && ((nc_inq_dimid(exoid, DIM_NUM_NM, &dimid)) == NC_NOERR)) ||
      (num_elem_maps > 0 && ((nc_inq_dimid(exoid, DIM_NUM_EM, &dimid)) == NC_NOERR))) {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: number of maps already defined for file id %d", exoid);
    ex_err(__func__, errmsg, EX_BADPARAM);
    EX_FUNC_LEAVE(EX_FATAL);
  }

  if ((num_node_maps > 0) || (num_elem_maps > 0)) {

    /* inquire previously defined dimensions  */
    if ((status = nc_inq_dimid(exoid, DIM_STR_NAME, &strdim)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to get string length in file id %d", exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }

    /* put file into define mode */
    if ((status = nc_redef(exoid)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to put file id %d into define mode", exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }

    /* node maps: */
    if (num_node_maps > 0) {

      if ((status = nc_def_dim(exoid, DIM_NUM_NM, num_node_maps, &dimid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define number of node maps in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /* node maps id array: */
      dim[0] = dimid;
      if ((status = nc_def_var(exoid, VAR_NM_PROP(1), id_type, 1, dim, &var_nm_id)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to create node maps property array in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /*   store property name as attribute of property array variable */
      if ((status = nc_put_att_text(exoid, var_nm_id, ATT_PROP_NAME, 3, "ID")) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to store node map property name %s in file id %d", "ID", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /* Node map names... */
      dim[0] = dimid;
      dim[1] = strdim;

      if (nc_def_var(exoid, VAR_NAME_NM, NC_CHAR, 2, dim, &varid) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define node map name array in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }
#if NC_HAS_HDF5
      nc_def_var_fill(exoid, varid, 0, &fill);
#endif

      /* determine number of nodes */
      if ((status = nc_inq_dimid(exoid, DIM_NUM_NODES, &dimid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: couldn't determine number of nodes in file id %d",
                 exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      dim[0] = dimid;

      /* create variable array in which to store the node maps */
      for (i = 0; i < num_node_maps; i++) {
        if ((status = nc_def_var(exoid, VAR_NODE_MAP(i + 1), int_type, 1, dim, &varid)) !=
            NC_NOERR) {
          if (status == NC_ENAMEINUSE) {
            snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: node map %d already defined in file id %d", i,
                     exoid);
            ex_err(__func__, errmsg, status);
          }
          else {
            snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to create node map %d in file id %d", i,
                     exoid);
            ex_err(__func__, errmsg, status);
          }
          goto error_ret; /* exit define mode and return */
        }
        ex_compress_variable(exoid, varid, 1);
      }
    }

    /* element maps: */
    if (num_elem_maps > 0) {
      if ((status = nc_def_dim(exoid, DIM_NUM_EM, num_elem_maps, &dimid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define number of element maps in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /* element maps id array: */
      dim[0] = dimid;
      if ((status = nc_def_var(exoid, VAR_EM_PROP(1), id_type, 1, dim, &var_em_id)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to create element maps property array in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /*   store property name as attribute of property array variable */
      if ((status = nc_put_att_text(exoid, var_em_id, ATT_PROP_NAME, 3, "ID")) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to store element map property name %s in file id %d", "ID", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /* Element map names... */
      dim[0] = dimid;
      dim[1] = strdim;

      if ((status = nc_def_var(exoid, VAR_NAME_EM, NC_CHAR, 2, dim, &varid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to define element map name array in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }
#if NC_HAS_HDF5
      nc_def_var_fill(exoid, varid, 0, &fill);
#endif

      /* determine number of elements */
      if ((status = nc_inq_dimid(exoid, DIM_NUM_ELEM, &dimid)) != NC_NOERR) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: couldn't determine number of elements in file id %d", exoid);
        ex_err(__func__, errmsg, status);
        goto error_ret; /* exit define mode and return */
      }

      /* create variable array in which to store the element maps */
      dim[0] = dimid;
      for (i = 0; i < num_elem_maps; i++) {
        if ((status = nc_def_var(exoid, VAR_ELEM_MAP(i + 1), int_type, 1, dim, &varid)) !=
            NC_NOERR) {
          if (status == NC_ENAMEINUSE) {
            snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: element map %d already defined in file id %d",
                     i, exoid);
            ex_err(__func__, errmsg, status);
          }
          else {
            snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to create element map %d in file id %d",
                     i, exoid);
            ex_err(__func__, errmsg, status);
          }
          goto error_ret; /* exit define mode and return */
        }
        ex_compress_variable(exoid, varid, 1);
      }
    }

    /* leave define mode */
    if ((status = nc_enddef(exoid)) != NC_NOERR) {
      snprintf(errmsg, MAX_ERR_LENGTH,
               "ERROR: failed to complete variable definitions in file id %d", exoid);
      ex_err(__func__, errmsg, status);
      EX_FUNC_LEAVE(EX_FATAL);
    }

    /* Fill the id arrays with EX_INVALID_ID */
    {
      int  maxset      = num_node_maps > num_elem_maps ? num_node_maps : num_elem_maps;
      int *invalid_ids = malloc(maxset * sizeof(int));
      if (invalid_ids == NULL) {
        snprintf(errmsg, MAX_ERR_LENGTH,
                 "ERROR: failed to allocate memory for invalid id "
                 "storage in file id %d",
                 exoid);
        ex_err(__func__, errmsg, EX_MEMFAIL);
        EX_FUNC_LEAVE(EX_FATAL);
      }
      for (i = 0; i < maxset; i++) {
        invalid_ids[i] = EX_INVALID_ID;
      }
      if (num_node_maps > 0) {
        status = nc_put_var_int(exoid, var_nm_id, invalid_ids);
        assert(status == NC_NOERR);
      }
      if (num_elem_maps > 0) {
        status = nc_put_var_int(exoid, var_em_id, invalid_ids);
        assert(status == NC_NOERR);
      }
      free(invalid_ids);
    }
  }

  EX_FUNC_LEAVE(EX_NOERR);

/* Fatal error: exit definition mode and return */
error_ret:
  if ((status = nc_enddef(exoid)) != NC_NOERR) /* exit define mode */
  {
    snprintf(errmsg, MAX_ERR_LENGTH, "ERROR: failed to complete definition for file id %d", exoid);
    ex_err(__func__, errmsg, status);
  }
  EX_FUNC_LEAVE(EX_FATAL);
}
Beispiel #7
0
int
main(int argc, char **argv)
{
   int mpi_namelen;
   char mpi_name[MPI_MAX_PROCESSOR_NAME];
   int mpi_size, mpi_rank;
   MPI_Comm comm = MPI_COMM_WORLD;
   MPI_Info info = MPI_INFO_NULL;
   double start_time = 0, total_time;
   int mpi_size_in;
#define NUM_TEST_TYPES 11
   nc_type test_type[NUM_TEST_TYPES] = {NC_BYTE, NC_CHAR, NC_SHORT, NC_INT, NC_FLOAT, NC_DOUBLE,
                                        NC_UBYTE, NC_USHORT, NC_UINT, NC_INT64, NC_UINT64};
   int tt, fv;
   int j, i, k, ret;

   /* Initialize MPI. */
   MPI_Init(&argc,&argv);
   MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
   MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
   MPI_Get_processor_name(mpi_name, &mpi_namelen);

   /* Must be able to evenly divide my slabs between processors. */
   if (NUM_SLABS % mpi_size)
   {
      if (!mpi_rank)
         printf("NUM_SLABS (%d) is not evenly divisible by mpi_size(%d)\n",
                NUM_SLABS, mpi_size);
      ERR;
   }

   if (!mpi_rank)
      printf("\n*** Testing parallel I/O some more.\n");

   /* Test for different fill value settings. */
   for (fv = 0; fv < NUM_FILL_TEST_RUNS; fv++)
   {
      /* Test for different netCDF types. */
      for (tt = 0; tt < NUM_TEST_TYPES; tt++)
      {
         char file_name[NC_MAX_NAME + 1];
         int fill_mode_in;
         void *data, *data_in;
         void *fill_value, *fill_value_in;
         size_t type_size;
         size_t write_start[NDIMS] = {0, 0, 1};
         size_t write_count[NDIMS] = {1, DIMSIZE, DIMSIZE - 1};
         size_t read_start[NDIMS] = {0, 0, 0};
         size_t read_count[NDIMS] = {1, DIMSIZE, DIMSIZE};
         int ncid, varid, dimids[NDIMS];
         int ndims_in, nvars_in, natts_in, unlimdimid_in;

         /* Fill values to be expected. */
         signed char byte_expected_fill_value;
         unsigned char char_expected_fill_value;
         short short_expected_fill_value;
         int int_expected_fill_value;
         float float_expected_fill_value;
         double double_expected_fill_value;
         unsigned char ubyte_expected_fill_value;
         unsigned short ushort_expected_fill_value;
         unsigned int uint_expected_fill_value;
         long long int int64_expected_fill_value;
         unsigned long long int uint64_expected_fill_value;

         /* Fill values used when writing. */
         signed char byte_fill_value = -TEST_VAL_42;
         unsigned char char_fill_value = 'x';
         short short_fill_value = TEST_VAL_42 * 100;
         int int_fill_value = TEST_VAL_42 * 1000;
         float float_fill_value = TEST_VAL_42 * 1000;
         double double_fill_value = TEST_VAL_42 * 1000;
         unsigned char ubyte_fill_value = TEST_VAL_42;
         unsigned short ushort_fill_value = TEST_VAL_42 * 100;
         unsigned int uint_fill_value = TEST_VAL_42 * 1000;
         long long int int64_fill_value = TEST_VAL_42 * 1000;
         unsigned long long int uint64_fill_value = TEST_VAL_42 * 1000;

         /* Fill values read in. */
         signed char byte_fill_value_in;
         unsigned char char_fill_value_in;
         short short_fill_value_in;
         int int_fill_value_in;
         float float_fill_value_in;
         double double_fill_value_in;
         unsigned char ubyte_fill_value_in;
         unsigned short ushort_fill_value_in;
         unsigned int uint_fill_value_in;
         long long int int64_fill_value_in;
         unsigned long long int uint64_fill_value_in;

         /* Data to write and read. */
         signed char byte_data[DIMSIZE * DIMSIZE], byte_data_in[DIMSIZE * DIMSIZE];
         unsigned char char_data[DIMSIZE * DIMSIZE], char_data_in[DIMSIZE * DIMSIZE];
         short short_data[DIMSIZE * DIMSIZE], short_data_in[DIMSIZE * DIMSIZE];
         int int_data[DIMSIZE * DIMSIZE], int_data_in[DIMSIZE * DIMSIZE];
         float float_data[DIMSIZE * DIMSIZE], float_data_in[DIMSIZE * DIMSIZE];
         double double_data[DIMSIZE * DIMSIZE], double_data_in[DIMSIZE * DIMSIZE];
         unsigned char ubyte_data[DIMSIZE * DIMSIZE], ubyte_data_in[DIMSIZE * DIMSIZE];
         unsigned short ushort_data[DIMSIZE * DIMSIZE], ushort_data_in[DIMSIZE * DIMSIZE];
         unsigned int uint_data[DIMSIZE * DIMSIZE], uint_data_in[DIMSIZE * DIMSIZE];
         long long int int64_data[DIMSIZE * DIMSIZE], int64_data_in[DIMSIZE * DIMSIZE];
         unsigned long long int uint64_data[DIMSIZE * DIMSIZE], uint64_data_in[DIMSIZE * DIMSIZE];

         if (!mpi_rank)
            printf("*** writing a %d x %d x %d file from %d processors for fill value test %d type %d...\n",
                   NUM_SLABS, DIMSIZE, DIMSIZE, mpi_size, fv, test_type[tt]);

         /* Initialize test data. */
         switch(test_type[tt])
         {
         case NC_BYTE:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               byte_data[i] = mpi_rank;
            data = byte_data;
            data_in = byte_data_in;
            byte_expected_fill_value = fv ? byte_fill_value : NC_FILL_BYTE;
            fill_value = &byte_expected_fill_value;
            fill_value_in = &byte_fill_value_in;
            break;
         case NC_CHAR:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               char_data[i] = mpi_rank;
            data = char_data;
            data_in = char_data_in;
            char_expected_fill_value = fv ? char_fill_value : NC_FILL_CHAR;
            fill_value = &char_expected_fill_value;
            fill_value_in = &char_fill_value_in;
            break;
         case NC_SHORT:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               short_data[i] = mpi_rank;
            data = short_data;
            data_in = short_data_in;
            short_expected_fill_value = fv ? short_fill_value : NC_FILL_SHORT;
            fill_value = &short_expected_fill_value;
            fill_value_in = &short_fill_value_in;
            break;
         case NC_INT:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               int_data[i] = mpi_rank;
            data = int_data;
            data_in = int_data_in;
            int_expected_fill_value = fv ? int_fill_value : NC_FILL_INT;
            fill_value = &int_expected_fill_value;
            fill_value_in = &int_fill_value_in;
            break;
         case NC_FLOAT:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               float_data[i] = mpi_rank;
            data = float_data;
            data_in = float_data_in;
            float_expected_fill_value = fv ? float_fill_value : NC_FILL_FLOAT;
            fill_value = &float_expected_fill_value;
            fill_value_in = &float_fill_value_in;
            break;
         case NC_DOUBLE:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               double_data[i] = mpi_rank;
            data = double_data;
            data_in = double_data_in;
            double_expected_fill_value = fv ? double_fill_value : NC_FILL_DOUBLE;
            fill_value = &double_expected_fill_value;
            fill_value_in = &double_fill_value_in;
            break;
         case NC_UBYTE:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               ubyte_data[i] = mpi_rank;
            data = ubyte_data;
            data_in = ubyte_data_in;
            ubyte_expected_fill_value = fv ? ubyte_fill_value : NC_FILL_UBYTE;
            fill_value = &ubyte_expected_fill_value;
            fill_value_in = &ubyte_fill_value_in;
            break;
         case NC_USHORT:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               ushort_data[i] = mpi_rank;
            data = ushort_data;
            data_in = ushort_data_in;
            ushort_expected_fill_value = fv ? ushort_fill_value : NC_FILL_USHORT;
            fill_value = &ushort_expected_fill_value;
            fill_value_in = &ushort_fill_value_in;
            break;
         case NC_UINT:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               uint_data[i] = mpi_rank;
            data = uint_data;
            data_in = uint_data_in;
            uint_expected_fill_value = fv ? uint_fill_value : NC_FILL_UINT;
            fill_value = &uint_expected_fill_value;
            fill_value_in = &uint_fill_value_in;
            break;
         case NC_INT64:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               int64_data[i] = mpi_rank;
            data = int64_data;
            data_in = int64_data_in;
            int64_expected_fill_value = fv ? int64_fill_value : NC_FILL_INT64;
            fill_value = &int64_expected_fill_value;
            fill_value_in = &int64_fill_value_in;
            break;
         case NC_UINT64:
            for (i = 0; i < DIMSIZE * DIMSIZE; i++)
               uint64_data[i] = mpi_rank;
            data = uint64_data;
            data_in = uint64_data_in;
            uint64_expected_fill_value = fv ? uint64_fill_value : NC_FILL_UINT64;
            fill_value = &uint64_expected_fill_value;
            fill_value_in = &uint64_fill_value_in;
            break;
         }

         /* Create a file name. */
         sprintf(file_name, "%s_type_%d_fv_%d.nc", TEST_NAME, test_type[tt], fv);

         /* Create a parallel netcdf-4 file. */
         if (nc_create_par(file_name, NC_NETCDF4, comm, info, &ncid)) ERR;

         /* Get the type len. */
         if (nc_inq_type(ncid, test_type[tt], NULL, &type_size)) ERR;

         /* A global attribute holds the number of processors that created
          * the file. */
         if (nc_put_att_int(ncid, NC_GLOBAL, "num_processors", NC_INT, 1, &mpi_size)) ERR;

         /* Create three dimensions. */
         if (nc_def_dim(ncid, DIM1_NAME, NUM_SLABS, dimids)) ERR;
         if (nc_def_dim(ncid, DIM2_NAME, DIMSIZE, &dimids[1])) ERR;
         if (nc_def_dim(ncid, DIM3_NAME, DIMSIZE, &dimids[2])) ERR;

         /* Create one var. */
         if (nc_def_var(ncid, VAR_NAME, test_type[tt], NDIMS, dimids, &varid)) ERR;
         if (nc_put_att_int(ncid, varid, "var_num_processors", NC_INT, 1, &mpi_size)) ERR;
         if (fv == 1)
         {
            if (nc_def_var_fill(ncid, varid, NC_FILL, fill_value)) ERR;
            if (nc_inq_var_fill(ncid, varid, &fill_mode_in, fill_value_in)) ERR;
            if (fill_mode_in != NC_FILL) ERR;
            if (memcmp(fill_value_in, fill_value, type_size)) ERR;
         }
         else if (fv == 2)
         {
            if (nc_def_var_fill(ncid, varid, NC_NOFILL, NULL)) ERR;
            if (nc_inq_var_fill(ncid, varid, &fill_mode_in, NULL)) ERR;
            if (!fill_mode_in) ERR; /* nofill will be true */
         }

         /* Write metadata to file. */
         if (nc_enddef(ncid)) ERR;

         /* Change access mode to collective, then back to independent. */
         if (nc_var_par_access(ncid, varid, NC_COLLECTIVE)) ERR;
         if (nc_var_par_access(ncid, varid, NC_INDEPENDENT)) ERR;

         if (!mpi_rank)
            start_time = MPI_Wtime();

         /* Write all the slabs this process is responsible for. */
         for (i = 0; i < NUM_SLABS / mpi_size; i++)
         {
            write_start[0] = NUM_SLABS / mpi_size * mpi_rank + i;

            /* Write one slab of data. Due to start/count settings,
             * every 16th value will be a fill value. */
            if (nc_put_vara(ncid, varid, write_start, write_count, data)) ERR;
         }

         /* On rank 0, keep track of time. */
         if (!mpi_rank)
         {
            total_time = MPI_Wtime() - start_time;
            printf("%d\t%g\t%g\n", mpi_size, total_time, DIMSIZE * DIMSIZE * NUM_SLABS *
                   sizeof(int) / total_time);
         }

         /* Close the netcdf file. */
         if (nc_close(ncid)) ERR;

         /* Reopen the file and check it. */
         if ((ret = nc_open_par(file_name, NC_NOWRITE, comm, info, &ncid))) ERR;
         if (nc_inq(ncid, &ndims_in, &nvars_in, &natts_in, &unlimdimid_in)) ERR;
         if (ndims_in != NDIMS || nvars_in != 1 || natts_in != 1 ||
             unlimdimid_in != -1) ERR;

         /* Check the attributes. */
         if (nc_get_att_int(ncid, NC_GLOBAL, "num_processors", &mpi_size_in)) ERR;
         if (mpi_size_in != mpi_size) ERR;
         if (nc_get_att_int(ncid, 0, "var_num_processors", &mpi_size_in)) ERR;
         if (mpi_size_in != mpi_size) ERR;
         if (fv == 1)
         {
            if (nc_inq_var_fill(ncid, varid, &fill_mode_in, fill_value_in)) ERR;
            if (fill_mode_in != NC_FILL) ERR;
            if (memcmp(fill_value_in, fill_value, type_size)) ERR;
         }

         /* Read all the slabs this process is responsible for. */
         for (i = 0; i < NUM_SLABS / mpi_size; i++)
         {
            read_start[0] = NUM_SLABS / mpi_size * mpi_rank + i;
            /* printf("mpi_rank %d i %d read_start[0] %ld\n", mpi_rank, i, read_start[0]); */

            /* Read one slab of data. */
            if (nc_get_vara(ncid, varid, read_start, read_count, data_in)) ERR;

            /* Check data.  For the third fill value test, fill is
             * turned off. So don't bother testing the values where k
             * is zero. */
            /* printf("mpi_rank %d fv %d i %d j %d k %d int_data_in[j * k] %d int_expected_fill_value %d " */
            /*        "expected_value %d\n", mpi_rank, fv, i, j, k, int_data_in[j * k], */
            /*        int_expected_fill_value, expected_value); */
            switch (test_type[tt])
            {
            case NC_BYTE:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (byte_data_in[j * DIMSIZE + k] != (signed char)(k ? mpi_rank : byte_expected_fill_value)) ERR;
               break;
            case NC_SHORT:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (short_data_in[j * DIMSIZE + k] != (short)(k ? mpi_rank : short_expected_fill_value)) ERR;
               break;
            case NC_INT:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (int_data_in[j * DIMSIZE + k] != (int)(k ? mpi_rank : int_expected_fill_value)) ERR;
               break;
            case NC_FLOAT:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (float_data_in[j * DIMSIZE + k] != (float)(k ? mpi_rank : float_expected_fill_value)) ERR;
               break;
            case NC_DOUBLE:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (double_data_in[j * DIMSIZE + k] != (double)(k ? mpi_rank : double_expected_fill_value)) ERR;
               break;
            case NC_UBYTE:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (ubyte_data_in[j * DIMSIZE + k] != (unsigned char)(k ? mpi_rank : ubyte_expected_fill_value)) ERR;
               break;
            case NC_USHORT:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (ushort_data_in[j * DIMSIZE + k] != (unsigned short)(k ? mpi_rank : ushort_expected_fill_value)) ERR;
               break;
            case NC_UINT:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (uint_data_in[j * DIMSIZE + k] != (unsigned int)(k ? mpi_rank : uint_expected_fill_value)) ERR;
               break;
            case NC_INT64:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (int64_data_in[j * DIMSIZE + k] != (long long int)(k ? mpi_rank : int64_expected_fill_value)) ERR;
               break;
            case NC_UINT64:
               for (j = 0; j < DIMSIZE; j++)
                  for (k = 0; k < DIMSIZE; k++)
                     if (fv < 2 || k)
                        if (uint64_data_in[j * DIMSIZE + k] != (unsigned long long int)(k ? mpi_rank : uint64_expected_fill_value)) ERR;
               break;
            }
         } /* next slab */

         /* Close the netcdf file. */
         if (nc_close(ncid))  ERR;

         if (!mpi_rank)
            SUMMARIZE_ERR;
      } /* next test type */
   } /* next fill value test run */

   /* Shut down MPI. */
   MPI_Finalize();

   if (!mpi_rank)
      FINAL_RESULTS;
   return 0;
}
Beispiel #8
0
int
main(int argc, char **argv)
{
#ifdef USE_PARALLEL
   MPI_Init(&argc, &argv);
#endif

   int ncid, dimids[3];
   int char_varid, byte_varid, ubyte_varid, short_varid, int_varid, float_varid, double_varid;
   int ushort_varid, uint_varid, int64_varid, uint64_varid;
   int i, j;

   unsigned char ubyte_out[DIM1_LEN][DIM2_LEN] = {{1, 128, 255},{1, 128, 255}};
   signed char byte_in[DIM1_LEN][DIM2_LEN], byte_out[DIM1_LEN][DIM2_LEN] = {{-127, 1, 127},{-127, 1, 127}};
   unsigned short ushort_out[DIM1_LEN][DIM2_LEN] = {{110, 128, 255},{110, 128, 255}};
   short short_in[DIM1_LEN][DIM2_LEN], short_out[DIM1_LEN][DIM2_LEN] = {{-110, -128, 255},{-110, -128, 255}};
   int int_in[DIM1_LEN][DIM2_LEN], int_out[DIM1_LEN][DIM2_LEN] = {{0, 128, 255},{0, 128, 255}};
   float float_in[DIM1_LEN][DIM2_LEN], float_out[DIM1_LEN][DIM2_LEN] = {{-.1, 9999.99, 100.001},{-.1, 9999.99, 100.001}};
   double double_in[DIM1_LEN][DIM2_LEN], double_out[DIM1_LEN][DIM2_LEN] = {{0.02, .1128, 1090.1},{0.02, .1128, 1090.1}};
   unsigned int uint_in[DIM1_LEN][DIM2_LEN], uint_out[DIM1_LEN][DIM2_LEN] = {{0, 128, 255},{0, 128, 255}};
   long long int64_in[DIM1_LEN][DIM2_LEN], int64_out[DIM1_LEN][DIM2_LEN] = {{-111, 777, 100},{-111, 777, 100}};
   unsigned long long uint64_in[DIM1_LEN][DIM2_LEN];
   unsigned long long uint64_out[DIM1_LEN][DIM2_LEN] = {{0, 10101, 9999999},{0, 10101, 9999999}};
   char char_out[DIM1_LEN][DIM2_LEN][DIM3_LEN] = {{"lalala", "lololo", "lelele"}, {"lalala", "lololo", "lelele"}};

   /*nc_set_log_level(4);*/

   printf("\n*** Testing netcdf-4 variable functions.\n");

   printf("*** testing netcdf-4 varids inq on netcdf-3 file...");
   {
      int nvars_in, varids_in[2];

      /* Create a netcdf-3 file with one dim and two vars. */
      if (nc_create(FILE_NAME, 0, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR;
      if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR;
      if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and make sure nc_inq_varids yeilds correct
       * result. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq_varids(ncid, &nvars_in, varids_in)) ERR;
      if (nvars_in != 2 || varids_in[0] != 0 || varids_in[1] != 1) ERR;
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing simple variables...");

   {      
      /* Create a file with a variable of each type. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR;
      if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR;
      if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR;
      if (nc_def_var(ncid, VAR_SHORT_NAME, NC_SHORT, 2, dimids, &short_varid)) ERR;
      if (nc_def_var(ncid, VAR_INT_NAME, NC_INT, 2, dimids, &int_varid)) ERR;
      if (nc_def_var(ncid, VAR_FLOAT_NAME, NC_FLOAT, 2, dimids, &float_varid)) ERR;
      if (nc_def_var(ncid, VAR_DOUBLE_NAME, NC_DOUBLE, 2, dimids, &double_varid)) ERR;
      if (nc_def_var(ncid, VAR_UBYTE_NAME, NC_UBYTE, 2, dimids, &ubyte_varid)) ERR;
      if (nc_def_var(ncid, VAR_USHORT_NAME, NC_USHORT, 2, dimids, &ushort_varid)) ERR;
      if (nc_def_var(ncid, VAR_UINT_NAME, NC_UINT, 2, dimids, &uint_varid)) ERR;
      if (nc_def_var(ncid, VAR_INT64_NAME, NC_INT64, 2, dimids, &int64_varid)) ERR;
      if (nc_def_var(ncid, VAR_UINT64_NAME, NC_UINT64, 2, dimids, &uint64_varid)) ERR;
      if (nc_put_var_schar(ncid, byte_varid, (signed char *)byte_out)) ERR;
      if (nc_put_var_text(ncid, char_varid, (char *)char_out)) ERR;
      if (nc_put_var_short(ncid, short_varid, (short *)short_out)) ERR;
      if (nc_put_var_int(ncid, int_varid, (int *)int_out)) ERR;
      if (nc_put_var_float(ncid, float_varid, (float *)float_out)) ERR;
      if (nc_put_var_double(ncid, double_varid, (double *)double_out)) ERR;
      if (nc_put_var_ubyte(ncid, ubyte_varid, (unsigned char *)ubyte_out)) ERR;
      if (nc_put_var_ushort(ncid, ushort_varid, (unsigned short *)ushort_out)) ERR;
      if (nc_put_var_uint(ncid, uint_varid, (unsigned int *)uint_out)) ERR;
      if (nc_put_var_longlong(ncid, int64_varid, (long long *)int64_out)) ERR;
      if (nc_put_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and check metadata. */
      {
	 nc_type xtype_in;
	 int ndims_in, dimids_in[10], natts_in, varid_in;
	 char name_in[NC_MAX_NAME+1];

	 if (nc_open(FILE_NAME, 0, &ncid)) ERR;
	 if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, 
			&natts_in)) ERR;
	 if (strcmp(name_in, VAR_BYTE_NAME) || xtype_in != NC_BYTE || 
	     ndims_in != 2 || natts_in != 0 || dimids_in[0] != dimids[0] ||
	     dimids_in[1] != dimids[1]) ERR;
	 if (nc_inq_varid(ncid, VAR_BYTE_NAME, &varid_in)) ERR;
	 if (varid_in != 0) ERR;
	 if (nc_inq_varid(ncid, VAR_CHAR_NAME, &varid_in)) ERR;
	 if (varid_in != 1) ERR;
	 if (nc_inq_varid(ncid, VAR_SHORT_NAME, &varid_in)) ERR;
	 if (varid_in != 2) ERR;
	 if (nc_inq_varname(ncid, 0, name_in)) ERR;
	 if (strcmp(name_in, VAR_BYTE_NAME)) ERR;
	 if (nc_inq_varname(ncid, 1, name_in)) ERR;
	 if (strcmp(name_in, VAR_CHAR_NAME)) ERR;
	 if (nc_inq_varname(ncid, 2, name_in)) ERR;
	 if (strcmp(name_in, VAR_SHORT_NAME)) ERR;
	 if (nc_inq_vartype(ncid, 0, &xtype_in)) ERR;      
	 if (xtype_in != NC_BYTE) ERR;
	 if (nc_inq_vartype(ncid, 1, &xtype_in)) ERR;      
	 if (xtype_in != NC_CHAR) ERR;
	 if (nc_inq_vartype(ncid, 2, &xtype_in)) ERR;      
	 if (xtype_in != NC_SHORT) ERR;
	 if (nc_close(ncid)) ERR;
      }

      /* Open the file and check data. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != byte_out[i][j]) ERR;
      if (nc_get_var_short(ncid, short_varid, (short *)short_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (short_in[i][j] != short_out[i][j]) ERR;
      if (nc_get_var_int(ncid, int_varid, (int *)int_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (int_in[i][j] != int_out[i][j]) ERR;
      if (nc_get_var_float(ncid, float_varid, (float *)float_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (float_in[i][j] != float_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_uint(ncid, uint_varid, (unsigned int *)uint_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (uint_in[i][j] != uint_out[i][j]) ERR;
      if (nc_get_var_longlong(ncid, int64_varid, (long long *)int64_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (int64_in[i][j] != int64_out[i][j]) ERR;
      if (nc_get_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (uint64_in[i][j] != uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and read everything as double. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_double(ncid, byte_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)byte_out[i][j]) ERR;
      if (nc_get_var_double(ncid, ubyte_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)ubyte_out[i][j]) ERR;
      if (nc_get_var_double(ncid, short_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)short_out[i][j]) ERR;
      if (nc_get_var_double(ncid, ushort_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)ushort_out[i][j]) ERR;
      if (nc_get_var_double(ncid, int_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)int_out[i][j]) ERR;
      if (nc_get_var_double(ncid, uint_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)uint_out[i][j]) ERR;
      if (nc_get_var_double(ncid, float_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)float_out[i][j]) ERR;
      if (nc_get_var_double(ncid, int64_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)int64_out[i][j]) ERR;
      if (nc_get_var_double(ncid, uint64_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and read everything as NC_BYTE. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)byte_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, ubyte_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)ubyte_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, short_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)short_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, ushort_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)ushort_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, int_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)int_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, uint_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)uint_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, float_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)float_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, int64_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)int64_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, uint64_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;

#define DEFLATE_LEVEL_4 4

   printf("*** testing simple variables with deflation...");
   {
      /* Create a file with a variable of each type. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM1_NAME, DIM1_LEN, &dimids[0])) ERR;
      if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimids[1])) ERR;
      if (nc_def_dim(ncid, DIM3_NAME, DIM3_LEN, &dimids[2])) ERR;
      if (nc_def_var(ncid, VAR_BYTE_NAME, NC_BYTE, 2, dimids, &byte_varid)) ERR;
      if (nc_def_var_deflate(ncid, byte_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_CHAR_NAME, NC_CHAR, 3, dimids, &char_varid)) ERR;
      if (nc_def_var_deflate(ncid, byte_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_SHORT_NAME, NC_SHORT, 2, dimids, &short_varid)) ERR;
      if (nc_def_var_deflate(ncid, short_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_INT_NAME, NC_INT, 2, dimids, &int_varid)) ERR;
      if (nc_def_var_deflate(ncid, int_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_FLOAT_NAME, NC_FLOAT, 2, dimids, &float_varid)) ERR;
      if (nc_def_var_deflate(ncid, float_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_DOUBLE_NAME, NC_DOUBLE, 2, dimids, &double_varid)) ERR;
      if (nc_def_var_deflate(ncid, double_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_UBYTE_NAME, NC_UBYTE, 2, dimids, &ubyte_varid)) ERR;
      if (nc_def_var_deflate(ncid, ubyte_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_USHORT_NAME, NC_USHORT, 2, dimids, &ushort_varid)) ERR;
      if (nc_def_var_deflate(ncid, ushort_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_UINT_NAME, NC_UINT, 2, dimids, &uint_varid)) ERR;
      if (nc_def_var_deflate(ncid, uint_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_INT64_NAME, NC_INT64, 2, dimids, &int64_varid)) ERR;
      if (nc_def_var_deflate(ncid, int64_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;
      if (nc_def_var(ncid, VAR_UINT64_NAME, NC_UINT64, 2, dimids, &uint64_varid)) ERR;
      if (nc_def_var_deflate(ncid, uint64_varid, 0, 1, DEFLATE_LEVEL_4)) ERR;

      if (nc_put_var_schar(ncid, byte_varid, (signed char *)byte_out)) ERR;
      if (nc_put_var_text(ncid, char_varid, (char *)char_out)) ERR;
      if (nc_put_var_short(ncid, short_varid, (short *)short_out)) ERR;
      if (nc_put_var_int(ncid, int_varid, (int *)int_out)) ERR;
      if (nc_put_var_float(ncid, float_varid, (float *)float_out)) ERR;
      if (nc_put_var_double(ncid, double_varid, (double *)double_out)) ERR;
      if (nc_put_var_ubyte(ncid, ubyte_varid, (unsigned char *)ubyte_out)) ERR;
      if (nc_put_var_ushort(ncid, ushort_varid, (unsigned short *)ushort_out)) ERR;
      if (nc_put_var_uint(ncid, uint_varid, (unsigned int *)uint_out)) ERR;
      if (nc_put_var_longlong(ncid, int64_varid, (long long *)int64_out)) ERR;
      if (nc_put_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_out)) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and check metadata. */
      {
	 nc_type xtype_in;
	 int ndims_in, dimids_in[10], natts_in, varid_in;
	 char name_in[NC_MAX_NAME+1];

	 if (nc_open(FILE_NAME, 0, &ncid)) ERR;
	 if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims_in, dimids_in, 
			&natts_in)) ERR;
	 if (strcmp(name_in, VAR_BYTE_NAME) || xtype_in != NC_BYTE || 
	     ndims_in != 2 || natts_in != 0 || dimids_in[0] != dimids[0] ||
	     dimids_in[1] != dimids[1]) ERR;
	 if (nc_inq_varid(ncid, VAR_BYTE_NAME, &varid_in)) ERR;
	 if (varid_in != 0) ERR;
	 if (nc_inq_varid(ncid, VAR_CHAR_NAME, &varid_in)) ERR;
	 if (varid_in != 1) ERR;
	 if (nc_inq_varid(ncid, VAR_SHORT_NAME, &varid_in)) ERR;
	 if (varid_in != 2) ERR;
	 if (nc_inq_varname(ncid, 0, name_in)) ERR;
	 if (strcmp(name_in, VAR_BYTE_NAME)) ERR;
	 if (nc_inq_varname(ncid, 1, name_in)) ERR;
	 if (strcmp(name_in, VAR_CHAR_NAME)) ERR;
	 if (nc_inq_varname(ncid, 2, name_in)) ERR;
	 if (strcmp(name_in, VAR_SHORT_NAME)) ERR;
	 if (nc_inq_vartype(ncid, 0, &xtype_in)) ERR;      
	 if (xtype_in != NC_BYTE) ERR;
	 if (nc_inq_vartype(ncid, 1, &xtype_in)) ERR;      
	 if (xtype_in != NC_CHAR) ERR;
	 if (nc_inq_vartype(ncid, 2, &xtype_in)) ERR;      
	 if (xtype_in != NC_SHORT) ERR;
	 if (nc_close(ncid)) ERR;
      }

      /* Open the file and check data. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != byte_out[i][j]) ERR;
      if (nc_get_var_short(ncid, short_varid, (short *)short_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (short_in[i][j] != short_out[i][j]) ERR;
      if (nc_get_var_int(ncid, int_varid, (int *)int_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (int_in[i][j] != int_out[i][j]) ERR;
      if (nc_get_var_float(ncid, float_varid, (float *)float_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (float_in[i][j] != float_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_double(ncid, double_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != double_out[i][j]) ERR;
      if (nc_get_var_uint(ncid, uint_varid, (unsigned int *)uint_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (uint_in[i][j] != uint_out[i][j]) ERR;
      if (nc_get_var_longlong(ncid, int64_varid, (long long *)int64_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (int64_in[i][j] != int64_out[i][j]) ERR;
      if (nc_get_var_ulonglong(ncid, uint64_varid, (unsigned long long *)uint64_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (uint64_in[i][j] != uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and read everything as double. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_double(ncid, byte_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)byte_out[i][j]) ERR;
      if (nc_get_var_double(ncid, ubyte_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)ubyte_out[i][j]) ERR;
      if (nc_get_var_double(ncid, short_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)short_out[i][j]) ERR;
      if (nc_get_var_double(ncid, ushort_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)ushort_out[i][j]) ERR;
      if (nc_get_var_double(ncid, int_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)int_out[i][j]) ERR;
      if (nc_get_var_double(ncid, uint_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)uint_out[i][j]) ERR;
      if (nc_get_var_double(ncid, float_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)float_out[i][j]) ERR;
      if (nc_get_var_double(ncid, int64_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)int64_out[i][j]) ERR;
      if (nc_get_var_double(ncid, uint64_varid, (double *)double_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (double_in[i][j] != (double)uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

      /* Open the file and read everything as NC_BYTE. */
      if (nc_open(FILE_NAME, 0, &ncid)) ERR;
      if (nc_get_var_schar(ncid, byte_varid, (signed char *)byte_in)) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)byte_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, ubyte_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)ubyte_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, short_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)short_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, ushort_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)ushort_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, int_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)int_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, uint_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)uint_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, float_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)float_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, int64_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)int64_out[i][j]) ERR;
      if (nc_get_var_schar(ncid, uint64_varid, (signed char *)byte_in) != NC_ERANGE) ERR;   
      for (i = 0; i < DIM1_LEN; i++)
	 for (j = 0; j < DIM2_LEN; j++)
	    if (byte_in[i][j] != (signed char)uint64_out[i][j]) ERR;
      if (nc_close(ncid)) ERR;

   }
   SUMMARIZE_ERR;

#define NDIMS4 1
#define NVARS4 1
#define DIM4_NAME "treaty_of_paris_1783"
#define DIM4_LEN 5
#define VAR_NAME4 "John_Adams"
#define DEFLATE_LEVEL 6

   printf("*** testing netcdf-4 simple variable define...");
   {
      int dimids[NDIMS4], dimids_in[NDIMS4];
      int varid, varids_in[NVARS4];
      int ndims, nvars, natts, unlimdimid;
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      int shuffle_in, deflate_in, deflate_level;

      /* Create a netcdf-4 file with one dim and one var. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM4_NAME, DIM4_LEN, &dimids[0])) ERR;
      if (dimids[0] != 0) ERR;
      if (nc_def_var(ncid, VAR_NAME4, NC_INT64, NDIMS4, dimids, &varid)) ERR;
      if (nc_def_var_deflate(ncid, varid, 0, 1, DEFLATE_LEVEL)) ERR;
      if (varid != 0) ERR;

      /* Check stuff. */
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS4 || nvars != NVARS4 || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS4) ERR;
      if (varids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
		     dimids_in, &natts)) ERR;
      if (strcmp(name_in, VAR_NAME4) || xtype_in != NC_INT64 ||
	  ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
      if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, 
			     &deflate_level)) ERR;
      if (shuffle_in ||!deflate_in || 
	  deflate_level != DEFLATE_LEVEL) ERR;

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS4 || nvars != NVARS4 || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS4) ERR;
      if (varids_in[0] != 0) ERR;
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
		     dimids_in, &natts)) ERR;
      if (strcmp(name_in, VAR_NAME4) || xtype_in != NC_INT64 ||
	  ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
      if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, 
			     &deflate_level)) ERR;
      if (shuffle_in ||!deflate_in || 
	  deflate_level != DEFLATE_LEVEL) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;

#define NDIMS5 1
#define NVARS5 5
#define DIM5_NAME "treaty_of_paris_1783"
#define DIM5_LEN 5

   printf("*** testing netcdf-4 less simple variable define...");
   {
      int dimids[NDIMS5], dimids_in[NDIMS5];
      int varid[NVARS5], varids_in[NVARS5];
      int ndims, nvars, natts, unlimdimid;
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      char var_name[NVARS5][NC_MAX_NAME + 1] = {"Jean-Pierre_Blanchard", "Madame_Blanchard",
						"Giffard", "Stanislas_Charles_Henri_Dupuy_de_Lome",
						"Charles_F_Ritchel"};
      int shuffle_in, deflate_in, deflate_level_in;
      int deflate_level[NVARS5];
      int i;

      /* Set up options for this var. */
      for (i = 0; i < NVARS5; i++)
	 deflate_level[i] = i;

      /* Create a netcdf-4 file with one dim and two vars. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM5_NAME, DIM5_LEN, &dimids[0])) ERR;
      if (dimids[0] != 0) ERR;
      for (i = 0; i < NVARS5; i++)
      {
	 if (nc_def_var(ncid, var_name[i], NC_INT64, NDIMS5, dimids, 
			&varid[i])) ERR;
	 if (varid[i] != i) ERR;
	 if (nc_def_var_deflate(ncid, varid[i], 1, 1, deflate_level[i])) ERR;
      }

      /* Check stuff. */
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS5 || nvars != NVARS5 || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS5) ERR;
      for (i = 0; i < NVARS5; i++)
      {
	 if (varids_in[i] != i) ERR;
	 if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims,
			dimids_in, &natts)) ERR;
	 if (strcmp(name_in, var_name[i]) || xtype_in != NC_INT64 ||
	     ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
	 if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, 
				&deflate_level_in)) ERR;
	 if (!shuffle_in || !deflate_in || 
	     deflate_level_in != deflate_level[i]) ERR;
      }

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS5 || nvars != NVARS5 || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS5) ERR;
      for (i = 0; i < NVARS5; i++)
      {
	 if (varids_in[i] != i) ERR;
	 if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims,
			dimids_in, &natts)) ERR;
	 if (strcmp(name_in, var_name[i]) || xtype_in != NC_INT64 ||
	     ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
	 if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, 
				&deflate_level_in)) ERR;
	 if (!shuffle_in || !deflate_in || 
	     deflate_level_in != deflate_level[i]) ERR;
      }

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;

#define NVARS 5
#define NDIMS 1
#define DIM6_NAME "airship_cross_sectional_area"
#define DIM6_LEN 100
#define TEN_K_M2 10000.0
#define INCREMENT 1000.0

   printf("*** testing more complex netcdf-4 variable defines...");
   {
      int dimids[NDIMS], dimids_in[NDIMS];
      int varid[NVARS], varids_in[NVARS];
      int ndims, nvars, natts, unlimdimid;
      char var_name[NVARS][50] = {"Jean-Pierre_Blanchard", "Madame_Blanchard",
				  "Giffard", "Stanislas_Charles_Henri_Dupuy_de_Lome",
				  "Charles_F_Ritchel"};
      double data[DIM6_LEN];
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      int shuffle_in, deflate_in, deflate_level_in;
      int fletcher32_in;
      int i;

      /* Create some phoney data. */
      for (i = 1, data[0] = TEN_K_M2; i < DIM6_LEN; i++)
	 data[i] = data[i - 1] + INCREMENT;

      /* Create a netcdf-4 file with one dim and 5 NC_DOUBLE vars. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM6_NAME, DIM6_LEN, &dimids[0])) ERR;
      for (i = 0; i < NVARS; i++)
      {
	 if (nc_def_var(ncid, var_name[i], NC_DOUBLE, NDIMS, dimids,
			&varid[i])) ERR;
	 if (nc_def_var_deflate(ncid, varid[i], 0, 1, 0)) ERR;
	 if (nc_def_var_fletcher32(ncid, varid[i], 1)) ERR;
      }

      /* Check stuff. */
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS || nvars != NVARS || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS) ERR;
      for (i = 0; i < NVARS; i++)
	 if (varids_in[i] != i) ERR;
      for (i = 0; i < NVARS; i++)
      {
	 if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims,
			dimids_in, &natts)) ERR;
	 if (strcmp(name_in, var_name[i]) || xtype_in != NC_DOUBLE ||
	     ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
	 if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, 
				&deflate_level_in)) ERR;
	 if (shuffle_in || !deflate_in || deflate_level_in != 0) ERR;
	 if (nc_inq_var_fletcher32(ncid, varid[i], &fletcher32_in)) ERR;
	 if (!fletcher32_in) ERR;
      }

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != NDIMS || nvars != NVARS || natts != 0 ||
	  unlimdimid != -1) ERR;
      if (nc_inq_varids(ncid, &nvars, varids_in)) ERR;
      if (nvars != NVARS) ERR;
      for (i = 0; i < NVARS; i++)
	 if (varids_in[i] != i) ERR;
      for (i = 0; i < NVARS; i++)
      {
	 if (nc_inq_var(ncid, i, name_in, &xtype_in, &ndims,
			dimids_in, &natts)) ERR;
	 if (strcmp(name_in, var_name[i]) || xtype_in != NC_DOUBLE ||
	     ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
	 if (nc_inq_var_deflate(ncid, varid[i], &shuffle_in, &deflate_in, 
				&deflate_level_in)) ERR;
	 if (shuffle_in || !deflate_in || 
	     deflate_level_in != 0) ERR;
	 if (nc_inq_var_fletcher32(ncid, varid[i], &fletcher32_in)) ERR;
	 if (!fletcher32_in) ERR;
      }

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
#define DIM7_LEN 2
#define DIM7_NAME "dim_7_from_Indiana"
#define VAR7_NAME "var_7_from_Idaho"
#define NDIMS 1

   printf("*** testing fill values...");
   {
      int dimids[NDIMS], dimids_in[NDIMS];
      size_t index[NDIMS];
      int varid, ndims, natts;
      nc_type xtype_in;
      char name_in[NC_MAX_NAME + 1];
      int shuffle_in, deflate_in, deflate_level_in;
      int fletcher32_in, no_fill;
      unsigned short ushort_data = 42, ushort_data_in, fill_value_in;

      /* Create a netcdf-4 file with one dim and 1 NC_USHORT var. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids,
		     &varid)) ERR;

      /* Check stuff. */
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
		     dimids_in, &natts)) ERR;
      if (strcmp(name_in, VAR7_NAME) || xtype_in != NC_USHORT ||
	  ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
      if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, 
			     &deflate_level_in)) ERR;
      if (shuffle_in || deflate_in) ERR;
      if (nc_inq_var_fletcher32(ncid, 0, &fletcher32_in)) ERR;
      if (fletcher32_in) ERR;
      if (nc_inq_var_fill(ncid, 0, &no_fill, &fill_value_in)) ERR;
      if (no_fill || fill_value_in != NC_FILL_USHORT) ERR;

      /* Write the second of two values. */
      index[0] = 1;
      if (nc_put_var1_ushort(ncid, 0, index, &ushort_data)) ERR;

      /* Get the first value, and make sure we get the default fill
       * value for USHORT. */
      index[0] = 0;
      if (nc_get_var1_ushort(ncid, 0, index, &ushort_data_in)) ERR;
      if (ushort_data_in != NC_FILL_USHORT) ERR;

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      /* Check stuff. */
      if (nc_inq_var(ncid, 0, name_in, &xtype_in, &ndims,
		     dimids_in, &natts)) ERR;
      if (strcmp(name_in, VAR7_NAME) || xtype_in != NC_USHORT ||
	  ndims != 1 || natts != 0 || dimids_in[0] != 0) ERR;
      if (nc_inq_var_deflate(ncid, 0, &shuffle_in, &deflate_in, 
			     &deflate_level_in)) ERR;
      if (shuffle_in || deflate_in) ERR;
      if (nc_inq_var_fletcher32(ncid, 0, &fletcher32_in)) ERR;
      if (fletcher32_in) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing more fill values...");
   {
      int dimids[NDIMS];
      size_t index[NDIMS];
      int varid;
      int no_fill;
      unsigned short ushort_data = 42, ushort_data_in, fill_value_in;

      /* Create a netcdf-4 file with one dim and 1 NC_USHORT var. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM7_NAME, DIM7_LEN, &dimids[0])) ERR;
      if (nc_def_var(ncid, VAR7_NAME, NC_USHORT, NDIMS, dimids,
		     &varid)) ERR;
      if (nc_def_var_fill(ncid, varid, 1, NULL)) ERR;

      /* Check stuff. */
      if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR;
      if (!no_fill) ERR;

      /* Write the second of two values. */
      index[0] = 1;
      if (nc_put_var1_ushort(ncid, varid, index, &ushort_data)) ERR;

      /* Get the first value, and make sure we get the default fill
       * value for USHORT. */
      index[0] = 0;
      if (nc_get_var1_ushort(ncid, varid, index, &ushort_data_in)) ERR;

      if (nc_close(ncid)) ERR;

      /* Open the file and check the same stuff. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;

      /* Check stuff. */
      if (nc_inq_var_fill(ncid, varid, &no_fill, &fill_value_in)) ERR;
      if (!no_fill) ERR;

      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
   printf("*** testing lots of variables...");
#define DIM_A_NAME "x"
#define DIM_A_LEN 10
#define NUM_VARS 2000
#define MAX_VARNAME 10
   {
      /* This simple test failed on HDF5 1.7.58, but passes just fine
       * on 1.8.0 alpha5... */
      int ncid, dimids[1], i;
      char varname[MAX_VARNAME];
      int varids[NUM_VARS];

      /* Create a file with three dimensions. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_A_NAME, DIM_A_LEN, &dimids[0])) ERR;

      /* Create a large number of variables. */
      for (i = 0; i < NUM_VARS; i++)
      {
	 sprintf(varname, "a_%d", i);
	 if (nc_def_var(ncid, varname, NC_FLOAT, 1, dimids, &varids[i])) ERR;
      }
      if (nc_close(ncid)) ERR;
   }

   SUMMARIZE_ERR;
#define NC3_CLASSIC_FILE "tst_pres_temp_4D_classic.nc"
#define NC3_64BIT_OFFSET_FILE "tst_pres_temp_4D_64bit_offset.nc"
#define NC3_NETCDF4_FILE "tst_pres_temp_4D_netcdf4.nc"
#define NC3_NETCDF4_CLASSIC_FILE "tst_pres_temp_4D_netcdf4_classic.nc"
   printf("*** testing 4D example file in classic format...");
   if (create_4D_example(NC3_CLASSIC_FILE, NC_CLOBBER)) ERR;
   if (check_4D_example(NC3_CLASSIC_FILE, NC_FORMAT_CLASSIC)) ERR;      
   SUMMARIZE_ERR;
   printf("*** testing 4D example file in 64-bit offset format...");
   if (create_4D_example(NC3_64BIT_OFFSET_FILE, NC_CLOBBER|NC_64BIT_OFFSET)) ERR;
   if (check_4D_example(NC3_64BIT_OFFSET_FILE, NC_FORMAT_64BIT)) ERR;      
   SUMMARIZE_ERR;
   printf("*** testing 4D example file in netCDF-4/HDF5 format...");
   if (create_4D_example(NC3_NETCDF4_FILE, NC_CLOBBER|NC_NETCDF4)) ERR;
   if (check_4D_example(NC3_NETCDF4_FILE, NC_FORMAT_NETCDF4)) ERR;      
   SUMMARIZE_ERR;
   printf("*** testing 4D example file in netCDF-4/HDF5 format with classic model rules...");
   if (create_4D_example(NC3_NETCDF4_CLASSIC_FILE, NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL)) ERR;
   if (check_4D_example(NC3_NETCDF4_CLASSIC_FILE, NC_FORMAT_NETCDF4_CLASSIC)) ERR;      
   SUMMARIZE_ERR;

   FINAL_RESULTS;
#ifdef USE_PARALLEL
   MPI_Finalize();
#endif   

}
Beispiel #9
0
/**
 * @ingroup PIO_def_var
 * Set chunksizes for a variable.
 *
 * This function only applies to netCDF-4 files. When used with netCDF
 * classic files, the error PIO_ENOTNC4 will be returned.
 *
 * See the <a
 * href="http://www.unidata.ucar.edu/software/netcdf/docs/group__variables.html">netCDF
 * variable documentation</a> for details about the operation of this
 * function.
 * 
 * Chunksizes have important performance repercussions. NetCDF
 * attempts to choose sensible chunk sizes by default, but for best
 * performance check chunking against access patterns.
 *
 * @param ncid the ncid of the open file.
 * @param varid the ID of the variable to set chunksizes for.
 * @param storage NC_CONTIGUOUS or NC_CHUNKED.
 * @param chunksizep an array of chunksizes. Must have a chunksize for
 * every variable dimension.
 * 
 * @return PIO_NOERR for success, otherwise an error code.
 */
int PIOc_def_var_fill(int ncid, int varid, int no_fill, const void *fill_value)
{
    int ierr;
    int msg;
    int mpierr;
    iosystem_desc_t *ios;
    file_desc_t *file;
    char *errstr;

    errstr = NULL;
    ierr = PIO_NOERR;

    if (!(file = pio_get_file_from_id(ncid)))
	return PIO_EBADID;
    ios = file->iosystem;
    msg = PIO_MSG_SET_FILL;

    if (ios->async_interface && ! ios->ioproc)
    {
	if (ios->compmaster) 
	    mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm);
	mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm);
    }

    if (ios->ioproc)
    {
	switch (file->iotype)
	{
#ifdef _NETCDF
#ifdef _NETCDF4
	case PIO_IOTYPE_NETCDF4P:
	    ierr = nc_def_var_fill(file->fh, varid, no_fill, fill_value);
	    break;
	case PIO_IOTYPE_NETCDF4C:
	    if (ios->io_rank==0)
	    {
		ierr = nc_def_var_fill(file->fh, varid, no_fill, fill_value);
	    }
	    break;
#endif
	case PIO_IOTYPE_NETCDF:
	    return PIO_ENOTNC4;
	    break;
#endif
#ifdef _PNETCDF
	case PIO_IOTYPE_PNETCDF:
	    return PIO_ENOTNC4;
	    break;
#endif
	default:
	    ierr = iotype_error(file->iotype,__FILE__,__LINE__);
	}
    }

    /* Allocate an error string if needed. */
    if (ierr != PIO_NOERR)
    {
	errstr = (char *) malloc((strlen(__FILE__) + 20)* sizeof(char));
	sprintf(errstr,"in file %s",__FILE__);
    }

    /* Check for netCDF error. */
    ierr = check_netcdf(file, ierr, errstr,__LINE__);

    /* Free the error string if it was allocated. */
    if (errstr != NULL)
	free(errstr);

    return ierr;
}
Beispiel #10
0
int main(int argc, char** argv) {
    char filename[256];
    int i, j, k, err, nerrs=0, ncid, varid[2], dimid[2], *buf;
    size_t start[2], count[2];
    int formats[5]={NC_FORMAT_CLASSIC, NC_FORMAT_64BIT_OFFSET, NC_FORMAT_CDF5,
                    NC_FORMAT_NETCDF4, NC_FORMAT_NETCDF4_CLASSIC};

    if (argc > 2) {
        printf("Usage: %s [filename]\n",argv[0]);
        return 1;
    }
    if (argc == 2) snprintf(filename, 256, "%s", argv[1]);
    else           strcpy(filename, "tst_def_var_fill.nc");

    char *cmd_str = (char*)malloc(strlen(argv[0]) + 256);
    sprintf(cmd_str, "*** TESTING C   %s for def_var_fill ", argv[0]);
    printf("%-66s ------ ", cmd_str); fflush(stdout);
    free(cmd_str);

    buf = (int*) malloc(NY*NX * sizeof(int));

    for (k=0; k<5; k++) {
#ifndef ENABLE_CDF5
        if (formats[k] == NC_FORMAT_CDF5) continue;
#endif
#ifndef USE_NETCDF4
        if (formats[k] == NC_FORMAT_NETCDF4 ||
            formats[k] == NC_FORMAT_NETCDF4_CLASSIC)
            continue;
#endif
        nc_set_default_format(formats[k], NULL);

        /* create a new file for writing ------------------------------------*/
        err = nc_create(filename, NC_CLOBBER, &ncid); CHECK_ERR

        /* define dimension */
        err = nc_def_dim(ncid, "Y", NY, &dimid[0]); CHECK_ERR
        err = nc_def_dim(ncid, "X", NX, &dimid[1]); CHECK_ERR

        /* define variables */
        err = nc_def_var(ncid, "var_nofill", NC_INT, 2, dimid, &varid[0]); CHECK_ERR
        err = nc_def_var(ncid, "var_fill",   NC_INT, 2, dimid, &varid[1]); CHECK_ERR

        /* set fill mode for variables */
        err = nc_def_var_fill(ncid, NC_GLOBAL, 0, NULL); EXP_ERR(NC_EGLOBAL)
        err = nc_def_var_fill(ncid, varid[0], 1, NULL); CHECK_ERR
        err = nc_def_var_fill(ncid, varid[1], 0, NULL); CHECK_ERR

        err = nc_enddef(ncid); CHECK_ERR

        /* write a subarray to both variables */
        for (i=0; i<NY*NX; i++) buf[i] = 5;
        start[0] = 0;
        start[1] = 2;
        count[0] = NY;
        count[1] = 2;
        err = nc_put_vara_int(ncid, varid[0], start, count, buf); CHECK_ERR
        err = nc_put_vara_int(ncid, varid[1], start, count, buf); CHECK_ERR
        err = nc_close(ncid); CHECK_ERR

        /* Now, reopen the file and read variables back */
        err = nc_open(filename, NC_WRITE, &ncid); CHECK_ERR

        /* get variable IDs */
        err = nc_inq_varid(ncid, "var_nofill", &varid[0]); CHECK_ERR
        err = nc_inq_varid(ncid, "var_fill",   &varid[1]); CHECK_ERR

        /* read variable "var_nofill" and check contents */
        for (i=0; i<NY*NX; i++) buf[i] = -1;
        err = nc_get_var_int(ncid, varid[0], buf); CHECK_ERR
        for (i=0; i<NY; i++) {
            for (j=0; j<NX; j++) {
                if (2 <= j && j < 4) {
                    if (buf[i*NX+j] != 5) {
                        printf("Error at line %d in %s: expect get buf[%d]=%d but got %d\n",
                               __LINE__,__FILE__,i*NX+j, 5, buf[i*NX+j]);
                        nerrs++;
                    }
                }
                else if (buf[i*NX+j] == NC_FILL_INT) {
                    printf("Warning at line %d in %s: get buf[%d] same as NC_FILL_INT\n",
                           __LINE__,__FILE__,i*NX+j);
                }
            }
        }

        /* read variable "var_fill" and check contents */
        for (i=0; i<NY*NX; i++) buf[i] = -1;
        err = nc_get_var_int(ncid, varid[1], buf); CHECK_ERR
        for (i=0; i<NY; i++) {
            for (j=0; j<NX; j++) {
                int expect = NC_FILL_INT;
                if (2 <= j && j< 4) expect = 5;

                if (buf[i*NX+j] != expect) {
                    printf("Error at line %d in %s: expect get buf[%d]=%d but got %d\n",
                           __LINE__,__FILE__,i*NX+j, expect, buf[i*NX+j]);
                    nerrs++;
                }
            }
        }

        err = nc_close(ncid); CHECK_ERR
    }
    free(buf);

    if (nerrs) printf("fail with %d mismatches\n",nerrs);
    else       printf("pass\n");

    return (nerrs > 0);
}
Beispiel #11
0
int
main(int argc, char **argv)
{
   printf("\n*** Testing netcdf-4 string type.\n");
   printf("*** testing string attribute...");
   {
#define ATT_LEN_1 1
#define MOUNTAIN_RANGE "mountain_range"
      size_t att_len;
      int ndims, nvars, natts, unlimdimid;
      nc_type att_type;
      int ncid, i;
      char *data_in[ATT_LEN_1] = {NULL};
      char *data[ATT_LEN_1] = {"R"};

      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att(ncid, NC_GLOBAL, MOUNTAIN_RANGE, NC_STRING, ATT_LEN_1, data)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 0 || nvars != 0 || natts != 1 || unlimdimid != -1) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, MOUNTAIN_RANGE, &att_type, &att_len)) ERR;
      if (att_type != NC_STRING || att_len != ATT_LEN_1) ERR;
      if (nc_close(ncid)) ERR;

      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 0 || nvars != 0 || natts != 1 || unlimdimid != -1) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, MOUNTAIN_RANGE, &att_type, &att_len)) ERR;
      if (att_type != NC_STRING || att_len != ATT_LEN_1) ERR;
      if (nc_get_att(ncid, NC_GLOBAL, MOUNTAIN_RANGE, data_in)) ERR;
      for (i = 0; i < att_len; i++)
      	 if (strcmp(data_in[i], data[i])) ERR;
      if (nc_free_string(ATT_LEN_1, (char **)data_in)) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing string attribute...");
   {
#define ATT_LEN 9
      size_t att_len;
      int ndims, nvars, natts, unlimdimid;
      nc_type att_type;
      int ncid, i;
      char *data_in[ATT_LEN];
      char *data[ATT_LEN] = {"Let but your honour know",
			     "Whom I believe to be most strait in virtue",
			     "That, in the working of your own affections",
			     "Had time cohered with place or place with wishing",
			     "Or that the resolute acting of your blood",
			     "Could have attain'd the effect of your own purpose",
			     "Whether you had not sometime in your life",
			     "Err'd in this point which now you censure him",
			     "And pull'd the law upon you."};

      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att(ncid, NC_GLOBAL, ATT_NAME, NC_STRING, ATT_LEN, data)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 0 || nvars != 0 || natts != 1 || unlimdimid != -1) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_NAME, &att_type, &att_len)) ERR;
      if (att_type != NC_STRING || att_len != ATT_LEN) ERR;
      if (nc_close(ncid)) ERR;

      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
      if (ndims != 0 || nvars != 0 || natts != 1 || unlimdimid != -1) ERR;
      if (nc_inq_att(ncid, NC_GLOBAL, ATT_NAME, &att_type, &att_len)) ERR;
      if (att_type != NC_STRING || att_len != ATT_LEN) ERR;
      if (nc_get_att(ncid, NC_GLOBAL, ATT_NAME, data_in)) ERR;
      for (i = 0; i < att_len; i++)
      	 if (strcmp(data_in[i], data[i])) ERR;
      if (nc_free_string(att_len, (char **)data_in)) ERR;
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing string var functions...");
   {
#define MOBY_LEN 16
      int ncid, varid, dimids[NDIMS];
      char *data[] = {"Perhaps a very little thought will now enable you to account for ",
		      "those repeated whaling disasters--some few of which are casually ",
		      "chronicled--of this man or that man being taken out of the boat by ",
		      "the line, and lost.",
		      "For, when the line is darting out, to be seated then in the boat, ",
		      "is like being seated in the midst of the manifold whizzings of a ",
		      "steam-engine in full play, when every flying beam, and shaft, and wheel, ",
		      "is grazing you.",
		      "It is worse; for you cannot sit motionless in the heart of these perils, ",
		      "because the boat is rocking like a cradle, and you are pitched one way and ",
		      "the other, without the slightest warning;",
		      "But why say more?",
		      "All men live enveloped in whale-lines.",
		      "All are born with halters round their necks; but it is only when caught ",
		      "in the swift, sudden turn of death, that mortals realize the silent, subtle, ",
		      "ever-present perils of life."};
      char *data_in[MOBY_LEN];
      int i;

      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_NAME, MOBY_LEN, dimids)) ERR;
      if (nc_def_var(ncid, VAR_NAME, NC_STRING, NDIMS, dimids, &varid)) ERR;
      if (nc_put_var_string(ncid, varid, (const char **)data)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check it out. */
     if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
     if (nc_get_var_string(ncid, varid, data_in)) ERR;
     for (i=0; i<MOBY_LEN; i++)
	if (strcmp(data_in[i], data[i])) ERR;
     if (nc_free_string(MOBY_LEN, (char **)data_in)) ERR;
     if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing string attributes...");
   {
#define SOME_PRES 16
#define NDIMS_PRES 1
#define ATT2_NAME "presidents"

      int ncid, i;
      char *data[SOME_PRES] = {"Washington", "Adams", "Jefferson", "Madison",
			       "Monroe", "Adams", "Jackson", "Van Buren",
			       "Harrison", "Tyler", "Polk", "Taylor",
			       "Fillmore", "Pierce", "Buchanan", "Lincoln"};
      char *data_in[SOME_PRES];

      /* Create a file with string attribute. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_put_att_string(ncid, NC_GLOBAL, ATT2_NAME, SOME_PRES, (const char **)data)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_get_att_string(ncid, NC_GLOBAL, ATT2_NAME, (char **)data_in)) ERR;
      for (i=0; i < SOME_PRES; i++)
	 if (strcmp(data_in[i], data[i])) ERR;

      /* Must free your data! */
      if (nc_free_string(SOME_PRES, (char **)data_in)) ERR;

      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing string fill value...");
   {
#define NUM_PRES 43
#define SOME_PRES 16
#define NDIMS_PRES 1
#define VAR_NAME_P "presidents"
      int ncid, varid, i, dimids[NDIMS_PRES];
      size_t start[NDIMS_PRES], count[NDIMS_PRES];
      char *data[SOME_PRES] = {"Washington", "Adams", "Jefferson", "Madison",
			       "Monroe", "Adams", "Jackson", "Van Buren",
			       "Harrison", "Tyler", "Polk", "Taylor",
			       "Fillmore", "Pierce", "Buchanan", "Lincoln"};
      char *data_in[NUM_PRES];

      /* Create a file with NUM_PRES strings, and write SOME_PRES of
       * them. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_NAME, NUM_PRES, dimids)) ERR;
      if (nc_def_var(ncid, VAR_NAME_P, NC_STRING, NDIMS_PRES, dimids, &varid)) ERR;
      start[0] = 0;
      count[0] = SOME_PRES;
      if (nc_put_vara_string(ncid, varid, start, count, (const char **)data)) ERR;
      if (nc_close(ncid)) ERR;

      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_get_var_string(ncid, varid, data_in)) ERR;
      for (i = 0; i < NUM_PRES; i++)
      {
	 if (i < SOME_PRES && (data_in[i] == NULL || strcmp(data_in[i], data[i]))) ERR;
	 if (i >= SOME_PRES && (data_in[i] == NULL || strcmp(data_in[i], ""))) ERR;
      }

      /* Must free your data! */
      if (nc_free_string(NUM_PRES, (char **)data_in)) ERR;

      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** Testing netcdf-4 strided string access...");
   {
#define NUM_PRES 43
#define SOME_PRES 16
#define NDIMS_PRES 1
#define VAR_NAME_P "presidents"
      int ncid, varid, i, dimids[NDIMS_PRES];
      size_t start[NDIMS_PRES], count[NDIMS_PRES];
      ptrdiff_t stride[NDIMS_PRES];
      char *data[SOME_PRES] = {"Washington", "Adams", "Jefferson", "Madison",
			       "Monroe", "Adams", "Jackson", "Van Buren",
			       "Harrison", "Tyler", "Polk", "Taylor",
			       "Fillmore", "Pierce", "Buchanan", "Lincoln"};
      char *data_in[NUM_PRES];
      int status;

      /* Create a file with NUM_PRES strings, and write SOME_PRES of
       * them. */
      if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
      if (nc_def_dim(ncid, DIM_NAME, NUM_PRES, dimids)) ERR;
      if (nc_def_var(ncid, VAR_NAME_P, NC_STRING, NDIMS_PRES, dimids, &varid)) ERR;
      start[0] = 0;
      count[0] = SOME_PRES;
      stride[0] = 2;
      status = nc_put_vars_string(ncid, varid, start, count, stride, (const char **)data);
      if(status != NC_NOERR)
	  fprintf(stderr,"%s\n",nc_strerror(status));
      if (nc_close(ncid)) ERR;

      /* Check it out. */
      if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
      if (nc_get_vars_string(ncid, varid, start, count, stride, data_in)) ERR;
      for (i = 0; i < NUM_PRES; i++)
      {
	 if (i < SOME_PRES && strcmp(data_in[i], data[i])) ERR;
      }

      /* Must free your data! */
      if (nc_free_string(SOME_PRES, (char **)data_in)) ERR;

      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   printf("*** testing string variables with fill values...");
   {
#define VAR_NAME2 "empty"
#define ATT_NAME2 "empty"
#define DHR_LEN 30
#define DIM_NAME1 "article"
#define VAR_NAME1 "universal_declaration_of_human_rights"
      int var_dimids[NDIMS];
      int ndims, nvars, natts, unlimdimid;
      nc_type var_type;
      char var_name[NC_MAX_NAME + 1];
      int var_natts, var_ndims;
      int ncid, varid, i, dimids[NDIMS], varid2;
      char *data[DHR_LEN] = {
	 "All human beings are born free and equal in dignity and rights. "
	 "They are endowed with reason and "
	 "conscience and should act towards one another in a "
	 "spirit of brotherhood.",
	 "Everyone is entitled to all the rights and freedoms set "
	 "forth in this Declaration, without distinction of "
	 "any kind, such as race, colour, sex, language, religion, "
	 "political or other opinion, national or social "
	 "origin, property, birth or other status. Furthermore, no "
	 "distinction shall be made on the basis of the "
	 "political, jurisdictional or international status of the "
	 "country or territory to which a person belongs, "
	 "whether it be independent, trust, non-self-governing or "
	 "under any other limitation of sovereignty.",
	 "Everyone has the right to life, liberty and security of person.",
	 "No one shall be held in slavery or servitude; slavery and the "
	 "slave trade shall be prohibited in all their forms.",
	 "No one shall be subjected to torture or to cruel, "
	 "inhuman or degrading treatment or punishment.",
	 "Everyone has the right to recognition everywhere as "
	 "a person before the law.",
	 "All are equal before the law and are entitled without "
	 "any discrimination to equal protection of the law. All are "
	 "entitled to equal protection against any discrimination in "
	 "violation of this Declaration and against any incitement "
	 "to such discrimination.",
	 "Everyone has the right to an effective remedy by the "
	 "competent national tribunals for acts violating the "
	 "fundamental rights granted "
	 "him by the constitution or by law.",
	 "No one shall be subjected to arbitrary arrest, detention or exile.",
	 "Everyone is entitled in full equality to a fair and public "
	 "hearing by an independent and impartial tribunal, in the "
	 "determination of his rights and obligations and of any "
	 "criminal charge against him.",
	 "(1) Everyone charged with a penal offence has the right "
	 "to be presumed innocent until proved guilty according to law in a "
	 "public trial at which he has had all the guarantees "
	 "necessary for his defence."
	 "(2) No one shall be held guilty of any penal offence "
	 "on account of any act or omission which did not constitute a penal "
	 "offence, under national or international law, at the time "
	 "when it was committed. Nor shall a heavier penalty be imposed "
	 "than the one that was applicable at the time the penal "
	 "offence was committed.",
	 "No one shall be subjected to arbitrary interference with "
	 "his privacy, family, home or correspondence, nor to attacks upon "
	 "his honour and reputation. Everyone has the right to the "
	 "protection of the law against such interference or attacks.",
	 "(1) Everyone has the right to freedom of movement and "
	 "residence within the borders of each state."
	 "(2) Everyone has the right to leave any country, "
	 "including his own, and to return to his country.",
	 "(1) Everyone has the right to seek and to enjoy in "
	 "other countries asylum from persecution. "
	 "(2) This right may not be invoked in the case of prosecutions "
	 "genuinely arising from non-political crimes or from acts "
	 "contrary to the purposes and principles of the United Nations.",
	 "(1) Everyone has the right to a nationality. (2) No one shall "
	 "be arbitrarily deprived of his nationality nor denied the "
	 "right to change his nationality.",
	 "(1) Men and women of full age, without any limitation "
	 "due to race, nationality or religion, have the right "
	 "to marry and to found a family. "
	 "They are entitled to equal rights as to marriage, "
	 "during marriage and at its dissolution. (2) Marriage "
	 "shall be entered into only with the free and full "
	 "consent of the intending spouses. (3) The family is "
	 "the natural and fundamental group unit of society and "
	 "is entitled to protection by society and the State.",
	 "(1) Everyone has the right to own property alone as "
	 "well as in association with others. (2) No one shall "
	 "be arbitrarily deprived of his property.",
	 "Everyone has the right to freedom of thought, conscience "
	 "and religion; this right includes freedom to change "
	 "his religion or belief, and freedom, "
	 "either alone or in community with others and in "
	 "public or private, to manifest his religion or "
	 "belief in teaching, practice, worship and observance.",
	 "Everyone has the right to freedom of opinion and "
	 "expression; this right includes freedom to hold "
	 "opinions without interference and to seek, receive "
	 "and impart information and ideas through any media "
	 "and regardless of frontiers.",
	 "(1) Everyone has the right to freedom of peaceful assembly "
	 "and association. (2) No one may be compelled to belong to "
	 "an association.",
	 "(1) Everyone has the right to take part in the government "
	 "of his country, directly or through freely chosen representatives. "
	 "(2) Everyone has the right of equal access to public "
	 "service in his country. (3) The will of the people "
	 "shall be the basis of the authority of government; "
	 "this will shall be expressed in periodic and genuine "
	 "elections which shall be by universal and equal suffrage "
	 "and shall be held by secret vote or by "
	 "equivalent free voting procedures.",
	 "Everyone, as a member of society, has the right to "
	 "social security and is entitled to realization, "
	 "through national effort and international co-operation "
	 "and in accordance with the organization and resources of "
	 "each State, of the economic, social and cultural rights "
	 "indispensable for his dignity and the free "
	 "development of his personality.",
	 "(1) Everyone has the right to work, to free choice "
	 "of employment, to just and favourable conditions of "
	 "work and to protection against unemployment. "
	 "(2) Everyone, without any discrimination, has the right "
	 "to equal pay for equal work. (3) Everyone who works "
	 "has the right to just and favourable "
	 "remuneration ensuring for himself and his family an "
	 "existence worthy of human dignity, and supplemented, "
	 "if necessary, by other means of social protection."
	 "(4) Everyone has the right to form and to join trade "
	 "unions for the protection of his interests.",
	 "Everyone has the right to rest and leisure, including "
	 "reasonable limitation of working hours and periodic "
	 "holidays with pay.",
	 "(1) Everyone has the right to a standard of living "
	 "adequate for the health and well-being of himself "
	 "and of his family, including food, clothing, housing "
	 "and medical care and necessary social services, and "
	 "the right to security in the event of unemployment, "
	 "sickness, disability, widowhood, old age or other lack "
	 "of livelihood in circumstances beyond his control. "
	 "(2) Motherhood and childhood are entitled to special "
	 "care and assistance. All children, whether "
	 "born in or out of wedlock, shall enjoy the same "
	 "social protection.",
	 "(1) Everyone has the right to education. Education "
	 "shall be free, at least in the elementary and "
	 "fundamental stages. Elementary education shall be compulsory. "
	 "Technical and professional education shall be made generally "
	 "available and higher education "
	 "shall be equally accessible to all on the basis of merit. "
	 "(2) Education shall be directed to the full development of "
	 "the human personality and to the strengthening of respect for "
	 "human rights and fundamental freedoms. "
	 "It shall promote understanding, tolerance and friendship among "
	 "all nations, racial or religious groups, and shall further the "
	 "activities of the United Nations "
	 "for the maintenance of peace. (3) Parents have a prior right to "
	 "choose the kind of education that shall be given to their children.",
	 "(1) Everyone has the right freely to participate in the cultural "
	 "life of the community, to enjoy the arts and to share in scientific "
	 "advancement and its benefits. "
	 "(2) Everyone has the right to the protection of the moral "
	 "and material interests resulting from any scientific, "
	 "literary or artistic production of which he is the author.",
	 "Everyone is entitled to a social and international order in "
	 "which the rights and freedoms set forth in this Declaration "
	 "can be fully realized.",
	 "(1) Everyone has duties to the community in which alone "
	 "the free and full development of his personality is possible. "
	 "(2) In the exercise of his rights and "
	 "freedoms, everyone shall be subject only to such limitations "
	 "as are determined by law solely for the purpose "
	 "of securing due recognition and respect for the rights "
	 "and freedoms of others and of meeting the just requirements "
	 "of morality, public order and the general welfare in a "
	 "democratic society. (3) These rights and freedoms may in no "
	 "case be exercised contrary to the purposes and "
	 "principles of the United Nations.",
	 "Nothing in this Declaration may be interpreted as implying "
	 "for any State, group or person any right to engage in any "
	 "activity or to perform any act aimed at the destruction of "
	 "any of the rights and freedoms set forth herein."
      };
      char *empty_string[] = {""};
      char *my_string_fill[] = {"fill_string"};

#define NUM_DIM_COMBOS 4
      int dim_combo;

      for (dim_combo = 0; dim_combo < NUM_DIM_COMBOS; dim_combo++)
      {
         char filename[NC_MAX_NAME + 1];
         int dim_len = dim_combo ? NC_UNLIMITED : DHR_LEN;
         int expected_unlimdimid = dim_combo ? 0 : -1;
         char *default_fill = ((char *)"");
         char **string_fillp = dim_combo == 3 ? my_string_fill : &default_fill;
         char *data_in;

         sprintf(filename, "%s_dim_combo_%d.nc", TEST_NAME, dim_combo);
         if (nc_create(filename, NC_NETCDF4, &ncid)) ERR;

         /* Create an array of strings for the Universal Declaraion of Human Rights. */
         if (nc_def_dim(ncid, DIM_NAME1, dim_len, dimids)) ERR;
         if (nc_def_var(ncid, VAR_NAME1, NC_STRING, NDIMS, dimids, &varid)) ERR;

         /* Create a scalar variable for the empty string. */
         if (nc_def_var(ncid, VAR_NAME2, NC_STRING, 0, NULL, &varid2)) ERR;
         if (dim_combo == 3)
            if (nc_put_att(ncid, varid, _FillValue, NC_STRING, 1, my_string_fill)) ERR;

         /* Check some stuff. */
         if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
         if (ndims != NDIMS || nvars != 2 || natts != 0 || unlimdimid != expected_unlimdimid) ERR;
         if (nc_inq_var(ncid, varid, var_name, &var_type, &var_ndims,
                        var_dimids, &var_natts)) ERR;
         if (var_type != NC_STRING || strcmp(var_name, VAR_NAME1) || var_ndims != NDIMS ||
             var_dimids[0] != dimids[0]) ERR;

         /* Write the universal declaraion of human rights. */
         if (dim_combo)
         {
            size_t start[NDIMS], count[NDIMS] = {1};
            int counter = 1;
            
            /* Write one record at a time. */
            for (start[0] = 0; start[0] < DHR_LEN; start[0]++)
            {
               size_t new_start[NDIMS];
               size_t *my_startp = start;

               /* For dim_combo 2 or 3 skip every other record. */
               new_start[0] = start[0] + counter++;
               if (dim_combo >= 2)
                  my_startp = new_start;

               /* Write a record. */
               nc_put_vara_string(ncid, varid, my_startp, count, (const char **)&data[start[0]]);
            }
         }
         else
         {
            /* Write all records at once. */
            if (nc_put_var(ncid, varid, data)) ERR;
         }

         /* Write an empty string with an empty attribute. */
         if (nc_put_var(ncid, varid2, empty_string)) ERR;
         if (nc_put_att(ncid, varid2, ATT_NAME2, NC_STRING, 0, empty_string)) ERR;

         /* Close the file. */
         if (nc_close(ncid)) ERR;

         /* Check it out. */
         if (nc_open(filename, NC_NOWRITE, &ncid)) ERR;
         if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
         if (ndims != NDIMS || nvars != 2 || natts != 0 || unlimdimid != expected_unlimdimid) ERR;

         /* Check declaration. */
         if (nc_inq_varid(ncid, VAR_NAME1, &varid)) ERR;
         if (nc_inq_var(ncid, varid, var_name, &var_type, &var_ndims, var_dimids,
                        &var_natts)) ERR;
         if (var_type != NC_STRING || strcmp(var_name, VAR_NAME1) || var_ndims != NDIMS ||
             var_dimids[0] != dimids[0]) ERR;

         /* Check fill value stuff. */
         {
            int no_fill;
            char *fill_value_in[1];
            
            if (nc_inq_var_fill(ncid, varid, &no_fill, (char **)fill_value_in)) ERR;
            if (no_fill) ERR;
            if (strcmp(fill_value_in[0], *string_fillp)) ERR;
            if (nc_free_string(1, (char **)fill_value_in)) ERR;
         }

         if (dim_combo < 2)
         {
            char *data_in[DHR_LEN];
            
            /* Get the data in one read of the entire var. */
            if (nc_get_var(ncid, varid, data_in)) ERR;
            for (i = 0; i < DHR_LEN; i++)
               if (strcmp(data_in[i], data[i])) ERR;
            if (nc_free_string(DHR_LEN, data_in)) ERR;
         }
         else
         {
            char *data_in;
            size_t start[NDIMS], count[NDIMS] = {1};
            int my_count = 0;
            
            /* Get the data one record at a time. Every other record,
             * starting with the first, is a fill value. */
            for (start[0] = 0; start[0] < DHR_LEN; start[0]++)
            {
               if (nc_get_vara(ncid, varid, start, count, &data_in)) ERR;
               if (start[0] % 2)
               {
                  if (strcmp(data_in, data[my_count++])) ERR;
               }
               else
               {
                  if (strcmp(data_in, *string_fillp)) ERR;
               }
               if (nc_free_string(1, &data_in)) ERR;
            }
         }

         /* Check the empty var and att. */
         if (nc_inq_varid(ncid, VAR_NAME2, &varid)) ERR;
         if (nc_get_var(ncid, varid, &data_in)) ERR;
         if (strcmp(data_in, empty_string[0])) ERR;
         if (nc_free_string(1, &data_in)) ERR;
         if (nc_get_att(ncid, varid, ATT_NAME2, NULL)) ERR;
         if (nc_close(ncid)) ERR;
      } /* next dim_combo */
   }
   SUMMARIZE_ERR;

   printf("*** Testing a file that causes ncdump problems...");
   {
#define NUM_DIMS 2
#define DIM_0_NAME "dim_0"
#define DIM_1_NAME "dim_1"
#define DIM_1_LEN 2
#define FILE_NAME_NCDUMP "tst_strings_ncdump_problem.nc"
#define VAR_NAME_NCDUMP "var_string"
      int ncid, varid, dimid[NUM_DIMS];
      char *string_data[] = {"x"};
      int t;

      /* Create a file. */
      if (nc_create(FILE_NAME_NCDUMP, NC_NETCDF4, &ncid)) ERR;

      /* Create dims. */
      if (nc_def_dim(ncid, DIM_0_NAME, NC_UNLIMITED, &dimid[0])) ERR;
      if (nc_def_dim(ncid, DIM_1_NAME, DIM_1_LEN, &dimid[1])) ERR;
               
      /* Create a var. */
      if (nc_def_var(ncid, VAR_NAME_NCDUMP, NC_STRING, NUM_DIMS, dimid, &varid)) ERR;

      /* Check that you can't turn off fill mode for NC_STRING variables. */
      if (nc_def_var_fill(ncid, varid, NC_NOFILL, NULL) != NC_EINVAL) ERR;

      /* End define mode. */
      if (nc_enddef(ncid)) ERR;

      /* Write to each var. */
      for (t = 0; t < 1; t++)
      {
         size_t start[NUM_DIMS] = {1, 0};
         size_t count[NUM_DIMS] = {1, 1};

         if (nc_put_vara_string(ncid, varid, start, count, (const char **)string_data)) ERR;
      }
      if (nc_close(ncid)) ERR;
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}