Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Fortran90 code with FORTRAN77 subroutine 1

Status
Not open for further replies.

FloatingFeather

Programmer
Apr 17, 2017
18
AR
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.
 
Have a look at
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
 
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.

 
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.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top