我开始在mpiJava编写一个mpi程序并设法编写一个工作程序,但由于其中一个或另一个原因它不想在平台上运行我需要它运行(I没有任何权限安装任何东西)。我不确定是否有必要(考虑到我现在遇到同样的问题),但我开始使用open-mpi和它的java绑定。关键是在平台上,open-mpi可用,因此我认为它会自动运行。它没有工作,我仍然试图找出原因(它可能与信用系统有关),但这不是我希望在这里解决的问题
真正的问题是我需要通过MPI发送java对象,我不知道如何以正确的方式执行它。在mpiJava我有优势,有一个MPI.Object数据类型可用(它只是序列化对象),但open-mpi没有这样的东西。我已经访问了post on BigInteger和post actually providing some answers,当然还有the open-mpi reference,但我现在还不完全确定在我的案例中哪种方法最好。
我想通过MPI发送3个不同的对象:
BigInteger
Object[]
,里面有3个不同的对象自编类看起来像这样:
public class AC implements Iterable<BS>, Comparable<AC>, LE, Serializable {
private static final long serialVersionUID = -530910801257060853L;
private static AC emptyAC = new AC();
private static AC emptySetAC = new AC();
static {emptySetAC.theAC.set(0);}
private BitSet theAC = new BitSet();
private BS universe = BS.universe();
...
//methods
}
public class BS implements Iterable<Integer>, Comparable<BS>, Serializable {
private static final long serialVersionUID = 4240724082500295998L;
private static BS theEmptySet = new BS();
private static long[] bits;
private long theSet;
...
//methods
}
到目前为止发送的open-mpi代码(省略了我的列表中的&#39; BigInteger
)看起来像:
public static void main(String[] args) {
...
//master code
SortedMap<AC, Long> functions = new TreeMap<>();
AC u = AC.oneSetAC(BS.universe(n));
SortedMap<AC, BigInteger> leftIntervalSize = new TreeMap<>();
MPI.COMM_WORLD.bcast(new Object[]{functions, leftIntervalSize, u}, 3, MPI.Object, 0);
...
AC[] sendbuf = new AC[1];
while(iterator.hasnext()) {
MPI.COMM_WORLD.send(sendbuf, 1, MPI.OBJECT, i, 0);
}
...
//worker code
Object[] buf = new Object[3];
MPI.COMM_WORLD.bcast(buf, 3, MPI.OBJECT, 0);
...
AC[] func = new AC[1];
Status stat = MPI.COMM_WORLD.recv(func, 1, MPI.OBJECT, 0, MPI.ANY_TAG);
...
}
请注意,MPI.Object
只是我的mpiJava实现的继承,这些是我需要正确更改的行。
我已经对它有了一些想法,我认为如果有人能给我一个如何正确使用MPI结构的例子,我可以使用the post actually providing some answers给BigInteger
的答案。 (我真的不完全从the open-mpi reference了解它。对于我自己的课程和另一方面Object[]
,我可以做以下任何一种情况:
我很抱歉这篇长篇文章,但我希望从第一次开始就明白。
提前致谢
答案 0 :(得分:1)
如果您控制通信的两个方面,并且两者都在Java 和中,您不太关心性能,那么您可以执行以下操作:
MyClass someObject = ...
serialized = ""
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(someObject);
oos.flush();
serialized = baos.toString();
}
catch (Exception e) {
System.out.println(e);
}
char [] message = serialized.toCharArray() ;
MPI.COMM_WORLD.Send(message, 0, message.length, MPI.CHAR, 1, 99) ;
另一方面,您只是接收并基本上反向执行相同的步骤以反序列化。
try {
byte b[] = serializedObject.getBytes();
ByteArrayInputStream bis = new ByteArrayInputStream(b);
ObjectInputStream ois = new ObjectInputStream(bis);
MyClass obj = (MyClass) ois.readObject();
} catch (Exception e) {
System.out.println(e);
}
这种方法的优点是简单,让你快速前进。如果您不打算发送很多物品,我认为这是完全可以接受的。
答案 1 :(得分:1)
最后,我决定使用sdotdi的答案序列化Object[]
。因为广播只发生过一次,所以这不应该太糟糕
对于BigInteger
,我使用toByteArray()
方法并首先发送数组的长度,然后发送字节数组本身。我怀疑它几乎与使用MPI结构一样快,但我不太确定。因此代码如下:
byte[] bigintbuf = result.toByteArray();
MPI.COMM_WORLD.send(new int[]{bigintbuf.length}, 1, MPI.INT, 0, NUMTAG);
MPI.COMM_WORLD.send(bigintbuf, bigintbuf.length, MPI.BYTE, 0, 0);
对于AC
类,我通过实现toLongArray()
方法应用了类似的技巧,因此代码变为:
long[] acbuf = next.toLongArray();
MPI.COMM_WORLD.send(new int[]{acbuf.length}, 1, MPI.INT, i, NUMTAG);
MPI.COMM_WORLD.send(acbuf, acbuf.length, MPI.LONG, i, 0);
这可能仍然不是最佳方式,但我认为它会达到最佳性能。