31 #include <string_view>
37 uint32_t interpretGenericParam(
const std::string& parvalue) {
39 std::string_view parvalue_sv = parvalue;
40 auto [
ptr, ec] = std::from_chars(parvalue_sv.data(), parvalue_sv.data() + parvalue_sv.size(),
val);
41 if (ec != std::errc()) {
42 if( parvalue.size()>=3 && parvalue[0]==
':' and parvalue[parvalue.size()-1]==
':' ) {
46 string parname = parvalue.substr(1,parvalue.size()-2);
49 val =
x->second.value;
51 cout <<
"Hardware constrained parameters are" << endl;
53 cout <<
" " <<
x.first << endl;
55 TCS_EXCEPTION(
"Generic parameter value " << parvalue <<
" has the hardware contrained parameter format, but '" <<
parname <<
"' is not listed in L1TopoHardware.cxx");
58 TCS_EXCEPTION(
"Generic parameter value " << parvalue <<
" is not a uint32_t and does not match the hardware contrained parameter specification ':<parname>:' ");
88 o <<
"Topo Steering Structure" << endl
89 <<
"-----------------------" << endl;
91 o <<
"Output summary:" << endl;
92 for(
const auto &
conn: outputConnectors() ) {
93 o <<
" " << *
conn.second << endl;
97 <<
"Algorithm detail:" << endl;
98 for(
const auto &
nc: outputConnectors() ) {
100 unsigned int firstBit =
conn->decision().firstBit();
101 unsigned int lastBit =
conn->numberOutputBits() + firstBit - 1;
105 o << std::setw(2) <<
"bits " << firstBit <<
"-" << lastBit <<
": " <<
conn->name() <<
" [input " << inputconn->
name() <<
"]" << endl;
106 o << *
alg << endl << endl;
107 o << *sortalg << endl;
116 if(
ps &&
ps->isInitialized())
117 o <<
"pos " << std::setw(2) <<
idx <<
": " <<
ps << endl;
127 cout <<
"/***************************************************************************/" << endl
128 <<
" L1Topo steering structure: configuring from L1 Topo Menu " << endl
129 <<
"/***************************************************************************/" << endl;
132 vector<string> storedConn;
133 vector<vector<string>> confAlgorithms;
134 vector<string> confMultAlgorithms;
137 string AvailableMultAlgs[] = {
"eEmMultiplicity",
149 for (
const string & boardName :
l1menu.boardNames() ){
151 auto & l1board =
l1menu.board(boardName);
153 if (l1board.type() !=
"TOPO")
continue;
154 if (l1board.legacy() !=
legacy)
continue;
158 for (
const string & connName : l1board.connectorNames() ){
160 auto & l1conn =
l1menu.connector(connName);
166 for(
size_t fpga : { 0, 1} ) {
167 for(
size_t clock : { 0, 1} ) {
168 for(
auto &
tl : l1conn.triggerLines(fpga, clock) ) {
170 const string & tlName =
tl.name();
171 auto & algo =
l1menu.algorithmFromTriggerline(tlName);
172 const string algoName = (
legacy?
"R2_"+algo.name():algo.name());
175 auto it =
find(storedConn.begin(), storedConn.end(), algoName);
176 if (
it == storedConn.end()) {
178 storedConn.push_back(algoName);
179 vector<string> inputNames;
180 for(
auto & input : algo.inputs() ) {
181 if( sortingConnector(input) == 0 ) {
183 cout <<
"L1TopoSteering: Decision algo( " << algo.name() <<
" ) input is not defined: " << input <<
". Creating sortingConnector" << endl;
185 auto & sortAlgo =
l1menu.algorithm(input, algo.category());
187 TCS_EXCEPTION(
"L1TopoSteering: Decision algo " << algo.name() <<
") has as input " << input <<
" which is not associated to a sorting algorithm");
192 cout <<
"Adding sorting connector " <<
"[" << *sortConn <<
"]" << endl;
193 addSortingConnector( sortConn );
194 confAlgorithms.push_back({sortAlgo.name(), sortAlgo.category()});
198 inputNames.push_back(input);
203 conn->m_decision.setNBits( algo.outputs().size() );
205 if(
tl.name() !=
"UNDEF")
206 conn->m_triggers.push_back(
tl);
209 cout <<
"Adding decision connector " <<
"[" << *
conn <<
"]" << endl;
210 addDecisionConnector(
conn );
211 confAlgorithms.push_back({algo.name(), algo.category()});
214 for(
const auto &
out : algo.outputs()){
215 auto c = m_outputLookup.find(
out);
216 if (
c != m_outputLookup.end()){
217 auto conn =
c->second;
218 if(
tl.name() !=
"UNDEF")
219 conn->m_triggers.push_back(
tl);
236 for(
auto &
tl : l1conn.triggerLines(0, 0) ) {
238 const string & tlName =
tl.name();
239 auto & algo =
l1menu.algorithmFromTriggerline(tlName);
241 string algo_klass = algo.klass();
242 if(algo_klass==
"eEmVarMultiplicity") algo_klass=
"eEmMultiplicity";
247 if ( algo_klass ==
"ZeroBias" )
continue;
249 auto it =
find(storedConn.begin(), storedConn.end(), algo.name());
250 if (
it == storedConn.end()) {
252 storedConn.push_back(algo.name());
254 cout <<
"L1TopoSteering: Multiplicity algo( " << algo.name() <<
" ) has as input " << algo.inputs().at(0) << endl;
257 conn->m_count.setNBits(
tl.nbits() );
258 conn->m_count.setFirstBit(
tl.startbit() );
260 if(
tl.name() !=
"UNDEF")
261 conn->m_triggers.push_back(
tl);
264 cout <<
"Adding count connector " <<
"[" << *
conn <<
"]" << endl;
265 addCountingConnector(
conn );
266 confMultAlgorithms.push_back( algo.name() );
279 cout <<
"... building input connectors" << endl;
280 for(
const auto & sortConn : m_sortedLookup) {
281 const string & in = sortConn.second->inputNames()[0];
283 if( m_inputLookup.count(in) > 0 )
continue;
286 m_connectors.push_back(
conn);
287 m_inputLookup[in] =
conn;
289 cout <<
"Adding input connector " <<
"[" << *
conn <<
"]" << endl;
291 for(
const auto & countConn : m_countLookup) {
292 const string & in = countConn.second->inputNames()[0];
294 if( m_inputLookup.count(in) > 0 )
continue;
297 m_connectors.push_back(
conn);
298 m_inputLookup[in] =
conn;
300 cout <<
"Adding input connector " <<
"[" << *
conn <<
"]" << endl;
308 cout <<
"... instantiating algorithms" << endl;
309 sc &= instantiateAlgorithms(
debug);
314 cout <<
"... setting algorithm parameters" << endl;
316 for (
auto & confAlgo : confAlgorithms ) {
318 auto & l1algo =
l1menu.algorithm(confAlgo.at(0), confAlgo.at(1));
319 auto l1algoName = confAlgo.at(0);
321 l1algoName =
"R2_"+confAlgo.at(0);
324 cout <<
"TopoSteeringStructure: Parameters for algorithm with name " << l1algoName <<
" going to be configured." << endl;
327 if(
alg->isDecisionAlg()){
328 (
static_cast<DecisionAlg *
>(
alg) )->setNumberOutputBits(l1algo.outputs().size());
331 auto ps = std::make_unique<ParameterSpace>(
alg->name());
333 for(
auto &
pe : l1algo.parameters()) {
335 auto & pname =
pe.name();
340 cout <<
"Algo Name: " << l1algoName <<
" parameter " <<
": " << setw(20) << left << pname <<
" value = " << setw(3) << left <<
val <<
" (selection " <<
sel <<
")" << endl;
345 for(
auto &
gen : l1algo.generics().getKeys()) {
347 auto pe = l1algo.generics().getObject(
gen);
349 uint32_t val = interpretGenericParam(
pe.getAttribute(
"value"));
350 if (pname ==
"NumResultBits"){
351 if(
val != l1algo.outputs().size()) {
352 TCS_EXCEPTION(
"Algorithm " << pname <<
" parameter OutputBits (" <<
val <<
") is different from output size (" << l1algo.outputs().size() <<
")");
357 cout <<
" fixed parameter : " << setw(20) << left << pname <<
" value = " << setw(3) << left <<
val << endl;
358 ps->addParameter( pname,
val );
364 cout <<
" (setting parameters)";
365 alg->setParameters( *
ps );
368 cout <<
" --> (parameters set)";
371 cout <<
" --> (parameters stored)" << endl;
375 for (
auto & multAlgo : confMultAlgorithms ) {
377 auto & l1algo =
l1menu.algorithm(multAlgo,
"MULTTOPO");
381 if ( l1algo.klass() ==
"ZeroBias" )
continue;
387 auto & l1thr =
l1menu.threshold( l1algo.outputs().at(0) );
389 if (not pCountAlg)
continue;
395 m_isConfigured =
true;
398 cout <<
"... L1TopoSteering successfully configured" << endl;
407 for(
const string & output :
conn->outputNames() )
415 for(
const string & output :
conn->outputNames() )
424 for(
const string & output :
conn->outputNames() )
434 for(
const std::string & inconn:
conn->inputNames())
446 if(
conn->isInputConnector())
continue;
449 const std::string &
alg =
conn->algorithmName();
452 std::string algType(
alg, 0,
alg.find(
'/'));
458 cout <<
"Instantiating " <<
alg << endl;
459 algInstance = TCS::AlgFactory::mutable_instance().create(algType,
algName);
461 if(algInstance->
className() != algType) {
462 TCS_EXCEPTION(
"L1 TopoSteering: duplicate algorithm names: algorithm " <<
algName <<
" has already been instantiated but with different type");
465 conn->setAlgorithm(algInstance);
474 if(
conn->name() == connectorName )
477 TCS_EXCEPTION(
"L1Topo Steering: can not find connector of name " << connectorName <<
". Need to abort!");
486 if(
conn->name() == connectorName ) {
489 TCS_EXCEPTION(
"TopoSteeringStructure: connector of name " << connectorName <<
" exists, but is not a SortingConnector. Need to abort!");
501 auto c = m_outputLookup.find(output);
502 if(
c != m_outputLookup.end() )
504 TCS_EXCEPTION(
"L1Topo Steering: can not find output connector of that produces " << output <<
". Need to abort!");
511 auto c = m_countLookup.find(output);
512 if(
c != m_countLookup.end() )
514 TCS_EXCEPTION(
"L1Topo Steering: can not find counting connector of that produces " << output <<
". Need to abort!");