1 //===--- Kernel.cpp - OpenMP device kernel interface -------------- 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 // This file contains the kernel entry points for the device. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "Debug.h" 14 #include "Interface.h" 15 #include "Mapping.h" 16 #include "State.h" 17 #include "Synchronization.h" 18 #include "Types.h" 19 20 using namespace _OMP; 21 22 #pragma omp declare target 23 24 static void inititializeRuntime(bool IsSPMD) { 25 // Order is important here. 26 synchronize::init(IsSPMD); 27 mapping::init(IsSPMD); 28 state::init(IsSPMD); 29 } 30 31 /// Simple generic state machine for worker threads. 32 static void genericStateMachine(IdentTy *Ident) { 33 34 uint32_t TId = mapping::getThreadIdInBlock(); 35 36 do { 37 ParallelRegionFnTy WorkFn = 0; 38 39 // Wait for the signal that we have a new work function. 40 synchronize::threads(); 41 42 // Retrieve the work function from the runtime. 43 bool IsActive = __kmpc_kernel_parallel(&WorkFn); 44 45 // If there is nothing more to do, break out of the state machine by 46 // returning to the caller. 47 if (!WorkFn) 48 return; 49 50 if (IsActive) { 51 ASSERT(!mapping::isSPMDMode()); 52 ((void (*)(uint32_t, uint32_t))WorkFn)(0, TId); 53 __kmpc_kernel_end_parallel(); 54 } 55 56 synchronize::threads(); 57 58 } while (true); 59 } 60 61 extern "C" { 62 63 /// Initialization 64 /// 65 /// \param Ident Source location identification, can be NULL. 66 /// 67 int32_t __kmpc_target_init(IdentTy *Ident, bool IsSPMD, 68 bool UseGenericStateMachine, bool) { 69 if (IsSPMD) { 70 inititializeRuntime(/* IsSPMD */ true); 71 synchronize::threads(); 72 } else { 73 inititializeRuntime(/* IsSPMD */ false); 74 // No need to wait since only the main threads will execute user 75 // code and workers will run into a barrier right away. 76 } 77 78 if (IsSPMD) { 79 state::assumeInitialState(IsSPMD); 80 return -1; 81 } 82 83 if (mapping::isMainThreadInGenericMode()) 84 return -1; 85 86 if (UseGenericStateMachine) 87 genericStateMachine(Ident); 88 89 return mapping::getThreadIdInBlock(); 90 } 91 92 /// De-Initialization 93 /// 94 /// In non-SPMD, this function releases the workers trapped in a state machine 95 /// and also any memory dynamically allocated by the runtime. 96 /// 97 /// \param Ident Source location identification, can be NULL. 98 /// 99 void __kmpc_target_deinit(IdentTy *Ident, bool IsSPMD, bool) { 100 state::assumeInitialState(IsSPMD); 101 if (IsSPMD) 102 return; 103 104 // Signal the workers to exit the state machine and exit the kernel. 105 state::ParallelRegionFn = nullptr; 106 } 107 108 int8_t __kmpc_is_spmd_exec_mode() { return mapping::isSPMDMode(); } 109 } 110 111 #pragma omp end declare target 112