- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all,
I'm new to this world of MIC and OpenMP. I'm trying to write a simple multithreaded program that uses a lock and it seems to give me a segmentation fault.
The code:
#include <stdio.h> #include <omp.h> __attribute__((target(mic))) int chk_target() { int retval; #ifdef __MIC__ retval = 1; #else retval = 0; #endif // Return 1 if target available return retval; } int main() { omp_lock_t lck; int id; int mic_ok; omp_init_lock(&lck); #pragma offload target(mic) #pragma omp parallel num_threads(2) private(id) shared(lck) { mic_ok = chk_target(); if (mic_ok == 0) { printf("Error offloading to MIC!\n"); } else { printf("MIC found and running!\n"); } id = omp_get_thread_num(); omp_set_lock(&lck); /* only one thread at a time can execute this printf */ printf("My thread id is %d.\n", id); omp_unset_lock(&lck); } omp_destroy_lock(&lck); return 0; }
Compilation command:
icc -qopenmp <filename> -o <output_filename>
The output:
offload error: process on the device 0 was terminated by signal 11 (SIGSEGV)
When the same code is run on the host, it runs fine without issue.
Would love to get some help to start me up on this subject :)
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try keeping the context of the lock exclusively within the scope of the offload. IOW, move the #pragma offload above the omp_init_lock and encapsulate the omp_init_lock/omp_destroy_lock within the scope of the offload.
Something like this works:
#pragma offload target(mic) { omp_init_lock(&lck); #pragma omp parallel num_threads(2) private(id) shared(lck) { mic_ok = chk_target(); if (mic_ok == 0) { printf("Error offloading to MIC!\n"); } else { printf("MIC found and running!\n"); } id = omp_get_thread_num(); omp_set_lock(&lck); /* only one thread at a time can execute this printf */ printf("My thread id is %d.\n", id); omp_unset_lock(&lck); } omp_destroy_lock(&lck); } // end pragma offload
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Try keeping the context of the lock exclusively within the scope of the offload. IOW, move the #pragma offload above the omp_init_lock and encapsulate the omp_init_lock/omp_destroy_lock within the scope of the offload.
Something like this works:
#pragma offload target(mic) { omp_init_lock(&lck); #pragma omp parallel num_threads(2) private(id) shared(lck) { mic_ok = chk_target(); if (mic_ok == 0) { printf("Error offloading to MIC!\n"); } else { printf("MIC found and running!\n"); } id = omp_get_thread_num(); omp_set_lock(&lck); /* only one thread at a time can execute this printf */ printf("My thread id is %d.\n", id); omp_unset_lock(&lck); } omp_destroy_lock(&lck); } // end pragma offload
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, that did it :)
Can you explain why there's a difference?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The omp_lock_t is an opaque object (struct) and may not necessarily be copy able as POD from outside the offload to inside the offload via shared(lck).
You also have a race condition in that mic_ok is not declared as private. This race condition is benign because all threads inside the offload parallel region ought to return the same value.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Many thanks! :)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jim Dempsey is correct. The omp_lock_t may contain a pointer to additional information, in which case it cannot be copied between address spaces.
The wider point is that if you're writing C/C++ and using OpenMP it is very helpful to follow the practice of declaring variables in the smallest possible scope. (I find this good practice anyway, but it particularly helps OpenMP since it often removes the need for private or firstprivate annotations which are easy to forget).
P.S. if your code is really all you're trying to do, there's no need to use an explicit lock. you could write the guarded printf using omp critical and do away with all of the lock manipulation, something like this
#pragma omp critical { printf("My thread id is %d.\n", id); }

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page