| 1 | /*****************************************
|
|---|
| 2 | * SOURCE: adder_par.c by vsl@udel
|
|---|
| 3 | * The source program is included in FEVS
|
|---|
| 4 | * vsl.cis.udel.edu/fevs
|
|---|
| 5 | * FILE: adder_par.cvl
|
|---|
| 6 | * DESCRIPTION: This a manually translated
|
|---|
| 7 | * CIVL program which is based on "adder_par.c"
|
|---|
| 8 | * This program sums all elements of an array
|
|---|
| 9 | * up.
|
|---|
| 10 | *
|
|---|
| 11 | * AUTHOR: Ziqing Luo
|
|---|
| 12 | * COMMANS: civl verify adder_par.cvl
|
|---|
| 13 | * -inputNPROCSB=5 -inputNB=10
|
|---|
| 14 | * or
|
|---|
| 15 | * make civl
|
|---|
| 16 | *****************************************/
|
|---|
| 17 |
|
|---|
| 18 | #include<civlc.h>
|
|---|
| 19 | #include<stdio.h>
|
|---|
| 20 | #include<mpi.h>
|
|---|
| 21 |
|
|---|
| 22 | $input int NPROCS;
|
|---|
| 23 | $input int NPROCSB;
|
|---|
| 24 | $input int N;
|
|---|
| 25 | $input int NB;
|
|---|
| 26 | $input double a[N];
|
|---|
| 27 | $output double SUM;
|
|---|
| 28 | $assume 0 < N && N < NB;
|
|---|
| 29 | $assume 0 < NPROCS && NPROCS <= NPROCSB;
|
|---|
| 30 | $assume NPROCS <= N;
|
|---|
| 31 |
|
|---|
| 32 | CMPI_Gcomm __MPI_COMM_WORLD;
|
|---|
| 33 |
|
|---|
| 34 | void MPI_Process(int place){
|
|---|
| 35 | double sum;
|
|---|
| 36 | double localSum = 0.0;
|
|---|
| 37 | int PID;
|
|---|
| 38 | int nprocs;
|
|---|
| 39 | MPI_Comm MPI_COMM_WORLD;
|
|---|
| 40 |
|
|---|
| 41 | double computeGlobalSum() {
|
|---|
| 42 | double result = localSum;
|
|---|
| 43 | double buffer;
|
|---|
| 44 | int i;
|
|---|
| 45 | MPI_Status status;
|
|---|
| 46 |
|
|---|
| 47 | for (i=1; i<nprocs; i++) {
|
|---|
| 48 | MPI_Recv(&buffer, 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD, &status);
|
|---|
| 49 | result += buffer;
|
|---|
| 50 | }
|
|---|
| 51 | return result;
|
|---|
| 52 | }
|
|---|
| 53 |
|
|---|
| 54 | int _main() {
|
|---|
| 55 |
|
|---|
| 56 | int first;
|
|---|
| 57 | int afterLast;
|
|---|
| 58 | int i;
|
|---|
| 59 |
|
|---|
| 60 | MPI_COMM_WORLD = CMPI_Comm_create($here, __MPI_COMM_WORLD, place);
|
|---|
| 61 | __MPI_Init(&MPI_COMM_WORLD);
|
|---|
| 62 | MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
|
|---|
| 63 | MPI_Comm_rank(MPI_COMM_WORLD, &PID);
|
|---|
| 64 | first = N * PID / nprocs;
|
|---|
| 65 | afterLast = N * (PID + 1) / nprocs;
|
|---|
| 66 |
|
|---|
| 67 | for (i=first; i<afterLast; i++) localSum += a[i];
|
|---|
| 68 | if (PID == 0) {
|
|---|
| 69 | sum = computeGlobalSum();
|
|---|
| 70 | SUM = sum;
|
|---|
| 71 | printf("%lf\n", sum);
|
|---|
| 72 | } else {
|
|---|
| 73 | MPI_Send(&localSum, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
|
|---|
| 74 | }
|
|---|
| 75 | __MPI_Finalize(&MPI_COMM_WORLD);
|
|---|
| 76 | CMPI_Comm_destroy(MPI_COMM_WORLD);
|
|---|
| 77 | return 0;
|
|---|
| 78 | }
|
|---|
| 79 |
|
|---|
| 80 | _main();
|
|---|
| 81 | }
|
|---|
| 82 |
|
|---|
| 83 | void main(){
|
|---|
| 84 | for(int i = 0; i<NPROCS; i++);
|
|---|
| 85 | for(int i = 0; i<N; i++);
|
|---|
| 86 |
|
|---|
| 87 | $proc procs[NPROCS];
|
|---|
| 88 |
|
|---|
| 89 | __MPI_COMM_WORLD = CMPI_Gcomm_create($root, NPROCS);
|
|---|
| 90 | for(int i = 0; i<NPROCS; i++)
|
|---|
| 91 | procs[i] = $spawn MPI_Process(i);
|
|---|
| 92 | for(int i = 0; i<NPROCS; i++)
|
|---|
| 93 | $wait(procs[i]);
|
|---|
| 94 | CMPI_Gcomm_destroy(__MPI_COMM_WORLD);
|
|---|
| 95 | }
|
|---|