source: CIVL/examples/mpi/dev/mpi_pi_send.c

main
Last change on this file was ea777aa, checked in by Alex Wilton <awilton@…>, 3 years ago

Moved examples, include, build_default.properties, common.xml, and README out from dev.civl.com into the root of the repo.

git-svn-id: svn://vsl.cis.udel.edu/civl/trunk@5704 fb995dde-84ed-4084-dfe6-e5aef3e2452c

  • Property mode set to 100644
File size: 5.8 KB
RevLine 
[e48510a]1/**********************************************************************
2 * FILE: mpi_pi_send.c
3 * DESCRIPTION:
4 * MPI pi Calculation Example - C Version
5 * Point-to-Point communications example
6 * This program calculates pi using a "dartboard" algorithm. See
7 * Fox et al.(1988) Solving Problems on Concurrent Processors, vol.1
8 * page 207. All processes contribute to the calculation, with the
9 * master averaging the values for pi. This version uses low level
10 * sends and receives to collect results.
11 * AUTHOR: Blaise Barney. Adapted from Ros Leibensperger, Cornell Theory
12 * Center. Converted to MPI: George L. Gusciora, MHPCC (1/95)
13 * LAST REVISED: 06/13/13 Blaise Barney
14 **********************************************************************/
15#include "mpi.h"
16#include <stdio.h>
17#include <stdlib.h>
18
19double dboard (int darts);
[c83e4aa]20#define DARTS 1 /* number of throws at dartboard */
21#define ROUNDS 1 /* number of times "darts" is iterated */
22#define MASTER 0 /* task ID of master task */
[5cca46e]23#pragma CIVL $output double __pi;
[e48510a]24
25int main (int argc, char *argv[])
26{
27 double
28 homepi, /* value of pi calculated by current task */
29 pi, /* average of pi after "darts" is thrown */
30 avepi, /* average pi value for all iterations */
31 pirecv, /* pi received from worker */
32 pisum; /* sum of workers pi values */
33 int
34 taskid, /* task ID - also used as seed number */
35 numtasks, /* number of tasks */
36 source, /* source of incoming message */
37 mtype, /* message type */
38 rc, /* return code */
39 i, n;
40 MPI_Status status;
41
42 /* Obtain number of tasks and task ID */
43 MPI_Init(&argc,&argv);
44 MPI_Comm_size(MPI_COMM_WORLD,&numtasks);
45 MPI_Comm_rank(MPI_COMM_WORLD,&taskid);
46 printf ("MPI task %d has started...\n", taskid);
47
48 /* Set seed for random number generator equal to task ID */
49 srandom (taskid);
50
51 avepi = 0;
52 for (i = 0; i < ROUNDS; i++) {
53 /* All tasks calculate pi using dartboard algorithm */
54 homepi = dboard(DARTS);
55
56 /* Workers send homepi to master */
57 /* - Message type will be set to the iteration count */
58 if (taskid != MASTER) {
59 mtype = i;
60 rc = MPI_Send(&homepi, 1, MPI_DOUBLE,
61 MASTER, mtype, MPI_COMM_WORLD);
62 if (rc != MPI_SUCCESS)
63 printf("%d: Send failure on round %d\n", taskid, mtype);
64 }
65 else
66 {
67 /* Master receives messages from all workers */
68 /* - Message type will be set to the iteration count */
69 /* - Message source will be set to the wildcard DONTCARE: */
70 /* a message can be received from any task, as long as the */
71 /* message types match */
72 /* - The return code will be checked, and a message displayed */
73 /* if a problem occurred */
74 mtype = i;
75 pisum = 0;
76 for (n = 1; n < numtasks; n++) {
77 rc = MPI_Recv(&pirecv, 1, MPI_DOUBLE, MPI_ANY_SOURCE,
78 mtype, MPI_COMM_WORLD, &status);
79 if (rc != MPI_SUCCESS)
80 printf("%d: Receive failure on round %d\n", taskid, mtype);
81 /* keep running total of pi */
82 pisum = pisum + pirecv;
83 }
84 /* Master calculates the average value of pi for this iteration */
85 pi = (pisum + homepi)/numtasks;
86 /* Master calculates the average value of pi over all iterations */
87 avepi = ((avepi * i) + pi)/(i + 1);
88 printf(" After %8d throws, average value of pi = %10.8f\n",
89 (DARTS * (i + 1)),avepi);
[5cca46e]90 }
[082db64]91 #pragma CIVL __pi = avepi;
[e48510a]92 }
93
94 if (taskid == MASTER)
95 printf ("\nReal value of PI: 3.1415926535897 \n");
96 MPI_Finalize();
97 return 0;
98}
99
100
101/**************************************************************************
102 * subroutine dboard
103 * DESCRIPTION:
104 * Used in pi calculation example codes.
105 * See mpi_pi_send.c and mpi_pi_reduce.c
106 * Throw darts at board. Done by generating random numbers
107 * between 0 and 1 and converting them to values for x and y
108 * coordinates and then testing to see if they "land" in
109 * the circle." If so, score is incremented. After throwing the
110 * specified number of darts, pi is calculated. The computed value
111 * of pi is returned as the value of this function, dboard.
112 *
113 * Explanation of constants and variables used in this function:
114 * darts = number of throws at dartboard
115 * score = number of darts that hit circle
116 * n = index variable
117 * r = random number scaled between 0 and 1
118 * x_coord = x coordinate, between -1 and 1
119 * x_sqr = square of x coordinate
120 * y_coord = y coordinate, between -1 and 1
121 * y_sqr = square of y coordinate
122 * pi = computed value of pi
123 ****************************************************************************/
124
125double dboard(int darts)
126{
127#define sqr(x) ((x)*(x))
128 //long random(void);
129 double x_coord, y_coord, pi, r;
130 int score, n;
131 unsigned int cconst = 9; /* must be 4-bytes in size */
132 /*************************************************************************
133 * The cconst variable must be 4 bytes. We check this and bail if it is
134 * not the right size
135 ************************************************************************/
136 /*if (sizeof(cconst) != 4) {
137 printf("Wrong data size for cconst variable in dboard routine!\n");
138 printf("See comments in source file. Quitting.\n");
139 exit(1);
140 }*/
141 /* 2 bit shifted to MAX_RAND later used to scale random number between 0 and 1 */
142 //cconst = 2 << (31 - 1);
143 score = 0;
144
145 /* "throw darts at board" */
146 for (n = 1; n <= darts; n++) {
147 /* generate random numbers for x and y coordinates */
148 r = (double)random()/cconst;
149 x_coord = (2.0 * r) - 1.0;
150 r = (double)random()/cconst;
151 y_coord = (2.0 * r) - 1.0;
152
153 /* if dart lands in circle, increment score */
154 if ((sqr(x_coord) + sqr(y_coord)) <= 1.0)
155 score++;
156 }
157
158 /* calculate pi */
159 pi = 4.0 * (double)score/(double)darts;
160 return(pi);
161}
162
163
Note: See TracBrowser for help on using the repository browser.