 |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
christyleomin
Joined: 08 Apr 2011 Posts: 155
|
Posted: Wed Feb 05, 2014 2:32 pm Post subject: Array sizes question during subroutine calls |
|
|
I would like to know the impact of the following calls with the arguments as stated:
Code: |
subroutine My_Subroutine
......... |
First :
Code: | call sa16_temp3(iramp,idist,temp,crtem,temp1) |
Second
Code: | call A_temp3(iramp,idist,temp,crtem(1,2),temp1) |
Third:
Code: | call A_temp3(iramp,idist,temp,crtem(1,3),temp1) |
Fourth:
Code: | call A_temp3(iramp,idist,temp,crtem(1,4),temp1) |
Fifth:
Code: | call A_temp3(iramp,idist,temp,crtem(1,4),temp1) |
Code: | subroutine A_temp3(iramp,idist,temp,temp2,temp1,iret)
c
c- To find the surface temperature
c
c On entry:
c iramp - No: of time points
c idist - No: of position points
c temp - array of temperature
c temp1 - Local array
c
c On return:
c temp2 - The required array of temperature
c
c
dimension temp1(*),temp2(*)
double precision :: temp(:)
i1=0
i2=0
do j=1,iramp
do i=j,idist*iramp,iramp
i1=i1+1
temp1(i1)=temp(i)
if (i1.eq.idist) then
i2=i2+1
call sa16_tsur(iramp,idist,temp1,tsur,iret)
temp2(i2)= tsur
i1=0
endif
enddo
enddo
return
end
end |
My question is:
1) What will be the size of crtem each time it is passed to subroutine A_temp3 |
|
Back to top |
|
 |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Wed Feb 05, 2014 5:30 pm Post subject: |
|
|
The code isn't valid Fortran so its difficult to answer this.
You shouldn't pass a two-dimensional array actual argument when a one-dimensional dummy argument is expected. _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Thu Feb 06, 2014 12:18 am Post subject: |
|
|
In each call to A_temp3, you are effectively passing a starting address in the array crtem.
Subroutine A_temp3 takes this starting address as the start of a vector temp2(iramp).
Presumably you have the declaration dimension crtem(iramp,5)
call 1: crtem provides the first iramp locations, probably equivalent to crtem(1:iramp,1)
call 2: provides crtem(1:iramp,2)
call 3: provides crtem(1:iramp,3)
call 4: provides crtem(1:iramp,4)
call 5: provides crtem(1:iramp,4)
Note:
what is iret ; it is not provided in the calls to A_temp3
temp1 could be declared local in A_temp3
you should be careful with the kind of your real arguments
I think your routine is equivalent to: Code: | subroutine A_temp3(iramp,idist,temp,temp2,temp1,iret)
c
c- To find the surface temperature
c
c On entry:
c iramp - No: of time points
c idist - No: of position points
c temp - array of temperature
c temp1 - Local array
c
c On return:
c temp2 - The required array of temperature
c iret - ??? is this required
c
real*8 temp(iramp,idist)
real*4 temp1(idist), temp2(iramp)
c
do j=1,iramp
do i1=1,idist
temp1(i1)=temp(j,i1)
end do
c
call sa16_tsur(iramp,idist,temp1,tsur,iret)
temp2(j)= tsur
end do
return
end |
|
|
Back to top |
|
 |
christyleomin
Joined: 08 Apr 2011 Posts: 155
|
Posted: Mon Feb 10, 2014 1:43 pm Post subject: |
|
|
If crtem is actually an allocatable array, then how do wee deal with it. I do not want temp1 to be local in A_temp3 . Is it possible? |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Tue Feb 11, 2014 3:23 am Post subject: |
|
|
There should not be any problem as long as you have allocated crterm first, with:
ALLOCATE ( crterm(n,m) )
where n >= iramp and m >= 4
The memory address of crtemp(1,2) is determined and transferred when the subroutine is called.
There is no problem transferring temp1 through the subroutine call, as long as it is dimensioned to be >= idist
Also, you have declared iret in the subroutine definition, but not provided it as an argument in the calls. This would probably produce an access violation when you run the program.
John |
|
Back to top |
|
 |
