Convolution.cpp 12.8 KB
Newer Older
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
1
2
3
// Copyright 2016-present, Facebook, Inc.
// All rights reserved.
//
Benjamin Graham's avatar
Benjamin Graham committed
4
// This source code is licensed under the BSD-style license found in the
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
5
6
7
// LICENSE file in the root directory of this source tree.

template <typename T>
Benjamin Thomas Graham's avatar
fixes  
Benjamin Thomas Graham committed
8
void Convolution_fp_bias(T *oF, T *b, Int nPlanes, Int nActive);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
9
template <typename T>
Benjamin Thomas Graham's avatar
fixes  
Benjamin Thomas Graham committed
10
void Convolution_bp_bias(T *d_oF, T *d_b, Int nPlanes, Int nActive);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
11
12
13
14
template <typename T>
double dConvolution_forward2(T *inFeatures, T *outFeatures, T *w,
                             RuleBook _rules, Int input_nPlanes,
                             Int input_stride, Int output_nPlanes,
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
15
                             Int output_stride, Int nGroups);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
16
17
18
19
20

template <typename T>
void dConvolution_backward_dW2(T *inFeatures, T *dInFeatures, T *dOutFeatures,
                               T *w, T *dw, RuleBook _rules, Int input_nPlanes,
                               Int input_stride, Int output_nPlanes,
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
21
                               Int output_stride, Int nGroups);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
22
23
24

template <typename T, Int Dimension>
double cuda_Convolution_updateOutput(
Michal Pandy's avatar
Michal Pandy committed
25
26
27
28
29
30
31
32
    /*long*/ at::Tensor &inputSize, /*long*/ at::Tensor &outputSize,
    /*long*/ at::Tensor &filterSize,
    /*long*/ at::Tensor &filterStride, Metadata<Dimension> &m,
    /*cuda float*/ at::Tensor &input_features,
    /*cuda float*/ at::Tensor &output_features, /*cuda float*/ at::Tensor &weight,
    /*cuda float*/ at::Tensor &bias) {

  const auto &_rules =
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
33
34
      m.getRuleBook(inputSize, outputSize, filterSize, filterStride, true);
  Int nActiveOut = m.getNActive(outputSize);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
35
36
37
38
  Int nGroups = weight.size(1);
  Int ip = weight.size(2);
  Int op = weight.size(3);
  output_features.resize_({nActiveOut, op * nGroups});
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
39
40
41
42
43
44
45
46
47
48
49

  if (nActiveOut) {
    auto iF = input_features.data<T>();
    auto oF = output_features.data<T>();
    auto w = weight.data<T>();

    if (bias.numel())
      Convolution_fp_bias(oF, bias.data<T>(), op, nActiveOut);
    else
      output_features.zero_();

Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
50
51
    return dConvolution_forward2<T>(iF, oF, w, _rules, ip, ip * nGroups, op,
                                    op * nGroups, nGroups);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
52
53
54
55
56
57
58
  } else {
    return 0;
  }
}

