1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
/*
* Copyright (c) 2001-2003 The Trustees of Indiana University.
* All rights reserved.
* Copyright (c) 1998-2001 University of Notre Dame.
* All rights reserved.
* Copyright (c) 1994-1998 The Ohio State University.
* All rights reserved.
*
* This file is part of the LAM/MPI software package. For license
* information, see the LICENSE file in the top level directory of the
* LAM/MPI source distribution.
*
* $HEADER$
*
* $Id: slave.c,v 6.8 2003/04/23 22:32:12 jsquyres Exp $
*
* Function: - slave program for mandelbrot demo
* - fault tolerant version
* - initially receives mandelbrot complex plane desc.
* - receives work orders from the master
* - sends color buffers to the master
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <mpi.h>
#include "mandel.h"
/*
* local functions
*/
static char xy2color(float x, float y);
int
main(int argc, char *argv[])
{
int ulx, uly; /* upper-left point */
int lrx, lry; /* lower-right point */
char *p; /* temp pointer */
char *region; /* color buffer */
int region_size; /* color buffer size (bytes) */
int i, j; /* loop counters */
float scale_x; /* used to convert from */
float scale_y; /* pixels to colors */
float translate_x; /* ... */
float translate_y; /* ... */
float init[4]; /* scaling factors */
int work[4]; /* work requests */
int size; /* world size */
MPI_Comm comm; /* communicator with master */
MPI_Status status; /* returned from MPI */
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_get_parent(&comm);
if (comm == MPI_COMM_NULL) {
printf("No parent!");
MPI_Abort(MPI_COMM_WORLD, (1 << 16) + 1);
}
/* Receive scaling and translating factors for grid. */
MPI_Recv((void *) init, 4, MPI_FLOAT, 0, WORKTAG, comm, MPI_STATUS_IGNORE);
scale_x = init[0];
scale_y = init[1];
translate_x = init[2];
translate_y = init[3];
/* Loop on work requests. */
for (;;) {
MPI_Recv((void *) work, 4, MPI_INT, 0, MPI_ANY_TAG, comm, &status);
/* If we get a DIE message, we are all done, so just exit. */
if (status.MPI_TAG == DIETAG)
break;
/* If we get here, we've gotten a message requesting us to do some
more work. Compute the given region, send the result back to
the master process, and wait for a new request. */
ulx = work[0];
lrx = work[1];
uly = work[2];
lry = work[3];
region_size = (lrx - ulx + 1) * (lry - uly + 1);
region = malloc((unsigned) region_size);
if (region == 0)
MPI_Abort(MPI_COMM_SELF, errno);
p = region;
for (j = uly; j <= lry; j++) {
for (i = ulx; i <= lrx; i++) {
*p++ = xy2color(translate_x + scale_x * i,
translate_y + scale_y * j);
}
}
/* Send back the computed colours. */
MPI_Send(region, region_size, MPI_CHAR, 0, REPLYTAG, comm);
free(region);
}
MPI_Finalize();
return (0);
}
/*
* xy2color
*
* Function: - Given a point on the complex plane x+iy,
* return color based on how close the
* point is to the Mandelbrot set.
* Accepts: - point in complex plane
* Returns: - 1 byte color
*/
static char
xy2color(float x, float y)
{
char colour;
int i;
complex z, c;
float mag2;
float scale;
scale = ((float) 255) / MAX_ITERATIONS;
colour = -1;
z.r = z.i = 0;
c.r = x;
c.i = y;
for (i = 0; i < MAX_ITERATIONS; ++i) {
x = (z.r * z.r) - (z.i * z.i) + c.r;
y = (2 * z.r * z.i) + c.i;
z.r = x;
z.i = y;
mag2 = (z.r * z.r) + (z.i * z.i);
if (mag2 >= 4) {
colour = (char) ((i * scale) + 0.5);
break;
}
}
return (colour);
}
|