Skip to content

Commit dab5469

Browse files
authored
[Offload][OpenMP] Move OMPT out of plugins (llvm#2282)
This PR addresses the issue that we currently cannot build `liboffload` downstream given the OMPT symbols inside the plugin. Since liboffload is moving forward upstream, we should enable building it downstream. This is also a first step towards making the OMPT implementation (more) acceptable to upstream. ## Problem liboffload links the plugins but not libomptarget. libomptarget defines some of the OMPT symbols that are used inside the plugins. As a result you end up with two error modes: (1) when building offload you get unresolved symbols linker errors. (2) If you were to add the files that contains these symbols to the plugin build to address (1), you end up with a multiply-defined symbols error in the libomptarget build. ## Solution This patch moves all OMPT symbols out of the plugins and into an OMPT library with a common interface `GenericProfilerTy` that is used inside the plugin. The interface is then implemented in the OMPT library as `OmptProfilerTy` which calls the appropriate existing OMPT infrastructure. That OMPT library is linked to libomptarget but not liboffload. liboffload links an empty default implementation for now. This separation was also a request from upstream when we want to upstream OMPT support. ## Future Work We need to clean up the whole OMPT build and code anyway, but I figured that should not be done in this patch, given that it is already too large. The clean up should look at moving things into the right places and simplify the implementation where possible, given that we statically link the plugins and all (potentially still existing) dlopen cruft can go away.
1 parent 9de1d0d commit dab5469

File tree

20 files changed

+815
-368
lines changed

20 files changed

+815
-368
lines changed

offload/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,8 +468,7 @@ add_subdirectory(docs)
468468
# Build target agnostic offloading library.
469469
add_subdirectory(libomptarget)
470470

471-
# FIXME: Re-enable once OMPT design allows
472-
# add_subdirectory(liboffload)
471+
add_subdirectory(liboffload)
473472

474473
# Add tests.
475474
if(OFFLOAD_INCLUDE_TESTS)

offload/include/OpenMP/OMPT/Interface.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -473,20 +473,21 @@ template <typename FunctionPairTy, typename AsyncInfoTy, typename... ArgsTy>
473473
class TracerInterfaceRAII {
474474
public:
475475
TracerInterfaceRAII(FunctionPairTy Callbacks, AsyncInfoTy &AsyncInfo,
476-
int TracedDeviceId, ompt_callbacks_t EventType,
477-
ArgsTy... Args)
476+
void *OmptSpecificData, int TracedDeviceId,
477+
ompt_callbacks_t EventType, ArgsTy... Args)
478478
: Arguments(Args...), beginFunction(std::get<0>(Callbacks)) {
479479
__tgt_async_info *AI = AsyncInfo;
480480
if (isTracingEnabled(TracedDeviceId, EventType)) {
481481
auto Record = begin();
482-
// Gets freed in interface.cpp, functions
483-
// targetKernel and targetData once launching target operations returns.
484-
if (!AI->ProfilerData)
485-
AI->ProfilerData = new OmptEventInfoTy();
486-
// TODO: Make sure this has the right type
487-
auto OEI = reinterpret_cast<OmptEventInfoTy *>(AI->ProfilerData);
488-
OEI->TraceRecord = Record;
489-
OEI->NumTeams = 0;
482+
483+
// Access the already allocated profiler data and populate it
484+
OmptEventInfoTy *ProfilerData =
485+
reinterpret_cast<OmptEventInfoTy *>(OmptSpecificData);
486+
ProfilerData->TraceRecord = Record;
487+
ProfilerData->NumTeams = 0;
488+
489+
// Allows to pass down into the plugins via AsyncInfoTy
490+
AI->ProfilerData = ProfilerData;
490491
} else {
491492
// Actively prevent further tracing of this event
492493
AI->ProfilerData = nullptr;

offload/include/OpenMP/OMPT/OmptTracing.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ ompt_set_result_t setTraceEventTy(int DeviceId, unsigned int Enable,
102102
/// Return thread id
103103
uint64_t getThreadId();
104104

105+
/// See TracedDevices in OmptDeviceTracing.h
106+
extern std::map<int32_t, uint64_t> TracedDevices;
107+
/// Activate tracing on the given device
108+
void enableDeviceTracing(int DeviceId);
109+
/// Deactivate tracing on the given device
110+
void disableDeviceTracing(int DeviceId);
111+
105112
/// Mutexes to serialize invocation of device registration and checks
106113
extern std::mutex DeviceAccessMutex;
107114

offload/include/Shared/APITypes.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <variant>
2626

2727
#ifdef OMPT_SUPPORT
28+
#include "OpenMP/OMPT/OmptEventInfoTy.h"
2829
#include <omp-tools.h>
2930
#endif
3031
#include <mutex>
@@ -94,9 +95,6 @@ struct __tgt_async_info {
9495
/// Use for sync interface. When false => synchronous execution
9596
bool ExecAsync = true;
9697
/// Maintain the actal data for OMPT.
97-
/// TODO: Moving forward, this should become a void* to not expose OMPT data
98-
/// type in general types
99-
// llvm::omp::target::ompt::OmptEventInfoTy *OmptEventInfo = nullptr;
10098
void *ProfilerData = nullptr;
10199
};
102100

offload/libomptarget/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ endforeach()
8585

8686
target_compile_options(omptarget PRIVATE ${offload_compile_flags})
8787
target_link_options(omptarget PRIVATE ${offload_link_flags})
88+
if (OMPT_TARGET_DEFAULT AND LIBOMPTARGET_OMPT_SUPPORT)
89+
target_link_libraries(omptarget PRIVATE PluginOmpt)
90+
endif()
8891

8992
macro(check_plugin_target target)
9093
if (TARGET omptarget.rtl.${target})

offload/libomptarget/PluginManager.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,3 +643,21 @@ Expected<DeviceTy &> PluginManager::getDevice(uint32_t DeviceNo) {
643643
DeviceNo);
644644
return *DevicePtr;
645645
}
646+
647+
#ifdef OMPT_SUPPORT
648+
649+
#include "OmptProfiler.h"
650+
651+
std::unique_ptr<llvm::omp::target::plugin::GenericProfilerTy>
652+
getProfilerToAttach() {
653+
return std::make_unique<llvm::omp::target::ompt::OmptProfilerTy>();
654+
}
655+
656+
#else
657+
658+
std::unique_ptr<llvm::omp::target::plugin::GenericProfilerTy>
659+
getProfilerToAttach() {
660+
return std::make_unique<llvm::omp::target::plugin::GenericProfilerTy>();
661+
}
662+
663+
#endif

offload/libomptarget/device.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,12 +245,18 @@ int32_t DeviceTy::submitData(void *TgtPtrBegin, void *HstPtrBegin, int64_t Size,
245245
RegionInterface.getCallbacks<ompt_target_data_transfer_to_device>(),
246246
omp_get_initial_device(), HstPtrBegin, DeviceID, TgtPtrBegin, Size,
247247
/*CodePtr=*/OMPT_GET_RETURN_ADDRESS);
248+
// The Profiler can allocate specific data to be used to pass information
249+
// from here to lower parts of the runtime system.
250+
// NOTE: It is the responsibility of the programmer to ensure type
251+
// compatibility and correct usage of the data. The profiler, however,
252+
// OWNS the pointer and frees it at an appropriate time.
253+
void *ProfData = RTL->getProfiler()->getProfilerSpecificData();
248254
// Only if 'TracedDeviceId' is actually traced, AsyncInfo->OmptEventInfo
249255
// is set and a trace record generated. Otherwise: No OMPT device tracing.
250256
TracerInterfaceRAII TargetDataSubmitTraceRAII(
251257
RegionInterface
252258
.getTraceGenerators<ompt_target_data_transfer_to_device>(),
253-
AsyncInfo, /*TracedDeviceId=*/DeviceID,
259+
AsyncInfo, ProfData, /*TracedDeviceId=*/DeviceID,
254260
/*EventType=*/ompt_callback_target_data_op, omp_get_initial_device(),
255261
HstPtrBegin, DeviceID, TgtPtrBegin, Size,
256262
/*CodePtr=*/OMPT_GET_RETURN_ADDRESS);)
@@ -275,12 +281,18 @@ int32_t DeviceTy::retrieveData(void *HstPtrBegin, void *TgtPtrBegin,
275281
RegionInterface.getCallbacks<ompt_target_data_transfer_from_device>(),
276282
DeviceID, TgtPtrBegin, omp_get_initial_device(), HstPtrBegin, Size,
277283
/*CodePtr=*/OMPT_GET_RETURN_ADDRESS);
284+
// The Profiler can allocate specific data to be used to pass information
285+
// from here to lower parts of the runtime system.
286+
// NOTE: It is the responsibility of the programmer to ensure type
287+
// compatibility and correct usage of the data. The profiler, however,
288+
// OWNS the pointer and frees it at an appropriate time.
289+
void *ProfData = RTL->getProfiler()->getProfilerSpecificData();
278290
// Only if 'TracedDeviceId' is actually traced, AsyncInfo->OmptEventInfo
279291
// is set and a trace record generated. Otherwise: No OMPT device tracing.
280292
TracerInterfaceRAII TargetDataSubmitTraceRAII(
281293
RegionInterface
282294
.getTraceGenerators<ompt_target_data_transfer_from_device>(),
283-
AsyncInfo, /*TracedDeviceId=*/DeviceID,
295+
AsyncInfo, ProfData, /*TracedDeviceId=*/DeviceID,
284296
/*EventType=*/ompt_callback_target_data_op, DeviceID, TgtPtrBegin,
285297
omp_get_initial_device(), HstPtrBegin, Size,
286298
/*CodePtr=*/OMPT_GET_RETURN_ADDRESS);)
@@ -304,12 +316,18 @@ int32_t DeviceTy::dataExchange(void *SrcPtr, DeviceTy &DstDev, void *DstPtr,
304316
RegionInterface.getCallbacks<ompt_target_data_transfer_from_device>(),
305317
RTLDeviceID, SrcPtr, DstDev.RTLDeviceID, DstPtr, Size,
306318
/*CodePtr=*/OMPT_GET_RETURN_ADDRESS);
319+
// The Profiler can allocate specific data to be used to pass information
320+
// from here to lower parts of the runtime system.
321+
// NOTE: It is the responsibility of the programmer to ensure type
322+
// compatibility and correct usage of the data. The profiler, however,
323+
// OWNS the pointer and frees it at an appropriate time.
324+
void *ProfData = RTL->getProfiler()->getProfilerSpecificData();
307325
// Only if 'TracedDeviceId' is actually traced, AsyncInfo->OmptEventInfo
308326
// is set and a trace record generated. Otherwise: No OMPT device tracing.
309327
TracerInterfaceRAII TargetDataExchangeTraceRAII(
310328
RegionInterface
311329
.getTraceGenerators<ompt_target_data_transfer_from_device>(),
312-
AsyncInfo, /*TracedDeviceId=*/RTLDeviceID,
330+
AsyncInfo, ProfData, /*TracedDeviceId=*/RTLDeviceID,
313331
/*EventType=*/ompt_callback_target_data_op, RTLDeviceID, SrcPtr,
314332
DstDev.RTLDeviceID, DstPtr, Size,
315333
/*CodePtr=*/OMPT_GET_RETURN_ADDRESS);)

