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

Floating point invalid operation

fourreal
Beginner
3,869 Views

I've just upgraded to Fortran 2016 from 2013 and now throw a floating point invalid operation exception 0x90.  The error is trapped at the declaration of a function.  I've reduced to the parameter list to a few reals and integers, and the parameters look good before the function is called and at the top of the function.  The exception is thrown before the first executable statement of the function.

I have tried different /fpe settings, debug & release, and throwing salt over my shoulder.  Any help would be appreciated.

Windows 10, Visual Studio 2015

 

 

0 Kudos
1 Solution
mecej4
Honored Contributor III
3,879 Views

I'll have to reformat the build log from html to txt before I'm allowed to upload it.

You can place files of any type into a Zip file and attach the Zip file in your response.

You use the options /Qsave /align:commons /Qtrapuv /Qinit:zero. If you are debugging code, especially code written in recent decades, /Qsave and /Qinit:zero should not be used -- they hide lots of bugs. Furthermore, after you use these options, /Qtrapuv will trap nothing that I can think of, since you have replaced uninitialized variables, if any, by zero.

The net effect of using bug-hiding options such as these with buggy code is to make finding the bugs much harder, and possibly to hide the bugs for decades if these options are also used in compiling production code.

View solution in original post

0 Kudos
36 Replies
Arjen_Markus
Honored Contributor I
2,947 Views

Can you post the code so that people can reproduce the problem? Without it we can only speculate.

0 Kudos
mecej4
Honored Contributor III
2,947 Views

From the description, "The error is trapped at the declaration of a function", I gather that you observed the code in a symbolic debugger. But, since declarations are not executable statements, the actual location of the FPE is somewhere nearby, either in the code that sets up the call, or in the code near the beginning of the routine.

Since we run code every day that matches your description and runs without triggering FPEs, there must be some specific problem with your particular code. As Arjen said, you will need to provide sample code or, even better, a complete reproducer.

0 Kudos
fourreal
Beginner
2,947 Views

The code:
        real*4 FUNCTION AREABU (idxOFlange, idxIFlange, idxWeb, D, holes, tl, isARafter)
     implicit none

     include 'inv.h'
     
        integer idxOFlange, idxIFlange, idxWeb
        real*4 D
     integer holes, tl, isARafter
     real*4 net  /0.0/
     real*4 bf /0.0/, tf/0.0/, bf2/0.0/, tf2/0.0/, tw /0.0/
        real*4  girtBoltDiameter /0.5/, purlinBoltDiameter /0.5/
        type(flange_data), pointer :: ifPtr, ofPtr
        type(web_data), pointer :: webPtr
     
        ifPtr => flange(idxIFlange)
     bf  = ifPtr.width
     tf  = ifPtr.thickness
        ofPtr => flange(idxOFlange)
     bf2 = ofPtr.width
     tf2 = ofPtr.thickness
        webPtr => web(idxWeb)
     tw  = webPtr.thickness
 
     if (holes) then
      if (tl) then
       if (isARafter) then
        net = bf2 - 2.0 * (purlinBoltDiameter + 0.0625)
       else
        net = bf2 - 2.0 * (girtBoltDiameter + 0.0625)
       end if
       bf2 = min(bf2, 5.0/6.0 * ofPtr.Fu/ ofPtr.Fy * net)
      else
       if (isARafter) then
        net = bf - 2.0 * (purlinBoltDiameter + 0.0625)
       else
        net = bf - 2.0 * (girtBoltDiameter + 0.0625)
       end if
       bf = min(bf, 5.0/6.0 * ifPtr.Fu/ ifPtr.Fy * net)
      end if
     end if
     AREABU = BF*TF + BF2*TF2 + (D-TF-TF2)*TW
     RETURN
     END
 
The debug output just before the crash:
idxOFlange = 2, idxIFlange = 2, idxWeb = 333
D = 27.75, holes = 0, tl = 0, isARafter = 0
 
This accurately reflects the values passed.
 
 
 
0 Kudos
Arjen_Markus
Honored Contributor I
2,947 Views

That is one part, the next one is: what does the code look like that calls the routine? Please try to make it so that we can create a program from this - a "reproducer".

0 Kudos
andrew_4619
Honored Contributor II
2,947 Views

Does this function crash the first time it is called?  real*4 net  /0.0/, for example net is reasssigned so may not be zero or may be uninitialised dependant upon compiler options on a subsequent call. the dot in  ifPtr.width is not standard fortran it should be a % BTW.

