[Openmp-commits] [openmp] r363799 - New implementation of OpenMP 5.0 detached tasks.

Andrey Churbanov via Openmp-commits openmp-commits at lists.llvm.org
Wed Jun 19 06:23:28 PDT 2019


Author: achurbanov
Date: Wed Jun 19 06:23:28 2019
New Revision: 363799

URL: http://llvm.org/viewvc/llvm-project?rev=363799&view=rev
Log:
New implementation of OpenMP 5.0 detached tasks.

Patch by Alex Duran

Differential Revision: https://reviews.llvm.org/D62485

Added:
    openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t1.c   (with props)
    openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t2.c   (with props)
    openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t3.c   (with props)
Modified:
    openmp/trunk/runtime/src/dllexports
    openmp/trunk/runtime/src/include/50/omp.h.var
    openmp/trunk/runtime/src/include/50/omp_lib.f.var
    openmp/trunk/runtime/src/include/50/omp_lib.f90.var
    openmp/trunk/runtime/src/include/50/omp_lib.h.var
    openmp/trunk/runtime/src/kmp.h
    openmp/trunk/runtime/src/kmp_ftn_entry.h
    openmp/trunk/runtime/src/kmp_ftn_os.h
    openmp/trunk/runtime/src/kmp_tasking.cpp

Modified: openmp/trunk/runtime/src/dllexports
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/dllexports?rev=363799&r1=363798&r2=363799&view=diff
==============================================================================
--- openmp/trunk/runtime/src/dllexports (original)
+++ openmp/trunk/runtime/src/dllexports Wed Jun 19 06:23:28 2019
@@ -408,7 +408,7 @@ kmpc_set_disp_num_buffers
         __kmpc_pause_resource               273
         __kmpc_task_reduction_modifier_init 274
         __kmpc_task_reduction_modifier_fini 275
-      # __kmpc_task_allow_completion_event  276
+        __kmpc_task_allow_completion_event  276
         __kmpc_taskred_init                 277
         __kmpc_taskred_modifier_init        278
     %endif
@@ -572,6 +572,7 @@ kmp_set_disp_num_buffers
     omp_pause_resource                      756
     omp_pause_resource_all                  757
     omp_get_supported_active_levels         758
+    omp_fulfill_event                       759
 
     omp_null_allocator                     DATA
     omp_default_mem_alloc                  DATA

Modified: openmp/trunk/runtime/src/include/50/omp.h.var
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/include/50/omp.h.var?rev=363799&r1=363798&r2=363799&view=diff
==============================================================================
--- openmp/trunk/runtime/src/include/50/omp.h.var (original)
+++ openmp/trunk/runtime/src/include/50/omp.h.var Wed Jun 19 06:23:28 2019
@@ -334,6 +334,15 @@
     extern void __KAI_KMPC_CONVENTION omp_display_affinity(char const *);
     extern size_t __KAI_KMPC_CONVENTION omp_capture_affinity(char *, size_t, char const *);
 
