Coverage Report

Created: 2019-07-03 22:50

/home/liu/buildslave/linux-x64-runtests/build/lib/nnc/cmd/ew/ccv_nnc_ew.c
Line
Count
Source (jump to first uncovered line)
1
#include <ccv.h>
2
#include <nnc/ccv_nnc.h>
3
#include <nnc/ccv_nnc_internal.h>
4
5
static int _ccv_nnc_arbitary_inplace(const int input_idx, const int input_size, const int output_idx, const int output_size)
6
2.42k
{
7
2.42k
  return 1;
8
2.42k
}
9
10
static int _ccv_nnc_ewsum_forw_bitmask(const int input_size, const int output_size, const uint64_t* const input_bitmasks, const int input_bitmask_size, const uint64_t* const output_bitmasks, const int output_bitmask_size)
11
88
{
12
88
  if (output_size == 1 && output_bitmasks[0] == 1)
13
88
  {
14
88
    int i, j, flag = 0;
15
88
    int input_bitcount = 0;
16
144
    for (i = 0; i < input_bitmask_size; 
i++56
)
17
88
    {
18
184
      for (j = 0; j < 64; 
j++96
)
19
184
        if (input_bitmasks[i] & (uint64_t)1 << j)
20
96
        {
21
96
          if (flag)
22
0
            return 0;
23
88
        } else
24
88
          break;
25
88
      input_bitcount += j;
26
88
      // Trailing zero even if it is not the end of input_bitmask_size, mark flag,
27
88
      // if we encounter additional 1, return invalid.
28
88
      if (j < 64)
29
88
        flag = 1;
30
88
      // Always like 1111100000, no 1110010101
31
3.61k
      for (; j < 64; 
j++3.52k
)
32
3.55k
        if (input_bitmasks[i] & (uint64_t)1 << j)
33
32
          return 0;
34
88
    }
35
88
    
return input_size == input_bitcount56
;
36
0
  }
37
0
  return 0;
38
0
}
39
40
static int _ccv_nnc_ewsum_back_bitmask(const int input_size, const int output_size, const uint64_t* const input_bitmasks, const int input_bitmask_size, const uint64_t* const output_bitmasks, const int output_bitmask_size)
41
103
{
42
103
  if (input_size >= 1 && (input_bitmasks[0] & 1u) == 1u)
43
91
  {
44
91
    int i, j, flag = 0;
45
91
    int output_bitcount = 0;
46
178
    for (i = 0; i < output_bitmask_size; 
i++87
)
47
91
    {
48
264
      for (j = 0; j < 64; 
j++173
)
49
264
        if (output_bitmasks[i] & (uint64_t)1 << j)
50
173
        {
51
173
          if (flag)
52
0
            return 0;
53
91
        } else
54
91
          break;
55
91
      output_bitcount += j;
56
91
      // Trailing zero even if it is not the end of input_bitmask_size, mark flag,
57
91
      // if we encounter additional 1, return invalid.
58
91
      if (j < 64)
59
91
        flag = 1;
60
91
      // Always like 1111100000, no 1110010101
61
5.49k
      for (; j < 64; 
j++5.39k
)
62
5.40k
        if (output_bitmasks[i] & (uint64_t)1 << j)
63
4
          return 0;
64
91
    }
65
91
    
return output_size == output_bitcount87
;
66
12
  }
67
12
  return 0;
68
12
}
69
70
REGISTER_COMMAND(CCV_NNC_EWSUM_FORWARD)(ccv_nnc_cmd_registry_t* const registry)
71
  FIND_BACKEND(ccv_nnc_ew_cpu_ref.c, gpu/ccv_nnc_ew_gpu_cudnn.cu)
72
1
{
73
1
  registry->bitmask = _ccv_nnc_ewsum_forw_bitmask;
74
1
  registry->tensor_auto = ccv_nnc_hint_tensor_auto_forward_from_inputs;
75
1
  registry->allow_inplace = _ccv_nnc_arbitary_inplace;
76
1
}
77
78
REGISTER_COMMAND(CCV_NNC_EWSUM_BACKWARD)(ccv_nnc_cmd_registry_t* const registry)
79
  FIND_BACKEND(ccv_nnc_ew_cpu_ref.c, gpu/ccv_nnc_ew_gpu_cudnn.cu)