template <typename T, Int Dimension>
void cuda_Convolution_backward(
Michal Pandy's avatar
Michal Pandy committed
59
60
61
62
63
64
65
66
67
68
    /*long*/ at::Tensor &inputSize, /*long*/ at::Tensor &outputSize,
    /*long*/ at::Tensor &filterSize,
    /*long*/ at::Tensor &filterStride, Metadata<Dimension> &m,
    /*cuda float*/ at::Tensor &input_features,
    /*cuda float*/ at::Tensor &d_input_features,
    /*cuda float*/ at::Tensor &d_output_features,
    /*cuda float*/ at::Tensor &weight, /*cuda float*/ at::Tensor &d_weight,
    /*cuda float*/ at::Tensor &d_bias) {

  const auto &_rules =
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
69
70
71
      m.getRuleBook(inputSize, outputSize, filterSize, filterStride, true);
  Int nActiveIn = m.getNActive(inputSize);
  Int nActiveOut = m.getNActive(outputSize);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
72
73
74
75
  Int nGroups = weight.size(1);
  Int ip = weight.size(2);
  Int op = weight.size(3);
  d_input_features.resize_({nActiveIn, ip * nGroups});
Benjamin Thomas Graham's avatar
fixes  
Benjamin Thomas Graham committed
76
  d_input_features.zero_();
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
77
78
79
80
81
82
83
84

  if (nActiveOut) {
    auto iF = input_features.data<T>();
    auto diF = d_input_features.data<T>();
    auto doF = d_output_features.data<T>();
    auto w = weight.data<T>();
    auto dw = d_weight.data<T>();

Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
85
86
    dConvolution_backward_dW2<T>(iF, diF, doF, w, dw, _rules, ip, ip * nGroups,
                                 op, op * nGroups, nGroups);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
87
88
89

    if (d_bias.numel()) {
      auto db = d_bias.data<T>();
Benjamin Thomas Graham's avatar
fixes  
Benjamin Thomas Graham committed
90
      Convolution_bp_bias(doF, db, op, nActiveOut);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
91
92
93
94
95
96
    }
  }
}

template <typename T, Int Dimension>
double cuda_SubmanifoldConvolution_updateOutput(
Michal Pandy's avatar
Michal Pandy committed
97
    /*long*/ at::Tensor &inputSize, /*long*/ at::Tensor &filterSize,
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
98
    Metadata<Dimension> &m,
Michal Pandy's avatar
Michal Pandy committed
99
100
101
    /*cuda float*/ at::Tensor &input_features,
    /*cuda float*/ at::Tensor &output_features, /*cuda float*/ at::Tensor &weight,
    /*cuda float*/ at::Tensor &bias) {
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
102

Michal Pandy's avatar
Michal Pandy committed
103
  const auto &_rules = m.getSubmanifoldRuleBook(inputSize, filterSize, true);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
104
  Int nActive = m.getNActive(inputSize);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
105
106
107
108
  Int nGroups = weight.size(1);
  Int ip = weight.size(2);
  Int op = weight.size(3);
  output_features.resize_({nActive, op * nGroups});
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
109
110
111
112
113
114
115
116
117
118
119

  if (nActive) {
    auto iF = input_features.data<T>();
    auto oF = output_features.data<T>();
    auto w = weight.data<T>();

    if (bias.numel())
      Convolution_fp_bias(oF, bias.data<T>(), op, nActive);
    else
      output_features.zero_();

Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
120
121
    return dConvolution_forward2<T>(iF, oF, w, _rules, ip, ip * nGroups, op,
                                    op * nGroups, nGroups);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
122
123
124
125
126
127
128
  } else {
    return 0;
  }
}

template <typename T, Int Dimension>
void cuda_SubmanifoldConvolution_backward(
Michal Pandy's avatar
Michal Pandy committed
129
    /*long*/ at::Tensor &inputSize, /*long*/ at::Tensor &filterSize,
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
130
    Metadata<Dimension> &m,
Michal Pandy's avatar
Michal Pandy committed
131
132
133
134
135
    /*cuda float*/ at::Tensor &input_features,
    /*cuda float*/ at::Tensor &d_input_features,
    /*cuda float*/ at::Tensor &d_output_features,
    /*cuda float*/ at::Tensor &weight, /*cuda float*/ at::Tensor &d_weight,
    /*cuda float*/ at::Tensor &d_bias) {
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
136

Michal Pandy's avatar
Michal Pandy committed
137
  const auto &_rules = m.getSubmanifoldRuleBook(inputSize, filterSize, true);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
138
  Int nActive = m.getNActive(inputSize);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
139
140
141
142
  Int nGroups = weight.size(1);
  Int ip = weight.size(2);
  Int op = weight.size(3);
  d_input_features.resize_({nActive, ip * nGroups});
Benjamin Thomas Graham's avatar
fixes  
Benjamin Thomas Graham committed
143
  d_input_features.zero_();
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
144
145
146
147
148

  if (nActive) {
    auto iF = input_features.data<T>();
    auto diF = d_input_features.data<T>();
    auto doF = d_output_features.data<T>();
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
149
150
151
    auto w = weight.data<T>();
    auto dw = d_weight.data<T>();

Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
152
153
    dConvolution_backward_dW2<T>(iF, diF, doF, w, dw, _rules, ip, ip * nGroups,
                                 op, op * nGroups, nGroups);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
154
155
156
157
158
159
160
161
162
163

    if (d_bias.numel()) {
      auto db = d_bias.data<T>();
      Convolution_bp_bias(doF, db, op, nActive);
    }
  }
}

