Wyświetl mapę typu MPI

101

type mapJest ważnym ale mylących koncepcja w MPI. Chciałbym, aby procedura wyświetlała lub drukowała dla mnie mapę typów.

Na przykład (wzięty ze standardu MPI-3),

 MPI_TYPE_CREATE_RESIZED(MPI_INT, -3, 9, type1) 

powoduje wyświetlenie mapy typu

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

Użyj tego typu ponownie:

MPI_TYPE_CONTIGUOUS(2, type1, type2) 

a typ mapy to

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

Chciałbym mieć sposób na automatyczne wyświetlanie tej mapy typu.

Z pewnością można by używać MPI_Type_get_contentsi MPI_Type_get_envelopei rekurencyjnie schodzić, aż do trafienia w typy wbudowane. To raczej ogromny ból i pomyślałbym, że będzie istnieć 20 lat na jakimś narzędziu, które zrobi to za mnie.

Niektóre narzędzia, które są obiecujące, ale nie do końca działają:

  • Znalazłem MPImap z ~ 2001 tutaj . Po pierwsze, musi zostać zaktualizowany dla współczesnego Tcl / TK, załatany, aby rozwiązać niektóre błędy pamięci, a potem to zrobić; otrzymujesz niereagujący GUI. Zamiast tego szukam biblioteki / procedury, do której mogę zadzwonić w czasie wykonywania.

  • MPIDU_Datatype_deubgjest wewnętrzną procedurą dumpingową specyficzną dla MPICH. Nie wyświetla mapy typów (wyświetla reprezentację dataloop, ponownie zamknij)

  • Był kiedyś debugger o nazwie XMPI, który wśród swoich funkcji wymienia możliwość wyświetlania mapy typu MPI. Ten debugger wydaje się być specyficzny dla LAM-MPI i nie używa get_contents / get_envelope.

Rob Latham
źródło
1
Czy dobrze rozumiem: biorąc pod uwagę lokalnie zdefiniowaną MPI_Datatypefunkcję, szukasz funkcji, która zwraca ciąg w postaci {(type, displacement), (type, displacement), ..}opisującej strukturę wspomnianego typu danych?
Phillip
masz to. Zaktualizuję pytanie, aby było bardziej jasne.
Rob Latham
1
Sprawdź to: [link] [1] Udało Ci się już znaleźć rozwiązanie, czy możesz opublikować przykładowy fragment kodu dla jakiegoś kontekstu? [1]: mpi-forum.org/docs/mpi-2.0/mpi-20-html/node161.htm
timxor
Jeśli znalazłeś / znajdziesz odpowiedź, byłbym wdzięczny, gdybyś zamieścił swój wynik badania jako odpowiedź.
Liran Funaro
Dwa lata później nie ma dobrych, istniejących wcześniej rozwiązań. To na tyle nisza, że ​​chyba będę musiał sam to napisać i odpowiedzieć na pytanie w ten sposób.
Rob Latham

Odpowiedzi:

2

Jak powiedział Rob Latham , nie ma dobrych, istniejących wcześniej rozwiązań. Z pomocą linków podanych przez Tima stworzyłem tę funkcję dostępną na Githubie . Wziąłem twój przykład dla testu ciągłego + zmiany rozmiaru ( tutaj ), a wynik to

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

Dzięki tej funkcji po prostu musisz to zrobić printMapDatatype(mydatatype). Mam nadzieję, że właśnie tego szukałeś.

Oto funkcja, tylko w przypadku:

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);
}
Taknok
źródło