Run - Maple Help

Grid

 Run
 run a parallel computation

 Calling Sequence Run(f,[fargs],options) Run(node,f,[fargs],options)

Parameters

 f - can either be a string containing the Maple code to run on each node, or a procedure or procedure name fargs - list; arguments passed to the remote procedure call node - integer, integer..integer, set(integer); identifier indicating which node(s) to run the command on options - (optional) equation(s) of the form option=value; see the Options section below

Description

 • The Run command runs a job in parallel. The job can be run on one designated node, or on all nodes at once. A node is a remote Maple process that does not share any variable or state with the current Maple process.
 • When using the calling sequence Run(n,f,[x]), the command f(x) will be executed on node n in the background. Maple will not wait for this command to finish before proceeding to execute the next command. Therefore, calling Run(1,f,[x]); Run(2,f,[y]); will launch the job f(x), and then immediately launch f(y) without waiting for f(x) to finish. Both f(x) and f(y) will execute on different nodes at the same time. See Grid:-Wait or Grid:-WaitForFirst to see how to sync up with a job that was previously launched. The wait=true option can be used to force the current thread to block until the remote process is finished.
 The Run command does not attempt to analyze input dependencies and push values to the remote nodes.  This includes the declaration of f itself. Unless f is a standard Maple command, or inline procedure declaration, the Grid:-Set command needs to be employed in order to define the routine on each remote node.
 • When using the calling sequence, Run(f,[x]), the command f(x) will be executed on all nodes. By default, Maple will wait for the nodes to finish, and return an array of results.
 • When using the calling sequence, Run("command"), such that the f argument is a string, the string will be parsed and evaluated in the remote node. The fargs option will not be used.
 • A parallel job initiated by the Run command does not terminate until all nodes are finished computing.  This is different than the Grid:-Launch command, which terminates when node 0 is done.
 • When initiating a computation without specifying the node number, n, the same code is run on multiple nodes. The MyNode command can be queried and used to take different branches within that code in order to assign alternate tasks to designated nodes within a computation. Otherwise, the Grid:-Set command can be used to initialize the remote nodes with different data given the same variable name.
 • The Run command is only available in local Grid mode.

