Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29253 Discussions

Rank mismatch of a passing array in a subroutine may lead wrong result

forcpp
New Contributor I
2,563 Views
I'm calling a subroutinesub(NofSites,NNInt,next) from a main program test. This is a just portion of computational package which I'm developing and attaching code here. Initially, I was defined 2-Rankarray next both in the main program and subroutine. For some reasons I need 3-Rank array next. I just changed the rank in subroutine but forgot to change in the main program. Because of this I noticed the assigned values of an allocatable array site changed in the execution process. Furthermore, If I didn't defined array site as an allocatable the assigned values given to site doesn't changed.

Is there any compiler option which can give the information about mismatch in the rank of an array which is passing through in a subroutine ?
Thanks.
[fortran]!********************************************************************!
program test
!********************************************************************!
  implicit none
  
    ! Declare variables:
    integer :: NofSites, err, NNInt
    integer, dimension(:,:), allocatable :: next 
    
    NNInt=3           
    NofSites=4
    allocate(next(0:NofSites-1,0:NNInt-1), stat=err)
    if (err /= 0) print *, "next: Allocation request denied"
    
    call sub(NofSites,NNInt,next)

end program test
!********************************************************************!


!********************************************************************!
subroutine sub(NofSites,NNInt,next)
!********************************************************************!    
    implicit none
    
      ! Declare calling parameters:
      integer, intent(in) :: NofSites, NNInt 
      integer, dimension(0:NofSites-1,0:1,0:NNInt-1), intent(out) :: next

      ! Declare local variables:
      integer :: xvalue, yvalue, i, j, err
      integer, parameter :: F1x=2, F1y=0, F2x=0, F2y=2, F12x=2, F12y=2
      integer, dimension(:), allocatable :: PosX, PosY
      integer, dimension(:,:), allocatable ::  site

      allocate(site(0:F1x,0:F12y), stat=err)
      if (err /= 0) print *, "site: Allocation request denied"
      
      allocate(PosX(0:NofSites-1), stat=err)
      if (err /= 0) print *, "PosX: Allocation request denied"
      allocate(PosY(0:NofSites-1), stat=err)
      if (err /= 0) print *, "PosY: Allocation request denied"
      
      
      site(0,0)=0; site(1,0)=1; site(2,0)=0
      site(0,1)=2; site(1,1)=3; site(2,1)=2
      site(0,2)=0; site(1,2)=1; site(2,2)=0

      PosX(0)=0; PosY(0)=0
      PosX(1)=1; PosY(1)=0
      PosX(2)=0; PosY(2)=1
      PosX(3)=1; PosY(3)=1

      do i = 0, F1x, 1
        do j = 0, F12y, 1
          print*,i,j,site(i,j)
        end do
      end do  

      do i = 0, NofSites-1, 1
        do j = 0, NNInt-1, 1

          ! In x-direction
          xvalue=PosX(i)+1+j/2
          yvalue=PosY(i)+mod(j,2)
          if ( xvalue<=F1x+abs(F2x) ) then
            next(i,0,j)=site(xvalue,yvalue)
          else
            if ( yvalue=F12x+abs(F2x) ) then
              xvalue=xvalue-F1x
              yvalue=yvalue-F1y
              next(i,1,j)=site(xvalue,yvalue)
            else
              xvalue=xvalue-F2x
              yvalue=yvalue-F2y  
              next(i,1,j)=site(xvalue,yvalue)
            end if
          end if
          !print*,i,next(i,1,j),j+1,"y"
        end do
      end do

      print*,""
      do i = 0, F1x, 1
        do j = 0, F12y, 1
          print*,i,j,site(i,j)
        end do
      end do
     
     if (allocated(site)) deallocate(site, stat=err)
     if (err /= 0) print *, "site: Deallocation request denied"
     if (allocated(PosX)) deallocate(PosX, stat=err)
     if (err /= 0) print *, "PosX: Deallocation request denied"
     if (allocated(PosY)) deallocate(PosY, stat=err)
     if (err /= 0) print *, "PosY: Deallocation request denied"

