OpenMP taskgroup issue with dependencies

Viewed 61

I have a larger program working with tasks and dependencies and I would like to use the taskgroup construct. But, I found an issue working with them so I wrote the following simple code example.

#include <omp.h>
#include <chrono>
#include <iostream>
#include <thread>

using namespace std::chrono_literals;

auto main() -> int {
    int level0[5] = {0, 0, 0, 0, 0};

#pragma omp parallel num_threads(4) default(none) \
    shared(level0, std::cout)
    {
        #pragma omp single
        {
// This taskgroup should synchronize M0 & M1 and their descendent tasks
// OMP ref : "The taskgroup construct specifies a wait on completion of child tasks of the current task and
// their descendent tasks."
#pragma omp taskgroup
            {
// First main task M0
#pragma omp task shared(level0)
                {
// Fix by adding the following taskgroup
// If not present, segfault
//#pragma omp taskgroup
//                    {
                        for(std::size_t i{0}; i < 5; ++i)
                        {
#pragma omp task firstprivate(i) depend(out: level0[i]) 
                            {
                                std::this_thread::sleep_for(i * i * 500ms);
                                std::cout << "Task A[" << i << "] : sleeps for " << i * i * 500 << "ms\n";
                            }
                        } 

#pragma omp task depend(in : level0[0], level0[1])
                        {
                            std::this_thread::sleep_for(1ms);
                            std::cout << "Task B depends task A[0] & A[1]\n";
                        }

#pragma omp task depend(in : level0[3])
                        {
                            std::this_thread::sleep_for(1ms);
                            std::cout << "Task C depends A[3]\n";
                        }
//                    }
                } 

// Second main task M1
 #pragma omp task 
                {
#pragma omp task 
                    {
                        std::this_thread::sleep_for(1ms);
                        std::cout << "Task D0 whenever\n";
                    }
#pragma omp task 
                    {
                        std::this_thread::sleep_for(1ms);
                        std::cout << "Task D1 whenever\n";
                    } 
                }
            } // wait here

#pragma omp task 
            {
                std::this_thread::sleep_for(1ms);
                std::cout << "Task E after taskgroup implicit wait\n";
            }
        }
    }

    return 0;
}

I have two main tasks spawning other tasks. I want to synchronize the tasks M0 and M1 with a taskgroup construct. When the descendent tasks of M0 don't use dependencies it works fine. When I add the dependencies, a segfault appears. If I add another level of taskgroup in M0, it runs fine. Am I missing something ? You can find the code here : https://godbolt.org/z/rbWTYT465

Thanks for your help !

0 Answers
Related