Consider this simple program:
program OpenMP_and_class implicit none type link_t integer :: id end type link_t type link_element_t type(link_t), allocatable :: element end type link_element_t type es_link_t class(link_t), pointer :: link_ptr => null() end type es_link_t type(link_element_t), allocatable, target :: links(:) integer, parameter :: n_links = 10 integer :: i type(es_link_t) :: this_link allocate(links(n_links)) do i = 1, n_links allocate(links(i)%element) links(i)%element%id = i end do !$OMP parallel do private(this_link) do i = 1, n_links call set_es_link_t(this_link, i) call process_link(this_link) end do !$OMP end parallel do contains subroutine set_es_link_t(this_link, i) type(es_link_t), intent(inout) :: this_link integer, intent(in) :: i this_link%link_ptr => links(i)%element end subroutine set_es_link_t subroutine process_link(this_link) type(es_link_t), intent(inout) :: this_link print*, this_link%link_ptr%id end subroutine process_link end program OpenMP_and_class
If you compile this program with /Qopenmp then when you run it it crashes with a stack overflow at the start of the parallel region.
The program runs fine without /Openmp and also if link_ptr is declared as type(link_t).
Now, I know the OpenMP 4.0 standard (1.6) states that Fortran 2003 polymorphic entities are not supported, so I shouldn't be surprised by this behaviour. However, it would be nice if the compiler provided a compilation diagnostic for this.
To get around this, is it legal to put the loop body into a subroutine and call it like this?
program OpenMP_and_class_2 implicit none type link_t integer :: id end type link_t type link_element_t type(link_t), allocatable :: element end type link_element_t type es_link_t class(link_t), pointer :: link_ptr => null() end type es_link_t type(link_element_t), allocatable, target :: links(:) integer, parameter :: n_links = 10 integer :: i allocate(links(n_links)) do i = 1, n_links allocate(links(i)%element) links(i)%element%id = i end do !$OMP parallel do do i = 1, n_links call set_and_process_link(i) end do !$OMP end parallel do contains subroutine set_and_process_link(i) integer, intent(in) :: i type(es_link_t) :: this_link call set_es_link_t(this_link, i) call process_link(this_link) end subroutine set_and_process_link subroutine set_es_link_t(this_link, i) type(es_link_t), intent(inout) :: this_link integer, intent(in) :: i this_link%link_ptr => links(i)%element end subroutine set_es_link_t subroutine process_link(this_link) type(es_link_t), intent(inout) :: this_link print*, this_link%link_ptr%id end subroutine process_link end program OpenMP_and_class_2
This seems to work ok. BTW, I'm using Intel Visual Fortran Composer for WIndows XE 2013 SP1 Update 2