summaryrefslogtreecommitdiffstats
path: root/openmp/runtime/src/kmp_gsupport.cpp
diff options
context:
space:
mode:
authorJonathan Peyton <jonathan.l.peyton@intel.com>2018-04-18 19:23:54 +0000
committerJonathan Peyton <jonathan.l.peyton@intel.com>2018-04-18 19:23:54 +0000
commit27a677fc95c77d9cc31762bb1dd11da3173de8a1 (patch)
treef291ceb4d78c814c17a7de4d4af3545d26b4448c /openmp/runtime/src/kmp_gsupport.cpp
parent099c720426b2e54fc17c8fddc270ea9a8ca2e356 (diff)
downloadbcm5719-llvm-27a677fc95c77d9cc31762bb1dd11da3173de8a1.tar.gz
bcm5719-llvm-27a677fc95c77d9cc31762bb1dd11da3173de8a1.zip
Introduce GOMP_taskloop API
This patch introduces GOMP_taskloop to our API. It adds GOMP_4.5 to our version symbols. Being a wrapper around __kmpc_taskloop, the function creates a task with the loop bounds properly nested in the shareds so that the GOMP task thunk will work properly. Also, the firstprivate copy constructors are properly handled using the __kmp_gomp_task_dup() auxiliary function. Currently, only linear spawning of tasks is supported for the GOMP_taskloop interface. Differential Revision: https://reviews.llvm.org/D45327 llvm-svn: 330282
Diffstat (limited to 'openmp/runtime/src/kmp_gsupport.cpp')
-rw-r--r--openmp/runtime/src/kmp_gsupport.cpp136
1 files changed, 136 insertions, 0 deletions
diff --git a/openmp/runtime/src/kmp_gsupport.cpp b/openmp/runtime/src/kmp_gsupport.cpp
index fd1e6b212c8..c63cbda350c 100644
--- a/openmp/runtime/src/kmp_gsupport.cpp
+++ b/openmp/runtime/src/kmp_gsupport.cpp
@@ -1413,6 +1413,137 @@ void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TEAMS)(unsigned int num_teams,
}
#endif // OMP_40_ENABLED
+#if OMP_45_ENABLED
+
+// Task duplication function which copies src to dest (both are
+// preallocated task structures)
+static void __kmp_gomp_task_dup(kmp_task_t *dest, kmp_task_t *src,
+ kmp_int32 last_private) {
+ kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(src);
+ if (taskdata->td_copy_func) {
+ (taskdata->td_copy_func)(dest->shareds, src->shareds);
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+template <typename T>
+void __GOMP_taskloop(void (*func)(void *), void *data,
+ void (*copy_func)(void *, void *), long arg_size,
+ long arg_align, unsigned gomp_flags,
+ unsigned long num_tasks, int priority, T start, T end,
+ T step) {
+ typedef void (*p_task_dup_t)(kmp_task_t *, kmp_task_t *, kmp_int32);
+ MKLOC(loc, "GOMP_taskloop");
+ int sched;
+ T *loop_bounds;
+ int gtid = __kmp_entry_gtid();
+ kmp_int32 flags = 0;
+ int if_val = gomp_flags & (1u << 10);
+ int nogroup = gomp_flags & (1u << 11);
+ int up = gomp_flags & (1u << 8);
+ p_task_dup_t task_dup = NULL;
+ kmp_tasking_flags_t *input_flags = (kmp_tasking_flags_t *)&flags;
+#ifdef KMP_DEBUG
+ {
+ const char *buff;
+ buff = __kmp_str_format(
+ "GOMP_taskloop: T#%%d: func:%%p data:%%p copy_func:%%p "
+ "arg_size:%%ld arg_align:%%ld gomp_flags:0x%%x num_tasks:%%lu "
+ "priority:%%d start:%%%s end:%%%s step:%%%s\n",
+ traits_t<T>::spec, traits_t<T>::spec, traits_t<T>::spec);
+ KA_TRACE(20, (buff, gtid, func, data, copy_func, arg_size, arg_align,
+ gomp_flags, num_tasks, priority, start, end, step));
+ __kmp_str_free(&buff);
+ }
+#endif
+ KMP_ASSERT((size_t)arg_size >= 2 * sizeof(T));
+ KMP_ASSERT(arg_align > 0);
+ // The low-order bit is the "untied" flag
+ if (!(gomp_flags & 1)) {
+ input_flags->tiedness = 1;
+ }
+ // The second low-order bit is the "final" flag
+ if (gomp_flags & 2) {
+ input_flags->final = 1;
+ }
+ // Negative step flag
+ if (!up) {
+ // If step is flagged as negative, but isn't properly sign extended
+ // Then manually sign extend it. Could be a short, int, char embedded
+ // in a long. So cannot assume any cast.
+ if (step > 0) {
+ for (int i = sizeof(T) * CHAR_BIT - 1; i >= 0L; --i) {
+ // break at the first 1 bit
+ if (step & ((T)1 << i))
+ break;
+ step |= ((T)1 << i);
+ }
+ }
+ }
+ input_flags->native = 1;
+ // Figure out if none/grainsize/num_tasks clause specified
+ if (num_tasks > 0) {
+ if (gomp_flags & (1u << 9))
+ sched = 1; // grainsize specified
+ else
+ sched = 2; // num_tasks specified
+ // neither grainsize nor num_tasks specified
+ } else {
+ sched = 0;
+ }
+
+ // __kmp_task_alloc() sets up all other flags
+ kmp_task_t *task =
+ __kmp_task_alloc(&loc, gtid, input_flags, sizeof(kmp_task_t),
+ arg_size + arg_align - 1, (kmp_routine_entry_t)func);
+ kmp_taskdata_t *taskdata = KMP_TASK_TO_TASKDATA(task);
+ taskdata->td_copy_func = copy_func;
+ taskdata->td_size_loop_bounds = sizeof(T);
+
+ // re-align shareds if needed and setup firstprivate copy constructors
+ // through the task_dup mechanism
+ task->shareds = (void *)((((size_t)task->shareds) + arg_align - 1) /
+ arg_align * arg_align);
+ if (copy_func) {
+ task_dup = __kmp_gomp_task_dup;
+ }
+ KMP_MEMCPY(task->shareds, data, arg_size);
+
+ loop_bounds = (T *)task->shareds;
+ loop_bounds[0] = start;
+ loop_bounds[1] = end + (up ? -1 : 1);
+ __kmpc_taskloop(&loc, gtid, task, if_val, (kmp_uint64 *)&(loop_bounds[0]),
+ (kmp_uint64 *)&(loop_bounds[1]), (kmp_int64)step, nogroup,
+ sched, (kmp_uint64)num_tasks, (void *)task_dup);
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKLOOP)(
+ void (*func)(void *), void *data, void (*copy_func)(void *, void *),
+ long arg_size, long arg_align, unsigned gomp_flags, unsigned long num_tasks,
+ int priority, long start, long end, long step) {
+ __GOMP_taskloop<long>(func, data, copy_func, arg_size, arg_align, gomp_flags,
+ num_tasks, priority, start, end, step);
+}
+
+void KMP_EXPAND_NAME(KMP_API_NAME_GOMP_TASKLOOP_ULL)(
+ void (*func)(void *), void *data, void (*copy_func)(void *, void *),
+ long arg_size, long arg_align, unsigned gomp_flags, unsigned long num_tasks,
+ int priority, unsigned long long start, unsigned long long end,
+ unsigned long long step) {
+ __GOMP_taskloop<unsigned long long>(func, data, copy_func, arg_size,
+ arg_align, gomp_flags, num_tasks,
+ priority, start, end, step);
+}
+
+#endif
+
/* The following sections of code create aliases for the GOMP_* functions, then
create versioned symbols using the assembler directive .symver. This is only
pertinent for ELF .so library. The KMP_VERSION_SYMBOL macro is defined in
@@ -1521,6 +1652,11 @@ KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TARGET_UPDATE, 40, "GOMP_4.0");
KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TEAMS, 40, "GOMP_4.0");
#endif
+#if OMP_45_ENABLED
+KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKLOOP, 45, "GOMP_4.5");
+KMP_VERSION_SYMBOL(KMP_API_NAME_GOMP_TASKLOOP_ULL, 45, "GOMP_4.5");
+#endif
+
#endif // KMP_USE_VERSION_SYMBOLS
#ifdef __cplusplus
OpenPOWER on IntegriCloud