cpu.c 4.55 KB
Newer Older
rusty1s's avatar
rusty1s committed
1
2
3
4
#ifndef TH_GENERIC_FILE
#define TH_GENERIC_FILE "generic/cpu.c"
#else

rusty1s's avatar
rusty1s committed
5
6
7
8
9
10
11
12
13
14
15
16
17
#define SPLINE_BASIS(M, basis, weight_index, pseudo, kernel_size, is_open_spline, K, CODE) { \
  int64_t *kernel_size_data = kernel_size->storage->data + kernel_size->storageOffset; \
  uint8_t *is_open_spline_data = is_open_spline->storage->data + is_open_spline->storageOffset; \
  int64_t D = THTensor_(size)(pseudo, 1); \
  int64_t S = THLongTensor_size(weight_index, 1); \
  int64_t s, d, k, k_mod, i, offset; real value, b; \
\
  TH_TENSOR_DIM_APPLY3(real, basis, int64_t, weight_index, real, pseudo, 1, TH_TENSOR_DIM_APPLY3_SIZE_EQ_EXCEPT_DIM, \
    for (s = 0; s < S; s++) { \
      b = 1; i = 0; k = s; offset = K; \
      for (d = 0; d < D; d++) { \
        offset /= kernel_size_data[d]; \
        k_mod = k % (M + 1); \
rusty1s's avatar
rusty1s committed
18
        k /= M + 1; \
rusty1s's avatar
rusty1s committed
19
        value = *(pseudo_data + d * pseudo_stride) * (kernel_size_data[d] - M * is_open_spline_data[d]); \
rusty1s's avatar
rusty1s committed
20
        i += (((int64_t) value + k_mod) % kernel_size_data[d]) * offset; \
rusty1s's avatar
rusty1s committed
21
22
23
24
25
26
27
28
        value -= floor(value); \
        CODE \
        b *= value; \
      } \
      basis_data[s * basis_stride] = b; \
      weight_index_data[s * weight_index_stride] = i; \
    }) \
}
rusty1s's avatar
rusty1s committed
29

rusty1s's avatar
rusty1s committed
30
31
void spline_(basis_linear)(THTensor *basis, THLongTensor *weight_index, THTensor *pseudo, THLongTensor *kernel_size, THByteTensor *is_open_spline, int K) {
  SPLINE_BASIS(1, basis, weight_index, pseudo, kernel_size, is_open_spline, K,
rusty1s's avatar
rusty1s committed
32
    value = (1 - k_mod) * (1 - value) + k_mod * value;
rusty1s's avatar
rusty1s committed
33
34
  )
}
rusty1s's avatar
rusty1s committed
35

rusty1s's avatar
rusty1s committed
36
37
38
39
40
41
42
void spline_(basis_quadratic)(THTensor *basis, THLongTensor *weight_index, THTensor *pseudo, THLongTensor *kernel_size, THByteTensor *is_open_spline, int K) {
  SPLINE_BASIS(2, basis, weight_index, pseudo, kernel_size, is_open_spline, K,
    if (k_mod == 0) value = 0.5 * (1 - value) * (1 - value);
    else if (k_mod == 1) value = -value * value + value + 0.5;
    else value = 0.5 * value * value;
  )
}
rusty1s's avatar
rusty1s committed
43

rusty1s's avatar
rusty1s committed
44
45
46
47
48
49
50
void spline_(basis_cubic)(THTensor *basis, THLongTensor *weight_index, THTensor *pseudo, THLongTensor *kernel_size, THByteTensor *is_open_spline, int K) {
  SPLINE_BASIS(3, basis, weight_index, pseudo, kernel_size, is_open_spline, K,
    if (k_mod == 0) value = (1 - value) * (1 - value) * (1 - value) / 6.0;
    else if (k_mod == 1) value = (3 * value * value * value - 6 * value * value + 4) / 6.0;
    else if (k_mod == 2) value = (-3 * value * value * value + 3 * value * value + 3 * value + 1) / 6.0;
    else value = value * value * value / 6.0;
  )
rusty1s's avatar
rusty1s committed
51
52
}

