167ab875fSJohannes Doerfert //===-------- Tasking.cpp - NVPTX OpenMP tasks support ------------ C++ -*-===//
267ab875fSJohannes Doerfert //
367ab875fSJohannes Doerfert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
467ab875fSJohannes Doerfert // See https://llvm.org/LICENSE.txt for license information.
567ab875fSJohannes Doerfert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
667ab875fSJohannes Doerfert //
767ab875fSJohannes Doerfert //===----------------------------------------------------------------------===//
867ab875fSJohannes Doerfert //
967ab875fSJohannes Doerfert // Task implementation support.
1067ab875fSJohannes Doerfert //
1167ab875fSJohannes Doerfert // TODO: We should not allocate and execute the task in two steps. A new API is
1267ab875fSJohannes Doerfert // needed for that though.
1367ab875fSJohannes Doerfert //
1467ab875fSJohannes Doerfert //===----------------------------------------------------------------------===//
1567ab875fSJohannes Doerfert
1667ab875fSJohannes Doerfert #include "Interface.h"
1767ab875fSJohannes Doerfert #include "State.h"
1867ab875fSJohannes Doerfert #include "Types.h"
1967ab875fSJohannes Doerfert #include "Utils.h"
2067ab875fSJohannes Doerfert
2167ab875fSJohannes Doerfert using namespace _OMP;
2267ab875fSJohannes Doerfert
23*b4f8443dSJoseph Huber #pragma omp begin declare target device_type(nohost)
2467ab875fSJohannes Doerfert
__kmpc_omp_task_alloc(IdentTy *,uint32_t,int32_t,uint64_t TaskSizeInclPrivateValues,uint64_t SharedValuesSize,TaskFnTy TaskFn)2567ab875fSJohannes Doerfert TaskDescriptorTy *__kmpc_omp_task_alloc(IdentTy *, uint32_t, int32_t,
2667ab875fSJohannes Doerfert uint64_t TaskSizeInclPrivateValues,
2767ab875fSJohannes Doerfert uint64_t SharedValuesSize,
2867ab875fSJohannes Doerfert TaskFnTy TaskFn) {
2974f91741SJoseph Huber FunctionTracingRAII();
3067ab875fSJohannes Doerfert auto TaskSizeInclPrivateValuesPadded =
3167ab875fSJohannes Doerfert utils::roundUp(TaskSizeInclPrivateValues, uint64_t(sizeof(void *)));
3267ab875fSJohannes Doerfert auto TaskSizeTotal = TaskSizeInclPrivateValuesPadded + SharedValuesSize;
3367ab875fSJohannes Doerfert TaskDescriptorTy *TaskDescriptor = (TaskDescriptorTy *)memory::allocGlobal(
3467ab875fSJohannes Doerfert TaskSizeTotal, "explicit task descriptor");
3567ab875fSJohannes Doerfert TaskDescriptor->Payload =
3667ab875fSJohannes Doerfert utils::advance(TaskDescriptor, TaskSizeInclPrivateValuesPadded);
3767ab875fSJohannes Doerfert TaskDescriptor->TaskFn = TaskFn;
3867ab875fSJohannes Doerfert
3967ab875fSJohannes Doerfert return TaskDescriptor;
4067ab875fSJohannes Doerfert }
4167ab875fSJohannes Doerfert
__kmpc_omp_task(IdentTy * Loc,uint32_t TId,TaskDescriptorTy * TaskDescriptor)4267ab875fSJohannes Doerfert int32_t __kmpc_omp_task(IdentTy *Loc, uint32_t TId,
4367ab875fSJohannes Doerfert TaskDescriptorTy *TaskDescriptor) {
4474f91741SJoseph Huber FunctionTracingRAII();
4567ab875fSJohannes Doerfert return __kmpc_omp_task_with_deps(Loc, TId, TaskDescriptor, 0, 0, 0, 0);
4667ab875fSJohannes Doerfert }
4767ab875fSJohannes Doerfert
__kmpc_omp_task_with_deps(IdentTy * Loc,uint32_t TId,TaskDescriptorTy * TaskDescriptor,int32_t,void *,int32_t,void *)4867ab875fSJohannes Doerfert int32_t __kmpc_omp_task_with_deps(IdentTy *Loc, uint32_t TId,
4967ab875fSJohannes Doerfert TaskDescriptorTy *TaskDescriptor, int32_t,
5067ab875fSJohannes Doerfert void *, int32_t, void *) {
5174f91741SJoseph Huber FunctionTracingRAII();
521e121568SJohannes Doerfert state::DateEnvironmentRAII DERAII(Loc);
5367ab875fSJohannes Doerfert
5467ab875fSJohannes Doerfert TaskDescriptor->TaskFn(0, TaskDescriptor);
5567ab875fSJohannes Doerfert
5667ab875fSJohannes Doerfert memory::freeGlobal(TaskDescriptor, "explicit task descriptor");
5767ab875fSJohannes Doerfert return 0;
5867ab875fSJohannes Doerfert }
5967ab875fSJohannes Doerfert
__kmpc_omp_task_begin_if0(IdentTy * Loc,uint32_t TId,TaskDescriptorTy * TaskDescriptor)6067ab875fSJohannes Doerfert void __kmpc_omp_task_begin_if0(IdentTy *Loc, uint32_t TId,
6167ab875fSJohannes Doerfert TaskDescriptorTy *TaskDescriptor) {
6274f91741SJoseph Huber FunctionTracingRAII();
631e121568SJohannes Doerfert state::enterDataEnvironment(Loc);
6467ab875fSJohannes Doerfert }
6567ab875fSJohannes Doerfert
__kmpc_omp_task_complete_if0(IdentTy * Loc,uint32_t TId,TaskDescriptorTy * TaskDescriptor)6667ab875fSJohannes Doerfert void __kmpc_omp_task_complete_if0(IdentTy *Loc, uint32_t TId,
6767ab875fSJohannes Doerfert TaskDescriptorTy *TaskDescriptor) {
6874f91741SJoseph Huber FunctionTracingRAII();
6967ab875fSJohannes Doerfert state::exitDataEnvironment();
7067ab875fSJohannes Doerfert
7167ab875fSJohannes Doerfert memory::freeGlobal(TaskDescriptor, "explicit task descriptor");
7267ab875fSJohannes Doerfert }
7367ab875fSJohannes Doerfert
__kmpc_omp_wait_deps(IdentTy * Loc,uint32_t TId,int32_t,void *,int32_t,void *)7467ab875fSJohannes Doerfert void __kmpc_omp_wait_deps(IdentTy *Loc, uint32_t TId, int32_t, void *, int32_t,
7574f91741SJoseph Huber void *) {
7674f91741SJoseph Huber FunctionTracingRAII();
7774f91741SJoseph Huber }
7867ab875fSJohannes Doerfert
__kmpc_taskgroup(IdentTy * Loc,uint32_t TId)7974f91741SJoseph Huber void __kmpc_taskgroup(IdentTy *Loc, uint32_t TId) { FunctionTracingRAII(); }
8067ab875fSJohannes Doerfert
__kmpc_end_taskgroup(IdentTy * Loc,uint32_t TId)8174f91741SJoseph Huber void __kmpc_end_taskgroup(IdentTy *Loc, uint32_t TId) { FunctionTracingRAII(); }
8267ab875fSJohannes Doerfert
__kmpc_omp_taskyield(IdentTy * Loc,uint32_t TId,int)8374f91741SJoseph Huber int32_t __kmpc_omp_taskyield(IdentTy *Loc, uint32_t TId, int) {
8474f91741SJoseph Huber FunctionTracingRAII();
8574f91741SJoseph Huber return 0;
8674f91741SJoseph Huber }
8767ab875fSJohannes Doerfert
__kmpc_omp_taskwait(IdentTy * Loc,uint32_t TId)8874f91741SJoseph Huber int32_t __kmpc_omp_taskwait(IdentTy *Loc, uint32_t TId) {
8974f91741SJoseph Huber FunctionTracingRAII();
9074f91741SJoseph Huber return 0;
9174f91741SJoseph Huber }
9267ab875fSJohannes Doerfert
__kmpc_taskloop(IdentTy * Loc,uint32_t TId,TaskDescriptorTy * TaskDescriptor,int,uint64_t * LowerBound,uint64_t * UpperBound,int64_t,int,int32_t,uint64_t,void *)9367ab875fSJohannes Doerfert void __kmpc_taskloop(IdentTy *Loc, uint32_t TId,
9467ab875fSJohannes Doerfert TaskDescriptorTy *TaskDescriptor, int,
9567ab875fSJohannes Doerfert uint64_t *LowerBound, uint64_t *UpperBound, int64_t, int,
9667ab875fSJohannes Doerfert int32_t, uint64_t, void *) {
9774f91741SJoseph Huber FunctionTracingRAII();
9867ab875fSJohannes Doerfert // Skip task entirely if empty iteration space.
9967ab875fSJohannes Doerfert if (*LowerBound > *UpperBound)
10067ab875fSJohannes Doerfert return;
10167ab875fSJohannes Doerfert
10267ab875fSJohannes Doerfert // The compiler has already stored lb and ub in the TaskDescriptorTy structure
10367ab875fSJohannes Doerfert // as we are using a single task to execute the entire loop, we can leave
10467ab875fSJohannes Doerfert // the initial task_t untouched
10567ab875fSJohannes Doerfert __kmpc_omp_task_with_deps(Loc, TId, TaskDescriptor, 0, 0, 0, 0);
10667ab875fSJohannes Doerfert }
10767ab875fSJohannes Doerfert
omp_in_final(void)10867ab875fSJohannes Doerfert int omp_in_final(void) {
10967ab875fSJohannes Doerfert // treat all tasks as final... Specs may expect runtime to keep
11067ab875fSJohannes Doerfert // track more precisely if a task was actively set by users... This
11167ab875fSJohannes Doerfert // is not explicitly specified; will treat as if runtime can
11267ab875fSJohannes Doerfert // actively decide to put a non-final task into a final one.
11367ab875fSJohannes Doerfert return 1;
11467ab875fSJohannes Doerfert }
11567ab875fSJohannes Doerfert
omp_get_max_task_priority(void)11667ab875fSJohannes Doerfert int omp_get_max_task_priority(void) { return 0; }
11767ab875fSJohannes Doerfert
11867ab875fSJohannes Doerfert #pragma omp end declare target
119