Coverage Report

Created: 2021-04-14 04:30

/home/liu/buildslave/linux-x64-runtests/build/lib/nnc/cmd/pool/ccv_nnc_max_pool_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_max_pool_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
326
{
15
326
  assert(input_size == 1);
16
326
  const ccv_nnc_tensor_view_t* a = (ccv_nnc_tensor_view_t*)inputs[0];
17
326
  assert(output_size == 1);
18
326
  ccv_nnc_tensor_view_t* b = (ccv_nnc_tensor_view_t*)outputs[0];
19
326
  const int *dim = cmd.info.size.dim;
20
326
  int i[CCV_NNC_MAX_DIM];
21
326
  int n[CCV_NNC_MAX_DIM];
22
326
  int m[CCV_NNC_MAX_DIM];
23
326
  int j[CCV_NNC_MAX_DIM];
24
326
  int c;
25
326
  const int a_nd = ccv_nnc_tensor_nd(a->info.dim);
26
326
  assert(a_nd == CCV_NNC_MAX_DIM + 1 || a_nd == CCV_NNC_MAX_DIM + 2);
27
326
  const int* adim = (a_nd == CCV_NNC_MAX_DIM + 1) ? 
a->info.dim19
:
a->info.dim + 1307
;
28
326
  const int b_nd = ccv_nnc_tensor_nd(b->info.dim);
29
326
  assert(b_nd == CCV_NNC_MAX_DIM + 1 || b_nd == CCV_NNC_MAX_DIM + 2);
30
326
  const int* bdim = (b_nd == CCV_NNC_MAX_DIM + 1) ? 
b->info.dim19
:
b->info.dim + 1307
;
31
326
  float* ap = a->data.f32;
32
326
  const int* ainc = CCV_IS_TENSOR_VIEW(a) ? 
((a_nd == 0
CCV_NNC_MAX_DIM0
+ 1) ?
a->inc0
:
a->inc + 10
) : adim;
33
326
  float* bp = b->data.f32;
34
326
  const int* binc = CCV_IS_TENSOR_VIEW(b) ? 
((b_nd == 0
CCV_NNC_MAX_DIM0
+ 1) ?
b->inc0
:
b->inc + 10
) : bdim;
35
5.44k
  for (i[0] = 0; i[0] < bdim[0]; 
i[0]++5.12k
)
36
5.12k
  {
37
5.12k
    SET_BORDER_OFFSET_SIZE_FOR(0, i, hint, dim, adim, n, m);
38
108k
    for (i[1] = 0; i[1] < bdim[1]; 
i[1]++103k
)
39
103k
    {
40
103k
      SET_BORDER_OFFSET_SIZE_FOR(1, i, hint, dim, adim, n, m);
41
5.25M
      for (c = 0; c < bdim[2]; 
c++5.14M
)
42
5.14M
      {
43
5.14M
        float* apz = ap + ccv_max(i[1] * hint.stride.dim[1] - hint.border.begin[1], 0) * ainc[CCV_NNC_MAX_DIM] + c;
44
5.14M
        float v = apz[0];
45
20.5M
        for (j[0] = 0; j[0] < m[0]; 
j[0]++15.4M
)
46
15.4M
        {
47
61.7M
          for (j[1] = 0; j[1] < m[1]; 
j[1]++46.3M
)
48
46.3M
            if (apz[j[1] * ainc[CCV_NNC_MAX_DIM]] > v)
49
7.42M
              v = apz[j[1] * ainc[CCV_NNC_MAX_DIM]];
50
15.4M
          apz += ainc[CCV_NNC_MAX_DIM - 1] * ainc[CCV_NNC_MAX_DIM];
51
15.4M
        }
52
5.14M
        bp[i[1] * binc[CCV_NNC_MAX_DIM] + c] = v;
53
5.14M
      }
54
103k
    }
55
5.12k
    bp += binc[CCV_NNC_MAX_DIM - 1] * binc[CCV_NNC_MAX_DIM];
56
5.12k
    ap += ainc[CCV_NNC_MAX_DIM - 1] * ainc[CCV_NNC_MAX_DIM] * (ccv_max((i[0] + 1) * hint.stride.dim[0] - hint.border.begin[0], 0) - ccv_max(i[0] * hint.stride.dim[0] - hint.border.begin[0], 0));
57
5.12k
  }
58
326
  return CCV_NNC_EXEC_SUCCESS;
59
326
}
60
61
static int _ccv_nnc_max_pool_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)
62
369
{
63
369
  assert(input_size == 3);
64
369
  const ccv_nnc_tensor_view_t* g = (ccv_nnc_tensor_view_t*)inputs[0]; // gradients
65
369
  const ccv_nnc_tensor_view_t* a = (ccv_nnc_tensor_view_t*)inputs[1];
66
369
  const ccv_nnc_tensor_view_t* b = (ccv_nnc_tensor_view_t*)inputs[2];
67
369
  assert(output_size == 1);
68
369
  ccv_nnc_tensor_view_t* h = (ccv_nnc_tensor_view_t*)outputs[0];
69
369
  const int *dim = cmd.info.size.dim;
70
369
  int i[CCV_NNC_MAX_DIM];
71
369
  int n[CCV_NNC_MAX_DIM];
72
369
  int m[CCV_NNC_MAX_DIM];
73
369
  int j[CCV_NNC_MAX_DIM];
74
369
  int c;
75
369
  const int a_nd = ccv_nnc_tensor_nd(a->info.dim);
76
369
  assert(a_nd == CCV_NNC_MAX_DIM + 1 || a_nd == CCV_NNC_MAX_DIM + 2);
77
369
  const int* adim = (a_nd == CCV_NNC_MAX_DIM + 1) ? 
a->info.dim2
:
a->info.dim + 1367
;
78
369
  const int b_nd = ccv_nnc_tensor_nd(b->info.dim);
79
369
  assert(b_nd == CCV_NNC_MAX_DIM + 1 || b_nd == CCV_NNC_MAX_DIM + 2);
80
369
  const int* bdim = (b_nd == CCV_NNC_MAX_DIM + 1) ? 
b->info.dim2
:
b->info.dim + 1367
;
81
369
  const int g_nd = ccv_nnc_tensor_nd(g->info.dim);
82
369
  assert(g_nd == CCV_NNC_MAX_DIM + 1 || g_nd == CCV_NNC_MAX_DIM + 2);
83
369
  const int* gdim = (g_nd == CCV_NNC_MAX_DIM + 1) ? 
g->info.dim2
:
g->info.dim + 1367
;
84
369
  const int h_nd = ccv_nnc_tensor_nd(h->info.dim);
85
369
  assert(h_nd == CCV_NNC_MAX_DIM + 1 || h_nd == CCV_NNC_MAX_DIM + 2);
86
369
  const int* hdim = (h_nd == CCV_NNC_MAX_DIM + 1) ? 
h->info.dim2
:
h->info.dim + 1367
;
87
369
  float* ap = a->data.f32;
88
369
  const int* ainc = CCV_IS_TENSOR_VIEW(a) ? 
((a_nd == 0
CCV_NNC_MAX_DIM0
+ 1) ?
a->inc0
:
a->inc + 10
) : adim;
89
369
  float* bp = b->data.f32;
90
369
  const int* binc = CCV_IS_TENSOR_VIEW(b) ? 
((b_nd == 0
CCV_NNC_MAX_DIM0
+ 1) ?
b->inc0
:
b->inc + 10
) : bdim;
91
369
  float* gp = g->data.f32;
92
369
  const int* ginc = CCV_IS_TENSOR_VIEW(g) ? 
((g_nd == 0
CCV_NNC_MAX_DIM0
+ 1) ?
g->inc0
:
g->inc + 10
) : gdim;
93
369
  float* hp = h->data.f32;
94
369
  const int* hinc = CCV_IS_TENSOR_VIEW(h) ? 
((h_nd == 0
CCV_NNC_MAX_DIM0
+ 1) ?
h->inc0
:
h->inc + 10
) : hdim;
95
1.84k
  for (c = 0; c < CCV_NNC_MAX_DIM_ALLOC; 
c++1.47k
)
96
1.84k
  {
97
1.84k
    assert(a->info.dim[c] == h->info.dim[c]);
98
1.84k
    if (a->info.dim[c] == 0 || 
h->info.dim[c] == 01.47k
)
99
369
      break;
100
1.84k
  }
101
1.84k
  
for (c = 0; 369
c < CCV_NNC_MAX_DIM_ALLOC;
c++1.47k
)
102
1.84k
  {
103
1.84k
    assert(b->info.dim[c] == g->info.dim[c]);
104
1.84k
    if (b->info.dim[c] == 0 || 
g->info.dim[c] == 01.47k
)
105
369
      break;
106
1.84k
  }
107
369
  ccv_nnc_tensor_zero(h);
108
369
  // Using b->info.dim and a->info.dim directly because they equal to g->info.dim and h->info.dim
109
5.88k
  for (i[0] = 0; i[0] < bdim[0]; 
i[0]++5.51k
)
110
5.51k
  {
111
5.51k
    SET_BORDER_OFFSET_SIZE_FOR(0, i, hint, dim, adim, n, m);
112
88.1k
    for (i[1] = 0; i[1] < bdim[1]; 
i[1]++82.5k
)
113
82.5k
    {
114
82.5k
      SET_BORDER_OFFSET_SIZE_FOR(1, i, hint, dim, adim, n, m);
115
2.72M
      for (c = 0; c < bdim[CCV_NNC_MAX_DIM]; 
c++2.64M
)
116
2.64M
      {
117
2.64M
        float* apz = ap + ccv_max(i[1] * hint.stride.dim[1] - hint.border.begin[1], 0) * ainc[CCV_NNC_MAX_DIM] + c;
118
2.64M
        float* hpz = hp + ccv_max(i[1] * hint.stride.dim[1] - hint.border.begin[1], 0) * hinc[CCV_NNC_MAX_DIM] + c;
119
2.64M
        float v = bp[i[1] * binc[CCV_NNC_MAX_DIM] + c];
120
2.64M
        float u = gp[i[1] * ginc[CCV_NNC_MAX_DIM] + c];
121
10.5M
        for (j[0] = 0; j[0] < m[0]; 
j[0]++7.92M
)
122
7.92M
        {
123
31.7M
          for (j[1] = 0; j[1] < m[1]; 
j[1]++23.7M
)
124
23.7M
            if (apz[j[1] * ainc[CCV_NNC_MAX_DIM]] == v)
125
2.65M
              hpz[j[1] * hinc[CCV_NNC_MAX_DIM]] += u;
126
7.92M
          apz += ainc[CCV_NNC_MAX_DIM - 1] * ainc[CCV_NNC_MAX_DIM];
127
7.92M
          hpz += hinc[CCV_NNC_MAX_DIM - 1] * hinc[CCV_NNC_MAX_DIM];
128
7.92M
        }
129
2.64M
      }
130
82.5k
    }
131
5.51k
    gp += ginc[CCV_NNC_MAX_DIM - 1] * ginc[CCV_NNC_MAX_DIM];
132
5.51k
    bp += binc[CCV_NNC_MAX_DIM - 1] * binc[CCV_NNC_MAX_DIM];
133
5.51k
    ap += ainc[CCV_NNC_MAX_DIM - 1] * ainc[CCV_NNC_MAX_DIM] * (ccv_max((i[0] + 1) * hint.stride.dim[0] - hint.border.begin[0], 0) - ccv_max(i[0] * hint.stride.dim[0] - hint.border.begin[0], 0));
134
5.51k
    hp += hinc[CCV_NNC_MAX_DIM - 1] * hinc[CCV_NNC_MAX_DIM] * (ccv_max((i[0] + 1) * hint.stride.dim[0] - hint.border.begin[0], 0) - ccv_max(i[0] * hint.stride.dim[0] - hint.border.begin[0], 0));
135
5.51k
  }
136
369
  return CCV_NNC_EXEC_SUCCESS;
137
369
}
138
139
REGISTER_COMMAND_BACKEND(CCV_NNC_MAX_POOL_FORWARD, CCV_NNC_BACKEND_CPU_REF)(ccv_nnc_cmd_backend_registry_t* const registry)
140
1
{
141
1
  registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC;
142
1
  registry->tensor_datatypes = CCV_32F;
143
1
  registry->tensor_memory = CCV_TENSOR_CPU_MEMORY;
144
1
  registry->algorithms = 1;
145
1
  registry->exec = _ccv_nnc_max_pool_forw;
146
1
}
147
148
REGISTER_COMMAND_BACKEND(CCV_NNC_MAX_POOL_BACKWARD, CCV_NNC_BACKEND_CPU_REF)(ccv_nnc_cmd_backend_registry_t* const registry)
149
1
{
150
1
  registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC;
151
1
  registry->tensor_datatypes = CCV_32F;
152
1
  registry->tensor_memory = CCV_TENSOR_CPU_MEMORY;
153
1
  registry->algorithms = 1;
154
1
  registry->exec = _ccv_nnc_max_pool_back;
155
1
}