source: CIVL/examples/mpi/mpi_prime.c@ 5c27aa5

1.23 2.0 main test-branch
Last change on this file since 5c27aa5 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: 4.4 KB
Line 
1/*
2 * mpi_prime.c: parallel prime numbers generator within a limited
3 * numbers.
4 * To execute: mpicc mpi_prime.c ; mpiexec -n 4 ./a.out Or
5 * replace "4" with however many procs you want to use.
6 * To verify: civl verify wave1d.c
7 *
8 * Modified from the original program: mpi_prime.c
9 * Source: https://computing.llnl.gov/tutorials/mpi/samples/C/mpi_prime.c
10 */
11#include <assert.h>
12#include <mpi.h>
13#include <math.h>
14#include <stdio.h>
15#include <stdlib.h>
16
17#define FIRST 0 // rank of the first process
18#ifdef _CIVL
19$input int _NPROCS_LOWER_BOUND = 1;
20$input int _NPROCS_UPPER_BOUND = 4;
21$input int LIMITB = 15; // upper bound of LIMITS
22$input int LIMIT; // upper bound of searching numbers
23$assume 10 < LIMIT && LIMIT <= LIMITB;
24/* results of sequential run with initializers. The first element
25 stores the number of found prime numbers, the second element stores
26 the largest found prime number. */
27int oracle[2] = {4, 0};
28#else
29#define LIMIT 800
30#endif
31
32/* Returns 1 if the given number n is a prime number, else returns 0 */
33int isprime(int n) {
34 int i,squareroot;
35
36 if (n>10) {
37 squareroot = (int) sqrt(n);
38 for (i=3; i<=squareroot; i=i+2)
39 if ((n%i)==0)
40 return 0;
41 return 1;
42 }
43 /* Assume first four primes are counted elsewhere. Forget everything else */
44 else
45 return 0;
46}
47
48#ifdef _CIVL
49/* sequential run for finding prime numbers within the limited number,
50 saving results */
51void seq_run() {
52 for (int n=3; n<=LIMIT; n=n+2) {
53 if (isprime(n)) {
54 oracle[0]++;
55 oracle[1] = n;
56 }
57 }
58}
59#endif
60
61int main (int argc, char *argv[])
62{
63 int
64 ntasks, /* total number of tasks in partitiion */
65 rank, /* task identifier */
66 n, /* loop variable */
67 pc, /* prime counter */
68 pcsum, /* number of primes found by all tasks */
69 foundone, /* most recent prime found */
70 maxprime, /* largest prime found */
71 mystart, /* where to start calculating */
72 stride; /* calculate every nth number */
73 double start_time,end_time;
74
75 MPI_Init(&argc,&argv);
76 MPI_Comm_rank(MPI_COMM_WORLD,&rank);
77 MPI_Comm_size(MPI_COMM_WORLD,&ntasks);
78 if (((ntasks%2) !=0) || ((LIMIT%ntasks) !=0)) {
79 printf("Sorry - this exercise requires an even number of tasks.\n");
80 printf("number of tasks %d should be evenly divisible into %d. "
81 " Try 4 or 8.\n",ntasks, LIMIT);
82 MPI_Finalize();
83 return 0;
84 }
85 start_time = MPI_Wtime(); /* Initialize start time */
86 mystart = (rank*2)+1; /* Find my starting point - must be odd number */
87 stride = ntasks*2; /* Determine stride, skipping even numbers */
88 pc=0; /* Initialize prime counter */
89 foundone = 0; /* Initialize */
90
91 /******************** task with rank 0 does this part ********************/
92 if (rank == FIRST) {
93#ifdef _CIVL
94 seq_run();
95#endif
96 printf("Using %d tasks to scan %d numbers\n",ntasks,LIMIT);
97 pc = 4; /* Assume first four primes are counted here */
98 for (n=mystart; n<=LIMIT; n=n+stride) {
99 if (isprime(n)) {
100 pc++;
101 foundone = n;
102 /***** Optional: print each prime as it is found
103 printf("%d\n",foundone);
104 *****/
105 }
106 }
107 MPI_Reduce(&pc,&pcsum,1,MPI_INT,MPI_SUM,FIRST,MPI_COMM_WORLD);
108 MPI_Reduce(&foundone,&maxprime,1,MPI_INT,MPI_MAX,FIRST,MPI_COMM_WORLD);
109 end_time=MPI_Wtime();
110#ifdef _CIVL
111 $assert(pcsum == oracle[0]) : "The calculated number of prime numbers is %d"
112 " but the expected number is %d with a limit of %d\n",pcsum, oracle[0], LIMIT;
113 $assert(maxprime == oracle[1]) : "The Largest prime is %d but the expected "
114 "one is %d with a limit of %d\n",maxprime, oracle[1], LIMIT;
115#endif
116 printf("Done. Largest prime is %d Total primes %d\n",maxprime,pcsum);
117 printf("Wallclock time elapsed: %.2lf seconds\n",end_time-start_time);
118 }
119
120
121 /******************** all other tasks do this part ***********************/
122 if (rank > FIRST) {
123 for (n=mystart; n<=LIMIT; n=n+stride) {
124 if (isprime(n)) {
125 pc++;
126 foundone = n;
127 /***** Optional: print each prime as it is found
128 printf("%d\n",foundone);
129 *****/
130 }
131 }
132 MPI_Reduce(&pc,&pcsum,1,MPI_INT,MPI_SUM,FIRST,MPI_COMM_WORLD);
133 MPI_Reduce(&foundone,&maxprime,1,MPI_INT,MPI_MAX,FIRST,MPI_COMM_WORLD);
134 }
135
136 MPI_Finalize();
137}
Note: See TracBrowser for help on using the repository browser.