root/test/datatype/checksum.c

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

DEFINITIONS

This source file includes following definitions.
  1. main

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2006 The University of Tennessee and The University
   4  *                         of Tennessee Research Foundation.  All rights
   5  *                         reserved.
   6  * Copyright (c) 2018      Triad National Security, LLC. All rights
   7  *                         reserved.
   8  * $COPYRIGHT$
   9  *
  10  * Additional copyrights may follow
  11  *
  12  * $HEADER$
  13  */
  14 
  15 #include "ompi_config.h"
  16 #include "opal/datatype/opal_convertor.h"
  17 #include "ompi/datatype/ompi_datatype.h"
  18 #include "opal/datatype/opal_datatype_checksum.h"
  19 #include "opal/runtime/opal.h"
  20 
  21 #include <stdio.h>
  22 #include <stdlib.h>
  23 #include <time.h>
  24 
  25 #define SIZE 1024
  26 
  27 typedef struct {
  28     int useful;
  29     int useless;
  30 } my_data_t;
  31 
  32 int main( int argc, char* argv[] )
  33 {
  34     MPI_Datatype sparse;
  35     int *array, *packed;
  36     my_data_t* sparse_array;
  37     int i;
  38     uint32_t iov_count;
  39     size_t max_data;
  40     uint32_t pack_checksum, contiguous_checksum, sparse_checksum, manual_checksum;
  41     struct iovec iov[2];
  42     opal_convertor_t* convertor;
  43 
  44     opal_init_util (NULL, NULL);
  45     ompi_datatype_init();
  46     srandom( (int)time(NULL) );
  47     /*srandomdev();*/
  48 
  49     ompi_datatype_create_vector( SIZE, 1, 2, MPI_INT, &sparse );
  50     ompi_datatype_commit( &sparse );
  51 
  52     sparse_array = (my_data_t*)malloc( sizeof(my_data_t) * SIZE );
  53     array = (int*)malloc( sizeof(int) * SIZE );
  54     packed = (int*)malloc( sizeof(int) * SIZE );
  55 
  56     /**
  57      * Initialize the sparse data using the index.
  58      */
  59     for( i = 0; i < SIZE; i++ ) {
  60         sparse_array[i].useful = random();
  61         sparse_array[i].useless = 0;
  62     }
  63 
  64     /**
  65      * Pack the sparse data into the packed array. This simulate the first step
  66      * of the buffered operation.
  67      */
  68     convertor = opal_convertor_create( opal_local_arch, 0 );
  69     opal_convertor_personalize( convertor, CONVERTOR_WITH_CHECKSUM, NULL );
  70     opal_convertor_prepare_for_send( convertor, &(sparse->super), SIZE, sparse_array );
  71 
  72     iov[0].iov_base = packed;
  73     iov[0].iov_len = sizeof(int) * SIZE;
  74     max_data = iov[0].iov_len;
  75 
  76     iov_count = 1;
  77     opal_convertor_pack( convertor, iov, &iov_count, &max_data );
  78     pack_checksum = convertor->checksum;
  79 
  80     OBJ_RELEASE(convertor);
  81 
  82     /**
  83      * Now move the data from the packed array into the fragment to
  84      * be sent over the network (still simulation).
  85      */
  86     convertor = opal_convertor_create( opal_local_arch, 0 );
  87     opal_convertor_personalize( convertor, CONVERTOR_WITH_CHECKSUM, NULL );
  88     opal_convertor_prepare_for_send( convertor, &(ompi_mpi_int.dt.super), SIZE, packed );
  89 
  90     iov[0].iov_base = array;
  91     iov[0].iov_len = sizeof(int) * SIZE;
  92     max_data = iov[0].iov_len;
  93 
  94     iov_count = 1;
  95     opal_convertor_pack( convertor, iov, &iov_count, &max_data );
  96     contiguous_checksum = convertor->checksum;
  97 
  98     OBJ_RELEASE(convertor);
  99 
 100     /**
 101      * And now we're on the receiver side. We just get one fragment from
 102      * the network and now we unpack it in the user memory using 2
 103      * separate iovec.
 104      */
 105     convertor = opal_convertor_create( opal_local_arch, 0 );
 106     opal_convertor_personalize( convertor, CONVERTOR_WITH_CHECKSUM, NULL );
 107     opal_convertor_prepare_for_recv( convertor, &(sparse->super), SIZE, sparse_array );
 108 
 109     max_data = sizeof(int) * SIZE;
 110     iov[0].iov_base = array;
 111     iov[0].iov_len = max_data / 2;
 112     iov[1].iov_base = (char*)array + iov[0].iov_len;
 113     iov[1].iov_len = max_data - iov[0].iov_len;
 114 
 115     iov_count = 2;
 116     opal_convertor_unpack( convertor, iov, &iov_count, &max_data );
 117     sparse_checksum = convertor->checksum;
 118 
 119     OBJ_RELEASE(convertor);
 120 
 121     /**
 122      * The datatype is not useful anymore
 123      */
 124     OBJ_RELEASE(sparse);
 125 
 126     /**
 127      * The 3 checksum have to match.
 128      */
 129     printf( "contiguous checksum %x\n", contiguous_checksum );
 130     printf( "packed checksum     %x\n", pack_checksum );
 131     printf( "sparse checksum     %x\n", sparse_checksum );
 132     if( (sparse_checksum != contiguous_checksum) ||
 133         (pack_checksum != sparse_checksum) ) {
 134         printf( "ERROR!!! the checksum algorithm does not work as expected\n" );
 135         return 1;
 136     }
 137     printf( "COOL the 3 checksum match\n" );
 138 
 139     /**
 140      * Now that the packed buffer contain the data we want, let's try to call
 141      * the checksum directly to see if there is any difference.
 142      */
 143     {
 144         uint32_t ui1 = 0;
 145         size_t ui2 = 0;
 146         manual_checksum = OPAL_CSUM_PARTIAL( packed, sizeof(int) * SIZE, &ui1, &ui2 );
 147     }
 148     printf( "manual checksum     %x\n", manual_checksum );
 149 
 150     free(sparse_array);
 151     free(array);
 152     free(packed);
 153 
 154     /* clean-ups all data allocations */
 155     ompi_datatype_finalize();
 156     opal_finalize_util ();
 157 
 158     return 0;
 159 }

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