openMP conditional pragma “if else”

可紊 提交于 2019-12-10 02:20:10

问题


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?


回答1:


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.




回答2:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!