Calling .Fortran from R with helper functions - r

I have a two-part question that might brush on preferred habits, and whether I'm unnecessarily complicating a problem. I've been using .C and learned .Call to do the heavy lifting from R. I wanted to do a comparison with .Fortran, and so I've been learning it as I go. Therefore, my issue may be due to my limited Fortran knowledge.
There are several functions implemented in R that I'd like to translate to Fortran that are related to each other. Rather than hash out the details of the problem I've created a minimum synonymous example that's impractical but a good illustration.
I have two functions and two related subroutines to find the magnitude and squared-magnitude, which make the entirety of the file:
! Actual functions
real function sumofsquaresfun (x,y)
implicit none
real :: x,y
sumofsquaresfun=x*x+y*y
end function sumofsquaresfun
real function magnitudefun(x,y)
implicit none
real :: x,y,tmp
tmp=sumofsquaresfun(x,y)
magnitudefun=sqrt(tmp)
end function magnitudefun
! Wrappers for R accessibility since R requires subroutines
subroutine sumofsquares(x,y,answer)
implicit none
real :: x,y
real answer
answer=sumofsquaresfun(x,y)
end subroutine sumofsquares
subroutine magnitude(x,y,answer)
implicit none
real :: x,y
real answer
answer=magnitudefun(x,y)
end subroutine magnitude
Suppose that both subroutines are useful when I'm in R, so keeping the two separate is important.
When I try t compile using
R CMD SHLIB fortrancode.f95
I have several errors the same two types of errors:
Error: Return type mismatch of function 'sumofsquaresfun' at (1) (UNKNOWN/REAL(4))
Error: Function 'sumofsquaresfun' at (1) has no IMPLICIT type
etc.
My questions in order of importance:
Even if feasible, is this the preferred approach to such a problem? Should I be using modules instead? I've seen this discussion (using a Fortran module in R?) and the related one by the same OP but don't know if involving modules is necessary/optimal.
If what I am trying to do is the correct way, what causes these embarrassing errors?
I like to use functions because that's what they're meant for, but am I being too much of a purist by creating the subroutine wrappers? Is it better style to just do away with them so I only have the two subroutines?
Many thanks!

This is more of a Fortran question than an R question.
You haven't declared the functions in your subroutines.
Do it like this and it should compile.
! Actual functions
real function sumofsquaresfun (x,y)
implicit none
real :: x,y
sumofsquaresfun=x*x+y*y
end function sumofsquaresfun
real function magnitudefun(x,y)
implicit none
real :: x,y,tmp
real sumofsquaresfun
tmp=sumofsquaresfun(x,y)
magnitudefun=sqrt(tmp)
end function magnitudefun
! Wrappers for R accessibility since R requires subroutines
subroutine sumofsquares(x,y,answer)
implicit none
real :: x,y
real answer
real sumofsquaresfun
answer=sumofsquaresfun(x,y)
end subroutine sumofsquares
subroutine magnitude(x,y,answer)
implicit none
real :: x,y
real answer
real magnitudefun
answer=magnitudefun(x,y)
end subroutine magnitude
Warning: You are using real but don't forget that R uses double precision. real is single precision. You should use something like real*8 or the Fortran95 equivalent of that.

Related

Fortran 90 difference between compaq visual fortran and gfortran

