int main(int argc, char *argv[]) { init_list_body_data(); int nbodies, x, y; Window win; // initialization for a window GC gc; // graphics context Display *display = NULL; unsigned int width = X_RESN, height = Y_RESN; /* window size */ clock_t start, end, elapsed; int rank; int size; MPI_Init (&argc, &argv); /* starts MPI */ MPI_Comm_rank(MPI_COMM_WORLD, &rank); /* get current process id */ MPI_Comm_size(MPI_COMM_WORLD, &size); /* get number of processes */ // I follow this topic // http://stackoverflow.com/questions/9864510/struct-serialization-in-c-and-transfer-over-mpi // alow MPI tranfer truct data type const int num_of_item = 8; int blocklengths[8] = {1, 1, 1, 1, 1, 1, 1, 1}; MPI_Datatype types[8] = {MPI_DOUBLE, MPI_DOUBLE, MPI_DOUBLE, MPI_DOUBLE, MPI_DOUBLE, MPI_DOUBLE, MPI_DOUBLE, MPI_INT}; MPI_Datatype mpi_body_type; MPI_Aint offsets[8]; offsets[0] = offsetof(body, position_x); offsets[1] = offsetof(body, position_y); offsets[2] = offsetof(body, velocity_x); offsets[3] = offsetof(body, velocity_y); offsets[4] = offsetof(body, force_x); offsets[5] = offsetof(body, force_y); offsets[6] = offsetof(body, mass); offsets[7] = offsetof(body, body_id); MPI_Type_create_struct(num_of_item, blocklengths, offsets, types, &mpi_body_type); MPI_Type_commit(&mpi_body_type); // // http://stackoverflow.com/questions/11246150/synchronizing-master-slave-model-with-mpi // for master/slave int j = 0; int i = 0; int k = 0; int num_of_move =100; int index = 0; int p; int steps = MAX_BODY / (size - 1); if (( MAX_BODY % (size - 1)) > 0) { steps++; } if(rank == 0) { display = x11setup(&win, &gc, width, height); // other setup code in the master } for (j = 0; j < num_of_move; j++) { //which number of moves process complte!? if(rank == 0) { printf("Processed %d of %d\n", j, num_of_move); } for (k = 0; k < MAX_BODY; k ++) { index = 0; for (i = 0; i < steps; i++ ) { if(rank == 0) { //master for(p = 1; p < size; p++){ body a = list_body[k]; body b = list_body[index]; if (index >= MAX_BODY -1) { b = list_body[MAX_BODY -1]; } // send 2 body to calculate force MPI_Send(&a, 1, mpi_body_type, p, 20, MPI_COMM_WORLD); MPI_Send(&b, 1, mpi_body_type, p, 20, MPI_COMM_WORLD); //recieve result body b_recv; MPI_Recv(&b_recv, 1, mpi_body_type, p, 21, MPI_COMM_WORLD, MPI_STATUS_IGNORE); //update to list list_body[k] = b_recv; index++; } } else { //workers //receive 2 body to calculate force body a; MPI_Recv(&a, 1, mpi_body_type, 0, 20, MPI_COMM_WORLD, MPI_STATUS_IGNORE); body b; MPI_Recv(&b, 1, mpi_body_type, 0, 20, MPI_COMM_WORLD, MPI_STATUS_IGNORE); // calculating.... update_body_force(&a, &b); update_body_velocity(&a); update_body_location(&a); // finish! send body a to master MPI_Send(&a, 1, mpi_body_type, 0, 21, MPI_COMM_WORLD); } } } if(rank == 0) { XClearWindow(display, win); for (i = 0; i < MAX_BODY; i++) { // draw the bodies on the display body b = list_body[i]; // this function will draw a circle inside a 3x3 box with the upper left // corner at (x,y). N.b. the last 2 arguments mean that it will fill from // 0 to 360 degrees - a full circle if (i == 0) { XFillArc(display, win, gc, b.position_x , b.position_y, 6, 6, 0, 23040); } XFillArc(display, win, gc, b.position_x , b.position_y, 3, 3, 0, 23040); // you campicould also use XDrawPoint(display, win, gc, x, y) to draw a single // pixel at (x,y) } XFlush(display); //reset force for (i = 0; i < MAX_BODY; i++) { body *b = & list_body[i]; b->force_x = 0; b->force_y = 0; } } usleep(100 * 1000); } // finaly, use rank=0 (master) to output result if (rank == 0) { i = 0; for (i = 0; i < MAX_BODY; i++) { body_info(list_body[i]); } } // main loop // int running = 1; // loop variable // start = clock(); // while(running) { // // checks to see if there have been any events, // // will exit the main loop if any key is pressed // if(rank==0) { // if(XPending(display)) { // XEvent ev; // XNextEvent(display, &ev); // switch(ev.type) { // case KeyPress: // running = 0; // break; // } // } // } // your code to calculate the forces on the bodies goes here // end = clock(); // elapsed = end - start; // // only update the display if > 1 millisecond has passed since the last update // if(elapsed / (CLOCKS_PER_SEC/1000) > 1 && rank==0) { // XClearWindow(display, win); // for (i = 0; i < MAX_BODY; i++) { // draw the bodies on the display // body b = list_body[i]; // // this function will draw a circle inside a 3x3 box with the upper left // // corner at (x,y). N.b. the last 2 arguments mean that it will fill from // // 0 to 360 degrees - a full circle // XFillArc(display, win, gc, b.position_x , b.position_y, 3, 3, 0, 23040); // // you campicould also use XDrawPoint(display, win, gc, x, y) to draw a single // // pixel at (x,y) // } // start = end; // XFlush(display); // } // } // if(rank==0 && display) { // XCloseDisplay(display); // close the display window // } MPI_Finalize(); return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { int rank, nprocs, x, y; Window win; // initialization for a window GC gc; // graphics context Display *display = NULL; Colormap screenColourmap; XColor colours[15]; unsigned int width = X_RESN, height = Y_RESN; /* window size */ clock_t start, end, elapsed; int pixelToDraw[3]; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); MPI_Comm_rank(MPI_COMM_WORLD, &rank); ComplexNumber c; ComplexNumber z; int depth = 1000; int cSize = 4; double cX = -2; double cY = -2; double cMinR = cX; double cMinI = cY; double cMaxR = cMinR + cSize; double cMaxI = cMinI + cSize; double increaseX = (cMaxR - cMinR) / X_RESN; double increaseY = (cMaxI - cMinI) / Y_RESN; int drawable[X_RESN][Y_RESN]; if(rank==0) { display = x11setup(&win, &gc, width, height); screenColourmap = DefaultColormap(display, DefaultScreen(display)); setupColours(display, colours, screenColourmap); int probeFlag = 0; MPI_Status status; int count = 0; int start = 1; for (int i = 1; i < nprocs; i++) { MPI_Send(&start, 1, MPI_INT, i, 98, MPI_COMM_WORLD); } for (int y = 0; y < Y_RESN; y++) { for (int x = 0; x < X_RESN; x++) { while (!probeFlag) { MPI_Iprobe(MPI_ANY_SOURCE, 99, MPI_COMM_WORLD, &probeFlag, &status); if (probeFlag) { int coords[2] = {x, y}; int slave = status.MPI_SOURCE; MPI_Recv(&pixelToDraw, 3, MPI_INT, MPI_ANY_SOURCE, 99, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Send(&coords, 2, MPI_INT, slave, 99, MPI_COMM_WORLD); drawable[pixelToDraw[0]][pixelToDraw[1]] = pixelToDraw[2]; count++; } else { MPI_Iprobe(MPI_ANY_SOURCE, 98, MPI_COMM_WORLD, &probeFlag, &status); if (probeFlag) { int slave = status.MPI_SOURCE; int coords[2] = {x, y}; MPI_Recv(&start, 1, MPI_INT, MPI_ANY_SOURCE, 98, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Send(&coords, 2, MPI_INT, slave, 99, MPI_COMM_WORLD); } } } probeFlag = 0; } } MPI_Recv(&pixelToDraw, 3, MPI_INT, MPI_ANY_SOURCE, 99, MPI_COMM_WORLD, MPI_STATUS_IGNORE); drawable[pixelToDraw[0]][pixelToDraw[1]] = pixelToDraw[2]; for (int y = 0; y < Y_RESN; y++) { for (int x = 0; x < X_RESN; x++) { drawPoint(display, win, gc, colours, x, y, depth, drawable[x][y]); } } } else { int flag = 1; int coords[2]; MPI_Recv(&start, 1, MPI_INT, 0, 98, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Send(&start, 1, MPI_INT, 0, 98, MPI_COMM_WORLD); while (flag) { MPI_Recv(&coords, 2, MPI_INT, 0, 99, MPI_COMM_WORLD, MPI_STATUS_IGNORE); c.r = coords[0] * increaseX - 2; c.i = coords[1] * increaseY - 2; resetComplexNumber(&z); int limit = seriesDiverges(depth, &z, &c); pixelToDraw[0] = coords[0]; pixelToDraw[1] = coords[1]; pixelToDraw[2] = limit; MPI_Send(&pixelToDraw, 3, MPI_INT, 0, 99, MPI_COMM_WORLD); } } // main loop int running = 1; // loop variable start = clock(); while(running) { // checks to see if there have been any events, // will exit the main loop if any key is pressed if(rank==0) { if(XPending(display)) { XEvent ev; XNextEvent(display, &ev); switch(ev.type) { case KeyPress: running = 0; break; } } } end = clock(); elapsed = end - start; // only update the display if > 1 millisecond has passed since the last update if(elapsed / (CLOCKS_PER_SEC/1000) > 1 && rank==0) { //XClearWindow(display, win); start = end; XFlush(display); } } if(rank==0 && display) { XCloseDisplay(display); // close the display window printf("Display closed\n"); } else { MPI_Finalize(); return 0; } MPI_Finalize(); return 0; }