Fortran function: pointer as actual argument and target as formal - function

I am trying to decipher a fortran code. It passes a pointer to a function as an actual argument, and the formal argument is instead a target. It defines and allocates a pointer of type globalDATA in the main program, then it calls a function passing that pointer:
module dataGLOBAL
type globalDATA
type (gl_1) , pointer :: gl1
type (gd_2) , pointer :: gd2
type (gdt_ok) , pointer :: gdtok
...
...
end type globalDATA
end module dataGLOBAL
Program main
....
....
use dataGLOBAL
...
type(globalDATA),pointer :: GD
allocate(GD)
returnvalue = INIT(GD)
....
....
end
The function reads:
integer function INIT(GD) result(returnvalue)
....
....
use dataGLOBAL
type(globalDATA) , target :: GD
allocate (GD%gl1)
allocate (GD%gd2)
allocate (GD%gdtok)
....
....
end function INIT
What is the meaning of doing this? And why do both the pointer in the main program and the single components of the target structure have to be allocated?
thanks
A.

A few things may come into play...
When you provide a pointer as an actual argument to a procedure where the corresponding dummy argument does NOT have the POINTER attribute (the case here), the thing that is associated with the dummy argument is the target of the actual argument pointer. So in this case, the thing being passed is the object that GD (in the main program) is pointing to - the thing that was allocated by the allocate statement. (When both the actual and dummy arguments have the POINTER argument, then the POINTER itself is "passed" - you can change what the POINTER points to and that change is reflected back in the calling scope.)
Because the GD dummy argument inside the function has the target attribute, pointers inside the function can be pointed at the dummy argument. You don't show any declarations for such pointers, but perhaps they are in elided code. If nothing is ever pointed at the GD dummy argument (including inside any procedures that might be called by the INIT function), then the TARGET attribute is superfluous, but harmless apart from inhibiting some optimisations.
Things that have the pointer attribute also (automatically by language rules) have the TARGET attribute - so GD in the main program has the TARGET attribute. The fact that GD in the main program and in the function BOTH have the target attribute may be relevant because...
When the dummy argument has the TARGET attribute and the thing passed as the actual argument has the TARGET attribute, then pointers associated with the dummy argument inside the procedure are also "usually" (there are exceptions/processor dependencies for coindexed things/non-contiguous arrays/vector subscripted sections too complicated for me to remember) associated with the corresponding actual argument. If a pointer is not a local variable (perhaps it is a pointer declared in a module) then this association survives past the end of the procedure. Perhaps that's relevant in the elided code. (Alternatively, if the the actual argument does not have the TARGET attribute, then any pointers associated with the dummy argument become undefined when the procedure ends.)
The components of the globalDATA type are themselves pointers. Consequently, GD in the main program is a pointer to something (that something being allocated by the single ALLOCATE statement in the main program) that itself contains pointers to other things (those other things being allocated by the numerous ALLOCATE statements in the function). You have two levels of pointer, hence two levels of ALLOCATE.
Before Fortran 2003 (or Fortran 95 with the "allocatable TR") you couldn't have ALLOCATABLE components in derived types, and you couldn't have ALLOCATABLE dummy arguments - when the need for dynamic allocation collided with these former restrictions you had to use pointers instead, even if you were only using the pointers as values. I strongly suspect your code dates from this era (Support for the allocatable TR became widespread about a decade ago). In very "modern" Fortran pointers are (should?) only used when you might want variables that point at other things (where other things includes "no thing").

With a pointer variable that is a user-defined type that itself contains pointers, you have to allocate (i.e., create the storage) both the overall variable and the component pointers. The components aren't automatically allocated when the overall variable is. Someone made a design choice to allocate the overall variable in the main program and the components in a subroutine. Maybe they thought that allocating the overall variable was simple but allocating all of the components was getting complicated and wanted to relegate that to a subroutine.

Because the pointer attribute is not specified for the dummy argument, the entire derived type GD is passed from the main code (not the pointer to it). On the subroutine side, you could explicitely write
integer function INIT(GD) result(returnvalue)
...
use dataGLOBAL
type(globalDATA), intent(inout), target :: GD
to make it more clear. The target attribute of the dummy argument only ensures, that you can point to that argument inside the subroutine via pointer assignment.
As long as you are only manipulating the fields of the derived type, but not the derived type as whole (e.g. by allocating or deallocating it), it should not make a difference, whether you call the INIT routine by passing a pointer or the derived type itself.
As noted already in other answers, the purpose of the program seems to separate the allocation of the derived type and its components from each other. One possible advantage of this strategy is the possibility to pass both, pointers and statically allocated derived types to the INIT routine.

