📄 ddt_test.c
字号:
free( psrc ); return OMPI_SUCCESS;}static intlocal_copy_with_convertor_2datatypes( ompi_datatype_t* send_type, int send_count, ompi_datatype_t* recv_type, int recv_count, int chunk ){ MPI_Aint send_extent, recv_extent; void *pdst = NULL, *psrc = NULL, *ptemp = NULL; ompi_convertor_t *send_convertor = NULL, *recv_convertor = NULL; struct iovec iov; uint32_t iov_count; size_t max_data; int32_t length = 0, done1 = 0, done2 = 0; TIMER_DATA_TYPE start, end, unpack_start, unpack_end; long total_time, unpack_time = 0; ompi_ddt_type_extent( send_type, &send_extent ); ompi_ddt_type_extent( recv_type, &recv_extent ); pdst = malloc( recv_extent * recv_count ); psrc = malloc( send_extent * send_count ); ptemp = malloc( chunk ); /* fill up the receiver with ZEROS */ { int i; for( i = 0; i < (send_count * send_extent); i++ ) ((char*)psrc)[i] = i % 128 + 32; } memset( pdst, 0, recv_count * recv_extent ); send_convertor = ompi_convertor_create( remote_arch, 0 ); if( OMPI_SUCCESS != ompi_convertor_prepare_for_send( send_convertor, send_type, send_count, psrc ) ) { printf( "Unable to create the send convertor. Is the datatype committed ?\n" ); goto clean_and_return; } recv_convertor = ompi_convertor_create( remote_arch, 0 ); if( OMPI_SUCCESS != ompi_convertor_prepare_for_recv( recv_convertor, recv_type, recv_count, pdst ) ) { printf( "Unable to create the recv convertor. Is the datatype committed ?\n" ); goto clean_and_return; } cache_trash(); /* make sure the cache is useless */ GET_TIME( start ); while( (done1 & done2) != 1 ) { /* They are supposed to finish in exactly the same time. */ if( done1 | done2 ) { printf( "WRONG !!! the send is %s but the receive is %s in local_copy_with_convertor_2datatypes\n", (done1 ? "finish" : "not finish"), (done2 ? "finish" : "not finish") ); } max_data = chunk; iov_count = 1; iov.iov_base = ptemp; iov.iov_len = chunk; if( done1 == 0 ) { done1 = ompi_convertor_pack( send_convertor, &iov, &iov_count, &max_data ); } if( done2 == 0 ) { GET_TIME( unpack_start ); done2 = ompi_convertor_unpack( recv_convertor, &iov, &iov_count, &max_data ); GET_TIME( unpack_end ); unpack_time += ELAPSED_TIME( unpack_start, unpack_end ); } length += max_data; } GET_TIME( end ); total_time = ELAPSED_TIME( start, end ); printf( "copying different data-types using convertors in %ld microsec\n", total_time ); printf( "\t unpack in %ld microsec [pack in %ld microsec]\n", unpack_time, total_time - unpack_time ); clean_and_return: if( send_convertor != NULL ) { OBJ_RELEASE( send_convertor ); assert( send_convertor == NULL ); } if( recv_convertor != NULL ) { OBJ_RELEASE( recv_convertor ); assert( recv_convertor == NULL ); } if( NULL != pdst ) free( pdst ); if( NULL != psrc ) free( psrc ); if( NULL != ptemp ) free( ptemp ); return OMPI_SUCCESS;}static int local_copy_with_convertor( ompi_datatype_t* pdt, int count, int chunk ){ MPI_Aint extent; void *pdst = NULL, *psrc = NULL, *ptemp = NULL; ompi_convertor_t *send_convertor = NULL, *recv_convertor = NULL; struct iovec iov; uint32_t iov_count; size_t max_data; int32_t length = 0, done1 = 0, done2 = 0; TIMER_DATA_TYPE start, end, unpack_start, unpack_end; long total_time, unpack_time = 0; ompi_ddt_type_extent( pdt, &extent ); pdst = malloc( extent * count ); psrc = malloc( extent * count ); ptemp = malloc( chunk ); { int i; for( i = 0; i < (count * extent); i++ ) ((char*)psrc)[i] = i % 128 + 32; } memset( pdst, 0, count * extent ); send_convertor = ompi_convertor_create( remote_arch, 0 ); if( OMPI_SUCCESS != ompi_convertor_prepare_for_send( send_convertor, pdt, count, psrc ) ) { printf( "Unable to create the send convertor. Is the datatype committed ?\n" ); goto clean_and_return; } recv_convertor = ompi_convertor_create( remote_arch, 0 ); if( OMPI_SUCCESS != ompi_convertor_prepare_for_recv( recv_convertor, pdt, count, pdst ) ) { printf( "Unable to create the recv convertor. Is the datatype committed ?\n" ); goto clean_and_return; } cache_trash(); /* make sure the cache is useless */ GET_TIME( start ); while( (done1 & done2) != 1 ) { /* They are supposed to finish in exactly the same time. */ if( done1 | done2 ) { printf( "WRONG !!! the send is %s but the receive is %s in local_copy_with_convertor\n", (done1 ? "finish" : "not finish"), (done2 ? "finish" : "not finish") ); } max_data = chunk; iov_count = 1; iov.iov_base = ptemp; iov.iov_len = chunk; if( done1 == 0 ) { done1 = ompi_convertor_pack( send_convertor, &iov, &iov_count, &max_data ); } if( done2 == 0 ) { GET_TIME( unpack_start ); done2 = ompi_convertor_unpack( recv_convertor, &iov, &iov_count, &max_data ); GET_TIME( unpack_end ); unpack_time += ELAPSED_TIME( unpack_start, unpack_end ); } length += max_data; } GET_TIME( end ); total_time = ELAPSED_TIME( start, end ); printf( "copying same data-type using convertors in %ld microsec\n", total_time ); printf( "\t unpack in %ld microsec [pack in %ld microsec]\n", unpack_time, total_time - unpack_time ); clean_and_return: if( NULL != send_convertor ) OBJ_RELEASE( send_convertor ); if( NULL != recv_convertor ) OBJ_RELEASE( recv_convertor ); if( NULL != pdst ) free( pdst ); if( NULL != psrc ) free( psrc ); if( NULL != ptemp ) free( ptemp ); return OMPI_SUCCESS;}/** * 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; ompi_ddt_init(); /** * By default simulate homogeneous architectures. */ remote_arch = ompi_mpi_local_arch; printf( "\n\n#\n * TEST INVERSED VECTOR\n #\n\n" ); pdt = create_inversed_vector( &ompi_mpi_int, 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_ddt_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 ); pdt1 = ompi_ddt_create( -1 ); pdt2 = ompi_ddt_create( -1 ); pdt3 = ompi_ddt_create( -1 ); ompi_ddt_add( pdt3, ompi_ddt_basicDatatypes[DT_INT], 10, 0, -1 ); ompi_ddt_add( pdt3, ompi_ddt_basicDatatypes[DT_FLOAT], 5, 10 * sizeof(int), -1 ); ompi_ddt_add( pdt2, ompi_ddt_basicDatatypes[DT_INT], 1, 0, -1 ); ompi_ddt_add( pdt2, pdt3, 3, sizeof(int) * 1, -1 ); ompi_ddt_add( pdt1, ompi_ddt_basicDatatypes[DT_LONG_LONG_INT], 5, 0, -1 ); ompi_ddt_add( pdt1, ompi_ddt_basicDatatypes[DT_LONG_DOUBLE], 2, sizeof(long long) * 5, -1 ); printf( ">>--------------------------------------------<<\n" ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_ddt_dump( pdt1 ); } printf( ">>--------------------------------------------<<\n" ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_ddt_dump( pdt2 ); } printf( ">>--------------------------------------------<<\n" ); if( outputFlags & DUMP_DATA_AFTER_COMMIT ) { ompi_ddt_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_ddt_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_ddt_dump( pdt ); 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 ); pdt2 = test_create_blacs_type2( &ompi_mpi_int ); 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_ddt_finalize(); return OMPI_SUCCESS;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -