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 ) {
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
0028
0029
0030
0031
0032
0033
0034
0035
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
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
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
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
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
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
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, false, work, out);
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 }