1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
/* -*- 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 <mpi.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#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;
}
|