【问题标题】:MPI in Windows (returning data from slave task to master task)Windows 中的 MPI(将数据从从属任务返回到主任务)
【发布时间】:2018-09-20 19:20:02
【问题描述】:

我正在学习如何使用 MPI。

现在我要做的就是在主任务和从任务之间发送和接收数据。从主任务向从任务发送数据正常工作。 (我通过让每个从属打印它们从主控接收到的数据来测试这一点)。

从从属任务接收主任务中的数据似乎不起作用。

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

#define MASTER_TAG 0    
#define WORKTAG 1
#define DIETAG 2

#define N 4
#define ARRAY_SIZE N*N

int getMin(int a, int b);
void print1D(int *arr, int n);
int* allocateIntegerArray(int n);
void master();
void slave();

int *inputArray = NULL;
int *outputArray = NULL;

int main(int argc, char **argv)
{
    int myrank = 0;

    MPI_Init(&argc, &argv); // initialize MPI

    MPI_Comm_rank(MPI_COMM_WORLD, &myrank); // process rank, 0 thru N-1

    if (myrank == 0)
        master();
    else
        slave();

    MPI_Finalize(); // cleanup MPI

    return 0;
}

void master()
{
    int numOfTasks;
    int rank = 0;
    int work = 0;
    int startIndex = 0;
    int dataPerTask = 0;
    int *tempArray = NULL;
    int i = 0;
    int k = 0;

    MPI_Status status;

    MPI_Comm_size( MPI_COMM_WORLD, &numOfTasks); // #processes in application

    // calculate the amount of data that each task will receive
    dataPerTask = ARRAY_SIZE;

    // create the array that will hold the data that will be transferred back and forth between the master and slave tasks
    tempArray = allocateIntegerArray( dataPerTask );

    for (i = 1; i < numOfTasks; ++i)
    {
        MPI_Send(&dataPerTask, 1, MPI_INT, i, WORKTAG, MPI_COMM_WORLD); // send the size of the data chunk to the slave task
        MPI_Send(tempArray, dataPerTask, MPI_INT, i, WORKTAG, MPI_COMM_WORLD); // send the actual chunk of data to the slave task

        print1D(tempArray, dataPerTask);
        MPI_Recv(tempArray, dataPerTask, MPI_INT, MPI_ANY_TAG, WORKTAG, MPI_COMM_WORLD, &status); // receive results from slave task
        print1D(tempArray, dataPerTask);
    }

    // tell all the slaves to exit
    for (i = 1; i < numOfTasks; ++i)
        MPI_Send(0, 0, MPI_INT, i, DIETAG, MPI_COMM_WORLD);

    free(tempArray);
}

void slave()
{
    MPI_Status status;
    int *in = NULL; // input array
    int *out = NULL; // outpu array
    int dataPerTask = 0;

    for (;;)
    {
        MPI_Recv(&dataPerTask, 1, MPI_INT, MASTER_TAG, MPI_ANY_TAG, MPI_COMM_WORLD, &status); // get the number of integers in the incoming array

        if (status.MPI_TAG == DIETAG) // check the tag of the received message (if the master task sent the DIETAG, then the slave must stop processing and return)
            return;

        in = allocateIntegerArray(dataPerTask); // array 'in' holds the data received from the master task
        out = allocateIntegerArray(dataPerTask); // array 'out' holds the data that is returned to the master task

        MPI_Recv(in, dataPerTask, MPI_INT, MASTER_TAG, MPI_ANY_TAG, MPI_COMM_WORLD, &status); // get the actual data from the master task

        out[0] = 1; // modify the data in some way
        MPI_Send(out, dataPerTask, MPI_INT, 0, WORKTAG, MPI_COMM_WORLD);
    }

    free(in);
    free(out);
}

void print1D(int *arr, int n)
{
    int i = 0;

    for (i = 0; i < n; i++)
        printf("%d ", arr[i]);

    printf("\n");
}

int* allocateIntegerArray(int n)
{
    int i = 0;

    if (n <= 0)
        return NULL;

    int *arr = (int*) malloc(sizeof(int)*n*n);
    memset(arr, 0, sizeof(int)*n*n);

    return arr;
}

【问题讨论】:

  • 请上传与您面临的问题相匹配的minimal reproducible example(例如从奴隶而不是从主人发送)
  • 你好。我还能做些什么来使代码最小化、完整和可验证?我删除了很多代码,只留下了重现问题所需的内容。我发布的代码演示了我能够向从属设备发送数据,但不能在主任务中从它们接收数据。我应该删除 slave()/master() 函数并将它们的代码插入 main() 吗?我认为这种方式使其更具可读性。
  • 我可能看错了你的问题描述,让我看看现在的代码。
  • 代码对我有用。是什么让你觉得它似乎不起作用
  • 我在 Linux fwiw 下使用Open MPI。请注意,您不应该在 MPI_Recv()MPI_ANY_TAG 上使用 MPI_ANY_SOURCEimaster0 上使用奴隶。尝试修复它,看看它有什么帮助。

标签: c mpi multitasking


【解决方案1】:

根本原因是你的程序调用MPI_Recv(...,source=MPI_ANY_TAG, ...)

MPI_ANY_TAG 不是有效来源,您应该使用正确的来源(例如,master 中的 islave 中的 0)或 MPI_ANY_SOURCE

FWIW,不要不要认为这是理所当然的,因为它可能会在未来发生变化

  • Open MPIMPI_ANY_SOURCEMPI_ANY_TAG 中具有相同的值,这就是为什么我最初认为它对我有用。
  • MPICH 中,MPI_ANY_TAGMPI_PROC_NULL 具有相同的值,这就是为什么消息在您的环境中只有零的原因。

【讨论】:

    猜你喜欢
    • 2012-07-01
    • 2022-07-05
    • 2022-11-18
    • 1970-01-01
    • 2014-07-18
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 2013-04-29
    相关资源
    最近更新 更多