Streamlined InputRecord / DataAllocator API Giulio Eulisse (CERN) - - PowerPoint PPT Presentation

streamlined inputrecord dataallocator api
SMART_READER_LITE
LIVE PREVIEW

Streamlined InputRecord / DataAllocator API Giulio Eulisse (CERN) - - PowerPoint PPT Presentation

Streamlined InputRecord / DataAllocator API Giulio Eulisse (CERN) WP4 - 24th Nov 2017 1 class via: 1https://github.com/AliceO2Group/AliceO2/blob/dev/Utilities/QC/Workflow/src/RootObjectProducerSpec.cxx 2 Improved API for DataAllocator (1)


slide-1
SLIDE 1

Streamlined InputRecord / DataAllocator API

Giulio Eulisse (CERN) WP4 - 24th Nov 2017

1

slide-2
SLIDE 2

Improved API for DataAllocator (1)

  • 2::framework::DataAllocator is the class which users must use to create
  • utput messages to be sent to the downstream DataProcessors.

It is now possible to create and serialise an instance of a TObject derived class via:

DataAllocator::make<T>(OutputSpec &spec, Args... args);

e.g. in 1:

[](ProcessingContext &ctx) { auto h = ctx.allocator().make<TH1>(OutputSpec{”QC”, ”HISTO”}, ”h”, ”test”, 100, -10., 10.); }

1https://github.com/AliceO2Group/AliceO2/blob/dev/Utilities/QC/Workflow/src/RootObjectProducerSpec.cxx

2

slide-3
SLIDE 3

Improved API for DataAllocator (2)

Similarly the API to create PODs or Collection<POD> has been revamped and made similar to the ROOT one:

struct XYZ { float x,y,z; }; ... [](ProcessingContext &ctx) { // Create a XYZ instance which will be sent once lambda completes auto &a = ctx.allocator().make<XYZ>(OutputSpec{”TPC”, ”POINT”}); // Create a Collection<XYZ> with 1000 instances in it. auto &c = ctx.allocator().make<XYZ>(OutputSpec{”TPC”, ”POINT”}, 1000); }

3

slide-4
SLIDE 4

Improved API for InputRecord (1)

An o2::framework::InputRecord represents the inputs being passed to the processing function. The API to access the various parts of a record is now orthogonal as well. In the ROOT case it becomes:

{InputSpec{”histos”, ”QC”, ”HISTO”}} ... [](ProcessingContext &ctx) { auto h = ctx.inputs().get<TH1F>(”histos”); }

Notice that h will be a copy of the actual contents of the message buffer, due to the fact ROOT selializes objects.

4

slide-5
SLIDE 5

Improved API for InputRecord (2)

The same API can be used to extract a POD instance from the message as well:

{InputSpec{”points”, ”QC”, ”HISTO”}} ... [](ProcessingContext &ctx) { XYZ &x = ctx.inputs().get<XYZ>(”points”); }

5

slide-6
SLIDE 6

Improved API for InputRecord (3)

By default, however, InputRecord::get still returns a o2::framework::DataRef i.e. the (header, payload) pointers.

DataRefUtils::as<T> can then be used to extract stuff as well. {InputSpec{”points”, ”TPC”, ”POINTS”}} ... [](ProcessingContext &ctx) { auto ref = ctx.inputs().get(”points”); Collection<XYZ> c = DataRefUtils::as<XYZ>(ref); }

6

slide-7
SLIDE 7

I already have an object…

Use DataAllocator::adopt to surrender object ownership to the framework. E.g. from Matthias last presentation2:

auto dataobject = std::unique_ptr<TObject>(producer->produceData()); auto serialized = std::make_unique<TMessage>(kMESS_OBJECT); serialized->WriteObject(dataobject.get()); auto tgt = pc.allocator().newChunk(OutputSpec{”QC”, ”ROOTOBJECT”, 0, OutputSpec::QA}, serialized->BufferSize()); memcpy(tgt.data, serialized->Buffer(), tgt.size);

becomes:

pc.allocator().adopt(OutputSpec{”QC”, ”ROOTOBJECT”, 0, OutputSpec::QA}, producer->produceData());

2https://github.com/AliceO2Group/AliceO2/blob/dev/Utilities/QC/Workflow/src/RootObjectProducerSpec.cxx

7

slide-8
SLIDE 8

Suggested future improvements

A non-owning pointer o2::ref<T>. Returned by ::make<T>, ::get<T> methods whenever the object is actually owned by the DPL. At the moment I use a standard reference, but this has the drawback that if you are not careful you end up with a copy of the contents. A static helper method o2::make<T>. To be used in place of

DataAllocator::make<T> to hide the need to know about the allocator.

Similarly o2::adopt<T> could be provided. Pass InputRecord directly. Assuming getting the inputs is very frequent,

ctx.inputs().get(”something”) would becomes inputs.get(”somthing”) }

8