forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Fortran 2003 and 2008 features
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9, 10  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Suggestions
View previous topic :: View next topic  
Author Message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2388
Location: Yateley, Hants, UK

PostPosted: Fri Aug 26, 2022 10:07 am    Post subject: Reply with quote

Paul,

So that's "smartish".

Smart enough for me, though.

Eddie
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Fri Aug 26, 2022 11:01 pm    Post subject: Reply with quote

Paul,
I'm trying to say that code does not complain if i define a and b in the module, it does not complain when i define a and b in CONTAINS like Ken revealed, but when i define a and b directly just one line before calling sub1(a=b) the compiler abruptly remembers the Standard and tells me that i forgot damn interface.
Sounds kind of unusual, right?
And the resolution i proposed is that despite asking for the interface is formally correct according to Standard but by the common sense compiler has to violate Standard and do not ask for interface just warning that in other circumstances in similar situations here could be an error (when two programs are in separate files). In my case with sub1(a=b) exactly there is no error in any circumstances as a and b are fully defined.

That how smart compiler should do. And FTN95 in many cases doing like that checking arguments of subroutines on match and mismatch. Can it do that at compile time instead of run time with /checkmate? Ideally it should.
Computers are not yet perfect but the humans are even worse. Analyzing not only my mistakes in my own codes but even driving mistakes recently made on 3000 miles trip i am sure Elon Masks self-driving software would not make any of my mistakes when i barely escaped collision or wrong turns Smile. It would do its own mistakes if i'll fall asleep but this is different story
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Sat Aug 27, 2022 8:06 am    Post subject: Reply with quote

Dan

I think that I now understand what you are asking for.

But perhaps you are not understanding the idea of an interface.

An interface can be explicit via an INTERFACE statement. It can also be implicit when provided automatically via USE and a MODULE or by a CONTAINS in a program or sub-program.

The idea that your code should provide a warning and not an error at compile time is interesting. It would be an extension to the Standard and might have its downside.
Back to top
View user's profile Send private message AIM Address
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Sun Aug 28, 2022 2:08 pm    Post subject: Reply with quote

My understanding of this latest thread is that “a” is an optional argument for the examples to work.
So in the calling routine, “a” doesn’t need to be declared, only “b”.
Should “a” be declared optional for this to work properly?
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1885

PostPosted: Mon Aug 29, 2022 2:23 am    Post subject: Reply with quote

It seems to me that Dan is confused by two features of subroutine argument lists that were added in Fortran 90 (and were not present in Fortran 77). One feature is that some dummy arguments may be given the attribute OPTIONAL. The other feature is that argument association may be controlled by position in the argument list, as in Fortran 77, OR by keyword. I think that Dan is unaware of association by keyword.

Dan is free to avoid these "new" features of Fortran 90 when he writes Fortran code. When, however, he has to collaborate with others who use these new features, he will have to understand the properties of these new features.

Here is a small program to shed some light on these features.

Code:
Program test

   Real a, b
   a = 1.23
   b = 2.34
   Call Sub1(a)        ! optional argument not passed
   call Sub1(a, b)     ! pass both arguments
   Call Sub1(b=a, a=b) ! pass both arguments, using keywords
   Call Sub1(a=a, b=b)

contains

   subroutine sub1(A, B)
      Real, Optional, Intent(in) :: B
      Real, Intent(in) :: A
      Real :: C

      C = -1.7              ! default value
      if (present(B)) C = B
      Print '(2F8.4)', A, C

   End Subroutine

End Program
Back to top
View user's profile Send private message
Kenneth_Smith



Joined: 18 May 2012
Posts: 697
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Mon Aug 29, 2022 1:45 pm    Post subject: Reply with quote

I found this via google which explains the logic, particularly when mixing optional and non-optional arguments.

Quote:
Dummy arguments can be made optional if they are declared with the OPTIONAL attribute. In this case, an actual argument does not have to be supplied for it in a procedure reference.

