## Coverage Report

#### Created: 2026-04-17 07:37

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

    /home/liu/actions-runner/_work/ccv/ccv/lib/nnc/cmd/convolution/cpu_opt/_ccv_nnc_conv_cpu_gemm.c

    Line
    Count
    Source
    1
    #include "ccv.h"
    2
    #include "ccv_internal.h"
    3
    #include "nnc/ccv_nnc.h"
    4
    #include "nnc/ccv_nnc_easy.h"
    5
    #include "nnc/ccv_nnc_internal.h"
    6
    #include "../_ccv_nnc_conv_cpu_opt.h"
    7
    8
    int _ccv_nnc_conv_forw_gemm_cpu_opt(const ccv_nnc_tensor_view_t* const a, const ccv_nnc_tensor_t* const w, const ccv_nnc_tensor_t* const bias, const ccv_nnc_hint_t hint, ccv_nnc_tensor_view_t* const b)
    9
    4
    {
    10
    4
      assert(CCV_IS_TENSOR_CONTIGUOUS(a));
    11
    4
      assert(CCV_IS_TENSOR_CONTIGUOUS(w));
    12
    4
      assert(!bias || !CCV_IS_TENSOR_VIEW(bias));
    13
    4
      assert(CCV_IS_TENSOR_CONTIGUOUS(b));
    14
    4
      const int a_nd = ccv_nnc_tensor_nd(a->info.dim);
    15
    4
      assert(a_nd == CCV_NNC_MAX_DIM + 1 || a_nd == CCV_NNC_MAX_DIM + 2);
    16
    4
      const int* adim = (a_nd == CCV_NNC_MAX_DIM + 1) ? a->info.dim : a->info.dim + 10;
    17
    4
      const int b_nd = ccv_nnc_tensor_nd(b->info.dim);
    18
    4
      assert(b_nd == CCV_NNC_MAX_DIM + 1 || b_nd == CCV_NNC_MAX_DIM + 2);
    19
    4
      const int* bdim = (b_nd == CCV_NNC_MAX_DIM + 1) ? b->info.dim : b->info.dim + 10;
    20
    4
      assert(hint.border.begin[0] == 0 && hint.border.begin[1] == 0);
    21
    4
      assert(hint.border.end[0] == 0 && hint.border.end[1] == 0);
    22
    4
      assert(adim[0] == bdim[0]);
    23
    4
      assert(adim[1] == bdim[1]);
    24
    4
      assert(hint.stride.dim[0] <= 1 && hint.stride.dim[1] <= 1);
    25
    4
      ccv_dense_matrix_t am = ccv_dense_matrix(adim[0] * adim[1], adim[2], CCV_32F | CCV_C1, a->data.u8, 0);
    26
    4
      ccv_dense_matrix_t bm = ccv_dense_matrix(bdim[0] * bdim[1], bdim[2], CCV_32F | CCV_C1, b->data.u8, 0);
    27
      // copy bias into each row.
    28
    4
      int i;
    29
    4
      if (bias)
    30
    104
        for (i = 0; 4i < bm.rows; i++100)
    31
    100
          memcpy(bm.data.f32 + i * bdim[2], bias->data.f32, sizeof(float) * bdim[2]);
    32
    4
      ccv_dense_matrix_t* dbm = &bm;
    33
    4
      ccv_dense_matrix_t wm = ccv_dense_matrix(bdim[2], adim[2], CCV_32F | CCV_C1, w->data.u8, 0);
    34
    4
      if (bias)
    35
    4
        ccv_gemm(&am, &wm, 1, dbm, 1, CCV_B_TRANSPOSE, (ccv_matrix_t**)&dbm, 0); // supply b as matrix C is allowed
    36
    0
      else
    37
    0
        ccv_gemm(&am, &wm, 1, 0, 0, CCV_B_TRANSPOSE, (ccv_matrix_t**)&dbm, 0); // supply b as matrix C is allowed
    38
    4
      return CCV_NNC_EXEC_SUCCESS;
    39
    4
    }