Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "L1Trigger/Phase2L1ParticleFlow/interface/dbgPrintf.h"
0002 
0003 template <typename T>
0004 void l1ct::multififo_regionizer::maybe_push(const T& t,
0005                                             const l1ct::PFRegionEmu& sector,
0006                                             const l1ct::PFRegionEmu& region,
0007                                             std::list<T>& fifo,
0008                                             bool /*useAlsoVtxCoords*/) {
0009   int local_eta = sector.hwGlbEtaOf(t).to_int() - region.hwEtaCenter.to_int();
0010   int local_phi = dphi_wrap(sector.hwGlbPhiOf(t).to_int() - region.hwPhiCenter.to_int());
0011   if (region.isInside(local_eta, local_phi)) {
0012     push_to_fifo(t, local_eta, local_phi, fifo);
0013   }
0014 }
0015 template <>
0016 void l1ct::multififo_regionizer::maybe_push<l1ct::TkObjEmu>(const l1ct::TkObjEmu& t,
0017                                                             const l1ct::PFRegionEmu& sector,
0018                                                             const l1ct::PFRegionEmu& region,
0019                                                             std::list<l1ct::TkObjEmu>& fifo,
0020                                                             bool useAlsoVtxCoords) {
0021   int local_eta_c = sector.hwGlbEtaOf(t).to_int() - region.hwEtaCenter.to_int();
0022   int local_phi_c = dphi_wrap(sector.hwGlbPhiOf(t).to_int() - region.hwPhiCenter.to_int());
0023   int local_eta_v = sector.hwGlbEta(t.hwVtxEta()).to_int() - region.hwEtaCenter.to_int();
0024   int local_phi_v = dphi_wrap(sector.hwGlbPhi(t.hwVtxPhi()).to_int() - region.hwPhiCenter.to_int());
0025   if (region.isInside(local_eta_c, local_phi_c) || (useAlsoVtxCoords && region.isInside(local_eta_v, local_phi_v))) {
0026     push_to_fifo(t, local_eta_c, local_phi_c, fifo);
0027     /*    printf("  pushed track pT %6d eta %+5d phi %+5d from sector eta %+5d phi %+5d to region eta %+5d phi %+5d\n",
0028             t.intPt(), t.intEta(), t.intPhi(), 
0029             sector.intEtaCenter(), sector.intPhiCenter(), 
0030             region.intEtaCenter(), region.intPhiCenter());
0031   } else {
0032     printf("  drop   track pT %6d eta %+5d phi %+5d from sector eta %+5d phi %+5d to region eta %+5d phi %+5d\n",
0033             t.intPt(), t.intEta(), t.intPhi(), 
0034             sector.intEtaCenter(), sector.intPhiCenter(), 
0035             region.intEtaCenter(), region.intPhiCenter());
0036 
0037     */
0038   }
0039 }
0040 
0041 template <typename T>
0042 void l1ct::multififo_regionizer::RegionBuffer<T>::initFifos(unsigned int nfifos) {
0043   assert(nfifos_ == 0);
0044   bool isGood =
0045       (nfifos == 1 || nfifos == 2 || nfifos == 3 || nfifos == 4 || nfifos == 6 || nfifos == 8 || nfifos == 12);
0046   if (!isGood) {
0047     dbgCerr() << "Error, created regionizer for nfifos == " << nfifos << ", not supported." << std::endl;
0048   }
0049   nfifos_ = nfifos;
0050   fifos_.resize(nfifos);
0051   unsigned int nmerged = nfifos;
0052   while (nmerged > 3) {
0053     assert(nmerged % 2 == 0);
0054     nmerged /= 2;
0055     queues_.emplace_back(std::vector<T>(nmerged), std::vector<T>(nmerged));
0056     for (auto& t : queues_.back().first)
0057       t.clear();
0058     for (auto& t : queues_.back().second)
0059       t.clear();
0060   }
0061   assert(isGood);
0062 }
0063 
0064 template <typename T>
0065 void l1ct::multififo_regionizer::RegionBuffer<T>::flush() {
0066   for (auto& f : fifos_)
0067     f.clear();
0068   for (auto& p : queues_) {
0069     for (auto& t : p.first)
0070       t.clear();
0071     for (auto& t : p.second)
0072       t.clear();
0073   }
0074 }
0075 
0076 template <typename T>
0077 void l1ct::multififo_regionizer::RegionBuffer<T>::maybe_push(int fifo, const T& t, const l1ct::PFRegionEmu& sector) {
0078   if (t.hwPt != 0)
0079     l1ct::multififo_regionizer::maybe_push<T>(t, sector, region_, fifos_[fifo], useAlsoVtxCoords_);
0080 }
0081 
0082 template <typename T>
0083 T l1ct::multififo_regionizer::RegionBuffer<T>::pop() {
0084   if (nfifos_ <= 3)
0085     return pop_next_trivial_();
0086   assert(!queues_.empty());
0087   for (unsigned int istep = 0, nsteps = queues_.size(); istep < nsteps; ++istep) {
0088     if (istep == 0)
0089       fifos_to_stage_(queues_.front().first);
0090     else
0091       queue_to_stage_(queues_[istep - 1].second, queues_[istep].first);
0092     stage_to_queue_(queues_[istep].first, queues_[istep].second);
0093   }
0094   return pop_queue_(queues_.back().second);
0095 }
0096 
0097 template <typename T>
0098 T l1ct::multififo_regionizer::RegionBuffer<T>::pop_next_trivial_() {
0099   T ret;
0100   ret.clear();
0101   for (unsigned int j = 0; j < nfifos_; ++j) {
0102     if (!fifos_[j].empty()) {
0103       pop_back(fifos_[j], ret);
0104       break;
0105     }
0106   }
0107   return ret;
0108 }
0109 
0110 template <typename T>
0111 void l1ct::multififo_regionizer::RegionBuffer<T>::fifos_to_stage_(std::vector<T>& staging_area) {
0112   assert(staging_area.size() * 2 == nfifos_);
0113   // shift data from each pair of fifos to the staging area
0114   for (unsigned int j = 0; j < nfifos_ / 2; ++j) {
0115     if (staging_area[j].hwPt != 0)
0116       continue;
0117     for (unsigned int i = 2 * j; i <= 2 * j + 1; ++i) {
0118       if (!fifos_[i].empty()) {
0119         pop_back(fifos_[i], staging_area[j]);
0120         break;
0121       }
0122     }
0123   }
0124 }
0125 
0126 template <typename T>
0127 void l1ct::multififo_regionizer::RegionBuffer<T>::queue_to_stage_(std::vector<T>& queue, std::vector<T>& staging_area) {
0128   assert(staging_area.size() * 2 == queue.size());
0129   // shift data from each pair of fifos to the staging area
0130   for (unsigned int j = 0, n = staging_area.size(); j < n; ++j) {
0131     if (staging_area[j].hwPt != 0)
0132       continue;
0133     for (unsigned int i = 2 * j; i <= 2 * j + 1; ++i) {
0134       if (queue[i].hwPt != 0) {
0135         shift(queue[i], staging_area[j]);
0136         break;
0137       }
0138     }
0139   }
0140 }
0141 
0142 template <typename T>
0143 void l1ct::multififo_regionizer::RegionBuffer<T>::stage_to_queue_(std::vector<T>& staging_area, std::vector<T>& queue) {
0144   assert(staging_area.size() == queue.size());
0145   // then from staging area to queue
0146   for (unsigned int j = 0, n = staging_area.size(); j < n; ++j) {
0147     if (staging_area[j].hwPt != 0 && queue[j].hwPt == 0) {
0148       shift(staging_area[j], queue[j]);
0149     }
0150   }
0151 }
0152 
0153 template <typename T>
0154 T l1ct::multififo_regionizer::RegionBuffer<T>::pop_queue_(std::vector<T>& queue) {
0155   T ret;
0156   ret.clear();
0157   for (T& t : queue) {
0158     if (t.hwPt != 0) {
0159       ret = t;
0160       t.clear();
0161       break;
0162     }
0163   }
0164   return ret;
0165 }
0166 
0167 template <typename T>
0168 void l1ct::multififo_regionizer::RegionBuilder<T>::push(const T& in) {
0169   unsigned int i = 0, nsort = sortbuffer_.size();
0170   T work = in;
0171   while (i < nsort && in.hwPt <= sortbuffer_[i].hwPt)
0172     i++;
0173   while (i < nsort) {
0174     std::swap(work, sortbuffer_[i]);
0175     i++;
0176   }
0177 }
0178 
0179 template <typename T>
0180 void l1ct::multififo_regionizer::RegionBuilder<T>::pop(RegionMux<T>& out) {
0181   out.push(iregion_, sortbuffer_);
0182 }
0183 
0184 template <typename T>
0185 void l1ct::multififo_regionizer::RegionMux<T>::push(unsigned int region, std::vector<T>& in) {
0186   assert(nregions_ > 0);
0187   assert(region < nregions_);
0188   assert(in.size() == nsort_);
0189   for (unsigned int i = 0, n = in.size(); i < n; ++i) {
0190     shift(in[i], buffer_[region * nsort_ + i]);
0191   }
0192 }
0193 
0194 template <typename T>
0195 bool l1ct::multififo_regionizer::RegionMux<T>::stream(bool newevt, std::vector<T>& out) {
0196   assert(out.size() == nout_);
0197   if (newevt) {
0198     iter_ = 0;
0199     ireg_ = 0;
0200   }
0201   if (ireg_ < nregions_) {
0202     if (!streaming_) {
0203       for (unsigned int i = 0; i < nout_; ++i) {
0204         out[i] = buffer_[ireg_ * nsort_ + i];
0205       }
0206     } else {
0207       for (unsigned int i = 0, j = 0; i < nout_; ++i, j += outii_) {
0208         if (j < nsort_) {
0209           out[i] = buffer_[ireg_ * nsort_ + j];
0210         } else {
0211           out[i].clear();
0212         }
0213       }
0214       for (unsigned int i = 1; i < nsort_; ++i) {
0215         shift(buffer_[ireg_ * nsort_ + i], buffer_[ireg_ * nsort_ + i - 1]);
0216       }
0217     }
0218     if (iter_ >= outii_) {
0219       assert(pauseii_ > 0);
0220       for (unsigned int i = 0; i < nout_; ++i) {
0221         out[i].clear();
0222       }
0223     }
0224     if (++iter_ >= (outii_ + pauseii_)) {
0225       ireg_++;
0226       iter_ = 0;
0227     }
0228     return true;
0229   } else {
0230     for (unsigned int i = 0; i < nout_; ++i) {
0231       out[i].clear();
0232     }
0233     return false;
0234   }
0235 }
0236 
0237 template <typename T>
0238 l1ct::multififo_regionizer::Regionizer<T>::Regionizer(unsigned int nsorted,
0239                                                       unsigned int nout,
0240                                                       bool streaming,
0241                                                       unsigned int outii,
0242                                                       unsigned int pauseii,
0243                                                       bool useAlsoVtxCoords)
0244     : nsectors_(0),
0245       nregions_(0),
0246       nsorted_(nsorted),
0247       nout_(nout),
0248       outii_(outii),
0249       pauseii_(pauseii),
0250       streaming_(streaming),
0251       useAlsoVtxCoords_(useAlsoVtxCoords),
0252       nevt_(0) {}
0253 
0254 template <typename T>
0255 void l1ct::multififo_regionizer::Regionizer<T>::initSectors(const std::vector<DetectorSector<T>>& sectors) {
0256   assert(nsectors_ == 0);
0257   nsectors_ = sectors.size();
0258   sectors_.resize(nsectors_);
0259   for (unsigned int i = 0; i < nsectors_; ++i) {
0260     sectors_[i] = sectors[i].region;
0261   }
0262 }
0263 
0264 template <typename T>
0265 void l1ct::multififo_regionizer::Regionizer<T>::initSectors(const DetectorSector<T>& sector) {
0266   assert(nsectors_ == 0);
0267   nsectors_ = 1;
0268   sectors_.resize(1, sector.region);
0269 }
0270 
0271 template <typename T>
0272 void l1ct::multififo_regionizer::Regionizer<T>::initRegions(const std::vector<PFInputRegion>& regions) {
0273   assert(nregions_ == 0);
0274   unsigned int nregions = regions.size();
0275   nregions_ = nregions;
0276   // buffers and builders
0277   buffers_.resize(nregions);
0278   builders_.resize(nregions);
0279   for (unsigned int i = 0; i < nregions; ++i) {
0280     buffers_[i].initRegion(regions[i].region, useAlsoVtxCoords_);
0281     builders_[i] = RegionBuilder<T>(i, nsorted_);
0282   }
0283   // bigmux
0284   bigmux_ = RegionMux<T>(nregions, nsorted_, nout_, streaming_, outii_, pauseii_);
0285 }
0286 
0287 template <typename T>
0288 void l1ct::multififo_regionizer::Regionizer<T>::initRouting(const std::vector<Route> routes, bool validateRoutes) {
0289   assert(nregions_ > 0 && routes_.empty());
0290   routes_ = routes;
0291   std::vector<unsigned int> nfifos(nregions_, 0);
0292   for (const auto& r : routes) {
0293     assert(r.region < nregions_);
0294     nfifos[r.region] = std::max<unsigned int>(nfifos[r.region], r.fifo + 1);
0295   }
0296   for (unsigned int i = 0; i < nregions_; ++i) {
0297     buffers_[i].initFifos(nfifos[i]);
0298   }
0299 
0300   if (validateRoutes) {
0301     std::vector<std::vector<Route>> routed(nregions_);
0302     for (unsigned int i = 0; i < nregions_; ++i) {
0303       routed[i].reserve(nfifos[i]);
0304       for (unsigned int j = 0; j < nfifos[i]; ++j) {
0305         routed[i].emplace_back(0, 0, nregions_, 0);
0306       }
0307     }
0308     for (const auto& r : routes) {
0309       if (routed[r.region][r.fifo].region != nregions_) {
0310         dbgPrintf("ERROR: duplicate route: %u,%u -> %u,%u and %u,%u -> %u,%u\n",
0311                   routed[r.region][r.fifo].sector,
0312                   routed[r.region][r.fifo].link,
0313                   routed[r.region][r.fifo].region,
0314                   routed[r.region][r.fifo].fifo,
0315                   r.sector,
0316                   r.link,
0317                   r.region,
0318                   r.fifo);
0319       }
0320       routed[r.region][r.fifo] = r;
0321     }
0322     for (unsigned int i = 0; i < nregions_; ++i) {
0323       for (unsigned int j = 0; j < nfifos[i]; ++j) {
0324         if (routed[i][j].region == nregions_) {
0325           dbgPrintf("ERROR: missing route to %u,%u\n", i, j);
0326         }
0327       }
0328     }
0329   }
0330 }
0331 
0332 template <typename T>
0333 bool l1ct::multififo_regionizer::Regionizer<T>::step(bool newEvent,
0334                                                      const std::vector<T>& links,
0335                                                      std::vector<T>& out,
0336                                                      bool mux) {
0337   if (newEvent) {
0338     flush();
0339     nevt_++;
0340   }
0341   unsigned int nlinks_sector = links.size() / nsectors_;
0342   for (const auto& r : routes_) {
0343     unsigned int index = nlinks_sector * r.sector + r.link;
0344     //printf("processing route (%2u,%2u)[%2u] -> (%2u,%u)\n", r.sector, r.link, index, r.region, r.fifo);
0345     buffers_[r.region].maybe_push(r.fifo, links[index], sectors_[r.sector]);
0346   }
0347   out.resize(nregions_);
0348   for (unsigned int i = 0; i < nregions_; ++i) {
0349     out[i] = buffers_[i].pop();
0350   }
0351   if (mux) {
0352     std::vector<T> work;
0353     std::swap(work, out);
0354     return muxonly_step(newEvent, /*flush=*/false, work, out);  // don't flush twice
0355   } else {
0356     return true;
0357   }
0358 }
0359 
0360 template <typename T>
0361 bool l1ct::multififo_regionizer::Regionizer<T>::muxonly_step(bool newEvent,
0362                                                              bool mayFlush,
0363                                                              const std::vector<T>& nomux_out,
0364                                                              std::vector<T>& out) {
0365   if (newEvent && mayFlush) {
0366     flush();
0367     nevt_++;
0368   }
0369   assert(nomux_out.size() == nregions_);
0370   out.resize(nout_);
0371   for (unsigned int i = 0; i < nregions_; ++i) {
0372     if (newEvent)
0373       builders_[i].pop(bigmux_);
0374     builders_[i].push(nomux_out[i]);
0375   }
0376   return bigmux_.stream(newEvent && (nevt_ > 1), out);
0377 }
0378 
0379 template <typename T>
0380 void l1ct::multififo_regionizer::Regionizer<T>::destream(int iclock,
0381                                                          const std::vector<T>& streams,
0382                                                          std::vector<T>& out) {
0383   assert(streaming_ && outii_ > 0);
0384   assert(streams.size() == nout_);
0385   unsigned int local_clk = iclock % (outii_ + pauseii_);
0386   if (local_clk == 0) {
0387     out.resize(nsorted_);
0388     for (auto& o : out)
0389       o.clear();
0390   }
0391   for (unsigned int i = 0, j = local_clk; j < nsorted_; ++i, j += outii_) {
0392     if (local_clk < outii_)
0393       out[j] = streams[i];
0394     else
0395       out[j].clear();
0396   }
0397 }