|
[Sponsors] |
[Fortran] Passing array arguments in recursive function |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
September 15, 2022, 02:18 |
[Fortran] Passing array arguments in recursive function
|
#1 |
Senior Member
Gerry Kan
Join Date: May 2016
Posts: 350
Rep Power: 10 |
Howdy Folks (and Fortran Connoisseurs):
Say, I have a recursive function that operates on an 1D array. Would it be more memory efficient to pass the entire array with optional bounds Code:
recursive subroutine recurse ( x, i0, i1 ) ! arguments integer, dimension(:) :: x integer, intent(in), optional :: i0, i1 ! default to 1, size(x) respectively ! code and termination conditions here call recurse ( x, i0, i1 ) end subroutine Code:
recursive subroutine recurse ( x ) ! arguments integer, dimension(:) :: x ! internal variables integer :: i0, i1 ! code and termination conditions here call recurse ( x(i0:i1) ) end subroutine Thanks in advance, Gerry. P.S. - My current implementation uses the first method so there is no ambiguity here. |
|
September 15, 2022, 04:12 |
|
#2 |
Senior Member
|
As long as you pass contiguous array sections, the compiler should not create a temporary. I know this because I used to get runtime warnings for the cases where a temporary was created.
I have several recursive functions and I typically use approach 2. So, while this isn't a definitive test, I never get any warnings from those recursive calls. You might still want to look at the shenanigans of the different ways to declare the input array, which I never remember after the implementation, but you should be fine with both approaches (still, for recursive functions, I prefer 2). However, I still suggest you to make a test to have a definitive answer. |
|
September 15, 2022, 04:18 |
|
#3 |
Super Moderator
Alex
Join Date: Jun 2012
Location: Germany
Posts: 3,400
Rep Power: 47 |
My guess is that it should not matter with 1D arrays (i.e. stride 1). Both implementations should™ pass by reference without creating a temporary.
To be sure, you can run your code with some debug flags enabled. At least gfortran has runtime warnings for creating temporary arrays. The only way to be sure which is faster -if any- is to actually measure run times. And it's probably a good idea to declare intent for array x. |
|
September 15, 2022, 05:55 |
|
#4 |
Senior Member
Gerry Kan
Join Date: May 2016
Posts: 350
Rep Power: 10 |
Your experience might by different, but I never had any good experience with INTENT(OUT) or INTENT(INOUT). When I do this the subroutine in question will screw up the data in x and I end up getting total nonsense.
Like I said, I might be doing it wrong. Gerry. Last edited by Gerry Kan; September 19, 2022 at 04:25. |
|
September 15, 2022, 07:41 |
|
#5 | |
Senior Member
|
Quote:
The only case where this would be ok (as there is no choice) is when the code must strictly adhere to F77 |
||
September 15, 2022, 12:04 |
|
#6 |
Super Moderator
Alex
Join Date: Jun 2012
Location: Germany
Posts: 3,400
Rep Power: 47 |
I concur. If your code breaks when declaring the proper intent for passed variables, then it is already broken before adding intent.
The right intent is this: The subroutine writes to these variables, but does not need the initial values -> intent(out) The subroutine needs the initial values as they were passed, but does not write to them -> intent(in) Both -> intent(inout) It may sound like an unnecessary extra step, but it really helps avoiding bugs and unintended features. |
|
September 19, 2022, 05:23 |
|
#7 |
Senior Member
Gerry Kan
Join Date: May 2016
Posts: 350
Rep Power: 10 |
I am referring to passing INTENT(OUT) arrays as subroutine arguments.
Somehow when I pass an already allocated array, I end up getting results that don't make any sense. My only guess is that the INTENT(OUT) array is expected to be allocated inside the subroutine, and ignores the fact that it has already been allocated. Why it doesn't cause a run-time error but instead gives me garbage was beyond me. I also tried this with INOUT but with no avail. Gerry. |
|
September 19, 2022, 05:33 |
|
#8 | |
Senior Member
|
Quote:
You want INOUT here (which, in general, doesn't hurt to use as default when you don't know exactly) I've seen my solver run smoothly on a mesh which, with the proper compilation flags on the mesher, couldn't even be produced because of a floating point error (which also don't get signaled by default) so, the take home message is to have a very conservative set of compilation flags to use in testing before going to the production phase. EDIT: if INOUT doesn't work neither, then the problem should be somewhere else, maybe another routine where the same happens? |
||
September 19, 2022, 06:38 |
|
#9 |
Senior Member
Gerry Kan
Join Date: May 2016
Posts: 350
Rep Power: 10 |
Paolo:
It is good to know that the official behavior matched my empirical observations. For the instances that caused problems, I have managed to isolate it to my own subroutine by printing the values immediately before and after the offending subroutine call. On the other hand, would INTENT(INOUT) have the same function of not defining the INTENT at all? Gerry. |
|
September 19, 2022, 06:53 |
|
#10 | |
Senior Member
|
Quote:
If you check the input before the call to your routine (and it is ok) and after the call (and it is not) and there is no possible side effect from other parts of the code, then I don't honestly know what might be the issue here. In these case one tries to reach a minimum working example of something that doesn't work |
||
September 19, 2022, 06:58 |
|
#11 |
Senior Member
|
||
September 19, 2022, 10:21 |
|
#12 |
Senior Member
Gerry Kan
Join Date: May 2016
Posts: 350
Rep Power: 10 |
Paolo:
I came across this a few years ago. Looking back it could be the case, since the subroutine in question only serves to modify part of the array. Thanks, Gerry. |
|
September 21, 2022, 13:10 |
|
#13 |
Senior Member
Gerry Kan
Join Date: May 2016
Posts: 350
Rep Power: 10 |
Paolo:
On INTENT(INOUT) vs no INTENT, here is a little discussion that should clarify things. https://stackoverflow.com/questions/...mitting-intent Gerry. |
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Point Set Profile User Function with Field Function Arguments | wcj1n18 | STAR-CCM+ | 0 | March 23, 2022 05:47 |
[blockMesh] Errors during blockMesh meshing | Madeleine P. Vincent | OpenFOAM Meshing & Mesh Conversion | 51 | May 30, 2016 10:51 |
[blockMesh] non-orthogonal faces and incorrect orientation? | nennbs | OpenFOAM Meshing & Mesh Conversion | 7 | April 17, 2013 05:42 |
Problem with compile the setParabolicInlet | ivanyao | OpenFOAM Running, Solving & CFD | 6 | September 5, 2008 20:50 |
Droplet Evaporation | Christian | Main CFD Forum | 2 | February 27, 2007 06:27 |