source: CIVL/examples/MPI/mpi_pi_send.c@ 50f834b

1.23 2.0 main test-branch
Last change on this file since 50f834b was e48510a, checked in by Manchun Zheng <zmanchun@…>, 12 years ago

improved IO transformer; added a method for printing AST as CIVL-C code; added two examples for MPI transformer, still need to improve MPI transformer; added a simple CIVL implementation of stdlib.h.

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

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