【问题标题】:How to wrap OpenMP directives (#pragmas) as a function or function-like macro?如何将 OpenMP 指令 (#pragmas) 包装为函数或类似函数的宏?
【发布时间】:2014-06-24 19:23:22
【问题描述】:

我正在尝试将 OpenMP 与另一种发出 C 代码的语言(C 代码生成器)连接起来。从我的角度来看(我不是其他语言的设计者),通过调用 C 函数或类似函数的宏而不是直接使用 #pragma 或 _Pragma 来做到这一点是最简单的。我对 C 预处理器没有太多经验,但我在 wikipedia 上找到了一个简单的例子,它以一种不令人满意的方式工作。这是原始的 C 示例:

#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char *argv[]) {
  int th_id, nthreads;
  #pragma omp parallel private(th_id)
  {
    th_id = omp_get_thread_num();
    printf("Hello World from thread %d\n", th_id);
    #pragma omp barrier
    if ( th_id == 0 ) {
      nthreads = omp_get_num_threads();
      printf("There are %d threads\n",nthreads);
    }
  }
  return EXIT_SUCCESS;
}

现在我在这里创建一个宏 (pragma_omp_parallel_private) 来做我想做的事:

#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

#define STR(x) #x
#define STRINGIFY(x) STR(x) 
#define omp_par_pri STRINGIFY(omp parallel private)

char omp_test[] = omp_par_pri;
#define pragma_omp_parallel_private(thread_id)        \
  _Pragma(STRINGIFY(omp parallel private ## (thread_id)))

int main (int argc, char *argv[]) {
  int th_id, nthreads;

  // #pragma omp parallel private(th_id)
  pragma_omp_parallel_private(th_id)
  {
    th_id = omp_get_thread_num();
    printf("Hello World from thread %d\n", th_id);
    #pragma omp barrier
    if ( th_id == 0 ) {
      nthreads = omp_get_num_threads();
      printf("There are %d threads\n",nthreads);
    }
  }
  return EXIT_SUCCESS;
}

预处理器会发出错误,但如果我真的编译预处理代码,它会按预期工作。有没有更合法的方法来实现这一点(更不用说在大多数构建管道中不会导致构建错误的方法)?

$ gcc -E -fopenmp wikiHello.c > wikiHello_pp.c
wikiHello.c:11:34: error: pasting "private" and "(" does not give a valid preprocessing token
   _Pragma(STRINGIFY(omp parallel private ## (thread_id)))
                                  ^
wikiHello.c:17:3: note: in expansion of macro ‘pragma_omp_parallel_private’
   pragma_omp_parallel_private(th_id)
   ^
$ gcc -fopenmp wikiHello_pp.c

$ ./a.exe
Hello World from thread 3
Hello World from thread 6
Hello World from thread 4
Hello World from thread 7
Hello World from thread 1
Hello World from thread 5
Hello World from thread 2
Hello World from thread 0
There are 8 threads

【问题讨论】:

  • 我试图在下面回答您的直接问题。无论如何,我很好奇你为什么首先需要这样的机器。
  • 谢谢,这成功了!原因似乎是该语言不允许在特定位置内联 C 代码。根据所使用的机制,它将被放置在顶部、底部或未指定的位置。但是,它确实支持调用 C 函数或宏(内联:bit.ly/1kMoZ2o;C 函数调用:bit.ly/1uBAd0g)。
  • 我明白了……您想使用打开/关闭宏在生成的 C 代码中定义并行区域。好吧,快乐的黑客! :-)

标签: c macros openmp c-preprocessor


【解决方案1】:

我会在将pragma 转换为字符串文字之前将其连接起来。像这样的:

#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

#define STR(x) #x
#define STRINGIFY(x) STR(x) 
#define CONCATENATE(X,Y) X ( Y )

#define pragma_omp_parallel_private(x) \
  _Pragma( STRINGIFY( CONCATENATE(omp parallel private,x) ) )

int main (int argc, char *argv[]) {
  int th_id, nthreads;

  // #pragma omp parallel private(th_id)
  pragma_omp_parallel_private(th_id)
  {
    th_id = omp_get_thread_num();
    printf("Hello World from thread %d\n", th_id);
    #pragma omp barrier
    if ( th_id == 0 ) {
      nthreads = omp_get_num_threads();
      printf("There are %d threads\n",nthreads);
    }
  }
  return EXIT_SUCCESS;
}

【讨论】:

猜你喜欢
  • 2014-01-05
  • 1970-01-01
  • 2013-01-26
  • 1970-01-01
  • 2020-03-14
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
  • 2013-02-08
相关资源
最近更新 更多