OpenMP descargando a Nvidia reducción incorrecta

Estoy interesado en descargar el trabajo a la GPU con OpenMP.

El siguiente código da el valor correcto desum en la CPU

//g++ -O3 -Wall foo.cpp -fopenmp
#pragma omp parallel for reduction(+:sum)                                                                                                                                    
for(int i = 0 ; i < 2000000000; i++) sum += i%11;

También funciona en la GPU con OpenACC como este

//g++ -O3 -Wall foo.cpp -fopenacc   
#pragma acc parallel loop reduction(+:sum)                                                                                                                                    
for(int i = 0 ; i < 2000000000; i++) sum += i%11;

nvprof muestra que se ejecuta en la GPU y también es más rápido que OpenMP en la CPU.

Sin embargo, cuando intento descargar a la GPU con OpenMP como este

//g++ -O3 -Wall foo.cpp -fopenmp -fno-stack-protector
#pragma omp target teams distribute parallel for reduction(+:sum)
for(int i = 0 ; i < 2000000000; i++) sum += i%11;

obtiene el resultado incorrecto parasum (solo devuelve cero).nvprof parece mostrar que se ejecuta en la GPU pero es mucho más lento que OpenMP en la CPU.

¿Por qué falla la reducción con OpenMP en la GPU?

Aquí está el código completo que usé para probar esto

#include <stdio.h>
//g++ -O3 -Wall acc2.cpp -fopenmp -fno-stack-protector                                                                                                                           
//sudo nvprof ./a.out                                                                                                                                                            
int main (void) {
  int sum = 0;
  //#pragma omp parallel for reduction(+:sum)                                                                                                                                    
  //#pragma acc parallel loop reduction(+:sum)                                                                                                                                   
  #pragma omp target teams distribute parallel for reduction(+:sum)
  for(int i = 0 ; i < 2000000000; i++) {
    sum += i%11;
  }
  printf("sum = %d\n",sum);
  return 0;
}

Usando GCC 7.2.0, Ubuntu 17.10, junto con gcc-offload-nvptx

Respuestas a la pregunta(1)

Su respuesta a la pregunta