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 23 void *ompd_library; 24 25 #define OMPD_WEAK_ATTR __attribute__((weak)) 26 27 struct _ompd_aspace_cont { 28 int id; 29 }; 30 struct _ompd_thread_cont { 31 int id; 32 }; 33 ompd_address_space_context_t acontext = {42}; 34 35 PyObject *pModule; 36 37 ompd_rc_t _print(const char *str, int category); 38 39 // NOTE: implement functions to check parameters of OMPD API functions for 40 // correctness 41 OMPD_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(ompd_library, "ompd_get_api_version"); 45 if (dlerror()) { 46 return ompd_rc_error; 47 } 48 } 49 return my_get_api_version(addr); 50 } 51 52 OMPD_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(ompd_library, "ompd_get_version_string"); 56 if (dlerror()) { 57 return ompd_rc_error; 58 } 59 } 60 return my_get_version_string(string); 61 } 62 63 OMPD_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(ompd_library, "ompd_finalize"); 67 if (dlerror()) { 68 return ompd_rc_error; 69 } 70 } 71 return my_ompd_finalize(); 72 } 73 74 OMPD_WEAK_ATTR ompd_rc_t 75 ompd_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(ompd_library, "ompd_process_initialize"); 81 if (dlerror()) { 82 return ompd_rc_error; 83 } 84 } 85 return my_ompd_process_initialize(context, handle); 86 } 87 88 OMPD_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(ompd_library, "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 101 OMPD_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(ompd_library, "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 115 OMPD_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(ompd_library, "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 130 OMPD_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(ompd_library, "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 145 OMPD_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(ompd_library, "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 160 OMPD_WEAK_ATTR ompd_rc_t 161 ompd_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(ompd_library, "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 175 OMPD_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(ompd_library, "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 191 OMPD_WEAK_ATTR ompd_rc_t 192 ompd_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(ompd_library, "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 206 OMPD_WEAK_ATTR ompd_rc_t 207 ompd_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(ompd_library, "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 221 OMPD_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(ompd_library, "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 235 OMPD_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(ompd_library, "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 249 OMPD_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(ompd_library, "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 263 OMPD_WEAK_ATTR ompd_rc_t 264 ompd_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(ompd_library, "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 277 OMPD_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(ompd_library, "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 291 OMPD_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(ompd_library, "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 306 OMPD_WEAK_ATTR ompd_rc_t 307 ompd_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(ompd_library, "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 322 OMPD_WEAK_ATTR ompd_rc_t 323 ompd_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(ompd_library, "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 339 OMPD_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(ompd_library, "ompd_get_state"); 346 if (dlerror()) { 347 return ompd_rc_error; 348 } 349 } 350 return my_get_state(threadHandle, state, waitId); 351 } 352 353 OMPD_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(ompd_library, "ompd_get_task_function"); 359 if (dlerror()) { 360 return ompd_rc_error; 361 } 362 } 363 return my_get_task_function(taskHandle, entryPoint); 364 } 365 366 OMPD_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(ompd_library, "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 380 OMPD_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(ompd_library, "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 394 OMPD_WEAK_ATTR ompd_rc_t 395 ompd_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(ompd_library, "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 409 OMPD_WEAK_ATTR ompd_rc_t 410 ompd_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(ompd_library, "ompd_rel_thread_handle"); 414 if (dlerror()) { 415 return ompd_rc_error; 416 } 417 } 418 return my_release_thread_handle(threadHandle); 419 } 420 421 OMPD_WEAK_ATTR ompd_rc_t 422 ompd_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(ompd_library, "ompd_rel_parallel_handle"); 428 if (dlerror()) { 429 return ompd_rc_error; 430 } 431 } 432 return my_release_parallel_handle(parallelHandle); 433 } 434 435 OMPD_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(ompd_library, "ompd_rel_task_handle"); 439 if (dlerror()) { 440 return ompd_rc_error; 441 } 442 } 443 return my_release_task_handle(taskHandle); 444 } 445 446 OMPD_WEAK_ATTR ompd_rc_t 447 ompd_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(ompd_library, "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 460 OMPD_WEAK_ATTR ompd_rc_t 461 ompd_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(ompd_library, "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 */ 481 static 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(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(&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 */ 506 ompd_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(1); 510 PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", str)); 511 PyObject_CallObject(pFunc, pArgs); 512 Py_XDECREF(pArgs); 513 } 514 Py_XDECREF(pFunc); 515 return ompd_rc_ok; 516 } 517 518 void _printf(char *format, ...) { 519 va_list args; 520 va_start(args, format); 521 char output[1024]; 522 vsnprintf(output, 1024, format, args); 523 va_end(args); 524 _print(output, 0); 525 } 526 527 /** 528 * Capsule destructors for thread, parallel and task handles. 529 */ 530 static void call_ompd_rel_thread_handle_temp(PyObject *capsule) { 531 ompd_thread_handle_t *threadHandle = 532 (ompd_thread_handle_t *)(PyCapsule_GetPointer(capsule, "ThreadHandle")); 533 534 ompd_rc_t retVal = ompd_rel_thread_handle(threadHandle); 535 if (retVal != ompd_rc_ok) { 536 _printf( 537 "An error occurred when calling ompd_rel_thread_handle! Error code: %d", 538 retVal); 539 } 540 } 541 542 static void destroyThreadCapsule(PyObject *capsule) { 543 call_ompd_rel_thread_handle_temp(capsule); 544 } 545 static void (*my_thread_capsule_destructor)(PyObject *) = destroyThreadCapsule; 546 547 static void call_ompd_rel_parallel_handle_temp(PyObject *capsule) { 548 ompd_parallel_handle_t *parallelHandle = 549 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(capsule, 550 "ParallelHandle")); 551 552 ompd_rc_t retVal = ompd_rel_parallel_handle(parallelHandle); 553 if (retVal != ompd_rc_ok) { 554 _printf("An error occurred when calling ompd_rel_parallel_handle! Error " 555 "code: %d", 556 retVal); 557 } 558 } 559 560 static void destroyParallelCapsule(PyObject *capsule) { 561 call_ompd_rel_parallel_handle_temp(capsule); 562 } 563 static void (*my_parallel_capsule_destructor)(PyObject *) = 564 destroyParallelCapsule; 565 566 static void call_ompd_rel_task_handle_temp(PyObject *capsule) { 567 ompd_task_handle_t *taskHandle = 568 (ompd_task_handle_t *)(PyCapsule_GetPointer(capsule, "TaskHandle")); 569 570 ompd_rc_t retVal = ompd_rel_task_handle(taskHandle); 571 if (retVal != ompd_rc_ok) { 572 _printf("An error occurred when calling ompd_rel_task_handle!\n"); 573 } 574 } 575 576 static void destroyTaskCapsule(PyObject *capsule) { 577 call_ompd_rel_task_handle_temp(capsule); 578 } 579 static void (*my_task_capsule_destructor)(PyObject *) = destroyTaskCapsule; 580 581 /** 582 * Release thread handle. Called inside destructor for Python thread_handle 583 * object. 584 */ 585 static 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(threadHandlePy, 589 "ThreadHandle")); 590 591 ompd_rc_t retVal = ompd_rel_thread_handle(threadHandle); 592 if (retVal != ompd_rc_ok) { 593 _printf( 594 "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 */ 603 ompd_rc_t _alloc(ompd_size_t bytes, void **ptr) { 604 if (ptr == NULL) { 605 return ompd_rc_bad_input; 606 } 607 *ptr = malloc(bytes); 608 return ompd_rc_ok; 609 } 610 611 /** 612 * Free memory in the debugger's address space. 613 */ 614 ompd_rc_t _free(void *ptr) { 615 free(ptr); 616 return ompd_rc_ok; 617 } 618 619 /** 620 * Look up the sizes of primitive types in the target. 621 */ 622 ompd_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 */ 638 ompd_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(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(pFunc, 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 */ 669 ompd_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(2); 679 PyTuple_SetItem(pArgs, 0, Py_BuildValue("l", readMem)); 680 PyTuple_SetItem(pArgs, 1, Py_BuildValue("l", nbytes)); 681 PyObject *retArray = PyObject_CallObject(pFunc, 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(buffer, strBuf, nbytes); 695 Py_XDECREF(retArray); 696 } 697 Py_XDECREF(pFunc); 698 return ompd_rc_ok; 699 } 700 701 /** 702 * Reads string from target. 703 */ 704 ompd_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(1); 714 PyTuple_SetItem(pArgs, 0, Py_BuildValue("l", readMem)); 715 PyObject *retString = PyObject_CallObject(pFunc, 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(retString, &retSize); 722 if ((ompd_size_t)retSize + 1 >= nbytes) { 723 retVal = ompd_rc_incomplete; 724 } 725 strncpy(buffer, strbuffer, nbytes); 726 ((char *)buffer)[nbytes - 1] = '\0'; 727 return retVal; 728 } 729 730 /** 731 * Write memory from the target. 732 */ 733 ompd_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(output, input, 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 */ 749 ompd_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 * 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(tc, 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 */ 773 ompd_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 = *(uint64_t *)thread_id; 787 else if (sizeof(long int) >= 4 && sizeof_thread_id == 4) 788 tid = *(uint32_t *)thread_id; 789 else if (sizeof(long int) >= 2 && sizeof_thread_id == 2) 790 tid = *(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(2); 796 PyTuple_SetItem(pArgs, 0, Py_BuildValue("l", kind)); 797 PyTuple_SetItem(pArgs, 1, Py_BuildValue("l", tid)); 798 PyObject *res = PyObject_CallObject(pFunc, 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(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 */ 820 static PyObject *call_ompd_initialize(PyObject *self, PyObject *noargs) { 821 pModule = PyImport_Import(PyUnicode_FromString("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(ompd_library, "ompd_initialize"); 829 ompd_rc_t returnInit = my_ompd_init(201811, &table); 830 if (returnInit != ompd_rc_ok) { 831 _printf("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(ompd_library, "ompd_process_initialize"); 838 ompd_rc_t retProcInit = my_proc_init(&acontext, &addr_space); 839 if (retProcInit != ompd_rc_ok) { 840 _printf("An error occurred when calling ompd_process_initialize! Error " 841 "code: %d", 842 retProcInit); 843 } 844 return PyCapsule_New(addr_space, "AddressSpace", NULL); 845 } 846 847 /** 848 * Returns a PyCapsule pointer to thread handle for thread with the given id. 849 */ 850 static 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(addrSpaceTup, 860 "AddressSpace"); 861 862 ompd_size_t sizeof_tid = (ompd_size_t)sizeof(uint64_t); 863 ompd_rc_t retVal = ompd_get_thread_handle(addrSpace, 1, sizeof_tid, &threadId, 864 &threadHandle); 865 866 if (retVal == ompd_rc_unavailable) { 867 return Py_BuildValue("i", -1); 868 } else if (retVal != ompd_rc_ok) { 869 _printf( 870 "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(threadHandle, "ThreadHandle", 875 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 */ 882 static 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(parallelHandlePy, 888 "ParallelHandle")); 889 ompd_thread_handle_t *threadHandle; 890 891 ompd_rc_t retVal = 892 ompd_get_thread_in_parallel(parallelHandle, threadNum, &threadHandle); 893 894 if (retVal != ompd_rc_ok) { 895 _printf("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(threadHandle, "ThreadHandle", 901 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 */ 908 static 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(threadHandlePy, 913 "ThreadHandle")); 914 ompd_parallel_handle_t *parallelHandle; 915 916 ompd_rc_t retVal = 917 ompd_get_curr_parallel_handle(threadHandle, ¶llelHandle); 918 919 if (retVal != ompd_rc_ok) { 920 _printf("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(parallelHandle, "ParallelHandle", 926 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 */ 933 static 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(parallelHandlePy, 938 "ParallelHandle")); 939 ompd_parallel_handle_t *enclosingParallelHandle; 940 941 ompd_rc_t retVal = ompd_get_enclosing_parallel_handle( 942 parallelHandle, &enclosingParallelHandle); 943 944 if (retVal != ompd_rc_ok) { 945 _printf("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(enclosingParallelHandle, "ParallelHandle", 951 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 */ 958 static 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(taskHandlePy, "TaskHandle"); 963 ompd_parallel_handle_t *taskParallelHandle; 964 965 ompd_rc_t retVal = 966 ompd_get_task_parallel_handle(taskHandle, &taskParallelHandle); 967 968 if (retVal != ompd_rc_ok) { 969 _printf("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(taskParallelHandle, "ParallelHandle", 974 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 */ 981 static 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(parallelHandlePy, 985 "ParallelHandle")); 986 987 ompd_rc_t retVal = ompd_rel_parallel_handle(parallelHandle); 988 if (retVal != ompd_rc_ok) { 989 _printf("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 */ 1000 static 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(threadHandlePy, 1005 "ThreadHandle")); 1006 ompd_task_handle_t *taskHandle; 1007 1008 ompd_rc_t retVal = ompd_get_curr_task_handle(threadHandle, &taskHandle); 1009 1010 if (retVal != ompd_rc_ok) { 1011 _printf("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(taskHandle, "TaskHandle", my_task_capsule_destructor); 1017 } 1018 1019 /** 1020 * Returns a task handle for the task that created the task specified. 1021 */ 1022 static 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(taskHandlePy, "TaskHandle")); 1027 ompd_task_handle_t *generatingTaskHandle; 1028 1029 ompd_rc_t retVal = 1030 ompd_get_generating_task_handle(taskHandle, &generatingTaskHandle); 1031 1032 if (retVal != ompd_rc_ok) { 1033 _printf("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(generatingTaskHandle, "TaskHandle", 1039 my_task_capsule_destructor); 1040 } 1041 1042 /** 1043 * Returns the task handle for the task that scheduled the task specified. 1044 */ 1045 static 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(taskHandlePy, "TaskHandle")); 1050 ompd_task_handle_t *schedulingTaskHandle; 1051 1052 ompd_rc_t retVal = 1053 ompd_get_scheduling_task_handle(taskHandle, &schedulingTaskHandle); 1054 1055 if (retVal == ompd_rc_unavailable) { 1056 return Py_None; 1057 } else if (retVal != ompd_rc_ok) { 1058 _printf("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(schedulingTaskHandle, "TaskHandle", 1064 my_task_capsule_destructor); 1065 } 1066 1067 /** 1068 * Returns task handles for the implicit tasks associated with a parallel 1069 * region. 1070 */ 1071 static 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(parallelHandlePy, 1077 "ParallelHandle")); 1078 ompd_task_handle_t *taskHandle; 1079 1080 ompd_rc_t retVal = 1081 ompd_get_task_in_parallel(parallelHandle, threadNum, &taskHandle); 1082 1083 if (retVal != ompd_rc_ok) { 1084 _printf("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(taskHandle, "TaskHandle", 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 */ 1096 static 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(taskHandlePy, "TaskHandle")); 1100 1101 ompd_rc_t retVal = ompd_rel_task_handle(taskHandle); 1102 if (retVal != ompd_rc_ok) { 1103 _printf( 1104 "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 */ 1114 static 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(taskHandlePy, "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, &exitFrameInfo, &enterFrameInfo); 1123 1124 if (retVal != ompd_rc_ok) { 1125 _printf( 1126 "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(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 */ 1145 static 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 addrSpaceHandlePy, "ThreadHandle"); 1156 break; 1157 case ompd_scope_parallel: 1158 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer( 1159 addrSpaceHandlePy, "ParallelHandle"); 1160 break; 1161 case ompd_scope_implicit_task: 1162 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer( 1163 addrSpaceHandlePy, "TaskHandle"); 1164 break; 1165 case ompd_scope_task: 1166 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer( 1167 addrSpaceHandlePy, "TaskHandle"); 1168 break; 1169 default: 1170 addrSpaceHandle = (ompd_address_space_handle_t *)PyCapsule_GetPointer( 1171 addrSpaceHandlePy, "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(addrSpaceHandle, scope, icvId, &icvValue); 1180 1181 if (retVal != ompd_rc_ok) { 1182 if (retVal != ompd_rc_incomplete) { 1183 _printf("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 */ 1195 static 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(addrSpaceHandlePy, 1201 "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(addrSpaceHandle, current, &nextId, 1209 &nextIcv, &nextScope, &more); 1210 1211 if (retVal != ompd_rc_ok) { 1212 _printf( 1213 "An error occurred when calling ompd_enumerate_icvs! Error code: %d", 1214 retVal); 1215 return Py_None; 1216 } 1217 PyObject *retTuple = PyTuple_New(4); 1218 PyTuple_SetItem(retTuple, 0, PyLong_FromUnsignedLong(nextId)); 1219 PyTuple_SetItem(retTuple, 1, PyUnicode_FromString(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 */ 1228 static 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(addrSpaceHandlePy, 1232 "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, &nextStateName, &moreEnums); 1242 1243 if (retVal != ompd_rc_ok) { 1244 _printf( 1245 "An error occurred when calling ompd_enumerate_states! Error code: %d", 1246 retVal); 1247 return Py_None; 1248 } 1249 PyObject *retTuple = PyTuple_New(3); 1250 PyTuple_SetItem(retTuple, 0, PyLong_FromLong(nextState)); 1251 PyTuple_SetItem(retTuple, 1, PyUnicode_FromString(nextStateName)); 1252 PyTuple_SetItem(retTuple, 2, PyLong_FromLong(moreEnums)); 1253 return retTuple; 1254 } 1255 1256 /** 1257 * Calls ompd_get_state. 1258 */ 1259 static 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(threadHandlePy, 1263 "ThreadHandle"); 1264 ompd_word_t state; 1265 ompd_wait_id_t waitId; 1266 1267 ompd_rc_t retVal = ompd_get_state(threadHandle, &state, &waitId); 1268 1269 if (retVal != ompd_rc_ok) { 1270 _printf("An error occurred when calling ompd_get_state! Error code: %d", 1271 retVal); 1272 return Py_None; 1273 } 1274 PyObject *retTuple = PyTuple_New(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 */ 1284 static 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(taskHandlePy, "TaskHandle"); 1288 ompd_address_t entryPoint; 1289 1290 ompd_rc_t retVal = ompd_get_task_function(taskHandle, &entryPoint); 1291 1292 if (retVal != ompd_rc_ok) { 1293 _printf( 1294 "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 */ 1304 static 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, PyUnicode_AsUTF8AndSize(name, NULL)); 1309 _printf("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 */ 1317 static 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(threadHandlePy, 1321 "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, sizeOfId, &thread); 1327 1328 if (retVal != ompd_rc_ok) { 1329 kind = 1; // OMPD_THREAD_ID_LWP 1330 retVal = ompd_get_thread_id(threadHandle, kind, sizeOfId, &thread); 1331 if (retVal != ompd_rc_ok) { 1332 _printf( 1333 "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 */ 1345 static 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(handlePy, 1354 "ThreadHandle")); 1355 handle = threadHandle; 1356 } else if (scope == 4) { 1357 ompd_parallel_handle_t *parallelHandle = 1358 (ompd_parallel_handle_t *)(PyCapsule_GetPointer(handlePy, 1359 "ParallelHandle")); 1360 handle = parallelHandle; 1361 } else if (scope == 5 || scope == 6) { 1362 ompd_task_handle_t *taskHandle = 1363 (ompd_task_handle_t *)(PyCapsule_GetPointer(handlePy, "TaskHandle")); 1364 handle = taskHandle; 1365 } else { 1366 _printf("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, &ptr); 1375 1376 if (retVal != ompd_rc_ok) { 1377 _printf("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(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 */ 1390 static 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(handlePy, "ThreadHandle"); 1402 break; 1403 case ompd_scope_parallel: 1404 handle = (ompd_parallel_handle_t *)PyCapsule_GetPointer(handlePy, 1405 "ParallelHandle"); 1406 break; 1407 case ompd_scope_implicit_task: 1408 handle = (ompd_task_handle_t *)PyCapsule_GetPointer(handlePy, "TaskHandle"); 1409 break; 1410 case ompd_scope_task: 1411 handle = (ompd_task_handle_t *)PyCapsule_GetPointer(handlePy, "TaskHandle"); 1412 break; 1413 default: 1414 handle = (ompd_address_space_handle_t *)PyCapsule_GetPointer( 1415 handlePy, "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); 1424 1425 if (retVal != ompd_rc_ok) { 1426 _printf("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(icvString); 1432 } 1433 1434 // Prototypes of API test functions. 1435 PyObject *test_ompd_get_thread_handle(PyObject *self, PyObject *args); 1436 PyObject *test_ompd_get_curr_parallel_handle(PyObject *self, PyObject *args); 1437 PyObject *test_ompd_get_thread_in_parallel(PyObject *self, PyObject *args); 1438 PyObject *test_ompd_thread_handle_compare(PyObject *self, PyObject *args); 1439 PyObject *test_ompd_get_thread_id(PyObject *self, PyObject *args); 1440 PyObject *test_ompd_rel_thread_handle(PyObject *self, PyObject *args); 1441 PyObject *test_ompd_get_enclosing_parallel_handle(PyObject *self, 1442 PyObject *args); 1443 PyObject *test_ompd_parallel_handle_compare(PyObject *self, PyObject *args); 1444 PyObject *test_ompd_rel_parallel_handle(PyObject *self, PyObject *args); 1445 PyObject *test_ompd_initialize(PyObject *self, PyObject *noargs); 1446 PyObject *test_ompd_get_api_version(PyObject *self, PyObject *noargs); 1447 PyObject *test_ompd_get_version_string(PyObject *self, PyObject *noargs); 1448 PyObject *test_ompd_finalize(PyObject *self, PyObject *noargs); 1449 PyObject *test_ompd_process_initialize(PyObject *self, PyObject *noargs); 1450 PyObject *test_ompd_device_initialize(PyObject *self, PyObject *noargs); 1451 PyObject *test_ompd_rel_address_space_handle(PyObject *self, PyObject *noargs); 1452 PyObject *test_ompd_get_omp_version(PyObject *self, PyObject *args); 1453 PyObject *test_ompd_get_omp_version_string(PyObject *self, PyObject *args); 1454 PyObject *test_ompd_get_curr_task_handle(PyObject *self, PyObject *args); 1455 PyObject *test_ompd_get_task_parallel_handle(PyObject *self, PyObject *args); 1456 PyObject *test_ompd_get_generating_task_handle(PyObject *self, PyObject *args); 1457 PyObject *test_ompd_get_scheduling_task_handle(PyObject *self, PyObject *args); 1458 PyObject *test_ompd_get_task_in_parallel(PyObject *self, PyObject *args); 1459 PyObject *test_ompd_rel_task_handle(PyObject *self, PyObject *noargs); 1460 PyObject *test_ompd_task_handle_compare(PyObject *self, PyObject *args); 1461 PyObject *test_ompd_get_task_function(PyObject *self, PyObject *args); 1462 PyObject *test_ompd_get_task_frame(PyObject *self, PyObject *args); 1463 PyObject *test_ompd_get_state(PyObject *self, PyObject *args); 1464 PyObject *test_ompd_get_display_control_vars(PyObject *self, PyObject *args); 1465 PyObject *test_ompd_rel_display_control_vars(PyObject *self, PyObject *noargs); 1466 PyObject *test_ompd_enumerate_icvs(PyObject *self, PyObject *noargs); 1467 PyObject *test_ompd_get_icv_from_scope_with_addr_handle(PyObject *self, 1468 PyObject *noargs); 1469 PyObject *test_ompd_get_icv_from_scope_with_thread_handle(PyObject *self, 1470 PyObject *noargs); 1471 PyObject *test_ompd_get_icv_from_scope_with_parallel_handle(PyObject *self, 1472 PyObject *noargs); 1473 PyObject *test_ompd_get_icv_from_scope_with_task_handle(PyObject *self, 1474 PyObject *noargs); 1475 PyObject *test_ompd_get_icv_string_from_scope(PyObject *self, PyObject *noargs); 1476 PyObject *test_ompd_get_tool_data(PyObject *self, PyObject *noargs); 1477 PyObject *test_ompd_enumerate_states(PyObject *self, PyObject *noargs); 1478 /** 1479 * Binds Python function names to C functions. 1480 */ 1481 static PyMethodDef ompdModule_methods[] = { 1482 {"ompd_open", ompd_open, METH_VARARGS, 1483 "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 1637 static 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 1649 void PyInit_ompdModule(void) { 1650 // (void) Py_InitModule("ompdModule", ompdModule_methods); 1651 PyModule_Create(&moduledef); 1652 } 1653