Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Array sections and F90/95 Standard

0 views
Skip to first unread message

Herman D. Knoble

unread,
May 14, 2008, 8:05:47 AM5/14/08
to
Question: Is the following program F90/F95 Standard conforming?
(It compiles and runs using most any compiller, displaying 3 values of 1.5).

If so, how would one compute the size of the arrray section, x(1,2)?
Or is the call to foo passing a scalar, period?

In any event...
How can one recode thte following program and determine in subroutine foo
such that foo expects either of two kinds of arguments: either x(1,2) as a scalar
or an array section vector (without using overloading)?

Thanks.
Skip Knoble


real, dimension(2,3) :: x
x=1.5
call foo(x(1,2),3)
end

subroutine foo(x,n)
integer, intent(in):: n
real, intent(in), dimension(n) :: x
integer :: i
write(*,*)"x = ",(x(i),i=1,n)
end subroutine foo

Michael Metcalf

unread,
May 14, 2008, 8:43:32 AM5/14/08
to

"Herman D. Knoble" <SkipKno...@SPAMpsu.DOT.edu> wrote in message
news:2dkl245i1flep1dmv...@4ax.com...

> Question: Is the following program F90/F95 Standard conforming?
> (It compiles and runs using most any compiller, displaying 3 values of
> 1.5).
>
> If so, how would one compute the size of the arrray section, x(1,2)?
> Or is the call to foo passing a scalar, period?
>
This is a Fortran 77-style array passing mechanism, as described in MR&C
Section 20.3. Have you thought about using elemental (which doesn't, of
course, allow I/O)?

real, dimension(2,3) :: x
x=1.5
print *, foo(x(1,2))
print *, foo(x(1,:))

contains

elemental function foo(x)
real, intent(in) :: x
integer :: i
foo = x + 1.
! write(*,*)"x = ", x
end function foo

end

Regards,

Mike Metcalf

Herman D. Knoble

unread,
May 14, 2008, 9:14:23 AM5/14/08
to
On Wed, 14 May 2008 12:43:32 GMT, "Michael Metcalf" <michael...@compuserve.com> wrote:

-|
-|"Herman D. Knoble" <SkipKno...@SPAMpsu.DOT.edu> wrote in message
-|news:2dkl245i1flep1dmv...@4ax.com...
-|> Question: Is the following program F90/F95 Standard conforming?
-|> (It compiles and runs using most any compiller, displaying 3 values of
-|> 1.5).
-|>
-|> If so, how would one compute the size of the arrray section, x(1,2)?
-|> Or is the call to foo passing a scalar, period?
-|>
-|This is a Fortran 77-style array passing mechanism, as described in MR&C
-|Section 20.3. Have you thought about using elemental (which doesn't, of
-|course, allow I/O)?
-|
-|real, dimension(2,3) :: x
-|x=1.5
-|print *, foo(x(1,2))
-|print *, foo(x(1,:))

Thanks, Mike:

The previous version that I posted displayed elements: x(1,2), x(2,2), x(1,3)
Doesn't the above (2nd) print display elements: x(1,1), x(1,2), x(1,3)?

Skip

-|
-|contains
-|
-|elemental function foo(x)
-|real, intent(in) :: x
-|integer :: i
-|foo = x + 1.
-|! write(*,*)"x = ", x
-|end function foo
-|
-|end
-|
-|Regards,
-|
-|Mike Metcalf
-|
-|

Michael Metcalf

unread,
May 14, 2008, 9:20:13 AM5/14/08
to

"Herman D. Knoble" <SkipKno...@SPAMpsu.DOT.edu> wrote in message
news:tvol24tojvad4daoh...@4ax.com...

> On Wed, 14 May 2008 12:43:32 GMT, "Michael Metcalf"
> <michael...@compuserve.com> wrote:
>
>
> The previous version that I posted displayed elements: x(1,2), x(2,2),
> x(1,3)
> Doesn't the above (2nd) print display elements: x(1,1), x(1,2), x(1,3)?
>
Right, but you're also talking about an 'array section x(1,2)' which isn't
an array section. What's your real problem?

Regards,

Mike Metcalf


Herman D. Knoble

unread,
May 14, 2008, 10:07:09 AM5/14/08
to
On Wed, 14 May 2008 13:20:13 GMT, "Michael Metcalf" <michael...@compuserve.com> wrote:

