ข้อผิดพลาดการส่งและรับ MPI ไม่ทำงาน

ฉันได้เขียนโค้ดต่อไปนี้เป็นการทดสอบที่ฉันได้รับจากโปรเซสเซอร์แต่ละตัวเป็นอาร์เรย์ และฉันกำลังวางไว้ในอาร์เรย์โฆษณา 2D แต่ละแถวใช้สำหรับอาร์เรย์จากโปรเซสเซอร์ที่แตกต่างกัน

#include <iostream>
#include <mpi.h>

using namespace std;

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

    int *sendBuff;
    int **table;
    int size, rank;
    MPI_Status stat;
    int pass = 1;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    sendBuff = new int[10];
    printf("task %d passed %d\n", rank, pass); //1
    pass++;
    if (rank == 0)
    {
        table = new int*[size];
    }
    for (int i = 0; i < 10; i++)
    {
        sendBuff[i] = rank;
    }

    printf("task %d passed %d\n", rank, pass); //2
    pass++;
    if (rank != 0)
    {
        MPI_Send(&sendBuff, 10, MPI_INT, 0, rank, MPI_COMM_WORLD);
    }

    printf("task %d passed %d\n", rank, pass); //3
    pass++;
    if (rank == 0)
    {
        table[0] = sendBuff;
        for (int i = 1; i < size; i++)
        {
            MPI_Recv(&table[i], 10, MPI_INT, i, i, MPI_COMM_WORLD, &stat);
        }
    }
    printf("task %d passed %d\n", rank, pass); //4
    pass++;
    delete[] sendBuff;
    if (rank == 0)
    {
        for (int i = 0; i < size; i++)
        {
            delete[] table[i];
        }
        delete[] table;
    }

    MPI_Finalize();
    return 0;
}

แต่มันไม่ได้วิ่งอยู่ฉันใช้อยู่

mpirun -np 4 a.out

และฉันได้รับสิ่งต่อไปนี้:

    [arch:03429] *** Process received signal ***
[arch:03429] Signal: Aborted (6)
[arch:03429] Signal code:  (-6)
[arch:03429] [ 0] /usr/lib/libpthread.so.0(+0xf870) [0x7fd2675bd870]
[arch:03429] [ 1] /usr/lib/libc.so.6(gsignal+0x39) [0x7fd2672383d9]
[arch:03429] [ 2] /usr/lib/libc.so.6(abort+0x148) [0x7fd2672397d8]
[arch:03429] [ 3] /usr/lib/libc.so.6(+0x72e64) [0x7fd267275e64]
[arch:03429] [ 4] /usr/lib/libc.so.6(+0x7862e) [0x7fd26727b62e]
[arch:03429] [ 5] /usr/lib/libc.so.6(+0x79307) [0x7fd26727c307]
[arch:03429] [ 6] a.out() [0x408704]
[arch:03429] [ 7] /usr/lib/libc.so.6(__libc_start_main+0xf5) [0x7fd267224bc5]
[arch:03429] [ 8] a.out() [0x408429]
[arch:03429] *** End of error message ***
--------------------------------------------------------------------------
mpirun noticed that process rank 0 with PID 3429 on node arch exited on signal 6 (Aborted).
--------------------------------------------------------------------------

ความช่วยเหลือใด ๆ ?


person Wissam Y. Khalil    schedule 12.12.2013    source แหล่งที่มา
comment
เมื่อส่งตัวแปรพอยน์เตอร์ เช่น sendBuf ของคุณไปยัง MPI_Send หรือ MPI_Recv คุณไม่จำเป็นต้องมี & เพิ่มเติม   -  person Hristo Iliev    schedule 13.12.2013


คำตอบ (1)


ดังที่ Hristo Iliev ชี้ให้เห็น อาร์เรย์ sendBuf ควรเป็นอาร์กิวเมนต์ของ MPI_Send มันทำงานในลักษณะเดียวกันกับ table[i]

ข้อเท็จจริงอีกประการหนึ่ง: MPI_Send และ MPI_Recv ไม่ได้จัดสรรหน่วยความจำ ฟังก์ชั่นเหล่านี้เพียงคัดลอกข้อความจากที่หนึ่งไปยังอีกที่หนึ่ง ควรจัดสรรทั้ง sendBuff และ table[i] ก่อนหน้านี้ และการเขียน table[0]=sendBuff จะทำให้หน่วยความจำรั่ว

นี่คือรหัสที่อาจช่วยคุณได้:

#include <iostream>
#include <mpi.h>

using namespace std;

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

    int *sendBuff;
    int **table;
    int size, rank;
    MPI_Status stat;
    int pass = 1;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    sendBuff = new int[10];
    printf("firts task %d passed %d\n", rank, pass); //1
    pass++;
    if (rank == 0)
    {
        table = new int*[size];
    }
    for (int i = 0; i < 10; i++)
    {
        sendBuff[i] = rank;
    }

    printf("second task %d passed %d\n", rank, pass); //2
    pass++;
    if (rank != 0)
    {
        MPI_Send(sendBuff, 10, MPI_INT, 0, rank, MPI_COMM_WORLD);
    }

    printf("thrid task %d passed %d\n", rank, pass); //3
    pass++;
    if (rank == 0)
    {
    table[0]=new int[10];
    for(int i=0;i<10;i++){
        table[0][i]=sendBuff[i];
}
       // table[0] = sendBuff;
        for (int i = 1; i < size; i++)
        {
    table[i]=new int[10];
            MPI_Recv(table[i], 10, MPI_INT, i, i, MPI_COMM_WORLD, &stat);
        }
    }
    printf("fourth task %d passed %d\n", rank, pass); //4
    pass++;


    if (rank == 0)
    {
        for (int i = 0; i < size; i++)
        {
            delete [] table[i];
        table[i]=NULL;
        }
        delete [] table;
    }

delete [] sendBuff;

    MPI_Finalize();
    return 0;
}

ฟังก์ชั่นที่อาจช่วยคุณได้ : MPI_Gather(...) ดูเหมือนว่าจะเป็นสิ่งที่คุณกำลังมองหา! ดูการจัดสรรหน่วยความจำหากคุณต้องการใช้ : ค่าทั้งหมดของตารางควรได้รับการจัดสรรเป็นหน่วยความจำที่ต่อเนื่องกันหนึ่งชิ้น

http://www.mcs.anl.gov/research/projects/mpi/www/www3/MPI_Gather.html

ลาก่อน,

ฟรานซิส

person francis    schedule 13.12.2013