Coverage Report

Created: 2022-08-03 23:52

/home/liu/buildslave/linux-x64-runtests/build/lib/nnc/cmd/reduce/ccv_nnc_argmax_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_argmax_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
3
{
18
3
  assert(input_size == 1);
19
3
  ccv_nnc_tensor_t* const a = inputs[0];
20
3
  assert(CCV_IS_TENSOR_CONTIGUOUS(a));
21
3
  assert(output_size == 1);
22
3
  ccv_nnc_tensor_t* const b = outputs[0];
23
3
  assert(CCV_IS_TENSOR_CONTIGUOUS(b));
24
3
  const int axis = cmd.info.reduce.axis[0];
25
3
  assert(cmd.info.reduce.count == 1);
26
3
  assert(axis >= 0);
27
3
  const int a_nd = ccv_nnc_tensor_nd(a->info.dim);
28
3
  assert(axis < a_nd);
29
3
  const int b_nd = ccv_nnc_tensor_nd(b->info.dim);
30
3
  int i, j, k;
31
9
  for (i = axis; i < a_nd; 
i++6
)
32
6
    { assert(a->info.dim[i] == (b_nd - (a_nd - i) >= 0) ? b->info.dim[b_nd - (a_nd - i)] : 1); }
33
3
  assert(1 == (b_nd - (a_nd - axis) >= 0) ? b->info.dim[b_nd - (a_nd - axis)] : 1);
34
5
  
for (i = 0; 3
i < axis;
i++2
)
35
2
    { assert(a->info.dim[i] == (b_nd - (a_nd - i) >= 0) ? b->info.dim[b_nd - (a_nd - i)] : 1); }
36
3
  const int tensor_count = ccv_nnc_tensor_count(a->info);
37
3
  const int axis_dim = a->info.dim[axis];
38
3
  int dim_after_axis = 1;
39
6
  for (i = axis + 1; i < a_nd; 
i++3
)
40
3
    dim_after_axis *= a->info.dim[i];
41
3
  const int dim_before_axis = tensor_count / axis_dim / dim_after_axis;
42
3
  assert(ccv_nnc_tensor_count(b->info) == tensor_count / axis_dim);
43
3
  const float* const ap = a->data.f32;
44
3
  assert(b->info.datatype == CCV_32F || b->info.datatype == CCV_32S);
45
3
  if (b->info.datatype == CCV_32S)
46
3
  {
47
3
    int* const bp = b->data.i32;
48
16
    for (i = 0; i < dim_before_axis; 
i++13
)
49
13
    {
50
13
      const float* const ap0 = ap + i * dim_after_axis * axis_dim;
51
13
      int* const bp0 = bp + i * dim_after_axis;
52
168
      for (j = 0; j < dim_after_axis; 
j++155
)
53
155
      {
54
155
        float max = ap0[j];
55
155
        int idx = 0;
56
462
        for (k = 1; k < axis_dim; 
k++307
)
57
307
          if (ap0[j + k * dim_after_axis] > max)
58
126
            max = ap0[j + k * dim_after_axis], idx = k;
59
155
        bp0[j] = idx;
60
155
      }
61
13
    }
62
3
  } else {
63
0
    float* const bp = b->data.f32;
64
0
    for (i = 0; i < dim_before_axis; i++)
65
0
    {
66
0
      const float* const ap0 = ap + i * dim_after_axis * axis_dim;
67
0
      float* const bp0 = bp + i * dim_after_axis;
68
0
      for (j = 0; j < dim_after_axis; j++)
69
0
      {
70
0
        float max = ap0[j];
71
0
        int idx = 0;
72
0
        for (k = 1; k < axis_dim; k++)
73
0
          if (ap0[j + k * dim_after_axis] > max)
74
0
            max = ap0[j + k * dim_after_axis], idx = k;
75
0
        bp0[j] = idx;
76
0
      }
77
0
    }
78
0
  }
79
3
  return CCV_NNC_EXEC_SUCCESS;
80
3
}
81
82
static int _ccv_nnc_argmax_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)
83
0
{
84
0
  return CCV_NNC_EXEC_INVALID;
85
0
}
86
87
REGISTER_COMMAND_BACKEND(CCV_NNC_ARGMAX_FORWARD, CCV_NNC_BACKEND_CPU_REF)(ccv_nnc_cmd_backend_registry_t* const registry)
88
1
{
89
1
  registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC | CCV_TENSOR_FORMAT_NCHW | CCV_TENSOR_FORMAT_CHWN;
90
1
  registry->tensor_datatypes = CCV_32F | CCV_32S;
91
1
  registry->tensor_memory = CCV_TENSOR_CPU_MEMORY;
92
1
  registry->algorithms = 1;
93
1
  registry->exec = _ccv_nnc_argmax_forw;
94
1
}
95
96
REGISTER_COMMAND_BACKEND(CCV_NNC_ARGMAX_BACKWARD, CCV_NNC_BACKEND_CPU_REF)(ccv_nnc_cmd_backend_registry_t* const registry)
97
1
{
98
1
  registry->tensor_formats = CCV_TENSOR_FORMAT_NHWC | CCV_TENSOR_FORMAT_NCHW | CCV_TENSOR_FORMAT_CHWN;
99
1
  registry->tensor_datatypes = CCV_32F | CCV_32S;
100
1
  registry->tensor_memory = CCV_TENSOR_CPU_MEMORY;
101
1
  registry->algorithms = 1;
102
1
  registry->exec = _ccv_nnc_argmax_back;
103
1
}