Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / Windows Forms
Article

Implementing parallel programming using MPI and C#

Rate me:
Please Sign up or sign in to vote.
3.87/5 (18 votes)
15 Apr 2008CPOL2 min read 90.1K   3K   38   9
An example of implementing a parallel program using the pure MPI .NET library, C#, and .NET Remoting.

Introduction

Pure .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 the .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 launch all your parallel programs as threads in one single process for debugging and testing issues.

Background

The .NET implementation of the Message Passing Interface (standard 2.0):

  • Built on Windows Communication Foundation (WCF).
  • Single process F5 experience for debugging and development.
  • Multi-threaded, multi-process, or multi-machine execution, and any combination there in.
  • MPI processors can run inside one process, or any number of processes on any number of machines.
  • Type-safe API.
  • x86, x64, and Itanium support.
  • Extensible. Supports existing and custom WCF bindings and channels. Adds higher level and custom synchronization mechanisms to communication objects.
  • Supports communication timeouts for deadlock detection and better error handling.
  • Environment and WCF settings completely configurable.

Using the code

This example draws a MandelBrot set using more than one process.

The attachments constitute of three different projects:

  1. The interface that draws the 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:

C#
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:

C#
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:

C#
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Integrated Digital Systems - IDS
Lebanon Lebanon
Been programming since 2001 interested in finance, security, workflows, SharePoint and algorithms. He is an MCSD, MCDBA, MCAD, MCSD, (again), MCTS, MCPD and MCT.
My Blog: www.alihamdar.com

Comments and Discussions

 
Questionhow to do use MPI command Pin
Member 115554542-May-15 19:18
Member 115554542-May-15 19:18 
QuestionHas anyone a solution for the problem? Pin
Lycopsis18-Jan-12 10:58
Lycopsis18-Jan-12 10:58 
GeneralMy vote of 2 Pin
pasondag23-Nov-10 9:20
pasondag23-Nov-10 9:20 
GeneralCrashes for me Pin
sam.hill15-Apr-08 15:21
sam.hill15-Apr-08 15:21 
GeneralRe: Crashes for me Pin
lhfiedler21-Apr-08 23:06
lhfiedler21-Apr-08 23:06 
GeneralRe: Crashes for me Pin
User 176853613-Jun-08 2:40
User 176853613-Jun-08 2:40 
GeneralRe: Crashes for me Pin
lhfiedler7-Jul-08 8:35
lhfiedler7-Jul-08 8:35 
GeneralRe: Crashes for me Pin
Dmitri Nеstеruk6-Jul-08 4:10
Dmitri Nеstеruk6-Jul-08 4:10 
GeneralRe: Crashes for me [modified] Pin
titan6810-Dec-09 7:35
titan6810-Dec-09 7:35 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.