The following function describes a map between two vectors of dimension n to a vector of dimension n^2. Here, vector is a type containing a rank-1 pointer, “values”, and a logical scalar, “tmp”.
module c_algebra
type vector
private
complex(dp), dimension(:), pointer :: values => null()
logical :: tmp = .false.
end type vector
function vec_dir_vec(v1,v2 ) result(v3)
implicit none
type(vector), intent(in) :: v1,v2
type(vector), intent(out) :: v3
integer :: n1, n2, i, j
n1=size(v1); n2=size(v2)
allocate(v3%values(n1 * n2))
! forall ( i = 1:n1, j = 1:n2 )
do i=1, n1
do j=1, n2
v3%values(2*(i-1)+j) = v1%values(i) * v2%values(j)
end do
end do
! end forall
v3%tmp=.true.
call cleanup( v1 , .true. )
call cleanup( v2 , .true. )
end function vec_dir_vec
end module c_algebra
Compiling and running with portland 6.1-5 on a x86-64 machine using RHEL produces the following results for v1%values=(/cmplx(1,0),cmplx(2,0/) and v2%values=(/(3,0),(4,0)/). With a forall loop, v3%values=((2,0),(4,0),(2,0),(4,0)), whereas with the nested do loops, the correct result of ((1,0),(2,0),(2,0),(4,0)) is produced.
Now I’m pretty sure the two should be identical. Can anybody help me here?