christyleomin
Joined: 08 Apr 2011 Posts: 155
|
Posted: Tue Feb 11, 2014 4:49 am Post subject: |
|
|
Thanks John..
Yes, I'm taking care of iret.
Yes, crtem is allocated as you said :
Quote: | ALLOCATE ( crterm(iramp,5) ) |
Now, again there is a problem of passing an allocatable array as argument, isn't it?
Can you put in an example of how would you deal with it?
That is:
iret=0
1)crtem declared a ALLOCATABLE 2d array
2)call A_temp3(iramp,idist,temp,crtem(1,2),temp1,iret)
As you said the statement 2 above provides crtem(1:iramp,2)
Quote: | subroutine A_temp3(iramp,idist,temp,temp2,temp1,iret)
dimension temp1(*),temp2(*) |
Now, temp2 (i.e. crtem) is infact an allocatable arary passed as an arguemnt, right?
This produces problem as discussed in an earlier thread? |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Tue Feb 11, 2014 1:54 pm Post subject: |
|
|
Once you allocate the arrays, they can be supplied in a subroutine call as a "normal" array. You do not declare them as allocatable in A_temp3. (That is possible in F2003, although it means something different.)
eg Code: | subroutine My_Subroutine
!
real*4, allocatable :: crtem(:,:)
real*8, allocatable :: temp(:,:)
real*4, allocatable :: temp1(:)
!
integer*4 iramp, idist, iret
!
iramp = 40
idist = 33
!
allocate ( crtem(iramp,5) )
allocate ( temp(iramp,idist) )
allocate ( temp1(idist) )
!
call get_temp (iramp,idist,temp)
!
! First :
call sa16_temp3 (iramp,idist,temp,crtem,temp1)
!
! Second
call A_temp3 (iramp,idist,temp,crtem(1,2),temp1,iret)
!
! Third:
call A_temp3 (iramp,idist,temp,crtem(1,3),temp1,iret)
!
! Fourth:
call A_temp3 (iramp,idist,temp,crtem(1,4),temp1,iret)
!
! Fifth:
call A_temp3 (iramp,idist,temp,crtem(1,5),temp1,iret)
!
END subroutine My_Subroutine
subroutine A_temp3 (iramp,idist,temp,temp2,temp1,iret)
!
!- To find the surface temperature
!
! On entry:
integer*4 iramp ! No: of time points
integer*4 idist ! No: of position points
real*8 temp(iramp,idist) ! array of temperature
real*4 temp1(idist) ! Local array
!
! On return:
real*4 temp2(iramp) ! The required array of temperature
integer*4 iret ! ??? is this required
!
integer*4 j, i
!
do j=1,iramp
do i=1,idist
temp1(i)=temp(j,i)
end do
!
call sa16_tsur(iramp,idist,temp1,tsur,iret)
temp2(j)= tsur
end do
return
end subroutine A_temp3 |
|
|
Back to top |
|
 |
christyleomin
Joined: 08 Apr 2011 Posts: 155
|
Posted: Thu Feb 13, 2014 9:50 am Post subject: |
|
|
I trried this bit of code and it works fine (even in Fortran90)
That is, all changes done in subroutine checktopo_1 below are refelected correctly in TOPOLOGY array (in the write statement after the call to checktopo_1) below.
Code: | MODULE TestModule
integer,ALLOCATABLE ::TOPOLOGY(:,:)
END MODULE TestModule
subroutine MyPanel(iret)
USE TestModule
integer n1,n2
n1=10
n2=6313
ALLOCATE(TOPOLOGY(n1,n2))
do i=1,6313
do j=1,10
TOPOLOGY(j,i)=1
enddo
enddo
call checktopo_1(TOPOLOGY(2,1:n2),n2)
do i=1,n2
write(*,*)'TOPOLOGY(1,i)= ',TOPOLOGY(1,i)
write(*,*)'TOPOLOGY(2,i)= ',TOPOLOGY(2,i)
enddo
end
subroutine checktopo_1(itopo1,n2)
USE TestModule
integer n2
dimension itopo1(*)
do i=1,n2
itopo1(i)=0
enddo
end
|
|
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Thu Feb 13, 2014 1:55 pm Post subject: |
|
|
I know you are allowed to do it, but why would you use an array section in call checktopo_1(TOPOLOGY(2,1:n2),n2) ?
You are just asking for trouble.
I'd never write this, although there are possibly many who do.
You have TOPOLOGY in the module, so wouldn't it be cleaner to USE it.
My recommendation,
Code: | subroutine checktopo_1
USE TestModule
integer n2
n2 = size (TOPOLOGY, 2)
do i=1,n2
TOPOLOGY(2,i)=0
end do
!
! or simply
TOPOLOGY(2,:)=0
end subroutine checktopo_1 |
John |
|
Back to top |
|
 |