-|
-|"Herman D. Knoble" <SkipKno...@SPAMpsu.DOT.edu> wrote in message
-|news:tvol24tojvad4daoh...@4ax.com...
-|> On Wed, 14 May 2008 12:43:32 GMT, "Michael Metcalf"
-|> <michael...@compuserve.com> wrote:
-|>
-|>
-|> The previous version that I posted displayed elements: x(1,2), x(2,2),
-|> x(1,3)
-|> Doesn't the above (2nd) print display elements: x(1,1), x(1,2), x(1,3)?
-|>
-|Right, but you're also talking about an 'array section x(1,2)' which isn't
-|an array section. What's your real problem?
Mike: I have a large code that was converted to F90 syntax but
uses F77 array section calls (like call foo(x(1,2),n). I can't change
the calling (main) program.
So I need to write
several subprograms like foo, and want to use interface (or contains)
but still maintain the correct "answers" (F77 array section element order) .

Thanks again.
Skip Knoble

James Van Buskirk

unread,
May 14, 2008, 12:30:00 PM5/14/08
to
"Herman D. Knoble" <SkipKno...@SPAMpsu.DOT.edu> wrote in message
news:a7ql24ho8jg6bobh0...@4ax.com...

> Mike: I have a large code that was converted to F90 syntax but
> uses F77 array section calls (like call foo(x(1,2),n). I can't change
> the calling (main) program.
> So I need to write
> several subprograms like foo, and want to use interface (or contains)
> but still maintain the correct "answers" (F77 array section element order)
> .

Actually what you propose should be fine because sequence association
is part f90 and subsequent standards. If you really want to pass
scalars (not array elements) to the subroutine, it may be possible
as follows:

C:\gfortran\clf\scalar_or_vector>type scalar_or_vector.f90
subroutine sub(x,n)
use ISO_C_BINDING
integer(C_INT) n
type(C_PTR), value :: x
real(C_FLOAT), pointer :: ps
real(C_FLOAT), pointer :: pv(:)

if(.NOT. C_ASSOCIATED(x)) then
write(*,'(a)') 'Pointer not associated in Sub.'// &
' Normally this shouldn''t happen.'
return
end if
if(n == 1) then
call C_F_POINTER(x, ps)
write(*,*) "x = ", ps
else if(n > 1) then
call C_F_POINTER(x, pv, [n])
write(*,*) "x = ", pv
else
write(*,*) 'Thought you would trip me up with that, didn''t you?'
end if
end subroutine sub

program main
implicit none
real x(2,3)
real y
real, pointer :: z
integer i

x = reshape([(i,i=1,size(x))],shape(x))
y = 1.5
nullify(z)
call sub(z,1)
call sub(y,1)
call sub(x(1,2), 3)
call sub(x(1,2), 0)
end program main

C:\gfortran\clf\scalar_or_vector>gfortran
scalar_or_vector.f90 -oscalar_or_vecto
r

C:\gfortran\clf\scalar_or_vector>scalar_or_vector
Pointer not associated in Sub. Normally this shouldn't happen.
x = 1.5000000
x = 3.0000000 4.0000000 5.0000000
Thought you would trip me up with that, didn't you?

It's also possible to rework this example with the subroutine
in a module and explicit interface in the calling procedure
if desired.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Herman D. Knoble

unread,
May 15, 2008, 7:46:58 AM5/15/08
to
On Wed, 14 May 2008 10:30:00 -0600, "James Van Buskirk" <not_...@comcast.net> wrote:

-|"Herman D. Knoble" <SkipKno...@SPAMpsu.DOT.edu> wrote in message
-|news:a7ql24ho8jg6bobh0...@4ax.com...
-|
-|> Mike: I have a large code that was converted to F90 syntax but
-|> uses F77 array section calls (like call foo(x(1,2),n). I can't change
-|> the calling (main) program.
-|> So I need to write
-|> several subprograms like foo, and want to use interface (or contains)
-|> but still maintain the correct "answers" (F77 array section element order)
-|> .
-|
-|Actually what you propose should be fine because sequence association
-|is part f90 and subsequent standards. If you really want to pass
-|scalars (not array elements) to the subroutine, it may be possible
-|as follows:
-|
-|C:\gfortran\clf\scalar_or_vector>type scalar_or_vector.f90
-|subroutine sub(x,n)
-| use ISO_C_BINDING
-| integer(C_INT) n
-| type(C_PTR), value :: x
-| real(C_FLOAT), pointer :: ps
-| real(C_FLOAT), pointer :: pv(:)
-|
-| if(.NOT. C_ASSOCIATED(x)) then
-| write(*,'(a)') 'Pointer not associated in Sub.'// &
-| ' Normally this shouldn''t happen.'
-| return
-| end if
-| if(n == 1) then
-| call C_F_POINTER(x, ps)
-| write(*,*) "x = ", ps
-| else if(n > 1) then
-| call C_F_POINTER(x, pv, [n])
-| write(*,*) "x = ", pv
-| else
-| write(*,*) 'Thought you would trip me up with that, didn''t you?'
-| end if
-|end subroutine sub
-|
-|program main
-| implicit none
-| real x(2,3)
-| real y
-| real, pointer :: z
-| integer i
-|
-| x = reshape([(i,i=1,size(x))],shape(x))
-| y = 1.5
-| nullify(z)
-| call sub(z,1)
-| call sub(y,1)
-| call sub(x(1,2), 3)
-| call sub(x(1,2), 0)
-|end program main
-|
-|C:\gfortran\clf\scalar_or_vector>gfortran
-|scalar_or_vector.f90 -oscalar_or_vecto
-|r
-|
-|C:\gfortran\clf\scalar_or_vector>scalar_or_vector
-|Pointer not associated in Sub. Normally this shouldn't happen.
-| x = 1.5000000
-| x = 3.0000000 4.0000000 5.0000000
-| Thought you would trip me up with that, didn't you?
-|
-|It's also possible to rework this example with the subroutine
-|in a module and explicit interface in the calling procedure
-|if desired.

James, Thanks. It will take me a few days to fully understand your code here.

Skip


0 new messages