Coverage Report

Created: 2019-07-03 22:50

/home/liu/buildslave/linux-x64-runtests/build/lib/nnc/cmd/blas/cpu_sys/_ccv_nnc_gemm_cpu_sys.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
#include "../_ccv_nnc_gemm_cpu_opt.h"
7
8
int _ccv_nnc_gemm_forw_cpu_sys(const ccv_nnc_tensor_view_t* const a, const ccv_nnc_tensor_view_t* const w, const ccv_nnc_tensor_view_t* const bias, ccv_nnc_tensor_view_t* const b)
9
5.17k
{
10
5.17k
#if (defined HAVE_CBLAS || defined HAVE_ACCELERATE_FRAMEWORK)
11
5.17k
  assert(!CCV_IS_TENSOR_VIEW(a));
12
5.17k
  assert(!CCV_IS_TENSOR_VIEW(b));
13
5.17k
  assert(!CCV_IS_TENSOR_VIEW(w));
14
5.17k
  assert(!bias || !CCV_IS_TENSOR_VIEW(bias));
15
5.17k
  assert(a->info.dim[2] == 0); // It is a 2-d array.
16
5.17k
  assert(b->info.dim[2] == 0); // It is a 2-d array.
17
5.17k
  // Copy the most of parameters, but reshape the dimension of a to a vector.
18
5.17k
  const int a_nd = ccv_nnc_tensor_nd(a->info.dim);
19
5.17k
  const int* adim = (a_nd == 1) ? 
a->info.dim52
:
a->info.dim + 15.12k
;
20
5.17k
  const int b_nd = ccv_nnc_tensor_nd(b->info.dim);
21
5.17k
  const int* bdim = (b_nd == 1) ? 
b->info.dim52
:
b->info.dim + 15.12k
;
22
5.17k
  const int batch_size = a_nd == 1 ? 
152
:
ccv_max5.12k
(1, a->info.dim[0]);
23
5.17k
  ccv_dense_matrix_t am = ccv_dense_matrix(batch_size, adim[0], CCV_32F | CCV_C1, a->data.u8, 0);
24
5.17k
  assert(!bias || bdim[0] == ccv_nnc_tensor_count(bias->info));
25
5.17k
  assert(batch_size == (b_nd == 1) ? 1 : ccv_max(1, b->info.dim[0]));
26
5.17k
  ccv_dense_matrix_t bm = ccv_dense_matrix(batch_size, bdim[0], CCV_32F | CCV_C1, b->data.u8, 0);
27
5.17k
  ccv_dense_matrix_t* dbm = &bm;
28
5.17k
  // copy bias into each row.
29
5.17k
  if (bias)
30
5.17k
  {
31
5.17k
    int i;
32
10.3k
    for (i = 0; i < batch_size; 
i++5.17k
)
33
5.17k
      memcpy(bm.data.f32 + i * bdim[0], bias->data.f32, sizeof(float) * bdim[0]);
34
5.17k
  } else
35
0
    memset(bm.data.f32, 0, sizeof(float) * bdim[0] * batch_size);
36
5.17k
  assert(bdim[0] == w->info.dim[0]);
37
5.17k
  assert(adim[0] == w->info.dim[1]);
38
5.17k
  ccv_dense_matrix_t wm = ccv_dense_matrix(bdim[0], adim[0], CCV_32F | CCV_C1, w->data.u8, 0);
39
5.17k
  ccv_gemm(&am, &wm, 1, dbm, 1, CCV_B_TRANSPOSE, (ccv_matrix_t**)&dbm, 0); // supply b as matrix C is allowed
40
5.17k
  return CCV_NNC_EXEC_SUCCESS;
41
#else
42
  return CCV_NNC_EXEC_INVALID;
43
#endif
44
}
45
46
int _ccv_nnc_gemm_back_cpu_sys(const ccv_nnc_tensor_view_t* const g, const ccv_nnc_tensor_view_t* const a, const ccv_nnc_tensor_view_t* const w, ccv_nnc_tensor_view_t* const dw, ccv_nnc_tensor_view_t* const bias, ccv_nnc_tensor_view_t* const h, const int flags)
47
5.21k
{
48
5.21k
#if (defined HAVE_CBLAS || defined HAVE_ACCELERATE_FRAMEWORK)
49
5.21k
  assert(!CCV_IS_TENSOR_VIEW(g));
50
5.21k
  assert(!CCV_IS_TENSOR_VIEW(a));
51
5.21k
  assert(!CCV_IS_TENSOR_VIEW(dw));
52
5.21k
  assert(!bias || !CCV_IS_TENSOR_VIEW(bias));
53
5.21k
  if (!(flags & CCV_NNC_ACCUMULATE_OUTPUT)) // reset the gradients to 0
54
5.21k
  {
55
5.21k
    memset(dw->data.u8, 0, sizeof(float) * ccv_nnc_tensor_count(w->info));
56
5.21k
    if (bias)
57
5.21k
      memset(bias->data.u8, 0, sizeof(float) * ccv_nnc_tensor_count(bias->info));
58
5.21k
  }
59
5.21k
  assert(a->info.dim[2] == 0); // It is a 2-d array.
60
5.21k
  assert(g->info.dim[2] == 0); // It is a 2-d array.
61
5.21k
  const int a_nd = ccv_nnc_tensor_nd(a->info.dim);
62
5.21k
  assert(a_nd == 1 || a_nd == 2);
63
5.21k
  const int* adim = (a_nd == 1) ? 
a->info.dim0
: a->info.dim + 1;
64
5.21k
  const int g_nd = ccv_nnc_tensor_nd(g->info.dim);
65
5.21k
  assert(g_nd == 1 || g_nd == 2);
66
5.21k
  const int* gdim = (g_nd == 1) ? 
g->info.dim0
: g->info.dim + 1;
67
5.21k
  const int batch_size = a_nd == 1 ? 
10
: ccv_max(1, a->info.dim[0]);
68
5.21k
  assert(batch_size == (g_nd == 1) ? 1 : ccv_max(1, g->info.dim[0]));
69
5.21k
  assert(!bias || bias->info.dim[0] == gdim[0]);
70
5.21k
  ccv_dense_matrix_t gm = ccv_dense_matrix(batch_size, gdim[0], CCV_32F | CCV_C1, g->data.u8, 0);
71
5.21k
  ccv_dense_matrix_t am = ccv_dense_matrix(batch_size, adim[0], CCV_32F | CCV_C1, a->data.u8, 0);
72
5.21k
  int i, j;
73
5.21k
  float* gp = g->data.f32;
74
5.21k
  if (bias)
75
5.21k
  {
76
5.21k
    float* bp = bias->data.f32;
77
10.4k
    for (i = 0; i < batch_size; 
i++5.21k
)
78
5.21k
    {
79
109k
      for (j = 0; j < gdim[0]; 
j++104k
)
80
104k
        bp[j] += gp[j];
81
5.21k
      gp += gdim[0];
82
5.21k
    }
83
5.21k
  }
84
5.21k
  assert(gdim[0] == w->info.dim[0]);
85
5.21k
  assert(adim[0] == w->info.dim[1]);
86
5.21k
  ccv_dense_matrix_t dwm = ccv_dense_matrix(gdim[0], adim[0], CCV_32F | CCV_C1, dw->data.u8, 0);
87
5.21k
  ccv_dense_matrix_t* ddwm = &dwm;
88
5.21k
  ccv_gemm(&gm, &am, 1, ddwm, 1, CCV_A_TRANSPOSE, (ccv_matrix_t**)&ddwm, 0);
89
5.21k
  if (h && w)
90
5.21k
  {
91
5.21k
    assert(!CCV_IS_TENSOR_VIEW(h));
92
5.21k
    assert(!CCV_IS_TENSOR_VIEW(w));
93
5.21k
    assert(h->info.dim[2] == 0); // It is a 2-d array.
94
5.21k
    assert(h->info.dim[0] == a->info.dim[0]);
95
5.21k
    const int h_nd = ccv_nnc_tensor_nd(h->info.dim);
96
5.21k
    assert(h_nd == 1 || h_nd == 2);
97
5.21k
    const int* hdim = (h_nd == 1) ? 
h->info.dim0
: h->info.dim + 1;
98
5.21k
    assert(hdim[0] == adim[0]);
99
5.21k
    assert(batch_size == (h_nd == 1) ? 1 : ccv_max(1, h->info.dim[0]));
100
5.21k
    ccv_dense_matrix_t wm = ccv_dense_matrix(gdim[0], hdim[0], CCV_32F | CCV_C1, w->data.u8, 0);
101
5.21k
    ccv_dense_matrix_t hm = ccv_dense_matrix(batch_size, hdim[0], CCV_32F | CCV_C1, h->data.u8, 0);
102
5.21k
    ccv_dense_matrix_t* dhm = &hm;
103
5.21k
    ccv_gemm(&gm, &wm, 1, 0, 0, 0 /* No transpose */, (ccv_matrix_t**)&dhm, 0);
104
5.21k
  }
105
5.21k
  return CCV_NNC_EXEC_SUCCESS;
106
#else
107
  return CCV_NNC_EXEC_INVALID;
108
#endif
109
}