有关MPI_Scatter执行器&的问题它的发送缓冲区分配 [英] Questions about MPI_Scatter executer & its send buffer allocation

查看:136
本文介绍了有关MPI_Scatter执行器&的问题它的发送缓冲区分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的第一个想法是MPI_Scatter,应该在if(proc_id == 0)子句中使用send-buffer分配,因为数据应该只分散一次,并且每个进程只需要send-buffer中的一部分数据,但是并没有不能正常工作.

My first thought was MPI_Scatter and send-buffer allocation should be used in if(proc_id == 0) clause, because the data should be scattered only once and each process needs only a portion of data in send-buffer, however it didn't work correctly.

看来,在应用程序正确运行之前,所有进程都必须执行发送缓冲区分配和MPI_Scatter.

It appears that send-buffer allocation and MPI_Scatter must be executed by all processes before the application goes right.

所以我徘徊,MPI_Scatter存在的原理是什么,因为所有进程都可以访问发送缓冲区.

So I wander, what's the philosophy for the existence of MPI_Scatter since all processes have access to the send-buffer.

任何帮助将不胜感激.


我这样写的代码:


Code I wrote like this:

if (proc_id == 0) {
    int * data = (int *)malloc(size*sizeof(int) * proc_size * recv_size);
    for (int i = 0; i < proc_size * recv_size; i++) data[i] = i;

    ierr = MPI_Scatter(&(data[0]), recv_size, MPI_INT, &recievedata, recv_size, MPI_INT, 0, MPI_COMM_WORLD);
}

我认为,对于根进程来说,分散数据就足够了,其他进程需要做的只是接收数据.因此,我将MPI_Scatter以及发送缓冲区定义&分配,在if(proc_id == 0)语句中.没有编译/运行时错误/警告,但其他进程的接收缓冲区未接收到它对应的数据部分.

I thought, that's enough for root processes to scatter data, what the other processes need to do is just receiving data. So I put MPI_Scatter, along with send buffer definition & allocation, in the if(proc_id == 0) statement. No compile/runtime error/warning, but the receive buffer of other processes didn't receive it's corresponding part of data.

推荐答案

您的问题不是很清楚,如果您显示了遇到问题的代码,将会更容易理解.这就是我您要问的问题,而我只是在猜测,因为这是我看到的一些不熟悉C语言的MPI的人的错误.

Your question isn't very clear, and would be a lot easier to understand if you showed some code that you were having trouble with. Here's what I think you're asking -- and I'm only guessing this because this is an error I've seen people new to MPI in C make.

如果您有类似这样的代码:

If you have some code like this:

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

int main(int argc, char **argv) {
    int proc_id, size, ierr;
    int *data;
    int recievedata;

    ierr = MPI_Init(&argc, &argv);
    ierr|= MPI_Comm_size(MPI_COMM_WORLD,&size);
    ierr|= MPI_Comm_rank(MPI_COMM_WORLD,&proc_id);

    if (proc_id == 0) {
        data = (int *)malloc(size*sizeof(int));
        for (int i=0; i<size; i++) data[i] = i;
    }

    ierr = MPI_Scatter(&(data[0]), 1, MPI_INT,
             &recievedata, 1, MPI_INT, 0, MPI_COMM_WORLD);

    printf("Rank %d recieved <%d>\n", proc_id, recievedata);

    if (proc_id == 0) free(data);

    ierr = MPI_Finalize();
    return 0;
}

为什么不起作用,为什么会出现细分错误?当然,其他进程无权访问data;这就是重点.

why doesn't it work, and why do you get a segmentation fault? Of course the other processes don't have access to data; that's the whole point.

答案是,在非根进程中,不使用sendbuf参数(MPI_Scatter()的第一个参数).因此,非根进程不需要需要访问data.但是您仍然无法取消引用未定义的指针.因此,您需要确保所有C代码都是有效的.但是在所有其他进程上,数据可以为NULL或完全未定义;您只需要确保您不会意外取消引用它即可.这样就可以正常工作,例如:

The answer is that in the non-root processes, the sendbuf argument (the first argument to MPI_Scatter()) isn't used. So the non-root processes don't need access to data. But you still can't go around dereferencing a pointer that you haven't defined. So you need to make sure all the C code is valid. But data can be NULL or completely undefined on all the other processes; you just have to make sure you're not accidentally dereferencing it. So this works just fine, for instance:

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

int main(int argc, char **argv) {
    int proc_id, size, ierr;
    int *data;
    int recievedata;

    ierr = MPI_Init(&argc, &argv);
    ierr|= MPI_Comm_size(MPI_COMM_WORLD,&size);
    ierr|= MPI_Comm_rank(MPI_COMM_WORLD,&proc_id);

    if (proc_id == 0) {
        data = (int *)malloc(size*sizeof(int));
        for (int i=0; i<size; i++) data[i] = i;
    } else {
        data = NULL;
    }

    ierr = MPI_Scatter(data, 1, MPI_INT,      
             &recievedata, 1, MPI_INT, 0, MPI_COMM_WORLD);

    printf("Rank %d recieved <%d>\n", proc_id, recievedata);

    if (proc_id == 0) free(data);

    ierr = MPI_Finalize();
    return 0;
}

如果您在C语言中使用多维数组",并说要分散一行矩阵,则必须跳过一两个额外的箍才能完成这项工作,但这仍然很容易.

If you're using "multidimensional arrays" in C, and say scattering a row of a matrix, then you have to jump through an extra hoop or two to make this work, but it's still pretty easy.

更新:

请注意,在上面的代码中,所有称为Scatter的例程-发送方和接收方. (实际上,发送者也是接收者).

Note that in the above code, all routines called Scatter - both the sender and the recievers. (Actually, the sender is also a receiver).

在消息传递范例中,发送者和接收者都必须合作来发送数据.原则上,这些任务可以在不同的计算机上,也可能位于不同的建筑物中,它们之间没有共享的内容.因此,任务1无法将数据仅放入"任务2的某些内存中. (请注意,MPI2具有单面消息",但即使这样,也需要在发件人和收件人之间建立高度的联结性,因为必须放置一个窗口以将数据推入或拉出数据.)

In the message passing paradigm, both the sender and the receiver have to cooperate to send data. In principle, these tasks could be on different computers, housed perhaps in different buildings -- nothing is shared between them. So there's no way for Task 1 to just "put" data into some part of Task 2's memory. (Note that MPI2 has "one sided messages", but even that requires a significant degree of cordination between sender and reciever, as a window has to be put asside to push data into or pull data out of).

最典型的例子是发送/接收对. (例如)进程0向进程3发送数据是不够的,进程3还必须接收数据.

The classic example of this is send/recieve pairs; it's not enough that (say) process 0 sends data to process 3, process 3 also has to recieve data.

MPI_Scatter函数包含发送和接收逻辑.根进程(在此指定为0)发出数据,所有接收者都接收到;每个参加者都必须拨打例行程序.散布是 MPI集体行动的示例,其中通信器中的所有任务都必须调用相同的例程.广播,屏障,减少操作和收集操作是其他示例.

The MPI_Scatter function contains both send and recieve logic. The root process (specified here as 0) sends out the data, and all the recievers recieve; everyone participating has to call the routine. Scatter is an example of an MPI Collective Operation, where all tasks in the communicator have to call the same routine. Broadcast, barrier, reduction operations, and gather operations are other examples.

如果只有进程0调用分散操作,则程序将挂起,永远等待其他任务参与.

If you have only process 0 call the scatter operation, your program will hang, waiting forever for the other tasks to participate.

这篇关于有关MPI_Scatter执行器&amp;的问题它的发送缓冲区分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