1

当我执行此代码时,我没有响应,它一直在等待,进程 1 正在向根进程发送数据,但根进程没有收到它(或者几乎就是我的想法)。

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


void my_parallel_function(int v[], int size, int rank)
{
   MPI_Status status;
   int i;

   if(rank==0)
   {
     MPI_Send(&v[0], 10, MPI_INT, 1, 1, MPI_COMM_WORLD);
   }
   else
   {
     MPI_Recv(&v[0], 10, MPI_INT, MPI_ANY_SOURCE, 1, MPI_COMM_WORLD,&status);
     for(i=0;i<10;i++)
     {
        //change the value
        v[i] = i;
        //printf("hola soy nodo: %d\n", i);
     }
     MPI_Send(&v[0], 10, MPI_INT, 0, 2, MPI_COMM_WORLD);
   }

   if(rank==0)
   {
     MPI_Recv(&v[0], 10, MPI_INT, MPI_ANY_SOURCE, 2, MPI_COMM_WORLD,&status);
     for(i=1;i<size;i++)
     {
        printf("\nvalue of item %d: %d\n", i, v[i]);
     }
   }
}

void simpleFunction()
{
    printf("Hi i am a simple function\n");
}

int main(int argc, char *argv[])
{        
    int rank, size;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Status status;

    int vect[10];
    int op=1;

    while(op != 0)
    {
        //system("clear");
        printf("Welcome to example program!\n\n");
        printf("\t1.- Call Parallel Function\n");
        printf("\t2.- Call another Function\n");
        printf("\t0.- Exit\n\t");

        printf("\n\n\tEnter option:");
        scanf("%d", &op);
        switch(op)
        {
            case 1:
                    my_parallel_function(vect, size, rank);
                    printf("Parallel function called successfully\n\n");
                    break;
            case 2:
                    simpleFunction();
                    printf("Function called successfully\n\n");
                    break;
        }
    }

    MPI_Finalize();
    return 0;
}

我正在使用 -np 2 执行

我认为这不是应该的: MPI_Recv(&v[0], 10, MPI_INT, MPI_ANY_SOURCE, 2, MPI_COMM_WORLD,&status);

任何想法?非常感谢您。

已编辑:但是当我删除 if(rank==0) 时,我得到了从属进程的所有 i/o,这意味着大量的菜单打印。我是 OpenMPI 的新手,如何解决这个问题?

非常感谢!。

4

2 回答 2

1

在 MPI 程序中实现菜单的正确方法是:

while (op != 0)
{
   if (rank == 0)
   {
      printf("Welcome to example program!\n\n");
      printf("\t1.- Call Parallel Function\n");
      printf("\t2.- Call another Function\n");
      printf("\t0.- Exit\n\t");

      printf("\n\n\tEnter option:");
      scanf("%d", &op);
   }

   // Broadcast the user's choice to all other ranks
   MPI_Bcast(&op, MPI_INT, 1, 0, MPI_COMM_WORLD);

   switch(op)
   {
      case 1:
         my_parallel_function(vect, size, rank);
         MPI_Barrier(MPI_COMM_WORLD);
         if (rank == 0)
            printf("Parallel function called successfully\n\n");
         break;
      case 2:
         simpleFunction();
         MPI_Barrier(MPI_COMM_WORLD);
         if (rank == 0)
            printf("Function called successfully\n\n");
         break;
   }
}

这两个障碍并不是绝对必要的——它们只是确保所有级别的呼叫都返回了。

请注意, MPI 标准不保证允许从标准输入读取 rank 0,并且执行此类 I/O 的程序不可移植。也就是说,大多数现有的 MPI 实现确实将等级 0 的标准输入和输出重定向到mpiexec/的标准输入和输出mpirun

于 2013-11-12T17:30:37.983 回答
1

my_parallel_function仅在rank为 0 时调用。因此,当rank为 1 时,不会将任何内容发送到 0 级,它MPI_Recv会永远等待。只需if从您的main.

于 2013-11-12T15:05:18.853 回答