|
Packit |
0848f5 |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
* (C) 2001 by Argonne National Laboratory.
|
|
Packit |
0848f5 |
* See COPYRIGHT in top-level directory.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
#include <stdio.h>
|
|
Packit |
0848f5 |
#include <stdlib.h>
|
|
Packit |
0848f5 |
#include <math.h>
|
|
Packit |
0848f5 |
#include <string.h>
|
|
Packit |
0848f5 |
#include "mpi.h"
|
|
Packit |
0848f5 |
#ifdef HAVE_WINDOWS_H
|
|
Packit |
0848f5 |
#include <process.h>
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* definitions */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#define PROMPT 1
|
|
Packit |
0848f5 |
#define USE_PPM /* define to output a color image, otherwise output is a grayscale pgm image */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#ifndef MIN
|
|
Packit |
0848f5 |
#define MIN(x, y) (((x) < (y))?(x):(y))
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
#ifndef MAX
|
|
Packit |
0848f5 |
#define MAX(x, y) (((x) > (y))?(x):(y))
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#define NOVALUE 99999 /* indicates a parameter is as of yet unspecified */
|
|
Packit |
0848f5 |
#define MAX_ITERATIONS 10000 /* maximum 'depth' to look for mandelbrot value */
|
|
Packit |
0848f5 |
#define INFINITE_LIMIT 4.0 /* evalue when fractal is considered diverging */
|
|
Packit |
0848f5 |
#define MAX_X_VALUE 2.0 /* the highest x can go for the mandelbrot, usually 1.0 */
|
|
Packit |
0848f5 |
#define MIN_X_VALUE -2.0 /* the lowest x can go for the mandelbrot, usually -1.0 */
|
|
Packit |
0848f5 |
#define MAX_Y_VALUE 2.0 /* the highest y can go for the mandelbrot, usually 1.0 */
|
|
Packit |
0848f5 |
#define MIN_Y_VALUE -2.0 /* the lowest y can go for the mandelbrot, usually -1.0 */
|
|
Packit |
0848f5 |
#define IDEAL_ITERATIONS 100 /* my favorite 'depth' to default to */
|
|
Packit |
0848f5 |
/* the ideal default x and y are currently the same as the max area */
|
|
Packit |
0848f5 |
#define IDEAL_MAX_X_VALUE 1.0
|
|
Packit |
0848f5 |
#define IDEAL_MIN_X_VALUE -1.0
|
|
Packit |
0848f5 |
#define IDEAL_MAX_Y_VALUE 1.0
|
|
Packit |
0848f5 |
#define IDEAL_MIN_Y_VALUE -1.0
|
|
Packit |
0848f5 |
#define MAX_WIDTH 2048 /* maximum size of image, across, in pixels */
|
|
Packit |
0848f5 |
#define MAX_HEIGHT 2048 /* maximum size of image, down, in pixels */
|
|
Packit |
0848f5 |
#define IDEAL_WIDTH 768 /* my favorite size of image, across, in pixels */
|
|
Packit |
0848f5 |
#define IDEAL_HEIGHT 768 /* my favorite size of image, down, in pixels */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#define RGBtocolor_t(r,g,b) ((color_t)(((unsigned char)(r)|((unsigned short)((unsigned char)(g))<<8))|(((unsigned long)(unsigned char)(b))<<16)))
|
|
Packit |
0848f5 |
#define getR(r) ((int)((r) & 0xFF))
|
|
Packit |
0848f5 |
#define getG(g) ((int)((g>>8) & 0xFF))
|
|
Packit |
0848f5 |
#define getB(b) ((int)((b>>16) & 0xFF))
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
typedef int color_t;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
typedef struct complex_t
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* real + imaginary * sqrt(-1) i.e. x + iy */
|
|
Packit |
0848f5 |
double real, imaginary;
|
|
Packit |
0848f5 |
} complex_t;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* prototypes */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
void read_mand_args(int argc, char *argv[], int *o_max_iterations,
|
|
Packit |
0848f5 |
int *o_pixels_across, int *o_pixels_down,
|
|
Packit |
0848f5 |
double *o_x_min, double *o_x_max,
|
|
Packit |
0848f5 |
double *o_y_min, double *o_y_max, int *o_julia,
|
|
Packit |
0848f5 |
double *o_julia_real_x, double *o_julia_imaginary_y,
|
|
Packit |
0848f5 |
double *o_divergent_limit, int *o_alternate,
|
|
Packit |
0848f5 |
char *filename, int *num_colors, int *use_stdin,
|
|
Packit |
0848f5 |
int *save_image);
|
|
Packit |
0848f5 |
void check_mand_params(int *m_max_iterations,
|
|
Packit |
0848f5 |
int *m_pixels_across, int *m_pixels_down,
|
|
Packit |
0848f5 |
double *m_x_min, double *m_x_max,
|
|
Packit |
0848f5 |
double *m_y_min, double *m_y_max,
|
|
Packit |
0848f5 |
double *m_divergent_limit);
|
|
Packit |
0848f5 |
void check_julia_params(double *julia_x_constant, double *julia_y_constant);
|
|
Packit |
0848f5 |
int additive_mandelbrot_point(complex_t coord_point,
|
|
Packit |
0848f5 |
complex_t c_constant,
|
|
Packit |
0848f5 |
int Max_iterations, double divergent_limit);
|
|
Packit |
0848f5 |
int additive_mandelbrot_point(complex_t coord_point,
|
|
Packit |
0848f5 |
complex_t c_constant,
|
|
Packit |
0848f5 |
int Max_iterations, double divergent_limit);
|
|
Packit |
0848f5 |
int subtractive_mandelbrot_point(complex_t coord_point,
|
|
Packit |
0848f5 |
complex_t c_constant,
|
|
Packit |
0848f5 |
int Max_iterations, double divergent_limit);
|
|
Packit |
0848f5 |
complex_t exponential_complex(complex_t in_complex);
|
|
Packit |
0848f5 |
complex_t multiply_complex(complex_t in_one_complex, complex_t in_two_complex);
|
|
Packit |
0848f5 |
complex_t divide_complex(complex_t in_one_complex, complex_t in_two_complex);
|
|
Packit |
0848f5 |
complex_t inverse_complex(complex_t in_complex);
|
|
Packit |
0848f5 |
complex_t add_complex(complex_t in_one_complex, complex_t in_two_complex);
|
|
Packit |
0848f5 |
complex_t subtract_complex(complex_t in_one_complex, complex_t in_two_complex);
|
|
Packit |
0848f5 |
double absolute_complex(complex_t in_complex);
|
|
Packit |
0848f5 |
void dumpimage(char *filename, int in_grid_array[], int in_pixels_across, int in_pixels_down,
|
|
Packit |
0848f5 |
int in_max_pixel_value, char input_string[], int num_colors, color_t colors[]);
|
|
Packit |
0848f5 |
int single_mandelbrot_point(complex_t coord_point,
|
|
Packit |
0848f5 |
complex_t c_constant,
|
|
Packit |
0848f5 |
int Max_iterations, double divergent_limit);
|
|
Packit |
0848f5 |
color_t getColor(double fraction, double intensity);
|
|
Packit |
0848f5 |
int Make_color_array(int num_colors, color_t colors[]);
|
|
Packit |
0848f5 |
void output_data(int *in_grid_array, int coord[4], int *out_grid_array, int width, int height);
|
|
Packit |
0848f5 |
void PrintUsage(void);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#ifdef USE_PPM
|
|
Packit |
0848f5 |
const char *default_filename = "pmandel.ppm";
|
|
Packit |
0848f5 |
#else
|
|
Packit |
0848f5 |
const char *default_filename = "pmandel.pgm";
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Solving the Mandelbrot set
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
Set a maximum number of iterations to calculate before forcing a terminate
|
|
Packit |
0848f5 |
in the Mandelbrot loop.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Command-line parameters are all optional, and include:
|
|
Packit |
0848f5 |
-xmin # -xmax # Limits for the x-axis for calculating and plotting
|
|
Packit |
0848f5 |
-ymin # -ymax # Limits for the y-axis for calculating and plotting
|
|
Packit |
0848f5 |
-xscale # -yscale # output pixel width and height
|
|
Packit |
0848f5 |
-depth # Number of iterations before we give up on a given
|
|
Packit |
0848f5 |
point and move on to calculate the next
|
|
Packit |
0848f5 |
-diverge # Criteria for assuming the calculation has been
|
|
Packit |
0848f5 |
"solved"-- for each point z, when
|
|
Packit |
0848f5 |
abs(z=z^2+c) > diverge_value
|
|
Packit |
0848f5 |
-julia Plot a Julia set instead of a Mandelbrot set
|
|
Packit |
0848f5 |
-jx # -jy # The Julia point that defines the set
|
|
Packit |
0848f5 |
-alternate # Plot an alternate Mandelbrot equation (varient 1 or 2 so far)
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int myid;
|
|
Packit |
0848f5 |
int use_stdin = 0;
|
|
Packit |
0848f5 |
MPI_Comm comm;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
void swap(int *i, int *j)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int x;
|
|
Packit |
0848f5 |
x = *i;
|
|
Packit |
0848f5 |
*i = *j;
|
|
Packit |
0848f5 |
*j = x;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int main(int argc, char *argv[])
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
complex_t coord_point, julia_constant;
|
|
Packit |
0848f5 |
double x_max, x_min, y_max, y_min, x_resolution, y_resolution;
|
|
Packit |
0848f5 |
double divergent_limit;
|
|
Packit |
0848f5 |
char file_message[160];
|
|
Packit |
0848f5 |
char filename[100];
|
|
Packit |
0848f5 |
int icount, imax_iterations;
|
|
Packit |
0848f5 |
int ipixels_across, ipixels_down;
|
|
Packit |
0848f5 |
int i, j, k, julia, alternate_equation;
|
|
Packit |
0848f5 |
int imin, imax, jmin, jmax;
|
|
Packit |
0848f5 |
int temp[5];
|
|
Packit |
0848f5 |
/* make an integer array of size [N x M] to hold answers. */
|
|
Packit |
0848f5 |
int *in_grid_array, *out_grid_array = NULL;
|
|
Packit |
0848f5 |
int numprocs;
|
|
Packit |
0848f5 |
int namelen;
|
|
Packit |
0848f5 |
char processor_name[MPI_MAX_PROCESSOR_NAME];
|
|
Packit |
0848f5 |
int num_colors;
|
|
Packit |
0848f5 |
color_t *colors = NULL;
|
|
Packit |
0848f5 |
MPI_Status status;
|
|
Packit |
0848f5 |
int save_image = 0;
|
|
Packit |
0848f5 |
int result;
|
|
Packit |
0848f5 |
char mpi_port[MPI_MAX_PORT_NAME];
|
|
Packit |
0848f5 |
MPI_Info info;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Init(&argc, &argv);
|
|
Packit |
0848f5 |
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
|
|
Packit |
0848f5 |
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
|
|
Packit |
0848f5 |
MPI_Get_processor_name(processor_name, &namelen);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (numprocs == 1)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
PrintUsage();
|
|
Packit |
0848f5 |
MPI_Finalize();
|
|
Packit |
0848f5 |
exit(0);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (myid == 0)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Welcome to the Mandelbrot/Julia set explorer.\n");
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Get inputs-- region to view (must be within x/ymin to x/ymax, make sure
|
|
Packit |
0848f5 |
xmax>xmin and ymax>ymin) and resolution (number of pixels along an edge,
|
|
Packit |
0848f5 |
N x M, i.e. 256x256)
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
read_mand_args(argc, argv, &imax_iterations, &ipixels_across, &ipixels_down,
|
|
Packit |
0848f5 |
&x_min, &x_max, &y_min, &y_max, &julia, &julia_constant.real,
|
|
Packit |
0848f5 |
&julia_constant.imaginary, &divergent_limit,
|
|
Packit |
0848f5 |
&alternate_equation, filename, &num_colors, &use_stdin, &save_image);
|
|
Packit |
0848f5 |
check_mand_params(&imax_iterations, &ipixels_across, &ipixels_down,
|
|
Packit |
0848f5 |
&x_min, &x_max, &y_min, &y_max, &divergent_limit);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (julia == 1) /* we're doing a julia figure */
|
|
Packit |
0848f5 |
check_julia_params(&julia_constant.real, &julia_constant.imaginary);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Bcast(&use_stdin, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&num_colors, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&imax_iterations, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&ipixels_across, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&ipixels_down, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&divergent_limit, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&julia, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&julia_constant.real, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&julia_constant.imaginary, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&alternate_equation, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
MPI_Bcast(&use_stdin, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&num_colors, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&imax_iterations, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&ipixels_across, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&ipixels_down, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&divergent_limit, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&julia, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&julia_constant.real, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&julia_constant.imaginary, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&alternate_equation, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (myid == 0)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
colors = malloc((num_colors+1)* sizeof(color_t));
|
|
Packit |
0848f5 |
if (colors == NULL)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
exit(-1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
Make_color_array(num_colors, colors);
|
|
Packit |
0848f5 |
colors[num_colors] = 0; /* add one on the top to avoid edge errors */
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* allocate memory */
|
|
Packit |
0848f5 |
if ( (in_grid_array = (int *)calloc(ipixels_across * ipixels_down, sizeof(int))) == NULL)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Memory allocation failed for data array, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
exit(-1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (myid == 0)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int istep, jstep, cur_proc;
|
|
Packit |
0848f5 |
int i1[400], i2[400], j1[400], j2[400];
|
|
Packit |
0848f5 |
int ii, jj;
|
|
Packit |
0848f5 |
char line[1024], *token;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if ( (out_grid_array = (int *)calloc(ipixels_across * ipixels_down, sizeof(int))) == NULL)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Memory allocation failed for data array, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
exit(-1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
srand(getpid());
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (!use_stdin)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
result = MPI_Info_create(&info;;
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to create an MPI_Info to be used in MPI_Open_port.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
result = MPI_Open_port(/*info*/MPI_INFO_NULL, mpi_port);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("MPI_Open_port failed, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
exit(-1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
result = MPI_Bcast(mpi_port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to broadcast the port name to COMM_WORLD.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
printf("%s listening on port:\n%s\n", processor_name, mpi_port);
|
|
Packit |
0848f5 |
fflush(stdout);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
result = MPI_Comm_accept(mpi_port, info, 0, MPI_COMM_WORLD, &comm);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("MPI_Comm_accept failed, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
exit(-1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
printf("accepted connection from visualization program.\n");
|
|
Packit |
0848f5 |
fflush(stdout);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
printf("sending image size to visualizer.\n");
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
printf("sending pixels_across.\n");
|
|
Packit |
0848f5 |
fflush(stdout);
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
result = MPI_Send(&ipixels_across, 1, MPI_INT, 0, 0, comm);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to send pixel width to visualizer, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
printf("sending pixels_down.\n");
|
|
Packit |
0848f5 |
fflush(stdout);
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
result = MPI_Send(&ipixels_down, 1, MPI_INT, 0, 0, comm);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to send pixel height to visualizer, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
printf("sending num_colors.\n");
|
|
Packit |
0848f5 |
fflush(stdout);
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
result = MPI_Send(&num_colors, 1, MPI_INT, 0, 0, comm);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to send num_colors to visualizer, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
result = MPI_Send(&imax_iterations, 1, MPI_INT, 0, 0, comm);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to send imax_iterations to visualizer, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (;;)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* get x_min, x_max, y_min, and y_max */
|
|
Packit |
0848f5 |
if (use_stdin)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("input xmin ymin xmax ymax max_iter, (0 0 0 0 0 to quit):\n");fflush(stdout);
|
|
Packit |
0848f5 |
fgets(line, 1024, stdin);
|
|
Packit |
0848f5 |
/*printf("read <%s> from stdin\n", line);fflush(stdout);*/
|
|
Packit |
0848f5 |
token = strtok(line, " \n");
|
|
Packit |
0848f5 |
x_min = atof(token);
|
|
Packit |
0848f5 |
token = strtok(NULL, " \n");
|
|
Packit |
0848f5 |
y_min = atof(token);
|
|
Packit |
0848f5 |
token = strtok(NULL, " \n");
|
|
Packit |
0848f5 |
x_max = atof(token);
|
|
Packit |
0848f5 |
token = strtok(NULL, " \n");
|
|
Packit |
0848f5 |
y_max = atof(token);
|
|
Packit |
0848f5 |
token = strtok(NULL, " \n");
|
|
Packit |
0848f5 |
imax_iterations = atoi(token);
|
|
Packit |
0848f5 |
/*sscanf(line, "%g %g %g %g", &x_min, &y_min, &x_max, &y_max);*/
|
|
Packit |
0848f5 |
/*scanf("%g %g %g %g", &x_min, &y_min, &x_max, &y_max);*/
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("reading xmin,ymin,xmax,ymax.\n");fflush(stdout);
|
|
Packit |
0848f5 |
result = MPI_Recv(&x_min, 1, MPI_DOUBLE, 0, 0, comm, &status);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to receive x_min from the visualizer, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
result = MPI_Recv(&y_min, 1, MPI_DOUBLE, 0, 0, comm, &status);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to receive y_min from the visualizer, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
result = MPI_Recv(&x_max, 1, MPI_DOUBLE, 0, 0, comm, &status);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to receive x_max from the visualizer, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
result = MPI_Recv(&y_max, 1, MPI_DOUBLE, 0, 0, comm, &status);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to receive y_max from the visualizer, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
result = MPI_Recv(&imax_iterations, 1, MPI_INT, 0, 0, comm, &status);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to receive imax_iterations from the visualizer, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
printf("x0,y0 = (%f, %f) x1,y1 = (%f,%f) max_iter = %d\n", x_min, y_min, x_max, y_max, imax_iterations);fflush(stdout);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* break the work up into 400 pieces */
|
|
Packit |
0848f5 |
istep = ipixels_across / 20;
|
|
Packit |
0848f5 |
jstep = ipixels_down / 20;
|
|
Packit |
0848f5 |
if (istep < 1)
|
|
Packit |
0848f5 |
istep = 1;
|
|
Packit |
0848f5 |
if (jstep < 1)
|
|
Packit |
0848f5 |
jstep = 1;
|
|
Packit |
0848f5 |
k = 0;
|
|
Packit |
0848f5 |
for (i=0; i<20; i++)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
for (j=0; j<20; j++)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
i1[k] = MIN(istep * i, ipixels_across - 1);
|
|
Packit |
0848f5 |
i2[k] = MIN((istep * (i+1)) - 1, ipixels_across - 1);
|
|
Packit |
0848f5 |
j1[k] = MIN(jstep * j, ipixels_down - 1);
|
|
Packit |
0848f5 |
j2[k] = MIN((jstep * (j+1)) - 1, ipixels_down - 1);
|
|
Packit |
0848f5 |
k++;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* shuffle the work */
|
|
Packit |
0848f5 |
for (i=0; i<500; i++)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
ii = rand() % 400;
|
|
Packit |
0848f5 |
jj = rand() % 400;
|
|
Packit |
0848f5 |
swap(&i1[ii], &i1[jj]);
|
|
Packit |
0848f5 |
swap(&i2[ii], &i2[jj]);
|
|
Packit |
0848f5 |
swap(&j1[ii], &j1[jj]);
|
|
Packit |
0848f5 |
swap(&j2[ii], &j2[jj]);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/*printf("bcasting the limits: (%f,%f)(%f,%f)\n", x_min, y_min, x_max, y_max);fflush(stdout);*/
|
|
Packit |
0848f5 |
/* let everyone know the limits */
|
|
Packit |
0848f5 |
MPI_Bcast(&x_min, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&x_max, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&y_min, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&y_max, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&imax_iterations, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* check for the end condition */
|
|
Packit |
0848f5 |
if (x_min == x_max && y_min == y_max)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* send a piece of work to each worker (there must be more work than workers) */
|
|
Packit |
0848f5 |
cur_proc = 1;
|
|
Packit |
0848f5 |
k = 0;
|
|
Packit |
0848f5 |
for (i=1; i
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
temp[0] = k+1;
|
|
Packit |
0848f5 |
temp[1] = i1[k]; /* imin */
|
|
Packit |
0848f5 |
temp[2] = i2[k]; /* imax */
|
|
Packit |
0848f5 |
temp[3] = j1[k]; /* jmin */
|
|
Packit |
0848f5 |
temp[4] = j2[k]; /* jmax */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/*printf("sending work(%d) to %d\n", k+1, cur_proc);fflush(stdout);*/
|
|
Packit |
0848f5 |
MPI_Send(temp, 5, MPI_INT, cur_proc, 100, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
cur_proc++;
|
|
Packit |
0848f5 |
k++;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
/* receive the results and hand out more work until the image is complete */
|
|
Packit |
0848f5 |
while (k<400)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
MPI_Recv(temp, 5, MPI_INT, MPI_ANY_SOURCE, 200, MPI_COMM_WORLD, &status);
|
|
Packit |
0848f5 |
cur_proc = temp[0];
|
|
Packit |
0848f5 |
MPI_Recv(in_grid_array, (temp[2] + 1 - temp[1]) * (temp[4] + 1 - temp[3]), MPI_INT, cur_proc, 201, MPI_COMM_WORLD, &status);
|
|
Packit |
0848f5 |
/* draw data */
|
|
Packit |
0848f5 |
output_data(in_grid_array, &temp[1], out_grid_array, ipixels_across, ipixels_down);
|
|
Packit |
0848f5 |
temp[0] = k+1;
|
|
Packit |
0848f5 |
temp[1] = i1[k];
|
|
Packit |
0848f5 |
temp[2] = i2[k];
|
|
Packit |
0848f5 |
temp[3] = j1[k];
|
|
Packit |
0848f5 |
temp[4] = j2[k];
|
|
Packit |
0848f5 |
/*printf("sending work(%d) to %d\n", k+1, cur_proc);fflush(stdout);*/
|
|
Packit |
0848f5 |
MPI_Send(temp, 5, MPI_INT, cur_proc, 100, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
k++;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
/* receive the last pieces of work */
|
|
Packit |
0848f5 |
/* and tell everyone to stop */
|
|
Packit |
0848f5 |
for (i=1; i
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
MPI_Recv(temp, 5, MPI_INT, MPI_ANY_SOURCE, 200, MPI_COMM_WORLD, &status);
|
|
Packit |
0848f5 |
cur_proc = temp[0];
|
|
Packit |
0848f5 |
MPI_Recv(in_grid_array, (temp[2] + 1 - temp[1]) * (temp[4] + 1 - temp[3]), MPI_INT, cur_proc, 201, MPI_COMM_WORLD, &status);
|
|
Packit |
0848f5 |
/* draw data */
|
|
Packit |
0848f5 |
output_data(in_grid_array, &temp[1], out_grid_array, ipixels_across, ipixels_down);
|
|
Packit |
0848f5 |
temp[0] = 0;
|
|
Packit |
0848f5 |
temp[1] = 0;
|
|
Packit |
0848f5 |
temp[2] = 0;
|
|
Packit |
0848f5 |
temp[3] = 0;
|
|
Packit |
0848f5 |
temp[4] = 0;
|
|
Packit |
0848f5 |
/*printf("sending %d to tell %d to stop\n", temp[0], cur_proc);fflush(stdout);*/
|
|
Packit |
0848f5 |
MPI_Send(temp, 5, MPI_INT, cur_proc, 100, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* tell the visualizer the image is done */
|
|
Packit |
0848f5 |
if (!use_stdin)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
temp[0] = 0;
|
|
Packit |
0848f5 |
temp[1] = 0;
|
|
Packit |
0848f5 |
temp[2] = 0;
|
|
Packit |
0848f5 |
temp[3] = 0;
|
|
Packit |
0848f5 |
result = MPI_Send(temp, 4, MPI_INT, 0, 0, comm);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to send a done command to the visualizer, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
if (!use_stdin)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
result = MPI_Info_create(&info;;
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to create an MPI_Info to be used in MPI_Open_port.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
result = MPI_Bcast(mpi_port, MPI_MAX_PORT_NAME, MPI_CHAR, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to broadcast the port name on COMM_WORLD.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
/*
|
|
Packit |
0848f5 |
printf("%s listening on port: %s\n", processor_name, mpi_port);
|
|
Packit |
0848f5 |
fflush(stdout);
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
result = MPI_Comm_accept(mpi_port, info, 0, MPI_COMM_WORLD, &comm);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("MPI_Comm_accept failed, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
exit(-1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
for (;;)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
MPI_Bcast(&x_min, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&x_max, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&y_min, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&y_max, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Bcast(&imax_iterations, 1, MPI_INT, 0, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* check for the end condition */
|
|
Packit |
0848f5 |
if (x_min == x_max && y_min == y_max)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
break;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
x_resolution = (x_max-x_min)/ ((double)ipixels_across);
|
|
Packit |
0848f5 |
y_resolution = (y_max-y_min)/ ((double)ipixels_down);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Recv(temp, 5, MPI_INT, 0, 100, MPI_COMM_WORLD, &status);
|
|
Packit |
0848f5 |
while (temp[0] != 0)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
imin = temp[1];
|
|
Packit |
0848f5 |
imax = temp[2];
|
|
Packit |
0848f5 |
jmin = temp[3];
|
|
Packit |
0848f5 |
jmax = temp[4];
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
k = 0;
|
|
Packit |
0848f5 |
for (j=jmin; j<=jmax; ++j)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
coord_point.imaginary = y_max - j*y_resolution; /* go top to bottom */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (i=imin; i<=imax; ++i)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* Call Mandelbrot routine for each code, fill array with number of iterations. */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
coord_point.real = x_min + i*x_resolution; /* go left to right */
|
|
Packit |
0848f5 |
if (julia == 1)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* doing Julia set */
|
|
Packit |
0848f5 |
/* julia eq: z = z^2 + c, z_0 = grid coordinate, c = constant */
|
|
Packit |
0848f5 |
icount = single_mandelbrot_point(coord_point, julia_constant, imax_iterations, divergent_limit);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else if (alternate_equation == 1)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* doing experimental form 1 */
|
|
Packit |
0848f5 |
icount = subtractive_mandelbrot_point(coord_point, julia_constant, imax_iterations, divergent_limit);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else if (alternate_equation == 2)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* doing experimental form 2 */
|
|
Packit |
0848f5 |
icount = additive_mandelbrot_point(coord_point, julia_constant, imax_iterations, divergent_limit);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* default to doing Mandelbrot set */
|
|
Packit |
0848f5 |
/* mandelbrot eq: z = z^2 + c, z_0 = c, c = grid coordinate */
|
|
Packit |
0848f5 |
icount = single_mandelbrot_point(coord_point, coord_point, imax_iterations, divergent_limit);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
in_grid_array[k] = icount;
|
|
Packit |
0848f5 |
++k;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
/* send the result to the root */
|
|
Packit |
0848f5 |
temp[0] = myid;
|
|
Packit |
0848f5 |
MPI_Send(temp, 5, MPI_INT, 0, 200, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
MPI_Send(in_grid_array, (temp[2] + 1 - temp[1]) * (temp[4] + 1 - temp[3]), MPI_INT, 0, 201, MPI_COMM_WORLD);
|
|
Packit |
0848f5 |
/* get the next piece of work */
|
|
Packit |
0848f5 |
MPI_Recv(temp, 5, MPI_INT, 0, 100, MPI_COMM_WORLD, &status);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (myid == 0 && save_image)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
imax_iterations = 0;
|
|
Packit |
0848f5 |
for (i=0; i
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* look for "brightest" pixel value, for image use */
|
|
Packit |
0848f5 |
if (out_grid_array[i] > imax_iterations)
|
|
Packit |
0848f5 |
imax_iterations = out_grid_array[i];
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (julia == 0)
|
|
Packit |
0848f5 |
printf("Done calculating mandelbrot, now creating file\n");
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
printf("Done calculating julia, now creating file\n");
|
|
Packit |
0848f5 |
fflush(stdout);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Print out the array in some appropriate form. */
|
|
Packit |
0848f5 |
if (julia == 0)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* it's a mandelbrot */
|
|
Packit |
0848f5 |
sprintf(file_message, "Mandelbrot over (%lf-%lf,%lf-%lf), size %d x %d",
|
|
Packit |
0848f5 |
x_min, x_max, y_min, y_max, ipixels_across, ipixels_down);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* it's a julia */
|
|
Packit |
0848f5 |
sprintf(file_message, "Julia over (%lf-%lf,%lf-%lf), size %d x %d, center (%lf, %lf)",
|
|
Packit |
0848f5 |
x_min, x_max, y_min, y_max, ipixels_across, ipixels_down,
|
|
Packit |
0848f5 |
julia_constant.real, julia_constant.imaginary);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
dumpimage(filename, out_grid_array, ipixels_across, ipixels_down, imax_iterations, file_message, num_colors, colors);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Comm_disconnect(&comm);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
MPI_Finalize();
|
|
Packit |
0848f5 |
free(colors);
|
|
Packit |
0848f5 |
return 0;
|
|
Packit |
0848f5 |
} /* end of main */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
void PrintUsage(void)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("usage: mpiexec -n x pmandel [options]\n");
|
|
Packit |
0848f5 |
printf("options:\n -xmin # -xmax #\n -ymin # -ymax #\n -depth #\n -xscale # -yscale #\n -out filename\n -i\n");
|
|
Packit |
0848f5 |
printf("All options are optional.\n");
|
|
Packit |
0848f5 |
printf("-i will allow you to input the min/max parameters from stdin and output the resulting image to a ppm file.");
|
|
Packit |
0848f5 |
printf(" Otherwise the root process will listen for a separate visualizer program to connect to it.\n");
|
|
Packit |
0848f5 |
printf("The defaults are:\n xmin %f, xmax %f\n ymin %f, ymax %f\n depth %d\n xscale %d, yscale %d\n %s\n",
|
|
Packit |
0848f5 |
IDEAL_MIN_X_VALUE, IDEAL_MAX_X_VALUE, IDEAL_MIN_Y_VALUE, IDEAL_MAX_Y_VALUE, IDEAL_ITERATIONS,
|
|
Packit |
0848f5 |
IDEAL_WIDTH, IDEAL_HEIGHT, default_filename);
|
|
Packit |
0848f5 |
fflush(stdout);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
color_t getColor(double fraction, double intensity)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* fraction is a part of the rainbow (0.0 - 1.0) = (Red-Yellow-Green-Cyan-Blue-Magenta-Red)
|
|
Packit |
0848f5 |
intensity (0.0 - 1.0) 0 = black, 1 = full color, 2 = white
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
double red, green, blue;
|
|
Packit |
0848f5 |
int r,g,b;
|
|
Packit |
0848f5 |
double dtemp;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
fraction = fabs(modf(fraction, &dtemp));
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (intensity > 2.0)
|
|
Packit |
0848f5 |
intensity = 2.0;
|
|
Packit |
0848f5 |
if (intensity < 0.0)
|
|
Packit |
0848f5 |
intensity = 0.0;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
dtemp = 1.0/6.0;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (fraction < 1.0/6.0)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
red = 1.0;
|
|
Packit |
0848f5 |
green = fraction / dtemp;
|
|
Packit |
0848f5 |
blue = 0.0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
if (fraction < 1.0/3.0)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
red = 1.0 - ((fraction - dtemp) / dtemp);
|
|
Packit |
0848f5 |
green = 1.0;
|
|
Packit |
0848f5 |
blue = 0.0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
if (fraction < 0.5)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
red = 0.0;
|
|
Packit |
0848f5 |
green = 1.0;
|
|
Packit |
0848f5 |
blue = (fraction - (dtemp*2.0)) / dtemp;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
if (fraction < 2.0/3.0)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
red = 0.0;
|
|
Packit |
0848f5 |
green = 1.0 - ((fraction - (dtemp*3.0)) / dtemp);
|
|
Packit |
0848f5 |
blue = 1.0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
if (fraction < 5.0/6.0)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
red = (fraction - (dtemp*4.0)) / dtemp;
|
|
Packit |
0848f5 |
green = 0.0;
|
|
Packit |
0848f5 |
blue = 1.0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
red = 1.0;
|
|
Packit |
0848f5 |
green = 0.0;
|
|
Packit |
0848f5 |
blue = 1.0 - ((fraction - (dtemp*5.0)) / dtemp);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (intensity > 1)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
intensity = intensity - 1.0;
|
|
Packit |
0848f5 |
red = red + ((1.0 - red) * intensity);
|
|
Packit |
0848f5 |
green = green + ((1.0 - green) * intensity);
|
|
Packit |
0848f5 |
blue = blue + ((1.0 - blue) * intensity);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
red = red * intensity;
|
|
Packit |
0848f5 |
green = green * intensity;
|
|
Packit |
0848f5 |
blue = blue * intensity;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
r = (int)(red * 255.0);
|
|
Packit |
0848f5 |
g = (int)(green * 255.0);
|
|
Packit |
0848f5 |
b = (int)(blue * 255.0);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
return RGBtocolor_t(r,g,b);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int Make_color_array(int num_colors, color_t colors[])
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
double fraction, intensity;
|
|
Packit |
0848f5 |
int i;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
intensity = 1.0;
|
|
Packit |
0848f5 |
for (i=0; i
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
fraction = (double)i / (double)num_colors;
|
|
Packit |
0848f5 |
colors[i] = getColor(fraction, intensity);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
return 0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
void getRGB(color_t color, int *r, int *g, int *b)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
*r = getR(color);
|
|
Packit |
0848f5 |
*g = getG(color);
|
|
Packit |
0848f5 |
*b = getB(color);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
void read_mand_args(int argc, char *argv[], int *o_max_iterations,
|
|
Packit |
0848f5 |
int *o_pixels_across, int *o_pixels_down,
|
|
Packit |
0848f5 |
double *o_x_min, double *o_x_max,
|
|
Packit |
0848f5 |
double *o_y_min, double *o_y_max, int *o_julia,
|
|
Packit |
0848f5 |
double *o_julia_real_x, double *o_julia_imaginary_y,
|
|
Packit |
0848f5 |
double *o_divergent_limit, int *o_alternate,
|
|
Packit |
0848f5 |
char *filename, int *o_num_colors, int *use_stdin,
|
|
Packit |
0848f5 |
int *save_image)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int i;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
*o_julia_real_x = NOVALUE;
|
|
Packit |
0848f5 |
*o_julia_imaginary_y = NOVALUE;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* set defaults */
|
|
Packit |
0848f5 |
*o_max_iterations = IDEAL_ITERATIONS;
|
|
Packit |
0848f5 |
*o_pixels_across = IDEAL_WIDTH;
|
|
Packit |
0848f5 |
*o_pixels_down = IDEAL_HEIGHT;
|
|
Packit |
0848f5 |
*o_x_min = IDEAL_MIN_X_VALUE;
|
|
Packit |
0848f5 |
*o_x_max = IDEAL_MAX_X_VALUE;
|
|
Packit |
0848f5 |
*o_y_min = IDEAL_MIN_Y_VALUE;
|
|
Packit |
0848f5 |
*o_y_max = IDEAL_MAX_Y_VALUE;
|
|
Packit |
0848f5 |
*o_divergent_limit = INFINITE_LIMIT;
|
|
Packit |
0848f5 |
strcpy(filename, default_filename);
|
|
Packit |
0848f5 |
*o_num_colors = IDEAL_ITERATIONS;
|
|
Packit |
0848f5 |
*use_stdin = 0; /* default is to listen for a controller */
|
|
Packit |
0848f5 |
*save_image = NOVALUE;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
*o_julia = 0; /* default is "generate Mandelbrot" */
|
|
Packit |
0848f5 |
*o_alternate = 0; /* default is still "generate Mandelbrot" */
|
|
Packit |
0848f5 |
*o_divergent_limit = INFINITE_LIMIT; /* default total range is assumed
|
|
Packit |
0848f5 |
if not explicitly overwritten */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* We just cycle through all given parameters, matching what we can.
|
|
Packit |
0848f5 |
Note that we force casting, because we expect that a nonsensical
|
|
Packit |
0848f5 |
value is better than a poorly formatted one (fewer crashes), and
|
|
Packit |
0848f5 |
we'll later sort out the good from the bad
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (i = 0; i < argc; ++i) /* grab command line arguments */
|
|
Packit |
0848f5 |
if (strcmp(argv[i], "-xmin\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
sscanf(argv[i+1], "%lf", &*o_x_min);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-xmax\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
sscanf(argv[i+1], "%lf", &*o_x_max);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-ymin\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
sscanf(argv[i+1], "%lf", &*o_y_min);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-ymax\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
sscanf(argv[i+1], "%lf", &*o_y_max);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-depth\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
sscanf(argv[i+1], "%d", &*o_max_iterations);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-xscale\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
sscanf(argv[i+1], "%d", &*o_pixels_across);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-yscale\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
sscanf(argv[i+1], "%d", &*o_pixels_down);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-diverge\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
sscanf(argv[i+1], "%lf", &*o_divergent_limit);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-jx\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
sscanf(argv[i+1], "%lf", &*o_julia_real_x);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-jy\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
sscanf(argv[i+1], "%lf", &*o_julia_imaginary_y);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-alternate\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
sscanf(argv[i+1], "%d", &*o_alternate);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-julia\0") == 0)
|
|
Packit |
0848f5 |
*o_julia = 1;
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-out\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
strcpy(filename, argv[i+1]);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-colors\0") == 0 && argv[i+1] != NULL)
|
|
Packit |
0848f5 |
sscanf(argv[i+1], "%d", &*o_num_colors);
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-i\0") == 0)
|
|
Packit |
0848f5 |
*use_stdin = 1;
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-save\0") == 0)
|
|
Packit |
0848f5 |
*save_image = 1;
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-nosave\0") == 0)
|
|
Packit |
0848f5 |
*save_image = 0;
|
|
Packit |
0848f5 |
else if (strcmp(argv[i], "-help\0") == 0)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
PrintUsage();
|
|
Packit |
0848f5 |
MPI_Finalize();
|
|
Packit |
0848f5 |
exit(0);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (*save_image == NOVALUE)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
if (*use_stdin == 1)
|
|
Packit |
0848f5 |
*save_image = 1;
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
*save_image = 0;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
#if DEBUG2
|
|
Packit |
0848f5 |
if (myid == 0)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Doing %d iterations over (%.2lf:%.2lf,%.2lf:%.2lf) on a %d x %d grid\n",
|
|
Packit |
0848f5 |
*o_max_iterations, *o_x_min,*o_x_max,*o_y_min,*o_y_max,
|
|
Packit |
0848f5 |
*o_pixels_across, *o_pixels_down);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
void check_mand_params(int *m_max_iterations,
|
|
Packit |
0848f5 |
int *m_pixels_across, int *m_pixels_down,
|
|
Packit |
0848f5 |
double *m_x_min, double *m_x_max,
|
|
Packit |
0848f5 |
double *m_y_min, double *m_y_max,
|
|
Packit |
0848f5 |
double *m_divergent_limit)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* Get first batch of limits */
|
|
Packit |
0848f5 |
#if PROMPT
|
|
Packit |
0848f5 |
if (*m_x_min == NOVALUE || *m_x_max == NOVALUE)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* grab unspecified limits */
|
|
Packit |
0848f5 |
printf("Enter lower and higher limits on x (within -1 to 1): ");
|
|
Packit |
0848f5 |
scanf("%lf %lf", &*m_x_min, &*m_x_max);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (*m_y_min == NOVALUE || *m_y_max == NOVALUE)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* grab unspecified limits */
|
|
Packit |
0848f5 |
printf("Enter lower and higher limits on y (within -1 to 1): ");
|
|
Packit |
0848f5 |
scanf("%lf %lf", &*m_y_min, &*m_y_max);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Verify limits are reasonable */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (*m_x_min < MIN_X_VALUE || *m_x_min > *m_x_max)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Chosen lower x limit is too low, resetting to %lf\n",MIN_X_VALUE);
|
|
Packit |
0848f5 |
*m_x_min = MIN_X_VALUE;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
if (*m_x_max > MAX_X_VALUE || *m_x_max <= *m_x_min)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Chosen upper x limit is too high, resetting to %lf\n",MAX_X_VALUE);
|
|
Packit |
0848f5 |
*m_x_max = MAX_X_VALUE;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
if (*m_y_min < MIN_Y_VALUE || *m_y_min > *m_y_max)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Chosen lower y limit is too low, resetting to %lf\n",MIN_Y_VALUE);
|
|
Packit |
0848f5 |
*m_y_min = MIN_Y_VALUE;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
if (*m_y_max > MAX_Y_VALUE || *m_y_max <= *m_y_min)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Chosen upper y limit is too high, resetting to %lf\n",MAX_Y_VALUE);
|
|
Packit |
0848f5 |
*m_y_max = MAX_Y_VALUE;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Get second set of limits */
|
|
Packit |
0848f5 |
#if PROMPT
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (*m_max_iterations == NOVALUE)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* grab unspecified limit */
|
|
Packit |
0848f5 |
printf("Enter max interations to do: ");
|
|
Packit |
0848f5 |
scanf("%d",&*m_max_iterations);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Verify second set of limits */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (*m_max_iterations > MAX_ITERATIONS || *m_max_iterations < 0)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Warning, unreasonable number of iterations, setting to %d\n", MAX_ITERATIONS);
|
|
Packit |
0848f5 |
*m_max_iterations = MAX_ITERATIONS;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Get third set of limits */
|
|
Packit |
0848f5 |
#if PROMPT
|
|
Packit |
0848f5 |
if (*m_pixels_across == NOVALUE || *m_pixels_down == NOVALUE)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* grab unspecified limits */
|
|
Packit |
0848f5 |
printf("Enter pixel size (horizonal by vertical, i.e. 256 256): ");
|
|
Packit |
0848f5 |
scanf(" %d %d", &*m_pixels_across, &*m_pixels_down);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Verify third set of limits */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (*m_pixels_across > MAX_WIDTH)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Warning, image requested is too wide, setting to %d pixel width\n", MAX_WIDTH);
|
|
Packit |
0848f5 |
*m_pixels_across = MAX_WIDTH;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
if (*m_pixels_down > MAX_HEIGHT)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Warning, image requested is too tall, setting to %d pixel height\n", MAX_HEIGHT);
|
|
Packit |
0848f5 |
*m_pixels_down = MAX_HEIGHT;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#if DEBUG2
|
|
Packit |
0848f5 |
printf("%d iterations over (%.2lf:%.2lf,%.2lf:%.2lf), %d x %d grid, diverge value %lf\n",
|
|
Packit |
0848f5 |
*m_max_iterations, *m_x_min,*m_x_max,*m_y_min,*m_y_max,
|
|
Packit |
0848f5 |
*m_pixels_across, *m_pixels_down, *m_divergent_limit);
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
void check_julia_params(double *julia_x_constant, double *julia_y_constant)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Hey, we're not stupid-- if they must Prompt, we will also be Noisy */
|
|
Packit |
0848f5 |
#if PROMPT
|
|
Packit |
0848f5 |
if (*julia_x_constant == NOVALUE || *julia_y_constant == NOVALUE)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* grab unspecified limits */
|
|
Packit |
0848f5 |
printf("Enter Coordinates for Julia expansion: ");
|
|
Packit |
0848f5 |
scanf("%lf %lf", &*julia_x_constant, &*julia_y_constant);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#if DEBUG2
|
|
Packit |
0848f5 |
/* In theory, any point can be investigated, although it's not much point
|
|
Packit |
0848f5 |
if it's outside of the area viewed. But, hey, that's not our problem */
|
|
Packit |
0848f5 |
printf("Exploring julia set around (%lf, %lf)\n", *julia_x_constant, *julia_y_constant);
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* This is a Mandelbrot variant, solving the code for the equation:
|
|
Packit |
0848f5 |
z = z(1-z)
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* This routine takes a complex coordinate point (x+iy) and a value stating
|
|
Packit |
0848f5 |
what the upper limit to the number of iterations is. It eventually
|
|
Packit |
0848f5 |
returns an integer of how many counts the code iterated for within
|
|
Packit |
0848f5 |
the given point/region until the exit condition ( abs(x+iy) > limit) was met.
|
|
Packit |
0848f5 |
This value is returned as an integer.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int subtractive_mandelbrot_point(complex_t coord_point,
|
|
Packit |
0848f5 |
complex_t c_constant,
|
|
Packit |
0848f5 |
int Max_iterations, double divergent_limit)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
complex_t z_point, a_point; /* we need 2 pts to use in our calculation */
|
|
Packit |
0848f5 |
int num_iterations; /* a counter to track the number of iterations done */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
num_iterations = 0; /* zero our counter */
|
|
Packit |
0848f5 |
z_point = coord_point; /* initialize to the given start coordinate */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* loop while the absolute value of the complex coordinate is < our limit
|
|
Packit |
0848f5 |
(for a mandelbrot) or until we've done our specified maximum number of
|
|
Packit |
0848f5 |
iterations (both julia and mandelbrot) */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
while (absolute_complex(z_point) < divergent_limit &&
|
|
Packit |
0848f5 |
num_iterations < Max_iterations)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* z = z(1-z) */
|
|
Packit |
0848f5 |
a_point.real = 1.0; a_point.imaginary = 0.0; /* make "1" */
|
|
Packit |
0848f5 |
a_point = subtract_complex(a_point,z_point);
|
|
Packit |
0848f5 |
z_point = multiply_complex(z_point,a_point);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
++num_iterations;
|
|
Packit |
0848f5 |
} /* done iterating for one point */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
return num_iterations;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* This is a Mandelbrot variant, solving the code for the equation:
|
|
Packit |
0848f5 |
z = z(z+c)
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* This routine takes a complex coordinate point (x+iy) and a value stating
|
|
Packit |
0848f5 |
what the upper limit to the number of iterations is. It eventually
|
|
Packit |
0848f5 |
returns an integer of how many counts the code iterated for within
|
|
Packit |
0848f5 |
the given point/region until the exit condition ( abs(x+iy) > limit) was met.
|
|
Packit |
0848f5 |
This value is returned as an integer.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int additive_mandelbrot_point(complex_t coord_point,
|
|
Packit |
0848f5 |
complex_t c_constant,
|
|
Packit |
0848f5 |
int Max_iterations, double divergent_limit)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
complex_t z_point, a_point; /* we need 2 pts to use in our calculation */
|
|
Packit |
0848f5 |
int num_iterations; /* a counter to track the number of iterations done */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
num_iterations = 0; /* zero our counter */
|
|
Packit |
0848f5 |
z_point = coord_point; /* initialize to the given start coordinate */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* loop while the absolute value of the complex coordinate is < our limit
|
|
Packit |
0848f5 |
(for a mandelbrot) or until we've done our specified maximum number of
|
|
Packit |
0848f5 |
iterations (both julia and mandelbrot) */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
while (absolute_complex(z_point) < divergent_limit &&
|
|
Packit |
0848f5 |
num_iterations < Max_iterations)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* z = z(z+C) */
|
|
Packit |
0848f5 |
a_point = add_complex(z_point,coord_point);
|
|
Packit |
0848f5 |
z_point = multiply_complex(z_point,a_point);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
++num_iterations;
|
|
Packit |
0848f5 |
} /* done iterating for one point */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
return num_iterations;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* This is a Mandelbrot variant, solving the code for the equation:
|
|
Packit |
0848f5 |
z = z(z+1)
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* This routine takes a complex coordinate point (x+iy) and a value stating
|
|
Packit |
0848f5 |
what the upper limit to the number of iterations is. It eventually
|
|
Packit |
0848f5 |
returns an integer of how many counts the code iterated for within
|
|
Packit |
0848f5 |
the given point/region until the exit condition ( abs(x+iy) > limit) was met.
|
|
Packit |
0848f5 |
This value is returned as an integer.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int exponential_mandelbrot_point(complex_t coord_point,
|
|
Packit |
0848f5 |
complex_t c_constant,
|
|
Packit |
0848f5 |
int Max_iterations, double divergent_limit)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
complex_t z_point, a_point; /* we need 2 pts to use in our calculation */
|
|
Packit |
0848f5 |
int num_iterations; /* a counter to track the number of iterations done */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
num_iterations = 0; /* zero our counter */
|
|
Packit |
0848f5 |
z_point = coord_point; /* initialize to the given start coordinate */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* loop while the absolute value of the complex coordinate is < our limit
|
|
Packit |
0848f5 |
(for a mandelbrot) or until we've done our specified maximum number of
|
|
Packit |
0848f5 |
iterations (both julia and mandelbrot) */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
while (absolute_complex(z_point) < divergent_limit &&
|
|
Packit |
0848f5 |
num_iterations < Max_iterations)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* z = z(1-z) */
|
|
Packit |
0848f5 |
a_point.real = 1.0; a_point.imaginary = 0.0; /* make "1" */
|
|
Packit |
0848f5 |
a_point = subtract_complex(a_point,z_point);
|
|
Packit |
0848f5 |
z_point = multiply_complex(z_point,a_point);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
++num_iterations;
|
|
Packit |
0848f5 |
} /* done iterating for one point */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
return num_iterations;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
void complex_points_to_image(complex_t in_julia_coord_set[],
|
|
Packit |
0848f5 |
int in_julia_set_size,
|
|
Packit |
0848f5 |
int i_pixels_across,int i_pixels_down,
|
|
Packit |
0848f5 |
int *out_image_final, int *out_max_colors)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int i, i_temp_quantize;
|
|
Packit |
0848f5 |
double x_resolution_element, y_resolution_element, temp_quantize;
|
|
Packit |
0848f5 |
double x_max, x_min, y_max, y_min;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Convert the complex points into an image--
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
first, find the min and max for each axis. */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
x_min = in_julia_coord_set[0].real;
|
|
Packit |
0848f5 |
x_max = x_min;
|
|
Packit |
0848f5 |
y_min = in_julia_coord_set[0].imaginary;
|
|
Packit |
0848f5 |
y_max = y_min;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (i=0;i
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
if (in_julia_coord_set[i].real < x_min)
|
|
Packit |
0848f5 |
x_min = in_julia_coord_set[i].real;
|
|
Packit |
0848f5 |
if (in_julia_coord_set[i].real > x_max)
|
|
Packit |
0848f5 |
x_max = in_julia_coord_set[i].real;
|
|
Packit |
0848f5 |
if (in_julia_coord_set[i].imaginary < y_min)
|
|
Packit |
0848f5 |
y_min = in_julia_coord_set[i].imaginary;
|
|
Packit |
0848f5 |
if (in_julia_coord_set[i].imaginary > y_max)
|
|
Packit |
0848f5 |
y_max = in_julia_coord_set[i].imaginary;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* convert to fit image grid size: */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
x_resolution_element = (x_max - x_min)/(double)i_pixels_across;
|
|
Packit |
0848f5 |
y_resolution_element = (y_max - y_min)/(double)i_pixels_down;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#ifdef DEBUG
|
|
Packit |
0848f5 |
printf("%lf %lf\n",x_resolution_element, y_resolution_element);
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* now we can put each point into a grid space, and up the count of
|
|
Packit |
0848f5 |
said grid. Since calloc initialized it to zero, this is safe */
|
|
Packit |
0848f5 |
/* A point x,y goes to grid region i,j, where
|
|
Packit |
0848f5 |
xi = (x-xmin)/x_resolution (position relative to far left)
|
|
Packit |
0848f5 |
yj = (ymax-y)/y_resolution (position relative to top)
|
|
Packit |
0848f5 |
This gets mapped to our 1-d array as xi + yj*i_pixels_across,
|
|
Packit |
0848f5 |
taken as an integer (rounding down) and checking array limits
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (i=0; i
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
temp_quantize =
|
|
Packit |
0848f5 |
(in_julia_coord_set[i].real - x_min)/x_resolution_element +
|
|
Packit |
0848f5 |
(y_max - in_julia_coord_set[i].imaginary)/y_resolution_element *
|
|
Packit |
0848f5 |
(double)i_pixels_across;
|
|
Packit |
0848f5 |
i_temp_quantize = (int)temp_quantize;
|
|
Packit |
0848f5 |
if (i_temp_quantize > i_pixels_across*i_pixels_down)
|
|
Packit |
0848f5 |
i_temp_quantize = i_pixels_across*i_pixels_down;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#ifdef DEBUG
|
|
Packit |
0848f5 |
printf("%d %lf %lf %lf %lf %lf %lf %lf\n",
|
|
Packit |
0848f5 |
i_temp_quantize, temp_quantize, x_min, x_resolution_element,
|
|
Packit |
0848f5 |
in_julia_coord_set[i].real, y_max, y_resolution_element,
|
|
Packit |
0848f5 |
in_julia_coord_set[i].imaginary);
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
++out_image_final[i_temp_quantize];
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* find the highest value (most occupied bin) */
|
|
Packit |
0848f5 |
*out_max_colors = 0;
|
|
Packit |
0848f5 |
for (i=0;i
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
if (out_image_final[i] > *out_max_colors)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
*out_max_colors = out_image_final[i];
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
complex_t exponential_complex(complex_t in_complex)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
complex_t out_complex;
|
|
Packit |
0848f5 |
double e_to_x;
|
|
Packit |
0848f5 |
/* taking the exponential, e^(x+iy) = e^xe^iy = e^x(cos(y)+isin(y) */
|
|
Packit |
0848f5 |
e_to_x = exp(in_complex.real);
|
|
Packit |
0848f5 |
out_complex.real = e_to_x * cos(in_complex.imaginary);
|
|
Packit |
0848f5 |
out_complex.imaginary = e_to_x * sin(in_complex.imaginary);
|
|
Packit |
0848f5 |
return out_complex;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
complex_t multiply_complex(complex_t in_one_complex, complex_t in_two_complex)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
complex_t out_complex;
|
|
Packit |
0848f5 |
/* multiplying complex variables-- (x+iy) * (a+ib) = xa - yb + i(xb + ya) */
|
|
Packit |
0848f5 |
out_complex.real = in_one_complex.real * in_two_complex.real -
|
|
Packit |
0848f5 |
in_one_complex.imaginary * in_two_complex.imaginary;
|
|
Packit |
0848f5 |
out_complex.imaginary = in_one_complex.real * in_two_complex.imaginary +
|
|
Packit |
0848f5 |
in_one_complex.imaginary * in_two_complex.real;
|
|
Packit |
0848f5 |
return out_complex;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
complex_t divide_complex(complex_t in_one_complex, complex_t in_two_complex)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
complex_t out_complex;
|
|
Packit |
0848f5 |
double divider;
|
|
Packit |
0848f5 |
/* dividing complex variables-- (x+iy)/(a+ib) = (xa - yb)/(a^2+b^2)
|
|
Packit |
0848f5 |
+ i (y*a-x*b)/(a^2+b^2) */
|
|
Packit |
0848f5 |
divider = (in_two_complex.real*in_two_complex.real -
|
|
Packit |
0848f5 |
in_two_complex.imaginary*in_two_complex.imaginary);
|
|
Packit |
0848f5 |
out_complex.real = (in_one_complex.real * in_two_complex.real -
|
|
Packit |
0848f5 |
in_one_complex.imaginary * in_two_complex.imaginary) / divider;
|
|
Packit |
0848f5 |
out_complex.imaginary = (in_one_complex.imaginary * in_two_complex.real -
|
|
Packit |
0848f5 |
in_one_complex.real * in_two_complex.imaginary) / divider;
|
|
Packit |
0848f5 |
return out_complex;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
complex_t inverse_complex(complex_t in_complex)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
complex_t out_complex;
|
|
Packit |
0848f5 |
double divider;
|
|
Packit |
0848f5 |
/* inverting a complex variable: 1/(x+iy) */
|
|
Packit |
0848f5 |
divider = (in_complex.real*in_complex.real -
|
|
Packit |
0848f5 |
in_complex.imaginary*in_complex.imaginary);
|
|
Packit |
0848f5 |
out_complex.real = (in_complex.real - in_complex.imaginary) / divider;
|
|
Packit |
0848f5 |
out_complex.imaginary = (in_complex.real - in_complex.imaginary) / divider;
|
|
Packit |
0848f5 |
return out_complex;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
complex_t add_complex(complex_t in_one_complex, complex_t in_two_complex)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
complex_t out_complex;
|
|
Packit |
0848f5 |
/* adding complex variables-- do by component */
|
|
Packit |
0848f5 |
out_complex.real = in_one_complex.real + in_two_complex.real;
|
|
Packit |
0848f5 |
out_complex.imaginary = in_one_complex.imaginary + in_two_complex.imaginary;
|
|
Packit |
0848f5 |
return out_complex;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
complex_t subtract_complex(complex_t in_one_complex, complex_t in_two_complex)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
complex_t out_complex;
|
|
Packit |
0848f5 |
/* subtracting complex variables-- do by component */
|
|
Packit |
0848f5 |
out_complex.real = in_one_complex.real - in_two_complex.real;
|
|
Packit |
0848f5 |
out_complex.imaginary = in_one_complex.imaginary - in_two_complex.imaginary;
|
|
Packit |
0848f5 |
return out_complex;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
double absolute_complex(complex_t in_complex)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
double out_double;
|
|
Packit |
0848f5 |
/* absolute value is (for x+yi) sqrt( x^2 + y^2) */
|
|
Packit |
0848f5 |
out_double = sqrt(in_complex.real*in_complex.real + in_complex.imaginary*in_complex.imaginary);
|
|
Packit |
0848f5 |
return out_double;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* This routine takes a complex coordinate point (x+iy) and a value stating
|
|
Packit |
0848f5 |
what the upper limit to the number of iterations is. It eventually
|
|
Packit |
0848f5 |
returns an integer of how many counts the code iterated for within
|
|
Packit |
0848f5 |
the given point/region until the exit condition ( abs(x+iy) > limit) was met.
|
|
Packit |
0848f5 |
This value is returned as an integer.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
int single_mandelbrot_point(complex_t coord_point,
|
|
Packit |
0848f5 |
complex_t c_constant,
|
|
Packit |
0848f5 |
int Max_iterations, double divergent_limit)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
complex_t z_point; /* we need a point to use in our calculation */
|
|
Packit |
0848f5 |
int num_iterations; /* a counter to track the number of iterations done */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
num_iterations = 0; /* zero our counter */
|
|
Packit |
0848f5 |
z_point = coord_point; /* initialize to the given start coordinate */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* loop while the absolute value of the complex coordinate is < our limit
|
|
Packit |
0848f5 |
(for a mandelbrot) or until we've done our specified maximum number of
|
|
Packit |
0848f5 |
iterations (both julia and mandelbrot) */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
while (absolute_complex(z_point) < divergent_limit &&
|
|
Packit |
0848f5 |
num_iterations < Max_iterations)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
/* z = z*z + c */
|
|
Packit |
0848f5 |
z_point = multiply_complex(z_point,z_point);
|
|
Packit |
0848f5 |
z_point = add_complex(z_point,c_constant);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
++num_iterations;
|
|
Packit |
0848f5 |
} /* done iterating for one point */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
return num_iterations;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
void output_data(int *in_grid_array, int coord[4], int *out_grid_array, int width, int height)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
int i, j, k;
|
|
Packit |
0848f5 |
int result;
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
k = 0;
|
|
Packit |
0848f5 |
for (j=coord[2]; j<=coord[3]; j++)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
for (i=coord[0]; i<=coord[1]; i++)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
out_grid_array[(j * height) + i] = in_grid_array[k];
|
|
Packit |
0848f5 |
k++;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
if (!use_stdin)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
result = MPI_Send(coord, 4, MPI_INT, 0, 0, comm);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to send coordinates to the visualizer, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
result = MPI_Send(in_grid_array, (coord[1] + 1 - coord[0]) * (coord[3] + 1 - coord[2]), MPI_INT, 0, 0, comm);
|
|
Packit |
0848f5 |
if (result != MPI_SUCCESS)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Unable to send coordinate data to the visualizer, aborting.\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* Writes out a linear integer array of grayscale pixel values to a
|
|
Packit |
0848f5 |
pgm-format file (with header). The exact format details are given
|
|
Packit |
0848f5 |
at the end of this routine in case you don't have the man pages
|
|
Packit |
0848f5 |
installed locally. Essentially, it's a 2-dimensional integer array
|
|
Packit |
0848f5 |
of pixel grayscale values. Very easy to manipulate externally.
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
/* You need the following inputs:
|
|
Packit |
0848f5 |
A linear integer array with the actual pixel values (read in as
|
|
Packit |
0848f5 |
consecutive rows),
|
|
Packit |
0848f5 |
The width and height of the grid, and
|
|
Packit |
0848f5 |
The maximum pixel value (to set greyscale range). We are assuming
|
|
Packit |
0848f5 |
that the lowest value is "0".
|
|
Packit |
0848f5 |
*/
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
void dumpimage(char *filename, int in_grid_array[], int in_pixels_across, int in_pixels_down,
|
|
Packit |
0848f5 |
int in_max_pixel_value, char input_string[], int num_colors, color_t colors[])
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
FILE *ifp;
|
|
Packit |
0848f5 |
int i, j, k;
|
|
Packit |
0848f5 |
#ifdef USE_PPM
|
|
Packit |
0848f5 |
int r, g, b;
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
printf("%s\nwidth: %d\nheight: %d\ncolors: %d\nstr: %s\n",
|
|
Packit |
0848f5 |
filename, in_pixels_across, in_pixels_down, num_colors, input_string);
|
|
Packit |
0848f5 |
fflush(stdout);
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if ( (ifp=fopen(filename, "w")) == NULL)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
printf("Error, could not open output file\n");
|
|
Packit |
0848f5 |
MPI_Abort(MPI_COMM_WORLD, -1);
|
|
Packit |
0848f5 |
exit(-1);
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
#ifdef USE_PPM
|
|
Packit |
0848f5 |
fprintf(ifp, "P3\n"); /* specifies type of file, in this case ppm */
|
|
Packit |
0848f5 |
fprintf(ifp, "# %s\n", input_string); /* an arbitrary file identifier */
|
|
Packit |
0848f5 |
/* now give the file size in pixels by pixels */
|
|
Packit |
0848f5 |
fprintf(ifp, "%d %d\n", in_pixels_across, in_pixels_down);
|
|
Packit |
0848f5 |
/* give the max r,g,b level */
|
|
Packit |
0848f5 |
fprintf(ifp, "255\n");
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
k=0; /* counter for the linear array of the final image */
|
|
Packit |
0848f5 |
/* assumes first point is upper left corner (element 0 of array) */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
if (in_max_pixel_value < 1)
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
for (j=0; j
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
for (i=0; i
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
fprintf(ifp, "0 0 0 ");
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
fprintf(ifp, "\n"); /* done writing one row, begin next line */
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
else
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
for (j=0; j
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
for (i=0; i
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
getRGB(colors[(in_grid_array[k] * num_colors) / in_max_pixel_value], &r, &g, &b);
|
|
Packit |
0848f5 |
fprintf(ifp, "%d %d %d ", r, g, b); /* +1 since 0 = first color */
|
|
Packit |
0848f5 |
++k;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
fprintf(ifp, "\n"); /* done writing one row, begin next line */
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
#else
|
|
Packit |
0848f5 |
fprintf(ifp, "P2\n"); /* specifies type of file, in this case pgm */
|
|
Packit |
0848f5 |
fprintf(ifp, "# %s\n", input_string); /* an arbitrary file identifier */
|
|
Packit |
0848f5 |
/* now give the file size in pixels by pixels */
|
|
Packit |
0848f5 |
fprintf(ifp, "%d %d\n", in_pixels_across, in_pixels_down);
|
|
Packit |
0848f5 |
/* gives max number of grayscale levels */
|
|
Packit |
0848f5 |
fprintf(ifp, "%d\n", in_max_pixel_value+1); /* plus 1 because 0=first color */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
k=0; /* counter for the linear array of the final image */
|
|
Packit |
0848f5 |
/* assumes first point is upper left corner (element 0 of array) */
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
for (j=0;j
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
for (i=0;i
|
|
Packit |
0848f5 |
{
|
|
Packit |
0848f5 |
fprintf(ifp, "%d ", in_grid_array[k]+1); /* +1 since 0 = first color */
|
|
Packit |
0848f5 |
++k;
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
fprintf(ifp, "\n"); /* done writing one row, begin next line */
|
|
Packit |
0848f5 |
}
|
|
Packit |
0848f5 |
#endif
|
|
Packit |
0848f5 |
|
|
Packit |
0848f5 |
fclose(ifp);
|
|
Packit |
0848f5 |
}
|