0 Kudos
mecej4
Honored Contributor III
2,948 Views

Because your code contains user-defined types, which I presume are declared in the include file "inv.h",  not much can be said or done unless the include file is provided.

0 Kudos
fourreal
Beginner
2,948 Views

 

This is the simplified calling code:
real*4   d,  sarea
integer isFalse
isFalse = 0
sarea = AREABU(ele.bu_oflange.index, ele.bu_iflange.index, ele.bu_web.index, d, isFalse, isFalse, isFalse)

Some definitions:

record /eleprops/ ele
 structure/eleprops/
  union
   map
      real*4 bu_D1,  bu_D2,  bu_minweb, bu_minflange
      record/invmap/ bu_oflange,  bu_web,  bu_iflange
   end map

. . . 

structure/invmap/

  integer*2 type, index

end structure


 

 

 

0 Kudos
fourreal
Beginner
2,948 Views

The function does crash the first time it is called.  And the code is profuse with the dot notation for structures.

This is actually the second version of the crashing function, the original being AREA.  I created it to experiment with different ways of trying to dodge the FP error.  The original AREA, called from other places, sometimes runs and sometimes crashes.  It's possible that the original function has executed unaltered since 1987.

 

0 Kudos
mecej4
Honored Contributor III
2,948 Views

The fragments of information that you added do not serve to give us a complete picture. Rather, they raise more questions. I could speculate that your code has some undefined variables (or undefined components of your non-standard structures), and their presence has gone unnoticed until now.

0 Kudos
andrew_4619
Honored Contributor II
2,948 Views

fourreal wrote:
  It's possible that the original function has executed unaltered since 1987.

Not likely since the pointer and derived types stuff is Fortran 90. You have quite a mishmash of non-standard and obsolete  things in your code. When you do that some unforeseen (undefined) things can rear their heads and bite you. Having worked in the past in this instance is no guarantee of  working in the future . I recall a recent bugfix relating to use of . rather than % for example. Logical tests on integers rather than logicals is also not good practice.

It is hard to know what is wrong, you really need to make a small but complete sample that reproduces the problem and then you will get better answers rather than guesses.

0 Kudos
fourreal
Beginner
2,948 Views

The failure occurred before the addition of the pointers.  The data fields were accessed in a more traditional manner. The integers used as logicals were a grasping-at-straws measure because the VS debugger local watch lists logical as ??? but integers as shorts.  These have been returned to being logicals.

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,947 Views

>>ele.bu_oflange.index, ele.bu_iflange.index, ele.bu_web.index

Is, and how is, ele, ele.bu_oflang, eld.bu_iflange, ele.bu_web defined?

IOW is ele an allocatable or pointer .not. defined?
and/or member objects/structures of ele: bu_... allocatable or pointer .not. defined?
and/or what are the integer types (1, 2, 4, 8) of the respective index of those member objects/structures?

Have you enabled the compile time diagnostics to generate and warn on invalid interfaces?

Jim Dempsey

0 Kudos
fourreal
Beginner
2,947 Views
record /eleprops/ ele
 structure/eleprops/
 union
     map
   real*4 bu_D1, bu_D2, bu_minweb, bu_minflange
   record/invmap/ bu_oflange, bu_web, bu_iflange
  end map

 ...

structure/invmap/
 integer*2 type, index
end structure
 
ele is not allocatable. bu_* is not allocatable.  The integer type are all *2, although I have experimented with *4.
 
I'll look for the invalid interfaces flag.
 
0 Kudos
fourreal
Beginner
2,947 Views

I've reduced the function to intrinsic variable types and hard wired data.  There are no parameters.  The behavior is the same - F10 off the function declaration and throw a Floating-point invalid exception.

 The call:
    sarea = AREABU()

The function:
      real*4 FUNCTION AREABU ()
      implicit none

