blob: 885757e28793c7017d81609661caef4d65cfe1da (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
//===-- OmptCallback.cpp - 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.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Implementation of OMPT callback interfaces for target independent layer
//
//===----------------------------------------------------------------------===//
#ifdef OMPT_SUPPORT
#include <assert.h>
#include <atomic>
#include <cstdlib>
#include <cstring>
#include "omp-tools.h"
#include "Debug.h"
#include "ompt_connector.h"
#include "ompt_device_callbacks.h"
#include "private.h"
#define fnptr_to_ptr(x) ((void *)(uint64_t)x)
/// Used to indicate whether OMPT was enabled for this library
bool OmptEnabled = false;
/// Object maintaining all the callbacks for this library
OmptDeviceCallbacksTy OmptDeviceCallbacks;
/// Used to maintain the finalization function that is received
/// from the plugin during connect
class LibomptargetRtlFinalizer {
public:
LibomptargetRtlFinalizer() : RtlFinalization(nullptr) {}
void registerRtl(ompt_finalize_t FinalizationFunction) {
assert((RtlFinalization == nullptr) &&
"RTL finalization may only be registered once");
RtlFinalization = FinalizationFunction;
}
void finalize() {
if (RtlFinalization)
RtlFinalization(nullptr /* tool_data */);
RtlFinalization = nullptr;
}
private:
ompt_finalize_t RtlFinalization;
};
/// 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);
}
/// 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");
// 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");
// 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.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");
}
extern "C" {
/// 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) {
// 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 */);
}
DP("OMPT: Leave ompt_libomptarget_connect\n");
}
}
#else
extern "C" {
/// Dummy definition when OMPT is disabled
void ompt_libomptarget_connect() {}
}
#endif // OMPT_SUPPORT
|