แสดงแผนผังพิมพ์ MPI


101

type mapเป็นสิ่งสำคัญ แต่รบกวนแนวคิดใน MPI ฉันต้องการให้กิจวัตรแสดงหรือพิมพ์แผนที่ประเภทต่างๆให้ฉัน

ตัวอย่างเช่น (นำมาจากมาตรฐาน MPI-3)

 MPI_TYPE_CREATE_RESIZED(MPI_INT, -3, 9, type1) 

ส่งผลให้พิมพ์แผนที่

{(lb_marker, -3), (int, 0), (ub_marker, 6)}.

ใช้ประเภทนั้นอีกครั้ง:

MPI_TYPE_CONTIGUOUS(2, type1, type2) 

และพิมพ์แผนที่คือ

{(lb_marker, -3), (int, 0), (int,9), (ub_marker, 15)}

ฉันต้องการวิธีแสดงแผนผังพิมพ์นั้นโดยอัตโนมัติ

แน่นอนว่าสามารถใช้MPI_Type_get_contentsและMPI_Type_get_envelopeและวนซ้ำลงมาได้จนกว่าจะกดปุ่มประเภทในตัว นี่เป็นความเจ็บปวดที่ยิ่งใหญ่และฉันคิดว่า 20 ปีจะมีเครื่องมือบางอย่างที่จะทำสิ่งนี้ให้ฉันได้

เครื่องมือบางอย่างที่มีแนวโน้ม แต่ใช้งานไม่ได้:

  • ฉันได้พบ MPImap จาก ~ 2001 ที่นี่ ก่อนอื่นต้องมีการอัปเดต Tcl / TK ที่ทันสมัยซึ่งได้รับการแก้ไขเพื่อแก้ไขข้อผิดพลาดของหน่วยความจำและหลังจากที่คุณทำเช่นนั้น คุณได้รับ GUI ที่ไม่ตอบสนอง แต่ฉันกำลังมองหาห้องสมุด / กิจวัตรที่ฉันสามารถโทรหาได้ในเวลาดำเนินการ

  • MPIDU_Datatype_deubgเป็นรูทีนการถ่ายโอนข้อมูลประเภทภายในเฉพาะของ MPICH ไม่แสดงแผนที่ประเภท (จะแสดงการเป็นตัวแทน dataloop ปิดอีกครั้ง)

  • ครั้งหนึ่งเคยมีดีบักเกอร์ที่เรียกว่า XMPI ซึ่งแสดงรายการคุณลักษณะของความสามารถในการแสดงแผนที่ประเภท MPI ตัวแก้ไขข้อบกพร่องนี้ดูเหมือนจะเป็น LAM-MPI เฉพาะและไม่ได้ใช้ประโยชน์จาก get_contents / get_envelope


1
ฉันทำให้คุณถูกต้องหรือไม่: เมื่อกำหนดไว้ในMPI_Datatypeเครื่องคุณจะค้นหาฟังก์ชันที่ส่งคืนสตริงของรูปแบบ{(type, displacement), (type, displacement), ..}ที่อธิบายโครงสร้างของประเภทข้อมูลดังกล่าวหรือไม่
Phillip

คุณได้มัน. ฉันจะอัปเดตคำถามให้ชัดเจนยิ่งขึ้น
Rob Latham

1
ลองดูสิ่งนี้: [link] [1] เรายังหาวิธีแก้ไขได้หรือยังโพสต์ตัวอย่างโค้ดสำหรับบริบทบางส่วนได้ไหม [1]: mpi-forum.org/docs/mpi-2.0/mpi-20-html/node161.htm
timxor

หากคุณได้ / จะพบคำตอบเราจะขอบคุณมากหากคุณจะโพสต์ผลการวิจัยเป็นคำตอบ
Liran Funaro

สองปีต่อมาและไม่มีโซลูชันที่มีอยู่แล้วที่ดี มันเพียงพอที่ฉันเดาว่าฉันจะต้องเขียนเองและตอบคำถามด้วยวิธีนั้น
Rob Latham

คำตอบ:


2

