- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I am currently rewriting our ray tracing code and hope to eventually make it work in parallel. I am now at a point where I need to decide what method I will be using. I was looking into Boost (C++) before but hopefully, Open MP will do the job so I do not have to mix languages.
This is my first multi-threaded project so I am starting small to make sure I understand how everything works. In the code below, I am setting the number of threads manually since I do not want to tangle with scheduling concepts just yet.
[cpp]program test use omp_lib implicit none integer ii,th_id !omp$ parallel !omp$ do, private(ii,th_id), num_threads(2) write(6,*) omp_get_num_threads() write(6,*) omp_get_num_procs() do ii=1,10 th_id = omp_get_thread_num() write(6,*) th_id end do !omp$ end do !omp$ end parallel endprogram[/cpp]
The output is 1, 2, followed by zeroes.
Obviously, the two cores are being recognized properly but only a single thread is being created so th_id is always 0. Also, running in debug mode only shows a single thread.
I must be doing something wrong in my !omp$ do declaration but I don't see what it is.
I am using 10.1.021 with default debug options (except for /Qopenmp obviously).
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[cpp]#ifdef _OPENMP !$omp parallel !$omp single nt=omp_get_num_threads() write(cmpter(16)(27:72),'(i0)'),nt !$omp end single !$omp end parallel #endif[/cpp]
I agree with the idea of putting your threading in Fortran, rather than making it mixed language.
You are already going beyond the simplest concepts. at least if I judge by what I can find explained in introductory material.
To begin with, your OMP DO directive should be immediately before the Fortran do. OMP END DO isn't needed, it knows enough to finish off with the Fortran end do.
I would suggest !$omp single ...... !$omp end single (inside aparallel region) for omp function calls outside a loop. You would also need #ifdef _OPENMP..... #endif around the function calls, if you want to preserve the ability to turn off OpenMP. In my posted example I use
#ifdef _OPENMP
!$omp parallel
!$omp single
nt=omp_get_num_threads()
write(cmpter(16)(27:72),'(i0)'),nt
!$omp end single
!$omp end parallel
#endif
Gosh, I wonder if the text insertion tools are working properly today. Both of us appear to be having trouble.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[cpp]#ifdef _OPENMP
!$omp parallel
!$omp single
nt=omp_get_num_threads()
write(cmpter(16)(27:72),'(i0)'),nt
!$omp end single
!$omp end parallel
#endif[/cpp]
I agree with the idea of putting your threading in Fortran, rather than making it mixed language.
You are already going beyond the simplest concepts. at least if I judge by what I can find explained in introductory material.
To begin with, your OMP DO directive should be immediately before the Fortran do. OMP END DO isn't needed, it knows enough to finish off with the Fortran end do.
I would suggest !$omp single ...... !$omp end single (inside aparallel region) for omp function calls outside a loop. You would also need #ifdef _OPENMP..... #endif around the function calls, if you want to preserve the ability to turn off OpenMP. In my posted example I use
#ifdef _OPENMP
!$omp parallel
!$omp single
nt=omp_get_num_threads()
write(cmpter(16)(27:72),'(i0)'),nt
!$omp end single
!$omp end parallel
#endif
Gosh, I wonder if the text insertion tools are working properly today. Both of us appear to be having trouble.
I am not sure SINGLE will do what I want: the help says this will be called only from a single thread in the team. Here, I am looking to get a handle that will be unique for each thread.
My reasoning is that in my code, I will need to print the ray trajectory. I want each thread to follow the starting ray from a given emission point as well as any other secondary rays it spawns when hitting various interfaces. Normally I write this to a file but I/O is troublesome in multi-threading and I need to keep the sequence intact fro a given primary ray so the trajectory makes sense.
If this was C++, I would simply use a thread-private vector
In any case, I tried simplifying the code even further to no avail. This still prints out nothing but zeroes in the loop.
[cpp]program test use omp_lib implicit none integer ii,th_id write(6,*) 'Number of processors: ', omp_get_num_procs() !OMP$ PARALLEL DO PRIVATE(th_id) NUM_THREADS(2) do ii=1,10 th_id = omp_get_thread_num() write(6,*) 'Hello from thread #: ', th_id end do endprogram
[/cpp]
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks so much. I had not noticed it was a different style than !DEC$. Works perfectly now so I can start thinking about the bigger project.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Fortran with OpenMP has ThreadPrivate capability (I use this). Create a thread private variable with a thread ID number with default initialization to -1. Add a module variable, intialized to 0 and then when thread runs and notices -1 in thread ID it call InterlockedIncrement on the shared variable, taking the result and placing it into the thread private thread ID (the InterlockedIncrement occures once for the life of the thread).
Jim Dempsey

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page