1/*
2Copyright 2009, UCAR/Unidata
3See COPYRIGHT file for copying and redistribution conditions.
4
5This program tests netcdf-4 performance with some AR-4 3D data.
6
7$Id: tst_ar4_4d.c,v 1.2 2010/01/14 20:25:55 ed Exp $
8*/
9
10#include <nc_tests.h>
11#include "err_macros.h"
12#include <time.h>
13#include <sys/time.h>
14#include <unistd.h>
15
16#define MEGABYTE 1048576
17#define HALF_MEG (MEGABYTE/2)
18#define MILLION 1000000
19#define SIXTEEN_MEG 16777216
20#define FOUR_MEG (SIXTEEN_MEG/4)
21#define THIRTY_TWO_MEG (SIXTEEN_MEG * 2)
22#define SIXTY_FOUR_MEG (SIXTEEN_MEG * 4)
23#define ONE_TWENTY_EIGHT_MEG (SIXTEEN_MEG * 8)
24
25  /* From the data file we are using:
26
27../ncdump/ncdump -h -s thetao_O1.SRESA1B_2.CCSM.ocnm.2000-01_cat_2099-12.nc
28netcdf thetao_O1.SRESA1B_2.CCSM.ocnm.2000-01_cat_2099-12 {
29dimensions:
30 lon = 320 ;
31 lat = 395 ;
32 depth = 40 ;
33 bnds = 2 ;
34 time = UNLIMITED ; // (1200 currently)
35variables:
36 double lon_bnds(lon, bnds) ;
37 double lat_bnds(lat, bnds) ;
38 double depth_bnds(depth, bnds) ;
39 double time_bnds(time, bnds) ;
40 double lon(lon) ;
41 lon:axis = "X" ;
42 lon:standard_name = "longitude" ;
43 lon:bounds = "lon_bnds" ;
44 lon:long_name = "Longitude" ;
45 lon:units = "degrees_east" ;
46 double lat(lat) ;
47 lat:axis = "Y" ;
48 lat:standard_name = "latitude" ;
49 lat:bounds = "lat_bnds" ;
50 lat:long_name = "Latitude" ;
51 lat:units = "degrees_north" ;
52 double depth(depth) ;
53 depth:axis = "Z" ;
54 depth:standard_name = "depth" ;
55 depth:positive = "down" ;
56 depth:units = "m" ;
57 depth:bounds = "depth_bnds" ;
58 double time(time) ;
59 time:calendar = "noleap" ;
60 time:standard_name = "time" ;
61 time:axis = "T" ;
62 time:units = "days since 0000-1-1" ;
63 time:bounds = "time_bnds" ;
64 float thetao(time, depth, lat, lon) ;
65 thetao:comment = "Created using NCL code CCSM_ocnm_2cf.ncl on\n",
66 " machine mineral" ;
67 thetao:missing_value = 1.e+20f ;
68 thetao:long_name = "sea_water_potential_temperature" ;
69 thetao:cell_methods = "time: mean (interval: 1 month)" ;
70 thetao:history = "Interpolated to regular grid from dipole grid,\n",
71 "TEMP+273.15" ;
72 thetao:units = "K" ;
73 thetao:original_units = "C" ;
74 thetao:original_name = "TEMP" ;
75 thetao:standard_name = "sea_water_potential_temperature" ;
76 thetao:_FillValue = 1.e+20f ;
77
78// global attributes:
79 :table_id = "Table O1" ;
80 :title = "model output prepared for IPCC AR4" ;
81 :institution = "NCAR (National Center for Atmospheric \n",
82 "Research, Boulder, CO, USA)" ;
83 :source = "CCSM3.0, version beta19 (2004): \n",
84 "atmosphere: CAM3.0, T85L26;\n",
85 "ocean     : POP1.4.3 (modified), gx1v3\n",
86 "sea ice   : CSIM5.0, gx1v3;\n",
87 "land      : CLM3.0, T85" ;
88 :contact = "ccsm@ucar.edu" ;
89 :project_id = "IPCC Fourth Assessment" ;
90 :Conventions = "CF-1.0" ;
91 :references = "Collins, W.D., et al., 2005:\n",
92 " The Community Climate System Model, Version 3\n",
93 " Journal of Climate\n",
94 " \n",
95 " Main website: http://www.ccsm.ucar.edu" ;
96 :acknowledgment = " Any use of CCSM data should acknowledge the contribution\n",
97 " of the CCSM project and CCSM sponsor agencies with the \n",
98 " following citation:\n",
99 " \'This research uses data provided by the Community Climate\n",
100 " System Model project (www.ccsm.ucar.edu), supported by the\n",
101 " Directorate for Geosciences of the National Science Foundation\n",
102 " and the Office of Biological and Environmental Research of\n",
103 " the U.S. Department of Energy.\'\n",
104 "In addition, the words \'Community Climate System Model\' and\n",
105 " \'CCSM\' should be included as metadata for webpages referencing\n",
106 " work using CCSM data or as keywords provided to journal or book\n",
107 "publishers of your manuscripts.\n",
108 "Users of CCSM data accept the responsibility of emailing\n",
109 " citations of publications of research using CCSM data to\n",
110 " ccsm@ucar.edu.\n",
111 "Any redistribution of CCSM data must include this data\n",
112 " acknowledgement statement." ;
113 :realization = 2 ;
114 :experiment_id = "720 ppm stabilization experiment (SRES A1B)" ;
115 :history = "Created from CCSM3 case b30.040b\n",
116 " by strandwg@ucar.edu\n",
117 " on Sun Apr 24 22:35:53 MDT 2005\n",
118 " \n",
119 " For all data, added IPCC requested metadata" ;
120 :comment = "This simulation was initiated from year 2000 of \n",
121 " CCSM3 model run b30.030b and executed on \n",
122 " hardware bluesky.ucar.edu. The input external forcings are\n",
123 "ozone forcing    : A1B.ozone.128x64_L18_1991-2100_c040528.nc\n",
124 "aerosol optics   : AerosolOptics_c040105.nc\n",
125 "aerosol MMR      : AerosolMass_V_128x256_clim_c031022.nc\n",
126 "carbon scaling   : carbonscaling_A1B_1990-2100_c040609.nc\n",
127 "solar forcing    : Fixed at 1366.5 W m-2\n",
128 "GHGs             : ghg_ipcc_A1B_1870-2100_c040521.nc\n",
129 "GHG loss rates   : noaamisc.r8.nc\n",
130 "volcanic forcing : none\n",
131 "DMS emissions    : DMS_emissions_128x256_clim_c040122.nc\n",
132 "oxidants         : oxid_128x256_L26_clim_c040112.nc\n",
133 "SOx emissions    : SOx_emissions_A1B_128x256_L2_1990-2100_c040608.nc\n",
134 " Physical constants used for derived data:\n",
135 " Lv (latent heat of evaporation): 2.501e6 J kg-1\n",
136 " Lf (latent heat of fusion     ): 3.337e5 J kg-1\n",
137 " r[h2o] (density of water      ): 1000 kg m-3\n",
138 " g2kg   (grams to kilograms    ): 1000 g kg-1\n",
139 " \n",
140 " Integrations were performed by NCAR and CRIEPI with support\n",
141 " and facilities provided by NSF, DOE, MEXT and ESC/JAMSTEC." ;
142 :_Format = "classic" ;
143}
144*/
145
146/* Subtract the `struct timeval' values X and Y, storing the result in
147   RESULT.  Return 1 if the difference is negative, otherwise 0.  This
148   function from the GNU documentation. */
149static int
150timeval_subtract (resultxy)
151   struct timeval *result, *x, *y;
152{
153   /* Perform the carry for the later subtraction by updating Y. */
154   if (x->tv_usec < y->tv_usec) {
155      int nsec = (y->tv_usec - x->tv_usec) / MILLION + 1;
156      y->tv_usec -= MILLION * nsec;
157      y->tv_sec += nsec;
158   }
159   if (x->tv_usec - y->tv_usec > MILLION) {
160      int nsec = (x->tv_usec - y->tv_usec) / MILLION;
161      y->tv_usec += MILLION * nsec;
162      y->tv_sec -= nsec;
163   }
164
165   /* Compute the time remaining to wait.
166      `tv_usec' is certainly positive. */
167   result->tv_sec = x->tv_sec - y->tv_sec;
168   result->tv_usec = x->tv_usec - y->tv_usec;
169
170   /* Return 1 if result is negative. */
171   return x->tv_sec < y->tv_sec;
172}
173
174#define USAGE   "\
175  [-h]        Print output header\n\
176  [-t]        Do a time-series read\n\
177  [-v]        Vertical profile read\n\
178  [-c CACHE_SIZE]        Set the HDF5 chunk cache to this size before read\n\
179  file        Name of netCDF file\n"
180
181static void
182usage(void)
183{
184   fprintf(stderr, "tst_ar4 -h -t -v -c CACHE_SIZE file\n%s", USAGE);
185}
186
187#define NDIMS4 4
188#define DATA_VAR_NAME "thetao"
189#define NUM_CACHE_TRIES 1
190#define LON_DIMID 0
191#define LAT_DIMID 1
192#define DEPTH_DIMID 2
193#define BNDS_DIMID 3
194#define TIME_DIMID 4
195#define LON_LEN 320
196#define LAT_LEN 395
197#define BNDS_LEN 2
198#define DEPTH_LEN 40
199#define TIME_LEN 1200
200#define NUM_TS 1
201#define MAX_READ_COUNT 100
202
203int
204main(int argc, char **argv)
205{
206   extern int optind;
207   extern int opterr;
208   extern char *optarg;
209   int cheader = 0, vertical_profile = 0, timeseries = 0;
210   int ncidvaridstorage;
211   char name_in[NC_MAX_NAME + 1];
212   size_t len;
213   size_t cs[NDIMS4] = {0, 0, 0, 0};
214   int cache = MEGABYTE;
215   int ndimsdimid[NDIMS4];
216   float hor_data[LAT_LEN * LON_LEN];
217   float vert_data[DEPTH_LEN];
218   int read_1_usavg_read_us;
219   float ts_data[TIME_LEN];
220   size_t start[NDIMS4], count[NDIMS4];
221   int deflateshuffledeflate_level;
222   struct timeval start_timeend_timediff_time;
223   int read_count = 0, num_reads;
224
225   while ((c = getopt(argcargv, "vhtc:")) != EOF)
226      switch(c)
227      {
228  case 'v':
229     vertical_profile++;
230     break;
231  case 'h':
232     header++;
233     break;
234  case 't':
235     timeseries++;
236     break;
237  case 'c':
238     sscanf(optarg, "%d", &cache);
239     break;
240  case '?':
241     usage();
242     return 1;
243      }
244
245   argc -= optind;
246   argv += optind;
247
248   /* If no file arguments left, report and exit */
249   if (argc < 1)
250   {
251      printf("no file specified\n");
252      return 0;
253   }
254
255   /* Print the header if desired. */
256   if (header)
257   {
258      printf("cs[0]\tcs[1]\tcs[2]\tcache(MB)\tdeflate\tshuffle");
259      if (timeseries)
260  printf("\t1st_read_ser(us)\tavg_read_ser(us)\n");
261      else if (vertical_profile)
262  printf("\t1st_read_vert(us)\tavg_read_vert(us)\n");
263      else
264  printf("\t1st_read_hor(us)\tavg_read_hor(us)\n");
265   }
266
267#define PREEMPTION .75
268      /* Also tried NELEMS of 2500009*/
269#define NELEMS 7919
270   if (nc_set_chunk_cache(cacheNELEMSPREEMPTION)) ERR;
271   if (nc_open(argv[0], 0, &ncid)) ERR;
272
273   /* Check to make sure that all the dimension information is
274    * correct. */
275   if (nc_inq_varid(ncidDATA_VAR_NAME, &varid)) ERR;
276   if (nc_inq_dim(ncidLON_DIMIDname_in, &len)) ERR;
277   if (strcmp(name_in, "lon") || len != LON_LENERR;
278   if (nc_inq_dim(ncidLAT_DIMIDname_in, &len)) ERR;
279   if (strcmp(name_in, "lat") || len != LAT_LENERR;
280   if (nc_inq_dim(ncidDEPTH_DIMIDname_in, &len)) ERR;
281   if (strcmp(name_in, "depth") || len != DEPTH_LENERR;
282   if (nc_inq_dim(ncidBNDS_DIMIDname_in, &len)) ERR;
283   if (strcmp(name_in, "bnds") || len != BNDS_LENERR;
284   if (nc_inq_dim(ncidTIME_DIMIDname_in, &len)) ERR;
285   if (strcmp(name_in, "time") || len != TIME_LENERR;
286   if (nc_inq_var(ncidvaridNULLNULL, &ndimsdimidNULL)) ERR;
287   if (ndims != NDIMS4 || dimid[0] != TIME_DIMID ||
288       dimid[1] != DEPTH_DIMID || dimid[2] != LAT_DIMID ||
289       dimid[3] != LON_DIMIDERR;
290
291   /* Get info about the main data var. */
292   if (nc_inq_var_chunking(ncidvarid, &storagecs)) ERR;
293   if (nc_inq_var_deflate(ncidvarid, &shuffle, &deflate,
294   &deflate_level)) ERR;
295
296   if (timeseries)
297   {
298      /* Read the var as a time series. */
299      start[0] = 0;
300      start[1] = 0;
301      start[2] = 0;
302      start[3] = 0;
303      count[0] = TIME_LEN;
304      count[1] = 1;
305      count[2] = 1;
306      count[3] = 1;
307
308      /* Read the first timeseries. */
309      if (gettimeofday(&start_timeNULL)) ERR;
310      if (nc_get_vara_float(ncidvaridstartcountts_data)) ERR_RET;
311      if (gettimeofday(&end_timeNULL)) ERR;
312      if (timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
313      read_1_us = (int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec;
314
315      /* Read all the rest. */
316      if (gettimeofday(&start_timeNULL)) ERR;
317      for (start[1] = 0; read_count < MAX_READ_COUNT && start[1] < LAT_LENstart[1]++)
318  for (start[2] = 1; read_count < MAX_READ_COUNT && start[2] < LON_LENstart[2]++)
319     for (start[3] = 1; read_count < MAX_READ_COUNT && start[3] < DEPTH_LENstart[3]++)
320     {
321        if (nc_get_vara_float(ncidvaridstartcountts_data)) ERR_RET;
322        read_count++;
323     }
324      if (gettimeofday(&end_timeNULL)) ERR;
325      if (timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
326      num_reads = (read_count == MAX_READ_COUNT) ? MAX_READ_COUNT : (LAT_LEN * LON_LEN * DEPTH_LEN);
327      avg_read_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec + read_1_us) /
328  num_reads;
329   }
330   else if (vertical_profile)
331   {
332      /* Read the var as a vertical profile. */
333      start[0] = 0;
334      start[1] = 0;
335      start[2] = 0;
336      start[3] = 0;
337      count[0] = 1;
338      count[1] = DEPTH_LEN;
339      count[2] = 1;
340      count[3] = 1;
341
342      /* Read the first vertical profile. */
343      if (gettimeofday(&start_timeNULL)) ERR;
344      if (nc_get_vara_float(ncidvaridstartcountvert_data)) ERR_RET;
345      if (gettimeofday(&end_timeNULL)) ERR;
346      if (timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
347      read_1_us = (int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec;
348
349      /* Read all the rest. */
350      if (gettimeofday(&start_timeNULL)) ERR;
351/*       for (start[0] = 0; read_count < MAX_READ_COUNT && start[1] < LAT_LEN; start[1]++) */
352/*       for (start[1] = 0; read_count < MAX_READ_COUNT && start[1] < LAT_LEN; start[1]++) */
353/*   for (start[2] = 1; read_count < MAX_READ_COUNT && start[2] < LON_LEN; start[2]++) */
354/*      for (start[] = 1; read_count < MAX_READ_COUNT && start[3] < DEPTH_LEN; start[3]++) */
355/*      { */
356/*         if (nc_get_vara_float(ncid, varid, start, count, vert_data)) ERR_RET; */
357/*         read_count++; */
358/*      } */
359      if (gettimeofday(&end_timeNULL)) ERR;
360      if (timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
361      num_reads = (read_count == MAX_READ_COUNT) ? MAX_READ_COUNT : (LAT_LEN * LON_LEN * DEPTH_LEN);
362      avg_read_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec + read_1_us) /
363  num_reads;
364   }
365   else
366   {
367      /* Read the data variable in horizontal slices. */
368      start[0] = 0;
369      start[1] = 0;
370      start[2] = 0;
371      start[3] = 0;
372      count[0] = 1;
373      count[1] = 1;
374      count[2] = LAT_LEN;
375      count[3] = LON_LEN;
376
377      /* Read (and time) the first one. */
378      if (gettimeofday(&start_timeNULL)) ERR;
379      if (nc_get_vara_float(ncidvaridstartcounthor_data)) ERR_RET;
380      if (gettimeofday(&end_timeNULL)) ERR;
381      if (timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
382      read_1_us = (int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec;
383
384      /* Read (and time) all the rest. */
385      if (gettimeofday(&start_timeNULL)) ERR;
386      for (start[0] = 0; read_count < MAX_READ_COUNT && start[0] < TIME_LENstart[0]++)
387  for (start[1] = 1; read_count < MAX_READ_COUNT && start[1] < DEPTH_LENstart[1]++)
388  {
389     if (nc_get_vara_float(ncidvaridstartcounthor_data)) ERR_RET;
390     read_count++;
391  }
392      if (gettimeofday(&end_timeNULL)) ERR;
393      if (timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
394      num_reads = (read_count == MAX_READ_COUNT) ? MAX_READ_COUNT : TIME_LEN;
395      avg_read_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec +
396      read_1_us) / num_reads;
397   }
398
399   /* Close file. */
400   if (nc_close(ncid)) ERR;
401
402   /* Print results. */
403   printf("%d\t%d\t%d\t%.1f\t\t%d\t%d\t\t",
404   (int)cs[0], (int)cs[1], (int)cs[2],
405   (storage == NC_CHUNKED) ? (cache/(float)MEGABYTE) : 0,
406   deflateshuffle);
407   if (timeseries)
408      printf("%d\t\t%d\n", (int)read_1_us, (int)avg_read_us);
409   else
410      printf("%d\t\t%d\n", (int)read_1_us, (int)avg_read_us);
411
412   return 0;
413}


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed