Open MPI logo

Open MPI User's Mailing List Archives

  |   Home   |   Support   |   FAQ   |   all Open MPI User's mailing list

Subject: Re: [OMPI users] Multi-program between Java and C/Fortran...
From: Andre Dozier (hambre_at_[hidden])
Date: 2013-07-22 12:13:48


I never got mpiJava to stop freezing at the MPI calls when trying to
talk to a program written in C (most likely because I don't understand
mpiJava). So, I wrapped simple openmpi commands (written in C) with Java
using JNA that only implemented some simple MPI commands... I am now
able to see Java and C talk to each other. I am interested still to hear
if anybody has suggestions on how to make a Java program communicate
with a C/Fortran program via mpiJava. Regardless, for anybody
interested, the code below shows what I got working (make sure
jna-4.0.0.jar is in the same folder as these files before you run
jumptest.sh):

**IJump.java:
import com.sun.jna.Library;
import com.sun.jna.Pointer;

public interface IJump extends Library
{
     void Init(int argslength, String[] args);
     int WorldRank();
     int WorldSize();
     void Finalize();

     void SendInt(int[] buf, int length, int receiver, int tag);

     void RecvInt(int[] buf, int length, int receiver, int tag);
}

**Jump.java:
import com.sun.jna.Native;

public class Jump
{
     private static IJump _lib = (IJump) Native.loadLibrary("jump",
IJump.class);

     public static void main(String args[])
     {
     try
         {
         _lib.Init(args.length, args);

         int rank = _lib.WorldRank();
         int size = _lib.WorldSize();
         int sender = 0;

         int offset = 0, cnt = 1;
         int[] buf = new int[cnt];

         if (rank == sender)
             {
             int recvr = 0;
             for (int i = 1; i < size; i++)
                 {
                 if (recvr == sender)
                     recvr++;
                 buf[0] = recvr;
                 System.out.print("Java program is sending " + recvr +
"\n");
                 _lib.SendInt(buf, cnt, recvr, 0);
                 recvr++;
                 }
             }
         else
             {
             System.out.print("Java program is waiting at " + rank + "\n");
             _lib.RecvInt(buf, cnt, sender, 0);
             }
         System.out.print("Java program received " + buf[0] + " at " +
rank + "\n");
         }
     catch (Exception e)
         {
             e.printStackTrace();
         }
     finally
         {
         try
             {
             _lib.Finalize();
             }
         catch(Exception ex)
             {
             ex.printStackTrace();
             }
         }
     }
}

**jump.c:
#include "mpi.h"
#include <string.h>

void Init(int argc, char *argv[])
{
   MPI_Init(&argc, &argv);
}

int WorldRank()
{
   int rank;
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   return rank;
}

int WorldSize()
{
   int size;
   MPI_Comm_size(MPI_COMM_WORLD, &size);
   return size;
}

void Finalize()
{
   MPI_Finalize();
}

void SendInt(int *buf, int length, int receiver, int tag)
{
   MPI_Send(buf, length, MPI_INT, receiver, tag, MPI_COMM_WORLD);
}

void RecvInt(int *buf, int length, int receiver, int tag)
{
   MPI_Status status;
   MPI_Recv(buf, length, MPI_INT, receiver, tag, MPI_COMM_WORLD, &status);
}

**interop.c:
#include "mpi.h"
#include <string.h>

int main(int argc, char *argv[])
{
   int rank, size;
   int i, bsize;
   MPI_Status status;
   int scatter = 0;
   int sender = 0;

   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD, &rank);
   MPI_Comm_size(MPI_COMM_WORLD, &size);

   for (i = 0; i < argc; i++)
     {
       if (strncmp(argv[i], "-scatter", 8) == 0)
     {
       scatter = 1;
       break;
     }
     }

   bsize = 1;
   int buf[bsize];
   if (scatter)
     {
       int sbuf[size];
       if (rank == sender)
     {
       printf("Scattering at %d\n", sender);
       for (i = 0; i < size; i++)
           sbuf[i] = i;
     }
       else
     printf("Waiting at %d\n", rank);
       MPI_Scatter(&sbuf, 1, MPI_INT32_T, &buf, 1, MPI_INT32_T, sender,
MPI_COMM_WORLD);
     }
   else
     {
       if (rank == sender)
     {
       int recvr = 0;
       for (i = 1; i < size; i++)
         {
           if (recvr == sender)
         recvr++;
           buf[0] = recvr;
           printf("C program is sending %d\n", buf[0]);
           MPI_Send(&buf, 1, MPI_INT32_T, i, 0, MPI_COMM_WORLD);
           recvr++;
         }
     }
       else
     {
       printf("C program is waiting at %d\n", rank);
       MPI_Recv(&buf, 1, MPI_INT32_T, sender, 0, MPI_COMM_WORLD, &status);
     }
     }
   printf("C program received %d at %d\n", buf[0], rank);

   MPI_Finalize();
   return 0;
}

**java2c.app:
-np 1 java -jar ./Jump.jar a e io u r mine
-np 3 interop

**c2java.app:
-np 1 interop
-np 3 java -jar ./Jump.jar a e io u r mine

**Makefile:
# Created by: Andre Dozier
# Date : July 16, 2013
# Purpose : Creates two programs to test the legacy model integration
tool with various different types of interaction
#

CC = mpicc
JCC = javac
MPIJCC = mpijavac
LIB = /usr/local/lib
JNA = ./jna-4.0.0.jar

all: interop jump JumpJava

interop: interop.c
     $(CC) -o interop interop.c

jump: jump.c
     $(CC) -fPIC -shared -o libjump.so jump.c

JumpJava: Jump.java
     $(JCC) -cp .:$(JNA) Jump.java IJump.java

**jumptest.sh:
BASEDIR=$(dirname $0)
cd $BASEDIR

echo
echo Finding source files...
find -name "*.java" > sources.txt
echo
echo Compiling code...
make -B
jar xf jna-4.0.0.jar
# javac -cp $HOME/extras/jna-4.0.0.jar:. @sources.txt
echo
echo Packaging code into Jar files...
echo Main-Class: Jump > manifest.txt
jar cfm Jump.jar manifest.txt IJump.class Jump.class libjump.so com
echo
echo Removing temporary files...
rm sources.txt manifest.txt
rm -rf com META-INF
find -name "*.class" | xargs rm -rf

echo
echo Testing Java to C MPI connection
mpirun --app java2c.app
echo
echo Testing C to Java MPI connection
mpirun --app c2java.app
echo

André