- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
the following code has a (very trivial) implementation of an auto-growing array (called "list"), where each instance of it can hold a different type. It works well, as long you don't use it multi-threaded:
If you compile the code with /Qopenmp it will simply crash!
The reason is (and I couldn't believe when I saw it in the assembler code) that inside of the append-subroutine at run-time the currently used type is switched and written to GLOBAL STATIC memory. This is simply insane, and I cannot find any reason, why this information is not written onto the stack or at least in thread-local storage when /threads is specified.
Tobias
module test_mod implicit none type list class(*), allocatable :: c(:) integer :: num_nodes contains procedure :: append end type contains subroutine append(this,element) class(list) :: this class(*), intent(in) :: element class(*), allocatable :: tmp(:) integer :: l if (.not.allocated(this%c)) then allocate(this%c(1),source=element) this%c(1) = element this%num_nodes = 1 return else l = size(this%c,1) allocate(tmp(l+1),source=element) tmp(1:l) = this%c(1:l) tmp(l+1) = element deallocate(this%c) call move_alloc(tmp,this%c) this%num_nodes = this%num_nodes + 1 endif end subroutine subroutine test() type(list) :: lines type(list) :: ilines character(256):: line integer:: err,cnt,i,file_unit !Init: cnt = 1 DO i=1,100 line = 'hello' call append(lines,line) call append(ilines,i) end do end subroutine end module program Console1 use test_mod implicit none integer loop_t, nr_temps nr_temps = 20000 !$omp parallel do do loop_t = 1,nr_temps call test() end do !$omp end parallel do end program Console1
Link Copied
- « Previous
-
- 1
- 2
- Next »
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Jim,
IMHO the problems with the code in #1 are:
- the code looks unsuspicious: it only uses basic runtime functions, which usually can be used in a thread-safe manner without the need for threading primitives
- searching the web for "unlimited polymorphism multi-threaded" or "unlimited polymorphism openmp" won't find the OpenMP document refered to by Steve. Furthermore, the term "polymorphic assignment" which is used in the OpenMP documentation doesn't seem to be an term in the intel-fortran docs. There, this is just an aspect of "unlimited polymorphism". So, it's quite hard to make the connection between "unlimited polymorphism" and the OpenMP-documention.
So, here is my recommendation for other users sharing the same problem (it is quite technical, but I tried to nail it down as exact as I could)
First, check if your version of the compiler addressed that problem (IF XE 2019 Update 5 (19.0.0052.16) is buggy, earlier version probably too) - if this is not the case:
If you cannot prove, that in all modules that share the same image of the IF-runtime, there is no concurrent access to unlimited polymorphic variables, then do not use unlimited polymorphic variables.
Sloppy stated the other way around: if you use unlimited polymorphic variables and you have concurrent access to them, your program may crash (or whatever you like to call the outcome of Console1.exe in #15).
Additional notes:
- The condition is not just about concurrent access to the SAME unlimited polymorphic variable, but concurrent access to ANY two (maybe distinct) unlimited polymorphic variables.
- You may also get away, if you always use the same type with unlimited polymorphism, but
- there are still writes to global static memory (and results in a race-condition in a multi-threaded environment)
- there is very few use of polymorphism, if you use it for just one type
- The prove can be e.g.
- my code is never used by two or more concurrent threads simultaneously, or a bit more fine-grained
- every access to unlimited polymorphic variable is guarded by a critical-section as supposed by Jim in #12 (but this will only work for OpenMP based multi-threading)
Tobias
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
-
- 1
- 2
- Next »