80
1
{
81
1
  registry->flags = CCV_NNC_CMD_ATTR_PASSTHROUGH | CCV_NNC_CMD_ATTR_NULL_IS_ONES;
82
1
  registry->bitmask = _ccv_nnc_ewsum_back_bitmask;
83
1
  registry->tensor_auto = ccv_nnc_hint_tensor_auto_backward_from_gradient;
84
1
  registry->allow_inplace = _ccv_nnc_arbitary_inplace;
85
1
}
86
87
//@REGISTER_EASY_COMMAND_MACRO(CCV_NNC_EWSUM_FORWARD)
88
#define CMD_EWSUM_FORWARD() ccv_nnc_cmd(CCV_NNC_EWSUM_FORWARD, 0, ccv_nnc_cmd_auto, 0)
89
//@REGISTER_EASY_COMMAND_MACRO(CCV_NNC_EWSUM_BACKWARD)
90
#define CMD_EWSUM_BACKWARD() ccv_nnc_cmd(CCV_NNC_EWSUM_BACKWARD, 0, ccv_nnc_cmd_auto, 0)
91
92
static int _ccv_nnc_ewprod_forw_bitmask(const int input_size, const int output_size, const uint64_t* const input_bitmasks, const int input_bitmask_size, const uint64_t* const output_bitmasks, const int output_bitmask_size)
93
36
{
94
36
  if (output_size == 1 && output_bitmasks[0] == 1)
95
36
  {
96
36
    int i, j, flag = 0;
97
36
    int input_bitcount = 0;
98
60
    for (i = 0; i < input_bitmask_size; 
i++24
)
99
36
    {
100
72
      for (j = 0; j < 64; 
j++36
)
101
72
        if (input_bitmasks[i] & (uint64_t)1 << j)
102
36
        {
103
36
          if (flag)
104
0
            return 0;
105
36
        } else
106
36
          break;
107
36
      input_bitcount += j;
108
36
      // Trailing zero even if it is not the end of input_bitmask_size, mark flag,
109
36
      // if we encounter additional 1, return invalid.
110
36
      if (j < 64)
111
36
        flag = 1;
112
36
      // Always like 1111100000, no 1110010101
113
1.54k
      for (; j < 64; 
j++1.51k
)
114
1.52k
        if (input_bitmasks[i] & (uint64_t)1 << j)
115
12
          return 0;
116
36
    }
117
36
    
return input_size == input_bitcount24
;
118
0
  }
119
0
  return 0;
120
0
}
121
122
static int _ccv_nnc_ewprod_back_bitmask(const int input_size, const int output_size, const uint64_t* const input_bitmasks, const int input_bitmask_size, const uint64_t* const output_bitmasks, const int output_bitmask_size)
123
5.15k
{
124
5.15k
  int i, j;
125
5.15k
  int input_flag = 0;
126
5.15k
  int input_bitcount = 0;
127
7.22k
  for (i = 0; i < input_bitmask_size; 
i++2.06k
)
128
5.15k
  {
129
15.4k
    for (j = 0; j < 64; 
j++10.3k
)
130
15.4k
      if (input_bitmasks[i] & (uint64_t)1 << j)
131
10.3k
      {
132
10.3k
        if (input_flag)
133
0
          return 0;
134
5.15k
      } else
135
5.15k
        break;
136
5.15k
    input_bitcount += j;
137
5.15k
    if (j < 64)
138
5.15k
      input_flag = 1;
139
5.15k
    // Always like 1111100000, no 1110010101
140
133k
    for (; j < 64; 
j++128k
)
141
131k
      if (input_bitmasks[i] & (uint64_t)1 << j)
142
3.08k
        return 0;
143
5.15k
  }
144
5.15k
  int output_flag = 0;
145
2.06k
  int output_bitcount = 0;
146
4.13k
  for (i = 0; i < output_bitmask_size; 
i++2.06k
)
147
2.06k
  {
148
6.19k
    for (j = 0; j < 64; 
j++4.12k
)
149
6.19k
      if ((output_bitmasks[i] & (uint64_t)1 << j))
150
4.12k
      {
151
4.12k
        if (output_flag)
152
0
          return 0;
153
2.06k
      } else
154
2.06k
        break;
155
2.06k
    output_bitcount += j;
156
2.06k
    if (j < 64)
157
2.06k
      output_flag = 1;
158
130k
    for (; j < 64; 
j++128k
)
159
128k
      if (output_bitmasks[i] & (uint64_t)1 << j)
160
2
        return 0;
161
2.06k
  }
162
2.06k
  
if (2.06k
output_bitcount != output_size2.06k
)
163
8
    return 0;
164
2.05k
  return output_bitcount + 2 /* Gradient + Original output */ == input_bitcount;
165
2.05k
}
166
167
REGISTER_COMMAND(CCV_NNC_EWPROD_FORWARD)(ccv_nnc_cmd_registry_t* const registry)
168
  FIND_BACKEND(ccv_nnc_ew_cpu_ref.c)