Related

Does specialization happen with or without a type annotation?

Documentation:
Argument-type declarations normally have no impact on performance:
regardless of what argument types (if any) are declared, Julia
compiles a specialized version of the function for the actual argument
types passed by the caller. For example, calling fib(1) will trigger
the compilation of specialized version of fib optimized specifically
for Int arguments, which is then re-used if fib(7) or fib(15) are
called.
The provided example:
fib(n::Integer) = n ≤ 2 ? one(n) : fib(n-1) + fib(n-2)
but then in the Performance Tips:
# This will not specialize:
function f_type(t) # or t::Type
x = ones(t, 10)
return sum(map(sin, x))
end
From my understanding of the performance tips, with or without type annotations fib(b::Integer) or fib(b) shouldn't specialize specifically for Int arguments.
It seems with or without the type annotation no specialization will happen, but why does the manual seem to indicate that it will specialize?
The example in the Performance Tips page is about the specific case where you pass the type itself as the argument to the function. As the beginning of that section says:
Julia avoids automatically specializing on argument type parameters in three specific cases: Type, Function, and Vararg
f_type in that example is a function that accepts a Type t. A call to that function will look like, for eg., f_type(Int). The section says that type specialization isn't done based on the Int type in this case, where the Int is passed as a value of the parameter itself (and then passed through to another function). (Specifically, the Type isn't specialized into a specific parametrized type like Type{Int}, as it normally would be if the argument wasn't one of the above mentioned three cases.)
This doesn't apply to the fib method (or most methods we normally define). fib accepts a value whose type is (a subtype of) Integer, not the type itself. In such cases, a call like fib(1) or fib(UInt8(2)) does create type-specialized compiled versions of the function.
In layman words, Julia will always specialize on function arguments either with or without annotation, except in three cases. One of them is when the arguments are passed to another function, since specializing twice will slow compilation down, and it will finally be specialized at the inner function call, so no performance hit occurs.
So, fib(n:Int) is equivalent to fib(n) and both will use a specialized compiled version of the function for the Int64 type unless n is already of a different type than Int64, it will specialize for that type.

Passing a lot of variables to subroutine v/s Declaring variables within subroutine

I am trying to integrate two Fortran-90 subroutines in one main function. The algorithm used in both the subroutines is logically similar but differs in array sizes (e.g. using 4 parameters to calculate a value instead of 3 etc).
I can either declare the array, allocate memory in main function and pass it as argument to subroutine or have the subroutine do it when called. In former case I will end up passing on a lot of arguments and in the latter case I will end up allocating and de-allocating variables a lot of times but passing only few arguments during subroutine call.
As the code might end up calling the subroutines several thousand times, I want to make sure that I choose the mot efficient way to achieve my goal. Can somebody shed any light on this?
If the arguments are conceptually linked you could create an object (derived data type) containing the parameters you want to use as arguments and pass the object to the subroutine.

What are the differences between functions and subroutines in Fortran?

I was under the impression that the main differences between subroutines and functions in Fortran was that functions returned values, while subroutines change some or all of the values passed as arguments. But then I learned that you could modify variables passed in to functions as arguments too. I'm confused, and can't find a good reference for the differences between them.
So, what are the differences between the two constructs, and when and why should one be preferred over the other?
Whether to use one or another is more or less a matter of programming style. You are allowed to write the arguments of both functions and subroutines as intent(in), intent(inout) or intent(out).
My personal style is however to only use the intent(in) arguments for functions, which is also a requirement for pure functions. An exception to this rule can be made when en error code intent(out) argument is necessary.
There is a subtle trap hidden in functions which return different results for the same input argument value. Consider a hypothetical function returning a random number
real function rnd()
end function
calling it once
x = rnd()
is completely OK. Calling it multiple times in a single expression
x = (rnd() + rnd()) / 2
can result in the function being called only once. Fortran language rules allow such behaviour. Therefore, the standard Fortran procedure for getting random numbers random_number() is a subroutine (and because all intrinsic functions are pure).
Where ever you cannot use a function, use a subroutine.
Any function can by converted to a subroutine by moving the result variable to a dummy argument with intent(out). The opposite process may be more problematic.

How to know where's the first function argument?

