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

catastrophic error using automatic arrays in module procedure declarations (in interface block)

zp3
Beginner
2,290 Views

Hi I'm getting a catastrophic error when trying something like this:

module foo_mod
    ...
    interface
        ...
        module subroutine foo(lb,v)
            integer(IK), intent(in) :: lb
            real(RK), intent(inout) :: v(lb,:)
        end subroutine foo
        ...
    end interface
    ...
  contains
    ...
    module procedure foo
        ...
    end procedure foo
    ...
end module foo_mod

I'm using ifort 16.0 beta. This problem looks somehow critical to me because the method above seems to be the only way to pass the lower bound of an array slice from a caller to a subroutine.

Thanks!

0 Kudos
21 Replies
Steven_L_Intel1
Employee
2,013 Views

Please use Intel Premier Support to report this and supply a complete test case. Thanks.

0 Kudos
zp3
Beginner
2,013 Views

Sorry, I haven't enough time for such; I encountered this problem lately and just thought that maybe someone might be interested to know... I by myself can't wait for a fix either way, I'll simply rewrite the code to get it work.

But thanks nevertheless

0 Kudos
mecej4
Honored Contributor III
2,013 Views

zp3 wrote:
This problem looks somehow critical to me because the method above seems to be the only way to pass the lower bound of an array slice from a caller to a subroutine.

I cannot reconcile this statement with the declaration

...
            real(RK), intent(inout) :: v(lb)
...

In this declaration, 'lb' is the upper bound and the implicit lower bound is 1. If you wanted to make 'lb' the lower bound, you should have written

...
            real(RK), intent(inout) :: v(lb:)
...

 

0 Kudos
FortranFan
Honored Contributor III
2,013 Views

zp3 wrote:

Sorry, I haven't enough time for such; I encountered this problem lately and just thought that maybe someone might be interested to know... I by myself can't wait for a fix either way, I'll simply rewrite the code to get it work.

But thanks nevertheless

@zp3,

If you're using 16.0 beta and making use of the free trial and its benefits, it will be nice if you care to follow up on all issues and report them to Intel Premier Support as requested by Intel for the beta evaluation.  I think this should be the basic "honor code" amongst all us developers since it is ultimately all the coder who benefit e.g., I've "selfish" reasons to ensure a fully functional, perfect Intel Fortran compiler given my heavy use of it, especially with submodules.  Note the use of "module procedure" syntax with interfaces is quite relevant for submodules.  So you'd be remiss in not following up on errors.  And this is especially true in this case since you had the basic elements of a test case right there and you'd already sunk some time into this thread.  Based on your original post, it took me all of 2 minutes to create a reproducer:

module foo_mod

   use, intrinsic :: iso_fortran_env, only : IK => int32, RK => real64

   interface

      module subroutine foo(lb,v)
      
         integer(IK), intent(in) :: lb
         real(RK), intent(inout) :: v(lb)
         
      end subroutine foo

   end interface

contains

   module procedure foo

   end procedure foo

end module foo_mod

