我是并行编程的新手,我想在java中完成它。 我想知道是否有可能通过MPI发送和接收更复杂的对象。我正在使用MPJ express。但是每当我想发送一个对象时,我都会得到一个ClassCastException。
MPI.Init(args);
myrank = MPI.COMM_WORLD.Rank();
numprocs = MPI.COMM_WORLD.Size();
Vector<CustomClass> chr = new Vector<CustomClass>();
if (myrank == 0 ) { //am I the master?
for (int i = 1; i < numprocs; i++) {
MPI.COMM_WORLD.Send(chr, 0, chr.size(), MPI.OBJECT, i, 99); //Here's where the
exception occurs
}
}
else {
Vector<BasicRegion> chr_received = new Vector<BasicRegion>();
MPI.COMM_WORLD.Recv(chr_received, 0, 1, MPI.OBJECT, 0, 99 );
}
例外:
mpi.MPIException:mpi.MPIException:java.lang.ClassCastException:java.util.Vector无法强制转换为[Ljava.lang.Object;
所以我的问题是: - 是否可以使用MPJ Express发送/接收更复杂的对象? - 如果是的话:我做错了什么?
答案 0 :(得分:4)
我也是MPJ express的新手,但似乎封闭的对象需要是原始类型 - 一些东西。 (就像在OpenMPI中使用C / C ++实现一样)。
这种代码对我有用:
Node t[] = new Node[4];
...
count[0] = t.length;
MPI.COMM_WORLD.Send(count, 0, 1, MPI.INT, 1, 98);
MPI.COMM_WORLD.Send(t, 0, t.length, MPI.OBJECT, 1, 99);
} else if( myRank == 1 ) {
int count[] = new int[1];
MPI.COMM_WORLD.Recv( count, 0, 1, MPI.INT, 0, 98);
Status mps = MPI.COMM_WORLD.Recv( t, 0, count[0], MPI.OBJECT, 0, 99 );
...
当然,您必须拥有实现Serializable接口的自定义类。
答案 1 :(得分:1)
您希望在发送之前对其进行序列化。
import mpi.*;
import java.io.*;
import java.nio.ByteBuffer;
public class MPITest
{
public static void main(String[] args)
{
MPI.Init(args);
int me = MPI.COMM_WORLD.Rank();
int tasks = MPI.COMM_WORLD.Size();
MPI.COMM_WORLD.Barrier();
if(me == 0)
{
Cat cat = new Cat("Tom", 15);
cat.Speak();
ByteBuffer byteBuff = ByteBuffer.allocateDirect(2000 + MPI.SEND_OVERHEAD);
MPI.Buffer_attach(byteBuff);
try
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = null;
out = new ObjectOutputStream(bos);
out.writeObject(cat);
byte[] bytes = bos.toByteArray();
System.out.println("Serialized to " + bytes.length);
MPI.COMM_WORLD.Isend(bytes, 0, bytes.length, MPI.BYTE, 1, 0);
}
catch(IOException ex)
{
}
}
else
{
byte[] bytes = new byte[2000];
Cat recv = null;
MPI.COMM_WORLD.Recv(bytes, 0, 2000, MPI.BYTE, MPI.ANY_SOURCE, 0);
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInput in = null;
try
{
in = new ObjectInputStream(bis);
Object obj = in.readObject();
recv = (Cat)obj;
recv.Speak();
}
catch(IOException ex)
{
}
catch(ClassNotFoundException cnf)
{
}
}
MPI.COMM_WORLD.Barrier();
MPI.Finalize();
}
}
但是这可以使用外部化并手动执行以避免序列化例程将发送的一些额外垃圾。
HTH 布赖恩
答案 2 :(得分:0)
import mpi.*;
/**
* Compile: javac -cp $MPJ_HOME/lib/mpj.jar:. ObjSend.java
* Execute: mpjrun.sh -np 2 -dport 11000 ObjSend
*/
public class ObjSend {
public static void main(String[] args) throws Exception {
int peer ;
MPI.Init(args);
int rank = MPI.COMM_WORLD.Rank() ;
int size = MPI.COMM_WORLD.Size() ;
int tag = 100 ;
if(rank == 0) {
String [] smsg = new String[1] ;
smsg[0] = "Hi from proc 0" ;
peer = 1 ;
MPI.COMM_WORLD.Send(smsg, 0, smsg.length, MPI.OBJECT,
peer, tag);
System.out.println("proc <"+rank+"> sent a msg to "+
"proc <"+peer+">") ;
} else if(rank == 1) {
String[] rmsg = new String[1] ;
peer = 0 ;
MPI.COMM_WORLD.Recv(rmsg, 0, rmsg.length , MPI.OBJECT,
peer, tag);
System.out.println("proc <"+rank+"> received a msg from "+
"proc <"+peer+">") ;
System.out.println("proc <"+rank+"> received the following "+
"message: \""+rmsg[0]+"\"") ;
}
MPI.Finalize();
}
}