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

PURE calling PURE

Ilie__Daniel
Beginner
1,358 Views

I have a program which calls one pure subroutine. This subroutine calls another pure subroutine. I pasted the code below:

pure subroutine times2(a)

implicit none

integer, intent(inout) :: a

a = a * 2

end subroutine times2


pure subroutine plus1(a)

implicit none

integer, intent(inout) :: a

call times2(a)

a = a + 1

end subroutine plus1


program odd_number

implicit none

integer :: a

read(*,*)a

call plus1(a)

print*,a

end program odd_number

I get the following error on compilation:
Error: Any procedure referenced in a PURE procedure, including one referenced via a defined operation or assignment, must be explicitly declared PURE. [TIMES2]

I do not think that I am doing anything wrong. Why do you think the error occurs?
I attached the relevant files.

Thank you for your time.

0 Kudos
8 Replies
Arjen_Markus
Honored Contributor II
1,358 Views
The point is that the interface to times2 is "implicit". The best way to solve it is to put
both plus1 and times2 in a module (either the same or each in its own), so that the
interfaces to these routines are known via the USE statement.

(Fortran compiler must assume that any subroutine/function that does not have
an explicit interface - via the module it is contained in or via an interface block -
follows the Fortran 77 conventions)

Regards,

Arjen
0 Kudos
mecej4
Honored Contributor III
1,358 Views
These comments supplement what Arjen Markus said.

In Fortran, declarations do not have file scope (unlike in other languages such as C) unless the file contains a single programming unit such as a module or a procedure.

Therefore, the declaration of times2 as pure has no effect beyond the "end subroutine times2" statement. Hence the error message.
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,358 Views
Suppose then, the original sample program is modified, not with MODULES, but with local INTERFACE declarations declaring each pure function/subroutine. Local interface declaration is not identical to MODULE declared interface since different source files may locallydeclare the interface differently (e.g. one with PURE another without PURE).

Jim
0 Kudos
Steven_L_Intel1
Employee
1,358 Views
You might find that the compiler is unhappy if you "lie" to it like that, either giving an error (if interface checking is enabled) or wrong answers.
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,358 Views
I am not suggesting you lie about the pureness of a function/subroutine. I am mearly asking if it is accepted to use local interface declaration as opposed to module declaration. Module is preferred since it can assert the pureness (assuming it is USED within the INTERFACED subroutine). The module has the disadvantage in that it creates/uses a .MOD file whereas a local INTERFACE will not. This may or may not be an issue.

Jim Dempsey
0 Kudos
Steven_L_Intel1
Employee
1,358 Views
It's certainly legal to have a local interface, though I consider this unwise because it means you are declaring the routine twice. It's not legal for the local interface to disagree with the actual routine, and the compiler has the capability of checking this. I don't know what you have against .mod files.
0 Kudos
mecej4
Honored Contributor III
1,358 Views
"..it means you are declaring the routine twice".

At least twice. In a typical nonlinear solver, there are four (sometimes repackaged as two) procedures to evaluate F, \grad F, C and \grad C, where F and C are vector functions -- the multiple objective and constraint functions. These functions are passed around from subroutine to subroutine as arguments before being actually invoked. In such programs, in the F77 era we simply declared these arguments EXTERNAL and took pains to make sure that the actual argument agreed with the implicit interface at the point of invocation -- the function definition and the function invocation were often in different files.

If you now want to provide local interfaces, possibly as part of converting the code to Fortran 9X/2xxx, you find yourself providing many copies of the local interfaces, after which any change to the functions -- e.g., adding extra arguments to F, C, ... -- becomes quite laborious and error-prone. This is where I find it so useful to write a single set of abstract interfaces in one module instead of multiple local interfaces.

"I don't know what you have against .mod files."

Jim probably is alluding to the problem of compilation cascades under the control of Make -- as was discussed in a recent thread: if a module source file is modified in such a way that the interfaces are left unchanged but the implementations are, other source files where this module is used may be subjected to unnecessary recompilation.
0 Kudos
jimdempseyatthecove
Honored Contributor III
1,358 Views
>>Jim probably is alluding to the problem of compilation cascades under the control of Make -- as was discussed in a recent thread: if a module source file is modified in such a way that the interfaces are left unchanged but the implementations are, other source files where this module is used may be subjected to unnecessary recompilation.

This is correct. In one of my solutions (using VS IDE, but this would be similar using MAKE), a non-consequential change often resulted in recompilation of 13 projects with 750 source files. A few minutes without IPO enabled.

After awhile I got smart(er) and separated the module sources into two or three parts: one for PRAGMA's (if present), one for variables, and one for CONTAINS. Then, USE only the appropriate component modules (which never included the code/CONTAINS). Now edits affect substantially fewer files and debug/edit/debug... cycles are much faster.

When your application consist of a handful of files, and builds take a few 0.1'ths of a second, it really doesn't matter how you construct your modules. On the other hand, when build (all's) take 60's of seconds efficiency matters.


Jim Dempsey
0 Kudos
Reply