[Openmp-dev] Detached tasks behavior changed

Raúl Peñacoba Veigas via Openmp-dev openmp-dev at lists.llvm.org
Mon Feb 1 23:30:44 PST 2021


Sure, thanks also for the quick reply.

Raúl

El 1/2/21 a las 19:10, Shilei Tian escribió:
> 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 
>> <mailto: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 <mailto:Openmp-dev at lists.llvm.org>
>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/openmp-dev
>>
>


http://bsc.es/disclaimer
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/openmp-dev/attachments/20210202/eaa5f643/attachment.html>


More information about the Openmp-dev mailing list