rusty1s's avatar
rusty1s committed
53
void spline_(weighting_forward)(THTensor *output, THTensor *input, THTensor *weight, THTensor *basis, THLongTensor *weight_index) {
rusty1s's avatar
rusty1s committed
54
55
56
57
  real *weight_data = weight->storage->data + weight->storageOffset;
  int64_t M_out = THTensor_(size)(output, 1);
  int64_t M_in = THTensor_(size)(input, 1);
  int64_t S = THLongTensor_size(weight_index, 1);
rusty1s's avatar
rename  
rusty1s committed
58
  int64_t m_out, m_in, s, w_idx; real b, value;
rusty1s's avatar
rusty1s committed
59
60
61
62
63
64

  TH_TENSOR_DIM_APPLY4(real, output, real, input, real, basis, int64_t, weight_index, 1,
    for (m_out = 0; m_out < M_out; m_out++) {
      value = 0;
      for (s = 0; s < S; s++) {
        b = *(basis_data + s * basis_stride);
rusty1s's avatar
rename  
rusty1s committed
65
        w_idx = *(weight_index_data + s * weight_index_stride);
rusty1s's avatar
rusty1s committed
66
        for (m_in = 0; m_in < M_in; m_in++) {
rusty1s's avatar
rename  
rusty1s committed
67
          value += b * *(weight_data + w_idx * M_in * M_out + m_in * M_out + m_out) * *(input_data + m_in * input_stride);
rusty1s's avatar
rusty1s committed
68
69
70
71
72
        }
      }
      output_data[m_out * output_stride] = value;
    }
  )
rusty1s's avatar
rusty1s committed
73
74
}

rusty1s's avatar
rusty1s committed
75
void spline_(weighting_backward)(THTensor *grad_input, THTensor *grad_weight, THTensor *grad_output, THTensor *input, THTensor *weight, THTensor *basis, THLongTensor *weight_index) {
rusty1s's avatar
rusty1s committed
76
77
  real *weight_data = weight->storage->data + weight->storageOffset;
  real *grad_weight_data = grad_weight->storage->data + grad_weight->storageOffset;
rusty1s's avatar
rusty1s committed
78
  int64_t M_out = THTensor_(size)(grad_output, 1);
rusty1s's avatar
rusty1s committed
79
80
  int64_t M_in = THTensor_(size)(input, 1);
  int64_t S = THLongTensor_size(weight_index, 1);
rusty1s's avatar
rename  
rusty1s committed
81
  int64_t m_out, m_in, s, w_idx, idx; real g_in, value, b, g_out;
rusty1s's avatar
rusty1s committed
82

rusty1s's avatar
rusty1s committed
83
  TH_TENSOR_DIM_APPLY5(real, grad_input, real, grad_output, real, input, real, basis, int64_t, weight_index, 1,
rusty1s's avatar
rusty1s committed
84
85
    for (m_in = 0; m_in < M_in; m_in++) {
      g_in = 0; value = *(input_data + m_in * input_stride);
rusty1s's avatar
rusty1s committed
86
87
      for (s = 0; s < S; s++) {
        b = *(basis_data + s * basis_stride);
rusty1s's avatar
rename  
rusty1s committed
88
        w_idx = *(weight_index_data + s * weight_index_stride);
rusty1s's avatar
rusty1s committed
89
        for (m_out = 0; m_out < M_out; m_out++) {
rusty1s's avatar
rename  
rusty1s committed
90
          idx = w_idx * M_in * M_out + m_in * M_out + m_out;
rusty1s's avatar
rusty1s committed
91
          g_out = *(grad_output_data + m_out * grad_output_stride);
rusty1s's avatar
rename  
rusty1s committed
92
93
          grad_weight_data[idx] += b * g_out * value;
          g_in += b * g_out * *(weight_data + idx);
rusty1s's avatar
rusty1s committed
94
95
        }
      }
rusty1s's avatar
rusty1s committed
96
      grad_input_data[m_in] = g_in;
rusty1s's avatar
rusty1s committed
97
    }
rusty1s's avatar
rusty1s committed
98
  )
rusty1s's avatar
rusty1s committed
99
100
}

rusty1s's avatar
rusty1s committed
101
#endif