Master Source Code For Monte Carlo Example
/* parallel Monte Carlo area calculation */
/* master program */
#include <stdio.h>
#include <pvm3.h>
#define task 100 /* number of tasks per quadrant */
main()
{
struct pvmhostinfo *hostp;
int bufid, check, dum, htid, nhost, narch, ptid, stid, type;
int back[1], done[5], i, j, q, k, min_t, min_q, result;
char name[20], name2[20], tmp[2];
double area;
ptid = pvm_mytid(); /* get your PVM ID number */
pvm_config( &nhost, &narch, &hostp ); /* configuration of virtual machine */
gethostname(name, 20);
printf("The master process runs on %s \n", name);
printf("I found the following hosts in your virtual machine\n");
for (i = 0; i < nhost; i++)
{
printf("\t%s\n", hostp[i].hi_name);
}
printf("\nStarting slaves\n");
for (i=0; i < 4; i++) done[i]=0; /* reset some counters */
i=0;
j=0;
result=0;
do
{
i++; /* start slaves 1,2,3,4,1,... */
if(i==5) i=1; /* until all machines have a */
strcpy(name, "monteslave"); /* job running */
sprintf(tmp, "%i", i);
strcat(name, tmp);
check=pvm_spawn(name, 0,PvmTaskHost,hostp[j].hi_name, 1, &stid);
if (!check)
{
printf("Couldn't start process on %s\n", hostp[j].hi_name);
nhost--;
}
else
{
printf("started slave for quadrant %i on %s\n", i, hostp[j].hi_name);
done[i]++;
}
j++;
}while ((j < nhost) && (j < 4*task));
for(i=j; i < 4*task; i++) /* wait for slaves to finish to */
{ /* start all additional tasks */
bufid=pvm_recv(-1, -1); /* any machine any message*/
pvm_bufinfo(bufid, &dum, &type, &stid); /* where from, which quadrant */
pvm_upkint(back, 1, 1); /* the result of the task */
result+=back[0];
if (done[type] < task) /* there are still open tasks in */
{ /* this quadrant so */
pvm_initsend(PvmDataDefault); /* tell slave to continue */
pvm_send(stid, 1);
done[type]++;
}
else /* no open tasks in this quadrant */
{ /* so start a different slave */
printf("quadrant %i is done\n", type);
htid=pvm_tidtohost(stid); /* find host of this slave */
for (k=0; k < nhost; k++)
{
if (htid==hostp[k].hi_tid) strcpy(name2, hostp[k].hi_name);
}
pvm_initsend(PvmDataDefault); /* tell slave to shut down */
pvm_send(stid, 0);
min_t=done[1]; /* find quadrant with most */
min_q=1; /* open tasks - this way */
for (k=2; k < 5; k++) /* the fastest machine */
{ /* will work on a new */
if (done[k] < min_t) /* quadrant or together */
{ /* with a slow machine */
min_t=done[k]; /* after it's done */
min_q=k;
}
}
strcpy(name, "monteslave"); /* which slave to start */
sprintf(tmp, "%i", min_q);
strcat(name, tmp);
pvm_spawn(name, 0,PvmTaskHost, name2, 1, &stid);
printf("started slave for quadrant %i on %s\n", min_q, name2);
done[min_q]++;
}
}
for(i=0; i < nhost; i++) /* wait for last tasks to end */
{
bufid=pvm_recv(-1, -1); /* any machine any message*/
pvm_bufinfo(bufid, &dum, &dum, &stid); /* where from */
pvm_upkint(back, 1, 1);
result+=back[0];
pvm_initsend(PvmDataDefault); /* tell slave to shut down */
pvm_send(stid, 0);
}
area=result; /* calculate final result */
printf("the area is %f\n", area/(task*4*50000));
pvm_exit;
}
Download: A html-free code you can save
Back: A Master For The Monte Carlo Integration