Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/selenium/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 与多对多处理器通信时出现MPI错误_C++_Mpi_Openmpi - Fatal编程技术网

C++ 与多对多处理器通信时出现MPI错误

C++ 与多对多处理器通信时出现MPI错误,c++,mpi,openmpi,C++,Mpi,Openmpi,我正在编写一个代码,其中每个处理器必须与多个处理器交互 我有12个处理器,所以处理器0必须通信,比如1、2、10和9。让我们将它们称为处理器0的邻居。我也有 处理器1必须通信,例如5、3。 处理器2必须与5,1,0,10,11通信 等等 数据流有两种方式,即处理器0必须向1、2、10和9发送数据,并从中接收数据。 此外,在标记计算中也没有问题。 我创建了一个代码,其工作原理如下: for(all neighbours) { store data in vector<double>

我正在编写一个代码,其中每个处理器必须与多个处理器交互

我有12个处理器,所以处理器0必须通信,比如1、2、10和9。让我们将它们称为处理器0的邻居。我也有 处理器1必须通信,例如5、3。 处理器2必须与5,1,0,10,11通信 等等 数据流有两种方式,即处理器0必须向1、2、10和9发送数据,并从中接收数据。 此外,在标记计算中也没有问题。 我创建了一个代码,其工作原理如下:

for(all neighbours) 
{
store data in vector<double> x;

     MPI_Send(x)
}
MPI_BARRIER();
for(all neighbours)
{
MPI_Recv(x);
do work with x
}
用于(所有邻居)
{
在向量x中存储数据;
MPI_发送(x)
}
MPI_屏障();
(所有邻居)
{
MPI_Recv(x);
与x一起工作
}
现在,我将针对不同大小的x和不同的邻居安排测试该算法。代码对某些人有效,但对其他人无效,它只是诉诸死锁。 我也尝试过:

for(all neighbours) 
{
store data in vector<double> x;

     MPI_ISend(x)
}
MPI_Test();
for(all neighbours)
{
MPI_Recv(x);
do work with x
}
用于(所有邻居)
{
在向量x中存储数据;
MPI_ISend(x)
}
MPI_测试();
(所有邻居)
{
MPI_Recv(x);
与x一起工作
}
结果是一样的,尽管死锁在结果中被NaN回复,因为MPI_Test()告诉我一些MPI_Isend()操作没有完成,它会立即跳到MPI_Recv()

有谁能在这件事上给我指点迷津,我怎么了?还是我的基本方法本身是错误的

编辑:为了更好地理解这个问题,我附上了代码片段。我主要致力于非结构化3D-CFD解算器的并行化

我附上了其中一份文件,附有一些解释。我不是在广播,而是在父处理器的邻居之间循环,通过接口发送数据(这可以定义为两个接口之间的边界)

所以,假设我有12个处理器,处理器0必须与1、2、10和9通信。因此,0是父处理器,1、2、10和9是它的邻居

由于文件太长,并且是解算器的一部分,为了简化,我只保留了MPI函数

void Reader::MPI_InitializeInterface_Values() {
double nbr_interface_id;
Interface *interface;
MPI_Status status;
MPI_Request send_request, recv_request;
int err, flag;
int err2;
char buffer[MPI_MAX_ERROR_STRING];
int len;
int count;


for (int zone_no = 0; zone_no<this->GetNumberOfZones(); zone_no++) { // Number of zone per processor is 1, so basically each zone is an independent processor
    UnstructuredGrid *zone = this->ZoneList[zone_no];
    int no_of_interface = zone->GetNumberOfInterfaces();
    // int count;
    long int count_send = 0;
    long int count_recv = 0;
    long int max_size = 10000; // can be set from test case later
    int max_size2 = 199;

    int proc_no = FlowSolution::processor_number;
    for (int interface_no = 0; interface_no < no_of_interface; interface_no++) { // interface is defined as a boundary between two zones


        interface = zone->GetInterface(interface_no);
        int no_faces = interface->GetNumberOfFaces();
        if (no_faces != 0) {

            std::vector< double > Variable_send; // The vector which stores the data to be sent across the interface
            std::vector< double > Variable_recieve;
            int total_size = FlowSolution::VariableOrder.size() * no_faces;
            Variable_send.resize(total_size);
            Variable_recieve.resize(total_size);
            int nbr_proc_no = zone->GetInterface(interface_no)->GetNeighborZoneId(); // neighbour of parent processor

                int j = 0;
                nbr_interface_id = interface->GetShared_Interface_ID();

                for (std::map<VARIABLE, int>::iterator iterator = FlowSolution::VariableOrder.begin(); iterator != FlowSolution::VariableOrder.end(); iterator++) {

                    for (int face_no = 0; face_no < no_faces; face_no++) {
                        Face *face = interface->GetFace(face_no);
                        int owner_id = face->Getinterface_Original_face_owner_id();
                        double value_send = zone->GetInterface(interface_no)->GetFace(face_no)->GetCell(owner_id)->GetPresentFlowSolution()->GetVariableValue((*iterator).first);
                        Variable_send[j] = value_send;
                        j++;
                    }
                }
                count_send = nbr_proc_no * max_size + nbr_interface_id; // tag for data to be sent
                err2 = MPI_Isend(&Variable_send.front(), total_size, MPI_DOUBLE, nbr_proc_no, count_send, MPI_COMM_WORLD, &send_request);
        }// end of sending

    } // all the processors have sent data to their corresponding neighbours

    MPI_Barrier(MPI_COMM_WORLD);

    for (int interface_no = 0; interface_no < no_of_interface; interface_no++) { // loop over of neighbours of the current processor to receive data

        interface = zone->GetInterface(interface_no);
        int no_faces = interface->GetNumberOfFaces();
        if (no_faces != 0) {
            std::vector< double > Variable_recieve; // The vector which collects the data sent across the interface from 
            int total_size = FlowSolution::VariableOrder.size() * no_faces;
            Variable_recieve.resize(total_size);
            count_recv = proc_no * max_size + interface_no; // tag to receive data
            int nbr_proc_no = zone->GetInterface(interface_no)->GetNeighborZoneId();
            nbr_interface_id = interface->GetShared_Interface_ID();
                MPI_Irecv(&Variable_recieve.front(), total_size, MPI_DOUBLE, nbr_proc_no, count_recv, MPI_COMM_WORLD, &recv_request);

                /* Now some work is done using received data */
                int j = 0;
                for (std::map<VARIABLE, int>::iterator iterator = FlowSolution::VariableOrder.begin(); iterator != FlowSolution::VariableOrder.end(); iterator++) {
                    for (int face_no = 0; face_no < no_faces; face_no++) {
                        double value_recieve = Variable_recieve[j];
                        j++;
                        Face *face = interface->GetFace(face_no);
                        int owner_id = face->Getinterface_Original_face_owner_id();
                        interface->GetFictitiousCell(face_no)->GetPresentFlowSolution()->SetVariableValue((*iterator).first, value_recieve);
                        double value1 = face->GetCell(owner_id)->GetPresentFlowSolution()->GetVariableValue((*iterator).first);
                        double face_value = 0.5 * (value1 + value_recieve);
                        interface->GetFace(face_no)->GetPresentFlowSolution()->SetVariableValue((*iterator).first, face_value);
                    }
                }
                // Variable_recieve.clear();

        }

    }// end of receiving
void读取器::MPI\u初始化接口\u值(){
双nbr\U接口\U id;
接口*接口;
MPI_状态;
MPI请求发送请求、接收请求;
int err,flag;
INTERR2;
字符缓冲区[MPI_MAX_ERROR_STRING];
内伦;
整数计数;
对于(int zone_no=0;zone_noGetNumberOfZones();zone_no++){//每个处理器的分区数是1,因此基本上每个分区都是一个独立的处理器
UnstructuredGrid*zone=此->区域列表[区域编号];
int no_of_interface=zone->GetNumberOfInterfaces();
//整数计数;
长整数计数_send=0;
长整数计数_recv=0;
long int max_size=10000;//可以稍后从测试用例中设置
int max_size=199;
int proc_no=FlowSolution::处理器编号;
对于(int interface_no=0;interface_no获取接口(接口号);
int no_faces=interface->GetNumberOfFaces();
如果(没有面!=0){
std::vectorVariable_send;//存储要通过接口发送的数据的向量
标准::向量变量接收;
int total_size=FlowSolution::VariableOrder.size()*无面;
变量_send.resize(总大小);
变量_receive.resize(总大小);
int nbr_proc_no=zone->GetInterface(interface_no)->GetNeighborZoneId();//父处理器的邻居
int j=0;
nbr_interface_id=interface->GetShared_interface_id();
对于(std::map::iterator iterator=FlowSolution::VariableOrder.begin();iterator!=FlowSolution::VariableOrder.end();iterator++){
对于(int face_no=0;face_noGetFace(面号);
int owner_id=face->Getinterface_Original_face_owner_id();
double value\u send=zone->GetInterface(interface\u no)->GetFace(face\u no)->GetCell(owner\u id)->GetPresentFlowSolution()->GetVariableValue((*迭代器).first;
变量_send[j]=值_send;
j++;
}
}
count\u send=nbr\u proc\u no*max\u size+nbr\u interface\u id;//要发送的数据的标记
err2=MPI发送(&Variable\u send.front()、总大小、MPI双精度、nbr\u进程号、计数发送、MPI通信世界和发送请求);
}//发送结束
}//所有处理器都已向其相应的邻居发送数据
MPI_屏障(MPI_通信世界);
对于(int interface_no=0;interface_no<_interface的no;interface_no++){//循环当前处理器的邻居以接收数据
接口=区域->获取接口(接口号);
int no_faces=interface->GetNumberOfFaces();
如果(没有面!=0){
std::vectorVariable_receive;//收集通过接口从
int total_size=FlowSolution::VariableOrder.size()*无面;
变量_receive.resize(总大小);
count\u recv=proc\u no*max\u size+interface\u no;//用于接收数据的标记
int nbr_proc_no=zone->GetInterface(interface_no)->GetNeighborZoneId();
nbr_interface_id=interface->GetShared_interface_id();
MPI\u Irecv(&Variable\u recieve.front()、总大小、MPI\u DOUBLE、nbr\u进程号、计数记录、MPI\u通信世界和记录请求);
/*现在使用接收到的数据完成了一些工作*/
int j=0;
对于(std::map::iterator iterator=FlowSolution::VariableOrder.begin();iterator!=FlowSolution::VariableOrder.end();iterator++){
对于(int face_no=0;face_noMPI_Request req[n];

MPI_Irecv(..., req[0]);
// ...
MPI_Irecv(..., req[n-1]);
MPI_Isend(..., req[0]);
// ...
MPI_Isend(..., req[n-1]);

MPI_Waitall(n, req, MPI_STATUSES_IGNORE);