30 #include <boost/lexical_cast.hpp>
34 using boost::lexical_cast;
37 uint32_t interpretGenericParam(
const std::string& parvalue) {
40 val = lexical_cast<uint32_t, string>(parvalue);
42 catch(
const boost::bad_lexical_cast & bc) {
43 if( parvalue.size()>=3 && parvalue[0]==
':' and parvalue[parvalue.size()-1]==
':' ) {
47 string parname = parvalue.substr(1,parvalue.size()-2);
50 val =
x->second.value;
52 cout <<
"Hardware constrained parameters are" << endl;
54 cout <<
" " <<
x.first << endl;
56 TCS_EXCEPTION(
"Generic parameter value " << parvalue <<
" has the hardware contrained parameter format, but '" <<
parname <<
"' is not listed in L1TopoHardware.cxx");
59 TCS_EXCEPTION(
"Generic parameter value " << parvalue <<
" is not a uint32_t and does not match the hardware contrained parameter specification ':<parname>:' ");
89 o <<
"Topo Steering Structure" << endl
90 <<
"-----------------------" << endl;
92 o <<
"Output summary:" << endl;
93 for(
const auto &
conn: outputConnectors() ) {
94 o <<
" " << *
conn.second << endl;
98 <<
"Algorithm detail:" << endl;
99 for(
const auto &
nc: outputConnectors() ) {
101 unsigned int firstBit =
conn->decision().firstBit();
102 unsigned int lastBit =
conn->numberOutputBits() + firstBit - 1;
106 o << std::setw(2) <<
"bits " << firstBit <<
"-" << lastBit <<
": " <<
conn->name() <<
" [input " << inputconn->
name() <<
"]" << endl;
107 o << *
alg << endl << endl;
108 o << *sortalg << endl;
117 if(ps && ps->isInitialized())
118 o <<
"pos " << std::setw(2) <<
idx <<
": " << ps << endl;
128 cout <<
"/***************************************************************************/" << endl
129 <<
" L1Topo steering structure: configuring from L1 Topo Menu " << endl
130 <<
"/***************************************************************************/" << endl;
133 vector<string> storedConn;
134 vector<vector<string>> confAlgorithms;
135 vector<string> confMultAlgorithms;
138 string AvailableMultAlgs[] = {
"eEmMultiplicity",
150 for (
const string & boardName :
l1menu.boardNames() ){
152 auto & l1board =
l1menu.board(boardName);
154 if (l1board.type() !=
"TOPO")
continue;
155 if (l1board.legacy() !=
legacy)
continue;
159 for (
const string & connName : l1board.connectorNames() ){
161 auto & l1conn =
l1menu.connector(connName);
167 for(
size_t fpga : { 0, 1} ) {
168 for(
size_t clock : { 0, 1} ) {
169 for(
auto &
tl : l1conn.triggerLines(fpga, clock) ) {
171 const string & tlName =
tl.name();
172 auto & algo =
l1menu.algorithmFromTriggerline(tlName);
173 const string algoName = (
legacy?
"R2_"+algo.name():algo.name());
176 auto it =
find(storedConn.begin(), storedConn.end(), algoName);
177 if (
it == storedConn.end()) {
179 storedConn.push_back(algoName);
180 vector<string> inputNames;
181 for(
auto &
input : algo.inputs() ) {
182 if( sortingConnector(
input) == 0 ) {
184 cout <<
"L1TopoSteering: Decision algo( " << algo.name() <<
" ) input is not defined: " <<
input <<
". Creating sortingConnector" << endl;
186 auto & sortAlgo =
l1menu.algorithm(
input, algo.category());
188 TCS_EXCEPTION(
"L1TopoSteering: Decision algo " << algo.name() <<
") has as input " <<
input <<
" which is not associated to a sorting algorithm");
193 cout <<
"Adding sorting connector " <<
"[" << *sortConn <<
"]" << endl;
194 addSortingConnector( sortConn );
195 confAlgorithms.push_back({sortAlgo.name(), sortAlgo.category()});
199 inputNames.push_back(
input);
204 conn->m_decision.setNBits( algo.outputs().size() );
206 if(
tl.name() !=
"UNDEF")
207 conn->m_triggers.push_back(
tl);
210 cout <<
"Adding decision connector " <<
"[" << *
conn <<
"]" << endl;
211 addDecisionConnector(
conn );
212 confAlgorithms.push_back({algo.name(), algo.category()});
215 for(
const auto &
out : algo.outputs()){
216 auto c = m_outputLookup.find(
out);
217 if (
c != m_outputLookup.end()){
218 auto conn =
c->second;
219 if(
tl.name() !=
"UNDEF")
220 conn->m_triggers.push_back(
tl);
237 for(
auto &
tl : l1conn.triggerLines(0, 0) ) {
239 const string & tlName =
tl.name();
240 auto & algo =
l1menu.algorithmFromTriggerline(tlName);
242 string algo_klass = algo.klass();
243 if(algo_klass==
"eEmVarMultiplicity") algo_klass=
"eEmMultiplicity";
248 if ( algo_klass ==
"ZeroBias" )
continue;
250 auto it =
find(storedConn.begin(), storedConn.end(), algo.name());
251 if (
it == storedConn.end()) {
253 storedConn.push_back(algo.name());
255 cout <<
"L1TopoSteering: Multiplicity algo( " << algo.name() <<
" ) has as input " << algo.inputs().at(0) << endl;
258 conn->m_count.setNBits(
tl.nbits() );
259 conn->m_count.setFirstBit(
tl.startbit() );
261 if(
tl.name() !=
"UNDEF")
262 conn->m_triggers.push_back(
tl);
265 cout <<
"Adding count connector " <<
"[" << *
conn <<
"]" << endl;
266 addCountingConnector(
conn );
267 confMultAlgorithms.push_back( algo.name() );
280 cout <<
"... building input connectors" << endl;
281 for(
const auto & sortConn : m_sortedLookup) {
282 const string & in = sortConn.second->inputNames()[0];
284 if( m_inputLookup.count(in) > 0 )
continue;
287 m_connectors.push_back(
conn);
288 m_inputLookup[in] =
conn;
290 cout <<
"Adding input connector " <<
"[" << *
conn <<
"]" << endl;
292 for(
const auto & countConn : m_countLookup) {
293 const string & in = countConn.second->inputNames()[0];
295 if( m_inputLookup.count(in) > 0 )
continue;
298 m_connectors.push_back(
conn);
299 m_inputLookup[in] =
conn;
301 cout <<
"Adding input connector " <<
"[" << *
conn <<
"]" << endl;
309 cout <<
"... instantiating algorithms" << endl;
310 sc &= instantiateAlgorithms(
debug);
315 cout <<
"... setting algorithm parameters" << endl;
317 for (
auto & confAlgo : confAlgorithms ) {
319 auto & l1algo =
l1menu.algorithm(confAlgo.at(0), confAlgo.at(1));
320 auto l1algoName = confAlgo.at(0);
322 l1algoName =
"R2_"+confAlgo.at(0);
325 cout <<
"TopoSteeringStructure: Parameters for algorithm with name " << l1algoName <<
" going to be configured." << endl;
328 if(
alg->isDecisionAlg()){
329 (
static_cast<DecisionAlg *
>(
alg) )->setNumberOutputBits(l1algo.outputs().size());
332 auto ps = std::make_unique<ParameterSpace>(
alg->name());
334 for(
auto &
pe : l1algo.parameters()) {
336 auto & pname =
pe.name();
341 cout <<
"Algo Name: " << l1algoName <<
" parameter " <<
": " << setw(20) << left << pname <<
" value = " << setw(3) << left <<
val <<
" (selection " <<
sel <<
")" << endl;
342 ps->addParameter( pname,
val,
sel);
346 for(
auto &
gen : l1algo.generics().getKeys()) {
348 auto pe = l1algo.generics().getObject(
gen);
350 uint32_t val = interpretGenericParam(
pe.getAttribute(
"value"));
351 if (pname ==
"NumResultBits"){
352 if(
val != l1algo.outputs().size()) {
353 TCS_EXCEPTION(
"Algorithm " << pname <<
" parameter OutputBits (" <<
val <<
") is different from output size (" << l1algo.outputs().size() <<
")");
358 cout <<
" fixed parameter : " << setw(20) << left << pname <<
" value = " << setw(3) << left <<
val << endl;
359 ps->addParameter( pname,
val );
365 cout <<
" (setting parameters)";
366 alg->setParameters( *ps );
369 cout <<
" --> (parameters set)";
372 cout <<
" --> (parameters stored)" << endl;
376 for (
auto & multAlgo : confMultAlgorithms ) {
378 auto & l1algo =
l1menu.algorithm(multAlgo,
"MULTTOPO");
382 if ( l1algo.klass() ==
"ZeroBias" )
continue;
388 auto & l1thr =
l1menu.threshold( l1algo.outputs().at(0) );
390 if (not pCountAlg)
continue;
396 m_isConfigured =
true;
399 cout <<
"... L1TopoSteering successfully configured" << endl;
408 for(
const string &
output :
conn->outputNames() )
416 for(
const string &
output :
conn->outputNames() )
425 for(
const string &
output :
conn->outputNames() )
435 for(
const std::string & inconn:
conn->inputNames())
447 if(
conn->isInputConnector())
continue;
450 const std::string &
alg =
conn->algorithmName();
453 std::string algType(
alg, 0,
alg.find(
'/'));
459 cout <<
"Instantiating " <<
alg << endl;
460 algInstance = TCS::AlgFactory::mutable_instance().create(algType,
algName);
462 if(algInstance->
className() != algType) {
463 TCS_EXCEPTION(
"L1 TopoSteering: duplicate algorithm names: algorithm " <<
algName <<
" has already been instantiated but with different type");
466 conn->setAlgorithm(algInstance);
475 if(
conn->name() == connectorName )
478 TCS_EXCEPTION(
"L1Topo Steering: can not find connector of name " << connectorName <<
". Need to abort!");
487 if(
conn->name() == connectorName ) {
490 TCS_EXCEPTION(
"TopoSteeringStructure: connector of name " << connectorName <<
" exists, but is not a SortingConnector. Need to abort!");
502 auto c = m_outputLookup.find(
output);
503 if(
c != m_outputLookup.end() )
505 TCS_EXCEPTION(
"L1Topo Steering: can not find output connector of that produces " <<
output <<
". Need to abort!");
512 auto c = m_countLookup.find(
output);
513 if(
c != m_countLookup.end() )
515 TCS_EXCEPTION(
"L1Topo Steering: can not find counting connector of that produces " <<
output <<
". Need to abort!");