1 //===-------- Tasking.cpp - NVPTX OpenMP tasks support ------------ C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Task implementation support. 10 // 11 // TODO: We should not allocate and execute the task in two steps. A new API is 12 // needed for that though. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "Interface.h" 17 #include "State.h" 18 #include "Types.h" 19 #include "Utils.h" 20 21 using namespace _OMP; 22 23 #pragma omp begin declare target device_type(nohost) 24 25 TaskDescriptorTy *__kmpc_omp_task_alloc(IdentTy *, uint32_t, int32_t, 26 uint64_t TaskSizeInclPrivateValues, 27 uint64_t SharedValuesSize, 28 TaskFnTy TaskFn) { 29 FunctionTracingRAII(); 30 auto TaskSizeInclPrivateValuesPadded = 31 utils::roundUp(TaskSizeInclPrivateValues, uint64_t(sizeof(void *))); 32 auto TaskSizeTotal = TaskSizeInclPrivateValuesPadded + SharedValuesSize; 33 TaskDescriptorTy *TaskDescriptor = (TaskDescriptorTy *)memory::allocGlobal( 34 TaskSizeTotal, "explicit task descriptor"); 35 TaskDescriptor->Payload = 36 utils::advance(TaskDescriptor, TaskSizeInclPrivateValuesPadded); 37 TaskDescriptor->TaskFn = TaskFn; 38 39 return TaskDescriptor; 40 } 41 42 int32_t __kmpc_omp_task(IdentTy *Loc, uint32_t TId, 43 TaskDescriptorTy *TaskDescriptor) { 44 FunctionTracingRAII(); 45 return __kmpc_omp_task_with_deps(Loc, TId, TaskDescriptor, 0, 0, 0, 0); 46 } 47 48 int32_t __kmpc_omp_task_with_deps(IdentTy *Loc, uint32_t TId, 49 TaskDescriptorTy *TaskDescriptor, int32_t, 50 void *, int32_t, void *) { 51 FunctionTracingRAII(); 52 state::DateEnvironmentRAII DERAII(Loc); 53 54 TaskDescriptor->TaskFn(0, TaskDescriptor); 55 56 memory::freeGlobal(TaskDescriptor, "explicit task descriptor"); 57 return 0; 58 } 59 60 void __kmpc_omp_task_begin_if0(IdentTy *Loc, uint32_t TId, 61 TaskDescriptorTy *TaskDescriptor) { 62 FunctionTracingRAII(); 63 state::enterDataEnvironment(Loc); 64 } 65 66 void __kmpc_omp_task_complete_if0(IdentTy *Loc, uint32_t TId, 67 TaskDescriptorTy *TaskDescriptor) { 68 FunctionTracingRAII(); 69 state::exitDataEnvironment(); 70 71 memory::freeGlobal(TaskDescriptor, "explicit task descriptor"); 72 } 73 74 void __kmpc_omp_wait_deps(IdentTy *Loc, uint32_t TId, int32_t, void *, int32_t, 75 void *) { 76 FunctionTracingRAII(); 77 } 78 79 void __kmpc_taskgroup(IdentTy *Loc, uint32_t TId) { FunctionTracingRAII(); } 80 81 void __kmpc_end_taskgroup(IdentTy *Loc, uint32_t TId) { FunctionTracingRAII(); } 82 83 int32_t __kmpc_omp_taskyield(IdentTy *Loc, uint32_t TId, int) { 84 FunctionTracingRAII(); 85 return 0; 86 } 87 88 int32_t __kmpc_omp_taskwait(IdentTy *Loc, uint32_t TId) { 89 FunctionTracingRAII(); 90 return 0; 91 } 92 93 void __kmpc_taskloop(IdentTy *Loc, uint32_t TId, 94 TaskDescriptorTy *TaskDescriptor, int, 95 uint64_t *LowerBound, uint64_t *UpperBound, int64_t, int, 96 int32_t, uint64_t, void *) { 97 FunctionTracingRAII(); 98 // Skip task entirely if empty iteration space. 99 if (*LowerBound > *UpperBound) 100 return; 101 102 // The compiler has already stored lb and ub in the TaskDescriptorTy structure 103 // as we are using a single task to execute the entire loop, we can leave 104 // the initial task_t untouched 105 __kmpc_omp_task_with_deps(Loc, TId, TaskDescriptor, 0, 0, 0, 0); 106 } 107 108 int omp_in_final(void) { 109 // treat all tasks as final... Specs may expect runtime to keep 110 // track more precisely if a task was actively set by users... This 111 // is not explicitly specified; will treat as if runtime can 112 // actively decide to put a non-final task into a final one. 113 return 1; 114 } 115 116 int omp_get_max_task_priority(void) { return 0; } 117 118 #pragma omp end declare target 119