/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2019 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2019 Research Organization for Information Science * and Technology (RIST). All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #include "ompi_config.h" #include "ddt_lib.h" #include "opal/datatype/opal_convertor.h" #include "opal/datatype/opal_datatype_internal.h" #include "opal/runtime/opal.h" #include #include #ifdef HAVE_SYS_TIME_H #include #endif #include static int mca_common_ompio_decode_datatype ( ompi_datatype_t *datatype, int count, struct iovec **iov, uint32_t *iovec_count, int increment) { opal_convertor_t *convertor; size_t remaining_length = 0; uint32_t i; uint32_t temp_count; struct iovec *temp_iov=NULL; size_t temp_data; convertor = opal_convertor_create( opal_local_arch, 0 ); if (OMPI_SUCCESS != opal_convertor_prepare_for_send (convertor, &(datatype->super), count, NULL)) { opal_output (1, "Cannot attach the datatype to a convertor\n"); return OMPI_ERROR; } if ( 0 == datatype->super.size ) { *iovec_count = 0; *iov = NULL; return OMPI_SUCCESS; } remaining_length = count * datatype->super.size; temp_count = increment; temp_iov = (struct iovec*)malloc(temp_count * sizeof(struct iovec)); if (NULL == temp_iov) { opal_output (1, "OUT OF MEMORY\n"); return OMPI_ERR_OUT_OF_RESOURCE; } while (0 == opal_convertor_raw(convertor, temp_iov, &temp_count, &temp_data)) { *iovec_count = *iovec_count + temp_count; *iov = (struct iovec *) realloc (*iov, *iovec_count * sizeof(struct iovec)); if (NULL == *iov) { opal_output(1, "OUT OF MEMORY\n"); free(temp_iov); return OMPI_ERR_OUT_OF_RESOURCE; } for (i = 0 ; i < temp_count ; i++) { (*iov)[i+(*iovec_count-temp_count)].iov_base = temp_iov[i].iov_base; (*iov)[i+(*iovec_count-temp_count)].iov_len = temp_iov[i].iov_len; } remaining_length -= temp_data; temp_count = increment; } *iovec_count = *iovec_count + temp_count; if ( temp_count > 0 ) { *iov = (struct iovec *) realloc (*iov, *iovec_count * sizeof(struct iovec)); if (NULL == *iov) { opal_output(1, "OUT OF MEMORY\n"); free(temp_iov); return OMPI_ERR_OUT_OF_RESOURCE; } } for (i=0 ; isuper.flags = 3332; datatype->super.id = 0; datatype->super.bdt_used = 512; datatype->super.size = 31684; datatype->super.true_lb = 4; datatype->super.true_ub = 218288; datatype->super.lb = 0; datatype->super.ub = 218344; datatype->super.nbElems = 31684; datatype->super.align = 1; datatype->super.loops = 1146; datatype->super.desc.length = 3351; datatype->super.desc.used = 184; datatype->super.desc.desc = descs; datatype->super.opt_desc.length = 3351; datatype->super.opt_desc.used = 184; datatype->super.opt_desc.desc = descs; /* Get the entire raw description of the datatype in a single call */ uint32_t iovec_count_300 = 0; struct iovec * iov_300 = NULL; mca_common_ompio_decode_datatype ( datatype, 1, &iov_300, &iovec_count_300, 300); /* Get the raw description of the datatype 10 elements at the time. This stresses some * of the execution paths in the convertor raw. */ uint32_t iovec_count_10 = 0; struct iovec * iov_10 = NULL; mca_common_ompio_decode_datatype ( datatype, 1, &iov_10, &iovec_count_10, 10); /* Get the raw description of the datatype one element at the time. This stresses all * execution paths in the convertor raw. */ uint32_t iovec_count_1 = 0; struct iovec * iov_1 = NULL; mca_common_ompio_decode_datatype ( datatype, 1, &iov_1, &iovec_count_1, 1); assert(iovec_count_300 == iovec_count_10); assert(iovec_count_300 == iovec_count_1); // assert(iov[100].iov_base == iov2[100].iov_base); // assert(iov[100].iov_len == iov2[100].iov_len); for (uint32_t i = 0; i < iovec_count_300; i++) { assert(iov_300[i].iov_base == iov_10[i].iov_base); assert(iov_300[i].iov_len == iov_10[i].iov_len); assert(iov_300[i].iov_base == iov_1[i].iov_base); assert(iov_300[i].iov_len == iov_1[i].iov_len); } return 0; }