我想使用Messgae Passing Interface(MPI)从主服务器向从服务线程发送一个字符串数组。 即String [] str = new String [10] str [0] =" XXX" ......等等。
如何避免将此数组中的每个元素作为一个字符串发送?
我成功地在一次发送操作中发送了一个整数数组......但是当它涉及一个字符串数组时我不知道如何做到这一点
答案 0 :(得分:3)
我不懂Java,但我会给你C答案。然而,概念 - 特别是解决这个问题的两种方法 - 在任何语言中都是相同的。
想象一下,如果这是一个简单的c字符串(一些字符以' \ 0'终止)。有两种方法:
你有最大长度吗? (例如PATH_MAX或类似的东西)。如果你不需要每个字节的内存,你可以做
MPI_Send(str, strlen(str), MPI_CHAR, slave_rank, slave_tag, MPI_COMM_WORLD);
并且您将其与
配对MPI_Recv(str, MAX_LENGTH, MPI_CHAR, master_rank, slave_tag, MPI_COMM_WORLD);
如果你不喜欢最后的slop,你必须在两个消息中做到这一点:
len=strlen(str) + 1; /* +1 for the NULL byte */
MPI_Send(&len, 1, MPI_INT, slave_rank, slave_tag, MPI_COMM_WORLD);
MPI_Send(str, strlen(str), MPI_CHAR, slave_rank, slave_tag, MPI_COMM_WORLD);
并且您与
匹配MPI_Recv(&len, 1, MPI_INT, master_rank, slave_tag, MPI_COMM_WORLD);
payload= malloc(len);
MPI_Recv(&payload, len, MPI_CHAR, master_rank, slave_tag, MPI_COMM_WORLD);
答案 1 :(得分:2)
发送字符串数组,特别是在大小不同的情况下,这是一个非常复杂的过程。有几个选项,但MPI最友好的选项是使用MPI的打包和解包设施,在mpiJava中显示为Comm.Pack
,Comm.Unpack
和Comm.Pack_size
。
你可以做某种事情:
byte[][] bytes = new byte[nStr][];
int[] lengths = new int[nStr];
int bufLen = MPI.COMM_WORLD.Pack_size(1, MPI.INT);
bufLen += MPI.COMM_WORLD.Pack_size(nStr, MPI.INT);
for (int i = 0; i < nStr; i++) {
bytes[i] = str[i].getBytes(Charset.forName("UTF-8"));
lengths[i] = bytes[i].length;
bufLen += MPI.COMM_WORLD.Pack_size(lengths[i], MPI.BYTE);
}
byte[] buf = new byte[bufLen];
int position = 0;
int nStrArray[] = new int[1];
nStrArray[0] = nStr;
position = MPI.COMM_WORLD.Pack(nStrArray, 0, 1, MPI.INT,
buf, position);
position = MPI.COMM_WORLD.Pack(lengths, 0, nStr, MPI.INT,
buf, position);
for (int i = 0; i < nStr; i++) {
position = MPI.COMM_WORLD.Pack(bytes[i], 0, lengths[i], MPI.BYTE,
buf, position);
}
MPI.COMM_WORLD.Send(buf, 0, bufLen, MPI.PACKED, rank, 0);
在辅助数组中包含字符串长度并将其打包在消息的开头简化了接收器逻辑。
假设发件人排名为0。
Status status = MPI.COMM_WORLD.Probe(0, 0);
int bufLen = status.Get_count(MPI.PACKED);
byte[] buf = new byte[bufLen];
MPI.COMM_WORLD.Recv(buf, 0, bufLen, MPI.PACKED, status.source, status.tag);
int position = 0;
int nStrArray[] = new int[1];
position = MPI.COMM_WORLD.Unpack(buf, position,
nStrArray, 0, 1, MPI.INT);
int nStr = nStrArray[0];
int lengths[] = new int[nStr];
position = MPI.COMM_WORLD.Unpack(buf, position,
lengths, 0, nStr, MPI.INT);
String[] str = new String[nStr];
for (int i = 0; i < nStr; i++) {
byte[] bytes = new byte[lengths[i]];
position = MPI.COMM_WORLD.Unpack(buf, position,
bytes, 0, lengths[i], MPI.BYTE);
str[i] = new String(bytes, "UTF-8");
}
免责声明:我没有安装MPJ Express,而且我的Java知识非常有限。该代码基于互联网上的mpiJava specification,MPJ Express JavaDocs和部分examples。