显示一个MPItypes图

type map在MPI中是一个重要而混乱的概念。 我想要一个例程为我显示或打印一个types映射。

例如(取自MPI-3标准),

  MPI_TYPE_CREATE_RESIZED(MPI_INT, -3, 9, type1) 

结果在typemap中

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

再次使用该types:

 MPI_TYPE_CONTIGUOUS(2, type1, type2) 

和typemap是

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

我想自动显示该types图的方法。

当然可以使用MPI_Type_get_contentsMPI_Type_get_envelope并recursion下降,直到达到内置types。 这是一个巨大的痛苦,我会想到20年的一些工具将存在为我做这个。

一些有希望的工具,但不是很有效:

  • 我在这里发现了〜2001年的MPImap。 首先,它需要更新为现代Tcl / TK,修补以解决一些内存错误,然后你这样做; 你得到一个没有反应的GUI。 相反,我正在寻找一个我可以在运行时调用的库/例程。

  • MPIDU_Datatype_deubg是MPICH特定的内部types转储例程。 它不显示types映射(它显示dataloop表示,再次closures)

  • 曾经有一个名为XMPI的debugging器在其function中列出了显示MPItypes映射的能力。 这个debugging器似乎是特定于LAM-MPI的,并没有使用get_contents / get_envelope。

正如Rob Latham所说,现有的解决scheme并不完善。 在tim给出的链接的帮助下,我在Github上创build了这个函数。 我把你的例子作为连续的+resizetesting( 在这里 ),输出是

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

有了这个函数,你只需要做printMapDatatype(mydatatype) 。 我希望这是你正在寻找的东西。

以下是该function,以防万一:

 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); }