diff --git a/openmp/libomptarget/CMakeLists.txt b/openmp/libomptarget/CMakeLists.txt --- a/openmp/libomptarget/CMakeLists.txt +++ b/openmp/libomptarget/CMakeLists.txt @@ -65,9 +65,9 @@ else() option(LIBOMPTARGET_ENABLE_DEBUG "Allow debug output with the environment variable LIBOMPTARGET_DEBUG=1" OFF) endif() -if(LIBOMPTARGET_ENABLE_DEBUG) +# if(LIBOMPTARGET_ENABLE_DEBUG) add_definitions(-DOMPTARGET_DEBUG) -endif() +# endif() # OMPT support for libomptarget # Follow host OMPT support and check if host support has been requested. 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,88 @@ +//===---- 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 ompt_callback(name, ...) \ + do { \ + if (ompt_callback_##name##_fn) { \ + printf("Executing: ompt_callback_%s_fn\n", #name); \ + ompt_callback_##name##_fn(__VA_ARGS__); \ + } else \ + printf("NOT Executing: ompt_callback_%s_fn\n", #name); \ + } 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 \ No newline at end of file diff --git a/openmp/libomptarget/include/ompt_connector.h b/openmp/libomptarget/include/ompt_connector.h --- a/openmp/libomptarget/include/ompt_connector.h +++ b/openmp/libomptarget/include/ompt_connector.h @@ -101,7 +101,7 @@ std::string LibIdent; }; -#undef DEBUG_PREFIX +// #undef DEBUG_PREFIX #endif // OMPT_SUPPORT diff --git a/openmp/libomptarget/include/ompt_device_callbacks.h b/openmp/libomptarget/include/ompt_device_callbacks.h --- a/openmp/libomptarget/include/ompt_device_callbacks.h +++ b/openmp/libomptarget/include/ompt_device_callbacks.h @@ -1,4 +1,4 @@ -//===--------- ompt_device_callbacks.h - OMPT callbacks -- C++ ----------===// +//===---------- 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. @@ -17,7 +17,9 @@ #ifdef OMPT_SUPPORT #include "Debug.h" +#include #include +#include #define DEBUG_PREFIX "OMPT" @@ -30,23 +32,32 @@ 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 } + */ + + /* + bool isEnabled() { return Enabled; } + */ /// 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; + // 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)); + printf("OMPT: class bound %s=%p\n", #Name, ((void *)(uint64_t)Name##_fn)); FOREACH_OMPT_TARGET_CALLBACK(OmptBindCallback); #undef OmptBindCallback + printf("Executed 'registerCallbacks' on OmptDeviceCallbacksTy -- obj=%p " + "-- Lookup=%p\n", + this, Lookup); } /// Used to find a callback given its name @@ -65,18 +76,23 @@ private: /// Set to true if callbacks for this library have been initialized - bool Enabled; + // bool Enabled = false; + /// Number of allocated devices + // static int NumAllocatedDevices; /// Callback functions #define DeclareName(Name, Type, Code) Name##_t Name##_fn; FOREACH_OMPT_TARGET_CALLBACK(DeclareName) #undef DeclareName + + /// Documentation based on omp-tools + // static const char *Documentation; }; /// Device callbacks object for the library that performs the instantiation extern OmptDeviceCallbacksTy OmptDeviceCallbacks; -#undef DEBUG_PREFIX +// #undef DEBUG_PREFIX #endif // OMPT_SUPPORT 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,59 @@ //===----------------------------------------------------------------------===// #ifdef OMPT_SUPPORT -#include -#include -#include -#include + +#include "llvm/Support/DynamicLibrary.h" + +#include +#include +#include #include "Debug.h" +#include "OmptCallback.h" #include "ompt_connector.h" -#include "ompt_device_callbacks.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) { + printf("OMPT: Executing initializeLibrary (libomptarget)\n"); +#define BindOmptFunctionName(srcFn, dstFn) \ + dstFn = (srcFn##_t)lookup(#srcFn); \ + printf("OMPT: initializeLibrary (libomptarget) bound %s=%p\n", #dstFn, \ + (void *)(dstFn)); -/// 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"); - /// Connect plugin instance with libomptarget +void llvm::omp::target::ompt::connectLibrary() { + DP("OMPT: Entering connectLibrary (libomptarget)\n"); + // Connect with libomptarget 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,40 @@ 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); + + printf("Before BindOmptCallback (GenericDeviceTy)\n"); + // Bind the callbacks to this device's member functions +#define BindOmptCallback(Name, Type, Code) \ + ompt::lookupCallbackByCode((ompt_callbacks_t)(Code), \ + ((ompt_callback_t *)&(Name##_fn))); \ + printf("OMPT (GenericDeviceTy): class bound %s=%p\n", #Name, \ + ((void *)(uint64_t)Name##_fn)); + + FOREACH_OMPT_DEVICE_EVENT(BindOmptCallback); +#undef BindOmptCallback + printf("After BindOmptCallback (GenericDeviceTy)\n"); + +#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)) + ompt_callback(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 +437,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 +447,14 @@ if (RecordReplay.isRecordingOrReplaying()) RecordReplay.deinit(); +#ifdef OMPT_SUPPORT + bool expectedStatus = true; + if (OmptDevice.compare_exchange_strong(expectedStatus, false)) + ompt_callback(device_finalize, /* device_num */ DeviceId); +#endif + return deinitImpl(); } - Expected<__tgt_target_table *> GenericDeviceTy::loadBinary(GenericPluginTy &Plugin, const __tgt_device_image *InputTgtImage) { @@ -457,6 +492,19 @@ if (auto Err = registerOffloadEntries(*Image)) return std::move(Err); +#ifdef OMPT_SUPPORT + size_t Bytes = getPtrDiff(InputTgtImage->ImageEnd, InputTgtImage->ImageStart); + ompt_callback(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(); } @@ -1033,6 +1081,10 @@ if (!NumDevicesOrErr) return NumDevicesOrErr.takeError(); +#ifdef OMPT_SUPPORT + // ompt::connectLibrary(); +#endif + NumDevices = *NumDevicesOrErr; if (NumDevices == 0) return Plugin::success(); @@ -1084,7 +1136,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,34 +12,33 @@ #ifdef OMPT_SUPPORT -#include -#include +#include "llvm/Support/DynamicLibrary.h" + #include #include - -#include "omp-tools.h" +#include #include "Debug.h" +#include "OmptCallback.h" #include "ompt_connector.h" -#include "ompt_device_callbacks.h" -#include "private.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 -class LibomptargetRtlFinalizer { +class LibomptargetPluginFinalizer { public: - LibomptargetRtlFinalizer() : FiniFn(nullptr) {} + LibomptargetPluginFinalizer() : FiniFn(nullptr) {} void registerRtl(ompt_finalize_t fn) { FiniFn = fn; } void finalize() { if (FiniFn) - FiniFn(nullptr /* tool_data */); + FiniFn(/* tool_data */ nullptr); FiniFn = nullptr; } @@ -48,69 +47,62 @@ }; /// Object that will maintain the finalizer of the plugin -static LibomptargetRtlFinalizer LibOmptTargetRTLFinalizer; +static LibomptargetPluginFinalizer PluginFinalizer; -/// 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(srcFn, dstFn) \ + dstFn = (srcFn##_t)lookup(#srcFn); \ + DP("OMPT: initializeLibrary (libomp) bound %s=%p\n", #dstFn, (void *)(dstFn)); + + 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 - LibOmptTargetRTLFinalizer.finalize(); - OmptEnabled = false; - DP("exit ompt_libomptarget_finalize!\n"); + PluginFinalizer.finalize(); } -/***************************************************************************** - * 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) \ + 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 @@ -119,14 +111,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 - LibOmptTargetRTLFinalizer.registerRtl(result->finalize); + PluginFinalizer.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/exports_so.txt b/openmp/runtime/src/exports_so.txt --- a/openmp/runtime/src/exports_so.txt +++ b/openmp/runtime/src/exports_so.txt @@ -25,8 +25,8 @@ # # OMPT API # - ompt_start_tool; # OMPT start interface - ompt_libomp_connect; # OMPT libomptarget interface + ompt_start_tool; # OMPT start interface + ompt_libomp_connect; # OMPT libomptarget interface ompc_*; # omp.h renames some standard functions to ompc_*. kmp_*; # Intel extensions. diff --git a/openmp/runtime/src/kmp_utility.cpp b/openmp/runtime/src/kmp_utility.cpp --- a/openmp/runtime/src/kmp_utility.cpp +++ b/openmp/runtime/src/kmp_utility.cpp @@ -407,6 +407,7 @@ #if !OMPT_SUPPORT extern "C" { typedef struct ompt_start_tool_result_t ompt_start_tool_result_t; + // Define symbols expected by VERSION script ompt_start_tool_result_t *ompt_start_tool(unsigned int omp_version, const char *runtime_version) { 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"); }