Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29419 ディスカッション

Wrong code (missing temporary) passing array section to explicit size dummy

Harald1
新規コントリビューター II
2,322件の閲覧回数

Hello,

the following code prints wrong results in the called subroutine:

module m
  implicit none
contains
  subroutine s(a, n)
    integer,  intent(in) :: n
    class(*), intent(in) :: a(n)

    select type(a)
    type is(integer)
       print *,'a is integer, a=', a
    class default
       print *,'a is unsupported type'
       stop 1
    end select
  end
end

program p
  use m
  implicit none
  integer :: b(2,2) = reshape([21, 22, 23, 24], [2,2])

  print *,b
  call s (b,4) ! OK
  print *
  print *,b(:,1::2)
  call s (b(:,1::2),2) ! OK
  print *
  print *,b(1::2,:)
  call s (b(1::2,:),2) ! bad
  print *
  print *,b(2::2,:)
  call s (b(2::2,:),2) ! bad
end

I get with current ifort:

          21          22          23          24
 a is integer, a=          21          22          23          24
 
          21          22
 a is integer, a=          21          22
 
          21          23
 a is integer, a=          21          22
 
          22          24
 a is integer, a=          22          23

So while the first two cases are ok, the last two are not.  Maybe there is no temporary generated for the passed array section to the explicit size dummy, and the actual stride of dimension 1 is not unity.

Thanks,

Harald

 

0 件の賞賛
1 解決策
Steve_Lionel
名誉コントリビューター III
2,180件の閲覧回数

I'm afraid that I'm on Harald's side here - there is no requirement that the dummy argument be assumed-shape. Sequence association does apply. 

F2018 15.5.2.4

p18 Except when a procedure reference is elemental (15.8), each element of an array actual argument or of a sequence in a sequence association (15.5.2.11) is associated with the element of the dummy array that has the same position in array element order (9.5.3.2).

 

The compiler would have to do copy-in (and copy-out if not INTENT(IN) or a vector subscript.)

元の投稿で解決策を見る

11 返答(返信)
Barbara_P_Intel
従業員
2,278件の閲覧回数

Thank you! Love these nice reproducers!

I'll check this out.



Barbara_P_Intel
従業員
2,245件の閲覧回数

I filed a bug, CMPLRLLVM-45596. This reproducer gets the same wrong results with ifx.



Barbara_P_Intel
従業員
2,236件の閲覧回数

UPDATE... the compiler should actually print an error message.

Intel's resident Fortran standards guru told me:

The problem with the test case is that they are passing a two dimensional array section to a one dimensional explicit shape array. This is wrong because 1) passing an array section requires the dummy argument be assumed shape or deferred shape (bounds are declared with colons), and 2) because they are passing a two dimensional array to a one dimensional array and the interface is explicit.

If at line 6, the dimensions of a are declared as “a(:, :)”, it compiles fine an produces the output.


Harald1
新規コントリビューター II
2,225件の閲覧回数

Would the resident Fortran standard guru please explain this?

For dummy arguments of intrisinc types, this works by F2018: 15.5.2.11 Sequence association.  I do not see a reason for this to not apply here, so any helpful pointer is appreciated.

 

Harald1
新規コントリビューター II
2,217件の閲覧回数

Here's an extended version that allows comparison of intrinsic type dummy and class(*) dummy:

 

module m
  implicit none
contains
  subroutine s(a, n)
    integer,  intent(in) :: n
    class(*), intent(in) :: a(n)

    select type(a)
    type is(integer)
       print *,'a is integer, a=', a
    class default
       print *,'a is unsupported type'
       stop 1
    end select
  end
  subroutine t(a, n)
    integer, intent(in) :: n
    integer, intent(in) :: a(n)
    print *,'subroutine t: a=', a
  end
end

program p
  use m
  implicit none
  integer :: b(2,2) = reshape([21, 22, 23, 24], [2,2])

  print *,b
  call s (b,4) ! OK
  call t (b,4) ! OK
  print *
  print *,b(:,1::2)
  call s (b(:,1::2),2) ! OK
  call t (b(:,1::2),2) ! OK
  print *
  print *,b(1::2,:)
  call s (b(1::2,:),2) ! bad
  call t (b(1::2,:),2) ! OK
  print *
  print *,b(2::2,:)
  call s (b(2::2,:),2) ! bad
  call t (b(2::2,:),2) ! OK
  print *
  print *, "With an explicit temporary:"
  call s ((b(2::2,:)),2) ! this is now OK!
  call t ((b(2::2,:)),2) ! also OK
end

 

So for the subroutine t with a dummy with explicit-shape array of type integer I get what I expect.  With class(*) I'd need an explicit temporary.

 

Steve_Lionel
名誉コントリビューター III
2,181件の閲覧回数

I'm afraid that I'm on Harald's side here - there is no requirement that the dummy argument be assumed-shape. Sequence association does apply. 

F2018 15.5.2.4

p18 Except when a procedure reference is elemental (15.8), each element of an array actual argument or of a sequence in a sequence association (15.5.2.11) is associated with the element of the dummy array that has the same position in array element order (9.5.3.2).

 

The compiler would have to do copy-in (and copy-out if not INTENT(IN) or a vector subscript.)

Barbara_P_Intel
従業員
2,175件の閲覧回数

After more research and discussion behind the scenes, the Fortran gurus determined that the original reproducer is valid code and Intel Fortran has a bug. Bug is filed as a runtime issue.



FortranFan
名誉コントリビューター III
2,163件の閲覧回数

@Barbara_P_Intel ,

It is not convincing this is a run-time issue only.  The evidence is this is a combination issue with the compile-time actions toward the handling of unlimited polymorphic type with the explicit shape received argument.  Because if you try with an integer type as opposed to unlimited polymorphic, you will see the program response is as expected by OP:

module m
contains
   subroutine s(a, n)
      integer, intent(in) :: n
      integer, intent(in) :: a(n)
      print *,'a is integer, a=', a
   end
end

You many want to review this with the Intel Fortran team. 

Barbara_P_Intel
従業員
2,155件の閲覧回数

@FortranFan, when I said "runtime issue" I meant that the compiler need not print an error message since the code is legal Fortran.

The compiler is indeed generating bad code for this case. That's the bug.



Barbara_P_Intel
従業員
1,787件の閲覧回数

With the release of 2024.0, both ifx and ifort are printing the correct answers at runtime.

Please check out the new releases.


Harald1
新規コントリビューター II
1,768件の閲覧回数

The testcase is fixed, indeed!

Thanks!

 

返信