ompi_datatype_t* test_contiguous( void ) { ompi_datatype_t *pdt, *pdt1, *pdt2; printf( "test contiguous (alignment)\n" ); ompi_datatype_create_contiguous(0, &ompi_mpi_datatype_null.dt, &pdt1); ompi_datatype_add( pdt1, &ompi_mpi_double.dt, 1, 0, -1 ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt1 ); } ompi_datatype_add( pdt1, &ompi_mpi_char.dt, 1, 8, -1 ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt1 ); } ompi_datatype_create_contiguous( 4, pdt1, &pdt2 ); OBJ_RELEASE( pdt1 ); /*assert( pdt1 == NULL );*/ if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt2 ); } ompi_datatype_create_contiguous( 2, pdt2, &pdt ); OBJ_RELEASE( pdt2 ); /*assert( pdt2 == NULL );*/ if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt ); } return pdt; }
ompi_datatype_t* test_struct( void ) { ompi_datatype_t* types[] = { &ompi_mpi_float.dt /* ompi_datatype_basicDatatypes[DT_FLOAT] */, NULL, &ompi_mpi_char.dt /* ompi_datatype_basicDatatypes[DT_CHAR] */ }; int lengths[] = { 2, 1, 3 }; MPI_Aint disp[] = { 0, 16, 26 }; ompi_datatype_t* pdt, *pdt1; printf( "test struct\n" ); ompi_datatype_create_contiguous(0, &ompi_mpi_datatype_null.dt, &pdt1); ompi_datatype_add( pdt1, &ompi_mpi_double.dt, 1, 0, -1 ); ompi_datatype_add( pdt1, &ompi_mpi_char.dt, 1, 8, -1 ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt1 ); } types[1] = pdt1; ompi_datatype_create_struct( 3, lengths, disp, types, &pdt ); OBJ_RELEASE( pdt1 ); /*assert( pdt1 == NULL );*/ if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt ); } return pdt; }
ompi_datatype_t* create_strange_dt( void ) { sdata_intern v[2]; MPI_Aint displ[3]; ompi_datatype_t* types[3] = { &ompi_mpi_int.dt }; sstrange t[2]; int pBlock[3] = {1, 10, 1}, dispi[3]; ompi_datatype_t *pdt, *pdt1, *pdt2, *pdtTemp; dispi[0] = (int)((char*)&(v[0].i1) - (char*)&(v[0])); /* 0 */ dispi[1] = (int)(((char*)(&(v[0].i2)) - (char*)&(v[0])) / sizeof(int)); /* 2 */ ompi_datatype_create_indexed_block( 2, 1, dispi, &ompi_mpi_int.dt, &pdtTemp ); #ifdef USE_RESIZED /* optional */ displ[0] = 0; displ[1] = (char*)&(v[1]) - (char*)&(v[0]); ompi_datatype_create_resized( pdtTemp, displ[0], displ[1], &pdt1 ); OBJ_RELEASE( pdtTemp ); assert( pdtTemp == NULL ); #else pdt1 = pdtTemp; #endif /* USE_RESIZED */ types[1] = pdt1; types[2] = &ompi_mpi_int.dt; displ[0] = 0; displ[1] = (long)((char*)&(t[0].v[0]) - (char*)&(t[0])); displ[2] = (long)((char*)&(t[0].last) - (char*)&(t[0])); ompi_datatype_create_struct( 3, pBlock, displ, types, &pdtTemp ); #ifdef USE_RESIZED /* optional */ displ[1] = (char*)&(t[1]) - (char*)&(t[0]); ompi_datatype_create_resized( pdtTemp, displ[0], displ[1], &pdt2 ); OBJ_RELEASE( pdtTemp ); assert( pdtTemp == NULL ); #else pdt2 = pdtTemp; #endif /* USE_RESIZED */ ompi_datatype_create_contiguous( SSTRANGE_CNT, pdt2, &pdt ); OBJ_RELEASE( pdt1 ); OBJ_RELEASE( pdt2 ); printf( "\nStrange datatype BEFORE COMMIT\n" ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt ); } ompi_datatype_commit( &pdt ); printf( "\nStrange datatype AFTER COMMIT\n" ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt ); } return pdt; }
ompi_datatype_t* test_create_blacs_type2( const ompi_datatype_t* base_type ) { ompi_datatype_t *pdt; ompi_datatype_create_vector( 7, 1, 2, base_type, &pdt ); ompi_datatype_commit( &pdt ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt ); } return pdt; }
ompi_datatype_t* test_create_blacs_type( void ) { ompi_datatype_t *pdt; ompi_datatype_create_indexed( 18, blacs_length, blacs_indices, &ompi_mpi_int.dt, &pdt ); ompi_datatype_commit( &pdt ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt ); } return pdt; }
ompi_datatype_t* test_create_twice_two_doubles( void ) { ompi_datatype_t* pdt; ompi_datatype_create_vector( 2, 2, 5, &ompi_mpi_double.dt, &pdt ); ompi_datatype_commit( &pdt ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt ); } return pdt; }
int main(int argc, char *argv[]) { int i; int myrank; MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); if (0 == myrank) { for (i = 1; i < OMPI_DATATYPE_MPI_MAX_PREDEFINED-1; i++) { ompi_datatype_dump(ompi_datatype_basicDatatypes[i]); } } MPI_Finalize(); return 0; }
ompi_datatype_t* test_struct_char_double( void ) { char_double_t data; int lengths[] = {1, 1}; MPI_Aint displ[] = {0, 0}; ompi_datatype_t *pdt; ompi_datatype_t* types[] = { &ompi_mpi_char.dt, &ompi_mpi_double.dt}; displ[0] = (char*)&(data.c) - (char*)&(data); displ[1] = (char*)&(data.d) - (char*)&(data); ompi_datatype_create_struct( 2, lengths, displ, types, &pdt ); ompi_datatype_commit( &pdt ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt ); } return pdt; }
ompi_datatype_t* create_struct_constant_gap_resized_ddt( ompi_datatype_t* type ) { struct structure data[1]; ompi_datatype_t *struct_type, *temp_type; ompi_datatype_t *types[2] = {type, type}; int blocklens[2] = {1, 1}; MPI_Aint disps[3]; MPI_Get_address(&data[0].transfered_1, &disps[0]); MPI_Get_address(&data[0].transfered_2, &disps[1]); MPI_Get_address(&data[0], &disps[2]); disps[1] -= disps[2]; /* 8 */ disps[0] -= disps[2]; /* 16 */ ompi_datatype_create_struct(2, blocklens, disps, types, &temp_type); ompi_datatype_create_resized(temp_type, 0, sizeof(data[0]), &struct_type); ompi_datatype_commit(&struct_type); OBJ_RELEASE(temp_type); assert( temp_type == NULL ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( struct_type ); } return struct_type; }
ompi_datatype_t* upper_matrix( unsigned int mat_size ) { int *disp, *blocklen; unsigned int i; ompi_datatype_t* upper; disp = (int*)malloc( sizeof(int) * mat_size ); blocklen = (int*)malloc( sizeof(int) * mat_size ); for( i = 0; i < mat_size; i++ ) { disp[i] = i * mat_size + i; blocklen[i] = mat_size - i; } ompi_datatype_create_indexed( mat_size, blocklen, disp, &ompi_mpi_double.dt, &upper ); ompi_datatype_commit( &upper ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( upper ); } free( disp ); free( blocklen ); return upper; }
/** * Main function. Call several tests and print-out the results. It try to stress the convertor * using difficult data-type constructions as well as strange segment sizes for the conversion. * Usually, it is able to detect most of the data-type and convertor problems. Any modifications * on the data-type engine should first pass all the tests from this file, before going into other * tests. */ int main( int argc, char* argv[] ) { ompi_datatype_t *pdt, *pdt1, *pdt2, *pdt3; int rc, length = 500; opal_init_util(&argc, &argv); ompi_datatype_init(); /** * By default simulate homogeneous architectures. */ remote_arch = opal_local_arch; printf( "\n\n#\n * TEST INVERSED VECTOR\n #\n\n" ); pdt = create_inversed_vector( &ompi_mpi_int.dt, 10 ); if( outputFlags & CHECK_PACK_UNPACK ) { local_copy_ddt_count(pdt, 100); local_copy_with_convertor(pdt, 100, 956); } OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( "\n\n#\n * TEST STRANGE DATATYPE\n #\n\n" ); pdt = create_strange_dt(); if( outputFlags & CHECK_PACK_UNPACK ) { local_copy_ddt_count(pdt, 1); local_copy_with_convertor(pdt, 1, 956); } OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( "\n\n#\n * TEST UPPER TRIANGULAR MATRIX (size 100)\n #\n\n" ); pdt = upper_matrix(100); if( outputFlags & CHECK_PACK_UNPACK ) { local_copy_ddt_count(pdt, 1); local_copy_with_convertor(pdt, 1, 48); } OBJ_RELEASE( pdt ); assert( pdt == NULL ); mpich_typeub(); mpich_typeub2(); mpich_typeub3(); printf( "\n\n#\n * TEST UPPER MATRIX\n #\n\n" ); rc = test_upper( length ); if( rc == 0 ) printf( "decode [PASSED]\n" ); else printf( "decode [NOT PASSED]\n" ); printf( "\n\n#\n * TEST MATRIX BORDERS\n #\n\n" ); pdt = test_matrix_borders( length, 100 ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt ); } OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( "\n\n#\n * TEST CONTIGUOUS\n #\n\n" ); pdt = test_contiguous(); OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( "\n\n#\n * TEST STRUCT\n #\n\n" ); pdt = test_struct(); OBJ_RELEASE( pdt ); assert( pdt == NULL ); ompi_datatype_create_contiguous(0, &ompi_mpi_datatype_null.dt, &pdt1); ompi_datatype_create_contiguous(0, &ompi_mpi_datatype_null.dt, &pdt2); ompi_datatype_create_contiguous(0, &ompi_mpi_datatype_null.dt, &pdt3); ompi_datatype_add( pdt3, &ompi_mpi_int.dt, 10, 0, -1 ); ompi_datatype_add( pdt3, &ompi_mpi_float.dt, 5, 10 * sizeof(int), -1 ); ompi_datatype_add( pdt2, &ompi_mpi_float.dt, 1, 0, -1 ); ompi_datatype_add( pdt2, pdt3, 3, sizeof(int) * 1, -1 ); ompi_datatype_add( pdt1, &ompi_mpi_long_long_int.dt, 5, 0, -1 ); ompi_datatype_add( pdt1, &ompi_mpi_long_double.dt, 2, sizeof(long long) * 5, -1 ); printf( ">>--------------------------------------------<<\n" ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt1 ); } printf( ">>--------------------------------------------<<\n" ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt2 ); } printf( ">>--------------------------------------------<<\n" ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_datatype_dump( pdt3 ); } OBJ_RELEASE( pdt1 ); assert( pdt1 == NULL ); OBJ_RELEASE( pdt2 ); assert( pdt2 == NULL ); OBJ_RELEASE( pdt3 ); assert( pdt3 == NULL ); printf( ">>--------------------------------------------<<\n" ); printf( " Contiguous data-type (MPI_DOUBLE)\n" ); pdt = MPI_DOUBLE; if( outputFlags & CHECK_PACK_UNPACK ) { local_copy_ddt_count(pdt, 4500); local_copy_with_convertor( pdt, 4500, 12 ); local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 12 ); } printf( ">>--------------------------------------------<<\n" ); printf( ">>--------------------------------------------<<\n" ); if( outputFlags & CHECK_PACK_UNPACK ) { printf( "Contiguous multiple data-type (4500*1)\n" ); pdt = create_contiguous_type( MPI_DOUBLE, 4500 ); local_copy_ddt_count(pdt, 1); local_copy_with_convertor( pdt, 1, 12 ); local_copy_with_convertor_2datatypes( pdt, 1, pdt, 1, 12 ); OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( "Contiguous multiple data-type (450*10)\n" ); pdt = create_contiguous_type( MPI_DOUBLE, 450 ); local_copy_ddt_count(pdt, 10); local_copy_with_convertor( pdt, 10, 12 ); local_copy_with_convertor_2datatypes( pdt, 10, pdt, 10, 12 ); OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( "Contiguous multiple data-type (45*100)\n" ); pdt = create_contiguous_type( MPI_DOUBLE, 45 ); local_copy_ddt_count(pdt, 100); local_copy_with_convertor( pdt, 100, 12 ); local_copy_with_convertor_2datatypes( pdt, 100, pdt, 100, 12 ); OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( "Contiguous multiple data-type (100*45)\n" ); pdt = create_contiguous_type( MPI_DOUBLE, 100 ); local_copy_ddt_count(pdt, 45); local_copy_with_convertor( pdt, 45, 12 ); local_copy_with_convertor_2datatypes( pdt, 45, pdt, 45, 12 ); OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( "Contiguous multiple data-type (10*450)\n" ); pdt = create_contiguous_type( MPI_DOUBLE, 10 ); local_copy_ddt_count(pdt, 450); local_copy_with_convertor( pdt, 450, 12 ); local_copy_with_convertor_2datatypes( pdt, 450, pdt, 450, 12 ); OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( "Contiguous multiple data-type (1*4500)\n" ); pdt = create_contiguous_type( MPI_DOUBLE, 1 ); local_copy_ddt_count(pdt, 4500); local_copy_with_convertor( pdt, 4500, 12 ); local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 12 ); OBJ_RELEASE( pdt ); assert( pdt == NULL ); } printf( ">>--------------------------------------------<<\n" ); printf( ">>--------------------------------------------<<\n" ); printf( "Vector data-type (450 times 10 double stride 11)\n" ); pdt = create_vector_type( MPI_DOUBLE, 450, 10, 11 ); ompi_datatype_dump( pdt ); if( outputFlags & CHECK_PACK_UNPACK ) { local_copy_ddt_count(pdt, 1); local_copy_with_convertor( pdt, 1, 12 ); local_copy_with_convertor_2datatypes( pdt, 1, pdt, 1, 12 ); local_copy_with_convertor( pdt, 1, 82 ); local_copy_with_convertor_2datatypes( pdt, 1, pdt, 1, 82 ); local_copy_with_convertor( pdt, 1, 6000 ); local_copy_with_convertor_2datatypes( pdt, 1, pdt, 1, 6000 ); local_copy_with_convertor( pdt, 1, 36000 ); local_copy_with_convertor_2datatypes( pdt, 1, pdt, 1, 36000 ); } printf( ">>--------------------------------------------<<\n" ); OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( ">>--------------------------------------------<<\n" ); pdt = test_struct_char_double(); if( outputFlags & CHECK_PACK_UNPACK ) { local_copy_ddt_count(pdt, 4500); local_copy_with_convertor( pdt, 4500, 12 ); local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 12 ); } printf( ">>--------------------------------------------<<\n" ); OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( ">>--------------------------------------------<<\n" ); pdt = test_create_twice_two_doubles(); if( outputFlags & CHECK_PACK_UNPACK ) { local_copy_ddt_count(pdt, 4500); local_copy_with_convertor( pdt, 4500, 12 ); local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 12 ); } printf( ">>--------------------------------------------<<\n" ); OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( ">>--------------------------------------------<<\n" ); pdt = test_create_blacs_type(); if( outputFlags & CHECK_PACK_UNPACK ) { ompi_datatype_dump( pdt ); local_copy_ddt_count(pdt, 2); local_copy_ddt_count(pdt, 4500); local_copy_with_convertor( pdt, 4500, 956 ); local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 956 ); local_copy_with_convertor( pdt, 4500, 16*1024 ); local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 16*1024 ); local_copy_with_convertor( pdt, 4500, 64*1024 ); local_copy_with_convertor_2datatypes( pdt, 4500, pdt, 4500, 64*1024 ); } printf( ">>--------------------------------------------<<\n" ); OBJ_RELEASE( pdt ); assert( pdt == NULL ); printf( ">>--------------------------------------------<<\n" ); pdt1 = test_create_blacs_type1( &ompi_mpi_int.dt ); pdt2 = test_create_blacs_type2( &ompi_mpi_int.dt ); if( outputFlags & CHECK_PACK_UNPACK ) { local_copy_with_convertor_2datatypes( pdt1, 1, pdt2, 1, 100 ); } printf( ">>--------------------------------------------<<\n" ); OBJ_RELEASE( pdt1 ); assert( pdt1 == NULL ); OBJ_RELEASE( pdt2 ); assert( pdt2 == NULL ); /* clean-ups all data allocations */ ompi_datatype_finalize(); return OMPI_SUCCESS; }