My project, Parallel Mathematica Environment on the RaspberryPi using OOP, is a sample application of Object Oriented Programming for the Mathematica cluster computing, implemented with a Mac and three RaspberryPi Zero connected with a USB hub and three USB cables.
Basic idea is to deploy a constructed instance image to calculating servers (RaspberryPi) and send messages to the instance. OOP on the Mathematica is already developed and shown in this community, and further detail is shown on slidesshare titled of “OOP for Mathematica.”
Preparing for RaspberryPi Zero is as follows using SSH connection from a Mac,
-
naming each Zero as raspberypi,raspberrypi1,raspberrypi2,…
-
set the server program “init” to each RaspberryPi, init is,
$ cat init While[True, Run[nc -l 8000>input]; temp=ReleaseHold[<<input]; temp >>output; Run[nc your-mac-hostname.local 8002<output] ]
where, socket numbers must be identical.
-
Run Mathematica manually, and wait the booting Mathematica up.
$ wolfram <init&
Checking each RaspberryPi is useful as,
$ nc -l 8002 >output|nc raspberrypi.local 8000 <<EOF
> 10!
> EOF
$ cat output
3628800
Cluster controller program on a Mac is,
-
set directory
SetDirectory[NotebookDirectory[]]; -
setup socket communication process
com1="nc -l 8002 >output1 |nc raspberrypi.local 8000 <input1"; com2="nc -l 9002 >output2 |nc raspberrypi1.local 9000 <input2"; com3="nc -l 9502 >output3 |nc raspberrypi2.local 9500 <input3"; -
set object property
obj={ <|"name"->node1,"comm"->com1,"in"->"input1","out"->"output1","p"->{2000,3500}|>, <|"name"->node2,"comm"->com2,"in"->"input2","out"->"output2","p"->{3501,4000}|>, <|"name"->node3,"comm"->com3,"in"->"input3","out"->"output3","p"->{4000,4500}|>}; -
define calculation server class, where is a sample Mersenne prime number calculation
new[nam_]:=Module[{ps,pe}, mersenneQ[n_]:=PrimeQ[2^n-1]; setv[nam[{s_,e_}]]^:={ps,pe}={s,e}; calc[nam]^:=Select[Range[ps,pe],mersenneQ] ]; -
construct instances
Map[new[#name]&,obj]; -
deploy instances to calculation servers
Map[Save[#in,#name]&,obj]; Map[Run[#comm]&,obj]; -
send message to each instance
Map[Put[Hold@setv[#name[#p]],#in]&,obj]; Map[Run[#comm]&,obj]; -
start calculation
Map[Put[Hold@calc[#name],#in]&,obj]; proc=Map[StartProcess[{$SystemShell,"-c",#comm}]&,obj] -
wait for the process termination (mannualy in this sample code)
Map[ProcessStatus[#]&,proc] {Finished,Finished,Finished} -
gather the results
Map[FilePrint[#out]&,obj]; {2203, 2281, 3217} {} {4253, 4423}
