Yannick
Yannick

Reputation: 50

Fortran: Cray Pointers and Derived Data Types

I've got a derived data type in fortran wich looks like this:

TYPE mytype
        INTEGER a
        DOUBLE COMPLEX, dimension(:), allocatable :: elem
END TYPE mytype

Now I want to program a function which gets a DOUBLE COMPLEX array as an argument. This array should become the array "elem" of "mytype" without allocating memory and copying the data. I tried to use a cray pointer in the following way:

DOUBLE COMPLEX, INTENT(IN) :: eleminput(5) !input array which should become x%elem
TYPE(mytype) :: x
pointer(xpntr,x%elem)
xpntr = LOC(eleminput)

When I try to compile I get an error saying it is expacting ")" instead of "%" in the line "pointer(xpntr,x%elem)". So it seems cray pointers don't work with elements of a derived data type. Is there a possibility to get this working with or also without cray pointers? The derived data type can not be changed. I hope you unterstand my question and thanks for your help.

Upvotes: 2

Views: 476

Answers (2)

IanH
IanH

Reputation: 21441

You can move an allocation. If the eleminput argument is allocatable:

integer, parameter :: dp = kind(1.0d0)
type mytype
  integer :: a
  complex(kind=dp), dimension(:), allocatable :: elem
end type

...    

subroutine foo(eleminput)
  complex(kind=dp), intent(inout), allocatable :: eleminput(:)
  type(mytype) :: x
  call move_alloc(eleminput, x%elem)
  !...  work with x
end subroutine foo

An actual argument associated with an allocatable dummy argument must itself be allocatable - that is - the call to foo must look something like:

complex(kind=dp), allocatable :: fred(:)
fred = [(0,0),(0,1),(1,1),(1,0)]
call foo(fred)

Because the allocation is moved out of the dummy argument eleminput inside the subroutine foo, the actual argument fred will be unallocated when that subroutine returns.

Upvotes: 3

user4490638
user4490638

Reputation:

Cray pointers don't work with with allocatables. I would advise strongly against using Cray pointer in new code, because Cray pointers differ subtly in implementation detail, and normal Fortran pointers work here:

module bar
  integer, parameter :: dp = selected_real_kind(15)
  TYPE mytype
     INTEGER:: a
     complex(kind=dp), dimension(:), allocatable :: elem
  END TYPE mytype

contains

  subroutine foo(eleminput)
    complex(kind=dp), dimension(:), intent(out), pointer :: eleminput
    type(mytype), target, save : : x
    allocate (x%elem(.....))
    eleminput => x%elem
  end subroutine foo
end module bar

Upvotes: 2

Related Questions