Можно ли использовать директивы OpenMP в нескольких файлах в программе? - PullRequest
2 голосов
/ 13 апреля 2011

У меня есть программа на C, которая состоит из нескольких файлов .c и нескольких файлов .h.Мне бы хотелось иметь одну директиву #pragma omp parallel (чтобы все потоки создавались только один раз) в основной функции, а затем делать другие вещи OpenMP, такие как #pragma omp for в других файлах.

Однако,Я не могу этого сделать.При компиляции основного файла он жалуется на то, что некоторые переменные, упомянутые в битах private() и shared() директивы #pragma omp parallel, не существуют (чего нет в этом файле - потому что они находятся вдругой файл), и при компиляции другого файла он жалуется, что у меня есть #pragma omp for без вложенного #pragma omp parallel.

Код красиво разделен между файлами, и я не хотел бы, чтобы поставитьвсе это обратно в один файл.Есть ли способ обойти это?

Ответы [ 2 ]

3 голосов
/ 13 апреля 2011

Вы определенно можете:

outer.c:

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

void inner(int n);

int main(int argc, char **argv) {
    int n=15;

    #pragma omp parallel shared(n) num_threads(4)
    {
        inner(n);
    }

    return 0;
}

inner.c:

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

void inner(int n) {
    int thread = omp_get_thread_num();
    printf("%3d: got %d\n", thread, n);

    #pragma omp for
    for  (int i=0;i<n;i++) {
        int newthread=omp_get_thread_num();
        printf("%3d: doing iter %d.\n",newthread,i);
    }
}

и работает:

$ make
gcc -fopenmp -std=c99   -c -o outer.o outer.c
gcc -fopenmp -std=c99   -c -o inner.o inner.c
gcc -o nested outer.o inner.o -fopenmp -std=c99 -lgomp    
$ ./nested 
  3: got 15
  3: doing iter 12.
  3: doing iter 13.
  3: doing iter 14.
  0: got 15
  0: doing iter 0.
  0: doing iter 1.
  0: doing iter 2.
  0: doing iter 3.
  1: got 15
  1: doing iter 4.
  1: doing iter 5.
  1: doing iter 6.
  1: doing iter 7.
  2: got 15
  2: doing iter 8.
  2: doing iter 9.
  2: doing iter 10.
  2: doing iter 11.

Но нет, вы не можете установить атрибуты совместного использования переменных в одной подпрограмме из другой - они просто не находятся в области видимости. Вы не можете установить их общий доступ больше, чем можете установить их значение.

Как только вы запустили (скажем) inner, все там является приватным; Вы должны передать любые общие вещи как общие.

Просто чтобы прояснить этот бит о «всем, что является частным»: вышесказанное ничем не отличается от

    int n=15;

    #pragma omp parallel shared(n) num_threads(4)
    {
        int thread = omp_get_thread_num();
        printf("%3d: got %d\n", thread, n);

        #pragma omp for
        for  (int i=0;i<n;i++) {
            int newthread=omp_get_thread_num();
            printf("%3d: doing iter %d.\n",newthread,i);
        }
    }

, поскольку thread, i и newthread определены внутри параллельного блока - будь то внутри функции или нет - все они обязательно являются частными.

1 голос
/ 13 апреля 2011

Вы пробовали "extern XY", чтобы сделать переменные известными в другом файле?

Разве вы не можете использовать общий заголовок для всех ваших файлов, который объявляет рассматриваемые переменные?

Являются ли они локальными переменными (тогда вы все равно не сможете это сделать)?

...