1330d8983SJohannes Doerfert //===-- OpenMP/OMPT/Callback.cpp - OpenMP Tooling Callback implementation -===// 2330d8983SJohannes Doerfert // 3330d8983SJohannes Doerfert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4330d8983SJohannes Doerfert // See https://llvm.org/LICENSE.txt for license information. 5330d8983SJohannes Doerfert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6330d8983SJohannes Doerfert // 7330d8983SJohannes Doerfert //===----------------------------------------------------------------------===// 8330d8983SJohannes Doerfert // 9330d8983SJohannes Doerfert // Implementation of OMPT callback interfaces for target independent layer 10330d8983SJohannes Doerfert // 11330d8983SJohannes Doerfert //===----------------------------------------------------------------------===// 12330d8983SJohannes Doerfert 13*d36f66b4SMichael Halkenhäuser #ifdef OMPT_SUPPORT 14330d8983SJohannes Doerfert 15330d8983SJohannes Doerfert #include <cstdlib> 16330d8983SJohannes Doerfert #include <cstring> 17330d8983SJohannes Doerfert #include <memory> 18330d8983SJohannes Doerfert 19330d8983SJohannes Doerfert #include "Shared/Debug.h" 20330d8983SJohannes Doerfert 21330d8983SJohannes Doerfert #include "OpenMP/OMPT/Callback.h" 22330d8983SJohannes Doerfert #include "OpenMP/OMPT/Connector.h" 23330d8983SJohannes Doerfert #include "OpenMP/OMPT/Interface.h" 24330d8983SJohannes Doerfert 25330d8983SJohannes Doerfert #include "llvm/Support/DynamicLibrary.h" 26330d8983SJohannes Doerfert 27330d8983SJohannes Doerfert #undef DEBUG_PREFIX 28330d8983SJohannes Doerfert #define DEBUG_PREFIX "OMPT" 29330d8983SJohannes Doerfert 30330d8983SJohannes Doerfert // Define OMPT callback functions (bound to actual callbacks later on) 31330d8983SJohannes Doerfert #define defineOmptCallback(Name, Type, Code) \ 32330d8983SJohannes Doerfert Name##_t llvm::omp::target::ompt::Name##_fn = nullptr; 33330d8983SJohannes Doerfert FOREACH_OMPT_NOEMI_EVENT(defineOmptCallback) 34330d8983SJohannes Doerfert FOREACH_OMPT_EMI_EVENT(defineOmptCallback) 35330d8983SJohannes Doerfert #undef defineOmptCallback 36330d8983SJohannes Doerfert 37*d36f66b4SMichael Halkenhäuser using namespace llvm::omp::target::ompt; 38*d36f66b4SMichael Halkenhäuser 39330d8983SJohannes Doerfert /// Forward declaration 40330d8983SJohannes Doerfert class LibomptargetRtlFinalizer; 41330d8983SJohannes Doerfert 42330d8983SJohannes Doerfert /// Object that will maintain the RTL finalizer from the plugin 43330d8983SJohannes Doerfert LibomptargetRtlFinalizer *LibraryFinalizer = nullptr; 44330d8983SJohannes Doerfert 45330d8983SJohannes Doerfert thread_local Interface llvm::omp::target::ompt::RegionInterface; 46330d8983SJohannes Doerfert 47330d8983SJohannes Doerfert thread_local void *llvm::omp::target::ompt::ReturnAddress = nullptr; 48330d8983SJohannes Doerfert 49330d8983SJohannes Doerfert bool llvm::omp::target::ompt::Initialized = false; 50330d8983SJohannes Doerfert 51330d8983SJohannes Doerfert ompt_get_callback_t llvm::omp::target::ompt::lookupCallbackByCode = nullptr; 52330d8983SJohannes Doerfert ompt_function_lookup_t llvm::omp::target::ompt::lookupCallbackByName = nullptr; 53330d8983SJohannes Doerfert ompt_get_target_task_data_t ompt_get_target_task_data_fn = nullptr; 54330d8983SJohannes Doerfert ompt_get_task_data_t ompt_get_task_data_fn = nullptr; 55330d8983SJohannes Doerfert 56330d8983SJohannes Doerfert /// Unique correlation id 57330d8983SJohannes Doerfert static std::atomic<uint64_t> IdCounter(1); 58330d8983SJohannes Doerfert 59330d8983SJohannes Doerfert /// Used to create a new correlation id 60330d8983SJohannes Doerfert static uint64_t createId() { return IdCounter.fetch_add(1); } 61330d8983SJohannes Doerfert 62330d8983SJohannes Doerfert /// Create a new correlation id and update the operations id 63330d8983SJohannes Doerfert static uint64_t createOpId() { 64330d8983SJohannes Doerfert uint64_t NewId = createId(); 65330d8983SJohannes Doerfert RegionInterface.setHostOpId(NewId); 66330d8983SJohannes Doerfert return NewId; 67330d8983SJohannes Doerfert } 68330d8983SJohannes Doerfert 69330d8983SJohannes Doerfert /// Create a new correlation id and update the target region id 70330d8983SJohannes Doerfert static uint64_t createRegionId() { 71330d8983SJohannes Doerfert uint64_t NewId = createId(); 72330d8983SJohannes Doerfert RegionInterface.setTargetDataValue(NewId); 73330d8983SJohannes Doerfert return NewId; 74330d8983SJohannes Doerfert } 75330d8983SJohannes Doerfert 76330d8983SJohannes Doerfert void Interface::beginTargetDataAlloc(int64_t DeviceId, void *HstPtrBegin, 77330d8983SJohannes Doerfert void **TgtPtrBegin, size_t Size, 78330d8983SJohannes Doerfert void *Code) { 79330d8983SJohannes Doerfert beginTargetDataOperation(); 80330d8983SJohannes Doerfert if (ompt_callback_target_data_op_emi_fn) { 81330d8983SJohannes Doerfert // HostOpId will be set by the tool. Invoke the tool supplied data op EMI 82330d8983SJohannes Doerfert // callback 83330d8983SJohannes Doerfert ompt_callback_target_data_op_emi_fn( 84330d8983SJohannes Doerfert ompt_scope_begin, TargetTaskData, &TargetData, &HostOpId, 85330d8983SJohannes Doerfert ompt_target_data_alloc, HstPtrBegin, 86330d8983SJohannes Doerfert /*SrcDeviceNum=*/omp_get_initial_device(), *TgtPtrBegin, 87330d8983SJohannes Doerfert /*TgtDeviceNum=*/DeviceId, Size, Code); 88330d8983SJohannes Doerfert } else if (ompt_callback_target_data_op_fn) { 89330d8983SJohannes Doerfert // HostOpId is set by the runtime 90330d8983SJohannes Doerfert HostOpId = createOpId(); 91330d8983SJohannes Doerfert // Invoke the tool supplied data op callback 92330d8983SJohannes Doerfert ompt_callback_target_data_op_fn( 93330d8983SJohannes Doerfert TargetData.value, HostOpId, ompt_target_data_alloc, HstPtrBegin, 94330d8983SJohannes Doerfert /*SrcDeviceNum=*/omp_get_initial_device(), *TgtPtrBegin, 95330d8983SJohannes Doerfert /*TgtDeviceNum=*/DeviceId, Size, Code); 96330d8983SJohannes Doerfert } 97330d8983SJohannes Doerfert } 98330d8983SJohannes Doerfert 99330d8983SJohannes Doerfert void Interface::endTargetDataAlloc(int64_t DeviceId, void *HstPtrBegin, 100330d8983SJohannes Doerfert void **TgtPtrBegin, size_t Size, 101330d8983SJohannes Doerfert void *Code) { 102330d8983SJohannes Doerfert // Only EMI callback handles end scope 103330d8983SJohannes Doerfert if (ompt_callback_target_data_op_emi_fn) { 104330d8983SJohannes Doerfert // HostOpId will be set by the tool. Invoke the tool supplied data op EMI 105330d8983SJohannes Doerfert // callback 106330d8983SJohannes Doerfert ompt_callback_target_data_op_emi_fn( 107330d8983SJohannes Doerfert ompt_scope_end, TargetTaskData, &TargetData, &HostOpId, 108330d8983SJohannes Doerfert ompt_target_data_alloc, HstPtrBegin, 109330d8983SJohannes Doerfert /*SrcDeviceNum=*/omp_get_initial_device(), *TgtPtrBegin, 110330d8983SJohannes Doerfert /*TgtDeviceNum=*/DeviceId, Size, Code); 111330d8983SJohannes Doerfert } 112330d8983SJohannes Doerfert endTargetDataOperation(); 113330d8983SJohannes Doerfert } 114330d8983SJohannes Doerfert 115330d8983SJohannes Doerfert void Interface::beginTargetDataSubmit(int64_t SrcDeviceId, void *SrcPtrBegin, 116330d8983SJohannes Doerfert int64_t DstDeviceId, void *DstPtrBegin, 117330d8983SJohannes Doerfert size_t Size, void *Code) { 118330d8983SJohannes Doerfert beginTargetDataOperation(); 119330d8983SJohannes Doerfert if (ompt_callback_target_data_op_emi_fn) { 120330d8983SJohannes Doerfert // HostOpId will be set by the tool. Invoke the tool supplied data op EMI 121330d8983SJohannes Doerfert // callback 122330d8983SJohannes Doerfert ompt_callback_target_data_op_emi_fn( 123330d8983SJohannes Doerfert ompt_scope_begin, TargetTaskData, &TargetData, &HostOpId, 124330d8983SJohannes Doerfert ompt_target_data_transfer_to_device, SrcPtrBegin, SrcDeviceId, 125330d8983SJohannes Doerfert DstPtrBegin, DstDeviceId, Size, Code); 126330d8983SJohannes Doerfert } else if (ompt_callback_target_data_op_fn) { 127330d8983SJohannes Doerfert // HostOpId is set by the runtime 128330d8983SJohannes Doerfert HostOpId = createOpId(); 129330d8983SJohannes Doerfert // Invoke the tool supplied data op callback 130330d8983SJohannes Doerfert ompt_callback_target_data_op_fn( 131330d8983SJohannes Doerfert TargetData.value, HostOpId, ompt_target_data_transfer_to_device, 132330d8983SJohannes Doerfert SrcPtrBegin, SrcDeviceId, DstPtrBegin, DstDeviceId, Size, Code); 133330d8983SJohannes Doerfert } 134330d8983SJohannes Doerfert } 135330d8983SJohannes Doerfert 136330d8983SJohannes Doerfert void Interface::endTargetDataSubmit(int64_t SrcDeviceId, void *SrcPtrBegin, 137330d8983SJohannes Doerfert int64_t DstDeviceId, void *DstPtrBegin, 138330d8983SJohannes Doerfert size_t Size, void *Code) { 139330d8983SJohannes Doerfert // Only EMI callback handles end scope 140330d8983SJohannes Doerfert if (ompt_callback_target_data_op_emi_fn) { 141330d8983SJohannes Doerfert // HostOpId will be set by the tool. Invoke the tool supplied data op EMI 142330d8983SJohannes Doerfert // callback 143330d8983SJohannes Doerfert ompt_callback_target_data_op_emi_fn( 144330d8983SJohannes Doerfert ompt_scope_end, TargetTaskData, &TargetData, &HostOpId, 145330d8983SJohannes Doerfert ompt_target_data_transfer_to_device, SrcPtrBegin, SrcDeviceId, 146330d8983SJohannes Doerfert DstPtrBegin, DstDeviceId, Size, Code); 147330d8983SJohannes Doerfert } 148330d8983SJohannes Doerfert endTargetDataOperation(); 149330d8983SJohannes Doerfert } 150330d8983SJohannes Doerfert 151330d8983SJohannes Doerfert void Interface::beginTargetDataDelete(int64_t DeviceId, void *TgtPtrBegin, 152330d8983SJohannes Doerfert void *Code) { 153330d8983SJohannes Doerfert beginTargetDataOperation(); 154330d8983SJohannes Doerfert if (ompt_callback_target_data_op_emi_fn) { 155330d8983SJohannes Doerfert // HostOpId will be set by the tool. Invoke the tool supplied data op EMI 156330d8983SJohannes Doerfert // callback 157330d8983SJohannes Doerfert ompt_callback_target_data_op_emi_fn( 158330d8983SJohannes Doerfert ompt_scope_begin, TargetTaskData, &TargetData, &HostOpId, 159330d8983SJohannes Doerfert ompt_target_data_delete, TgtPtrBegin, DeviceId, 160330d8983SJohannes Doerfert /*TgtPtrBegin=*/nullptr, /*TgtDeviceNum=*/-1, /*Bytes=*/0, Code); 161330d8983SJohannes Doerfert } else if (ompt_callback_target_data_op_fn) { 162330d8983SJohannes Doerfert // HostOpId is set by the runtime 163330d8983SJohannes Doerfert HostOpId = createOpId(); 164330d8983SJohannes Doerfert // Invoke the tool supplied data op callback 165330d8983SJohannes Doerfert ompt_callback_target_data_op_fn(TargetData.value, HostOpId, 166330d8983SJohannes Doerfert ompt_target_data_delete, TgtPtrBegin, 167330d8983SJohannes Doerfert DeviceId, /*TgtPtrBegin=*/nullptr, 168330d8983SJohannes Doerfert /*TgtDeviceNum=*/-1, /*Bytes=*/0, Code); 169330d8983SJohannes Doerfert } 170330d8983SJohannes Doerfert } 171330d8983SJohannes Doerfert 172330d8983SJohannes Doerfert void Interface::endTargetDataDelete(int64_t DeviceId, void *TgtPtrBegin, 173330d8983SJohannes Doerfert void *Code) { 174330d8983SJohannes Doerfert // Only EMI callback handles end scope 175330d8983SJohannes Doerfert if (ompt_callback_target_data_op_emi_fn) { 176330d8983SJohannes Doerfert // HostOpId will be set by the tool. Invoke the tool supplied data op EMI 177330d8983SJohannes Doerfert // callback 178330d8983SJohannes Doerfert ompt_callback_target_data_op_emi_fn( 179330d8983SJohannes Doerfert ompt_scope_end, TargetTaskData, &TargetData, &HostOpId, 180330d8983SJohannes Doerfert ompt_target_data_delete, TgtPtrBegin, DeviceId, 181330d8983SJohannes Doerfert /*TgtPtrBegin=*/nullptr, /*TgtDeviceNum=*/-1, /*Bytes=*/0, Code); 182330d8983SJohannes Doerfert } 183330d8983SJohannes Doerfert endTargetDataOperation(); 184330d8983SJohannes Doerfert } 185330d8983SJohannes Doerfert 186330d8983SJohannes Doerfert void Interface::beginTargetDataRetrieve(int64_t SrcDeviceId, void *SrcPtrBegin, 187330d8983SJohannes Doerfert int64_t DstDeviceId, void *DstPtrBegin, 188330d8983SJohannes Doerfert size_t Size, void *Code) { 189330d8983SJohannes Doerfert beginTargetDataOperation(); 190330d8983SJohannes Doerfert if (ompt_callback_target_data_op_emi_fn) { 191330d8983SJohannes Doerfert // HostOpId will be set by the tool. Invoke the tool supplied data op EMI 192330d8983SJohannes Doerfert // callback 193330d8983SJohannes Doerfert ompt_callback_target_data_op_emi_fn( 194330d8983SJohannes Doerfert ompt_scope_begin, TargetTaskData, &TargetData, &HostOpId, 195330d8983SJohannes Doerfert ompt_target_data_transfer_from_device, SrcPtrBegin, SrcDeviceId, 196330d8983SJohannes Doerfert DstPtrBegin, DstDeviceId, Size, Code); 197330d8983SJohannes Doerfert } else if (ompt_callback_target_data_op_fn) { 198330d8983SJohannes Doerfert // HostOpId is set by the runtime 199330d8983SJohannes Doerfert HostOpId = createOpId(); 200330d8983SJohannes Doerfert // Invoke the tool supplied data op callback 201330d8983SJohannes Doerfert ompt_callback_target_data_op_fn( 202330d8983SJohannes Doerfert TargetData.value, HostOpId, ompt_target_data_transfer_from_device, 203330d8983SJohannes Doerfert SrcPtrBegin, SrcDeviceId, DstPtrBegin, DstDeviceId, Size, Code); 204330d8983SJohannes Doerfert } 205330d8983SJohannes Doerfert } 206330d8983SJohannes Doerfert 207330d8983SJohannes Doerfert void Interface::endTargetDataRetrieve(int64_t SrcDeviceId, void *SrcPtrBegin, 208330d8983SJohannes Doerfert int64_t DstDeviceId, void *DstPtrBegin, 209330d8983SJohannes Doerfert size_t Size, void *Code) { 210330d8983SJohannes Doerfert // Only EMI callback handles end scope 211330d8983SJohannes Doerfert if (ompt_callback_target_data_op_emi_fn) { 212330d8983SJohannes Doerfert // HostOpId will be set by the tool. Invoke the tool supplied data op EMI 213330d8983SJohannes Doerfert // callback 214330d8983SJohannes Doerfert ompt_callback_target_data_op_emi_fn( 215330d8983SJohannes Doerfert ompt_scope_end, TargetTaskData, &TargetData, &HostOpId, 216330d8983SJohannes Doerfert ompt_target_data_transfer_from_device, SrcPtrBegin, SrcDeviceId, 217330d8983SJohannes Doerfert DstPtrBegin, DstDeviceId, Size, Code); 218330d8983SJohannes Doerfert } 219330d8983SJohannes Doerfert endTargetDataOperation(); 220330d8983SJohannes Doerfert } 221330d8983SJohannes Doerfert 222*d36f66b4SMichael Halkenhäuser void Interface::beginTargetSubmit(unsigned int NumTeams) { 223330d8983SJohannes Doerfert if (ompt_callback_target_submit_emi_fn) { 224330d8983SJohannes Doerfert // HostOpId is set by the tool. Invoke the tool supplied target submit EMI 225330d8983SJohannes Doerfert // callback 226330d8983SJohannes Doerfert ompt_callback_target_submit_emi_fn(ompt_scope_begin, &TargetData, &HostOpId, 227*d36f66b4SMichael Halkenhäuser NumTeams); 228330d8983SJohannes Doerfert } else if (ompt_callback_target_submit_fn) { 229330d8983SJohannes Doerfert // HostOpId is set by the runtime 230330d8983SJohannes Doerfert HostOpId = createOpId(); 231*d36f66b4SMichael Halkenhäuser ompt_callback_target_submit_fn(TargetData.value, HostOpId, NumTeams); 232330d8983SJohannes Doerfert } 233330d8983SJohannes Doerfert } 234330d8983SJohannes Doerfert 235*d36f66b4SMichael Halkenhäuser void Interface::endTargetSubmit(unsigned int NumTeams) { 236330d8983SJohannes Doerfert // Only EMI callback handles end scope 237330d8983SJohannes Doerfert if (ompt_callback_target_submit_emi_fn) { 238330d8983SJohannes Doerfert // HostOpId is set by the tool. Invoke the tool supplied target submit EMI 239330d8983SJohannes Doerfert // callback 240330d8983SJohannes Doerfert ompt_callback_target_submit_emi_fn(ompt_scope_end, &TargetData, &HostOpId, 241*d36f66b4SMichael Halkenhäuser NumTeams); 242330d8983SJohannes Doerfert } 243330d8983SJohannes Doerfert } 244330d8983SJohannes Doerfert 245330d8983SJohannes Doerfert void Interface::beginTargetDataEnter(int64_t DeviceId, void *Code) { 246330d8983SJohannes Doerfert beginTargetRegion(); 247330d8983SJohannes Doerfert if (ompt_callback_target_emi_fn) { 248330d8983SJohannes Doerfert // Invoke the tool supplied target EMI callback 249330d8983SJohannes Doerfert ompt_callback_target_emi_fn(ompt_target_enter_data, ompt_scope_begin, 250330d8983SJohannes Doerfert DeviceId, TaskData, TargetTaskData, &TargetData, 251330d8983SJohannes Doerfert Code); 252330d8983SJohannes Doerfert } else if (ompt_callback_target_fn) { 253330d8983SJohannes Doerfert // Invoke the tool supplied target callback 254330d8983SJohannes Doerfert ompt_callback_target_fn(ompt_target_enter_data, ompt_scope_begin, DeviceId, 255330d8983SJohannes Doerfert TaskData, TargetData.value, Code); 256330d8983SJohannes Doerfert } 257330d8983SJohannes Doerfert } 258330d8983SJohannes Doerfert 259330d8983SJohannes Doerfert void Interface::endTargetDataEnter(int64_t DeviceId, void *Code) { 260330d8983SJohannes Doerfert if (ompt_callback_target_emi_fn) { 261330d8983SJohannes Doerfert // Invoke the tool supplied target EMI callback 262330d8983SJohannes Doerfert ompt_callback_target_emi_fn(ompt_target_enter_data, ompt_scope_end, 263330d8983SJohannes Doerfert DeviceId, TaskData, TargetTaskData, &TargetData, 264330d8983SJohannes Doerfert Code); 265330d8983SJohannes Doerfert } else if (ompt_callback_target_fn) { 266330d8983SJohannes Doerfert // Invoke the tool supplied target callback 267330d8983SJohannes Doerfert ompt_callback_target_fn(ompt_target_enter_data, ompt_scope_end, DeviceId, 268330d8983SJohannes Doerfert TaskData, TargetData.value, Code); 269330d8983SJohannes Doerfert } 270330d8983SJohannes Doerfert endTargetRegion(); 271330d8983SJohannes Doerfert } 272330d8983SJohannes Doerfert 273330d8983SJohannes Doerfert void Interface::beginTargetDataExit(int64_t DeviceId, void *Code) { 274330d8983SJohannes Doerfert beginTargetRegion(); 275330d8983SJohannes Doerfert if (ompt_callback_target_emi_fn) { 276330d8983SJohannes Doerfert // Invoke the tool supplied target EMI callback 277330d8983SJohannes Doerfert ompt_callback_target_emi_fn(ompt_target_exit_data, ompt_scope_begin, 278330d8983SJohannes Doerfert DeviceId, TaskData, TargetTaskData, &TargetData, 279330d8983SJohannes Doerfert Code); 280330d8983SJohannes Doerfert } else if (ompt_callback_target_fn) { 281330d8983SJohannes Doerfert TargetData.value = createRegionId(); 282330d8983SJohannes Doerfert // Invoke the tool supplied target callback 283330d8983SJohannes Doerfert ompt_callback_target_fn(ompt_target_exit_data, ompt_scope_begin, DeviceId, 284330d8983SJohannes Doerfert TaskData, TargetData.value, Code); 285330d8983SJohannes Doerfert } 286330d8983SJohannes Doerfert } 287330d8983SJohannes Doerfert 288330d8983SJohannes Doerfert void Interface::endTargetDataExit(int64_t DeviceId, void *Code) { 289330d8983SJohannes Doerfert if (ompt_callback_target_emi_fn) { 290330d8983SJohannes Doerfert // Invoke the tool supplied target EMI callback 291330d8983SJohannes Doerfert ompt_callback_target_emi_fn(ompt_target_exit_data, ompt_scope_end, DeviceId, 292330d8983SJohannes Doerfert TaskData, TargetTaskData, &TargetData, Code); 293330d8983SJohannes Doerfert } else if (ompt_callback_target_fn) { 294330d8983SJohannes Doerfert // Invoke the tool supplied target callback 295330d8983SJohannes Doerfert ompt_callback_target_fn(ompt_target_exit_data, ompt_scope_end, DeviceId, 296330d8983SJohannes Doerfert TaskData, TargetData.value, Code); 297330d8983SJohannes Doerfert } 298330d8983SJohannes Doerfert endTargetRegion(); 299330d8983SJohannes Doerfert } 300330d8983SJohannes Doerfert 301330d8983SJohannes Doerfert void Interface::beginTargetUpdate(int64_t DeviceId, void *Code) { 302330d8983SJohannes Doerfert beginTargetRegion(); 303330d8983SJohannes Doerfert if (ompt_callback_target_emi_fn) { 304330d8983SJohannes Doerfert // Invoke the tool supplied target EMI callback 305330d8983SJohannes Doerfert ompt_callback_target_emi_fn(ompt_target_update, ompt_scope_begin, DeviceId, 306330d8983SJohannes Doerfert TaskData, TargetTaskData, &TargetData, Code); 307330d8983SJohannes Doerfert } else if (ompt_callback_target_fn) { 308330d8983SJohannes Doerfert TargetData.value = createRegionId(); 309330d8983SJohannes Doerfert // Invoke the tool supplied target callback 310330d8983SJohannes Doerfert ompt_callback_target_fn(ompt_target_update, ompt_scope_begin, DeviceId, 311330d8983SJohannes Doerfert TaskData, TargetData.value, Code); 312330d8983SJohannes Doerfert } 313330d8983SJohannes Doerfert } 314330d8983SJohannes Doerfert 315330d8983SJohannes Doerfert void Interface::endTargetUpdate(int64_t DeviceId, void *Code) { 316330d8983SJohannes Doerfert if (ompt_callback_target_emi_fn) { 317330d8983SJohannes Doerfert // Invoke the tool supplied target EMI callback 318330d8983SJohannes Doerfert ompt_callback_target_emi_fn(ompt_target_update, ompt_scope_end, DeviceId, 319330d8983SJohannes Doerfert TaskData, TargetTaskData, &TargetData, Code); 320330d8983SJohannes Doerfert } else if (ompt_callback_target_fn) { 321330d8983SJohannes Doerfert // Invoke the tool supplied target callback 322330d8983SJohannes Doerfert ompt_callback_target_fn(ompt_target_update, ompt_scope_end, DeviceId, 323330d8983SJohannes Doerfert TaskData, TargetData.value, Code); 324330d8983SJohannes Doerfert } 325330d8983SJohannes Doerfert endTargetRegion(); 326330d8983SJohannes Doerfert } 327330d8983SJohannes Doerfert 328caaf8099SJan Patrick Lehr void Interface::beginTargetAssociatePointer(int64_t DeviceId, void *HstPtrBegin, 329caaf8099SJan Patrick Lehr void *TgtPtrBegin, size_t Size, 330caaf8099SJan Patrick Lehr void *Code) { 331caaf8099SJan Patrick Lehr beginTargetDataOperation(); 332caaf8099SJan Patrick Lehr if (ompt_callback_target_data_op_emi_fn) { 333caaf8099SJan Patrick Lehr ompt_callback_target_data_op_emi_fn( 334caaf8099SJan Patrick Lehr ompt_scope_begin, TargetTaskData, &TargetData, &HostOpId, 335caaf8099SJan Patrick Lehr ompt_target_data_associate, HstPtrBegin, omp_get_initial_device(), 336caaf8099SJan Patrick Lehr TgtPtrBegin, DeviceId, Size, Code); 337caaf8099SJan Patrick Lehr } else if (ompt_callback_target_data_op_fn) { 338caaf8099SJan Patrick Lehr HostOpId = createOpId(); 339caaf8099SJan Patrick Lehr ompt_callback_target_data_op_fn( 340caaf8099SJan Patrick Lehr TargetData.value, HostOpId, ompt_target_data_associate, HstPtrBegin, 341caaf8099SJan Patrick Lehr omp_get_initial_device(), TgtPtrBegin, DeviceId, Size, Code); 342caaf8099SJan Patrick Lehr } 343caaf8099SJan Patrick Lehr } 344caaf8099SJan Patrick Lehr 345caaf8099SJan Patrick Lehr void Interface::endTargetAssociatePointer(int64_t DeviceId, void *HstPtrBegin, 346caaf8099SJan Patrick Lehr void *TgtPtrBegin, size_t Size, 347caaf8099SJan Patrick Lehr void *Code) { 348caaf8099SJan Patrick Lehr if (ompt_callback_target_data_op_emi_fn) { 349caaf8099SJan Patrick Lehr ompt_callback_target_data_op_emi_fn( 350caaf8099SJan Patrick Lehr ompt_scope_end, TargetTaskData, &TargetData, &HostOpId, 351caaf8099SJan Patrick Lehr ompt_target_data_associate, HstPtrBegin, omp_get_initial_device(), 352caaf8099SJan Patrick Lehr TgtPtrBegin, DeviceId, Size, Code); 353caaf8099SJan Patrick Lehr } 354caaf8099SJan Patrick Lehr } 355caaf8099SJan Patrick Lehr 356caaf8099SJan Patrick Lehr void Interface::beginTargetDisassociatePointer(int64_t DeviceId, 357caaf8099SJan Patrick Lehr void *HstPtrBegin, 358caaf8099SJan Patrick Lehr void *TgtPtrBegin, size_t Size, 359caaf8099SJan Patrick Lehr void *Code) { 360caaf8099SJan Patrick Lehr beginTargetDataOperation(); 361caaf8099SJan Patrick Lehr if (ompt_callback_target_data_op_emi_fn) { 362caaf8099SJan Patrick Lehr ompt_callback_target_data_op_emi_fn( 363caaf8099SJan Patrick Lehr ompt_scope_begin, TargetTaskData, &TargetData, &HostOpId, 364caaf8099SJan Patrick Lehr ompt_target_data_disassociate, HstPtrBegin, omp_get_initial_device(), 365caaf8099SJan Patrick Lehr TgtPtrBegin, DeviceId, Size, Code); 366caaf8099SJan Patrick Lehr } else if (ompt_callback_target_data_op_fn) { 367caaf8099SJan Patrick Lehr HostOpId = createOpId(); 368caaf8099SJan Patrick Lehr ompt_callback_target_data_op_fn( 369caaf8099SJan Patrick Lehr TargetData.value, HostOpId, ompt_target_data_disassociate, HstPtrBegin, 370caaf8099SJan Patrick Lehr omp_get_initial_device(), TgtPtrBegin, DeviceId, Size, Code); 371caaf8099SJan Patrick Lehr } 372caaf8099SJan Patrick Lehr } 373caaf8099SJan Patrick Lehr void Interface::endTargetDisassociatePointer(int64_t DeviceId, 374caaf8099SJan Patrick Lehr void *HstPtrBegin, 375caaf8099SJan Patrick Lehr void *TgtPtrBegin, size_t Size, 376caaf8099SJan Patrick Lehr void *Code) { 377caaf8099SJan Patrick Lehr if (ompt_callback_target_data_op_emi_fn) { 378caaf8099SJan Patrick Lehr ompt_callback_target_data_op_emi_fn( 379caaf8099SJan Patrick Lehr ompt_scope_end, TargetTaskData, &TargetData, &HostOpId, 380caaf8099SJan Patrick Lehr ompt_target_data_disassociate, HstPtrBegin, omp_get_initial_device(), 381caaf8099SJan Patrick Lehr TgtPtrBegin, DeviceId, Size, Code); 382caaf8099SJan Patrick Lehr } 383caaf8099SJan Patrick Lehr } 384caaf8099SJan Patrick Lehr 385330d8983SJohannes Doerfert void Interface::beginTarget(int64_t DeviceId, void *Code) { 386330d8983SJohannes Doerfert beginTargetRegion(); 387330d8983SJohannes Doerfert if (ompt_callback_target_emi_fn) { 388330d8983SJohannes Doerfert // Invoke the tool supplied target EMI callback 389330d8983SJohannes Doerfert ompt_callback_target_emi_fn(ompt_target, ompt_scope_begin, DeviceId, 390330d8983SJohannes Doerfert TaskData, TargetTaskData, &TargetData, Code); 391330d8983SJohannes Doerfert } else if (ompt_callback_target_fn) { 392330d8983SJohannes Doerfert TargetData.value = createRegionId(); 393330d8983SJohannes Doerfert // Invoke the tool supplied target callback 394330d8983SJohannes Doerfert ompt_callback_target_fn(ompt_target, ompt_scope_begin, DeviceId, TaskData, 395330d8983SJohannes Doerfert TargetData.value, Code); 396330d8983SJohannes Doerfert } 397330d8983SJohannes Doerfert } 398330d8983SJohannes Doerfert 399330d8983SJohannes Doerfert void Interface::endTarget(int64_t DeviceId, void *Code) { 400330d8983SJohannes Doerfert if (ompt_callback_target_emi_fn) { 401330d8983SJohannes Doerfert // Invoke the tool supplied target EMI callback 402330d8983SJohannes Doerfert ompt_callback_target_emi_fn(ompt_target, ompt_scope_end, DeviceId, TaskData, 403330d8983SJohannes Doerfert TargetTaskData, &TargetData, Code); 404330d8983SJohannes Doerfert } else if (ompt_callback_target_fn) { 405330d8983SJohannes Doerfert // Invoke the tool supplied target callback 406330d8983SJohannes Doerfert ompt_callback_target_fn(ompt_target, ompt_scope_end, DeviceId, TaskData, 407330d8983SJohannes Doerfert TargetData.value, Code); 408330d8983SJohannes Doerfert } 409330d8983SJohannes Doerfert endTargetRegion(); 410330d8983SJohannes Doerfert } 411330d8983SJohannes Doerfert 412330d8983SJohannes Doerfert void Interface::beginTargetDataOperation() { 413330d8983SJohannes Doerfert DP("in ompt_target_region_begin (TargetRegionId = %lu)\n", TargetData.value); 414330d8983SJohannes Doerfert } 415330d8983SJohannes Doerfert 416330d8983SJohannes Doerfert void Interface::endTargetDataOperation() { 417330d8983SJohannes Doerfert DP("in ompt_target_region_end (TargetRegionId = %lu)\n", TargetData.value); 418330d8983SJohannes Doerfert } 419330d8983SJohannes Doerfert 420330d8983SJohannes Doerfert void Interface::beginTargetRegion() { 421330d8983SJohannes Doerfert // Set up task state 422330d8983SJohannes Doerfert assert(ompt_get_task_data_fn && "Calling a null task data function"); 423330d8983SJohannes Doerfert TaskData = ompt_get_task_data_fn(); 424330d8983SJohannes Doerfert // Set up target task state 425330d8983SJohannes Doerfert assert(ompt_get_target_task_data_fn && 426330d8983SJohannes Doerfert "Calling a null target task data function"); 427330d8983SJohannes Doerfert TargetTaskData = ompt_get_target_task_data_fn(); 428330d8983SJohannes Doerfert // Target state will be set later 429330d8983SJohannes Doerfert TargetData = ompt_data_none; 430330d8983SJohannes Doerfert } 431330d8983SJohannes Doerfert 432330d8983SJohannes Doerfert void Interface::endTargetRegion() { 433330d8983SJohannes Doerfert TaskData = 0; 434330d8983SJohannes Doerfert TargetTaskData = 0; 435330d8983SJohannes Doerfert TargetData = ompt_data_none; 436330d8983SJohannes Doerfert } 437330d8983SJohannes Doerfert 438330d8983SJohannes Doerfert /// Used to maintain the finalization functions that are received 439330d8983SJohannes Doerfert /// from the plugins during connect. 440330d8983SJohannes Doerfert /// Note: Currently, there are no plugin-specific finalizations, so each plugin 441330d8983SJohannes Doerfert /// will call the same (empty) function. 442330d8983SJohannes Doerfert class LibomptargetRtlFinalizer { 443330d8983SJohannes Doerfert public: 444330d8983SJohannes Doerfert LibomptargetRtlFinalizer() {} 445330d8983SJohannes Doerfert 446330d8983SJohannes Doerfert void registerRtl(ompt_finalize_t FinalizationFunction) { 447330d8983SJohannes Doerfert if (FinalizationFunction) { 448330d8983SJohannes Doerfert RtlFinalizationFunctions.emplace_back(FinalizationFunction); 449330d8983SJohannes Doerfert } 450330d8983SJohannes Doerfert } 451330d8983SJohannes Doerfert 452330d8983SJohannes Doerfert void finalize() { 453330d8983SJohannes Doerfert for (auto FinalizationFunction : RtlFinalizationFunctions) 454*d36f66b4SMichael Halkenhäuser FinalizationFunction(/*tool_data=*/nullptr); 455330d8983SJohannes Doerfert RtlFinalizationFunctions.clear(); 456330d8983SJohannes Doerfert } 457330d8983SJohannes Doerfert 458330d8983SJohannes Doerfert private: 459330d8983SJohannes Doerfert llvm::SmallVector<ompt_finalize_t> RtlFinalizationFunctions; 460330d8983SJohannes Doerfert }; 461330d8983SJohannes Doerfert 462330d8983SJohannes Doerfert int llvm::omp::target::ompt::initializeLibrary(ompt_function_lookup_t lookup, 463330d8983SJohannes Doerfert int initial_device_num, 464330d8983SJohannes Doerfert ompt_data_t *tool_data) { 465*d36f66b4SMichael Halkenhäuser DP("Executing initializeLibrary\n"); 466330d8983SJohannes Doerfert #define bindOmptFunctionName(OmptFunction, DestinationFunction) \ 467*d36f66b4SMichael Halkenhäuser if (lookup) \ 468330d8983SJohannes Doerfert DestinationFunction = (OmptFunction##_t)lookup(#OmptFunction); \ 469*d36f66b4SMichael Halkenhäuser DP("initializeLibrary bound %s=%p\n", #DestinationFunction, \ 470330d8983SJohannes Doerfert ((void *)(uint64_t)DestinationFunction)); 471330d8983SJohannes Doerfert 472330d8983SJohannes Doerfert bindOmptFunctionName(ompt_get_callback, lookupCallbackByCode); 473330d8983SJohannes Doerfert bindOmptFunctionName(ompt_get_task_data, ompt_get_task_data_fn); 474330d8983SJohannes Doerfert bindOmptFunctionName(ompt_get_target_task_data, ompt_get_target_task_data_fn); 475330d8983SJohannes Doerfert #undef bindOmptFunctionName 476330d8983SJohannes Doerfert 477330d8983SJohannes Doerfert // Store pointer of 'ompt_libomp_target_fn_lookup' for use by libomptarget 478330d8983SJohannes Doerfert lookupCallbackByName = lookup; 479330d8983SJohannes Doerfert 480330d8983SJohannes Doerfert assert(lookupCallbackByCode && "lookupCallbackByCode should be non-null"); 481330d8983SJohannes Doerfert assert(lookupCallbackByName && "lookupCallbackByName should be non-null"); 482330d8983SJohannes Doerfert assert(ompt_get_task_data_fn && "ompt_get_task_data_fn should be non-null"); 483330d8983SJohannes Doerfert assert(ompt_get_target_task_data_fn && 484330d8983SJohannes Doerfert "ompt_get_target_task_data_fn should be non-null"); 485330d8983SJohannes Doerfert assert(LibraryFinalizer == nullptr && 486330d8983SJohannes Doerfert "LibraryFinalizer should not be initialized yet"); 487330d8983SJohannes Doerfert 488330d8983SJohannes Doerfert LibraryFinalizer = new LibomptargetRtlFinalizer(); 489330d8983SJohannes Doerfert 490330d8983SJohannes Doerfert Initialized = true; 491330d8983SJohannes Doerfert 492330d8983SJohannes Doerfert return 0; 493330d8983SJohannes Doerfert } 494330d8983SJohannes Doerfert 495330d8983SJohannes Doerfert void llvm::omp::target::ompt::finalizeLibrary(ompt_data_t *data) { 496*d36f66b4SMichael Halkenhäuser DP("Executing finalizeLibrary\n"); 497330d8983SJohannes Doerfert // Before disabling OMPT, call the (plugin) finalizations that were registered 498330d8983SJohannes Doerfert // with this library 499330d8983SJohannes Doerfert LibraryFinalizer->finalize(); 500330d8983SJohannes Doerfert delete LibraryFinalizer; 501330d8983SJohannes Doerfert Initialized = false; 502330d8983SJohannes Doerfert } 503330d8983SJohannes Doerfert 504330d8983SJohannes Doerfert void llvm::omp::target::ompt::connectLibrary() { 505*d36f66b4SMichael Halkenhäuser DP("Entering connectLibrary\n"); 506330d8983SJohannes Doerfert // Connect with libomp 507330d8983SJohannes Doerfert static OmptLibraryConnectorTy LibompConnector("libomp"); 508330d8983SJohannes Doerfert static ompt_start_tool_result_t OmptResult; 509330d8983SJohannes Doerfert 510330d8983SJohannes Doerfert // Initialize OmptResult with the init and fini functions that will be 511330d8983SJohannes Doerfert // called by the connector 512330d8983SJohannes Doerfert OmptResult.initialize = ompt::initializeLibrary; 513330d8983SJohannes Doerfert OmptResult.finalize = ompt::finalizeLibrary; 514330d8983SJohannes Doerfert OmptResult.tool_data.value = 0; 515330d8983SJohannes Doerfert 516330d8983SJohannes Doerfert // Now call connect that causes the above init/fini functions to be called 517330d8983SJohannes Doerfert LibompConnector.connect(&OmptResult); 518330d8983SJohannes Doerfert 519330d8983SJohannes Doerfert #define bindOmptCallback(Name, Type, Code) \ 520330d8983SJohannes Doerfert if (lookupCallbackByCode) \ 521330d8983SJohannes Doerfert lookupCallbackByCode( \ 522330d8983SJohannes Doerfert (ompt_callbacks_t)(Code), \ 523330d8983SJohannes Doerfert (ompt_callback_t *)&(llvm::omp::target::ompt::Name##_fn)); 524330d8983SJohannes Doerfert FOREACH_OMPT_NOEMI_EVENT(bindOmptCallback) 525330d8983SJohannes Doerfert FOREACH_OMPT_EMI_EVENT(bindOmptCallback) 526330d8983SJohannes Doerfert #undef bindOmptCallback 527330d8983SJohannes Doerfert 528*d36f66b4SMichael Halkenhäuser DP("Exiting connectLibrary\n"); 529330d8983SJohannes Doerfert } 530330d8983SJohannes Doerfert 531330d8983SJohannes Doerfert #endif // OMPT_SUPPORT 532