llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-offload Author: Jan Patrick Lehr (jplehr) <details> <summary>Changes</summary> Adds the OMPT profiler implementation without wiring it up into the whole plugins infrastructure yet. The individual commits do a bit of cleanup from the original port and to keep up with the changes to `main` in the meantime. --- <sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub> --- Patch is 29.98 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/229410.diff 7 Files Affected: - (added) offload/include/OpenMP/OMPT/OmptCommonDefs.h (+128) - (added) offload/include/OpenMP/OMPT/OmptEventInfoTy.h (+39) - (modified) offload/plugins-nextgen/common/CMakeLists.txt (+5) - (added) offload/plugins-nextgen/common/OMPT/OmptDeviceTracing.h (+100) - (added) offload/plugins-nextgen/common/OMPT/OmptProfiler.cpp (+110) - (added) offload/plugins-nextgen/common/OMPT/OmptProfiler.h (+122) - (added) offload/plugins-nextgen/common/OMPT/OmptTracing.cpp (+256) ``````````diff diff --git a/offload/include/OpenMP/OMPT/OmptCommonDefs.h b/offload/include/OpenMP/OMPT/OmptCommonDefs.h new file mode 100644 index 000000000000000..8ab2ba10a869337 --- /dev/null +++ b/offload/include/OpenMP/OMPT/OmptCommonDefs.h @@ -0,0 +1,128 @@ +//===------ OmptCommonDefs.h - Common definitions for OMPT --*- 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 +// +//===----------------------------------------------------------------------===// +// +// Common defines and typedefs for OMPT callback and tracing functionality. +// +//===----------------------------------------------------------------------===// + +#ifndef OFFLOAD_INCLUDE_OMPTCOMMONDEFS_H +#define OFFLOAD_INCLUDE_OMPTCOMMONDEFS_H + +#ifdef OMPT_SUPPORT + +#include "omp-tools.h" + +#pragma push_macro("DEBUG_PREFIX") +#undef DEBUG_PREFIX +#define DEBUG_PREFIX "OMPT" + +#define FUNCPTR_TO_PTR(x) ((void *)(uint64_t)x) + +#define FOREACH_OMPT_TARGET_CALLBACK(macro) \ + FOREACH_OMPT_DEVICE_EVENT(macro) \ + FOREACH_OMPT_NOEMI_EVENT(macro) \ + FOREACH_OMPT_EMI_EVENT(macro) + +// Common device tracing functions +#define FOREACH_OMPT_DEVICE_TRACING_FN_COMMON(macro) \ + macro(ompt_set_trace_ompt) macro(ompt_start_trace) macro(ompt_flush_trace) \ + macro(ompt_stop_trace) macro(ompt_advance_buffer_cursor) \ + macro(ompt_get_record_type) + +// Supported device tracing entry points +#define FOREACH_OMPT_DEVICE_TRACING_FN(macro) \ + FOREACH_OMPT_DEVICE_TRACING_FN_COMMON(macro) \ + macro(ompt_get_record_ompt) macro(ompt_get_device_time) \ + macro(ompt_translate_time) + +// Device tracing functionalities, which are also e.g. coupled to mutexes +#define FOREACH_OMPT_DEVICE_TRACING_FN_IMPLEMENTAIONS(macro) \ + FOREACH_OMPT_DEVICE_TRACING_FN_COMMON(macro) \ + macro(ompt_set_timestamp) macro(ompt_set_granted_teams) + +#define OMPT_API_ROUTINE static + +#define OMPT_CALLBACK_AVAILABLE(fn) (llvm::omp::target::ompt::Initialized && fn) + +#define OMPT_IF_BUILT(stmt) stmt + +#define OMPT_IF_ENABLED(stmts) \ + do { \ + if (llvm::omp::target::ompt::Initialized) { \ + stmts \ + } \ + } while (0) + +#define OMPT_IF_TRACING_ENABLED(stmts) \ + do { \ + if (llvm::omp::target::ompt::TracingActive) { \ + stmts \ + } \ + } while (0) + +#define OMPT_FRAME_FLAGS (ompt_frame_runtime | OMPT_FRAME_POSITION_DEFAULT) + +#if (__PPC64__ | __arm__) +#define OMPT_GET_FRAME_ADDRESS(level) __builtin_frame_address(level) +#define OMPT_FRAME_POSITION_DEFAULT ompt_frame_cfa +#else +#define OMPT_GET_FRAME_ADDRESS(level) __builtin_frame_address(level) +#define OMPT_FRAME_POSITION_DEFAULT ompt_frame_framepointer +#endif + +#define OMPT_PTR_UNKNOWN ((void *)0) + +#define performIfOmptInitialized(stmt) \ + do { \ + if (llvm::omp::target::ompt::Initialized) { \ + stmt; \ + } \ + } while (0) + +#define performOmptCallback(CallbackName, ...) \ + do { \ + if (ompt_callback_##CallbackName##_fn) \ + ompt_callback_##CallbackName##_fn(__VA_ARGS__); \ + } while (0) + +/// Device-independent OMPT tracing entry points, implemented by libomptarget +/// and linked into the same library as their plugin-side callers. +extern "C" { +ompt_set_result_t libomptarget_ompt_set_trace_ompt(int DeviceId, + unsigned int Enable, + unsigned int EventTy); +int libomptarget_ompt_start_trace(int DeviceId, + ompt_callback_buffer_request_t Request, + ompt_callback_buffer_complete_t Complete); +int libomptarget_ompt_flush_trace(int DeviceId); +int libomptarget_ompt_stop_trace(int DeviceId); +int libomptarget_ompt_advance_buffer_cursor(ompt_device_t *Device, + ompt_buffer_t *Buffer, size_t Size, + ompt_buffer_cursor_t CurrentPos, + ompt_buffer_cursor_t *NextPos); +ompt_record_t +libomptarget_ompt_get_record_type(ompt_buffer_t *Buffer, + ompt_buffer_cursor_t CurrentPos); +void libomptarget_ompt_set_granted_teams(uint32_t NumTeams); +void libomptarget_ompt_set_timestamp(uint64_t Start, uint64_t Stop); +} // extern "C" + +/// Function type def used for maintaining unique target region, target +/// operations ids +typedef uint64_t (*IdInterfaceTy)(); + +#pragma pop_macro("DEBUG_PREFIX") + +#else +#define performIfOmptInitialized(stmt) +#define OMPT_IF_BUILT(stmt) +#define OMPT_IF_ENABLED(stmts) +#define OMPT_IF_TRACING_ENABLED(stmts) +#endif // OMPT_SUPPORT + +#endif // OFFLOAD_INCLUDE_OMPTCOMMONDEFS_H diff --git a/offload/include/OpenMP/OMPT/OmptEventInfoTy.h b/offload/include/OpenMP/OMPT/OmptEventInfoTy.h new file mode 100644 index 000000000000000..7124b3a3ff501b2 --- /dev/null +++ b/offload/include/OpenMP/OMPT/OmptEventInfoTy.h @@ -0,0 +1,39 @@ +//===- OmptEventInfoTy.h - OMPT specific trace record data ------*- 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 +// +//===----------------------------------------------------------------------===// +// +// Data structure used to communicate OMPT specific profiler data from the +// high-level libomptarget into the vendor-specific plugins +// +//===----------------------------------------------------------------------===// + +#ifndef OFFLOAD_INCLUDE_OPENMP_OMPT_OMPTEVENTINFOTY_H +#define OFFLOAD_INCLUDE_OPENMP_OMPT_OMPTEVENTINFOTY_H + +#include "Shared/Debug.h" + +struct ompt_record_ompt_t; + +namespace llvm { +namespace omp { +namespace target { +namespace ompt { + +/// Holds info needed to fill asynchronous trace records +struct OmptEventInfoTy { + /// The granted number of teams at runtime + uint64_t NumTeams; + /// Pointer to the actual buffer storage location + ompt_record_ompt_t *TraceRecord; +}; + +} // namespace ompt +} // namespace target +} // namespace omp +} // namespace llvm + +#endif // OFFLOAD_INCLUDE_OPENMP_OMPT_OMPTEVENTINFOTY_H diff --git a/offload/plugins-nextgen/common/CMakeLists.txt b/offload/plugins-nextgen/common/CMakeLists.txt index 19ce102309a7245..556b8ddf3311ca2 100644 --- a/offload/plugins-nextgen/common/CMakeLists.txt +++ b/offload/plugins-nextgen/common/CMakeLists.txt @@ -37,6 +37,11 @@ endif() include(FindLibcCommonUtils) target_link_libraries(PluginCommon PRIVATE llvm-libc-common-utilities) +if (TARGET flang_rt.runtime.static) + target_link_libraries(PluginCommon PRIVATE flang_rt.runtime.static) + target_compile_definitions(PluginCommon PRIVATE OFFLOAD_HAS_FLANG_RT) +endif() + # Define the TARGET_NAME and DEBUG_PREFIX. target_compile_definitions(PluginCommon PRIVATE TARGET_NAME=PluginInterface diff --git a/offload/plugins-nextgen/common/OMPT/OmptDeviceTracing.h b/offload/plugins-nextgen/common/OMPT/OmptDeviceTracing.h new file mode 100644 index 000000000000000..adc3695b1398761 --- /dev/null +++ b/offload/plugins-nextgen/common/OMPT/OmptDeviceTracing.h @@ -0,0 +1,100 @@ +//===- OmptDeviceTracing.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 tracing functionality. +// +//===----------------------------------------------------------------------===// + +#ifndef OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_OMPTDEVICETRACING_H +#define OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_OMPTDEVICETRACING_H + +#ifdef OMPT_SUPPORT + +#include "OpenMP/OMPT/OmptCommonDefs.h" + +#include <map> +#include <mutex> + +#pragma push_macro("DEBUG_PREFIX") +#undef DEBUG_PREFIX +#define DEBUG_PREFIX "OMPT" + +extern void setOmptAsyncCopyProfile(bool Enable); +extern void setGlobalOmptKernelProfile(void *Device, int Enable); +extern uint64_t getSystemTimestampInNs(); + +namespace llvm { +namespace omp { +namespace target { +namespace ompt { + +// Declare OMPT device tracing function mutexes +#define declareOmptTracingFnMutex(Name) extern std::mutex Name##_mutex; +FOREACH_OMPT_DEVICE_TRACING_FN_IMPLEMENTAIONS(declareOmptTracingFnMutex) +#undef declareOmptTracingFnMutex + +extern std::mutex DeviceIdWritingMutex; + +/// Activate tracing on the given device +void enableDeviceTracing(int DeviceId); + +/// Deactivate tracing on the given device +void disableDeviceTracing(int DeviceId); + +/// Set 'start' and 'stop' in trace records +void setOmptTimestamp(uint64_t StartTime, uint64_t EndTime); + +/// Set the linear function correlation between host and device clocks +void setOmptHostToDeviceRate(double Slope, double Offset); + +/// Set / store the number of granted teams in trace records +void setOmptGrantedNumTeams(uint64_t NumTeams); + +/// Lookup the given device pointer and return its RTL device ID +int getDeviceId(ompt_device_t *Device); + +/// Map the given device pointer to the given DeviceId +void setDeviceId(ompt_device_t *Device, int32_t DeviceId); + +/// Rempve the given device pointer from the current mapping +void removeDeviceId(ompt_device_t *Device); + +/// Check whether the provided device is currently traced. +bool isTracedDevice(int32_t DeviceId); + +/// Provide name based lookup for the device tracing functions +extern ompt_interface_fn_t +lookupDeviceTracingFn(const char *InterfaceFunctionName); + +/// Host to device linear clock correlation +extern double HostToDeviceSlope; + +/// Host to device constant clock offset +extern double HostToDeviceOffset; + +/// Mapping of device pointers to their corresponding RTL device ID +extern std::map<ompt_device_t *, int32_t> Devices; + +/// Mapping of RTL device IDs to their currently enabled tracing event types. +/// Note: Event type '0' (bit position) indicates if this device is traced. +extern std::map<int32_t, uint64_t> TracedDevices; + +/// OMPT global tracing status. Indicates if at least one device is traced. +extern bool TracingActive; + +} // namespace ompt +} // namespace target +} // namespace omp +} // namespace llvm + +#pragma pop_macro("DEBUG_PREFIX") + +#endif // OMPT_SUPPORT + +#endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_OMPTDEVICETRACING_H diff --git a/offload/plugins-nextgen/common/OMPT/OmptProfiler.cpp b/offload/plugins-nextgen/common/OMPT/OmptProfiler.cpp new file mode 100644 index 000000000000000..d74e6e3b9b82acf --- /dev/null +++ b/offload/plugins-nextgen/common/OMPT/OmptProfiler.cpp @@ -0,0 +1,110 @@ +//===- OmptProfiler.cpp - OMPT impl of GenericProfilerTy --------*- 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 +// +//===----------------------------------------------------------------------===// +// +// Implementation of OmptProfilerTy +// +//===----------------------------------------------------------------------===// + +#include "OmptProfiler.h" +#include "OpenMP/OMPT/Interface.h" +#include "PluginInterface.h" +#include "Shared/Debug.h" + +#include <memory> + +using namespace llvm::omp::target; + +void ompt::OmptProfilerTy::handleDataAlloc(uint64_t StartNanos, + uint64_t EndNanos, void *HostPtr, + uint64_t Size, void *Data) { + ompt::setOmptTimestamp(StartNanos, EndNanos); +} + +void ompt::OmptProfilerTy::handleDataDelete(uint64_t StartNanos, + uint64_t EndNanos, void *TgtPtr, + void *Data) { + ompt::setOmptTimestamp(StartNanos, EndNanos); +} + +void ompt::OmptProfilerTy::handlePreKernelLaunch( + plugin::GenericDeviceTy *Device, uint32_t NumBlocks[3], + __tgt_async_info *AI) { + if (!ompt::isTracedDevice( + ompt::getDeviceId(reinterpret_cast<ompt_device_t *>(Device)))) + return; + + if (AI->ProfilerData == nullptr) + return; + + auto ProfilerSpecificData = + reinterpret_cast<ompt::OmptEventInfoTy *>(AI->ProfilerData); + assert(ProfilerSpecificData && "Invalid ProfilerSpecificData"); + // Set number of granted teams for OMPT + setOmptGrantedNumTeams(NumBlocks[0]); + ProfilerSpecificData->NumTeams = NumBlocks[0]; +} + +void ompt::OmptProfilerTy::handleKernelCompletion(uint64_t StartNanos, + uint64_t EndNanos, + void *Data) { + + if (!isProfilingEnabled()) + return; + + // Null data means no trace record was assigned for this event, see + // TracerInterfaceRAII in OpenMP/OMPT/Interface.h. + if (!Data) + return; + + ODBG(ODT_Tool) << "OMPT-Async: Time kernel for asynchronous execution: Start " + << StartNanos << " End " << EndNanos; + + auto OmptEventInfo = reinterpret_cast<ompt::OmptEventInfoTy *>(Data); + assert(OmptEventInfo && "Invalid OmptEventInfo"); + assert(OmptEventInfo->TraceRecord && "Invalid TraceRecord"); + + ompt::RegionInterface.stopTargetSubmitTraceAsync(OmptEventInfo->TraceRecord, + OmptEventInfo->NumTeams, + StartNanos, EndNanos); + + // Done processing, our responsibility to free the memory + freeProfilerDataEntry(OmptEventInfo); +} + +void ompt::OmptProfilerTy::handleDataTransfer(uint64_t StartNanos, + uint64_t EndNanos, void *Data) { + + if (!isProfilingEnabled()) + return; + + // Null data means no trace record was assigned for this event, see + // TracerInterfaceRAII in OpenMP/OMPT/Interface.h. + if (!Data) + return; + + ODBG(ODT_Tool) << "OMPT-Async: Time data for asynchronous execution: Start " + << StartNanos << " End " << EndNanos; + + auto OmptEventInfo = reinterpret_cast<ompt::OmptEventInfoTy *>(Data); + assert(OmptEventInfo && "Invalid OmptEventInfo"); + assert(OmptEventInfo->TraceRecord && "Invalid TraceRecord"); + + ompt::RegionInterface.stopTargetDataMovementTraceAsync( + OmptEventInfo->TraceRecord, StartNanos, EndNanos); + + // Done processing, our responsibility to free the memory + freeProfilerDataEntry(OmptEventInfo); +} + +bool ompt::OmptProfilerTy::isProfilingEnabled() { return ompt::TracingActive; } + +void ompt::OmptProfilerTy::setTimeConversionFactorsImpl(double Slope, + double Offset) { + ODBG(ODT_Tool) << "Using Time Slope: " << Slope << " and Offset: " << Offset; + setOmptHostToDeviceRate(Slope, Offset); +} diff --git a/offload/plugins-nextgen/common/OMPT/OmptProfiler.h b/offload/plugins-nextgen/common/OMPT/OmptProfiler.h new file mode 100644 index 000000000000000..4c2c90e3f385add --- /dev/null +++ b/offload/plugins-nextgen/common/OMPT/OmptProfiler.h @@ -0,0 +1,122 @@ +//===- OmptProfiler.h - OMPT specific impl of GenericProfilerTy -*- 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 +// +//===----------------------------------------------------------------------===// +// +// OMPT specific implementation of the GenericProfilerTy class. +// This class uses the already existing implementation of OMPT to invoke +// callbacks and perform tracing. +// +//===----------------------------------------------------------------------===// + +#ifndef OFFLOAD_PLUGINS_NEXTGEN_COMMON_OMPT_OMPTPROFILERTY_H +#define OFFLOAD_PLUGINS_NEXTGEN_COMMON_OMPT_OMPTPROFILERTY_H + +#include "GenericProfiler.h" + +#include "OmptDeviceTracing.h" +#include "OpenMP/OMPT/Callback.h" +#include "OpenMP/OMPT/OmptEventInfoTy.h" +#include "Shared/Debug.h" +#include "omp-tools.h" + +#include <functional> +#include <memory> +#include <mutex> +#include <tuple> + +#pragma push_macro("DEBUG_PREFIX") +#undef DEBUG_PREFIX +#define DEBUG_PREFIX "OMPT" + +extern uint64_t getSystemTimestampInNs(); + +using namespace llvm::omp::target::debug; + +namespace llvm { +namespace omp { +namespace target { +namespace plugin { +struct GenericDeviceTy; +class GenericProfilerTy; + +} // namespace plugin + +namespace ompt { + +/** + * Implements an OMPT backend for the Profiler interface used in the plugins. + * + * Forwards / Implements the different generic hooks with OMPT semantics. + */ +class OmptProfilerTy : public plugin::GenericProfilerTy { +public: + bool isProfilingEnabled() override; + + void handleDataAlloc(uint64_t StartNanos, uint64_t EndNanos, void *HostPtr, + uint64_t Size, void *Data) override; + void handleDataDelete(uint64_t StartNanos, uint64_t EndNanos, void *TgtPtr, + void *Data) override; + + void handlePreKernelLaunch(plugin::GenericDeviceTy *Device, + uint32_t NumBlocks[3], + __tgt_async_info *AI) override; + + void handleKernelCompletion(uint64_t StartNanos, uint64_t EndNanos, + void *Data) override; + + void handleDataTransfer(uint64_t StartNanos, uint64_t EndNanos, + void *Data) override; + + void setTimeConversionFactorsImpl(double Slope, double Offset) override; + + /// Allocate the event info that carries \p Record into the plugins for + /// asynchronous completion. The profiler owns the returned object and frees + /// it via freeProfilerDataEntry once the plugin completed the record. + OmptEventInfoTy *trackAsyncRecord(ompt_record_ompt_t *Record) { + // TODO: This is ID is not used currently + uint64_t Id = OmptProfDataId.fetch_add(1); + std::scoped_lock<std::mutex> Lock(ProfilerDataMutex); + auto &Info = ProfilerData[Id]; + Info = std::make_unique<OmptEventInfoTy>(); + Info->TraceRecord = Record; + Info->NumTeams = 0; + return Info.get(); + } + + void freeProfilerDataEntry(OmptEventInfoTy *DataPtr) { + std::scoped_lock<std::mutex> Lock(ProfilerDataMutex); + + for (auto &Entry : ProfilerData) + if (Entry.second.get() == DataPtr) { + ProfilerData.erase(Entry.first); + break; + } + } + +private: + /// Holds a unique ID for each allocation of OmptEventInfoTy + std::atomic<uint64_t> OmptProfDataId{0}; + + /// Holds memory used to store OMPT specific data and pass it down from + /// libomptarget into the plugins. + std::map<uint64_t, std::unique_ptr<OmptEventInfoTy>> ProfilerData; + + /// Lock to guard STL ProfilerData map + std::mutex ProfilerDataMutex; +}; + +/// Process-wide OMPT profile... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/229410 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
