00001 #define TRACE_NAME "NthEventPolicy" 00002 #include "artdaq/Application/Routing/RoutingMasterPolicy.hh" 00003 #include "artdaq/Application/Routing/PolicyMacros.hh" 00004 #include "fhiclcpp/ParameterSet.h" 00005 #include "cetlib_except/exception.h" 00006 00007 namespace artdaq 00008 { 00013 class NthEventPolicy : public RoutingMasterPolicy 00014 { 00015 public: 00016 explicit NthEventPolicy(fhicl::ParameterSet ps); 00017 00018 virtual ~NthEventPolicy() { } 00019 00020 detail::RoutingPacket GetCurrentTable() override; 00021 private: 00022 size_t nth_; 00023 int nth_rank_; 00024 }; 00025 00036 NthEventPolicy::NthEventPolicy(fhicl::ParameterSet ps) 00037 : RoutingMasterPolicy(ps) 00038 , nth_(ps.get<size_t>("nth_event")) 00039 , nth_rank_(ps.get<int>("target_receiver")) 00040 { 00041 if (nth_ == 0) throw cet::exception("NthEvent_policy") << "nth_event must be greater than 0!"; 00042 } 00043 00050 detail::RoutingPacket NthEventPolicy::GetCurrentTable() 00051 { 00052 auto tokens = getTokensSnapshot(); 00053 std::map<int, int> table; 00054 for (auto token : *tokens.get()) 00055 { 00056 table[token]++; 00057 } 00058 if (table.count(nth_rank_) == 0) table[nth_rank_] = 0; 00059 tokens->clear(); 00060 00061 detail::RoutingPacket output; 00062 TLOG(5) << "table[nth_rank_]=" << std::to_string(table[nth_rank_]) 00063 << ", Next nth=" << std::to_string(((next_sequence_id_ / nth_) + 1) * nth_) 00064 << ", max seq=" << std::to_string(next_sequence_id_ + table.size() - 1) ; 00065 auto endCondition = table.size() < GetReceiverCount() || (table[nth_rank_] <= 0 && (next_sequence_id_ % nth_ == 0 || ((next_sequence_id_ / nth_) + 1) * nth_ < next_sequence_id_ + table.size() - 1)); 00066 while (!endCondition) 00067 { 00068 for (auto r : table) 00069 { 00070 TLOG(5) << "nth_=" << std::to_string(nth_) 00071 << ", nth_rank=" << std::to_string(nth_rank_) 00072 << ", r=" << std::to_string(r.first) 00073 << ", next_sequence_id=" << std::to_string(next_sequence_id_) ; 00074 if (next_sequence_id_ % nth_ == 0) 00075 { 00076 TLOG(5) << "Diverting event " << std::to_string(next_sequence_id_) << " to EVB " << nth_rank_ ; 00077 output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, nth_rank_)); 00078 table[nth_rank_]--; 00079 } 00080 if (r.first != nth_rank_) { 00081 TLOG(5) << "Sending event " << std::to_string(next_sequence_id_) << " to EVB " << r.first ; 00082 output.emplace_back(detail::RoutingPacketEntry(next_sequence_id_++, r.first)); 00083 if (!endCondition) endCondition = r.second == 1; 00084 table[r.first]--; 00085 } 00086 } 00087 TLOG(5) << "table[nth_rank_]=" << std::to_string(table[nth_rank_]) 00088 << ", Next nth=" << std::to_string(((next_sequence_id_ / nth_) + 1) * nth_) 00089 << ", max seq=" << std::to_string(next_sequence_id_ + table.size() - 1) ; 00090 endCondition = endCondition || (table[nth_rank_] <= 0 && (next_sequence_id_ % nth_ == 0 || (next_sequence_id_ / nth_) * nth_ + nth_ < next_sequence_id_ + table.size() - 1)); 00091 } 00092 00093 for (auto r : table) 00094 { 00095 for (auto i = 0; i < r.second; ++i) 00096 { 00097 tokens->push_back(r.first); 00098 } 00099 } 00100 addUnusedTokens(std::move(tokens)); 00101 00102 return output; 00103 } 00104 } 00105 00106 DEFINE_ARTDAQ_ROUTING_POLICY(artdaq::NthEventPolicy)