[OMPI users] Multi-program between Java and C/Fortran...
I'm interested in connecting new Java programs with legacy programs written in C and Fortran using MPI (so that they are machine independent and parallel). To try this out at first, I was hoping to simply Send arrays of basic datatypes (integer, floats, etc.) from a Java program to a simple C or Fortran program. So, I put together a simple example, but am unable to Send or Receive anything (the program just freezes... I'm guessing it freezes at the MPI_Send and MPI_Recv calls). What am I doing wrong (see code below)? *Java program - interopj.java (sending program): * import mpi.*; public class interopj { public static void main(String args[]) { try { MPI.Init(args); int rank = MPI.COMM_WORLD.Rank(); int size = MPI.COMM_WORLD.Size(); int offset = 0, cnt = 1; int buf[] = new int[cnt]; for (int i = 1; i < size; i++) { buf[0] = i; System.out.println("Sending " + i); MPI.COMM_WORLD.Send(buf, offset, cnt, MPI.INT, i, 0); } } catch (Exception e) { e.printStackTrace(); } finally { try { MPI.Finalize(); } catch(Exception ex) { ex.printStackTrace(); } } } } *C program - interop.c (receiving program): * #include "mpi.h" int main(int argc, char *argv[]) { int rank, size; int i, bsize; MPI_Status status; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); bsize = 1; int buf[bsize]; printf("Waiting for an integer"); MPI_Recv(&buf, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, &status); printf("Received %d", buf[0]); MPI_Finalize(); return 0; } *Makefile: * CC = mpicc JCC = mpijavac LIB = /usr/local/lib all: interop interopj interop: interop.c $(CC) -o interop interop.c interopj: interopj.java $(JCC) -cp $(LIB)/mpi.jar interopj.java *Shell file to run a test: * echo Building make -B echo Running mpirun -np 1 java interopj : -np 2 interop Thanks for your help in advance, André
Re: [OMPI users] Multi-program between Java and C/Fortran...
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 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 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 Ju
Re: [OMPI users] Multi-program between Java and C/Fortran...
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. 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 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 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 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 { i