open(16,file=filrdf,status='replace')
write(*,'(1x,"Monte Carlo calculation")')
!$OMP PARALLEL SHARED(X,Y,Z,ISTP) PRIVATE(TID)
!$ TID=OMP_GET_THREAD_NUM()
!$ write(*,*) "Master Thread =", TID
!! Only master thread does this
!$ IF (TID .EQ. 0) THEN
!$ NTHREADS = OMP_GET_NUM_THREADS()
!$ write(*,*) 'Number of threads = ', NTHREADS
!$ END IF
!$OMP DO
mcstp: do istp=1,rmcs
iatm=int(ntot*rvec(istp))+1
old_x=x(iatm);old_y=y(iatm);old_z=z(iatm)
x(iatm)=x(iatm)+dr*(rvec(iatm)-0.5)
y(iatm)=y(iatm)+dr*(rvec(iatm)-0.5)
z(iatm)=z(iatm)+dr*(rvec(iatm)-0.5)
call PBC(x,y,z,boxl)
!$OMP CRITICAL
call crdf(filrdf,x,y,z,boxl,ntot,nap,rrl,gr_new,rmin,exst)
!$OMP END CRITICAL
! write(*,*) gr_new
if (.not.exst) then
write(*,*) "Problem in openning file ",filrdf,"in step",istp
stop
endif
mcst=rmcs/10
if (mod(istp,mcst)==0) write(*,'(a2,$)') ". "
!---------------------------------------------------------------
call metropolis(rdf_ex,gr,gr_new,ntot,chng,rho,boxl,sigma,istp)
if (chng==1)then
x(iatm)=old_x
y(iatm)=old_y
z(iatm)=old_z
end if
end do mcstp
!$OMP END DO
!$OMP END PARALLEL
close(16)
where i am expecting the do loop will be shared by all threads equally
(say, if rmcs=1000,istp1=100 will work on first thread,101 to 200 on
2nd thread and so on) but its not ...whats wrong in the code and how
to make it correct? all the other subroutine is serial and i am using
gfortran -fopenmp
if you want to divide the loop into some equal shares, you maybe need
a nested do.
!$omp do
do istp=1,10
do i=1,rmcs/10
...
enddo
enddo
yes, every step of loop must be equal.
if divide the loop to some shares, things is different.
At least you have to declare as PRIVATE the following variables:
old_x, old_y, old_z, iatm, mcst, probably chng, and maybe others, like
gr_new, ntot and so on.
I suggest you use DEFAULT(NONE) and declare every single variable as
either SHARED or PRIVATE after thinking about its usage. This is a step
that you, the programmer, have to do! The compiler just uses the
default, which is SHARED ... unlikely that you really want this because
it produces data races in the code that you've shown.
HTH,
Kay
Monte Carlo calculation
Threads = 7
Threads = 0
Number of threads = 8
Threads = 6
Threads = 5
Threads = 4
Threads = 3
Threads = 2
Threads = 1
then i wrote the thread numbers and which istp id done by which thread
by adding a line :
write(22,*) istp,"is done by",TID
inside mcstp do loop. here i am seeing
these are my threads and most of my jobs are done by the thread listed
at the bottom (1 here).
is it what it suppose to do? in my understanding, whole work will be
divided equally to all the thread.
It seems that the inner "omp do" doesn't work.
so , pay attention to envirement variable "omp_nested" ( and
"omp_max_active_levels).
Um, that's not how I understand OpenMP to work -- as I understand
it, the number of threads is by default the number of processors,
or it can be explicitly set with an environment variable
(OMP_NUM_THREADS) or with a call to OMP_SET_NUM_THREADS.
> if you want to divide the loop into some equal shares, you maybe need
> a nested do.
>
> !$omp do
> do istp=1,10
> do i=1,rmcs/10
> ...
> enddo
> enddo
How the iterations of a loop are split up among threads
can be controlled by the SCHEDULE clause of the OpenMP DO
construct. I'm not sure what the default is (and it may be
implementation-dependent), but "SCHEDULE(STATIC)" will split
up the iterations evenly among threads. That's usually a good
choice if all of the iterations of the loop do about the same
amount of work. I haven't looked carefully enough at the OP's
code to know whether that's the case.
How threads are assigned to processors is, as far as I know,
determined by the operating system, but (limited) experiment
suggests that if you have one thread per processor, the system
will assign one thread to each processor.
--
B. L. Massingill
ObDisclaimer: I don't speak for my employers; they return the favor.
> > !$ TID=OMP_GET_THREAD_NUM()
> > !$ write(*,*) "Master Thread =", TID
> > !! Only master thread does this
> > !$ IF (TID .EQ. 0) THEN
> > !$ NTHREADS = OMP_GET_NUM_THREADS()
> > !$ write(*,*) 'Number of threads = ', NTHREADS
> > !$ END IF
For code you only want to be executed by one thread, you could
use the OpenMP "master" construct (warning -- untested code):
!$OMP MASTER
NTHREADS = OMP_GET_NUM_THREADS()
write(*,*) 'Number of threads = ', NTHREADS
!$OMP END MASTER
Something of a nitpick, but might be useful to know.
> > !$OMP DO
> >
> > mcstp: do istp=1,rmcs
[ snip ]
> I suggest you use DEFAULT(NONE) and declare every single variable as
> either SHARED or PRIVATE after thinking about its usage. This is a step
> that you, the programmer, have to do! The compiler just uses the
> default, which is SHARED ... unlikely that you really want this because
> it produces data races in the code that you've shown.
This is excellent advice!
SCHEDULE(STATIC) should do that.
> It seems that the inner "omp do" doesn't work.
> so , pay attention to envirement variable "omp_nested" ( and
> "omp_max_active_levels).
For which I *think* you will need a fairly recent version of gfortran;
as I understand it, some versions don't support nested parallelism.
I'm skeptical, though, about whether it's needed.
Well, that (work divided among threads) is probably what you want,
all right! But I'm not sure what happens if you don't have a
SCHEDULE clause on the DO -- it may depend on the implementation,
and it's possible that gfortran makes a choice that's not what
one might want.
Try it again with "!$OMP DO SCHEDULE(STATIC)" and see if you get
different behavior.
[ snip ]
> > inside mcstp do loop. here i am seeing
> > these are my threads and most of my jobs are done by the thread listed
> > at the bottom (1 here).
> > is it what it suppose to do? in my understanding, whole work will be
> > divided equally to all the thread.
>
> Well, that (work divided among threads) is probably what you want,
> all right! But I'm not sure what happens if you don't have a
> SCHEDULE clause on the DO -- it may depend on the implementation,
> and it's possible that gfortran makes a choice that's not what
> one might want.
>
> Try it again with "!$OMP DO SCHEDULE(STATIC)" and see if you get
> different behavior.
Would it be pushy of me to request that the OP come back and tell us
at some point whether any of the advice posted was useful?
[Snip...]
> Would it be pushy of me to request that the OP come back and tell us
> at some point whether any of the advice posted was useful?
IMO, not at all. However, this seems to be another drive-by poster (maybe
slacking on homework assignments) who labors under the delusion of Usenet
as a 365/24/7 no-fee HellDesk. Ergo, I wouldn't get my hopes up... :)
JMO; YMMV...
--
Regards, Weird (Harold Stevens) * IMPORTANT EMAIL INFO FOLLOWS *
Pardon any bogus email addresses (wookie) in place for spambots.
Really, it's (wyrd) at airmail, dotted with net. DO NOT SPAM IT.
I toss GoogleGroup posts from gitgo (http://improve-usenet.org).
Eh, I think rudra has posted enough (and detailed enough) questions that
we can say that s/he isn't trying to get homework done.