Example #1
0
main(int argc, char* argv[]) {
    int me, np, i;
    int x, y, w, h;
    int x1, y1, x2, y2;
    int color, button, pressed;
    int space, num_colors;
    MPE_Color col_array[64];      /* Color array */
    MPE_Point points[80];         /* Array to store 80 pixels in */

    w=10;
    h=20;                   /* Width and height of colored rectangles */

    MPI_Init (&argc, &argv);              /* Initialize MPI */
    MPI_Comm_size(MPI_COMM_WORLD, &np);   /* Get nr of processes */
    MPI_Comm_rank(MPI_COMM_WORLD, &me);   /* Get own id */

    /* Check that we have exactly two processes */
    if (np != 2) {
        if (me == 0) printf("You have to run this program with 2 processes\n");
        MPI_Finalize();
        exit(0);
    }

    if (me == 0) printf("Opening a graphics window\n") ;

    /* Open the graphics window in position (0,0) on the display */
    MPE_Open_graphics(&graph, MPI_COMM_WORLD, displayname, 0, 0, width, height, 0 );

    /* Get number of colors */
    MPE_Num_colors(graph, &num_colors);

    if (me == 0) {
        printf("Number of colors = %d,\n", num_colors) ;
    }

    /* Processor 0 puts a pink rectangle of size 100*240 in position (0,0) */
    if (me==0) {
        MPE_Fill_rectangle( graph, 0, 0, 100, 240, MPE_PINK );
        MPE_Update( graph );
    }

    /* Both processors draws one rectangle for each colour, placed in a row */
    x=0;
    y=(me)*50;
    space=2;
    for (color=0; color<num_colors; color++) {
        x=x+w+space;         /* Set position of rectangles */
        MPE_Fill_rectangle( graph, x, y, w, h, color );
    }
    MPE_Update( graph );

    /* Create a new color array with 64 colours */
    MPE_Make_color_array(graph, 64, col_array);
    /* Get number of colors */
    MPE_Num_colors(graph, &num_colors);
    if ( me == 0 ) {
        printf("Number of colors = %d,\n", num_colors) ;
    }

    /* Both processors draw one rectangle for each colour, placed in a row */
    x=0;
    y=(me+1)*100;
    for (color=0; color<num_colors; color++) {
        x=x+w+space;         /* Set position of rectangles */
        MPE_Fill_rectangle( graph, x, y, w, h, color );
    }
    MPE_Update( graph );

    /* Set lines to be 2 pixels thick */
    MPE_Line_thickness(graph, 2);
    /* Both processes draw a line, each with different color */
    MPE_Draw_line(graph, 300+(20*me), 10+(20*me), 800+(20*me), 70+(20*me), 30+(20*me));
    MPE_Update( graph );

    /* Both processes draw a circle of different size and color */
    MPE_Draw_circle(graph, 100+(50*me), 300+(50*me), 20+(5*me), num_colors-(20*me));
    MPE_Update(graph);

    /* Both processes draw 50 pixels with different colors */
    for (i=0; i<50; i++) {
        int rx, ry;
        rx = 200+rand()%15;       /* Random positions where to draw points */
        ry = 300+rand()%15+40*me;
        MPE_Draw_point(graph, rx, ry, num_colors-(20*me));
    }
    MPE_Update(graph);

    /* Build 80 pixels with randomly chosen colors in the array points */
    for (i=0; i<80; i++) {
        points[i].x = 250+rand()%15;        /* Set x coordinate */
        points[i].y = 300+rand()%15+40*me;  /* Set y coordinate */
        points[i].c = rand()%num_colors;    /* Set a color */
    }
    MPE_Draw_points(graph, points, 80);   /* Draw all 80 points */
    MPE_Update(graph);

    /* Draw a text string */
    MPE_Draw_string(graph, 400, 250, MPE_BLACK, "Hello from MPE_Draw_string");
    MPE_Update(graph);

    /* Wait until the user selects a region of the graph, using button 1 */
    /* Print out the coordinates of the selected region and draw a black */
    /* rectangle around the selected region */

    button=1;   /* Use button 1 */
    if (me==0) {
        printf("Select a region of the graph using mouse button %d\n", button);
        MPE_Get_drag_region( graph, button, MPE_DRAG_RECT, &x1, &y1, &x2, &y2 );

        printf("Selected region is (%d,%d) to (%d,%d)\n", x1, y1, x2, y2);

        /* Draw a black rectangle around the selected area */
        /* This should of course be implemented in a procedure MPE_Draw_rectangle */
        /* Maybe I will write one some day ... */
        MPE_Draw_line(graph, x1, y1, x1, y2, MPE_BLACK);
        MPE_Draw_line(graph, x1, y2, x2, y2, MPE_BLACK);
        MPE_Draw_line(graph, x2, y2, x2, y1, MPE_BLACK);
        MPE_Draw_line(graph, x2, y1, x1, y1, MPE_BLACK);
        MPE_Update(graph);
    }

    /* Wait until the user presses a mouse button */
    if (me == 0) {
        printf("Press a mouse button to terminate\n");
        MPE_Get_mouse_press(graph, &x, &y, &button);
        printf("User clicked button %d in position (%d,%d)\n", button, x, y);
    }

    /* We can also poll the mouse buttons with MPE_Iget_mouse_pressed */

    /*   pressed = 0;                                                           */
    /*   if (me == 0) {                                                          */
    /*     do {                                                                  */
    /*       MPE_Iget_mouse_press(graph, &x, &y, &button, &pressed);             */
    /*     } while (!pressed);                                                   */
    /*     printf("User clicked button %d in position (%d,%d)\n", button, x, y); */
    /*   }                                                                       */


    /* Wait here for terminationn signal from process 0 */
    /* MPI_Barrier(MPI_COMM_WORLD); */

    /* Close the graphics window and terminate */
    MPE_Close_graphics(&graph);
    MPI_Finalize();
    exit(0);
}
Example #2
0
//master process
void master(int np) {
    int window = 0;//which window;
    int l_sent = 0;//how many lines have sent;
    int l_recv = 0;//how many lines have received;
    int i;
    //the points of a line.
    MPE_Point* points = (MPE_Point*)malloc(W*sizeof(MPE_Point));
    double start, stop;
    do {
        start = MPI_Wtime();
        window++;

        //first send a line number to each slave
        for(i = 1; i < np; i++) {
            if(l_sent < H) {
                MPI_Send(&l_sent, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
                l_sent++;
            }
        };

        do {
            /*Receive the result back from the slaves, we use MPI_ANY_SOURCE here
            because we just receive the result from the fastest slave*/
            MPI_Recv(mans, W+1, MPI_INT, MPI_ANY_SOURCE, tag, MPI_COMM_WORLD, &status);

            /*after we received a computed mandelbrot number of points of a line,
            the master process begin to draw that line and increase the received
            lines variable*/
            draw_line(mans,points);
            l_recv++;

            /*if there are still some rows to send, send the next row to the free slave*/
            if(l_sent < H) {
                MPI_Send(&l_sent, 1, MPI_INT, status.MPI_SOURCE, tag, MPI_COMM_WORLD);
                l_sent++;
            } else {
                /*if we have sent all the rows, then the end signal to the free slave
                  to tell that it can have a rest now.
                  we use -1 which is an impossible line number to represent the end signal
                */
                int endSignal = -1;
                MPI_Send(&endSignal, 1, MPI_INT, status.MPI_SOURCE, tag, MPI_COMM_WORLD);
            }
        } while(l_recv < H);/*if we have received results back of all the rows from slaves,
			 then current window is ready, we can wait for the user to drag
			 an area to zoom in*/
        stop = MPI_Wtime();
        printf("Window %d takes %f seconds\n", window, stop-start);//how long it takes to draw a window

        int px, py, rx, ry;

        /*get the drag region from the user.
          It is interesting that I found (px,py) is always the lower left poit
          and (rx, ry) is always the upper right point no matter I drag from left
          to right or from right to left*/
        MPE_Get_drag_region(graph, MPE_BUTTON1, MPE_DRAG_SQUARE, &px, &py, &rx, &ry);
        /*
          When the user indicates that it is time to terminate, the master
          sends a stop-signal to all slaves.
          User indicates termination by selecting a very small area(less than 10*10 pixels) to zoom in to,
          e.g. clicks with cursor in the window instead of dragging a square area.
         */
        if((rx-px)*(ry-py) < 10*10) {
            /*
            when it is the time to terminate the program, we broadcast the impossible lower left(-3, -3)
            and upper right point(-3, -3) to indicate the slaves that it is time to terminate.
                  */
            min_max[0]=min_max[1]=min_max[2]=min_max[3]=-3.0;
            MPI_Bcast(min_max, 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
            break;
        } else {
            /*
            when user select a area to zoom in, the master recalculate the lower left and upper right points
            and broadcast these two points to the slaves.
                  */
            min_max[0] = real_min + px*real_scale;
            min_max[1] = real_min + rx*real_scale;
            min_max[2] = imag_min + py*imag_scale;
            min_max[3] = imag_min + ry*imag_scale;
            real_min = min_max[0];
            real_max = min_max[1];
            imag_min = min_max[2];
            imag_max = min_max[3];
            real_scale = (real_max - real_min) / (double)W;
            imag_scale = (imag_max - imag_min) / (double)H;

            /* reset the send counter and received counter*/
            l_sent = 0;
            l_recv = 0;
            MPI_Bcast(min_max, 4, MPI_DOUBLE, 0, MPI_COMM_WORLD);
        }
    } while(1);
    free(points);
}