Dynamic Array inside subroutine

Dynamic Array inside subroutine

How we can pass a dynamic array inside a subroutine??

Example:

Program test

real, allocatable :: array(:,:)

call mysub(array)

end Program test

subroutine mysub(a)

real, allocatable :: a(:,:)

allocate(a(10,10))

end subroutine mysub

results:

ifort test.f90

./a.out

forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image PC Routine Line Source
a.out 0000000000402B24 Unknown Unknown Unknown
a.out 0000000000402ACC Unknown Unknown Unknown
libc.so.6 00000034FC41D994 Unknown Unknown Unknown
a.out 00000000004029D9 Unknown Unknown Unknown

SPECS:
CentOS release 5.5 x86_64

ifort: 11.1.046

and the funny thing is no compilation errors

17 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

When an allocatable array is to be passed as an argument to a subroutine, an explicit interface to the subroutine must be available to the compiler. For example:

Program test
real, allocatable :: array(:,:)
call mysub(array)

contains
subroutine mysub(a)
real, allocatable :: a(:,:)
allocate(a(10,10))
end subroutine mysub

end Program test

I have a source file with 650 lines of code
and I defentely want a subroutine outside the program to do this job
because I have plans on using it for general perpose and only for
the particular program what we can do about it?

I can give you an example how to do it in C/C++ using pointers but in fortran
things are more complicated

In my opinion this is a serious issue that must be solved

Here (below) is how to provide an interface to external subroutines with allocatable arguments.

Intel Fortran (and third party utilities) can generate interfaces for you from your existing source code, or you can write them yourself. If you call one such subroutine from more than one place, it would be economical to put the interface declarations in a module, and USE the module wherever needed.

As to "In my opinion this is a serious issue that must be solved" -- what is that issue? If it is Fortran pointers being different from C pointers, it will not be solved in my lifetime, and one must live with the differences.

--------------------------------------------------------

Program test

interface
  subroutine mysub(a)
  real,allocatable :: a(:,:)
  end subroutine mysub
end interface

real, allocatable :: a(:,:)
call mysub(a)
write(*,*)lbound(a,1),ubound(a,1),lbound(a,2),ubound(a,2),a(5,5)
end Program test

subroutine mysub(a)  
  real, allocatable :: a(:,:)  
  allocate(a(10,10)) 
  a(5,5)=123.0 
  return
end subroutine mysub

I don't understand what you are trying to do. Why call a subroutine just to do the allocation? Why not do the allocation in the main program or wherever it is needed?

Once you allocate the array, you can treat it as a normal array and pass it F77-style. Just don't use (:) bounds unless you have an explicit interface (a module or contained procedure is best for this.)

There's no need to go to C for this - in fact, that will make your job MUCH harder.

Steve - Intel Developer Support

so.. in my 650lines code there are several other scientists age 40+, 50+, 60+
how I expect them to learn how an interface is working for a simple matrix
interpolation.. it took me a whole semester in Java to understand it :)

I don't care how pointers or alocatable parameters is working in fortran I want to
solve it as it is as variable without interface modules.. etc simple as that can we?

I guess you're a little confused by the somewhat similar keywords in Fortran and C/C++/Java. For future reference, keep in mind that FORTRAN IS NOT C/C++/Java. First of all, Fortran procedures DO NOT HAVE parameters, but arguments ---a Fortran parameter is just a constant, as in:

real(kind(1.d0)), parameter :: PI = 3.1415926535897932384626433832795028841971693993751d0

Just like in C you need function prototypes, usually included in headers, in Fortran you need something similar ---in Fortran it's called explicit interface, but it has NO direct relation with Java interfaces. Many Fortran 90+ features (allocatable arguments, optional arguments, operator definition/overloading, etc.) require an explicit interface, and there are usually three ways in which they are provided:

  • The procedure (function or subroutine) is contained by a MODULE unit
  • The procedure is contained by the PROGRAM unit
  • The user provides an interface block that describes the procedure "prototype".

Keep in mind that in Fortran, the source file is not a boundary, and therefore in your example, the PROGRAM unit is not aware of the subroutine, even if they are in the same source file ---and that's why in your example you need an explicit interface to the subroutine.

Since your subroutine is intended to be reusable, your best option is to put it in a module, e.g.:

module some_module

contains

subroutine mysub(a)
   real, allocatable :: a(:,:)
   allocate(a(10,10))
end subroutine

end module some_module


program test

   use some_module

   real, allocatable :: array(:,:)

   call mysub(array)

end program test

That way, your several other scientists age 40+, 50+, 60+ will only have to add the "use some_module" line in order to access mysub.

Fortran pointers are not C-like pointers, even though they share the same name. I'd suggest you take some time to learn what they are, and if you really need to use them at all ---I'd bet you don't.

Finally, if you want to solve your problem using Fortran, but don't want to use any Fortran features or learn its semantics, then you're doomed ---since the Fortran standard is not going to change in order to please you!

ftp://ftp.nag.co.uk/sc22wg5/N1801-N1850/N1830.pdf

these are the standards of fortran.. page 457

16.6.8 Pointer association context
1 Some pointers are prohibited from appearing in a syntactic context that would imply alteration of the pointer
association status (16.5.2.2,5.3.10, 5.3.15). The following are the contexts in which the appearance of a pointer
implies such alteration of its pointer association status:
- a pointer-object in a nullify-stmt;
- a data-pointer-object or proc-pointer-object in a pointer-assignment-stmt;
- an allocate-object in an allocate-stmt or deallocate-stmt;
- an actual argument in a reference to a procedure if the associated dummy argument is a pointer with the
INTENT (OUT) or INTENT (INOUT) attribute.

