Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display a MPI typemap

Tags:

mpi

typemaps

The type map is an important but confounding concept in MPI. I would like a routine to display or print a type map for me.

For example (taken from the MPI-3 standard),

 MPI_TYPE_CREATE_RESIZED(MPI_INT, -3, 9, type1)  

results in the typemap

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

Use that type again:

MPI_TYPE_CONTIGUOUS(2, type1, type2)  

and the typemap is

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

I would like a way to display that typemap automatically.

Certainly one could use MPI_Type_get_contents and MPI_Type_get_envelope and recursively descend until hitting the built-in types. This is rather a giant pain and I would have thought 20 years on some tool would exist to do this for me.

Some tools that are promising, but not quite working:

  • I had found MPImap from ~ 2001 here. First, it needs to be updated for modern Tcl/TK, patched to address some memory errors and after you do that; you get an unresponsive GUI. Instead, I'm looking for a library/routine I can call at run time.

  • MPIDU_Datatype_deubg is an MPICH specific internal type-dumping routine. It does not display the type map (it does display the dataloop representation, again close)

  • There once was a debugger called XMPI that lists among its features the ability to display a MPI type map. This debugger appears to be LAM-MPI specific and does not make use of get_contents/ get_envelope.

like image 335
Rob Latham Avatar asked Jan 21 '15 19:01

Rob Latham


1 Answers

As Rob Latham said, there isn't good pre-existing solutions. With the help of the links given by tim I created this function available on Github. I took your example for the contiguous + resize test (here) and the output is

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

With this function you just need to do printMapDatatype(mydatatype). I hope this was what you was searching for.

Here is the function, just in case of :

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); } 
like image 129
Taknok Avatar answered Oct 15 '22 08:10

Taknok