Monday, November 28, 2011

Compiling MPI.NET under Ubuntu Oneiric

I recently wanted to experiment with parallel programming and - since my language of choice is C# - thought it might be interesting to try out using Message Passing.  There are two main libraries available: The Message Passing API (MPAPI) and MPI.NET.  MPAPI provides an independent framework (that does not rely on the Message Passing Interface (MPI) or MPI-2 standards), while MPI.NET provides low-level bindings to the MPI-2 standard directly.

I have done some previous work with MPAPI and found it to be a capable framework that I would highly recommend.  However, that initial choice was because I had significant difficulty compiling MPI.NET under Ubuntu.  I've since resolve those difficulties, so today we will discuss building MPI.NET under Ubuntu (Oneiric).

Step 1: Download MPI.NET version 1.0.0 from the MPI.NET download page.  You want the package (source code for Unix).

Step 2: Untar the files and enter the directory:
tar xzvf
Step 3: Install build prerequisites
sudo apt-get install mono-complete libtool automake autoconf build-essential
Step 4: Install an MPI framework

This is subject to some choice.  Two good libraries are OpenMPI and MPICH2 which you can install through apt get via one of (do not execute both) of the following commands:
sudo apt-get install libopenmpi-dev openmpi-bin openmpi-doc
sudo apt-get install mpich2 libmpich2-dev
 Step 5: Create a symbolic link from /usr/bin/ilasm to /usr/bin/ilasm2.  For some reason that is not clear to me MPI.NET looks for ilasm2 which is not present (wrapped into ilasm?) in later versions of Mono.
ln -s /usr/bin/ilasm /usr/bin/ilasm2
Step 6: Download and install patches

Several source files need to be patched to allow successful compilation (see this helpful mailing list posting).  Download,, and from this repository.  Save them in the directory.

Apply the patches with the following three commands:
patch <
patch MPI/ <
patch MPI/ <
These should all complete successfully.  If not, check the exact filename you used when you saved the patch.  Rename them (or modify the above three commands), as appropriate.

Step 7: Run the standard compilation sequence.  Everything should complete successfully:
make install
The desired MPI.dll and MPI.dll.config is in the MPI subdirectory of the

Step 8: Try creating a hello world program to verify MPI.NET works.

In a new folder, create a source file (Hello.cs) containing a Hello World program similar to the one shown in the MPI.NET tutorial, such as:

using System;
using MPI;

class MPIHello
    static void Main(string[] args)
        using (new MPI.Environment(ref args))
           Console.Write("Greetings from node {0} of {1}\n",

Copy MPI.dll and MPI.dll.config to this folder and compile under mono:
gmcs Hello.cs -reference:MPI.dll - target:exe -out:Hello.exe
Compilation should succeed without errors or warnings.

Run the resultant program using mpiexec to launch four threads:
mpiexec -np 4 ./Hello.exe
 If the resultant output is (the order of lines may vary), then everything is working as expected:
Greetings from node 0 of 4
Greetings from node 2 of 4
Greetings from node 1 of 4
Greetings from node 4 of 4
If all this worked, you should now have a working installation of MPI.NET and can use the MPI-2 framework to write parallel and distributed programs.

Further reading


  1. This comment has been removed by the author.

  2. I've compiled MPI.NET in a laptop with Ubuntu 10.04 LTS, all worked well. Then I tried to do the same in a cluster with Suse and powerpc64 processors, the configure script gave me no error. Nevertheless doing make I obtained the following error message:

    Making all in MPIUtils
    make[1]: Entering directory `/gpfs/home/ULP010/jmedina/'
    make[1]: Nothing to be done for `all'.
    make[1]: Leaving directory `/gpfs/home/ULP010/jmedina/'
    Making all in MPI
    make[1]: Entering directory `/gpfs/home/ULP010/jmedina/'
    if /bin/sh ../libtool --tag=CC --tag=CC --mode=compile mpicc -DPACKAGE_NAME=\"MPI.NET\" -DPACKAGE_TARNAME=\"mpi-net\" -DPACKAGE_VERSION=\"0.6.0\" -DPACKAGE_STRING=\"MPI.NET\ 0.6.0\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"mpi-net\" -DVERSION=\"0.6.0\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DHAVE_MPI=1 -I. -I. -g -O2 -MT cbridge.lo -MD -MP -MF ".deps/cbridge.Tpo" -c -o cbridge.lo cbridge.c; \
    then mv -f ".deps/cbridge.Tpo" ".deps/cbridge.Plo"; else rm -f ".deps/cbridge.Tpo"; exit 1; fi
    xlc_r: 1501-218 (W) file 0.6.0" contains an incorrect file suffix
    xlc_r: 1501-228 (W) input file 0.6.0" not found
    xlc_r: 1501-208 (S) command option D is missing a subargument
    make[1]: *** [cbridge.lo] Error 1
    make[1]: Leaving directory `/gpfs/home/ULP010/jmedina/'
    make: *** [all-recursive] Error 1

    with gcc as mpicc choice the result was the same.
    has someone a hint about the reason of this error?


    Juan S.

  3. I'm not entirely sure. Does "sh" completely successfully in step 7?

  4. Sorry by the delay, I was busy in another task.

    Apparently, "sh" works without any warning, indeed the output is:

    --> Running aclocal
    --> autoheader not needed
    --> Running autoconf
    --> Running libtoolize
    --> Running automake

    and nothing else, as far as I remember is the same answer I got from my laptop using Ubuntu.


    Juan S.

  5. Really appreciate you post on this, wish I saw this littler earlier before compiling everything by hand :/

    Anyway, I ran into one issue. When I do mpiexec (say with two processes)with the simplest HelloWorld kind of program shown above, I see two outputs but they are independent copies and they both see world size as 1 instead of 2. Any thoughts on this?


  6. Update on my comment. I got it resolved by going with OpenMPI.

  7. I am using CentOS 7 with openMPI.
    I have some error to install

    I apply the patches with the following three commands:

    patch MPI/ <

    Downloaded this patch from --->

    After configuring, I do write make command.

    In this section we have error :

    CustomUnsafe.cs(112,41): error CS1525: Unexpected symbol `;'
    CustomUnsafe.cs(3238,12): error CS1525: Unexpected symbol `switch'
    CustomUnsafe.cs(3240,16): error CS1525: Unexpected symbol `case'
    CustomUnsafe.cs(3287,1): error CS8025: Parsing error
    Compilation failed: 4 error(s), 0 warnings

    Please help me, how to fix it.