1/*
2 * ompdModule.c
3 */
4
5//===----------------------------------------------------------------------===//
6//
7// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8// See https://llvm.org/LICENSE.txt for license information.
9// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10//
11//===----------------------------------------------------------------------===//
12
13#include <Python.h>
14#include <omp-tools.h>
15// #include <ompd.h>
16#include <dlfcn.h>
17#include <errno.h>
18#include <pthread.h>
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23void *ompd_library;
24
25#define OMPD_WEAK_ATTR __attribute__((weak))
26
27struct _ompd_aspace_cont {
28 int id;
29};
30struct _ompd_thread_cont {
31 int id;
32};
33ompd_address_space_context_t acontext = {42};
34
35PyObject *pModule;
36
37ompd_rc_t _print(const char *str, int category);
38
39// NOTE: implement functions to check parameters of OMPD API functions for
40// correctness
41OMPD_WEAK_ATTR ompd_rc_t ompd_get_api_version(ompd_word_t *addr) {
42 static ompd_rc_t (*my_get_api_version)(ompd_word_t *) = NULL;
43 if (!my_get_api_version) {
44 my_get_api_version = dlsym(handle: ompd_library, name: "ompd_get_api_version");
45 if (dlerror()) {
46 return ompd_rc_error;
47 }
48 }
49 return my_get_api_version(addr);
50}
51
52OMPD_WEAK_ATTR ompd_rc_t ompd_get_version_string(const char **string) {
53 static ompd_rc_t (*my_get_version_string)(const char **) = NULL;
54 if (!my_get_version_string) {
55 my_get_version_string = dlsym(handle: ompd_library, name: "ompd_get_version_string");
56 if (dlerror()) {
57 return ompd_rc_error;
58 }
59 }
60 return my_get_version_string(string);
61}
62
63OMPD_WEAK_ATTR ompd_rc_t ompd_finalize(void) {
64 static ompd_rc_t (*my_ompd_finalize)(void) = NULL;
65 if (!my_ompd_finalize) {
66 my_ompd_finalize = dlsym(handle: ompd_library, name: "ompd_finalize");
67 if (dlerror()) {
68 return ompd_rc_error;
69 }
70 }
71 return my_ompd_finalize();
72}
73
74OMPD_WEAK_ATTR ompd_rc_t
75ompd_process_initialize(ompd_address_space_context_t *context,
76 ompd_address_space_handle_t **handle) {
77 static ompd_rc_t (*my_ompd_process_initialize)(
78 ompd_address_space_context_t *, ompd_address_space_handle_t **) = NULL;
79 if (!my_ompd_process_initialize) {
80 my_ompd_process_initialize = dlsym(handle: ompd_library, name: "ompd_process_initialize");
81 if (dlerror()) {
82 return ompd_rc_error;
83 }
84 }
85 return my_ompd_process_initialize(context, handle);
86}
87
88OMPD_WEAK_ATTR ompd_rc_t ompd_get_omp_version(
89 ompd_address_space_handle_t *address_space, ompd_word_t *omp_version) {
90 static ompd_rc_t (*my_ompd_get_omp_version)(ompd_address_space_handle_t *,
91 ompd_word_t *) = NULL;
92 if (!my_ompd_get_omp_version) {
93 my_ompd_get_omp_version = dlsym(handle: ompd_library, name: "ompd_get_omp_version");
94 if (dlerror()) {
95 return ompd_rc_error;
96 }
97 }
98 return my_ompd_get_omp_version(address_space, omp_version);
99}
100
101OMPD_WEAK_ATTR ompd_rc_t ompd_get_omp_version_string(
102 ompd_address_space_handle_t *address_space, const char **string) {
103 static ompd_rc_t (*my_ompd_get_omp_version_string)(
104 ompd_address_space_handle_t *, const char **) = NULL;
105 if (!my_ompd_get_omp_version_string) {
106 my_ompd_get_omp_version_string =
107 dlsym(handle: ompd_library, name: "ompd_get_omp_version_string");
108 if (dlerror()) {
109 return ompd_rc_error;
110 }
111 }
112 return my_ompd_get_omp_version_string(address_space, string);
113}
114
115OMPD_WEAK_ATTR ompd_rc_t ompd_get_thread_handle(
116 ompd_address_space_handle_t *handle, ompd_thread_id_t kind,
117 ompd_size_t tidSize, const void *tid, ompd_thread_handle_t **threadHandle) {
118 static ompd_rc_t (*my_get_thread_handle)(
119 ompd_address_space_handle_t *, ompd_thread_id_t, ompd_size_t,
120 const void *, ompd_thread_handle_t **) = NULL;
121 if (!my_get_thread_handle) {
122 my_get_thread_handle = dlsym(handle: ompd_library, name: "ompd_get_thread_handle");
123 if (dlerror()) {
124 return ompd_rc_error;
125 }
126 }
127 return my_get_thread_handle(handle, kind, tidSize, tid, threadHandle);
128}
129
130OMPD_WEAK_ATTR ompd_rc_t ompd_get_thread_in_parallel(
131 ompd_parallel_handle_t *parallelHandle, int threadNum,
132 ompd_thread_handle_t **threadHandle) {
133 static ompd_rc_t (*my_get_thread_in_parallel)(ompd_parallel_handle_t *, int,
134 ompd_thread_handle_t **) = NULL;
135 if (!my_get_thread_in_parallel) {
136 my_get_thread_in_parallel =
137 dlsym(handle: ompd_library, name: "ompd_get_thread_in_parallel");
138 if (dlerror()) {
139 return ompd_rc_error;
140 }
141 }
142 return my_get_thread_in_parallel(parallelHandle, threadNum, threadHandle);
143}
144
145OMPD_WEAK_ATTR ompd_rc_t ompd_thread_handle_compare(
146 ompd_thread_handle_t *thread_handle1, ompd_thread_handle_t *thread_handle2,
147 int *cmp_value) {
148 static ompd_rc_t (*my_thread_handle_compare)(
149 ompd_thread_handle_t *, ompd_thread_handle_t *, int *) = NULL;
150 if (!my_thread_handle_compare) {
151 my_thread_handle_compare =
152 dlsym(handle: ompd_library, name: "ompd_thread_handle_compare");
153 if (dlerror()) {
154 return ompd_rc_error;
155 }
156 }
157 return my_thread_handle_compare(thread_handle1, thread_handle2, cmp_value);
158}
159
160OMPD_WEAK_ATTR ompd_rc_t
161ompd_get_curr_parallel_handle(ompd_thread_handle_t *threadHandle,
162 ompd_parallel_handle_t **parallelHandle) {
163 static ompd_rc_t (*my_get_current_parallel_handle)(
164 ompd_thread_handle_t *, ompd_parallel_handle_t **) = NULL;
165 if (!my_get_current_parallel_handle) {
166 my_get_current_parallel_handle =
167 dlsym(handle: ompd_library, name: "ompd_get_curr_parallel_handle");
168 if (dlerror()) {
169 return ompd_rc_error;
170 }
171 }
172 return my_get_current_parallel_handle(threadHandle, parallelHandle);
173}
174
175OMPD_WEAK_ATTR ompd_rc_t ompd_parallel_handle_compare(
176 ompd_parallel_handle_t *parallel_handle_1,
177 ompd_parallel_handle_t *parallel_handle_2, int *cmp_value) {
178 static ompd_rc_t (*my_parallel_handle_compare)(
179 ompd_parallel_handle_t *, ompd_parallel_handle_t *, int *) = NULL;
180 if (!my_parallel_handle_compare) {
181 my_parallel_handle_compare =
182 dlsym(handle: ompd_library, name: "ompd_parallel_handle_compare");
183 if (dlerror()) {
184 return ompd_rc_error;
185 }
186 }
187 return my_parallel_handle_compare(parallel_handle_1, parallel_handle_2,
188 cmp_value);
189}
190
191OMPD_WEAK_ATTR ompd_rc_t
192ompd_get_enclosing_parallel_handle(ompd_parallel_handle_t *parallelHandle,
193 ompd_parallel_handle_t **enclosing) {
194 static ompd_rc_t (*my_get_enclosing_parallel_handle)(
195 ompd_parallel_handle_t *, ompd_parallel_handle_t **) = NULL;
196 if (!my_get_enclosing_parallel_handle) {
197 my_get_enclosing_parallel_handle =
198 dlsym(handle: ompd_library, name: "ompd_get_enclosing_parallel_handle");
199 if (dlerror()) {
200 return ompd_rc_error;
201 }
202 }
203 return my_get_enclosing_parallel_handle(parallelHandle, enclosing);
204}
205
206OMPD_WEAK_ATTR ompd_rc_t
207ompd_get_task_parallel_handle(ompd_task_handle_t *taskHandle,
208 ompd_parallel_handle_t **taskParallelHandle) {
209 static ompd_rc_t (*my_get_task_parallel_handle)(
210 ompd_task_handle_t *, ompd_parallel_handle_t **) = NULL;
211 if (!my_get_task_parallel_handle) {
212 my_get_task_parallel_handle =
213 dlsym(handle: ompd_library, name: "ompd_get_task_parallel_handle");
214 if (dlerror()) {
215 return ompd_rc_error;
216 }
217 }
218 return my_get_task_parallel_handle(taskHandle, taskParallelHandle);
219}
220
221OMPD_WEAK_ATTR ompd_rc_t ompd_get_curr_task_handle(
222 ompd_thread_handle_t *threadHandle, ompd_task_handle_t **taskHandle) {
223 static ompd_rc_t (*my_get_current_task_handle)(ompd_thread_handle_t *,
224 ompd_task_handle_t **) = NULL;
225 if (!my_get_current_task_handle) {
226 my_get_current_task_handle =
227 dlsym(handle: ompd_library, name: "ompd_get_curr_task_handle");
228 if (dlerror()) {
229 return ompd_rc_error;
230 }
231 }
232 return my_get_current_task_handle(threadHandle, taskHandle);
233}
234
235OMPD_WEAK_ATTR ompd_rc_t ompd_get_generating_task_handle(
236 ompd_task_handle_t *taskHandle, ompd_task_handle_t **generating) {
237 static ompd_rc_t (*my_get_generating_task_handle)(
238 ompd_task_handle_t *, ompd_task_handle_t **) = NULL;
239 if (!my_get_generating_task_handle) {
240 my_get_generating_task_handle =
241 dlsym(handle: ompd_library, name: "ompd_get_generating_task_handle");
242 if (dlerror()) {
243 return ompd_rc_error;
244 }
245 }
246 return my_get_generating_task_handle(taskHandle, generating);
247}
248
249OMPD_WEAK_ATTR ompd_rc_t ompd_get_scheduling_task_handle(
250 ompd_task_handle_t *taskHandle, ompd_task_handle_t **scheduling) {
251 static ompd_rc_t (*my_get_scheduling_task_handle)(
252 ompd_task_handle_t *, ompd_task_handle_t **) = NULL;
253 if (!my_get_scheduling_task_handle) {
254 my_get_scheduling_task_handle =
255 dlsym(handle: ompd_library, name: "ompd_get_scheduling_task_handle");
256 if (dlerror()) {
257 return ompd_rc_error;
258 }
259 }
260 return my_get_scheduling_task_handle(taskHandle, scheduling);
261}
262
263OMPD_WEAK_ATTR ompd_rc_t
264ompd_get_task_in_parallel(ompd_parallel_handle_t *parallelHandle, int threadNum,
265 ompd_task_handle_t **taskHandle) {
266 static ompd_rc_t (*my_get_task_in_parallel)(ompd_parallel_handle_t *, int,
267 ompd_task_handle_t **) = NULL;
268 if (!my_get_task_in_parallel) {
269 my_get_task_in_parallel = dlsym(handle: ompd_library, name: "ompd_get_task_in_parallel");
270 if (dlerror()) {
271 return ompd_rc_error;
272 }
273 }
274 return my_get_task_in_parallel(parallelHandle, threadNum, taskHandle);
275}
276
277OMPD_WEAK_ATTR ompd_rc_t ompd_get_task_frame(ompd_task_handle_t *taskHandle,
278 ompd_frame_info_t *exitFrame,
279 ompd_frame_info_t *enterFrame) {
280 static ompd_rc_t (*my_get_task_frame)(
281 ompd_task_handle_t *, ompd_frame_info_t *, ompd_frame_info_t *) = NULL;
282 if (!my_get_task_frame) {
283 my_get_task_frame = dlsym(handle: ompd_library, name: "ompd_get_task_frame");
284 if (dlerror()) {
285 return ompd_rc_error;
286 }
287 }
288 return my_get_task_frame(taskHandle, exitFrame, enterFrame);
289}
290
291OMPD_WEAK_ATTR ompd_rc_t ompd_get_icv_from_scope(void *handle,
292 ompd_scope_t scope,
293 ompd_icv_id_t icvId,
294 ompd_word_t *icvValue) {
295 static ompd_rc_t (*my_get_icv_from_scope)(void *, ompd_scope_t, ompd_icv_id_t,
296 ompd_word_t *) = NULL;
297 if (!my_get_icv_from_scope) {
298 my_get_icv_from_scope = dlsym(handle: ompd_library, name: "ompd_get_icv_from_scope");
299 if (dlerror()) {
300 return ompd_rc_error;
301 }
302 }
303 return my_get_icv_from_scope(handle, scope, icvId, icvValue);
304}
305
306OMPD_WEAK_ATTR ompd_rc_t
307ompd_enumerate_icvs(ompd_address_space_handle_t *handle, ompd_icv_id_t current,
308 ompd_icv_id_t *next, const char **nextIcvName,
309 ompd_scope_t *nextScope, int *more) {
310 static ompd_rc_t (*my_enumerate_icvs)(
311 ompd_address_space_handle_t *, ompd_icv_id_t, ompd_icv_id_t *,
312 const char **, ompd_scope_t *, int *) = NULL;
313 if (!my_enumerate_icvs) {
314 my_enumerate_icvs = dlsym(handle: ompd_library, name: "ompd_enumerate_icvs");
315 if (dlerror()) {
316 return ompd_rc_error;
317 }
318 }
319 return my_enumerate_icvs(handle, current, next, nextIcvName, nextScope, more);
320}
321
322OMPD_WEAK_ATTR ompd_rc_t
323ompd_enumerate_states(ompd_address_space_handle_t *addrSpaceHandle,
324 ompd_word_t currentState, ompd_word_t *nextState,
325 const char **nextStateName, ompd_word_t *moreEnums) {
326 static ompd_rc_t (*my_enumerate_states)(ompd_address_space_handle_t *,
327 ompd_word_t, ompd_word_t *,
328 const char **, ompd_word_t *) = NULL;
329 if (!my_enumerate_states) {
330 my_enumerate_states = dlsym(handle: ompd_library, name: "ompd_enumerate_states");
331 if (dlerror()) {
332 return ompd_rc_error;
333 }
334 }
335 return my_enumerate_states(addrSpaceHandle, currentState, nextState,
336 nextStateName, moreEnums);
337}
338
339OMPD_WEAK_ATTR ompd_rc_t ompd_get_state(ompd_thread_handle_t *threadHandle,
340 ompd_word_t *state,
341 ompd_wait_id_t *waitId) {
342 static ompd_rc_t (*my_get_state)(ompd_thread_handle_t *, ompd_word_t *,
343 ompd_wait_id_t *) = NULL;
344 if (!my_get_state) {
345 my_get_state = dlsym(handle: ompd_library, name: "ompd_get_state");
346 if (dlerror()) {
347 return ompd_rc_error;
348 }
349 }
350 return my_get_state(threadHandle, state, waitId);
351}
352
353OMPD_WEAK_ATTR ompd_rc_t ompd_get_task_function(ompd_task_handle_t *taskHandle,
354 ompd_address_t *entryPoint) {
355 static ompd_rc_t (*my_get_task_function)(ompd_task_handle_t *,
356 ompd_address_t *) = NULL;
357 if (!my_get_task_function) {
358 my_get_task_function = dlsym(handle: ompd_library, name: "ompd_get_task_function");
359 if (dlerror()) {
360 return ompd_rc_error;
361 }
362 }
363 return my_get_task_function(taskHandle, entryPoint);
364}
365
366OMPD_WEAK_ATTR ompd_rc_t ompd_get_thread_id(ompd_thread_handle_t *threadHandle,
367 ompd_thread_id_t kind,
368 ompd_size_t tidSize, void *tid) {
369 static ompd_rc_t (*my_get_thread_id)(ompd_thread_handle_t *, ompd_thread_id_t,
370 ompd_size_t, void *) = NULL;
371 if (!my_get_thread_id) {
372 my_get_thread_id = dlsym(handle: ompd_library, name: "ompd_get_thread_id");
373 if (dlerror()) {
374 return ompd_rc_error;
375 }
376 }
377 return my_get_thread_id(threadHandle, kind, tidSize, tid);
378}
379
380OMPD_WEAK_ATTR ompd_rc_t ompd_get_tool_data(void *handle, ompd_scope_t scope,
381 ompd_word_t *value,
382 ompd_address_t *ptr) {
383 static ompd_rc_t (*my_get_tool_data)(void *, ompd_scope_t, ompd_word_t *,
384 ompd_address_t *) = NULL;
385 if (!my_get_tool_data) {
386 my_get_tool_data = dlsym(handle: ompd_library, name: "ompd_get_tool_data");
387 if (dlerror()) {
388 return ompd_rc_error;
389 }
390 }
391 return my_get_tool_data(handle, scope, value, ptr);
392}
393
394OMPD_WEAK_ATTR ompd_rc_t
395ompd_get_icv_string_from_scope(void *handle, ompd_scope_t scope,
396 ompd_icv_id_t icvId, const char **icvString) {
397 static ompd_rc_t (*my_get_icv_string_from_scope)(
398 void *, ompd_scope_t, ompd_icv_id_t, const char **) = NULL;
399 if (!my_get_icv_string_from_scope) {
400 my_get_icv_string_from_scope =
401 dlsym(handle: ompd_library, name: "ompd_get_icv_string_from_scope");
402 if (dlerror()) {
403 return ompd_rc_error;
404 }
405 }
406 return my_get_icv_string_from_scope(handle, scope, icvId, icvString);
407}
408
409OMPD_WEAK_ATTR ompd_rc_t
410ompd_rel_thread_handle(ompd_thread_handle_t *threadHandle) {
411 static ompd_rc_t (*my_release_thread_handle)(ompd_thread_handle_t *) = NULL;
412 if (!my_release_thread_handle) {
413 my_release_thread_handle = dlsym(handle: ompd_library, name: "ompd_rel_thread_handle");
414 if (dlerror()) {
415 return ompd_rc_error;
416 }
417 }
418 return my_release_thread_handle(threadHandle);
419}
420
421OMPD_WEAK_ATTR ompd_rc_t
422ompd_rel_parallel_handle(ompd_parallel_handle_t *parallelHandle) {
423 static ompd_rc_t (*my_release_parallel_handle)(ompd_parallel_handle_t *) =
424 NULL;
425 if (!my_release_parallel_handle) {
426 my_release_parallel_handle =
427 dlsym(handle: ompd_library, name: "ompd_rel_parallel_handle");
428 if (dlerror()) {
429 return ompd_rc_error;
430 }
431 }
432 return my_release_parallel_handle(parallelHandle);
433}
434
435OMPD_WEAK_ATTR ompd_rc_t ompd_rel_task_handle(ompd_task_handle_t *taskHandle) {
436 static ompd_rc_t (*my_release_task_handle)(ompd_task_handle_t *) = NULL;
437 if (!my_release_task_handle) {
438 my_release_task_handle = dlsym(handle: ompd_library, name: "ompd_rel_task_handle");
439 if (dlerror()) {
440 return ompd_rc_error;
441 }
442 }
443 return my_release_task_handle(taskHandle);
444}
445
446OMPD_WEAK_ATTR ompd_rc_t
447ompd_task_handle_compare(ompd_task_handle_t *task_handle_1,
448 ompd_task_handle_t *task_handle_2, int *cmp_value) {
449 static ompd_rc_t (*my_task_handle_compare)(
450 ompd_task_handle_t *, ompd_task_handle_t *, int *) = NULL;
451 if (!my_task_handle_compare) {
452 my_task_handle_compare = dlsym(handle: ompd_library, name: "ompd_task_handle_compare");
453 if (dlerror()) {
454 return ompd_rc_error;
455 }
456 }
457 return my_task_handle_compare(task_handle_1, task_handle_2, cmp_value);
458}
459
460OMPD_WEAK_ATTR ompd_rc_t
461ompd_get_display_control_vars(ompd_address_space_handle_t *address_space_handle,
462 const char *const **control_vars) {
463 static ompd_rc_t (*my_ompd_get_display_control_vars)(
464 ompd_address_space_handle_t *, const char *const **) = NULL;
465 if (!my_ompd_get_display_control_vars) {
466 my_ompd_get_display_control_vars =
467 dlsym(handle: ompd_library, name: "ompd_get_display_control_vars");
468 if (dlerror()) {
469 return ompd_rc_error;
470 }
471 }
472 return my_ompd_get_display_control_vars(address_space_handle, control_vars);
473}
474
475/**
476 * Loads the OMPD library (libompd.so). Returns an integer with the version if
477 * the OMPD library could be loaded successfully. Error codes: -1: argument
478 * could not be converted to string -2: error when calling dlopen -3: error when
479 * fetching version of OMPD API else: see ompd return codes
480 */
481static PyObject *ompd_open(PyObject *self, PyObject *args) {
482 const char *name, *dlerr;
483 dlerror();
484 if (!PyArg_ParseTuple(args, "s", &name)) {
485 return Py_BuildValue("i", -1);
486 }
487 ompd_library = dlopen(file: name, RTLD_LAZY);
488 if ((dlerr = dlerror())) {
489 return Py_BuildValue("i", -2);
490 }
491 if (dlerror()) {
492 return Py_BuildValue("i", -3);
493 }
494 ompd_word_t version;
495 ompd_rc_t rc = ompd_get_api_version(addr: &version);
496 if (rc != ompd_rc_ok)
497 return Py_BuildValue("l", -10 - rc);
498
499 int returnValue = version;
500 return Py_BuildValue("i", returnValue);
501}
502
503/**
504 * Have the debugger print a string.
505 */
506ompd_rc_t _print(const char *str, int category) {
507 PyObject *pFunc = PyObject_GetAttrString(pModule, "_print");
508 if (pFunc && PyCallable_Check(pFunc)) {
509 PyObject *pArgs = PyTuple_New(size: 1);
510 PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", str));
511 PyObject_CallObject(callable: pFunc, args: pArgs);
512 Py_XDECREF(pArgs);
513 }
514 Py_XDECREF(pFunc);
515 return ompd_rc_ok;
516}
517
518void _printf(const char *format, ...) {
519 va_list args;
520 va_start(args, format);
521 char output[1024];
522 vsnprintf(s: output, maxlen: 1024, format: format, arg: args);
523 va_end(args);
524 _print(str: output, category: 0);
525}
526
527/**
528 * Capsule destructors for thread, parallel and task handles.
529 */
530static void call_ompd_rel_thread_handle_temp(PyObject *capsule) {
531 ompd_thread_handle_t *threadHandle =
532 (ompd_thread_handle_t *)(PyCapsule_GetPointer(capsule, name: "ThreadHandle"));
533
534 ompd_rc_t retVal = ompd_rel_thread_handle(threadHandle);
535 if (retVal != ompd_rc_ok) {
536 _printf(
537 format: "An error occurred when calling ompd_rel_thread_handle! Error code: %d",
538 retVal);
539 }
540}
541
542static void destroyThreadCapsule(PyObject *capsule) {
543 call_ompd_rel_thread_handle_temp(capsule);
544}
545static void (*my_thread_capsule_destructor)(PyObject *) = destroyThreadCapsule;
546
547static void call_ompd_rel_parallel_handle_temp(PyObject *capsule) {
548 ompd_parallel_handle_t *parallelHandle =
549 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(capsule,
550 name: "ParallelHandle"));
551
552 ompd_rc_t retVal = ompd_rel_parallel_handle(parallelHandle);
553 if (retVal != ompd_rc_ok) {
554 _printf(format: "An error occurred when calling ompd_rel_parallel_handle! Error "
555 "code: %d",
556 retVal);
557 }
558}
559
560static void destroyParallelCapsule(PyObject *capsule) {
561 call_ompd_rel_parallel_handle_temp(capsule);
562}
563static void (*my_parallel_capsule_destructor)(PyObject *) =
564 destroyParallelCapsule;
565
566static void call_ompd_rel_task_handle_temp(PyObject *capsule) {
567 ompd_task_handle_t *taskHandle =
568 (ompd_task_handle_t *)(PyCapsule_GetPointer(capsule, name: "TaskHandle"));
569
570 ompd_rc_t retVal = ompd_rel_task_handle(taskHandle);
571 if (retVal != ompd_rc_ok) {
572 _printf(format: "An error occurred when calling ompd_rel_task_handle!\n");
573 }
574}
575
576static void destroyTaskCapsule(PyObject *capsule) {
577 call_ompd_rel_task_handle_temp(capsule);
578}
579static void (*my_task_capsule_destructor)(PyObject *) = destroyTaskCapsule;
580
581/**
582 * Release thread handle. Called inside destructor for Python thread_handle
583 * object.
584 */
585static PyObject *call_ompd_rel_thread_handle(PyObject *self, PyObject *args) {
586 PyObject *threadHandlePy = PyTuple_GetItem(args, 0);
587 ompd_thread_handle_t *threadHandle =
588 (ompd_thread_handle_t *)(PyCapsule_GetPointer(capsule: threadHandlePy,
589 name: "ThreadHandle"));
590
591 ompd_rc_t retVal = ompd_rel_thread_handle(threadHandle);
592 if (retVal != ompd_rc_ok) {
593 _printf(
594 format: "An error occurred when calling ompd_rel_thread_handle! Error code: %d",
595 retVal);
596 }
597 return Py_BuildValue("l", retVal);
598}
599
600/**
601 * Allocate memory in the debugger's address space.
602 */
603ompd_rc_t _alloc(ompd_size_t bytes, void **ptr) {
604 if (ptr == NULL) {
605 return ompd_rc_bad_input;
606 }
607 *ptr = malloc(size: bytes);
608 return ompd_rc_ok;
609}
610
611/**
612 * Free memory in the debugger's address space.
613 */
614ompd_rc_t _free(void *ptr) {
615 free(ptr: ptr);
616 return ompd_rc_ok;
617}
618
619/**
620 * Look up the sizes of primitive types in the target.
621 */
622ompd_rc_t _sizes(ompd_address_space_context_t *_acontext, /* IN */
623 ompd_device_type_sizes_t *sizes) /* OUT */
624{
625 if (acontext.id != _acontext->id)
626 return ompd_rc_stale_handle;
627 ompd_device_type_sizes_t mysizes = {
628 (uint8_t)sizeof(char), (uint8_t)sizeof(short),
629 (uint8_t)sizeof(int), (uint8_t)sizeof(long),
630 (uint8_t)sizeof(long long), (uint8_t)sizeof(void *)};
631 *sizes = mysizes;
632 return ompd_rc_ok;
633}
634
635/**
636 * Look up the address of a global symbol in the target.
637 */
638ompd_rc_t _sym_addr(ompd_address_space_context_t *context, /* IN */
639 ompd_thread_context_t *tcontext, /* IN */
640 const char *symbol_name, /* IN */
641 ompd_address_t *symbol_addr, /* OUT */
642 const char *file_name) /* IN */
643{
644 int thread_id = -1;
645 PyObject *symbolAddress;
646 if (tcontext != NULL) {
647 thread_id = tcontext->id;
648 }
649 PyObject *pFunc = PyObject_GetAttrString(pModule, "_sym_addr");
650 if (pFunc && PyCallable_Check(pFunc)) {
651 PyObject *pArgs = PyTuple_New(size: 2);
652 PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", thread_id));
653 PyTuple_SetItem(pArgs, 1, Py_BuildValue("s", symbol_name));
654 symbolAddress = PyObject_CallObject(callable: pFunc, args: pArgs);
655 if (symbolAddress == NULL) {
656 PyErr_Print();
657 }
658 symbol_addr->address = PyLong_AsLong(symbolAddress);
659 Py_XDECREF(pArgs);
660 Py_XDECREF(symbolAddress);
661 }
662 Py_XDECREF(pFunc);
663 return ompd_rc_ok;
664}
665
666/**
667 * Read memory from the target.
668 */
669ompd_rc_t _read(ompd_address_space_context_t *context, /* IN */
670 ompd_thread_context_t *tcontext, /* IN */
671 const ompd_address_t *addr, /* IN */
672 ompd_size_t nbytes, /* IN */
673 void *buffer) /* OUT */
674{
675 uint64_t readMem = (uint64_t)addr->address;
676 PyObject *pFunc = PyObject_GetAttrString(pModule, "_read");
677 if (pFunc && PyCallable_Check(pFunc)) {
678 PyObject *pArgs = PyTuple_New(size: 2);
679 PyTuple_SetItem(pArgs, 0, Py_BuildValue("l", readMem));
680 PyTuple_SetItem(pArgs, 1, Py_BuildValue("l", nbytes));
681 PyObject *retArray = PyObject_CallObject(callable: pFunc, args: pArgs);
682 Py_XDECREF(pArgs);
683 if (retArray == NULL) {
684 PyErr_Print();
685 }
686 if (!PyByteArray_Check(retArray)) {
687 return ompd_rc_error;
688 }
689 Py_ssize_t retSize = PyByteArray_Size(retArray);
690 const char *strBuf = PyByteArray_AsString(retArray);
691 if ((ompd_size_t)retSize != nbytes) {
692 return ompd_rc_error;
693 }
694 memcpy(dest: buffer, src: strBuf, n: nbytes);
695 Py_XDECREF(retArray);
696 }
697 Py_XDECREF(pFunc);
698 return ompd_rc_ok;
699}
700
701/**
702 * Reads string from target.
703 */
704ompd_rc_t _read_string(ompd_address_space_context_t *context, /* IN */
705 ompd_thread_context_t *tcontext, /* IN */
706 const ompd_address_t *addr, /* IN */
707 ompd_size_t nbytes, /* IN */
708 void *buffer) /* OUT */
709{
710 ompd_rc_t retVal = ompd_rc_ok;
711 uint64_t readMem = (uint64_t)addr->address;
712 PyObject *pFunc = PyObject_GetAttrString(pModule, "_read_string");
713 PyObject *pArgs = PyTuple_New(size: 1);
714 PyTuple_SetItem(pArgs, 0, Py_BuildValue("l", readMem));
715 PyObject *retString = PyObject_CallObject(callable: pFunc, args: pArgs);
716 Py_XDECREF(pArgs);
717 if (!PyUnicode_Check(retString)) {
718 return ompd_rc_error;
719 }
720 Py_ssize_t retSize;
721 const char *strbuffer = PyUnicode_AsUTF8AndSize(unicode: retString, size: &retSize);
722 if ((ompd_size_t)retSize + 1 >= nbytes) {
723 retVal = ompd_rc_incomplete;
724 }
725 strncpy(dest: buffer, src: strbuffer, n: nbytes);
726 ((char *)buffer)[nbytes - 1] = '\0';
727 return retVal;
728}
729
730/**
731 * Write memory from the target.
732 */
733ompd_rc_t
734_endianess(ompd_address_space_context_t *address_space_context, /* IN */
735 const void *input, /* IN */
736 ompd_size_t unit_size, /* IN */
737 ompd_size_t count, /* IN: number of primitive type */
738 void *output) {
739 if (acontext.id != address_space_context->id)
740 return ompd_rc_stale_handle;
741 memmove(dest: output, src: input, n: count * unit_size);
742 return ompd_rc_ok;
743}
744
745/**
746 * Returns thread context for thread id; helper function for _thread_context
747 * callback.
748 */
749ompd_thread_context_t *get_thread_context(int id) {
750 static ompd_thread_context_t *tc = NULL;
751 static int size = 0;
752 int i;
753 if (id < 1)
754 return NULL;
755 if (tc == NULL) {
756 size = 16;
757 tc = malloc(size: size * sizeof(ompd_thread_context_t));
758 for (i = 0; i < size; i++)
759 tc[i].id = i + 1;
760 }
761 if (id - 1 >= size) {
762 size += 16;
763 tc = realloc(ptr: tc, size: size * sizeof(ompd_thread_context_t));
764 for (i = 0; i < size; i++)
765 tc[i].id = i + 1;
766 }
767 return tc + id - 1;
768}
769
770/**
771 * Get thread specific context.
772 */
773ompd_rc_t
774_thread_context(ompd_address_space_context_t *context, /* IN */
775 ompd_thread_id_t kind, /* IN, 0 for pthread, 1 for lwp */
776 ompd_size_t sizeof_thread_id, /* IN */
777 const void *thread_id, /* IN */
778 ompd_thread_context_t **thread_context) /* OUT */
779{
780 if (acontext.id != context->id)
781 return ompd_rc_stale_handle;
782 if (kind != 0 && kind != 1)
783 return ompd_rc_unsupported;
784 long int tid;
785 if (sizeof(long int) >= 8 && sizeof_thread_id == 8)
786 tid = *(const uint64_t *)thread_id;
787 else if (sizeof(long int) >= 4 && sizeof_thread_id == 4)
788 tid = *(const uint32_t *)thread_id;
789 else if (sizeof(long int) >= 2 && sizeof_thread_id == 2)
790 tid = *(const uint16_t *)thread_id;
791 else
792 return ompd_rc_bad_input;
793 PyObject *pFunc = PyObject_GetAttrString(pModule, "_thread_context");
794 if (pFunc && PyCallable_Check(pFunc)) {
795 PyObject *pArgs = PyTuple_New(size: 2);
796 PyTuple_SetItem(pArgs, 0, Py_BuildValue("l", kind));
797 PyTuple_SetItem(pArgs, 1, Py_BuildValue("l", tid));
798 PyObject *res = PyObject_CallObject(callable: pFunc, args: pArgs);
799 int resAsInt = (int)PyLong_AsLong(res);
800 if (resAsInt == -1) {
801 // NOTE: could not find match for thread_id
802 return ompd_rc_unavailable;
803 }
804 (*thread_context) = get_thread_context(id: resAsInt);
805 Py_XDECREF(pArgs);
806 Py_XDECREF(res);
807 Py_XDECREF(pFunc);
808 if (*thread_context == NULL) {
809 return ompd_rc_bad_input;
810 }
811 return ompd_rc_ok;
812 }
813 Py_XDECREF(pFunc);
814 return ompd_rc_error;
815}
816
817/**
818 * Calls ompd_process_initialize; returns pointer to ompd_address_space_handle.
819 */
820static PyObject *call_ompd_initialize(PyObject *self, PyObject *noargs) {
821 pModule = PyImport_Import(name: PyUnicode_FromString(u: "ompd_callbacks"));
822
823 static ompd_callbacks_t table = {
824 _alloc, _free, _print, _sizes, _sym_addr, _read,
825 NULL, _read_string, _endianess, _endianess, _thread_context};
826
827 ompd_rc_t (*my_ompd_init)(ompd_word_t version, ompd_callbacks_t *) =
828 dlsym(handle: ompd_library, name: "ompd_initialize");
829 ompd_rc_t returnInit = my_ompd_init(201811, &table);
830 if (returnInit != ompd_rc_ok) {
831 _printf(format: "An error occurred when calling ompd_initialize! Error code: %d",
832 returnInit);
833 }
834 ompd_address_space_handle_t *addr_space = NULL;
835 ompd_rc_t (*my_proc_init)(ompd_address_space_context_t *,
836 ompd_address_space_handle_t **) =
837 dlsym(handle: ompd_library, name: "ompd_process_initialize");
838 ompd_rc_t retProcInit = my_proc_init(&acontext, &addr_space);
839 if (retProcInit != ompd_rc_ok) {
840 _printf(format: "An error occurred when calling ompd_process_initialize! Error "
841 "code: %d",
842 retProcInit);
843 }
844 return PyCapsule_New(pointer: addr_space, name: "AddressSpace", NULL);
845}
846
847/**
848 * Returns a PyCapsule pointer to thread handle for thread with the given id.
849 */
850static PyObject *get_thread_handle(PyObject *self, PyObject *args) {
851 PyObject *threadIdTup = PyTuple_GetItem(args, 0);
852 uint64_t threadId = (uint64_t)PyLong_AsLong(threadIdTup);
853 // NOTE: compiler does not know what thread handle looks like, so no memory
854 // is allocated automatically in the debugger's memory space
855
856 PyObject *addrSpaceTup = PyTuple_GetItem(args, 1);
857 ompd_thread_handle_t *threadHandle;
858 ompd_address_space_handle_t *addrSpace =
859 (ompd_address_space_handle_t *)PyCapsule_GetPointer(capsule: addrSpaceTup,
860 name: "AddressSpace");
861
862 ompd_size_t sizeof_tid = (ompd_size_t)sizeof(uint64_t);
863 ompd_rc_t retVal = ompd_get_thread_handle(handle: addrSpace, kind: 1, tidSize: sizeof_tid, tid: &threadId,
864 threadHandle: &threadHandle);
865
866 if (retVal == ompd_rc_unavailable) {
867 return Py_BuildValue("i", -1);
868 } else if (retVal != ompd_rc_ok) {
869 _printf(
870 format: "An error occured when calling ompd_get_thread_handle! Error code: %d",
871 retVal);
872 return Py_BuildValue("l", retVal);
873 }
874 return PyCapsule_New(pointer: threadHandle, name: "ThreadHandle",
875 destructor: my_thread_capsule_destructor);
876}
877
878/**
879 * Returns a PyCapsule pointer to a thread handle for a specific thread id in
880 * the current parallel context.
881 */
882static PyObject *call_ompd_get_thread_in_parallel(PyObject *self,
883 PyObject *args) {
884 PyObject *parallelHandlePy = PyTuple_GetItem(args, 0);
885 int threadNum = (int)PyLong_AsLong(PyTuple_GetItem(args, 1));
886 ompd_parallel_handle_t *parallelHandle =
887 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(capsule: parallelHandlePy,
888 name: "ParallelHandle"));
889 ompd_thread_handle_t *threadHandle;
890
891 ompd_rc_t retVal =
892 ompd_get_thread_in_parallel(parallelHandle, threadNum, threadHandle: &threadHandle);
893
894 if (retVal != ompd_rc_ok) {
895 _printf(format: "An error occurred when calling ompd_get_thread_in_parallel! Error "
896 "code: %d",
897 retVal);
898 return Py_BuildValue("l", retVal);
899 }
900 return PyCapsule_New(pointer: threadHandle, name: "ThreadHandle",
901 destructor: my_thread_capsule_destructor);
902}
903
904/**
905 * Returns a PyCapsule pointer to the parallel handle of the current parallel
906 * region associated with a thread.
907 */
908static PyObject *call_ompd_get_curr_parallel_handle(PyObject *self,
909 PyObject *args) {
910 PyObject *threadHandlePy = PyTuple_GetItem(args, 0);
911 ompd_thread_handle_t *threadHandle =
912 (ompd_thread_handle_t *)(PyCapsule_GetPointer(capsule: threadHandlePy,
913 name: "ThreadHandle"));
914 ompd_parallel_handle_t *parallelHandle;
915
916 ompd_rc_t retVal =
917 ompd_get_curr_parallel_handle(threadHandle, parallelHandle: &parallelHandle);
918
919 if (retVal != ompd_rc_ok) {
920 _printf(format: "An error occurred when calling ompd_get_curr_parallel_handle! "
921 "Error code: %d",
922 retVal);
923 return Py_BuildValue("l", retVal);
924 }
925 return PyCapsule_New(pointer: parallelHandle, name: "ParallelHandle",
926 destructor: my_parallel_capsule_destructor);
927}
928
929/**
930 * Returns a PyCapsule pointer to the parallel handle for the parallel region
931 * enclosing the parallel region specified by parallel_handle.
932 */
933static PyObject *call_ompd_get_enclosing_parallel_handle(PyObject *self,
934 PyObject *args) {
935 PyObject *parallelHandlePy = PyTuple_GetItem(args, 0);
936 ompd_parallel_handle_t *parallelHandle =
937 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(capsule: parallelHandlePy,
938 name: "ParallelHandle"));
939 ompd_parallel_handle_t *enclosingParallelHandle;
940
941 ompd_rc_t retVal = ompd_get_enclosing_parallel_handle(
942 parallelHandle, enclosing: &enclosingParallelHandle);
943
944 if (retVal != ompd_rc_ok) {
945 _printf(format: "An error occurred when calling "
946 "ompd_get_enclosing_parallel_handle! Error code: %d",
947 retVal);
948 return Py_BuildValue("l", retVal);
949 }
950 return PyCapsule_New(pointer: enclosingParallelHandle, name: "ParallelHandle",
951 destructor: my_parallel_capsule_destructor);
952}
953
954/**
955 * Returns a PyCapsule pointer to the parallel handle for the parallel region
956 * enclosing the task specified.
957 */
958static PyObject *call_ompd_get_task_parallel_handle(PyObject *self,
959 PyObject *args) {
960 PyObject *taskHandlePy = PyTuple_GetItem(args, 0);
961 ompd_task_handle_t *taskHandle =
962 PyCapsule_GetPointer(capsule: taskHandlePy, name: "TaskHandle");
963 ompd_parallel_handle_t *taskParallelHandle;
964
965 ompd_rc_t retVal =
966 ompd_get_task_parallel_handle(taskHandle, taskParallelHandle: &taskParallelHandle);
967
968 if (retVal != ompd_rc_ok) {
969 _printf(format: "An error occurred when calling ompd_get_task_parallel_handle! "
970 "Error code: %d");
971 return Py_BuildValue("l", retVal);
972 }
973 return PyCapsule_New(pointer: taskParallelHandle, name: "ParallelHandle",
974 destructor: my_parallel_capsule_destructor);
975}
976
977/**
978 * Releases a parallel handle; is called in by the destructor of a Python
979 * parallel_handle object.
980 */
981static PyObject *call_ompd_rel_parallel_handle(PyObject *self, PyObject *args) {
982 PyObject *parallelHandlePy = PyTuple_GetItem(args, 0);
983 ompd_parallel_handle_t *parallelHandle =
984 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(capsule: parallelHandlePy,
985 name: "ParallelHandle"));
986
987 ompd_rc_t retVal = ompd_rel_parallel_handle(parallelHandle);
988 if (retVal != ompd_rc_ok) {
989 _printf(format: "An error occurred when calling ompd_rel_parallel_handle! Error "
990 "code: %d",
991 retVal);
992 }
993 return Py_BuildValue("l", retVal);
994}
995
996/**
997 * Returns a PyCapsule pointer to the task handle of the current task region
998 * associated with a thread.
999 */
1000static PyObject *call_ompd_get_curr_task_handle(PyObject *self,
1001 PyObject *args) {
1002 PyObject *threadHandlePy = PyTuple_GetItem(args, 0);
1003 ompd_thread_handle_t *threadHandle =
1004 (ompd_thread_handle_t *)(PyCapsule_GetPointer(capsule: threadHandlePy,
1005 name: "ThreadHandle"));
1006 ompd_task_handle_t *taskHandle;
1007
1008 ompd_rc_t retVal = ompd_get_curr_task_handle(threadHandle, taskHandle: &taskHandle);
1009
1010 if (retVal != ompd_rc_ok) {
1011 _printf(format: "An error occurred when calling ompd_get_curr_task_handle! Error "
1012 "code: %d",
1013 retVal);
1014 return Py_BuildValue("l", retVal);
1015 }
1016 return PyCapsule_New(pointer: taskHandle, name: "TaskHandle", destructor: my_task_capsule_destructor);
1017}
1018
1019/**
1020 * Returns a task handle for the task that created the task specified.
1021 */
1022static PyObject *call_ompd_get_generating_task_handle(PyObject *self,
1023 PyObject *args) {
1024 PyObject *taskHandlePy = PyTuple_GetItem(args, 0);
1025 ompd_task_handle_t *taskHandle =
1026 (ompd_task_handle_t *)(PyCapsule_GetPointer(capsule: taskHandlePy, name: "TaskHandle"));
1027 ompd_task_handle_t *generatingTaskHandle;
1028
1029 ompd_rc_t retVal =
1030 ompd_get_generating_task_handle(taskHandle, generating: &generatingTaskHandle);
1031
1032 if (retVal != ompd_rc_ok) {
1033 _printf(format: "An error occurred when calling ompd_get_generating_task_handle! "
1034 "Error code: %d",
1035 retVal);
1036 return Py_BuildValue("l", retVal);
1037 }
1038 return PyCapsule_New(pointer: generatingTaskHandle, name: "TaskHandle",
1039 destructor: my_task_capsule_destructor);
1040}
1041
1042/**
1043 * Returns the task handle for the task that scheduled the task specified.
1044 */
1045static PyObject *call_ompd_get_scheduling_task_handle(PyObject *self,
1046 PyObject *args) {
1047 PyObject *taskHandlePy = PyTuple_GetItem(args, 0);
1048 ompd_task_handle_t *taskHandle =
1049 (ompd_task_handle_t *)(PyCapsule_GetPointer(capsule: taskHandlePy, name: "TaskHandle"));
1050 ompd_task_handle_t *schedulingTaskHandle;
1051
1052 ompd_rc_t retVal =
1053 ompd_get_scheduling_task_handle(taskHandle, scheduling: &schedulingTaskHandle);
1054
1055 if (retVal == ompd_rc_unavailable) {
1056 return Py_None;
1057 } else if (retVal != ompd_rc_ok) {
1058 _printf(format: "An error occurred when calling ompd_get_scheduling_task_handle! "
1059 "Error code: %d",
1060 retVal);
1061 return Py_BuildValue("l", retVal);
1062 }
1063 return PyCapsule_New(pointer: schedulingTaskHandle, name: "TaskHandle",
1064 destructor: my_task_capsule_destructor);
1065}
1066
1067/**
1068 * Returns task handles for the implicit tasks associated with a parallel
1069 * region.
1070 */
1071static PyObject *call_ompd_get_task_in_parallel(PyObject *self,
1072 PyObject *args) {
1073 PyObject *parallelHandlePy = PyTuple_GetItem(args, 0);
1074 int threadNum = (int)PyLong_AsLong(PyTuple_GetItem(args, 1));
1075 ompd_parallel_handle_t *parallelHandle =
1076 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(capsule: parallelHandlePy,
1077 name: "ParallelHandle"));
1078 ompd_task_handle_t *taskHandle;
1079
1080 ompd_rc_t retVal =
1081 ompd_get_task_in_parallel(parallelHandle, threadNum, taskHandle: &taskHandle);
1082
1083 if (retVal != ompd_rc_ok) {
1084 _printf(format: "An error occurred when calling ompd_get_task_in_parallel! Error "
1085 "code: %d",
1086 retVal);
1087 return Py_BuildValue("l", retVal);
1088 }
1089 return PyCapsule_New(pointer: taskHandle, name: "TaskHandle", destructor: my_task_capsule_destructor);
1090}
1091
1092/**
1093 * Releases a task handle; is called by the destructor of a Python task_handle
1094 * object.
1095 */
1096static PyObject *call_ompd_rel_task_handle(PyObject *self, PyObject *args) {
1097 PyObject *taskHandlePy = PyTuple_GetItem(args, 0);
1098 ompd_task_handle_t *taskHandle =
1099 (ompd_task_handle_t *)(PyCapsule_GetPointer(capsule: taskHandlePy, name: "TaskHandle"));
1100
1101 ompd_rc_t retVal = ompd_rel_task_handle(taskHandle);
1102 if (retVal != ompd_rc_ok) {
1103 _printf(
1104 format: "An error occurred when calling ompd_rel_task_handle! Error code: %d",
1105 retVal);
1106 }
1107 return Py_BuildValue("l", retVal);
1108}
1109
1110/**
1111 * Calls ompd_get_task_frame and returns a PyCapsule for the enter frame of the
1112 * given task.
1113 */
1114static PyObject *call_ompd_get_task_frame(PyObject *self, PyObject *args) {
1115 PyObject *taskHandlePy = PyTuple_GetItem(args, 0);
1116 ompd_task_handle_t *taskHandle =
1117 (ompd_task_handle_t *)PyCapsule_GetPointer(capsule: taskHandlePy, name: "TaskHandle");
1118 ompd_frame_info_t exitFrameInfo;
1119 ompd_frame_info_t enterFrameInfo;
1120
1121 ompd_rc_t retVal =
1122 ompd_get_task_frame(taskHandle, exitFrame: &exitFrameInfo, enterFrame: &enterFrameInfo);
1123
1124 if (retVal != ompd_rc_ok) {
1125 _printf(
1126 format: "An error occurred when calling ompd_get_task_frame! Error code: %d",
1127 retVal);
1128 return Py_BuildValue("l", retVal);
1129 }
1130
1131 PyObject *result = PyTuple_New(size: 4);
1132 PyTuple_SetItem(
1133 result, 0, PyLong_FromUnsignedLong(enterFrameInfo.frame_address.address));
1134 PyTuple_SetItem(result, 1,
1135 PyLong_FromUnsignedLong(enterFrameInfo.frame_flag));
1136 PyTuple_SetItem(result, 2,
1137 PyLong_FromUnsignedLong(exitFrameInfo.frame_address.address));
1138 PyTuple_SetItem(result, 3, PyLong_FromUnsignedLong(exitFrameInfo.frame_flag));
1139 return result;
1140}
1141
1142/**
1143 * Calls ompd_get_icv_from_scope.
1144 */
1145static PyObject *call_ompd_get_icv_from_scope(PyObject *self, PyObject *args) {
1146 PyObject *addrSpaceHandlePy = PyTuple_GetItem(args, 0);
1147 PyObject *scopePy = PyTuple_GetItem(args, 1);
1148 PyObject *icvIdPy = PyTuple_GetItem(args, 2);
1149
1150 ompd_scope_t scope = (ompd_scope_t)PyLong_AsLong(scopePy);
1151 ompd_address_space_handle_t *addrSpaceHandle;
1152 switch (scope) {
1153 case ompd_scope_thread:
1154 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(
1155 capsule: addrSpaceHandlePy, name: "ThreadHandle");
1156 break;
1157 case ompd_scope_parallel:
1158 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(
1159 capsule: addrSpaceHandlePy, name: "ParallelHandle");
1160 break;
1161 case ompd_scope_implicit_task:
1162 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(
1163 capsule: addrSpaceHandlePy, name: "TaskHandle");
1164 break;
1165 case ompd_scope_task:
1166 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(
1167 capsule: addrSpaceHandlePy, name: "TaskHandle");
1168 break;
1169 default:
1170 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(
1171 capsule: addrSpaceHandlePy, name: "AddressSpace");
1172 break;
1173 }
1174
1175 ompd_icv_id_t icvId = (ompd_icv_id_t)PyLong_AsLong(icvIdPy);
1176 ompd_word_t icvValue;
1177
1178 ompd_rc_t retVal =
1179 ompd_get_icv_from_scope(handle: addrSpaceHandle, scope, icvId, icvValue: &icvValue);
1180
1181 if (retVal != ompd_rc_ok) {
1182 if (retVal != ompd_rc_incomplete) {
1183 _printf(format: "An error occurred when calling ompd_get_icv_from_scope(%i, %i): "
1184 "Error code: %d",
1185 scope, icvId, retVal);
1186 }
1187 return Py_None;
1188 }
1189 return PyLong_FromLong(icvValue);
1190}
1191
1192/**
1193 * Calls ompd_enumerate_icvs.
1194 */
1195static PyObject *call_ompd_enumerate_icvs(PyObject *self, PyObject *args) {
1196 PyObject *addrSpaceHandlePy = PyTuple_GetItem(args, 0);
1197 PyObject *currentPy = PyTuple_GetItem(args, 1);
1198 ompd_icv_id_t current = (ompd_icv_id_t)(PyLong_AsLong(currentPy));
1199 ompd_address_space_handle_t *addrSpaceHandle =
1200 (ompd_address_space_handle_t *)PyCapsule_GetPointer(capsule: addrSpaceHandlePy,
1201 name: "AddressSpace");
1202
1203 const char *nextIcv;
1204 ompd_scope_t nextScope;
1205 int more;
1206 ompd_icv_id_t nextId;
1207
1208 ompd_rc_t retVal = ompd_enumerate_icvs(handle: addrSpaceHandle, current, next: &nextId,
1209 nextIcvName: &nextIcv, nextScope: &nextScope, more: &more);
1210
1211 if (retVal != ompd_rc_ok) {
1212 _printf(
1213 format: "An error occurred when calling ompd_enumerate_icvs! Error code: %d",
1214 retVal);
1215 return Py_None;
1216 }
1217 PyObject *retTuple = PyTuple_New(size: 4);
1218 PyTuple_SetItem(retTuple, 0, PyLong_FromUnsignedLong(nextId));
1219 PyTuple_SetItem(retTuple, 1, PyUnicode_FromString(u: nextIcv));
1220 PyTuple_SetItem(retTuple, 2, PyLong_FromUnsignedLong(nextScope));
1221 PyTuple_SetItem(retTuple, 3, PyLong_FromLong(more));
1222 return retTuple;
1223}
1224
1225/**
1226 * Calls ompd_enumerate_states.
1227 */
1228static PyObject *call_ompd_enumerate_states(PyObject *self, PyObject *args) {
1229 PyObject *addrSpaceHandlePy = PyTuple_GetItem(args, 0);
1230 ompd_address_space_handle_t *addrSpaceHandle =
1231 (ompd_address_space_handle_t *)PyCapsule_GetPointer(capsule: addrSpaceHandlePy,
1232 name: "AddressSpace");
1233 ompd_word_t currentState =
1234 (ompd_word_t)PyLong_AsLong(PyTuple_GetItem(args, 1));
1235
1236 ompd_word_t nextState;
1237 const char *nextStateName;
1238 ompd_word_t moreEnums;
1239
1240 ompd_rc_t retVal = ompd_enumerate_states(
1241 addrSpaceHandle, currentState, nextState: &nextState, nextStateName: &nextStateName, moreEnums: &moreEnums);
1242
1243 if (retVal != ompd_rc_ok) {
1244 _printf(
1245 format: "An error occurred when calling ompd_enumerate_states! Error code: %d",
1246 retVal);
1247 return Py_None;
1248 }
1249 PyObject *retTuple = PyTuple_New(size: 3);
1250 PyTuple_SetItem(retTuple, 0, PyLong_FromLong(nextState));
1251 PyTuple_SetItem(retTuple, 1, PyUnicode_FromString(u: nextStateName));
1252 PyTuple_SetItem(retTuple, 2, PyLong_FromLong(moreEnums));
1253 return retTuple;
1254}
1255
1256/**
1257 * Calls ompd_get_state.
1258 */
1259static PyObject *call_ompd_get_state(PyObject *self, PyObject *args) {
1260 PyObject *threadHandlePy = PyTuple_GetItem(args, 0);
1261 ompd_thread_handle_t *threadHandle =
1262 (ompd_thread_handle_t *)PyCapsule_GetPointer(capsule: threadHandlePy,
1263 name: "ThreadHandle");
1264 ompd_word_t state;
1265 ompd_wait_id_t waitId;
1266
1267 ompd_rc_t retVal = ompd_get_state(threadHandle, state: &state, waitId: &waitId);
1268
1269 if (retVal != ompd_rc_ok) {
1270 _printf(format: "An error occurred when calling ompd_get_state! Error code: %d",
1271 retVal);
1272 return Py_None;
1273 }
1274 PyObject *retTuple = PyTuple_New(size: 2);
1275 PyTuple_SetItem(retTuple, 0, PyLong_FromLong(state));
1276 PyTuple_SetItem(retTuple, 1, PyLong_FromUnsignedLong(waitId));
1277 return retTuple;
1278}
1279
1280/**
1281 * Calls ompd_get_task_function and returns entry point of the code that
1282 * corresponds to the code executed by the task.
1283 */
1284static PyObject *call_ompd_get_task_function(PyObject *self, PyObject *args) {
1285 PyObject *taskHandlePy = PyTuple_GetItem(args, 0);
1286 ompd_task_handle_t *taskHandle =
1287 (ompd_task_handle_t *)PyCapsule_GetPointer(capsule: taskHandlePy, name: "TaskHandle");
1288 ompd_address_t entryPoint;
1289
1290 ompd_rc_t retVal = ompd_get_task_function(taskHandle, entryPoint: &entryPoint);
1291
1292 if (retVal != ompd_rc_ok) {
1293 _printf(
1294 format: "An error occurred when calling ompd_get_task_function! Error code: %d",
1295 retVal);
1296 return Py_None;
1297 }
1298 return PyLong_FromLong((long)entryPoint.address);
1299}
1300
1301/**
1302 * Prints pointer stored inside PyCapusle.
1303 */
1304static PyObject *print_capsule(PyObject *self, PyObject *args) {
1305 PyObject *capsule = PyTuple_GetItem(args, 0);
1306 PyObject *name = PyTuple_GetItem(args, 1);
1307 void *pointer =
1308 PyCapsule_GetPointer(capsule, name: PyUnicode_AsUTF8AndSize(unicode: name, NULL));
1309 _printf(format: "Capsule pointer: %p", pointer);
1310 return Py_None;
1311}
1312
1313/**
1314 * Calls ompd_get_thread_id for given handle and returns the thread id as a
1315 * long.
1316 */
1317static PyObject *call_ompd_get_thread_id(PyObject *self, PyObject *args) {
1318 PyObject *threadHandlePy = PyTuple_GetItem(args, 0);
1319 ompd_thread_handle_t *threadHandle =
1320 (ompd_thread_handle_t *)(PyCapsule_GetPointer(capsule: threadHandlePy,
1321 name: "ThreadHandle"));
1322 ompd_thread_id_t kind = 0; // OMPD_THREAD_ID_PTHREAD
1323 ompd_size_t sizeOfId = (ompd_size_t)sizeof(pthread_t);
1324
1325 uint64_t thread;
1326 ompd_rc_t retVal = ompd_get_thread_id(threadHandle, kind, tidSize: sizeOfId, tid: &thread);
1327
1328 if (retVal != ompd_rc_ok) {
1329 kind = 1; // OMPD_THREAD_ID_LWP
1330 retVal = ompd_get_thread_id(threadHandle, kind, tidSize: sizeOfId, tid: &thread);
1331 if (retVal != ompd_rc_ok) {
1332 _printf(
1333 format: "An error occurred when calling ompd_get_thread_id! Error code: %d",
1334 retVal);
1335 return Py_None;
1336 }
1337 }
1338 return PyLong_FromLong(thread);
1339}
1340
1341/**
1342 * Calls ompd_get_tool_data and returns a tuple containing the value and pointer
1343 * of the ompt_data_t union for the selected scope.
1344 */
1345static PyObject *call_ompd_get_tool_data(PyObject *self, PyObject *args) {
1346 PyObject *scopePy = PyTuple_GetItem(args, 0);
1347 ompd_scope_t scope = (ompd_scope_t)(PyLong_AsLong(scopePy));
1348 PyObject *handlePy = PyTuple_GetItem(args, 1);
1349 void *handle = NULL;
1350
1351 if (scope == 3) {
1352 ompd_thread_handle_t *threadHandle =
1353 (ompd_thread_handle_t *)(PyCapsule_GetPointer(capsule: handlePy,
1354 name: "ThreadHandle"));
1355 handle = threadHandle;
1356 } else if (scope == 4) {
1357 ompd_parallel_handle_t *parallelHandle =
1358 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(capsule: handlePy,
1359 name: "ParallelHandle"));
1360 handle = parallelHandle;
1361 } else if (scope == 5 || scope == 6) {
1362 ompd_task_handle_t *taskHandle =
1363 (ompd_task_handle_t *)(PyCapsule_GetPointer(capsule: handlePy, name: "TaskHandle"));
1364 handle = taskHandle;
1365 } else {
1366 _printf(format: "An error occured when calling ompd_get_tool_data! Scope type not "
1367 "supported.");
1368 return Py_None;
1369 }
1370
1371 ompd_word_t value;
1372 ompd_address_t ptr;
1373
1374 ompd_rc_t retVal = ompd_get_tool_data(handle, scope, value: &value, ptr: &ptr);
1375
1376 if (retVal != ompd_rc_ok) {
1377 _printf(format: "An error occured when calling ompd_get_tool_data! Error code: %d",
1378 retVal);
1379 return Py_None;
1380 }
1381
1382 PyObject *retTuple = PyTuple_New(size: 2);
1383 PyTuple_SetItem(retTuple, 0, PyLong_FromLong(value));
1384 PyTuple_SetItem(retTuple, 1, PyLong_FromLong(ptr.address));
1385 return retTuple;
1386}
1387
1388/** Calls ompd_get_icv_string_from_scope.
1389 */
1390static PyObject *call_ompd_get_icv_string_from_scope(PyObject *self,
1391 PyObject *args) {
1392 PyObject *handlePy = PyTuple_GetItem(args, 0);
1393 PyObject *scopePy = PyTuple_GetItem(args, 1);
1394 PyObject *icvIdPy = PyTuple_GetItem(args, 2);
1395
1396 ompd_scope_t scope = (ompd_scope_t)PyLong_AsLong(scopePy);
1397 void *handle = NULL;
1398 switch (scope) {
1399 case ompd_scope_thread:
1400 handle =
1401 (ompd_thread_handle_t *)PyCapsule_GetPointer(capsule: handlePy, name: "ThreadHandle");
1402 break;
1403 case ompd_scope_parallel:
1404 handle = (ompd_parallel_handle_t *)PyCapsule_GetPointer(capsule: handlePy,
1405 name: "ParallelHandle");
1406 break;
1407 case ompd_scope_implicit_task:
1408 handle = (ompd_task_handle_t *)PyCapsule_GetPointer(capsule: handlePy, name: "TaskHandle");
1409 break;
1410 case ompd_scope_task:
1411 handle = (ompd_task_handle_t *)PyCapsule_GetPointer(capsule: handlePy, name: "TaskHandle");
1412 break;
1413 default:
1414 handle = (ompd_address_space_handle_t *)PyCapsule_GetPointer(
1415 capsule: handlePy, name: "AddressSpace");
1416 break;
1417 }
1418
1419 ompd_icv_id_t icvId = (ompd_icv_id_t)PyLong_AsLong(icvIdPy);
1420 const char *icvString;
1421
1422 ompd_rc_t retVal =
1423 ompd_get_icv_string_from_scope(handle, scope, icvId, icvString: &icvString);
1424
1425 if (retVal != ompd_rc_ok) {
1426 _printf(format: "An error occurred when calling ompd_get_icv_string_from_scope! "
1427 "Error code: %d",
1428 retVal);
1429 return Py_None;
1430 }
1431 return PyUnicode_FromString(u: icvString);
1432}
1433
1434// Prototypes of API test functions.
1435PyObject *test_ompd_get_thread_handle(PyObject *self, PyObject *args);
1436PyObject *test_ompd_get_curr_parallel_handle(PyObject *self, PyObject *args);
1437PyObject *test_ompd_get_thread_in_parallel(PyObject *self, PyObject *args);
1438PyObject *test_ompd_thread_handle_compare(PyObject *self, PyObject *args);
1439PyObject *test_ompd_get_thread_id(PyObject *self, PyObject *args);
1440PyObject *test_ompd_rel_thread_handle(PyObject *self, PyObject *args);
1441PyObject *test_ompd_get_enclosing_parallel_handle(PyObject *self,
1442 PyObject *args);
1443PyObject *test_ompd_parallel_handle_compare(PyObject *self, PyObject *args);
1444PyObject *test_ompd_rel_parallel_handle(PyObject *self, PyObject *args);
1445PyObject *test_ompd_initialize(PyObject *self, PyObject *noargs);
1446PyObject *test_ompd_get_api_version(PyObject *self, PyObject *noargs);
1447PyObject *test_ompd_get_version_string(PyObject *self, PyObject *noargs);
1448PyObject *test_ompd_finalize(PyObject *self, PyObject *noargs);
1449PyObject *test_ompd_process_initialize(PyObject *self, PyObject *noargs);
1450PyObject *test_ompd_device_initialize(PyObject *self, PyObject *noargs);
1451PyObject *test_ompd_rel_address_space_handle(PyObject *self, PyObject *noargs);
1452PyObject *test_ompd_get_omp_version(PyObject *self, PyObject *args);
1453PyObject *test_ompd_get_omp_version_string(PyObject *self, PyObject *args);
1454PyObject *test_ompd_get_curr_task_handle(PyObject *self, PyObject *args);
1455PyObject *test_ompd_get_task_parallel_handle(PyObject *self, PyObject *args);
1456PyObject *test_ompd_get_generating_task_handle(PyObject *self, PyObject *args);
1457PyObject *test_ompd_get_scheduling_task_handle(PyObject *self, PyObject *args);
1458PyObject *test_ompd_get_task_in_parallel(PyObject *self, PyObject *args);
1459PyObject *test_ompd_rel_task_handle(PyObject *self, PyObject *noargs);
1460PyObject *test_ompd_task_handle_compare(PyObject *self, PyObject *args);
1461PyObject *test_ompd_get_task_function(PyObject *self, PyObject *args);
1462PyObject *test_ompd_get_task_frame(PyObject *self, PyObject *args);
1463PyObject *test_ompd_get_state(PyObject *self, PyObject *args);
1464PyObject *test_ompd_get_display_control_vars(PyObject *self, PyObject *args);
1465PyObject *test_ompd_rel_display_control_vars(PyObject *self, PyObject *noargs);
1466PyObject *test_ompd_enumerate_icvs(PyObject *self, PyObject *noargs);
1467PyObject *test_ompd_get_icv_from_scope_with_addr_handle(PyObject *self,
1468 PyObject *noargs);
1469PyObject *test_ompd_get_icv_from_scope_with_thread_handle(PyObject *self,
1470 PyObject *noargs);
1471PyObject *test_ompd_get_icv_from_scope_with_parallel_handle(PyObject *self,
1472 PyObject *noargs);
1473PyObject *test_ompd_get_icv_from_scope_with_task_handle(PyObject *self,
1474 PyObject *noargs);
1475PyObject *test_ompd_get_icv_string_from_scope(PyObject *self, PyObject *noargs);
1476PyObject *test_ompd_get_tool_data(PyObject *self, PyObject *noargs);
1477PyObject *test_ompd_enumerate_states(PyObject *self, PyObject *noargs);
1478/**
1479 * Binds Python function names to C functions.
1480 */
1481static PyMethodDef ompdModule_methods[] = {
1482 {.ml_name: "ompd_open", .ml_meth: ompd_open, METH_VARARGS,
1483 .ml_doc: "Execute dlopen, return OMPD version."},
1484 {"call_ompd_initialize", call_ompd_initialize, METH_NOARGS,
1485 "Initializes OMPD environment and callbacks."},
1486 {"call_ompd_rel_thread_handle", call_ompd_rel_thread_handle, METH_VARARGS,
1487 "Releases a thread handle."},
1488 {"get_thread_handle", get_thread_handle, METH_VARARGS,
1489 "Collects information on threads."},
1490 {"call_ompd_get_thread_in_parallel", call_ompd_get_thread_in_parallel,
1491 METH_VARARGS,
1492 "Obtains handle for a certain thread within parallel region."},
1493 {"call_ompd_get_curr_parallel_handle", call_ompd_get_curr_parallel_handle,
1494 METH_VARARGS,
1495 "Obtains a pointer to the parallel handle for the current parallel "
1496 "region."},
1497 {"call_ompd_get_enclosing_parallel_handle",
1498 call_ompd_get_enclosing_parallel_handle, METH_VARARGS,
1499 "Obtains a pointer to the parallel handle for the parallel region "
1500 "enclosing the parallel region specified."},
1501 {"call_ompd_get_task_parallel_handle", call_ompd_get_task_parallel_handle,
1502 METH_VARARGS,
1503 "Obtains a pointer to the parallel handle for the parallel region "
1504 "enclosing the task region specified."},
1505 {"call_ompd_rel_parallel_handle", call_ompd_rel_parallel_handle,
1506 METH_VARARGS, "Releases a parallel region handle."},
1507 {"call_ompd_get_curr_task_handle", call_ompd_get_curr_task_handle,
1508 METH_VARARGS,
1509 "Obtains a pointer to the task handle for the current task region "
1510 "associated with an OpenMP thread."},
1511 {"call_ompd_get_generating_task_handle",
1512 call_ompd_get_generating_task_handle, METH_VARARGS,
1513 "Obtains a pointer to the task handle for the task that was created when "
1514 "the task handle specified was encountered."},
1515 {"call_ompd_get_scheduling_task_handle",
1516 call_ompd_get_scheduling_task_handle, METH_VARARGS,
1517 "Obtains a pointer to the task handle for the task that scheduled the "
1518 "task specified."},
1519 {"call_ompd_get_task_in_parallel", call_ompd_get_task_in_parallel,
1520 METH_VARARGS,
1521 "Obtains the handle for implicit tasks associated with a parallel "
1522 "region."},
1523 {"call_ompd_rel_task_handle", call_ompd_rel_task_handle, METH_VARARGS,
1524 "Releases a task handle."},
1525 {"call_ompd_get_task_frame", call_ompd_get_task_frame, METH_VARARGS,
1526 "Returns a pointer to the enter and exit frame address and flag of the "
1527 "given task."},
1528 {"call_ompd_enumerate_icvs", call_ompd_enumerate_icvs, METH_VARARGS,
1529 "Saves ICVs in map."},
1530 {"call_ompd_get_icv_from_scope", call_ompd_get_icv_from_scope, METH_VARARGS,
1531 "Gets ICVs from scope."},
1532 {"call_ompd_enumerate_states", call_ompd_enumerate_states, METH_VARARGS,
1533 "Enumerates OMP states."},
1534 {"call_ompd_get_state", call_ompd_get_state, METH_VARARGS,
1535 "Returns state for given thread handle."},
1536 {"call_ompd_get_task_function", call_ompd_get_task_function, METH_VARARGS,
1537 "Returns point of code where task starts executing."},
1538 {"print_capsule", print_capsule, METH_VARARGS, "Print capsule content"},
1539 {"call_ompd_get_thread_id", call_ompd_get_thread_id, METH_VARARGS,
1540 "Maps an OMPD thread handle to a native thread."},
1541 {"call_ompd_get_tool_data", call_ompd_get_tool_data, METH_VARARGS,
1542 "Returns value and pointer of ompd_data_t for given scope and handle."},
1543 {"call_ompd_get_icv_string_from_scope", call_ompd_get_icv_string_from_scope,
1544 METH_VARARGS, "Gets ICV string representation from scope."},
1545
1546 {"test_ompd_get_thread_handle", test_ompd_get_thread_handle, METH_VARARGS,
1547 "Test API ompd_get_thread_handle."},
1548 {"test_ompd_get_curr_parallel_handle", test_ompd_get_curr_parallel_handle,
1549 METH_VARARGS, "Test API test_ompd_get_curr_parallel_handle."},
1550 {"test_ompd_get_thread_in_parallel", test_ompd_get_thread_in_parallel,
1551 METH_VARARGS, "Test API ompd_get_thread_in_parallel."},
1552 {"test_ompd_thread_handle_compare", test_ompd_thread_handle_compare,
1553 METH_VARARGS, "Test API ompd_thread_handle_compare."},
1554 {"test_ompd_get_thread_id", test_ompd_get_thread_id, METH_VARARGS,
1555 "Test API ompd_get_thread_id."},
1556 {"test_ompd_rel_thread_handle", test_ompd_rel_thread_handle, METH_VARARGS,
1557 "Test API ompd_rel_thread_handle."},
1558 {"test_ompd_get_enclosing_parallel_handle",
1559 test_ompd_get_enclosing_parallel_handle, METH_VARARGS,
1560 "Test API ompd_get_enclosing_parallel_handle."},
1561 {"test_ompd_parallel_handle_compare", test_ompd_parallel_handle_compare,
1562 METH_VARARGS, "Test API test_ompd_parallel_handle_compare."},
1563 {"test_ompd_rel_parallel_handle", test_ompd_rel_parallel_handle,
1564 METH_VARARGS, "Test API ompd_rel_parallel_handle."},
1565
1566 {"test_ompd_initialize", test_ompd_initialize, METH_VARARGS,
1567 "Test API ompd_initialize."},
1568 {"test_ompd_get_api_version", test_ompd_get_api_version, METH_VARARGS,
1569 "Test API ompd_get_api_version."},
1570 {"test_ompd_get_version_string", test_ompd_get_version_string, METH_VARARGS,
1571 "Test API ompd_get_version_string."},
1572 {"test_ompd_finalize", test_ompd_finalize, METH_VARARGS,
1573 "Test API ompd_finalize."},
1574 {"test_ompd_process_initialize", test_ompd_process_initialize, METH_VARARGS,
1575 "Test API ompd_process_initialize. "},
1576 {"test_ompd_device_initialize", test_ompd_device_initialize, METH_VARARGS,
1577 "Test API ompd_device_initialize."},
1578 {"test_ompd_rel_address_space_handle", test_ompd_rel_address_space_handle,
1579 METH_VARARGS, "Test API ompd_rel_address_space_handle."},
1580 {"test_ompd_get_omp_version", test_ompd_get_omp_version, METH_VARARGS,
1581 "Test API ompd_get_omp_version."},
1582 {"test_ompd_get_omp_version_string", test_ompd_get_omp_version_string,
1583 METH_VARARGS, "Test API ompd_get_omp_version_string."},
1584
1585 {"test_ompd_get_curr_task_handle", test_ompd_get_curr_task_handle,
1586 METH_VARARGS, "Test API ompd_get_curr_task_handle."},
1587 {"test_ompd_get_task_parallel_handle", test_ompd_get_task_parallel_handle,
1588 METH_VARARGS, "Test API ompd_get_task_parallel_handle."},
1589 {"test_ompd_get_generating_task_handle",
1590 test_ompd_get_generating_task_handle, METH_VARARGS,
1591 "Test API ompd_get_generating_task_handle."},
1592 {"test_ompd_get_scheduling_task_handle",
1593 test_ompd_get_scheduling_task_handle, METH_VARARGS,
1594 "Test API ompd_get_scheduling_task_handle."},
1595 {"test_ompd_get_task_in_parallel", test_ompd_get_task_in_parallel,
1596 METH_VARARGS, "Test API ompd_get_task_in_parallel."},
1597 {"test_ompd_rel_task_handle", test_ompd_rel_task_handle, METH_VARARGS,
1598 "Test API ompd_rel_task_handle."},
1599 {"test_ompd_task_handle_compare", test_ompd_task_handle_compare,
1600 METH_VARARGS, "Test API ompd_task_handle_compare."},
1601 {"test_ompd_get_task_function", test_ompd_get_task_function, METH_VARARGS,
1602 "Test API ompd_get_task_function."},
1603 {"test_ompd_get_task_frame", test_ompd_get_task_frame, METH_VARARGS,
1604 "Test API ompd_get_task_frame."},
1605 {"test_ompd_get_state", test_ompd_get_state, METH_VARARGS,
1606 "Test API ompd_get_state."},
1607 {"test_ompd_get_display_control_vars", test_ompd_get_display_control_vars,
1608 METH_VARARGS, "Test API ompd_get_display_control_vars."},
1609 {"test_ompd_rel_display_control_vars", test_ompd_rel_display_control_vars,
1610 METH_VARARGS, "Test API ompd_rel_display_control_vars."},
1611 {"test_ompd_enumerate_icvs", test_ompd_enumerate_icvs, METH_VARARGS,
1612 "Test API ompd_enumerate_icvs."},
1613 {"test_ompd_get_icv_from_scope_with_addr_handle",
1614 test_ompd_get_icv_from_scope_with_addr_handle, METH_VARARGS,
1615 "Test API ompd_get_icv_from_scope with addr_handle."},
1616 {"test_ompd_get_icv_from_scope_with_thread_handle",
1617 test_ompd_get_icv_from_scope_with_thread_handle, METH_VARARGS,
1618 "Test API ompd_get_icv_from_scope with thread_handle."},
1619 {"test_ompd_get_icv_from_scope_with_parallel_handle",
1620 test_ompd_get_icv_from_scope_with_parallel_handle, METH_VARARGS,
1621 "Test API ompd_get_icv_from_scope with parallel_handle."},
1622 {"test_ompd_get_icv_from_scope_with_task_handle",
1623 test_ompd_get_icv_from_scope_with_task_handle, METH_VARARGS,
1624 "Test API ompd_get_icv_from_scope with task_handle."},
1625 {"test_ompd_get_icv_string_from_scope", test_ompd_get_icv_string_from_scope,
1626 METH_VARARGS, "Test API ompd_get_icv_string_from_scope."},
1627 {"test_ompd_get_tool_data", test_ompd_get_tool_data, METH_VARARGS,
1628 "Test API ompd_get_tool_data."},
1629 {"test_ompd_enumerate_states", test_ompd_enumerate_states, METH_VARARGS,
1630 "Test API ompd_enumerate_states."},
1631 {NULL, NULL, 0, NULL}};
1632
1633/**
1634 * Lets Python initialize module.
1635 */
1636#if PY_MAJOR_VERSION >= 3
1637static struct PyModuleDef moduledef = {
1638 PyModuleDef_HEAD_INIT,
1639 "ompdModule", /* m_name */
1640 "This is a module", /* m_doc */
1641 -1, /* m_size */
1642 ompdModule_methods, /* m_methods */
1643 NULL, /* m_reload */
1644 NULL, /* m_traverse */
1645 NULL, /* m_clear */
1646 NULL, /* m_free */
1647};
1648#endif
1649void PyInit_ompdModule(void) {
1650 // (void) Py_InitModule("ompdModule", ompdModule_methods);
1651 PyModule_Create(&moduledef);
1652}
1653

source code of openmp/libompd/gdb-plugin/ompdModule.c