source: CIVL/examples/mpi/sum_array.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: 2.3 KB
Line 
1#ifdef _CIVL
2#include <civlc.cvh>
3#endif
4/* sum_array.c : parallel adder for an array of
5 * floating-point numbers.
6 * To execute: mpicc sum_array.c ; mpiexec -n 4 ./a.out
7 * Or replace "4" with however many procs you want to use.
8 * To verify: civl verify sum_array.c
9 */
10#include <stdio.h>
11#include <mpi.h>
12
13/* MPI message passing tags */
14#define MSG_DATA 100
15#define MSG_RESULT 101
16#ifdef _CIVL
17$input long NB = 20; // upper bound of N
18$input long N; // length of the array
19$input int _mpi_nprocs_hi = 8;
20$assume(0 < N && N <= NB);
21double oracle;
22#else
23#define N 100000
24#endif
25
26void master (void);
27void slave (void);
28
29int main (int argc, char **argv) {
30 int myrank;
31
32 MPI_Init (&argc, &argv);
33 MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
34 if (!myrank)
35 master ();
36 else
37 slave ();
38 MPI_Finalize ();
39 return 0;
40}
41
42void master (void) {
43 float array[N];
44 double mysum, tmpsum;
45 unsigned long long step, i;
46 int size;
47 MPI_Status status;
48
49 //Initialization of the array
50 for (i = 0; i < N; i++)
51 array[i] = i + 1;
52#ifdef _CIVL
53 oracle = 0.0;
54 for(i = 0; i < N; i++)
55 oracle += array[i];
56#endif
57 MPI_Comm_size (MPI_COMM_WORLD, &size);
58 if (size != 1)
59 step = N / (size - 1);
60 else
61 step = N;
62 //The array is divided by the number of slaves
63 for (i = 0; i < size - 1; i++)
64 MPI_Send (array + i * step, step, MPI_FLOAT, i + 1, MSG_DATA, MPI_COMM_WORLD);
65 //The master completes the work if necessary
66 for (i = (size - 1) * step, mysum = 0; i < N; i++)
67 mysum += array[i];
68 //The master receives the results in any order
69 for (i = 1; i < size; mysum += tmpsum, i++)
70 MPI_Recv (&tmpsum, 1, MPI_DOUBLE, MPI_ANY_SOURCE, MSG_RESULT, MPI_COMM_WORLD, &status);
71#ifdef _CIVL
72 $assert(oracle == mysum, "The sum of %d array elements "
73 "is %f but the expected one is %f.\n", N, mysum, oracle);
74#endif
75 printf ("%lf\n", mysum);
76}
77
78void slave (void) {
79 float array[N];
80 double sum;
81 unsigned long long i;
82 int count;
83 MPI_Status status;
84 MPI_Recv (array, N, MPI_FLOAT, 0, MSG_DATA, MPI_COMM_WORLD, &status);
85 //The slave finds the size of the array
86 MPI_Get_count (&status, MPI_FLOAT, &count);
87 for (i = 0, sum = 0; i < count; i++)
88 sum += array[i];
89 MPI_Send (&sum, 1, MPI_DOUBLE, 0, MSG_RESULT, MPI_COMM_WORLD);
90}
Note: See TracBrowser for help on using the repository browser.