christyleomin
Joined: 08 Apr 2011 Posts: 155
|
Posted: Fri Feb 14, 2014 5:35 am Post subject: |
|
|
Thanks...I know it is not a good coding ethic.
I have a huge pice of code that needs to eb understood and upgraded.
Why do you say "asking for trouble"? Is it incorrect to pass an allocatable array as an argument? |
|
Back to top |
|
 |
christyleomin
Joined: 08 Apr 2011 Posts: 155
|
Posted: Fri Feb 14, 2014 1:20 pm Post subject: |
|
|
Hi John,
Please see my post immediately above this as well..I'm facing a peculiar problem. There are times my code compiles/builds without any issues/problems (having used above approach).
But there are times when it gives me a bunch of errors stating
Quote: | Error 8 Error: The type of the actual argument differs from the type of the dummy argument. [STRE] D:\christy_2013\FFES\source_codes\christy_16_12_2013\fortran_to_cpp\flib\my_control.F 250 |
the array [STRE] is an allocatble array passed as an argument...
All errors are of the above form to do with allocatable arrays passed as argument.
Can you help whats going on and why? |
|
Back to top |
|
 |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8210 Location: Salford, UK
|
Posted: Fri Feb 14, 2014 1:37 pm Post subject: |
|
|
You will need to show us the code that is generating the error report. |
|
Back to top |
|
 |
mecej4
Joined: 31 Oct 2006 Posts: 1899
|
Posted: Sat Feb 15, 2014 12:48 am Post subject: Re: |
|
|
christyleomin wrote: | Thanks...I know it is not a good coding ethic.
Is it incorrect to pass an allocatable array as an argument? |
It depends.
If the actual argument has been allocated before being used in a subroutine/function call, and the subroutine expects to receive an argument of size(*), nothing special needs to be done.
If the actual argument may have its allocation status changed in the subroutine, or its size, etc., are going to be queried in the subroutine, the formal argument will probably have dimension ( or (:, , and the calling subprogram must be provided with an explicit interface to the subroutine, as required by the Fortran 95 standard with the TR 15581 extensions. |
|
Back to top |
|
 |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2615 Location: Sydney
|
Posted: Sat Feb 15, 2014 3:56 am Post subject: |
|
|
Calls of the type: call checktopo_1(TOPOLOGY(2,1:n2),n2)
This can cause problems as it can create a temporary storage for the array section. Repeated use can lead to a "Stack Overflow". I would recommend to avoid array sections, as they can readily lead to Stack Overflow problems.
To answer your othe problem: Quote: | Error 8 Error: The type of the actual argument differs from the type of the dummy argument. [STRE] D:\christy_2013\FFES\source_codes\christy_16_12_2013\fortran_to_cpp\flib\my_control.F 250 |
These types of error messages are common in old fortran code prior to ALLOCATE in F90. They used memory management techniques which mixwed variable types through subroutine calls, as they shared/managed memory locations. I still use this approach, but am slowly moving to ALLOCATE. The new ALLOCATE still does not do some of the things typically done by the old approach, such as resize large arrays.
I would recommend avoiding these errors if you are not sure how to manage what the error is warning against.
John |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|