I was just wondering, If I have this ASM function:
PUSH EBP
MOV EBP, ESP
SUB ESP, 8
LEAVE
RETN 8
That does nothing and takes two 4-bytes arguments. It seems that the first argument is at EBP+8 and the second at EBP+12. But, how to know that? Because if the function takes three 4-bytes parameters, then the third will be at EBP+16. Will the first argument be always at EBP+8 and then I just have to add the argument size to get the next one? If yes, why 8?
Thanks in advance.
It's at 8 because, generally, EBP+0 = caller's saved EBP, EBP+4 = return address, EBP+8 = first stack based argument.
Also, offsets like this are normally expressed in hexadecimal values so the 2nd stack based argument will be at EBP+C and the third will be at EBP+10.
A good way (not 100% though) to deduce the calling convention of the function is to see how callers of the function prepare registers and/or the stack just prior to calling the function (and also just after the function returns).
The first stack argument will always be at [EBP+8] when using a stack frame, but calling conventions can pass arguments in both registers (general purpose and SIMD) and on the stack.
This your example assume you use a standardized convention such as __stdcall, __cdecl but arguments in __fastcall and VC++13's new __vectorcall will be in general purpose and SIMD registers respectively (and the registers themselves differ based on ABI Sys-V vs MS).
Layout of function arguments depends on calling convention being used for this function. And the calling convention can be anything that the function creator was potent to imagine.

What is the difference between a function and a subroutine?

