2

MPI通过引用数组的第一个值将数组传递给调用时,我遇到了编译时警告。考虑以下示例代码,这是我能得到的最精简的代码:

module mymod
implicit none
contains

subroutine test_sequence(input,output,icomw,N)
use MPI
integer, intent(in), contiguous :: input(:)
integer, intent(in) :: icomw, N
integer, intent(out) :: output(:)
integer :: ier

write(*,*) 'in sub: ', is_contiguous(input), is_contiguous(output)

call MPI_REDUCE(input(1),output(1),N,MPI_INTEGER,MPI_MAX,0,icomw,ier)
   ! -- This is the line referenced in the error

end subroutine test_sequence
end module mymod

program main
use MPI
use mymod
implicit none
integer :: icomw, id, nproc, ier, N, i
integer, allocatable :: input(:), output(:)
real :: harvest

call MPI_INIT(ier)
icomw = MPI_COMM_WORLD

N = 10
allocate(input(N), output(N))
input = 1

write(*,*) 'in main: ', is_contiguous(input), is_contiguous(output)

call test_sequence(input,output,icomw,N)

call MPI_FINALIZE(ier)
end program main

请注意,我MPI_REDUCE只传递了 的第一个元素,inputoutput使用了 的计数N,即(在本例中)数组的完整大小。值得注意的是,像这样引用数组部分可能不是最佳实践,但无论如何我都在这样做。

我得到以下编译器警告和运行时输出:

km-gs3% mpifort test_sequence.f90
PGF90-W-0312-Array input should be declared SEQUENCE (test_sequence.f90: 14)
PGF90-W-0312-Array output should be declared SEQUENCE (test_sequence.f90: 14)
  0 inform,   2 warnings,   0 severes, 0 fatal for test_sequence
km-gs3% mpirun -np 2 ./a.out 
 in main:   T  T
 in sub:   F  F
 in main:   T  T
 in sub:   F  F

我收到 PGI 14.3/OpenMPI 1.8.0 或 PGI 15.5/OpenMPI 1.8.6 的警告。我没有收到 PGI 12.9/OpenMPI 1.6.2、PGI 14.3/OpenMPI 1.6.5 或 Intel 14.0/OpenMPI 1.8.0 的警告。

据我了解,这sequence是一个仅影响派生数据类型的关键字,input这里output是纯整数。此外,这些是一维数组 - 它们是否必须是连续的?

我的问题是:这里发生了什么?我可以(并且应该)将整数声明为序列吗?

编辑 1按照 francescalus 的建议,我尝试将虚拟数组定义为contiguous. 我已经添加contiguousinput论点并询问了 main 和 sub 的连续性(这是一个词吗?)input并在其中output使用is_contiguous。我没有重新发布整个代码,而是编辑了上面显示的原始代码。不幸的是,我仍然收到相同的编译器警告。此外,该contiguous属性似乎没有做任何事情,因为is_contiguous在子例程中报告了 falseinputoutput

contiguous是否正确使用了该属性?input要求和output成为似乎是合理的contiguous,但不是sequence。也许我应该PGI直接报告这个问题,特别是现在我在一个相当新的版本上遇到了这个问题pgfortran

4

2 回答 2

2

我无法访问相同的设置来进行复制,但仍有一些话要说。

sequence属性确实只能应用于派生类型。这意味着您不能(也不应该)声明inputand outputwith sequence

现在,在我们注意到你看到的是一个警告(它促使你思考这个问题——你可以比编译器做更多的事情)之后,还有什么其他问题?

作为序列类型有几个含义。连续性是一个重要的问题,并在您的倒数第二个问题中得到解决。

一维虚拟参数,例如input,不必是连续的。考虑

  real a(11), b(5)
  call sub(a(1::5))    ! Look at the stride
  call sub(b(5:1:-1))  ! Look at the order

contains

   subroutine sub(input)
     real, intent(in) :: input(:)
   end subroutine

end program

一般来说,在 Fortran 中,我们不必关心虚拟参数的连续性或其他方面。但是,有一个is_contiguous内在函数可以查询数组的连续性。

