Esta pregunta es específica para la construcción de tareas en OpenMP 3.0 y su uso de firstprivate implícito para C++. Estoy buscando una explicación del problema y también posibles soluciones.Error de segmentación al acceder a una variable de instancia (firstprivate implícita) a través de la tarea de Openmp
Tuve algunos errores de segmentación con un programa en el que estaba trabajando; Logré reducir el problema al siguiente caso de prueba.
El problema se produce porque yo soy el acceso a una variable de instancia (de objeto A) desde dentro de un #pragma omp task
#include <iostream>
#include <omp.h>
using namespace std;
class A {
private:
int someInstanceVariable;
public:
// This is never called
A(int _someInstanceVariable) {
someInstanceVariable = _someInstanceVariable;
}
A(const A& _A) {
cout << "Copy constructor called" << endl;
someInstanceVariable = _A.someInstanceVariable;
}
void simpleTask() {
// This task makes a reference to someInstanceVariable in the current object
#pragma omp task
{
// For access to stdout
#pragma omp critical
{
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This line uses someInstanceVariable and causes a segfault
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
cout << "The value of the someInstanceVariable = " << someInstanceVariable << endl;
}
}
}
};
int main(int argc, char* argv[]) {
#pragma omp parallel
{
#pragma omp single
{
for(int i = 0; i < 10; i++) {
A* temp = new A(i);
temp->simpleTask();
}
}
}
return 0;
}
Cuando compilar y ejecutar el programa con gcc 4.5 o superior (la versión que soporta la función de tarea en OpenMP) es decir gcc -fopenmp myprogram.cpp
funciona bien. Pero cuando compilo y ejecuto el programa con el compilador C++ de Intel (la versión que también admite la función de tarea), es decir, icpc -openmp myprogram.cpp
, segmenta. salida
de GCC:
The value of the someInstanceVariable = 0
The value of the someInstanceVariable = 1
...
salida del CIPC:
Segmentation fault
Estoy asumiendo que al menos uno de ellos debe estar equivocado. Mis preguntas específicas:
- ¿Cuál es la causa del problema? ¿Es porque estoy usando
someInstanceVariable
en el#pragma omp task
y está causando una primera referencia implícita al este puntero? - Mejor aún, ¿alguien podría indicarme la sección específica en el OpenMP 3.0 spec que habla de esto?
sé que puedo solucionar el problema mediante la creación de una variable local
void simpleTask() { // This task makes a reference to someInstanceVariable in the current object #pragma omp task { int tempVariable = this -> someInstanceVariable; // For access to stdout #pragma omp critical { cout << "The value of the someInstanceVariable = " << tempVariable << endl; } } }
¿Hay otras maneras sin crear una variable temporal?
¿Podría señalar la sección correspondiente que especifica la definición del término "variables"? Lo más parecido que pude encontrar a la descripción de objetos de clase es la Sección 2.9.3.4 en la página 93 donde dice "Una variable que es parte de otra variable (como una matriz de estructura) no puede aparecer en una cláusula firstprivate".Sin embargo, como no especifiqué explícitamente nada con una cláusula firstprivate, el compilador automáticamente se encargó de hacer una referencia (aunque erróneamente, parece). ¿Por qué el compilador simplemente no señalizó un error en lugar de proceder? ¿Hay algo más que estoy malentendiendo? – vazexqi
@vazexqi Actualmente estoy lidiando con un problema similar. ¿Podría compartir su explicación/solución a este problema? Todavía no está claro cómo manejar objetos de clase en openMP. – Callahan