## Coverage Report

#### Created: 2026-05-04 15:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /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; 15j < 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; 150x < 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"