File: checksum.c

package info (click to toggle)
openmpi 5.0.8-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 201,684 kB
  • sloc: ansic: 613,078; makefile: 42,353; sh: 11,194; javascript: 9,244; f90: 7,052; java: 6,404; perl: 5,179; python: 1,859; lex: 740; fortran: 61; cpp: 20; tcl: 12
file content (158 lines) | stat: -rw-r--r-- 4,724 bytes parent folder | download | duplicates (3)
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
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
/*
 * Copyright (c) 2004-2006 The University of Tennessee and The University
 *                         of Tennessee Research Foundation.  All rights
 *                         reserved.
 * Copyright (c) 2018      Triad National Security, LLC. All rights
 *                         reserved.
 * $COPYRIGHT$
 *
 * Additional copyrights may follow
 *
 * $HEADER$
 */

#include "ompi_config.h"
#include "opal/datatype/opal_convertor.h"
#include "ompi/datatype/ompi_datatype.h"
#include "opal/datatype/opal_datatype_checksum.h"
#include "opal/runtime/opal.h"

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SIZE 1024

typedef struct {
    int useful;
    int useless;
} my_data_t;

int main( int argc, char* argv[] )
{
    MPI_Datatype sparse;
    int *array, *packed;
    my_data_t* sparse_array;
    int i;
    uint32_t iov_count;
    size_t max_data;
    uint32_t pack_checksum, contiguous_checksum, sparse_checksum, manual_checksum;
    struct iovec iov[2];
    opal_convertor_t* convertor;

    opal_init(NULL, NULL);
    ompi_datatype_init();
    srandom( (int)time(NULL) );
    /*srandomdev();*/

    ompi_datatype_create_vector( SIZE, 1, 2, MPI_INT, &sparse );
    ompi_datatype_commit( &sparse );

    sparse_array = (my_data_t*)malloc( sizeof(my_data_t) * SIZE );
    array = (int*)malloc( sizeof(int) * SIZE );
    packed = (int*)malloc( sizeof(int) * SIZE );

    /**
     * Initialize the sparse data using the index.
     */
    for( i = 0; i < SIZE; i++ ) {
        sparse_array[i].useful = random();
        sparse_array[i].useless = 0;
    }

    /**
     * Pack the sparse data into the packed array. This simulate the first step
     * of the buffered operation.
     */
    convertor = opal_convertor_create( opal_local_arch, 0 );
    opal_convertor_personalize( convertor, CONVERTOR_WITH_CHECKSUM, NULL );
    opal_convertor_prepare_for_send( convertor, &(sparse->super), SIZE, sparse_array );

    iov[0].iov_base = packed;
    iov[0].iov_len = sizeof(int) * SIZE;
    max_data = iov[0].iov_len;

    iov_count = 1;
    opal_convertor_pack( convertor, iov, &iov_count, &max_data );
    pack_checksum = convertor->checksum;

    OBJ_RELEASE(convertor);

    /**
     * Now move the data from the packed array into the fragment to
     * be sent over the network (still simulation).
     */
    convertor = opal_convertor_create( opal_local_arch, 0 );
    opal_convertor_personalize( convertor, CONVERTOR_WITH_CHECKSUM, NULL );
    opal_convertor_prepare_for_send( convertor, &(ompi_mpi_int.dt.super), SIZE, packed );

    iov[0].iov_base = array;
    iov[0].iov_len = sizeof(int) * SIZE;
    max_data = iov[0].iov_len;

    iov_count = 1;
    opal_convertor_pack( convertor, iov, &iov_count, &max_data );
    contiguous_checksum = convertor->checksum;

    OBJ_RELEASE(convertor);

    /**
     * And now we're on the receiver side. We just get one fragment from
     * the network and now we unpack it in the user memory using 2
     * separate iovec.
     */
    convertor = opal_convertor_create( opal_local_arch, 0 );
    opal_convertor_personalize( convertor, CONVERTOR_WITH_CHECKSUM, NULL );
    opal_convertor_prepare_for_recv( convertor, &(sparse->super), SIZE, sparse_array );

    max_data = sizeof(int) * SIZE;
    iov[0].iov_base = array;
    iov[0].iov_len = max_data / 2;
    iov[1].iov_base = (char*)array + iov[0].iov_len;
    iov[1].iov_len = max_data - iov[0].iov_len;

    iov_count = 2;
    opal_convertor_unpack( convertor, iov, &iov_count, &max_data );
    sparse_checksum = convertor->checksum;

    OBJ_RELEASE(convertor);

    /**
     * The datatype is not useful anymore
     */
    OBJ_RELEASE(sparse);

    /**
     * The 3 checksum have to match.
     */
    printf( "contiguous checksum %x\n", contiguous_checksum );
    printf( "packed checksum     %x\n", pack_checksum );
    printf( "sparse checksum     %x\n", sparse_checksum );
    if( (sparse_checksum != contiguous_checksum) ||
        (pack_checksum != sparse_checksum) ) {
        printf( "ERROR!!! the checksum algorithm does not work as expected\n" );
        return 1;
    }
    printf( "COOL the 3 checksum match\n" );

    /**
     * Now that the packed buffer contain the data we want, let's try to call
     * the checksum directly to see if there is any difference.
     */
    {
        uint32_t ui1 = 0;
        size_t ui2 = 0;
        manual_checksum = OPAL_CSUM_PARTIAL( packed, sizeof(int) * SIZE, &ui1, &ui2 );
    }
    printf( "manual checksum     %x\n", manual_checksum );

    free(sparse_array);
    free(array);
    free(packed);

    /* clean-ups all data allocations */
    opal_finalize_util();

    return 0;
}