c
c host.f 8.1 91/04/04 11:08:04
c
c This program calculates the value of pi, using numerical integration
c with parallel processing, and clocks the solution time. 
c
c The user selects the number of processors and the number of points
c of integration.  By selecting and timing different cube sizes you
c obtain a measure of the speedup with perfectly parallel problems.
c
c
c   Program Components:
c
c   Constants:
c	
c	APPLPID		Application process id
c	INITTYPE	Type of initial message to the cube
c	MSGSIZE		Size of initial message to the cube (in bytes)
c	ALLNODES	Used to load all nodes in cube with a node process
c	TIMEFACTOR	Conversion factor to obtain seconds from system clock
c
c   Variables:
c
c	points		number of points to use in the integration
c	a		lower limit of integration
c	b		upper limit of integration
c	integral 	calculated integral
c	msg		message sent to and from cube. Holds a, b, & points
c
c   Calls:
c   
c	userinpt	to get integration parameters from user
c	csend		to send messages to the cube
c	crecv		to receive messages from the cube
c	killcube	to kill processes in the cube
c
	program host

	include 'fcube.h'

c	external  userinpt
	integer*4 userinpt

	integer*4 APPLPID, SIZETYPE, INITTYPE, MSGSIZE,
     >		  CUBESIZE, ALLNODES, HOSTPID, PARTTYPE

        integer*4 tms, ms, tsec, sec, min, i
	integer*4 size, points
	integer*4 msg(5)
 
        character*50 cpyright  
  
	double precision  integral, a, b
c
c	equivalence a, b, and points to elements of msg
c
	equivalence (msg(1), a)
	equivalence (msg(3), b)
	equivalence (msg(5), points)

	data 	  APPLPID /0/, 
     >		  SIZETYPE /0/, 
     >		  INITTYPE /5/, 
     >		  MSGSIZE /20/, 
     >		  CUBESIZE /4/, 
     >		  ALLNODES /-1/, 
     >		  HOSTPID/100/,
     >		  PARTTYPE /20/

        cpyright = 'Copyright (c) 1989,1990 Intel Corporation' 

        call setpid(HOSTPID)
    	print *, 'LOADING THE CUBE ...' 
    	call load ('node', ALLNODES, APPLPID)

100	size = numnodes()
	i = userinpt(a,b,points,size)
	if (i.le.0) go to 200

c send size to use into cube
	    call csend(SIZETYPE, size, CUBESIZE, ALLNODES, APPLPID)

c send integration parameters into cube
	    call csend(INITTYPE, msg, MSGSIZE, ALLNODES, APPLPID)

c receive final integral value from cube (as 'a'), and the time,
c in milliseconds (as 'b')
	    call crecv(PARTTYPE, msg, MSGSIZE)
	    integral = a

c clean out unreceived messages
c	    call flushmsg(-1, ALLNODES, APPLPID)
 
	    write(6, 110) integral
110	    format('  pi is approximately : ', F18.16)

c
c Figure out elapsed time.  Total milliseconds were returned
c from node 0 in 'points'
c
	    tms = points
	    ms  = mod(tms, 1000)
	    tsec = (tms - ms) / 1000
	    sec  = mod(tsec, 60)
	    min  = (tsec - sec) / 60

	    write(6, 111) min, sec, ms
111	    format('  elapsed time = ',i4,' min. ',i2,'.',i3.3, ' sec.')

	    goto 100

200	continue

    	print *, 'PLEASE WAIT WHILE I CLEAN OUT THE CUBE ...'
    	call killcube(ALLNODES, APPLPID)
	end
