Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parallel processing 使用Fortran的OpenMP FFTW不是线程安全的_Parallel Processing_Fortran_Openmp_Fftw - Fatal编程技术网

Parallel processing 使用Fortran的OpenMP FFTW不是线程安全的

Parallel processing 使用Fortran的OpenMP FFTW不是线程安全的,parallel-processing,fortran,openmp,fftw,Parallel Processing,Fortran,Openmp,Fftw,我试图将FFTW与openMP和Fortran一起使用,但并行执行时会得到错误的结果,这也会在每个执行步骤中更改它们的值,在并行化出错时显示典型的行为 我的目标是一个简单的三维真实到复杂的转换。在FFTW教程之后,除了调用并行区域中的dfftw\u execute\u dft\u r2c()之外,我接受了所有调用,但它似乎不起作用 我使用FFTW 3.3.8,配置为/configure--enable threads--enable openmp--enable mpi,并使用gfortran

我试图将FFTW与openMP和Fortran一起使用,但并行执行时会得到错误的结果,这也会在每个执行步骤中更改它们的值,在并行化出错时显示典型的行为

我的目标是一个简单的三维真实到复杂的转换。在FFTW教程之后,除了调用并行区域中的
dfftw\u execute\u dft\u r2c()
之外,我接受了所有调用,但它似乎不起作用

我使用FFTW 3.3.8,配置为
/configure--enable threads--enable openmp--enable mpi
,并使用
gfortran program.f03-o program.o-I/usr/include-fopenmp-lfftw3_omp-lfftw3-g-Wall
编译代码

我的程序是这样的:

program use_fftw

  use,intrinsic :: iso_c_binding
  use omp_lib
  implicit none
  include 'fftw3.f03'

  integer, parameter     :: dp=kind(1.0d0)
  integer, parameter     :: Nx = 10
  integer, parameter     :: Ny = 5
  integer, parameter     :: Nz = 5
  real(dp), parameter    :: pi = 3.1415926d0
  real(dp), parameter    :: physical_length_x = 20.d0
  real(dp), parameter    :: physical_length_y = 10.d0
  real(dp), parameter    :: physical_length_z = 10.d0
  real(dp), parameter    :: lambda1 = 0.5d0
  real(dp), parameter    :: lambda2 = 0.7d0
  real(dp), parameter    :: lambda3 = 0.9d0
  real(dp), parameter    :: dx = physical_length_x/real(Nx,dp)
  real(dp), parameter    :: dy = physical_length_y/real(Ny,dp)
  real(dp), parameter    :: dz = physical_length_z/real(Nz,dp)

  integer :: void, nthreads

  integer :: i, j, k
  real(dp):: d

  complex(dp), allocatable, dimension(:,:,:)  :: arr_out
  real(dp), allocatable, dimension(:,:,:)     :: arr_in
  integer*8                                   :: plan_forward


  allocate(arr_in( 1:Nx, 1:Ny, 1:Nz));     arr_in = 0
  allocate(arr_out(1:Nx/2+1, 1:Ny, 1:Nz)); arr_out = 0


  !------------------------------
  ! Initialize fftw stuff
  !------------------------------

  ! Call before any FFTW routine is called outside of parallel region
  void = fftw_init_threads()
  if (void==0) then
    write(*,*) "Error in fftw_init_threads, quitting"
    stop
  endif
  nthreads = omp_get_num_threads()
  call fftw_plan_with_nthreads(nthreads)

  ! plan execution is thread-safe, but plan creation and destruction are not:
  ! you should create/destroy plans only from a single thread
  call dfftw_plan_dft_r2c_3d(plan_forward, Nx, Ny, Nz, arr_in, arr_out, FFTW_ESTIMATE)


  !--------------------------------
  ! Start parallel region
  !--------------------------------

  !$OMP PARALLEL PRIVATE( j, k, d)

    ! Fill array with wave
    ! NOTE: wave only depends on x so you can plot it later.
    !$OMP DO
      do i = 1, Nx
        d = 2.0*pi*i*dx
        do j = 1, Ny
          do k = 1, Nz
            arr_in(i,j,k) = cos(d/lambda1)+sin(d/lambda2)+cos(d/lambda3) 
          enddo
        enddo
      enddo
    !$OMP END DO


    call dfftw_execute_dft_r2c(plan_forward, arr_in, arr_out)

  !$OMP END PARALLEL


  !-----------------
  ! print results
  !-----------------

  do i=1, Nx/2+1
    do j=1, Ny
      do k=1, Nz
        write(*,'(F12.6,A3,F12.6,A3)',advance='no') real(arr_out(i,j,k)), " , ", aimag(arr_out(i,j,k)), " ||"
      enddo
      write(*,*)
    enddo
    write(*,*)
  enddo



  deallocate(arr_in, arr_out)
  ! destroy plans is not thread-safe; do only with single
  call dfftw_destroy_plan(plan_forward)

end program use_fftw
我还尝试将FFTW的初始化部分(
void=FFTW_init_threads();调用FFTW_plan_with_nthreads(nthreads));调用dfftw_plan_dft_r2c_3d(…)
到并行区域,使用
!$OMP SINGLE
块,然后与屏障同步,但情况没有改善

有人能帮我吗


编辑:我能够在另一个系统上测试我的程序,问题仍然存在。因此,问题显然不在我的openmp或FFTW实现中,而是在程序本身的某个地方。

您通常应该在
并行
区域的之外调用FFTW执行例程。它们有自己的并行re他们将负责在规划过程中按照您的要求与那么多线程并行运行转换。他们将重用您现有的OpenMP线程

您也可以在并行区域内调用它们,但是在不同的阵列上,而不是在相同的阵列上!然后您的计划应该使用1个线程。例如,每个线程将对阵列的一个切片执行2D变换


线程安全性意味着您可以同时调用例程,但每个例程用于不同的数据。

您通常应该在
并行
区域的外部调用fftw execute ROUTIES。它们内部有自己的并行区域,并且它们将负责与尽可能多的线程并行运行转换u在规划期间请求。他们将重新使用您现有的OpenMP线程

您也可以在并行区域内调用它们,但是在不同的阵列上,而不是在相同的阵列上!然后您的计划应该使用1个线程。例如,每个线程将对阵列的一个切片执行2D变换


线程安全性意味着您可以同时调用这些例程,但每个例程用于不同的数据。

这不应该发生。我经常在OpenMP中使用FFTW,没有任何问题。我刚刚在另一台机器上检查过,我知道FFTW和OpenMP工作正常,问题仍然存在。因此我的代码中一定有问题。@VladimirF What exa你的意思是“但是在不同的数组上,而不是在相同的数组上”?我把它移到了一个答案。这不应该发生。我经常在OpenMP中使用FFTW,没有任何问题。我刚刚在另一台机器上检查过,我知道FFTW和OpenMP工作正常,问题仍然存在。所以我的代码中一定有问题。@VladimirF“但在不同的阵列上,而不是在相同的阵列上”到底是什么意思?我把它移到了一个答案。现在似乎可以了,谢谢!我真的希望那里会有一些更详细的FFTW教程和示例…现在似乎可以了,谢谢!我真的希望那里会有一些更详细的FFTW教程和示例。。。