source: CIVL/examples/mpi/mpi_prime.c@ bb03188

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