root/test/datatype/position.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. create_segments
  2. shuffle_segments
  3. pack_segments
  4. unpack_segments
  5. dump_ldi
  6. bytes_dump
  7. main

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2007 The University of Tennessee and The University
   4  *                         of Tennessee Research Foundation.  All rights
   5  *                         reserved.
   6  * Copyright (c) 2011      Cisco Systems, Inc.  All rights reserved.
   7  * Copyright (c) 2014-2015 Intel, Inc. All rights reserved.
   8  * Copyright (c) 2018      Triad National Security, LLC. All rights
   9  *                         reserved.
  10  * $COPYRIGHT$
  11  *
  12  * Additional copyrights may follow
  13  *
  14  * $HEADER$
  15  */
  16 
  17 #include "ompi_config.h"
  18 #include <stdio.h>
  19 #include <string.h>
  20 
  21 #include "opal/datatype/opal_convertor.h"
  22 #include "ompi/datatype/ompi_datatype.h"
  23 #include "opal/util/output.h"
  24 #include "opal/runtime/opal.h"
  25 
  26 /**
  27  * The purpose of this test is to simulate the multi-network packing and
  28  * unpacking process. The pack operation will happens in-order while the
  29  * will be done randomly. Therefore, before each unpack the correct
  30  * position in the user buffer has to be set.
  31  */
  32 
  33 static int fragment_size = 113;
  34 static int data_count = 2048;
  35 
  36 typedef struct {
  37     size_t position;
  38     size_t size;
  39     void* buffer;
  40 } ddt_segment_t;
  41 
  42 static int
  43 create_segments( ompi_datatype_t* datatype, int count,
  44                  size_t segment_length,
  45                  ddt_segment_t** segments, int* seg_count )
  46 {
  47     size_t data_size, total_length, position;
  48     opal_convertor_t* convertor;
  49     int i;
  50     ddt_segment_t* segment;
  51 
  52     ompi_datatype_type_size( datatype, &data_size );
  53     data_size *= count;
  54     *seg_count = data_size / segment_length;
  55     if( ((*seg_count) * segment_length) != data_size )
  56         *seg_count += 1;
  57  allocate_segments:
  58     *segments = (ddt_segment_t*)malloc( (*seg_count) * sizeof(ddt_segment_t) );
  59 
  60     convertor = opal_convertor_create( opal_local_arch, 0 );
  61     opal_convertor_prepare_for_send( convertor, &(datatype->super), count, NULL );
  62 
  63     position = 0;
  64     total_length = 0;
  65     for( i = 0; i < (*seg_count); i++ ) {
  66         segment = &((*segments)[i]);
  67         segment->buffer = malloc(segment_length);
  68         segment->position = position;
  69 
  70         /* Find the end of the segment */
  71         position += segment_length;
  72         opal_convertor_set_position( convertor, &position );
  73         segment->size = position - segment->position;
  74         total_length += segment->size;
  75     }
  76     OBJ_RELEASE(convertor);
  77     if( total_length != data_size ) {
  78         for( i = 0; i < (*seg_count); i++ ) {
  79             segment = &((*segments)[i]);
  80             free(segment->buffer);
  81         }
  82         free( *segments );
  83         (*seg_count) += 1;
  84         goto allocate_segments;
  85     }
  86     return 0;
  87 }
  88 
  89 static int
  90 shuffle_segments( ddt_segment_t* segments, int seg_count )
  91 {
  92     ddt_segment_t temporary;
  93     int i;
  94 
  95     for( i = 0; i < (seg_count/2); i += 2 ) {
  96         temporary = segments[i];
  97         segments[i] = segments[seg_count - i - 1];
  98         segments[seg_count - i - 1] = temporary;
  99     }
 100     return 0;
 101 }
 102 
 103 static int
 104 pack_segments( ompi_datatype_t* datatype, int count,
 105                size_t segment_size,
 106                ddt_segment_t* segments, int seg_count,
 107                void* buffer )
 108 {
 109     size_t max_size, position;
 110     opal_convertor_t* convertor;
 111     struct iovec iov;
 112     int i;
 113     uint32_t iov_count;
 114 
 115     convertor = opal_convertor_create( opal_local_arch, 0 );
 116     opal_convertor_prepare_for_send( convertor, &(datatype->super), count, buffer );
 117 
 118     for( i = 0; i < seg_count; i++ ) {
 119         iov.iov_len  = segments[i].size;
 120         iov.iov_base = segments[i].buffer;
 121         max_size = iov.iov_len;
 122         position = segments[i].position;
 123         opal_convertor_set_position( convertor, &position );
 124         if( position != segments[i].position ) {
 125             opal_output( 0, "Setting position failed (%lu != %lu)\n",
 126                          (unsigned long)segments[i].position, (unsigned long)position );
 127             break;
 128         }
 129 
 130         iov_count = 1;
 131         opal_convertor_pack( convertor, &iov, &iov_count, &max_size );
 132         if( max_size != segments[i].size ) {
 133             opal_output( 0, "Amount of packed data do not match (%lu != %lu)\n",
 134                          (unsigned long)max_size, (unsigned long)segments[i].size );
 135             opal_output( 0, "Segment %d position %lu size %lu\n", i,
 136                          (unsigned long)segments[i].position, segments[i].size );
 137         }
 138     }
 139     OBJ_RELEASE(convertor);
 140     return i;
 141 }
 142 
 143 static int
 144 unpack_segments( ompi_datatype_t* datatype, int count,
 145                  size_t segment_size,
 146                  ddt_segment_t* segments, int seg_count,
 147                  void* buffer )
 148 {
 149     opal_convertor_t* convertor;
 150     size_t max_size, position;
 151     int i;
 152     uint32_t iov_count;
 153     struct iovec iov;
 154 
 155     convertor = opal_convertor_create( opal_local_arch, 0 );
 156     opal_convertor_prepare_for_recv( convertor, &(datatype->super), count, buffer );
 157 
 158     for( i = 0; i < seg_count; i++ ) {
 159         iov.iov_len = segments[i].size;
 160         iov.iov_base = segments[i].buffer;
 161         max_size = iov.iov_len;
 162 
 163         position = segments[i].position;
 164         opal_convertor_set_position( convertor, &position );
 165         if( position != segments[i].position ) {
 166             opal_output( 0, "Setting position failed (%lu != %lu)\n",
 167                          (unsigned long)segments[i].position, (unsigned long)position );
 168             break;
 169         }
 170 
 171         iov_count = 1;
 172         opal_convertor_unpack( convertor, &iov, &iov_count, &max_size );
 173         if( max_size != segments[i].size ) {
 174             opal_output( 0, "Amount of unpacked data do not match (%lu != %lu)\n",
 175                          (unsigned long)max_size, (unsigned long)segments[i].size );
 176             opal_output( 0, "Segment %d position %lu size %lu\n", i,
 177                          (unsigned long)segments[i].position, segments[i].size );
 178         }
 179     }
 180     OBJ_RELEASE(convertor);
 181     return 0;
 182 }
 183 
 184 typedef struct {
 185     long double ld;
 186     int         i;
 187 } ddt_ldi_t;
 188 
 189 #if 0
 190 /* For debugging */
 191 static void dump_ldi( ddt_ldi_t* buffer, int start_pos, int end_pos )
 192 {
 193     int i;
 194 
 195     for( i = start_pos; i < end_pos; i++ ) {
 196         printf( "buffer[%d] = (%Lf, %d)\n", i, buffer[i].ld, buffer[i].i );
 197 
 198     }
 199 }
 200 #endif
 201 
 202 #if (OPAL_ENABLE_DEBUG == 1) && (OPAL_C_HAVE_VISIBILITY == 0)
 203 extern bool opal_unpack_debug;
 204 extern bool opal_pack_debug;
 205 extern bool opal_position_debug ;
 206 #endif  /* OPAL_ENABLE_DEBUG */
 207 
 208 static char* bytes_dump( void* src, size_t cnt )
 209 {
 210     static char text[1024];
 211     int index, i;
 212 
 213     index = sprintf( text, "0x" );
 214     for( i = 0; i < (int)cnt; i++ )
 215         index += sprintf( text + index, "%x", (int)(((char*)src)[i]) );
 216     *(text + index) = '\0';
 217     return text;
 218 }
 219 
 220 int main( int argc, char* argv[] )
 221 {
 222     ddt_segment_t* segments;
 223     ddt_ldi_t *send_buffer, *recv_buffer;
 224     int i, seg_count, errors;
 225     int show_only_first_error = 1;
 226     ompi_datatype_t* datatype = MPI_LONG_DOUBLE_INT;
 227 
 228     send_buffer = malloc( sizeof(ddt_ldi_t) * data_count );
 229     recv_buffer = malloc( sizeof(ddt_ldi_t) * data_count );
 230 
 231     for( i = 0; i < data_count; i++ ) {
 232         send_buffer[i].ld = (long double)i + (long double)i / 100000.0;
 233         send_buffer[i].i  = i;
 234     }
 235     memcpy(recv_buffer, send_buffer, sizeof(ddt_ldi_t) * data_count );
 236 
 237     opal_init_util (NULL, NULL);
 238     ompi_datatype_init();
 239 
 240 #if (OPAL_ENABLE_DEBUG == 1) && (OPAL_C_HAVE_VISIBILITY == 0)
 241     opal_unpack_debug   = false;
 242     opal_pack_debug     = false;
 243     opal_position_debug = false;
 244 #endif  /* OPAL_ENABLE_DEBUG */
 245 
 246     create_segments( datatype, data_count, fragment_size,
 247                      &segments, &seg_count );
 248 
 249     /* shuffle the segments */
 250     shuffle_segments( segments, seg_count );
 251 
 252     /* pack the data */
 253     pack_segments( datatype, data_count, fragment_size, segments, seg_count,
 254                    send_buffer );
 255 
 256     /* unpack the data back in the user space (recv buffer) */
 257     unpack_segments( datatype, data_count, fragment_size, segments, seg_count,
 258                      recv_buffer );
 259 
 260     /* And now check the data */
 261     for( errors = i = 0; i < data_count; i++ ) {
 262         /*if( !bytes_equal(&send_buffer[i].ld, &recv_buffer[i].ld, sizeof(long double)) ||*/
 263         if( (send_buffer[i].ld != recv_buffer[i].ld) ||
 264             (send_buffer[i].i != recv_buffer[i].i) ) {
 265             if( (show_only_first_error && (0 == errors)) ||
 266                 !show_only_first_error ) {
 267                 printf( "error at %4d [*(%s,%d)\n"
 268                         "             != (%s,%d)\n", i,
 269                         bytes_dump( &send_buffer[i].ld, sizeof(long double)), send_buffer[i].i,
 270                         bytes_dump( &recv_buffer[i].ld, sizeof(long double)), recv_buffer[i].i );
 271             }
 272             errors++;
 273         }
 274     }
 275     printf( "Found %d errors\n", errors );
 276     free(send_buffer); free(recv_buffer);
 277 
 278     for( i = 0; i < seg_count; i++ ) {
 279         free( segments[i].buffer );
 280     }
 281     free(segments);
 282 
 283     ompi_datatype_finalize();
 284     opal_finalize_util ();
 285 
 286     return (0 == errors ? 0 : -1);
 287 }

/* [<][>][^][v][top][bottom][index][help] */