/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2018-2020 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 TYPE_COUNT 3 #define TYPE_BLEN 2 #define TYPE_STRIDE 4 #define CONT_COUNT 2 #define COUNT 3 #define CHUNK ((TYPE_BLEN*8)*2-4) /** * Print how many elements on both sides of ptr. */ static void show_neighborhood(double* ptr, int how_many, bool show_hex) { int i; printf("%12p: ", (void*)ptr); for( i = -how_many; i < how_many; i++ ) { if( 0 == i ) { printf(" <%g> ", ptr[i]); } else { printf(" %g ", ptr[i]); } } if( show_hex ) { char* cptr = (char*)ptr; printf("\n : "); for( i = -how_many; i < how_many; i++ ) { if( 0 == i ) printf(" <"); for( int j = 0; j < sizeof(double); j++ ) { printf("%02x", cptr[i * sizeof(double)+j]); } if( 0 == i ) printf("> "); else printf(" "); } } printf("\n\n"); } /** * -------G---[---][---] OPAL_LOOP_S 19 times the next 2 elements extent 18432 * -cC---P-DB-[---][---] OPAL_FLOAT8 count 72 disp 0x80 (128) blen 16 extent 256 (size 9216) * -------G---[---][---] OPAL_LOOP_E prev 2 elements first elem displacement 128 size of data 9216 * -------G---[---][---] OPAL_LOOP_E prev 3 elements first elem displacement 128 size of data 175104 */ int main( int argc, char* argv[] ) { opal_datatype_t* vector; ompi_datatype_t* base; uint32_t iov_count; size_t max_data, size, length; struct iovec iov[2]; opal_convertor_t* convertor; ptrdiff_t extent, base_extent; double *array, *packed; char* bpacked; int i, j; opal_init_util (NULL, NULL); ompi_datatype_init(); ompi_datatype_create_vector(TYPE_COUNT, TYPE_BLEN, TYPE_STRIDE, MPI_DOUBLE, &base); ompi_datatype_create_contiguous(CONT_COUNT, base, &vector); opal_datatype_commit( vector ); ompi_datatype_dump(vector); opal_datatype_type_size(vector, &size); opal_datatype_type_extent(vector, &extent); opal_datatype_type_extent(base, &base_extent); array = (double*)malloc( extent * COUNT ); packed = (double*)malloc( size * COUNT ); bpacked = (char*)packed; /** * Initialize the sparse data using the index. */ for( i = 0; i < (TYPE_BLEN * TYPE_COUNT * CONT_COUNT * COUNT); i++ ) { packed[i] = (double)(i % TYPE_BLEN); } memset(array, extent * COUNT, TYPE_BLEN + 1); /** * 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_prepare_for_recv( convertor, vector, COUNT, array ); for( length = 0; length < (size * COUNT); ) { iov[0].iov_base = bpacked + length; iov[0].iov_len = CHUNK; max_data = iov[0].iov_len; iov_count = 1; opal_convertor_unpack( convertor, iov, &iov_count, &max_data ); length += max_data; int idx = 0, checked = 0; for( int m = 0; m < COUNT; m++ ) { char* mptr = (char*)array + m * extent; for( int k = 0; k < CONT_COUNT; k++ ) { char* kptr = mptr + k * base_extent; for( j = 0; j < TYPE_COUNT; j++ ) { double* jarray = (double*)kptr + j * TYPE_STRIDE; for( i = 0; i < TYPE_BLEN; i++ ) { checked += sizeof(double); if( checked > length ) goto next_iteration; if( jarray[i] != (double)(idx % TYPE_BLEN) ) { fprintf(stderr, "\n\n\nError during check for the %d element, length %" PRIsize_t " (chunk %d)\n", idx, length, CHUNK); fprintf(stderr, "Error at position %d [%d:%d:%d:%d] found %g expected %g\n\n\n", idx, m, k, j, i, jarray[i], (double)(idx % TYPE_BLEN)); show_neighborhood(jarray + i, 4, true); exit(-1); } idx++; } } } } next_iteration: /* nothing special to do here, just move to the next conversion */ continue; } OBJ_RELEASE(convertor); /** * The datatype is not useful anymore */ OBJ_RELEASE(vector); free(array); free(packed); /* clean-ups all data allocations */ ompi_datatype_finalize(); opal_finalize_util (); return 0; }