4

我想使用 Messgae 传递接口 (MPI) 将字符串数组从主线程发送到从线程。即 String [] str = new String [10] str[0]= "XXX" ...等

如何在避免将此数组中的每个元素作为字符链发送的同时做到这一点?

我成功地在一个发送操作中发送了一个整数数组......但是当它是关于一个字符串数组时我不知道该怎么做

4

2 回答 2

3

我不懂 Java,但我会给你 C 的答案。但是,这些概念——尤其是解决这个问题的两种方法——在任何语言中都是相同的。

想象一下,如果这是一个简单的 c 字符串(一些字符以 '\0' 结尾)。有两种方法:

  1. 过度配置内存并接收到某个限制,
  2. 或发送一条消息,指明预期的数据量。

你有最大长度吗?(例如 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);
于 2014-09-23T15:14:45.860 回答
2

发送字符串数组,尤其是不同大小的字符串,是一个相当复杂的过程。有几种选择,但对 MPI 最友好的一种是使用 MPI 的打包和解包工具,在 mpiJava 中以Comm.PackComm.UnpackComm.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 规范MPJ Express JavaDocs和Internet 上的一些示例。

于 2014-09-23T17:47:19.320 回答