I have a for loop that can be executed using schedule(static)
or schedule(dynamic, 10)
depending on a condition. Currently, My code is not DRY (Don't repeat yourself) enough and to accommodate the previous functionality it has the following repetition:
boolean isDynamic; //can be true or false
if(isDynamic){
#pragma omp parallel for num_threads(thread_count) default(shared) private(...) schedule(dynamic, 10)
for(...){
//for code inside
}
}else{
#pragma omp parallel for num_threads(thread_count) default(shared) private(...) schedule(static)
for(...){
//SAME for code inside, in fact, this is the EXACT same for as before
}
}
After reading these threads, I noticed that openMP has an #if(expression)
pragma:
- OpenMP: conditional use of #pragma
- http://msdn.microsoft.com/en-us/library/5187hzke.aspx
- Choose OpenMP pragma according to condition
- Conditional "pragma omp"
- http://openmp.org/mp-documents/ntu-vanderpas.pdf
But although I've seen many people with my problem, there seems to be lacking a general solution. The best solution is to transform the body of the for loop into a function, and then have the function called, but this solution is not good enough for me.
So I wonder, does OpenMP have an #if(expression) else
sort of pragma?
Something like:
#if(isDynamic )pragma omp parallel for num_threads(thread_count) default(shared)
private(...) schedule(dynamic, 10)
else
pragma omp parallel for num_threads(thread_count) default(shared)
private(...) schedule(static)
Or am I forced to place my for loop body into a separate function and call it that way?
This is an interesting question. Basically, you want to change schedule
policy at runtime. As far as I know, there is no such directive for the current OpenMP.
I had the exactly same problem you did. My solution ended up making the loop body as a function, as you mentioned. Otherwise, you need to use an ugly macro.
However, I also tried to use schedule(runtime)
, which reads the environment variable OMP_SCHEDULE
. So, I changed this environment variable at runtime, but didn't work. It's because OpenMP runtime read this environment only once at the beginning. It may be an implementation-specific issue. So, other implementation may read this environment variable on the fly. You may try this approach.
This is years late, but for this particular case you can use the runtime library to set the schedule at runtime. It is defined in §3.2.12 in OpenMP 4.5:
void omp_set_schedule(omp_sched_t kind, int chunk_size);
typedef enum omp_sched_t {
omp_sched_static = 1,
omp_sched_dynamic = 2,
omp_sched_guided = 3,
omp_sched_auto = 4
} omp_sched_t;
For your case, what you do is:
/* wherever currently isDynamic is set */
if (isDynamic) {
omp_set_schedule(omp_sched_dynamic, 10);
} else {
/* chunk_size < 1 uses default */
omp_set_schedule(static, 0);
}
/* later */
#pragma omp parallel for num_threads(thread_count) default(shared) private(...) schedule(runtime)
for (...) {
/* do a thing */
}
来源:https://stackoverflow.com/questions/15504080/openmp-conditional-pragma-if-else