/* -*- Mode: C; c-basic-offset:4 ; -*- */ /* * Copyright (c) 2018 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ /** * This test check the correct OMPI datatype description for * extremely large types (over 4GB). */ #include #include #include #include #include #include "ompi_config.h" #include "ompi/datatype/ompi_datatype.h" #include "opal/runtime/opal.h" #include "opal/datatype/opal_convertor.h" #include "opal/datatype/opal_datatype_internal.h" #define MAX_IOVEC 10 #define MAX_CHUNK (1024*1024*1024) /* 1GB */ static int verbose = 0; static size_t count_length_via_convertor_raw(char* msg, MPI_Datatype dtype, int count) { opal_convertor_t* pconv; struct iovec iov[MAX_IOVEC]; uint32_t iov_count = MAX_IOVEC, i; size_t length = MAX_CHUNK, packed_iovec = 0, packed = 0; pconv = opal_convertor_create( opal_local_arch, 0 ); opal_convertor_prepare_for_send(pconv, (const struct opal_datatype_t *)dtype, 1, NULL); while( 0 == opal_convertor_raw(pconv, iov, &iov_count, &length) ) { if( verbose ) { printf("iov_count = %d packed_iovec = %"PRIsize_t" length = %"PRIsize_t"\n", iov_count, packed_iovec, length); } packed += length; for( i = 0; i < iov_count; i++ ) { packed_iovec += iov[i].iov_len; if( verbose ) { printf("[%s] add %"PRIsize_t" bytes -> so far %"PRIsize_t" bytes\n", msg, iov[i].iov_len, packed_iovec); } } if( packed != packed_iovec ) { printf( "[%s] Raw data amount diverges %"PRIsize_t" != %"PRIsize_t"\n", msg, packed, packed_iovec); exit(-1); } iov_count = MAX_IOVEC; /* number of available iov */ length = MAX_CHUNK; } if( verbose ) { printf("iov_count = %d packed_iovec = %"PRIsize_t" length = %"PRIsize_t"\n", iov_count, packed_iovec, length); } packed += length; for( i = 0; i < iov_count; i++ ) { packed_iovec += iov[i].iov_len; if( verbose ) { printf("[%s] add %"PRIsize_t" bytes -> so far %"PRIsize_t" bytes\n", msg, iov[i].iov_len, packed_iovec); } } if( packed != packed_iovec ) { printf( "[%s] Raw data amount diverges %"PRIsize_t" != %"PRIsize_t"\n", msg, packed, packed_iovec); exit(-1); } return packed_iovec; } int main(int argc, char * argv[]) { int const per_process = 192; int const per_type = 20000000; int blocklen, stride, count; int scounts[2] = {per_process, per_process}; int sdispls[2] = {3*per_process, 0*per_process}; int rcounts[2] = {per_process, per_process}; int rdispls[2] = {1*per_process, 2*per_process}; MPI_Datatype ddt, stype, rtype; size_t length, packed; opal_init(&argc, &argv); ompi_datatype_init(); ompi_datatype_create_contiguous( per_type, MPI_FLOAT, &ddt); /* * Large sparse datatype: indexed contiguous */ ompi_datatype_create_indexed(2, scounts, sdispls, ddt, &stype); ompi_datatype_commit(&stype); packed = count_length_via_convertor_raw("1. INDEX", stype, 1); opal_datatype_type_size(&stype->super, &length); if( length != packed ) { printf("Mismatched length of packed data to datatype size (%"PRIsize_t" != %"PRIsize_t")\n", packed, length); exit(-2); } ompi_datatype_destroy(&stype); /* * Large contiguous datatype: indexed contiguous */ ompi_datatype_create_indexed(2, rcounts, rdispls, ddt, &rtype); ompi_datatype_commit(&rtype); packed = count_length_via_convertor_raw("2. INDEX", rtype, 1); opal_datatype_type_size(&rtype->super, &length); if( length != packed ) { printf("Mismatched length of packed data to datatype size (%"PRIsize_t" != %"PRIsize_t")\n", packed, length); exit(-2); } ompi_datatype_destroy(&rtype); ompi_datatype_destroy(&ddt); /* * Large sparse datatype: vector */ count = INT_MAX / 2; blocklen = stride = 4; ompi_datatype_create_vector(count, blocklen, stride, MPI_FLOAT, &ddt); ompi_datatype_commit(&ddt); packed = count_length_via_convertor_raw("3. VECTOR", ddt, 1); opal_datatype_type_size(&ddt->super, &length); if( length != packed ) { printf("Mismatched length of packed data to datatype size (%"PRIsize_t" != %"PRIsize_t")\n", packed, length); exit(-2); } ompi_datatype_destroy(&ddt); /* * Large sparse datatype: contiguous */ MPI_Datatype tmp; ompi_datatype_create_contiguous(stride, MPI_FLOAT, &tmp); ompi_datatype_create_contiguous(count, tmp, &ddt); ompi_datatype_commit(&ddt); packed = count_length_via_convertor_raw("4. CONTIG", ddt, 1); opal_datatype_type_size(&ddt->super, &length); if( length != packed ) { printf("Mismatched length of packed data to datatype size (%"PRIsize_t" != %"PRIsize_t")\n", packed, length); exit(-2); } ompi_datatype_destroy(&ddt); ompi_datatype_destroy(&tmp); return 0; }