1 /*
2   Copyright (C) 2021  The Blosc Developers <blosc@blosc.org>
3   https://blosc.org
4   License: BSD 3-Clause (see LICENSE.txt)
5 
6   Benchmark showing Blosc filter from C code.
7 
8   To compile this program:
9 
10   $ gcc -O3 delta_schunk.c -o delta_schunk -lblosc2
11 
12 */
13 
14 #include <stdio.h>
15 #include <stdint.h>
16 #include <assert.h>
17 #include <blosc2.h>
18 
19 #define KB  1024
20 #define MB  (1024*KB)
21 #define GB  (1024*MB)
22 
23 #define CHUNKSIZE (50 * 1000)
24 #define NCHUNKS 100
25 // Setting NTHREADS > 1 increases the likelihood of a crash.  See #112.
26 #define NTHREADS 1
27 
28 
main(void)29 int main(void) {
30   int32_t *data, *data_dest;
31   blosc2_cparams cparams = BLOSC2_CPARAMS_DEFAULTS;
32   blosc2_dparams dparams = BLOSC2_DPARAMS_DEFAULTS;
33   blosc2_schunk *schunk;
34   int32_t isize = CHUNKSIZE * sizeof(int32_t);
35   int dsize;
36   int64_t nbytes, cbytes;
37   int nchunk;
38   int nchunks = 0;
39   blosc_timestamp_t last, current;
40   double totaltime;
41   float totalsize = (float)(isize * NCHUNKS);
42 
43   data = malloc(CHUNKSIZE * sizeof(int32_t));
44   data_dest = malloc(CHUNKSIZE * sizeof(int32_t));
45   for (int i = 0; i < CHUNKSIZE; i++) {
46     data[i] = i;
47   }
48 
49   printf("Blosc version info: %s (%s)\n", BLOSC_VERSION_STRING, BLOSC_VERSION_DATE);
50 
51   /* Initialize the Blosc compressor */
52   blosc_init();
53 
54   /* Create a super-chunk container */
55   cparams.filters[0] = BLOSC_DELTA;
56   //cparams.filters[BLOSC2_MAX_FILTERS - 1] = BLOSC_BITSHUFFLE;
57   cparams.typesize = sizeof(int32_t);
58   cparams.compcode = BLOSC_BLOSCLZ;
59   cparams.clevel = 1;
60   cparams.nthreads = NTHREADS;
61   blosc2_storage storage = {.cparams=&cparams, .dparams=&dparams};
62   schunk = blosc2_schunk_new(&storage);
63 
64   /* Append chunks (the first will be taken as reference for delta) */
65   blosc_set_timestamp(&last);
66   for (nchunk = 0; nchunk < NCHUNKS; nchunk++) {
67     nchunks = blosc2_schunk_append_buffer(schunk, data, isize);
68   }
69   blosc_set_timestamp(&current);
70   totaltime = blosc_elapsed_secs(last, current);
71   printf("[Compr] Elapsed time:\t %6.3f s.  Processed data: %.3f GB (%.3f GB/s)\n",
72          totaltime, totalsize / GB, totalsize / (GB * totaltime));
73 
74   /* Gather some info */
75   nbytes = schunk->nbytes;
76   cbytes = schunk->cbytes;
77   printf("Compression super-chunk: %ld -> %ld (%.1fx)\n",
78          (long)nbytes, (long)cbytes, (1. * nbytes) / cbytes);
79 
80   /* Retrieve and decompress the chunks */
81   blosc_set_timestamp(&last);
82   for (nchunk = 0; nchunk < NCHUNKS; nchunk++) {
83     dsize = blosc2_schunk_decompress_chunk(schunk, nchunk, data_dest, isize);
84     if (dsize < 0) {
85       printf("Decompression error.  Error code: %d\n", dsize);
86       return dsize;
87     }
88     assert (dsize == (int)isize);
89   }
90   blosc_set_timestamp(&current);
91   totaltime = blosc_elapsed_secs(last, current);
92   totalsize = (float)(isize * nchunks);
93   printf("[Decompr] Elapsed time:\t %6.3f s.  Processed data: %.3f GB (%.3f GB/s)\n",
94          totaltime, totalsize / GB, totalsize / (GB * totaltime));
95 
96   printf("Decompression successful!\n");
97 
98   for (int i = 0; i < CHUNKSIZE; i++) {
99     if (data[i] != data_dest[i]) {
100       printf("Decompressed data differs from original %d, %d, %d!\n",
101              i, data[i], data_dest[i]);
102       return -1;
103     }
104   }
105 
106   printf("Successful roundtrip!\n");
107 
108   /* Free resources */
109   free(data);
110   free(data_dest);
111   /* Destroy the super-chunk */
112   blosc2_schunk_free(schunk);
113   /* Destroy the Blosc environment */
114   blosc_destroy();
115 
116   return 0;
117 }
118