|
Lightning user doc contents
|
MPMD parallel job example
This example uses MPI MPMD (Message Passing Interface-standard
Multiple Processors Multiple Data structures) to sum a set of 1,000,000
exponentials. The Message Passing Interface is a standardized
programming paradigm for parallel computers designed to allow separate
processes to efficiently communicate with each other via messages.
This example consists of four parts:
- A script for the LSF batch subsystem that submits the job
to lightning
- Fortran code that runs the example
- C code that runs the same example
- C++ code that runs the same example
To run this example, you have two choices:
In the /usr/local/examples/lsf/batch/ directory on lightning:
cp mpmd.* $PWD
Submit the example codes to the LSF batch subsystem by entering:
bsub < mpmd.lsf
Copy the codes on this page and paste them into your own
files:
- Copy the
LSF batch job script below and paste it into
a file named mpmd.lsf in your working directory on
lightning.
- Copy the
Fortran code below and paste it into a file named
mpmd.f in your working directory on lightning.
- Copy the
C code below and paste it into a file named
mpmd.c in your working directory on lightning.
- Copy the
C++ code below and paste it into a file named
mpmd.cc in your working directory on lightning.
- Submit the example codes to the LSF batch subsystem by
entering:
bsub < mpmd.lsf
Studying this example will help you prepare your own MPMD jobs
for submittal to lightning via LSF.
#!/bin/ksh
#
# LSF batch script to run an MPMD code
#
#BSUB -a mpich_gm
#BSUB -n 2
#BSUB -x
#BSUB -R "span[ptile=1]"
#BSUB -o mpmdlsf.out # output filename
#BSUB -e mpmdlsf.err # error filename
#BSUB -J mpmdlsf.test # job name
#BSUB -q regular # queue
#
#Build pgfile for mpmd run
rm -f pgfile
touch pgfile
#
EXE=./mpmd
#
echo LSB_HOSTS = $LSB_HOSTS
j=0
for h in ‘echo $LSB_HOSTS‘
do
echo ${h}" "${j}" "${EXE}${j} >> pgfile
j=‘expr $j + 1‘
done
#
# Fortran example
mpif90 -Mextend -o $EXE'0' mpmd.f
mpif90 -Mextend -o $EXE'1' mpmd.f
mpirun.lsf -pg pgfile /bin/pwd
# C example
mpicc -o $EXE'0' mpmd.c
mpicc -o $EXE'1' mpmd.c
mpirun.lsf -pg pgfile /bin/pwd
# C++ example
mpicxx --no_auto_instantiation -o $EXE'0' mpmd.cc
mpicxx --no_auto_instantiation -o $EXE'1' mpmd.cc
mpirun.lsf -pg pgfile /bin/pwd
rm $EXE'0' $EXE'1' pgfile
program main
implicit none
include 'mpif.h'
character (len=MPI_MAX_PROCESSOR_NAME) nodename
integer name_len, ierr
! Establish the number of the process being run with the variable "rank"
integer i
integer rank,error,tag,length,status(MPI_STATUS_SIZE)
integer hz, clock0, clock1, t
real(kind=8):: sum, buf(2), elapsed
call mpi_init(error)
! Assign the process number to the current process with "rank"
call mpi_comm_rank(MPI_COMM_WORLD,rank,error)
length=2
tag =999
! Test for the process being run, then calculate sum (process 1) or
! print sum (process 0)
call system_clock(count_rate = hz)
call system_clock(count = clock0)
if (rank .eq. 1) then
sum=0.0
do i=1,1000000
sum=sum+exp(.00000001*i)
end do
call system_clock(count = clock1)
elapsed = real(clock1 - clock0) / hz
buf(1)=sum
buf(2)=elapsed/1000.0
call mpi_send(buf,length,MPI_REAL8,0,tag,MPI_COMM_WORLD,error)
call MPI_GET_PROCESSOR_NAME(nodename, name_len, ierr)
print *,'f90 MPI task ', rank,' sending data from node ', nodename(1:name_len)
elseif (rank .eq. 0) then
call mpi_recv(buf,length,MPI_REAL8,1,tag,MPI_COMM_WORLD,status,error)
call MPI_GET_PROCESSOR_NAME(nodename, name_len, ierr)
print *,'f90 MPI task ', rank,' receiving data on node ', nodename(1:name_len)
print 10, buf(1), buf(2)
10 format(' f90 mpmd Results: Sum = ',1pe12.6,' Loop time = ',0pf12.8)
end if
call mpi_finalize(error)
stop
end
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <mpi.h>
/* Establish the number of the process being run with the variable "rank" */
main(int argc,char **argv)
{
MPI_Status status;
int i;
int rank,error,tag=42,length=2;
double buf[2], sum=0.0, elapsed, rtc();
int name_len;
char nodename[MPI_MAX_PROCESSOR_NAME];
error = MPI_Init(&argc,&argv);
/* Assign the process number to the current process with "rank" */
error=MPI_Comm_rank(MPI_COMM_WORLD,&rank);
/* Test for the process being run, then calculate sum (process 1) or */
/* print sum (process 0) */
if(rank==1)
{
elapsed=rtc();
for(i=1; i<1000000; i++)
{
sum += exp( .00000001 * (double)i );
}
elapsed=rtc()-elapsed;
buf[0]=sum;
buf[1]=elapsed;
error = MPI_Send(&buf, length, MPI_DOUBLE,0,tag,MPI_COMM_WORLD);
MPI_Get_processor_name(nodename, &name_len);
printf(" c MPI task %4d data sent from node %s\n", rank, nodename);
}
else
{
error=MPI_Recv(&buf,length,MPI_DOUBLE,1,tag,MPI_COMM_WORLD,&status);
MPI_Get_processor_name(nodename, &name_len);
printf(" c MPI task %4d data received on node %s\n", rank, nodename);
printf( " c MPI Results: Sum = %11e Loop time = %8f \n",buf[0],buf[1] );
}
error=MPI_Finalize();
exit (0);
}
double rtc()
{
static struct timeval time;
gettimeofday(&time,NULL);
return ( (double)(time.tv_sec)+(double)(time.tv_usec)/1000000.0 );
}
#include <iostream>
#include <string>
#include <math.h>
#include <mpi.h>
#include <sys/time.h>
using namespace std;
//---------------Class Defs-----------------------------------------------
class exp_sum {
public:
double elapsed;
double sum();
private:
double summer;
struct timeval time;
double rtc();
};
double exp_sum::sum()
{
int i;
summer=0.0;
elapsed=rtc();
for(i=1; i<1000000; i++)
{
summer += exp( .00000001 * (double)i );
}
elapsed=rtc()-elapsed;
return summer;
};
double exp_sum:: rtc()
{
gettimeofday(&time,NULL);
return ( (double)(time.tv_sec*1000000+time.tv_usec)/1000000 );
};
//----------------------------------------------------------------------- ---
//--------------Main Program--------------------------------------------------
int main(int argc,char **argv)
{
exp_sum total;
MPI_Status status;
int rank,error,tag=99,length=2;
double buf[2];
int name_len;
char nodename[MPI_MAX_PROCESSOR_NAME];
error = MPI_Init(&argc,&argv);
error=MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if(rank==1){
buf[0]=total.sum();
buf[1]=total.elapsed;
error = MPI_Send(&buf, length, MPI_DOUBLE,0,tag,MPI_COMM_WORLD);
MPI_Get_processor_name(nodename, &name_len);
cout << " c++ MPI task " << rank << " data sent from node " << \
nodename << endl;
}
else
{
error=MPI_Recv(&buf,length,MPI_DOUBLE,1,tag,MPI_COMM_WORLD,&status);
MPI_Get_processor_name(nodename, &name_len);
cout << " c++ MPI task " << rank << " data received on node " << \
nodename << endl;
cout << " c++ mpi Results: Sum = " << buf[0] << " Loop time = " << buf[1] << '\n';
}
error=MPI_Finalize();
return 0;
}
Next page |
IBM Linux cluster systems fundamentals -
Table of contents
If you have questions about this document, please contact
SCD Customer Support.
You can also reach us by telephone 24 hours a day, seven days a week at
303-497-1278.
Additional contact methods:
consult1@ucar.edu
and during
business hours
in NCAR Mesa Lab Suite 39.
© Copyright 2005. University Corporation for Atmospheric
Research (UCAR). All Rights Reserved.
Address of this page:
http://www.scd.ucar.edu/docs/lightning/examples/mpmd.jsp
|