我不知道MPI程序中的问题是什么

时间:2015-12-09 02:53:06

标签: c mpi

到目前为止,我不知道如何解决这个程序的问题。这个程序的目的是将所有数字加在一个数组中,但我几乎无法在错误开始出现之前发送数组。它与if statement my_rank!=0部分中的for循环有关。

#include <stdio.h>
#include <mpi.h>

int main(int argc, char* argv[]){
 int my_rank, p, source, dest, tag, total, n = 0;
 MPI_Status status;

 MPI_Init(&argc, &argv);
 MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
 MPI_Comm_size(MPI_COMM_WORLD, &p);

 //15 processors(1-15) not including processor 0
 if(my_rank != 0){
  MPI_Recv( &n, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status);
  int arr[n];
  MPI_Recv( arr, n, MPI_INT, source, tag, MPI_COMM_WORLD, &status);

  //printf("%i ", my_rank);
  int i;
  for(i = ((my_rank-1)*(n/15)); i < ((my_rank-1)+(n/15)); i++ ){
   //printf("%i ", arr[0]);
  }

 }
 else{
  printf("Please enter an integer:\n");
  scanf("%i", &n);

  int i;
  int arr[n];

  for(i = 0; i < n; i++){
   arr[i] = i + 1;
  }

  for(dest = 0; dest < p; dest++){
   MPI_Send( &n, 1, MPI_INT, dest, tag, MPI_COMM_WORLD);
   MPI_Send( arr, n, MPI_INT, dest, tag, MPI_COMM_WORLD);
  }
 }
 MPI_Finalize();
}

当我把它作为循环输出时,它会编译并运行但是当我把它放回去时它就会停止工作。这是它给我的错误:

[compute-0-24.local:1072] *** An error occurred in MPI_Recv
[compute-0-24.local:1072] *** on communicator MPI_COMM_WORLD
[compute-0-24.local:1072] *** MPI_ERR_RANK: invalid rank
[compute-0-24.local:1072] *** MPI_ERRORS_ARE_FATAL: your MPI job will now abort
Please enter an integer:
--------------------------------------------------------------------------
mpirun has exited due to process rank 8 with PID 1072 on
node compute-0-24 exiting improperly. There are two reasons this could occur:

1. this process did not call "init" before exiting, but others in
the job did. This can cause a job to hang indefinitely while it waits
for all processes to call "init". By rule, if one process calls "init",
then ALL processes must call "init" prior to termination.

2. this process called "init", but exited without calling "finalize".
By rule, all processes that call "init" MUST call "finalize" prior to
exiting or it will be considered an "abnormal termination"

This may have caused other processes in the application to be
terminated by signals sent by mpirun (as reported here).
--------------------------------------------------------------------------
[compute-0-16.local][[31957,1],0][btl_tcp_endpoint.c:638:mca_btl_tcp_endpoint_complete_connect] connect() to 192.168.4.237 failed: Connection refused (111)
[cs-cluster:11677] 14 more processes have sent help message help-mpi-errors.txt / mpi_errors_are_fatal
[cs-cluster:11677] Set MCA parameter "orte_base_help_aggregate" to 0 to see all help / error messages

2 个答案:

答案 0 :(得分:1)

您发布的代码存在两个问题:

  1. 发送循环从p=0开始,这意味着排名零的过程将发送给自己。但是,由于零流程没有接收部分,因此无法正常工作。只需让循环从p=1开始,那就应该解决它。
  2. 您使用的tag未初始化。因此,它的价值可以是任何(可以),但每个过程可以是不同的,这将导致各种通信永远不会相互匹配。例如,只需初始化tag=0,这应该可以解决这个问题。
  3. 有了这个,你的代码片段应该可以工作。

答案 1 :(得分:1)

学习阅读Open MPI为您提供的信息性错误消息,并应用一些常规调试策略。

[compute-0-24.local:1072] *** An error occurred in MPI_Recv
[compute-0-24.local:1072] *** on communicator MPI_COMM_WORLD
[compute-0-24.local:1072] *** MPI_ERR_RANK: invalid rank

库告诉您使用无效的等级值调用接收操作。有了这些知识,你可以看看你的代码:

int my_rank, p, source, dest, tag, total, n = 0;
...
//15 processors(1-15) not including processor 0
if(my_rank != 0){
  MPI_Recv( &n, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status);
  ...

等级为sourcesource是一个自动变量,之前声明了一些行但从未初始化,因此它的初始值是完全随机的。您可以通过为source分配0的初始值,或者只需将其替换为0来解决问题,因为您已经通过单独输入代码对发送方的排名进行了硬编码在else运算符的if块中。

上述错误的存在最终暗示您也要检查其他变量。因此,您注意到tag也未经初始化使用,您可以将其初始化为例如{1}}。 0或完全替换它。

现在你的程序几乎是正确的。您注意到似乎<{em> 正常n高达约33000(自我运输的默认急切限制除以sizeof(int)),但随后它会挂起以获得更大的值。您可以在每个发送和接收操作之前和之后触发调试器,只需添加printf语句,并发现已经MPI_Send的第一次调用dest等于0回报。然后,您仔细查看代码并发现:

for(dest = 0; dest < p; dest++){

dest0开始,但这是错误的,因为排名0仅发送数据而未接收。您可以通过将初始值设置为1来修复它。

您的程序现在应该按预期工作(或者至少在n中不会导致堆栈溢出的int arr[n];的值)。恭喜!现在去了解MPI_ProbeMPI_Get_count,这将帮助您在不明确发送数组长度的情况下执行相同操作。然后了解MPI_ScatterMPI_Reduce,这将使您能够更优雅地实施算法。