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 @@ -17,7 +17,9 @@ #ifdef OMPT_SUPPORT #include "Debug.h" +#include #include +#include #define DEBUG_PREFIX "OMPT" @@ -26,9 +28,66 @@ FOREACH_OMPT_NOEMI_EVENT(macro) \ FOREACH_OMPT_EMI_EVENT(macro) +/// Internal representation for OMPT device +class OmptDeviceTy { +public: + OmptDeviceTy() { Enabled.store(false); } + bool initialize() { + bool Old = false; + return Enabled.compare_exchange_strong(Old, true); + } + bool finalize() { + bool Old = true; + return Enabled.compare_exchange_strong(Old, false); + } + +private: + std::atomic Enabled; +}; + /// Internal representation for OMPT device callback functions. class OmptDeviceCallbacksTy { public: + /// Invoked when a device is initialized + void OmptCallbackDeviceInitialize(int DeviceNum, const char *Type) { + if (ompt_callback_device_initialize_fn) { + OmptDeviceTy *Device = lookupDevice(DeviceNum); + if (Device && Device->initialize()) { + ompt_callback_device_initialize_fn( + DeviceNum, Type, reinterpret_cast(Device), + doLookup, Documentation); + } + } + } + + /// Invoked when a device is finalized + void OmptCallbackDeviceFinalize(int DeviceNum) { + if (ompt_callback_device_finalize_fn) { + OmptDeviceTy *Device = lookupDevice(DeviceNum); + if (Device && Device->finalize()) { + ompt_callback_device_finalize_fn(DeviceNum); + } + } + } + + /// Invoked when a device image is loaded + void OmptCallbackDeviceLoad(int DeviceNum, const char *Filename, + int64_t OffsetInFile, void *VmaInFile, + size_t Bytes, void *HostAddr, void *DeviceAddr, + uint64_t ModuleId) { + if (ompt_callback_device_load_fn) { + ompt_callback_device_load_fn(DeviceNum, Filename, OffsetInFile, VmaInFile, + Bytes, HostAddr, DeviceAddr, ModuleId); + } + } + + /// Invoked when a device image is unloaded + void OmptCallbackDeviceUnload(int DeviceNum, uint64_t ModuleId) { + if (ompt_callback_device_unload_fn) { + ompt_callback_device_unload_fn(DeviceNum, ModuleId); + } + } + /// Initialize the enabled flag and all the callbacks void init() { Enabled = false; @@ -37,6 +96,12 @@ #undef initName } + bool isEnabled() { return Enabled; } + /// Devices must be prepared before use + void prepareDevices(int NumDevices) { resize(NumDevices); } + /// Devices must be released after use + void releaseDevices() { release(); } + /// 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) { @@ -71,6 +136,15 @@ #define DeclareName(Name, Type, Code) Name##_t Name##_fn; FOREACH_OMPT_TARGET_CALLBACK(DeclareName) #undef DeclareName + + /// Allocate devices + static void resize(int NumDevices); + /// Deallocate devices + static void release(); + /// Find a device given its id + static OmptDeviceTy *lookupDevice(int DeviceNum); + /// Documentation based on omp-tools + static const char *Documentation; }; /// Device callbacks object for the library that performs the instantiation diff --git a/openmp/libomptarget/plugins/amdgpu/src/ompt_callback.cpp b/openmp/libomptarget/plugins/amdgpu/src/ompt_callback.cpp --- a/openmp/libomptarget/plugins/amdgpu/src/ompt_callback.cpp +++ b/openmp/libomptarget/plugins/amdgpu/src/ompt_callback.cpp @@ -18,8 +18,26 @@ #include "ompt_connector.h" #include "ompt_device_callbacks.h" +#ifdef OMPT_SUPPORT +#define DEBUG_PREFIX "OMPT" + /// Object maintaining all the callbacks in the plugin -OmptDeviceCallbacksTy ompt_device_callbacks; +OmptDeviceCallbacksTy OmptDeviceCallbacks; + +const char *OmptDeviceCallbacksTy::Documentation = 0; + +/// Array denoting the devices +static OmptDeviceTy *devices = 0; + +void OmptDeviceCallbacksTy::resize(int NumDevices) { + devices = new OmptDeviceTy[NumDevices]; +} + +void OmptDeviceCallbacksTy::release() { delete[] devices; } + +OmptDeviceTy *OmptDeviceCallbacksTy::lookupDevice(int DeviceNum) { + return &devices[DeviceNum]; +} /// Lookup function used for querying callback functions maintained /// by the plugin @@ -32,7 +50,6 @@ /// Used to indicate whether OMPT was enabled for this library static bool ompt_enabled = false; -#ifdef OMPT_SUPPORT /// 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 @@ -45,7 +62,7 @@ // 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. - ompt_device_callbacks.registerCallbacks(lookup); + OmptDeviceCallbacks.registerCallbacks(lookup); DP("OMPT: Exit ompt_device_init\n"); return 0; } @@ -76,10 +93,11 @@ OmptResult.tool_data.value = 0; // Initialize the device callbacks first - ompt_device_callbacks.init(); + OmptDeviceCallbacks.init(); // Now call connect that causes the above init/fini functions to be called LibomptargetConnector.connect(&OmptResult); DP("OMPT: Exiting ompt_init\n"); } +#undef DEBUG_PREFIX #endif diff --git a/openmp/libomptarget/plugins/amdgpu/src/rtl.cpp b/openmp/libomptarget/plugins/amdgpu/src/rtl.cpp --- a/openmp/libomptarget/plugins/amdgpu/src/rtl.cpp +++ b/openmp/libomptarget/plugins/amdgpu/src/rtl.cpp @@ -42,6 +42,22 @@ #include "omptargetplugin.h" #include "print_tracing.h" +#include "Debug.h" + +#ifdef OMPT_SUPPORT +#include "ompt_device_callbacks.h" +#define OMPT_IF_BUILT_AND_ENABLED(stmts) \ + do { \ + if (OmptDeviceCallbacks.isEnabled()) { \ + stmts; \ + } \ + } while (0) +#else +#define OMPT_IF_BUILT_AND_ENABLED(stmts) +#endif + +#define DEBUG_PREFIX "AMDGPU" + using namespace llvm; using namespace llvm::object; using namespace llvm::ELF; @@ -973,6 +989,29 @@ return Res; } +#ifdef OMPT_SUPPORT + void doOmptDeviceLoad(int32_t DeviceId, const char *FileName, + int64_t OffsetInFile, void *VmaInFile, size_t Bytes, + void *HostAddr, void *DeviceAddr, uint64_t ModuleId) { + OmptDeviceCallbacks.OmptCallbackDeviceLoad(DeviceId, FileName, OffsetInFile, + VmaInFile, Bytes, HostAddr, + DeviceAddr, ModuleId); + } + + void doOmptDeviceInitialize(int32_t DeviceId, const char *InfoName) { + std::string OmptGPUType("AMD "); + OmptGPUType += InfoName; + OmptDeviceCallbacks.OmptCallbackDeviceInitialize(DeviceId, + OmptGPUType.c_str()); + } + + void doOmptDeviceFinalize() { + for (int i = 0; i < NumberOfDevices; i++) + OmptDeviceCallbacks.OmptCallbackDeviceFinalize(i); + OmptDeviceCallbacks.releaseDevices(); + } +#endif + RTLDeviceInfoTy() { DP("Start initializing " GETNAME(TARGET_NAME) "\n"); @@ -1047,6 +1086,10 @@ return; } +#ifdef OMPT_SUPPORT + OmptDeviceCallbacks.prepareDevices(NumberOfDevices); +#endif + for (int I = 0; I < NumberOfDevices; I++) { uint32_t QueueSize = 0; { @@ -1099,6 +1142,9 @@ // Then none of these can have been set up and they can't be torn down return; } + + OMPT_IF_BUILT_AND_ENABLED(doOmptDeviceFinalize()); + // Run destructors on types that use HSA before // impl_finalize removes access to it DeviceStateStore.clear(); @@ -2082,6 +2128,9 @@ DeviceInfo().GroupsPerDevice[DeviceId] * DeviceInfo().ThreadsPerGroup[DeviceId]); + OMPT_IF_BUILT_AND_ENABLED( + DeviceInfo().doOmptDeviceInitialize(DeviceId, GetInfoName)); + return OFFLOAD_SUCCESS; } @@ -2172,6 +2221,10 @@ DP("AMDGPU module successfully loaded!\n"); + OMPT_IF_BUILT_AND_ENABLED(DeviceInfo().doOmptDeviceLoad( + DeviceId, nullptr /* FileName */, 0 /* OffsetInFile */, + nullptr /* VmaInFile */, ImgSize, Image->ImageStart, + nullptr /* DeviceAddr */, 0 /* FIXME ModuleId */)); { // the device_State array is either large value in bss or a void* that // needs to be assigned to a pointer to an array of size device_state_bytes @@ -2613,3 +2666,4 @@ } } // extern "C" +#undef DEBUG_PREFIX 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 /*----------------------------------------------------------------------------