[Openmp-dev] Detached tasks behavior changed

Shilei Tian via Openmp-dev openmp-dev at lists.llvm.org
Mon Feb 1 10:10:04 PST 2021


Hi Raúl,

This patch (https://reviews.llvm.org/D95798 <https://reviews.llvm.org/D95798>) should fix the issue. Can I include your test into the repo?

Regards,
Shilei

> On Feb 1, 2021, at 12:31 PM, Shilei Tian <tianshilei1992 at gmail.com> wrote:
> 
> Hi Raúl,
> 
> Thanks for your report. I’ll fix it soon.
> 
> Regards,
> Shilei
> 
>> On Feb 1, 2021, at 3:48 AM, Raúl Peñacoba Veigas via Openmp-dev <openmp-dev at lists.llvm.org <mailto:openmp-dev at lists.llvm.org>> wrote:
>> 
>> Hi everyone,
>> 
>> I've noticed in 9d64275a the behavior of detached tasks has changed. From this commit now the runtime does not taskwait the detached task until completion. If I understand correctly, detached tasks behave like a proxy task, and proxy tasks are taskwaited until completion.
>> 
>> I attach test that creates a detached or proxy task that performs a sleep to check that the master thread stays in the taskwait.
>> 
>> // test.c
>> 
>> #if !defined(DETACH) && !defined(PROXY)
>> #error Use -DDETACH or -DPROXY to compile the test
>> #endif
>> 
>> #include <stdio.h>
>> #include <pthread.h>
>> #include <omp.h>
>> #include <unistd.h>
>> 
>> // detached
>> #define PTASK_FLAG_DETACHABLE 0x40
>> // proxy
>> #define PTASK_FLAG_PROXY 0x10
>> 
>> // OpenMP RTL interfaces
>> typedef long long kmp_int64;
>> 
>> typedef struct ID {
>>   int reserved_1;
>>   int flags;
>>   int reserved_2;
>>   int reserved_3;
>>   char *psource;
>> } id;
>> 
>> // Compiler-generated code (emulation)
>> typedef struct ident {
>>   void* dummy; // not used in the library
>> } ident_t;
>> 
>> typedef enum kmp_event_type_t {
>>   KMP_EVENT_UNINITIALIZED = 0,
>>   KMP_EVENT_ALLOW_COMPLETION = 1
>> } kmp_event_type_t;
>> 
>> typedef struct {
>>   kmp_event_type_t type;
>>   union {
>>     void *task;
>>   } ed;
>> } kmp_event_t;
>> 
>> typedef struct shar { // shareds used in the task
>> } *pshareds;
>> 
>> typedef struct task {
>>   pshareds shareds;
>>   int(*routine)(int,struct task*);
>>   int part_id;
>> // void *destructor_thunk; // optional, needs flag setting if provided
>> // int priority; // optional, needs flag setting if provided
>> // ------------------------------
>> // privates used in the task:
>>   omp_event_handle_t evt;
>> } *ptask, kmp_task_t;
>> 
>> typedef int(* task_entry_t)( int, ptask );
>> 
>> #ifdef __cplusplus
>> extern "C" {
>> #endif
>> extern int  __kmpc_global_thread_num(void *id_ref);
>> extern int** __kmpc_omp_task_alloc(id *loc, int gtid, int flags,
>>                                    size_t sz, size_t shar, task_entry_t rtn);
>> extern int __kmpc_omp_task(id *loc, kmp_int64 gtid, kmp_task_t *task);
>> extern void __kmpc_proxy_task_completed_ooo ( kmp_task_t *ptask );
>> extern omp_event_handle_t __kmpc_task_allow_completion_event(
>>                               ident_t *loc_ref, int gtid, kmp_task_t *task);
>> #ifdef __cplusplus
>> }
>> #endif
>> 
>> int volatile checker;
>> 
>> void *target(void *task)
>> {
>>     sleep( 3 );
>>     checker = 1;
>> #ifdef DETACH
>>     omp_fulfill_event(((ptask)task)->evt);
>> #endif
>> #ifdef PROXY
>>     __kmpc_proxy_task_completed_ooo((ptask)task);
>> #endif
>>     return NULL;
>> }
>> 
>> pthread_t target_thread;
>> 
>> // User's code
>> int task_entry(int gtid, ptask task)
>> {
>>     pthread_create(&target_thread, NULL, &target, task);
>>     return 0;
>> }
>> 
>> int main() {
>>   int gtid = __kmpc_global_thread_num(NULL);
>>   ptask task;
>>   checker = 0;
>>   omp_event_handle_t evt;
>> /*
>>   #pragma omp task detach(evt)
>>   {}
>> */
>> #ifdef DETACH
>>   printf("detaching...\n");
>>   task = (ptask)__kmpc_omp_task_alloc(NULL,gtid,PTASK_FLAG_DETACHABLE,
>>                     sizeof(struct task),sizeof(struct shar),&task_entry);
>>   evt = (omp_event_handle_t)__kmpc_task_allow_completion_event(NULL,gtid,task);
>>   task->evt = evt;
>> #endif
>> #ifdef PROXY
>>   printf("proxifying...\n");
>>   task = (ptask)__kmpc_omp_task_alloc(NULL,gtid,PTASK_FLAG_PROXY,
>>                     sizeof(struct task),sizeof(struct shar),&task_entry);
>> #endif
>>   __kmpc_omp_task(NULL, gtid, task);
>>   #pragma omp taskwait
>> 
>>   // check results
>>   if (checker == 1) {
>>     printf("passed\n");
>>     return 0;
>>   } else {
>>     printf("failed\n");
>>     return 1;
>>   }
>> }
>> 
>> // end test.c
>> 
>> To use detached or proxy task use -DDETACH or -DPROXY in the compilation line.
>> 
>> The source line that is performing that behavior is https://github.com/llvm/llvm-project/blob/main/openmp/runtime/src/kmp_tasking.cpp#L1274 <https://github.com/llvm/llvm-project/blob/main/openmp/runtime/src/kmp_tasking.cpp#L1274> . Previously the code was https://github.com/llvm/llvm-project/blob/357eea6e8bf78a822b8d3a6fe3bc6f85fee66a3e/openmp/runtime/src/kmp_tasking.cpp#L1236 <https://github.com/llvm/llvm-project/blob/357eea6e8bf78a822b8d3a6fe3bc6f85fee66a3e/openmp/runtime/src/kmp_tasking.cpp#L1236> .
>> 
>> Regards,
>> 
>> Raúl
>> 
>> 
>> 
>> http://bsc.es/disclaimer <http://bsc.es/disclaimer>
>> _______________________________________________
>> Openmp-dev mailing list
>> Openmp-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/openmp-dev
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/openmp-dev/attachments/20210201/26e73baf/attachment-0001.html>


More information about the Openmp-dev mailing list