示例#1
0
/**
 * @ingroup PIO_def_var
 *
 * Set chunk cache netCDF files to be opened/created.
 *
 * This function only applies to netCDF-4 files. When used with netCDF
 * classic files, the error PIO_ENOTNC4 will be returned.
 *
 * The file chunk cache for HDF5 can be set, and will apply for any
 * files opened or created until the program ends, or the settings are
 * changed again. The cache settings apply only to the open file. They
 * do not persist with the file, and must be set each time the file is
 * opened, before it is opened, if they are to have effect.
 *
 * 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.
 * 
 * @param iotype the iotype of files to be created or opened.
 * @param size size of file cache.
 * @param nelems number of elements in file cache.
 * @param preemption preemption setting for file cache.
 * 
 * @return PIO_NOERR for success, otherwise an error code.
 */
int PIOc_set_chunk_cache(int iosysid, int iotype, PIO_Offset size,
			 PIO_Offset nelems, float preemption)
{
    int ierr;
    int msg;
    int mpierr;
    iosystem_desc_t *ios;
    file_desc_t *file;
    char *errstr;

    errstr = NULL;
    ierr = PIO_NOERR;
    msg = PIO_MSG_SET_CHUNK_CACHE;

    ios = pio_get_iosystem_from_id(iosysid);
    if(ios == NULL)
	return PIO_EBADID;

  /* 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); */
    /* } */

    switch (iotype)
    {
#ifdef _NETCDF
#ifdef _NETCDF4
    case PIO_IOTYPE_NETCDF4P:
	ierr = nc_set_chunk_cache(size, nelems, preemption);
	break;
    case PIO_IOTYPE_NETCDF4C:
	if (!ios->io_rank)
	    ierr = nc_set_chunk_cache(size, nelems, preemption);
	break;
#endif
    case PIO_IOTYPE_NETCDF:
	ierr = PIO_ENOTNC4;
	break;
#endif
#ifdef _PNETCDF
    case PIO_IOTYPE_PNETCDF:
	ierr = PIO_ENOTNC4;
	break;
#endif
    default:
	ierr = iotype_error(file->iotype,__FILE__,__LINE__);
    }

    /* Propogate error code to all processes. */
    MPI_Bcast(&ierr, 1, MPI_INTEGER, ios->ioroot, ios->my_comm);    

    return ierr;
}    
示例#2
0
int 
main(int argc, char **argv)
{
   extern int optind;
   extern int opterr;
   extern char *optarg;
   int c, header = 0, verbose = 0, timeseries = 0;
   int ncid, varid, storage;
   char name_in[NC_MAX_NAME + 1];
   size_t len;
   size_t cs[NDIMS3] = {0, 0, 0};
   int cache = MEGABYTE;
   int ndims, dimid[NDIMS3];
   float hor_data[LAT_LEN * LON_LEN];
   int read_1_us, avg_read_us;
   float ts_data[TIME_LEN];
   size_t start[NDIMS3], count[NDIMS3];
   int deflate, shuffle, deflate_level;
   struct timeval start_time, end_time, diff_time;

   while ((c = getopt(argc, argv, "vhtc:")) != EOF)
      switch(c) 
      {
	 case 'v':
	    verbose++;
	    break;
	 case 'h':
	    header++;
	    break;
	 case 't':
	    timeseries++;
	    break;
	 case 'c':
	    sscanf(optarg, "%d", &cache);
	    break;
	 case '?':
	    usage();
	    return 1;
      }
      
   argc -= optind;
   argv += optind;
      
   /* If no file arguments left, report and exit */
   if (argc < 1)
   {
      printf("no file specified\n");
      return 0;
   }
      
   /* Print the header if desired. */
   if (header)
   {
      printf("cs[0]\tcs[1]\tcs[2]\tcache(MB)\tdeflate\tshuffle");
      if (timeseries)
	 printf("\t1st_read_ser(us)\tavg_read_ser(us)\n");
      else
	 printf("\t1st_read_hor(us)\tavg_read_hor(us)\n");
   }

#define PREEMPTION .75
      /* Also tried NELEMS of 2500009*/
#define NELEMS 7919
   if (nc_set_chunk_cache(cache, NELEMS, PREEMPTION)) ERR;
   if (nc_open(argv[0], 0, &ncid)) ERR;

   /* Check to make sure that all the dimension information is
    * correct. */
   if (nc_inq_varid(ncid, DATA_VAR_NAME, &varid)) ERR;
   if (nc_inq_dim(ncid, LON_DIMID, name_in, &len)) ERR;
   if (strcmp(name_in, "lon") || len != LON_LEN) ERR;
   if (nc_inq_dim(ncid, LAT_DIMID, name_in, &len)) ERR;
   if (strcmp(name_in, "lat") || len != LAT_LEN) ERR;
   if (nc_inq_dim(ncid, BNDS_DIMID, name_in, &len)) ERR;
   if (strcmp(name_in, "bnds") || len != BNDS_LEN) ERR;
   if (nc_inq_dim(ncid, TIME_DIMID, name_in, &len)) ERR;
   if (strcmp(name_in, "time") || len != TIME_LEN) ERR;
   if (nc_inq_var(ncid, varid, NULL, NULL, &ndims, dimid, NULL)) ERR;
   if (ndims != NDIMS3 || dimid[0] != TIME_DIMID || 
       dimid[1] != LAT_DIMID || dimid[2] != LON_DIMID) ERR;

   /* Get info about the main data var. */
   if (nc_inq_var_chunking(ncid, varid, &storage, cs)) ERR;
   if (nc_inq_var_deflate(ncid, varid, &shuffle, &deflate, 
			  &deflate_level)) ERR;

   if (timeseries)
   {
      /* Read the var as a time series. */
      start[0] = 0;
      start[1] = 0;
      start[2] = 0;
      count[0] = TIME_LEN;
      count[1] = 1;
      count[2] = 1;
      
      /* Read the first timeseries. */
      if (gettimeofday(&start_time, NULL)) ERR;
      if (nc_get_vara_float(ncid, varid, start, count, ts_data)) ERR_RET;
      if (gettimeofday(&end_time, NULL)) ERR;
      if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
      read_1_us = (int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec;

      /* Read all the rest. */
      if (gettimeofday(&start_time, NULL)) ERR;
      for (start[1] = 0; start[1] < LAT_LEN; start[1]++)
	 for (start[2] = 1; start[2] < LON_LEN; start[2]++)
	    if (nc_get_vara_float(ncid, varid, start, count, ts_data)) ERR_RET;
      if (gettimeofday(&end_time, NULL)) ERR;
      if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
      avg_read_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec + read_1_us) / 
	 (LAT_LEN * LON_LEN);
   }
   else
   {
      /* Read the data variable in horizontal slices. */
      start[0] = 0;
      start[1] = 0;
      start[2] = 0;
      count[0] = 1;
      count[1] = LAT_LEN;
      count[2] = LON_LEN;

      /* Read (and time) the first one. */
      if (gettimeofday(&start_time, NULL)) ERR;
      if (nc_get_vara_float(ncid, varid, start, count, hor_data)) ERR_RET;
      if (gettimeofday(&end_time, NULL)) ERR;
      if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
      read_1_us = (int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec;

      /* Read (and time) all the rest. */
      if (gettimeofday(&start_time, NULL)) ERR;
      for (start[0] = 1; start[0] < TIME_LEN; start[0]++)
	 if (nc_get_vara_float(ncid, varid, start, count, hor_data)) ERR_RET;
      if (gettimeofday(&end_time, NULL)) ERR;
      if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
      avg_read_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec + 
		     read_1_us) / TIME_LEN;
   }

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

   /* Print results. */
   printf("%d\t%d\t%d\t%.1f\t\t%d\t%d\t\t",
	  (int)cs[0], (int)cs[1], (int)cs[2], 
	  (storage == NC_CHUNKED) ? (cache/(float)MEGABYTE) : 0, 
	  deflate, shuffle);
   if (timeseries)
      printf("%d\t\t%d\n", (int)read_1_us, (int)avg_read_us);
   else
      printf("%d\t\t%d\n", (int)read_1_us, (int)avg_read_us);

   return 0;
}
示例#3
0
/* This function creates a file with 10 2D variables, no unlimited
 * dimension. */