If argument keywords are not used, argument association is positional. The first dummy argument becomes associated with the first actual argument, and so on. If argument keywords are used, arguments are associated by the keyword name, so actual arguments can be in a different order than dummy arguments. A keyword is required for an argument only if a preceding optional argument is omitted or if the argument sequence is changed.

Positional arguments (if any) must appear first in an actual argument list, followed by keyword arguments (if any). If an optional argument is the last positional argument, it can simply be omitted if desired.

However, if the optional argument is to be omitted but it is not the last positional argument, keyword arguments must be used for any subsequent arguments in the list.

Optional arguments must have explicit procedure interfaces so that appropriate argument associations can be made.

The PRESENT intrinsic function can be used to determine if an actual argument is associated with an optional dummy argument in a particular reference.
Back to top
View user's profile Send private message Visit poster's website
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Mon Sep 05, 2022 9:06 am    Post subject: Reply with quote

We are discussing new or rare features to find why people use them and are they worth using. If someone uses them my immediate question is why? Even if this is just the personal programming style then there still could be reason for that. I observed couple programs recently which heavily use all new features. When the author is present and supports these programs are looks kind of ok but the fun is - rarely who to no one else uses them even though they are open source.

When i asked authors why they use this or that new features they can not explain that. Meantime i see if they would not use them the code would be much more clean and easy. I also see other much more dangerous consequences for that when adding some key things to the code which was easy in previous "not so modern" versions of the same code become difficult to add (or they are even absent in the new and "modern" versions and the authors admit "adding that would be difficult...". Of course difficult, when you added 100 Linked Lists, derived types and pointers pointing on pointers Smile.

Another observation - it takes weeks and months even for authors to do elementary things with such "modern" codes.

As to this last example - it was almost nothing to argue about here besides that as soon as you use keywords the subroutine needs interface or be in the module or CONTASINS because of "All shut up, I am the Fortran Standard and I say so" while my example used just one single argument and it does not matter what keyword you will use there all arguments and variables when calling SUB1 (a) or SUB1(a=b) is A keyword or an actual argument all were 100% defined there and asking for interface (which could be reasonable in other complex cases of many optional arguments could be reasonable or obligatory) in this simplest example was not so needed. I pointed out that the future compilers with AI will just issue a warning.

By the way, I have not heard from anyone that they use keyword arguments and claim it worth programming like that. But this thread is exactly to push everyone to use them and find how useful they are.


Last edited by DanRRight on Mon Sep 05, 2022 9:43 am; edited 2 times in total
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Mon Sep 05, 2022 9:08 am    Post subject: Reply with quote

Meantime let's return to our sheep.
This example does not compile with FTN95

Code:
module basis_module
  implicit none

  type, abstract :: Basis
    integer :: NBasis
  contains
    procedure(allocBasisR1Interface), deferred :: allocateBasisR1
    generic :: allocateBasis => allocateBasisR1
  end type Basis

  interface
    ! Interface for real basis allocation
    subroutine allocBasisR1Interface(self, array)
      import
      class(Basis), intent(inout) :: self
      real, intent(in) :: array(:)
    end subroutine allocBasisR1Interface
  end interface

end module basis_module


module extension_module
  use basis_module
  implicit none

  type, extends(Basis) :: GridBasis
  contains
    ! Extending the mapping allocateBasis => allocateBasisR1 of
    ! the parent type.
    generic :: allocateBasis => allocateBasisC1
    procedure :: allocateBasisC1
    ! Implementation for the deferred procedure in Basis
    procedure :: allocateBasisR1
  end type GridBasis

contains

  subroutine allocateBasisR1(self, array)
    class(GridBasis), intent(inout) :: self
    real, intent(in) :: array(:)

    self%NBasis = size(array)
    print *, "GridBasis:allocateBasisR1"

  end subroutine allocateBasisR1


  subroutine allocateBasisC1(self, array)
    class(GridBasis), intent(inout) :: self
    complex, intent(in) :: array(:)

    self%NBasis = size(array)
    print *, "GridBasis:allocateBasisC1"

  end subroutine allocateBasisC1

end module extension_module


program test
  use extension_module
  implicit none

  type(GridBasis) :: mybasis
  real :: myRealArray(10)
  complex :: myComplexArray(5)

  call mybasis%allocateBasis(myRealArray)
  call mybasis%allocateBasis(myComplexArray)

end program test
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Mon Sep 05, 2022 9:38 am    Post subject: Reply with quote

Dan
Would you use this feature of Fortran 2003/8 if it was added to FTN95?
These "suggestions" should be about useful additions.
Back to top
View user's profile Send private message AIM Address
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Mon Sep 05, 2022 11:07 am    Post subject: Reply with quote

Paul,

This is another demo of another 2003-2008 feature from the codes i learn and i try to use which are compiled with gFortran, Intel etc but not with FTN95. If these codes would compile with FTN95 that would simplify the life immensely as there are no such nice GUI debuggers for other Linux compilers like SDBG64. Without such GUI debugger just to understand how these codes doing even elementary things is like deciphering Enigma machine.

When i find new unknown to FTN95 features in the codes i then search the web and find good demo which demonstrates this feature.

My postings would be unnecessary if you guys at Silverfrost just try to compile these codes i mentioned before and find what the other programmers seems very widely using. My shocking discovery of last months was that if in some other respects FTN95 is by far ahead of other compilers (GUI, OpenGL, fast compilation, HDMI, graphics, bug hunting in older codes) but in the Fortran 2003-2008, OpenMP and OpenMPI parallelization, fast execution, C/C++ integration it is not just the last but lagging far behind all other Fortran compilers which all compile these codes. This is leaving FTN95 not only as the one which can not compile modern codes but which seems is not even close. Intel for example is already fully Fortran-2018 capable.

Additionally what FTN95 missing are the major features which are associated in the perception of absolutely all people with why to use Fortran, not some other compilers Like C, Python, Matlab or new fashion Julia. Because all think that first of all Fortran means being #1 in speed. I afraid the lag here is like a decade or more because the same Intel for example is using all cores of processors by auto-parallelization and in some even single core tests beating FTN95 by an order of magnitude. It also supports all other parallelization techniques including graphics GPU-based like NVIDIA CUDA what all other compilers also do (GPU is a new unstoppable trend) while FTN95 has none excluding one proprietary workaround (i mean FTN95 specific multithreading subroutine. I may also add linear algebra libraries like Laipe or MKL). That in most cases gives additional orders and orders of magnitude ahead of FTN95.

Autoparallelization these my "modern Fortran" codes not using. And not using GPU. Which means that even these my modern codes are not that modern.
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Tue Sep 06, 2022 2:38 am    Post subject: Reply with quote

More extractions from these PIC codes which are Fortran 2003/2008 addition:

1) "ERROR STOP" instead of just STOP.