template <typename T, Int Dimension>
double cuda_PermutohedralSubmanifoldConvolution_updateOutput(
Michal Pandy's avatar
Michal Pandy committed
164
165
166
167
    /*long*/ at::Tensor &inputSize, Metadata<Dimension> &m,
    /*cuda float*/ at::Tensor &input_features,
    /*cuda float*/ at::Tensor &output_features, /*cuda float*/ at::Tensor &weight,
    /*cuda float*/ at::Tensor &bias) {
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
168

Michal Pandy's avatar
Michal Pandy committed
169
  const auto &_rules = m.getPermutohedralSubmanifoldRuleBook(inputSize, true);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
170
  Int nActive = m.getNActive(inputSize);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
171
172
173
174
  Int nGroups = weight.size(1);
  Int ip = weight.size(2);
  Int op = weight.size(3);
  output_features.resize_({nActive, op * nGroups});
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
175
176
177
178
179
180
181
182
183
184
185

  if (nActive) {
    auto iF = input_features.data<T>();
    auto oF = output_features.data<T>();
    auto w = weight.data<T>();

    if (bias.numel())
      Convolution_fp_bias(oF, bias.data<T>(), op, nActive);
    else
      output_features.zero_();

Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
186
187
    return dConvolution_forward2<T>(iF, oF, w, _rules, ip, ip * nGroups, op,
                                    op * nGroups, nGroups);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
188
189
190
191
192
193
194
  } else {
    return 0;
  }
}

template <typename T, Int Dimension>
void cuda_PermutohedralSubmanifoldConvolution_backward(
Michal Pandy's avatar
Michal Pandy committed
195
196
197
198
199
200
201
202
    /*long*/ at::Tensor &inputSize, Metadata<Dimension> &m,
    /*cuda float*/ at::Tensor &input_features,
    /*cuda float*/ at::Tensor &d_input_features,
    /*cuda float*/ at::Tensor &d_output_features,
    /*cuda float*/ at::Tensor &weight, /*cuda float*/ at::Tensor &d_weight,
    /*cuda float*/ at::Tensor &d_bias) {

  const auto &_rules = m.getPermutohedralSubmanifoldRuleBook(inputSize, true);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
203
  Int nActive = m.getNActive(inputSize);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
204
205
206
207
  Int nGroups = weight.size(1);
  Int ip = weight.size(2);
  Int op = weight.size(3);
  d_input_features.resize_({nActive, ip * nGroups});
Benjamin Thomas Graham's avatar
fixes  
Benjamin Thomas Graham committed
208
  d_input_features.zero_();
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
209
210
211
212
213

  if (nActive) {
    auto iF = input_features.data<T>();
    auto diF = d_input_features.data<T>();
    auto doF = d_output_features.data<T>();
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
214
215
216
    auto w = weight.data<T>();
    auto dw = d_weight.data<T>();

Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
217
218
    dConvolution_backward_dW2<T>(iF, diF, doF, w, dw, _rules, ip, ip * nGroups,
                                 op, op * nGroups, nGroups);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
219
220
221

    if (d_bias.numel()) {
      auto db = d_bias.data<T>();
Benjamin Thomas Graham's avatar
fixes  
Benjamin Thomas Graham committed
222
      Convolution_bp_bias(doF, db, op, nActive);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
223
224
225
226
227
228
    }
  }
}