+    /* OpenMP 5.0 events */
+#   if defined(_WIN32)
+    // On Windows cl and icl do not support 64-bit enum, let's use integer then.
+    typedef omp_uintptr_t omp_event_handle_t;
+#   else
+    typedef enum omp_event_handle_t { KMP_EVENT_MAX_HANDLE = UINTPTR_MAX } omp_event_handle_t;
+#   endif
+    extern void __KAI_KMPC_CONVENTION omp_fulfill_event ( omp_event_handle_t event );
+
     /* OpenMP 5.0 Pause Resources */
     typedef enum omp_pause_resource_t {
       omp_pause_resume = 0,

Modified: openmp/trunk/runtime/src/include/50/omp_lib.f.var
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/include/50/omp_lib.f.var?rev=363799&r1=363798&r2=363799&view=diff
==============================================================================
--- openmp/trunk/runtime/src/include/50/omp_lib.f.var (original)
+++ openmp/trunk/runtime/src/include/50/omp_lib.f.var Wed Jun 19 06:23:28 2019
@@ -45,6 +45,7 @@
 
         integer, parameter :: omp_pause_resource_kind = omp_integer_kind
         integer, parameter :: omp_depend_kind = int_ptr_kind()
+        integer, parameter :: omp_event_handle_kind = int_ptr_kind()
 
       end module omp_lib_kinds
 
@@ -351,6 +352,11 @@
             integer (kind=omp_integer_kind) omp_get_supported_active_levels
           end function omp_get_supported_active_levels
 
+          subroutine omp_fulfill_event(event)
+            use omp_lib_kinds
+            integer (kind=omp_event_handle_kind) event
+          end subroutine omp_fulfill_event
+
           subroutine omp_init_lock(svar)
 !DIR$ IF(__INTEL_COMPILER.GE.1400)
 !DIR$ attributes known_intrinsic :: omp_init_lock
@@ -705,6 +711,7 @@
 !dec$ attributes alias:'OMP_PAUSE_RESOURCE' :: omp_pause_resource
 !dec$ attributes alias:'OMP_PAUSE_RESOURCE_ALL' :: omp_pause_resource_all
 !dec$ attributes alias:'OMP_GET_SUPPORTED_ACTIVE_LEVELS' :: omp_get_supported_active_levels
+!dec$ attributes alias:'OMP_FULFILL_EVENT' :: omp_fulfill_event
 
 !dec$ attributes alias:'OMP_CONTROL_TOOL' :: omp_control_tool
 !dec$ attributes alias:'OMP_SET_AFFINITY_FORMAT' :: omp_set_affinity_format
@@ -796,6 +803,7 @@
 !dec$ attributes alias:'_OMP_PAUSE_RESOURCE' :: omp_pause_resource
 !dec$ attributes alias:'_OMP_PAUSE_RESOURCE_ALL' :: omp_pause_resource_all
 !dec$ attributes alias:'_OMP_GET_SUPPORTED_ACTIVE_LEVELS' :: omp_get_supported_active_levels
+!dec$ attributes alias:'_OMP_FULFILL_EVENT' :: omp_fulfill_event
 
 !dec$ attributes alias:'_OMP_CONTROL_TOOL' :: omp_control_tool
 !dec$ attributes alias:'_OMP_SET_AFFINITY_FORMAT' :: omp_set_affinity_format
@@ -890,6 +898,7 @@
 !dec$ attributes alias:'omp_pause_resource_' :: omp_pause_resource
 !dec$ attributes alias:'omp_pause_resource_all_' :: omp_pause_resource_all
 !dec$ attributes alias:'omp_get_supported_active_levels_' :: omp_get_supported_active_levels
+!dec$ attributes alias:'omp_fulfill_event_' :: omp_fulfill_event
 
 !dec$ attributes alias:'omp_set_affinity_format_' :: omp_set_affinity_format
 !dec$ attributes alias:'omp_get_affinity_format_' :: omp_get_affinity_format
@@ -983,6 +992,7 @@
 !dec$ attributes alias:'_omp_pause_resource_' :: omp_pause_resource
 !dec$ attributes alias:'_omp_pause_resource_all_' :: omp_pause_resource_all
 !dec$ attributes alias:'_omp_get_supported_active_levels_' :: omp_get_supported_active_levels
+!dec$ attributes alias:'_omp_fulfill_event_' :: omp_fulfill_event
 
 !dec$ attributes alias:'_omp_init_lock_'::omp_init_lock
 !dec$ attributes alias:'_omp_init_lock_with_hint_'::omp_init_lock_with_hint

Modified: openmp/trunk/runtime/src/include/50/omp_lib.f90.var
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/include/50/omp_lib.f90.var?rev=363799&r1=363798&r2=363799&view=diff
==============================================================================
--- openmp/trunk/runtime/src/include/50/omp_lib.f90.var (original)
+++ openmp/trunk/runtime/src/include/50/omp_lib.f90.var Wed Jun 19 06:23:28 2019
@@ -42,6 +42,7 @@
 
         integer, parameter :: omp_pause_resource_kind = omp_integer_kind
         integer, parameter :: omp_depend_kind = c_intptr_t
+        integer, parameter :: omp_event_handle_kind = c_intptr_t
 
       end module omp_lib_kinds
 
@@ -366,6 +367,11 @@
             integer (kind=omp_integer_kind) omp_get_supported_active_levels
           end function omp_get_supported_active_levels
 
+          subroutine omp_fulfill_event(event) bind(c)
+            use omp_lib_kinds
+            integer (kind=omp_event_handle_kind), value :: event
+          end subroutine omp_fulfill_event
+
           subroutine omp_init_lock(svar) bind(c)
 !DIR$ IF(__INTEL_COMPILER.GE.1400)
 !DIR$ attributes known_intrinsic :: omp_init_lock

Modified: openmp/trunk/runtime/src/include/50/omp_lib.h.var
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/include/50/omp_lib.h.var?rev=363799&r1=363798&r2=363799&view=diff
==============================================================================
--- openmp/trunk/runtime/src/include/50/omp_lib.h.var (original)
+++ openmp/trunk/runtime/src/include/50/omp_lib.h.var Wed Jun 19 06:23:28 2019
@@ -50,6 +50,8 @@
       parameter(omp_pause_resource_kind=omp_integer_kind)
       integer omp_depend_kind
       parameter(omp_depend_kind=int_ptr_kind())
+      integer omp_event_handle_kind
+      parameter(omp_event_handle_kind=int_ptr_kind())
 
       integer(kind=omp_integer_kind)openmp_version
       parameter(openmp_version=@LIBOMP_OMP_YEAR_MONTH@)
@@ -442,6 +444,11 @@
           integer (kind=omp_integer_kind) omp_get_supported_active_levels
         end function omp_get_supported_active_levels
 
+        subroutine omp_fulfill_event(event) bind(c)
+          import
+          integer (kind=omp_event_handle_kind), value :: event
+        end subroutine omp_fulfill_event
+
         subroutine omp_init_lock(svar) bind(c)
 !DIR$ IF(__INTEL_COMPILER.GE.1400)
 !DIR$ attributes known_intrinsic :: omp_init_lock
@@ -778,6 +785,7 @@
 !DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_pause_resource
 !DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_pause_resource_all
 !DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_supported_active_levels
+!DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_fulfill_event
 !DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_num_teams
 !DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_get_team_num
 !DIR$ ATTRIBUTES OFFLOAD:MIC :: omp_init_lock
@@ -860,6 +868,7 @@
 !$omp declare target(omp_pause_resource )
 !$omp declare target(omp_pause_resource_all )
 !$omp declare target(omp_get_supported_active_levels )
+!$omp declare target(omp_fulfill_event)
 !$omp declare target(omp_get_num_teams )
 !$omp declare target(omp_get_team_num )
 !$omp declare target(omp_init_lock )

Modified: openmp/trunk/runtime/src/kmp.h
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp.h?rev=363799&r1=363798&r2=363799&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp.h (original)
+++ openmp/trunk/runtime/src/kmp.h Wed Jun 19 06:23:28 2019
@@ -48,6 +48,8 @@
 #define TASK_IMPLICIT 0
 #define TASK_PROXY 1
 #define TASK_FULL 0
+#define TASK_DETACHABLE 1
+#define TASK_UNDETACHABLE 0
 
 #define KMP_CANCEL_THREADS
 #define KMP_THREAD_ATTR
@@ -2269,6 +2271,19 @@ typedef struct kmp_task_affinity_info {
     kmp_int32 reserved : 30;
   } flags;
 } kmp_task_affinity_info_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;