Used for stopping all running images (processes) while STOP just stops execution of the current image.

2) "Protected" (Fortran 2003)
Example:
integer, protected :: GAS_num_gases = 0

3) NEWUNIT in OPEN (Fortran 2008).
The NEWUNIT specifier opens a file on an unused unit number that is automatically chosen.

Example:
open (newunit=my_unit, ....

4) attribute "non_overridable" (Fortran 2003)

Example:
procedure, non_overridable :: set_random_seed

5) Got error here
Code:
if (iand(jmp_c(i), shiftl(1_i8, b)) /= 0) then
*** The second argument (J) to the intrinsic IAND must be of INTEGER type, not
    REAL(KIND=1)
*** SHIFTL must appear in a type declaration because IMPLICIT NONE has been
    used


Looks like SHIFTL(I, SHIFT) (Fortran 2008) is missing or/and IAND does something with possibly boz-literal (?) variable (Fortran 2003)

Also here
Code:
 res = ior(shiftl(x, k), shiftr(x, 64 - k))
*** The first argument (I) to the intrinsic IOR must be of INTEGER type, not
    REAL(KIND=1)
*** The second argument (J) to the intrinsic IOR must be of INTEGER type, not
    REAL(KIND=1)
*** SHIFTR must appear in a type declaration because IMPLICIT NONE has been
    used
