【问题标题】:C - MPI child processes receiving incorrect stringC - MPI 子进程收到不正确的字符串
【发布时间】:2017-08-13 02:39:45
【问题描述】:

我正在制作一个 MPI 密码破解器,它使用蛮力方法破解 SHA512 哈希密钥,我的代码可以在 1 个密码和多个进程或多个密码和 1 个进程下正常工作,但是当我执行多个密码和多个进程我收到以下错误:

[ubuntu:2341] *** An error occurred in MPI_Recv
[ubuntu:2341] *** reported by process [191954945,1]
[ubuntu:2341] *** on communicator MPI_COMM_WORLD
[ubuntu:2341] *** MPI_ERR_TRUNCATE: message truncated
[ubuntu:2341] *** MPI_ERRORS_ARE_FATAL (processes in this communicator will now abort,
[ubuntu:2341] ***    and potentially your MPI job)

我相信这是由进程排名 #1 接收字符串“/”而不是密码哈希引起的。 问题是我不知道为什么。

我还注意到我的代码有些奇怪,我在进程等级 0 中有以下循环:

      while(!done){
        MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &done, &status);
        if(done==1) {   
          for(i=1;i<size;i++){
            if(i!=status.MPI_SOURCE){
              printf("sending done to process %d\n", i);
              MPI_Isend(&done, 1, MPI_INT, i, 0, MPI_COMM_WORLD, &request[i]);
            }   
          }
        }          
      }

它一直在循环等待其中一个子进程提醒它已经找到密码。假设我正在运行 2 个进程(不包括基本进程)并且进程 2 找到了密码,那么输出将是:

sending done to process 1
sending done to process 1

当它应该只发送一次,或者至少如果它肯定发送两次,那么这些值之一应该是 2,而不是它们都是 1?

我的主要代码如下: 进程 0:

      while(!feof(f))  {
      fscanf(f, "%s\n", buffer);
      int done = 0;
      int i, sm;
      // lengths of the word (we know it should be 92 though)
      length = strlen(buffer);
      // Send the password to every process except process 0
      for (sm=1;sm<size;sm++) {
        MPI_Send(&length, 1, MPI_INT, sm, 0, MPI_COMM_WORLD);
        MPI_Send(buffer, length+1, MPI_CHAR, sm, 0, MPI_COMM_WORLD);
      }
      // While the passwords are busy cracking - Keep probing. 
      while(!done){
        MPI_Iprobe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &done, &status);
        if(done==1) {   
          for(i=1;i<size;i++){
            if(i!=status.MPI_SOURCE){
              printf("sending done to process %d\n", i);
              MPI_Isend(&done, 1, MPI_INT, i, 0, MPI_COMM_WORLD, &request[i]);
            }   
          }
        }          
      }
    }

遍历文件,获取新密码,将字符串发送给子进程,此时子进程会收到它:

    MPI_Recv(&length, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    printf("string to be recieived has %d characters\n", length);
    MPI_Recv(buffer, length+1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
    printf("Process %d received %s\n", rank, buffer); 

子进程破解密码,然后重复下一个。 (假设有一个,目前它是一个无限循环,但我想在修复之前用 2 个密码对其进行排序)。

所有进程第一次收到正确的密码,当他们获得第二个密码时,只有一个进程有正确的密码,其余的收到一个“/”字符。

【问题讨论】:

    标签: c linux mpi


    【解决方案1】:

    好吧,典型的情况是我很生气,看不起一些简单的事情。 我会留下这个问题,以防万一其他人碰巧有同样的问题。

    我在探索后忘记也收到解决方案。 从来没有完全清楚探测与接收有何不同,但我猜探测只是标记了一些变化,但要真正把它从“队列”中取出,你需要用接收来收集它。

    【讨论】:

    • 澄清一下,探测可以让您提取传入消息的长度,以便可以正确分配接收缓冲区。另一方面,MPI_Irecv 需要明确的消息长度。查看this 了解更多信息。
    猜你喜欢
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多