home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * findroot.c : A parallel root finding program
- * author: Victor R. Volkman
- *
- * Based on a problem suggested by: Professor Dave Poplawski
- * Department of Computer Science
- * Michigan Technological University
- * Houghton, Michigan 49931
- */
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "dvapi.h"
- #include "dvapi2.h"
- #include "monitor.h"
-
- #include "monitor.fd"
- #ifndef MAKEFD
- #include "findroot.fd"
- #endif
-
- double f();
- static double global_x0, global_x1, global_y0, global_y1;
- #define STACKSIZE 1000
-
- int master[NUMPRC];
- DESQ_HAN glob_win_han;
- static MONITOR *root_mon;
-
-
- /* The main() program serves a passive role in the root finding
- process. The main() program activates node-0 which assumes
- temporary control over the other subprocesses. Note that
- the lower and upper bounds (global_x0 and global_x1 must be
- set prior to activating node-0. */
-
- main()
- {
- int i;
- int version;
- DESQ_HAN task_han;
- char stacks[NUMPRC][STACKSIZE];
- char node_str[40];
- double dummy;
-
- global_x0 = 0.0; /* Lower Limit */
- global_x1 = 1.0; /* Upper Limit */
-
- version = api_init();
- if (version < REQ_DESQVIEW) {
- printf("This program requires DESQView %d.%02d or later.\n",
- REQ_DESQVIEW >> 8, REQ_DESQVIEW & 0xFF);
- exit(1);
- }
- /* set minimum API function level */
- api_level(REQ_DESQVIEW);
-
- if (NUMPRC % 2 != 0) {
- printf("NUMPRC is %d, please use an even number of nodes\n",NUMPRC);
- exit(-1);
- }
-
- glob_win_han = win_new(GLOB_NAME,strlen(GLOB_NAME),
- GLOB_HEIGHT,GLOB_WIDTH);
- win_move(glob_win_han,0,0); /* Set screen row=0, col=0 */
- win_logattr(glob_win_han,TRUE); /* Use logical screen attributes */
- win_attr(glob_win_han,1); /* Display text in default color */
- win_frame(glob_win_han,FALSE); /* Don't display a box border */
- win_unhide(glob_win_han); /* Mark this window as visible */
- win_top(glob_win_han); /* Bring to top & redraw window */
-
- win_printf(glob_win_han,
- "Root finder activated with %d subprocesses and resolution %f...\n",
- NUMPRC, EPSILON);
- global_y0 = f(global_x0); /* Establish initial values */
- global_y1 = f(global_x1);
- open_monitor("rootfinder",&root_mon);
- sendv(root_mon,0.0,MASTER); /* Allow MASTER signal to be claimed */
-
- for (i=0; i<NUMPRC; i++) {
- master[i] = 0;
- task_han = tsk_new(task_findroot, stacks[i], STACKSIZE, "", 0, 0, 0);
- win_printf(glob_win_han,"spawned task %d\n",i);
- win_top(glob_win_han);
- sprintf(node_str,"%d",i);
- mal_write(mal_of(task_han), node_str, sizeof(node_str));
- }
-
- recvl(root_mon,&dummy,TERMINATE);
- win_printf(glob_win_han,"Lower limit X0 is %f,
- f(X0) is %f\n",global_x0,global_y0);
- win_printf(glob_win_han,"Upper limit X1 is %f, f(X1) is %f\n",
- global_x1,global_y1);
- win_printf(glob_win_han,"Master status %d, %d, %d, %d\n",
- master[0],master[1],master[2],master[3]);
- win_printf(glob_win_han,"Press any key to continue...\n");
- win_top(glob_win_han);
- close_monitor(&root_mon);
- getch();
- }
-
-
-
- task_findroot(void)
- {
- char *msg_buffer;
- char title[30];
- DESQ_HAN my_mal_han;
- DESQ_HAN win_han;
- double interv, y0, y1, dummy;
- int lastnode, indx;
- int msg_len;
- int node;
- int term;
-
- my_mal_han = mal_me(); /* Find out and read mail from parent */
- mal_read(my_mal_han,&msg_buffer,&msg_len);
- sscanf(msg_buffer,"%d",&node);
-
- sprintf(title,"Node %03d",node);
- win_han = win_new(title,strlen(title),3,38+(node<4)*40);
- win_move(win_han,7+(node%4)*5,1+(node>3)*40);
- win_logattr(win_han,1); /* Use logical screen attributes */
- win_attr(win_han,1); /* Display text in default color */
- win_unhide(win_han); /* Mark this window as visible */
- win_top(win_han); /* Bring to top & redraw window */
-
- lastnode = (node==(NUMPRC-1));
- do
- {
- interv = (global_x1-global_x0)/(NUMPRC);
- y1 = f(global_x0+interv*(node+1));
-
- /* First, all even nodes send & odd nodes receive, via recv semafore */
- if (node % 2 == 0)
- sendv(root_mon,y1,node+1);
- else /* I'm an odd node */
- recvl(root_mon,&y0,node);
-
- /* Second, all odd nodes send & even nodes receive, via recv semafore */
- /* Node 0 may not receive, and the lastnode may not send */
- if (!lastnode)
- {
- if (node % 2 == 1)
- sendv(root_mon,y1,node+1);
- else if (node) /* I'm an even node > 0 */
- recvl(root_mon,&y0, node);
- else /* I'm node 0, so my left value is already computed */
- y0 = global_y0;
- }
-
- win_printf(win_han,"y0 = %f, y1 = %f\n",y0,y1); win_top(win_han);
- /* Determine which process will be the controller */
- if ( (y1*y0) < 0.0)
- {
- /* MASTER status must be inherited from the ex-controller */
- win_fprintf(win_han,"Node %d waiting for MASTER status\n",node);
- win_top(win_han);
- recvl(root_mon,&dummy,MASTER);
- master[node]++;
- win_printf(win_han,"Node %d has received MASTER status\n",node);
- win_top(win_han);
-
- /* compute new boundary conditions */
- global_x0 += interv * node;
- global_y0 = y0;
-
- if (!lastnode)
- global_x1 = global_x0 + interv;
- global_y1 = y1;
- term = (interv < EPSILON);
-
- /* synchronize waiting processes below */
- for (indx=0; indx<NUMPRC; indx++)
- if (indx!=node)
- sendv(root_mon, (double)term, indx+NUMPRC);
-
- /* Relinquish MASTER status to the next controller or TERMINATE */
- if (term)
- sendv(root_mon,0.0,TERMINATE);
- else
- sendv(root_mon,0.0,MASTER);
- }
- else /* synchronize */
- {
- win_printf(win_han,"Node %d suspended until notified \n",node);
- win_top(win_han);
- recvl(root_mon,&dummy,node+NUMPRC);
- term = (int) dummy;
- win_printf(win_han,"Node %d restarted by the MASTER \n",node);
- win_top(win_han);
- }
- }
- while (!term);
-
- win_printf(win_han,"Leaving...\n");
- tsk_free(tsk_me()); /* De-allocate DESQview resources */
- }
-
-
- double f(x)
- float x;
- {
- return(x*x*x - x*x + x - 0.5);
- }
-