1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <math.h>
5 #include <assert.h>
7 #include "benchmark.h"
8 #include "idct.h"
10 // Generate random coefficients in the range [-15..15].
11 void gen_random_coeffs(int16_t* dst, size_t len)
12 {
13         // Standard NR LCG (we avoid rand() to get consistent behavior across platforms).
14         static uint32_t seed = 1234;
15         for (unsigned i = 0; i < len; ++i) {
16                 seed = seed * 1664525U + 1013904223U;
17                 if (seed >> 31) {
18                         dst[i] = (uint8_t)(seed >> 27) & 0x7;
19                 } else {
20                         dst[i] = -((uint8_t)(seed >> 27) & 0x7);
21                 }
22         }
23 }
25 // Test that the input is pretty close to the reference for random inputs.
26 // (If the reference funtion is given in, this becomes a simple test of its
27 // determinism.)
28 void test_random_inputs(idct_alloc_t* idct_alloc, idct_free_t* idct_free, idct_func_t* idct)
29 {
30         int16_t coeff[DCTSIZE2];
31         uint32_t quant[DCTSIZE2];
32         uint8_t output[DCTSIZE2];
33         uint8_t reference[DCTSIZE2];
35         // Unit quantization (ie., no scaling).
36         for (unsigned i = 0; i < DCTSIZE2; ++i) {
37                 quant[i] = 1;
38         }
40         void* userdata_reference = idct_reference_alloc(quant);
41         void* userdata = idct_alloc(quant);
43         for (unsigned i = 0; i < 1000; ++i) {
44                 gen_random_coeffs(coeff, DCTSIZE2);
46                 (*idct)(coeff, userdata, output);
47                 (idct_reference)(coeff, userdata_reference, reference);
49                 // Find the RMS difference.
50                 int diff_squared = 0;
51                 for (unsigned i = 0; i < DCTSIZE2; ++i) {
52                         diff_squared += (output[i] - reference[i]) * (output[i] - reference[i]);
53                 }
55                 assert(diff_squared <= 5);
56         }
58         idct_reference_free(userdata_reference);
59         idct_free(userdata);
60 }
62 // Test that a single DC coefficient becomes spread out to all blocks.
63 void test_dc_becomes_spread_out(idct_alloc_t* idct_alloc, idct_free_t* idct_free, idct_func_t* idct)
64 {
65         int16_t coeff[DCTSIZE2] = { 0 };
66         uint32_t quant[DCTSIZE2];
67         uint8_t output[DCTSIZE2];
69         // Unit quantization (ie., no scaling).
70         for (unsigned i = 0; i < DCTSIZE2; ++i) {
71                 quant[i] = 1;
72         }
74         void* userdata = idct_alloc(quant);
76         for (unsigned i = 0; i < 255*8; ++i) {
77                 uint32_t reference_value = i / 8;
78                 coeff = i;
80                 (*idct)(coeff, userdata, output);
82                 for (unsigned i = 0; i < DCTSIZE2; ++i) {
83                         assert(abs(output[i] - reference_value) <= 1);
84                 }
85         }
87         idct_free(userdata);
88 }
90 double timediff(const struct timeval* a, const struct timeval* b)
91 {
92         return (double)(b->tv_sec - a->tv_sec) +
93                 (double)(b->tv_usec - a->tv_usec) * 1e-6;
94 }
96 void test_performance(idct_alloc_t* idct_alloc, idct_free_t* idct_free, idct_func_t* idct)
97 {
98         const unsigned num_runs = (idct == idct_reference) ? 5000 : 5000000;
100         int16_t coeff[DCTSIZE2];
101         uint32_t quant[DCTSIZE2];
102         uint8_t output[DCTSIZE2];
104         gen_random_coeffs(coeff, DCTSIZE2);
106         // Unit quantization (ie., no scaling).
107         for (unsigned i = 0; i < DCTSIZE2; ++i) {
108                 quant[i] = 1;
109         }
111         void* userdata = idct_alloc(quant);
113         start_benchmark_timer();
115         for (unsigned i = 0; i < num_runs; ++i) {
116                 (*idct)(coeff, userdata, output);
117         }
119         double diff = stop_benchmark_timer();
120         printf("%u runs in %.2f CPU seconds = %.2f IDCTs/sec\n",
121                 num_runs, diff, num_runs / diff);
123         idct_free(userdata);
124 }
126 void test_all_idct(idct_alloc_t* idct_alloc, idct_free_t* idct_free, idct_func_t* idct)
127 {
131         printf("  test_random_inputs()\n");
132         test_random_inputs(idct_alloc, idct_free, idct);
134         printf("  performance test: ");
135         test_performance(idct_alloc, idct_free, idct);
136 }
138 int main(void)
139 {
140         printf("idct_reference:\n");
141         test_all_idct(idct_reference_alloc, idct_reference_free, idct_reference);
143         printf("idct_float:\n");
144         test_all_idct(idct_float_alloc, idct_float_free, idct_float);
146         printf("All tests pass.\n");
147         return 0;
148 }
{"ft_lang_label":"__label__en","ft_lang_prob":0.50663936,"math_prob":0.9324999,"size":3416,"snap":"2022-05-2022-21","text_gpt3_token_len":1132,"char_repetition_ratio":0.17203987,"word_repetition_ratio":0.11328976,"special_character_ratio":0.38553864,"punctuation_ratio":0.2108014,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9842002,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2022-05-20T10:15:00Z\",\"WARC-Record-ID\":\"<urn:uuid:cc94b01b-d56c-4693-a8de-86ec6aed3d78>\",\"Content-Length\":\"43520\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:1299305b-37c5-4bb2-9624-769b97bb50a3>\",\"WARC-Concurrent-To\":\"<urn:uuid:03a26c27-1672-4f3c-b0a7-a413f9e39146>\",\"WARC-IP-Address\":\"193.35.52.50\",\"WARC-Target-URI\":\"https://git.sesse.net/?p=fjl;a=blob;f=idct_test.c;h=78374f89860b4f788bcee3d2c62fed8c9ac8a3bb;hb=13b48c4e2de5ceb4922ee47db32dd1a18edfffe4\",\"WARC-Payload-Digest\":\"sha1:L5UXEWSYPF3NIWLYR7KAB6MWX3EDLMQD\",\"WARC-Block-Digest\":\"sha1:EL4E6NNW3JA7FYMWE3SXAECXTB3KIJQT\",\"WARC-Identified-Payload-Type\":\"application/xhtml+xml\",\"warc_filename\":\"/cc_download/warc_2022/CC-MAIN-2022-21/CC-MAIN-2022-21_segments_1652662531779.10_warc_CC-MAIN-20220520093441-20220520123441-00160.warc.gz\"}"}