This is an archive of the discontinued LLVM Phabricator instance.

Do not block on explicit task depending on proxy task
ClosedPublic

Authored by Hahnfeld on Aug 3 2016, 4:15 AM.

Details

Summary

Consider the following code:

int dep;
#pragma omp target nowait depend(out: dep)
{
    sleep(1);
}
#pragma omp task depend(in: dep)
{
    printf("Task with dependency\n");
}
printf("Doing some work...\n");

In its current state the runtime will block on the second task and not
continue execution.

Diff Detail

Repository
rL LLVM

Event Timeline

Hahnfeld updated this revision to Diff 66643.Aug 3 2016, 4:15 AM
Hahnfeld retitled this revision from to Do not block on explicit task depending on proxy task.
Hahnfeld updated this object.
Hahnfeld added reviewers: jlpeyton, AndreyChurbanov.
Hahnfeld added a subscriber: openmp-commits.
hfinkel added a subscriber: hfinkel.Aug 3 2016, 4:20 AM

Please add your example as a regression test case.

Hahnfeld updated this revision to Diff 66795.Aug 4 2016, 6:16 AM

Add test emulating what I think the Intel Compiler generates and which shows the issue

Jonas,

What if you add one more dependent task (not on the proxy task)? E.g.

int dep;
#pragma omp target nowait depend(out: dep)
{
    sleep(1);
}
#pragma omp task depend(in: dep)
{
    printf("Task with dependency\n");
}
#pragma omp task depend(out: dep)
{
    printf("Another task with dependency\n");
}
printf("Doing some work...\n");

The second dependent task will be lost (unless it also has "in" dependency and thus only depends on the proxy task). It should not be hard to allow all serial dependent tasks be deferred in the presence of proxy task, just couple more changes in the

__kmp_task_finish()

routine can solve this I think. But is it what you want? If you want to only allow tasks those depend on the proxy task be deferred letting other serial dependent tasks be undeferred, then more changes may be needed. Library will need to distinguish tasks dependent on proxy task (among possible multiple dependencies) from tasks dependent on only regular tasks.

Hahnfeld updated this revision to Diff 66911.Aug 5 2016, 12:26 AM
Hahnfeld edited edge metadata.

Fix for dependency chain with proxy task as its origin

Jonas,

What if you add one more dependent task (not on the proxy task)? E.g.

int dep;
#pragma omp target nowait depend(out: dep)
{
    sleep(1);
}
#pragma omp task depend(in: dep)
{
    printf("Task with dependency\n");
}
#pragma omp task depend(out: dep)
{
    printf("Another task with dependency\n");
}
printf("Doing some work...\n");

The second dependent task will be lost (unless it also has "in" dependency and thus only depends on the proxy task). It should not be hard to allow all serial dependent tasks be deferred in the presence of proxy task, just couple more changes in the

__kmp_task_finish()

routine can solve this I think. But is it what you want? If you want to only allow tasks those depend on the proxy task be deferred letting other serial dependent tasks be undeferred, then more changes may be needed. Library will need to distinguish tasks dependent on proxy task (among possible multiple dependencies) from tasks dependent on only regular tasks.

Good catch, thanks! I think I've modified __kmp_task_finish() as you said to release eventual deps and added another dependent task to the test.

I think this will only allow dependency chains with a proxy task as its origin. Otherwise the previous tasks in the serial team will already have finished.
This probably means some no-op checking for serial tasks with dependencies after a proxy task has occured but I think that this is better than blocking on a dependent task.

Thanks,
Jonas

AndreyChurbanov accepted this revision.Aug 5 2016, 7:05 AM
AndreyChurbanov edited edge metadata.

LGTM

This revision is now accepted and ready to land.Aug 5 2016, 7:05 AM
This revision was automatically updated to reflect the committed changes.