Sharing arrays in Fortran 95

General OpenMP discussion

Sharing arrays in Fortran 95

Postby hein61 » Mon Feb 25, 2013 9:02 am

Hi everybody from a Newby.
Glad I found you, and hope my questions won't be too trivial.

I'm in the process of rewriting a highly specialized raytracer from F77 into F95 (GNU-Fortran). The first bits of code are working nicely serially, and I thought it might be a good idea to start implementing parallelization "quickly". That was 2 weeks ago, and by now I've run out of ideas of what else to check.

Quick description of the program's structure:
So far, there are 3 modules. One contains the main program, one contains globally defined veriables, and the 3rd one some subroutines. Both main program and subroutines have access to the global veriables, and the subroutines are called from the main program.

Problem:
Arrays defined as "global" apparently can't be accessed from the subroutines (in the seperate module file). Whenever the array is referenced in one of these subroutines, the value returned equals the last one active in the preceeding serial section.
Also, the globally defined thread ID always returns nul when referenced in one of the subroutines.

I give a highly condensed (but executable) version of the program and all it's bits in the following.

The main program:
Code: Select all
program ex_tcomf

   use omp_lib
   use global_def
   use ex_raytrace

   implicit none

   integer :: ibeam


   call define_beams

   !$omp parallel default(firstprivate) shared(beam_array)

   !$ thread_id=omp_get_thread_num()

   !$omp do
   do ibeam=1,nbeams,1
      !$omp critical
      beam=beam_array(ibeam,:)
      write(*,*) 'thread',thread_id,' main: ',beam
      call check_beams
      !$omp end critical
   end do
   !$omp end do
   !$omp end parallel

end program ex_tcomf


The module with global definitions:
Code: Select all
module global_def

   implicit none

   integer :: nbeams,thread_id=0
   real,dimension(:,:),allocatable :: beam_array
   real,dimension(1) :: beam

end module global_def


The module with some subroutines:
Code: Select all
module ex_raytrace

   use global_def

   implicit none

   contains

!  ##################################################################
   subroutine define_beams

      implicit none

      integer :: ibeam


      nbeams=12

      allocate(beam_array(nbeams,1))
      beam_array=0.0

      do ibeam=1,nbeams,1
         beam(1)=real(ibeam)
         beam_array(ibeam,:)=beam
      end do

   end subroutine define_beams


!  ##################################################################
   subroutine check_beams

      implicit none


      write(*,*) 'thread',thread_id,' subr: ',beam
      write(*,*)

   end subroutine check_beams


end module ex_raytrace


And here the output withg nbeams=12
Code: Select all
thread           1  main:    4.0000000000000000
thread           0  subr:    12.000000000000000

thread           1  main:    5.0000000000000000
thread           0  subr:    12.000000000000000

thread           1  main:    6.0000000000000000
thread           0  subr:    12.000000000000000

thread           3  main:    10.000000000000000
thread           0  subr:    12.000000000000000

thread           3  main:    11.000000000000000
thread           0  subr:    12.000000000000000

thread           3  main:    12.000000000000000
thread           0  subr:    12.000000000000000

thread           0  main:    1.0000000000000000
thread           0  subr:    12.000000000000000

thread           0  main:    2.0000000000000000
thread           0  subr:    12.000000000000000

thread           0  main:    3.0000000000000000
thread           0  subr:    12.000000000000000

thread           2  main:    7.0000000000000000
thread           0  subr:    12.000000000000000

thread           2  main:    8.0000000000000000
thread           0  subr:    12.000000000000000

thread           2  main:    9.0000000000000000
thread           0  subr:    12.000000000000000


again, I do hope this is nott a question too silly. If it is, well, here I go.


Thanks for any hits,
Hein61
hein61
 
Posts: 2
Joined: Fri Feb 22, 2013 3:20 am

Re: Sharing arrays in Fortran 95

Postby MarkB » Mon Feb 25, 2013 9:48 am

Hi there,

This is not a silly question!

Inside the check_beams routine, your code references the variables thread_id and beam, which were declared private, via the default(firstprivate) clause, in the parallel region from which check_beams is called. In such a case it is unspecified whether the references in the called routine are to the private copies, or to the original items (see lines 14-21 on page 96 of the Version 3.1 spec): it appears that the implementation you have is referring to the original items.

If you want to access the private copies of thread_id and beam from inside check_beams, you can pass them in through the argument list.

Hope that helps,
Mark.
MarkB
 
Posts: 454
Joined: Thu Jan 08, 2009 10:12 am
Location: EPCC, University of Edinburgh

Re: Sharing arrays in Fortran 95

Postby hein61 » Mon Feb 25, 2013 2:33 pm

Mark,

thanks so much! Seems I got a bit carried away with streamlining my code.

And I do confess to careless reading. Looks like the spec's careful distinction between parallel construct and region does have a purpose, after all.


Again, thanks a lot!
hein61
 
Posts: 2
Joined: Fri Feb 22, 2013 3:20 am

Re: Sharing arrays in Fortran 95

Postby MarkB » Tue Feb 26, 2013 3:02 am

You're very welcome!

Mark.
MarkB
 
Posts: 454
Joined: Thu Jan 08, 2009 10:12 am
Location: EPCC, University of Edinburgh


Return to Using OpenMP

Who is online

Users browsing this forum: Google [Bot], Yahoo [Bot] and 9 guests