📄 73.html
字号:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> <style type="text/css"> body { font-family: Verdana, Arial, Helvetica, sans-serif;} a.at-term { font-style: italic; } </style> <title>Demonstration MLP program</title> <meta name="Generator" content="ATutor"> <meta name="Keywords" content=""></head><body> <p>How do you know Multi-Level Parallel Processing is occurring? We ask this question because the MPI library calls create <em>processes</em> and OpenMP directives create <em>threads</em> but while an MLP progam is executing, are these processes and threads actually being run on different physical processing chips? For example, an MLP program using
8 MPI processes and 32 OpenMP threads could be run on a single-processor workstation. But, in that case, <em>true</em> parallel processing is not happening.</p>
<p>In this section we present one method for proving that true MLP processing is taking place. Internal to a demonstration MLP program, calls to the UNIX ps command will be made at two points. The output of the ps calls will show process and thread creation (along with other critical information). The reader will see that MPI processes and OpenMP threads are indeed being executed on separate processing chips.</p>
<p>The demonstration program shown below uses the classic Boss-Worker algorithm to conduct a parallel search. A large one-dimensional array is searched for the locations (indices) of a certain value (called the mark). This particular parallel search program is designed to be run
with four MPI processes. First, the Boss MPI process (rank=0) sends different thirds of the array to three Worker MPI processes. Then, for each Worker MPI process, the search
loop of its own subarray is parallelized with OpenMP directives.</p>
<p>The first internal ps call is made near the beginning of the code when only the four MPI processes have been created. The second is toward the end of the program when each
Worker MPI process has four parallel threads searching for the index of the mark.</p>
<h3>MLP Parallel Search Demonstration Program</h3>
<p>Comments will be interspersed throughout this code. Comments written in red will explain what the next section of code is doing. Comments written in blue show where in the program the critical ps calls are made.</p>
<pre><code>
program search
INCLUDE 'mpif.h'
parameter (N=3003)
INTEGER err,rank,size
integer i
integer sub_b(N/3)
integer mark
integer b(N),thread,nts
integer status(MPI_STATUS_SIZE)
integer*8 seed
character*80, command
<em class="red">c Here are the initialization calls for both the
c MPI and OpenMP libraries</em>
CALL MPI_INIT(err)
CALL MPI_COMM_RANK(MPI_COMM_WORLD, rank, err)
CALL MPI_COMM_SIZE(MPI_COMM_WORLD, size, err)
call omp_set_num_threads(4)
if(rank==0) then
<em class="blue">c This is the first call to ps from inside the
c program. This is accomplished by giving a UNIX command to the
c subroutine SYSTEM. WARNING: the SYSTEM routine is not a
c Fortran 77 Standard</em>
print *,"R:",rank," ps using MPI only"
c command="ps -u $USER -o pid,ppid,stime,etime,cpu,comm"
command="ps -m -o pid,ppid,tid,thcount,stime,etime,cpu,comm"
call system(command)
end if
<em class="red">c The integer to be searched for is set by all
c four MPI processes</em>
mark=10
<em class="red">c The boss process first fills up the array b
c (the one that will be searched) with random integers between
c -50 and 50.</em>
if(rank.eq.0) then
seed=78946230
call ranset(seed)
do i=1,N
b(i)=nint(100.0*ranf())-50
end do
<em class="red">c The boss then sends the first third of b to
c worker 1, the second 3 to worker 2, and the last third to worker 3
</em>
CALL MPI_SEND(b(1),N/3,MPI_INTEGER,1,51,
& MPI_COMM_WORLD,err)
CALL MPI_SEND(b(N/3+1),N/3,MPI_INTEGER,2,52,
& MPI_COMM_WORLD,err)
CALL MPI_SEND(b(2*N/3+1),N/3,MPI_INTEGER,3,53,
& MPI_COMM_WORLD,err)
else if(rank.eq.1) then
<em class="red">c Worker 1 first receives its third of the
c search array and puts in its local array sub_b</em>
CALL MPI_RECV(sub_b,N/3,MPI_INTEGER,0,51,MPI_COMM_WORLD,
& status,err)
<em class="red">c Here we set up the lower level of parallel
c programming by using OpenMP directives to parallelize the search loop
c of sub_b over the 4 OpenMP threads. If the worker finds the
c mark (actually its absolute value) it prints out its MPI rank
c and OpenMP thread numbers and then the global index of the mark
c location </em>
c$omp parallel private(i,thread,command,j)
c$omp&firstprivate(rank,mark,sub_b)
thread=omp_get_thread_num()
c$omp do
do i=1,N/3
if (abs(sub_b(i)).eq.mark) then
j=(rank-1)*(N/3)+i
write(11,*)"R:",rank,"T:",thread," j=",j
end if
end do
c$omp end parallel
else if(rank.eq.2) then
CALL MPI_RECV(sub_b,N/3,MPI_INTEGER,0,52,MPI_COMM_WORLD,
& status,err)
c$omp parallel private(i,thread,command,j)
c$omp&firstprivate(rank,mark,sub_b)
thread=omp_get_thread_num()
<em class="blue">c Before beginning its search of its sub_array,
c Worker 2 first performs a call to ps from inside the program.
c Now both the threads and MPI processes should show up in
c the ps output</em>
c command="ps -u $USER -o pid,ppid,stime,etime,cpu,comm"
command="ps -m -o pid,ppid,tid,thcount,stime,etime,cpu,comm"
if(thread.eq.0) then
print *,"R:",rank,"T:",thread," ps within OpenMP"
call system(command)
end if
c$omp do
do i=1,N/3
if (abs(sub_b(i)).eq.mark) then
j=(rank-1)*(N/3)+i
write(12,*)"R:",rank,"T:",thread," j=",j
end if
end do
c$omp end parallel
else if(rank.eq.3) then
CALL MPI_RECV(sub_b,N/3,MPI_INTEGER,0,53,MPI_COMM_WORLD,
& status,err)
c$omp parallel private(i,thread,command,j)
c$omp&firstprivate(rank,mark,sub_b)
thread=omp_get_thread_num()
c$omp do
do i=1,N/3
if (abs(sub_b(i)).eq.mark) then
j=(rank-1)*(N/3)+i
write(13,*)"R:",rank,"T:",thread," j=",j
end if
end do
c$omp end parallel
end if
CALL MPI_FINALIZE(err)
end</code></pre>
<p>To see the C version of this code click on
<a href="mlp.ccode.html">C Code</a>.</p></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -