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

5
void spline_(linear_basis_forward)(THTensor *basis, THLongTensor *weight_index, THTensor *pseudo, THLongTensor *kernel_size, THByteTensor *is_open_spline, int K) {
rusty1s's avatar
rusty1s committed
6
  SPLINE_BASIS_FORWARD(1, basis, weight_index, pseudo, kernel_size, is_open_spline, K,
rusty1s's avatar
rusty1s committed
7
    value = (1 - k_mod) * (1 - value) + k_mod * value;
rusty1s's avatar
rusty1s committed
8
9
  )
}
rusty1s's avatar
rusty1s committed
10

11
void spline_(quadratic_basis_forward)(THTensor *basis, THLongTensor *weight_index, THTensor *pseudo, THLongTensor *kernel_size, THByteTensor *is_open_spline, int K) {
rusty1s's avatar
rusty1s committed
12
  SPLINE_BASIS_FORWARD(2, basis, weight_index, pseudo, kernel_size, is_open_spline, K,
rusty1s's avatar
rusty1s committed
13
14
15
16
17
    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
18

19
void spline_(cubic_basis_forward)(THTensor *basis, THLongTensor *weight_index, THTensor *pseudo, THLongTensor *kernel_size, THByteTensor *is_open_spline, int K) {
rusty1s's avatar
rusty1s committed
20
  SPLINE_BASIS_FORWARD(3, basis, weight_index, pseudo, kernel_size, is_open_spline, K,
rusty1s's avatar
rusty1s committed
21
22
23
24
25
    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
26
27
}

rusty1s's avatar
rusty1s committed
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
void spline_(linear_basis_backward)(THTensor *grad_pseudo, THTensor *grad_basis, THTensor *pseudo, THLongTensor *kernel_size, THByteTensor *is_open_spline) {
  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 = THTensor_(size)(grad_basis, 1);
  int64_t s, d, d_it;

  TH_TENSOR_DIM_APPLY3(real, grad_pseudo, real, grad_basis, real, pseudo, 1, TH_TENSOR_DIM_APPLY3_SIZE_EQ_EXCEPT_DIM,
    for (d = 0; d < D; d++) {
      real g_out = 0;
      int64_t quotient = (int64_t) pow(2, d);
      for (s = 0; s < S; s++) {
        int64_t k_mod = (s/quotient) % 2;
        real a = -(1 - k_mod) + k_mod;

        for (d_it = 0; d_it < D; d_it++) {
          if (d_it != d) {
            k_mod = (s/((int64_t) pow(2, d_it))) % 2;
            real value = *(pseudo_data + d_it * pseudo_stride) * (kernel_size_data[d_it] - is_open_spline_data[d_it]);
            value -= floor(value);
            a *= (1 - k_mod) * (1 - value) + k_mod * value;
          }
        }
        g_out += a * *(grad_basis_data + s * grad_basis_stride);
      }
      grad_pseudo_data[d * grad_pseudo_stride] = g_out * (kernel_size_data[d] - is_open_spline_data[d]);
    }
  )
rusty1s's avatar
rusty1s committed
56
57
}

rusty1s's avatar
rusty1s committed
58
void spline_(quadratic_basis_backward)(THTensor *grad_pseudo, THTensor *grad_basis, THTensor *pseudo, THLongTensor *kernel_size, THByteTensor *is_open_spline) {
rusty1s's avatar
rusty1s committed
59
60
}

rusty1s's avatar
rusty1s committed
61
void spline_(cubic_basis_backward)(THTensor *grad_pseudo, THTensor *grad_basis, THTensor *pseudo, THLongTensor *kernel_size, THByteTensor *is_open_spline) {
rusty1s's avatar
rusty1s committed
62
63
}

rusty1s's avatar
rusty1s committed
64
void spline_(weighting_forward)(THTensor *output, THTensor *input, THTensor *weight, THTensor *basis, THLongTensor *weight_index) {
rusty1s's avatar
rusty1s committed
65
66
  real *weight_data = weight->storage->data + weight->storageOffset; real b;
  SPLINE_WEIGHTING(output, input, basis, weight_index, THTensor_(size)(weight, 1), THTensor_(size)(weight, 2), THLongTensor_size(weight_index, 1),
rusty1s's avatar
rusty1s committed
67
68
69
70
    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
71
        w_idx = *(weight_index_data + s * weight_index_stride);
rusty1s's avatar
rusty1s committed
72
        for (m_in = 0; m_in < M_in; m_in++) {
rusty1s's avatar
rename  
rusty1s committed
73
          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
74
75
76
77
78
        }
      }
      output_data[m_out * output_stride] = value;
    }
  )
rusty1s's avatar
rusty1s committed
79
80
}

81
82
void spline_(weighting_backward_input)(THTensor *grad_input, THTensor *grad_output, THTensor *weight, THTensor *basis, THLongTensor *weight_index) {
  real *weight_data = weight->storage->data + weight->storageOffset; real b;
rusty1s's avatar
rusty1s committed
83
  SPLINE_WEIGHTING(grad_input, grad_output, basis, weight_index, THTensor_(size)(weight, 1), THTensor_(size)(weight, 2), THLongTensor_size(weight_index, 1),
rusty1s's avatar
rusty1s committed
84
    for (m_in = 0; m_in < M_in; m_in++) {
85
      value = 0;
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++) {
90
91
92
          value += b * *(grad_output_data + m_out * grad_output_stride) * *(weight_data + w_idx * M_in * M_out + m_in * M_out + m_out);
        }
      }
rusty1s's avatar
rusty1s committed
93
      grad_input_data[m_in * grad_input_stride] = value;
94
95
96
97
    }
  )
}

