#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define LIMIT 2500000 /* Increase this to find more primes */
#define FIRST 0 /* Rank of first task */
int prime(int n) {
int i,squareroot;
if (n>10) {
squareroot
= (int) sqrt(n
); for (i=3; i<=squareroot; i=i+2)
if ((n%i)==0)
return 0;
return 1;
}
/* Assume first four primes are counted elsewhere. Forget everything else */
else
return 0;
}
int main (int argc, char *argv[])
{
int ntasks, /* total number of tasks in partitiion */
rank, /* task identifier */
n, /* loop variable */
pc, /* prime counter */
pcsum, /* number of primes found by all tasks */
foundone, /* most recent prime found */
maxprime, /* largest prime found */
mystart, /* where to start calculating */
stride; /* calculate every nth number */
double start_time,end_time;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&ntasks);
if (((ntasks%2) !=0) || ((LIMIT%ntasks) !=0)) {
printf("Sorry - this exercise requires an even number of tasks.\n"); printf("evenly divisible into %d. Try 4 or 8.\n",LIMIT
); MPI_Finalize();
}
start_time = MPI_Wtime(); /* Initialize start time */
mystart = (rank*2)+1; /* Find my starting point - must be odd number */
stride = ntasks*2; /* Determine stride, skipping even numbers */
pc=0; /* Initialize prime counter */
foundone = 0; /* Initialize */
/******************** task with rank 0 does this part ********************/
if (rank == FIRST) {
printf("Using %d tasks to scan %d numbers\n",ntasks
,LIMIT
); pc = 4; /* Assume first four primes are counted here */
for (n=mystart; n<=LIMIT; n=n+stride) {
if (isprime(n)) {
pc++;
foundone = n;
/***** Optional: print each prime as it is found
printf("%d\n",foundone);
*****/
}
}
MPI_Reduce(&pc,&pcsum,1,MPI_INT,MPI_SUM,FIRST,MPI_COMM_WORLD);
MPI_Reduce(&foundone,&maxprime,1,MPI_INT,MPI_MAX,FIRST,MPI_COMM_WORLD);
end_time=MPI_Wtime();
printf("Done. Largest prime is %d Total primes %d\n",maxprime
,pcsum
); printf("Wallclock time elapsed: %.2lf seconds\n",end_time
-start_time
); }
/******************** all other tasks do this part ***********************/
if (rank > FIRST) {
for (n=mystart; n<=LIMIT; n=n+stride) {
if (isprime(n)) {
pc++;
foundone = n;
/***** Optional: print each prime as it is found
printf("%d\n",foundone);
*****/
}
}
MPI_Reduce(&pc,&pcsum,1,MPI_INT,MPI_SUM,FIRST,MPI_COMM_WORLD);
MPI_Reduce(&foundone,&maxprime,1,MPI_INT,MPI_MAX,FIRST,MPI_COMM_WORLD);
}
MPI_Finalize();
}
I2luY2x1ZGUgIm1waS5oIgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8bWF0aC5oPgoKI2RlZmluZSBMSU1JVCAgICAgMjUwMDAwMCAgICAgLyogSW5jcmVhc2UgdGhpcyB0byBmaW5kIG1vcmUgcHJpbWVzICovCiNkZWZpbmUgRklSU1QgICAgIDAgICAgICAgICAgIC8qIFJhbmsgb2YgZmlyc3QgdGFzayAqLwoKaW50IHByaW1lKGludCBuKSB7CmludCBpLHNxdWFyZXJvb3Q7CmlmIChuPjEwKSB7CiAgIHNxdWFyZXJvb3QgPSAoaW50KSBzcXJ0KG4pOwogICBmb3IgKGk9MzsgaTw9c3F1YXJlcm9vdDsgaT1pKzIpCiAgICAgIGlmICgobiVpKT09MCkKICAgICAgICAgcmV0dXJuIDA7CiAgIHJldHVybiAxOwogICB9Ci8qIEFzc3VtZSBmaXJzdCBmb3VyIHByaW1lcyBhcmUgY291bnRlZCBlbHNld2hlcmUuIEZvcmdldCBldmVyeXRoaW5nIGVsc2UgKi8KZWxzZQogICByZXR1cm4gMDsKfQoKCmludCBtYWluIChpbnQgYXJnYywgY2hhciAqYXJndltdKQp7CmludCAgIG50YXNrcywgICAgICAgICAgICAgICAvKiB0b3RhbCBudW1iZXIgb2YgdGFza3MgaW4gcGFydGl0aWlvbiAqLwogICAgICByYW5rLCAgICAgICAgICAgICAgICAgLyogdGFzayBpZGVudGlmaWVyICovCiAgICAgIG4sICAgICAgICAgICAgICAgICAgICAvKiBsb29wIHZhcmlhYmxlICovCiAgICAgIHBjLCAgICAgICAgICAgICAgICAgICAvKiBwcmltZSBjb3VudGVyICovCiAgICAgIHBjc3VtLCAgICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgcHJpbWVzIGZvdW5kIGJ5IGFsbCB0YXNrcyAqLwogICAgICBmb3VuZG9uZSwgICAgICAgICAgICAgLyogbW9zdCByZWNlbnQgcHJpbWUgZm91bmQgKi8KICAgICAgbWF4cHJpbWUsICAgICAgICAgICAgIC8qIGxhcmdlc3QgcHJpbWUgZm91bmQgKi8KICAgICAgbXlzdGFydCwgICAgICAgICAgICAgIC8qIHdoZXJlIHRvIHN0YXJ0IGNhbGN1bGF0aW5nICovCiAgICAgIHN0cmlkZTsgICAgICAgICAgICAgICAvKiBjYWxjdWxhdGUgZXZlcnkgbnRoIG51bWJlciAqLwoKZG91YmxlIHN0YXJ0X3RpbWUsZW5kX3RpbWU7CgkKTVBJX0luaXQoJmFyZ2MsJmFyZ3YpOwpNUElfQ29tbV9yYW5rKE1QSV9DT01NX1dPUkxELCZyYW5rKTsKTVBJX0NvbW1fc2l6ZShNUElfQ09NTV9XT1JMRCwmbnRhc2tzKTsKaWYgKCgobnRhc2tzJTIpICE9MCkgfHwgKChMSU1JVCVudGFza3MpICE9MCkpIHsKICAgcHJpbnRmKCJTb3JyeSAtIHRoaXMgZXhlcmNpc2UgcmVxdWlyZXMgYW4gZXZlbiBudW1iZXIgb2YgdGFza3MuXG4iKTsKICAgcHJpbnRmKCJldmVubHkgZGl2aXNpYmxlIGludG8gJWQuICBUcnkgNCBvciA4LlxuIixMSU1JVCk7CiAgIE1QSV9GaW5hbGl6ZSgpOwogICBleGl0KDApOwogICB9CgpzdGFydF90aW1lID0gTVBJX1d0aW1lKCk7ICAgLyogSW5pdGlhbGl6ZSBzdGFydCB0aW1lICovCm15c3RhcnQgPSAocmFuayoyKSsxOyAgICAgICAvKiBGaW5kIG15IHN0YXJ0aW5nIHBvaW50IC0gbXVzdCBiZSBvZGQgbnVtYmVyICovCnN0cmlkZSA9IG50YXNrcyoyOyAgICAgICAgICAvKiBEZXRlcm1pbmUgc3RyaWRlLCBza2lwcGluZyBldmVuIG51bWJlcnMgKi8KcGM9MDsgICAgICAgICAgICAgICAgICAgICAgIC8qIEluaXRpYWxpemUgcHJpbWUgY291bnRlciAqLwpmb3VuZG9uZSA9IDA7ICAgICAgICAgICAgICAgLyogSW5pdGlhbGl6ZSAqLwoKLyoqKioqKioqKioqKioqKioqKioqIHRhc2sgd2l0aCByYW5rIDAgZG9lcyB0aGlzIHBhcnQgKioqKioqKioqKioqKioqKioqKiovCmlmIChyYW5rID09IEZJUlNUKSB7CiAgIHByaW50ZigiVXNpbmcgJWQgdGFza3MgdG8gc2NhbiAlZCBudW1iZXJzXG4iLG50YXNrcyxMSU1JVCk7CiAgIHBjID0gNDsgICAgICAgICAgICAgICAgICAvKiBBc3N1bWUgZmlyc3QgZm91ciBwcmltZXMgYXJlIGNvdW50ZWQgaGVyZSAqLwogICBmb3IgKG49bXlzdGFydDsgbjw9TElNSVQ7IG49bitzdHJpZGUpIHsKICAgICAgaWYgKGlzcHJpbWUobikpIHsKICAgICAgICAgcGMrKzsKICAgICAgICAgZm91bmRvbmUgPSBuOwogICAgICAgICAvKioqKiogT3B0aW9uYWw6IHByaW50IGVhY2ggcHJpbWUgYXMgaXQgaXMgZm91bmQKICAgICAgICAgcHJpbnRmKCIlZFxuIixmb3VuZG9uZSk7CiAgICAgICAgICoqKioqLwogICAgICAgICB9CiAgICAgIH0KICAgTVBJX1JlZHVjZSgmcGMsJnBjc3VtLDEsTVBJX0lOVCxNUElfU1VNLEZJUlNULE1QSV9DT01NX1dPUkxEKTsKICAgTVBJX1JlZHVjZSgmZm91bmRvbmUsJm1heHByaW1lLDEsTVBJX0lOVCxNUElfTUFYLEZJUlNULE1QSV9DT01NX1dPUkxEKTsKICAgZW5kX3RpbWU9TVBJX1d0aW1lKCk7CiAgIHByaW50ZigiRG9uZS4gTGFyZ2VzdCBwcmltZSBpcyAlZCBUb3RhbCBwcmltZXMgJWRcbiIsbWF4cHJpbWUscGNzdW0pOwogICBwcmludGYoIldhbGxjbG9jayB0aW1lIGVsYXBzZWQ6ICUuMmxmIHNlY29uZHNcbiIsZW5kX3RpbWUtc3RhcnRfdGltZSk7CiAgIH0KCgovKioqKioqKioqKioqKioqKioqKiogYWxsIG90aGVyIHRhc2tzIGRvIHRoaXMgcGFydCAqKioqKioqKioqKioqKioqKioqKioqKi8KaWYgKHJhbmsgPiBGSVJTVCkgewogICBmb3IgKG49bXlzdGFydDsgbjw9TElNSVQ7IG49bitzdHJpZGUpIHsKICAgICAgaWYgKGlzcHJpbWUobikpIHsKICAgICAgICAgcGMrKzsKICAgICAgICAgZm91bmRvbmUgPSBuOwogICAgICAgICAvKioqKiogT3B0aW9uYWw6IHByaW50IGVhY2ggcHJpbWUgYXMgaXQgaXMgZm91bmQKICAgICAgICAgcHJpbnRmKCIlZFxuIixmb3VuZG9uZSk7CiAgICAgICAgICoqKioqLwogICAgICAgICB9CiAgICAgIH0KICAgTVBJX1JlZHVjZSgmcGMsJnBjc3VtLDEsTVBJX0lOVCxNUElfU1VNLEZJUlNULE1QSV9DT01NX1dPUkxEKTsKICAgTVBJX1JlZHVjZSgmZm91bmRvbmUsJm1heHByaW1lLDEsTVBJX0lOVCxNUElfTUFYLEZJUlNULE1QSV9DT01NX1dPUkxEKTsKICAgfQoKTVBJX0ZpbmFsaXplKCk7Cn0K