Ошибка при использовании плана FFTW как threadprivate - PullRequest
0 голосов
/ 03 августа 2020

Я пытаюсь использовать OpenMP в коде, выполняющем сложную алгебру с использованием операций FFTW. Каждый поток должен работать отдельно, используя свои собственные рабочие массивы. Поэтому я последовал этому ответу ( Повторно используемые частные динамически выделяемые массивы в OpenMP ) и попытался использовать функциональность threadprivate. Планы FFTW и переменные рабочей области необходимо многократно использовать в коде в нескольких параллельных сегментах.

Ниже приведен тестовый код. Однако он выдает всевозможные ошибки (ошибки сегментации и т. Д. c.) В строке p1=fftw_plan_ .... Есть идеи, что я делаю неправильно? Кажется, это хорошо работает только с массивами, но не работает для плана FFTW. Может ли план FFTW совместно использоваться потоками, но работать с их отдельными сегментами данных inpd, outc1, outc2?

#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, частными для разных потоков.

1 Ответ

0 голосов
/ 03 августа 2020

Извините, в разделе о безопасности потоков в руководстве по 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);
        }
...