-
Notifications
You must be signed in to change notification settings - Fork 96
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tutorial3 cleanup #1349
Tutorial3 cleanup #1349
Conversation
@@ -76,12 +72,12 @@ class FairTestDetectorFileSink : public fair::mq::Device | |||
void InitTask() override; | |||
|
|||
private: | |||
std::unique_ptr<TClonesArray> fOutput; | |||
TClonesArray* fOutput; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you turning this back from a unique_ptr to a raw pointer?
One could even think of using a value member instead?
TClonesArray fOutput{FairTestDetectorHit::Class()};
The Branch()
then should look like this:
fTree.Branch("Output", &fOutput, 64000, 99);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in FileSinkTMessage.h there is fTree.SetBranchAddress("Output", &fOutput);
, which wants to have a pointer to a pointer....
Apparently it was just broken before, so I "repair" it here.
I don't like the solution either.
But I can't get value member or unique_ptr to work directly... maybe i'm still missing something x)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, very strange.
I would have expected this overload of SetBranchAddress to be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I change it back to unique_ptr, and:
fTree.SetBranchAddress("Output", fOutput.get());
, which seems to be the overload you suggest, then I get this at runtime:
Error in <TTree::SetBranchAddress>: The address for "Output" should be the address of a pointer!
*** Break *** segmentation violation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have the feeling, that this is a bug. I actually have an idea. I am going to post on the root forum and ask for some help in understanding their code.
Another question: Do we actually need the additional tree.SetBranchAddress
when we already set the address in the tree.Branch()
call?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually there is another aspect in this device. Before it calls SetBranchAddress()
it also calls the Deserializer:
RootSerializer().Deserialize(*msg, fOutput); |
Which translates to either of:
template<typename T>
void Deserialize(const fair::mq::Message& msg, T*& output)
{
delete output;
FairTMessage tm(msg.GetData(), msg.GetSize());
output = static_cast<T*>(tm.ReadObjectAny(tm.GetClass()));
}
template<typename T>
void Deserialize(const fair::mq::Message& msg, std::unique_ptr<T>& output)
{
FairTMessage tm(msg.GetData(), msg.GetSize());
output.reset(static_cast<T*>(tm.ReadObjectAny(tm.GetClass())));
}
So we already call delete ourselves on it before it gets to ROOT. This "generic part" would be the next thing which I would propose to delete. It would be better to see these ugly details directly in the example, to understand and improve them for whatever the use case is.
I suspect the TClonesArray* fOutput;
is not ideal for every serializer and may have been chosen to keep the class "generic".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not obvious to me what the best solution for this issue will be, accounting both for SetBranchAddress
and the serializers.
For this PR I prefer to leave it at raw ptr + new/delete, as it is also done in:
https://github.com/FairRootGroup/FairRoot/blob/dev/examples/MQ/Lmd/runMBSSink.cxx#L75
and
https://github.com/FairRootGroup/FairRoot/blob/dev/examples/MQ/serialization/sink.cxx#L83
The change from unique_ptr to raw ptr in this PR is necessary to get it to work at all - it was entirely broken before, which the added tests reveal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I wondered: If the deserializers usually allocate the TCA, do we actually need to new
one in the constructor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like it is not needed to be in the ctor. Probably it doesn't have to be a member at all. But rather be created and destroyed for each message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having it as a member is good. Because TBranch needs its address.
Well, you're right: Let's keep it for this PR and clean this up in another go.
- rename runTestDetector[name] -> [name] - rename .tpl files to .h and include them where they are used
* basemq/devices/FairMQProcessor.h -> into examples/advanced/Tutorial3/MQ/processor.cxx * basemq/devices/FairMQSampler.h -> into examples/advanced/Tutorial3/MQ/sampler.cxx> * basemq/tasks/FairMQProcessorTask.h -> examples/advanced/Tutorial3/MQ/processorTask/ProcessorTask.h * basemq/tasks/FairMQSamplerTask.h -> examples/advanced/Tutorial3/MQ/samplerTask/SamplerTask.h
481eb09
to
065dad4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I wasn't able to follow each detail, but generally this starts to look good for me.
Some final things I noticed.
Looks good to me. I would still prefer if someone else could take a look as well. |
basemq
to the example directory. These have very limited reusability value and are more suitable as an example. I added these to the breaking changes. The only known user is some old code in Panda. Confirmed with Tobias that it is not actually needed and are OK to remove.The example classes could use further modernization (namespaces, memory management for (Fair)ROOT objects), but I'll leave that for future work.