// Adsmith sample program; NOT INTENDED TO BE EFFICIENT as a prime // finder, either in algorithm or implementation // // finds and reports the number of primes less than or equal to N // each node works on a range of Chunk numbers at a time, testing // them for primeness by straight division; if a potential divisor // has already been found to be composite (i.e. nonprime), then we // skip it // necessary includes #include #include #include #include "adsm.h" #include "adsmutil.h" #include "adsmtime.h" // the following variables are shared in the Adsmith sense; note that // we typically access them via pointers, which are returned to us by // calls to adsm_malloc() and adsm_malloc_array() int **Composite; // array of pointers to composites found so // far, code 1 for composite, 0 otherwise int *NPtr, // check primes from 2 to N *ChunkPtr, // how many numbers to check at one time *NNodesPtr; // number of nodes in computation // the following variables are not shared in the Adsmith sense, though // they will have the same (unchanging) values at every node int N,Chunk,NNodes; // the following variable is not shared in the Adsmith sense, and in // fact has different values at each node int Me; // number of this node // declare an instance of Adsmith's built-in barrier class, AdsmBarrier AdsmBarrier PrintBarr("printbar"); // declare an instance of Adsmith's built-in mutex (lock) class, // AdsmMutex AdsmMutex CompCountMtx("ccmutex"); int IsComposite(int K) // returns 1 if K is found to be composite { int J; for (J = 2; J*J <= K; J++) { // if J is known to be composite, don't bother dividing by it adsm_refresh(Composite[J]); // get latest value if (*Composite[J] == 0) if (K % J == 0) return 1; } return 0; } Worker() { int First,Last,Iter,NIters,I,Block,MyComposites = 0; Block = NNodes * Chunk; First = 1 + Me * Chunk; Last = First + Chunk - 1; NIters = N / Block; for (Iter = 0; Iter < NIters; Iter++) { for (I = First; I <= Last; I++) if (IsComposite(I)) { *Composite[I] = 1; // update the other nodes adsm_flush(Composite[I]); MyComposites++; } First += Block; Last += Block; } PrintBarr.barrier(NNodes); CompCountMtx.lock(); // need atomic access to *Composite[0] adsm_refresh(Composite[0]); // get latest count value *Composite[0] += MyComposites; adsm_flush(Composite[0]); // update the other nodes CompCountMtx.unlock(); // end of critical section } int main(int argc, char **argv) { int I; Me = get_seqno(); // Adsmith library function, like MPI_Comm_rank() if (Me == 0) { // pick up the command-line arguments N = atoi(argv[1]); Chunk = atoi(argv[2]); NNodes = atoi(argv[3]); // since the other nodes don't have access to argv, we need to // make these Adsmith shared variables, even though they will // never change values after the beginning of the program // // so, the following call with have Adsmith set up a space in // its own shared memory pool, and set up a buffer for us to // reference that variable in, returning a pointer to the buffer; // the initial value in the pool and in that buffer will be drawn // from N; the spot in the pool will be named "n" NPtr = (int *) adsm_malloc("n",sizeof(int),&N); ChunkPtr = (int *) adsm_malloc("chunk",sizeof(int),&Chunk); NNodesPtr = (int *) adsm_malloc("number of nodes",sizeof(int),&NNodes); // no calls to adsm_flush() are needed above, since it is done by // the call to adsm_malloc() } else { // call adsm_malloc() here too, but without initial values, // getting them from node 0's call to adsm_malloc() NPtr = (int *) adsm_malloc("n",sizeof(int)); // get the latest value adsm_refresh(NPtr); N = *NPtr; ChunkPtr = (int *) adsm_malloc("chunk",sizeof(int)); adsm_refresh(ChunkPtr); Chunk = *ChunkPtr; NNodesPtr = (int *) adsm_malloc("number of nodes",sizeof(int)); adsm_refresh(NNodesPtr); NNodes = *NNodesPtr; } Composite = (int **) malloc((N+1)*sizeof(int *)); if (N % (NNodes*Chunk) > 0) { printf("N must be an even multiple of NNodes*Chunk\n"); exit(1); } char SegName[100]; int Zero = 0; for (I = 0; I < N+1; I++) { sprintf(SegName,"composite[%d]",I); if (Me == 0) Composite[I] = (int *) adsm_malloc(SegName,sizeof(int),&Zero); else { Composite[I] = (int *) adsm_malloc(SegName,sizeof(int)); adsm_refresh(Composite[I]); } } // spawn at other nodes if (Me == 0) { int NSpawned = adsm_spawn(execname(argv[0]),NNodes-1); cout<<"number spawned = "<