Fortran - passing unknown array to subroutine

Click For Summary

Discussion Overview

The discussion revolves around the challenges of passing an unknown size array to a Fortran subroutine, specifically focusing on the use of allocatable arrays and interface blocks. Participants explore various approaches to defining and managing array sizes within subroutines, as well as the implications of using incorrect declarations.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant describes an attempt to pass an allocatable array to a subroutine but encounters compiler errors related to memory references and interface requirements.
  • Another participant suggests that the interface block contains incorrect variable names, which may lead to confusion and errors in the subroutine's parameter declarations.
  • A different viewpoint emphasizes the need to allocate space for the allocatable array using the SIZE intrinsic function to determine the necessary size based on the input arrays.
  • Some participants propose that the work could be done in the main program instead of the subroutine until a better understanding of allocatable arrays is achieved.
  • One participant expresses a desire to pass the third_array to the subroutine for further processing, specifically to find common numbers between datasets, indicating a need for dynamic allocation based on the data's context rather than fixed sizes.
  • Feedback highlights the importance of correctly declaring array parameters in the subroutine to match the intended usage, suggesting that the current declarations may lead to errors.
  • There is a recommendation to use modules or the contains feature instead of interface blocks to streamline the code and reduce redundancy.

Areas of Agreement / Disagreement

Participants generally agree that there are issues with the current implementation, particularly regarding variable declarations and the use of interface blocks. However, there is no consensus on the best approach to resolve these issues, as multiple competing views on how to handle allocatable arrays and subroutine design are presented.

Contextual Notes

Limitations include unresolved questions about the correct use of interface blocks versus modules, the handling of allocatable arrays, and the implications of variable scope and declaration within subroutines.

hobmarcus
Messages
10
Reaction score
0
Im trying to pass an unknown size of array to the subroutine. Then I will define the size of array in subroutine and pass it back to main program. I tried to use interface but the complier said invalid memory reference
or Explicit interface required for ' ' at (1): allocatable argument
. Any suggestions or helps? I would really appreciate for any advice/tips.
Fortran:
program
implicit none
integer :: data_1(10)
integer ::  data_2(9)
integer, allocatable :: third_array(:)

data_1= (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /)
data_2 = (/ 3, 4, 5, 6, 7, 8, 9, 10,11 /)

interface
subroutine abc  (d1,d2,ta)
implicit none
integer, INTENT(IN) :: n1
integer, INTENT(IN) :: n2
integer, INTENT(OUT), allocatable :: ta(:)
end subroutine abc
end interfacecall abc (data_1,data_2, third_array)

write(*,*) "third_array", third_array

stop

endprogram

!-------------------------------------------------------------------------subroutine abc (d1,d2,ta)

implicit none

integer, INTENT(IN) :: d1
integer, INTENT(IN) :: d2
integer, INTENT(OUT), allocatable :: ta(:)
integer :: i
allocate(ta(19))
do i=1,10
     ta(i)=d1(i)
end do
do i=11,19
     ta(i)=d1(i-10)
end do
return
end subroutine abc
 
Last edited:
Technology news on Phys.org
Just FYI, if you are going to be posting code, please learn to use the "code" tags so that it is much more readable.
 
Fortran:
subroutine abc  (d1,d2,ta)
implicit none
integer, INTENT(IN) :: n1
integer, INTENT(IN) :: n2
integer, INTENT(OUT), allocatable :: ta(:)
end subroutine abc
Your declarations for n1 and n2 don't agree with the formal parameters in your subroutine -- d1 and d2.

The last time I wrote any fortran code was about 20 years ago, and I didn't get into any of the features of allocatable arrays. From current reading, though, what you need to do after declaring an array to be allocatable, is to actually allocate space to it, using ALLOCATE. You can determine how much space to allocate to your merge array by using the SIZE intrinsic function to get the size of each of the two arrays that will be merged.

Since I am not knowledgeable about the mechanics of passing allocatable arrays to a subroutine, if I were doing this program, I would do all of the work in the main program, at least until I figured out how to work with allocatable arrays as parameters.

I think the following would work, but I don't have a Fortran compiler, so haven't tested it.

Fortran:
REAL, ALLOCATABLE :: Merged (:)  ! Rank-1 allocatable array

Arr1Size = SIZE(Array1)
Ary2Size = SIZE(Array2)
ALLOCATE (Merged(Arr1Size + Arr2Size))
  . . .
IF (ALLOCATED Merged)) DEALLOCATE (Merged)
 
Yeah, part of the problem may be the interface with the incorrect variable names, not to mentioned that the local function variables were not declared correctly to accept arrays.

But maybe the whole function call is an overkill:
Code:
integer s1, s2
s1 = size(data_1)
s2 = size(data_2)
allocate( third_array(s1+s2) )
third_array(1:s1) = data_1(1:s1)
third_array(s1+1:s1+s2) = data_2(1:s2)
 
But is there a way for me to pass the third_array to the subroutine first, and then allocate it? because i wantto use do loop to find the common number of each data set and assign them into third array actually. It is not directly related to the size of d1,d2
 
Last edited:
You are already passing the third_array just fine.

Say, did you pick up the two pieces of feedback that Mark and I posted?
1.- (From Mark) Your interface block is wrong...it lists d1 and d2 in the subroutine argument list but then it includes declaration for n1 and n2, instead.
2.- (From me) In your interface and subroutine, if d1 and d2 are meant to accept array arguments, they need to reflect that in their declaration just like data_1 and data_2 do...i.e., you need "d1(:) ", instead of simply " d1 " ...the latter is just a scalar.
3.- (one more) In your subroutine, you are using "d1" in both loops; I am sure the second instance was meant to be "d2".

Additionally, interface blocks are to be included after all non-executable statement and before any executable...up above, you included the interface block after a couple of executable statements where you assign values to data_1 and data_2 arrays.

Lastly, to eliminate one more source of errors and a lot of unnecessary redundancy, I would recommend to stop using interface blocks and start using modules or the contains feature. In this simple program of yours contains would do just fine and would spare you the interface block.
 

Similar threads

  • · Replies 20 ·
Replies
20
Views
3K
  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 4 ·
Replies
4
Views
3K
  • · Replies 5 ·
Replies
5
Views
13K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 8 ·
Replies
8
Views
4K
  • · Replies 4 ·
Replies
4
Views
4K