replica nfl jerseysreplica nfl jerseyssoccer jerseyreplica nfl jerseys forums.silverfrost.com :: View topic - Array sizes question during subroutine calls
forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Array sizes question during subroutine calls

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General
View previous topic :: View next topic  
Author Message
christyleomin



Joined: 08 Apr 2011
Posts: 155

PostPosted: Wed Feb 05, 2014 2:32 pm    Post subject: Array sizes question during subroutine calls Reply with quote

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
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Wed Feb 05, 2014 5:30 pm    Post subject: Reply with quote

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
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2615
Location: Sydney

PostPosted: Thu Feb 06, 2014 12:18 am    Post subject: Reply with quote

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
View user's profile Send private message
christyleomin



Joined: 08 Apr 2011
Posts: 155

PostPosted: Mon Feb 10, 2014 1:43 pm    Post subject: Reply with quote

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
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2615
Location: Sydney

PostPosted: Tue Feb 11, 2014 3:23 am    Post subject: Reply with quote

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
View user's profile Send private message
christyleomin



Joined: 08 Apr 2011
Posts: 155

PostPosted: Tue Feb 11, 2014 4:49 am    Post subject: Reply with quote

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
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2615
Location: Sydney

PostPosted: Tue Feb 11, 2014 1:54 pm    Post subject: Reply with quote

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
View user's profile Send private message
christyleomin



Joined: 08 Apr 2011
Posts: 155

PostPosted: Thu Feb 13, 2014 9:50 am    Post subject: Reply with quote

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
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2615
Location: Sydney

PostPosted: Thu Feb 13, 2014 1:55 pm    Post subject: Reply with quote

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
View user's profile Send private message
christyleomin



Joined: 08 Apr 2011
Posts: 155

PostPosted: Fri Feb 14, 2014 5:35 am    Post subject: Reply with quote

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
View user's profile Send private message
christyleomin



Joined: 08 Apr 2011
Posts: 155

PostPosted: Fri Feb 14, 2014 1:20 pm    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 8210
Location: Salford, UK

PostPosted: Fri Feb 14, 2014 1:37 pm    Post subject: Reply with quote

You will need to show us the code that is generating the error report.
Back to top
View user's profile Send private message AIM Address
mecej4



Joined: 31 Oct 2006
Posts: 1899

PostPosted: Sat Feb 15, 2014 12:48 am    Post subject: Re: Reply with quote

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 (Smile or (:,Smile, 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
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2615
Location: Sydney

PostPosted: Sat Feb 15, 2014 3:56 am    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> General All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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