Ross
Ross

Reputation: 2179

Compile-time warning to declare array as sequence

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

Answers (2)

Ross
Ross

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.

Issue with 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.

Warning to Declare as 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

francescalus
francescalus

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:

  • thorough testing (how does the compiler/MPI environment really handle things?)
  • add the contiguous attribute to the dummy arguments
  • pass the arrays themselves to MPI_Reduce, not the first elements

Upvotes: 2

Related Questions