1

I'm trying to compile some Fortran code but get errors about: kind value. I am compiling it with Silverfrost (PLATO FN95). Errors say about the precision format of variables. For some reason, using " kind = 8" is necessary. The code is shown below:

  function diaedg ( x0, y0, x1, y1, x2, y2, x3, y3 )

  implicit none

  real ( kind = 8 ) ca
  real ( kind = 8 ) cb
  integer ( kind = 4 ) diaedg
  real ( kind = 8 ) dx10
  real ( kind = 8 ) dx12
  real ( kind = 8 ) dx30
  real ( kind = 8 ) dx32
  real ( kind = 8 ) dy10
  real ( kind = 8 ) dy12
  real ( kind = 8 ) dy30
  real ( kind = 8 ) dy32
  real ( kind = 8 ) s
  real ( kind = 8 ) tol
  real ( kind = 8 ) tola
  real ( kind = 8 ) tolb
  real ( kind = 8 ) x0
  real ( kind = 8 ) x1
  real ( kind = 8 ) x2
  real ( kind = 8 ) x3
  real ( kind = 8 ) y0
  real ( kind = 8 ) y1
  real ( kind = 8 ) y2
  real ( kind = 8 ) y3

  tol = 100.0D+00 * epsilon ( tol )

  dx10 = x1 - x0
  dy10 = y1 - y0
  dx12 = x1 - x2
  dy12 = y1 - y2
  dx30 = x3 - x0
  dy30 = y3 - y0
  dx32 = x3 - x2
  dy32 = y3 - y2

  tola = tol * max ( abs ( dx10 ), abs ( dy10 ), abs ( dx30 ), abs ( dy30 ) )
  tolb = tol * max ( abs ( dx12 ), abs ( dy12 ), abs ( dx32 ), abs ( dy32 ) )

  ca = dx10 * dx30 + dy10 * dy30
  cb = dx12 * dx32 + dy12 * dy32

  if ( tola < ca .and. tolb < cb ) then

    diaedg = -1

  else if ( ca < -tola .and. cb < -tolb ) then

    diaedg = 1

  else

    tola = max ( tola, tolb )
    s = ( dx10 * dy30 - dx30 * dy10 ) * cb + ( dx32 * dy12 - dx12 * dy32 ) * ca

    if ( tola < s ) then
      diaedg = -1
    else if ( s < -tola ) then
      diaedg = 1
    else
      diaedg = 0
    end if

  end if

  return
end

And the errors are shown below:

error 600 - The KIND number should be 1, 2, 3, 4, or 7

ALIN
  • 62
  • 1
  • 6
  • 4
    If a careful study of https://stackoverflow.com/questions/838310/fortran-90-kind-parameter (and possibly of other Qs and As on the topic) doesn't help you resolve the problem then refine your question. But of one thing be certain: that compiler is telling you it won't let your code use `kind = 8` and something's going to have to give way. – High Performance Mark Aug 08 '20 at 15:27
  • To see what the different KIND parameters mean on plato, click on help, type **Real KINDs** in the search, select **Real KINDs**. It will list the allowed values, what they mean and what the ranges are. – cup Aug 08 '20 at 17:39
  • 4
    We say, do not use `kind=8` all the time. But people will just wave their hand and say: I am using gfortran or Intel Compiler and therefore it is fine. Well, you do not know what compiler will some other user of your code be using... – Vladimir F Героям слава Aug 08 '20 at 17:59
  • @cup I searched on help library and just find "1,2,3" as allowed values but as I showed above in error comment, 4 and 7 are also allowed values. What are they:??? – ALIN Aug 09 '20 at 07:31
  • @HighPerformanceMark Thanks for your useful comment. – ALIN Aug 11 '20 at 16:23

3 Answers3

1

"For some reason, using kind = 8 is necessary." No it is not necessary. The author of the code might have thought that it is necessary, but there are always better alternatives as explained at Fortran 90 kind parameter

Your main option is to make a search and replace all kind=8 with something else. With what exactly depends on how much you want to deal with that code. The fastest will be to change it to 2, more portable will be kind(1d0) or the respective selected_real_kind(), which most likely will all do the same but may differ for some other compiler in future. Using some constants from some intrinsic modules would require inserting the use statements and that may or may not be simple.


"4 and 7 are also allowed values. What are they:" That is easy to test for you, just try it and use some inquire functions like bit_size(),epsilon() or print some numeric values stored there. Or it might be somewhere in the manual but you are more likely to have a good access to that, I do not have your compiler, so I cannot try it myself.

But be careful with the 4 value, because you have integer(kind=4) in you code and you might have also real(kind=4) somewhere. Check that you don't actually need to change it to just integer or real or to kind 1 or something else.

albert
  • 8,285
  • 3
  • 19
  • 32
1

Hard wired kind numbers are a dangerous thing because they are not guaranteed to be compatible between Fortran compilers. You are using Silverfrost FTN95 and their real kind values are 1,2 and 3: https://www.silverfrost.com/ftn95-help/kinds/real_kinds.aspx

The warning you see is the compiler telling you that it does not recognise the kind value. I am guessing that kind=8 implies a 64-bit real (because they take up 8 bytes). You could use SELECTED_REAL_KIND and SELECTED_INT_KIND to choose a kind values like this:

integer,parameter :: kr_8 = selected_real_kind(12)  ! 12-digits of precision
integer,parameter :: ki_4 = selected_int_kind(8)  ! 8 digits of precision
real ( kind = k_8 ) ca
real ( kind = k_8 ) cb
integer ( kind = ki_4 ) diaedg
real ( kind = k_8 ) dx10
Rob
  • 3,315
  • 1
  • 24
  • 35
1

4 and 7 are also allowed values. What are they:???

KIND=4 and KIND=7 only apply to the 64-bit compiler. It is for Windows Handles. This is in the vendor documentation

https://www.silverfrost.com/ftn95-help/devel/x64_compiler.aspx

There is a silverfrost compiler option /ALT_KINDS which allows KIND=8.

https://www.silverfrost.com/ftn95-help/options/default_kind_values_for_intrinsic_types.aspx

If you are using plato,

  1. from the menu select Project/Properties.
  2. Under Compiler Options select Miscellaneous.
  3. Click on Extra compiler options.
  4. In the Params box, enter /ALT_KINDS.
  5. Click OK to close

Your program should compile with KIND=8 with a comment that it is potentially not portable. If you are using silverfrost as a Visual Studio Add in, the process is similar

  1. Right click on the Project name and select Properties.
  2. Under Compiler Options, select Miscellaneous.
  3. Edit the line with Extra Compiler Options and add /ALT_KINDS.
cup
  • 7,589
  • 4
  • 19
  • 42