## Coverage Report

#### Created: 2026-04-18 18:15

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

    /home/liu/actions-runner/_work/ccv/ccv/lib/nnc/ccv_cnnp_dataframe_core.c

    Line
    Count
    Source
    1
    #include "ccv_nnc.h"
    2
    #include "ccv_nnc_easy.h"
    3
    #include "ccv_nnc_internal.h"
    4
    #include "ccv_internal.h"
    5
    #include "_ccv_cnnp_dataframe.h"
    6
    #ifdef CCV_BLOCK_SUPPORT
    7
    #include <Block.h>
    8
    #endif
    9
    10
    // MARK - Reducer
    11
    12
    typedef struct {
    13
      int column_idx;
    14
      int batch_size;
    15
      int iter_idx;
    16
      ccv_cnnp_column_data_sample_f sample;
    17
      ccv_cnnp_dataframe_t* dataframe;
    18
      ccv_cnnp_dataframe_iter_t* iter;
    19
      ccv_cnnp_column_data_deinit_f data_deinit;
    20
      void* context;
    21
      ccv_cnnp_column_data_context_deinit_f context_deinit;
    22
      void* batch_data[1];
    23
    } ccv_cnnp_dataframe_sampler_t;
    24
    25
    static void _ccv_cnnp_sampler_enum(const int column_idx, const int* const row_idxs, const int row_size, void** const data, void* const context, ccv_nnc_stream_context_t* const stream_context)
    26
    375
    {
    27
    375
      ccv_cnnp_dataframe_sampler_t* const sampler = (ccv_cnnp_dataframe_sampler_t*)context;
    28
    375
      if (!sampler->iter)
    29
    17
      {
    30
    17
        sampler->iter = ccv_cnnp_dataframe_iter_new(sampler->dataframe, &sampler->column_idx, 1);
    31
    17
        sampler->iter_idx = -1;
    32
    17
      }
    33
    375
      ccv_cnnp_dataframe_iter_t* const iter = sampler->iter;
    34
    375
      int i, j;
    35
    750
      for (i = 0; i < row_size; i++375)
    36
    375
      {
    37
    375
        if (sampler->iter_idx + 1 != row_idxs[i])
    38
    2
          ccv_cnnp_dataframe_iter_set_cursor(iter, row_idxs[i] * sampler->batch_size);
    39
    375
        sampler->iter_idx = row_idxs[i];
    40
    375
        ccv_cnnp_dataframe_iter_prefetch(iter, sampler->batch_size, stream_context);
    41
    181k
        for (j = 0; j < sampler->batch_size; j++180k)
    42
    180k
          if (0 != ccv_cnnp_dataframe_iter_next(iter, sampler->batch_data + j, 1, stream_context))
    43
    14
            break;
    44
    375
        sampler->sample(sampler->batch_data, j, data + i, sampler->context, stream_context);
    45
    375
      }
    46
    375
    }
    47
    48
    static void _ccv_cnnp_sampler_data_deinit(void* const data, void* const context)
    49
    16
    {
    50
    16
      ccv_cnnp_dataframe_sampler_t* const sampler = (ccv_cnnp_dataframe_sampler_t*)context;
    51
    16
      assert(sampler->data_deinit);
    52
    16
      sampler->data_deinit(data, sampler->context);
    53
    16
    }
    54
    55
    static void _ccv_cnnp_sampler_deinit(void* const context)
    56
    17
    {
    57
    17
      ccv_cnnp_dataframe_sampler_t* const sampler = (ccv_cnnp_dataframe_sampler_t*)context;
    58
    17
      if (sampler->iter)
    59
    17
        ccv_cnnp_dataframe_iter_free(sampler->iter);
    60
    17
      if (sampler->context_deinit)
    61
    13
        sampler->context_deinit(sampler->context);
    62
    17
      ccfree(sampler);
    63
    17
    }
    64
    65
    ccv_cnnp_dataframe_t* ccv_cnnp_dataframe_sample_new(ccv_cnnp_dataframe_t* const dataframe, ccv_cnnp_column_data_sample_f sample, ccv_cnnp_column_data_deinit_f data_deinit, const int column_idx, const int batch_size, void* const context, ccv_cnnp_column_data_context_deinit_f context_deinit)
    66
    17
    {
    67
    17
      assert(batch_size > 0);
    68
    17
      ccv_cnnp_dataframe_sampler_t* const sampler = (ccv_cnnp_dataframe_sampler_t*)ccmalloc(sizeof(ccv_cnnp_dataframe_sampler_t) + sizeof(void*) * (batch_size - 1));
    69
    17
      sampler->column_idx = column_idx;
    70
    17
      sampler->batch_size = batch_size;
    71
    17
      sampler->sample = sample;
    72
    17
      sampler->dataframe = dataframe;
    73
    17
      sampler->iter = 0;
    74
    17
      sampler->data_deinit = data_deinit;
    75
    17
      sampler->context = context;
    76
    17
      sampler->context_deinit = context_deinit;
    77
    17
      ccv_cnnp_column_data_t sample_column = {
    78
    17
        .data_enum = _ccv_cnnp_sampler_enum,
    79
    17
        .data_deinit = data_deinit ? _ccv_cnnp_sampler_data_deinit13 : 04, // Redirect to our data deinit method.
    80
    17
        .context = sampler,
    81
    17
        .context_deinit = _ccv_cnnp_sampler_deinit,
    82
    17
      };
    83
    17
      return ccv_cnnp_dataframe_new(&sample_column, 1, (ccv_cnnp_dataframe_row_count(dataframe) + batch_size - 1) / batch_size);
    84
    17
    }
    85
    86
    // MARK - Extract
    87
    88
    static void _ccv_cnnp_extract_value(void* const* const* const column_data, const int column_size, const int batch_size, void** const data, void* const context, ccv_nnc_stream_context_t* const stream_context)
    89
    711
    {
    90
    711
      const off_t offset = (off_t)(uintptr_t)context;
    91
    711
      int i;
    92
    302k
      for (i = 0; i < batch_size; i++301k)
    93
    301k
      {
    94
    301k
        char* const values = (char*)column_data[0][i];
    95
    301k
        data[i] = *(void**)(values + offset);
    96
    301k
      }
    97
    711
    }
    98
    99
    int ccv_cnnp_dataframe_extract_value(ccv_cnnp_dataframe_t* const dataframe, const int column_idx, const off_t offset, const char* name)
    100
    55
    {
    101
    55
      return ccv_cnnp_dataframe_map(dataframe, _ccv_cnnp_extract_value, 0, 0, &column_idx, 1, (void*)(uintptr_t)offset, 0, name);
    102
    55
    }
    103
    104
    // MARK - Make Tuple
    105
    106
    static void _ccv_cnnp_tuple_deinit(void* const data, void* const context)
    107
    11.4k
    {
    108
    11.4k
      ccfree(data);
    109
    11.4k
    }
    110
    111
    static void _ccv_cnnp_make_tuple(void* const* const* const column_data, const int column_size, const int batch_size, void** const data, void* const context, ccv_nnc_stream_context_t* const stream_context)
    112
    679
    {
    113
    679
      const ccv_cnnp_dataframe_tuple_t* const tuple = (ccv_cnnp_dataframe_tuple_t*)context;
    114
    679
      int i, j;
    115
    301k
      for (i = 0; i < batch_size; i++300k)
    116
    300k
      {
    117
    300k
        if (!data[i])
    118
    11.4k
          data[i] = ccmalloc(sizeof(void*) * tuple->size);
    119
    300k
        void** tuple_data = (void**)data[i];
    120
    753k
        for (j = 0; j < column_size; j++452k)
    121
    452k
          tuple_data[j] = column_data[j][i];
    122
    300k
      }
    123
    679
    }
    124
    125
    int ccv_cnnp_dataframe_make_tuple(ccv_cnnp_dataframe_t* const dataframe, const int* const column_idxs, const int column_idx_size, const char* name)
    126
    22
    {
    127
    22
      ccv_cnnp_dataframe_tuple_t* const tuple = (ccv_cnnp_dataframe_tuple_t*)ccmalloc(sizeof(ccv_cnnp_dataframe_tuple_t));
    128
    22
      tuple->size = column_idx_size;
    129
    22
      return ccv_cnnp_dataframe_map(dataframe, _ccv_cnnp_make_tuple, 0, _ccv_cnnp_tuple_deinit, column_idxs, column_idx_size, tuple, (ccv_cnnp_column_data_context_deinit_f)ccfree, name);
    130
    22
    }
    131
    132
    int ccv_cnnp_dataframe_tuple_size(const ccv_cnnp_dataframe_t* const dataframe, const int column_idx)
    133
    2
    {
    134
    2
      const ccv_cnnp_dataframe_tuple_t* const tuple = (ccv_cnnp_dataframe_tuple_t*)ccv_cnnp_dataframe_column_context(dataframe, column_idx);
    135
    2
      return tuple->size;
    136
    2
    }
    137
    138
    int ccv_cnnp_dataframe_extract_tuple(ccv_cnnp_dataframe_t* const dataframe, const int column_idx, const int index, const char* name)
    139
    37
    {
    140
    37
      return ccv_cnnp_dataframe_extract_value(dataframe, column_idx, index * sizeof(void*), name);
    141
    37
    }