5

I'm trying to interface OpenMP with another language that emits C code (a C code generator). From my perspective (I'm not the designer of the other language), it will be easiest to do this by calling a C function or function-like macro instead of using #pragma or _Pragma directly. I do not have much experience with the C preprocessor, but I have gotten a simple example found on wikipedia to work in a non-satisfactory way. Here is the original C example:

#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;
}

Now here is where I create a macro (pragma_omp_parallel_private) to do what I want:

#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;
}

The preprocessor will emit an error, but if I actually compile the preprocessed code, it works as expected. Is there a more legit way to accomplish this (not to mention a way that wouldn't cause build errors in most build pipelines)?

$ 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
bbarker
  • 11,636
  • 9
  • 38
  • 62
  • 1
    I tried to answer your direct question below. Anyhow I am curious why you need such a machinery in the first place. – Massimiliano May 07 '14 at 18:34
  • Thanks, this worked! The reason seems to be that the language does not allow inlining of C code at specific locations; it will either be placed at the top, bottom, or an unspecified location depending on the mechanism used. But, it does support calling C functions or macros (inlining: http://bit.ly/1kMoZ2o; C function calling: http://bit.ly/1uBAd0g). – bbarker May 07 '14 at 19:03
  • I see... you want to use an open/close macro to define a parallel region in the generated C code. Well, happy hacking! :-) – Massimiliano May 07 '14 at 19:32

1 Answers1

2

I would concatenate the pragma before turning it to a string literal. Something like this:

#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;
}
Massimiliano
  • 7,842
  • 2
  • 47
  • 62
  • 1
    Good answer. See http://stackoverflow.com/questions/3030099/c-c-pragma-in-define-macro for an explanation of `_Pragma`. – pburka May 08 '14 at 13:28