artdaq  v3_11_01
BinaryNetOutput_module.cc
1 #define TRACE_NAME "BinaryNetOutput"
2 #include "artdaq/DAQdata/Globals.hh"
3 
4 #include "art/Framework/Core/ModuleMacros.h"
5 #include "art/Framework/Core/OutputModule.h"
6 #include "art/Framework/Principal/EventPrincipal.h"
7 #include "art/Framework/Principal/Handle.h"
8 #include "art/Framework/Principal/RunPrincipal.h"
9 #include "art/Framework/Principal/Selector.h"
10 #include "art/Framework/Principal/SubRunPrincipal.h"
11 #include "art/Persistency/Common/GroupQueryResult.h"
12 #include "art/Persistency/Provenance/ModuleContext.h"
13 #include "canvas/Persistency/Common/Wrapper.h"
14 #include "canvas/Utilities/DebugMacros.h"
15 #include "canvas/Utilities/Exception.h"
16 #if ART_HEX_VERSION < 0x30901
17 #include "canvas/Utilities/WrappedTypeID.h"
18 #else
19 #include "canvas/Persistency/Common/WrappedTypeID.h"
20 #endif
21 #include "fhiclcpp/ParameterSet.h"
22 
23 #include "artdaq-core/Data/Fragment.hh"
24 #include "artdaq/DAQrate/DataSenderManager.hh"
25 
26 #include <unistd.h>
27 #include <iomanip>
28 #include <iostream>
29 #include <memory>
30 #include <sstream>
31 #include <string>
32 #include <vector>
33 
34 namespace art {
35 class BinaryNetOutput;
36 }
37 
39 using fhicl::ParameterSet;
40 
46 class art::BinaryNetOutput final : public OutputModule
47 {
48 public:
61  explicit BinaryNetOutput(ParameterSet const& ps);
62 
66  ~BinaryNetOutput() override;
67 
68 private:
69  BinaryNetOutput(BinaryNetOutput const&) = delete;
70  BinaryNetOutput(BinaryNetOutput&&) = delete;
71  BinaryNetOutput& operator=(BinaryNetOutput const&) = delete;
72  BinaryNetOutput& operator=(BinaryNetOutput&&) = delete;
73 
74  void beginJob() override;
75 
76  void endJob() override;
77 
78  void write(EventPrincipal& /*ep*/) override;
79 
80  void writeRun(RunPrincipal& /*r*/) override{};
81  void writeSubRun(SubRunPrincipal& /*sr*/) override{};
82 
83  void initialize_MPI_();
84 
85  void deinitialize_MPI_();
86 
87  bool readParameterSet_(fhicl::ParameterSet const& pset);
88 
89 private:
90  ParameterSet data_pset_;
91  std::string name_ = "BinaryNetOutput";
92  int rt_priority_ = 0;
93  std::unique_ptr<artdaq::DataSenderManager> sender_ptr_ = {nullptr};
94 };
95 
97  : OutputModule(ps)
98 {
99  TLOG(TLVL_DEBUG) << "Begin: BinaryNetOutput::BinaryNetOutput(ParameterSet const& ps)\n";
100  readParameterSet_(ps);
101  TLOG(TLVL_DEBUG) << "End: BinaryNetOutput::BinaryNetOutput(ParameterSet const& ps)\n";
102 }
103 
104 art::BinaryNetOutput::~BinaryNetOutput() { TLOG(TLVL_DEBUG) << "Begin/End: BinaryNetOutput::~BinaryNetOutput()\n"; }
105 
106 void art::BinaryNetOutput::beginJob()
107 {
108  TLOG(TLVL_DEBUG) << "Begin: BinaryNetOutput::beginJob()\n";
109  initialize_MPI_();
110  TLOG(TLVL_DEBUG) << "End: BinaryNetOutput::beginJob()\n";
111 }
112 
113 void art::BinaryNetOutput::endJob()
114 {
115  TLOG(TLVL_DEBUG) << "Begin: BinaryNetOutput::endJob()\n";
116  deinitialize_MPI_();
117  TLOG(TLVL_DEBUG) << "End: BinaryNetOutput::endJob()\n";
118 }
119 
120 void art::BinaryNetOutput::initialize_MPI_()
121 {
122  if (rt_priority_ > 0)
123  {
124 #pragma GCC diagnostic push
125 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
126  sched_param s_param = {};
127  s_param.sched_priority = rt_priority_;
128  int status = pthread_setschedparam(pthread_self(), SCHED_RR, &s_param);
129  if (status != 0)
130  {
131  TLOG(TLVL_ERROR) << name_ << "Failed to set realtime priority to " << rt_priority_
132  << ", return code = " << status;
133  }
134 #pragma GCC diagnostic pop
135  }
136 
137  sender_ptr_ = std::make_unique<artdaq::DataSenderManager>(data_pset_);
138  assert(sender_ptr_);
139 }
140 
141 void art::BinaryNetOutput::deinitialize_MPI_() { sender_ptr_.reset(nullptr); }
142 
143 bool art::BinaryNetOutput::readParameterSet_(fhicl::ParameterSet const& pset)
144 {
145  TLOG(TLVL_DEBUG) << name_ << "BinaryNetOutput::readParameterSet_ method called with "
146  << "ParameterSet = \"" << pset.to_string() << "\".";
147 
148  // determine the data sending parameters
149  data_pset_ = pset;
150  name_ = pset.get<std::string>("module_name", "BinaryNetOutput");
151  rt_priority_ = pset.get<int>("rt_priority", 0);
152 
153  TLOG(TLVL_TRACE) << "BinaryNetOutput::readParameterSet()";
154 
155  return true;
156 }
157 
158 void art::BinaryNetOutput::write(EventPrincipal& ep)
159 {
160  assert(sender_ptr_);
161 
162  using RawEvent = artdaq::Fragments;
163  ;
164  using RawEvents = std::vector<RawEvent>;
165  using RawEventHandle = art::Handle<RawEvent>;
166  using RawEventHandles = std::vector<RawEventHandle>;
167 
168  auto result_handles = std::vector<art::GroupQueryResult>();
169 
170  auto const& wrapped = art::WrappedTypeID::make<RawEvent>();
171 
172  ModuleContext const mc{moduleDescription()};
173  ProcessTag const processTag{"", mc.moduleDescription().processName()};
174 
175  result_handles = ep.getMany(mc, wrapped, art::MatchAllSelector{}, processTag);
176 
177  artdaq::Fragment::sequence_id_t sequence_id = 0;
178 
179  for (auto const& result_handle : result_handles)
180  {
181  auto const raw_event_handle = RawEventHandle(result_handle);
182 
183  if (!raw_event_handle.isValid())
184  {
185  continue;
186  }
187 
188  for (auto const& fragment : *raw_event_handle)
189  {
190  auto fragment_copy = fragment;
191  auto fragid_id = fragment_copy.fragmentID();
192  sequence_id = fragment_copy.sequenceID();
193  TLOG(TLVL_DEBUG) << "BinaryNetOutput::write seq=" << sequence_id << " frag=" << fragid_id << " start";
194  sender_ptr_->sendFragment(std::move(fragment_copy));
195  TLOG(TLVL_DEBUG) << "BinaryNetOutput::write seq=" << sequence_id << " frag=" << fragid_id << " done";
196  }
197  }
198 
199  // Events are unique in art, so this will be the only send with this sequence ID!
200  // ELF 1/23/2020: Only remove routing entry AFTER all Fragments have been sent!
201  sender_ptr_->RemoveRoutingTableEntry(sequence_id);
202 }
203 
204 DEFINE_ART_MODULE(art::BinaryNetOutput) // NOLINT(performance-unnecessary-value-param)
BinaryNetOutput(ParameterSet const &ps)
BinaryNetOutput Constructor.
An art::OutputModule which sends Fragments using DataSenderManager. This module produces output ident...
~BinaryNetOutput() override
BinaryNetOutput Destructor.