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

array valued functions

rahzan
Novice
2,554 Views
The follwoing code in cvf6.6b gives mismacthed arguments warning.
The function value itself is an array with some simlpe inputs

real,allocatable:: x(:),y(:)
allocate(x(4),y(4))
x=[1.,2.,3.,4.]
y=doubleAnArray(x,3)
write(*,*)x,y
read(*,*)
end
function doubleAnArray(inp,start) result (xx)
real,intent(in):: inp(:)
integer,intent(in):: start
real xx(4)
integer:: j,n
n=size(inP)
xx(:start-1)=0.
do j=start,n
xx(j)=2.*inp(j)
enddo
end function doubleAnArray
Any hints on how to do this will be appreciated.
0 Kudos
23 Replies
Steven_L_Intel1
Employee
2,084 Views
0 Kudos
rahzan
Novice
2,084 Views
Thanks,
I somehow thought that I needed that only for module procedures (which are inthe same file).
Can you explain very breifly
1. Why the explicit Interface is needed?
2. Why is it not needed if the routine/module is in another file
3. My real intent was to test the on-the-fly-dimensioning of the function result as below (which seems to work!)
function doubleAnArray(inp,start)
real,intent(in):: inp(:)
integer,intent(in):: start
real doubleAnArray(size(inp))
integer:: j,n
n=size(inP)
doubleAnArray(:start-1)=0.
do j=start,n
doubleAnArray(j)=2.*inp(j)
enddo
end function doubleAnArray
Is this really ok, or did it work just in a simple console app?
many thanks.
Tim
0 Kudos
Steven_L_Intel1
Employee
2,084 Views
You need it in all cases, same file or different file. The explicit interface does not go in the function itself, but it goes in or has to be visible to the caller. Otherwise, the compiler has no clue how to process the array function return value.
0 Kudos
durisinm
Novice
2,084 Views
Steve,
The link you put in to the explicit interface information doesn't work for me. Is there an alternate way to get to it?
Mike D.
0 Kudos
Steven_L_Intel1
Employee
2,084 Views
Fascinating. It disappeared since a couple of days ago. Here's the content.
Doctor Fortran Gets Explicit!
Steve Lionel
Visual Fortran Engineering

In our last issue, the Good Doctor covered the topic of optional arguments, noting that an explicit interface was required. Since explicit interfaces seem to be a common point of confusion for those new to Fortran 90, (and some not so new), we'll cover this subject in more detail.
In Fortran terminology, an interface is a declaration of some other procedure that supplies details, including:
  • Name of the procedure
  • Whether it is a subroutine or function
  • If a function, the result type
  • Number, names, shapes and types of arguments
  • Argument attributes, such as OPTIONAL and INTENT


Prior to Fortran 90, the only kind of interface was implicit, meaning that the compiler assumed that a routine call matched the actual routine - all you could do was specify the type of a function. The standard required that "the actual arguments ... must agree in order, number and type with the corresponding dummy arguments in the dummy argument list of the referenced subroutine." Not only was this error-prone, but it made it difficult to support desirable features such as optional arguments and array function results.

The explicit interface, introduced with Fortran 90, allows you to tell the compiler many more details about the called routine. This additional information allows a compiler to check for consistency in routine calls and also enables features such as optional arguments that depend on changes in the way the routine is called. In most cases, an explicit interface consists of an INTERFACE block which contains a copy of the called routine's declaration. For example:

INTERFACE
SUBROUTINE MYSUB (A,B)
INTEGER ::A
REAL, OPTIONAL, INTENT(IN) :: B
END SUBROUTINE MYSUB
END INTERFACE

An INTERFACE block can go in the declaration section of a program unit, or can be made visible by use-association (in a MODULE that is USEd) or host-association (a program unit that contains the one that needs to see the interface.) An explicit interface also exists, without an INTERFACE block, if the routine is a contained procedure or is a module procedure in the enclosing module or a module that is use-associated (and the module procedure has not been made PRIVATE).
While there are many good reasons why you should always use explicit interfaces, including better error checking and improved run-time performance (avoiding unnecessary copy-in, copy-out code), there are some cases where you are required to have an explicit interface visible. These are:
  • If the procedure has any of the following:
    • An optional dummy argument
    • A dummy argument that is an assumed-shape array, a pointer, or a target
    • A result that is array-valued or a pointer (functions only)
    • A result whose length is neither assumed nor a constant (character functions only)
    • A dummy argument that appears in a High Performance Fortran (HPF) data mapping directive. (While Visual Fortran does not support HPF functionality, it does recognize HPF syntax and checks it for errors. Our Tru64 UNIX compiler does support HPF.)
  • If a reference to the procedure appears as follows:
    • With an argument keyword
    • As a reference by its generic name
    • As a defined assignment (subroutines only)
    • In an expression as a defined operator (functions only)
    • In a context that requires it to be pure
    • If the procedure is elemental


