source: CIVL/examples/compare/dot/mpithreads_mpi_weak_scaling.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: 3.7 KB
Line 
1/*****************************************************************************
2* FILE: mpithreads_mpi.c
3* DESCRIPTION:
4* This simple program illustrates the use of MPI in a program obtained
5* by modifying a serial code that performs a dot product. It is the third
6* of four codes used to show the progression from a serial program to a
7* hybrid MPI/Pthreads program. The other relevant codes are:
8* - mpithreads_serial.c - The serial version
9* - mpithreads_threads.c - A shared memory programming model using
10* Pthreads
11* - mpithreads_both.c - A hybrid model that utilizes both MPI and
12* Pthreads to execute on systems that are comprised of clusters
13* of SMP's.
14* Use of the SPMD model was chosen and for convenience, with replication
15* of the main data on all nodes. A more memory efficient implementation
16* would be advisable for larger data sets.
17* SOURCE: Vijay Sonnad, IBM
18* LAST REVISED: 01/29/09 Blaise Barney
19******************************************************************************/
20#include <mpi.h>
21#include <stdio.h>
22#include <stdlib.h>
23
24/*
25The following structure contains the necessary information to allow the
26function "dotprod" to access its input data and place its output into
27the structure. Note that this structure is unchanged from the sequential
28version.
29*/
30
31typedef struct
32 {
33 double *a;
34 double *b;
35 double sum;
36 int veclen;
37 } DOTDATA;
38
39/* Define globally accessible variables */
40#ifdef _CIVL
41$input int VECLEN;
42$output double _sum;
43#else
44#define VECLEN 100
45#endif
46DOTDATA dotstr;
47
48/*
49The function dotprod is very similar to the sequential version except that
50we now have each node working on a different part of the data. As before,
51all access to the input is through a structure of type DOTDATA and all
52output from this function is written into this same structure.
53*/
54
55void *dotprod(int numprocs)
56{
57
58 /* Define and use local variables for convenience */
59
60 int i, start, end, myid, len, partial;
61 double mysum, *x, *y;
62
63 /* Obtain rank of this node */
64
65 MPI_Comm_rank (MPI_COMM_WORLD, &myid);
66
67 len = dotstr.veclen;
68
69 if (len % numprocs == 0)
70 partial = len / numprocs;
71 else
72 partial = (len / numprocs) + 1;
73
74 start = myid*partial;
75 end = ((start + partial) > len ? len : start + partial);
76 x = dotstr.a;
77 y = dotstr.b;
78
79 /*
80 Perform the dot product and assign result to the appropriate variable in
81 the structure.
82 */
83
84 mysum = 0;
85 for (i=start; i<end ; i++)
86 {
87 mysum += (x[i] * y[i]);
88 }
89
90 dotstr.sum += mysum;
91
92}
93
94/*
95As before,the main program does very little computation. It does however make
96all the calls to the MPI routines. This is not a master-worker arrangement
97and all nodes participate equally in the work.
98*/
99
100int main (int argc, char* argv[])
101{
102int i,len=VECLEN;
103int myid, numprocs;
104double *a, *b;
105double mysum, allsum;
106
107/* MPI Initialization */
108MPI_Init (&argc, &argv);
109MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
110MPI_Comm_rank (MPI_COMM_WORLD, &myid);
111
112/* Assign storage and initialize values */
113a = (double*) malloc (len*sizeof(double));
114b = (double*) malloc (len*sizeof(double));
115
116for (i=0; i<len; i++) {
117 a[i]=1;
118 b[i]=a[i];
119 }
120
121dotstr.veclen = len;
122dotstr.a = a;
123dotstr.b = b;
124dotstr.sum=0;
125
126/* Call the dot product routine */
127dotprod(numprocs);
128mysum = dotstr.sum;
129printf("Task %d partial sum is %f\n",myid, mysum);
130
131/* After the dot product, perform a summation of results on each node */
132MPI_Reduce (&mysum, &allsum, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
133
134if (myid == 0)
135 printf ("Done. MPI version: sum = %f \n", allsum);
136#ifdef _CIVL
137 if(myid == 0)
138 _sum=allsum;
139#endif
140free (a);
141free (b);
142MPI_Finalize();
143}
Note: See TracBrowser for help on using the repository browser.