Options

 The options argument can contain one or more of the following options.
 • assignto=name
 This option lets you specify a variable that will be assigned to the last result upon completion of the operation.  For example, use assignto=ret to cause the variable ret to be assigned to the run result. This is a useful option for non-blocking executions. The command Grid:-GetLastResult can also be used to get the final result of a Grid computation. When multiple nodes are involved in the execution, the last result is an array, ranging from 0 to numnodes-1, with each index containing the result from each individual node.
 • firstarrayindex=integer
 This option lets you specify the starting index of the result array (when computing with multiple nodes). By default, the array contains entries from 0..numnodes-1, with the value computed in node i, stored in the array at index i. It may sometimes be convenient to have the result array start at 1, in which case all node results computed at node i will be stored at index i+1.
 • numnodes=posint
 This option is used to specify the number of nodes to be used in the compute pool. The default value of numnodes is given by kernelopts(numcpus). Setting this option will affect future calls to Grid:-Run and Grid:-Launch because subsequent calls will use the number of active nodes left over from the previous call.
 • printer=procedure
 This option lets you specify a procedure for coordinating output from each node. The printer procedure will be called with a string every time there is a line of output available from an external computation. The printf command is the default if no custom procedure is supplied. The printer is called with a single argument, a string, that represents intermediate printed output from each of the nodes.
 • set={list,set}
 This option lets you specify some named values that should be pushed from the current session to the remote nodes. For example, set=[f,g] will cause f and g to be assigned in the compute nodes that are about to run the given command. This is synonymous with imports as used in the Grid:-Launch command. Note that there is no get option, the Grid:-Get command should be used for that instead.
 • uneval=truefalse
 This option controls whether fargs uses normal evaluation rules or not. The default uneval=false is to use normal evaluation rules, keeping in mind that the expression is processed twice -- once in the current environment, and once in the remote environment. For example, Run(f,[k]) will produce f(k) if k is not assigned anywhere.  If k=4 in the local environment and k=5 in the remote node, then Run(f,[k]) will produce f(4) no matter what k is assigned in the remote environment.  Using uneval quotes, Run(f,['k']) will cause 1-level of evaluation in the local environment turning 'k' into k, and the result will be f(5).  To get the symbol k, two levels of quoting is needed, Run(f,[''k'']).  The option, uneval=true, causes arguments with uneval quotes to be left alone during the local processing of fargs in the call to Run.  The remote nodes then process all arguments using normal rules.
 • wait=truefalse
 When this option is set to true, the Run command will block until all nodes relevant to the computation are finished.  When this option is set to false, the Run command will return immediately, while the nodes continue to operate in the background.  The default is wait=false when computing on just one node (presumably you would have just computed in the main thread if you wanted to wait for the result of just one node's work).  However, when running a job on all nodes, the default is wait=true.

Examples

It is best to leave this as the default, but for consistent example output, 4 compute nodes will be used (regardless of whether you have 4 cores)

 > $\mathrm{kernelopts}\left(\mathrm{numcpus}=4\right)$
 ${8}$ (1)
 > $\mathrm{Grid}:-\mathrm{Setup}\left(\mathrm{numnodes}=4\right)$

This example shows results from multi-node computations are returned in an array. When generating random numbers, use randomize() to set a random seed for the sequence of numbers to generate. Avoid this only for testing purposes when you want a repeatable sequence. Note that randomize needs to be called on all of the compute nodes, which is done here in the first statement.

 > $\mathrm{Grid}:-\mathrm{Run}\left(\mathrm{randomize}\right):$
 > $\mathrm{Grid}:-\mathrm{Run}\left(\mathrm{rand}\left(10..100\right)\right)$
 > $\mathrm{Grid}:-\mathrm{Run}\left(\mathrm{rand}\left(10..100\right),'\mathrm{firstarrayindex}'=1\right)$
 $\left[\begin{array}{cccc}{71}& {97}& {20}& {70}\end{array}\right]$ (2)

This example shows how to run two jobs in the background. The assignto option allows to capture the results into the local session. It is important to wait for the jobs to finish before using the results or starting new jobs on the same nodes.

 > $\mathrm{Grid}:-\mathrm{Run}\left(0,\mathrm{Optimization}:-\mathrm{NLPSolve},\left[\frac{\mathrm{sin}\left(x\right)}{x},x=1..30\right],'\mathrm{assignto}'='\mathrm{ans0}'\right)$
 > $\mathrm{Grid}:-\mathrm{Run}\left(1,\mathrm{Optimization}:-\mathrm{NLPSolve},\left[{x}^{3}+2xy-2{y}^{2},x=-10..10,y=-10..10,\mathrm{initialpoint}=\left\{x=3,y=4\right\},'\mathrm{maximize}'\right],'\mathrm{assignto}'='\mathrm{ans1}'\right)$
 > $\mathrm{Grid}:-\mathrm{Wait}\left(\right)$
 > $\mathrm{ans0}$
 $\left[{-0.0424796169776126}{,}\left[{x}{=}{23.5194525023235}\right]\right]$ (3)
 > $\mathrm{ans1}$
 $\left[{1050.}{,}\left[{x}{=}{10.}{,}{y}{=}{5.}\right]\right]$ (4)

This example will run four different jobs and wait for the first one to finish; then will terminate the others. Note the use of Grid:-Set to define the delay procedure on the remote nodes.

 > delay := proc( n, c )   local i;   for i from 1 to n do       printf("%c",c);       Threads:-Sleep(1);   od;   printf("\n");   c; end proc:
 > $\mathrm{Grid}:-\mathrm{Set}\left(\mathrm{delay}\right):$
 > $\mathrm{Grid}:-\mathrm{Run}\left(0,\mathrm{delay},\left[15,"0"\right]\right)$
 > $\mathrm{Grid}:-\mathrm{Run}\left(1,\mathrm{delay},\left[3,"1"\right]\right)$
 > $\mathrm{Grid}:-\mathrm{Run}\left(2,\mathrm{delay},\left[16,"2"\right]\right)$
 > $\mathrm{Grid}:-\mathrm{Run}\left(3,\mathrm{delay},\left[9,"3"\right]\right):$
 > $n≔\mathrm{Grid}:-\mathrm{WaitForFirst}\left(\right)$
 ${n}{≔}{0}$ (5)
 > $\mathrm{Grid}:-\mathrm{Interrupt}\left(\right)$
 > $\mathrm{Grid}:-\mathrm{Wait}\left(\right)$
 > $\mathrm{Grid}:-\mathrm{GetLastResult}\left(n\right)$

This example shows how to set state before running a computation, and notes that uneval quoting must consider both local and remote processing of arguments.

 > $\mathrm{Grid}:-\mathrm{Set}\left(0,'x'=\mathrm{x_node0}\right)$
 > $\mathrm{Grid}:-\mathrm{Set}\left(1,'x'=\mathrm{x_node1}\right)$
 > $x≔\mathrm{x_local}$
 ${x}{≔}{\mathrm{x_local}}$ (6)
 > $\mathrm{Grid}:-\mathrm{Run}\left(f,\left[x\right]\right)$
 > $\mathrm{Grid}:-\mathrm{Run}\left(f,\left['x'\right]\right)$
 > $\mathrm{Grid}:-\mathrm{Run}\left(f,\left[''x''\right]\right)$
 > $\mathrm{Grid}:-\mathrm{Run}\left(0,\mathrm{print},\left['x'\right],'\mathrm{wait}'\right)$
 x_node0

This example displays a message including the current clock time before, during, and after running jobs on all nodes.

 > show_time := proc( msg := "" )     local t := time[current]();     printf("node=%d current-time=%s.%d: %s\n",        Grid:-MyNode(),        StringTools:-FormatTime("%I:%M:%S",timestamp=trunc(t)),           trunc(10^6*(t - trunc(t))),        msg); end proc:
 > $\mathrm{show_time}\left("initialize"\right)$
 node=-1 current-time=11:26:40.626143: initialize
 > $\mathrm{Grid}:-\mathrm{Set}\left(\mathrm{show_time}\right)$
 > $\mathrm{Grid}:-\mathrm{Run}\left(\mathrm{show_time},\left["worker"\right],'\mathrm{wait}'=\mathrm{true}\right)$
 node=0 current-time=11:26:40.691038: worker node=2 current-time=11:26:40.698353: worker node=1 current-time=11:26:40.697357: worker node=3 current-time=11:26:40.699002: worker
 > $\mathrm{show_time}\left("done"\right)$
 node=-1 current-time=11:26:40.710445: done

Compatibility

 • The Grid[Run] command was introduced in Maple 2015.