1660f49b0SGreg Tucker /**********************************************************************
2660f49b0SGreg Tucker Copyright(c) 2011-2016 Intel Corporation All rights reserved.
3660f49b0SGreg Tucker
4660f49b0SGreg Tucker Redistribution and use in source and binary forms, with or without
5660f49b0SGreg Tucker modification, are permitted provided that the following conditions
6660f49b0SGreg Tucker are met:
7660f49b0SGreg Tucker * Redistributions of source code must retain the above copyright
8660f49b0SGreg Tucker notice, this list of conditions and the following disclaimer.
9660f49b0SGreg Tucker * Redistributions in binary form must reproduce the above copyright
10660f49b0SGreg Tucker notice, this list of conditions and the following disclaimer in
11660f49b0SGreg Tucker the documentation and/or other materials provided with the
12660f49b0SGreg Tucker distribution.
13660f49b0SGreg Tucker * Neither the name of Intel Corporation nor the names of its
14660f49b0SGreg Tucker contributors may be used to endorse or promote products derived
15660f49b0SGreg Tucker from this software without specific prior written permission.
16660f49b0SGreg Tucker
17660f49b0SGreg Tucker THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18660f49b0SGreg Tucker "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19660f49b0SGreg Tucker LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20660f49b0SGreg Tucker A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21660f49b0SGreg Tucker OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22660f49b0SGreg Tucker SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23660f49b0SGreg Tucker LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24660f49b0SGreg Tucker DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25660f49b0SGreg Tucker THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26660f49b0SGreg Tucker (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27660f49b0SGreg Tucker OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28660f49b0SGreg Tucker **********************************************************************/
29660f49b0SGreg Tucker
3052f644d3SHailiang Wang #define _FILE_OFFSET_BITS 64
31660f49b0SGreg Tucker #include <stdio.h>
32660f49b0SGreg Tucker #include <stdlib.h>
33660f49b0SGreg Tucker #include <assert.h>
34660f49b0SGreg Tucker #include <string.h>
355d155804SRoy Oursler #include <getopt.h>
36660f49b0SGreg Tucker #include "igzip_lib.h"
37660f49b0SGreg Tucker #include "test.h"
38660f49b0SGreg Tucker
39660f49b0SGreg Tucker #define BUF_SIZE 1024
40660f49b0SGreg Tucker
414ae2d1beSRoy Oursler int level_size_buf[10] = {
424ae2d1beSRoy Oursler #ifdef ISAL_DEF_LVL0_DEFAULT
434ae2d1beSRoy Oursler ISAL_DEF_LVL0_DEFAULT,
444ae2d1beSRoy Oursler #else
454ae2d1beSRoy Oursler 0,
464ae2d1beSRoy Oursler #endif
474ae2d1beSRoy Oursler #ifdef ISAL_DEF_LVL1_DEFAULT
484ae2d1beSRoy Oursler ISAL_DEF_LVL1_DEFAULT,
494ae2d1beSRoy Oursler #else
504ae2d1beSRoy Oursler 0,
514ae2d1beSRoy Oursler #endif
524ae2d1beSRoy Oursler #ifdef ISAL_DEF_LVL2_DEFAULT
534ae2d1beSRoy Oursler ISAL_DEF_LVL2_DEFAULT,
544ae2d1beSRoy Oursler #else
554ae2d1beSRoy Oursler 0,
564ae2d1beSRoy Oursler #endif
574ae2d1beSRoy Oursler #ifdef ISAL_DEF_LVL3_DEFAULT
584ae2d1beSRoy Oursler ISAL_DEF_LVL3_DEFAULT,
594ae2d1beSRoy Oursler #else
604ae2d1beSRoy Oursler 0,
614ae2d1beSRoy Oursler #endif
624ae2d1beSRoy Oursler #ifdef ISAL_DEF_LVL4_DEFAULT
634ae2d1beSRoy Oursler ISAL_DEF_LVL4_DEFAULT,
644ae2d1beSRoy Oursler #else
654ae2d1beSRoy Oursler 0,
664ae2d1beSRoy Oursler #endif
674ae2d1beSRoy Oursler #ifdef ISAL_DEF_LVL5_DEFAULT
684ae2d1beSRoy Oursler ISAL_DEF_LVL5_DEFAULT,
694ae2d1beSRoy Oursler #else
704ae2d1beSRoy Oursler 0,
714ae2d1beSRoy Oursler #endif
724ae2d1beSRoy Oursler #ifdef ISAL_DEF_LVL6_DEFAULT
734ae2d1beSRoy Oursler ISAL_DEF_LVL6_DEFAULT,
744ae2d1beSRoy Oursler #else
754ae2d1beSRoy Oursler 0,
764ae2d1beSRoy Oursler #endif
774ae2d1beSRoy Oursler #ifdef ISAL_DEF_LVL7_DEFAULT
784ae2d1beSRoy Oursler ISAL_DEF_LVL7_DEFAULT,
794ae2d1beSRoy Oursler #else
804ae2d1beSRoy Oursler 0,
814ae2d1beSRoy Oursler #endif
824ae2d1beSRoy Oursler #ifdef ISAL_DEF_LVL8_DEFAULT
834ae2d1beSRoy Oursler ISAL_DEF_LVL8_DEFAULT,
844ae2d1beSRoy Oursler #else
854ae2d1beSRoy Oursler 0,
864ae2d1beSRoy Oursler #endif
874ae2d1beSRoy Oursler #ifdef ISAL_DEF_LVL9_DEFAULT
884ae2d1beSRoy Oursler ISAL_DEF_LVL9_DEFAULT,
894ae2d1beSRoy Oursler #else
904ae2d1beSRoy Oursler 0,
914ae2d1beSRoy Oursler #endif
924ae2d1beSRoy Oursler };
934ae2d1beSRoy Oursler
94*55fbfabfSMarcel Cornu int
usage(void)95*55fbfabfSMarcel Cornu usage(void)
965d155804SRoy Oursler {
97*55fbfabfSMarcel Cornu fprintf(stderr, "Usage: igzip_file_perf [options] <infile>\n"
985d155804SRoy Oursler " -h help\n"
995d155804SRoy Oursler " -X use compression level X with 0 <= X <= 1\n"
1005d155804SRoy Oursler " -b <size> input buffer size, 0 buffers all the input\n"
10189f7c46cSGreg Tucker " -i <time> time in seconds to benchmark (at least 0)\n"
1021500db75SColin Ian King " -o <file> output file for compressed data\n"
103aa8b5193SRoy Oursler " -d <file> dictionary file used by compression\n"
104aa8b5193SRoy Oursler " -w <size> log base 2 size of history window, between 8 and 15\n");
105ed15402fSRoy Oursler
1065d155804SRoy Oursler exit(0);
1075d155804SRoy Oursler }
1085d155804SRoy Oursler
109*55fbfabfSMarcel Cornu void
deflate_perf(struct isal_zstream * stream,uint8_t * inbuf,size_t infile_size,size_t inbuf_size,uint8_t * outbuf,size_t outbuf_size,int level,uint8_t * level_buf,int level_size,uint32_t hist_bits,uint8_t * dictbuf,size_t dictfile_size,struct isal_dict * dict_str,struct isal_hufftables * hufftables_custom)110*55fbfabfSMarcel Cornu deflate_perf(struct isal_zstream *stream, uint8_t *inbuf, size_t infile_size, size_t inbuf_size,
111*55fbfabfSMarcel Cornu uint8_t *outbuf, size_t outbuf_size, int level, uint8_t *level_buf, int level_size,
112*55fbfabfSMarcel Cornu uint32_t hist_bits, uint8_t *dictbuf, size_t dictfile_size, struct isal_dict *dict_str,
11319035917SGreg Tucker struct isal_hufftables *hufftables_custom)
114699bb5bdSRoy Oursler {
115699bb5bdSRoy Oursler int avail_in;
116699bb5bdSRoy Oursler isal_deflate_init(stream);
117699bb5bdSRoy Oursler stream->level = level;
118699bb5bdSRoy Oursler stream->level_buf = level_buf;
119699bb5bdSRoy Oursler stream->level_buf_size = level_size;
12019035917SGreg Tucker
12119035917SGreg Tucker if (COMP_OK != isal_deflate_reset_dict(stream, dict_str))
12219035917SGreg Tucker if (dictbuf != NULL)
12319035917SGreg Tucker isal_deflate_set_dict(stream, dictbuf, dictfile_size);
12419035917SGreg Tucker
12519035917SGreg Tucker stream->end_of_stream = 0;
12619035917SGreg Tucker stream->flush = NO_FLUSH;
127699bb5bdSRoy Oursler stream->next_out = outbuf;
128699bb5bdSRoy Oursler stream->avail_out = outbuf_size;
129699bb5bdSRoy Oursler stream->next_in = inbuf;
130699bb5bdSRoy Oursler if (hufftables_custom != NULL)
131699bb5bdSRoy Oursler stream->hufftables = hufftables_custom;
132699bb5bdSRoy Oursler stream->hist_bits = hist_bits;
133699bb5bdSRoy Oursler avail_in = infile_size;
134699bb5bdSRoy Oursler
135699bb5bdSRoy Oursler while (avail_in > 0) {
136699bb5bdSRoy Oursler stream->avail_in = avail_in >= inbuf_size ? inbuf_size : avail_in;
137699bb5bdSRoy Oursler avail_in -= inbuf_size;
138699bb5bdSRoy Oursler
139699bb5bdSRoy Oursler if (avail_in <= 0)
140699bb5bdSRoy Oursler stream->end_of_stream = 1;
141699bb5bdSRoy Oursler
142699bb5bdSRoy Oursler isal_deflate(stream);
143699bb5bdSRoy Oursler
144699bb5bdSRoy Oursler if (stream->avail_in != 0)
145699bb5bdSRoy Oursler break;
146699bb5bdSRoy Oursler }
147699bb5bdSRoy Oursler }
148699bb5bdSRoy Oursler
149*55fbfabfSMarcel Cornu int
main(int argc,char * argv[])150*55fbfabfSMarcel Cornu main(int argc, char *argv[])
151660f49b0SGreg Tucker {
152ed15402fSRoy Oursler FILE *in = NULL, *out = NULL, *dict = NULL;
153ed15402fSRoy Oursler unsigned char *inbuf, *outbuf, *level_buf = NULL, *dictbuf = NULL;
154699bb5bdSRoy Oursler int c, time = BENCHMARK_TIME, inbuf_size = 0;
155699bb5bdSRoy Oursler size_t infile_size, outbuf_size, dictfile_size;
156660f49b0SGreg Tucker struct isal_huff_histogram histogram;
157660f49b0SGreg Tucker struct isal_hufftables hufftables_custom;
158699bb5bdSRoy Oursler int level = 0, level_size = 0;
159ed15402fSRoy Oursler char *in_file_name = NULL, *out_file_name = NULL, *dict_file_name = NULL;
160aa8b5193SRoy Oursler uint32_t hist_bits = 0;
161699bb5bdSRoy Oursler struct isal_zstream stream;
162660f49b0SGreg Tucker
163aa8b5193SRoy Oursler while ((c = getopt(argc, argv, "h0123456789i:b:o:d:w:")) != -1) {
1644ae2d1beSRoy Oursler if (c >= '0' && c <= '9') {
1654ae2d1beSRoy Oursler if (c > '0' + ISAL_DEF_MAX_LEVEL)
1664ae2d1beSRoy Oursler usage();
1674ae2d1beSRoy Oursler else {
1684ae2d1beSRoy Oursler level = c - '0';
1694ae2d1beSRoy Oursler level_size = level_size_buf[level];
1704ae2d1beSRoy Oursler }
1714ae2d1beSRoy Oursler continue;
1724ae2d1beSRoy Oursler }
1734ae2d1beSRoy Oursler
1745d155804SRoy Oursler switch (c) {
1755d155804SRoy Oursler case 'o':
1765d155804SRoy Oursler out_file_name = optarg;
1775d155804SRoy Oursler break;
178ed15402fSRoy Oursler case 'd':
179ed15402fSRoy Oursler dict_file_name = optarg;
180ed15402fSRoy Oursler break;
1815d155804SRoy Oursler case 'i':
182699bb5bdSRoy Oursler time = atoi(optarg);
18389f7c46cSGreg Tucker if (time < 0)
1845d155804SRoy Oursler usage();
1855d155804SRoy Oursler break;
1865d155804SRoy Oursler case 'b':
1875d155804SRoy Oursler inbuf_size = atoi(optarg);
1885d155804SRoy Oursler break;
189aa8b5193SRoy Oursler case 'w':
190aa8b5193SRoy Oursler hist_bits = atoi(optarg);
191aa8b5193SRoy Oursler if (hist_bits > 15 || hist_bits < 8)
192aa8b5193SRoy Oursler usage();
193aa8b5193SRoy Oursler break;
1945d155804SRoy Oursler case 'h':
1955d155804SRoy Oursler default:
1965d155804SRoy Oursler usage();
1975d155804SRoy Oursler break;
198660f49b0SGreg Tucker }
1995d155804SRoy Oursler }
2005d155804SRoy Oursler
2015d155804SRoy Oursler if (optind < argc) {
2025d155804SRoy Oursler in_file_name = argv[optind];
2035d155804SRoy Oursler in = fopen(in_file_name, "rb");
2045d155804SRoy Oursler } else
2055d155804SRoy Oursler usage();
2065d155804SRoy Oursler
207660f49b0SGreg Tucker if (!in) {
2085d155804SRoy Oursler fprintf(stderr, "Can't open %s for reading\n", in_file_name);
209660f49b0SGreg Tucker exit(0);
210660f49b0SGreg Tucker }
2115d155804SRoy Oursler if (out_file_name != NULL) {
2125d155804SRoy Oursler out = fopen(out_file_name, "wb");
213660f49b0SGreg Tucker if (!out) {
2145d155804SRoy Oursler fprintf(stderr, "Can't open %s for writing\n", out_file_name);
215660f49b0SGreg Tucker exit(0);
216660f49b0SGreg Tucker }
2175d155804SRoy Oursler printf("outfile=%s\n", out_file_name);
218660f49b0SGreg Tucker }
2195d155804SRoy Oursler
220ed15402fSRoy Oursler if (dict_file_name != NULL) {
221ed15402fSRoy Oursler dict = fopen(dict_file_name, "rb");
222ed15402fSRoy Oursler if (!dict) {
223ed15402fSRoy Oursler fprintf(stderr, "Can't open %s for reading\n", dict_file_name);
224ed15402fSRoy Oursler exit(0);
225ed15402fSRoy Oursler }
226ed15402fSRoy Oursler printf("outfile=%s\n", dict_file_name);
227ed15402fSRoy Oursler }
228ed15402fSRoy Oursler
229aa8b5193SRoy Oursler if (hist_bits == 0)
2305d155804SRoy Oursler printf("Window Size: %d K\n", IGZIP_HIST_SIZE / 1024);
231aa8b5193SRoy Oursler
232aa8b5193SRoy Oursler else if (hist_bits < 10)
233aa8b5193SRoy Oursler printf("Window Size: %.2f K\n", 1.0 * (1 << hist_bits) / 1024);
234aa8b5193SRoy Oursler else
235aa8b5193SRoy Oursler printf("Window Size: %d K\n", (1 << hist_bits) / 1024);
236aa8b5193SRoy Oursler
237660f49b0SGreg Tucker printf("igzip_file_perf: \n");
238660f49b0SGreg Tucker fflush(0);
2395d155804SRoy Oursler
240660f49b0SGreg Tucker /* Allocate space for entire input file and output
241660f49b0SGreg Tucker * (assuming some possible expansion on output size)
242660f49b0SGreg Tucker */
243660f49b0SGreg Tucker infile_size = get_filesize(in);
244660f49b0SGreg Tucker
2455d155804SRoy Oursler outbuf_size = 2 * infile_size + BUF_SIZE;
2465d155804SRoy Oursler
24748d74d6eSGreg Tucker dictfile_size = (dict_file_name != NULL) ? get_filesize(dict) : 0;
248ed15402fSRoy Oursler
249660f49b0SGreg Tucker inbuf = malloc(infile_size);
250660f49b0SGreg Tucker if (inbuf == NULL) {
251660f49b0SGreg Tucker fprintf(stderr, "Can't allocate input buffer memory\n");
252660f49b0SGreg Tucker exit(0);
253660f49b0SGreg Tucker }
254660f49b0SGreg Tucker outbuf = malloc(outbuf_size);
255660f49b0SGreg Tucker if (outbuf == NULL) {
256660f49b0SGreg Tucker fprintf(stderr, "Can't allocate output buffer memory\n");
257660f49b0SGreg Tucker exit(0);
258660f49b0SGreg Tucker }
259660f49b0SGreg Tucker
260ed15402fSRoy Oursler if (dictfile_size != 0) {
261ed15402fSRoy Oursler dictbuf = malloc(dictfile_size);
262ed15402fSRoy Oursler if (dictbuf == NULL) {
263ed15402fSRoy Oursler fprintf(stderr, "Can't allocate dictionary buffer memory\n");
264ed15402fSRoy Oursler exit(0);
265ed15402fSRoy Oursler }
266ed15402fSRoy Oursler }
267ed15402fSRoy Oursler
2685d155804SRoy Oursler if (level_size != 0) {
2695d155804SRoy Oursler level_buf = malloc(level_size);
2705d155804SRoy Oursler if (level_buf == NULL) {
2715d155804SRoy Oursler fprintf(stderr, "Can't allocate level buffer memory\n");
2725d155804SRoy Oursler exit(0);
2735d155804SRoy Oursler }
2745d155804SRoy Oursler }
2755d155804SRoy Oursler
2765d155804SRoy Oursler inbuf_size = inbuf_size ? inbuf_size : infile_size;
2775d155804SRoy Oursler
278699bb5bdSRoy Oursler printf("igzip_file_perf: %s\n", in_file_name);
27948d74d6eSGreg Tucker
280660f49b0SGreg Tucker /* Read complete input file into buffer */
281660f49b0SGreg Tucker stream.avail_in = (uint32_t) fread(inbuf, 1, infile_size, in);
282660f49b0SGreg Tucker if (stream.avail_in != infile_size) {
283660f49b0SGreg Tucker fprintf(stderr, "Couldn't fit all of input file into buffer\n");
284660f49b0SGreg Tucker exit(0);
285660f49b0SGreg Tucker }
286660f49b0SGreg Tucker
28748d74d6eSGreg Tucker /* Read complete dictionary into buffer */
28848d74d6eSGreg Tucker if ((dictfile_size != 0) && (dictfile_size != fread(dictbuf, 1, dictfile_size, dict))) {
289ed15402fSRoy Oursler fprintf(stderr, "Couldn't fit all of dictionary file into buffer\n");
290ed15402fSRoy Oursler exit(0);
291ed15402fSRoy Oursler }
292ed15402fSRoy Oursler
29319035917SGreg Tucker struct isal_dict dict_str;
29419035917SGreg Tucker stream.level = level;
29519035917SGreg Tucker isal_deflate_process_dict(&stream, &dict_str, dictbuf, dictfile_size);
29619035917SGreg Tucker
297699bb5bdSRoy Oursler struct perf start;
29889f7c46cSGreg Tucker if (time > 0) {
299699bb5bdSRoy Oursler BENCHMARK(&start, time,
300699bb5bdSRoy Oursler deflate_perf(&stream, inbuf, infile_size, inbuf_size, outbuf, outbuf_size,
301699bb5bdSRoy Oursler level, level_buf, level_size, hist_bits, dictbuf,
302*55fbfabfSMarcel Cornu dictfile_size, &dict_str, NULL));
303*55fbfabfSMarcel Cornu } else {
304*55fbfabfSMarcel Cornu deflate_perf(&stream, inbuf, infile_size, inbuf_size, outbuf, outbuf_size, level,
305*55fbfabfSMarcel Cornu level_buf, level_size, hist_bits, dictbuf, dictfile_size, &dict_str,
306*55fbfabfSMarcel Cornu NULL);
30789f7c46cSGreg Tucker }
308660f49b0SGreg Tucker if (stream.avail_in != 0) {
309660f49b0SGreg Tucker fprintf(stderr, "Could not compress all of inbuf\n");
310660f49b0SGreg Tucker exit(0);
311660f49b0SGreg Tucker }
312660f49b0SGreg Tucker
313*55fbfabfSMarcel Cornu printf(" file %s - in_size=%lu out_size=%d ratio=%3.1f%%", in_file_name, infile_size,
314*55fbfabfSMarcel Cornu stream.total_out, 100.0 * stream.total_out / infile_size);
3155d155804SRoy Oursler
3165d155804SRoy Oursler if (level == 0) {
3175d155804SRoy Oursler memset(&histogram, 0, sizeof(histogram));
318660f49b0SGreg Tucker
319660f49b0SGreg Tucker isal_update_histogram(inbuf, infile_size, &histogram);
320660f49b0SGreg Tucker isal_create_hufftables(&hufftables_custom, &histogram);
321660f49b0SGreg Tucker
322*55fbfabfSMarcel Cornu deflate_perf(&stream, inbuf, infile_size, inbuf_size, outbuf, outbuf_size, level,
323*55fbfabfSMarcel Cornu level_buf, level_size, hist_bits, dictbuf, dictfile_size, &dict_str,
324*55fbfabfSMarcel Cornu &hufftables_custom);
3255d155804SRoy Oursler
3265d155804SRoy Oursler printf(" ratio_custom=%3.1f%%", 100.0 * stream.total_out / infile_size);
3275d155804SRoy Oursler }
3285d155804SRoy Oursler printf("\n");
329660f49b0SGreg Tucker
330660f49b0SGreg Tucker if (stream.avail_in != 0) {
331660f49b0SGreg Tucker fprintf(stderr, "Could not compress all of inbuf\n");
332660f49b0SGreg Tucker exit(0);
333660f49b0SGreg Tucker }
334660f49b0SGreg Tucker
335660f49b0SGreg Tucker printf("igzip_file: ");
336699bb5bdSRoy Oursler perf_print(start, (long long) infile_size);
337660f49b0SGreg Tucker
338660f49b0SGreg Tucker if (argc > 2 && out) {
3395d155804SRoy Oursler printf("writing %s\n", out_file_name);
340660f49b0SGreg Tucker fwrite(outbuf, 1, stream.total_out, out);
341660f49b0SGreg Tucker fclose(out);
342660f49b0SGreg Tucker }
343660f49b0SGreg Tucker
344660f49b0SGreg Tucker fclose(in);
345660f49b0SGreg Tucker printf("End of igzip_file_perf\n\n");
346660f49b0SGreg Tucker fflush(0);
347660f49b0SGreg Tucker return 0;
348660f49b0SGreg Tucker }
349