11#ifndef O2_FRAMEWORK_DATAALLOCATOR_H_
12#define O2_FRAMEWORK_DATAALLOCATOR_H_
44#include <fairmq/FwdDecls.h>
45#include <fairmq/Version.h>
46#include <fairmq/shmem/Message.h>
55class RecordBatchWriter;
61struct ServiceRegistry;
84 this->ptr =
other.ptr;
87 this->callback = std::move(
other.callback);
89 this->callback =
nullptr;
91 other.callback =
nullptr;
98 this->callback = std::move(
other.callback);
100 this->callback =
nullptr;
102 other.callback =
nullptr;
124 std::unique_ptr<T> released{
ptr};
126 auto releaseCallback = std::move(
callback);
127 if (!releaseCallback) {
130 releaseCallback(*released);
149 is_messageable<typename T::value_type>::value;
153 is_messageable<typename T::value_type>::value;
169 template <
typename T>
170 requires std::is_fundamental_v<T>
189 template <
typename T,
typename... Args>
190 requires is_specialization_v<T, o2::framework::DataAllocator::UninitializedVector>
196 auto routeIndex = matchDataHeader(spec, timingInfo.timeslice);
198 using ValueType =
typename T::value_type;
203 std::move(headerMessage), routeIndex, 0, std::forward<Args>(args)...)
207 template <
typename T,
typename... Args>
214 auto routeIndex = matchDataHeader(spec, timingInfo.timeslice);
217 using ValueType =
typename T::value_type;
224 template <
typename T,
typename... Args>
231 auto routeIndex = matchDataHeader(spec, timingInfo.timeslice);
243 template <
typename T,
typename... Args>
244 requires std::is_base_of_v<std::string, T>
247 auto* s =
new std::string(args...);
252 template <
typename T,
typename... Args>
253 requires(
requires {
static_cast<struct
TableBuilder>(std::declval<std::decay_t<T>>()); })
261 template <
typename T,
typename... Args>
262 requires(
requires {
static_cast<struct
FragmentToBatch>(std::declval<std::decay_t<T>>()); })
270 template <
typename T>
271 requires is_messageable<T>::value && (!is_specialization_v<T, UninitializedVector>)
274 return *
reinterpret_cast<T*
>(
newChunk(spec,
sizeof(T)).data());
277 template <
typename T>
278 requires is_messageable<T>::value && (!is_specialization_v<T, UninitializedVector>)
279 decltype(
auto)
make(
const Output& spec, std::integral
auto nElements)
283 auto routeIndex = matchDataHeader(spec, timingInfo.timeslice);
289 template <
typename T,
typename Arg>
290 decltype(
auto)
make(
const Output& spec, std::same_as<std::shared_ptr<arrow::Schema>>
auto schema)
292 std::shared_ptr<arrow::ipc::RecordBatchWriter> writer;
293 create(spec, &writer,
schema);
336 template <
typename T>
337 requires(!std::ranges::contiguous_range<T> && is_messageable<T>::value)
340 return snapshot(spec, std::span<T const>(&
object, &
object + 1));
349 template <
typename T>
355 using ElementType =
typename std::remove_pointer<typename T::value_type>::type;
359 constexpr auto elementSizeInBytes =
sizeof(ElementType);
360 auto sizeInBytes = elementSizeInBytes *
object.size();
361 fair::mq::MessagePtr payloadMessage = proxy.createOutputMessage(routeIndex, sizeInBytes);
364 if (
object.
data() && sizeInBytes) {
365 memcpy(payloadMessage->GetData(),
object.data(), sizeInBytes);
373 template <
typename T>
374 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>)
379 using ElementType =
typename std::remove_pointer_t<typename T::value_type>;
383 constexpr auto elementSizeInBytes =
sizeof(ElementType);
384 auto sizeInBytes = elementSizeInBytes *
object.size();
385 fair::mq::MessagePtr payloadMessage = proxy.createOutputMessage(routeIndex, sizeInBytes);
388 auto target =
reinterpret_cast<unsigned char*
>(payloadMessage->GetData());
391 target += elementSizeInBytes;
399 template <
typename T>
408 constexpr auto elementSizeInBytes =
sizeof(
typename T::value_type);
409 auto sizeInBytes = elementSizeInBytes *
object.size();
410 fair::mq::MessagePtr payloadMessage = proxy.createOutputMessage(routeIndex, sizeInBytes);
413 auto target =
reinterpret_cast<unsigned char*
>(payloadMessage->GetData());
416 target += elementSizeInBytes;
421 template <
typename T>
422 requires(is_specialization_v<T, ROOTSerialized>)
428 fair::mq::MessagePtr payloadMessage = proxy.createOutputMessage(routeIndex);
429 payloadMessage->Rebuild(4096, {64});
430 const TClass* cl =
nullptr;
435 using WrappedType =
typename T::wrapped_type;
437 if (
object.getHint() ==
nullptr) {
439 cl = TClass::GetClass(
typeid(WrappedType));
440 }
else if (std::is_same<typename T::hint_type, TClass>::value) {
442 cl =
reinterpret_cast<const TClass*
>(
object.getHint());
443 }
else if (std::is_same<typename T::hint_type, const char>::value) {
445 cl = TClass::GetClass(
reinterpret_cast<const char*
>(
object.getHint()));
448 if (std::is_same<typename T::hint_type, const char>::value) {
449 throw runtime_error_f(
"ROOT serialization not supported, dictionary not found for type %s",
450 reinterpret_cast<const char*
>(
object.getHint()));
452 throw runtime_error_f(
"ROOT serialization not supported, dictionary not found for type %s",
453 typeid(WrappedType).
name());
460 template <
typename T>
467 fair::mq::MessagePtr payloadMessage = proxy.createOutputMessage(routeIndex);
468 payloadMessage->Rebuild(4096, {64});
476 void snapshot(
const Output& spec,
const char* payload,
size_t payloadSize,
489 template <
typename T,
typename... Args>
492 return make<T>(getOutputByBind(std::move(
ref)), std::forward<Args>(args)...);
500 template <
typename T>
503 return adopt(getOutputByBind(std::move(
ref)), obj);
511 RouteIndex routeIndex = matchDataHeader(spec, timingInfo.timeslice);
512 return *proxy.getOutputTransport(routeIndex);
516 template <
typename T,
typename... Args>
534 template <
typename ContainerT>
537 static_assert(always_static_assert_v<ContainerT>,
"Container cannot be moved. Please make sure it is backed by a o2::pmr::FairMQMemoryResource");
550 template <
typename ContainerT>
565 template <
typename... Args>
568 return snapshot(getOutputByBind(std::move(
ref)), std::forward<Args>(args)...);
603 fair::mq::MessagePtr headerMessageFromOutput(
Output const& spec,
609 void addPartToContext(
RouteIndex routeIndex, fair::mq::MessagePtr&& payload,
614template <
typename ContainerT>
620 auto routeIndex = matchDataHeader(spec, timingInfo.timeslice);
624 fair::mq::MessagePtr payloadMessage =
o2::pmr::getMessage(std::forward<ContainerT>(container), *transport);
625 fair::mq::MessagePtr headerMessage = headerMessageFromOutput(spec, routeIndex,
627 payloadMessage->GetSize()
635 cacheId.
value = context.addToCache(payloadMessage);
636 auto meta =
dynamic_cast<fair::mq::shmem::Message*
>(payloadMessage.get())->GetMeta();
637 cacheId.handle = meta.fHandle;
638 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