169
1
{
170
1
  registry->bitmask = _ccv_nnc_ewprod_forw_bitmask;
171
1
  registry->tensor_auto = ccv_nnc_hint_tensor_auto_forward_from_inputs;
172
1
  registry->allow_inplace = _ccv_nnc_arbitary_inplace;
173
1
}
174
175
REGISTER_COMMAND(CCV_NNC_EWPROD_BACKWARD)(ccv_nnc_cmd_registry_t* const registry)
176
  FIND_BACKEND(ccv_nnc_ew_cpu_ref.c)
177
1
{
178
1
  registry->flags = CCV_NNC_CMD_ATTR_NULL_IS_ONES;
179
1
  registry->bitmask = _ccv_nnc_ewprod_back_bitmask;
180
1
  registry->tensor_auto = ccv_nnc_hint_tensor_auto_backward_from_gradient;
181
1
}
182
183
//@REGISTER_EASY_COMMAND_MACRO(CCV_NNC_EWPROD_FORWARD)
184
#define CMD_EWPROD_FORWARD() ccv_nnc_cmd(CCV_NNC_EWPROD_FORWARD, 0, ccv_nnc_cmd_auto, 0)
185
//@REGISTER_EASY_COMMAND_MACRO(CCV_NNC_EWPROD_BACKWARD)
186
#define CMD_EWPROD_BACKWARD() ccv_nnc_cmd(CCV_NNC_EWPROD_BACKWARD, 0, ccv_nnc_cmd_auto, 0)
187
188
static int _ccv_nnc_ewdiv_forw_bitmask(const int input_size, const int output_size, const uint64_t* const input_bitmasks, const int input_bitmask_size, const uint64_t* const output_bitmasks, const int output_bitmask_size)
189
0
{
190
0
  if ((input_bitmasks[0] & 3u) == ((1u << 0) | (1u << 1)) && output_bitmasks[0] == 1u)
191
0
    return 1;
192
0
  // Nominator can be null (meaning 1).
193
0
  if ((input_bitmasks[0] & 3u) == ((0u << 0) | (1u << 1)) && output_bitmasks[0] == 1u)
194
0
    return 1;
195
0
  return 0;
196
0
}
197
198
static int _ccv_nnc_ewdiv_back_bitmask(const int input_size, const int output_size, const uint64_t* const input_bitmasks, const int input_bitmask_size, const uint64_t* const output_bitmasks, const int output_bitmask_size)
199
17
{
200
17
  // We don't need to know the original output.
201
17
  if ((input_bitmasks[0] & (15u & ~((uint64_t)1u << 1))) == ((1u << 0) | (0u << 1) | (1u << 2) | (1u << 3)) && 
output_bitmasks[0] == ((1u << 0) | (1u << 1))5
)
202
1
    return 1;
203
16
  if ((input_bitmasks[0] & (15u & ~((uint64_t)1u << 1))) == ((1u << 0) | (0u << 1) | (1u << 2) | (0u << 3)) && 
output_bitmasks[0] == ((1u << 0) | (0u << 1))4
)
204
0
    return 1;
205
16
  if ((input_bitmasks[0] & (15u & ~((uint64_t)1u << 1))) == ((1u << 0) | (0u << 1) | (1u << 2) | (1u << 3)) && 
output_bitmasks[0] == ((0u << 0) | (1u << 1))4
)
206
4
    return 1;
207
12
  return 0;
208
12
}
209
210
REGISTER_COMMAND(CCV_NNC_EWDIV_FORWARD)(ccv_nnc_cmd_registry_t* const registry)
211
  FIND_BACKEND(ccv_nnc_ew_cpu_ref.c)
212
1
{
213
1
  registry->flags = CCV_NNC_CMD_ATTR_NULL_IS_ONES;
214
1
  registry->bitmask = _ccv_nnc_ewdiv_forw_bitmask;
215
1
  registry->tensor_auto = ccv_nnc_hint_tensor_auto_forward_from_inputs;
216
1
  registry->allow_inplace = _ccv_nnc_arbitary_inplace;
217
1
}
218
219
REGISTER_COMMAND(CCV_NNC_EWDIV_BACKWARD)(ccv_nnc_cmd_registry_t* const registry)
220
  FIND_BACKEND(ccv_nnc_ew_cpu_ref.c)
