【问题标题】:Looping through an MPI ring in C循环通过 C 中的 MPI 环
【发布时间】:2017-11-08 18:31:17
【问题描述】:

我无法弄清楚如何在我的 MPI 代码中进行多次迭代。仅通过在不同位置测试多个 for 循环就告诉我我做错了什么。我们的部分指令是在命令行参数中指定的环上多次传递令牌,但我似乎无法通过对迭代进行硬编码来使其正常工作。我将顶部的 for 循环留在了(这不起作用),但注释掉了其他的。

这可能是一个比我预期的更复杂的任务。 任何帮助表示赞赏

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

int main(int argc, char* argv[])
{
    double starttime, endtime;
    MPI_Init(&argc, &argv);
    starttime = MPI_Wtime();
    int world_rank;
    int world_size;

    for (int i = 0; i < 3; i++)

        MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
        MPI_Comm_size(MPI_COMM_WORLD, &world_size);

//pass the token

        int token =1000;

//for (int i = 0; i < 3; i++)
//{
    if (world_rank == 0)
    {
        token = 0;
        MPI_Send(&token, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);

        MPI_Recv(&token, 1, MPI_INT, world_size - 1, 0, MPI_COMM_WORLD, 
        MPI_STATUS_IGNORE);

        printf("FINAL TOKEN %d\n", token);
    }
    else if(world_rank < world_size - 1 )
    {
        MPI_Recv(&token, 1, MPI_INT, world_rank-1, 0, MPI_COMM_WORLD, 
        MPI_STATUS_IGNORE);

        printf("%d has token %d sending to %d\n", world_rank, token, 
        world_rank+1);
        token = token + 2;

        MPI_Send(&token, 1, MPI_INT, world_rank+1, 0, MPI_COMM_WORLD);
        }
    else
        {
        MPI_Recv(&token, 1, MPI_INT, world_rank-1, 0, MPI_COMM_WORLD, 
        MPI_STATUS_IGNORE);
        printf("%d has token %d sending to %d\n", world_rank, token, 
        world_rank+1);
        token = token + 2;
        MPI_Send(&token, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
        }
    endtime = MPI_Wtime();
    printf("That took %f seconds\n",endtime-starttime);
    }
    MPI_Finalize();

    return 0;
}

这是编译和运行的输出:

$ mpicc -std=c99 test.c
$ mpirun -np 3 ./a.out
1 has token 0 sending to 2
That took 0.000187 seconds
2 has token 2 sending to 3
That took 0.000145 seconds
FINAL TOKEN 4
That took 0.000180 seconds
FINAL TOKEN 4
That took 0.000212 seconds
2 has token 2 sending to 3
That took 0.000202 seconds
2 has token 2 sending to 3
That took 0.000233 seconds
1 has token 0 sending to 2
That took 0.000291 seconds
1 has token 0 sending to 2
That took 0.000322 seconds
FINAL TOKEN 4
That took 0.000244 seconds

【问题讨论】:

  • 一个printf()是错误的,你发送到0。你期望什么结果?它执行代码所说的...您的意思是在 for 循环之外初始化 token=0 吗?请注意 for 循环是无用的,缩进是误导性的。
  • 好吧,我试图让它通过令牌传递多次。到目前为止,for 循环给了我奇怪的输出。
  • 作为above comment,在for循环外取int token = 1000行(使其成为实际的for循环,缺少{})并删除token = 0行。
  • 这解决了我的问题。如果你把它作为一个答案,那就把它标记为正确

标签: c mpi


【解决方案1】:

如this comment 中所述,for 循环缺少大括号{},并且每次循环迭代都会重置令牌。

此外,您可以删除其中一个案例,并使用模运算符 % 包含 world_rank==world_size。

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

int main(int argc, char* argv[])
{
    double starttime, endtime;
    MPI_Init(&argc, &argv);
    starttime = MPI_Wtime();
    int world_rank;
    int world_size;

    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    //pass the token

    int token =1000;

    for (int i = 0; i < 3; i++)
    {
        if (world_rank == 0)
        {
            // token = 0; removed
            MPI_Send(&token, 1, MPI_INT, 1, 0, MPI_COMM_WORLD);

            MPI_Recv(&token, 1, MPI_INT, world_size - 1, 0, MPI_COMM_WORLD, 
            MPI_STATUS_IGNORE);

            printf("FINAL TOKEN %d\n", token);
        }
        else
        {
            MPI_Recv(&token, 1, MPI_INT, world_rank-1, 0, MPI_COMM_WORLD, 
            MPI_STATUS_IGNORE);

            printf("%d has token %d sending to %d\n", world_rank, token, 
            (world_rank+1)%world_size); // modified
            token = token + 2;

            MPI_Send(&token, 1, MPI_INT, (world_rank+1)%world_size, 0, MPI_COMM_WORLD); // modified
        }

        endtime = MPI_Wtime();
        printf("That took %f seconds\n",endtime-starttime);
    }
    MPI_Finalize();

    return 0;
}

【讨论】:

  • 出于好奇,你为什么初始化token=1000?
  • 哈哈,老师希望我们将其初始化为一个随机数,以表明它会更改为 if 语句中设置的任何值。不知道为什么,但他问那个在里面。
猜你喜欢
  • 2012-01-02
  • 2016-01-05
  • 1970-01-01
  • 2017-04-27
  • 2014-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多