Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:21:27

0001 #ifndef NNET_DENSE_H_
0002 #define NNET_DENSE_H_
0003 
0004 #include "nnet_common.h"
0005 #include "nnet_mult.h"
0006 #include <math.h>
0007 
0008 namespace nnet {
0009 
0010   struct dense_config {
0011     // Internal data type definitions
0012     typedef float bias_t;
0013     typedef float weight_t;
0014     typedef float accum_t;
0015 
0016     // Layer Sizes
0017     static const unsigned n_in = 10;
0018     static const unsigned n_out = 10;
0019 
0020     // Resource reuse info
0021     int io_type = io_parallel;
0022     int strategy = latency;
0023     int reuse_factor = 1;
0024     static const bool store_weights_in_bram = false;
0025     int n_zeros = 0;
0026     // partitioning arrays cyclically to go with roll factors?
0027     // Product function to use
0028     template <class x_T, class y_T>
0029     using product = nnet::product::mult<x_T, y_T>;
0030   };
0031 
0032   template <class data_T, class res_T, typename CONFIG_T>
0033   void dense(data_T data[CONFIG_T::n_in],
0034              res_T res[CONFIG_T::n_out],
0035              typename CONFIG_T::weight_t weights[CONFIG_T::n_in * CONFIG_T::n_out],
0036              typename CONFIG_T::bias_t biases[CONFIG_T::n_out]) {
0037     data_T cache;
0038     typename CONFIG_T::accum_t mult[CONFIG_T::n_in * CONFIG_T::n_out];
0039     typename CONFIG_T::accum_t acc[CONFIG_T::n_out];
0040 
0041     // Do the matrix-multiply
0042     for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) {
0043       cache = data[ii];
0044       for (unsigned jj = 0; jj < CONFIG_T::n_out; jj++) {
0045         unsigned index = ii * CONFIG_T::n_out + jj;
0046         mult[index] = CONFIG_T::template product<data_T, typename CONFIG_T::weight_t>::product(cache, weights[index]);
0047       }
0048     }
0049 
0050     // Initialize accumulator with input biases
0051     for (unsigned iacc = 0; iacc < CONFIG_T::n_out; iacc++) {
0052       acc[iacc] = (typename CONFIG_T::accum_t)biases[iacc];
0053     }
0054 
0055     // Accumulate multiplication result
0056     for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) {
0057       for (unsigned jj = 0; jj < CONFIG_T::n_out; jj++) {
0058         unsigned index = ii * CONFIG_T::n_out + jj;
0059         acc[jj] += mult[index];
0060       }
0061     }
0062 
0063     // Cast to "res_t" type
0064     for (unsigned ires = 0; ires < CONFIG_T::n_out; ires++) {
0065       // res[ires] = (res_T) (acc[ires]);
0066       res[ires] = cast<data_T, res_T, CONFIG_T>(acc[ires]);
0067     }
0068   }
0069 
0070 }  // namespace nnet
0071 
0072 #endif