ดังที่Rob Lathamกล่าวไว้ไม่มีโซลูชันที่มีอยู่แล้วที่ดี ด้วยความช่วยเหลือของการเชื่อมโยงที่กำหนดโดยทิมฉันสร้างฟังก์ชั่นนี้สามารถใช้ได้บนGithub ฉันใช้ตัวอย่างของคุณสำหรับการทดสอบการปรับขนาด + ที่ต่อเนื่องกัน ( ที่นี่ ) และผลลัพธ์คือ

contiguous + resize
"(LB, -3), (MPI_INT, 0), (MPI_INT, 9), (UB, 15)"

printMapDatatype(mydatatype)ด้วยฟังก์ชันนี้คุณเพียงแค่ต้องทำ ฉันหวังว่านี่คือสิ่งที่คุณกำลังค้นหา

นี่คือฟังก์ชั่นในกรณีของ:

MPI_Aint printdatatype( MPI_Datatype datatype, MPI_Aint prevExtentTot ) { 
    int *array_of_ints; 
    MPI_Aint *array_of_adds; 
    MPI_Datatype *array_of_dtypes; 
    int num_ints, num_adds, num_dtypes, combiner; 
    int i, j; 


    MPI_Type_get_envelope( datatype, &num_ints, &num_adds, &num_dtypes, &combiner ); 

    array_of_ints = (int *) malloc( num_ints * sizeof(int) ); 
    array_of_adds = (MPI_Aint *) malloc( num_adds * sizeof(MPI_Aint) ); 
    array_of_dtypes = (MPI_Datatype *) malloc( num_dtypes * sizeof(MPI_Datatype) );

    MPI_Aint extent, subExtent;
    MPI_Type_extent(datatype, &extent);

    switch (combiner) { 
    case MPI_COMBINER_NAMED: 
        // To print the specific type, we can match against the predefined forms.

        if (datatype == MPI_BYTE)                   printf( "(MPI_BYTE, %ld)", prevExtentTot);
        else if (datatype == MPI_LB)                printf( "(MPI_LB, %ld)", prevExtentTot);
        else if (datatype == MPI_PACKED)            printf( "(MPI_PACKED, %ld)", prevExtentTot);
        else if (datatype == MPI_UB)                printf( "(MPI_UB, %ld)", prevExtentTot);
        else if (datatype == MPI_CHAR)              printf( "(MPI_CHAR, %ld)", prevExtentTot);
        else if (datatype == MPI_DOUBLE)            printf( "(MPI_DOUBLE, %ld)", prevExtentTot);
        else if (datatype == MPI_FLOAT)             printf( "(MPI_FLOAT, %ld)", prevExtentTot);
        else if (datatype == MPI_INT)               printf( "(MPI_INT, %ld)", prevExtentTot );
        else if (datatype == MPI_LONG)              printf( "(MPI_LONG, %ld)", prevExtentTot);
        else if (datatype == MPI_LONG_DOUBLE)       printf( "(MPI_LONG_DOUBLE, %ld)", prevExtentTot);
        else if (datatype == MPI_LONG_LONG)         printf( "(MPI_LONG_LONG, %ld)", prevExtentTot);
        else if (datatype == MPI_LONG_LONG_INT)     printf( "(MPI_LONG_LONG_INT, %ld)", prevExtentTot);
        else if (datatype == MPI_SHORT)             printf( "(MPI_SHORT, %ld)", prevExtentTot);
        else if (datatype == MPI_SIGNED_CHAR)       printf( "(MPI_SIGNED_CHAR, %ld)", prevExtentTot);
        else if (datatype == MPI_UNSIGNED)          printf( "(MPI_UNSIGNED, %ld)", prevExtentTot);
        else if (datatype == MPI_UNSIGNED_CHAR)     printf( "(MPI_UNSIGNED_CHAR, %ld)", prevExtentTot);
        else if (datatype == MPI_UNSIGNED_LONG)     printf( "(MPI_UNSIGNED_LONG, %ld)", prevExtentTot);
        else if (datatype == MPI_UNSIGNED_LONG_LONG)printf( "(MPI_UNSIGNED_LONG_LONG, %ld)", prevExtentTot);
        else if (datatype == MPI_UNSIGNED_SHORT)    printf( "(MPI_UNSIGNED_SHORT, %ld)", prevExtentTot);
        else if (datatype == MPI_WCHAR)             printf( "(MPI_WCHAR, %ld)", prevExtentTot);

        free( array_of_ints ); 
        free( array_of_adds ); 
        free( array_of_dtypes );

        return prevExtentTot;
        break;
    case MPI_COMBINER_DUP:
        MPI_Type_get_contents( datatype, num_ints, num_adds, num_dtypes, array_of_ints, array_of_adds, array_of_dtypes ); 

        printdatatype( array_of_dtypes[0], prevExtentTot);

        printf(", \n");

        break;
    case MPI_COMBINER_CONTIGUOUS:
        MPI_Type_get_contents( datatype, num_ints, num_adds, num_dtypes, array_of_ints, array_of_adds, array_of_dtypes ); 

        MPI_Type_extent(array_of_dtypes[0], &subExtent); // no need to do in loop because same type

        for (i=0; i < array_of_ints[0]; i++) { 
            prevExtentTot = printdatatype( array_of_dtypes[0], prevExtentTot);
            prevExtentTot += subExtent;
            printf(", ");
        }

        break;
    case MPI_COMBINER_VECTOR:
        MPI_Type_get_contents( datatype, num_ints, num_adds, num_dtypes, array_of_ints, array_of_adds, array_of_dtypes ); 

        MPI_Type_extent(array_of_dtypes[0], &subExtent); // no need to do in loop because same type

        printf("[");
        for (i = 0; i < array_of_ints[0]; i++) { //count
            printf( "BL : %d - ", array_of_ints[1]);
            for (j = 0; j < array_of_ints[2]; j++) { // stride
                if (j < array_of_ints[1]) { // if in blocklength
                    prevExtentTot = printdatatype( array_of_dtypes[0], prevExtentTot);
                    printf(", ");
                }
                prevExtentTot += subExtent;

            }
        }
        printf("], ");

        break;
    case MPI_COMBINER_HVECTOR:
    case MPI_COMBINER_HVECTOR_INTEGER:{
        MPI_Aint backupPrevExtent = prevExtentTot;

        MPI_Type_get_contents( datatype, num_ints, num_adds, num_dtypes, array_of_ints, array_of_adds, array_of_dtypes ); 

        MPI_Type_extent(array_of_dtypes[0], &subExtent); // no need to do in loop because same type

        printf("[");
        for (i = 0; i < array_of_ints[0]; i++) { //count
            printf( "BL : %d - ", array_of_ints[1]);
            for (j = 0; j < array_of_ints[1]; j++) { // blocklength
                prevExtentTot = printdatatype( array_of_dtypes[0], prevExtentTot);
                printf(", ");
                prevExtentTot += subExtent;
            }
            prevExtentTot = backupPrevExtent + array_of_adds[0]; // + stride un byte
        }
        printf("], ");

        break;
    }
    case MPI_COMBINER_INDEXED:{
        MPI_Aint tmpPrevExtent;
        int count, blocklength;
        MPI_Type_get_contents( datatype, num_ints, num_adds, num_dtypes, array_of_ints, array_of_adds, array_of_dtypes ); 

        MPI_Type_extent(array_of_dtypes[0], &subExtent); // no need to do in loop because same type

        printf("<");
        count = array_of_ints[0];
        for (i = 0; i < count; i++) { // count
            blocklength = array_of_ints[i + 1]; // array of blocklength
            tmpPrevExtent = prevExtentTot;
            tmpPrevExtent += array_of_ints[count + 1 + i] * subExtent; // + displacement * size of block
            printf( "BL : %d - ", blocklength);
            for (j = 0; j < blocklength; j++) { // blocklength
                tmpPrevExtent = printdatatype( array_of_dtypes[0], tmpPrevExtent);
                printf(", ");
                tmpPrevExtent += subExtent;
            }
        }
        printf(">, ");

        prevExtentTot = tmpPrevExtent;

        break;
    }
    case MPI_COMBINER_HINDEXED:
    case MPI_COMBINER_HINDEXED_INTEGER:{
        MPI_Aint tmpPrevExtent;
        int count, blocklength;
        MPI_Type_get_contents( datatype, num_ints, num_adds, num_dtypes, array_of_ints, array_of_adds, array_of_dtypes ); 

        MPI_Type_extent(array_of_dtypes[0], &subExtent); // no need to do in loop because same type

        printf("<");
        count = array_of_ints[0];
        for (i = 0; i < count; i++) { // count
            blocklength = array_of_ints[i + 1]; // array of blocklength
            tmpPrevExtent = prevExtentTot;
            tmpPrevExtent += array_of_adds[i]; // + displacement in byte
            printf( "BL : %d - ", blocklength);
            for (j = 0; j < blocklength; j++) {
                tmpPrevExtent = printdatatype( array_of_dtypes[0], tmpPrevExtent);
                printf(", ");
                tmpPrevExtent += subExtent;
            }
        }
        printf(">, ");

        prevExtentTot = tmpPrevExtent;

        break;
    }
    case MPI_COMBINER_INDEXED_BLOCK:{
        MPI_Aint tmpPrevExtent;
        int count;
        MPI_Type_get_contents( datatype, num_ints, num_adds, num_dtypes, array_of_ints, array_of_adds, array_of_dtypes ); 

        MPI_Type_extent(array_of_dtypes[0], &subExtent); // no need to do in loop because same type

        printf("<");
        count = array_of_ints[0];
        for (i = 0; i < count; i++) { // count
            tmpPrevExtent = prevExtentTot;
            tmpPrevExtent += array_of_ints[i + 2] * subExtent; // + displacement * size of block
            printf( "BL : %d - ", array_of_ints[i + 1]);
            for (j = 0; j < array_of_ints[1]; j++) { // blocklength
                tmpPrevExtent = printdatatype( array_of_dtypes[0], tmpPrevExtent);
                printf(", ");
                tmpPrevExtent += subExtent;
            }
        }
        printf(">, ");

        prevExtentTot = tmpPrevExtent;

        break;
    }
    case MPI_COMBINER_STRUCT: 
    case MPI_COMBINER_STRUCT_INTEGER:{
        MPI_Aint tmpPrevExtent;
        MPI_Type_get_contents( datatype, num_ints, num_adds, num_dtypes, array_of_ints, array_of_adds, array_of_dtypes ); 

        printf( "{"); 
        for (i = 0; i < array_of_ints[0]; i++) { // count
            tmpPrevExtent = prevExtentTot + array_of_adds[i]; // origin + displacement
            printf( "BL : %d - ", array_of_ints[i + 1]);
            tmpPrevExtent = printdatatype( array_of_dtypes[i], tmpPrevExtent);
            tmpPrevExtent += subExtent;
            printf(", ");
        }
        printf("}, ");

        prevExtentTot = tmpPrevExtent;

        break;
    }
    case MPI_COMBINER_SUBARRAY:
        // I don't know what is interresting to display here...
        printf("... subarray not handled ...");
        break;
    case MPI_COMBINER_DARRAY:
        // Same
        printf("... darray not handled ...");
        break;
    case MPI_COMBINER_RESIZED:
        MPI_Type_get_contents( datatype, num_ints, num_adds, num_dtypes, array_of_ints, array_of_adds, array_of_dtypes );

        prevExtentTot = printdatatype( array_of_dtypes[0], prevExtentTot);

        printf(", \n");

        break;
    default: 
        printf( "Unrecognized combiner type\n" ); 
    } 

    free( array_of_ints ); 
    free( array_of_adds ); 
    free( array_of_dtypes );

    return prevExtentTot;
}

void printMapDatatype(MPI_Datatype datatype) {
    MPI_Aint lb, ub;
    MPI_Type_lb(datatype, &lb);
    MPI_Type_ub(datatype, &ub);

    printf("\"(LB, %ld), ", lb);
    printdatatype(datatype, 0);
    printf("(UB, %ld)\"\n", ub);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.