- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am having a problem using parameterized derived data types with openMP.
I would like to have a derived data type (mytype), that contains both an integer (idx) and an array (a). The array (a) has a dimension (n) that is not known at compiler time, so I parameterize it.
Then I want an array of mytypes (x) of length (m).
This all works great without OpenMP. However, when I try to parallelize it, I get racing conditions that produce terminal errors. For example "forrtl: severe (157): Program Exception - access violation"
Debugging suggests that the problem is that when one thread creates a new instance of x, in assigning the dimension (n) it overwrites the dimension (n) on all other thread's version of x. So if thread 2 assigns n=2, and then thread 1 assigns n=1, when thread 2 goes to access x(:)%a(2) I get an error because thread 1 has overwritten the dimension of (n).
See minimal working example below.
It appears that mytype's parameter (n) is shared across threads. My questions are:
- Is there a way to explicitly make mytype's parameter (n) private?
- Am I trying to violate a standard of which I am unaware here?
- Is there a better way to do this that maintains the array (x) of derived times (mytype) containing an array (a) of unknown size at compiler time?
!! Module
module Program_SomeMath
implicit none
type mytype(n)
integer, len :: n
integer :: idx
real*8, dimension(n) :: a
end type mytype
contains
subroutine SomeMath(i)
implicit none
integer, intent(in) :: i
type(mytype(i)), dimension(i) :: x
integer :: j, k
do j=1,i
do k=1,i
x(k)%idx=k
x(k)%a(j)=dble(j)**2+k
end do
end do
do j=1,i
write(*,"(A,4I,30f12.0)") 'a=', i,j, size(x(j)%a), x%n, x(j)%a
end do
end subroutine SomeMath
end module Program_SomeMath
!! Main Program
program ParameterizedDerviedDataAndOpenMP
use Program_SomeMath
implicit none
integer :: i
integer, parameter :: z=10
!$OMP PARALLEL DEFAULT(PRIVATE)
!$OMP DO
do i=z,1,-1
call SomeMath(i)
end do
!$OMP END DO
!$OMP END PARALLEL
end program ParameterizedDerviedDataAndOpenMP
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Update. The below example appears to have solved this problem by making (a) an allocatable array within the derived data type.
!! Module
module Program_SomeMath
implicit none
type mytype
integer :: idx
real*8, dimension(:), allocatable :: a
end type mytype
contains
subroutine SomeMath(i)
implicit none
integer, intent(in) :: i
type(mytype),dimension(:), allocatable :: x
integer :: j, k
allocate(x(i))
do j=1,i
allocate(x(j)%a(i))
end do
do j=1,i
do k=1,i
x(k)%idx=k
x(k)%a(j)=dble(j)**2+k
end do
end do
do j=1,i
write(*,"(A,4I,30f12.0)") 'a=', i,j, size(x), size(x(j)%a), x(j)%a
end do
deallocate(x)
end subroutine SomeMath
end module Program_SomeMath
!! Main Program
program ParameterizedDerviedDataAndOpenMP
use Program_SomeMath
implicit none
! Variables
integer :: i
integer, parameter :: z=10
!Body
!$OMP PARALLEL DEFAULT(PRIVATE)
!$OMP DO
do i=z,1,-1
call SomeMath(i)
end do
!$OMP END DO
!$OMP END PARALLEL
end program ParameterizedDerviedDataAndOpenMP
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page