This may be a specific question, but I think it pertains to how memory is handled with these two compilers (Compaq visual Fortran Optimizing Compiler Version 6.5 and minGW). I am trying to get an idea of best practices with using pointers in Fortran 90 (which I must use). Here is an example code, which should work "out of the box" with one warning from a gfortran compiler: "POINTER valued function appears on RHS of assignment", and no warnings from the other compiler.
module vectorField_mod
implicit none
type vecField1D
private
real(8),dimension(:),pointer :: x
logical :: TFx = .false.
end type
contains
subroutine setX(this,x)
implicit none
type(vecField1D),intent(inout) :: this
real(8),dimension(:),target :: x
logical,save :: first_entry = .true.
if (first_entry) nullify(this%x); first_entry = .false.
if (associated(this%x)) deallocate(this%x)
allocate(this%x(size(x)))
this%x = x
this%TFx = .true.
end subroutine
function getX(this) result(res)
implicit none
real(8),dimension(:),pointer :: res
type(vecField1D),intent(in) :: this
logical,save :: first_entry = .true.
if (first_entry) nullify(res); first_entry = .false.
if (associated(res)) deallocate(res)
allocate(res(size(this%x)))
if (this%TFx) then
res = this%x
endif
end function
end module
program test
use vectorField_mod
implicit none
integer,parameter :: Nx = 15000
integer :: i
real(8),dimension(Nx) :: f
type(vecField1D) :: f1
do i=1,10**4
f = i
call setX(f1,f)
f = getX(f1)
call setX(f1,f)
if (mod(i,5000).eq.1) then
write(*,*) 'i = ',i,f(1)
endif
enddo
end program
This program runs in both compilers. However, changing the loop from 10**4 to 10**5 causes a serious memory problem with gfortran.
Using CTR-ALT-DLT, and opening "performance", the physical memory increases rapidly when running in gfortran, and doesn't seem to move for the compaq compiler. I usually cancel before my computer crashes, so I'm not sure of the behavior after it reaches the maximum.
This doesn't seem to be the appropriate way to use pointers (which I need in derived data types). So my question is: how can I safely use pointers while maintaining the same sort of interface and functionality?
p.s. I know that the main program does not seem to do anything constructive, but the point is that I don't think that the loop should be limited by the memory, but rather it should be a function of run-time.
Any help is greatly appreciated.
This code has a few problems, perhaps caused by misunderstandings around the language. These problems have nothing to do with the specific compiler - the code itself is broken.
Conceptually, note that:
There is one and only one instance of a saved variable in a procedure per program in Fortran 90.
The variable representing the function result always starts off undefined each time a function is called.
If you want a pointer in a calling scope to point at the result of a function with a pointer result, then you must use pointer assignment.
If a pointer is allocated, you need to have a matching deallocate.
There is a latent logic error, in that the saved first_entry variables in the getX and setX procedures are conflated with object specific state in the setX procedure and procedure instance specific state in the getX procedure.
The first time setX is ever called the x pointer component of the particular this object will be nullified due to the if statement (there's an issue of poor style there too - be careful having multiple statements after an if statement - it is only the first one that is subject to the conditional!). If setX is then called again with a different this, first_entry will have been set to false and the this object will not be correctly set-up. I suspect you are supposed to be testing this%TFX instead.
Similarly, the first time getX is called the otherwise undefined function result variable res will be nullified. However, in all subsequent calls the function result will not be nullified (the function result starts off undefined each execution of the function) and will then be erroneously used in an associated test and also perhaps erroneously in a deallocate statement. (It is illegal to call associated (or deallocate for that matter) on a pointer with an undefined association status - noting that an undefined association status is not the same thing as dissociated.)
getX returns a pointer result - one that is created by the pointer being allocated. This pointer is then lost because "normal" assignment is used to access the value that results from evaluating the function. Because this pointer is lost there can't be (and so there isn't...) a matching deallocate statement to reverse the pointer allocation. The program therefore leaks memory. What almost certainly should be happening is that the thing that captures the value of the getX function in the main program (f in this case, but f is used for multiple things, so I'll call it f_ptr...) itself should be a pointer, and it should be pointer assigned - f_ptr => getX(f1). After the value of f_ptr has been used in the subsequent setX call and write statement, it can then be explicitly deallocated.
The potential for accidental use of normal assignment when pointer assignment is intended is one of the reasons that use of functions with pointer results is discouraged. If you need to return a pointer - then use a subroutine.
Fortran 95 simplifies management of pointer components by allowing default initialization of those components to NULL. (Note that you are using default initialization in your type definition - so your code isn't Fortran 90 anyway!)
Fortran 2003 (or Fortran 95 + the allocatable TR - which is a language level supported by most maintained compilers) introduces allocatable function results - which remove many of the potential errors that can otherwise be made using pointer functions.
Fortran 95 + allocatable TR support is so ubiquitous these days and the language improvements and fixes made to that point are so useful that (unless you are operating on some sort of obscure platform) limiting the language level to Fortran 90 is frankly ridiculous.

Assigning a routine name to a different routine in Fortran

I have a solver that iterates for a good amount of time (several hours) and I'm trying to remove several if statements from the main loop in order to save time.
What I'm essentially trying to do here is to create a routine, updateGhosts, which points to an assigned routine. This routine belongs to a derived data type which contains several other properties and routines. I want to use a routine, setGhosts, to set updateGhost to be either ghostOne or ghostTwo, which will be routines that properly update some conditions.
I can't seem to figure out a method that leads the code to compile, though I've tried several different things to no avail.
I have attempted to reduce the code sample down as far as possible for simplicity, but in reality types GridPoint and BlockType have many more parameters to deal with, so simple refactoring is not an option.
Here's the reduced code:
module BlockModule
implicit none
type GridPoint
real(kind=8) :: x, y, T
end type GridPoint
type BlockType
integer :: BC
type (GridPoint) :: Points(0:102,0:102)
contains
procedure :: setGhosts, updateGhosts
procedure :: ghostOne, ghostTwo
end type BlockType
contains
subroutine setGhosts(this)
class(BlockType), intent(inout) :: this
if (this%BC == -1) then
! We want to assign updateGhosts to ghostOne.
this%updateGhosts => this%ghostOne
else
! We want to assign updateGhosts to ghostTwo.
this%updateGhosts => this%ghostTwo
end if
end subroutine
! Routine that will be either ghostOne or ghostTwo.
subroutine updateGhosts(this)
class(BlockType), intent(inout) :: this
end subroutine
! Routine will do something.
subroutine ghostOne(this)
class(BlockType), intent(inout) :: this
end subroutine
! Routine will do something completely different, with same inputs.
subroutine ghostTwo(this)
class(BlockType), intent(inout) :: this
end subroutine
end module
How can I assign a routine name to point to a different routine in Fortran90/95/03? (The oldest version possible is ideal, but not necessary.) Sorry if similar questions have been asked before, I tried a search but I'm not quite sure what I need to look for.
Thanks for reading!
(Question was answered in a comment. See Question with no answers, but issue solved in the comments (or extended in chat) )
#SuperCow wrote:
Does this help? Procedure Pointer, Derived Type
The OP wrote:
Yes! This was the trick.

Fortran Pointer arithmetic

That's my first question post ever ... don't be cruel, please.
My problem is the following. I'd like to assign a fortran pointer as an expression. I think that's not possible by simple fortran techniques. But since new fortran versions seem to provide ways to handle things used in C and C++ (like c_ptr and c_f_pointer ... ), maybe someone knows a way to solve my problem. (I have not really in idea about C, but I read that pointer arithmetic is possible in C)
To make things more clear, here is the code which came to my mind immediately but isn't working:
program pointer
real(8),target :: a
real(8),pointer :: b
b=>a*2.0d0 ! b=>a is of course working
do i=1,10
a=dble(i)*2.0d0
write(*,*)b
end do
end program
I know that there are ways around this issue, but in the actual program, all of which came to my mind, would lead to much longer computation time and/or quite wiered code.
Thanks, a lot, in advance!
Best, Peter
From Michael Metcalf,
Pointers are variables with the POINTER attribute; they are not a distinct data type (and so no 'pointer arithmetic' is possible).
They are conceptually a descriptor listing the attributes of the objects (targets) that the pointer may point to, and the address, if any, of a target. They have no associated storage until it is allocated or otherwise associated (by pointer assignment, see below):
So your idea of b=>a*2 doesn't work because b is being assigned to a and not given the value of a.
Expression, in general (there two and a half very significant exceptions), are not valid pointer targets. Evaluation of an expression (in general) yields a value, not an object.
(The exceptions relate to the case where the overall expression results in a reference to a function with a data pointer result - in that case the expression can be used on the right hand side of a pointer assignment statement, or as the actual argument in a procedure reference that correspond to a pointer dummy argument or [perhaps - and F2008 only] in any context where a variable might be required, such as the left hand side of an ordinary assignment statement. But your expressions do not result in such a function reference and I don't think the use cases are relevant to what you wnt to do. )
I think you want the value of b to change as the "underlying" value of a changes, as per the form of the initial expression. Beyond the valid pointer target issue, this requires behaviour contrary to one of the basic principles of the language (most languages really) - evaluation of an expression uses the value of its primaries at the time the expression is evaluation - subsequent changes in those primaries do not result in a change in the historically evaluated value.
Instead, consider writing a function that calculates b based on a.
program pointer
IMPLICIT NONE
real(8) :: a
do i=1,10
a=dble(i)*2.0d0
write(*,*) b(a)
end do
contains
function b(x)
real(kind(a)), intent(in) :: x
real(kind(a)) :: b
b = 2.0d0 * x
end function b
end program
Update: I'm getting closer to what I wanted to have (for those who are interested):
module test
real,target :: a
real, pointer :: c
abstract interface
function func()
real :: func
end function func
end interface
procedure (func), pointer :: f => null ()
contains
function f1()
real,target :: f1
c=>a
f1 = 2.0*c
return
end function f1
end module
program test_func_ptrs
use test
implicit none
integer::i
f=>f1
do i=1,10
a=real(i)*2.0
write(*,*)f()
end do
end program test_func_ptrs
I would be completely satisfied if I could find a way to avoid the dummy arguments (at least in when I'm calling f).
Additional information: The point is that I want to define different functions f1 and deside before starting the loop, what f is going to be inside of the loop (depending on whatever input).
Pointer arithmetic, in the sense of calculating address offsets from a pointer, is not allowed in Fortran. Pointer arithmetic can easily cause memory errors and the authors of Fortran considered it unnecessary. (One could do it via the back door of interoperability with C.)
Pointers in Fortran are useful for passing procedures as arguments, setting up data structures such as linked lists (e.g., How can I implement a linked list in fortran 2003-2008), etc.

Passing functions in R as .Fortran arguments

After spending some days already searching for something like this on the internet, I still couldn't manage to find anything describing this problem. Reading through the (otherwise quite recommendable) 'Writing R Extensions' dind't offer a solution as well. Thus, here's my most urgent question:
Is it possible to pass functions (for simplicity's sake, assume a simple R function - in reality, the problem is even uglier) as function/subroutine parameters to Fortran via .Fortran(...) call - and if so, how?
I wrote two simple functions in order to test this, first a Fortran subroutine (tailored to use the function I originally intended to pass, thus the kinda weird dimensions in the interface):
subroutine foo(o, x)
implicit none
interface
subroutine o(t, y, param, f)
double precision, intent(in) :: t
double precision, dimension(58), intent(in) :: y, param
double precision, dimension(22), intent(out) :: f
end subroutine
end interface
double precision, dimension(22), intent(out) :: x
double precision, dimension(58) :: yt, paramt
integer :: i
do i = 1, 58
yt(i) = rand(0)
paramt(i) = rand(1)
end do
call o(dble(4.2), yt, paramt, x)
end subroutine
and a simple R function to pass to the above function:
asdf <- function(a, s, d, f){x <- c(a, s, d, f)}
Calling .Fortran("foo", asdf, vector(mode="numeric", length=22)) yields
Error: invalid mode (closure) to pass to Fortran (arg 1) and passing "asdf" (as a string) results in a segfault, as the argument obviously doesn't fit the expected type (namely, a function).
FYI, I don't expect the code to do anything meaningful (that would be the task of another function), I mainly would like to know, whether passing functions (or function pointers) from R is possible at all or wether I better give up on this approach instantly and look for something that might work.
Thanks in advance,
Dean
You can't pass R objects via .Fortran. You would need to use the .Call or .External interface to pass the R objects to C/C++ code.
You could write a C/C++ wrapper for your R function, which you could then call from your Fortran code (see Calling-C-from-FORTRAN-and-vice-versa in Writing R Extensions).

pointer as a dummy argument

I am somewhat puzzled by the following program
module test
implicit none
type TestType
integer :: i
end type
contains
subroutine foo(test)
type (TestType), intent(out) :: test
test%i = 5
end subroutine
subroutine bar(test)
type (TestType), intent(out) :: test
test%i = 6
end subroutine
end module
program hello
use test
type(TestType) :: t
call foo(t)
print *, t%i
call bar(t)
print *, t%i
end program hello
and its derivatives. More on those later. As we know, Fortran transfers routine arguments as a pass-by-reference, meaning that the entity emerging at the dummy argument test for both foo and bar is the same memory space granted on the stack in program hello. So far so good.
Suppose I define in program hello the type(TestType) :: t as a pointer, and allocate it.
program hello
use test
type(TestType), pointer :: t
allocate(t)
call foo(t)
print *, t%i
call bar(t)
print *, t%i
deallocate(t)
end program hello
The code works as before, the only difference being that the object was not allocated on the stack, but on the heap.
Now assume to go back to the stack-allocated program and that subroutine bar is instead defined as
subroutine bar(test)
type (TestType), pointer :: test
test%i = 6
end subroutine
The program does not compile anymore because you must use the heap-allocated version to make it work, or to be more accurate it is mandatory to pass a pointer to the routine when the routine is defined to accept a pointer as a dummy argument. On the other hand, if the dummy argument does not contain the pointer keyword, the routine would accept both pointers and non-pointers.
This makes me wonder... what's the point of declaring a dummy argument a pointer ?
Reposted from comp.lang.fortran, an answer by Tobias Burns:
Now assume to go back to the stack-allocated program and that
subroutine bar is instead defined as
subroutine bar(test)
type (TestType), pointer :: test
test%i = 6
end subroutine
The program does not compile anymore because you must use the
heap-allocated version to make it work,
That's not quite correct: You can also not pass an ALLOCATABLE variable
to a dummy with POINTER attribute. I think one (practical) reason is
that the pointer address can escape and you would thus cause alias
problems. A formal reason is that an ALLOCATABLE is simply not a
POINTER; additionally, the standard does not talk about heap vs. stack
vs. static memory. And in fact, local arrays [with constant bounds] will
often be created in static memory and not on the stack (unless you use
OpenMP or the RECURSIVE attribute). Thus, your "stack" example could
also be a "static memory" example, depending on the compiler and the
used options.
or to be more accurate it is
mandatory to pass a pointer to the routine when the routine is defined
to accept a pointer as a dummy argument.
That's also not completely true. In Fortran 2008 you can pass a
non-POINTER, which has the TARGET attribute, to a pointer dummy which
has the INTENT(IN) attribute. (Pointer intent is relative to the pointer
association status; for non-pointer dummies the intents are about the
value stored in the variable.)
This makes me wonder... what's the point of declaring a dummy argument
a pointer ?
Well, if the argument has the POINTER attribute, you can allocate and
free the pointer target, you can associate the pointer with some target
etc. Up to Fortran 95 it was not possible to have ALLOCATABLE dummy
arguments thus a pointer had to be used if a (dummy) argument had to be
allocated in a procedure.
If you can, you should try to use rather ALLOCATABLEs than POINTERs -
they are easier to use, do not leak memory and have pose no
alias-analysis problems to the compiler. On the other hand, if you want
to create, e.g., a linked list, you need a pointer. (Though, for a heap
usage, also Fortran 2008's allocatable components could be used.*)
*I mean:
type t
type(t), allocatable :: next
end type
where the component is of the same type as the type being defined;
before F2008 this was only allowed for pointers but not for allocatables.
and by R. Maine
As we know, Fortran transfers routine arguments as a
pass-by-reference,
We apparently know incorectly, then. The standard never specifies that
and, indeed goes quite a lot out of its way to avoid such specification.
Although yours is a common misconception, it was not strictly accurate
even in most older compilers, particularly with optimization turned on.
A strict pass-by-reference would kill many common optimizations.
With recent standards, pass-by-reference is all but disallowed in some
cases. The standard doesn't use those words in its normative text, but
there are things that would be impractical to implement with
pass-by-reference.
When you start getting into things like pointers, the error of assuming
that everything is pass-by-reference will start making itself more
evident than before. You'll have to drop that misconception or many
things wil confuse you.
I think other people have answered the rest of the post adequately. Some
also addressed the above point, but I wanted to emphasize it.
Hope this answers your question.

Resources