rusty1s's avatar
rusty1s committed
98
99
void spline_(weighting_backward_basis)(THTensor *grad_basis, THTensor *grad_output, THTensor *input, THTensor *weight, THLongTensor *weight_index) {
  real *weight_data = weight->storage->data + weight->storageOffset;
rusty1s's avatar
rusty1s committed
100
  SPLINE_WEIGHTING(grad_basis, grad_output, input, weight_index, THTensor_(size)(weight, 1), THTensor_(size)(weight, 2), THLongTensor_size(weight_index, 1),
101
102
    for (m_out = 0; m_out < M_out; m_out++) {
      for (s = 0; s < S; s++) {
rusty1s's avatar
rusty1s committed
103
        w_idx = *(weight_index_data + s * weight_index_stride); value = 0;
104
        for (m_in = 0; m_in < M_in; m_in++) {
rusty1s's avatar
rusty1s committed
105
          value += *(input_data + m_in * input_stride) * *(weight_data + w_idx * M_in * M_out + m_in * M_out + m_out);
106
        }
rusty1s's avatar
rusty1s committed
107
        grad_basis_data[s * grad_basis_stride] += value * *(grad_output_data + m_out * grad_output_stride);
108
109
110
111
112
      }
    }
  )
}

rusty1s's avatar
rusty1s committed
113
114
void spline_(weighting_backward_weight)(THTensor *grad_weight, THTensor *grad_output, THTensor *input, THTensor *basis, THLongTensor *weight_index) {
  real *grad_weight_data = grad_weight->storage->data + grad_weight->storageOffset; real b;
rusty1s's avatar
rusty1s committed
115
  SPLINE_WEIGHTING(grad_output, input, basis, weight_index, THTensor_(size)(input, 1), THTensor_(size)(grad_output, 1), THLongTensor_size(weight_index, 1),
116
    for (m_out = 0; m_out < M_out; m_out++) {
rusty1s's avatar
rusty1s committed
117
      value = *(grad_output_data + m_out * grad_output_stride);
118
      for (s = 0; s < S; s++) {
rusty1s's avatar
rusty1s committed
119
120
        b = *(basis_data + s * basis_stride);
        w_idx = *(weight_index_data + s * weight_index_stride);
121
        for (m_in = 0; m_in < M_in; m_in++) {
rusty1s's avatar
rusty1s committed
122
          grad_weight_data[w_idx * M_in * M_out + m_in * M_out + m_out] += b * value * *(input_data + m_in * input_stride);
rusty1s's avatar
rusty1s committed
123
124
125
        }
      }
    }
rusty1s's avatar
rusty1s committed
126
  )
rusty1s's avatar
rusty1s committed
127
128
}

rusty1s's avatar
rusty1s committed
129
#endif