diff --git a/openmp/libomptarget/include/OmptCallback.h b/openmp/libomptarget/include/OmptCallback.h new file mode 100644 --- /dev/null +++ b/openmp/libomptarget/include/OmptCallback.h @@ -0,0 +1,85 @@ +//===---- OmptCallback.h - Target independent OMPT callbacks --*- C++ -*---===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Interface used by target-independent runtimes to coordinate registration and +// invocation of OMPT callbacks and initialization / finalization. +// +//===----------------------------------------------------------------------===// + +#ifndef _OMPTCALLBACK_H +#define _OMPTCALLBACK_H + +#ifdef OMPT_SUPPORT + +#include "omp-tools.h" + +#define DEBUG_PREFIX "OMPT" + +#define FOREACH_OMPT_TARGET_CALLBACK(macro) \ + FOREACH_OMPT_DEVICE_EVENT(macro) \ + FOREACH_OMPT_NOEMI_EVENT(macro) \ + FOREACH_OMPT_EMI_EVENT(macro) + +#define performOmptCallback(CallbackName, ...) \ + do { \ + if (ompt_callback_##CallbackName##_fn) \ + ompt_callback_##CallbackName##_fn(__VA_ARGS__); \ + } while (0) + +namespace llvm { +namespace omp { +namespace target { +namespace ompt { + +#define OmptDeclareCallback(Name, Type, Code) extern Name##_t Name##_fn; +FOREACH_OMPT_NOEMI_EVENT(OmptDeclareCallback) +FOREACH_OMPT_EMI_EVENT(OmptDeclareCallback) +#undef OmptDeclareCallback + +/// This function will call an OpenMP API function. Which in turn will lookup a +/// given enum value of type \p ompt_callbacks_t and copy the address of the +/// corresponding callback funtion into the provided pointer. +/// The pointer to the runtime function is passed during 'initializeLibrary'. +/// \p which the enum value of the requested callback function +/// \p callback the destination pointer where the address shall be copied +extern ompt_get_callback_t lookupCallbackByCode; + +/// Lookup function to be used by the lower layer (e.g. the plugin). This +/// function has to be provided when actually calling callback functions like +/// 'ompt_callback_device_initialize_fn' (param: 'lookup'). +/// The pointer to the runtime function is passed during 'initializeLibrary'. +/// \p InterfaceFunctionName the name of the OMPT callback function to look up +extern ompt_function_lookup_t lookupCallbackByName; + +/// This is the function called by the higher layer (libomp / libomtarget) +/// responsible for initializing OMPT in this library. This is passed to libomp +/// as part of the OMPT connector object. +/// \p lookup to be used to query callbacks registered with libomp +/// \p initial_device_num initial device num (id) provided by libomp +/// \p tool_data as provided by the tool +int initializeLibrary(ompt_function_lookup_t lookup, int initial_device_num, + ompt_data_t *tool_data); + +/// This function is passed to libomp / libomtarget as part of the OMPT +/// connector object. It is called by libomp during finalization of OMPT in +/// libomptarget -OR- by libomptarget during finalization of OMPT in the plugin. +/// \p tool_data as provided by the tool +void finalizeLibrary(ompt_data_t *tool_data); + +/// This function will connect the \p initializeLibrary and \p finalizeLibrary +/// functions to their respective higher layer. +void connectLibrary(); + +} // namespace ompt +} // namespace target +} // namespace omp +} // namespace llvm + +#endif // OMPT_SUPPORT + +#endif // _OMPTCALLBACK_H diff --git a/openmp/libomptarget/include/ompt_connector.h b/openmp/libomptarget/include/OmptConnector.h rename from openmp/libomptarget/include/ompt_connector.h rename to openmp/libomptarget/include/OmptConnector.h --- a/openmp/libomptarget/include/ompt_connector.h +++ b/openmp/libomptarget/include/OmptConnector.h @@ -1,4 +1,4 @@ -//=== ompt_connector.h - Target independent OpenMP target RTL -- C++ ------===// +//===- OmptConnector.h - Target independent OpenMP target RTL -- C++ ------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _OMPT_CONNECTOR_H -#define _OMPT_CONNECTOR_H +#ifndef _OMPTCONNECTOR_H +#define _OMPTCONNECTOR_H #ifdef OMPT_SUPPORT @@ -101,8 +101,6 @@ std::string LibIdent; }; -#undef DEBUG_PREFIX - #endif // OMPT_SUPPORT -#endif // _OMPT_CONNECTOR_H +#endif // _OMPTCONNECTOR_H diff --git a/openmp/libomptarget/include/ompt_device_callbacks.h b/openmp/libomptarget/include/ompt_device_callbacks.h deleted file mode 100644 --- a/openmp/libomptarget/include/ompt_device_callbacks.h +++ /dev/null @@ -1,83 +0,0 @@ -//===--------- ompt_device_callbacks.h - OMPT callbacks -- C++ ----------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// Interface used by both target-independent and device-dependent runtimes -// to coordinate registration and invocation of OMPT callbacks -// -//===----------------------------------------------------------------------===// - -#ifndef _OMPT_DEVICE_CALLBACKS_H -#define _OMPT_DEVICE_CALLBACKS_H - -#ifdef OMPT_SUPPORT - -#include "Debug.h" -#include - -#define DEBUG_PREFIX "OMPT" - -#define FOREACH_OMPT_TARGET_CALLBACK(macro) \ - FOREACH_OMPT_DEVICE_EVENT(macro) \ - FOREACH_OMPT_NOEMI_EVENT(macro) \ - FOREACH_OMPT_EMI_EVENT(macro) - -/// Internal representation for OMPT device callback functions. -class OmptDeviceCallbacksTy { -public: - /// Initialize the enabled flag and all the callbacks - void init() { - Enabled = false; -#define initName(Name, Type, Code) Name##_fn = 0; - FOREACH_OMPT_TARGET_CALLBACK(initName) -#undef initName - } - - /// Used to register callbacks. \p Lookup is used to query a given callback - /// by name and the result is assigned to the corresponding callback function. - void registerCallbacks(ompt_function_lookup_t Lookup) { - Enabled = true; -#define OmptBindCallback(Name, Type, Code) \ - Name##_fn = (Name##_t)Lookup(#Name); \ - DP("OMPT: class bound %s=%p\n", #Name, ((void *)(uint64_t)Name##_fn)); - - FOREACH_OMPT_TARGET_CALLBACK(OmptBindCallback); -#undef OmptBindCallback - } - - /// Used to find a callback given its name - ompt_interface_fn_t lookupCallback(const char *InterfaceFunctionName) { -#define OmptLookup(Name, Type, Code) \ - if (strcmp(InterfaceFunctionName, #Name) == 0) \ - return (ompt_interface_fn_t)Name##_fn; - - FOREACH_OMPT_TARGET_CALLBACK(OmptLookup); -#undef OmptLookup - return (ompt_interface_fn_t) nullptr; - } - - /// Wrapper function to find a callback given its name - static ompt_interface_fn_t doLookup(const char *InterfaceFunctionName); - -private: - /// Set to true if callbacks for this library have been initialized - bool Enabled; - - /// Callback functions -#define DeclareName(Name, Type, Code) Name##_t Name##_fn; - FOREACH_OMPT_TARGET_CALLBACK(DeclareName) -#undef DeclareName -}; - -/// Device callbacks object for the library that performs the instantiation -extern OmptDeviceCallbacksTy OmptDeviceCallbacks; - -#undef DEBUG_PREFIX - -#endif // OMPT_SUPPORT - -#endif // _OMPT_DEVICE_CALLBACKS_H diff --git a/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp b/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp --- a/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp +++ b/openmp/libomptarget/plugins-nextgen/amdgpu/src/rtl.cpp @@ -23,6 +23,7 @@ #include "Debug.h" #include "DeviceEnvironment.h" #include "GlobalHandler.h" +#include "OmptCallback.h" #include "PluginInterface.h" #include "Utilities.h" #include "UtilitiesRTL.h" @@ -2359,6 +2360,10 @@ // HSA functions from now on, e.g., hsa_shut_down. Initialized = true; +#ifdef OMPT_SUPPORT + ompt::connectLibrary(); +#endif + // Register event handler to detect memory errors on the devices. Status = hsa_amd_register_system_event_handler(eventHandler, nullptr); if (auto Err = Plugin::check( diff --git a/openmp/libomptarget/plugins-nextgen/common/OMPT/OmptCallback.cpp b/openmp/libomptarget/plugins-nextgen/common/OMPT/OmptCallback.cpp --- a/openmp/libomptarget/plugins-nextgen/common/OMPT/OmptCallback.cpp +++ b/openmp/libomptarget/plugins-nextgen/common/OMPT/OmptCallback.cpp @@ -11,73 +11,60 @@ //===----------------------------------------------------------------------===// #ifdef OMPT_SUPPORT -#include -#include -#include -#include + +#include "llvm/Support/DynamicLibrary.h" + +#include +#include +#include #include "Debug.h" -#include "ompt_connector.h" -#include "ompt_device_callbacks.h" +#include "OmptCallback.h" +#include "OmptConnector.h" -/// Object maintaining all the callbacks in the plugin -OmptDeviceCallbacksTy OmptDeviceCallbacks; +using namespace llvm::omp::target::ompt; -/// Lookup function used for querying callback functions maintained -/// by the plugin -ompt_interface_fn_t -OmptDeviceCallbacksTy::doLookup(const char *InterfaceFunctionName) { - // TODO This will be populated with device tracing functions - return (ompt_interface_fn_t) nullptr; -} +ompt_get_callback_t llvm::omp::target::ompt::lookupCallbackByCode = 0; +ompt_function_lookup_t llvm::omp::target::ompt::lookupCallbackByName = 0; + +int llvm::omp::target::ompt::initializeLibrary(ompt_function_lookup_t lookup, + int initial_device_num, + ompt_data_t *tool_data) { + DP("OMPT: Executing initializeLibrary (libomptarget)\n"); +#define BindOmptFunctionName(OmptFunction, DestinationFunction) \ + if (lookup) \ + DestinationFunction = (OmptFunction##_t)lookup(#OmptFunction); \ + DP("OMPT: initializeLibrary (libomptarget) bound %s=%p\n", \ + #DestinationFunction, ((void *)(uint64_t)DestinationFunction)); -/// Used to indicate whether OMPT was enabled for this library -static bool OmptEnabled = false; + BindOmptFunctionName(ompt_get_callback, lookupCallbackByCode); +#undef BindOmptFunctionName + + // Store pointer of 'ompt_libomp_target_fn_lookup' for use by the plugin + lookupCallbackByName = lookup; -/// This function is passed to libomptarget as part of the OMPT connector -/// object. It is called by libomptarget during initialization of OMPT in the -/// plugin. \p lookup to be used to query callbacks registered with libomptarget -/// \p initial_device_num Initial device num provided by libomptarget -/// \p tool_data as provided by the tool -static int OmptDeviceInit(ompt_function_lookup_t lookup, int initial_device_num, - ompt_data_t *tool_data) { - DP("OMPT: Enter OmptDeviceInit\n"); - OmptEnabled = true; - // The lookup parameter is provided by libomptarget which already has the tool - // callbacks registered at this point. The registration call below causes the - // same callback functions to be registered in the plugin as well. - OmptDeviceCallbacks.registerCallbacks(lookup); - DP("OMPT: Exit OmptDeviceInit\n"); return 0; } -/// This function is passed to libomptarget as part of the OMPT connector -/// object. It is called by libomptarget during finalization of OMPT in the -/// plugin. -static void OmptDeviceFini(ompt_data_t *tool_data) { - DP("OMPT: Executing OmptDeviceFini\n"); +void llvm::omp::target::ompt::finalizeLibrary(ompt_data_t *tool_data) { + DP("OMPT: Executing finalizeLibrary (libomptarget)\n"); } -/// Used to initialize callbacks implemented by the tool. This interface will -/// lookup the callbacks table in libomptarget and assign them to the callbacks -/// table maintained in the calling plugin library. -void OmptCallbackInit() { - DP("OMPT: Entering OmptCallbackInit\n"); +void llvm::omp::target::ompt::connectLibrary() { + DP("OMPT: Entering connectLibrary (libomptarget)\n"); /// Connect plugin instance with libomptarget - OmptLibraryConnectorTy LibomptargetConnector("libomptarget"); - ompt_start_tool_result_t OmptResult; + static OmptLibraryConnectorTy LibomptargetConnector("libomptarget"); + static ompt_start_tool_result_t OmptResult; // Initialize OmptResult with the init and fini functions that will be // called by the connector - OmptResult.initialize = OmptDeviceInit; - OmptResult.finalize = OmptDeviceFini; + OmptResult.initialize = ompt::initializeLibrary; + OmptResult.finalize = ompt::finalizeLibrary; OmptResult.tool_data.value = 0; - // Initialize the device callbacks first - OmptDeviceCallbacks.init(); - // Now call connect that causes the above init/fini functions to be called LibomptargetConnector.connect(&OmptResult); - DP("OMPT: Exiting OmptCallbackInit\n"); + DP("OMPT: Exiting connectLibrary (libomptarget)\n"); } + #endif diff --git a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.h b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.h --- a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.h +++ b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.h @@ -24,6 +24,7 @@ #include "JIT.h" #include "MemoryManager.h" #include "Utilities.h" +#include "omp-tools.h" #include "omptarget.h" #include "llvm/ADT/SmallVector.h" @@ -512,7 +513,7 @@ /// Deinitialize the device and free all its resources. After this call, the /// device is no longer considered ready, so no queries or modifications are /// allowed. - Error deinit(); + Error deinit(GenericPluginTy &Plugin); virtual Error deinitImpl() = 0; /// Load the binary image into the device and return the target table. @@ -748,6 +749,16 @@ /// Map of host pinned allocations used for optimize device transfers. PinnedAllocationMapTy PinnedAllocs; + +#ifdef OMPT_SUPPORT + /// Callback functions +#define OmptDeclareCallback(Name, Type, Code) Name##_t Name##_fn = 0; + FOREACH_OMPT_DEVICE_EVENT(OmptDeclareCallback) +#undef OmptDeclareCallback + + /// Internal representation for OMPT device (initialize & finalize) + std::atomic OmptDevice; +#endif }; /// Class implementing common functionalities of offload plugins. Each plugin diff --git a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp --- a/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp +++ b/openmp/libomptarget/plugins-nextgen/common/PluginInterface/PluginInterface.cpp @@ -12,7 +12,9 @@ #include "Debug.h" #include "GlobalHandler.h" #include "JIT.h" +#include "OmptCallback.h" #include "elf_common.h" +#include "omp-tools.h" #include "omptarget.h" #include "omptargetplugin.h" @@ -360,12 +362,37 @@ OMPX_InitialNumEvents("LIBOMPTARGET_NUM_INITIAL_EVENTS", 32), DeviceId(DeviceId), GridValues(OMPGridValues), PeerAccesses(NumDevices, PeerAccessState::PENDING), PeerAccessesLock(), - PinnedAllocs(*this) {} + PinnedAllocs(*this) { +#ifdef OMPT_SUPPORT + OmptDevice.store(false); + // Bind the callbacks to this device's member functions +#define BindOmptCallback(Name, Type, Code) \ + if (ompt::lookupCallbackByCode) \ + ompt::lookupCallbackByCode((ompt_callbacks_t)(Code), \ + ((ompt_callback_t *)&(Name##_fn))); \ + DP("OMPT: class bound %s=%p\n", #Name, ((void *)(uint64_t)Name##_fn)); + + FOREACH_OMPT_DEVICE_EVENT(BindOmptCallback); +#undef BindOmptCallback + +#endif +} Error GenericDeviceTy::init(GenericPluginTy &Plugin) { if (auto Err = initImpl(Plugin)) return Err; +#ifdef OMPT_SUPPORT + bool expectedStatus = false; + if (OmptDevice.compare_exchange_strong(expectedStatus, true)) + performOmptCallback(device_initialize, + /* device_num */ DeviceId, + /* type */ getComputeUnitKind().c_str(), + /* device */ reinterpret_cast(this), + /* lookup */ ompt::lookupCallbackByName, + /* documentation */ nullptr); +#endif + // Read and reinitialize the envars that depend on the device initialization. // Notice these two envars may change the stack size and heap size of the // device, so they need the device properly initialized. @@ -407,8 +434,8 @@ return Plugin::success(); } -Error GenericDeviceTy::deinit() { - // Delete the memory manager before deinitilizing the device. Otherwise, +Error GenericDeviceTy::deinit(GenericPluginTy &Plugin) { + // Delete the memory manager before deinitializing the device. Otherwise, // we may delete device allocations after the device is deinitialized. if (MemoryManager) delete MemoryManager; @@ -417,9 +444,14 @@ if (RecordReplay.isRecordingOrReplaying()) RecordReplay.deinit(); +#ifdef OMPT_SUPPORT + bool expectedStatus = true; + if (OmptDevice.compare_exchange_strong(expectedStatus, false)) + performOmptCallback(device_finalize, /* device_num */ DeviceId); +#endif + return deinitImpl(); } - Expected<__tgt_target_table *> GenericDeviceTy::loadBinary(GenericPluginTy &Plugin, const __tgt_device_image *InputTgtImage) { @@ -457,6 +489,19 @@ if (auto Err = registerOffloadEntries(*Image)) return std::move(Err); +#ifdef OMPT_SUPPORT + size_t Bytes = getPtrDiff(InputTgtImage->ImageEnd, InputTgtImage->ImageStart); + performOmptCallback(device_load, + /* device_num */ DeviceId, + /* FileName */ nullptr, + /* File Offset */ 0, + /* VmaInFile */ nullptr, + /* ImgSize */ Bytes, + /* HostAddr */ InputTgtImage->ImageStart, + /* DeviceAddr */ nullptr, + /* FIXME: ModuleId */ 0); +#endif + // Return the pointer to the table of entries. return Image->getOffloadEntryTable(); } @@ -1084,7 +1129,7 @@ return Plugin::success(); // Deinitialize the device and release its resources. - if (auto Err = Devices[DeviceId]->deinit()) + if (auto Err = Devices[DeviceId]->deinit(*this)) return Err; // Delete the device and invalidate its reference. diff --git a/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp b/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp --- a/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp +++ b/openmp/libomptarget/plugins-nextgen/cuda/src/rtl.cpp @@ -19,6 +19,7 @@ #include "Debug.h" #include "DeviceEnvironment.h" #include "GlobalHandler.h" +#include "OmptCallback.h" #include "PluginInterface.h" #include "llvm/BinaryFormat/ELF.h" @@ -899,6 +900,10 @@ return 0; } +#ifdef OMPT_SUPPORT + ompt::connectLibrary(); +#endif + if (Res == CUDA_ERROR_NO_DEVICE) { // Do not initialize if there are no devices. DP("There are no devices supporting CUDA.\n"); diff --git a/openmp/libomptarget/src/OmptCallback.cpp b/openmp/libomptarget/src/OmptCallback.cpp --- a/openmp/libomptarget/src/OmptCallback.cpp +++ b/openmp/libomptarget/src/OmptCallback.cpp @@ -12,24 +12,23 @@ #ifdef OMPT_SUPPORT -#include -#include +#include "llvm/Support/DynamicLibrary.h" + #include #include - -#include "omp-tools.h" +#include #include "Debug.h" -#include "ompt_connector.h" -#include "ompt_device_callbacks.h" -#include "private.h" +#include "OmptCallback.h" +#include "OmptConnector.h" -#define fnptr_to_ptr(x) ((void *)(uint64_t)x) +using namespace llvm::omp::target::ompt; -/// Used to indicate whether OMPT was enabled for this library -bool OmptEnabled = false; -/// Object maintaining all the callbacks for this library -OmptDeviceCallbacksTy OmptDeviceCallbacks; +#define OmptDeclareCallback(Name, Type, Code) \ + Name##_t llvm::omp::target::ompt::Name##_fn = 0; +FOREACH_OMPT_NOEMI_EVENT(OmptDeclareCallback) +FOREACH_OMPT_EMI_EVENT(OmptDeclareCallback) +#undef OmptDeclareCallback /// Used to maintain the finalization function that is received /// from the plugin during connect @@ -54,67 +53,62 @@ /// Object that will maintain the RTL finalizer from the plugin static LibomptargetRtlFinalizer LibraryFinalizer; -/// Lookup function to be used by libomptarget library -ompt_interface_fn_t -OmptDeviceCallbacksTy::doLookup(const char *InterfaceFunctionName) { - return OmptDeviceCallbacks.lookupCallback(InterfaceFunctionName); -} +ompt_get_callback_t llvm::omp::target::ompt::lookupCallbackByCode = 0; +ompt_function_lookup_t llvm::omp::target::ompt::lookupCallbackByName = 0; + +int llvm::omp::target::ompt::initializeLibrary(ompt_function_lookup_t lookup, + int initial_device_num, + ompt_data_t *tool_data) { + DP("OMPT: Executing initializeLibrary (libomp)\n"); +#define BindOmptFunctionName(OmptFunction, DestinationFunction) \ + DestinationFunction = (OmptFunction##_t)lookup(#OmptFunction); \ + DP("OMPT: initializeLibrary (libomp) bound %s=%p\n", #DestinationFunction, \ + ((void *)(uint64_t)DestinationFunction)); + + BindOmptFunctionName(ompt_get_callback, lookupCallbackByCode); +#undef BindOmptFunctionName + + // Store pointer of 'ompt_libomp_target_fn_lookup' for use by libomptarget + lookupCallbackByName = lookup; + + assert(lookupCallbackByCode && "lookupCallbackByCode should be non-null"); + assert(lookupCallbackByName && "lookupCallbackByName should be non-null"); -/// This is the function called by the higher layer (libomp) responsible -/// for initializing OMPT in this library. This is passed to libomp -/// as part of the OMPT connector object. -/// \p lookup to be used to query callbacks registered with libomp -/// \p initial_device_num Initial device num provided by libomp -/// \p tool_data as provided by the tool -static int ompt_libomptarget_initialize(ompt_function_lookup_t lookup, - int initial_device_num, - ompt_data_t *tool_data) { - DP("enter ompt_libomptarget_initialize!\n"); - OmptEnabled = true; - // The lookup parameter is provided by libomp which already has the - // tool callbacks registered at this point. The registration call - // below causes the same callback functions to be registered in - // libomptarget as well - OmptDeviceCallbacks.registerCallbacks(lookup); - DP("exit ompt_libomptarget_initialize!\n"); return 0; } -/// This function is passed to libomp as part of the OMPT connector object. -/// It is called by libomp during finalization of OMPT in libomptarget. -static void ompt_libomptarget_finalize(ompt_data_t *data) { - DP("enter ompt_libomptarget_finalize!\n"); +void llvm::omp::target::ompt::finalizeLibrary(ompt_data_t *data) { + DP("OMPT: Executing finalizeLibrary (libomp)\n"); // Before disabling OMPT, call the finalizer (of the plugin) that was // registered with this library LibraryFinalizer.finalize(); - OmptEnabled = false; - DP("exit ompt_libomptarget_finalize!\n"); } -/***************************************************************************** - * constructor - *****************************************************************************/ -/// Used to initialize callbacks implemented by the tool. This interface -/// will lookup the callbacks table in libomp and assign them to the callbacks -/// maintained in libomptarget. -void InitOmptLibomp() { - DP("OMPT: Enter InitOmptLibomp\n"); +void llvm::omp::target::ompt::connectLibrary() { + DP("OMPT: Entering connectLibrary (libomp)\n"); // Connect with libomp static OmptLibraryConnectorTy LibompConnector("libomp"); static ompt_start_tool_result_t OmptResult; // Initialize OmptResult with the init and fini functions that will be // called by the connector - OmptResult.initialize = ompt_libomptarget_initialize; - OmptResult.finalize = ompt_libomptarget_finalize; + OmptResult.initialize = ompt::initializeLibrary; + OmptResult.finalize = ompt::finalizeLibrary; OmptResult.tool_data.value = 0; - // Initialize the device callbacks first - OmptDeviceCallbacks.init(); - // Now call connect that causes the above init/fini functions to be called LibompConnector.connect(&OmptResult); - DP("OMPT: Exit InitOmptLibomp\n"); + +#define OmptBindCallback(Name, Type, Code) \ + if (lookupCallbackByCode) \ + lookupCallbackByCode( \ + (ompt_callbacks_t)(Code), \ + (ompt_callback_t *)&(llvm::omp::target::ompt::Name##_fn)); + FOREACH_OMPT_NOEMI_EVENT(OmptBindCallback) + FOREACH_OMPT_EMI_EVENT(OmptBindCallback) +#undef OmptBindCallback + + DP("OMPT: Exiting connectLibrary (libomp)\n"); } #endif // OMPT_SUPPORT @@ -123,14 +117,14 @@ /// Used for connecting libomptarget with a plugin void ompt_libomptarget_connect(ompt_start_tool_result_t *result) { DP("OMPT: Enter ompt_libomptarget_connect\n"); - if (OmptEnabled && result) { + if (result) { // Cache the fini function so that it can be invoked on exit LibraryFinalizer.registerRtl(result->finalize); // Invoke the provided init function with the lookup function maintained // in this library so that callbacks maintained by this library are // retrieved. - result->initialize(OmptDeviceCallbacksTy::doLookup, - 0 /* initial_device_num */, nullptr /* tool_data */); + result->initialize(lookupCallbackByName, + /* initial_device_num */ 0, /* tool_data */ nullptr); } DP("OMPT: Leave ompt_libomptarget_connect\n"); } diff --git a/openmp/libomptarget/src/rtl.cpp b/openmp/libomptarget/src/rtl.cpp --- a/openmp/libomptarget/src/rtl.cpp +++ b/openmp/libomptarget/src/rtl.cpp @@ -12,6 +12,7 @@ #include "llvm/Object/OffloadBinary.h" +#include "OmptCallback.h" #include "device.h" #include "private.h" #include "rtl.h" @@ -44,7 +45,7 @@ static char *ProfileTraceFile = nullptr; #ifdef OMPT_SUPPORT -extern void InitOmptLibomp(); +extern void ompt::connectLibrary(); #endif __attribute__((constructor(101))) void init() { @@ -69,10 +70,10 @@ if (ProfileTraceFile) timeTraceProfilerInitialize(500 /* us */, "libomptarget"); - #ifdef OMPT_SUPPORT - // Initialize OMPT first - InitOmptLibomp(); - #endif +#ifdef OMPT_SUPPORT + // Initialize OMPT first + ompt::connectLibrary(); +#endif PM->RTLs.loadRTLs(); PM->registerDelayedLibraries(); diff --git a/openmp/libomptarget/test/ompt/veccopy.c b/openmp/libomptarget/test/ompt/veccopy.c --- a/openmp/libomptarget/test/ompt/veccopy.c +++ b/openmp/libomptarget/test/ompt/veccopy.c @@ -1,8 +1,5 @@ // RUN: %libomptarget-compile-run-and-check-generic // REQUIRES: ompt -// UNSUPPORTED: nvptx64-nvidia-cuda -// UNSUPPORTED: nvptx64-nvidia-cuda-oldDriver -// UNSUPPORTED: nvptx64-nvidia-cuda-LTO // UNSUPPORTED: x86_64-pc-linux-gnu // UNSUPPORTED: x86_64-pc-linux-gnu-oldDriver // UNSUPPORTED: x86_64-pc-linux-gnu-LTO @@ -56,11 +53,10 @@ return rc; } -/// CHECK: Could not register callback 'ompt_callback_device_initialize' -/// CHECK: Could not register callback 'ompt_callback_device_finalize' -/// CHECK: Could not register callback 'ompt_callback_device_load' /// CHECK: Could not register callback 'ompt_callback_target_data_op' /// CHECK: Could not register callback 'ompt_callback_target' /// CHECK: Could not register callback 'ompt_callback_target_submit' -/// CHECK: Success +/// CHECK: Callback Init: +/// CHECK: Callback Load: +/// CHECK: Callback Fini: diff --git a/openmp/libomptarget/test/ompt/veccopy_disallow_both.c b/openmp/libomptarget/test/ompt/veccopy_disallow_both.c --- a/openmp/libomptarget/test/ompt/veccopy_disallow_both.c +++ b/openmp/libomptarget/test/ompt/veccopy_disallow_both.c @@ -1,8 +1,5 @@ // RUN: %libomptarget-compile-run-and-check-generic // REQUIRES: ompt -// UNSUPPORTED: nvptx64-nvidia-cuda -// UNSUPPORTED: nvptx64-nvidia-cuda-oldDriver -// UNSUPPORTED: nvptx64-nvidia-cuda-LTO // UNSUPPORTED: x86_64-pc-linux-gnu // UNSUPPORTED: x86_64-pc-linux-gnu-oldDriver // UNSUPPORTED: x86_64-pc-linux-gnu-LTO @@ -59,11 +56,10 @@ return rc; } -/// CHECK: Could not register callback 'ompt_callback_device_initialize' -/// CHECK: Could not register callback 'ompt_callback_device_finalize' -/// CHECK: Could not register callback 'ompt_callback_device_load' /// CHECK: Could not register callback 'ompt_callback_target_data_op' /// CHECK: Could not register callback 'ompt_callback_target' /// CHECK: Could not register callback 'ompt_callback_target_submit' -/// CHECK: Success +/// CHECK: Callback Init: +/// CHECK: Callback Load: +/// CHECK: Callback Fini: diff --git a/openmp/libomptarget/test/ompt/veccopy_emi.c b/openmp/libomptarget/test/ompt/veccopy_emi.c --- a/openmp/libomptarget/test/ompt/veccopy_emi.c +++ b/openmp/libomptarget/test/ompt/veccopy_emi.c @@ -1,8 +1,5 @@ // RUN: %libomptarget-compile-run-and-check-generic // REQUIRES: ompt -// UNSUPPORTED: nvptx64-nvidia-cuda -// UNSUPPORTED: nvptx64-nvidia-cuda-oldDriver -// UNSUPPORTED: nvptx64-nvidia-cuda-LTO // UNSUPPORTED: x86_64-pc-linux-gnu // UNSUPPORTED: x86_64-pc-linux-gnu-oldDriver // UNSUPPORTED: x86_64-pc-linux-gnu-LTO @@ -57,11 +54,10 @@ return rc; } -/// CHECK: Could not register callback 'ompt_callback_device_initialize' -/// CHECK: Could not register callback 'ompt_callback_device_finalize' -/// CHECK: Could not register callback 'ompt_callback_device_load' /// CHECK: Could not register callback 'ompt_callback_target_data_op_emi' /// CHECK: Could not register callback 'ompt_callback_target_emi' /// CHECK: Could not register callback 'ompt_callback_target_submit_emi' -/// CHECK: Success +/// CHECK: Callback Init: +/// CHECK: Callback Load: +/// CHECK: Callback Fini: diff --git a/openmp/libomptarget/test/ompt/veccopy_emi_map.c b/openmp/libomptarget/test/ompt/veccopy_emi_map.c --- a/openmp/libomptarget/test/ompt/veccopy_emi_map.c +++ b/openmp/libomptarget/test/ompt/veccopy_emi_map.c @@ -1,8 +1,5 @@ // RUN: %libomptarget-compile-run-and-check-generic // REQUIRES: ompt -// UNSUPPORTED: nvptx64-nvidia-cuda -// UNSUPPORTED: nvptx64-nvidia-cuda-oldDriver -// UNSUPPORTED: nvptx64-nvidia-cuda-LTO // UNSUPPORTED: x86_64-pc-linux-gnu // UNSUPPORTED: x86_64-pc-linux-gnu-oldDriver // UNSUPPORTED: x86_64-pc-linux-gnu-LTO @@ -57,12 +54,11 @@ return rc; } -/// CHECK: Could not register callback 'ompt_callback_device_initialize' -/// CHECK: Could not register callback 'ompt_callback_device_finalize' -/// CHECK: Could not register callback 'ompt_callback_device_load' /// CHECK: Could not register callback 'ompt_callback_target_data_op_emi' /// CHECK: Could not register callback 'ompt_callback_target_emi' /// CHECK: Could not register callback 'ompt_callback_target_submit_emi' /// CHECK: Could not register callback 'ompt_callback_target_map_emi' -/// CHECK: Success +/// CHECK: Callback Init: +/// CHECK: Callback Load: +/// CHECK: Callback Fini: diff --git a/openmp/libomptarget/test/ompt/veccopy_map.c b/openmp/libomptarget/test/ompt/veccopy_map.c --- a/openmp/libomptarget/test/ompt/veccopy_map.c +++ b/openmp/libomptarget/test/ompt/veccopy_map.c @@ -1,8 +1,5 @@ // RUN: %libomptarget-compile-run-and-check-generic // REQUIRES: ompt -// UNSUPPORTED: nvptx64-nvidia-cuda -// UNSUPPORTED: nvptx64-nvidia-cuda-oldDriver -// UNSUPPORTED: nvptx64-nvidia-cuda-LTO // UNSUPPORTED: x86_64-pc-linux-gnu // UNSUPPORTED: x86_64-pc-linux-gnu-oldDriver // UNSUPPORTED: x86_64-pc-linux-gnu-LTO @@ -56,11 +53,10 @@ return rc; } -/// CHECK: Could not register callback 'ompt_callback_device_initialize' -/// CHECK: Could not register callback 'ompt_callback_device_finalize' -/// CHECK: Could not register callback 'ompt_callback_device_load' /// CHECK: Could not register callback 'ompt_callback_target_data_op' /// CHECK: Could not register callback 'ompt_callback_target' /// CHECK: Could not register callback 'ompt_callback_target_submit' -/// CHECK: Success +/// CHECK: Callback Init: +/// CHECK: Callback Load: +/// CHECK: Callback Fini: diff --git a/openmp/libomptarget/test/ompt/veccopy_no_device_init.c b/openmp/libomptarget/test/ompt/veccopy_no_device_init.c --- a/openmp/libomptarget/test/ompt/veccopy_no_device_init.c +++ b/openmp/libomptarget/test/ompt/veccopy_no_device_init.c @@ -1,8 +1,5 @@ // RUN: %libomptarget-compile-run-and-check-generic // REQUIRES: ompt -// UNSUPPORTED: nvptx64-nvidia-cuda -// UNSUPPORTED: nvptx64-nvidia-cuda-oldDriver -// UNSUPPORTED: nvptx64-nvidia-cuda-LTO // UNSUPPORTED: x86_64-pc-linux-gnu // UNSUPPORTED: x86_64-pc-linux-gnu-oldDriver // UNSUPPORTED: x86_64-pc-linux-gnu-LTO @@ -57,9 +54,10 @@ return rc; } -/// CHECK: Could not register callback 'ompt_callback_device_load' /// CHECK: Could not register callback 'ompt_callback_target_data_op' /// CHECK: Could not register callback 'ompt_callback_target' /// CHECK: Could not register callback 'ompt_callback_target_submit' -/// CHECK: Success +/// CHECK-NOT: Callback Init: +/// CHECK-NOT: Callback Load: +/// CHECK-NOT: Callback Fini: diff --git a/openmp/libomptarget/test/ompt/veccopy_wrong_return.c b/openmp/libomptarget/test/ompt/veccopy_wrong_return.c --- a/openmp/libomptarget/test/ompt/veccopy_wrong_return.c +++ b/openmp/libomptarget/test/ompt/veccopy_wrong_return.c @@ -1,8 +1,5 @@ // RUN: %libomptarget-compile-run-and-check-generic // REQUIRES: ompt -// UNSUPPORTED: nvptx64-nvidia-cuda -// UNSUPPORTED: nvptx64-nvidia-cuda-oldDriver -// UNSUPPORTED: nvptx64-nvidia-cuda-LTO // UNSUPPORTED: x86_64-pc-linux-gnu // UNSUPPORTED: x86_64-pc-linux-gnu-oldDriver // UNSUPPORTED: x86_64-pc-linux-gnu-LTO @@ -57,11 +54,10 @@ return rc; } -/// CHECK: Could not register callback 'ompt_callback_device_initialize' -/// CHECK: Could not register callback 'ompt_callback_device_finalize' -/// CHECK: Could not register callback 'ompt_callback_device_load' /// CHECK: Could not register callback 'ompt_callback_target_data_op' /// CHECK: Could not register callback 'ompt_callback_target' /// CHECK: Could not register callback 'ompt_callback_target_submit' -/// CHECK: Success +/// CHECK-NOT: Callback Init: +/// CHECK-NOT: Callback Load: +/// CHECK-NOT: Callback Fini: diff --git a/openmp/runtime/src/ompt-event-specific.h b/openmp/runtime/src/ompt-event-specific.h --- a/openmp/runtime/src/ompt-event-specific.h +++ b/openmp/runtime/src/ompt-event-specific.h @@ -64,10 +64,10 @@ #define ompt_callback_control_tool_implemented ompt_event_MAY_ALWAYS -#define ompt_callback_device_initialize_implemented ompt_event_UNIMPLEMENTED -#define ompt_callback_device_finalize_implemented ompt_event_UNIMPLEMENTED +#define ompt_callback_device_initialize_implemented ompt_event_MAY_ALWAYS +#define ompt_callback_device_finalize_implemented ompt_event_MAY_ALWAYS -#define ompt_callback_device_load_implemented ompt_event_UNIMPLEMENTED +#define ompt_callback_device_load_implemented ompt_event_MAY_ALWAYS #define ompt_callback_device_unload_implemented ompt_event_UNIMPLEMENTED /*---------------------------------------------------------------------------- diff --git a/openmp/runtime/src/ompt-general.cpp b/openmp/runtime/src/ompt-general.cpp --- a/openmp/runtime/src/ompt-general.cpp +++ b/openmp/runtime/src/ompt-general.cpp @@ -880,6 +880,13 @@ /// Lookup function to query libomp callbacks registered by the tool static ompt_interface_fn_t ompt_libomp_target_fn_lookup(const char *s) { +#define provide_fn(fn) \ + if (strcmp(s, #fn) == 0) \ + return (ompt_interface_fn_t)fn; + + provide_fn(ompt_get_callback); +#undef provide_fn + #define ompt_interface_fn(fn, type, code) \ if (strcmp(s, #fn) == 0) \ return (ompt_interface_fn_t)ompt_callbacks.ompt_callback(fn); @@ -887,7 +894,6 @@ FOREACH_OMPT_DEVICE_EVENT(ompt_interface_fn) FOREACH_OMPT_EMI_EVENT(ompt_interface_fn) FOREACH_OMPT_NOEMI_EVENT(ompt_interface_fn) - #undef ompt_interface_fn return (ompt_interface_fn_t)0; @@ -896,7 +902,7 @@ /// This function is called by the libomptarget connector to assign /// callbacks already registered with libomp. _OMP_EXTERN void ompt_libomp_connect(ompt_start_tool_result_t *result) { - OMPT_VERBOSE_INIT_PRINT("libomp --> OMPT: Enter libomp_ompt_connect\n"); + OMPT_VERBOSE_INIT_PRINT("libomp --> OMPT: Enter ompt_libomp_connect\n"); // Ensure libomp callbacks have been added if not already __ompt_force_initialization(); @@ -912,11 +918,11 @@ // functions can be extracted and assigned to the callbacks in // libomptarget result->initialize(ompt_libomp_target_fn_lookup, - 0 /* initial_device_num */, nullptr /* tool_data */); + /* initial_device_num */ 0, /* tool_data */ nullptr); // Track the object provided by libomptarget so that the finalizer can be // called during OMPT finalization libomptarget_ompt_result = result; } } - OMPT_VERBOSE_INIT_PRINT("libomp --> OMPT: Exit libomp_ompt_connect\n"); + OMPT_VERBOSE_INIT_PRINT("libomp --> OMPT: Exit ompt_libomp_connect\n"); }