- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Until lately I was using function pointers to alias different elemental procedures sharing the same abstract interface. Obviously that's forbidden according to the standard but allowed until the last version of the ifort compiler. Ifort 16.0.2 now prints the error:
error #6128: Non-intrinsic ELEMENTAL procedure is not allowed as a pointer procedure target.
First, where is the sense in this restriction and second, what else can I do to alias dynamically elemental functions?
Thanks for help!
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There are two constraints involved here. The immediate one is (7.2.2.2):
C730 (R740) The proc-target shall not be a nonintrinsic elemental procedure.
There is also C1218, in the discussion of procedure pointer declarations (section 12.4.3.6):
C1218 (R1211) If a proc-interface describes an elemental procedure, each procedure-entity-name shall specify an external procedure.
That is, you can't declare a procedure pointer with an elemental interface.
I did a bit of archaeology here and found that procedure pointers were basically modeled on dummy procedures, and those were not allowed to be elemental, so procedure pointers were also not allowed to be elemental. I know this isn't satisfactory, but as I've often griped to the committee, the rationales for decisions were rarely recorded.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To answer your other questions, it was a bug that we didn't check the constraint. Offhand I don't know of another way to do this.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot for explanation Steve,
If I understood that right, there are no obvious (rational) reasons to forbid pointing to elemental subroutines. I know that ifort isn't following the standard all the way, thatswhy flags as -standard-semantics are needed. So wouldn't that be a nice case of application for this flag, simply allowing targeting to elemental procedures if not set?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This seems to stretch the idea of -standard-semantics too much into new territory. The option has been used to permit non-standard legacy usage to remain a default for ifort, not to support extensions. In some cases optimization has been better for the legacy usage, but the developers have fixed some of those annoyances. For example, I haven't seen any cases where properly written code performs better (and correctly) without protect_parens.
I was somewhat disappointed to see that the bug fix for -standard-semantics with 16.0 update 2 eliminated the attempt to perform simd optimization of maxloc and minloc. So it is still necessary to add -old_maxminloc in order to optimize those intrinsics (although they will not fail as they might with update 1).
This leads to the suspicion that -standard-semantics is kept as non-default in order to perform better on certain benchmarks. Those who wish benchmarks to be performed under standards compliant compile options haven't won any battles.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If we made all of -standard-semantics the default, it would break so many older programs that customers would be at our door with torches and pitchforks. We are evaluating each of the non-standard semantics (these are not extensions) to see if we can change individual defaults. For example, we are planning to make -assume realloc_lhs the default in the next major release, as most if not all other Fortran compilers already do, assuming we can resolve performance issues (which we have a handle on.) On the other hand, -assume byterecl will probably never become the default.
Tim is right that -standard-semantics is not about extensions, and we are very conservative about implementing extensions nowadays. There may well be a very good reason for the standard's restriction here that I am not aware of. I'll see if I can find out.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Some comments I got from those who have been on the committee longer than I:
My recollection of this is the question whether elemental is implemented by wrapping loops around procedure references, or having a version of the procedure for each rank. There was some resistance to the possibility that allowing elemental procedure pointers (and arguments) might prejudice how developers implement elemental.
The association of a procedure pointer with its target is as for the association of a dummy procedure with its actual procedure. A dummy procedure is essentially a pointer, so were just extending what had been around for a long time.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve Lionel (Intel) wrote:
There was some resistance to the possibility that allowing elemental procedure pointers (and arguments) might prejudice how developers implement elemental.
So when the committee is that worried about prejudication, then why is this allowed?:
module epointer implicit none type, abstract :: I contains procedure(eint), nopass, deferred :: f end type I abstract interface elemental function eint(x,y) result(z) real, intent(in) :: x,y real :: z end function eint end interface type, extends(I) :: A contains procedure, nopass :: f => fA end type A type, extends(I) :: B contains procedure, nopass :: f => fB end type B contains elemental function fA(x,y) result(z) real, intent(in) :: x,y real :: z z=x*y end function fA elemental function fB(x,y) result(z) real, intent(in) :: x,y real :: z z=x/y end function fB end module epointer program main use epointer implicit none class(I), pointer :: gfo type(A),target :: ao type(B),target :: bo gfo=>ao write(*,*) gfo%f(12.0,3.0) write(*,*) gfo%f([15.0,18.0],[5.0,9.0]) gfo=>bo write(*,*) gfo%f(12.0,3.0) write(*,*) gfo%f([15.0,18.0],[5.0,9.0]) end program main
From my understanding, this implementation leads basically to the same questioning for the developers when implementing the polymorphic functionalities.... but no arguing of the compiler....
Steve Lionel (Intel) wrote:
Tim is right that -standard-semantics is not about extensions, and we are very conservative about implementing extensions nowadays. There may well be a very good reason for the standard's restriction here that I am not aware of. I'll see if I can find out.
Well, until ifort 16.0.2 my code was working without complaints, so speaking of an extension might not be the right terminology. Probably it falls more under the category "legacy features support"...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Neither. It's the category of "compiler bug that we fixed". It was never intended as a feature. I'm not quite sure I get the point of your latest example.
You're the second customer I've come across who tripped over this, but the better course is to rewrite the code to conform to the standard.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page