sorry for the high latency. I think there are a few things to check before going down the sub-process route:
- how large is the memory usage for your problematic application?
valgrind --tool=massif on it, does the memory hogging come from cling?
- can you rearrange the application flow in a way that you book all operations for all RDataFrames first, and then run all event loops? That would guarantee the smallest memory footprint but also the best performance possible. That’s the recommended way to run multiple RDFs, whenever possible, and via RunGraphs you can also run the separate event loops concurrently for another performance boost
If the problem is indeed cling memory hogging, and it is not possible to book all RDF computations upfront but instead you have to build and run one RDF computation graph at a time, you can use TProcessExecutor to spawn one subprocess per RDF, with two caveats:
- to reduce memory usage you should run RDFs one after the other, while
TProcessExecutor::Process will spawn N processes, one per argument. So instead that passing all RDFs to a single
TProcessExecutor::Process call, you need to call it multiple times, once per RDF
- you have to make sure to call
EnableImplicitMT inside the subprocess, because forking a multi-thread application can result in deadlocks or other problems
@Wile_E_Coyote currently maintained alternatives to PROOF-lite are TTreeProcessorMP or TProcessExecutor (for multi-process solutions) or TTreeProcessorMT, TThreadExecutor and RDataFrame (for multi-threading). We are also working on an RDataFrame-based PROOF alternative, it has just been merged in master as an experimental feature.
EDIT: it took me a while to reply because I wanted to check with our cling experts how a cling-side solution to the memory-hogging problem would look like (i.e. what it would take exactly to implement something like the
ROOT::ClearJitted() call that you propose. It is possible but very tricky – so it’s on our to-do list, but it will take a while.
EDIT 2: about cpp-subprocess: if each subprocess does not need to return anything to the parent process, that’s probably a viable solution. To return results to the parent process, TProcessExecutor might be a better alternative because it leverages ROOT I/O to pass C++ objects between processes, which is otherwise not trivial