Coverage Report

Created: 2019-07-03 22:50

/home/liu/buildslave/linux-x64-runtests/build/lib/nnc/cmd/reduce/ccv_nnc_reduce_max_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
// Shared methods.
14
#include "../_ccv_nnc_cpu_ref.h"
15
16
static int _ccv_nnc_reduce_max_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)
17
1
{
18
1
  assert(input_size == 1);
19
1
  ccv_nnc_tensor_view_t* const a = (ccv_nnc_tensor_view_t*)inputs[0];
20
1
  ccv_nnc_tensor_view_t* const b = (ccv_nnc_tensor_view_t*)outputs[0];
21
1
  assert(a->info.dim[CCV_NNC_MAX_DIM + 2] == 0);
22
1
  assert(b->info.dim[CCV_NNC_MAX_DIM + 2] == 0);
23
1
  // Assuming this is float 32.
24
1
  int adim[CCV_NNC_MAX_DIM + 2];
25
1
  int bdim[CCV_NNC_MAX_DIM + 2];
26
1
  ccv_nnc_tensor_view_get_dim(a, adim);
27
1
  ccv_nnc_tensor_view_get_dim(b, bdim);
28
1
  assert(ccv_nnc_tensor_view_check_broadcast_dim(b, adim));
29
1
  int ainc[CCV_NNC_MAX_DIM + 2];
30
1
  int binc[CCV_NNC_MAX_DIM + 2];
31
1
  assert(CCV_NNC_MAX_DIM == 2); // Need to change this logic for CCV_NNC_MAX_DIM == other number.
32
1
  ccv_nnc_tensor_view_get_inc(a, ainc);
33
1
  ccv_nnc_tensor_view_get_inc(b, binc);
34
1
  int i[CCV_NNC_MAX_DIM + 2];
35
1
  int x;
36
1
  _ccv_nnc_tensor_set_cpu_ref(b, -FLT_MAX);
37
1
  float* ap = a->data.f32;
38
1
  float* const bp = b->data.f32;
39
1
  // Non-optimal case, need to do skip if needed.
40
2
  for (i[0] = 0; i[0] < adim[0]; 
i[0]++1
)
41
1
  {
42
1
    float* const bp0 = bdim[0] == 1 ? bp : 
bp + i[0] * binc[1] * binc[2] * binc[3]0
;
43
2
    for (i[1] = 0; i[1] < adim[1]; 
i[1]++1
)
44
1
    {
45
1
      float* const bp1 = bdim[1] == 1 ? bp0 : 
bp0 + i[1] * binc[2] * binc[3]0
;
46
2
      for (i[2] = 0; i[2] < adim[2]; 
i[2]++1
)
47
1
      {
48
1
        float* const bp2 = bdim[2] == 1 ? bp1 : 
bp1 + i[2] * binc[3]0
;
49
1
        if (bdim[3] == 1)
50
1
        {
51
101
          for (x = 0; x < adim[3]; 
x++100
)
52
100
            if (ap[x] > bp2[0])
53
5
              bp2[0] = ap[x];
54
1
        } else {
55
0
          for (x = 0; x < adim[3]; x++)
56
0
            if (ap[x] > bp2[x])
57
0
              bp2[x] = ap[x];
58
0
        }
59
1
        ap += ainc[3];
60
1
      }
61
1
      ap += (ainc[2] - adim[2]) * ainc[3];
62
1
    }
63
1
    ap += (ainc[1] - adim[1]) * ainc[2] * ainc[3];
64
1
  }
65
1
  return CCV_NNC_EXEC_SUCCESS;
66
1
}
67
68
static int _ccv_nnc_reduce_max_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)
69
1
{
70
1
  if (inputs[0] == 0)
71
0
  {
72
0
    ccv_nnc_tensor_view_t* const h = (ccv_nnc_tensor_view_t*)outputs[0];
73
0
    ccv_nnc_tensor_view_t* const a = (ccv_nnc_tensor_view_t*)inputs[1];
74
0
    ccv_nnc_tensor_view_t* const b = (ccv_nnc_tensor_view_t*)inputs[2];
75
0
    assert(h->info.dim[CCV_NNC_MAX_DIM + 2] == 0);
76
0
    assert(a->info.dim[CCV_NNC_MAX_DIM + 2] == 0);
77
0
    assert(b->info.dim[CCV_NNC_MAX_DIM + 2] == 0);
78
0
    // Assuming this is float 32.
79
0
    int hdim[CCV_NNC_MAX_DIM + 2];
80
0
    int bdim[CCV_NNC_MAX_DIM + 2];
81
0
    ccv_nnc_tensor_view_get_dim(h, hdim);
82
0
    ccv_nnc_tensor_view_get_dim(b, bdim);
83
0
    assert(ccv_nnc_tensor_view_check_broadcast_dim(b, hdim));
84
0
    assert(ccv_nnc_tensor_view_check_dim(a, hdim));
85
0
    int hinc[CCV_NNC_MAX_DIM + 2];
86
0
    int ainc[CCV_NNC_MAX_DIM + 2];
87
0
    int binc[CCV_NNC_MAX_DIM + 2];
88
0
    assert(CCV_NNC_MAX_DIM == 2); // Need to change this logic for CCV_NNC_MAX_DIM == other number.
89
0
    ccv_nnc_tensor_view_get_inc(h, hinc);
90
0
    ccv_nnc_tensor_view_get_inc(a, ainc);
91
0
    ccv_nnc_tensor_view_get_inc(b, binc);
92
0
    int i[CCV_NNC_MAX_DIM + 2];
93
0
    int x;
94
0
    float* hp = h->data.f32;
95
0
    float* ap = a->data.f32;
96
0
    float* const bp = b->data.f32;
97
0
    ccv_nnc_tensor_zero(h);
98
0
    // Non-optimal case, need to do skip if needed.
99
0
    for (i[0] = 0; i[0] < hdim[0]; i[0]++)
100
0
    {
101
0
      float* const bp0 = bdim[0] == 1 ? bp : bp + i[0] * binc[1] * binc[2] * binc[3];
102
0
      for (i[1] = 0; i[1] < hdim[1]; i[1]++)
103
0
      {
104
0
        float* const bp1 = bdim[1] == 1 ? bp0 : bp0 + i[1] * binc[2] * binc[3];
105
0
        for (i[2] = 0; i[2] < hdim[2]; i[2]++)
106
0
        {
107
0
          float* const bp2 = bdim[2] == 1 ? bp1 : bp1 + i[2] * binc[3];
108
0
          if (bdim[3] == 1)
109
0
          {
110
0
            for (x = 0; x < hdim[3]; x++)
111
0
              if (ap[x] == bp2[0])
112
0
                hp[x] = 1;
113
0
          } else {
114
0
            for (x = 0; x < hdim[3]; x++)
115
0
              if (ap[x] == bp2[x])
116
0
                hp[x] = 1;
117
0
          }
118
0
          hp += hinc[3];
119
0
          ap += ainc[3];
120
0
        }
121
0
        hp += (hinc[2] - hdim[2]) * hinc[3];
122
0
        ap += (ainc[2] - hdim[2]) * ainc[3];
123
0
      }
124
0
      hp += (hinc[1] - hdim[1]) * hinc[2] * hinc[3];
125
0
      ap += (ainc[1] - hdim[1]) * ainc[2] * ainc[3];
126
0
    }
127
0
    return CCV_NNC_EXEC_SUCCESS;
128
1
  }
129
1
  ccv_nnc_tensor_view_t* const h = (ccv_nnc_tensor_view_t*)outputs[0];
130
1
  ccv_nnc_tensor_view_t* const g = (ccv_nnc_tensor_view_t*)inputs[0];
131
1
  ccv_nnc_tensor_view_t* const a = (ccv_nnc_tensor_view_t*)inputs[1];
132
1
  ccv_nnc_tensor_view_t* const b = (ccv_nnc_tensor_view_t*)inputs[2];
133
1
  assert(h->info.dim[CCV_NNC_MAX_DIM + 2] == 0);
134
1
  assert(g->info.dim[CCV_NNC_MAX_DIM + 2] == 0);
135
1
  assert(a->info.dim[CCV_NNC_MAX_DIM + 2] == 0);
136
1
  assert(b->info.dim[CCV_NNC_MAX_DIM + 2] == 0);
137
1
  // Assuming this is float 32.
138
1
  int hdim[CCV_NNC_MAX_DIM + 2];
139
1
  int gdim[CCV_NNC_MAX_DIM + 2];
140
1
  ccv_nnc_tensor_view_get_dim(h, hdim);
141
1
  ccv_nnc_tensor_view_get_dim(g, gdim);
142
1
  assert(ccv_nnc_tensor_view_check_broadcast_dim(g, hdim));
143
1
  assert(ccv_nnc_tensor_view_check_dim(a, hdim));
144
1
  assert(ccv_nnc_tensor_view_check_dim(b, gdim));
145
1
  int hinc[CCV_NNC_MAX_DIM + 2];
146
1
  int ginc[CCV_NNC_MAX_DIM + 2];
147
1
  int ainc[CCV_NNC_MAX_DIM + 2];
148
1
  int binc[CCV_NNC_MAX_DIM + 2];
149
1
  assert(CCV_NNC_MAX_DIM == 2); // Need to change this logic for CCV_NNC_MAX_DIM == other number.
150
1
  ccv_nnc_tensor_view_get_inc(h, hinc);
151
1
  ccv_nnc_tensor_view_get_inc(g, ginc);
152
1
  ccv_nnc_tensor_view_get_inc(a, ainc);
153
1
  ccv_nnc_tensor_view_get_inc(b, binc);
154
1
  int i[CCV_NNC_MAX_DIM + 2];
155
1
  int x;
156
1
  float* hp = h->data.f32;
157
1
  float* const gp = g->data.f32;
158
1
  float* ap = a->data.f32;
159
1
  float* const bp = b->data.f32;
160
1
  ccv_nnc_tensor_zero(h);
161
1
  // Non-optimal case, need to do skip if needed.
162
2
  for (i[0] = 0; i[0] < hdim[0]; 
i[0]++1
)
163
1
  {
164
1
    float* const gp0 = gdim[0] == 1 ? gp : 
gp + i[0] * ginc[1] * ginc[2] * ginc[3]0
;
165
1
    float* const bp0 = gdim[0] == 1 ? bp : 
bp + i[0] * binc[1] * binc[2] * binc[3]0
;
166
2
    for (i[1] = 0; i[1] < hdim[1]; 
i[1]++1
)
167
1
    {
168
1
      float* const gp1 = gdim[1] == 1 ? gp0 : 
gp0 + i[1] * ginc[2] * ginc[3]0
;
169
1
      float* const bp1 = gdim[1] == 1 ? bp0 : 
bp0 + i[1] * binc[2] * binc[3]0
;
170
2
      for (i[2] = 0; i[2] < hdim[2]; 
i[2]++1
)
171
1
      {
172
1
        float* const gp2 = gdim[2] == 1 ? gp1 : 
gp1 + i[2] * ginc[3]0
;
173
1
        float* const bp2 = gdim[2] == 1 ? bp1 : 
bp1 + i[2] * binc[3]0
;
174
1
        if (gdim[3] == 1)
175
1
        {
176
101
          for (x = 0; x < hdim[3]; 
x++100
)
177
100
            if (ap[x] == bp2[0])
178
1
              hp[x] = gp2[0];
179
1
        } else {
180
0
          for (x = 0; x < hdim[3]; x++)
181
0
            if (ap[x] == bp2[x])
182
0
              hp[x] = gp2[x];
183
0
        }
184
1
        hp += hinc[3];
185
1
        ap += ainc[3];
186
1
      }
187
1
      hp += (hinc[2] - hdim[2]) * hinc[3];
188
1
      ap += (ainc[2] - hdim[2]) * ainc[3];
189
1
    }
190
1
    hp += (hinc[1] - hdim[1]) * hinc[2] * hinc[3];
191
1
    ap += (ainc[1] - hdim[1]) * ainc[2] * ainc[3];
192
1
  }
193
1
  return CCV_NNC_EXEC_SUCCESS;
194
1
}
195
196
REGISTER_COMMAND_BACKEND(CCV_NNC_REDUCE_MAX_FORWARD, CCV_NNC_BACKEND_CPU_REF)(ccv_nnc_cmd_backend_registry_t* const registry)
197
1
{
198
1
  registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC | CCV_TENSOR_FORMAT_NCHW | CCV_TENSOR_FORMAT_CHWN;
199
1
  registry->tensor_datatypes = CCV_32F;
200
1
  registry->tensor_memory = CCV_TENSOR_CPU_MEMORY;
201
1
  registry->algorithms = 1;
202
1
  registry->exec = _ccv_nnc_reduce_max_forw;
203
1
}
204
205
REGISTER_COMMAND_BACKEND(CCV_NNC_REDUCE_MAX_BACKWARD, CCV_NNC_BACKEND_CPU_REF)(ccv_nnc_cmd_backend_registry_t* const registry)
206
1
{
207
1
  registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC | CCV_TENSOR_FORMAT_NCHW | CCV_TENSOR_FORMAT_CHWN;
208
1
  registry->tensor_datatypes = CCV_32F;
209
1
  registry->tensor_memory = CCV_TENSOR_CPU_MEMORY;
210
1
  registry->algorithms = 1;
211
1
  registry->exec = _ccv_nnc_reduce_max_back;
212
1
}