File: slave.c

package info (click to toggle)
lam 7.1.4-8
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 56,404 kB
  • sloc: ansic: 156,541; sh: 9,991; cpp: 7,699; makefile: 5,621; perl: 488; fortran: 260; asm: 83
file content (162 lines) | stat: -rw-r--r-- 3,771 bytes parent folder | download | duplicates (11)
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);
}