Monte Carlo Simulation

advertisement
Monte Carlo Simulation
• Used when it is infeasible or impossible to compute
an exact result with a deterministic algorithm
• Especially useful in
– Studying systems with a large number of coupled degrees
of freedom
• Fluids, disordered materials, strongly coupled solids, cellular
structures
– For modeling phenomena with significant uncertainty in
inputs
• The calculation of risk in business
– These methods are also widely used in mathematics
• The evaluation of definite integrals, particularly multidimensional
integrals with complicated boundary conditions
1
Monte Carlo Simulation
• No single approach, multitude of different
methods
• Usually follows pattern
– Define a domain of possible inputs
– Generate inputs randomly from the domain
– Perform a deterministic computation using the
inputs
– Aggregate the results of the individual
computations into the final result
• Example: calculate Pi
2
•
•
•
•
•
•
•
Monte Carlo: Algorithm for Pi
The value of PI can be calculated in a number of
ways. Consider the following method of
approximating PI Inscribe a circle in a square
Randomly generate points in the square
Determine the number of points in the square that
are also in the circle
Let r be the number of points in the circle divided
by the number of points in the square
PI ~ 4 r
Note that the more points generated, the better
the approximation
Algorithm :
npoints = 10000
circle_count = 0
do j = 1,npoints
generate 2 random numbers between 0 and 1
xcoordinate = random1 ; ycoordinate = random2
if (xcoordinate, ycoordinate) inside circle
then circle_count = circle_count + 1
end do
PI = 4.0*circle_count/npoints
3
4
OpenMP Pi Calculation
Initialize variables
Initialize OpenMP parallel environment
N WorkerThreads
Master Thread
N
Generate random X,Y
Generate random X,Y
Generate random X,Y
Calculate Z=X^2+Y^2
Calculate Z =X^2+Y^2
Calculate Z =X^2+Y^2
If point
lies within
the circle
If point
lies within
the circle
Count ++
Y
Count ++
N
Y
N
If point
lies within
the circle
Count ++
Y
Reduction ∑
Calculate PI
Print value of pi
5
OpenMP Calculating Pi
#include <omp.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#define SEED 42
Seed for generating random number
main(int argc, char* argv)
{
int niter=0;
double x,y;
int i,tid,count=0; /* # of points in the 1st quadrant of unit circle
*/
double z;
double pi;
time_t rawtime;
struct tm * timeinfo;
printf("Enter the number of iterations used to estimate pi: ");
scanf("%d",&niter);
time ( &rawtime );
timeinfo = localtime ( &rawtime );
http://www.umsl.edu/~siegelj/cs4790/openmp/pimonti_omp.c.HTML
6
OpenMP Calculating Pi
printf ( "The current date/time is: %s", asctime (timeinfo) );
Initialize random number generator; srand is used to
/* initialize random numbers */
srand(SEED);
seed the random number generated by rand()
#pragma omp parallel for private(x,y,z,tid) reduction(+:count)
for ( i=0; i<niter; i++) {
Initialize OpenMP parallel for with reduction(∑)
x = (double)rand()/RAND_MAX;
y = (double)rand()/RAND_MAX;
Randomly generate x,y points
z = (x*x+y*y);
Calculate x^2+y^2 and check if it lies within the circle; if
if (z<=1) count++;
if (i==(niter/6)-1) {
yes then increment count
tid = omp_get_thread_num();
printf(" thread %i just did iteration %i the count is %i\n",tid,i,count);
}
if (i==(niter/3)-1) {
tid = omp_get_thread_num();
printf(" thread %i just did iteration %i the count is %i\n",tid,i,count);
}
if (i==(niter/2)-1) {
tid = omp_get_thread_num();
printf(" thread %i just did iteration %i the count is %i\n",tid,i,count);
}
http://www.umsl.edu/~siegelj/cs4790/openmp/pimonti_omp.c.HTML
7
Calculating Pi
if (i==(2*niter/3)-1) {
tid = omp_get_thread_num();
printf(" thread %i just did iteration %i the count is %i\n",tid,i,count);
}
if (i==(5*niter/6)-1) {
tid = omp_get_thread_num();
printf(" thread %i just did iteration %i the count is %i\n",tid,i,count);
}
if (i==niter-1) {
tid = omp_get_thread_num();
printf(" thread %i just did iteration %i the count is %i\n",tid,i,count);
}
}
time ( &rawtime );
timeinfo = localtime ( &rawtime );
printf ( "The current date/time is: %s", asctime (timeinfo) );
Calculate PI based on the aggregate count of
printf(" the total count is %i\n",count);
pi=(double)count/niter*4;
the points that lie within the circle
printf("# of trials= %d , estimate of pi is %g \n",niter,pi);
return 0;
}
http://www.umsl.edu/~siegelj/cs4790/openmp/pimonti_omp.c.HTML
8
Demo : OpenMP Pi
[LSU760000@n00 PA1]$ ./omcpi
Enter the number of iterations used to estimate pi: 100000
The current date/time is: Mon Mar 15 23:36:25 2010
thread 1 just did iteration 16665 the count is 3262
thread 5 just did iteration 66665 the count is 3263
thread 2 just did iteration 33332 the count is 6564
thread 6 just did iteration 83332 the count is 6596
thread 3 just did iteration 49999 the count is 9769
thread 7 just did iteration 99999 the count is 9810
The current date/time is: Mon Mar 15 23:36:25 2010
the total count is 78534
# of trials= 100000 , estimate of pi is 3.14136
9
Creating Custom Communicators
• Communicators define groups and the
access patterns among them
• Default communicator is
MPI_COMM_WORLD
• Some algorithms demand more sophisticated
control of communications to take advantage
of reduction operators
• MPI permits creation of custom
communicators
• MPI_Comm_create
10
MPI Monte Carlo Pi Computation
Master
Worker
Initialize MPI Environment
Initialize MPI Environment
Server
Initialize MPI
Environment
Broadcast Error Bound
Receive Error Bound
Send Request to Server
Receive Request
Send Request to Server
Receive Random Array
Receive Random Array
Compute
Random Array
Perform Computations
Perform Computations
Propagate Number of Points
(Allreduce)
Propagate Number of Points
(Allreduce)
Output Partial Result
N
Stop Condition
Satisfied?
Y
Print Statistics
Send Array to
Requestor
N
N
Stop Condition
Satisfied?
Y
Finalize MPI
Last
Request?
Y
Finalize MPI
Finalize MPI
11
Monte Carlo : MPI - Pi (source
code)
#include <stdio.h>
#include <math.h>
#include "mpi.h“
#define CHUNKSIZE 1000
#define INT_MAX 1000000000
#define REQUEST 1
#define REPLY 2
int main( int argc, char *argv[] )
{
int iter;
int in, out, i, iters, max, ix, iy, ranks[1], done, temp;
double x, y, Pi, error, epsilon;
int numprocs, myid, server, totalin, totalout, workerid;
int rands[CHUNKSIZE], request;
MPI_Comm world, workers;
MPI_Group world_group, worker_group;
MPI_Status status;
MPI_Init(&argc,&argv);
world = MPI_COMM_WORLD;
MPI_Comm_size(world,&numprocs);
MPI_Comm_rank(world,&myid);
Initialize MPI environment
12
Monte Carlo : MPI - Pi (source
code)
server = numprocs-1;
/* last proc is server */
if (myid == 0)
sscanf( argv[1], "%lf", &epsilon );
Broadcast Error Bounds: epsilon
MPI_Bcast( &epsilon, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD );
MPI_Comm_group( world, &world_group );
ranks[0] = server;
MPI_Group_excl( world_group, 1, ranks, &worker_group );
Create a custom communicator
MPI_Comm_create( world, worker_group, &workers );
MPI_Group_free(&worker_group);
if (myid == server) { do {
MPI_Recv(&request, 1, MPI_INT, MPI_ANY_SOURCE, REQUEST, world, &status);
if (request) {
Server process :
for (i = 0; i < CHUNKSIZE; ) {
1. Receives request to generate a random ,2. Computes the
rands[i] = random();
random number array, 3. Send array to requestor
if (rands[i] <= INT_MAX) i++; }/* Send random number array*/
MPI_Send(rands, CHUNKSIZE, MPI_INT, status.MPI_SOURCE, REPLY, world); }
}while( request>0 ); }
else {
/* Begin Worker Block */
request = 1; done = in = out = 0; max = INT_MAX;
/* max int, for normalization */
MPI_Send( &request, 1, MPI_INT, server, REQUEST, world );
MPI_Comm_rank( workers, &workerid );
Worker process :
iter = 0;
Request the server to generate a random number array
13
while (!done) {
iter++;
request = 1;
Monte Carlo : MPI - Pi (source
code)
Worker :
Receive random number array from the Server
/* Recv. random array from server*/
MPI_Recv( rands, CHUNKSIZE, MPI_INT, server, REPLY, world, &status );
for (i=0; i<CHUNKSIZE-1; ) {
Worker:
x = (((double) rands[i++])/max) * 2 - 1;
For each pair of x,y in the random
y = (((double) rands[i++])/max) * 2 - 1;
number array, calculate the coordinates
if (x*x + y*y < 1.0) in++;
Determine if the number is inside or out of the circle
else out++;
}
MPI_Allreduce(&in, &totalin, 1, MPI_INT, MPI_SUM, workers);
MPI_Allreduce(&out, &totalout, 1, MPI_INT, MPI_SUM, workers);
Pi = (4.0*totalin)/(totalin + totalout);
Compute the value of pi and Check
error = fabs( Pi-3.141592653589793238462643);
if error is within threshhold
done = (error < epsilon || (totalin+totalout) > 1000000);
request = (done) ? 0 : 1;
if (myid == 0) {
/* If “Master” : Print current value of PI */
printf( "\rpi = %23.20f", Pi );
Print current value of PI and request for more work
MPI_Send( &request, 1, MPI_INT, server, REQUEST, world );
}
else {
/* If “Worker” : Request new array if not finished */
if (request)
MPI_Send(&request, 1, MPI_INT, server, REQUEST, world);
}
}
MPI_Comm_free(&workers);
}
14
Monte Carlo : MPI - Pi (source
code)
if (myid == 0) {
/* If “Master” : Print Results */
printf( "\npoints: %d\nin: %d, out: %d, <ret> to exit\n",
totalin+totalout, totalin, totalout );
getchar();
}
MPI_Finalize();
Print the final value of PI
}
15
Demo : MPI Monte Carlo, Pi
[LSU760000@n00 PA1]$ mpiexec -np 4 ./monte 1e-7
pi = 3.14159265262020515053
points: 12957000
in: 10176404, out: 2780596
16
Download