⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mandelbrot_master.c

📁 for parallel computation
💻 C
字号:
/*  
* Mandlebrot Sets
*/

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <stdio.h>
#include <stdlib.h> 	
#include <time.h>
#include "pvm3.h"

#define	X_RESN	800      /* x resolution */
#define	Y_RESN	800       /* y resolution */
//define MAX_SLAVES 20
#define MAX_ITER	100
#define LINES_ASSIGNED_PER_TIME 100 /* assign 100 lines a time */
#define SLAVENAME "mandelbrot_slave"	/* name of slave file */
#define ENCODING  PvmDataDefault

#define DATA_TAG 0
#define TERMINATOR_TAG 1
//define TAG_ANY -1
//define PROC_ANY -1

//int	nhost, *stid;		/* num of the hosts; array to place slaves' id */
//int display_width = X_RESN;
//int display_height = Y_RESN;

Window	win;                    /* initialization for a window */
Display	*display;
GC	gc;
Colormap cmap;
unsigned int screen;                         /* which screen */

//int spawnSlave();
//void killSlaves(int nSlave);
int assignRows(int slaveTid,int startRow);
//int recvResults(int slaveTid, int tag, int *startRow, int *nRows, int result[]);
void drawPixels(int result[], int startRow, int nRows);
void initDisplay();		/*init X-Windows*/


/************************************************************/
void main ()
{
	/* init variable  */
	
	
	
	int i;
	
	/* record time */
	time_t	startTime, endTime;
	int usedTime;		
  startTime = time(NULL);
	printf("Start at %ld.\n", startTime);	
	
	int mytid;
	if ((mytid = pvm_mytid()) < 0) {
		exit(1);
	}
	printf("I'm t%x\n", mytid);
	
	/* spawn slaves */
	int nSlave, n;
	struct pvmhostinfo *hosts[20];	
	
	//int nhost, narch, i, nSlave;
	//struct pvmhostinfo *hostp[MAX_SLAVES];
	
	///* get the state of the pvm, also get num of machines */
	if (pvm_config(&nSlave,&n,hosts) < 0)
	{
		printf("PVM config error!\n");
		return 0;
	}
	//printf("There are %d machines!\n", nhost);
	//if(nhost<=0)
	//{
		//return 0;
	//}

	/* fork slaves, total num = nhost */
	//nSlave = nhost;
	int *stid = new int[nSlave];/* array to put slaves' id(s) */
	if (pvm_spawn(SLAVENAME, (char**)0, 0, "", nSlave, stid) < 0)
	{
		printf("Failed to spawnSlave! Program will exit now.\n");
		pvm_exit();
		exit(-1);
	}
	printf("Spawned %d slaves. They are: ", nSlave);
	for(i=0; i<nSlave; i++)
	{
		printf(" %x\t", stid[i]);
	}		
	printf("\n");

	//return nSlave;
	//nSlave = spawnSlave();
	/*if(nSlave==0)
	{
		printf("Failed to spawnSlave! Program will exit now.\n");
		pvm_exit();
		exit(-1);
	}*/
	
    /* at first send job to each slave, to make all slaves busy */
	int		curRow = 0;
	int		Count = 0;		/* record row number that haven't returned from slave */
	for(i=0; i<nSlave; i++)/* for each node(slave) */
	{
		curRow = i * LINES_ASSIGNED_PER_TIME;/* no. of the first line sent */
		Count += assignRows(stid[i], curRow);/* include line num determination */
		printf("Now unreturned Rows = %d \n", Count);
    }
	
	/* init display enviroment, while slaves are calculating */
	//printf("Initing display.................");
	/*Window	win;                    /* initialization for a window 
  Display	*display;
  GC	gc;
  resultmap cmap;
  unsigned int screen;                         /* which screen */
	initDisplay();
	//printf("Init display finished.\n");
	
	/* init variable */
	int 	startRow, nRows, slaveTid;
	
	//int Size = X_RESN * LINES_ASSIGNED_PER_TIME;
	int *result = new int [X_RESN * LINES_ASSIGNED_PER_TIME] ;
	int Size;
	/* receive results */
	do
	{
		//slaveTid = recvResults(PROC_ANY, TAG_ANY, &startRow, &nRows, result);
		pvm_upkint(&slaveTid,1,1);		/* first data is the slave's id */
	  pvm_upkint(&startRow,1,1); 	/* start row no. */
	  pvm_upkint(&nRows,1,1);		/* how many rows */
	  Size = nRows * X_RESN;
	  pvm_upkint(result,Size,1);/* result array */
		Count -= nRows;
		//printf(">>Recved row:%d - %d from slave:%x. Now unreturned Rows = %d\n", startRow, startRow+nRows, slaveTid, Count);		
			
		/* send some rows back to the slave came */
		curRow += LINES_ASSIGNED_PER_TIME;	/* the 1st line of the block to send */
		Count += assignRows(slaveTid, curRow);
			
		/* display pixels received */
		drawPixels(result, startRow, nRows);
		
	}while(Count>0);
	
	/* record time */
  endTime = time(NULL);
	usedTime = endTime - startTime;
	printf("End at %ld.\n", endTime);
	printf("Totally cost: %d\n", usedTime);
		
	XFlush (display);
	
	sleep (200);
	for(int i=0; i<nSlave; i++)
	{
	    if (stid[i] > 0)
			pvm_kill(stid[i]);/* kill the slaves that were successfully spawned  */
	}
	
	//killSlaves(nSlave);
//	pvm_exit();
//    exit(0);
}