offload/libomptarget/interface.cpp

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -200,14 +200,6 @@ targetData(ident_t *Loc, int64_t DeviceId, int32_t ArgNum, void **ArgsBase,
200200
Rc = AsyncInfo.synchronize();
201201
}
202202

203-
#ifdef OMPT_SUPPORT
204-
if (__tgt_async_info *AI = AsyncInfo; AI->ProfilerData) {
205-
auto OmptData = reinterpret_cast<OmptEventInfoTy*>(AI->ProfilerData);
206-
// These deletes are going to go into the OmptProfiler
207-
delete OmptData;
208-
}
209-
#endif
210-
211203
handleTargetOutcome(Rc == OFFLOAD_SUCCESS, Loc);
212204
}
213205

@@ -493,23 +485,6 @@ static inline int targetKernel(ident_t *Loc, int64_t DeviceId, int32_t NumTeams,
493485
}
494486
}
495487

496-
#ifdef OMPT_SUPPORT
497-
if (__tgt_async_info *AI = AsyncInfo; AI->ProfilerData) {
498-
auto OmptData = reinterpret_cast<OmptEventInfoTy*>(AI->ProfilerData);
499-
// These deletes are going to go into the OmptProfiler
500-
delete OmptData;
501-
}
502-
503-
for (TargetAsyncInfoTy *LocalTAI : TargetAsyncInfos) {
504-
AsyncInfoTy &AsyncInfo = *LocalTAI;
505-
if (__tgt_async_info *AI = AsyncInfo; AI->ProfilerData) {
506-
auto OmptData = reinterpret_cast<OmptEventInfoTy*>(AI->ProfilerData);
507-
// These deletes are going to go into the OmptProfiler
508-
delete OmptData;
509-
}
510-
}
511-
#endif
512-
513488
// Deallocate the multi-device async infos if any were allocated.
514489
for (TargetAsyncInfoTy *LocalTAI : TargetAsyncInfos)
515490
delete LocalTAI;

