Coverage Report

Created: 2021-04-07 03:47

/home/liu/buildslave/linux-x64-runtests/build/lib/nnc/cmd/softmax/ccv_nnc_softmax_cpu_ref.c
Line
Count
Source (jump to first uncovered line)
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_softmax_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
505
{
15
505
  assert(input_size == 1);
16
505
  const ccv_nnc_tensor_t* a = inputs[0];
17
505
  assert(!CCV_IS_TENSOR_VIEW(a));
18
505
  assert(output_size == 1);
19
505
  ccv_nnc_tensor_t* b = outputs[0];
20
505
  assert(!CCV_IS_TENSOR_VIEW(b));
21
505
  const int axis_count = ccv_nnc_tensor_nd(a->info.dim);
22
505
  const int batch_size = axis_count < 2 ? 
1498
:
a->info.dim[0]7
;
23
505
  const int count = ccv_nnc_tensor_count(a->info) / batch_size;
24
505
  int i;
25
1.01k
  for (i = 0; i < CCV_NNC_MAX_DIM_ALLOC && a->info.dim[i] > 0; 
i++514
)
26
514
    { assert(a->info.dim[i] == b->info.dim[i]); }
27
505
  parallel_for(i, batch_size) {
28
0
    int j;
29
0
    float* const ap = a->data.f32 + i * count;
30
0
    float* const bp = b->data.f32 + i * count;
31
0
    double maxval = ap[0];
32
1.29M
    for (j = 1; j < count; j++)
33
1.29M
      if (ap[j] > maxval)
34
2.47k
        maxval = ap[j];
35
0
    double sumval = 0;
36
1.29M
    for (j = 0; j < count; j++)
37
1.29M
      sumval += (bp[j] = expf(ap[j] - maxval));
38
0
    sumval = 1.0 / sumval;
39
1.29M
    for (j = 0; j < count; j++)
40
1.29M
      bp[j] *= sumval;
41
505
  } parallel_endfor
42
505
  return CCV_NNC_EXEC_SUCCESS;
43
505
}
44
45
static int _ccv_nnc_softmax_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)
46
5
{
47
5
  assert(input_size == 3);
48
5
  assert(output_size == 1);
49
5
  const ccv_nnc_tensor_t* g = inputs[0];
50
5
  assert(!CCV_IS_TENSOR_VIEW(g));
51
5
  const ccv_nnc_tensor_t* b = inputs[2];
52
5
  assert(!CCV_IS_TENSOR_VIEW(b));
53
5
  ccv_nnc_tensor_t* h = outputs[0];
54
5
  assert(!CCV_IS_TENSOR_VIEW(h));
55
5
  const int axis_count = ccv_nnc_tensor_nd(g->info.dim);
56
5
  const int batch_size = axis_count < 2 ? 
11
:
g->info.dim[0]4
;
57
5
  const int count = ccv_nnc_tensor_count(g->info) / batch_size;
58
5
  int i;
59
14
  for (i = 0; i < CCV_NNC_MAX_DIM_ALLOC && g->info.dim[i] > 0; 
i++9
)
60
9
    { assert(g->info.dim[i] == h->info.dim[i] && h->info.dim[i] == b->info.dim[i]); }
61
5
  parallel_for(i, batch_size) {
62
0
    int j;
63
0
    float* const gp = g->data.f32 + i * count;
64
0
    float* const bp = b->data.f32 + i * count;
65
0
    float* const hp = h->data.f32 + i * count;
66
0
    float sumval = 0;
67
579
    for (j = 0; j < count; j++)
68
579
      sumval += gp[j] * bp[j];
69
536
    for (j = 0; j < count; j++)
70
536
      hp[j] = (gp[j] - sumval) * bp[j];
71
5
  } parallel_endfor
72
5
  return CCV_NNC_EXEC_SUCCESS;
73
5
}
74
75
REGISTER_COMMAND_BACKEND(CCV_NNC_SOFTMAX_FORWARD, CCV_NNC_BACKEND_CPU_REF)(ccv_nnc_cmd_backend_registry_t* const registry)
76
1
{
77
1
  registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC | CCV_TENSOR_FORMAT_NCHW;
78
1
  registry->tensor_datatypes = CCV_32F;
79
1
  registry->tensor_memory = CCV_TENSOR_CPU_MEMORY;
80
1
  registry->algorithms = 1;
81
1
  registry->exec = _ccv_nnc_softmax_forw;
82
1
}
83
84
REGISTER_COMMAND_BACKEND(CCV_NNC_SOFTMAX_BACKWARD, CCV_NNC_BACKEND_CPU_REF)(ccv_nnc_cmd_backend_registry_t* const registry)
85
1
{
86
1
  registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC | CCV_TENSOR_FORMAT_NCHW;
87
1
  registry->tensor_datatypes = CCV_32F;
88
1
  registry->tensor_memory = CCV_TENSOR_CPU_MEMORY;
89
1
  registry->algorithms = 1;
90
1
  registry->exec = _ccv_nnc_softmax_back;
91
1
}