/*******************************
* int spawnSlave()
* config pvm, and spawn slaves
* return the num of slaves ( 0 for fail)
********************************/
/*int spawnSlave()
{
	int nhost, narch, i, nSlave;
	struct pvmhostinfo *hostp[MAX_SLAVES];
	
	//get the state of the pvm, also get num of machines 
	if (pvm_config(&nhost,&narch,hostp) < 0)
	{
		printf("PVM config error!\n");
		return 0;
	}
	printf("There are %d machines!\n", nhost);
	if(nhost<=0)
	{
		return 0;
	}

	/* fork slaves, total num = nhost 
	nSlave = nhost;
	stid = new int[nSlave];/* array to put slaves' id(s) 
	if (pvm_spawn(SLAVENAME, (char**)0, 0, "", nSlave, stid) < 0)
	{
		printf("Failed to spawn slaves!\n");
		killSlaves(nSlave);
		return 0;
	}
	printf("Spawned %d slaves. They are: ", nSlave);
	for(i=0; i<nSlave; i++)
	{
		printf(" %x\t", stid[i]);
	}		
	printf("\n");

	return nSlave;
}


/***************************
* kill the slaves
* param nSlave : num of the slaves to kill

void killSlaves(int nSlave)
{
	for(int i=0; i<nSlave; i++)
	{
	    if (stid[i] > 0)
			pvm_kill(stid[i]);/* kill the slaves that were successfully spawned  
	}
}
*/
/*****************************
* int assignRows(..)
* send rows of data (only startRow and nRows)
* 		or TERMINATOR_TAG if no lines left
* return num of the rows sent this time
******************************/
int assignRows(int slaveTid,int startRow)
{
	int nRows;

	///* init to send */
	pvm_initsend(ENCODING);			

	///* calculate num of rows to send */
	if(startRow >= Y_RESN) /* all lines have been assigned */
	{
		//printf("No more lines to assign, slave: %x can quit.\n", slaveTid);
		pvm_send(slaveTid, TERMINATOR_TAG);/* send term msg */
		nRows = 0;
	}
	else
	{
		if((startRow+LINES_ASSIGNED_PER_TIME) >= Y_RESN) /* less than a block(100 rows) left */
		{
			nRows = Y_RESN - startRow;
			//printf("Only %d lines left, assigned row:%d - %d to slave: %x\n", nRows, startRow, Y_RESN, slaveTid);
		}
		else
		{
			nRows = LINES_ASSIGNED_PER_TIME;
			//printf("Assign row:%d - %d to slave: %x\n", startRow, startRow+nRows, slaveTid);
		}
		
		/* pk and send */
		pvm_pkint(&startRow,1,1);				/* start row no. */
		pvm_pkint(&nRows,1,1);			/* how many rows */
		if(pvm_send(slaveTid, DATA_TAG) <0 )
		{
			printf("Send data failed!\n");
		}	
		
	}
	return nRows;	/* num of the rows sent this time */
}