当与其他事物交互时,可能有理由担心。您可以在这里做一些事情:

  • 彻底的测试(编译器/MPI 环境如何真正处理事情?)
  • contiguous属性添加到虚拟参数
  • 将数组本身传递给MPI_Reduce,而不是第一个元素
于 2015-09-01T07:24:24.830 回答
1

我现在对这个问题有了一些结论,想分享一下。这个答案有望为未来的读者提供一些清晰的信息。感谢 francescalus 和 Vladimir F 的帮助;我还在波特兰集团论坛上获得了帮助。

这里有两个单独的错误在pgfortran起作用。第一个是is_contiguous 内在的错误。第二个是错误使用遗留警告。这两个问题都已报告,并将(希望)在新的编译器版本中得到修复。

问题is_contiguous

is_contiguous没有按预期执行。该错误已通过 tag 报告TPR#21939。考虑以下示例代码:

module mymod 
implicit none 
contains 

subroutine mysub(ia1,ia2) 
integer, intent(in), contiguous :: ia1(:) 
integer, intent(in) :: ia2(:) 

write(*,*) 'in sub: ', is_contiguous(ia1), is_contiguous(ia2) 

end subroutine mysub 
end module mymod 

program main 
use mymod 
implicit none 

integer, allocatable :: ia1(:), ia2(:) 
integer :: N 

N = 10 
allocate(ia1(N), ia2(N)) 

write(*,*) 'in main: ', is_contiguous(ia1), is_contiguous(ia2) 

call mysub(ia1,ia2) 

end program main 

给出以下输出:

km-gs3% pgfortran test_contiguous.f90; ./a.out 
 in main:   T  T 
 in sub:   F  F 
km-gs3% pgfortran --version 

pgfortran 15.5-0 64-bit target on x86-64 Linux -tp piledriver 
The Portland Group - PGI Compilers and Tools 
Copyright (c) 2015, NVIDIA CORPORATION.  All rights reserved.

两者inputoutput都是连续的,我什至分配ia1contiguous属性。然而is_contiguous报告他们在mysub.

警告声明为sequence

这是导致这个问题的原始问题 - 将数组声明为的编译时警告sequence。此问题已通过 tag 报告TPR#21947。考虑以下示例代码:

module mymod 
implicit none 
contains 

subroutine test_sequence(input,output,icomw,N) 
use MPI 
integer, intent(in) :: input(:) 
integer, intent(in) :: icomw, N 
integer, intent(out) :: output(:) 
integer :: ier 

call MPI_REDUCE(input(1),output(1),N,MPI_INTEGER,MPI_MAX,0,icomw,ier) 
   ! -- This is the problem line referenced in the warning 

end subroutine test_sequence 
end module mymod 

program main 
use MPI 
use mymod 
implicit none 
integer :: icomw, id, nproc, ier, N, i 
integer, allocatable :: input(:), output(:) 
real :: harvest 

call MPI_INIT(ier) 
icomw = MPI_COMM_WORLD 

N = 10 
allocate(input(N), output(N)) 
input = 1 

call test_sequence(input,output,icomw,N) 

call MPI_FINALIZE(ier) 
end program main 

如问题中所述,我通过引用每个数组中的第一个元素input并分配. 这不是一个好习惯,但我还是这样做了。我收到以下编译时警告:outputMPI_REDUCEN

[chaud106@hyperion-login-1 Testing]$ mpif90 test_sequence.f90 
PGF90-W-0312-Array input should be declared SEQUENCE (test_sequence.f90: 12) 
PGF90-W-0312-Array output should be declared SEQUENCE (test_sequence.f90: 12) 
  0 inform,   2 warnings,   0 severes, 0 fatal for test_sequence

[chaud106@hyperion-login-1 Testing]$ mpif90 --version

pgf90 14.3-0 64-bit target on x86-64 Linux -tp piledriver 
The Portland Group - PGI Compilers and Tools
Copyright (c) 2014, NVIDIA CORPORATION.  All rights reserved.
[chaud106@hyperion-login-1 Testing]$ mpirun --version
mpirun (Open MPI) 1.8

Report bugs to http://www.open-mpi.org/community/help/

这是不正确的,因为数组(如input)可能未定义为sequence.

于 2015-09-08T20:35:17.223 回答