Deixando de fora o código não essencial:
double* max_of_two(double *r,double *n);
int npoints = 1000000;
double* xy = (double*)malloc(2*npoints*sizeof(double));
double zero_coord[2] = {0.0,0.0};
double max_coord[2] = {0.0,0.0};
#pragma omp declare reduction\
(takemax:double*:omp_out=max_of_two(omp_out,omp_in)) \
initializer(omp_priv=zero_coord)
#pragma omp parallel for reduction(takemax:max_coord)
for (int i=0; i<npoints; i++) {
max_coord = max_of_two(max_coord,xy+2*i);
}
Isso dá o erro:
error: '#pragma omp declare reduction' initializer refers to variable 'zero_coord' which is not 'omp_priv' nor 'omp_orig'
O que é estranho porque em códigos mais simples eu posso inicializar omp_priv=-1
e tal.
Há vários problemas: OpenMP permite reduzir arrays elemento a elemento. Para arrays de pilha, o compilador quer usar uma operação de redução elemento a elemento e procura uma redução para o tipo
double
. Se você quiser definir a redução em um par de doubles, você deve usar esse tipo.Para esse tipo, você pode simplesmente inicializar com
omp_priv = {0,0}
ouomp_priv = omp_orig
(funciona para o máximo, mas não para o caso geral).O principal motivo para descartar variáveis diferentes de
omp_priv
eomp_orig
é uma questão de escopo de variáveis. Variáveis gerais não são necessariamente visíveis no escopo da inicialização. Se você quiser inicializar a partir de uma variável (global), precisará encapsular a variável em uma função e chamar essa função a partir da cláusula initializerinitializer(init(&omp_priv))
ouinitializer(omp_priv = init())
.O seguinte compila e executa para mim usando gcc e clang: