|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
IntroductionPure .NET MPI is a completely managed implementation of MPI. The object-oriented API is powerful, yet easy to use for parallel programming. It has been developed based on .NET Framework 3.0 and ported to 3.5 using much of Windows Communication Foundation (WCF). With the help of WCF, you can use the configuration file to declare the number of process that you are using, which process is the master process, and the locations of the process on your network as IP Addresses and ports. What is most fantastic in Pure MPI .NET is that you can lauch all your parallel programs as threads in one single process for debugging and testing issues. Background.NET implemenation of Message Passing Interface (standard 2.0)
Using the codeThis example draws MandelBrot set using more than one process. The attachments constitute of 3 different projects: 1- The Interface that draws MandelBrot Set 2- The MPI program 3- The library containing the marshaled objects. The interface can work in sequential mode and in parallel mode. When working in parallel mode, the interface will launch the MPI-enabled processes to calculate the MandelBrot Set and will use .NET remoting to collect the result from the master process as follows: TcpChannel channel = new TcpChannel(8090); ChannelServices.RegisterChannel(channel, false) RemotingConfiguration.RegisterWellKnownServiceType(typeof(Points), "MandelBrot", WellKnownObjectMode.SingleCall); Cache.Attach(observer); The following is the implementation of the master process: Console.WriteLine("Master Process: Working..."); int row = 0; for (int i = 1; i < comm.Size; i++) { comm.Send<int>(i, "ROW_NUMBER", row); row += processIncrement; } ArrayList list = new ArrayList(); int max = (int)Math.Floor((double)width * height / partition) + 1; for (int i = 0; i <= max; i++) { ArrayList partList = comm.Receive<ArrayList>(Constants.AnySource, "RESULT"); if (partList != null) list.AddRange(partList); } Points points; TcpChannel chan = new TcpChannel(); ChannelServices.RegisterChannel(chan, false); points = (Points)Activator.GetObject(typeof(Points), "tcp://localhost:8090/MandelBrot"); points.SetMessage(list); Console.WriteLine("Finished Calculating: " + list.Count + " points.");The following is the implementation of the slave process: Console.WriteLine("Slave Process: " + comm.Rank + ".Working..."); int row = comm.Receive<int>(0, "ROW_NUMBER"); decimal scaleX = (maxNumber.Real - minNumber.Real) / width; decimal scaleY = (maxNumber.Imaginary - minNumber.Imaginary) / height; ComplexNumber c = new ComplexNumber(); ArrayList list = new ArrayList(); c.Real = minNumber.Real; for (int x = 0; x < width; x++) { c.Imaginary = minNumber.Imaginary + row * scaleY; for (int y = row; y < (row + processIncrement); y++) { int count = CalculatePixel(c); PointSet set = new PointSet(); set.W = x; set.H = y; set.Pixel = count; list.Add(set); c.Imaginary += scaleY; if (list.Count == partition) { comm.Send<ArrayList>(0, "RESULT", list); list.Clear(); } } c.Real += scaleX; } if (list.Count > 0) { comm.Send<ArrayList>(0, "RESULT", list); } Console.WriteLine("Done");The configuration file should be set as necessary to determine the number of processes and where the processes will launch.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||