/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2004-2006 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2018 Triad National Security, LLC. All rights * reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #include "ompi_config.h" #include "opal/datatype/opal_convertor.h" #include "ompi/datatype/ompi_datatype.h" #include "opal/datatype/opal_datatype_checksum.h" #include "opal/runtime/opal.h" #include #include #include #define SIZE 1024 typedef struct { int useful; int useless; } my_data_t; int main( int argc, char* argv[] ) { MPI_Datatype sparse; int *array, *packed; my_data_t* sparse_array; int i; uint32_t iov_count; size_t max_data; uint32_t pack_checksum, contiguous_checksum, sparse_checksum, manual_checksum; struct iovec iov[2]; opal_convertor_t* convertor; opal_init(NULL, NULL); ompi_datatype_init(); srandom( (int)time(NULL) ); /*srandomdev();*/ ompi_datatype_create_vector( SIZE, 1, 2, MPI_INT, &sparse ); ompi_datatype_commit( &sparse ); sparse_array = (my_data_t*)malloc( sizeof(my_data_t) * SIZE ); array = (int*)malloc( sizeof(int) * SIZE ); packed = (int*)malloc( sizeof(int) * SIZE ); /** * Initialize the sparse data using the index. */ for( i = 0; i < SIZE; i++ ) { sparse_array[i].useful = random(); sparse_array[i].useless = 0; } /** * Pack the sparse data into the packed array. This simulate the first step * of the buffered operation. */ convertor = opal_convertor_create( opal_local_arch, 0 ); opal_convertor_personalize( convertor, CONVERTOR_WITH_CHECKSUM, NULL ); opal_convertor_prepare_for_send( convertor, &(sparse->super), SIZE, sparse_array ); iov[0].iov_base = packed; iov[0].iov_len = sizeof(int) * SIZE; max_data = iov[0].iov_len; iov_count = 1; opal_convertor_pack( convertor, iov, &iov_count, &max_data ); pack_checksum = convertor->checksum; OBJ_RELEASE(convertor); /** * Now move the data from the packed array into the fragment to * be sent over the network (still simulation). */ convertor = opal_convertor_create( opal_local_arch, 0 ); opal_convertor_personalize( convertor, CONVERTOR_WITH_CHECKSUM, NULL ); opal_convertor_prepare_for_send( convertor, &(ompi_mpi_int.dt.super), SIZE, packed ); iov[0].iov_base = array; iov[0].iov_len = sizeof(int) * SIZE; max_data = iov[0].iov_len; iov_count = 1; opal_convertor_pack( convertor, iov, &iov_count, &max_data ); contiguous_checksum = convertor->checksum; OBJ_RELEASE(convertor); /** * And now we're on the receiver side. We just get one fragment from * the network and now we unpack it in the user memory using 2 * separate iovec. */ convertor = opal_convertor_create( opal_local_arch, 0 ); opal_convertor_personalize( convertor, CONVERTOR_WITH_CHECKSUM, NULL ); opal_convertor_prepare_for_recv( convertor, &(sparse->super), SIZE, sparse_array ); max_data = sizeof(int) * SIZE; iov[0].iov_base = array; iov[0].iov_len = max_data / 2; iov[1].iov_base = (char*)array + iov[0].iov_len; iov[1].iov_len = max_data - iov[0].iov_len; iov_count = 2; opal_convertor_unpack( convertor, iov, &iov_count, &max_data ); sparse_checksum = convertor->checksum; OBJ_RELEASE(convertor); /** * The datatype is not useful anymore */ OBJ_RELEASE(sparse); /** * The 3 checksum have to match. */ printf( "contiguous checksum %x\n", contiguous_checksum ); printf( "packed checksum %x\n", pack_checksum ); printf( "sparse checksum %x\n", sparse_checksum ); if( (sparse_checksum != contiguous_checksum) || (pack_checksum != sparse_checksum) ) { printf( "ERROR!!! the checksum algorithm does not work as expected\n" ); return 1; } printf( "COOL the 3 checksum match\n" ); /** * Now that the packed buffer contain the data we want, let's try to call * the checksum directly to see if there is any difference. */ { uint32_t ui1 = 0; size_t ui2 = 0; manual_checksum = OPAL_CSUM_PARTIAL( packed, sizeof(int) * SIZE, &ui1, &ui2 ); } printf( "manual checksum %x\n", manual_checksum ); free(sparse_array); free(array); free(packed); /* clean-ups all data allocations */ opal_finalize_util(); return 0; }