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

时间:2015-08-31 22:54:28

标签: fortran mpi openmpi pgi-visual-fortran

在通过引用第一个值将数组传递给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这里是普通整数。另外,这些是1D阵列 - 不管怎么说它们必须是连续的?

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

编辑1 根据francescalus的建议,我试图将虚拟数组定义为contiguous。我已将contiguous添加到input参数中并使用input查询outputis_contiguous的{​​{1}}和/ contiguous的连续性(是一个单词?)主要和次要。我没有重新发布整个代码,而是编辑了上面显示的原始代码。不幸的是,我仍然得到相同的编译器警告。此外,is_contiguous属性似乎没有做任何事情,因为inputoutputcontiguous的子例程中报告为false。

我是否正确使用input属性?要求outputcontiguoussequence,而不是PGI似乎是合理的。也许我应该直接向pgfortran报告此问题,特别是现在我已经在 var mydata0 = null; $.post('php/ProductionChange.php', function(data) { // This is Where I use an AJAX call into a php file. mydata0=data; // This takes the array from the call and puts it //into //a variable var pa = JSON.parse(mydata0); var temp = {}; for (var i = 0; i < data.length-1; i++) { var job=pa[i][0]; var shipdate = pa[i][1]; var status = pa[i][2]; var name = pa[i][3]; var EnclLoc = pa[i][13]; var Enclsize = pa[i][14]; var BackPanLoc = pa[i][15]; var percentCom = pa[i][16]; var isVis = pa[i][17]; var png = pa[i][18]; var WorkC = pa[i][20]; temp={'bayData': job, shipdate, name, EnclLoc, Enclsize, BackPanLoc, percentCom, isVis, png, WorkC}; isVacant1.push(temp); 的合理新版本上遇到了问题。

2 个答案:

答案 0 :(得分:2)

我无法访问相同的设置以进行复制,但仍有一些事情需要说明。

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

现在,在我们注意到你所看到的是一个警告(它促使你思考问题 - 你可以做的比编译器更多),还有其他问题吗?

序列类型有几个含义。熄灭是一个重要问题,并在倒数第二个问题中得到解决。

1D伪参数,例如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,而不是第一个元素

答案 1 :(得分:1)

我现在已经关闭了这个问题并希望分享。这个答案有望为未来的读者提供一些清晰的答案。感谢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 报告此问题。请考虑以下示例代码:

input

正如问题所述,我通过引用每个数组中的第一个元素并指定大小{{{}}来将整个outputMPI_REDUCE数组传递给N 1}}。这是良好做法,但无论如何我都是这样做的。我得到以下编译时警告:

[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