2012-02-16 33 views
0

私はC++でOpenMPを使っている初心者です。私はforループを使って2つの配列をロードする、単純な関数を実行していました。これらの配列は複合体として定義されています。私はコンパイルするときOpenMPを使用した複雑なタイプ

#include <omp.h> 
#include <iostream> 
#include <stdlib.h> 
#include <complex> 
#define CHUNKSIZE 10 
#define N  100 

using namespace std; 

int main (int argc, char *argv[]) 
{ 
int nthreads, tid, i, chunk; 
complex<double> a[N], b[N], c[N]; 

/* Some initializations */ 
for (i=0; i < N; i++) 
    a[i].real() = b[i].real() = i * 1.0; 
chunk = CHUNKSIZE; 

#pragma omp parallel shared(a,b,c,nthreads,chunk) private(i,tid) 
{ 
    tid = omp_get_thread_num(); 
    if (tid == 0) 
    { 
     nthreads = omp_get_num_threads(); 
     printf("Number of threads = %d\n", nthreads); 
    } 
    printf("Thread %d starting...\n",tid); 

#pragma omp for schedule(dynamic,chunk) 
    for (i=0; i<N; i++) 
    { 
     c[i] = a[i] + b[i]; 
     printf("Thread %d: c[%d]= %e\n",tid,i,c[i]); 
    } 

} /* end of parallel section */ 

} 

、私はこの警告を得る:

omp_complex.cpp:43:警告:を通じて非PODタイプ「構造体のstd ::コンプレックス」のオブジェクトを渡すことはできません「...」;実行時にコールが中止されます

私がa.outを実行すると、画面に「Illegal instruction」というメッセージが表示されます。私は何が起こっているのかを調べようとしていましたが、私は良い参考文献を見つけられませんでした。複雑な型がOpenMPディレクティブで許可されているかどうかは誰にも分かりますか?

+0

これはOpenMPとはまったく関係がありません。次回は、問題を最小限に抑えるためにコードを減らしてください! –

答えて

4

エラーはここにある:

printf("Thread %d: c[%d]= %e\n",tid,i,c[i]); 

printfstd::complexを処理する方法を知っている(と知る方法はありません)しません。複雑な型を出力するには、C++ストリーミング操作を使用します。

さらに、並行性の問題を避けるためには、stdoutに書き込む前にスレッドローカルバッファにストリームする必要があります。そうしないと、C++ストリーミング構文が競合条件を作成します。

私は通常、そのためにマクロを使用する(ただし、C++ 11は、可変引数テンプレートと、これが容易になります)

#define THREAD_SAFE_OUT(out, message) \ 
    do { \ 
     std::ostringstream buffer; \ 
     buffer << message; \ 
     out << buffer.str(); \ 
    while (false) 

… 

THREAD_SAFE_OUT(std::cout, "Thread " << tid << ": c[" << i << "] = " << c[i]); 

のOpenMPを使用してスタイルの単語を:

しないでくださいprivateディレクティブを使用してください。これは、メソッドの最初にすべての変数を宣言する必要がある言語の回避策に過ぎません。 C++はこれを強制するものではないので、最初に使用するときに変数を宣言する方が良いです(つまり、の内部)パラレルセクションです。そうすれば、スレッドプライベートでもあります。

+0

ありがとうございました。これが問題です。実際には、私は他のコードで別のコードを持っていました。私はこの単純なプログラムを書いて、私は同様のエラーがあると思っていました。 – AlexNoir

+0

回答をお寄せいただきありがとうございます。プライベートディレクティブを使用していない私も持っていた大きな問題を修正します。素晴らしいアドバイス! – AlexNoir

2

問題がstd::complex<double>printfに渡しています。これは、コンパイラが指示するように、動作しません。とにかくそれをどのように表示したいのですか?

実数部と虚数部を別々に印刷するか、必要に応じてノルムと位相を印刷する必要があります。

+0

ありがとうございました。これが問題です。実際には、私は他のコードで別のコードを持っていました。私はこの単純なプログラムを書いて、私は同様のエラーがあると思っていました。 – AlexNoir

関連する問題