_ROOT Version:6.22/08
_Platform: linuxx8664gcc Compiler: Not Provided
Dear colleagues,
I have found some answers about parallelization on other forum pages, but I still do not find the one I am looking for.
How, if possible, to parallelize a function within a ROOT macro?
To give some context, I give you an example pretty close to what I am doing:
void func_parallel();
void my_macro(){
/// some code
}
void func_parallel(){
// Section I want to parallelize
for (){
// heavy code
}
}
This func_parallel() does not handle the same ROOT object simultaneously, so there should be no thread write/read conflict.
In compile code, I usually would use “omp” library:
I suppose you already searched the forum, right? And if RDataFrame doesn’t help, then I think you’ll have to use std::thread. You can take a look at the examples in tutorials\multicore
Hi, I find the solution in the tutorials partially.
void my_parallel_func();
void save_objs();
void my_macro(){
my_parallel_func();
save_objs();
}
void my_parallel_func(){
gROOT->SetBatch();
const UInt_t n_thread = 16;
// This function contains what was before inside the for loop
auto work_item = [](size_t thread_id) {
/// heavy code
// Creating TObjects and save them to some containers
return 0;
};
// Create the pool of workers
ROOT::TProcessExecutor workers(n_thread );
// Fill the pool with work
workers.Map(work_item , ROOT::TSeqI(n_thread ));
// This replaces the for loop and parallelized
}
After my_parallel_func is called, a different function is called to save all objects stored in some containers: objects created for individual pool tasks. But seems that function is called even before the works in the pools have finished cause those objects created are never saved.
Is there a way to check whether an individual task or the entire pool is finished??
the behavior you see is unexpected and I cannot reproduce it. Map should only return when all tasks are done.
Indeed that’s what happens when I run this version of your example where I added a couple of printouts to check the order of operations:
// my_macro.C
void save_objs() { std::cerr << "saving objs\n"; }
void my_parallel_func() {
gROOT->SetBatch();
const UInt_t n_thread = 16;
// This function contains what was before inside the for loop
auto work_item = [](size_t thread_id) {
/// heavy code
// Creating TObjects and save them to some containers
std::cerr << "task for " << thread_id << " done.\n";
return 0;
};
// Create the pool of workers
ROOT::TProcessExecutor workers(n_thread);
// Fill the pool with work
workers.Map(work_item, ROOT::TSeqI(n_thread));
// This replaces the for loop and parallelized
}
void my_macro() {
my_parallel_func();
save_objs();
}
Here is the output of 3 example executions, you can see saving objs is always printed after the tasks are done (while the tasks running concurrently sometimes messes up their printouts):
/tmp root -l -b -q my_macro.C
Processing my_macro.C...
task for 0task for done.
2 done.
task for 1 done.
task for 3 done.
task for task for 5 done.
task for 6 done.
4 done.
task for 13 done.
task for 8 done.
task for 9 done.
task for 11 done.
task for 10 done.
task for 7 done.
task for 12 done.
task for 14 done.
task for 15 done.
saving objs
/tmp root -l -b -q my_macro.C
Processing my_macro.C...
task for 0 done.
task for 2 done.
task for 1 done.
task for 5 done.
task for 3 done.
task for 4 done.
task for 6 done.
task for 8 done.
task for 7 done.
task for 9 done.
task for 13 done.
task for 12 done.
task for 10 done.
task for 11 done.
task for 14 done.
task for 15 done.
saving objs
/tmp root -l -b -q my_macro.C
Processing my_macro.C...
task for 0 done.
task for 3 done.
task for 1task for done.
2 done.
task for 4 done.
task for 5 done.
task for task for task for task for 13task for 6task for done.
109 done.
done.
11 done.
task for 8 done.
7 done.
done.
task for 12 done.
task for 14 done.
task for 15 done.
saving objs
Feel free to provide a self-contained reproducer for your issue that we can use to debug what is happening.
Thanks a lot. This clarifies my initial questions. As the problem I have now is a different topic, I will close this one and thank you again for the help!!!