tiny_dnn 1.0.0
A header only, dependency-free deep learning framework in C++11
Loading...
Searching...
No Matches
backend_avx.h
1/*
2 Copyright (c) 2016, Taiga Nomi, Edgar Riba
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the <organization> nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
17 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27#pragma once
28
29#include "tiny_dnn/core/backend.h"
30
31#include "tiny_dnn/core/kernels/avx_deconv2d_kernel.h"
32#include "tiny_dnn/core/kernels/avx_deconv2d_back_kernel.h"
33
34namespace tiny_dnn {
35namespace core {
36
37class avx_backend : public backend {
38 public:
39 // context holds solution-dependent parameters
40 // context should be able to hold any types of structures (like boost::any)
41
42 // convolution
44 std::function<void(const tensor_t&)> f1,
45 std::function<void(const tensor_t&, tensor_t&)> f2,
46 std::function<void(const tensor_t&, const tensor_t&, tensor_t&)> f3,
48 : params_c_(params)
49 , conv_layer_worker_storage_(ptr)
50 , copy_and_pad_input(f1)
51 , copy_and_unpad_delta(f2)
52 , backward_activation(f3) {}
53
54 // deconvolution
56 std::function<void(const tensor_t&)> f1,
57 std::function<void(const tensor_t&, tensor_t&)> f2,
58 std::function<void(const tensor_t&, const tensor_t&, tensor_t&)> f3,
60 : params_d_(params)
61 , deconv_layer_worker_storage_(ptr)
62 , copy_and_unpad_output(f1)
63 , copy_and_pad_delta(f2)
64 , backward_activation(f3) {}
65
66 // maxpooling
67 avx_backend(std::vector<std::vector<serial_size_t>>* out2in,
68 std::vector<serial_size_t>* in2out,
69 std::function<void(const tensor_t&, const tensor_t&, tensor_t&)> f,
71 : max_pooling_layer_worker_storage_(ptr)
72 , out2in_(out2in)
73 , in2out_(in2out)
74 , backward_activation(f) {}
75
76 // fully_connected
78 std::function<void(const tensor_t&, const tensor_t&, tensor_t&)> f)
79 : params_f_(params)
80 , backward_activation(f) {}
81
82 // core math functions
83
84 void conv2d(const std::vector<tensor_t*>& in_data,
85 std::vector<tensor_t*>& out_data) override {
86
87 if (params_c_) return; // workaround to fix warnings
88 if (params_f_) return; // workaround to fix warnings
89 if (conv_layer_worker_storage_) return; // workaround to fix warnings
90 /*copy_and_pad_input(*in_data[0]);
91 const vec_t& W = (*in_data[1])[0];
92 const vec_t& bias = (*in_data[2])[0];
93 tensor_t& a = *out_data[1];
94 const std::vector<const vec_t*> &in = (*conv_layer_worker_storage_).prev_out_padded_; // input // NOLINT
95
96 fill_tensor(a, float_t(0));
97
98 kernels::avx_conv2d_kernel(*params_c_,
99 in, W, bias, a, layer_->parallelize());*/
100 }
101
102 void conv2d_q(const std::vector<tensor_t*>& in_data,
103 std::vector<tensor_t*>& out_data) override {
104 throw nn_error("not implemented yet.");
105 }
106
107 void conv2d_eq(const std::vector<tensor_t*>& in_data,
108 std::vector<tensor_t*>& out_data) override {
109 throw nn_error("not implemented yet.");
110 }
111
112 void conv2d(const std::vector<tensor_t*>& in_data,
113 const std::vector<tensor_t*>& out_data,
114 std::vector<tensor_t*>& out_grad,
115 std::vector<tensor_t*>& in_grad) override {
116 /*conv_layer_worker_specific_storage& cws = (*conv_layer_worker_storage_);
117
118 //std::vector<const vec_t*>& prev_out = cws.prev_out_padded_;
119 const vec_t& W = (*in_data[1])[0];
120 tensor_t& dW = *in_grad[1];
121 tensor_t& db = *in_grad[2];
122 tensor_t& curr_delta = *out_grad[1];
123 tensor_t* prev_delta = (params_c_->pad_type == padding::same) ?
124 &cws.prev_delta_padded_ : in_grad[0];
125
126 assert(W.size() == params_c_->weight.size());
127 assert(dW[0].size() == params_c_->weight.size());
128 assert(curr_delta[0].size() == layer_->out_shape()[0].size());
129
130 backward_activation(*out_grad[0], *out_data[0], curr_delta);
131
132 fill_tensor(*prev_delta, float_t(0));
133
134 kernels::avx_conv2d_back_kernel(*params_c_,
135 prev_out, W, dW, db, curr_delta, prev_delta);
136
137 if (params_c_->pad_type == padding::same) {
138 copy_and_unpad_delta(cws.prev_delta_padded_, *in_grad[0]);
139 }*/
140 }
141
142 void conv2d_q(const std::vector<tensor_t*>& in_data,
143 const std::vector<tensor_t*>& out_data,
144 std::vector<tensor_t*>& out_grad,
145 std::vector<tensor_t*>& in_grad) override {
146 throw nn_error("not implemented yet.");
147 }
148
149 void deconv2d(const std::vector<tensor_t*>& in_data,
150 std::vector<tensor_t*>& out_data) override {
151 (*deconv_layer_worker_storage_).prev_out_ = in_data[0];
152 const vec_t& W = (*in_data[1])[0];
153 const vec_t& bias = (*in_data[2])[0];
154 tensor_t& a = *out_data[1];
155 const tensor_t &in = *in_data[0]; // input
156
157 fill_tensor(a, float_t(0));
158
159 kernels::avx_deconv2d_kernel(*params_d_,
160 in, W, bias, a, layer_->parallelize());
161
162 copy_and_unpad_output(a);
163 a = *(*deconv_layer_worker_storage_).curr_out_unpadded_;
164 }
165
166 void deconv2d_q(const std::vector<tensor_t*>& in_data,
167 std::vector<tensor_t*>& out_data) override {
168 throw nn_error("not implemented yet.");
169 }
170
171 void deconv2d_eq(const std::vector<tensor_t*>& in_data,
172 std::vector<tensor_t*>& out_data) override {
173 throw nn_error("not implemented yet.");
174 }
175
176 void deconv2d(const std::vector<tensor_t*>& in_data,
177 const std::vector<tensor_t*>& out_data,
178 std::vector<tensor_t*>& out_grad,
179 std::vector<tensor_t*>& in_grad) override {
180
181 deconv_layer_worker_specific_storage& cws = (*deconv_layer_worker_storage_);
182 if (params_d_->pad_type == padding::same)
183 copy_and_pad_delta(cws.curr_delta_padded, *in_grad[0]);
184
185 const tensor_t& prev_out = *(cws.prev_out_);
186 const vec_t& W = (*in_data[1])[0];
187 tensor_t& dW = *in_grad[1];
188 tensor_t& db = *in_grad[2];
189 tensor_t& curr_delta = (params_d_->pad_type == padding::same) ? cws.curr_delta_padded : *out_grad[1];
190 tensor_t* prev_delta = in_grad[0];
191
192 assert(W.size() == params_d_->weight.size());
193 assert(dW[0].size() == params_d_->weight.size());
194 assert(curr_delta[0].size() == layer_->out_shape()[0].size());
195
196 backward_activation(*out_grad[0], *out_data[0], curr_delta);
197
198 fill_tensor(*prev_delta, float_t(0));
199
200 kernels::avx_deconv2d_back_kernel(*params_d_,
202 }
203
204 void deconv2d_q(const std::vector<tensor_t*>& in_data,
205 const std::vector<tensor_t*>& out_data,
206 std::vector<tensor_t*>& out_grad,
207 std::vector<tensor_t*>& in_grad) override {
208 throw nn_error("not implemented yet.");
209 }
210
211 void maxpool(const std::vector<tensor_t*>& in_data,
212 std::vector<tensor_t*>& out_data) override {
213 // just to fix warning. Remove in a future
214 if (max_pooling_layer_worker_storage_) {}
215 if (out2in_) {}
216 if (in2out_) {}
217
218 /*const tensor_t& in = *in_data[0];
219 tensor_t& a = *out_data[1];
220 std::vector<std::vector<serial_size_t>>& max_idx =
221 (*max_pooling_layer_worker_storage_).out2inmax_;
222
223 kernels::avx_maxpool_kernel(in, a,
224 max_idx, *out2in_, layer_->parallelize());*/
225 }
226
227 void maxpool(const std::vector<tensor_t*>& in_data,
228 const std::vector<tensor_t*>& out_data,
229 std::vector<tensor_t*>& out_grad,
230 std::vector<tensor_t*>& in_grad) override {
231 /*tensor_t& prev_delta = *in_grad[0];
232 tensor_t& curr_delta = *out_grad[1];
233 std::vector<std::vector<serial_size_t>>& max_idx =
234 (*max_pooling_layer_worker_storage_).out2inmax_;
235
236 CNN_UNREFERENCED_PARAMETER(in_data);
237
238 backward_activation(*out_grad[0], *out_data[0], curr_delta);
239
240 kernels::avx_maxpool_back_kernel(prev_delta, curr_delta,
241 max_idx, *in2out_, layer_->parallelize());*/
242 }
243
244 void fully(const std::vector<tensor_t*>& in_data,
245 std::vector<tensor_t*>& out_data) override {
246 /*const tensor_t& in = *in_data[0];
247 const vec_t& W = (*in_data[1])[0];
248 tensor_t& a = *out_data[1];
249
250 kernels::avx_fully_connected_kernel(*params_f_,
251 in, W, params_f_->has_bias_ ? (*in_data[2])[0] : vec_t(),
252 a, layer_->parallelize());*/
253 }
254
255 void fully_q(const std::vector<tensor_t*>& in_data,
256 std::vector<tensor_t*>& out_data) override {
257 throw nn_error("not implemented yet.");
258 }
259
260 void fully_eq(const std::vector<tensor_t*>& in_data,
261 std::vector<tensor_t*>& out_data) override {
262 throw nn_error("not implemented yet.");
263 }
264
265 void fully(const std::vector<tensor_t*>& in_data,
266 const std::vector<tensor_t*>& out_data,
267 std::vector<tensor_t*>& out_grad,
268 std::vector<tensor_t*>& in_grad) override {
269 /*const tensor_t& prev_out = *in_data[0];
270 const vec_t& W = (*in_data[1])[0];
271 tensor_t& dW = *in_grad[1];
272 tensor_t& db = *in_grad[2];
273 tensor_t& prev_delta = *in_grad[0];
274 tensor_t& curr_delta = *out_grad[1];
275
276 backward_activation(*out_grad[0], *out_data[0], curr_delta);
277
278 kernels::avx_fully_connected_back_kernel(*params_f_, prev_out,
279 W, dW, prev_delta, curr_delta, db, layer_->parallelize());*/
280 }
281
282 void fully_q(const std::vector<tensor_t*>& in_data,
283 const std::vector<tensor_t*>& out_data,
284 std::vector<tensor_t*>& out_grad,
285 std::vector<tensor_t*>& in_grad) override {
286 throw nn_error("not implemented yet.");
287 }
288
289 backend_t type() const override { return backend_t::avx; }
290
291 private:
292 /* Pointer to the convolution parameters */
293 conv_params* params_c_;
294 deconv_params* params_d_;
295 fully_params* params_f_;
296
297 /* Pointer to the workers */
298 conv_layer_worker_specific_storage* conv_layer_worker_storage_;
299 deconv_layer_worker_specific_storage* deconv_layer_worker_storage_;
300 max_pooling_layer_worker_specific_storage* max_pooling_layer_worker_storage_;
301 std::vector<std::vector<serial_size_t>>* out2in_;
302 std::vector<serial_size_t>* in2out_;
303
304 /* Pointers to parent class functions */
305 std::function<void(const tensor_t&)> copy_and_pad_input;
306 std::function<void(const tensor_t&)> copy_and_unpad_output;
307 std::function<void(const tensor_t&, tensor_t&)> copy_and_unpad_delta;
308 std::function<void(const tensor_t&, tensor_t&)> copy_and_pad_delta;
309 std::function<void(const tensor_t&, const tensor_t&, tensor_t&)> backward_activation;
310};
311
312} // namespace core
313} // namespace tiny_dnn
Definition backend_avx.h:37
Definition backend.h:68
Definition conv_params.h:92
Definition fully_params.h:34
Simple image utility class.
Definition image.h:94
virtual std::vector< shape3d > out_shape() const =0
array of output shapes (width x height x depth)
error exception class for tiny-dnn
Definition nn_error.h:37
Definition deconv_params.h:39