int test_pio_2d(size_t cache_size, int facc_type, int access_flag, MPI_Comm comm, 
		MPI_Info info, int mpi_size, int mpi_rank, 
		size_t *chunk_size) 
{
   double starttime, endtime, write_time = 0, bandwidth = 0;
   int ncid;
   int dimids[NDIMS1];
   size_t start[NDIMS1], count[NDIMS1];
   float *data;
   char file_name[NC_MAX_NAME + 1];
   char var_name1[NUMVARS][NC_MAX_NAME + 1] = {"GWa", "JAd", "TJe", "JMa", "JMo", 
					       "JQA", "AJa", "MVB", "WHH", "JTy"};
   int varid1[NUMVARS];
   size_t nelems_in;
   float preemption_in;
   int j, i, t;

   /* Create some data. */
   if (!(data = malloc(sizeof(float) * DIMSIZE2 * DIMSIZE1 / mpi_size)))
      return -2;
   for (j = 0; j < DIMSIZE2; j++)
      for (i = 0; i < DIMSIZE1 / mpi_size; i++)
	 data[j * DIMSIZE1 / mpi_size + i] = (float)mpi_rank * (j + 1);

   /* Get the file name. */
   sprintf(file_name, "%s/%s", TEMP_LARGE, FILENAME);

   /* Set the cache size. */
   if (nc_get_chunk_cache(NULL, &nelems_in, &preemption_in)) ERR;
   if (nc_set_chunk_cache(cache_size, nelems_in, preemption_in)) ERR;

   for (t = 0; t < NUM_TRIES; t++)
   {
      /* Create a netcdf-4 file, opened for parallel I/O. */
      if (nc_create_par(file_name, facc_type|NC_NETCDF4, comm, 
			info, &ncid)) ERR;

      /* Create two dimensions. */
      if (nc_def_dim(ncid, "d1", DIMSIZE2, &dimids[0])) ERR;
      if (nc_def_dim(ncid, "d2", DIMSIZE1, &dimids[1])) ERR;

      /* Create our variables. */
      for (i = 0; i < NUMVARS; i++)
      {
	 if (nc_def_var(ncid, var_name1[i], NC_INT, NDIMS1,
			dimids, &varid1[i])) ERR;
	 if (chunk_size[0])
	    if (nc_def_var_chunking(ncid, varid1[i], 0, chunk_size)) ERR;
      }

      if (nc_enddef(ncid)) ERR;

      /* Set up slab for this process. */
      start[0] = 0;
      start[1] = mpi_rank * DIMSIZE1/mpi_size;
      count[0] = DIMSIZE2;
      count[1] = DIMSIZE1 / mpi_size;

      /* start parallel netcdf4 */
      for (i = 0; i < NUMVARS; i++) 
	 if (nc_var_par_access(ncid, varid1[i], access_flag)) ERR;

      starttime = MPI_Wtime();

      /* Write two dimensional float data */
      for (i = 0; i < NUMVARS; i++)
	 if (nc_put_vara_float(ncid, varid1[i], start, count, data)) ERR;

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

      endtime = MPI_Wtime();
      if (!mpi_rank) 
      {
	 bandwidth += ((sizeof(float) * DIMSIZE1 * DIMSIZE2 * NUMVARS) / 
		       ((endtime - starttime) * 1024 * 1024)) / NUM_TRIES;
	 write_time += (endtime - starttime) / NUM_TRIES;
      }
   }
   free(data);
   if (!mpi_rank) 
   {
      char chunk_string[NC_MAX_NAME + 1] = "";

      /* What was our chunking? */
      if (chunk_size[0])
	 sprintf(chunk_string, "%dx%d    ", (int)chunk_size[0], (int)chunk_size[1]);
      else
	 strcat(chunk_string, "contiguous");

      /* Print the results. */
      printf("%d\t\t%s\t%s\t%d\t\t%dx%d\t\t%s\t%f\t\t%f\t\t\t%d\n", mpi_size, 
	     (facc_type == NC_MPIIO ? "MPI-IO   " : "MPI-POSIX"), 
	     (access_flag == NC_INDEPENDENT ? "independent" : "collective"), 
	     (int)cache_size/MEGABYTE, DIMSIZE1, DIMSIZE2, chunk_string, 
	     write_time, bandwidth, NUM_TRIES); 
   }

   /* Delete this file. */
   remove(file_name); 

   return 0;
}
示例#4
0
/* Case 2: create four dimensional integer data,
   one dimension is unlimited. */