/*******************************
* int recvResults(...)
* receive rows of data(result of each pixel)
* return the slave's id (upk from the packet data)
*******************************/
/*int recvResults(int slaveTid, int tag, int *startRow, int *nRows, int result[])
{
	int sid, Size;
	if(pvm_recv(slaveTid,tag)<0)
	{
		printf("Recv data failed!\n");
	}	
	
	/* unpacket 
	pvm_upkint(&sid,1,1);		/* first data is the slave's id 
	pvm_upkint(startRow,1,1); 	/* start row no. 
	pvm_upkint(nRows,1,1);		/* how many rows 
	Size = (*nRows) * X_RESN;
	pvm_upkint(result,Size,1);/* result array 

	return sid;			/* return num of received rows 
}
*/

/******************************
* display pixels received recently
* from startRow to (startRow + nRows)
* their results are stored in result[]
*******************************/
void drawPixels(int result[], int startRow, int nRows)
{
	int x,y;
	int i=0;
	int tempC;
	XColor  xcolor;
	for(y=startRow; y<(startRow+nRows); y++)	/* y means row */
	{
		for(x=0; x<X_RESN; x++)			/* x means col */
		{
			i++;
			tempC = result[i] * result[i] * 5;
			
			if(result[i]==MAX_ITER)	/* foregroud : dark */
			{			
				xcolor.red = 65535U - (unsigned int) tempC ;
				xcolor.green = 65535U - (unsigned int) tempC ;
				xcolor.blue = 65535U - (unsigned int) tempC ;
				if (XAllocColor (display,cmap, &xcolor))
				{
					XSetForeground (display, gc, xcolor.pixel);
				}
				XDrawPoint (display, win, gc, y, x);	/* (row,col) */
			}
			
			else if(result[i] >= MAX_ITER/4 ) /* red, cut down g&b */
			{
				xcolor.red = 65535U - (unsigned int) tempC ;
				xcolor.green = 0;
				xcolor.blue = 65535U - (unsigned int) tempC ;
				if (XAllocColor (display,cmap, &xcolor))
				{
					XSetForeground (display, gc, xcolor.pixel);
				}
				XDrawPoint (display, win, gc, y, x);
			}
			
			else if(result[i] >= MAX_ITER/8)	/* result[i]<MAX_ITER/2, remain black as backgroud, NOT drawed */
			{
				xcolor.red = 0;
				xcolor.green = 65535U - (unsigned int) tempC ;
				xcolor.blue = 0;
				if (XAllocColor (display,cmap, &xcolor))
				{
					XSetForeground (display, gc, xcolor.pixel);
				}
				XDrawPoint (display, win, gc, y, x);
			}
			
	
			else if(result[i] >= MAX_ITER/10)	/* result[i]<MAX_ITER/2, remain black as backgroud, NOT drawed */
			{
				xcolor.red = 65535U - (unsigned int) tempC;
				xcolor.green = 65535U - (unsigned int) tempC ;
				xcolor.blue = 0 ;
				if (XAllocColor (display,cmap, &xcolor))
				{
					XSetForeground (display, gc, xcolor.pixel);
				}
				XDrawPoint (display, win, gc, y, x);
			}
			
			else if(result[i] >= MAX_ITER/16)	/* result[i]<MAX_ITER/2, remain black as backgroud, NOT drawed */
			{
				xcolor.red = 0;
				xcolor.green = 0;
				xcolor.blue = 65535U - (unsigned int) tempC ;
				if (XAllocColor (display,cmap, &xcolor))
				{
					XSetForeground (display, gc, xcolor.pixel);
				}
				XDrawPoint (display, win, gc, y, x);
			}
			
			else if(result[i] >= MAX_ITER/20)	/* result[i]<MAX_ITER/2, remain black as backgroud, NOT drawed */
			{
				xcolor.red = 0;
				xcolor.green = 65535U - (unsigned int) tempC ;
				xcolor.blue = 65535U - (unsigned int) tempC ;
				if (XAllocColor (display,cmap, &xcolor))
				{
					XSetForeground (display, gc, xcolor.pixel);
				}
				XDrawPoint (display, win, gc, y, x);
			}
			
			else if( result[i] >= MAX_ITER/50 ) /* yellow, depend on r&g, cut down b */
			{
				xcolor.red = 65535U - (unsigned int)tempC*500;
				xcolor.green = 65535U - (unsigned int)tempC*500;
				xcolor.blue = 65535U - (unsigned int)tempC*500;
				if (XAllocColor (display,cmap, &xcolor))
				{
					XSetForeground (display, gc, xcolor.pixel);
				}
				XDrawPoint (display, win, gc, y, x);
			}
			
		}
	}/* for (each pixel) */
}


