source: CIVL/examples/mpi-pthread/mpi-pthreads-pie-collective.c@ 83af34d

1.23 2.0 main test-branch
Last change on this file since 83af34d was e3151da, checked in by Ziqing Luo <ziqing@…>, 11 years ago

re-organized example directory

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

  • Property mode set to 100644
File size: 3.8 KB
Line 
1/**********************************************************************
2 ProMCore 2008
3 February 05 - 09, 2008
4
5
6 Example 1.2 : mpi-Pthreads-pie-collective.c
7
8 Objective : Write an MPI-Pthreads program to compute the value
9 of PI by numerical integration of a function f(x)
10 =4/(1+x*x) between the limits 0 and 1.Pthreads and
11 MPI Collective communication library calls are used.
12
13 This example demonstrates the use of
14
15 pthread_create()
16 pthread_join()
17 pthread_mutex_lock()
18 pthread_mutex_unlock()
19
20 MPI_Init
21 MPI_Comm_rank
22 MPI_Comm_size
23 MPI_Bcast
24 MPI_Reduce
25 MPI_Finalize
26
27 Input : Number of Intervals.
28
29 Output : Calculated Value of PI.
30
31 Created : January 2008
32 National PARAM Supercomputing Facility,C-DAC,Pune.
33
34
35 E-mail : betatest@cdac.in
36
37************************************************************************/
38
39#include <stdio.h>
40#include <math.h>
41#include "mpi.h"
42#include <pthread.h>
43
44double intervalWidth, mypi = 0.0;
45int *MyIntervals;
46int MyRank, Numprocs, Root = 0, MyCount = 0;
47pthread_mutex_t mypi_mutex = PTHREAD_MUTEX_INITIALIZER;
48
49void * MyPartOfCalc(int myID)
50{
51 int myInterval;
52 double myIntervalMidPoint;
53 double myArea = 0.0, result;
54
55 myIntervalMidPoint = ((double) MyIntervals[myID] - 0.5) * intervalWidth;
56 myArea += (4.0 / (1.0 + myIntervalMidPoint * myIntervalMidPoint));
57
58 result = myArea * intervalWidth;
59
60 /* Lock the mutex controlling the access to area. */
61
62 pthread_mutex_lock(&mypi_mutex);
63 mypi += result;
64 pthread_mutex_unlock(&mypi_mutex);
65}
66
67double func(double x)
68{
69 return (4.0 / (1.0 + x * x));
70}
71
72int main(int argc, char *argv[])
73{
74 int NoInterval, interval, i;
75 double pi, sum, h, x;
76 double PI25DT = 3.141592653589793238462643;
77 pthread_t *threads;
78#pragma CIVL $assume 0 < NoInterval && NoInterval < 3;
79
80 /* ....MPI initialisation.... */
81 MPI_Init(&argc, &argv);
82 MPI_Comm_size(MPI_COMM_WORLD, &Numprocs);
83 MPI_Comm_rank(MPI_COMM_WORLD, &MyRank);
84
85 if (MyRank == Root) {
86 printf("\nEnter the number of intervals : ");
87 scanf("%d", &NoInterval);
88 }
89 /* ....Broadcast the number of subintervals to each processor.... */
90 MPI_Bcast(&NoInterval, 1, MPI_INT, 0, MPI_COMM_WORLD);
91
92 if (NoInterval <= 0) {
93 if (MyRank == Root)
94 printf("Invalid Value for Number of Intervals .....\n");
95 MPI_Finalize();
96 exit(-1);
97 }
98 h = 1.0 / (double) NoInterval;
99 intervalWidth = h;
100
101 /* Start Calcualtions to determine the number of intervals for each */
102 /* processes of the Communicator. */
103
104 MyCount = 0;
105 for (interval = MyRank + 1; interval <= NoInterval; interval += Numprocs)
106 MyCount++;
107
108 MyIntervals = (int *) malloc(sizeof(int) * MyCount);
109
110 for (i = 0, interval = MyRank + 1; interval <= NoInterval; i++, interval += Numprocs)
111 MyIntervals[i] = interval;
112
113 /* Start creating threads. */
114
115 threads = (pthread_t *) malloc(sizeof(pthread_t) * MyCount);
116
117 for (interval = 0; interval < MyCount; interval++)
118 pthread_create(&threads[interval], NULL, (void *(*) (void *)) MyPartOfCalc, (void *) interval);
119
120 for (interval = 0; interval < MyCount; interval++)
121 pthread_join(threads[interval], NULL);
122
123 /* ....Collect the areas calculated in P0.... */
124 MPI_Reduce(&mypi, &pi, 1, MPI_DOUBLE, MPI_SUM, Root, MPI_COMM_WORLD);
125
126 if (MyRank == Root) {
127 printf("pi is approximately %.16f, Error is %.16f\n",
128 pi, fabs(pi - PI25DT));
129 }
130 MPI_Finalize();
131
132}
Note: See TracBrowser for help on using the repository browser.