int test_pio_4d(size_t cache_size, int facc_type, int access_flag, MPI_Comm comm, 
		MPI_Info info, int mpi_size, int mpi_rank, size_t *chunk_size) 
{
   int ncid, dimuids[NDIMS2], varid2[NUMVARS];
   size_t ustart[NDIMS2], ucount[NDIMS2];
   float *udata, *tempudata;
   char file_name[NC_MAX_NAME + 1];
   char var_name2[NUMVARS][NC_MAX_NAME + 1] = {"JKP", "ZTa", "MFi", "FPi", "JBu", 
					       "ALi", "AJo", "USG", "RBH", "JAG"};
   double starttime, endtime, write_time = 0, bandwidth = 0;
   size_t nelems_in;
   float preemption_in;
   int k, j, i, t;

   udata = malloc(DIMSIZE3 * DIMSIZE2 * DIMSIZE1 / mpi_size * sizeof(int));

   /* Create phony data. */
   tempudata = udata;
   for(k = 0; k < DIMSIZE3; k++)
      for(j = 0; j < DIMSIZE2; j++)
	 for(i = 0; i < DIMSIZE1 / mpi_size; i++)
	 {
	    *tempudata = (float)(1 + mpi_rank) * 2 * (j + 1) * (k + 1);
	    tempudata++;
	 }

   /* Get the file name. */
   sprintf(file_name, "%s/%s", TEMP_LARGE, FILENAME);
      
   /* Set the cache size. */
   if (nc_get_chunk_cache(NULL, &nelems_in, &preemption_in)) ERR;
   if (nc_set_chunk_cache(cache_size, nelems_in, preemption_in)) ERR;

   for (t = 0; t < NUM_TRIES; t++)
   {
      /* Create a netcdf-4 file. */
      if (nc_create_par(file_name, facc_type|NC_NETCDF4, comm, info, 
			&ncid)) ERR;

      /* Create four dimensions. */
      if (nc_def_dim(ncid, "ud1", TIMELEN, dimuids)) ERR;
      if (nc_def_dim(ncid, "ud2", DIMSIZE3, &dimuids[1])) ERR;
      if (nc_def_dim(ncid, "ud3", DIMSIZE2, &dimuids[2])) ERR;
      if (nc_def_dim(ncid, "ud4", DIMSIZE1, &dimuids[3])) ERR;

      /* Create 10 variables. */
      for (i = 0; i < NUMVARS; i++)
	 if (nc_def_var(ncid, var_name2[i], NC_INT, NDIMS2,
			dimuids, &varid2[i])) ERR;

      if (nc_enddef(ncid)) ERR;
 
      /* Set up selection parameters */
      ustart[0] = 0;
      ustart[1] = 0;
      ustart[2] = 0;
      ustart[3] = DIMSIZE1 * mpi_rank / mpi_size;
      ucount[0] = 1;
      ucount[1] = DIMSIZE3;
      ucount[2] = DIMSIZE2;
      ucount[3] = DIMSIZE1 / mpi_size;

      /* Access parallel */
      for (i = 0; i < NUMVARS; i++)
	 if (nc_var_par_access(ncid, varid2[i], access_flag)) ERR;

      starttime = MPI_Wtime();

      /* Write slabs of phony data. */
      for(ustart[0] = 0; ustart[0] < TIMELEN; ustart[0]++)
	 for (i = 0; i < NUMVARS; i++)
	    if (nc_put_vara_float(ncid, varid2[i], ustart, ucount, udata)) ERR;

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

      endtime = MPI_Wtime();
      if (!mpi_rank)
      {
	 write_time += (endtime - starttime) / NUM_TRIES;
	 bandwidth += (sizeof(float) * TIMELEN * DIMSIZE1 * DIMSIZE2 * DIMSIZE3 * NUMVARS) / 
	    ((endtime - starttime) * 1024 * 1024 * NUM_TRIES);
      }
   }
   free(udata);
   if (!mpi_rank)
   {
      char chunk_string[NC_MAX_NAME + 1] = "";

      /* What was our chunking? */
      if (chunk_size[0])
	 sprintf(chunk_string, "%dx%dx%dx%d", (int)chunk_size[0], (int)chunk_size[1], 
		 (int)chunk_size[2], (int)chunk_size[3]);
      else
	 strcat(chunk_string, "contiguous");

      /* Print our results. */
      printf("%d\t\t%s\t%s\t%d\t\t%dx%dx%dx%d\t%s\t%f\t\t%f\t\t\t%d\n", mpi_size, 
	     (facc_type == NC_MPIIO ? "MPI-IO   " : "MPI-POSIX"), 
	     (access_flag == NC_INDEPENDENT ? "independent" : "collective"), 
	     (int)cache_size / MEGABYTE, TIMELEN, DIMSIZE3, DIMSIZE2, DIMSIZE1, chunk_string, write_time, 
	     bandwidth, NUM_TRIES); 
   }

   /* Delete this file. */
   remove(file_name); 

   return 0;
}
示例#5
0
/* compare contiguous, chunked, and compressed performance */
int
main(int argc, char *argv[]) {

    int  stat;  /* return status */
    int  ncid;  /* netCDF id */
    int i, j, k;
    int dim1id, dim2id, dim3id;
    int varid_g;		  /* varid for contiguous */
    int varid_k;		  /* varid for chunked */
    int varid_x;		  /* varid for compressed */

    float *varxy, *varxz, *varyz;    /* 2D memory slabs used for I/O */
    int mm;
    size_t dims[] = {256, 256, 256}; /* default dim lengths */
    size_t chunks[] = {32, 32, 32}; /* default chunk sizes */
    size_t start[3], count[3];
    float contig_time, chunked_time, compressed_time, ratio;
    int deflate_level = 1;	/* default compression level, 9 is
				 * better and slower.  If negative,
				 * turn on shuffle filter also. */
    int shuffle = NC_NOSHUFFLE;
    size_t cache_size_def;
    size_t cache_hash_def;
    float cache_pre_def;
    size_t cache_size = 0;	    /* use library default */
    size_t cache_hash = 0;	    /* use library default */
    float cache_pre = -1.0f;	    /* use library default */

    /* rank (number of dimensions) for each variable */
#   define RANK_var1 3

    /* variable shapes */
    int var_dims[RANK_var1];

    TIMING_DECLS(TMsec) ;

    /* From args, get parameters for timing, including variable and
       chunk sizes.  Negative deflate level means also use shuffle
       filter. */
    parse_args(argc, argv, &deflate_level, &shuffle, dims,
	       chunks, &cache_size, &cache_hash, &cache_pre);

    /* get cache defaults, then set cache parameters that are not default */
    if((stat = nc_get_chunk_cache(&cache_size_def, &cache_hash_def,
				   &cache_pre_def)))
	ERR1(stat);
    if(cache_size == 0)
	cache_size = cache_size_def;
    if(cache_hash == 0)
	cache_hash = cache_hash_def;
    if(cache_pre == -1.0f)
	cache_pre = cache_pre_def;
    if((stat = nc_set_chunk_cache(cache_size, cache_hash, cache_pre)))
	ERR1(stat);
    printf("cache: %3.2f MBytes  %ld objs  %3.2f preempt, ",
	   cache_size/1.e6, cache_hash, cache_pre);

    if(deflate_level == 0) {
	printf("uncompressed        ");
    } else {
	printf("compression level %d", deflate_level);
    }
    if(shuffle == 1) {
	printf(", shuffled");
    }
    printf("\n\n");

    /* initialize 2D slabs for writing along each axis with phony data */
    varyz = (float *) emalloc(sizeof(float) * 1 * dims[1] * dims[2]);
    varxz = (float *) emalloc(sizeof(float) * dims[0] * 1 * dims[2]);
    varxy = (float *) emalloc(sizeof(float) * dims[0] * dims[1] * 1);
    mm = 0;
    for(j = 0; j < dims[1]; j++) {
	for(k = 0; k < dims[2]; k++) {
	    varyz[mm++] = k + dims[2]*j;
	}
    }
    mm = 0;
    for(i = 0; i < dims[0]; i++) {
	for(k = 0; k < dims[2]; k++) {
	    varxz[mm++] = k + dims[2]*i;
	}
    }
    mm = 0;
    for(i = 0; i < dims[0]; i++) {
	for(j = 0; j < dims[1]; j++) {
	    varxy[mm++] = j + dims[1]*i;
	}
    }

    if((stat = nc_create(FILENAME, NC_NETCDF4 | NC_CLASSIC_MODEL, &ncid)))
	ERR1(stat);

    /* define dimensions */
    if((stat = nc_def_dim(ncid, "dim1", dims[0], &dim1id)))
	ERR1(stat);
    if((stat = nc_def_dim(ncid, "dim2", dims[1], &dim2id)))
	ERR1(stat);
    if((stat = nc_def_dim(ncid, "dim3", dims[2], &dim3id)))
	ERR1(stat);

    /* define variables */
    var_dims[0] = dim1id;
    var_dims[1] = dim2id;
    var_dims[2] = dim3id;
    if((stat = nc_def_var(ncid, "var_contiguous", NC_FLOAT, RANK_var1,
			   var_dims, &varid_g)))
	ERR1(stat);
    if((stat = nc_def_var(ncid, "var_chunked", NC_FLOAT, RANK_var1,
			   var_dims, &varid_k)))
	ERR1(stat);
    if((stat = nc_def_var(ncid, "var_compressed", NC_FLOAT, RANK_var1,
			   var_dims, &varid_x)))
	ERR1(stat);

    if((stat = nc_def_var_chunking(ncid, varid_g, NC_CONTIGUOUS, 0)))
	ERR1(stat);

    if((stat = nc_def_var_chunking(ncid, varid_k, NC_CHUNKED, chunks)))
	ERR1(stat);

    if((stat = nc_def_var_chunking(ncid, varid_x, NC_CHUNKED, chunks)))
	ERR1(stat);

    if (deflate_level != 0) {
	if((stat = nc_def_var_deflate(ncid, varid_x, shuffle,
				       NC_COMPRESSED, deflate_level)))
	    ERR1(stat);
    }

    /* leave define mode */
    if((stat = nc_enddef (ncid)))
	ERR1(stat);

    /* write each variable one yz slab at a time */
    start[0] = 0;
    start[1] = 0;
    start[2] = 0;
    count[0] = 1;
    count[1] = dims[1];
    count[2] = dims[2];

    sprintf(time_mess,"  contiguous write %3ld %3ld %3ld",
	    1, dims[1], dims[2]);
    TIMING_START ;
    for(i = 0; i < dims[0]; i++) {
	start[0] = i;
	if((stat = nc_put_vara(ncid, varid_g, start, count, &varyz[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    printf("\n");
    contig_time = TMsec;

    sprintf(time_mess,"  chunked    write %3ld %3ld %3ld  %3ld %3ld %3ld",
	    1, dims[1], dims[2], chunks[0], chunks[1], chunks[2]);
    TIMING_START ;
    for(i = 0; i < dims[0]; i++) {
	start[0] = i;
	if((stat = nc_put_vara(ncid, varid_k, start, count, &varyz[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    chunked_time = TMsec;
    ratio = contig_time/chunked_time;
    if(ratio >= 1.0)
	printf(" %5.2g x faster\n", ratio);
    else
	printf(" %5.2g x slower\n", 1.0/ratio);

    sprintf(time_mess,"  compressed write %3ld %3ld %3ld  %3ld %3ld %3ld",
	    1, dims[1], dims[2], chunks[0], chunks[1], chunks[2]);
    TIMING_START ;
    for(i = 0; i < dims[0]; i++) {
	start[0] = i;
	if((stat = nc_put_vara(ncid, varid_x, start, count, &varyz[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    compressed_time = TMsec;
    ratio = contig_time/compressed_time;
    if(ratio >= 1.0)
	printf(" %5.2g x faster\n", ratio);
    else
	printf(" %5.2g x slower\n", 1.0/ratio);
    printf("\n");

    /* write each variable one xz slab at a time */
    start[0] = 0;
    start[1] = 0;
    start[2] = 0;
    count[0] = dims[0];
    count[1] = 1;
    count[2] = dims[2];

    sprintf(time_mess,"  contiguous write %3ld %3ld %3ld",
	    dims[0], 1, dims[2]);
    TIMING_START ;
    for(i = 0; i < dims[1]; i++) {
	start[1] = i;
	if((stat = nc_put_vara(ncid, varid_g, start, count, &varxz[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    printf("\n");
    contig_time = TMsec;

    sprintf(time_mess,"  chunked    write %3ld %3ld %3ld  %3ld %3ld %3ld",
	    dims[0], 1, dims[2], chunks[0], chunks[1], chunks[2]);
    TIMING_START ;
    for(i = 0; i < dims[1]; i++) {
	start[1] = i;
	if((stat = nc_put_vara(ncid, varid_k, start, count, &varxz[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    chunked_time = TMsec;
    ratio = contig_time/chunked_time;
    if(ratio >= 1.0)
	printf(" %5.2g x faster\n", ratio);
    else
	printf(" %5.2g x slower\n", 1.0/ratio);

    sprintf(time_mess,"  compressed write %3ld %3ld %3ld  %3ld %3ld %3ld",
	    dims[0], 1, dims[2], chunks[0], chunks[1], chunks[2]);
    TIMING_START ;
    for(i = 0; i < dims[1]; i++) {
	start[1] = i;
	if((stat = nc_put_vara(ncid, varid_x, start, count, &varxz[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    compressed_time = TMsec;
    ratio = contig_time/compressed_time;
    if(ratio >= 1.0)
	printf(" %5.2g x faster\n", ratio);
    else
	printf(" %5.2g x slower\n", 1.0/ratio);
    printf("\n");

    /* write each variable one xy slab at a time */
    start[0] = 0;
    start[1] = 0;
    start[2] = 0;
    count[0] = dims[0];
    count[1] = dims[1];
    count[2] = 1;

    sprintf(time_mess,"  contiguous write %3ld %3ld %3ld",
	    dims[0], dims[1], 1);
    TIMING_START ;
    for(i = 0; i < dims[2]; i++) {
	start[2] = i;
	if((stat = nc_put_vara(ncid, varid_g, start, count, &varxy[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    printf("\n");
    contig_time = TMsec;

    sprintf(time_mess,"  chunked    write %3ld %3ld %3ld  %3ld %3ld %3ld",
	    dims[0], dims[1], 1, chunks[0], chunks[1], chunks[2]);
    TIMING_START ;
    for(i = 0; i < dims[2]; i++) {
	start[2] = i;
	if((stat = nc_put_vara(ncid, varid_k, start, count, &varxy[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    chunked_time = TMsec;
    ratio = contig_time/chunked_time;
    if(ratio >= 1.0)
	printf(" %5.2g x faster\n", ratio);
    else
	printf(" %5.2g x slower\n", 1.0/ratio);

    sprintf(time_mess,"  compressed write %3ld %3ld %3ld  %3ld %3ld %3ld",
	    dims[0], dims[1], 1, chunks[0], chunks[1], chunks[2]);
    TIMING_START ;
    for(i = 0; i < dims[2]; i++) {
	start[2] = i;
	if((stat = nc_put_vara(ncid, varid_x, start, count, &varxy[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    compressed_time = TMsec;
    ratio = contig_time/compressed_time;
    if(ratio >= 1.0)
	printf(" %5.2g x faster\n", ratio);
    else
	printf(" %5.2g x slower\n", 1.0/ratio);
    printf("\n");

    /* read each variable one yz slab at a time */
    start[0] = 0;
    start[1] = 0;
    start[2] = 0;
    count[0] = 1;
    count[1] = dims[1];
    count[2] = dims[2];

    sprintf(time_mess,"  contiguous  read %3ld %3ld %3ld",
	    1, dims[1], dims[2]);
    TIMING_START ;
    for(i = 0; i < dims[0]; i++) {
	start[0] = i;
	if((stat = nc_get_vara(ncid, varid_g, start, count, &varyz[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    printf("\n");
    contig_time = TMsec;

    sprintf(time_mess,"  chunked     read %3ld %3ld %3ld  %3ld %3ld %3ld",
	    1, dims[1], dims[2] , chunks[0], chunks[1], chunks[2]);
    TIMING_START ;
    for(i = 0; i < dims[0]; i++) {
	start[0] = i;
	if((stat = nc_get_vara(ncid, varid_k, start, count, &varyz[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    chunked_time = TMsec;
    ratio = contig_time/chunked_time;
    if(ratio >= 1.0)
	printf(" %5.2g x faster\n", ratio);
    else
	printf(" %5.2g x slower\n", 1.0/ratio);

    sprintf(time_mess,"  compressed  read %3ld %3ld %3ld  %3ld %3ld %3ld",
	    1, dims[1], dims[2] , chunks[0], chunks[1], chunks[2]);
    TIMING_START ;
    for(i = 0; i < dims[0]; i++) {
	start[0] = i;
	if((stat = nc_get_vara(ncid, varid_x, start, count, &varyz[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    compressed_time = TMsec;
    ratio = contig_time/compressed_time;
    if(ratio >= 1.0)
	printf(" %5.2g x faster\n", ratio);
    else
	printf(" %5.2g x slower\n", 1.0/ratio);
    printf("\n");

    /* read each variable one xz slab at a time */
    start[0] = 0;
    start[1] = 0;
    start[2] = 0;
    count[0] = dims[0];
    count[1] = 1;
    count[2] = dims[2];

    sprintf(time_mess,"  contiguous  read %3ld %3ld %3ld",
	    dims[0], 1, dims[2]);
    TIMING_START ;
    for(i = 0; i < dims[1]; i++) {
	start[1] = i;
	if((stat = nc_get_vara(ncid, varid_g, start, count, &varxz[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    printf("\n");
    contig_time = TMsec;

    sprintf(time_mess,"  chunked     read %3ld %3ld %3ld  %3ld %3ld %3ld",
	    dims[0], 1, dims[2], chunks[0], chunks[1], chunks[2]);
    TIMING_START ;
    for(i = 0; i < dims[1]; i++) {
	start[1] = i;
	if((stat = nc_get_vara(ncid, varid_k, start, count, &varxz[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    chunked_time = TMsec;
    ratio = contig_time/chunked_time;
    if(ratio >= 1.0)
	printf(" %5.2g x faster\n", ratio);
    else
	printf(" %5.2g x slower\n", 1.0/ratio);

    sprintf(time_mess,"  compressed  read %3ld %3ld %3ld  %3ld %3ld %3ld",
	    dims[0], 1, dims[2], chunks[0], chunks[1], chunks[2]);
    TIMING_START ;
    for(i = 0; i < dims[1]; i++) {
	start[1] = i;
	if((stat = nc_get_vara(ncid, varid_x, start, count, &varxz[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    compressed_time = TMsec;
    ratio = contig_time/compressed_time;
    if(ratio >= 1.0)
	printf(" %5.2g x faster\n", ratio);
    else
	printf(" %5.2g x slower\n", 1.0/ratio);
    printf("\n");

    /* read variable one xy slab at a time */
    start[0] = 0;
    start[1] = 0;
    start[2] = 0;
    count[0] = dims[0];
    count[1] = dims[1];
    count[2] = 1;

    sprintf(time_mess,"  contiguous  read %3ld %3ld %3ld",
	    dims[0], dims[1], 1);
    TIMING_START ;
    for(i = 0; i < dims[2]; i++) {
	start[2] = i;
	if((stat = nc_get_vara(ncid, varid_g, start, count, &varxy[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    printf("\n");
    contig_time = TMsec;

    sprintf(time_mess,"  chunked     read %3ld %3ld %3ld  %3ld %3ld %3ld",
	    dims[0], dims[1], 1, chunks[0], chunks[1], chunks[2]);
    TIMING_START ;
    for(i = 0; i < dims[2]; i++) {
	start[2] = i;
	if((stat = nc_get_vara(ncid, varid_k, start, count, &varxy[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    chunked_time = TMsec;
    ratio = contig_time/chunked_time;
    if(ratio >= 1.0)
	printf(" %5.2g x faster\n", ratio);
    else
	printf(" %5.2g x slower\n", 1.0/ratio);

    sprintf(time_mess,"  compressed  read %3ld %3ld %3ld  %3ld %3ld %3ld",
	    dims[0], dims[1], 1, chunks[0], chunks[1], chunks[2]);
    TIMING_START ;
    for(i = 0; i < dims[2]; i++) {
	start[2] = i;
	if((stat = nc_get_vara(ncid, varid_x, start, count, &varxy[0])))
	    ERR1(stat);
    }
    TIMING_END(TMsec) ;
    compressed_time = TMsec;
    ratio = contig_time/compressed_time;
    if(ratio >= 1.0)
	printf(" %5.2g x faster\n", ratio);
    else
	printf(" %5.2g x slower\n", 1.0/ratio);

    if((stat = nc_close(ncid)))
	ERR1(stat);

    return 0;
}
int
test_redef(int format)   
{
   int ncid, varid, dimids[REDEF_NDIMS], dimids_in[REDEF_NDIMS];
   int ndims, nvars, natts, unlimdimid;
   int dimids_var[REDEF_NDIMS], var_type;
   int cflags = 0;
   size_t dim_len;
   char dim_name[NC_MAX_NAME+1], var_name[NC_MAX_NAME+1];
   float float_in;
   double double_out = 99E99;
   int int_in;
   unsigned char uchar_in, uchar_out = 255;
   short short_out = -999;
   nc_type xtype_in;
   size_t cache_size_in, cache_nelems_in;
   float cache_preemption_in;
   int ret;

   if (format == NC_FORMAT_64BIT)
      cflags |= NC_64BIT_OFFSET;
   else if (format == NC_FORMAT_NETCDF4_CLASSIC)
      cflags |= (NC_NETCDF4|NC_CLASSIC_MODEL);
   else if (format == NC_FORMAT_NETCDF4)
      cflags |= NC_NETCDF4;

   /* Change chunk cache. */
   if (nc_set_chunk_cache(NEW_CACHE_SIZE, NEW_CACHE_NELEMS, 
			  NEW_CACHE_PREEMPTION)) ERR;

   /* Create a file with two dims, two vars, and two atts. */
   if (nc_create(FILE_NAME, cflags|NC_CLOBBER, &ncid)) ERR;

   /* Retrieve the chunk cache settings, just for fun. */
   if (nc_get_chunk_cache(&cache_size_in, &cache_nelems_in, 
			  &cache_preemption_in)) ERR;
   if (cache_size_in != NEW_CACHE_SIZE || cache_nelems_in != NEW_CACHE_NELEMS ||
       cache_preemption_in != NEW_CACHE_PREEMPTION) ERR;

   /* This will fail, except for netcdf-4/hdf5, which permits any
    * name. */
   if (format != NC_FORMAT_NETCDF4)
      if ((ret = nc_def_dim(ncid, REDEF_NAME_ILLEGAL, REDEF_DIM2_LEN, 
			    &dimids[1])) != NC_EBADNAME) ERR;

   if (nc_def_dim(ncid, REDEF_DIM1_NAME, REDEF_DIM1_LEN, &dimids[0])) ERR;
   if (nc_def_dim(ncid, REDEF_DIM2_NAME, REDEF_DIM2_LEN, &dimids[1])) ERR;
   if (nc_def_var(ncid, REDEF_VAR1_NAME, NC_INT, REDEF_NDIMS, dimids, &varid)) ERR;
   if (nc_def_var(ncid, REDEF_VAR2_NAME, NC_BYTE, REDEF_NDIMS, dimids, &varid)) ERR;
   if (nc_put_att_double(ncid, NC_GLOBAL, REDEF_ATT1_NAME, NC_DOUBLE, 1, &double_out)) ERR;
   if (nc_put_att_short(ncid, NC_GLOBAL, REDEF_ATT2_NAME, NC_SHORT, 1, &short_out)) ERR;

   /* Check it out. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;

   /* Close it up. */
   if (format != NC_FORMAT_NETCDF4)
      if (nc_enddef(ncid)) ERR;
   if (nc_close(ncid)) ERR;

   /* Reopen as read only - make sure it doesn't let us change file. */
   if (nc_open(FILE_NAME, 0, &ncid)) ERR;
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;

   /* This will fail. */
   ret = nc_def_var(ncid, REDEF_VAR3_NAME, NC_UBYTE, REDEF_NDIMS, 
			  dimids, &varid);
   if(format == NC_FORMAT_NETCDF4) {
	if(ret != NC_EPERM) {
	    ERR;
	}
   } else {
	if(ret != NC_ENOTINDEFINE) {
	    ERR;
	}
   }
   /* This will fail. */
   if (!nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_CHAR, 1, &uchar_out)) ERR;
   if (nc_close(ncid)) ERR;      

   /* Make sure we can't redef a file opened for NOWRITE. */
   if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
   if (nc_redef(ncid) != NC_EPERM) ERR;

   /* Check it out again. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;

   if (nc_close(ncid)) ERR;      

   /* Reopen the file and check it, add a variable and attribute. */
   if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;

   /* Check it out. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 2 || natts != 2 || unlimdimid != -1) ERR;

   /* Add var. */
   if ((format != NC_FORMAT_NETCDF4) && nc_redef(ncid)) ERR;
   if (nc_def_var(ncid, REDEF_VAR3_NAME, NC_BYTE, REDEF_NDIMS, dimids, &varid)) ERR;

   /* Add att. */
   ret = nc_put_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, NC_BYTE, 1, &uchar_out);
   if (format != NC_FORMAT_NETCDF4 && ret) ERR;
   else if (format == NC_FORMAT_NETCDF4 && ret != NC_ERANGE) ERR;

   /* Check it out. */
   if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
   if (ndims != REDEF_NDIMS || nvars != 3 || natts != 3 || unlimdimid != -1) ERR;
   if (nc_inq_var(ncid, 0, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR1_NAME) || xtype_in != NC_INT || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 1, var_name, &xtype_in, &ndims, dimids_in, &natts)) ERR;
   if (strcmp(var_name, REDEF_VAR2_NAME) || xtype_in != NC_BYTE || ndims != REDEF_NDIMS || 
       dimids_in[0] != dimids[0] || dimids_in[1] != dimids[1]) ERR;
   if (nc_inq_var(ncid, 2, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR3_NAME) || var_type != NC_BYTE ||
       natts != 0) ERR;

   if (nc_close(ncid)) ERR;      

   /* Reopen it and check each dim, var, and att. */
   if (nc_open(FILE_NAME, 0, &ncid)) ERR;
   if (nc_inq_dim(ncid, 0, dim_name, &dim_len)) ERR;
   if (dim_len != REDEF_DIM1_LEN || strcmp(dim_name, REDEF_DIM1_NAME)) ERR;
   if (nc_inq_dim(ncid, 1, dim_name, &dim_len)) ERR;
   if (dim_len != REDEF_DIM2_LEN || strcmp(dim_name, REDEF_DIM2_NAME)) ERR;
   if (nc_inq_var(ncid, 0, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR1_NAME) || var_type != NC_INT ||
       natts != 0) ERR;
   if (nc_inq_var(ncid, 1, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR2_NAME) || var_type != NC_BYTE ||
       natts != 0) ERR;
   if (nc_inq_var(ncid, 2, var_name, &var_type, &ndims, dimids_var, &natts)) ERR;
   if (ndims != REDEF_NDIMS || strcmp(var_name, REDEF_VAR3_NAME) || var_type != NC_BYTE ||
       natts != 0) ERR;
   if (nc_get_att_float(ncid, NC_GLOBAL, REDEF_ATT1_NAME, &float_in) != NC_ERANGE) ERR;
   if (nc_get_att_int(ncid, NC_GLOBAL, REDEF_ATT2_NAME, &int_in)) ERR;
   if (int_in != short_out) ERR;
   ret = nc_get_att_uchar(ncid, NC_GLOBAL, REDEF_ATT3_NAME, &uchar_in);
   if (format == NC_FORMAT_NETCDF4)
   {
      if (ret != NC_ERANGE) ERR;
   }
   else if (ret) ERR;
	 
   if (uchar_in != uchar_out) ERR;
   if (nc_close(ncid)) ERR;      
   return NC_NOERR;
}
示例#7
0
int
main(int argc, char **argv)
{

   printf("\n*** Testing netcdf-4 file functions, some more.\n");
   last_sbrk = sbrk(0);
   printf("*** testing lots of open files...\n");
   {
#define NUM_TRIES 6
      int *ncid_in;
      int mem_used, mem_used2;
      /* int mem_per_file; */
      int num_files[NUM_TRIES] = {1, 5, 10, 20, 35, 50};
      char file_name[NUM_TRIES][NC_MAX_NAME + 1];
      int num_vars[NUM_TRIES];
      size_t cache_size[NUM_TRIES];
      int mode[NUM_TRIES];
      char mode_name[NUM_TRIES][8];
      int ndims[NUM_TRIES];
      int dim_len[NUM_TRIES][MAX_DIMS];
      int dim_4d[MAX_DIMS] = {NC_UNLIMITED, 10, 100, 100};
      char dimstr[30];
      char chunkstr[30];
      int num_recs[NUM_TRIES] = {1, 1, 1, 1, 1, 1};
      struct timeval start_time, end_time, diff_time;
      struct timeval close_start_time, close_end_time, close_diff_time;
      int open_us, close_us, create_us;
      size_t chunksize[MAX_DIMS];
      int storage;
      int d, f, t;

      printf("dims\t\tchunks\t\tformat\tnum_files\tcache(kb)\tnum_vars\tmem(kb)\t"
	     "open_time(us/file)\tclose_time(us/file)\tcreate_time(us/file)\n");
      for (t = 0; t < NUM_TRIES; t++)
      {
	 strcpy(mode_name[t], "netcdf4");
	 mode[t] = NC_NETCDF4;
	 cache_size[t] = 16000000;
	 num_vars[t] = 10;
	 ndims[t] = 4;
	 for (d = 0; d < ndims[t]; d++)
	    dim_len[t][d] = dim_4d[d];

	 /* Create sample files. */
         if (gettimeofday(&start_time, NULL)) ERR;
	 for (f = 0; f < num_files[t]; f++)
         {
            /* Set up filename. */
            sprintf(file_name[t], "tst_files2_%d_%d.nc", t, f);
            if (create_sample_file(file_name[t], ndims[t], dim_len[t], num_vars[t],
                                   mode[t], num_recs[t])) ERR;

            /* How long did it take? */
            if (gettimeofday(&end_time, NULL)) ERR;
            if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
            create_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec) / num_files[t];
         }

         /* /\* Change the cache settings. *\/ */
         /* if (nc_set_chunk_cache(cache_size[t], 20000, .75)) ERR; */

         /* We need storage for an array of ncids. */
         if (!(ncid_in = malloc(num_files[t] * sizeof(int)))) ERR;

         /* How much memory is in use now? */
         if (get_mem_used1(&mem_used)) ERR;

         /* Open the first file to get chunksizes. */
         if (gettimeofday(&start_time, NULL)) ERR;
         if (nc_open(file_name[t], 0, &ncid_in[0])) ERR;
         if (nc_inq_var_chunking(ncid_in[0], 0, &storage, chunksize)) ERR;

         /* Now reopen this file a large number of times. */
         for (f = 1; f < num_files[t]; f++)
            if (nc_open(file_name[t], 0, &ncid_in[f])) ERR_RET;

         /* How long did it take per file? */
         if (gettimeofday(&end_time, NULL)) ERR;
         if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
         open_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec) / num_files[t];

         /* How much memory is in use by this process now? */
         if (get_mem_used1(&mem_used2)) ERR;

         /* Close all netcdf files. */
         if (gettimeofday(&close_start_time, NULL)) ERR;
         for (f = 0; f < num_files[t]; f++)
            if (nc_close(ncid_in[f])) ERR_RET;

         /* How long did it take to close all files? */
         if (gettimeofday(&close_end_time, NULL)) ERR;
         if (nc4_timeval_subtract(&close_diff_time, &close_end_time, &close_start_time)) ERR;
         close_us = ((int)close_diff_time.tv_sec * MILLION +
                     (int)close_diff_time.tv_usec) / num_files[t];

         /* We're done with this. */
         free(ncid_in);

         /* How much memory was used for each open file? */
         /* mem_per_file = mem_used2/num_files[t]; */

         /* Prepare the dimensions string. */
         if (ndims[t] == MAX_DIMS)
            sprintf(dimstr, "%dx%dx%dx%d", dim_len[t][0], dim_len[t][1],
                    dim_len[t][2], dim_len[t][3]);
         else
            sprintf(dimstr, "%dx%dx%d", dim_len[t][0], dim_len[t][1],
                    dim_len[t][2]);

         /* Prepare the chunksize string. */
         if (storage == NC_CHUNKED)
         {
            if (ndims[t] == MAX_DIMS)
               sprintf(chunkstr, "%dx%dx%dx%d", (int)chunksize[0], (int)chunksize[1],
                       (int)chunksize[2], (int)chunksize[3]);
            else
               sprintf(chunkstr, "%dx%dx%d", (int)chunksize[0], (int)chunksize[1],
                       (int)chunksize[2]);
         }
         else
            strcpy(chunkstr, "contig       ");

         /* Output results. */
         printf("%s\t%s\t%s\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\t\t%d\n",
                dimstr, chunkstr, mode_name[t], num_files[t], (int)(cache_size[t]/1024),
                num_vars[t], mem_used2, open_us, close_us, create_us);
      }
   }
   SUMMARIZE_ERR;
   printf("Test for memory consumption...\n");
   {
#define NUM_TRIES_100 100
      int ncid, i;
      int mem_used, mem_used1, mem_used2;

      get_mem_used2(&mem_used);
      mem_used1 = mem_used;
      mem_used2 = mem_used;
      printf("start: memuse= %d\t%d\t%d \n",mem_used, mem_used1,
	     mem_used2);

      printf("bef_open\taft_open\taft_close\tused_open\tused_closed\n");
      for (i=0; i < NUM_TRIES_100; i++)
      {
	 /* Open the file. NC_NOWRITE tells netCDF we want read-only access
	  * to the file.*/

	 get_mem_used2(&mem_used);
	 nc_set_chunk_cache(10,10,.5);
	 if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR;
	 get_mem_used2(&mem_used1);

	 /* Close the file, freeing all resources.   ????  */
	 if (nc_close(ncid)) ERR;

	 get_mem_used2(&mem_used2);

	 if (mem_used2 - mem_used)
	    printf("try %d - %d\t\t%d\t\t%d\t\t%d\t\t%d \n", i,
		   mem_used, mem_used1, mem_used2, mem_used1 - mem_used,
		   mem_used2 - mem_used);
      }
   }
   SUMMARIZE_ERR;
   FINAL_RESULTS;
}