この質問は、OpenMP 3.0のタスク構造とC++の暗黙的なfirstprivateの使用に固有です。私は問題の説明と可能な解決策を探しています。OpenMPタスクによるインスタンス変数(暗黙のfirstprivate)にアクセスする際のセグメンテーションフォルト
私が取り組んでいるプログラムでは、いくつかのセグメンテーション違反がありました。私は次のテストケースに問題を減らすことができました。私はインスタンス変数にアクセスしていますので、私はGCC 4.5以降でプログラムをコンパイルして実行すると
問題は、タスク機能をサポートするバージョン(#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;
}
内から(オブジェクトAの)発生しますOpenMPで)gcc -fopenmp myprogram.cpp
それは正常に動作します。しかし、私がコンパイルして、インテルのC++コンパイラ(タスク機能もサポートしているバージョン)でプログラムを実行すると、icpc -openmp myprogram.cpp
というセグメンテーションが発生します。
GCCの出力:
The value of the someInstanceVariable = 0
The value of the someInstanceVariable = 1
...
ICPCの出力:
Segmentation fault
私はそれらの少なくとも1つが間違ってなければならないことを想定しています。私の具体的な質問:
- 何が原因ですか?それは
#pragma omp task
にsomeInstanceVariable
を使用していて、このポインタへの暗黙的な第1のプライベート参照を引き起こしているからですか? - これについて語るOpenMP 3.0 specの特定のセクションに誰かが指摘できますか?私は、ローカル変数に
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; } } }
を作成することで問題を解決できることを知っている
は、一時変数を作成することなく、そこに他の方法はありますか?
「変数」という用語の定義を指定する関連セクションを指摘できますか?クラスオブジェクトの説明に最も近いのは、93ページのセクション2.9.3.4です。「構造体の配列としての別の変数の一部である変数はfirstprivate節に現れません」と書かれています。しかし、私はfirstprivate句で何も明示的に指定しなかったので、コンパイラは自動的にリファレンスを作成しました(誤っているように見えますが)。なぜコンパイラは処理するのではなく、エラーを通知するだけでしたか?私が誤解している何か他のものがありますか? – vazexqi
@vazexqi私は現在、同様の問題を扱っています。この問題にあなたの説明/解決策を教えてください。 OpenMPでクラスオブジェクトを処理する方法は私にはまだ分かりません。 – Callahan