Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor II

What is the effect of violating the contiguity attribute of a dummy argument?

Hello,

I am experimenting with the CONTIGUOUS attribute and I found to my surprise that passing a non-contiguous array section via a dummy argument that does have this attribute makes no difference. So I wonder if it should - for instance lead to a runtime error message - or not. I compiled the program below with the flag -check:all to see if any runtime error or warning is issued and none is (using Intel Fortran 15). The program works as if this attribute were not present.

Can someone enlighten me? (I can imagine that the attribute is recognised but does not lead to more efficient code ...)

! chktemp.f90 --
!
module temp
contains
subroutine mytemp( a, n )
    real, contiguous, dimension(:) :: a
    integer, intent(in) :: n

    a(1:n) = 1.0
end subroutine
end module temp

program chktemp
    use temp
    implicit none

    real, dimension(10,10) :: aha

    aha = 0.0

    call mytemp( aha(1,:), size(aha(1,:)) )

    write(*,'(10f5.2)') aha
end program chktemp

 

 

0 Kudos
4 Replies
Highlighted

Try making subroutine mytemp

Try making subroutine mytemp an external subroutine placed into a library...
and where the library is not subject to multi-file inlining (disable multi-file ipo).

I suspect that the compiler optimization of inlining the code may have circumvented you attempt at discovery as to the consequences of violation of your contract.

Jim Dempsey

0 Kudos
Highlighted
Valued Contributor II

I did that - the module is

I did that - the module is now in one file and the program is in another and via a series of commands a library and a program using that library are built. But it made no difference. The program still works as if there was no CONTIGUOUS.

0 Kudos
Highlighted

Because the compiler knows

Because the compiler knows that the dummy argument is expected to be contiguous, it makes a temporary (contiguous) array and does copy in/copy out around the routine call.

What you could try is to have a completely separate subroutine, not in a module and without an interface, and see what happens.

            --Lorri

0 Kudos
Highlighted
Valued Contributor II

Thanks for the suggestion,

Thanks for the suggestion, but I need to provide an interface for the routine - I tried it without and that predictably crashed :).

Of course I can cheat a bit ... trying that now. Oh, the output is wrong now:

 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00
 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

The funny thing is I expected that the option -check:all would lead to at least messages about temporary arrays (something that does happen in a different version of the program, which I specifically set up for that type of things, as an illustration), but these did not appear.

Trying with the contiguous attribute in the interface: no warning, but the result is correct now.

Just to allow someone to repeat the experiment, here are the two source files:

! chktemp.f90 --
!
program chktemp
    implicit none

    interface
        subroutine mytemp( a, n )
            real, dimension(:) :: a ! Cheat: no contiguous attribute
            integer :: n
        end subroutine mytemp
    end interface

    real, dimension(10,10) :: aha

    aha = 0.0

    call mytemp( aha(1,:), size(aha(1,:)) )

    write(*,'(10f5.2)') aha
end program chktemp

and the code for the library:

! templib.f90 --
!
!module temp
!contains
subroutine mytemp( a, n )
    real, contiguous, dimension(:) :: a
    integer, intent(in) :: n

    a(1:n) = 1.0
end subroutine
!end module temp

 

0 Kudos