  
  [1X3 [33X[0;0YUsing ZeroMQ with the zgap script[133X[101X
  
  [33X[0;0YThe  [10Xzgap[110X  script  provides  facilities to start a number of child processes
  controlled  by  a  single  master process and to allow for easy coordination
  between them.[133X
  
  
  [1X3.1 [33X[0;0YRunning zgap[133X[101X
  
  [33X[0;0YFrom the shell, run zgap via:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28Xbin/zgap -N <nodes> <gap_options> <gap_files>[128X[104X
  [4X[32X[104X
  
  [33X[0;0YHere,  [10Xnodes[110X  should  be  a  positive  integer  that describes the number of
  workers one wishes to start. The rest of the command line, consisting of gap
  options and gap files, will be passed to the master and the worker processes
  verbatim.  This  allows,  for  example, the initialization of functions that
  need  to  be known by all workers. The first line of output will be prefixed
  with  [10X[zgap][110X and will list the directory where [10Xzgap[110X will store the files and
  sockets  it  uses  to communicate. In particular, the [10XlogXX.txt[110X files within
  that  directory  will  contain  the output generated by the workers; this is
  useful  for  debugging,  as  the  workers  do not have a working break loop.
  Example:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28Xbin/zgap -N 4 -P 8 -m 1G common.g[128X[104X
  [4X[32X[104X
  
  [33X[0;0YOn  NUMA  architectures  that support the [10Xnumactl[110X command, it is possible to
  further  specify  which node each worker should be running on. This can take
  one of two forms:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28Xbin/zgap -N <count>:<start>-<end>[128X[104X
    [4X[28Xbin/zgap -N <count>:+<start>-<end>[128X[104X
  [4X[32X[104X
  
  [33X[0;0YEach  will  distribute  [10Xcount[110X worker processes on the physical nodes ranging
  from  [10Xstart[110X to [10Xend[110X in a round-robin fashion, reusing nodes if there are more
  workers than nodes. The first mode (without a [10X+[110X sign) will use absolute node
  numbers,  the second will be relative to the master process. See the [10Xnumactl[110X
  manual page for further details. Example:[133X
  
  [4X[32X  Example  [32X[104X
    [4X[28Xbin/zgap -N 4:+0-3 -P 8 -m 1G common.g[128X[104X
  [4X[32X[104X
  
  [33X[0;0YNote:  Currently,  [10Xzgap[110X can only be run from the GAP root directory. This is
  an implementation restriction that is to be removed at a later date.[133X
  
  
  [1X3.2 [33X[0;0YZgap API[133X[101X
  
  [33X[0;0YMost  of  the following API functions take a [10Xdest[110X argument, which is used to
  specify  the  destination of the operation. To specify a worker thread, [10Xdest[110X
  would  have  to  be  an  integer in the range from 1 to the number of worker
  processes;  0  specifies  the  master  process.  Multiple  processes  can be
  specified by a range or list of integers. The variable [10XZAll[110X contains a range
  encompassing  the  worker processes; [10XZSelf[110X contains the index of the current
  worker or 0 for the master.[133X
  
  [1X3.2-1 ZExec[101X
  
  [33X[1;0Y[29X[2XZExec[102X( [3Xdest[103X, [3Xcmd[103X ) [32X function[133X
  
  [33X[0;0YThis  function sends [10Xcmd[110X to the given destination and executes it there. The
  command  must  be  a  valid  GAP  statement  ending  in a semicolon. If [10Xdest[110X
  specifies multiple processes, the command will be executed on all of them.[133X
  
  [1X3.2-2 ZBind[101X
  
  [33X[1;0Y[29X[2XZBind[102X( [3Xdest[103X, [3Xvar[103X, [3Xexpr[103X ) [32X function[133X
  
  [33X[0;0YThis  function  binds the global variable described by the string [10Xvar[110X to the
  value  [10Xexpr[110X in all processes listed in [10Xdest[110X. Note that [10Xexpr[110X must evaluate to
  a serializable value.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XZBind(ZAll, "counter", 0);[127X[104X
  [4X[32X[104X
  
  [1X3.2-3 ZUnbind[101X
  
  [33X[1;0Y[29X[2XZUnbind[102X( [3Xdest[103X, [3Xvar[103X ) [32X function[133X
  
  [33X[0;0YThis  function  is  the  counterpart  to  [10XZBind[110X.  It  will unbind [10Xvar[110X in all
  specified processes.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XZUnbind(ZAll, "status");[127X[104X
  [4X[32X[104X
  
  [1X3.2-4 ZCall[101X
  
  [33X[1;0Y[29X[2XZCall[102X( [3Xdest[103X, [3Xfunc[103X, [3Xargs[103X ) [32X function[133X
  
  [33X[0;0YThis  function will execute the function specified by the string [10Xfunc[110X in the
  specified  processes.  The string [10Xfunc[110X must be the name of a global variable
  referring to the function to be executed. This function should be created at
  startup  by  adding a file to the commandline that defines it in all workers
  or by [10XZExec[110X.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27XZBind(ZAll, "counter", 0);[127X[104X
    [4X[25Xgap>[125X [27XZExec(Zall, "add := function(n) counter := counter + n; end;");[127X[104X
    [4X[25Xgap>[125X [27XZCall(1, "add", [1]);[127X[104X
  [4X[32X[104X
  
  [1X3.2-5 ZQuery[101X
  
  [33X[1;0Y[29X[2XZQuery[102X( [3Xdest[103X, [3Xfunc[103X, [3Xargs[103X, [3Xcallback[103X ) [32X function[133X
  
  [33X[0;0YThis  function works like [10XZCall[110X, except that any return value will be passed
  to the callback function.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xres := false;[127X[104X
    [4X[28Xfalse[128X[104X
    [4X[25Xgap>[125X [27XZQuery(1, "ReturnTrue", [], function(x) res := x; end);[127X[104X
    [4X[25Xgap>[125X [27Xres;[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  [1X3.2-6 ZResponse[101X
  
  [33X[1;0Y[29X[2XZResponse[102X(  ) [32X function[133X
  
  [33X[0;0Y[10XZResponse[110X  is  a  convenience  function  to construct blocking callbacks for
  [10XZCall[110X  and  [10XZTask[110X.  It  returns a record containing a [10Xput[110X, a [10Xget[110X, and a [10Xtest[110X
  function.  Here,  [10Xput[110X is passed as the callback; [10Xget[110X can be used to read the
  returned value; and [10Xtest[110X can be used to test for the presence of a value.[133X
  
  [4X[32X  Example  [32X[104X
    [4X[25Xgap>[125X [27Xresp := ZResponse();;[127X[104X
    [4X[25Xgap>[125X [27XZQuery(1, "Z", [4], resp.put);[127X[104X
    [4X[25Xgap>[125X [27Xresp.get();[127X[104X
    [4X[28XZ(2^2)[128X[104X
    [4X[25Xgap>[125X [27Xresp.test();[127X[104X
    [4X[28Xtrue[128X[104X
  [4X[32X[104X
  
  [1X3.2-7 ZTask[101X
  
  [33X[1;0Y[29X[2XZTask[102X( [3Xdest[103X, [3Xfunc[103X, [3Xargs[103X, [3Xcallback[103X ) [32X function[133X
  
  [33X[0;0YThis  function  works like [10XZQuery[110X, except that the function will be executed
  via a task and [10Xcallback[110X will be called after the task finishes and returns a
  result.[133X
  
  [1X3.2-8 ZAsync[101X
  
  [33X[1;0Y[29X[2XZAsync[102X( [3Xdest[103X, [3Xfunc[103X, [3Xargs[103X ) [32X function[133X
  
  [33X[0;0YThis  function  works  like [10XZCall[110X, except that the function will be executed
  via a task.[133X
  
  [1X3.2-9 ZRead[101X
  
  [33X[1;0Y[29X[2XZRead[102X( [3Xdest[103X, [3Xfile[103X ) [32X function[133X
  
  [33X[0;0YThis function does a [10XRead(file)[110X for all specified processes.[133X
  
  [1X3.2-10 ZReadGapRoot[101X
  
  [33X[1;0Y[29X[2XZReadGapRoot[102X( [3Xdest[103X, [3Xfile[103X ) [32X function[133X
  
  [33X[0;0YThis function does a [10XReadGapRoot(file)[110X for all specified processes.[133X
  
  [33X[0;0Y [133X
  
