source: CIVL/examples/mpi/sum_array.c@ fbb1e35

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

clean up pointerAddWork and involved helper functions

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

  • Property mode set to 100644
File size: 2.3 KB
RevLine 
[3ff27cf]1#ifdef _CIVL
2#include <civlc.cvh>
3#endif
[7c2f812]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
[18c399c]17$input int _NPROCS_LOWER_BOUND = 2;
[7c2f812]18$input int _NPROCS_UPPER_BOUND = 5;
19$input long NB = 20; // upper bound of N
20$input long N; // length of the array
[3ff27cf]21$assume(0 < N && N <= NB);
[7c2f812]22double oracle;
23#else
24#define N 100000
25#endif
[5773b57e]26
27void master (void);
28void slave (void);
29
30int main (int argc, char **argv) {
31 int myrank;
[7c2f812]32
[5773b57e]33 MPI_Init (&argc, &argv);
34 MPI_Comm_rank (MPI_COMM_WORLD, &myrank);
[1775f38]35 if (!myrank)
[5773b57e]36 master ();
37 else
38 slave ();
39 MPI_Finalize ();
40 return 0;
41}
42
43void master (void) {
44 float array[N];
[1775f38]45 double mysum, tmpsum;
46 unsigned long long step, i;
47 int size;
[5773b57e]48 MPI_Status status;
[7c2f812]49
[5773b57e]50 //Initialization of the array
51 for (i = 0; i < N; i++)
52 array[i] = i + 1;
[7c2f812]53#ifdef _CIVL
54 oracle = 0.0;
55 for(i = 0; i < N; i++)
56 oracle += array[i];
57#endif
[1775f38]58 MPI_Comm_size (MPI_COMM_WORLD, &size);
59 if (size != 1)
60 step = N / (size - 1);
61 //The array is divided by the number of slaves
62 for (i = 0; i < size - 1; i++)
63 MPI_Send (array + i * step, step, MPI_FLOAT, i + 1, MSG_DATA, MPI_COMM_WORLD);
64 //The master completes the work if necessary
65 for (i = (size - 1) * step, mysum = 0; i < N; i++)
66 mysum += array[i];
67 //The master receives the results in any order
68 for (i = 1; i < size; mysum += tmpsum, i++)
69 MPI_Recv (&tmpsum, 1, MPI_DOUBLE, MPI_ANY_SOURCE, MSG_RESULT, MPI_COMM_WORLD, &status);
[7c2f812]70#ifdef _CIVL
[3ff27cf]71 $assert(oracle == mysum, "The sum of %d array elements "
72 "is %f but the expected one is %f.\n", N, mysum, oracle);
[7c2f812]73#endif
[5773b57e]74 printf ("%lf\n", mysum);
75}
[7c2f812]76
[5773b57e]77void slave (void) {
78 float array[N];
79 double sum;
80 unsigned long long i;
[1775f38]81 int count;
[5773b57e]82 MPI_Status status;
[1775f38]83 MPI_Recv (array, N, MPI_FLOAT, 0, MSG_DATA, MPI_COMM_WORLD, &status);
84 //The slave finds the size of the array
85 MPI_Get_count (&status, MPI_FLOAT, &count);
86 for (i = 0, sum = 0; i < count; i++)
[5773b57e]87 sum += array[i];
88 MPI_Send (&sum, 1, MPI_DOUBLE, 0, MSG_RESULT, MPI_COMM_WORLD);
89}
Note: See TracBrowser for help on using the repository browser.