221
1
{
222
1
  registry->flags = CCV_NNC_CMD_ATTR_NULL_IS_ONES;
223
1
  registry->bitmask = _ccv_nnc_ewdiv_back_bitmask;
224
1
  registry->tensor_auto = ccv_nnc_hint_tensor_auto_backward_from_gradient;
225
1
}
226
227
//@REGISTER_EASY_COMMAND_MACRO(CCV_NNC_EWDIV_FORWARD)
228
#define CMD_EWDIV_FORWARD() ccv_nnc_cmd(CCV_NNC_EWDIV_FORWARD, 0, ccv_nnc_cmd_auto, 0)
229
//@REGISTER_EASY_COMMAND_MACRO(CCV_NNC_EWDIV_BACKWARD)
230
#define CMD_EWDIV_BACKWARD() ccv_nnc_cmd(CCV_NNC_EWDIV_BACKWARD, 0, ccv_nnc_cmd_auto, 0)
231
232
static int _ccv_nnc_ewexp_forw_bitmask(const int input_size, const int output_size, const uint64_t* const input_bitmasks, const int input_bitmask_size, const uint64_t* const output_bitmasks, const int output_bitmask_size)
233
0
{
234
0
  if ((input_bitmasks[0] & 1u) == 1u && output_bitmasks[0] == 1u)
235
0
    return 1;
236
0
  return 0;
237
0
}
238
239
static int _ccv_nnc_ewexp_back_bitmask(const int input_size, const int output_size, const uint64_t* const input_bitmasks, const int input_bitmask_size, const uint64_t* const output_bitmasks, const int output_bitmask_size)
240
12
{
241
12
  // We don't care about the original input.
242
12
  if ((input_bitmasks[0] & (7u & ~((uint64_t)1u << 1))) == ((1u << 0) | (0u << 1) | (1u << 2)) && 
output_bitmasks[0] == 1u4
)
243
4
    return 1;
244
8
  return 0;
245
8
}
246
247
REGISTER_COMMAND(CCV_NNC_EWEXP_FORWARD)(ccv_nnc_cmd_registry_t* const registry)
248
  FIND_BACKEND(ccv_nnc_ew_cpu_ref.c)
249
1
{
250
1
  registry->bitmask = _ccv_nnc_ewexp_forw_bitmask;
251
1
  registry->tensor_auto = ccv_nnc_hint_tensor_auto_forward_from_inputs;
252
1
  registry->allow_inplace = _ccv_nnc_arbitary_inplace;
253
1
}
254
255
REGISTER_COMMAND(CCV_NNC_EWEXP_BACKWARD)(ccv_nnc_cmd_registry_t* const registry)
256
  FIND_BACKEND(ccv_nnc_ew_cpu_ref.c)
257
1
{
258
1
  registry->flags = CCV_NNC_CMD_ATTR_NULL_IS_ONES;
259
1
  registry->bitmask = _ccv_nnc_ewexp_back_bitmask;
260
1
  registry->tensor_auto = ccv_nnc_hint_tensor_auto_backward_from_gradient;
261
1
  registry->allow_inplace = _ccv_nnc_arbitary_inplace;
262
1
}
263
264
//@REGISTER_EASY_COMMAND_MACRO(CCV_NNC_EWEXP_FORWARD)
265
#define CMD_EWEXP_FORWARD() ccv_nnc_cmd(CCV_NNC_EWEXP_FORWARD, 0, ccv_nnc_cmd_auto, 0)
266
//@REGISTER_EASY_COMMAND_MACRO(CCV_NNC_EWEXP_BACKWARD)
267
#define CMD_EWEXP_BACKWARD() ccv_nnc_cmd(CCV_NNC_EWEXP_BACKWARD, 0, ccv_nnc_cmd_auto, 0)
268
269
static int _ccv_nnc_ewlog_forw_bitmask(const int input_size, const int output_size, const uint64_t* const input_bitmasks, const int input_bitmask_size, const uint64_t* const output_bitmasks, const int output_bitmask_size)
270
0
{
271
0
  if ((input_bitmasks[0] & 1u) == 1u && output_bitmasks[0] == 1u)
272
0
    return 1;
273
0
  return 0;
274
0
}
275
276
static int _ccv_nnc_ewlog_back_bitmask(const int input_size, const int output_size, const uint64_t* const input_bitmasks, const int input_bitmask_size, const uint64_t* const output_bitmasks, const int output_bitmask_size)
277
50
{
278
50
  // We don't care about the original output.
279
50
  if ((input_bitmasks[0] & 3u) == 3u && 
output_bitmasks[0] == 1u18
)
280
18
    return 1;
281
32
  return 0;
282
32
}
283
284
REGISTER_COMMAND(CCV_NNC_EWLOG_FORWARD)(ccv_nnc_cmd_registry_t* const registry)
285
  FIND_BACKEND(ccv_nnc_ew_cpu_ref.c)
