Question about implementation of task dependencies

Dear all,

I'm currently doing some tests with task dependencies and have found a
behavior which I would have at least not expected. I'm possibly missing
something and there is not much documentation in the code so maybe the Intel
folks or someone else can enlighten me here.

With the following code snippet, the runtime will currently add a dependence
from task #3 to task #2:

    #pragma omp parallel num_threads(4)
    #pragma omp single
    {
        int dep;
        #pragma omp task depend(out: dep)
        {
            sleep(1);
            printf("task #1\n");
        }
        #pragma omp task depend(in: dep)
        {
            sleep(1);
            printf("task #2\n");
        }
        #pragma omp task depend(out: dep)
        {
            sleep(1);
            printf("task #3\n");
        }
    }

As out means the same as inout per the current standard, I would expect a
dependence to task #1 which specifies out on the same variable. (Note: The
dependence from #2 to task #1 is not questioned.)

I have attached a patch which then fulfills my expectations. However I don't
want to officially put it to review until I fully understand the reasoning
behind the current code.

Thanks,
Jonas

task-dependencies.patch (5.01 KB)

Jonas,

The OpenMP specification says (section 2.13.9 depend Clause):

For the out and inout dependence-types, if the storage location of at least one of the list items is
the same as the storage location of a list item appearing in an in, out, or inout dependence-type
list of a task construct from which a sibling task was previously generated, then the generated task
will be a dependent task of that sibling task.

So in your example task #3 must depend on task #2, as well as on task #1. The runtime behavior looks correct.
The only independent sequence is when task with depend(in:dep) follows another task with depend(in:dep).
All other combinations produce dependencies.

Regards,
Andrey

Hi Andrey,

Thanks for the clarification. I must have somehow skipped that when reading
what the spec says about the depend-clause.

Thanks,
Jonas

From: Churbanov, Andrey [mailto:Andrey.Churbanov@intel.com]
Sent: Wednesday, August 03, 2016 2:15 PM
To: Hahnfeld, Jonas
Cc: Duran, Alejandro; LLVM-OpenMP (openmp-dev@lists.llvm.org)
Subject: RE: Question about implementation of task dependencies

Jonas,

The OpenMP specification says (section 2.13.9 depend Clause):

For the out and inout dependence-types, if the storage location of at

least

one of the list items is the same as the storage location of a list item
appearing in an in, out, or inout dependence-type list of a task construct
from which a sibling task was previously generated, then the generated

task

will be a dependent task of that sibling task.

So in your example task #3 must depend on task #2, as well as on task #1.
The runtime behavior looks correct.
The only independent sequence is when task with depend(in:dep) follows
another task with depend(in:dep).
All other combinations produce dependencies.

Regards,
Andrey

From: Openmp-dev [mailto:openmp-dev-bounces@lists.llvm.org] On Behalf
Of Hahnfeld, Jonas via Openmp-dev
Sent: Wednesday, August 3, 2016 2:37 PM
To: LLVM-OpenMP (openmp-dev@lists.llvm.org) <openmp-
dev@lists.llvm.org>
Cc: Duran, Alejandro <alejandro.duran@intel.com>
Subject: [Openmp-dev] Question about implementation of task
dependencies

Dear all,

I'm currently doing some tests with task dependencies and have found a
behavior which I would have at least not expected. I'm possibly missing
something and there is not much documentation in the code so maybe the
Intel folks or someone else can enlighten me here.

With the following code snippet, the runtime will currently add a
dependence from task #3 to task #2:

    #pragma omp parallel num_threads(4)
    #pragma omp single
    {
        int dep;
        #pragma omp task depend(out: dep)
        {
            sleep(1);
            printf("task #1\n");
        }
        #pragma omp task depend(in: dep)
        {
            sleep(1);
            printf("task #2\n");
        }
        #pragma omp task depend(out: dep)
        {
            sleep(1);
            printf("task #3\n");
        }
    }

As out means the same as inout per the current standard, I would expect a
dependence to task #1 which specifies out on the same variable. (Note: The
dependence from #2 to task #1 is not questioned.)

I have attached a patch which then fulfills my expectations. However I

don't

want to officially put it to review until I fully understand the reasoning

behind

the current code.

Thanks,
Jonas

--
Jonas Hahnfeld, MATSE-Auszubildender

IT Center
Group: High Performance Computing
Division: Computational Science and Engineering RWTH Aachen University
Seffenter Weg 23 D 52074 Aachen (Germany) Hahnfeld@itc.rwth-aachen.de
www.itc.rwth-aachen.de

--------------------------------------------------------------------
Joint Stock Company Intel A/O
Registered legal address: Krylatsky Hills Business Park,
17 Krylatskaya Str., Bldg 4, Moscow 121614, Russian Federation

This e-mail and any attachments may contain confidential material for the
sole use of the intended recipient(s). Any review or distribution by

others is

strictly prohibited. If you are not the intended recipient, please contact

the