xref: /llvm-project/openmp/libompd/test/ompt_plugin.h (revision 4c63672ca706c708de1e49bb29d026a705daa0d2)
1 #include <dlfcn.h>
2 #include <omp-tools.h>
3 #include <omp.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <sys/types.h>
7 #include <unistd.h>
8 
9 typedef struct omp_t_data {
10   // Thread data
11   ompt_state_t ompt_state;
12   ompt_wait_id_t ompt_wait_id;
13   int omp_thread_num;
14   ompt_data_t *ompt_thread_data;
15   // Parallel data
16   int omp_num_threads;
17   int omp_level;
18   int omp_active_level;
19   ompt_data_t *ompt_parallel_data;
20   // Task data
21   int omp_max_threads;
22   int omp_parallel;
23   int omp_final;
24   int omp_dynamic;
25   int omp_nested;
26   int omp_max_active_levels;
27   omp_sched_t omp_kind;
28   int omp_modifier;
29   omp_proc_bind_t omp_proc_bind;
30   ompt_frame_t *ompt_frame_list;
31   ompt_data_t *ompt_task_data;
32 } omp_t_data_t;
33 
34 static __thread omp_t_data_t thread_data;
35 
36 static ompt_function_lookup_t ompt_lookup;
37 // NOLINTNEXTLINE "Used in Macro:register_callback_t below."
38 static ompt_set_callback_t ompt_set_callback;
39 static ompt_get_callback_t ompt_get_callback;
40 static ompt_get_state_t ompt_get_state;
41 static ompt_get_task_info_t ompt_get_task_info;
42 static ompt_get_thread_data_t ompt_get_thread_data;
43 static ompt_get_parallel_info_t ompt_get_parallel_info;
44 static ompt_get_unique_id_t ompt_get_unique_id;
45 static ompt_get_num_procs_t ompt_get_num_procs;
46 static ompt_get_num_places_t ompt_get_num_places;
47 static ompt_get_place_proc_ids_t ompt_get_place_proc_ids;
48 static ompt_get_place_num_t ompt_get_place_num;
49 static ompt_get_partition_place_nums_t ompt_get_partition_place_nums;
50 static ompt_get_proc_id_t ompt_get_proc_id;
51 static ompt_enumerate_states_t ompt_enumerate_states;
52 static ompt_enumerate_mutex_impls_t ompt_enumerate_mutex_impls;
53 static int checks = 0;
54 
on_ompt_callback_implicit_task(ompt_scope_endpoint_t endpoint,ompt_data_t * parallel_data,ompt_data_t * task_data,unsigned int team_size,unsigned int thread_num,int flags)55 static void on_ompt_callback_implicit_task(ompt_scope_endpoint_t endpoint,
56                                            ompt_data_t *parallel_data,
57                                            ompt_data_t *task_data,
58                                            unsigned int team_size,
59                                            unsigned int thread_num, int flags) {
60   if (endpoint == ompt_scope_begin)
61     task_data->value = ompt_get_unique_id();
62 }
63 
on_ompt_callback_thread_begin(ompt_thread_t thread_type,ompt_data_t * t_data)64 static void on_ompt_callback_thread_begin(ompt_thread_t thread_type,
65                                           ompt_data_t *t_data) {
66   t_data->value = ompt_get_unique_id();
67 }
68 
on_ompt_callback_parallel_begin(ompt_data_t * encountering_task_data,const ompt_frame_t * encountering_task_frame,ompt_data_t * parallel_data,uint32_t requested_team_size,int flag,const void * codeptr_ra)69 static void on_ompt_callback_parallel_begin(
70     ompt_data_t *encountering_task_data,
71     const ompt_frame_t *encountering_task_frame, ompt_data_t *parallel_data,
72     uint32_t requested_team_size, int flag, const void *codeptr_ra) {
73   parallel_data->value = ompt_get_unique_id();
74 }
75 
76 #define register_callback_t(name, type)                                        \
77   do {                                                                         \
78     type f_##name = &on_##name;                                                \
79     if (ompt_set_callback(name, (ompt_callback_t)f_##name) == ompt_set_never)  \
80       printf("0: Could not register callback '" #name "'\n");                  \
81   } while (0)
82 
83 #define register_callback(name) register_callback_t(name, name##_t)
84 
ompt_initialize(ompt_function_lookup_t lookup,int initial_device_num,ompt_data_t * tool_data)85 static int ompt_initialize(ompt_function_lookup_t lookup,
86                            int initial_device_num, ompt_data_t *tool_data) {
87   ompt_lookup = lookup;
88   // TODO: remove: printf("runtime_version: %s, omp_version: %i\n",
89   // runtime_version, omp_version);
90 
91   // TODO: remove macro
92   // #define declare_inquery_fn(F) F = (F##_t)lookup(#F);
93   // FOREACH_OMPT_INQUIRY_FN(declare_inquery_fn)
94   // #undef declare_inquery_fn
95 
96   ompt_set_callback_t ompt_set_callback =
97       (ompt_set_callback_t)lookup("ompt_set_callback");
98   ompt_get_callback = (ompt_get_callback_t)lookup("ompt_get_callback");
99   ompt_get_state = (ompt_get_state_t)lookup("ompt_get_state");
100   ompt_get_task_info = (ompt_get_task_info_t)lookup("ompt_get_task_info");
101   ompt_get_thread_data = (ompt_get_thread_data_t)lookup("ompt_get_thread_data");
102   ompt_get_parallel_info =
103       (ompt_get_parallel_info_t)lookup("ompt_get_parallel_info");
104   ompt_get_unique_id = (ompt_get_unique_id_t)lookup("ompt_get_unique_id");
105 
106   ompt_get_num_procs = (ompt_get_num_procs_t)lookup("ompt_get_num_procs");
107   ompt_get_num_places = (ompt_get_num_places_t)lookup("ompt_get_num_places");
108   ompt_get_place_proc_ids =
109       (ompt_get_place_proc_ids_t)lookup("ompt_get_place_proc_ids");
110   ompt_get_place_num = (ompt_get_place_num_t)lookup("ompt_get_place_num");
111   ompt_get_partition_place_nums =
112       (ompt_get_partition_place_nums_t)lookup("ompt_get_partition_place_nums");
113   ompt_get_proc_id = (ompt_get_proc_id_t)lookup("ompt_get_proc_id");
114   ompt_enumerate_states =
115       (ompt_enumerate_states_t)lookup("ompt_enumerate_states");
116   ompt_enumerate_mutex_impls =
117       (ompt_enumerate_mutex_impls_t)lookup("ompt_enumerate_mutex_impls");
118 
119   register_callback(ompt_callback_implicit_task);
120   register_callback(ompt_callback_thread_begin);
121   register_callback(ompt_callback_parallel_begin);
122 
123   return 1; // activate tool
124 }
125 
ompt_finalize(ompt_data_t * tool_data)126 static void ompt_finalize(ompt_data_t *tool_data) {}
127 
128 // "This func will be invoked by OpenMP implementation, refer spec: 4.2.1"
129 // NOLINTNEXTLINE
ompt_start_tool(unsigned int omp_version,const char * runtime_version)130 ompt_start_tool_result_t *ompt_start_tool(unsigned int omp_version,
131                                           const char *runtime_version) {
132   static ompt_start_tool_result_t ompt_start_tool_result = {
133       &ompt_initialize, &ompt_finalize, {0}};
134   return &ompt_start_tool_result;
135 }
136 
collectParallelData(omp_t_data_t * data)137 static void collectParallelData(omp_t_data_t *data) {
138   data->omp_num_threads = omp_get_num_threads();
139   data->omp_level = omp_get_level();
140   data->omp_active_level = omp_get_active_level();
141   ompt_get_parallel_info(0, &(data->ompt_parallel_data), NULL);
142 }
143 
collectTaskData(omp_t_data_t * data)144 static void collectTaskData(omp_t_data_t *data) {
145   data->omp_max_threads = omp_get_max_threads();
146   data->omp_parallel = omp_in_parallel();
147   data->omp_final = omp_in_final();
148   data->omp_dynamic = omp_get_dynamic();
149   data->omp_nested = omp_get_max_active_levels() > 1;
150   data->omp_max_active_levels = omp_get_max_active_levels();
151   omp_get_schedule(&(data->omp_kind), &(data->omp_modifier));
152   data->omp_proc_bind = omp_get_proc_bind();
153   ompt_get_task_info(0, NULL, &(data->ompt_task_data), &(data->ompt_frame_list),
154                      NULL, NULL);
155 }
156 
collectThreadData(omp_t_data_t * data)157 static void collectThreadData(omp_t_data_t *data) {
158   data->omp_thread_num = omp_get_thread_num();
159   data->ompt_state = (ompt_state_t)ompt_get_state(&(data->ompt_wait_id));
160   data->ompt_thread_data = ompt_get_thread_data();
161 }
162 
163 #ifdef __cplusplus
164 extern "C" {
165 #endif
breakToolTest(omp_t_data_t * data)166 __attribute__((noinline)) static void *breakToolTest(omp_t_data_t *data) {
167   return data;
168 }
169 #ifdef __cplusplus
170 }
171 #endif
172 
173 #ifdef __cplusplus
174 extern "C" {
175 #endif
ompd_tool_break(void * n)176 static void *ompd_tool_break(void *n) {
177   (void)n;
178   asm("");
179   return NULL;
180 }
181 #ifdef __cplusplus
182 }
183 #endif
184 
185 // NOLINTNEXTLINE "This func will be invoked in testcases."
ompd_tool_test(void * n)186 static void *ompd_tool_test(void *n) {
187   collectThreadData(&thread_data);
188   collectParallelData(&thread_data);
189   collectTaskData(&thread_data);
190   breakToolTest(&thread_data);
191   checks++;
192   ompd_tool_break(NULL);
193   return NULL;
194 }
195 
init(void)196 __attribute__((__constructor__)) static void init(void) {}
197 
fini(void)198 __attribute__((__destructor__)) static void fini(void) {
199   printf("Finished %i testsuites.\n", checks);
200 }
201