Silverfrost Forums

Welcome to our forums

[ADVICE] /OPT with /64 - Internal Compiler Error

30 Aug 2019 10:50 #24271

When running /64 /OPTIMISE compilation, I'm getting various floating point exception internal compiler errors cropping up. When running /64 /FU, compilation works.

As a relative beginner, I'm trying to get an idea of how/whether to deal with these, so have some questions:

  1. Is there a comprehensive list of compiler optimisations, in relatively plain English, for me to study?
  2. When /OPT compilation is done, what are some of the most frequent issues arising?
  3. Is the issue I'm seeing (ICE FPE) common, or is it something that would be worth putting into a minimally reproducible example for the forum?
30 Aug 2019 11:03 #24272

Please provide a simple example of the failure and then we can work from that.

30 Aug 2019 12:15 #24273

Hopefully the source of teh problem is unidentified coding bugs. If there are bugs in your program, /OPT is more likely to find them. Try using /CHECKMATE and see what happens then. This can help with identifying those annoying bugs.

30 Aug 2019 5:11 #24278

To ahalls_dsc:

Are you getting errors during compilation and/or linking, or are you getting errors when you run the EXE that got built?

Only the former can be called ICE, and their occurrence should be reported along with the source files being compiled.

On the other hand, if an EXE gets built the errors occur when that EXE is run, those are not internal compiler errors. Floating point errors that arise when your EXE is run can be caused by bugs in the code generation process, but more often such bugs arise in the user's code.

It is not possible to give you a list of conditions that lead to ICEs. These are errors that are not expected at all, and need considerable study when they occur. In fact, such conditions are nearly impossible to reproduce based on a mere description of the program. A full bug report is needed with all the information that is relevant: compiler version, OS details, CPU, memory available, complete source code and related files, instructions to build and run, and any data files that are needed.

30 Aug 2019 7:53 #24279

Thanks all.

It is likely errors in the code; definitely an ICE as it occurs when compiling.

Will get something together. Watch this space.

30 Aug 2019 9:18 #24280

The following code:

      SUBROUTINE rdgenc_purp(jyr)
      INTEGER,INTENT(IN) :: jyr
      INTEGER,PARAMETER :: JAYEAR=803,JBYEAR=804,LXTZN=1714,
     & MXNSEW=4,MXNCOT=4
      REAL, DIMENSION(1:lxtzn,1:lxtzn,1:mxnsew,1:mxncot,JAYEAR:JBYEAR)
     &  :: gchowkswcoyr

      gchowkswcoyr(:,:,:,:,jyr) =  1.0E05

      ENDSUBROUTINE

compiled thus:

ftn95 rdgenc_purp.for /64 /defint_kind 3 /deflog_kind 1 /no_com /optimise /im /mod_path \source\mods /cfpp /define DEBUG 0

produces the following compiler message in v8.51:

[FTN95/x64 Ver. 8.51.0 Copyright (c) Silverfrost Ltd 1993-2019]
     Licensed to:  Alistair Halls
     Organisation: David Simmonds Consultancy

0005)       REAL, DIMENSION(1:lxtzn,1:lxtzn,1:mxnsew,1:mxncot,JAYEAR:JBYEAR)
0006)      &  :: gchowkswcoyr
WARNING - Variable GCHOWKSWCOYR has been given a value but never used
*** Internal compiler error - floating point exception

    1 ERROR [rdgenc_purp.FOR] - Compilation failed.

Entirely possible that a) there are issues with the code, b) there are issues with the compiler options or c) both of the above...

NB the subroutine this is taken from is much larger, with various other USE and INCLUDE statements. The purpose is to read a specific subset of a data file, according to the parameters in the array which is causing the issue.

31 Aug 2019 1:11 #24281

I don't have Ver 8.51 installed, but I suspect there is overflow in calculating the array offset. ( lxtzn * lxtzn * mxnsew * mxncot * JBYEAR = 37,791,807,744 ) Ver 8.4 does not fail for my test of your example.

