2015-01-21 3 views
96

Il type map è un concetto importante, ma per confondere in MPI. Vorrei una routine per visualizzare o stampare una mappa dei tipi per me.Visualizzare una typemap MPI

Ad esempio (tratto dallo standard MPI-3),

MPI_TYPE_CREATE_RESIZED(MPI_INT, -3, 9, type1) 

risultati nella typemap

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

usare quel tipo nuovo:

MPI_TYPE_CONTIGUOUS(2, type1, type2) 

e typemap è

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

Vorrei un modo per visualizzare automaticamente quella tipografia.

Certamente si potrebbe usare MPI_Type_get_contents e MPI_Type_get_envelope e ricorsivamente scendere fino a colpire i tipi built-in. Questo è piuttosto un dolore gigantesco e avrei pensato che 20 anni su alcuni strumenti esistessero per fare questo per me.

alcuni strumenti che sono promettenti, ma non funziona del tutto:

  • avevo trovato MPImap da ~ 2001 here. Innanzitutto, deve essere aggiornato per il Tcl/TK moderno, corretto per risolvere alcuni errori di memoria e dopo averlo fatto; ottieni una GUI non rispondente. Invece, sto cercando una libreria/routine che posso chiamare in fase di esecuzione.

  • MPIDU_Datatype_deubg è una routine di tipo-dumping interno specifica per MPICH. Esso non visualizza il tipo di mappa (lo fa visualizzare la rappresentazione dataloop, ancora una volta vicino)

  • C'era una volta un debugger chiamato XMPI che elenca tra le sue caratteristiche la possibilità di visualizzare una mappa di tipo MPI. Questo debugger sembra essere specifico per LAM-MPI e non utilizza get_contents/get_envelope.

+1

faccio ad avere il tasto destro: dato un definito localmente 'MPI_Datatype', si cerca una funzione che restituisce una stringa della forma' {(tipo, spostamento), (tipo, spostamento), ...} 'che descrive la struttura di detto tipo di dati? – Phillip

+0

ce l'hai. Aggiornerò la domanda per essere più chiara. –

+1

Dai un'occhiata a questo: [collegamento] [1] Siamo in grado di trovare ancora una soluzione o puoi pubblicare un esempio di codice di frammento per qualche contesto? [1]: http://mpi-forum.org/docs/mpi-2.0/mpi-20-html/node161.htm –

risposta

1

Come Rob Latham detto, non c'è buone soluzioni pre-esistenti. Con l'aiuto dei collegamenti forniti da tim ho creato questa funzione disponibile su Github. Ho preso il vostro esempio per la contigua + ridimensionare prova (here) e l'uscita è

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

Con questa funzione è solo bisogno di fare printMapDatatype(mydatatype). Spero che questo fosse quello che stavi cercando.

Qui è la funzione, solo in caso di:

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