2016-10-03 51 views
0

我試圖並行以下循環:不同的結果使用OpenMP時和FFTW

#pragma omp parallel for private(j,i,mxy) firstprivate(in,out,p) 
    for(int j = 0; j < Ny; j++) { 
     //  #pragma omp parallel for private(i,mxy) firstprivate(in,my,j) 
     for(int i = 0; i < Nx; i++){ 
      mxy = i + j*Nx; 
      in[i+1] = b_2D[mxy] + I*0.0 ; 
     } 
     fftw_execute(p); 
     for(int i = 0; i < Nx; i++){ 
      mxy = i + j*Nx; 
      b_2D[mxy] = cimag(out[i+1]) ; 
     } 
    } 

我得到一個小的速度,但我不斷收到不同的結果,無論我設置爲私有哪些變量和FIRSTPRIVATE。我相信這是我正確的做法,但是爲什麼我得到的結果與我在系列中運行時不同?

我曾嘗試以下:

fftw_make_planner_thread_safe(); 
fftw_complex *in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); 
fftw_complex *out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); 

#pragma omp parallel private(j,i,mxy) firstprivate(in,out) 
{ 
    fftw_plan p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE); 
    for(j = 0; j < N; j++) 
     in[j] = 0.0; 

#pragma omp for 
    for(j = 0; j < Ny; j++) { 
     for(i = 0; i < Nx; i++) 
      in[i+1] = b_2D[i + j*Nx] + I*0.0; 
     fftw_execute(p); 
     for(i = 0; i < Nx; i++) 
      b_2D[i + j*Nx] = cimag(out[i+1]) ; 
    } 

    fftw_destroy_plan(p); 
} 
fftw_free(in); 
fftw_free(out); 

這給我的錯誤: 「段錯誤:11」:

fftw_make_planner_thread_safe(); 
#pragma omp parallel private(j,i,mxy) 
{ 
    fftw_complex *in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); 
    fftw_complex *out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N); 
    fftw_plan p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE); 
    for(j = 0; j < N; j++) 
     in[j] = 0.0; 

#pragma omp for 
    for(j = 0; j < Ny; j++) { 
     for(i = 0; i < Nx; i++) 
      in[i+1] = b_2D[i + j*Nx] + I*0.0; 
     fftw_execute(p); 
     for(i = 0; i < Nx; i++) 
      b_2D[i + j*Nx] = cimag(out[i+1]) ; 
    } 

    fftw_destroy_plan(p); 
    fftw_free(in); 
    fftw_free(out); 
} 

我得到這個錯誤再次

如果我這個跑:「Segmentation fault:11」 但我再次運行它說:

solver(9674,0x7fff74e22000) malloc: *** error for object 0x7f8d70f00410: double free 
*** set a breakpoint in malloc_error_break to debug 
Abort trap: 6 
+0

爲什麼'i + 1'的'in'和'out'指數? –

+0

輸入和輸出的大小是2 * Nx + 2,其餘輸入爲0.這確保在[0] = 0中 – user906357

+1

您是否構建/安裝了FFTW的線程安全版本?請參閱[本答案](http://stackoverflow.com/a/15013395/253056),其中涵蓋了關於在OpenMP中使用FFTW的相關主題。 –

回答

1

您在所有主題中都使用相同的計劃p調用FFTW。由於該計劃包含輸入和輸出緩衝區的位置(提供給fftw_plan_dft_whatever計劃構造函數的位置),所有併發的fftw_execute調用將使用這些相同的緩衝區而不是私有副本。解決的辦法是建立一個單獨的計劃爲每個線程:

#pragma omp parallel private(j,i,mxy) firstprivate(in,out) 
{ 
    // The following OpenMP construct enforces thread-safety 
    // Remove if the plan constructor is thread-safe 
    #pragma omp critical (plan_ops) 
    fftw_plan my_p = fftw_plan_dft_whatever(..., in, out, ...); 
    // my_p now refers the private in and out arrays 

    #pragma omp for 
    for(int j = 0; j < Ny; j++) { 
     for(int i = 0; i < Nx; i++){ 
      mxy = i + j*Nx; 
      in[i+1] = b_2D[mxy] + I*0.0 ; 
     } 
     fftw_execute(my_p); 
     for(int i = 0; i < Nx; i++){ 
      mxy = i + j*Nx; 
      b_2D[mxy] = cimag(out[i+1]) ; 
     } 
    } 

    // See comment above for the constructor operation 
    #pragma omp critical (plan_ops) 
    fftw_destroy_plan(my_p); 
} 
+0

謝謝您的回答!這導致「Segmentation fault:11」 – user906357

+0

'in'和'out'可能是指針而不是靜態數組。在這種情況下,私人拷貝不是真正的私人拷貝。在計劃構造函數之前分配每個步驟中的私有緩衝區,並在計劃析構函數之後釋放它們。 –

+0

這會導致另一個錯誤,我將發佈編輯以顯示我曾嘗試過的內容 – user906357

0

的根本原因應該是這個patch沒有回遷到FFTW-3.3.5版本,我覺得你應該自己合併的補丁。您也可以參考討論here