Отображение карты типов 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, пропатчить, чтобы исправить некоторые ошибки памяти, и после этого; вы получаете неотвечающий графический интерфейс. Вместо этого я ищу библиотеку / процедуру, которую я могу вызвать во время выполнения.

  • MPIDU_Datatype_deubg- это специальная для MPICH внутренняя процедура сброса типа. Он не отображает карту типов (он отображает представление цикла данных, снова закрывается)

  • Когда-то существовал отладчик под названием XMPI, который среди своих функций перечислял возможность отображать карту типов MPI. Этот отладчик, похоже, специфичен для LAM-MPI и не использует get_contents / get_envelope.


1
Правильно ли я понимаю: для заданного локально MPI_Datatypeвы ищете функцию, которая возвращает строку в форме {(type, displacement), (type, displacement), ..}, описывающей структуру указанного типа данных?
Филлип

у тебя вышло. Я обновлю вопрос, чтобы было понятнее.
Роб Лэтэм,

1
Проверьте это: [ссылка] [1] Мы еще можем найти решение или вы можете опубликовать пример кода для некоторого контекста? [1]: mpi-forum.org/docs/mpi-2.0/mpi-20-html/node161.htm
timxor

Если вы нашли / найдете ответ, я буду признателен, если вы опубликуете результат своего исследования в качестве ответа.
Лиран Фунаро

Два года спустя, а хороших решений уже нет. Он достаточно нишевый, и я думаю, что мне придется написать его самому и таким образом ответить на вопрос.
Роб Лэтэм

Ответы:


2

Как сказал Роб Лэтэм , хороших уже существующих решений не существует. С помощью ссылок, предоставленных Тимом, я создал эту функцию, доступную на 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);
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.