template <typename T, Int Dimension>
double cuda_FullConvolution_updateOutput(
Michal Pandy's avatar
Michal Pandy committed
229
230
231
    /*long*/ at::Tensor &inputSize, /*long*/ at::Tensor &outputSize,
    /*long*/ at::Tensor &filterSize,
    /*long*/ at::Tensor &filterStride, Metadata<Dimension> &mIn,
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
232
    Metadata<Dimension> &mOut,
Michal Pandy's avatar
Michal Pandy committed
233
234
235
    /*cuda float*/ at::Tensor &input_features,
    /*cuda float*/ at::Tensor &output_features, /*cuda float*/ at::Tensor &weight,
    /*cuda float*/ at::Tensor &bias) {
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
236

Michal Pandy's avatar
Michal Pandy committed
237
  const auto &_rules = mIn.getFullConvolutionRuleBook(inputSize, outputSize,
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
238
239
                                               filterSize, filterStride, mOut);
  Int nActiveOut = mOut.getNActive(outputSize);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
240
241
242
243
  Int nGroups = weight.size(1);
  Int ip = weight.size(2);
  Int op = weight.size(3);
  output_features.resize_({nActiveOut, op * nGroups});
Benjamin Thomas Graham's avatar
fixes  
Benjamin Thomas Graham committed
244

Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
245
246
247
248
249
250
251
252
253
254
  if (nActiveOut) {
    auto iF = input_features.data<T>();
    auto oF = output_features.data<T>();
    auto w = weight.data<T>();

    if (bias.numel())
      Convolution_fp_bias(oF, bias.data<T>(), op, nActiveOut);
    else
      output_features.zero_();

Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
255
256
    return dConvolution_forward2<T>(iF, oF, w, _rules, ip, ip * nGroups, op,
                                    op * nGroups, nGroups);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
257
258
259
260
261
262
263
  } else {
    return 0;
  }
}

template <typename T, Int Dimension>
void cuda_FullConvolution_backward(
Michal Pandy's avatar
Michal Pandy committed
264
265
266
    /*long*/ at::Tensor &inputSize, /*long*/ at::Tensor &outputSize,
    /*long*/ at::Tensor &filterSize,
    /*long*/ at::Tensor &filterStride, Metadata<Dimension> &mIn,
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
267
    Metadata<Dimension> &mOut,
Michal Pandy's avatar
Michal Pandy committed
268
269
270
271
272
    /*cuda float*/ at::Tensor &input_features,
    /*cuda float*/ at::Tensor &d_input_features,
    /*cuda float*/ at::Tensor &d_output_features,
    /*cuda float*/ at::Tensor &weight, /*cuda float*/ at::Tensor &d_weight,
    /*cuda float*/ at::Tensor &d_bias) {
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
273

Michal Pandy's avatar
Michal Pandy committed
274
  const auto &_rules = mIn.getFullConvolutionRuleBook(inputSize, outputSize,
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
275
276
277
                                               filterSize, filterStride, mOut);
  Int nActiveIn = mIn.getNActive(inputSize);
  Int nActiveOut = mOut.getNActive(outputSize);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
278
279
280
281
  Int nGroups = weight.size(1);
  Int ip = weight.size(2);
  Int op = weight.size(3);
  d_input_features.resize_({nActiveIn, ip * nGroups});
Benjamin Thomas Graham's avatar
fixes  
Benjamin Thomas Graham committed
282
  d_input_features.zero_();
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
283
284
285
286
287
288
289
290

  if (nActiveOut) {
    auto iF = input_features.data<T>();
    auto diF = d_input_features.data<T>();
    auto doF = d_output_features.data<T>();
    auto w = weight.data<T>();
    auto dw = d_weight.data<T>();

Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
291
292
    dConvolution_backward_dW2<T>(iF, diF, doF, w, dw, _rules, ip, ip * nGroups,
                                 op, op * nGroups, nGroups);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
293
294
295

    if (d_bias.numel()) {
      auto db = d_bias.data<T>();
Benjamin Thomas Graham's avatar
fixes  
Benjamin Thomas Graham committed
296
      Convolution_bp_bias(doF, db, op, nActiveOut);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
297
298
299
300
301
    }
  }
}
template <typename T, Int Dimension>
double cuda_RandomizedStrideConvolution_updateOutput(
Michal Pandy's avatar
Michal Pandy committed
302
303
304
305
306
307
308
309
    /*long*/ at::Tensor &inputSize, /*long*/ at::Tensor &outputSize,
    /*long*/ at::Tensor &filterSize,
    /*long*/ at::Tensor &filterStride, Metadata<Dimension> &m,
    /*cuda float*/ at::Tensor &input_features,
    /*cuda float*/ at::Tensor &output_features,
    /*cuda float*/ at::Tensor &weight, /*cuda float*/ at::Tensor &bias) {

  const auto &_rules = m.getRandomizedStrideRuleBook(inputSize, outputSize, filterSize,
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
310
311
                                              filterStride, true);
  Int nActiveOut = m.getNActive(outputSize);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
312
313
314
315
  Int nGroups = weight.size(1);
  Int ip = weight.size(2);
  Int op = weight.size(3);
  output_features.resize_({nActiveOut, op * nGroups});
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
316
317
318
319
320
321
322
323
324
325
326

  if (nActiveOut) {
    auto iF = input_features.data<T>();
    auto oF = output_features.data<T>();
    auto w = weight.data<T>();

    if (bias.numel())
      Convolution_fp_bias(oF, bias.data<T>(), op, nActiveOut);
    else
      output_features.zero_();

Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
327
328
    return dConvolution_forward2<T>(iF, oF, w, _rules, ip, ip * nGroups, op,
                                    op * nGroups, nGroups);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
329
330
331
332
333
334
335
  } else {
    return 0;
  }
}