+  kmp_tas_lock_t lock;
+  union {
+    kmp_task_t *task;
+  } ed;
+} kmp_event_t;
 #endif
 
 #endif
@@ -2304,7 +2319,8 @@ typedef struct kmp_tasking_flags { /* To
                          context of the RTL) */
   unsigned priority_specified : 1; /* set if the compiler provides priority
                                       setting for the task */
-  unsigned reserved : 10; /* reserved for compiler use */
+  unsigned detachable : 1; /* 1 == can detach */
+  unsigned reserved : 9; /* reserved for compiler use */
 #else
   unsigned reserved : 12; /* reserved for compiler use */
 #endif
@@ -2372,6 +2388,9 @@ struct kmp_taskdata { /* aligned during
   // GOMP sends in a copy function for copy constructors
   void (*td_copy_func)(void *, void *);
 #endif
+#if OMP_50_ENABLED
+  kmp_event_t td_allow_completion_event;
+#endif
 #if OMPT_SUPPORT
   ompt_task_info_t ompt_task_info;
 #endif
@@ -3642,6 +3661,14 @@ extern void __kmp_init_implicit_task(ide
                                      int set_curr_task);
 extern void __kmp_finish_implicit_task(kmp_info_t *this_thr);
 extern void __kmp_free_implicit_task(kmp_info_t *this_thr);
+
+#ifdef OMP_50_ENABLED
+extern kmp_event_t *__kmpc_task_allow_completion_event(ident_t *loc_ref,
+                                                       int gtid,
+                                                       kmp_task_t *task);
+extern void __kmp_fulfill_event(kmp_event_t *event);
+#endif
+
 int __kmp_execute_tasks_32(kmp_info_t *thread, kmp_int32 gtid,
                            kmp_flag_32 *flag, int final_spin,
                            int *thread_finished,

Modified: openmp/trunk/runtime/src/kmp_ftn_entry.h
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_ftn_entry.h?rev=363799&r1=363798&r2=363799&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp_ftn_entry.h (original)
+++ openmp/trunk/runtime/src/kmp_ftn_entry.h Wed Jun 19 06:23:28 2019
@@ -1387,6 +1387,12 @@ int FTN_STDCALL FTN_GET_SUPPORTED_ACTIVE
 #endif
 }
 
+void FTN_STDCALL FTN_FULFILL_EVENT(kmp_event_t *event) {
+#ifndef KMP_STUB
+  __kmp_fulfill_event(event);
+#endif
+}
+
 #endif // OMP_50_ENABLED
 
 // GCC compatibility (versioned symbols)
@@ -1493,6 +1499,7 @@ KMP_VERSION_SYMBOL(FTN_GET_PARTITION_PLA
 // KMP_VERSION_SYMBOL(FTN_PAUSE_RESOURCE, 50, "OMP_5.0");
 // KMP_VERSION_SYMBOL(FTN_PAUSE_RESOURCE_ALL, 50, "OMP_5.0");
 // KMP_VERSION_SYMBOL(FTN_GET_SUPPORTED_ACTIVE_LEVELS, 50, "OMP_5.0");
+// KMP_VERSION_SYMBOL(FTN_FULFILL_EVENT, 50, "OMP_5.0");
 #endif
 
 #endif // KMP_USE_VERSION_SYMBOLS

Modified: openmp/trunk/runtime/src/kmp_ftn_os.h
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_ftn_os.h?rev=363799&r1=363798&r2=363799&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp_ftn_os.h (original)
+++ openmp/trunk/runtime/src/kmp_ftn_os.h Wed Jun 19 06:23:28 2019
@@ -144,6 +144,7 @@
 #define FTN_PAUSE_RESOURCE omp_pause_resource
 #define FTN_PAUSE_RESOURCE_ALL omp_pause_resource_all
 #define FTN_GET_SUPPORTED_ACTIVE_LEVELS omp_get_supported_active_levels
+#define FTN_FULFILL_EVENT omp_fulfill_event
 #endif
 
 #endif /* KMP_FTN_PLAIN */
@@ -278,6 +279,7 @@
 #define FTN_PAUSE_RESOURCE omp_pause_resource_
 #define FTN_PAUSE_RESOURCE_ALL omp_pause_resource_all_
 #define FTN_GET_SUPPORTED_ACTIVE_LEVELS omp_get_supported_active_levels_
+#define FTN_FULFILL_EVENT omp_fulfill_event_
 #endif
 
 #endif /* KMP_FTN_APPEND */
@@ -410,6 +412,7 @@
 #define FTN_PAUSE_RESOURCE OMP_PAUSE_RESOURCE
 #define FTN_PAUSE_RESOURCE_ALL OMP_PAUSE_RESOURCE_ALL
 #define FTN_GET_SUPPORTED_ACTIVE_LEVELS OMP_GET_SUPPORTED_ACTIVE_LEVELS
+#define FTN_FULFILL_EVENT OMP_FULFILL_EVENT
 #endif
 
 #endif /* KMP_FTN_UPPER */
@@ -544,6 +547,7 @@
 #define FTN_PAUSE_RESOURCE OMP_PAUSE_RESOURCE_
 #define FTN_PAUSE_RESOURCE_ALL OMP_PAUSE_RESOURCE_ALL_
 #define FTN_GET_SUPPORTED_ACTIVE_LEVELS OMP_GET_SUPPORTED_ACTIVE_LEVELS_
+#define FTN_FULFILL_EVENT OMP_FULFILL_EVENT_
 #endif
 
 #endif /* KMP_FTN_UAPPEND */

Modified: openmp/trunk/runtime/src/kmp_tasking.cpp
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/src/kmp_tasking.cpp?rev=363799&r1=363798&r2=363799&view=diff
==============================================================================
--- openmp/trunk/runtime/src/kmp_tasking.cpp (original)
+++ openmp/trunk/runtime/src/kmp_tasking.cpp Wed Jun 19 06:23:28 2019
@@ -874,28 +874,47 @@ static void __kmp_task_finish(kmp_int32
   }
 
   KMP_DEBUG_ASSERT(taskdata->td_flags.complete == 0);
-  taskdata->td_flags.complete = 1; // mark the task as completed
+  bool detach = false;
+#if OMP_50_ENABLED
+  if (taskdata->td_flags.detachable == TASK_DETACHABLE) {
+    if (taskdata->td_allow_completion_event.type ==
+        KMP_EVENT_ALLOW_COMPLETION) {
+      // event hasn't been fulfilled yet. Try to detach task.
+      __kmp_acquire_tas_lock(&taskdata->td_allow_completion_event.lock, gtid);
+      if (taskdata->td_allow_completion_event.type ==
+          KMP_EVENT_ALLOW_COMPLETION) {
+        taskdata->td_flags.proxy = TASK_PROXY; // proxify!
+        detach = true;
+      }
+      __kmp_release_tas_lock(&taskdata->td_allow_completion_event.lock, gtid);
+    }
+  }
+#endif
   KMP_DEBUG_ASSERT(taskdata->td_flags.started == 1);
   KMP_DEBUG_ASSERT(taskdata->td_flags.freed == 0);
 
-  // Only need to keep track of count if team parallel and tasking not
-  // serialized
-  if (!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser)) {
-    // Predecrement simulated by "- 1" calculation
-    children =
-        KMP_ATOMIC_DEC(&taskdata->td_parent->td_incomplete_child_tasks) - 1;
-    KMP_DEBUG_ASSERT(children >= 0);
+  if (!detach) {
+    taskdata->td_flags.complete = 1; // mark the task as completed
+
+    // Only need to keep track of count if team parallel and tasking not
+    // serialized
+    if (!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser)) {
+      // Predecrement simulated by "- 1" calculation
+      children =
+          KMP_ATOMIC_DEC(&taskdata->td_parent->td_incomplete_child_tasks) - 1;
+      KMP_DEBUG_ASSERT(children >= 0);
 #if OMP_40_ENABLED
-    if (taskdata->td_taskgroup)
-      KMP_ATOMIC_DEC(&taskdata->td_taskgroup->count);
-    __kmp_release_deps(gtid, taskdata);
-#if OMP_45_ENABLED
-  } else if (task_team && task_team->tt.tt_found_proxy_tasks) {
-    // if we found proxy tasks there could exist a dependency chain
-    // with the proxy task as origin
-    __kmp_release_deps(gtid, taskdata);
+      if (taskdata->td_taskgroup)
+        KMP_ATOMIC_DEC(&taskdata->td_taskgroup->count);
+      __kmp_release_deps(gtid, taskdata);
+#if OMP_45_ENABLED
+    } else if (task_team && task_team->tt.tt_found_proxy_tasks) {
+      // if we found proxy tasks there could exist a dependency chain
+      // with the proxy task as origin
+      __kmp_release_deps(gtid, taskdata);
 #endif // OMP_45_ENABLED
 #endif // OMP_40_ENABLED
+    }
   }
 
   // td_flags.executing must be marked as 0 after __kmp_release_deps has been
@@ -942,7 +961,8 @@ static void __kmp_task_finish(kmp_int32
   // johnmc: if an asynchronous inquiry peers into the runtime system
   // it doesn't see the freed task as the current task.
   thread->th.th_current_task = resumed_task;
-  __kmp_free_task_and_ancestors(gtid, taskdata, thread);
+  if (!detach)
+    __kmp_free_task_and_ancestors(gtid, taskdata, thread);
 
   // TODO: GEH - make sure root team implicit task is initialized properly.
   // KMP_DEBUG_ASSERT( resumed_task->td_flags.executing == 0 );
@@ -1069,6 +1089,9 @@ void __kmp_init_implicit_task(ident_t *l
   task->td_depnode = NULL;
 #endif
   task->td_last_tied = task;
+#if OMP_50_ENABLED
+  task->td_allow_completion_event.type = KMP_EVENT_UNINITIALIZED;
+#endif
 
   if (set_curr_task) { // only do this init first time thread is created
     KMP_ATOMIC_ST_REL(&task->td_incomplete_child_tasks, 0);
@@ -1187,11 +1210,19 @@ kmp_task_t *__kmp_task_alloc(ident_t *lo
     KMP_CHECK_UPDATE(thread->th.th_task_team->tt.tt_untied_task_encountered, 1);
   }
 
+#if OMP_50_ENABLED
+  // Detachable tasks are not proxy tasks yet but could be in the future. Doing
+  // the tasking setup
+  // when that happens is too late.
+  if (flags->proxy == TASK_PROXY || flags->detachable == TASK_DETACHABLE) {
+#endif
 #if OMP_45_ENABLED
-  if (flags->proxy == TASK_PROXY) {
-    flags->tiedness = TASK_UNTIED;
-    flags->merged_if0 = 1;
-
+    if (flags->proxy == TASK_PROXY) {
+      flags->tiedness = TASK_UNTIED;
+      flags->merged_if0 = 1;
+#if OMP_50_ENABLED
+    }
+#endif
     /* are we running in a sequential parallel or tskm_immediate_exec... we need
        tasking support enabled */
     if ((thread->th.th_task_team) == NULL) {
@@ -1295,6 +1326,9 @@ kmp_task_t *__kmp_task_alloc(ident_t *lo
 #endif // OMP_40_ENABLED
 #if OMP_45_ENABLED
   taskdata->td_flags.proxy = flags->proxy;
+#if OMP_50_ENABLED
+  taskdata->td_flags.detachable = flags->detachable;
+#endif
   taskdata->td_task_team = thread->th.th_task_team;
   taskdata->td_size_alloc = shareds_offset + sizeof_shareds;
 #endif
@@ -1334,15 +1368,20 @@ kmp_task_t *__kmp_task_alloc(ident_t *lo
     taskdata->td_last_tied = NULL; // will be set when the task is scheduled
   else
     taskdata->td_last_tied = taskdata;
-
+#if OMP_50_ENABLED
+  taskdata->td_allow_completion_event.type = KMP_EVENT_UNINITIALIZED;
+#endif
 #if OMPT_SUPPORT
   if (UNLIKELY(ompt_enabled.enabled))
     __ompt_task_init(taskdata, gtid);
 #endif
 // Only need to keep track of child task counts if team parallel and tasking not
-// serialized or if it is a proxy task
+// serialized or if it is a proxy or detachable task
 #if OMP_45_ENABLED
   if (flags->proxy == TASK_PROXY ||
+#if OMP_50_ENABLED
+      flags->detachable == TASK_DETACHABLE ||
+#endif
       !(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser))
 #else
   if (!(taskdata->td_flags.team_serial || taskdata->td_flags.tasking_ser))
@@ -1378,11 +1417,20 @@ kmp_task_t *__kmpc_omp_task_alloc(ident_
 // __kmp_task_alloc() sets up all other runtime flags
 
 #if OMP_45_ENABLED
+#if OMP_50_ENABLED
+  KA_TRACE(10, ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s %s %s) "
+                "sizeof_task=%ld sizeof_shared=%ld entry=%p\n",
+                gtid, loc_ref, input_flags->tiedness ? "tied  " : "untied",
+                input_flags->proxy ? "proxy" : "",
+                input_flags->detachable ? "detachable" : "", sizeof_kmp_task_t,
+                sizeof_shareds, task_entry));
+#else
   KA_TRACE(10, ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s %s) "
                 "sizeof_task=%ld sizeof_shared=%ld entry=%p\n",
                 gtid, loc_ref, input_flags->tiedness ? "tied  " : "untied",
                 input_flags->proxy ? "proxy" : "", sizeof_kmp_task_t,
                 sizeof_shareds, task_entry));
+#endif
 #else
   KA_TRACE(10, ("__kmpc_omp_task_alloc(enter): T#%d loc=%p, flags=(%s) "
                 "sizeof_task=%ld sizeof_shared=%ld entry=%p\n",
@@ -3914,6 +3962,58 @@ void __kmpc_proxy_task_completed_ooo(kmp
        taskdata));
 }
 
+#if OMP_50_ENABLED
+kmp_event_t *__kmpc_task_allow_completion_event(ident_t *loc_ref, int gtid,
+                                                kmp_task_t *task) {
+  kmp_taskdata_t *td = KMP_TASK_TO_TASKDATA(task);
+  if (td->td_allow_completion_event.type == KMP_EVENT_UNINITIALIZED) {
+    td->td_allow_completion_event.type = KMP_EVENT_ALLOW_COMPLETION;
+    td->td_allow_completion_event.ed.task = task;
+    __kmp_init_tas_lock(&td->td_allow_completion_event.lock);
+  }
+  return &td->td_allow_completion_event;
+}
+
+void __kmp_fulfill_event(kmp_event_t *event) {
+  if (event->type == KMP_EVENT_ALLOW_COMPLETION) {
+    kmp_task_t *ptask = event->ed.task;
+    kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(ptask);
+    bool detached = false;
+    int gtid = __kmp_get_gtid();
+
+    if (taskdata->td_flags.proxy == TASK_PROXY) {
+      // The associated task code completed before this call and detached.
+      detached = true;
+      event->type = KMP_EVENT_UNINITIALIZED;
+    } else {
+      // The associated task has not completed but could be completing at this
+      // point.
+      // We need to take the lock to avoid races
+      __kmp_acquire_tas_lock(&event->lock, gtid);
+      if (taskdata->td_flags.proxy == TASK_PROXY)
+        detached = true;
+      event->type = KMP_EVENT_UNINITIALIZED;
+      __kmp_release_tas_lock(&event->lock, gtid);
+    }
+
+    if (detached) {
+      // If the task detached complete the proxy task
+      if (gtid >= 0) {
+        kmp_team_t *team = taskdata->td_team;
+        kmp_info_t *thread = __kmp_get_thread();
+        if (thread->th.th_team == team) {
+          __kmpc_proxy_task_completed(gtid, ptask);
+          return;
+        }
+      }
+
+      // fallback
+      __kmpc_proxy_task_completed_ooo(ptask);
+    }
+  }
+}
+#endif
+
 // __kmp_task_dup_alloc: Allocate the taskdata and make a copy of source task
 // for taskloop
 //

Added: openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t1.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t1.c?rev=363799&view=auto
==============================================================================
--- openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t1.c (added)
+++ openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t1.c Wed Jun 19 06:23:28 2019
@@ -0,0 +1,113 @@
+// RUN: %libomp-compile && env OMP_NUM_THREADS='3' %libomp-run
+// RUN: %libomp-compile && env OMP_NUM_THREADS='1' %libomp-run
+
+#include <stdio.h>
+#include <omp.h>
+#include "omp_my_sleep.h"
+
+// detached untied
+#define PTASK_FLAG_DETACHABLE 0x40
+
+// OpenMP RTL interfaces
+typedef unsigned long long kmp_uint64;
+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 ptask __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, int gtid, ptask task);
+extern omp_event_handle_t __kmpc_task_allow_completion_event(
+                              ident_t *loc_ref, int gtid, ptask task);
+#if __cplusplus
+}
+#endif
+
+int volatile checker;
+
+// User's code, outlined into task entry
+int task_entry(int gtid, ptask task) {
+  checker = 1;
+  return 0;
+}
+
+int main() {
+  int i, j, gtid = __kmpc_global_thread_num(NULL);
+  int nt = omp_get_max_threads();
+  ptask task;
+  pshareds psh;
+  checker = 0;
+  omp_set_dynamic(0);
+  #pragma omp parallel //num_threads(N)
+  {
+    #pragma omp master
+    {
+      int gtid = __kmpc_global_thread_num(NULL);
+      omp_event_handle_t evt;
+/*
+      #pragma omp task detach(evt)
+      {}
+*/
+      task = (ptask)__kmpc_omp_task_alloc(NULL,gtid,PTASK_FLAG_DETACHABLE,sizeof(struct task),sizeof(struct shar),&task_entry);
+      psh = task->shareds;
+      evt = (omp_event_handle_t)__kmpc_task_allow_completion_event(NULL,gtid,task);
+      task->evt = evt;
+
+      __kmpc_omp_task(NULL, gtid, task);
+      my_sleep(2.0);
+      omp_fulfill_event(evt);
+
+    } // end master
+  } // end parallel
+
+  // check results
+  if (checker == 1) {
+    printf("passed\n");
+    return 0;
+  } else {
+    printf("failed\n");
+    return 1;
+  }
+}

Propchange: openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t1.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t1.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t1.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t2.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t2.c?rev=363799&view=auto
==============================================================================
--- openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t2.c (added)
+++ openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t2.c Wed Jun 19 06:23:28 2019
@@ -0,0 +1,116 @@
+// RUN: %libomp-compile && env OMP_NUM_THREADS='3' %libomp-run
+// RUN: %libomp-compile && env OMP_NUM_THREADS='1' %libomp-run
+
+#include <stdio.h>
+#include <omp.h>
+#include "omp_my_sleep.h"
+
+// detached tied
+#define PTASK_FLAG_DETACHABLE 0x41
+
+// OpenMP RTL interfaces
+typedef unsigned long long kmp_uint64;
+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, int gtid, kmp_task_t *task);
+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;
+
+// User's code, outlined into task entry
+int task_entry(int gtid, ptask task) {
+  my_sleep(2.0);
+  checker = 1;
+  return 0;
+}
+
+int main() {
+  int i, j, gtid = __kmpc_global_thread_num(NULL);
+  int nt = omp_get_max_threads();
+  ptask task;
+  pshareds psh;
+  checker = 0;
+  omp_set_dynamic(0);
+  #pragma omp parallel //num_threads(N)
+  {
+    #pragma omp master
+    {
+      int gtid = __kmpc_global_thread_num(NULL);
+      omp_event_handle_t evt;
+/*
+      #pragma omp task detach(evt)
+      {}
+*/
+      task = (ptask)__kmpc_omp_task_alloc(NULL,gtid,PTASK_FLAG_DETACHABLE,
+                        sizeof(struct task),sizeof(struct shar),&task_entry);
+      psh = task->shareds;
+      evt = (omp_event_handle_t)__kmpc_task_allow_completion_event(NULL,gtid,task);
+      task->evt = evt;
+      __kmpc_omp_task(NULL, gtid, task);
+      omp_fulfill_event(evt);
+      #pragma omp taskwait
+      ;
+//      printf("after tw %d\n", omp_get_thread_num());
+    } // end master
+  } // end parallel
+
+  // check results
+  if (checker == 1) {
+    printf("passed\n");
+    return 0;
+  } else {
+    printf("failed\n");
+    return 1;
+  }
+}

Propchange: openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t2.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t2.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t2.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t3.c
URL: http://llvm.org/viewvc/llvm-project/openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t3.c?rev=363799&view=auto
==============================================================================
--- openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t3.c (added)
+++ openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t3.c Wed Jun 19 06:23:28 2019
@@ -0,0 +1,138 @@
+// RUN: %libomp-compile && env OMP_NUM_THREADS='3' %libomp-run
+// RUN: %libomp-compile && env OMP_NUM_THREADS='1' %libomp-run
+// The runtime currently does not get dependency information from GCC.
+// UNSUPPORTED: gcc
+
+#include <stdio.h>
+#include <omp.h>
+#include "omp_my_sleep.h"
+
+// detached untied
+#define PTASK_FLAG_DETACHABLE 0x40
+
+// OpenMP RTL interfaces
+typedef unsigned long long kmp_uint64;
+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 struct DEP {
+  size_t addr;
+  size_t len;
+  int flags;
+} dep;
+
+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_with_deps(id *loc, int gtid, ptask task, int nd,
+               dep *dep_lst, int nd_noalias, dep *noalias_dep_lst);
+extern int __kmpc_omp_task(id *loc, int gtid, kmp_task_t *task);
+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;
+
+// User's code, outlined into task entry
+int task_entry(int gtid, ptask task) {
+  checker = 1;
+  return 0;
+}
+
+int main() {
+  int i, j, gtid = __kmpc_global_thread_num(NULL);
+  int nt = omp_get_max_threads();
+  ptask task;
+  pshareds psh;
+  checker = 0;
+  omp_set_dynamic(0);
+  #pragma omp parallel //num_threads(N)
+  {
+    #pragma omp master
+    {
+      #pragma omp task depend(inout:nt)
+      {
+        my_sleep(2.0);
+      }
+      int gtid = __kmpc_global_thread_num(NULL);
+      omp_event_handle_t evt;
+/*
+      #pragma omp task detach(evt)
+      {}
+*/
+      task = (ptask)__kmpc_omp_task_alloc(NULL,gtid,PTASK_FLAG_DETACHABLE,
+                        sizeof(struct task),sizeof(struct shar),&task_entry);
+      psh = task->shareds;
+      evt = (omp_event_handle_t)__kmpc_task_allow_completion_event(NULL,gtid,task);
+      task->evt = evt;
+
+      dep sdep;
+      sdep.addr = (size_t)&nt;
+      sdep.len = 0L;
+      sdep.flags = 3;
+
+      __kmpc_omp_task_with_deps(NULL,gtid,task,1,&sdep,0,0);
+      //__kmpc_omp_task(NULL, gtid, task);
+
+      omp_fulfill_event(evt);
+
+      #pragma omp taskwait
+      ;
+//      printf("after tw %d\n", omp_get_thread_num());
+    } // end master
+  } // end parallel
+
+  // check results
+  if (checker == 1) {
+    printf("passed\n");
+    return 0;
+  } else {
+    printf("failed\n");
+    return 1;
+  }
+}

Propchange: openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t3.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t3.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Rev URL

Propchange: openmp/trunk/runtime/test/tasking/kmp_detach_tasks_t3.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain




More information about the Openmp-commits mailing list