artdaq  v2_02_03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Pages
BinaryMPIOutput_module.cc
1 #include "art/Framework/Core/ModuleMacros.h"
2 #include "art/Framework/Core/OutputModule.h"
3 #include "art/Framework/Principal/EventPrincipal.h"
4 #include "art/Framework/Principal/RunPrincipal.h"
5 #include "art/Framework/Principal/SubRunPrincipal.h"
6 #include "art/Framework/Principal/Handle.h"
7 #include "art/Persistency/Common/GroupQueryResult.h"
8 #include "canvas/Utilities/DebugMacros.h"
9 #include "canvas/Utilities/Exception.h"
10 #include "fhiclcpp/ParameterSet.h"
11 
12 #include "artdaq/DAQrate/DataSenderManager.hh"
13 #include "artdaq/DAQdata/Globals.hh"
14 #include "artdaq-core/Data/Fragment.hh"
15 
16 #define TRACE_NAME "BinaryMPIOutput"
17 
18 #include <iomanip>
19 #include <iostream>
20 #include <sstream>
21 #include <string>
22 #include <vector>
23 #include <memory>
24 #include "unistd.h"
25 
26 namespace art
27 {
28  class BinaryMPIOutput;
29 }
30 
32 using fhicl::ParameterSet;
33 
39 class art::BinaryMPIOutput final: public OutputModule
40 {
41 public:
54  explicit BinaryMPIOutput(ParameterSet const& ps);
55 
59  virtual ~BinaryMPIOutput();
60 
61 private:
62  void beginJob() override;
63 
64  void endJob() override;
65 
66  void write(EventPrincipal&) override;
67 
68  void writeRun(RunPrincipal&) override {};
69  void writeSubRun(SubRunPrincipal&) override {};
70 
71  void initialize_MPI_();
72 
73  void deinitialize_MPI_();
74 
75  bool readParameterSet_(fhicl::ParameterSet const& pset);
76 
77 private:
78  ParameterSet data_pset_;
79  std::string name_ = "BinaryMPIOutput";
80  int rt_priority_ = 0;
81  std::unique_ptr<artdaq::DataSenderManager> sender_ptr_ = {nullptr};
82 };
83 
85 BinaryMPIOutput(ParameterSet const& ps)
86  : OutputModule(ps)
87 {
88  FDEBUG(1) << "Begin: BinaryMPIOutput::BinaryMPIOutput(ParameterSet const& ps)\n";
89  readParameterSet_(ps);
90  FDEBUG(1) << "End: BinaryMPIOutput::BinaryMPIOutput(ParameterSet const& ps)\n";
91 }
92 
95 {
96  FDEBUG(1) << "Begin/End: BinaryMPIOutput::~BinaryMPIOutput()\n";
97 }
98 
99 void
100 art::BinaryMPIOutput::
101 beginJob()
102 {
103  FDEBUG(1) << "Begin: BinaryMPIOutput::beginJob()\n";
104  initialize_MPI_();
105  FDEBUG(1) << "End: BinaryMPIOutput::beginJob()\n";
106 }
107 
108 void
109 art::BinaryMPIOutput::
110 endJob()
111 {
112  FDEBUG(1) << "Begin: BinaryMPIOutput::endJob()\n";
113  deinitialize_MPI_();
114  FDEBUG(1) << "End: BinaryMPIOutput::endJob()\n";
115 }
116 
117 
118 void
119 art::BinaryMPIOutput::
120 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_ERROR(name_)
132  << "Failed to set realtime priority to " << rt_priority_
133  << ", return code = " << status << TLOG_ENDL;
134  }
135 #pragma GCC diagnostic pop
136  }
137 
138  sender_ptr_ = std::make_unique<artdaq::DataSenderManager>(data_pset_);
139  assert(sender_ptr_);
140 }
141 
142 void
143 art::BinaryMPIOutput::
144 deinitialize_MPI_()
145 {
146  sender_ptr_.reset(nullptr);
147 }
148 
149 bool
150 art::BinaryMPIOutput::
151 readParameterSet_(fhicl::ParameterSet const& pset)
152 {
153  TLOG_DEBUG(name_) << "BinaryMPIOutput::readParameterSet_ method called with "
154  << "ParameterSet = \"" << pset.to_string()
155  << "\"." << TLOG_ENDL;
156 
157  // determine the data sending parameters
158  data_pset_ = pset;
159  name_ = pset.get<std::string>("module_name", "BinaryMPIOutput");
160  rt_priority_ = pset.get<int>("rt_priority", 0);
161 
162  TRACE(4, "BinaryMPIOutput::readParameterSet()");
163 
164  return true;
165 }
166 
167 void
168 art::BinaryMPIOutput::
169 write(EventPrincipal& ep)
170 {
171  assert(sender_ptr_);
172 
173  using RawEvent = artdaq::Fragments;;
174  using RawEvents = std::vector<RawEvent>;
175  using RawEventHandle = art::Handle<RawEvent>;
176  using RawEventHandles = std::vector<RawEventHandle>;
177 
178  auto result_handles = std::vector<art::GroupQueryResult>();
179  ep.getManyByType(art::TypeID(typeid(RawEvent)), result_handles);
180 
181  for (auto const& result_handle : result_handles)
182  {
183  auto const raw_event_handle = RawEventHandle(result_handle);
184 
185  if (!raw_event_handle.isValid())
186  continue;
187 
188  for (auto const& fragment : *raw_event_handle)
189  {
190  auto fragment_copy = fragment;
191  auto fragid_id = fragment_copy.fragmentID();
192  auto sequence_id = fragment_copy.sequenceID();
193  TRACE(1, "BinaryMPIOutput::write seq=%lu frag=%i start", sequence_id, fragid_id);
194  sender_ptr_->sendFragment(std::move(fragment_copy));
195  TRACE(2, "BinaryMPIOutput::write seq=%lu frag=%i done", sequence_id, fragid_id);
196  }
197  }
198 
199  return;
200 }
201 
202 DEFINE_ART_MODULE(art::BinaryMPIOutput)
An art::OutputModule which sends Fragments using DataSenderManager. This module produces output ident...
virtual ~BinaryMPIOutput()
BinaryMPIOutput Destructor.
BinaryMPIOutput(ParameterSet const &ps)
BinaryMPIOutput Constructor.