Skip to content

Commit cae4f94

Browse files
committed
DPL: initial support for FairMQRegionInfo callback
This should allow users to register a callback and be notified whenever FairMQ creates a new shared memory region. Guaranteed to be called synchronously wrt the processing.
1 parent b2b4dcb commit cae4f94

3 files changed

Lines changed: 52 additions & 9 deletions

File tree

Framework/Core/include/Framework/CallbackService.h

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "CallbackRegistry.h"
1414
#include <tuple>
1515

16+
class FairMQRegionInfo;
17+
1618
namespace o2
1719
{
1820
namespace framework
@@ -35,7 +37,23 @@ class CallbackService
3537
/// Invoked when we are notified that no further data will arrive.
3638
/// Notice that one could have more "EndOfData" notifications. Because
3739
/// we could be signaled by control that the data flow restarted.
38-
EndOfStream
40+
EndOfStream,
41+
42+
/// Invoked whenever FairMQ notifies us of a new region
43+
///
44+
/// return AlgorithmSpec::InitCallback{[=](InitContext& ic) {
45+
/// auto& callbacks = ic.services().get<CallbackService>();
46+
/// callbacks.set(CallbackService::Id::RegionInfoCallback, [](FairMQRegionInfo const& info) {
47+
/// ... do GPU init ...
48+
/// });
49+
/// }
50+
/// ...
51+
/// return [task](ProcessingContext& pc) {
52+
/// // your processing loop. Guaranteed to be called synchronously
53+
/// // with the callback
54+
/// };
55+
/// }};
56+
RegionInfoCallback
3957
};
4058

4159
template <typename T, T... v>
@@ -51,15 +69,17 @@ class CallbackService
5169
using IdleCallback = std::function<void()>;
5270
using ClockTickCallback = std::function<void()>;
5371
using EndOfStreamCallback = std::function<void(EndOfStreamContext&)>;
72+
using RegionInfoCallback = std::function<void(FairMQRegionInfo const&)>;
5473

55-
using Callbacks = CallbackRegistry<Id, //
56-
RegistryPair<Id, Id::Start, StartCallback>, //
57-
RegistryPair<Id, Id::Stop, StopCallback>, //
58-
RegistryPair<Id, Id::Reset, ResetCallback>, //
59-
RegistryPair<Id, Id::Idle, IdleCallback>, //
60-
RegistryPair<Id, Id::ClockTick, ClockTickCallback>, //
61-
RegistryPair<Id, Id::EndOfStream, EndOfStreamCallback> //
62-
>; //
74+
using Callbacks = CallbackRegistry<Id, //
75+
RegistryPair<Id, Id::Start, StartCallback>, //
76+
RegistryPair<Id, Id::Stop, StopCallback>, //
77+
RegistryPair<Id, Id::Reset, ResetCallback>, //
78+
RegistryPair<Id, Id::Idle, IdleCallback>, //
79+
RegistryPair<Id, Id::ClockTick, ClockTickCallback>, //
80+
RegistryPair<Id, Id::EndOfStream, EndOfStreamCallback>, //
81+
RegistryPair<Id, Id::RegionInfoCallback, RegionInfoCallback> //
82+
>; //
6383

6484
// set callback for specified processing step
6585
template <typename U>

Framework/Core/include/Framework/DataProcessingDevice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class DataProcessingDevice : public FairMQDevice
4545
public:
4646
DataProcessingDevice(DeviceSpec const& spec, ServiceRegistry&, DeviceState& state);
4747
void Init() final;
48+
void InitTask() final;
4849
void PreRun() final;
4950
void PostRun() final;
5051
void Reset() final;
@@ -84,6 +85,7 @@ class DataProcessingDevice : public FairMQDevice
8485
uint64_t mBeginIterationTimestamp = 0; /// The timestamp of when the current ConditionalRun was started
8586
DataProcessingStats mStats; /// Stats about the actual data processing.
8687
int mCurrentBackoff = 0; /// The current exponential backoff value.
88+
std::vector<FairMQRegionInfo> mPendingRegionInfos; /// A list of the region infos not yet notified.
8789
};
8890

8991
} // namespace o2::framework

Framework/Core/src/DataProcessingDevice.cxx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,20 @@ void DataProcessingDevice::Init()
165165
}
166166
}
167167

168+
void DataProcessingDevice::InitTask()
169+
{
170+
for (auto& channel : fChannels) {
171+
channel.second.at(0).Transport()->SubscribeToRegionEvents([& pendingRegionInfos = mPendingRegionInfos](FairMQRegionInfo info) {
172+
LOG(debug) << ">>> Region info event" << info.event;
173+
LOG(debug) << "id: " << info.id;
174+
LOG(debug) << "ptr: " << info.ptr;
175+
LOG(debug) << "size: " << info.size;
176+
LOG(debug) << "flags: " << info.flags;
177+
pendingRegionInfos.push_back(info);
178+
});
179+
}
180+
}
181+
168182
void DataProcessingDevice::PreRun() { mServiceRegistry.get<CallbackService>()(CallbackService::Id::Start); }
169183

170184
void DataProcessingDevice::PostRun() { mServiceRegistry.get<CallbackService>()(CallbackService::Id::Stop); }
@@ -250,6 +264,13 @@ bool DataProcessingDevice::ConditionalRun()
250264
auto now = std::chrono::high_resolution_clock::now();
251265
mBeginIterationTimestamp = (uint64_t)std::chrono::duration<double, std::milli>(now.time_since_epoch()).count();
252266

267+
if (mPendingRegionInfos.empty() == false) {
268+
std::vector<FairMQRegionInfo> toBeNotified;
269+
toBeNotified.swap(mPendingRegionInfos); // avoid any MT issue.
270+
for (auto& info : toBeNotified) {
271+
mServiceRegistry.get<CallbackService>()(CallbackService::Id::RegionInfoCallback, info);
272+
}
273+
}
253274
mServiceRegistry.get<CallbackService>()(CallbackService::Id::ClockTick);
254275
// Whether or not we had something to do.
255276
bool active = false;

0 commit comments

Comments
 (0)