CONTIGUOUS attribute for dummy arguments: what happens when the actual argument is not contiguous?

CONTIGUOUS attribute for dummy arguments: what happens when the actual argument is not contiguous?

Steve,

The code listed below compiles and runs without any errors in Intel Fortran XE 2013 Update 2 (13.1.0.149).  And it writes out a result value of false for the statement on line 27.  But do you think this is correct?  I was expecting a compiler error given the CONTIGUOUS attribute on the dummy argument in AssumedShape subroutine?  Does it not require that the actual argument has to be simply contiguous and which is not the case here?

You would recall from the Fortran 2008 standard:

5 5.3.7 CONTIGUOUS attribute
6 C530 An entity with the CONTIGUOUS attribute shall be an array pointer or an assumed-shape array.
7 1 The CONTIGUOUS attribute specifies that an assumed-shape array can only be argument associated with a
8 contiguous effective argument, or that an array pointer can only be pointer associated with a contiguous target.
9 2 An object is contiguous if it is
10 (1) an object with the CONTIGUOUS attribute,
11 (2) a nonpointer whole array that is not assumed-shape,
12 (3) an assumed-shape array that is argument associated with an array that is contiguous,
13 (4) an array allocated by an ALLOCATE statement,
14 (5) a pointer associated with a contiguous target, or
15 (6) a nonzero-sized array section (6.5.3) provided that
16 (a) its base object is contiguous,
17 (b) it does not have a vector subscript,
18 (c) the elements of the section, in array element order, are a subset of the base object elements
19 that are consecutive in array element order,
20 (d) if the array is of type character and a substring-range appears, the substring-range specifies all
21 of the characters of the parent-string (6.4.1),
22 (e) only its final part-ref has nonzero rank, and ..

 

PROGRAM p
 
   IMPLICIT NONE
 
   INTEGER, ALLOCATABLE :: a(:,:)
   INTEGER :: Istat
 
   ALLOCATE(a(5,5), STAT=Istat)
   IF (Istat /= 0) THEN
      STOP
   END IF
 
   a = 0
 
   CALL AssumedShape(a(3,:))
 
   STOP
 
CONTAINS
 
   SUBROUTINE AssumedShape(arg)
 
      !..
      INTEGER, CONTIGUOUS, INTENT(IN) :: arg(:)
 
      !..
      WRITE(*,*) "Is arg contiguous? ",IS_CONTIGUOUS(arg)
 
      RETURN
 
   END SUBROUTINE AssumedShape
 
END PROGRAM p

12 posts / novo 0
Último post
Para obter mais informações sobre otimizações de compiladores, consulte Aviso sobre otimizações.

If the array in the above example is explicitly declared, then the compiler gives an error as I'd expect it to:

PROGRAM p

   IMPLICIT NONE

   INTEGER :: a(5,5)

   a = 0

   CALL AssumedShape(a(3,:))

   STOP

CONTAINS

   SUBROUTINE AssumedShape(arg)

      !..
      INTEGER, CONTIGUOUS, INTENT(IN) :: arg(:)

      !..
      WRITE(*,*) "Is arg contiguous? ",IS_CONTIGUOUS(arg)

      RETURN

   END SUBROUTINE AssumedShape

END PROGRAM p
1>------ Build started: Project: TestFor, Configuration: Debug x64 ------
1>Compiling with Intel(R) Visual Fortran Compiler XE 13.1.0.149 [Intel(R) 64]...
1>TestFor.f90
1>C:\dev\Fortran\Test15\sor\TestFor.f90(9): error #8374: Array section is not contiguous
1> with such set of indices.
1>C:\dev\Fortran\Test15\sor\TestFor.f90(9): error #8372: If dummy argument is declared
1>CONTIGUOUS, actual argument must be contiguous as well.   [A]
1>compilation aborted for C:\dev\Fortran\Test15\sor\TestFor.f90 (code 1)
1>
1>Build log written to  "file://C:\dev\Fortran\Test15\Debug\x64\TestForBuildLog.htm"
1>TestFor - 3 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

 