286
1
{
287
1
  registry->bitmask = _ccv_nnc_ewlog_forw_bitmask;
288
1
  registry->tensor_auto = ccv_nnc_hint_tensor_auto_forward_from_inputs;
289
1
  registry->allow_inplace = _ccv_nnc_arbitary_inplace;
290
1
}
291
292
REGISTER_COMMAND(CCV_NNC_EWLOG_BACKWARD)(ccv_nnc_cmd_registry_t* const registry)
293
  FIND_BACKEND(ccv_nnc_ew_cpu_ref.c)
294
1
{
295
1
  registry->flags = CCV_NNC_CMD_ATTR_NULL_IS_ONES;
296
1
  registry->bitmask = _ccv_nnc_ewlog_back_bitmask;
297
1
  registry->tensor_auto = ccv_nnc_hint_tensor_auto_backward_from_gradient;
298
1
  registry->allow_inplace = _ccv_nnc_arbitary_inplace;
299
1
}
300
301
//@REGISTER_EASY_COMMAND_MACRO(CCV_NNC_EWLOG_FORWARD)
302
#define CMD_EWLOG_FORWARD() ccv_nnc_cmd(CCV_NNC_EWLOG_FORWARD, 0, ccv_nnc_cmd_auto, 0)
303
//@REGISTER_EASY_COMMAND_MACRO(CCV_NNC_EWLOG_BACKWARD)
304
#define CMD_EWLOG_BACKWARD() ccv_nnc_cmd(CCV_NNC_EWLOG_BACKWARD, 0, ccv_nnc_cmd_auto, 0)
305
306
static int _ccv_nnc_ewsqrt_forw_bitmask(const int input_size, const int output_size, const uint64_t* const input_bitmasks, const int input_bitmask_size, const uint64_t* const output_bitmasks, const int output_bitmask_size)
307
0
{
308
0
  if ((input_bitmasks[0] & 1u) == 1u && output_bitmasks[0] == 1u)
309
0
    return 1;
310
0
  return 0;
311
0
}
312
313
static int _ccv_nnc_ewsqrt_back_bitmask(const int input_size, const int output_size, const uint64_t* const input_bitmasks, const int input_bitmask_size, const uint64_t* const output_bitmasks, const int output_bitmask_size)
314
6
{
315
6
  // We don't care about the original input.
316
6
  if ((input_bitmasks[0] & (7u & ~((uint64_t)1u << 1))) == ((1u << 0) | (0u << 1) | (1u << 2)) && 
output_bitmasks[0] == 1u2
)
317
2
    return 1;
318
4
  return 0;
319
4
}
320
321
REGISTER_COMMAND(CCV_NNC_EWSQRT_FORWARD)(ccv_nnc_cmd_registry_t* const registry)
322
  FIND_BACKEND(ccv_nnc_ew_cpu_ref.c)
323
1
{
324
1
  registry->bitmask = _ccv_nnc_ewsqrt_forw_bitmask;
325
1
  registry->tensor_auto = ccv_nnc_hint_tensor_auto_forward_from_inputs;
326
1
  registry->allow_inplace = _ccv_nnc_arbitary_inplace;
327
1
}
328
329
REGISTER_COMMAND(CCV_NNC_EWSQRT_BACKWARD)(ccv_nnc_cmd_registry_t* const registry)
330
  FIND_BACKEND(ccv_nnc_ew_cpu_ref.c)
331
1
{
332
1
  registry->flags = CCV_NNC_CMD_ATTR_NULL_IS_ONES;
333
1
  registry->bitmask = _ccv_nnc_ewsqrt_back_bitmask;
334
1
  registry->tensor_auto = ccv_nnc_hint_tensor_auto_backward_from_gradient;
335
1
  registry->allow_inplace = _ccv_nnc_arbitary_inplace;
336
1
}
337
338
//@REGISTER_EASY_COMMAND_MACRO(CCV_NNC_EWSQRT_FORWARD)
339
#define CMD_EWSQRT_FORWARD() ccv_nnc_cmd(CCV_NNC_EWSQRT_FORWARD, 0, ccv_nnc_cmd_auto, 0)
340
//@REGISTER_EASY_COMMAND_MACRO(CCV_NNC_EWSQRT_BACKWARD)
341
#define CMD_EWSQRT_BACKWARD() ccv_nnc_cmd(CCV_NNC_EWSQRT_BACKWARD, 0, ccv_nnc_cmd_auto, 0)