c     include 'inv.h'
     
        integer*4 idxOFlange, idxIFlange, idxWeb
        real*4 D
     logical*4 holes, tl, isARafter
     real*4 net  /0.0/
     real*4 bf /0.0/, tf/0.0/, bf2/0.0/, tf2/0.0/, tw /0.0/
        real*4  girtBoltDiameter /0.5/, purlinBoltDiameter /0.5/
     holes = .false.
        tl = .false.
        isARafter = .false.
        bf = 5.0
        tf = 0.3125
        bf2 = 5.0
        bf2 = 0.3125
        tw = 0.1875
        D = 27.75
     if (holes) then
      if (tl) then
       if (isARafter) then
        net = bf2 - 2.0 * (purlinBoltDiameter + 0.0625)
       else
        net = bf2 - 2.0 * (girtBoltDiameter + 0.0625)
       end if
                bf2 = min(bf2, 5.0/6.0 * 70/55  * net)
      else
       if (isARafter) then
        net = bf - 2.0 * (purlinBoltDiameter + 0.0625)
       else
        net = bf - 2.0 * (girtBoltDiameter + 0.0625)
       end if
       bf = min(bf, 5.0/6.0 * 70/55 * net)
      end if
     end if
     AREABU = BF*TF + BF2*TF2 + (D-TF-TF2)*TW
     RETURN
     END

 

 

0 Kudos
fourreal
Beginner
2,947 Views

Same invalid FP failure:
        REAL*4 FUNCTION AREABU ()
            AREABU = 9.999
            RETURN
        END

Is it possible to simplify this? Maybe I should try punch cards?

0 Kudos
andrew_4619
Honored Contributor II
2,947 Views

interesting! But, there is usually a simple answer. Can you post a complete example that fails and also the buildlog so we can also see what options are used. There are still a long list of  potential causes... 

How Is AREABU() declared in the caller? Is it declared external, is it in a module, ....

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,947 Views

#14>> The integer type are all *2, although I have experimented with *4.

#4>> integer idxOFlange, idxIFlange, idxWeb
#4>>...
#4>> integer holes, tl, isARafter

The Dummy (integer) arguments to function AREABU are declared as default INTEGER. Unless an option switch overrides this, these are declared as INTEGER(4). FORTRAN is call by reference. Without a function interface (not required), the call will not promote your INTEGER(2) reference into INTEGER(4). Effectively, without an interface, the references to your caller's INTEGER(2) will be treated as INTEGER(4). IOW they will overlap. This in turn will cause the dereference of idxOFlange, idxIFlange, idxWeb to read in two bytes following the actual arguments (as additional precision), thus (likely) causing index out of range.

#16>>Same invalid FP failure:     REAL*4 FUNCTION AREABU ()

Did your call, call with no arguments?

Is AREABU in a .LIB or .DLL?

Note, these questions would be easily answered by you supplying a simple (complete) reproducer.

Jim Dempsey

0 Kudos
fourreal
Beginner
2,947 Views

I reduced the call to:
    sarea = AREABU()

​ and the function to:
        REAL*4 FUNCTION AREABU ()
            AREABU = 9.999
            RETURN
        END

This is all tucked inside a DLL. The debugger will step to the FUNCTION statement.  Stepping off the FUNCTION statement generates a floating point invalid operation exception.  This happens without a floating point operation - not even an assignment.  No parameters are passed so I can't corrupt or misalign a call list.  There are no integers, default or otherwise.  There are no logicals.  I don't have a language issue.  Can I eliminate a linker issue? I'll guess it's a compiler issue.

 

 

0 Kudos
mecej4
Honored Contributor III
2,947 Views

So far (19 posts already!) you have not established that there is a compiler issue. Here is a non-reproducer that serves only to demonstrate that your list of attributes and features is insufficient to enable the problem, if there exists one, to be investigated. It is based on your statements.

The DLL code:

c
        REAL*4 FUNCTION AREABU ()
            AREABU = 9.999
            RETURN
        END
c

The program that calls the DLL:

c
      program parea
      implicit none
      real AREABU, S
      S = AREABU()
      print *,' S = ',S
      end
c

I built the DLL and the EXE using the 16.0.4.246 compiler for X64 on Windows 10.

ifort /LD /Zi areabu.f /link /export:AREABU
ifort /Zi parea.f areabu.lib

Running the resulting EXE in the debugger displays completely normal, if boring, behavior. No exceptions of any kind, one line of output with expected result.

I hope that you can see from this counter-example that we really need a reproducer from you. The ball is very much in your court.

 

0 Kudos
andrew_4619
Honored Contributor II
2,574 Views
    Program test
        implicit none
        real(4)           ::  sarea
        real(4), external :: AREABU
    
        sarea = AREABU()
        print *, sarea
    end 
   
    REAL*4 FUNCTION AREABU ()
        AREABU = 9.999
        RETURN
    END

The above program compiles and runs just fine. So what is different in your test case which we have not seen. If your test case is built into an application I would suggest that the stack has already been corrupted by some  problem unrelated to AREABU. Do you have run time option /check:stack on compilation?

0 Kudos
Reply