forked from openkylin/openmpi
172 lines
5.2 KiB
C
172 lines
5.2 KiB
C
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
|
/*
|
|
* Copyright (c) 2018-2020 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 TYPE_COUNT 3
|
|
#define TYPE_BLEN 2
|
|
#define TYPE_STRIDE 4
|
|
|
|
#define CONT_COUNT 2
|
|
|
|
#define COUNT 3
|
|
|
|
#define CHUNK ((TYPE_BLEN*8)*2-4)
|
|
|
|
/**
|
|
* Print how many elements on both sides of ptr.
|
|
*/
|
|
static void show_neighborhood(double* ptr, int how_many, bool show_hex)
|
|
{
|
|
int i;
|
|
|
|
printf("%12p: ", (void*)ptr);
|
|
for( i = -how_many; i < how_many; i++ ) {
|
|
if( 0 == i ) {
|
|
printf(" <%g> ", ptr[i]);
|
|
} else {
|
|
printf(" %g ", ptr[i]);
|
|
}
|
|
}
|
|
if( show_hex ) {
|
|
char* cptr = (char*)ptr;
|
|
printf("\n : ");
|
|
for( i = -how_many; i < how_many; i++ ) {
|
|
if( 0 == i ) printf(" <");
|
|
for( int j = 0; j < sizeof(double); j++ ) {
|
|
printf("%02x", cptr[i * sizeof(double)+j]);
|
|
}
|
|
if( 0 == i ) printf("> ");
|
|
else printf(" ");
|
|
}
|
|
}
|
|
printf("\n\n");
|
|
}
|
|
|
|
/**
|
|
* -------G---[---][---] OPAL_LOOP_S 19 times the next 2 elements extent 18432
|
|
* -cC---P-DB-[---][---] OPAL_FLOAT8 count 72 disp 0x80 (128) blen 16 extent 256 (size 9216)
|
|
* -------G---[---][---] OPAL_LOOP_E prev 2 elements first elem displacement 128 size of data 9216
|
|
* -------G---[---][---] OPAL_LOOP_E prev 3 elements first elem displacement 128 size of data 175104
|
|
*/
|
|
|
|
int main( int argc, char* argv[] )
|
|
{
|
|
opal_datatype_t* vector;
|
|
ompi_datatype_t* base;
|
|
uint32_t iov_count;
|
|
size_t max_data, size, length;
|
|
struct iovec iov[2];
|
|
opal_convertor_t* convertor;
|
|
ptrdiff_t extent, base_extent;
|
|
double *array, *packed;
|
|
char* bpacked;
|
|
int i, j;
|
|
|
|
opal_init_util (NULL, NULL);
|
|
ompi_datatype_init();
|
|
|
|
ompi_datatype_create_vector(TYPE_COUNT, TYPE_BLEN, TYPE_STRIDE, MPI_DOUBLE, &base);
|
|
ompi_datatype_create_contiguous(CONT_COUNT, base, &vector);
|
|
|
|
opal_datatype_commit( vector );
|
|
|
|
ompi_datatype_dump(vector);
|
|
|
|
opal_datatype_type_size(vector, &size);
|
|
opal_datatype_type_extent(vector, &extent);
|
|
opal_datatype_type_extent(base, &base_extent);
|
|
|
|
array = (double*)malloc( extent * COUNT );
|
|
packed = (double*)malloc( size * COUNT );
|
|
bpacked = (char*)packed;
|
|
|
|
/**
|
|
* Initialize the sparse data using the index.
|
|
*/
|
|
for( i = 0; i < (TYPE_BLEN * TYPE_COUNT * CONT_COUNT * COUNT); i++ ) {
|
|
packed[i] = (double)(i % TYPE_BLEN);
|
|
}
|
|
memset(array, extent * COUNT, TYPE_BLEN + 1);
|
|
|
|
/**
|
|
* 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_prepare_for_recv( convertor, vector, COUNT, array );
|
|
|
|
for( length = 0; length < (size * COUNT); ) {
|
|
iov[0].iov_base = bpacked + length;
|
|
iov[0].iov_len = CHUNK;
|
|
max_data = iov[0].iov_len;
|
|
|
|
iov_count = 1;
|
|
opal_convertor_unpack( convertor, iov, &iov_count, &max_data );
|
|
length += max_data;
|
|
|
|
int idx = 0, checked = 0;
|
|
for( int m = 0; m < COUNT; m++ ) {
|
|
char* mptr = (char*)array + m * extent;
|
|
for( int k = 0; k < CONT_COUNT; k++ ) {
|
|
char* kptr = mptr + k * base_extent;
|
|
for( j = 0; j < TYPE_COUNT; j++ ) {
|
|
double* jarray = (double*)kptr + j * TYPE_STRIDE;
|
|
for( i = 0; i < TYPE_BLEN; i++ ) {
|
|
checked += sizeof(double);
|
|
if( checked > length )
|
|
goto next_iteration;
|
|
if( jarray[i] != (double)(idx % TYPE_BLEN) ) {
|
|
fprintf(stderr, "\n\n\nError during check for the %d element, length %" PRIsize_t " (chunk %d)\n",
|
|
idx, length, CHUNK);
|
|
fprintf(stderr, "Error at position %d [%d:%d:%d:%d] found %g expected %g\n\n\n",
|
|
idx, m, k, j, i, jarray[i], (double)(idx % TYPE_BLEN));
|
|
show_neighborhood(jarray + i, 4, true);
|
|
exit(-1);
|
|
}
|
|
idx++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
next_iteration:
|
|
/* nothing special to do here, just move to the next conversion */
|
|
continue;
|
|
}
|
|
|
|
OBJ_RELEASE(convertor);
|
|
|
|
/**
|
|
* The datatype is not useful anymore
|
|
*/
|
|
OBJ_RELEASE(vector);
|
|
|
|
free(array);
|
|
free(packed);
|
|
|
|
/* clean-ups all data allocations */
|
|
ompi_datatype_finalize();
|
|
opal_finalize_util ();
|
|
|
|
return 0;
|
|
}
|