将数组声明为序列的编译时警告

Compile-time warning to declare array as sequence

我在通过引用第一个值将数组传递给 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 是一个只影响派生数据类型的关键字,inputoutput 这里是普通整数。此外,这些是一维数组 - 无论如何它们都必须是连续的吗?

我的问题是:这是怎么回事?我可以(并且应该)将整数声明为序列吗?

编辑 1 根据 francescalus 的建议,我尝试将虚拟数组定义为 contiguous。我已经将 contiguous 添加到 input 参数,并在 main 和 is_contiguous 中查询 inputoutput 的连续性(这是一个词吗?子。我没有重新 post 整个代码,而是编辑了上面显示的原始代码。不幸的是,我仍然收到相同的编译器警告。此外,contiguous 属性似乎没有做任何事情,因为 is_contiguousinputoutput.

的子例程中报告错误

我是否正确使用了 contiguous 属性?要求 inputoutputcontiguous 似乎是合理的,而不是 sequence。也许我应该直接向 PGI 报告这个问题,尤其是现在我已经在相当新的 pgfortran.

版本上遇到了这个问题

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

sequence 属性确实只能应用于派生类型。这意味着你不能(也不应该)用 sequence.

声明 inputoutput

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

序列类型有几个含义。连续性很重要,在倒数第二个问题中得到解决。

一维虚拟参数,例如 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 内部函数可以查询数组的连续性。

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

  • 彻底测试(compiler/MPI 环境如何真正处理事情?)
  • contiguous 属性添加到虚拟参数
  • 将数组本身传递给 MPI_Reduce,而不是第一个元素

我现在已经结束了这个问题并想分享。这个答案有望为未来的读者提供一些清晰度。感谢 francescalus 和 Vladimir F 的帮助;我还在 Portland Group Forums.

方面获得了帮助

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

问题 is_contiguous

is_contiguous 未按预期执行。该错误已通过标记 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 都是连续的,我什至将 ia1 分配给 contiguous 属性。然而 is_contiguous 报告它们在 mysub.

中不连续

警告声明为sequence

这是导致此问题的原始问题 - 将数组声明为 sequence 的编译时警告。此问题已通过标记 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 

如问题中所述,我通过引用每个数组中的第一个元素并分配 [=] 的大小,将整个 inputoutput 数组传递给 MPI_REDUCE 31=]。这 不是 好的做法,但我还是这样做了。我收到以下编译时警告:

[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