11#ifndef O2_FRAMEWORK_DATAALLOCATOR_H_
12#define O2_FRAMEWORK_DATAALLOCATOR_H_
44#include <fairmq/FwdDecls.h>
45#include <fairmq/Version.h>
46#if (FAIRMQ_VERSION_DEC >= 111000)
47#include <fairmq/shmem/Message.h>
57class RecordBatchWriter;
63struct ServiceRegistry;
86 this->ptr =
other.ptr;
89 this->callback = std::move(
other.callback);
91 this->callback =
nullptr;
93 other.callback =
nullptr;
100 this->callback = std::move(
other.callback);
102 this->callback =
nullptr;
104 other.callback =
nullptr;
126 std::unique_ptr<T> released{
ptr};
128 auto releaseCallback = std::move(
callback);
129 if (!releaseCallback) {
132 releaseCallback(*released);
151 is_messageable<typename T::value_type>::value;
155 is_messageable<typename T::value_type>::value;
171 template <
typename T>
172 requires std::is_fundamental_v<T>
191 template <
typename T,
typename... Args>
192 requires is_specialization_v<T, o2::framework::DataAllocator::UninitializedVector>
198 auto routeIndex = matchDataHeader(spec, timingInfo.timeslice);
200 using ValueType =
typename T::value_type;
205 std::move(headerMessage), routeIndex, 0, std::forward<Args>(args)...)
209 template <
typename T,
typename... Args>
216 auto routeIndex = matchDataHeader(spec, timingInfo.timeslice);
219 using ValueType =
typename T::value_type;
226 template <
typename T,
typename... Args>
233 auto routeIndex = matchDataHeader(spec, timingInfo.timeslice);
245 template <
typename T,
typename... Args>
246 requires std::is_base_of_v<std::string, T>
249 auto* s =
new std::string(args...);
254 template <
typename T,
typename... Args>
255 requires(
requires {
static_cast<struct
TableBuilder>(std::declval<std::decay_t<T>>()); })
263 template <
typename T,
typename... Args>
264 requires(
requires {
static_cast<struct
FragmentToBatch>(std::declval<std::decay_t<T>>()); })
272 template <
typename T>
273 requires is_messageable<T>::value && (!is_specialization_v<T, UninitializedVector>)
276 return *
reinterpret_cast<T*
>(
newChunk(spec,
sizeof(T)).data());
279 template <
typename T>
280 requires is_messageable<T>::value && (!is_specialization_v<T, UninitializedVector>)
281 decltype(
auto)
make(
const Output& spec, std::integral
auto nElements)
285 auto routeIndex = matchDataHeader(spec, timingInfo.timeslice);
291 template <
typename T,
typename Arg>
292 decltype(
auto)
make(
const Output& spec, std::same_as<std::shared_ptr<arrow::Schema>>
auto schema)
294 std::shared_ptr<arrow::ipc::RecordBatchWriter> writer;
295 create(spec, &writer,
schema);
338 template <
typename T>
339 requires(!std::ranges::contiguous_range<T> && is_messageable<T>::value)
342 return snapshot(spec, std::span<T const>(&
object, &
object + 1));
351 template <
typename T>
357 using ElementType =
typename std::remove_pointer<typename T::value_type>::type;
361 constexpr auto elementSizeInBytes =
sizeof(ElementType);
362 auto sizeInBytes = elementSizeInBytes *
object.size();
363 fair::mq::MessagePtr payloadMessage = proxy.createOutputMessage(routeIndex, sizeInBytes);
366 if (
object.
data() && sizeInBytes) {
367 memcpy(payloadMessage->GetData(),
object.data(), sizeInBytes);
375 template <
typename T>
376 requires(std::ranges::random_access_range<T> && is_messageable<typename std::remove_pointer_t<typename T::value_type>>
::value && std::is_pointer_v<typename T::value_type>)
381 using ElementType =
typename std::remove_pointer_t<typename T::value_type>;
385 constexpr auto elementSizeInBytes =
sizeof(ElementType);
386 auto sizeInBytes = elementSizeInBytes *
object.size();
387 fair::mq::MessagePtr payloadMessage = proxy.createOutputMessage(routeIndex, sizeInBytes);
390 auto target =
reinterpret_cast<unsigned char*
>(payloadMessage->GetData());
393 target += elementSizeInBytes;
401 template <
typename T>
410 constexpr auto elementSizeInBytes =
sizeof(
typename T::value_type);
411 auto sizeInBytes = elementSizeInBytes *
object.size();
412 fair::mq::MessagePtr payloadMessage = proxy.createOutputMessage(routeIndex, sizeInBytes);
415 auto target =
reinterpret_cast<unsigned char*
>(payloadMessage->GetData());
418 target += elementSizeInBytes;
423 template <
typename T>
424 requires(is_specialization_v<T, ROOTSerialized>)
430 fair::mq::MessagePtr payloadMessage = proxy.createOutputMessage(routeIndex);
431 payloadMessage->Rebuild(4096, {64});
432 const TClass* cl =
nullptr;
437 using WrappedType =
typename T::wrapped_type;
439 if (
object.getHint() ==
nullptr) {
441 cl = TClass::GetClass(
typeid(WrappedType));
442 }
else if (std::is_same<typename T::hint_type, TClass>::value) {
444 cl =
reinterpret_cast<const TClass*
>(
object.getHint());
445 }
else if (std::is_same<typename T::hint_type, const char>::value) {
447 cl = TClass::GetClass(
reinterpret_cast<const char*
>(
object.getHint()));
450 if (std::is_same<typename T::hint_type, const char>::value) {
451 throw runtime_error_f(
"ROOT serialization not supported, dictionary not found for type %s",
452 reinterpret_cast<const char*
>(
object.getHint()));
454 throw runtime_error_f(
"ROOT serialization not supported, dictionary not found for type %s",
455 typeid(WrappedType).
name());
462 template <
typename T>
469 fair::mq::MessagePtr payloadMessage = proxy.createOutputMessage(routeIndex);
470 payloadMessage->Rebuild(4096, {64});
478 void snapshot(
const Output& spec,
const char* payload,
size_t payloadSize,
491 template <
typename T,
typename... Args>
494 return make<T>(getOutputByBind(std::move(
ref)), std::forward<Args>(args)...);
502 template <
typename T>
505 return adopt(getOutputByBind(std::move(
ref)), obj);
513 RouteIndex routeIndex = matchDataHeader(spec, timingInfo.timeslice);
514 return *proxy.getOutputTransport(routeIndex);
518 template <
typename T,
typename... Args>
536 template <
typename ContainerT>
539 static_assert(always_static_assert_v<ContainerT>,
"Container cannot be moved. Please make sure it is backed by a o2::pmr::FairMQMemoryResource");
552 template <
typename ContainerT>
567 template <
typename... Args>
570 return snapshot(getOutputByBind(std::move(
ref)), std::forward<Args>(args)...);
605 fair::mq::MessagePtr headerMessageFromOutput(
Output const& spec,
611 void addPartToContext(
RouteIndex routeIndex, fair::mq::MessagePtr&& payload,
616template <
typename ContainerT>
622 auto routeIndex = matchDataHeader(spec, timingInfo.timeslice);
626 fair::mq::MessagePtr payloadMessage =
o2::pmr::getMessage(std::forward<ContainerT>(container), *transport);
627 fair::mq::MessagePtr headerMessage = headerMessageFromOutput(spec, routeIndex,
629 payloadMessage->GetSize()
637 cacheId.
value = context.addToCache(payloadMessage);
638#if (FAIRMQ_VERSION_DEC >= 111000)
639 auto meta =
dynamic_cast<fair::mq::shmem::Message*
>(payloadMessage.get())->GetMeta();
640 cacheId.handle = meta.fHandle;
641 cacheId.segment = meta.fSegmentId;
std::shared_ptr< arrow::Schema > schema
Type wrappers for enfording a specific serialization method.
static constexpr ServiceKind service_kind
::value &&!is_specialization_v< T, UninitializedVector > decltype(auto) make(const Output &spec, std::integral auto nElements)
void adopt(const Output &spec, std::string *)
o2::pmr::vector< T > makeVector(const Output &spec, Args &&... args)
void snapshot(const Output &spec, T const &object)
o2::pmr::FairMQMemoryResource * getMemoryResource(const Output &spec)
decltype(auto) make(OutputRef &&ref, Args &&... args)
DataChunk & newChunk(const Output &, size_t)
o2::header::DataHeader::SubSpecificationType SubSpecificationType
o2::header::Stack * findMessageHeaderStack(const Output &spec)
decltype(auto) make(const Output &spec, Args... args)
::value &&!is_specialization_v< T, UninitializedVector > decltype(auto) make(const Output &spec)
void pruneFromCache(CacheId id)
void snapshot(const Output &spec, std::string_view const &object)
decltype(auto) make(const Output &spec, Args... args)
auto snapshot(OutputRef &&ref, Args &&... args)
void adopt(const Output &spec, std::shared_ptr< class arrow::Table >)
Adopt an Arrow table and send it to all consumers of spec.
int countDeviceOutputs(bool excludeDPLOrigin=false)
o2::header::DataHeader * findMessageHeader(OutputRef &&ref)
void adoptFromCache(Output const &spec, CacheId id, header::SerializationMethod method=header::gSerializationMethodNone)
Adopt an already cached message, using an already provided CacheId.
decltype(auto) make(const Output &spec, Args... args)
std::vector< OutputRoute > AllowedOutputRoutes
decltype(auto) make(const Output &spec, Args... args)
void snapshot(const Output &spec, T const &object)
CacheId adoptContainer(const Output &, ContainerT &, CacheStrategy, o2::header::SerializationMethod)
void forwardPayload(const Output &spec, fair::mq::Message &inputPayload, o2::header::SerializationMethod serializationMethod=o2::header::gSerializationMethodNone)
void adoptChunk(const Output &, char *, size_t, fair::mq::FreeFn *, void *)
void snapshot(const Output &spec, T const &object)
bool isAllowed(Output const &query)
check if a certain output is allowed
void cookDeadBeef(const Output &spec)
o2::header::Stack * findMessageHeaderStack(OutputRef &&ref)
DataChunk & newChunk(OutputRef &&ref, size_t size)
decltype(auto) make(const Output &spec, Args... args)
decltype(auto) make(const Output &spec, std::same_as< std::shared_ptr< arrow::Schema > > auto schema)
void adopt(OutputRef &&ref, T *obj)
decltype(auto) make(const Output &spec, Args... args)
o2::header::DataHeader * findMessageHeader(const Output &spec)
void snapshot(const Output &spec, T const &object)
void snapshot(const Output &spec, T const &object)
void snapshot(const Output &spec, T const &object)
TrivialObject handles a message object.
GLuint const GLchar * name
GLsizei const GLfloat * value
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
Defining ITS Vertex explicitly as messageable.
ServiceKind
The kind of service we are asking for.
RuntimeErrorRef runtime_error_f(const char *,...)
fair::mq::MessagePtr getMessage(ContainerT &&container, FairMQMemoryResource *targetResource=nullptr)
std::vector< T, fair::mq::pmr::polymorphic_allocator< T > > vector
fair::mq::MemoryResource FairMQMemoryResource
LifetimeHolder(const LifetimeHolder &)=delete
LifetimeHolder & operator=(LifetimeHolder &&other)
LifetimeHolder & operator=(const LifetimeHolder &)=delete
LifetimeHolder(LifetimeHolder &&other)
std::function< void(T &)> callback
VectorOfTObjectPtrs other