offload/libomptarget/omptarget.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2101,6 +2101,13 @@ int target(ident_t *Loc, DeviceTy &Device, void *HostPtr,
21012101
InterfaceRAII TargetSubmitRAII(
21022102
RegionInterface.getCallbacks<ompt_callback_target_submit>(), NumTeams);
21032103

2104+
// The Profiler can allocate specific data to be used to pass information
2105+
// from here to lower parts of the runtime system.
2106+
// NOTE: It is the responsibility of the programmer to ensure type
2107+
// compatibility and correct usage of the data. The profiler, however, OWNS
2108+
// the pointer and frees it at an appropriate time.
2109+
void *ProfData = Device.RTL->getProfiler()->getProfilerSpecificData();
2110+
21042111
// Calls "begin" for the OMPT trace record and let the plugin
21052112
// enqueue the stop operation for after the kernel is done. The stop
21062113
// operation completes the trace record entry with the information from
@@ -2109,7 +2116,7 @@ int target(ident_t *Loc, DeviceTy &Device, void *HostPtr,
21092116
// set and a trace record generated. Otherwise: No OMPT device tracing.
21102117
TracerInterfaceRAII TargetTraceRAII(
21112118
RegionInterface.getTraceGenerators<ompt_callback_target_submit>(),
2112-
AsyncInfo, /*TracedDeviceId=*/DeviceId,
2119+
AsyncInfo, ProfData, /*TracedDeviceId=*/DeviceId,
21132120
/*EventType=*/ompt_callback_target_submit, DeviceId, NumTeams);
21142121
#endif
21152122
Ret = Device.launchKernel(TgtEntryPtr, TgtArgs.data(), TgtOffsets.data(),

0 commit comments

Comments
 (0)