1 /*
2  * (C) Copyright 2005- ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  *
7  * In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
8  * virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
9  */
10 
11 #include "grib_api_internal.h"
12 
13 #if ECCODES_TIMER
14 
usage(char * prog)15 void usage(char* prog)
16 {
17     printf("usage: %s [-a outfile | -w outfile ] grib_file repetitions bitsPerValue\n", prog);
18     exit(1);
19 }
20 
grib_handle_write(grib_handle * h,char * filename)21 size_t grib_handle_write(grib_handle* h, char* filename)
22 {
23     FILE* of = NULL;
24     const void* buffer;
25     size_t size;
26 
27     of = fopen(filename, "wb");
28     if (!of) {
29         perror(filename);
30         exit(1);
31     }
32     GRIB_CHECK(grib_get_message(h, &buffer, &size), 0);
33     if (fwrite(buffer, 1, size, of) != size) {
34         perror(filename);
35         exit(1);
36     }
37     fclose(of);
38 
39     return size;
40 }
41 
print_timer(grib_timer * t,int repeat)42 static void print_timer(grib_timer* t, int repeat)
43 {
44     printf("%s : %g cpu\n", t->name_, t->timer_ / repeat);
45 }
46 
main(int argc,char * argv[])47 int main(int argc, char* argv[])
48 {
49     grib_handle* h  = NULL;
50     grib_context* c = NULL;
51     FILE* fin       = NULL;
52     FILE* fout      = NULL;
53     char* finname;
54     char* ofilename;
55     char defofilename[] = "grib_ccsds_perf.out";
56     double* values      = NULL;
57     int append          = 0;
58     size_t nvalues      = 0;
59     int count, e = 0;
60     int repeatccsds  = 1;
61     int repeatsimple = 1;
62     grib_timer *tes, *tds, *tej, *tdj;
63     char grid_ccsds[]    = "grid_ccsds";
64     size_t grid_ccsds_l  = strlen(grid_ccsds);
65     char grid_simple[]   = "grid_simple";
66     size_t grid_simple_l = strlen(grid_simple);
67     char packingType[50] = {
68         0,
69     };
70     size_t len     = 50;
71     char param[50] = {
72         0,
73     };
74     char gridType[50] = {
75         0,
76     };
77     char outfilename[255] = {
78         0,
79     };
80     size_t filesize_ccsds  = 0;
81     size_t filesize_simple = 0;
82     double perc            = 0;
83     long bitsPerValue      = 0;
84     int iarg               = 1;
85     char grid[40]          = {
86         0,
87     };
88     char shortName[20] = {
89         0,
90     };
91     long level;
92     char levelType[20] = {
93         0,
94     };
95 
96     tes = grib_get_timer(0, "encoding simple", 0, 0);
97     tds = grib_get_timer(0, "decoding simple", 0, 0);
98     tej = grib_get_timer(0, "encoding ccsds", 0, 0);
99     tdj = grib_get_timer(0, "decoding ccsds", 0, 0);
100 
101     if (argc != 4 && argc != 6) usage(argv[0]);
102     if (!strcmp(argv[iarg], "-w")) {
103         append = 0;
104         iarg++;
105         ofilename = argv[iarg];
106         iarg++;
107     }
108     else if (!strcmp(argv[iarg], "-a")) {
109         append = 1;
110         iarg++;
111         ofilename = argv[iarg];
112         iarg++;
113     }
114     else {
115         append    = 0;
116         ofilename = defofilename;
117     }
118     finname      = argv[iarg++];
119     repeatsimple = atoi(argv[iarg++]);
120     bitsPerValue = atoi(argv[iarg++]);
121 
122     fin = fopen(finname, "rb");
123     if (!fin) {
124         perror(finname);
125         exit(1);
126     }
127 
128     if (append)
129         fout = fopen(ofilename, "ab");
130     else
131         fout = fopen(ofilename, "wb");
132 
133     if (!fout) {
134         perror(ofilename);
135         exit(1);
136     }
137 
138     c = grib_context_get_default();
139     e = 0;
140     h = grib_handle_new_from_file(c, fin, &e);
141     fclose(fin);
142 
143     GRIB_CHECK(e, 0);
144 
145     len = 50;
146     grib_get_string(h, "shortName", param, &len);
147 
148     len = 20;
149     grib_get_string(h, "levelType", levelType, &len);
150 
151     if (!strcmp(levelType, "pl")) {
152         GRIB_CHECK(grib_get_long(h, "level", &level), 0);
153         sprintf(shortName, "%s%ld", param, level);
154     }
155     else {
156         sprintf(shortName, "%s", param);
157     }
158 
159 
160     grib_set_long(h, "editionNumber", 2);
161     GRIB_CHECK(grib_get_size(h, "values", &nvalues), 0);
162     values = (double*)grib_context_malloc(c, sizeof(double) * nvalues);
163     if (!values) {
164         printf("%s: memory allocation error\n", argv[0]);
165         exit(1);
166     }
167 
168     len = 50;
169     grib_get_string(h, "gridType", gridType, &len);
170 
171     len = 50;
172     grib_get_string(h, "packingType", packingType, &len);
173 
174     GRIB_CHECK(grib_get_double_array(h, "values", values, &nvalues), 0);
175     grib_set_long(h, "bitsPerValue", bitsPerValue);
176     GRIB_CHECK(grib_set_double_array(h, "values", values, nvalues), 0);
177 
178     printf("--------------------------------\n");
179     printf("- %s - gridType=%s packingType=%s numberOfValues=%ld bitsPerValue=%ld\n",
180            param, gridType, packingType, (long)nvalues, bitsPerValue);
181 
182     if (!strcmp(packingType, "spectral_complex") || !strcmp(packingType, "spectral_simple")) {
183         printf("unable to process spectral data\n");
184         exit(1);
185     }
186 
187     if (!strcmp(gridType, "reduced_gg") || !strcmp(gridType, "regular_gg")) {
188         long N;
189         grib_get_long(h, "N", &N);
190         printf("    N=%ld\n", N);
191         sprintf(grid, "%ld", N);
192     }
193     if (!strcmp(gridType, "regular_ll")) {
194         double Di, Dj;
195         grib_get_double(h, "DiInDegrees", &Di);
196         grib_get_double(h, "DjInDegrees", &Dj);
197         printf("    Di=%g Dj=%g\n", Di, Dj);
198         sprintf(grid, "%g/%g", Di, Dj);
199     }
200 
201 
202     if (!append)
203         fprintf(fout,
204                 "shortName gridType numberOfValues bitsPerValue grid sizeSimple sizeccsds encodeccsds encodeSimple decodeccsds decodeSimple\n");
205 
206     /* decode values grid_simple */
207     if (strcmp(packingType, grid_simple))
208         grib_set_string(h, "packingType", grid_simple, &grid_simple_l);
209     /* printf("decoding simple\n"); */
210     grib_timer_start(tds);
211     for (count = 0; count < repeatsimple; count++)
212         GRIB_CHECK(grib_get_double_array(h, "values", values, &nvalues), 0);
213     grib_timer_stop(tds, 0);
214     /* printf("%d messages decoded\n\n",count); */
215 
216     *outfilename = '\0';
217     sprintf(outfilename, "%s_%s_%ld_simple.grib2", param, gridType, bitsPerValue);
218     filesize_simple = grib_handle_write(h, outfilename);
219     printf("file size simple = %ld\n", (long)filesize_simple);
220 
221     /* encode values grid_simple*/
222     /* printf("encoding simple\n"); */
223     grib_timer_start(tes);
224     for (count = 0; count < repeatsimple; count++)
225         GRIB_CHECK(grib_set_double_array(h, "values", values, nvalues), 0);
226     grib_timer_stop(tes, 0);
227     /* printf("%d messages encoded \n\n",count); */
228 
229     /* decode values grid_ccsds */
230     grib_set_string(h, "packingType", grid_ccsds, &grid_ccsds_l);
231     /* printf("decoding ccsds\n"); */
232     grib_timer_start(tdj);
233     for (count = 0; count < repeatccsds; count++)
234         GRIB_CHECK(grib_get_double_array(h, "values", values, &nvalues), 0);
235     grib_timer_stop(tdj, 0);
236     /* printf("%d messages decoded\n\n",count); */
237 
238     *outfilename = '\0';
239     sprintf(outfilename, "%s_%s_%ld_ccsds.grib2", param, gridType, bitsPerValue);
240     filesize_ccsds = grib_handle_write(h, outfilename);
241     printf("file size ccsds   = %ld\n", (long)filesize_ccsds);
242 
243     perc = (double)filesize_simple / (double)filesize_ccsds;
244 
245     printf("compression ratio = %g \n", perc);
246     printf("space savings = %g \n", (1.0 - 1.0 / perc) * 100);
247 
248     /* encode values grid_ccsds*/
249     /* printf("encoding ccsds\n"); */
250     grib_timer_start(tej);
251     for (count = 0; count < repeatccsds; count++)
252         GRIB_CHECK(grib_set_double_array(h, "values", values, nvalues), 0);
253     grib_timer_stop(tej, 0);
254     /* printf("%d messages encoded \n\n",count); */
255 
256     grib_handle_delete(h);
257     grib_context_free(c, values);
258 
259     print_timer(tej, repeatccsds);
260     print_timer(tdj, repeatccsds);
261     print_timer(tes, repeatsimple);
262     print_timer(tds, repeatsimple);
263     printf("--------------------------------\n\n");
264     fprintf(fout, "%s %s %ld %ld %s %ld %ld %g %g %g %g\n",
265             shortName, gridType, (long)nvalues, bitsPerValue,
266             grid, (long)filesize_simple, (long)filesize_ccsds, tej->timer_ / repeatccsds, tes->timer_ / repeatsimple, tdj->timer_ / repeatccsds, tds->timer_ / repeatsimple);
267 
268     return 0;
269 }
270 #else
271 
main(int argc,char * argv[])272 int main(int argc, char* argv[])
273 {
274     return 0;
275 }
276 
277 #endif
278