Description

 The functions described below initialize a cluster of machines and
 enable data transfer and remote execution of Octave commands. No
 additional parallel computing libraries such as MPI and PVM are
 used. The operation has been confirmed only on Linux (but it may be
 applicable to other operating systems).


Requirements

 1. A cluster of computers (for testing, also works with only one
    computer).

 2. Octave and identical versions of package "parallel" installed on
    these computers.


Security note

 Commands are sent to slave machines over TCP connections to port
 12502, data is sent between machines over TCP connections to port
 12501. With the current version, it is your own responsibility to
 secure these ports against unauthorized access. There is no
 ecryption.


How to use

 Note first that this package assumes the use in a multiple-computer 
 system consisting of a master (your console) computer and some 
 slave computers.  Run Octave with argument "server.m" on every slave 
 computer, e.g. (the actual path to server.m may differ):

 $ octave /usr/share/octave/packages/parallel-...version.../server.m

 Run Octave without argument "server.m" on the master computer

 $ octave -q -f script.m 
  or
 $ octave

 > script



Command references

connect (hosts) 
 Make bi-directional connections among the computers specified by 
 the matrix "hosts" and return the matrix of the sockets (file 
 descriptors) directed to the listed computers.
 This command should be executed on the master computer before 
 starting parallel computation. For example, 
 you can execute the following command on the master computer:
        sockets = connect ([ "host1"; "host2"; "host3" ])
                => sockets =

                      0   0   0
                      7   5   1
                      8   6   1

 where host1, host2 and host3 are the host names (or IP addresses).  
 In a typical situation, host1 is the master, and host2 and host3 
 are the slave computers.  A pair of socket numbers (e.g., "7, 5")
 is assigned to each host.  As a side effect, this command automatically 
 issues the connect commands at the slave computers host2 and host3 
 in order to establish the connection from each slave computer 
 (host2 or host3) to the other master/slave computers.  Note that
 the return value of the connect command automatically executed 
 on each slave computer is stored in the variable "sockets".  The
 slave computer can refer this variable to send/receive data to/from
 other computers.  As a result, a complete net of bi-directional
 connections among the listed computers is established.


send (x, sockets)
 Send the variable "x" to the computers specified by matrix "sockets".
 For example,

        send ([ 1+2i, 3; 4, 5+6i ],sockets(2:3,:));

 The variable can be any Octave data type.

recv (socket)
 Receive a variable from the computer specified by the row vector "socket". 
 For example,

        recv (sockets(1,:))
           => [ 1+2i, 3; 4, 5+6i ]

reval (commands, sockets)
 Evaluate "commands" at the remote hosts specified by the matrix "sockets".
 For example,

        reval ([ "a=[ 1:3 ]"; "a=a'*a" ],socket(2,:));

scloseall (sockets)
 Close the connections specified by the matrix "sockets".
 For example,

        scloseall (sockets);

select_sockets: [N, IDX] = select_sockets (SOCKETS, TIMEOUT[, NFDS])
 See help-text of this function. Returns an index to rows in "sockets"
 with pending input from slave machines. Useful for advanced usage.

Notes for the current version:
* The slave computer must have the directory whose name and path are 
  identical with the current directory of the master computer.


Sample program:
 The following Octave script calculates the sum of the integers 
 from 1 to 100.  The computation is divided into half and assigned 
 to "host2" and "host3".

clear;
hosts = [ "host1"; "host2"; "host3" ];
sockets = connect (hosts);
psum = zeros (1, 2);
reval ("send (sum (1:50), sockets(1, :))", sockets(2, :));
reval ("send (sum (51:100), sockets(1, :))", sockets(3, :));
psum(1) = recv (sockets(2, :));
psum(2) = recv (sockets(3, :));
sum (psum)
scloseall (sockets);


 In the following script, the variable s="Hello, again!" 
 passes through 4 computers.

clear;
hosts = [ "host1"; "host2"; "host3"; "host4" ]; 
sockets = connect(hosts);
s = "Hello, again!";
send (s,sockets(2,:)); # for larger data than contained in "s", this command should be given _after_ the following "reval" commands
reval ("s = recv (sockets(1, :));", sockets(2, :));
reval ("send (s, sockets(3, :));", sockets(2, :));
reval ("s = recv (sockets(2, :));", sockets(3, :));
reval ("send (s, sockets(4,:));", sockets(3, :));
reval ("s = recv (sockets(3,:));", sockets(4, :));
reval ("send (s, sockets(1, :));",sockets(4, :));
s2 = recv (sockets(4,:))
scloseall (sockets);
