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: Ralph Castain (rhc_at_[hidden])
Date: 2013-07-23 15:20:46


On Jul 23, 2013, at 12:10 PM, Andre Dozier <hambre_at_[hidden]> wrote:

> I was using the OMPI trunk version 1.9a1r28764...
>
> I tried building openmpi both with and without GC_DOES_PINNING defined, because I noticed that the MPI calls are handled differently with that defined (although I may not have defined it in the correct place.... ompi/mpi/java/c/mpiJava.h). Without it defined, it looks like the data is packed to a byte array before sending, and then, unpack on the receiving side. So, I thought that I would have to do the same thing in the C program I built. Am I correct in assuming that I would have to pack data into a byte array (or unpack it) in my C program without GC_DOES_PINNING defined when building openmpi? When I built it with GC_DOES_PINNING, nothing noticeably changed.

Aahhhh....yeah, that's a good point. The Java side assumes it's another Java program on the other end, so it does do some data handling under the covers. Required due to the mismatch between Java and the way MPI handles things.

Hadn't thought about that - I suspect your approach might be required. Some folks are reworking the java bindings on-the-side and will be committing it shortly, so it could be that they will consider this problem.

>
> André
>
>
>
> On 7/23/2013 12:29 PM, Ralph Castain wrote:
>> There shouldn't be an inter-language issue here as all the Java code does is use a JNI module to access the C bindings. Were you using the Java bindings in the OMPI trunk? Or were you using a 3rd party library?
>>
>> On Jul 22, 2013, at 9:13 AM, Andre Dozier <hambre_at_[hidden]> wrote:
>>
>>> 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é
>>>
>>> _______________________________________________
>>> users mailing list
>>> users_at_[hidden]
>>> http://www.open-mpi.org/mailman/listinfo.cgi/users
>>
>> _______________________________________________
>> users mailing list
>> users_at_[hidden]
>> http://www.open-mpi.org/mailman/listinfo.cgi/users
>
> _______________________________________________
> users mailing list
> users_at_[hidden]
> http://www.open-mpi.org/mailman/listinfo.cgi/users