What is the difference between a function and a subroutine? I was told that the difference between a function and a subroutine is as follows:
A function takes parameters, works locally and does not alter any value or work with any value outside its scope (high cohesion). It also returns some value. A subroutine works directly with the values of the caller or code segment which invoked it and does not return values (low cohesion), i.e. branching some code to some other code in order to do some processing and come back.
Is this true? Or is there no difference, just two terms to denote one?
I disagree. If you pass a parameter by reference to a function, you would be able to modify that value outside the scope of the function. Furthermore, functions do not have to return a value. Consider void some_func() in C. So the premises in the OP are invalid.
In my mind, the difference between function and subroutine is semantic. That is to say some languages use different terminology.
A function returns a value whereas a subroutine does not. A function should not change the values of actual arguments whereas a subroutine could change them.
Thats my definition of them ;-)
If we talk in C, C++, Java and other related high level language:
a. A subroutine is a logical construct used in writing Algorithms (or flowcharts) to designate processing functionality in one place. The subroutine provides some output based on input where the processing may remain unchanged.
b. A function is a realization of the Subroutine concept in the programming language
Both function and subroutine return a value but while the function can not change the value of the arguments coming IN on its way OUT, a subroutine can. Also, you need to define a variable name for outgoing value, where as for function you only need to define the ingoing variables. For e.g., a function:
double multi(double x, double y)
{
double result;
result = x*y;
return(result)
}
will have only input arguments and won't need the output variable for the returning value. On the other hand same operation done through a subroutine will look like this:
double mult(double x, double y, double result)
{
result = x*y;
x=20;
y = 2;
return()
}
This will do the same as the function did, that is return the product of x and y but in this case you (1) you need to define result as a variable and (2) you can change the values of x and y on its way back.
One of the differences could be from the origin where the terminology comes from.
Subroutine is more of a computer architecture/organization terminology which means a reusable group of instructions which performs one task. It is is stored in memory once, but used as often as necessary.
Function got its origin from mathematical function where the basic idea is mapping a set of inputs to a set of permissible outputs with the property that each input is related to exactly one output.
In terms of Visual Basic a subroutine is a set of instructions that carries out a well defined task. The instructions are placed within Sub and End Sub statements.
Functions are similar to subroutines, except that the functions return a value. Subroutines perform a task but do not report anything to the calling program. A function commonly carries out some calculations and reports the result to the caller.
Based on Wikipedia subroutine definition:
In computer programming, a subroutine is a sequence of program
instructions that perform a specific task, packaged as a unit. This
unit can then be used in programs wherever that particular task should
be performed.
Subroutines may be defined within programs, or separately in libraries
that can be used by many programs. In different programming languages,
a subroutine may be called a procedure, a function, a routine, a
method, or a subprogram. The generic term callable unit is sometimes
used.
In Python, there is no distinction between subroutines and functions.
In VB/VB.NET function can return some result/data, and subroutine/sub can't.
In C# both subroutine and function referred to a method.
Sometimes in OOP the function that belongs to the class is called a method.
There is no more need to distinguish between function, subroutine and procedure because of hight level languages abstract that difference, so in the end, there is very little semantic difference between those two.
Yes, they are different, similar to what you mentioned.
A function has deterministic output and no side effects.
A subroutine does not have these restrictions.
A classic example of a function is int multiply(int a, int b)
It is deterministic as multiply(2, 3) will always give you 6.
It has no side effects because it does not modify any values outside its scope, including the values of a and b.
An example of a subroutine is void consume(Food sandwich)
It has no output so it is not a function.
It has side effects as calling this code will consume the sandwich and you can't call any operations on the same sandwich anymore.
You can think of a function as f(x) = y, or for the case of multiply, f(a, b) = c. Yes, this is programming and not math. But math models and begs to be used. So we use math in cs. If you are interested to know why the distinction between function and subroutine, you should check out functional programming. It works like magic.
From the view of the user, there is no difference between a programming function and a subroutine but in theory, there definitely is!
The concept itself is different between a subroutine and a function. Formally, the OP's definition is correct. Subroutines don't take arguments or give return values by formal semantics. That's just an interpretion with conventions. And variables in subroutines are accessible in other subroutines of the same file although this can be achieved as well in C with some difficulties.
Summary:
Subroutines work only based on side-effects, in the view of the programming language you are programming with. The concept itself has no explicit arguments or return values. You have to use side effects to simulate them.
Functions are mappings of input to output value(s) in the original sense, some kind of general substitution operation. In the adopted sense of the programming world, functions are an abstraction of subroutines with information about return value and arguments, inspired by mathematical functions. The additional formal abstraction differentiates a function from a subroutine in programming context.
Details:
The subroutine originally is simply a repeatable snippet of code which you can call in between other code. It originates in Assembly or Machine language programming and designates the instruction sequence itself. In the light of this meaning, Perl also uses the term subroutine for its callable code snippets.
Subroutines are concrete objects.
This is what I understood: the concept of a (pure) function is a mathematical concept which is a special case of mathematical relations with an own formal notation. You have an input or argument and it is defined what value is represented by the function with the given argument. The original function concept is entirely unrelated to instructions or calculations. Mathematical operations (or instructions in the programming world) only are a popular formal representation (description) of the actual mapping. The original function term itself is not defined as code. Calculations do not constitute the function, so that functions actually don't have any computational overhead because they are direct mappings. Function complexity considerations only arrived as there is an overhead to find the mapping.
Functions are abstract objects.
Now, since the whole PC-stuff is running on small machine instructions, the easiest way to model (or instantiate) mathematics is with a sequence of instructions itself. Computer Science has been founded by mathematicians (noteworthy: Alan Turing) and the first programming concepts are based on it so there is a need to bring mathematics into the machine. That's how I imagine the reason why "function" is the name of something which is implemented as subroutine and why the term "pure" function was coined to differentiate the original function concept from the overly broad term-use in programming languages.
Note: in Assembly Language Programming, it is typically said, that a subroutine has been passed arguments and gives a return value. This is an interpretation on top of the concrete formal semantics. Calling conventions specify the location where values, to be considered as arguments and return values, should be written to before calling a subroutine or returning. The call itself takes only a subroutine address, and has no formal arguments or return values.
PS: functions in programming languages don't necessarily need to be a subroutine (even though programming language terminology developed this way). Functions in functional programming languages can be constant variables, arrays or hash tables. Isn't every datastructure in ECMAScript a function?
The difference is isolation. A subroutine is just a piece of the program that begins with a label and ends with a go to. A function is outside the namespace of the rest of the program. It is like a separate program that can have the same variable names as used in the calling program, and whatever it does to them does not affect the state of those variables with the same name in the calling program.
From a coding perspective, the isolation means that you don’t have to use the variable names that are local to the function.
Sub double:
a = a + a
Return
fnDouble(whatever):
whatever = whatever + whatever
Return whatever
The subroutine works only on a. If you want to double b you have to set a = b before calling the subroutine. Then you may need to set a to null or zero after. Then when you want to double c you have to again set a to equal c.
Also the sub might have in it some other variable, z, that is changed when the sub is jumped to, which is a bit dangerous.
The essential is isolation of names to the function (unless declared global in the function.)
I am writing this answer from a VBA for excel perspective. If you are writing a function then you can use it as an expression i. e. you can call it from any cell in excel.
eg: normal vlookup function in excel cannot look up values > 256 characters. So I used this function:
Function MyVlookup(Lval As Range, c As Range, oset As Long) As Variant
Dim cl As Range
For Each cl In c.Columns(1).Cells
If UCase(Lval) = UCase(cl) Then
MyVlookup = cl.Offset(, oset - 1)
Exit Function
End If
Next
End Function
This is not my code. Got it from another internet post. It works fine.
But the real advantage is I can now call it from any cell in excel. If wrote a subroutine I couldn't do that.
Every subroutine performs some specific task. For some subroutines, that task is to compute or retrieve some data value. Subroutines of this type are called functions. We say that a function returns a value. Generally, the returned value is meant to be used somehow in the program that calls the function.