I hope intel fortran is following the isos.. in my version it is not so.. fix it

and man.. start reading the standards of fortran and then start talking
what I have to learn or not

If you want to still running this business you'd better follow the isos

This is good advice -- just put your subroutines into modules and use the modules from any program that calls them, or from any subroutine in a different module. This will automatically make the interfaces explicit. It is simple and easy. It is less error prone than writing interface statements -- if you later update the subroutine argument list, you don't have to remember to update the interface statement.

If you want people to really help, coming in with an attitude like that isn't going to get you very far.

And if you want to cite the standard, read all of it:

12.4.2.2 Explicit interface
1 A procedure other than a statement function shall have an explicit interface if it is referenced and
(1) a reference to the procedure appears
(a) with an argument keyword (12.5.2), or
(b) in a context that requires it to be pure,
(2) the procedure has a dummy argument that
(a) has the ALLOCATABLE, ASYNCHRONOUS, OPTIONAL, POINTER, TARGET, VALUE,
or VOLATILE attribute,
(b) is an assumed-shape array,
(c) is a coarray,
(d) is of a parameterized derived type, or
(e) is polymorphic,
(3) the procedure has a result that
(a) is an array,
(b) is a pointer or is allocatable, or
(c) has a nonassumed type parameter value that is not a constant expression,
(4) the procedure is elemental, or
(5) the procedure has the BIND attribute.

Your example clearly falls under (2)(a) and so it requires an explicit interface, which you did not provide in your example and others have shown you how to write. If you use modules, it's all taken care of for you and makes your code reusable, which is the point.

The section you cited is about pointers, not about ALLOCATABLE variables. They are not the same thing.

Tim

As I pointed out above, simple use of allocatable arrays does not require interfaces. I'd still like a better explanation of what is being asked for.

Steve - Intel Developer Support

The section of the standard that you included in your post (#7) has no bearing on this thread, since the code that you posted (as well as those that I provided for your use) does not involve pointers.

Allocatable arrays were not allowed as dummy arguments in Fortran 95. This feature was added as TR 15581, and is implemented in Intel Fortran. The document that you cited is a draft of the Fortran 2008 standard. Intel Fortran supports some parts of Fortran 2003. However, none of the features of Fortran later than Fortran 95 + TR 15581 are involved in the topic of this thread, and there is no point in starting an argument about the legality of a piece of code in the context of a standard to which no claim is made by the compiler vendor (Intel) as to faithfulness.

I want to clarify something.

ALLOCATABLE arrays were not allowed as dummy arguments in Fortran 90/95. They were allowed as actual arguments. The only time you would need to make a dummy argument ALLOCATABLE is if you intend to change its allocation status in the called routine. If you are just allocating the data (think malloc in C) and passing it around, nothing special is needed.

I agree that nickos85's post showed a subroutine doing an ALLOCATE, for which an explicit interface is required, but I don't think he really needs to do that. This is why I asked for more information.

Please try to keep the tone friendly here. We're all trying to help.

Steve - Intel Developer Support

in C++ you can pass the parameters in a function by reference with
this symbol: & it's not clear how parameters are passing in fortran
most of them I guest are by value.. that's why there are these kind
of issues

Generally speaking, the variables are passed by reference in Fortran. The exceptions are variables in parenthesis and variables used in expressions, which makes sense, such as:

CALL mysub( (array) )

and

CALL mysub( array+5 )

You can also specify that variables should be passed by VALUE in F2003.

Basically the choice of the name POINTER in Fortran is misleading for people from a C/C++ background. They aren't generally pointers like one would expect, it's more like an alias for a variable. Although, it is possible to use POINTER's in Fortran in similar ways as C.

Tim

Fortran is a language with a higher level of abstraction than C. Many things that in C are well-nigh expressions of machine code in "universal assembler syntax" have no counterpart in Fortran, and details of how to pass arguments are kept out of the language specification and declared as "implementation dependent". If one finds oneself asking for such information, and no mixed-language program is involved, that should give cause for some reflection.

Although Fortran pointers are not used in the code in question, since they have been brought up more than once, perhaps an example pair would help.

What we achive in C with

#include 

struct ci{
   char c; 
   int i;};
   
typedef struct ci itm ;

main(){
itm V1, *pV, V2;

V1.c='A'; V1.i=127;
/*
..
*/
pV = &V1; 
/*
..
*/

V2 =  *pV;
printf("%c %dn",V2.c,V2.i);
}

would, in Fortran, be handled by

program fptr
!
type itm
  character :: c
  integer :: i
end type itm
!
type(itm),target :: V
type(itm) :: V2
type(itm),pointer :: pV
!
V%c='A'; V%i=127
!...
!   do some processing
!...
pV=>V   ! set the pointer
!..
!   do some processing
!...
V2=pV    ! use the pointee; no special symbol for dereferencing!
!
write(*,*)V2
!
end program fptr

It would be preferable for nickos85 to state why he needs to use an allocatable array as a dummy argument, but my hunch is that he is writing a subroutine for others to call.

In the subroutine, he wishes to allocate the array, set values into the array and return it to the caller. He probably does not want to bother the caller to figure out how much storage to allocate and do the allocation.

Leave a Comment

Please sign in to add a comment. Not a member? Join today