Message Boards Message Boards

Parallel Computing and Object Oriented Programming - Part 1

Posted 5 years ago

See Part 2 here: https://community.wolfram.com/groups/-/m/t/1851278

Wolfram language includes Parallel Computing Tools and the parallel computing is a first step of high-performance computing. A combination of the Parallel Computing Tools and Object Oriented Programming, here after OOP, introduces a new view for the Wolfram language programming. Up to now author had introduced a OOP system for Wolfram language, and now shows an example of OOP based parallel computing.

OOP suits well with the parallel computation because the Instance is basically independent calculation unit and you can find that the same code can apply for both parallel and mono kernel environment.

Part 1 is concerning to the calculation with one instance on one local kernel and the method is explained by an example of Mersenne number calculation. Followings are the Wolfram code steps and you can see first that OOP is composed of basic functions.

step 1; startup local kernels

CloseKernels[];
LaunchKernels[];
kernelList = ParallelEvaluate[$KernelID]

step 2; definition of parallel class using instance preceded method

 mq[nam_] := Module[{ins, ine},
     nam[set[{ns_, ne_}]] := {ins, ine} = {ns, ne};
   go[] := Select[Range[ins, ine], PrimeQ[2^# - 1] &]
      ];

step 3; definition of object properties with the association list supposing the local kernel number is 4.

object = {
   Association["name" -> Unique[k], "range" -> {9000, 9399}, 
    "kernel" -> kernelList[[1]]],
   Association["name" -> Unique[k], "range" -> {9400, 9699}, 
    "kernel" -> kernelList[[2]]],
   Association["name" -> Unique[k], "range" -> {9700, 9899}, 
    "kernel" -> kernelList[[3]]],
   Association["name" -> Unique[k], "range" -> {9900, 10000}, 
    "kernel" -> kernelList[[4]]
    ]};

step 4; using the association list, we will construct instances, then set parameters for each instance.

Map[ParallelEvaluate[mq[#name], #kernel] &, object];
Map[ParallelEvaluate[#name[set[#range]], #kernel] &, object]

step 5; execute parallel calculation (this case used Mac 3.4 GHz Intel Core i5)

ts = SessionTime[];
ans = ParallelEvaluate[go[]];
{SessionTime[] - ts, ans}

result is

{10.542539, {{}, {9689}, {}, {9941}}}

To evaluate the result we can compare with a mono-kernel computation.

mq[mono];
mono[set[{9000, 10000}]];

ts = SessionTime[];
ans = go[];
{SessionTime[] - ts, ans}

result is

{30.087534, {9689, 9941}}

The parallel computation with 4 local kernels get about 3 times faster than the mono kernel calculation.

Enjoy OOP for Wolfram language.

7 Replies
Posted 3 years ago

Thanks for your help! It is solved, and the speed truly improved! I think the OOP would be a great way to support my research.

POSTED BY: Tony Coliderse

Dear Tony

Please change OOP to,

case[nam_] := 
 Module[{begin, end}, 
  nam[set[{be_, en_}]] := {begin, end} = {be, en};
  sol = NDSolve[{y'[x] == Sin[x^2 + 2 x]/(2 Cos[x/2 + 3 x] + 3), 
     y[0] == 0}, y, {x, 0, 500}, MaxSteps -> 10^6, AccuracyGoal -> 30];
  go[] := Table[{x, y[x] /. sol[[1]]}, {x, begin, end, 0.01}]
  ]

object = {Association["name" -> Unique[k], "range" -> {0, 125}, 
    "kernel" -> kernelList[[1]]], 
   Association["name" -> Unique[k], "range" -> {125, 250}, 
    "kernel" -> kernelList[[2]]], 
   Association["name" -> Unique[k], "range" -> {250, 375}, 
    "kernel" -> kernelList[[3]]], 
   Association["name" -> Unique[k], "range" -> {375, 500}, 
    "kernel" -> kernelList[[4]]]};

Map[ParallelEvaluate[case[#name], #kernel] &, object];
Map[ParallelEvaluate[#name[set[#range]], #kernel] &, object];

Then, execute as,

enter codin1 = SessionTime[]
para1 = ParallelEvaluate[go[]];
SessionTime[] - in1e here

ListPlot[para1]

In the Mathematica parallel calculation style, it should be avoided much communication between controller and nodes. From this point of view, NDSolve should be evaluated on each node.

Posted 4 years ago

Dear Hirokazu Kobayashi: I'm a Dr. student in theoritical physics, and recently i'm doing some numerical calculation so I'm trying to use parallel evaluate in Mathematica. Your instance is quite good, but I'm still confusing about it.(I'm green hand abou it.) Could the OOP method be used in NDSolve function? Hope you can give me a favor and show some instance. Thanks a lot!

POSTED BY: Tony Coliderse

Hi Tony ! Thanks your reply. NDSolve can be used in the OOP as in my report, "Chaos bifurcation of double pendulums calculation with OOP":

https://community.wolfram.com/groups/-/m/t/1109273

In this example, OOP will run on a single core, however, you can run the program on independent core individually. If you can use standard Mathematica, 8 core Mathematica OOPed program will run simultaneously. Regards.

Posted 4 years ago

Thanks for your reply! I"ll carefully read it. By the way I wonder if there is some detailed intruduction about OOP method?

POSTED BY: Tony Coliderse
Posted 3 years ago

Dear Hirokazu Kobayashi,

After studying the post about the OOP method, I tried use it to solve differential equation, but I met another problem. When I solved a differential equation numerically, I want to export some data about the solution, and I found use the OOP would be slow more than directly use Table[] function, I don't know if I did wrong, the porceding is:

1:

In[1]:= sol = 
 NDSolve[{y'[x] == Sin[x^2 + 2 x]/(2 Cos[x/2 + 3 x] + 3), y[0] == 0}, 
  y, {x, 0, 500}, MaxSteps -> 10^6, AccuracyGoal -> 30]

Out[1]= {{y -> InterpolatingFunction[{{0., 500.}}, <>]}}

2:use the OOP

LaunchKernels[];

kernelList = ParallelEvaluate[$KernelID];

case[nam_] := Module[{begin, end},
  nam[set[{be_, en_}]] := {begin, end} = {be, en};
  go[] := Table[{x, y[x] /. sol[[1]]}, {x, begin, end, 0.01}];
  ]

object = {
   Association["name" -> Unique[k], "range" -> {0, 125}, 
    "kernel" -> kernelList[[1]]],
   Association["name" -> Unique[k], "range" -> {125, 250}, 
    "kernel" -> kernelList[[2]]],
   Association["name" -> Unique[k], "range" -> {250, 375}, 
    "kernel" -> kernelList[[3]]],
   Association["name" -> Unique[k], "range" -> {375, 500}, 
    "kernel" -> kernelList[[4]]]
   };

Map[ParallelEvaluate[case[#name], #kernel] &, object];
Map[ParallelEvaluate[#name[set[#range]], #kernel] &, object];

3: comparing the time

In[8]:= in1 = SessionTime[]
para1 = ParallelEvaluate[go[]];
SessionTime[] - in1

Out[8]= 406.966900

Out[10]= 50.845088

In[11]:= in2 = SessionTime[]
para2 = Table[{x, y[x] /. sol[[1]]}, {x, 0, 500, 0.01}];
SessionTime[] - in2

Out[11]= 457.863461

Out[13]= 0.108939

I don't know if I used the method incorrectly? If the OOP can solve the problem that will be a great improvment for my work! Thanks!

POSTED BY: Tony Coliderse

enter image description here -- you have earned Featured Contributor Badge enter image description here

Your exceptional post has been selected for our editorial column Staff Picks http://wolfr.am/StaffPicks and Your Profile is now distinguished by a Featured Contributor Badge and is displayed on the Featured Contributor Board. Thank you, keep it coming, and consider contributing to the The Notebook Archive!

POSTED BY: EDITORIAL BOARD
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract