Reputation: 2179
I'm encountering a compile-time warning when passing arrays to MPI
calls by referencing their first value. Consider the following example code, which is the leanest I could get:
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
Notice that I'm passing MPI_REDUCE
only the first element of input
and output
but using a count of N
, which is (in this case) the complete size of the array. It's worth noting that referencing array sections like this probably isn't best practice but I'm doing it anyway.
I get the following compiler warning and runtime output:
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
I get the warning with PGI 14.3/OpenMPI 1.8.0 or PGI 15.5/OpenMPI 1.8.6. I do not get the warning with PGI 12.9/OpenMPI 1.6.2, PGI 14.3/OpenMPI 1.6.5, or Intel 14.0/OpenMPI 1.8.0.
It's my understanding that sequence
is a keyword affecting derived data types only, and input
and output
here are plain integers. Also, these are 1D arrays - don't they have to be contiguous anyway?
My question is: what's going on here? Can (and should) I declare integers as sequence?
Edit 1 Following the advice of francescalus, I've attempted to define the the dummy array as contiguous
. I've added contiguous
to the input
argument and inquired about the contiguity (is that a word?) of input
and output
using is_contiguous
in main and sub. Rather than re-post the entire code, I've edited the original code shown above. Unfortunately, I still get the same compiler warning. Furthermore, the contiguous
attribute doesn't seem to be doing anything because is_contiguous
reports false in the subroutine for both input
and output
.
Am I using the contiguous
attribute correctly? It seems reasonable to require input
and output
to be contiguous
, but not sequence
. Perhaps I should report this to PGI
directly, especially now that I've encountered the problem on a reasonably new version of pgfortran
.
Upvotes: 2
Views: 151
Reputation: 2179
I've now got some closure on this issue and wanted to share. This answer will hopefully provide some clarity for future readers. Thanks francescalus and Vladimir F for your help; I also received help on the Portland Group Forums.
There are two separate bugs in pgfortran
at play here. The first is a bug in the is_contiguous
intrinsic. The second is an erroneous use of a legacy warning. Both issues have been reported and will (hopefully) be fixed in a new compiler release.
is_contiguous
is_contiguous
isn't performing as expected. The bug has been reported with tag TPR#21939
. Consider the following example code:
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
which gives the following output:
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.
Both input
and output
are contiguous, and I'm even assigning ia1
the contiguous
attribute. Yet is_contiguous
reports them to be not contiguous in mysub
.
sequence
This is the original issue that led to this question - a compile-time warning to declare an array as sequence
. This issue has been reported with tag TPR#21947
. Consider the following example code:
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
As mentioned in the question, I'm passing the entire input
and output
array to MPI_REDUCE
by referencing the first element in each array and assigning a size of N
. This is not good practice, but I was doing it anyway. I get the following compile-time warning:
[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/
which is incorrect because arrays (like input
) may not be defined as sequence
.
Upvotes: 1
Reputation: 32451
I don't have access to the same setup to be able to replicate, but there are some things still to say.
The sequence
attribute can indeed apply only to derived types. That means you can't (and shouldn't) declare input
and output
with sequence
.
Now, after we note that what you see is a warning (which has prompted you to think about the problem - which you can do more than the compiler can), what are the other concerns?
There are several implications that come from being a sequence type. Continguity is an important one, and is addressed in your penultimate question.
A 1D dummy argument, such as input
, needn't be contiguous. Consider
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
In general, in Fortran we don't have to care about the contiguity or otherwise of dummy arguments. There is, though, the is_contiguous
intrinsic function which inquires of the contiguity of an array.
When interfacing with other things there may be reason to worry. There are some things you can do here:
contiguous
attribute to the dummy argumentsMPI_Reduce
, not the first elementsUpvotes: 2