template <typename T, Int Dimension>
void cuda_RandomizedStrideConvolution_backward(
Michal Pandy's avatar
Michal Pandy committed
336
337
338
339
340
341
342
343
344
345
    /*long*/ at::Tensor &inputSize, /*long*/ at::Tensor &outputSize,
    /*long*/ at::Tensor &filterSize,
    /*long*/ at::Tensor &filterStride, Metadata<Dimension> &m,
    /*cuda float*/ at::Tensor &input_features,
    /*cuda float*/ at::Tensor &d_input_features,
    /*cuda float*/ at::Tensor &d_output_features,
    /*cuda float*/ at::Tensor &weight, /*cuda float*/ at::Tensor &d_weight,
    /*cuda float*/ at::Tensor &d_bias) {

  const auto &_rules = m.getRandomizedStrideRuleBook(inputSize, outputSize, filterSize,
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
346
347
348
                                              filterStride, true);
  Int nActiveIn = m.getNActive(inputSize);
  Int nActiveOut = m.getNActive(outputSize);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
349
350
351
352
  Int nGroups = weight.size(1);
  Int ip = weight.size(2);
  Int op = weight.size(3);
  d_input_features.resize_({nActiveIn, ip * nGroups});
Benjamin Thomas Graham's avatar
fixes  
Benjamin Thomas Graham committed
353
  d_input_features.zero_();
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
354
355
356
357
358
359
360
361

  if (nActiveOut) {
    auto iF = input_features.data<T>();
    auto diF = d_input_features.data<T>();
    auto doF = d_output_features.data<T>();
    auto w = weight.data<T>();
    auto dw = d_weight.data<T>();

Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
362
363
    dConvolution_backward_dW2<T>(iF, diF, doF, w, dw, _rules, ip, ip * nGroups,
                                 op, op * nGroups, nGroups);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
364
365
366

    if (d_bias.numel()) {
      auto db = d_bias.data<T>();
Benjamin Thomas Graham's avatar
fixes  
Benjamin Thomas Graham committed
367
      Convolution_bp_bias(doF, db, op, nActiveOut);
Benjamin Thomas Graham's avatar
Benjamin Thomas Graham committed
368
369
370
    }
  }
}