Grid Computing - Maple Programming Help

Online Help

All Products    Maple    MapleSim


Home : Support : Online Help : System : Information : Updates : Maple 2015 : updates/Maple2015/Grid

Grid Computing

The Grid package contains methods for multiprocess parallel execution. Unlimited same-machine parallel execution is built-into Maple 2015. You can spawn as many parallel processes as you want without requiring any additional toolbox or licensing.

 

Maple 2015 makes it even easier to initiate parallel jobs with new commands that abstract away MPI-like message passing protocols. The result is a very simple and intuitive interface for running commands and dealing with data.

 

 

New Commands: Run, Set, Get, GetLastResult, Wait, WaitForFirst

Improvements to Grid:-Map and Grid:-Seq

time[current]

New Commands: Run, Set, Get, GetLastResult, Wait, WaitForFirst

withGrid;

Barrier,Get,GetLastResult,Interrupt,Launch,Map,MyNode,NumNodes,Receive,Run,Send,Seq,Server,Set,Setup,Status,Wait,WaitForFirst

(1.1)

The key new command, Grid:-Run, lets you spawn asynchronous jobs on individual nodes. This means:

• 

no need to wait for the result

• 

can be used with 1 or more nodes

• 

when all nodes are used, Run implicitly waits, and returns individual node results

• 

usually does not require Send and Receive

Example: Background Jobs

This example shows how to run two jobs in the background. The assignto option allows you to capture the results in 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.

Grid:-Run0,Optimization:-NLPSolve,sinxx,x=1..30,'assignto'='ans0'

Grid:-Run1,Optimization:-NLPSolve,x3+2xy2y2,x=10..10,y=10..10,initialpoint=x=3,y=4,'maximize','assignto'='ans1'

Grid:-Wait

ans0

0.0424796169776126,x=23.5194525023235

(1.1.1)

ans1

1050.,x=10.,y=5.

(1.1.2)

These same commands could have been run in serial as shown later. Using the Run command with two computations as above lets you run both commands at the same time. The first command does not need to finish before the second one can start. Running two commands in parallel can cut your execution time in half. Run many jobs to achieve even greater performance improvements compared to sequential jobs.  

Optimization:-NLPSolve sinxx,x=1..30;

0.0424796169776126,x=23.5194525023235

(1.1.3)

Optimization:-NLPSolve x3+2xy2y2,x=10..10,y=10..10,initialpoint=x=3,y=4,'maximize' ;

1050.,x=10.,y=5.

(1.1.4)

Example: Results from All Nodes

This example shows results from multi-node computations can be returned in an array. Note that the Grid:-Set command is used to assign values from the current session into the worker nodes. In this case, the work procedure is defined locally, and therefore not known to the parallel processes until the Set command is applied.

work  proc       randomize;       catnode , Grid:-MyNode, computed , rand1..10 ; end:

Grid:-Setwork;

R  Grid:-Runwork

R:=Array0..3,0=node 0 computed 9,1=node 1 computed 10,2=node 2 computed 5,3=node 3 computed 8

(1.2.1)

R0;

node 0 computed 9

(1.2.2)

R1;

node 1 computed 10

(1.2.3)

R2;

node 2 computed 5

(1.2.4)

R3;

node 3 computed 8

(1.2.5)

A 4-core machine will automatically spawn 4 jobs when no target node is specified as the first parameter to Run. All results will be returned in an array with result at the corresponding node number.

Example: Competition - First-to-Finish Wins

This example will run 4 different jobs and only wait for the first one to finish; then will terminate the others. As mentioned earlier, note the use of Grid:-Set to define the delay procedure on the remote nodes.

method0  proc   Threads:-Sleep15:    result of method 0; end: Grid:-Set0,method0;

method1  proc    Threads:-Sleep13:    result of method 1; end: Grid:-Set1,method1;

method2  proc    Threads:-Sleep3:    result of method 2; end: Grid:-Set2,method2;

method3  proc   Threads:-Sleep9:    result of method 3; end: Grid:-Set3,method3;

Grid:-Run0,method0;Grid:-Run1,method1;Grid:-Run2,method2;Grid:-Run3,method3; 

n:=Grid:-WaitForFirst

n:=2

(1.3.1)

Grid:-Interrupt

Grid:-Wait

Grid:-GetLastResultn

result of method 2

(1.3.2)

The Grid:-WaitForFirst command will return the node number of the first node to finish computing. The Grid:-GetLastResult can then be used to fetch whatever value was last computed on that node. If that computed result had a name, the Get command could also be used to fetch the value.

Improvements to Grid:-Map and Grid:-Seq

Grid:-Map and Grid:-Seq have been re-implemented using Grid:-Run. This means:

• 

less overhead spawning processes

• 

better division of work

• 

optional tasksize parameter

tasksize

In this example, the work can be unevenly divided. The sequence of heavy computations at the end of the list is may require an adjustment to the default tasksize

data  seq5^mini,10,i=1..12;

data:=5,25,125,625,3125,15625,78125,390625,1953125,9765625,9765625,9765625

(2.1.1)

timereal Grid:-Mapprocn printfnode %d computing %d\n,Grid:-MyNode,n; addi,i=1..n; end proc, data ;

node 2 computing 78125
node 1 computing 625

node 3 computing 9765625
node 0 computing 5
node 0 computing 25
node 1 computing 3125
node 0 computing 125
node 1 computing 15625
node 2 computing 390625
node 2 computing 1953125

node 3 computing 9765625

node 3 computing 9765625

2.312

(2.1.2)

With only a few numbers in the computation, the default is to divide the operation into equal portions. Node 0 gets the first three data points, node 1 gets the next three, and so on. Because, in this case, the work is unevenly distributed, node 3 ends up computing the three hardest cases and becomes the bottleneck.  

To optimize the timing on this kind of example, you can set a smaller tasksize. With tasksize=1, the algorithm will split the data into chunks of 1 element (instead of 3-elements in the previous example). There are 12 tasks but only 4 compute nodes. Each node will finish one task before asking for another.  

 

timereal Grid:-Maptasksize=1procn printfnode %d computing %d\n,Grid:-MyNode,n; addi,i=1..n; end proc, data ;

node 0 computing 5

node 1 computing 25
node 3 computing 625
node 2 computing 125
node 0 computing 3125
node 1 computing 15625
node 2 computing 78125
node 3 computing 390625
node 0 computing 1953125
node 1 computing 9765625
node 2 computing 9765625
node 3 computing 9765625

1.609

(2.1.3)

time[current]

A new option to the time() command allows fine-grained, sub-second measurement of the current time, which can be useful when comparing execution in different processes.

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:

Grid:-Setshow_time

show_timeinitializeGrid:-Runshow_time,worker,'wait'=true:show_timedone

node=0 current-time=02:32:11.781000: initialize

node=0 current-time=02:32:11.781000: worker
node=1 current-time=02:32:11.781000: worker
node=2 current-time=02:32:11.781000: worker
node=3 current-time=02:32:11.797000: worker
node=0 current-time=02:32:11.797000: done