Could you try the following adaptation. SUBROUTINE rdgenc_purp(jyr) INTEGER,INTENT(IN) :: jyr INTEGER,PARAMETER :: JAYEAR=803,JBYEAR=804,LXTZN=1714, & & MXNSEW=4,MXNCOT=4 INTEGER,PARAMETER :: J0YEAR=JAYEAR-1

      REAL, DIMENSION(1:lxtzn,1:lxtzn,1:mxnsew,1:mxncot,JBYEAR-J0YEAR)  &
     &  :: gchowkswcoyr 

      gchowkswcoyr(:,:,:,:,jyr-J0YEAR) =  1.0E05 

      END SUBROUTINE
31 Aug 2019 2:02 #24282

Quoted from JohnCampbell I don't have Ver 8.51 installed, but I suspect there is overflow in calculating the array offset. ( lxtzn * lxtzn * mxnsew * mxncot * JBYEAR = 37,791,807,744 )

The array has its fifth dimension varying from JAYEAR to JBYEAR, not 1 to JBYEAR, so that you should have had (JBYEAR-JAYEAR+1) = 2 instead of JBYEAR in the size calculation. That would make the size of the array to be about 94 million, i.e., about 0.4 GB.

When I compiled the original source with Ver 8.51, but without all those options, it compiled fine. I suggest removing the options one by one to see which one (if it is just one) caused the compiler to fault.

31 Aug 2019 2:55 #24283

My mistake, I left off /opt.
FTN95 /64 /opt also fails with Ver 8.40 No surprises with this result.

mecej4, it would depend how the offset is calculated. Perhaps /opt tries to simplify the offset calculation to gchowkswcoyr(i,j,k,l,m) as (((m*mxncot+l)*mxnsew+k)*lxtzn+j)lxtzn+i - offset where offset = (((yayearmxncot+1)*mxnsew+1)*lxtzn+1)*lxtzn+1 - 1, ie calculating for gchowkswcoyr(1,1,1,1,yayear) ; the minimum address

31 Aug 2019 8:31 #24285

I can confirm that the following adaptation compiles fine:

      SUBROUTINE rdgenc_purp(jyr)
      INTEGER,INTENT(IN) :: jyr
      INTEGER,PARAMETER :: JAYEAR=803,JBYEAR=804,LXTZN=1714,
     & MXNSEW=4,MXNCOT=4
      INTEGER, PARAMETER :: J0YEAR=JAYEAR-1
      REAL, DIMENSION(1:lxtzn,1:lxtzn,1:mxnsew,1:mxncot,JBYEAR-J0YEAR)
     &  :: gchowkswcoyr

      gchowkswcoyr(:,:,:,:,jyr-J0YEAR) =  1.0E05

      ENDSUBROUTINE

I will return once the exe has been tested.

1 Oct 2019 6:16 #24448

This internal compiler error has now been fixed with the effect that the error is now reported as 'Array size is too big when optimising'. This will be in the next release of FTN95.

2 Oct 2019 11:29 #24450

Paul,

The actual array size is not too big, but I was guessing that the optimised approach may utilise a virtual array that is too big. Shouldn't there be a test that 'if this were the case' then this guessed optimising approach should be rejected ?

3 Oct 2019 8:39 #24451

I forgot to mention that the failure can be avoided by adding /INHIBIT_OPT 63. An alternative in this particular case is to change the range of the final dimension from JAYEAR:JBYEAR to 1:JBYEAR-JAYEAR.

John

The optimiser fails with an arithmetic overflow whilst calculating the bounds of the array. An initial investigation has shown that a major revision would be required at this point of the code in order to fix the problem. So the current 'fix' has been limited to that of providing a better failure message.

4 Oct 2019 10:47 #24452

I suppose that I shouldn't be surprised that there are at least 63 optimisation 'actions', because reading the corresponding list for gfortran makes one's head spin with the number that they have.

Mind you, it does make me wonder what are Nos 1 .. 62 and, and what are Nos 64 et seq.

Not that it makes any difference to me, as FTN95 without /opt is adequate, but a tiny bit of me hankers after a speed improvement, even if it's meaningless to me !

Eddie

4 Oct 2019 4:31 #24455

Unfortunately the available documentation is very limited and incomplete.

Please login to reply.