root/test/datatype/position_noncontig.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. main

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2017 The University of Tennessee and The University
   4  *                         of Tennessee Research Foundation.  All rights
   5  *                         reserved.
   6  * Copyright (c) 2011-2013 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  * unpack 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 
  35 typedef struct {
  36     size_t position;
  37     size_t size;
  38     void* buffer;
  39 } ddt_segment_t;
  40 
  41 static int
  42 create_segments( ompi_datatype_t* datatype, int count,
  43                  size_t segment_length,
  44                  ddt_segment_t** segments, int* seg_count )
  45 {
  46     size_t data_size, total_length, position;
  47     opal_convertor_t* convertor;
  48     int i;
  49     ddt_segment_t* segment;
  50 
  51     ompi_datatype_type_size( datatype, &data_size );
  52     data_size *= count;
  53     *seg_count = data_size / segment_length;
  54     if( ((*seg_count) * segment_length) != data_size )
  55         *seg_count += 1;
  56  allocate_segments:
  57     *segments = (ddt_segment_t*)malloc( (*seg_count) * sizeof(ddt_segment_t) );
  58 
  59     convertor = opal_convertor_create( opal_local_arch, 0 );
  60     opal_convertor_prepare_for_send( convertor, &(datatype->super), count, NULL );
  61 
  62     position = 0;
  63     total_length = 0;
  64     for( i = 0; i < (*seg_count); i++ ) {
  65         segment = &((*segments)[i]);
  66         segment->buffer = malloc(segment_length);
  67         segment->position = position;
  68 
  69         /* Find the end of the segment */
  70         position += segment_length;
  71         opal_convertor_set_position( convertor, &position );
  72         segment->size = position - segment->position;
  73         total_length += segment->size;
  74     }
  75     OBJ_RELEASE(convertor);
  76     if( total_length != data_size ) {
  77         for( i = 0; i < (*seg_count); i++ ) {
  78             segment = &((*segments)[i]);
  79             free(segment->buffer);
  80         }
  81         free( *segments );
  82         (*seg_count) += 1;
  83         goto allocate_segments;
  84     }
  85     return 0;
  86 }
  87 
  88 static int
  89 shuffle_segments( ddt_segment_t* segments, int seg_count )
  90 {
  91     ddt_segment_t temporary;
  92     int i;
  93 
  94     for( i = 0; i < (seg_count/2); i += 2 ) {
  95         temporary = segments[i];
  96         segments[i] = segments[seg_count - i - 1];
  97         segments[seg_count - i - 1] = temporary;
  98     }
  99     return 0;
 100 }
 101 
 102 static int
 103 pack_segments( ompi_datatype_t* datatype, int count,
 104                size_t segment_size,
 105                ddt_segment_t* segments, int seg_count,
 106                void* buffer )
 107 {
 108     size_t max_size, position;
 109     opal_convertor_t* convertor;
 110     struct iovec iov;
 111     int i;
 112     uint32_t iov_count;
 113 
 114     convertor = opal_convertor_create( opal_local_arch, 0 );
 115     opal_convertor_prepare_for_send( convertor, &(datatype->super), count, buffer );
 116 
 117     for( i = 0; i < seg_count; i++ ) {
 118         iov.iov_len  = segments[i].size;
 119         iov.iov_base = segments[i].buffer;
 120         max_size = iov.iov_len;
 121         position = segments[i].position;
 122         opal_convertor_set_position( convertor, &position );
 123         if( position != segments[i].position ) {
 124             opal_output( 0, "Setting position failed (%lu != %lu)\n",
 125                          (unsigned long)segments[i].position, (unsigned long)position );
 126             break;
 127         }
 128 
 129         iov_count = 1;
 130         opal_convertor_pack( convertor, &iov, &iov_count, &max_size );
 131         if( max_size != segments[i].size ) {
 132             opal_output( 0, "Amount of packed data do not match (%lu != %lu)\n",
 133                          (unsigned long)max_size, (unsigned long)segments[i].size );
 134             opal_output( 0, "Segment %d position %lu size %lu\n", i,
 135                          (unsigned long)segments[i].position, segments[i].size );
 136         }
 137     }
 138     OBJ_RELEASE(convertor);
 139     return i;
 140 }
 141 
 142 static int
 143 unpack_segments( ompi_datatype_t* datatype, int count,
 144                  size_t segment_size,
 145                  ddt_segment_t* segments, int seg_count,
 146                  void* buffer )
 147 {
 148     opal_convertor_t* convertor;
 149     size_t max_size, position;
 150     int i;
 151     uint32_t iov_count;
 152     struct iovec iov;
 153 
 154     convertor = opal_convertor_create( opal_local_arch, 0 );
 155     opal_convertor_prepare_for_recv( convertor, &(datatype->super), count, buffer );
 156 
 157     for( i = 0; i < seg_count; i++ ) {
 158         iov.iov_len = segments[i].size;
 159         iov.iov_base = segments[i].buffer;
 160         max_size = iov.iov_len;
 161 
 162         position = segments[i].position;
 163         opal_convertor_set_position( convertor, &position );
 164         if( position != segments[i].position ) {
 165             opal_output( 0, "Setting position failed (%lu != %lu)\n",
 166                          (unsigned long)segments[i].position, (unsigned long)position );
 167             break;
 168         }
 169 
 170         iov_count = 1;
 171         opal_convertor_unpack( convertor, &iov, &iov_count, &max_size );
 172         if( max_size != segments[i].size ) {
 173             opal_output( 0, "Amount of unpacked data do not match (%lu != %lu)\n",
 174                          (unsigned long)max_size, (unsigned long)segments[i].size );
 175             opal_output( 0, "Segment %d position %lu size %lu\n", i,
 176                          (unsigned long)segments[i].position, segments[i].size );
 177         }
 178     }
 179     OBJ_RELEASE(convertor);
 180     return 0;
 181 }
 182 
 183 #if (OPAL_ENABLE_DEBUG == 1) && (OPAL_C_HAVE_VISIBILITY == 0)
 184 extern bool opal_unpack_debug;
 185 extern bool opal_pack_debug;
 186 extern bool opal_position_debug ;
 187 #endif  /* OPAL_ENABLE_DEBUG */
 188 
 189 int main( int argc, char* argv[] )
 190 {
 191     ddt_segment_t* segments;
 192     int *send_buffer, *recv_buffer;
 193     int i, seg_count, errors;
 194     int show_only_first_error = 1;
 195     ompi_datatype_t* datatype = MPI_DATATYPE_NULL;
 196 
 197 #define NELT (300)
 198     send_buffer = malloc(NELT*sizeof(int));
 199     recv_buffer = malloc(NELT*sizeof(int));
 200     for (i = 0; i < NELT; ++i) {
 201         send_buffer[i] = i;
 202         recv_buffer[i] = 0xdeadbeef;
 203     }
 204 
 205     opal_init_util (NULL, NULL);
 206     ompi_datatype_init();
 207 
 208     ompi_datatype_create_vector(NELT/2, 1, 2, MPI_INT, &datatype);
 209     ompi_datatype_commit(&datatype);
 210 
 211 #if (OPAL_ENABLE_DEBUG == 1) && (OPAL_C_HAVE_VISIBILITY == 0)
 212     opal_unpack_debug   = false;
 213     opal_pack_debug     = false;
 214     opal_position_debug = false;
 215 #endif  /* OPAL_ENABLE_DEBUG */
 216 
 217     create_segments( datatype, 1, fragment_size,
 218                      &segments, &seg_count );
 219 
 220     /* shuffle the segments */
 221     shuffle_segments( segments, seg_count );
 222 
 223     /* pack the data */
 224     pack_segments( datatype, 1, fragment_size, segments, seg_count,
 225                    send_buffer );
 226 
 227     /* unpack the data back in the user space (recv buffer) */
 228     unpack_segments( datatype, 1, fragment_size, segments, seg_count,
 229                      recv_buffer );
 230 
 231     /* And now check the data */
 232     for( errors = i = 0; i < NELT; i++ ) {
 233         int expected = ((i % 2) ? (int)0xdeadbeef : i);
 234         if (recv_buffer[i] != expected) {
 235             if( (show_only_first_error && (0 == errors)) ||
 236                 !show_only_first_error ) {
 237                 printf("error at index %4d: 0x%08x != 0x%08x\n", i, recv_buffer[i], expected);
 238             }
 239             errors++;
 240         }
 241     }
 242     printf( "Found %d errors\n", errors );
 243     free(send_buffer); free(recv_buffer);
 244 
 245     for( i = 0; i < seg_count; i++ ) {
 246         free( segments[i].buffer );
 247     }
 248     free(segments);
 249 
 250     ompi_datatype_finalize();
 251     opal_finalize_util ();
 252 
 253     return (0 == errors ? 0 : -1);
 254 }

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