*** SHIFTL must appear in a type declaration because IMPLICIT NONE has been
    used


I temporally substituted Error Stop with just the Stop, removed PROTERCTED and non_overridable attributes, changed NEWUNIT with just the UNIT but SHIFTL and IAND putted the stop on my efforts to further compile this code with FTN95
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue Sep 06, 2022 7:02 am    Post subject: Reply with quote

Dan

Although our aim is to provide the best Fortran compiler that we can, it is sensible for us to prioritise and look first at the improvements that are most useful to our current users.

I suggest that you use a different compiler (i.e. not FTN95) when exploring the latest additions to the Fortran Standard. When you see a feature that you understand and would like to use in your own code, then make a request.

Frankly I don't think that you are likely to need or use any of the new features that you have listed. If you are collaborating with others who use these features then you will need to use the same compiler that they are using.

In the meantime, ask for something that is do-able in a matter of days not years. Your request for NORM2, for example, required 2 or 3 man days to implement. It was also something that other FTN95 users might want to use.
Back to top
View user's profile Send private message AIM Address
Kenneth_Smith



Joined: 18 May 2012
Posts: 697
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Sun Oct 16, 2022 10:59 pm    Post subject: Reply with quote

In Fortran 2008, the intrinsic function ATAN now has an extra form ATAN(Y,X), which is exactly the same as ATAN2(Y,X), i.e. the following code is valid in Fortran 2008:

Code:
print*, ATAN(1.d0,1.d0)


Another one to possibly add to the list - sorry Paul. This really had me confused looking at a colleague's new code.
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Mon Oct 17, 2022 7:44 am    Post subject: Reply with quote

Thanks Ken. I will make a note of this.
Back to top
View user's profile Send private message AIM Address
Kenneth_Smith



Joined: 18 May 2012
Posts: 697
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Wed Oct 19, 2022 1:57 pm    Post subject: Reply with quote

Thanks Paul, I think it is important that the core math functions of the later versions of the standard find their way into Silverfrost Fortran - and you have come a long way toward achieving this since this thread was started, for which we are all grateful.

There has been an extension to the support for complex numbers in 2008 that permit the independent assignment of the real and imaginary parts of a complex number. It is also possible to extract these parts without the use of the REAL or AIMAG functions. Below is a simple example of what is now possible via the % operator i.e. the complex number looks like a derived type in this context.

Code:
program new_complex
complex z
!                               ! Classical assignment and extraction of Real and Imaginary parts
z = (0.0,1.0)                   ! z = 0 + j1
print*, real(z), aimag(z)       ! prints  0.00000000       1.00000000

                                ! New ways as permitted by 2008
                               
print*, z%re, z%im              ! Instead of print*, real(z), aimag(z), prints  0.00000000       1.00000000
z%re = 1.0                      ! Set real part only
print*, z%re, z%im              ! Prints    1.00000000       1.00000000 
z%im = 0.0                      ! Set imaginary part only
print*, z%re, z%im              ! Prints    1.00000000       0.00000000
end program new_complex


I suspect this may be a more difficult one to implement, but please take a look at this to see if it may be possible to implement this extension within FTN95. The multiple/sequential/independent assignment of real and imaginary parts in code written for a 2008 compiler using this "derived type" would be rather time-consuming/error-prone to reverse into FTN95 format.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Suggestions All times are GMT + 1 Hour
Goto page Previous  1, 2, 3, 4, 5, 6, 7, 8, 9, 10  Next
Page 8 of 10

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group