使用消息传递接口发送字符串数组

时间:2014-09-22 13:06:23

标签: mpi mpj-express

我想使用Messgae Passing Interface(MPI)从主服务器向从服务线程发送一个字符串数组。 即String [] str = new String [10] str [0] =" XXX" ......等等。

如何避免将此数组中的每个元素作为一个字符串发送?

我成功地在一次发送操作中发送了一个整数数组......但是当它涉及一个字符串数组时我不知道如何做到这一点

2 个答案:

答案 0 :(得分:3)

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

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

  1. 过度配置内存并获得一些限制,
  2. 或发送一条消息,指出预期的数据量。
  3. 你有最大长度吗? (例如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.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 specificationMPJ Express JavaDocs和部分examples