## Coverage Report

#### Created: 2026-04-14 19:45

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

    /home/liu/actions-runner/_work/ccv/ccv/lib/nnc/cmd/swish/ccv_nnc_swish_cpu_ref.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
    #ifdef USE_OPENMP
    7
    #include <omp.h>
    8
    #endif
    9
    #ifdef USE_DISPATCH
    10
    #include <dispatch/dispatch.h>
    11
    #endif
    12
    13
    static int _ccv_nnc_swish_forw(const ccv_nnc_cmd_t cmd, const ccv_nnc_hint_t hint, const int flags, ccv_nnc_tensor_t* const* const inputs, const int input_size, ccv_nnc_tensor_t* const* const outputs, const int output_size, ccv_nnc_stream_context_t* const stream_context)
    14
    8
    {
    15
    8
      assert(input_size == 1);
    16
    8
      const ccv_nnc_tensor_t* a = inputs[0];
    17
    8
      assert(CCV_IS_TENSOR_CONTIGUOUS(a));
    18
    8
      assert(output_size == 1);
    19
    8
      ccv_nnc_tensor_t* b = outputs[0];
    20
    8
      assert(CCV_IS_TENSOR_CONTIGUOUS(b));
    21
    8
      const int count = ccv_nnc_tensor_count(a->info);
    22
    8
      int i;
    23
    21
      for (i = 0; i < CCV_NNC_MAX_DIM_ALLOC && a->info.dim[i] > 0; i++13)
    24
    13
      {
    25
    13
        assert(a->info.dim[i] == b->info.dim[i]);
    26
    13
      }
    27
    8
      const float beta = cmd.info.swish.beta;
    28
    8
      float* ap = a->data.f32;
    29
    8
      float* bp = b->data.f32;
    30
    3.51k
      for (i = 0; i < count; i++3.50k)
    31
    3.50k
      {
    32
    3.50k
        const float x = ap[i];
    33
    3.50k
        const float y = 1. / (1. + exp(-beta * x));
    34
    3.50k
        bp[i] = x * y;
    35
    3.50k
      }
    36
    8
      return CCV_NNC_EXEC_SUCCESS;
    37
    8
    }
    38
    39
    static int _ccv_nnc_swish_back(const ccv_nnc_cmd_t cmd, const ccv_nnc_hint_t hint, const int flags, ccv_nnc_tensor_t* const* const inputs, const int input_size, ccv_nnc_tensor_t* const* const outputs, const int output_size, ccv_nnc_stream_context_t* const stream_context)
    40
    6
    {
    41
    6
      assert(input_size == 3);
    42
    6
      const ccv_nnc_tensor_t* g = inputs[0]; // gradient
    43
    6
      assert(CCV_IS_TENSOR_CONTIGUOUS(g));
    44
    6
      const ccv_nnc_tensor_t* a = inputs[1];
    45
    6
      assert(CCV_IS_TENSOR_CONTIGUOUS(a));
    46
    6
      assert(output_size == 1);
    47
    6
      ccv_nnc_tensor_t* h = outputs[0];
    48
    6
      assert(CCV_IS_TENSOR_CONTIGUOUS(h));
    49
    6
      const int count = ccv_nnc_tensor_count(g->info);
    50
    6
      int i;
    51
    15
      for (i = 0; i < CCV_NNC_MAX_DIM_ALLOC && g->info.dim[i] > 0; i++9)
    52
    9
      {
    53
    9
        assert(a->info.dim[i] == g->info.dim[i]);
    54
    9
        assert(g->info.dim[i] == h->info.dim[i]);
    55
    9
      }
    56
    6
      const float beta = cmd.info.swish.beta;
    57
    6
      float* ap = a->data.f32;
    58
    6
      float* gp = g->data.f32;
    59
    6
      float* hp = h->data.f32;
    60
      /* d/dx (x * sigmoid(beta * x)) = sigmoid(beta * x) + beta * x * sigmoid(beta * x) * (1 - sigmoid(beta * x)). */
    61
    3.11k
      for (i = 0; i < count; i++3.10k)
    62
    3.10k
      {
    63
    3.10k
        const float x = ap[i];
    64
    3.10k
        const float y = 1. / (1. + exp(-beta * x));
    65
    3.10k
        const float y2 = y * y;
    66
    3.10k
        hp[i] = gp[i] * (beta * x * (y - y2) + y);
    67
    3.10k
      }
    68
    6
      return CCV_NNC_EXEC_SUCCESS;
    69
    6
    }
    70
    71
    REGISTER_COMMAND_BACKEND(CCV_NNC_SWISH_FORWARD, CCV_NNC_BACKEND_CPU_REF)(ccv_nnc_cmd_backend_registry_t* const registry)
    72
    1
    {
    73
    1
      registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC | CCV_TENSOR_FORMAT_NCHW | CCV_TENSOR_FORMAT_CHWN;
    74
    1
      registry->tensor_datatypes = CCV_32F;
    75
    1
      registry->tensor_memory = CCV_TENSOR_CPU_MEMORY;
    76
    1
      registry->algorithms = 1;
    77
    1
      registry->exec = _ccv_nnc_swish_forw;
    78
    1
    }
    79
    80
    REGISTER_COMMAND_BACKEND(CCV_NNC_SWISH_BACKWARD, CCV_NNC_BACKEND_CPU_REF)(ccv_nnc_cmd_backend_registry_t* const registry)
    81
    1
    {
    82
    1
      registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC | CCV_TENSOR_FORMAT_NCHW | CCV_TENSOR_FORMAT_CHWN;
    83
    1
      registry->tensor_datatypes = CCV_32F;
    84
    1
      registry->tensor_memory = CCV_TENSOR_CPU_MEMORY;
    85
    1
      registry->algorithms = 1;
    86
    1
      registry->exec = _ccv_nnc_swish_back;
    87
    1
    }