2010-09-23 21 views
19

¿OpenMP soporta de forma nativa la reducción de una variable que representa una matriz?¿Es posible hacer una reducción en una matriz con openmp?

esto funcionaría algo como lo siguiente ...

float* a = (float*) calloc(4*sizeof(float)); 
omp_set_num_threads(13); 
#pragma omp parallel reduction(+:a) 
for(i=0;i<4;i++){ 
    a[i] += 1; // Thread-local copy of a incremented by something interesting 
} 
// a now contains [13 13 13 13] 

Idealmente, habría algo similar para una OMP paralelo para, y si usted tiene un número suficientemente grande de hilos para que tenga sentido, la acumulación pasaría a través de un árbol binario.

+7

solo en fortran – Anycorn

+1

Puede ser que pueda explicar un poco más lo que quiere hacer exactamente. Proporcionar código de serie podría ayudar. – FFox

+0

Excavando un poco más, parece que "solo en fortran" es la respuesta.Terminé asignando solo una gran matriz de copias locales fuera del ciclo, dejando que los hilos se acumularan en sus propias copias dentro del ciclo for, luego se acumularan en un conjunto global después del ciclo for, aún dentro de la región paralela, dentro de un ciclo sección crítica. –

Respuesta

3

Solo en Fortran en OpenMP 3.0, y probablemente solo con ciertos compiladores.

Ver el último ejemplo (ejemplo 3) en:

http://wikis.sun.com/display/openmp/Fortran+Allocatable+Arrays

+3

Ahora es posible desde OpenMP 4.5; ver la respuesta de Chen Jiang a continuación. Básicamente, debe especificar _las secciones de conjunto_ (vea la Sección 2.4, página 44 de la especificación OpenMP 4.5). Su especificación #pragma se vería así: 'reducción paralela #pragma omp (+: a [: 4])' Tenga cuidado con esto, sin embargo, debe tener en cuenta que cada hilo asignará su propia versión del sección de matriz; si haces esto en arreglos grandes con muchos hilos, podrías hacer que tu memoria explote. –

1

OpenMP no puede realizar reducciones en las variables de tipo de matriz o estructura (ver restrictions).

También es posible que desee leer en private y shared cláusulas. private declara que una variable es privada para cada subproceso, donde shared declara una variable para ser compartida entre todos los subprocesos. También encontré la respuesta a esto question muy útil con respecto a OpenMP y matrices.

3

Ahora es posible reducir la matriz con OpenMP 4.5 para C y C++. He aquí un ejemplo:

#include <iostream> 

int main() 
{ 

    int myArray[6] = {}; 

    #pragma omp parallel for reduction(+:myArray[:6]) 
    for (int i=0; i<50; ++i) 
    { 
    double a = 2.0; // Or something non-trivial justifying the parallelism... 
    for (int n = 0; n<6; ++n) 
    { 
     myArray[n] += a; 
    } 
    } 
    // Print the array elements to see them summed 
    for (int n = 0; n<6; ++n) 
    { 
    std::cout << myArray[n] << " " << std::endl; 
    } 
} 

Salidas:

100 
100 
100 
100 
100 
100 

Compilé esto con GCC 6.2. Puede ver qué versiones de compilador comunes son compatibles con las características de OpenMP 4.5 aquí: http://www.openmp.org/resources/openmp-compilers/

Tenga en cuenta de los comentarios anteriores que si bien esta es una sintaxis conveniente, puede invocar una gran cantidad de transparencias para crear copias de cada sección de matriz para cada subproceso.

0

OpenMP puede realizar esta operación a partir de OpenMP 4.5 y GCC 6.3 (y posiblemente más bajo) lo admite. Un programa de ejemplo se ve de la siguiente manera:

#include <vector> 
#include <iostream> 

int main(){ 
    std::vector<int> vec; 

    #pragma omp declare reduction (merge : std::vector<int> : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end())) 

    #pragma omp parallel for default(none) schedule(static) reduction(merge: vec) 
    for(int i=0;i<100;i++) 
    vec.push_back(i); 

    for(const auto x: vec) 
    std::cout<<x<<"\n"; 

    return 0; 
} 

Tenga en cuenta que omp_outomp_in y son variables especiales y que el tipo de la declare reduction debe coincidir con el vector que está planeando para reducir sucesivamente.

Cuestiones relacionadas