Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef NNET_ACTIVATION_H_
0002 #define NNET_ACTIVATION_H_
0003 
0004 #include <cmath>
0005 #include "ap_fixed.h"
0006 #include "nnet_common.h"
0007 
0008 namespace nnet {
0009 
0010   struct activ_config {
0011     // IO size
0012     static const unsigned n_in = 10;
0013 
0014     // Internal info
0015     static const unsigned table_size = 1024;
0016 
0017     // Resource reuse info
0018     static const unsigned io_type = io_parallel;
0019     static const unsigned reuse_factor = 1;
0020 
0021     // Internal data type definitions
0022     typedef ap_fixed<18, 8> table_t;
0023   };
0024 
0025   // *************************************************
0026   //       LINEAR Activation -- See Issue 53
0027   // *************************************************
0028   template <class data_T, class res_T, typename CONFIG_T>
0029   void linear(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) {
0030     for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) {
0031       res[ii] = data[ii];
0032     }
0033   }
0034 
0035   // *************************************************
0036   //       RELU Activation
0037   // *************************************************
0038   template <class data_T, class res_T, typename CONFIG_T>
0039   void relu(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) {
0040     data_T datareg;
0041     for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) {
0042       datareg = data[ii];
0043       if (datareg > 0)
0044         res[ii] = datareg;
0045       else
0046         res[ii] = 0;
0047     }
0048   }
0049 
0050   // *************************************************
0051   //       Sigmoid Activation
0052   // *************************************************
0053   template <class out_T>
0054   inline out_T sigmoid_fcn_float(float input) {
0055     return 1.0 / (1 + exp(-input));
0056   }
0057 
0058   template <class res_T, typename CONFIG_T, int N_TABLE>
0059   void init_sigmoid_table(res_T table_out[N_TABLE]) {
0060     // Default logistic sigmoid function:
0061     //   result = 1/(1+e^(-x))
0062     for (unsigned ii = 0; ii < N_TABLE; ii++) {
0063       // First, convert from table index to X-value (signed 8-bit, range -8 to +8)
0064       float in_val = 2 * 8.0 * (ii - float(N_TABLE) / 2.0) / float(N_TABLE);
0065       // Next, compute lookup table function
0066       res_T real_val = sigmoid_fcn_float<res_T>(in_val);
0067       //std::cout << "Lookup table In Value: " << in_val << " Result: " << real_val << std::endl;
0068       table_out[ii] = (res_T)real_val;
0069     }
0070   }
0071 
0072   template <class data_T, class res_T, typename CONFIG_T>
0073   void sigmoid(data_T data[CONFIG_T::n_in], res_T res[CONFIG_T::n_in]) {
0074     // Initialize the lookup table
0075     res_T sigmoid_table[CONFIG_T::table_size];
0076     init_sigmoid_table<res_T, CONFIG_T, CONFIG_T::table_size>(sigmoid_table);
0077 
0078     // Index into the lookup table based on data
0079     int data_round;
0080     unsigned index;
0081     for (unsigned ii = 0; ii < CONFIG_T::n_in; ii++) {
0082       data_round = data[ii] * CONFIG_T::table_size / 16;
0083       index = data_round + 8 * CONFIG_T::table_size / 16;
0084       /*if (index < 0)
0085         index = 0;*/
0086       if (index > CONFIG_T::table_size - 1)
0087         index = CONFIG_T::table_size - 1;
0088       res[ii] = (res_T)sigmoid_table[index];
0089     }
0090   }
0091 
0092 }  // namespace nnet
0093 
0094 #endif