source: CIVL/examples/mpi/sum_array.c@ 276a7df

1.23 2.0 main test-branch
Last change on this file since 276a7df was 7c2f812, checked in by Ziqing Luo <ziqing@…>, 11 years ago

re-write some mpi example to the comparison scheme

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

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