×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

Fortran90 code with FORTRAN77 subroutine

Fortran90 code with FORTRAN77 subroutine

Fortran90 code with FORTRAN77 subroutine

(OP)
Hi there. I have written a code, as a series of subroutines. The code works properly, it does the job. However, I've written it for the first time in FORTRAN77 (don't ask why, I wish I wouldn't). And then I passed it to Fortran90, because I needed dynamic arrays to work with MPI.

However, I have some array, which has a certain shape, and doesn't start in 1.

Let's say my array is f(sx:ex). And in a certain subroutine, I call another subroutine like this (I do this for different arrays f's, with different shapes):

call mysub(f, and some other parameters I need)

Then comes the subroutine, and this is why I am writing this post. This subroutine looks much like my first F77 code, and I have:

subroutine mysub(g, other parameters)
integer mxpts
parameter (mxpts=1024)

real*8 g(mxpts)

Then I work with the array g. And when it finishes it continues in the previous subroutine, but now what the code has done is, it has put the result for g, which wasn't defined with the shape of f, in the array f(sx:ex).

When I did this for the first time, I didn't realize. The code worked, and stills works, and everything is fine like this. However, I would like to understand what the compiler is doing, if I had thought a little bit more on what I was doing, I would have thought that the approach was wrong, because I have different arrays, with different shapes, even f is allocated (while g is set as an static array), and I call this subroutine for different allocated arrays, with different shapes, but it would look like if the code would take anything I put for g, copy it to the first element of g, operate on g, and return again whatever array I put with the result operated on g, but giving the correct shape for the array I have used as an argument in the subroutine call.

Can somebody tell me how is that this actually works?

Thanks in advance.

RE: Fortran90 code with FORTRAN77 subroutine

Have a look at https://software.intel.com/en-us/blogs/2009/03/31/...

The only bit that I would disagree with is that the arguments are passed by location-reference: this was the Computer Science term that was used in the 70s. I don't know what the modern terminology for this is. This is a technique that is unique to Fortran. This is different concept to pass by reference as in languages like C#, Java and C++. In those languages, pass by reference has to be a variable. In Fortran, it can be a variable or a constant, which can lead to interesting results, depending on the compiler..

Using different starting bounds is just for convenience of coding. Sometimes, it is easier to start at something else rather than 1.

CODE

!
      integer, parameter:: minx = 1, maxx = 7, zero = 4
      real temp(maxx)

      ! ii is a value between -3 and +3
      temp(ii + offset) = x 
The same algorithm can be coded as

CODE

!
      integer, parameter:: minx = -3, maxx = 3
      real temp(minx:maxx)

      ! ii is a value between -3 and +3
      temp(ii) = x 

You can do strange things when passing arrays in Fortran

CODE

!
      subroutine show(x)
      integer, parameter:: maxx = 5
!     The size does not really matter.  The dimension specified is for documentation.
      integer x(*)
      write(*, '(5I4)') (x(ii), ii = 1, maxx)
!     Change something
      x(2) = 99
      end subroutine show


      program main
      integer m5(-5:4) / 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /

      ! This starts at -5
      call show(m5)
      call show(m5)
      ! This starts at 0
      call show(m5(0:))
      call show(m5(0:))
      ! You cannot do this in any other language -5 to 4 in steps of 2
      call show(m5(-5:4:2))
      call show(m5)
      end 

RE: Fortran90 code with FORTRAN77 subroutine

(OP)
Thanks a lot for your reply.

I have a few more questions. The first one is with respect to the assignment of real*8 g(mxpts) in my code. The question is if, written like that, everytime I call the subroutine it has to make the memory assignment for the array. My intuition is that, due that it is an static array, it wouldn't. It only creates the memory space once and for all. If this array would be a dynamic array, it would allocate it every time I call the subroutine?

The second question I have is that in my code, the array g(mxpts) and the array I pass, f(sx:ex) have different sizes, and shapes. So, when I call my subroutine, what the code seems to do is to copy each element like this:

CODE

nx=ex-sx !the compiler seems to automatically "realize" of this
do i=1,nx+1
 g(i)=f(sx+i-1)
enddo 

Is that correct? and is it correct to have this subroutine with different shape than the array that I use as input? the major advantage I gain from this is that I can use this subroutine for different arrays, with different shapes, otherwise, I would need different subroutines for the arrays with different shapes and sizes.

I use to fix some big number for mxpts, like 1024 in the example below, in that way, any array smaller than that won't have any trouble going through the code.

RE: Fortran90 code with FORTRAN77 subroutine

Initially, I thought it just put the address of the first item of the passed in array instead of duplicating the array. That idea seemed to be logical for a long time. Then I discovered that you could put in a slice of non consecutive elements - the m(-5:4:2) case. I'll have to experiment a bit more and check the code generation to find out what the compiler actually does.

Re the 1024. It would be better if you passed in the size like this

CODE

!
      subroutine vary(array, size)
      real array(*)
      integer size
      do ii = 1, size
          ...


      call vary(big, ubound(big) - lbound(big) + 1) 
ubound and lbound are fortran built ins. Compilers are fussy as to where they can be applied. Sometimes they don't work, sometimes they do. You just have to work it out.

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close