For more information on explicit interfaces, see Chapter 8 of the Compaq Fortran Language Reference Manual.

In closing, Doctor Fortran prescribes using explicit interfaces throughout your application, ideally with an appropriate INTENT attribute specified for each argument. It may be a bit more typing up front, but it will quickly pay off in smoother development and, possibly, faster execution.
0 Kudos
rahzan
Novice
2,084 Views
One hates to disagree with steve.
However, I still do not understand why it is that if I break up the code I gave at the start betweem two files ina simple console project, I do not get the type mismatch error, which would otherwise go away with an explicit interface. I must be missing something here.
0 Kudos
Steven_L_Intel1
Employee
2,084 Views
Oh, you won't get the error because the compiler cannot see that there is an error. But the code will not work without the explicit interface.
0 Kudos
rahzan
Novice
2,084 Views
Hmm!
Should I send the project and the executable to show thatit works, or would you like to try it yourself?
0 Kudos
Steven_L_Intel1
Employee
2,084 Views
I tried the code in the original post, compiled separately.

CVF won't link it because of the argument mismatch caused by the lack of the explicit interface.

Intel Fortran will build it but gets an access violation at run-time.

Both of these are behaviors I would expect. What are you seeing?
0 Kudos
rahzan
Novice
2,084 Views
It runs and gives the expected answer.
Iattached the project to this msg, if you care to see it.
You can if you prefer, email me separately for faster response:
tsh att mathllc dott com
0 Kudos
Steven_L_Intel1
Employee
2,084 Views
Not the same program as you posted. This one uses modules and has the main program USE the module that defines the array-returning function as a module procedure. That's an explicit interface.
0 Kudos
rahzan
Novice
2,084 Views
Sorry about that.
My memory of the last time I asked about this must be faulty, since that time (1-2 yrs ago) I had used a module like this.
Is there anyway to read off the interface, (that is somehow generated automatically) from the LIB or the MOD or some other file?
This would aid documentation greatly.
Thanks.
0 Kudos
Steven_L_Intel1
Employee
2,084 Views
No, sorry. However, the next major release of the compiler will offer an option to generate interfaces (in .f90 form) of routines you compile.
0 Kudos
g_f_thomas
Beginner
2,084 Views
In mixed-language (C++ and Fortran) does C++ make use of Fortran procedure interfaces?

Thanks,
Gerry T.
0 Kudos
Steven_L_Intel1
Employee
2,084 Views
I'm not sure I understand your question. C++ does not know of any declarations you make on the Fortran side - you have to supply C++ declarations as appropriate.
0 Kudos
g_f_thomas
Beginner
2,084 Views
Actually the query is unimportant.
Fortran interfaces are for Fortran's benefit. C++ doesn't care whether they're present or not.

Thanks,
Gerry T.
0 Kudos
glyn
Beginner
2,084 Views

I have some functions that I would want to be pure, but they return an array: e.g. below, however, I do not know and have not been able to find out how to define the return as an array. Hence I get the warning "This name has not been given an explicit type."

PURE

FUNCTION GetNodeCoords(NodeNo) result (Coords)

integer, intent(in) :: NodeNo

double precision :: Coords(3) !I suspect this is wrong, but I cant use Intent(out)

Coords(x) = GetNodeX(NodeNo)

Coords(y) = GetNodeY(NodeNo)

Coords(z) = GetNodeZ(NodeNo)

RETURN

END

My interface is therefore:

PURE FUNCTION GetNodeCoords(NodeNo) RESULT(Coords)

INTEGER, INTENT(IN) :: NodeNo

double precision :: Coords(3)

END FUNCTION GetNodeCoords

I would have thought that I need to have the return type in, like I do with other pure functions that do not return arrays, but how do I say that I have double precision(3) being returned?

Any help of how to write this correctly appreciated

0 Kudos
Steven_L_Intel1
Employee
2,084 Views
What is the exact and complete text of the message you get? I can't match what you describe to the source you posted.

Your declaration of the array-valued result is correct. You don't use intent when declaring a result.

Where are x, and the GetNodeX, etc. routines declared?
0 Kudos
glyn
Beginner
2,084 Views

Thanks for you reply:

Sorry, I made a mistake in my code, I'd managed to miss out the "result (coords)" in the interface (but then add it into my "simplifed" example - Friday afternoons!).

However, you've answered my question as I was sceptical that I'd declared my array-valued result correctly, as I hadn't specified the type of the result explictly between the PURE & FUNCTION keywords.

Sorry, still learning after last using FTN77 >10 years ago and then doing C++ until recently!

Cheers for your swift response

Glyn

0 Kudos
Steven_L_Intel1
Employee
1,868 Views
You don't have to declare the type in the FUNCTION statement - it's perfectly ok (and some would say better style) to do so in the declaration section of the routine.
0 Kudos
Reply