After my post about the contiguous attribute yesterday I did a bit more digging - it looks like my understanding was wrong.  I took the words "the CONTIGUOUS attribute specifies that an assumed-shape array can only be argument associated with a contiguous effective argument" in your quote above to be a requirement on the program (as in - the programmer has to ensure this).  Apparently that is not the case - see http://mailman.j3-fortran.org/pipermail/j3/2011-June/004412.html

If the compiler doesn't know for sure that the argument isn't contiguous then the compiler should arrange at runtime to make a copy of the actual argument, so that the procedure can work with something that is contiguous.  Details around the pointer association rules for actual and dummy arguments support this.  This is much more robust than my initial understanding.  Good.

But, if you go a spelunking with LOC, you can see that ifort isn't doing that for your original example.  Hence I think it returns what is clearly the wrong result for the IS_CONTIGUOUS intrinsic.

And, given your second example, it looks like I wasn't the only one to misread the intent of the standard.

Whether something is contiguous or not is a runtime condition in the general case.  Beyond a minimum set of things that are considered contiguous it is also processor dependent. 

"Simply contiguous" is a subset of everything that is considered contiguous - it covers the cases where the compiler can know at compile time that the argument has to be contiguous (and hence it can issue a compile time error message if a requirement that something be simply contiguous is not met) .  It is not processor dependent.

The rules around pointer association of a pointer with the contiguous attribute with some target do place a requirement on the programmer that the target is contiguous.

 

Edit to note that F2008 corrigendum two fixed the text to be "the CONTIGUOUS attribute specifies that an assumed-shape array is contiguous".

In the original F2008 standard, CONTIGUOUS was a requirement on the programmer. As Ian says, F2008 Corrigendum 2 changed that to require that the compiler make sure the actual argument was contiguous. We have not yet implemented that change, though it is being worked on. The issue number is DPD200241665.

Steve - Intel Developer Support

Steve,

In your implementation, when the actual argument is NOT contiguous and the DUMMY argument has CONTIGUOUS (and of course interface is seen), what is (will be) the course of action?

a) Compile time warning "Warning Array temporary created for CONTIGUOUS argument"
b) Compile time error "Error Array argument must be contiguous"

And will there be an option to control the compiler behavior? (make error, or make temp and warn, or make temp an no warn)

Jim Dempsey
 

www.quickthreadprogramming.com

Good questions, Jim.  I was about to ask the same.  Thanks,

The eventual implementation is that a contiguous copy is passed, much like when you pass a noncontiguous array section to an assumed-size array - and any changes are copied back. You will get no warning (unless you have /check:arg_temp_created enabled).. What happens now is that the compiler gives an error.as shown in reply #2.

Steve - Intel Developer Support

Quote:

Steve Lionel (Intel) wrote:

The eventual implementation is that a contiguous copy is passed, much like when you pass a noncontiguous array section to an assumed-size array - and any changes are copied back. You will get no warning (unless you have /check:arg_temp_created enabled).. What happens now is that the compiler gives an error.as shown in reply #2.

Steve,

Why doesn't the example in the original post give an error?  Is that a bug that will be fixed with the tracking incident you provided above?

Because we're not checking it when the compiler doesn't know at compile time. We'll add that.

Steve - Intel Developer Support

In the next release, planned for later this year (and beta starting soon), we've implemented the Corrigendum 2 behavior for CONTIGUOUS so that if you pass a non-contiguous section, we'll do copy-in/copy-out of a contiguous copy.

Steve - Intel Developer Support

Quote:

Steve Lionel (Intel) wrote:

In the next release, planned for later this year (and beta starting soon), we've implemented the Corrigendum 2 behavior for CONTIGUOUS so that if you pass a non-contiguous section, we'll do copy-in/copy-out of a contiguous copy.

Thanks Steve.  So the IS_CONTINUOUS(arg) test in a procedure that has the dummy argument arg with CONTINUOUS attribute, as shown in the OP, will always return .TRUE., is that correct?

 

It should, yes.

Steve - Intel Developer Support

Deixar um comentário

Faça login para adicionar um comentário. Não é membro? Inscreva-se hoje mesmo!