Upon compilation using 16.0 beta,update 2 on Windows (not Linux, though I'd think one can reproduce this on Linux too) :

Compiling with Intel(R) Visual Fortran Compiler 16.0.0.063 [Intel(R) 64]...
m.f90
C:\..\m.f90(7): remark #7712: This variable has not been used.   
C:\..\m.f90(1): catastrophic error: **Internal compiler error: internal abort** Please report this error along with the circumstances in which it occurred in a Software Problem Report.  Note: File and line given may not be explicit cause of this error.
compilation aborted for C:\..\m.f90 (code 1)

 

By the way, did you indeed mean to declare your v variable as v(lb)?  That defines the extent as lb but your comments mention lower bound; did you mean v(lb:) instead?

Steve, by the way,  the ICE goes away if v is declared as assumed shape, v(:), but the ICE remains with v(lb:) syntax..

0 Kudos
Steven_L_Intel1
Employee
2,013 Views

Interesting. I tried to reproduce it on Windows but couldn't. I will try Linux.

0 Kudos
Steven_L_Intel1
Employee
2,013 Views

What compile options did you use to see the error?

0 Kudos
zp3
Beginner
2,013 Views

@mecej4, FortranFan: Sorry for that, it's a speed error, it should be v(lb,:), but for me that makes no difference, no kind of automatic array works...

@Steve: Sorry for unclean testing, now I could retrace the error to the compiler flag -ftrapuv. And why did I use the concept incorrect? I know that the 'module procedure' implementation part should be located in a submodule, but that should make no difference... 

@FortranFan: I'm not using anything for free here. I'm using the beta because of the submodule support

0 Kudos
FortranFan
Honored Contributor III
2,013 Views

Steve Lionel (Intel) wrote:

What compile options did you use to see the error?

Steve,

It looks like you need /debug (e.g., /debug:full) to reproduce the error.

By the way, I've submitted this at Intel Premier Support: the reference number is : 6000113253.

Thanks,

0 Kudos
FortranFan
Honored Contributor III
2,013 Views

zp3 wrote:

.. 

@FortranFan: I'm not using anything for free here. I'm using the beta because of the submodule support

Call whatever you want, but since you brought up the issue of time in other posts, note you're getting access to submodules nearly half a year ahead of when it would have been available otherwise which is a huge benefit.  I feel some courtesy to Intel is due by the coders.

0 Kudos
Steven_L_Intel1
Employee
2,013 Views

Ah - /debug does it. Thanks, FortranFan! Issue ID is DPD200372476.

zp3, I deleted my comment suggesting you are using the syntax incorrectly as I was mistaken. I admit I had never seen module procedure used that way before, but after studying the standard I see it is legal (though I can't see why one would do it that way.)

0 Kudos
zp3
Beginner
2,013 Views

FortranFan wrote:

I feel some courtesy to Intel is due by the coders.

That's why I posted the error here. And btw. submodules are part of the standard since F2008, so my recognition as 'huge benefit' is limited. I would say it was about time to be implemented finally...

@Steve: I'm using it because that way I can cleanly separate the interface declaration part from the rest and I do not need to declare it eventually redundantly multiple times

0 Kudos
FortranFan
Honored Contributor III
2,013 Views

Steve Lionel (Intel) wrote:

.. module procedure .. studying the standard I see it is legal (though I can't see why one would do it that way.)

I suppose a coder would use it this way because of a desire to avoid redeclaration of the procedure interface part which would usually be with submodules or having a need to create explicit interface blocks for whatever reason.  But I too do not think it is a "good coding practice".  

0 Kudos
zp3
Beginner
2,013 Views

I did some further testings and I found out, that 'v(lb)' only compiles when -g or -debug or maybe other flags are not set. The version v(lb:) compiles under no circumstances on my platform. To see this please use the following code

module foo_mod

    interface

        module subroutine foo(lb,v)
            integer, intent(in) :: lb
            real, intent(inout) :: v(lb:)
        end subroutine foo

    end interface

  contains

    module procedure foo
        v(lb)=1.0
    end procedure foo

end module foo_mod

 

0 Kudos
Steven_L_Intel1
Employee
2,013 Views

Thanks.

0 Kudos
FortranFan
Honored Contributor III
2,013 Views

zp3 wrote:

I did some further testings and I found out, that 'v(lb)' only compiles when -g or -debug or maybe other flags are not set. The version v(lb:) compiles under no circumstances on my platform. ..

I'm not sure what array-slice syntax v(lb:) buys you - as I mentioned in message #5, using assumed shape syntax as in v(:) seems to work.  Perhaps you can use it as a workaround and employ the slice (lb:) in the execution section of procedure where v is used instead of restricting it so at the declaration level?

0 Kudos
zp3
Beginner
2,013 Views

FortranFan wrote:

I'm not sure what array-slice syntax v(lb:) buys you - as I mentioned in message #5, using assumed shape syntax as in v(:) seems to work.  Perhaps you can use it as a workaround and employ the slice (lb:) in the execution section of procedure where v is used instead of restricting it so at the declaration level?

Well the stuff I'm doing is quite complicated, to keep it simple: One has a matrix where indices have a mathematical meaning, not starting with 1. From the nature of the problem one can compute elements column-wise:

...
real, allocatable :: mat(:,:)
...
allocate(mat(k_min:k_max,l_min:l_max))
...
do l=l_min,l_max
    foo(...,k_min,mat(:,l))
end do
...

using the mathematically correct indices makes programming a lot easier and therefore more readable. What I'll do now is to port the do loop into the function foo, so that I can pass the whole array as allocatable where bounds are retained; that's mathematically not very reasonable but probably the best I can do...

0 Kudos
FortranFan
Honored Contributor III
2,013 Views

zp3 wrote:

Well the stuff I'm doing is quite complicated, to keep it simple: One has a matrix where indices have a mathematical meaning, not starting with 1.  ..

A temporary workaround until the problem is fixed with module procedures may be to use pointers, caveat emptor of course!

module m

   use, intrinsic :: iso_fortran_env, only : IK => int32, RK => real64

   interface

      module subroutine foo( lb, v )

         integer(IK), intent(in)         :: lb
         real(RK), intent(inout), target :: v(:)

      end subroutine foo

   end interface

contains

   module procedure foo

      real(RK), pointer :: vcol(:)
      
      print *, " enter foo: "
      
      vcol(lb:) => v
      print *, " lbound(vcol) = ", lbound(vcol, dim=1)
      print *, " ubound(vcol) = ", ubound(vcol, dim=1)
      vcol => null()
      
      print *, " exit foo: "

   end procedure foo

end module m
program p

   use m, only : IK, RK, foo

   implicit none

   integer(IK) :: istat
   integer(IK), parameter :: k_min = -1
   integer(IK), parameter :: k_max = 1
   integer(IK), parameter :: l_min = -1
   integer(IK), parameter :: l_max = 1

   real(RK), allocatable :: mat(:,:)
   
   allocate( mat(k_min:k_max, l_min:l_max), source=0.0_RK, stat=istat )
   if (istat /= 0) then
      print *, " error allocating mat"
      stop
   end if

   call foo( k_min, mat(:,1) )

   deallocate( mat, stat=istat)

   stop

end program p
  enter foo:
  lbound(vcol) =  -1
  ubound(vcol) =  1
  exit foo:
Press any key to continue . . .

 

0 Kudos
zp3
Beginner
2,013 Views

Thanks for your advice FortranFan, nice idea! I'll consider doing that.

The only thing I always dislike on pointers is the fact that one has to use the target keyword; because of the circumstance that in my code even the caller only receives the matrix as an actual argument, I'ld have to change the interface (adding the target keyword) through the whole caller tree, that's ... suboptimal :/ . I could change the matrix itself to a pointer, but until now I've always tried to avoid using pointers too much since Fortran is probably more safe/optimizable when using allocatables...

0 Kudos
ereisch
New Contributor II
2,013 Views

I doubt this is a related problem, but I noticed I get a similar catastrophic error when compiling some Fortran files (on Linux) with "-check interfaces" enabled, and the ".mod" files the compiler pulled in for interface checking were built with a prior version of the compiler.  In our situation, we had to remove all of the .mod files previously generated and re-create them with the new compiler version (or disable interface checking) to get the compile to succeed.  Since you use F90 modules here, it is almost certainly pulling in .mod files, so make sure they're built with the same version.

0 Kudos
Steven_L_Intel1
Employee
1,922 Views

I am told that the problem zp3 reported will be fixed for the final 16.0 release.

ereisch, It is very unlikely your problem is related. If you can reproduce it in a current compiler, please report it in a separate topic or through Intel Premier Support.

0 Kudos
Reply