CMS 3D CMS Logo

nnet_layer.h
Go to the documentation of this file.
1 //
2 // rfnoc-hls-neuralnet: Vivado HLS code for neural-net building blocks
3 //
4 // Copyright (C) 2017 EJ Kreinar
5 //
6 // This program is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 //
19 
20 #ifndef NNET_LAYER_H_
21 #define NNET_LAYER_H_
22 
23 #include "nnet_common.h"
24 #include <cmath>
25 
26 namespace nnet {
27 
28  struct layer_config {
29  // Internal data type definitions
30  typedef float bias_t;
31  typedef float weight_t;
32  typedef float accum_t;
33 
34  // Layer Sizes
35  static const unsigned n_in = 10;
36  static const unsigned n_out = 10;
37 
38  // Resource reuse info
39  static const unsigned io_type = io_parallel;
40  static const unsigned reuse_factor = 1;
41  static const bool store_weights_in_bram = false;
42  static const unsigned n_zeros = 0;
43  static const bool use_lowlatency = true;
44  // partitioning arrays cyclically to go with roll factors?
45  };
46 
47 #define DIV_ROUNDUP(n, d) ((n + d - 1) / d)
48 
49  template <class data_T, class res_T, typename CONFIG_T>
50  void compute_layer(data_T data[CONFIG_T::n_in],
51  res_T res[CONFIG_T::n_out],
52  typename CONFIG_T::weight_t weights[CONFIG_T::n_in * CONFIG_T::n_out],
53  typename CONFIG_T::bias_t biases[CONFIG_T::n_out]) {
54  unsigned cycle_factor = DIV_ROUNDUP(CONFIG_T::n_in * CONFIG_T::n_out, CONFIG_T::reuse_factor);
55  typename CONFIG_T::weight_t mult[CONFIG_T::n_in * CONFIG_T::n_out];
56  /*
57  if(CONFIG_T::use_lowlatency) {
58  int multiplier_limit = ceil(float(CONFIG_T::n_in*CONFIG_T::n_out) / float(CONFIG_T::reuse_factor)) - floor(float(CONFIG_T::n_zeros) / float(CONFIG_T::reuse_factor));
59  }
60  */
61  typename CONFIG_T::accum_t acc[CONFIG_T::n_out];
62  for (unsigned iacc = 0; iacc < CONFIG_T::n_out; iacc++) {
63  acc[iacc] = (typename CONFIG_T::accum_t)biases[iacc];
64  }
65  unsigned rufactor = CONFIG_T::reuse_factor;
66  if (CONFIG_T::use_lowlatency) {
67  rufactor = CONFIG_T::n_in;
68  cycle_factor = CONFIG_T::n_out;
69  }
70  data_T cache;
71  for (unsigned ii = 0; ii < rufactor; ii++) {
72  if (CONFIG_T::use_lowlatency) {
73  cache = data[ii];
74  }
75  for (unsigned jj = 0; jj < cycle_factor; jj++) {
76  unsigned windex = ii * cycle_factor + jj;
77  unsigned index = windex / CONFIG_T::n_out;
78  if (windex > CONFIG_T::n_in * CONFIG_T::n_out - 1)
79  continue;
80  if (CONFIG_T::use_lowlatency) {
81  mult[windex] = cache * (weights[windex]);
82  } else {
83  int aindex = windex / CONFIG_T::n_in;
84  acc[aindex] += data[index] * weights[windex];
85  }
86  }
87  }
88  if (CONFIG_T::use_lowlatency) {
89  // Accumulate multiplication result
90  for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) {
91  for (unsigned jj = 0; jj < CONFIG_T::n_out; jj++) {
92  int index = ii * CONFIG_T::n_out + jj;
93  acc[jj] += mult[index];
94  }
95  }
96  }
97  for (unsigned ires = 0; ires < CONFIG_T::n_out; ires++) {
98  res[ires] = (res_T)(acc[ires]);
99  }
100  }
101 
102 } // namespace nnet
103 
104 #endif
static const unsigned n_zeros
Definition: nnet_layer.h:42
static const unsigned n_out
Definition: nnet_layer.h:36
Definition: Electron.h:6
void compute_layer(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_out], typename CONFIG_T::weight_t weights[CONFIG_T::n_in *CONFIG_T::n_out], typename CONFIG_T::bias_t biases[CONFIG_T::n_out])
Definition: nnet_layer.h:50
static const bool store_weights_in_bram
Definition: nnet_layer.h:41
static const bool use_lowlatency
Definition: nnet_layer.h:43
#define DIV_ROUNDUP(n, d)
Definition: nnet_layer.h:47
ii
Definition: cuy.py:589
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
def cache(function)
Definition: utilities.py:3
static const unsigned reuse_factor
Definition: nnet_layer.h:40
static const unsigned n_in
Definition: nnet_layer.h:35