#!../src/tops
# File cluster  March 2004

# Running the Make-pi demo of file clu.v.
{
   In directory tops/test, this file runs from the Unix prompt using:

      % cluster

   or from the program's ready prompt (running in tops/test) with:

      ready > 'cluster' source

   When run from the ready prompt, the node windows remain connected
   and in view (if X11), and are handy for further study of network 
   commands.

   If the node windows remain connected and visible, by running as
   noted above, then their keyboards can be enabled by running the
   following phrase from the window where the cluster was started:

      "'key.v' source" cluster_run
}
\-----------------------------------------------------------------------

   "CONNECT" missing
   IF " cluster: words for networking not present, test skipped" dot nl
      halt
   THEN 

   "USE_PORT" missing IF "clu.v" source THEN

\-----------------------------------------------------------------------

\  Words new.

   inline: cluster_start (N p --- ) \ start N nodes running processor p
{     For this demo, this word replaces the version of cluster_start
      for a real cluster in file clu.v, just sourced above.

      To act as a cluster of three nodes, three background servers are 
      started by running script usr/tserv.  Because this is a simula-
      tion on a single machine, each server is listening on a different
      port; node servers on a cluster can all listen on the same port 
      number since they are on separate networks. 

      In addition to starting the cluster nodes listening, this word 
      also connects the nodes to the head node by running word
      cluster_connect.

      The head node connects to the nodes using the machine's loopback 
      IP address.

      If some nodes fail to connect, try increasing SEC, the time for 
      the program to idle before trying to connect to the nodes.

      Increasing SEC gives more time for the node programs to start up 
      and get into listening mode as servers.
} 
      [ 5 "SEC" book 
        host "sigma" = IF 10 "SEC" book THEN \ this one needs more time
      ]

      "cluster_connect" "HOST" yank any? 
      IF (N p hHOST) 3 dump
         " cluster_start: cluster is running" dot nl return 
      THEN 

      (N p) 2drop \ N and p are not used in this demo

      def_port nextport "PORT" book
      usrpath "tserv -port " catpath PORT 2 + int$ " &" cat cat
      usrpath "tserv -port " catpath PORT 1 + int$ " &" cat cat
      usrpath "tserv -port " catpath PORT     int$ " &" cat cat

      (qPORT2 qPORT1 qPORT)
      X11 
      IF "-geometry 50x8+0+0"   "nodewin" "GEO" bank nodewin
         "-geometry 50x8+0+150" "nodewin" "GEO" bank nodewin
         "-geometry 50x8+0+300" "nodewin" "GEO" bank nodewin
      ELSE nullshell 
           nullshell 
           nullshell
      THEN \ running locally on loopback IP address:
      IPloop spaced PORT     int$ cat
      IPloop spaced PORT 1 + int$ cat
      IPloop spaced PORT 2 + int$ cat
      3 pilen "JOBS" book

      SEC " Idle " that int$ " seconds while cluster nodes start..." 
      cat cat dot idle
      " done" dot nl

      " Connecting cluster nodes to head node..." dot
      cluster_connect 
      " done" dot nl

   end

   inline: Ready ( --- ) \ nodes at attention
      X11 
      IF "nl 'Ready ' dot" (qS)          \ show Ready message on node
      ELSE "'/dev/null' set_sysout" (qS) \ show no node text
      THEN (qS) cluster_run              \ broadcast S to all to run
   end

\  End of new words.

\-----------------------------------------------------------------------

\  Running the Make-pi demo.

   nl
   3 1 cluster_start
 
   cluster_ack (f) \ acknowledgment from all the nodes
   IF Ready " All nodes are connected" dot nl
   ELSE 
      " Failed to connect all nodes; "
      "the following sockets are connected:" cat (qS) dot nl
      "cluster_ack" "ACK" yank (hACK) .m nl
      " cluster: in file cluster, try increasing SEC in cluster_start" 
      (qS) dot nl
      " cluster: halting" (qS) dot nl 
      halt
   THEN
        
   " Node names, sockets, and ports:" dot nl
   cluster_props 2 indent dot nl \ node names, sockets, and ports
   pause

   " Preparing to run the Make-pi demo" dot nl
   "clu.v" "Make-pi demo." msource \ sourcing words for Make-pi demo

   32 "Pieces" book \ make pi from this many pieces

   keys?
   IF "whos" cluster_run \ show words on the nodes
      Ready
      whos               \ show words on the head node
   THEN
   pause
   
   cluster_ack not \ is everybody ready?
   IF " cluster: nodes are not ready; demo halting" dot nl HALT THEN

   "wtrace" cluster_run \ activate trace on all nodes

   Pieces INIT 
   keys?
   IF " Summing these " Pieces int$ cat " intervals from 0 to 1:" cat 
      dot nl
      "make_piece" "RANGES" yank .m nl
   THEN

   "make_piece" cluster_source \ running; head node wait
   " Cluster is running the Make-pi demo" dot nl

   os "aix" = 
   IF 30 \ AIX is slowed on purpose, so allow more time here
   ELSE 10 
   THEN (sec)
   (sec) "awhile" WAIT_INIT \ word awhile, clu.v, flags when pi is done

   WAIT_BEGIN \ begin indeterminate wait state

   PI "%16.14f" format nl sp sp dot 
   " computed using " Pieces int$ " pieces for pi" cat cat dot nl

   pi "%16.14f" format sp sp dot " is the program's pi" dot nl

   " End of cluster demo" nl dot nl

   keys? not 
   IF " Cluster closing" dot nl  cluster_close
   ELSE 
      "nowtrace" cluster_run \ deactivate trace on all nodes
      Ready
   THEN

   end