end subroutine sub
!********************************************************************![/fortran]
0 Kudos
7 Replies
mecej4
Honored Contributor III
2,563 Views
Although the mismatch may be, from your point of view, an error, it is not forbidden by the language rules. See, for example, Metcalfe, Reid and Cohen, Fortran 95/2003 explained, Article 20.3: "Shape and character length disagreement", wherein one finds "...An object of one size or rank may be passed to an explicit-shape or assumed-size dummy argument array that is of another size or rank."

In many applications of Fortran, the ability to pass array sections as arguments and have the subroutine treat the arguments as having a different shape is vital. Unfortunately, this versatility places a greater burden on the programmer as to making sure that arguments are passed correctly and as intended.

The Intel Fortran compiler can generate interface blocks using the /gen-interfaces option.

Some Fortran compilers may be requested to issue warnings of such mismatches, e.g., the Salford compiler on Windows, given an interface body for the subroutine, says:

[bash]0022)     call sub(NofSites,NNInt,next)
WARNING - In the INTERFACE to SUB, the third argument (NEXT) is rank 3, but it is rank 2 in this call
    NO ERRORS, 1 WARNING  [ FTN95/Win32 v5.50.0]
    NO ERRORS  [ FTN95/Win32 v5.50.0]


[/bash]
0 Kudos
Steven_L_Intel1
Employee
2,563 Views
Use "-warn interface" to diagnose mismatches. But, as mecej4 says, this "mismatch" is allowed by the language and the Intel compiler won't complain about it.
0 Kudos
forcpp
New Contributor I
2,563 Views
Thanks mecej4 and Steve. I already checked this program with options:

$ifort -m64 -g -implicitnone -warn -ftrapuv -debug full -fp-stack-check -heap-arrays -traceback -check -fpe0
-gen-interfaces -warn interfaces test.f90
$./a.out
but nothing happens as a warning or an error. I'm using Mac OS 10.6.3 and ifort11.1.088 (64 bit). One remaining question which I asked in my post: why the mismatch affecting the values of other assigned allocated array site ? Between two print statements I'm not changing the values of site array but final print values differs from previous one. This is still not understandable for me.
0 Kudos
mecej4
Honored Contributor III
2,563 Views
In my opinion it is not worthwhile to investigate what side effects are caused by a bug in your code, unless you are debugging the compiler itself. In general, the effect of running code with errors in it is "undefined". You may obtain correct results today, junk tomorrow; the FBI may come calling, or you might receive flowers in the mail, etc., ... :)

In the old days, I remember, sometimes I obtained my card deck back with a blank sheet of output, with a note from the operator saying "your code executed data".
0 Kudos
forcpp
New Contributor I
2,563 Views
Thanks again mecej4. I think this forum is well supported by developers too. So it is genuine question to know insight out of errors if we are not in a position to understand them. Escape root may restrict our research and knowledge. There should be some reasonable logic why this is happening. I appreciate your point but at the same time I also need some logical and satisfactory explanations.
0 Kudos
forcpp
New Contributor I
2,563 Views
I figure out that conflict in rank can be checked by Source Code Checker. This can be done by using option
-diag-enable sc3. Unfortunately ifort on Mac system didn't notice this while on a linux machine it gives properly like this:
error #12030: size of actual argument 3 in call of "sub" is less than size of formal argument.
ifort on mac:11.1.088
ifort on Linux:11.1.046
0 Kudos
forcpp
New Contributor I
2,563 Views
I figure out that conflict in rank can be checked by Source Code Checker. This can be done by using option
-diag-enable sc3. Unfortunately ifort on Mac system didn't notice this while on a linux machine it gives properly like this:
error #12030: size of actual argument 3 in call of "sub" is less than size of formal argument.
ifort on mac:11.1.088
ifort on Linux:11.1.046
0 Kudos
Reply