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

F-95 standard: internal procedures of ELEMENTAL procedures

forall
Beginner
647 Views
last question for the week :-)

As far as I can see, there is no need to make the internal routine of an ELEMENTAL procedure also elemental - being declared pure is good enough.

Interestingly, cvf doesnt seem to allow making the internal recursive routine ELEMENTAL anyway, returning the error message "Error: Multiple or conflicting PURE/ELEMENTAL/EXTRINSIC/RECURSIVE/type specification" (when replacing pure --> elemental).

I currently dont have access to ivf, so cant check that yet. Finally, other compilers complain when the internal procedure is PURE but not ELEMENTAL.

I think that the other compilers are wrong to complain about the code below, but at the same time the standard doesnt prohibit internal elemental recursive routines, doesnt it??

thanks in advance...

!----------------------------------------------------
elemental function func2(n)
implicit none
integer,intent(in)::n
integer::func2
func2=func2_eng(n)
contains
!---
pure recursive function func2_eng(n) result(res)
implicit none
integer,intent(in)::n
integer::res
...
endfunction func2_eng
!---
endfunction func2
!----------------------------------------------------
0 Kudos
6 Replies
Steven_L_Intel1
Employee
647 Views
Yes, the standard does prohibit the combination of ELEMENTAL and RECURSIVE. PURE and RECURSIVE is ok.

An ELEMENTAL routine is just a PURE routine that accepts and returns a scalar which can then be called with an array argument. Once you're inside the ELEMENTAL, it's a scalar world. You could have an internal elemental routine but unless you had an array to pass to it, what's the point?

Message Edited by Steve_Lionel on 05-12-2006 02:30 PM

0 Kudos
forall
Beginner
647 Views
thanks again Steve,
Two quick clarifications:
1) Indeed, I think making this internal procedure elemental (if allowed) would be counter-efficient in terms of code speed, since elemental code is a bit slower than pure code, right?
2) Is there a "logical" reason why elemental recursive procedures are prohibited (other than its possibly(?) much harder to implement)?
0 Kudos
Steven_L_Intel1
Employee
647 Views
1) Elemental functions, by themselves, are no different from pure functions. The difference comes into play when they are called with array arguments, then additional code is generated by the caller. The function itself does nothing different.

2) I can't think of it offhand, but I'm sure the standards committee had a reason. You could ask in comp.lang.fortran to see if any committee members care to offer their opinions.
0 Kudos
brianlamm
Beginner
647 Views

forall,

Think of using a FORALL statement wherein each line is processed fully (all indices at that level) and assignments made before executing the next line. If an ELEMENTAL procedure is called on that line and it where allowed to be RECURSIVE then updates to array elementscould be corrupted if the recursive procedure updatedelements of varin var = expr. Of course, when used in a FORALL it would be the scalar "version" of the ELEMENTAL procedure that would necessarily be invoked.

Message Edited by Brian-Lamm on 05-12-200602:03 PM

0 Kudos
forall
Beginner
647 Views
Brian-Lamm,

I am trying to understand what you mean.

if you have

forall(i=1:n)var(i)=func(x(i))

then, since func has to be pure (whether or not it is also elemental), it cannot have side-effects and cannot affect (corrupt) anything else. In fact as you point out when calling a function within in a "forall" construct you are invoking the scalar version and that has the same behaviour as a scalar pure function.

Message Edited by forall on 05-12-200603:08 PM

0 Kudos
brianlamm
Beginner
647 Views

It's really quite simple. In a single FORALL execution statement, func is evaluated FOR ALL indexes masked TRUE at once Before assignments to var are made. If func where resursive, then it could very well be that in the a'th evaluation of func that (many) other elements of var (other than the a'th one) are REASSIGNED. EVERY TIME func resurses for a SINGLE index (a'th one) of var, other than the a'th element of var would be redefined thus necessarily obviating any chance that the assignments could be made in PARALLEL. I don't think you grasp that func is evaluated FOR ALL indexes IN ANY ORDER BEFORE assignment to any elements of var are made IN ANY ORDER, all for the sake of making it as "easy" as possible for the processor to optimize those evaluations, especially if parallelization is available.

A recursive procedure Will have side effectsin this case. It may not alter the "x", but if it is indeed resursive, it certainly will alter at least sections of var and possibly ALL of var in a SINGLE call to func, thus making it IMPOSSIBLE TO ASSIGN ALL ELEMENTS OF VAR IN ANY ORDER.

So, if your recursive function indeed does not redefine any other elements of var other than the current one func is operationg on, then you can use a recursive funciton in a FORALL. A RECURSIVE function can be PURE.

You cannot use an ELEMENTALfunction in a FORALL however if func is RECURSIVE (the standard disallows both ELEMENTAL and RECURSIVE for a subprogram).

Message Edited by Brian-Lamm on 05-13-200610:14 AM

0 Kudos
Reply