Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

passing pointers to subroutines

abaraldi
Beginner
675 Views

Hi, I started using Intel Fortran on my Linux machine. I am trying to do the following: exploit the column-major memory management of Fortran in order to go from 1D array of pointers into 2D arrays. Here is an example:

PROGRAM main

REAL, DIMENSION(:), POINTER :: U

ALLOCATE(U(IMAX*JMAX*KMAX))

...

CALL getslice(U(1))

...

CONTAINS

SUBROUTINE getslice(V)

real, dimension(IMAX,JMAX), intent(IN) :: V

...

END SUBROUTINE getslice

END PROGRAM main

As you can see from this sample code, I am passing the pointer to the first entry of U to the subroutine, which receives a 2D array. I always did this, with pathscale and also Intel compiler but on different architectures. Now with Intel on Linux it does not work (I am using .f90 files):

main.f90(75): error #7836: If the actual argument is scalar, the corresponding dummy argument shall be scalar unless the actual argument is an element of an array that is not an assumed-shape or pointer array, or a substring of such an element.
call getslice(U(1))

Thanks for any help!

Also, is it possible to use the array visualizer on Linux?

AB

0 Kudos
1 Solution
rreis
New Contributor I
675 Views

CALL getslice(U(1:IMAX*JMAX))

should do it. What you're doing is passing element U(1) from the array. An alternative would be:

integer :: k

REAL, DIMENSION(:), TARGET :: U

REAL, DIMENSION(:), pointer :: U_ptr

ALLOCATE(U(IMAX*JMAX*KMAX))

k=1

U_ptr => U(k*(IMAX*JMAX))

...

CALL getslice(U_ptr)

...

or, just another way of looking into the flat array ...

REAL, DIMENSION(:), TARGET :: U

REAL, DIMENSION(:,:), pointer :: U_ptr

ALLOCATE(U(IMAX*JMAX*KMAX))

k=1

U_ptr => U((k-1)*(IMAX*JMAX)+1:k*(IMAX*JMAX))

U_ptr(1,1) = some_real_number

View solution in original post

0 Kudos
2 Replies
rreis
New Contributor I
676 Views

CALL getslice(U(1:IMAX*JMAX))

should do it. What you're doing is passing element U(1) from the array. An alternative would be:

integer :: k

REAL, DIMENSION(:), TARGET :: U

REAL, DIMENSION(:), pointer :: U_ptr

ALLOCATE(U(IMAX*JMAX*KMAX))

k=1

U_ptr => U(k*(IMAX*JMAX))

...

CALL getslice(U_ptr)

...

or, just another way of looking into the flat array ...

REAL, DIMENSION(:), TARGET :: U

REAL, DIMENSION(:,:), pointer :: U_ptr

ALLOCATE(U(IMAX*JMAX*KMAX))

k=1

U_ptr => U((k-1)*(IMAX*JMAX)+1:k*(IMAX*JMAX))

U_ptr(1,1) = some_real_number

0 Kudos
Steven_L_Intel1
Employee
675 Views
See Doctor Fortran in "I've Come Here For an Argument", the section on Sequence Association.
0 Kudos
Reply