/* cellauto.h -bds 10/02 * Ane dimensional cellular automata project. * Draft sequential code */ #include #include #include using namespace std; #include "apply_rule.h" // apply_rule.h defines these functions: // apply_rule(), display_cells(), areEqual(), and binrule(). // apply_rule(rule, left, center, right) gives next value for center. // according to rule. You shouldn't need to modify any of that. /* cellular_automaton_steps applies the rule to modify each position * in [b..e), assuming wrap around so that b is a neighbor of e-1. * Requires e-b is at least 3, and 0 <= rule < 256. * The process is repeated M times. * * this is the serial version. * Make a parallel version. Add a MPI_Communicator to the argument * list of your parallel version. */ template void cellular_automaton_steps(int rule, Ptr b, Ptr e, int M) { typedef iterator_traits::value_type Cell; for (int i = 1; i < M; ++i) { Cell left = e[-1]; Cell first = *b; for (Ptr i = b; i < e-1; ++i) { left = apply_rule(rule, left, *i, i[1]); swap(left, *i); } e[-1] = apply_rule(rule, left, e[-1], first); } } int main(int argc, char** argv) { // N is size of cell ring int N = 1680; // divisible by all p in [1..16], except 9, 11, 13. vector C; // number of generations. int M = 1000000; // rule number and initial cells state int rule = 30; unsigned long long initial = 1; int p, r; MPI_Init( &argc, &argv ); MPI_Comm_size(MPI_COMM_WORLD, &p); MPI_Comm_rank(MPI_COMM_WORLD, &r); if (r == 0) { if (argc > 1) rule = atoi(argv[1]); if (argc > 2) initial = static_cast(atol(argv[2])); cout << "million generations, rin size 1680, running: " << argv[0]; cout << " " << rule << " " << initial << endl; // set the initial state for the first 64 positions. C.resize(N); unsigned long long L; for (int i = 0; i < 64; ++i) C[i] = (initial & ((L=1) << i))?1:0; for (int i = 0; i < 64; ++i) cout << C[i]; cout << endl; } // main part if (p == 1) cellular_automaton_steps(rule, C.begin(), C.end(), M); else { // parallel version // End with final state in process 0's vector named C. } MPI_Finalize(); // run a few generations for display int display_length = 50; int display_width = 80; // show this many per generation. char ON = '+', OFF = ' '; for (int i = 0; i < display_length; ++i) { vector::iterator b = C.begin() + (N - display_width)/2; display_cells(C.begin(), C.begin() + display_width, ON, OFF); cellular_automaton_steps(rule, C.begin(), C.end(), 1); } }