使用 FFTW 计划作为 threadprivate 时出错

Getting error when using FFTW plan as threadprivate

我正在尝试在使用 FFTW 运算的代码上使用 OpenMP 来执行一些复杂的代数运算。每个线程都需要使用自己的工作数组单独工作。因此,我遵循了这个答案 ( Reusable private dynamically allocated arrays in OpenMP ) 并尝试使用 threadprivate 功能。 FFTW 计划和工作区变量需要在多个并行段的代码中多次使用。

以下是测试代码。但是,它在 p1=fftw_plan_ ... 行给出了各种错误(分段错误等)。知道我做错了什么吗?这似乎只适用于数组,但不适用于 FFTW 计划。 FFTW 计划是否可以由线程共享但处理它们单独的数据段 inpdoutc1outc2

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
...
#include <math.h>
#include <complex.h>
#include <omp.h>
#include <fftw3.h>

int main(int argc, char *argv[])
{
    int npts2, id;
    
    static double *inpd;
    static fftw_complex *outc1, *outc2;
    static fftw_plan p1, p2;
    static int npts2stat;
    #pragma omp threadprivate(inpd,outc1,outc2,p1,p2,npts2stat)
    
    npts2=1000;
    
    #pragma omp parallel private(id) shared(npts2)
    {
        id=omp_get_thread_num();
        printf("Thread %d: Allocating threadprivate memory \n",id);
        
        npts2stat=npts2;
        
        printf("step1 \n");
        inpd=malloc(sizeof(double)*npts2stat);
        outc1=fftw_malloc(sizeof(fftw_complex)*npts2stat);
        outc2=fftw_malloc(sizeof(fftw_complex)*npts2stat);
        printf("step2 \n");
        // CODE COMPILES FINE BUT STOPS HERE WITH ERROR
        p1=fftw_plan_dft_r2c_1d(npts2stat,inpd,outc1,FFTW_ESTIMATE);
        p2=fftw_plan_dft_1d(npts2stat,outc1,outc2,FFTW_BACKWARD,FFTW_ESTIMATE);
        printf("step3 \n");
    }
    
    // multiple omp parallel segments with different threads doing some calculations on complex numbers using FFTW
    
    #pragma omp parallel private(id)
    {
        id=omp_get_thread_num();
        printf("Thread %d: Deallocating threadprivate memory \n",id);
        free(inpd);
        fftw_free(outc1);
        fftw_free(outc2);
        fftw_destroy_plan(p1);
        fftw_destroy_plan(p2);
    }
}

EDIT1:我似乎已经解决了下面的分段错误问题。但是,如果您有更好的方法来执行此操作,那将很有帮助。例如,我不知道所有线程的单一计划是否足够,因为它作用于不同线程私有的不同数据inpd

抱歉,FFTW 手册中有关线程安全的部分非常清楚地表明 FFTW 规划器一次只能调用一个线程。这似乎已经解决了分段错误问题。

#pragma omp critical
        {
        p1=fftw_plan_dft_r2c_1d(npts2stat,inpd,outc1,FFTW_ESTIMATE);
        p2=fftw_plan_dft_1d(npts2stat,outc1,outc2,FFTW_BACKWARD,FFTW_ESTIMATE);
        }