/******************************
* config to display
******************************/
void initDisplay()
{
	unsigned int width, height,                  /* window size */
				x, y,                           /* window position */
				border_width,                   /*border width in pixels */
				display_width, display_height;  /* size of screen */

	char  	*window_name = "Mandelbrot Set",
			*display_name = NULL;
	unsigned long valuemask = 0;
	XGCValues	values;
	XSizeHints	size_hints;
	Pixmap		bitmap;
	XPoint		points[800];
	FILE		*fp, *fopen ();
	char		str[100];
	
	XSetWindowAttributes attr[1];
       
	/* connect to Xserver */
	if (  (display = XOpenDisplay (display_name)) == NULL ) {
	   fprintf (stderr, "drawon: cannot connect to X server %s\n",
				XDisplayName (display_name) );
	exit (-1);
	}
	
	/* get screen size */
	screen = DefaultScreen (display);
	display_width = DisplayWidth (display, screen);
	display_height = DisplayHeight (display, screen);

	/* set window size */
	width = X_RESN;
	height = Y_RESN;

	/* set window position */
	x = 0;
	y = 0;

	/* create opaque window */
	border_width = 4;
	win = XCreateSimpleWindow (display, RootWindow (display, screen),
								x, y, width, height, border_width, 
								BlackPixel (display, screen), WhitePixel (display, screen));

	
	cmap = DefaultColormap  (display,screen);							
								
	size_hints.flags = USPosition|USSize;
	size_hints.x = x;
	size_hints.y = y;
	size_hints.width = width;
	size_hints.height = height;
	size_hints.min_width = 300;
	size_hints.min_height = 300;
	
	XSetNormalHints (display, win, &size_hints);
	XStoreName(display, win, window_name);

	/* create graphics context */
	gc = XCreateGC (display, win, valuemask, &values);

	XSetBackground (display, gc, WhitePixel (display, screen));
	XSetForeground (display, gc, BlackPixel (display, screen));
	XSetLineAttributes (display, gc, 1, LineSolid, CapRound, JoinRound);

	attr[0].backing_store = Always;
	attr[0].backing_planes = 1;
	attr[0].backing_pixel = BlackPixel(display, screen);

	XChangeWindowAttributes(display, win, CWBackingStore | CWBackingPlanes | CWBackingPixel, attr);

	XMapWindow (display, win);
	XSync(display, 0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -