1/* This is part of the netCDF package.
2   Copyright 2005 University Corporation for Atmospheric Research/Unidata
3   See COPYRIGHT file for conditions of use.
4
5   Test netcdf-4 variables.
6   $Id: tst_files2.c,v 1.11 2010/01/31 19:00:44 ed Exp $
7*/
8
9#include <nc_tests.h>
10#include "err_macros.h"
11#include "netcdf.h"
12#include <unistd.h>
13#include <time.h>
14#include <sys/time.h> /* Extra high precision time info. */
15
16#define MAX_LEN 30
17#define TMP_FILE_NAME "tst_files2_tmp.out"
18#define FILE_NAME "tst_files2_1.nc"
19#define MILLION 1000000
20
21void *last_sbrk;
22
23/* This function uses the ps command to find the amount of memory in
24use by the process. From the ps man page:
25
26size SZ approximate amount of swap space that would be required if
27        the process were to dirty all writable pages and then be
28        swapped out. This number is very rough!
29*/
30int
31get_mem_used1(int *mem_used)
32{
33   char cmd[NC_MAX_NAME + 1];
34   char blob[MAX_LEN + 1] = "";
35   FILE *fp;
36   int num_char;
37
38   /* Run the ps command for this process, putting output (one number)
39    * into file TMP_FILE_NAME. */
40   sprintf(cmd, "ps -o size= %d > %s", getpid(), TMP_FILE_NAME);
41   system(cmd);
42
43   /* Read the results and delete temp file. */
44   if (!(fp = fopen(TMP_FILE_NAME, "r"))) ERR;
45   num_char = fread(blobMAX_LEN, 1, fp);
46   sscanf(blob, "%d", mem_used);
47   fclose(fp);
48   unlink(TMP_FILE_NAME);
49   return NC_NOERR;
50}
51
52void
53get_mem_used2(int *mem_used)
54{
55   char buf[30];
56   FILE *pf;
57
58   snprintf(buf, 30, "/proc/%u/statm", (unsigned)getpid());
59   pf = fopen(buf, "r");
60   if (pf) {
61      unsigned size; /*       total program size */
62      unsigned resident;/*   resident set size */
63      unsigned share;/*      shared pages */
64      unsigned text;/*       text (code) */
65      unsigned lib;/*        library */
66      unsigned data;/*       data/stack */
67      /*unsigned dt;          dirty pages (unused in Linux 2.6)*/
68      fscanf(pf, "%u %u %u %u %u %u", &size, &resident, &share,
69      &text, &lib, &data);
70      *mem_used = data;
71   }
72   else
73      *mem_used = -1;
74  fclose(pf);
75}
76
77void
78get_mem_used3(int *mem_used)
79{
80   void *vp;
81   vp = sbrk(0);
82   *mem_used = ((char *)vp - (char *)last_sbrk)/1024;
83}
84
85/* Create a sample file, with num_vars 3D or 4D variables, with dim
86 * lens of dim_len size. */
87#define MAX_DIMS 4
88int
89create_sample_file(char *file_name, int ndims, int *dim_len,
90    int num_vars, int mode, int num_recs)
91{
92   int nciddimids[MAX_DIMS], *varids;
93   char varname[NC_MAX_NAME + 1];
94   char dim_name[NC_MAX_NAME + 1];
95   float *data_out;
96   size_t start[MAX_DIMS], count[MAX_DIMS];
97   int slab_nelems;
98   int idret;
99
100   if (ndims != MAX_DIMS && ndims != MAX_DIMS - 1) ERR_RET;
101
102   /* Create a file. */
103   ret = nc_create(file_nameNC_NOCLOBBER|mode, &ncid);
104   if (ret == NC_EEXIST)
105      return NC_NOERR;
106   else if (ret)
107      ERR_RET;
108
109   /* Initialize sample data. Slab of data will be full extent of last
110    * two dimensions. */
111   slab_nelems = dim_len[ndims - 1] * dim_len[ndims - 2];
112   if (!(data_out = malloc(slab_nelems * sizeof(float)))) ERR_RET;
113   for (i = 0; i < slab_nelemsi++)
114      data_out[i] = 42.42 + i;
115
116   /* Create the dimensions. */
117   for (d = 0; d < ndimsd++)
118   {
119      sprintf(dim_name, "dim_%d", d);
120      if (nc_def_dim(nciddim_namedim_len[d], &dimids[d])) ERR_RET;
121   }
122
123   /* Define num_vars variables. */
124   if (!(varids = malloc(num_vars * sizeof(int)))) ERR_RET;
125   for (i = 0; i < num_varsi++)
126   {
127      sprintf(varname, "a_%d", i);
128      if (nc_def_var(ncidvarnameNC_FLOATndimsdimids,
129      &varids[i])) ERR_RET;
130   }
131
132   /* Enddef required for classic files. */
133   if (nc_enddef(ncid)) ERR;
134
135   /* Set up start/count to write slabs of data. */
136   for (d = 0; d < ndimsd++)
137   {
138      if (d < ndims - 2)
139  count[d] = 1;
140      else
141      {
142  start[d] = 0;
143  count[d] = dim_len[d];
144      }
145   }
146
147   /* Now write some data to the vars in slabs. */
148   for (i = 0; i < num_varsi++)
149   {
150      if (ndims == MAX_DIMS)
151      {
152  for (start[0] = 0; start[0] < (dim_len[0] ? dim_len[0] : num_recs); start[0]++)
153     for (start[1] = 0; start[1] < dim_len[1]; start[1]++)
154        if (nc_put_vara_float(ncidvarids[i], startcount,
155      data_out)) ERR_RET;
156      }
157      else
158      {
159  for (start[0] = 0; start[0] < (dim_len[0] ? dim_len[0] : num_recs); start[0]++)
160     if (nc_put_vara_float(ncidvarids[i], startcount,
161   data_out)) ERR_RET;
162      }
163   }
164
165   /* Free data and close file. */
166   free(data_out);
167   free(varids);
168   if (nc_close(ncid)) ERR_RET;
169
170   return NC_NOERR;
171}
172
173int
174main(int argc, char **argv)
175{
176
177   printf("\n*** Testing netcdf-4 file functions, some more.\n");
178   last_sbrk = sbrk(0);
179   printf("*** testing lots of open files...\n");
180   {
181#define NUM_TRIES 6
182      int *ncid_in;
183      int mem_usedmem_used2;
184      int mem_per_file;
185      int num_files[NUM_TRIES] = {1, 1, 1, 1, 1, 1};
186      char file_name[NUM_TRIES][NC_MAX_NAME + 1];
187      int num_vars[NUM_TRIES];
188      size_t cache_size[NUM_TRIES];
189      int mode[NUM_TRIES];
190      char mode_name[NUM_TRIES][8];
191      int ndims[NUM_TRIES];
192      int dim_len[NUM_TRIES][MAX_DIMS];
193      int dim_4d[MAX_DIMS] = {NC_UNLIMITED, 10, 1000, 1000};
194      char dimstr[30];
195      char chunkstr[30];
196      int num_recs[NUM_TRIES] = {1, 1, 1};
197      struct timeval start_timeend_timediff_time;
198      struct timeval close_start_timeclose_end_timeclose_diff_time;
199      int open_usclose_uscreate_us;
200      size_t chunksize[MAX_DIMS];
201      int storage;
202      int dft;
203
204      printf("dims\t\tchunks\t\tformat\tnum_files\tcache(kb)\tnum_vars\tmem(kb)\t"
205      "open_time(us)\tclose_time(us)\tcreate_time(us)\n");
206      for (t = 0; t < NUM_TRIESt++)
207      {
208  /* Set up filename. */
209  sprintf(file_name[t], "tst_files2_%d.nc", t);
210  strcpy(mode_name[t], "netcdf4");
211  mode[t] = NC_NETCDF4;
212  cache_size[t] = 16000000;
213  num_vars[t] = 10;
214  ndims[t] = 4;
215  for (d = 0; d < ndims[t]; d++)
216     dim_len[t][d] = dim_4d[d];
217
218  /* Create sample file (unless it already exists). */
219  if (gettimeofday(&start_timeNULL)) ERR;
220  if (create_sample_file(file_name[t], ndims[t], dim_len[t], num_vars[t],
221 mode[t], num_recs[t])) ERR;
222
223  /* How long did it take? */
224  if (gettimeofday(&end_timeNULL)) ERR;
225  if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
226  create_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec);
227
228  /* Change the cache settings. */
229  if (nc_set_chunk_cache(cache_size[t], 20000, .75)) ERR;
230
231  /* We need storage for an array of ncids. */
232  if (!(ncid_in = malloc(num_files[t] * sizeof(int)))) ERR;
233
234  /* How much memory is in use now? */
235   if (get_mem_used1(&mem_used)) ERR;
236/*   get_mem_used2(&mem_used);
237  get_mem_used3(&mem_used);*/
238
239  /* Open the first file to get chunksizes. */
240  if (gettimeofday(&start_timeNULL)) ERR;
241  if (nc_open(file_name[t], 0, &ncid_in[0])) ERR;
242  if (nc_inq_var_chunking(ncid_in[0], 0, &storagechunksize)) ERR;
243
244  /* Now reopen this file a large number of times. */
245  for (f = 1; f < num_files[t]; f++)
246     if (nc_open(file_name[t], 0, &ncid_in[f])) ERR_RET;
247
248  /* How long did it take per file? */
249  if (gettimeofday(&end_timeNULL)) ERR;
250  if (nc4_timeval_subtract(&diff_time, &end_time, &start_time)) ERR;
251  open_us = ((int)diff_time.tv_sec * MILLION + (int)diff_time.tv_usec);
252
253  /* How much memory is in use by this process now? */
254   if (get_mem_used1(&mem_used2)) ERR;
255
256  /* Close all netcdf files. */
257  if (gettimeofday(&close_start_timeNULL)) ERR;
258  for (f = 0; f < num_files[t]; f++)
259     if (nc_close(ncid_in[f])) ERR_RET;
260
261  /* How long did it take to close all files? */
262  if (gettimeofday(&close_end_timeNULL)) ERR;
263  if (nc4_timeval_subtract(&close_diff_time, &close_end_time, &close_start_time)) ERR;
264  close_us = ((int)close_diff_time.tv_sec * MILLION + (int)close_diff_time.tv_usec);
265
266  /* We're done with this. */
267  free(ncid_in);
268
269  /* How much memory was used for each open file? */
270  mem_per_file = mem_used2/num_files[t];
271
272  /* Prepare the dimensions string. */
273  if (ndims[t] == MAX_DIMS)
274     sprintf(dimstr, "%dx%dx%dx%d", dim_len[t][0], dim_len[t][1],
275     dim_len[t][2], dim_len[t][3]);
276  else
277     sprintf(dimstr, "%dx%dx%d", dim_len[t][0], dim_len[t][1],
278     dim_len[t][2]);
279
280  /* Prepare the chunksize string. */
281  if (storage == NC_CHUNKED)
282  {
283     if (ndims[t] == MAX_DIMS)
284        sprintf(chunkstr, "%dx%dx%dx%d", (int)chunksize[0], (int)chunksize[1],
285        (int)chunksize[2], (int)chunksize[3]);
286     else
287        sprintf(chunkstr, "%dx%dx%d", (int)chunksize[0], (int)chunksize[1],
288        (int)chunksize[2]);
289  }
290  else
291     strcpy(chunkstr, "contig       ");
292
293  /* Output results. */
294  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",
295 dimstrchunkstrmode_name[t], num_files[t], (int)(cache_size[t]/1024),
296 num_vars[t], mem_used2open_usclose_uscreate_us);
297      }
298   }
299  SUMMARIZE_ERR;
300   printf("Test for memory consumption...\n");
301   {
302#define NUM_TRIES_100 100
303      int ncidi;
304      int mem_usedmem_used1mem_used2;
305
306      get_mem_used2(&mem_used);
307      mem_used1 = mem_used;
308      mem_used2 = mem_used;
309      printf("start: memuse= %d\t%d\t%d \n",mem_usedmem_used1,
310      mem_used2);
311
312      printf("bef_open\taft_open\taft_close\tused_open\tused_closed\n");
313      for (i=0; i < NUM_TRIES_100i++)
314      {
315  /* Open the file. NC_NOWRITE tells netCDF we want read-only access
316   * to the file.*/
317
318  get_mem_used2(&mem_used);
319  nc_set_chunk_cache(10,10,.5);
320  if (nc_open(FILE_NAMENC_NOWRITE, &ncid)) ERR;
321  get_mem_used2(&mem_used1);
322
323  /* Close the file, freeing all resources.   ????  */
324  if (nc_close(ncid)) ERR;
325
326  get_mem_used2(&mem_used2);
327
328  if (mem_used2 - mem_used)
329     printf("try %d - %d\t\t%d\t\t%d\t\t%d\t\t%d \n", i,
330    mem_usedmem_used1mem_used2mem_used1 - mem_used,
331    mem_used2 - mem_used);
332      }
333   }
334   SUMMARIZE_ERR;
335   FINAL_RESULTS;
336}


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