Associate construct

Dear all,
I have some issues with associate construct
The following code

program test
implicit none

type type_a
  complex(8), dimension(:,:), allocatable :: z
end type type_a

type(type_a) :: a
integer, parameter :: n = 2
integer :: i, j

allocate(a%z(n,n))

do j = 1, n
  associate ( array => a%z(:,j) )
  call do_stuff( array, n )
  end associate
end do

do i = 1, n
   print*, a%z(i,:)
end do

contains

subroutine do_stuff( b, n )
integer, intent(in) :: n
complex(8)          :: b(n)
integer             :: i

do i = 1, n
  b(i) = (1,1)
end do

end subroutine do_stuff

end program test

Gives Segmentation fault: 11

The result must be

( 1.0000000000000000 , 1.0000000000000000 ) ( 1.0000000000000000 , 1.0000000000000000 )
( 1.0000000000000000 , 1.0000000000000000 ) ( 1.0000000000000000 , 1.0000000000000000 )

If array z is not a derived type attribute, it works.
Cheers
Pierre

Reply to myself.

After investigations in my own code, i discover that the PGI compiler does not deal well with slicing inside an associated construct.

You need to give the explicit bounds of the array slice. If you change

associate ( array => a%z(:,j) ) by associate ( array => a%z(1:n,j) ) It works.

Everytime you will use a slice of “array” bounds must be mentioned.
Pierre

Pierre,

Your program compiles without a problem using the 17.1 release, out
as soon as we can get it out. There was a bit of work on ASSOCIATE for the
17.1 release.

dave

Dear PGI
I try to build this test program but it doesn’t work with 18.3 version

program test
implicit none
integer :: i, j
integer, parameter  :: n1 = 5
integer, parameter  :: n2 = 5
real(8) :: dx
real(8), dimension(n1,n2) :: derivs

dx = 1.0_8 / real(n1, kind=8)
do i = 1, n1
  do j = 1, n2
    derivs(i,j) = (i-1) * dx
  end do
end do

associate( h => [(dx**i, i=1, ubound(derivs,1))] )
  do j = lbound(derivs,2), ubound(derivs,2)
    derivs(1:,j) = derivs(1:,j) * h !(1:)
  end do
end associate

do i = 1, n1
  write(*,"(5f7.3)") ( derivs(i,j), j = 1, n2)
end do

end program test

The result should be:

$ ifort test.F90 && ./a.out
  0.000  0.000  0.000  0.000  0.000
  0.008  0.008  0.008  0.008  0.008
  0.003  0.003  0.003  0.003  0.003
  0.001  0.001  0.001  0.001  0.001
  0.000  0.000  0.000  0.000  0.000
$ gfortran test.F90 &&  ./a.out
  0.000  0.000  0.000  0.000  0.000
  0.008  0.008  0.008  0.008  0.008
  0.003  0.003  0.003  0.003  0.003
  0.001  0.001  0.001  0.001  0.001
  0.000  0.000  0.000  0.000  0.000

The developers like to code fortran like this, i am just the software engineer, sorry :-)

Pierre

Thanks Pierre.

I have recreated this issue here and sent our engineers problem report (TPR#25575).

-Mat

This last issue looks like it was addressed sometime around the transition to the NVIDIA HPC compilers and nvfortran. Sorry for not replying earlier, and not quite sure which exact release, but it appears to work at least a year back.

1 Like