File indexing completed on 2024-09-07 04:37:00
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef L1Trigger_L1TMuonOverlapPhase2_LutNetworkFixedPointRegression2Outputs_h
0009 #define L1Trigger_L1TMuonOverlapPhase2_LutNetworkFixedPointRegression2Outputs_h
0010
0011 #include "L1Trigger/L1TMuonOverlapPhase2/interface/LutNeuronLayerFixedPoint.h"
0012
0013 #include "ap_int.h"
0014
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016
0017 #include <cmath>
0018
0019 #include <boost/property_tree/ptree.hpp>
0020 #include <boost/property_tree/xml_parser.hpp>
0021
0022 namespace lutNN {
0023
0024
0025
0026 template <int input_I,
0027 int input_F,
0028 std::size_t inputSize,
0029 int layer1_lut_I,
0030 int layer1_lut_F,
0031 int layer1_neurons,
0032 int layer1_output_I,
0033 int layer2_input_I,
0034 int layer2_lut_I,
0035 int layer2_lut_F,
0036 int layer2_neurons,
0037 int layer3_input_I,
0038 int layer3_0_inputCnt,
0039 int layer3_0_lut_I,
0040 int layer3_0_lut_F,
0041 int output0_I,
0042 int output0_F,
0043 int layer3_1_inputCnt,
0044 int layer3_1_lut_I,
0045 int layer3_1_lut_F,
0046 int output1_I,
0047 int output1_F>
0048 class LutNetworkFixedPointRegression2Outputs : public LutNetworkFixedPointRegressionBase {
0049 public:
0050 LutNetworkFixedPointRegression2Outputs() {
0051 static_assert(layer2_neurons == (layer3_0_inputCnt + layer3_1_inputCnt));
0052
0053 std::cout << "LutNetworkFixedPoint" << std::endl;
0054 lutLayer1.setName("lutLayer1");
0055 lutLayer2.setName("lutLayer2");
0056 lutLayer3_0.setName("lutLayer3_0");
0057 lutLayer3_1.setName("lutLayer3_1");
0058 };
0059
0060 ~LutNetworkFixedPointRegression2Outputs() override {}
0061
0062 typedef LutNeuronLayerFixedPoint<input_I, input_F, inputSize, layer1_lut_I, layer1_lut_F, layer1_neurons, layer1_output_I>
0063 LutLayer1;
0064 LutLayer1 lutLayer1;
0065
0066 static constexpr unsigned int noHitCntShift = layer1_output_I;
0067
0068 static constexpr int layer2_input_F = layer1_lut_F;
0069
0070 typedef LutNeuronLayerFixedPoint<layer2_input_I,
0071 layer2_input_F,
0072 layer1_neurons,
0073 layer2_lut_I,
0074 layer2_lut_F,
0075 layer2_neurons,
0076 layer3_input_I>
0077 LutLayer2;
0078 LutLayer2 lutLayer2;
0079
0080 static constexpr int layer3_input_F = layer2_lut_F;
0081
0082 typedef LutNeuronLayerFixedPoint<layer3_input_I,
0083 layer3_input_F,
0084 layer3_0_inputCnt,
0085 layer3_0_lut_I,
0086 layer3_0_lut_F,
0087 1,
0088 output0_I>
0089 LutLayer3_0;
0090 LutLayer3_0 lutLayer3_0;
0091
0092 typedef LutNeuronLayerFixedPoint<layer3_input_I,
0093 layer3_input_F,
0094 layer3_1_inputCnt,
0095 layer3_1_lut_I,
0096 layer3_1_lut_F,
0097 1,
0098 output1_I>
0099 LutLayer3_1;
0100 LutLayer3_1 lutLayer3_1;
0101
0102 void runWithInterpolation() {
0103 lutLayer1.runWithInterpolation(inputArray);
0104 auto& layer1Out = lutLayer1.getOutWithOffset();
0105
0106 std::array<ap_ufixed<layer2_input_I + layer2_input_F, layer2_input_I, AP_TRN, AP_SAT>, layer1_neurons>
0107 layer1OutWithBias;
0108 for (unsigned int i = 0; i < layer1Out.size(); i++) {
0109 layer1OutWithBias[i] = layer1Out[i] + layer1Bias;
0110 }
0111
0112 lutLayer2.runWithInterpolation(layer1OutWithBias);
0113 auto& layer2Out = lutLayer2.getOutWithOffset();
0114
0115 typename LutLayer3_0::inputArrayType lutLayer3_0_input;
0116 std::copy(layer2Out.begin(), layer2Out.begin() + lutLayer3_0_input.size(), lutLayer3_0_input.begin());
0117
0118 typename LutLayer3_1::inputArrayType lutLayer3_1_input;
0119 std::copy(layer2Out.begin() + lutLayer3_0_input.size(), layer2Out.end(), lutLayer3_1_input.begin());
0120
0121 lutLayer3_0.runWithInterpolation(lutLayer3_0_input);
0122 lutLayer3_1.runWithInterpolation(lutLayer3_1_input);
0123 }
0124
0125 void run(std::vector<float>& inputs, float noHitVal, std::vector<double>& nnResult) override {
0126 unsigned int noHitsCnt = 0;
0127 for (unsigned int iInput = 0; iInput < inputs.size(); iInput++) {
0128 inputArray[iInput] = inputs[iInput];
0129 if (inputs[iInput] == noHitVal)
0130 noHitsCnt++;
0131 }
0132
0133 unsigned int bias = (noHitsCnt << noHitCntShift);
0134
0135
0136
0137 layer1Bias = bias;
0138
0139 runWithInterpolation();
0140
0141
0142
0143
0144 auto layer3_0_out = lutLayer3_0.getLutOutSum()[0];
0145 auto layer3_1_out = lutLayer3_1.getLutOutSum()[0];
0146
0147 nnResult[0] = layer3_0_out.to_float();
0148 nnResult[1] = layer3_1_out.to_float();
0149 LogTrace("l1tOmtfEventPrint") << "layer3_0_out[0] " << layer3_0_out[0] << " layer3_1_out[0] " << layer3_1_out[0]
0150 << std::endl;
0151 }
0152
0153
0154 int getCalibratedHwPt() override {
0155 auto lutAddr = ap_ufixed<output0_I + output0_F + output0_F, output0_I + output0_F, AP_RND_CONV, AP_SAT>(
0156 lutLayer3_0.getLutOutSum()[0]);
0157 lutAddr = lutAddr << output0_F;
0158
0159 return ptCalibrationArray[lutAddr.to_uint()].to_uint();
0160 }
0161
0162 void save(const std::string& filename) override {
0163
0164 boost::property_tree::ptree tree;
0165
0166 PUT_VAR(tree, name, output0_I)
0167 PUT_VAR(tree, name, output0_F)
0168 PUT_VAR(tree, name, output1_I)
0169 PUT_VAR(tree, name, output1_F)
0170
0171 lutLayer1.save(tree, name);
0172 lutLayer2.save(tree, name);
0173 lutLayer3_0.save(tree, name);
0174 lutLayer3_1.save(tree, name);
0175
0176 int size = ptCalibrationArray.size();
0177 std::string key = "LutNetworkFixedPointRegression2Outputs.ptCalibrationArray";
0178 PUT_VAR(tree, key, size)
0179 std::ostringstream ostr;
0180 for (auto& a : ptCalibrationArray) {
0181 ostr << a.to_uint() << ", ";
0182 }
0183 tree.put(key + ".values", ostr.str());
0184
0185 boost::property_tree::write_xml(filename,
0186 tree,
0187 std::locale(),
0188 boost::property_tree::xml_parser::xml_writer_make_settings<std::string>(' ', 2));
0189 }
0190
0191 void load(const std::string& filename) override {
0192
0193 boost::property_tree::ptree tree;
0194
0195 boost::property_tree::read_xml(filename, tree);
0196
0197 CHECK_VAR(tree, name, output0_I)
0198 CHECK_VAR(tree, name, output0_F)
0199 CHECK_VAR(tree, name, output1_I)
0200 CHECK_VAR(tree, name, output1_F)
0201
0202 lutLayer1.load(tree, name);
0203 lutLayer2.load(tree, name);
0204 lutLayer3_0.load(tree, name);
0205 lutLayer3_1.load(tree, name);
0206
0207 std::string key = "LutNetworkFixedPointRegression2Outputs.ptCalibrationArray";
0208 int size = ptCalibrationArray.size();
0209 CHECK_VAR(tree, key, size)
0210
0211 auto str = tree.get<std::string>(key + ".values");
0212
0213 std::stringstream ss(str);
0214 std::string item;
0215
0216 for (auto& a : ptCalibrationArray) {
0217 if (std::getline(ss, item, ',')) {
0218 a = std::stoul(item, nullptr, 10);
0219 } else {
0220 throw std::runtime_error(
0221 "LutNetworkFixedPointRegression2Outputs::read: number of items get from file is smaller than lut size");
0222 }
0223 }
0224 }
0225
0226 auto& getPtCalibrationArray() { return ptCalibrationArray; }
0227
0228 private:
0229 std::array<ap_ufixed<LutLayer1::input_W, input_I, AP_TRN, AP_SAT>, inputSize> inputArray;
0230 ap_uint<layer2_input_I> layer1Bias;
0231
0232
0233
0234 std::array<ap_uint<9>, 1 << (output0_I + output0_F)> ptCalibrationArray;
0235
0236 std::string name = "LutNetworkFixedPointRegression2Outputs";
0237 };
0238
0239 }
0240
0241 #endif