[Openmp-dev] Detached tasks behavior changed

Raúl Peñacoba Veigas via Openmp-dev openmp-dev at lists.llvm.org
Mon Feb 1 00:48:11 PST 2021


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 
. Previously the code was 
https://github.com/llvm/llvm-project/blob/357eea6e8bf78a822b8d3a6fe3bc6f85fee66a3e/openmp/runtime/src/kmp_tasking.cpp#L1236 
.

Regards,

Raúl



http://bsc.es/disclaimer


More information about the Openmp-dev mailing list