/home/liu/actions-runner/_work/ccv/ccv/test/unit/nnc/compression.tests.c
Line | Count | Source |
1 | | #include "case.h" |
2 | | #include "ccv_case.h" |
3 | | #include "ccv_nnc_case.h" |
4 | | #include <ccv.h> |
5 | | #include <nnc/ccv_nnc.h> |
6 | | #include <nnc/ccv_nnc_easy.h> |
7 | | #include "3rdparty/dsfmt/dSFMT.h" |
8 | | |
9 | | TEST_SETUP() |
10 | | { |
11 | | ccv_nnc_init(); |
12 | | } |
13 | | |
14 | | #ifdef HAVE_LIBPNG |
15 | | TEST_CASE("LSSC for natural image") |
16 | 1 | { |
17 | 1 | ccv_dense_matrix_t* image = 0; |
18 | 1 | ccv_read("../../../samples/nature.png", &image, CCV_IO_RGB_COLOR | CCV_IO_ANY_FILE); |
19 | 1 | ccv_dense_matrix_t* i32 = 0; |
20 | 1 | ccv_shift(image, (ccv_matrix_t**)&i32, CCV_32F, 0, 0); |
21 | 1 | ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 3, image->rows, image->cols), 0); |
22 | 1 | ccv_nnc_cmd_exec(CMD_FORMAT_TRANSFORM_FORWARD(), ccv_nnc_no_hint, 0, TENSOR_LIST((ccv_nnc_tensor_t*)i32), TENSOR_LIST(a), 0); |
23 | 1 | ccv_nnc_tensor_param_t a_params = CPU_TENSOR_NCHW(16F, 3, image->rows, image->cols); |
24 | 1 | ccv_nnc_tensor_t* const a16 = ccv_nnc_tensor_new(0, a_params, 0); |
25 | 1 | ccv_nnc_tensor_param_t b_params; |
26 | 1 | ccv_nnc_hint_tensor_auto(CMD_COMPRESSION_LSSC_FORWARD(), &a_params, 1, ccv_nnc_no_hint, &b_params, 1); |
27 | 1 | ccv_nnc_tensor_t* const b16 = ccv_nnc_tensor_new(0, b_params, 0); |
28 | 1 | ccv_nnc_tensor_t* const c16 = ccv_nnc_tensor_new(0, a_params, 0); |
29 | 1 | ccv_nnc_tensor_t* const c = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 3, image->rows, image->cols), 0); |
30 | 1 | ccv_float_to_half_precision(a->data.f32, (uint16_t*)a16->data.f16, 3 * image->rows * image->cols); |
31 | 1 | ccv_nnc_cmd_exec(CMD_COMPRESSION_LSSC_FORWARD(), ccv_nnc_no_hint, 0, TENSOR_LIST(a16), TENSOR_LIST(b16), 0); |
32 | 1 | ccv_nnc_cmd_exec(CMD_COMPRESSION_LSSC_BACKWARD(), ccv_nnc_no_hint, 0, TENSOR_LIST(b16), TENSOR_LIST(c16), 0); |
33 | 1 | ccv_half_precision_to_float((uint16_t*)c16->data.f16, c->data.f32, 3 * image->rows * image->cols); |
34 | 1 | ccv_nnc_cmd_exec(CMD_FORMAT_TRANSFORM_FORWARD(), ccv_nnc_no_hint, 0, TENSOR_LIST(c), TENSOR_LIST((ccv_nnc_tensor_t*)i32), 0); |
35 | 1 | ccv_dense_matrix_t* restore = 0; |
36 | 1 | ccv_shift(i32, (ccv_matrix_t**)&restore, CCV_8U, 0, 0); |
37 | 1 | REQUIRE_MATRIX_FILE_EQ(restore, "data/nature.lssc.bin", "the natural image should be equal"); |
38 | 1 | ccv_matrix_free(i32); |
39 | 1 | ccv_matrix_free(restore); |
40 | 1 | ccv_matrix_free(image); |
41 | 1 | ccv_nnc_tensor_free(a); |
42 | 1 | ccv_nnc_tensor_free(c); |
43 | 1 | ccv_nnc_tensor_free(a16); |
44 | 1 | ccv_nnc_tensor_free(b16); |
45 | 1 | ccv_nnc_tensor_free(c16); |
46 | 1 | } |
47 | | #endif |
48 | | |
49 | | TEST_CASE("LSSC should give exact result for 2-value data") |
50 | 1 | { |
51 | 1 | ccv_nnc_tensor_t* const a = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 5, 10, 11), 0); |
52 | 1 | ccv_nnc_tensor_param_t a_params = CPU_TENSOR_NCHW(16F, 5, 10, 11); |
53 | 1 | ccv_nnc_tensor_t* const a16 = ccv_nnc_tensor_new(0, a_params, 0); |
54 | 1 | ccv_nnc_tensor_param_t b_params; |
55 | 1 | ccv_nnc_hint_tensor_auto(CMD_COMPRESSION_LSSC_FORWARD(), &a_params, 1, ccv_nnc_no_hint, &b_params, 1); |
56 | 1 | ccv_nnc_tensor_t* const b16 = ccv_nnc_tensor_new(0, b_params, 0); |
57 | 1 | ccv_nnc_tensor_t* const c16 = ccv_nnc_tensor_new(0, a_params, 0); |
58 | 1 | ccv_nnc_tensor_t* const c = ccv_nnc_tensor_new(0, CPU_TENSOR_NCHW(32F, 5, 10, 11), 0); |
59 | 1 | dsfmt_t dsfmt; |
60 | 1 | int i, j, k, x, y; |
61 | 1 | dsfmt_init_gen_rand(&dsfmt, 1); |
62 | 551 | for (i = 0; i < 5 * 10 * 11; i++550 ) |
63 | 550 | a->data.f32[i] = dsfmt_genrand_open_close(&dsfmt) * 2 - 1; |
64 | 1 | ccv_float_to_half_precision(a->data.f32, (uint16_t*)a16->data.f16, 5 * 10 * 11); |
65 | | // Now, for each 4x4 region, pick 2 values and assign to the rest of that region. |
66 | 6 | for (k = 0; k < 5; k++5 ) |
67 | 5 | { |
68 | 20 | for (i = 0; i < 10; i += 415 ) |
69 | 60 | for (j = 0; 15 j < 11; j += 445 ) |
70 | 45 | { |
71 | 45 | ccv_float16_t v[2] = { a16->data.f16[k * 11 * 10 + i * 11 + j], a16->data.f16[k * 11 * 10 + i * 11 + j + 1] }; |
72 | 195 | for (y = 0; y < ccv_min(i + 4, 10) - i; y++150 ) |
73 | 700 | for (x = 0; 150 x < ccv_min(j + 4, 11) - j; x++550 ) |
74 | 550 | a16->data.f16[k * 11 * 10 + (i + y) * 11 + j + x] = v[dsfmt_genrand_uint32(&dsfmt) % 2]; |
75 | 45 | } |
76 | 5 | } |
77 | 1 | ccv_half_precision_to_float((uint16_t*)a16->data.f16, a->data.f32, 5 * 10 * 11); |
78 | 1 | ccv_nnc_cmd_exec(CMD_COMPRESSION_LSSC_FORWARD(), ccv_nnc_no_hint, 0, TENSOR_LIST(a16), TENSOR_LIST(b16), 0); |
79 | 1 | ccv_nnc_cmd_exec(CMD_COMPRESSION_LSSC_BACKWARD(), ccv_nnc_no_hint, 0, TENSOR_LIST(b16), TENSOR_LIST(c16), 0); |
80 | 1 | ccv_half_precision_to_float((uint16_t*)c16->data.f16, c->data.f32, 5 * 10 * 11); |
81 | 1 | REQUIRE_TENSOR_EQ(a, c, "decompressed tensor should be equal to original"); |
82 | 1 | ccv_nnc_tensor_free(a); |
83 | 1 | ccv_nnc_tensor_free(c); |
84 | 1 | ccv_nnc_tensor_free(a16); |
85 | 1 | ccv_nnc_tensor_free(b16); |
86 | 1 | ccv_nnc_tensor_free(c16); |
87 | 1 | } |
88 | | |
89 | | #include "case_main.h" |