1
1

Merge pull request #1509 from ggouaillardet/topic/external_support2

Add support for packing to/from external32 format.
Этот коммит содержится в:
bosilca 2016-03-30 15:51:14 -04:00
родитель 7eca2f9650 5932287cef
Коммит 21f59b81a7
16 изменённых файлов: 715 добавлений и 185 удалений

Просмотреть файл

@ -13,6 +13,8 @@
# Copyright (c) 2007-2013 Los Alamos National Security, LLC. All rights
# reserved.
# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
# Copyright (c) 2016 Research Organization for Information Science
# and Technology (RIST). All rights reserved.
# $COPYRIGHT$
#
# Additional copyrights may follow
@ -37,6 +39,7 @@ libdatatype_la_SOURCES = \
ompi_datatype_create_vector.c \
ompi_datatype_create_darray.c \
ompi_datatype_create_subarray.c \
ompi_datatype_external.c \
ompi_datatype_external32.c \
ompi_datatype_match_size.c \
ompi_datatype_module.c \

Просмотреть файл

@ -7,7 +7,7 @@
* Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2013 Los Alamos National Security, LLC. All rights
* reserved.
* Copyright (c) 2015 Research Organization for Information Science
* Copyright (c) 2015-2016 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
*
@ -363,5 +363,16 @@ OMPI_DECLSPEC int ompi_datatype_safeguard_pointer_debug_breakpoint( const void*
int count );
#endif /* OPAL_ENABLE_DEBUG */
OMPI_DECLSPEC int ompi_datatype_pack_external( const char datarep[], const void *inbuf, int incount,
ompi_datatype_t *datatype, void *outbuf,
MPI_Aint outsize, MPI_Aint *position);
OMPI_DECLSPEC int ompi_datatype_unpack_external( const char datarep[], const void *inbuf, MPI_Aint insize,
MPI_Aint *position, void *outbuf, int outcount,
ompi_datatype_t *datatype);
OMPI_DECLSPEC int ompi_datatype_pack_external_size( const char datarep[], int incount,
ompi_datatype_t *datatype, MPI_Aint *size);
END_C_DECLS
#endif /* OMPI_DATATYPE_H_HAS_BEEN_INCLUDED */

135
ompi/datatype/ompi_datatype_external.c Обычный файл
Просмотреть файл

@ -0,0 +1,135 @@
/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2016 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2013 Los Alamos National Security, LLC. All rights
* reserved.
* Copyright (c) 2015-2016 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "ompi_config.h"
#include <stdio.h>
#include "ompi/runtime/params.h"
#include "ompi/communicator/communicator.h"
#include "ompi/datatype/ompi_datatype.h"
#include "opal/datatype/opal_convertor.h"
int ompi_datatype_pack_external(const char datarep[], const void *inbuf, int incount,
ompi_datatype_t *datatype, void *outbuf,
MPI_Aint outsize, MPI_Aint *position)
{
int rc = MPI_SUCCESS;
opal_convertor_t local_convertor;
struct iovec invec;
unsigned int iov_count;
size_t size;
OBJ_CONSTRUCT(&local_convertor, opal_convertor_t);
/* The resulting convertor will be set to the position zero. We have to use
* CONVERTOR_SEND_CONVERSION in order to force the convertor to do anything
* more than just packing the data.
*/
opal_convertor_copy_and_prepare_for_send( ompi_mpi_external32_convertor,
&(datatype->super), incount, (void *) inbuf,
CONVERTOR_SEND_CONVERSION,
&local_convertor );
/* Check for truncation */
opal_convertor_get_packed_size( &local_convertor, &size );
if( (*position + size) > (size_t)outsize ) { /* we can cast as we already checked for < 0 */
OBJ_DESTRUCT( &local_convertor );
return MPI_ERR_TRUNCATE;
}
/* Prepare the iovec with all informations */
invec.iov_base = (char*) outbuf + (*position);
invec.iov_len = size;
/* Do the actual packing */
iov_count = 1;
rc = opal_convertor_pack( &local_convertor, &invec, &iov_count, &size );
*position += size;
OBJ_DESTRUCT( &local_convertor );
/* All done. Note that the convertor returns 1 upon success, not
OMPI_SUCCESS. */
return (rc == 1) ? OMPI_SUCCESS : MPI_ERR_UNKNOWN;
}
int ompi_datatype_unpack_external (const char datarep[], const void *inbuf, MPI_Aint insize,
MPI_Aint *position, void *outbuf, int outcount,
ompi_datatype_t *datatype)
{
int rc = MPI_SUCCESS;
opal_convertor_t local_convertor;
struct iovec outvec;
unsigned int iov_count;
size_t size;
OBJ_CONSTRUCT(&local_convertor, opal_convertor_t);
/* the resulting convertor will be set to the position ZERO */
opal_convertor_copy_and_prepare_for_recv( ompi_mpi_external32_convertor,
&(datatype->super), outcount, outbuf,
0,
&local_convertor );
/* Check for truncation */
opal_convertor_get_packed_size( &local_convertor, &size );
if( (*position + size) > (unsigned int)insize ) {
OBJ_DESTRUCT( &local_convertor );
return MPI_ERR_TRUNCATE;
}
/* Prepare the iovec with all informations */
outvec.iov_base = (char*) inbuf + (*position);
outvec.iov_len = size;
/* Do the actual unpacking */
iov_count = 1;
rc = opal_convertor_unpack( &local_convertor, &outvec, &iov_count, &size );
*position += size;
OBJ_DESTRUCT( &local_convertor );
/* All done. Note that the convertor returns 1 upon success, not
OMPI_SUCCESS. */
return (rc == 1) ? OMPI_SUCCESS : MPI_ERR_UNKNOWN;
}
int ompi_datatype_pack_external_size(const char datarep[], int incount,
ompi_datatype_t *datatype, MPI_Aint *size)
{
opal_convertor_t local_convertor;
size_t length;
OBJ_CONSTRUCT(&local_convertor, opal_convertor_t);
/* the resulting convertor will be set to the position ZERO */
opal_convertor_copy_and_prepare_for_recv( ompi_mpi_external32_convertor,
&(datatype->super), incount, NULL,
CONVERTOR_SEND_CONVERSION,
&local_convertor );
opal_convertor_get_unpacked_size( &local_convertor, &length );
*size = (MPI_Aint)length;
OBJ_DESTRUCT( &local_convertor );
return OMPI_SUCCESS;
}

Просмотреть файл

@ -3,7 +3,7 @@
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* Copyright (c) 2004-2016 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
@ -45,7 +45,7 @@ static const char FUNC_NAME[] = "MPI_Pack";
int MPI_Pack(const void *inbuf, int incount, MPI_Datatype datatype,
void *outbuf, int outsize, int *position, MPI_Comm comm)
{
int rc;
int rc = MPI_SUCCESS;
opal_convertor_t local_convertor;
struct iovec invec;
unsigned int iov_count;
@ -67,9 +67,11 @@ int MPI_Pack(const void *inbuf, int incount, MPI_Datatype datatype,
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME);
} else if (outsize < 0) {
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_ARG, FUNC_NAME);
} else if (MPI_DATATYPE_NULL == datatype || NULL == datatype) {
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME);
}
OMPI_CHECK_DATATYPE_FOR_SEND(rc, datatype, incount);
OMPI_ERRHANDLER_CHECK(rc, comm, rc, FUNC_NAME);
OMPI_CHECK_USER_BUFFER(rc, inbuf, datatype, incount);
OMPI_ERRHANDLER_CHECK(rc, comm, rc, FUNC_NAME);
}
OPAL_CR_ENTER_LIBRARY();

Просмотреть файл

@ -3,7 +3,7 @@
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* Copyright (c) 2004-2016 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
@ -46,11 +46,7 @@ int MPI_Pack_external(const char datarep[], const void *inbuf, int incount,
MPI_Datatype datatype, void *outbuf,
MPI_Aint outsize, MPI_Aint *position)
{
int rc;
opal_convertor_t local_convertor;
struct iovec invec;
unsigned int iov_count;
size_t size;
int rc = MPI_SUCCESS;
MEMCHECKER(
memchecker_datatype(datatype);
@ -65,46 +61,21 @@ int MPI_Pack_external(const char datarep[], const void *inbuf, int incount,
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COUNT, FUNC_NAME);
} else if (outsize < 0) {
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME);
} else if (MPI_DATATYPE_NULL == datatype || NULL == datatype) {
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_TYPE, FUNC_NAME);
}
OMPI_CHECK_DATATYPE_FOR_SEND(rc, datatype, incount);
OMPI_ERRHANDLER_CHECK(rc, MPI_COMM_WORLD, rc, FUNC_NAME);
OMPI_CHECK_USER_BUFFER(rc, inbuf, datatype, incount);
OMPI_ERRHANDLER_CHECK(rc, MPI_COMM_WORLD, rc, FUNC_NAME);
}
OPAL_CR_ENTER_LIBRARY();
OBJ_CONSTRUCT(&local_convertor, opal_convertor_t);
/* The resulting convertor will be set to the position zero. We have to use
* CONVERTOR_SEND_CONVERSION in order to force the convertor to do anything
* more than just packing the data.
*/
opal_convertor_copy_and_prepare_for_send( ompi_mpi_external32_convertor,
&(datatype->super), incount, (void *) inbuf,
CONVERTOR_SEND_CONVERSION,
&local_convertor );
/* Check for truncation */
opal_convertor_get_packed_size( &local_convertor, &size );
if( (*position + size) > (size_t)outsize ) { /* we can cast as we already checked for < 0 */
OBJ_DESTRUCT( &local_convertor );
OPAL_CR_EXIT_LIBRARY();
return OMPI_ERRHANDLER_INVOKE( MPI_COMM_WORLD, MPI_ERR_TRUNCATE, FUNC_NAME );
}
/* Prepare the iovec with all informations */
invec.iov_base = (char*) outbuf + (*position);
invec.iov_len = size;
/* Do the actual packing */
iov_count = 1;
rc = opal_convertor_pack( &local_convertor, &invec, &iov_count, &size );
*position += size;
OBJ_DESTRUCT( &local_convertor );
rc = ompi_datatype_pack_external(datarep, inbuf, incount,
datatype, outbuf,
outsize, position);
OPAL_CR_EXIT_LIBRARY();
/* All done. Note that the convertor returns 1 upon success, not
OMPI_SUCCESS. */
OMPI_ERRHANDLER_RETURN((rc == 1) ? OMPI_SUCCESS : OMPI_ERROR,
MPI_COMM_WORLD, MPI_ERR_UNKNOWN, FUNC_NAME);
OMPI_ERRHANDLER_RETURN((OMPI_SUCCESS == rc) ? OMPI_SUCCESS : OMPI_ERROR,
MPI_COMM_WORLD, rc, FUNC_NAME);
}

Просмотреть файл

@ -13,7 +13,7 @@
* Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2013 Los Alamos National Security, LLC. All rights
* reserved.
* Copyright (c) 2015 Research Organization for Information Science
* Copyright (c) 2015-2016 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
*
@ -45,8 +45,7 @@ static const char FUNC_NAME[] = "MPI_Pack_external_size";
int MPI_Pack_external_size(const char datarep[], int incount,
MPI_Datatype datatype, MPI_Aint *size)
{
opal_convertor_t local_convertor;
size_t length;
int rc = MPI_SUCCESS;
MEMCHECKER(
memchecker_datatype(datatype);
@ -63,18 +62,10 @@ int MPI_Pack_external_size(const char datarep[], int incount,
OPAL_CR_ENTER_LIBRARY();
OBJ_CONSTRUCT(&local_convertor, opal_convertor_t);
/* the resulting convertor will be set to the position ZERO */
opal_convertor_copy_and_prepare_for_recv( ompi_mpi_external32_convertor,
&(datatype->super), incount, NULL,
CONVERTOR_SEND_CONVERSION,
&local_convertor );
opal_convertor_get_unpacked_size( &local_convertor, &length );
*size = (MPI_Aint)length;
OBJ_DESTRUCT( &local_convertor );
rc = ompi_datatype_pack_external_size(datarep, incount,
datatype, size);
OPAL_CR_EXIT_LIBRARY();
return OMPI_SUCCESS;
OMPI_ERRHANDLER_RETURN((OMPI_SUCCESS == rc) ? OMPI_SUCCESS : OMPI_ERROR,
MPI_COMM_WORLD, rc, FUNC_NAME);
}

Просмотреть файл

@ -2,7 +2,7 @@
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* Copyright (c) 2004-2016 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
@ -43,7 +43,7 @@ int MPI_Unpack(const void *inbuf, int insize, int *position,
void *outbuf, int outcount, MPI_Datatype datatype,
MPI_Comm comm)
{
int rc = 1;
int rc = MPI_SUCCESS;
opal_convertor_t local_convertor;
struct iovec outvec;
unsigned int iov_count;
@ -70,9 +70,10 @@ int MPI_Unpack(const void *inbuf, int insize, int *position,
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_COUNT, FUNC_NAME);
}
if (MPI_DATATYPE_NULL == datatype || NULL == datatype) {
return OMPI_ERRHANDLER_INVOKE(comm, MPI_ERR_TYPE, FUNC_NAME);
}
OMPI_CHECK_DATATYPE_FOR_RECV(rc, datatype, outcount);
OMPI_ERRHANDLER_CHECK(rc, comm, rc, FUNC_NAME);
OMPI_CHECK_USER_BUFFER(rc, outbuf, datatype, outcount);
OMPI_ERRHANDLER_CHECK(rc, comm, rc, FUNC_NAME);
}
OPAL_CR_ENTER_LIBRARY();
@ -103,12 +104,11 @@ int MPI_Unpack(const void *inbuf, int insize, int *position,
/* All done. Note that the convertor returns 1 upon success, not
OMPI_SUCCESS. */
rc = (1 == rc) ? OMPI_SUCCESS : OMPI_ERROR;
}
OPAL_CR_EXIT_LIBRARY();
OMPI_ERRHANDLER_RETURN((rc == 1) ? OMPI_SUCCESS : OMPI_ERROR,
comm, MPI_ERR_UNKNOWN, FUNC_NAME);
}

Просмотреть файл

@ -3,7 +3,7 @@
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2005 The University of Tennessee and The University
* Copyright (c) 2004-2016 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2008 High Performance Computing Center Stuttgart,
@ -45,11 +45,7 @@ int MPI_Unpack_external (const char datarep[], const void *inbuf, MPI_Aint insiz
MPI_Aint *position, void *outbuf, int outcount,
MPI_Datatype datatype)
{
int rc;
opal_convertor_t local_convertor;
struct iovec outvec;
unsigned int iov_count;
size_t size;
int rc = MPI_SUCCESS;
MEMCHECKER(
memchecker_datatype(datatype);
@ -62,41 +58,21 @@ int MPI_Unpack_external (const char datarep[], const void *inbuf, MPI_Aint insiz
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME);
} else if (outcount < 0) {
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COUNT, FUNC_NAME);
} else if (MPI_DATATYPE_NULL == datatype || NULL == datatype) {
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_TYPE, FUNC_NAME);
}
OMPI_CHECK_DATATYPE_FOR_RECV(rc, datatype, outcount);
OMPI_ERRHANDLER_CHECK(rc, MPI_COMM_WORLD, rc, FUNC_NAME);
OMPI_CHECK_USER_BUFFER(rc, outbuf, datatype, outcount);
OMPI_ERRHANDLER_CHECK(rc, MPI_COMM_WORLD, rc, FUNC_NAME);
}
OPAL_CR_ENTER_LIBRARY();
OBJ_CONSTRUCT(&local_convertor, opal_convertor_t);
/* the resulting convertor will be set to the position ZERO */
opal_convertor_copy_and_prepare_for_recv( ompi_mpi_external32_convertor,
&(datatype->super), outcount, outbuf, 0, &local_convertor );
/* Check for truncation */
opal_convertor_get_packed_size( &local_convertor, &size );
if( (*position + size) > (unsigned int)insize ) {
OBJ_DESTRUCT( &local_convertor );
OPAL_CR_EXIT_LIBRARY();
return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_TRUNCATE, FUNC_NAME);
}
/* Prepare the iovec with all informations */
outvec.iov_base = (char*) inbuf + (*position);
outvec.iov_len = size;
/* Do the actual unpacking */
iov_count = 1;
rc = opal_convertor_unpack( &local_convertor, &outvec, &iov_count, &size );
*position += size;
OBJ_DESTRUCT( &local_convertor );
rc = ompi_datatype_unpack_external(datarep, inbuf, insize,
position, outbuf, outcount,
datatype);
OPAL_CR_EXIT_LIBRARY();
/* All done. Note that the convertor returns 1 upon success, not
OMPI_SUCCESS. */
OMPI_ERRHANDLER_RETURN((rc == 1) ? OMPI_SUCCESS : OMPI_ERROR,
MPI_COMM_WORLD, MPI_ERR_UNKNOWN, FUNC_NAME);
OMPI_ERRHANDLER_RETURN((OMPI_SUCCESS == rc) ? OMPI_SUCCESS : OMPI_ERROR,
MPI_COMM_WORLD, rc, FUNC_NAME);
}

Просмотреть файл

@ -3,7 +3,7 @@
* Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2014 The University of Tennessee and The University
* Copyright (c) 2004-2016 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
@ -12,7 +12,7 @@
* All rights reserved.
* Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
* Copyright (c) 2011 NVIDIA Corporation. All rights reserved.
* Copyright (c) 2013 Research Organization for Information Science
* Copyright (c) 2013-2016 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* $COPYRIGHT$
*
@ -449,16 +449,17 @@ int32_t opal_convertor_set_position_nocheck( opal_convertor_t* convertor,
/**
* Compute the remote size.
* Compute the remote size. If necessary remove the homogeneous flag
* and redirect the convertor description toward the non-optimized
* datatype representation.
*/
#if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
#define OPAL_CONVERTOR_COMPUTE_REMOTE_SIZE(convertor, datatype, bdt_mask) \
{ \
if( OPAL_UNLIKELY(0 != (bdt_mask)) ) { \
opal_convertor_master_t* master; \
int i; \
uint32_t mask = datatype->bdt_used; \
convertor->flags ^= CONVERTOR_HOMOGENEOUS; \
convertor->flags &= (~CONVERTOR_HOMOGENEOUS); \
master = convertor->master; \
convertor->remote_size = 0; \
for( i = OPAL_DATATYPE_FIRST_TYPE; mask && (i < OPAL_DATATYPE_MAX_PREDEFINED); i++ ) { \
@ -472,13 +473,6 @@ int32_t opal_convertor_set_position_nocheck( opal_convertor_t* convertor,
convertor->use_desc = &(datatype->desc); \
} \
}
#else
#define OPAL_CONVERTOR_COMPUTE_REMOTE_SIZE(convertor, datatype, bdt_mask) \
{ \
assert(0 == (bdt_mask)); \
(void)bdt_mask; /* silence compiler warning */ \
}
#endif /* OPAL_ENABLE_HETEROGENEOUS_SUPPORT */
/**
* This macro will initialize a convertor based on a previously created
@ -511,16 +505,13 @@ int32_t opal_convertor_set_position_nocheck( opal_convertor_t* convertor,
convertor->flags |= (CONVERTOR_NO_OP | CONVERTOR_HOMOGENEOUS); \
convertor->pDesc = (opal_datatype_t*)datatype; \
convertor->bConverted = 0; \
/* By default consider the optimized description */ \
convertor->use_desc = &(datatype->opt_desc); \
\
convertor->remote_size = convertor->local_size; \
if( OPAL_LIKELY(convertor->remoteArch == opal_local_arch) ) { \
if( (convertor->flags & (CONVERTOR_WITH_CHECKSUM | OPAL_DATATYPE_FLAG_NO_GAPS)) == OPAL_DATATYPE_FLAG_NO_GAPS ) { \
return OPAL_SUCCESS; \
} \
if( ((convertor->flags & (CONVERTOR_WITH_CHECKSUM | OPAL_DATATYPE_FLAG_CONTIGUOUS)) \
== OPAL_DATATYPE_FLAG_CONTIGUOUS) && (1 == count) ) { \
if( !(convertor->flags & CONVERTOR_WITH_CHECKSUM) && \
((convertor->flags & OPAL_DATATYPE_FLAG_NO_GAPS) || \
((convertor->flags & OPAL_DATATYPE_FLAG_CONTIGUOUS) && (1 == count))) ) { \
return OPAL_SUCCESS; \
} \
} \
@ -532,8 +523,9 @@ int32_t opal_convertor_set_position_nocheck( opal_convertor_t* convertor,
/* For predefined datatypes (contiguous) do nothing more */ \
/* if checksum is enabled then always continue */ \
if( ((convertor->flags & (CONVERTOR_WITH_CHECKSUM | OPAL_DATATYPE_FLAG_NO_GAPS)) \
== OPAL_DATATYPE_FLAG_NO_GAPS) && \
(convertor->flags & (CONVERTOR_SEND | CONVERTOR_HOMOGENEOUS)) ) { \
== OPAL_DATATYPE_FLAG_NO_GAPS) && \
((convertor->flags & (CONVERTOR_SEND | CONVERTOR_HOMOGENEOUS)) == \
(CONVERTOR_SEND | CONVERTOR_HOMOGENEOUS)) ) { \
return OPAL_SUCCESS; \
} \
convertor->flags &= ~CONVERTOR_NO_OP; \
@ -566,26 +558,24 @@ int32_t opal_convertor_prepare_for_recv( opal_convertor_t* convertor,
OPAL_CONVERTOR_PREPARE( convertor, datatype, count, pUserBuf );
if( convertor->flags & CONVERTOR_WITH_CHECKSUM ) {
#if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
if( !(convertor->flags & CONVERTOR_HOMOGENEOUS) ) {
convertor->fAdvance = opal_unpack_general_checksum;
} else
#endif
if( convertor->pDesc->flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
convertor->fAdvance = opal_unpack_homogeneous_contig_checksum;
} else {
convertor->fAdvance = opal_generic_simple_unpack_checksum;
if( convertor->pDesc->flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
convertor->fAdvance = opal_unpack_homogeneous_contig_checksum;
} else {
convertor->fAdvance = opal_generic_simple_unpack_checksum;
}
}
} else {
#if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
if( !(convertor->flags & CONVERTOR_HOMOGENEOUS) ) {
convertor->fAdvance = opal_unpack_general;
} else
#endif
if( convertor->pDesc->flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
convertor->fAdvance = opal_unpack_homogeneous_contig;
} else {
convertor->fAdvance = opal_generic_simple_unpack;
if( convertor->pDesc->flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
convertor->fAdvance = opal_unpack_homogeneous_contig;
} else {
convertor->fAdvance = opal_generic_simple_unpack;
}
}
}
return OPAL_SUCCESS;
@ -605,24 +595,32 @@ int32_t opal_convertor_prepare_for_send( opal_convertor_t* convertor,
OPAL_CONVERTOR_PREPARE( convertor, datatype, count, pUserBuf );
if( convertor->flags & CONVERTOR_WITH_CHECKSUM ) {
if( datatype->flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
if( ((datatype->ub - datatype->lb) == (OPAL_PTRDIFF_TYPE)datatype->size)
|| (1 >= convertor->count) )
convertor->fAdvance = opal_pack_homogeneous_contig_checksum;
else
convertor->fAdvance = opal_pack_homogeneous_contig_with_gaps_checksum;
if( CONVERTOR_SEND_CONVERSION == (convertor->flags & (CONVERTOR_SEND_CONVERSION|CONVERTOR_HOMOGENEOUS)) ) {
convertor->fAdvance = opal_pack_general_checksum;
} else {
convertor->fAdvance = opal_generic_simple_pack_checksum;
if( datatype->flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
if( ((datatype->ub - datatype->lb) == (OPAL_PTRDIFF_TYPE)datatype->size)
|| (1 >= convertor->count) )
convertor->fAdvance = opal_pack_homogeneous_contig_checksum;
else
convertor->fAdvance = opal_pack_homogeneous_contig_with_gaps_checksum;
} else {
convertor->fAdvance = opal_generic_simple_pack_checksum;
}
}
} else {
if( datatype->flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
if( ((datatype->ub - datatype->lb) == (OPAL_PTRDIFF_TYPE)datatype->size)
|| (1 >= convertor->count) )
convertor->fAdvance = opal_pack_homogeneous_contig;
else
convertor->fAdvance = opal_pack_homogeneous_contig_with_gaps;
if( CONVERTOR_SEND_CONVERSION == (convertor->flags & (CONVERTOR_SEND_CONVERSION|CONVERTOR_HOMOGENEOUS)) ) {
convertor->fAdvance = opal_pack_general;
} else {
convertor->fAdvance = opal_generic_simple_pack;
if( datatype->flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
if( ((datatype->ub - datatype->lb) == (OPAL_PTRDIFF_TYPE)datatype->size)
|| (1 >= convertor->count) )
convertor->fAdvance = opal_pack_homogeneous_contig;
else
convertor->fAdvance = opal_pack_homogeneous_contig_with_gaps;
} else {
convertor->fAdvance = opal_generic_simple_pack;
}
}
}
return OPAL_SUCCESS;
@ -678,15 +676,33 @@ int opal_convertor_clone( const opal_convertor_t* source,
void opal_convertor_dump( opal_convertor_t* convertor )
{
printf( "Convertor %p count %d stack position %d bConverted %ld\n", (void*)convertor,
convertor->count, convertor->stack_pos, (unsigned long)convertor->bConverted );
printf( "\tlocal_size %ld remote_size %ld flags %X stack_size %d pending_length %d\n",
(unsigned long)convertor->local_size, (unsigned long)convertor->remote_size,
convertor->flags, convertor->stack_size, convertor->partial_length );
opal_output( 0, "Convertor %p count %d stack position %d bConverted %ld\n"
"\tlocal_size %ld remote_size %ld flags %X stack_size %d pending_length %d\n"
"\tremote_arch %u local_arch %u\n",
(void*)convertor,
convertor->count, convertor->stack_pos, (unsigned long)convertor->bConverted,
(unsigned long)convertor->local_size, (unsigned long)convertor->remote_size,
convertor->flags, convertor->stack_size, convertor->partial_length,
convertor->remoteArch, opal_local_arch );
if( convertor->flags & CONVERTOR_RECV ) opal_output( 0, "unpack ");
if( convertor->flags & CONVERTOR_SEND ) opal_output( 0, "pack ");
if( convertor->flags & CONVERTOR_SEND_CONVERSION ) opal_output( 0, "conversion ");
if( convertor->flags & CONVERTOR_HOMOGENEOUS ) opal_output( 0, "homogeneous " );
else opal_output( 0, "heterogeneous ");
if( convertor->flags & CONVERTOR_NO_OP ) opal_output( 0, "no_op ");
if( convertor->flags & CONVERTOR_WITH_CHECKSUM ) opal_output( 0, "checksum ");
if( convertor->flags & CONVERTOR_CUDA ) opal_output( 0, "CUDA ");
if( convertor->flags & CONVERTOR_CUDA_ASYNC ) opal_output( 0, "CUDA Async ");
if( convertor->flags & CONVERTOR_COMPLETED ) opal_output( 0, "COMPLETED ");
opal_datatype_dump( convertor->pDesc );
printf( "Actual stack representation\n" );
opal_datatype_dump_stack( convertor->pStack, convertor->stack_pos,
convertor->pDesc->desc.desc, convertor->pDesc->name );
if( !((0 == convertor->stack_pos) &&
((size_t)convertor->pStack[convertor->stack_pos].index > convertor->pDesc->desc.length)) ) {
/* only if the convertor is completely initialized */
opal_output( 0, "Actual stack representation\n" );
opal_datatype_dump_stack( convertor->pStack, convertor->stack_pos,
convertor->pDesc->desc.desc, convertor->pDesc->name );
}
}

Просмотреть файл

@ -175,9 +175,7 @@ static inline int opal_convertor_cleanup( opal_convertor_t* convertor )
*/
static inline int32_t opal_convertor_need_buffers( const opal_convertor_t* pConvertor )
{
#if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
if (OPAL_UNLIKELY(0 == (pConvertor->flags & CONVERTOR_HOMOGENEOUS))) return 1;
#endif
#if OPAL_CUDA_SUPPORT
if( pConvertor->flags & (CONVERTOR_CUDA | CONVERTOR_CUDA_UNIFIED)) return 1;
#endif

Просмотреть файл

@ -3,7 +3,7 @@
* Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2009 The University of Tennessee and The University
* Copyright (c) 2004-2016 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
@ -278,27 +278,14 @@ int32_t opal_datatype_add( opal_datatype_t* pdtBase, const opal_datatype_t* pdtA
*/
if( (pdtAdd->flags & (OPAL_DATATYPE_FLAG_PREDEFINED | OPAL_DATATYPE_FLAG_DATA)) == (OPAL_DATATYPE_FLAG_PREDEFINED | OPAL_DATATYPE_FLAG_DATA) ) {
pdtBase->btypes[pdtAdd->id] += count;
pLast->elem.common.type = pdtAdd->id;
pLast->elem.count = count;
pLast->elem.disp = disp;
pLast->elem.extent = extent;
pdtBase->desc.used++;
pLast->elem.common.flags = pdtAdd->flags & ~(OPAL_DATATYPE_FLAG_COMMITTED);
if( (extent != (OPAL_PTRDIFF_TYPE)pdtAdd->size) && (count > 1) ) { /* gaps around the datatype */
localFlags = pdtAdd->flags & ~(OPAL_DATATYPE_FLAG_COMMITTED | OPAL_DATATYPE_FLAG_CONTIGUOUS | OPAL_DATATYPE_FLAG_NO_GAPS);
CREATE_LOOP_START( pLast, count, 2, extent, localFlags );
pLast++;
pLast->elem.common.type = pdtAdd->id;
pLast->elem.count = 1;
pLast->elem.disp = disp;
pLast->elem.extent = pdtAdd->size;
pLast->elem.common.flags = localFlags | OPAL_DATATYPE_FLAG_CONTIGUOUS;
pLast++;
CREATE_LOOP_END( pLast, 2, disp, pdtAdd->size, localFlags );
pdtBase->desc.used += 3;
pdtBase->btypes[OPAL_DATATYPE_LOOP] = 1;
pdtBase->btypes[OPAL_DATATYPE_END_LOOP] = 1;
} else {
pLast->elem.common.type = pdtAdd->id;
pLast->elem.count = count;
pLast->elem.disp = disp;
pLast->elem.extent = extent;
pdtBase->desc.used++;
pLast->elem.common.flags = pdtAdd->flags & ~(OPAL_DATATYPE_FLAG_COMMITTED);
pLast->elem.common.flags &= ~(OPAL_DATATYPE_FLAG_CONTIGUOUS | OPAL_DATATYPE_FLAG_NO_GAPS);
}
} else {
/* keep trace of the total number of basic datatypes in the datatype definition */

Просмотреть файл

@ -89,8 +89,8 @@ int opal_datatype_dump_data_desc( dt_elem_desc_t* pDesc, int nbElems, char* ptr,
(int)pDesc->end_loop.items, (long)pDesc->end_loop.first_elem_disp,
(int)pDesc->end_loop.size );
else
index += snprintf( ptr + index, length - index, "count %d disp 0x%lx (%ld) extent %d (size %ld)\n",
(int)pDesc->elem.count, (long)pDesc->elem.disp, (long)pDesc->elem.disp,
index += snprintf( ptr + index, length - index, "count %d disp 0x%lx (%ld) blen %d extent %d (size %ld)\n",
(int)pDesc->elem.count, (long)pDesc->elem.disp, (long)pDesc->elem.disp, (int)pDesc->elem.blocklen,
(int)pDesc->elem.extent, (long)(pDesc->elem.count * opal_datatype_basicDatatypes[pDesc->elem.common.type]->size) );
pDesc++;

Просмотреть файл

@ -3,7 +3,7 @@
* Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2014 The University of Tennessee and The University
* Copyright (c) 2004-2016 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
@ -42,10 +42,12 @@
#define opal_pack_homogeneous_contig_function opal_pack_homogeneous_contig_checksum
#define opal_pack_homogeneous_contig_with_gaps_function opal_pack_homogeneous_contig_with_gaps_checksum
#define opal_generic_simple_pack_function opal_generic_simple_pack_checksum
#define opal_pack_general_function opal_pack_general_checksum
#else
#define opal_pack_homogeneous_contig_function opal_pack_homogeneous_contig
#define opal_pack_homogeneous_contig_with_gaps_function opal_pack_homogeneous_contig_with_gaps
#define opal_generic_simple_pack_function opal_generic_simple_pack
#define opal_pack_general_function opal_pack_general
#endif /* defined(CHECKSUM) */
@ -393,3 +395,199 @@ opal_generic_simple_pack_function( opal_convertor_t* pConvertor,
pConvertor->stack_pos, pStack->index, (int)pStack->count, (long)pStack->disp ); );
return 0;
}
/*
* Remember that the first item in the stack (ie. position 0) is the number
* of times the datatype is involved in the operation (ie. the count argument
* in the MPI_ call).
*/
/* Convert data from multiple input buffers (as received from the network layer)
* to a contiguous output buffer with a predefined size.
* return OPAL_SUCCESS if everything went OK and if there is still room before the complete
* conversion of the data (need additional call with others input buffers )
* 1 if everything went fine and the data was completly converted
* -1 something wrong occurs.
*/
static inline void
pack_predefined_heterogeneous( opal_convertor_t* CONVERTOR,
const dt_elem_desc_t* ELEM,
uint32_t* COUNT,
unsigned char** SOURCE,
unsigned char** DESTINATION,
size_t* SPACE )
{
uint32_t _count = *(COUNT);
size_t _r_blength, _l_blength;
const ddt_elem_desc_t* _elem = &((ELEM)->elem);
unsigned char* _source = (*SOURCE) + _elem->disp;
const opal_convertor_master_t* master = (CONVERTOR)->master;
OPAL_PTRDIFF_TYPE advance;
_r_blength = master->remote_sizes[_elem->common.type];
_l_blength = opal_datatype_basicDatatypes[_elem->common.type]->size;
if( (_count * _r_blength) > *(SPACE) ) {
_count = (uint32_t)(*(SPACE) / _r_blength);
if( 0 == _count ) return; /* nothing to do */
}
OPAL_DATATYPE_SAFEGUARD_POINTER( _source, (_count * _elem->extent), (CONVERTOR)->pBaseBuf,
(CONVERTOR)->pDesc, (CONVERTOR)->count );
DO_DEBUG( opal_output( 0, "pack [l %s r %s] memcpy( %p, %p, %lu ) => space %lu\n",
((OPAL_PTRDIFF_TYPE)_l_blength == _elem->extent) ? "cont" : "----",
((OPAL_PTRDIFF_TYPE)_r_blength == _elem->extent) ? "cont" : "----",
*(DESTINATION), _source, (unsigned long)_r_blength,
(unsigned long)(*(SPACE)) ); );
master->pFunctions[_elem->common.type]( CONVERTOR, _count,
_source, *SPACE, _elem->extent,
*DESTINATION, *SPACE, _r_blength,
&advance );
_r_blength *= _count; /* update the remote length to encompass all the elements */
*(SOURCE) += _count * _elem->extent;
*(DESTINATION) += _r_blength;
*(SPACE) -= _r_blength;
*(COUNT) -= _count;
}
int32_t
opal_pack_general_function( opal_convertor_t* pConvertor,
struct iovec* iov, uint32_t* out_size,
size_t* max_data )
{
dt_stack_t* pStack; /* pointer to the position on the stack */
uint32_t pos_desc; /* actual position in the description of the derived datatype */
uint32_t count_desc; /* the number of items already done in the actual pos_desc */
size_t total_packed = 0; /* total amount packed this time */
dt_elem_desc_t* description;
dt_elem_desc_t* pElem;
const opal_datatype_t *pData = pConvertor->pDesc;
unsigned char *conv_ptr, *iov_ptr;
size_t iov_len_local;
uint32_t iov_count;
int type, rc;
const opal_convertor_master_t* master = pConvertor->master;
ptrdiff_t advance;
DO_DEBUG( opal_output( 0, "opal_convertor_general_pack( %p:%p, {%p, %lu}, %d )\n",
(void*)pConvertor, (void*)pConvertor->pBaseBuf,
iov[0].iov_base, (unsigned long)iov[0].iov_len, *out_size ); );
description = pConvertor->use_desc->desc;
/* For the first step we have to add both displacement to the source. After in the
* main while loop we will set back the conv_ptr to the correct value. This is
* due to the fact that the convertor can stop in the middle of a data with a count
*/
pStack = pConvertor->pStack + pConvertor->stack_pos;
pos_desc = pStack->index;
conv_ptr = pConvertor->pBaseBuf + pStack->disp;
count_desc = (uint32_t)pStack->count;
pStack--;
pConvertor->stack_pos--;
pElem = &(description[pos_desc]);
DO_DEBUG( opal_output( 0, "pack start pos_desc %d count_desc %d disp %ld\n"
"stack_pos %d pos_desc %d count_desc %d disp %ld\n",
pos_desc, count_desc, (long)(conv_ptr - pConvertor->pBaseBuf),
pConvertor->stack_pos, pStack->index, (int)pStack->count, (long)pStack->disp ); );
for( iov_count = 0; iov_count < (*out_size); iov_count++ ) {
iov_ptr = (unsigned char *) iov[iov_count].iov_base;
iov_len_local = iov[iov_count].iov_len;
while( 1 ) {
while( pElem->elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
type = description[pos_desc].elem.common.type;
/* now here we have a basic datatype */
DO_DEBUG( opal_output( 0, "pack (%p:%ld, %d, %ld) -> (%p, %ld) type %s\n",
pConvertor->pBaseBuf, conv_ptr + pElem->elem.disp - pConvertor->pBaseBuf,
count_desc, description[pos_desc].elem.extent,
iov_ptr, iov_len_local,
opal_datatype_basicDatatypes[type]->name ); );
pack_predefined_heterogeneous( pConvertor, pElem, &count_desc,
&conv_ptr, &iov_ptr, &iov_len_local);
#if 0
PACK_PREDEFINED_DATATYPE( pConvertor, pElem, count_desc,
conv_ptr, iov_ptr, iov_len_local );
#endif
if( 0 == count_desc ) { /* completed */
conv_ptr = pConvertor->pBaseBuf + pStack->disp;
pos_desc++; /* advance to the next data */
UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
continue;
}
goto complete_loop;
}
if( OPAL_DATATYPE_END_LOOP == pElem->elem.common.type ) { /* end of the current loop */
DO_DEBUG( opal_output( 0, "pack end_loop count %d stack_pos %d"
" pos_desc %d disp %ld space %lu\n",
(int)pStack->count, pConvertor->stack_pos,
pos_desc, (long)pStack->disp, (unsigned long)iov_len_local ); );
if( --(pStack->count) == 0 ) { /* end of loop */
if( 0 == pConvertor->stack_pos ) {
/* we lie about the size of the next element in order to
* make sure we exit the main loop.
*/
*out_size = iov_count;
goto complete_loop; /* completed */
}
pConvertor->stack_pos--;
pStack--;
pos_desc++;
} else {
pos_desc = pStack->index + 1;
if( pStack->index == -1 ) {
pStack->disp += (pData->ub - pData->lb);
} else {
assert( OPAL_DATATYPE_LOOP == description[pStack->index].loop.common.type );
pStack->disp += description[pStack->index].loop.extent;
}
}
conv_ptr = pConvertor->pBaseBuf + pStack->disp;
UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
DO_DEBUG( opal_output( 0, "pack new_loop count %d stack_pos %d pos_desc %d count_desc %d disp %ld space %lu\n",
(int)pStack->count, pConvertor->stack_pos, pos_desc,
count_desc, (long)pStack->disp, (unsigned long)iov_len_local ); );
}
if( OPAL_DATATYPE_LOOP == pElem->elem.common.type ) {
OPAL_PTRDIFF_TYPE local_disp = (OPAL_PTRDIFF_TYPE)conv_ptr;
#if 0
if( pElem->loop.common.flags & OPAL_DATATYPE_FLAG_CONTIGUOUS ) {
PACK_CONTIGUOUS_LOOP( pConvertor, pElem, count_desc,
conv_ptr, iov_ptr, iov_len_local );
if( 0 == count_desc ) { /* completed */
pos_desc += pElem->loop.items + 1;
goto update_loop_description;
}
/* Save the stack with the correct last_count value. */
}
#endif /* in a heterogeneous environment we can't handle the contiguous loops */
local_disp = (OPAL_PTRDIFF_TYPE)conv_ptr - local_disp;
PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, OPAL_DATATYPE_LOOP, count_desc,
pStack->disp + local_disp);
pos_desc++;
update_loop_description: /* update the current state */
conv_ptr = pConvertor->pBaseBuf + pStack->disp;
UPDATE_INTERNAL_COUNTERS( description, pos_desc, pElem, count_desc );
DDT_DUMP_STACK( pConvertor->pStack, pConvertor->stack_pos, pElem, "advance loop" );
continue;
}
}
complete_loop:
iov[iov_count].iov_len -= iov_len_local; /* update the amount of valid data */
total_packed += iov[iov_count].iov_len;
}
*max_data = total_packed;
pConvertor->bConverted += total_packed; /* update the already converted bytes */
*out_size = iov_count;
if( pConvertor->bConverted == pConvertor->local_size ) {
pConvertor->flags |= CONVERTOR_COMPLETED;
return 1;
}
/* Save the global position for the next round */
PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, pElem->elem.common.type, count_desc,
conv_ptr - pConvertor->pBaseBuf );
DO_DEBUG( opal_output( 0, "pack save stack stack_pos %d pos_desc %d count_desc %d disp %ld\n",
pConvertor->stack_pos, pStack->index, (int)pStack->count, (long)pStack->disp ); );
return 0;
}

Просмотреть файл

@ -1,6 +1,6 @@
/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* Copyright (c) 2004-2009 The University of Tennessee and The University
* Copyright (c) 2004-2016 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
@ -24,6 +24,14 @@ BEGIN_C_DECLS
*/
OPAL_DECLSPEC int32_t
opal_pack_general( opal_convertor_t* pConvertor,
struct iovec* iov, uint32_t* out_size,
size_t* max_data );
OPAL_DECLSPEC int32_t
opal_pack_general_checksum( opal_convertor_t* pConvertor,
struct iovec* iov, uint32_t* out_size,
size_t* max_data );
OPAL_DECLSPEC int32_t
opal_unpack_general( opal_convertor_t* pConvertor,
struct iovec* iov, uint32_t* out_size,
size_t* max_data );

Просмотреть файл

@ -14,7 +14,7 @@
#
if PROJECT_OMPI
MPI_TESTS = checksum position position_noncontig ddt_test ddt_raw unpack_ooo ddt_pack
MPI_TESTS = checksum position position_noncontig ddt_test ddt_raw unpack_ooo ddt_pack external32
MPI_CHECKS = to_self
endif
TESTS = opal_datatype_test $(MPI_TESTS)
@ -72,5 +72,11 @@ opal_datatype_test_LDFLAGS = $(OMPI_PKG_CONFIG_LDFLAGS)
opal_datatype_test_LDADD = \
$(top_builddir)/opal/lib@OPAL_LIB_PREFIX@open-pal.la
external32_SOURCES = external32.c
external32_LDFLAGS = $(OMPI_PKG_CONFIG_LDFLAGS)
external32_LDADD = \
$(top_builddir)/ompi/libmpi.la \
$(top_builddir)/opal/lib@OPAL_LIB_PREFIX@open-pal.la
distclean:
rm -rf *.dSYM .deps .libs *.log *.o *.trs $(check_PROGRAMS) Makefile

228
test/datatype/external32.c Обычный файл
Просмотреть файл

@ -0,0 +1,228 @@
/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* Copyright (c) 2016 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include <stdio.h>
#include <stdlib.h>
#include "ompi_config.h"
#include "ompi/datatype/ompi_datatype.h"
#include "opal/runtime/opal.h"
#include "opal/datatype/opal_convertor.h"
#include "opal/datatype/opal_datatype_internal.h"
#include <arpa/inet.h>
static int verbose = 0;
typedef int (*checker_t)(void*, void*, ompi_datatype_t *, int, void*);
int check_contiguous( void* send_buffer, void* packed,
ompi_datatype_t * datatype, int count, void* arg );
int check_vector( void* send_buffer, void* packed,
ompi_datatype_t * datatype, int count, void* arg );
static int pack_unpack_datatype( void* send_data, ompi_datatype_t *datatype, int count,
void* recv_data, checker_t validator, void *validator_arg );
static void dump_hex(void* what, size_t length);
static void dump_hex(void* what, size_t length)
{
size_t i;
for( i = 0; i < length; i++ ) {
printf("%02x", (unsigned int)(((unsigned char*)what)[i]));
}
}
int check_contiguous( void* send_buffer, void* packed,
ompi_datatype_t* datatype, int count, void* arg )
{
int i;
if( (datatype == &ompi_mpi_int.dt) || (datatype == &ompi_mpi_int32_t.dt) ) {
uint32_t val;
for( i = 0 ; i < count; i++ ) {
val = htonl(((uint32_t*)send_buffer)[i]);
if( val != ((uint32_t*)packed)[i] ) {
printf("Error at position %d expected %x found %x (type %s)\n",
i, ((uint32_t*)packed)[i], ((uint32_t*)send_buffer)[i], datatype->name);
return -1;
}
}
} else if( (datatype == &ompi_mpi_short.dt) || (datatype == &ompi_mpi_int16_t.dt) ) {
uint16_t val;
for( i = 0 ; i < count; i++ ) {
val = htons(((uint16_t*)send_buffer)[i]);
if( val != ((uint16_t*)packed)[i] ) {
printf("Error at position %d expected %x found %x (type %s)\n",
i, ((uint16_t*)packed)[i], ((uint16_t*)send_buffer)[i], datatype->name);
return -1;
}
}
} else {
printf("Unknown type\n");
return -1;
}
return 0;
}
int check_vector( void* send_buffer, void* packed,
ompi_datatype_t* datatype, int count, void* arg )
{
int i;
ompi_datatype_t *origtype = (ompi_datatype_t *)arg;
if( (origtype == &ompi_mpi_int.dt) || (origtype == &ompi_mpi_int32_t.dt) ) {
uint32_t val;
for( i = 0 ; i < count; i++ ) {
val = htonl(((uint32_t*)send_buffer)[2*i]);
if( val != ((uint32_t*)packed)[i] ) {
printf("Error at position %d expected %x found %x (type %s)\n",
i, ((uint32_t*)packed)[i], ((uint32_t*)send_buffer)[2*i], datatype->name);
return -1;
}
}
} else if( (origtype == &ompi_mpi_short.dt) || (origtype == &ompi_mpi_int16_t.dt) ) {
uint16_t val;
for( i = 0 ; i < count; i++ ) {
val = htons(((uint16_t*)send_buffer)[2*i]);
if( val != ((uint16_t*)packed)[i] ) {
printf("Error at position %d expected %x found %x (type %s)\n",
i, ((uint16_t*)packed)[i], ((uint16_t*)send_buffer)[2*i], datatype->name);
return -1;
}
}
} else {
printf("Unknown %s type\n", datatype->name);
return -1;
}
return 0;
}
static int pack_unpack_datatype( void* send_data, ompi_datatype_t *datatype, int count,
void* recv_data,
checker_t validator, void* validator_arg)
{
MPI_Aint position = 0, buffer_size;
void* buffer;
int error;
error = ompi_datatype_pack_external_size("external32",
count, datatype, &buffer_size);
if( MPI_SUCCESS != error ) goto return_error_code;
buffer = (void*)malloc(buffer_size);
if( NULL == buffer ) { error = MPI_ERR_UNKNOWN; goto return_error_code; }
error = ompi_datatype_pack_external("external32", (void*)send_data, count, datatype,
buffer, buffer_size, &position);
if( MPI_SUCCESS != error ) goto return_error_code;
if( 0 != validator(send_data, buffer, datatype, count, validator_arg) ) {
printf("Error during pack external. Bailing out\n");
return -1;
}
printf("packed %ld bytes into a %ld bytes buffer ", position, buffer_size); dump_hex(buffer, position); printf("\n");
position = 0;
error = ompi_datatype_unpack_external("external32", buffer, buffer_size, &position,
recv_data, count, datatype);
if( MPI_SUCCESS != error ) goto return_error_code;
free(buffer);
return_error_code:
return (error == MPI_SUCCESS ? 0 : -1);
}
int main(int argc, char *argv[])
{
opal_init_util(&argc, &argv);
ompi_datatype_init();
/* Simple contiguous data: MPI_INT32_T */
{
int32_t send_data[2] = {1234, 5678};
int32_t recv_data[2] = {-1, -1};
if( verbose ) {
printf("send data %08x %08x \n", send_data[0], send_data[1]);
printf("data "); dump_hex(&send_data, sizeof(int32_t) * 2); printf("\n");
}
(void)pack_unpack_datatype( send_data, &ompi_mpi_int32_t.dt, 2,
recv_data, check_contiguous, (void*)&ompi_mpi_int32_t.dt );
if( verbose ) {
printf("recv "); dump_hex(&recv_data, sizeof(int32_t) * 2); printf("\n");
printf("recv data %08x %08x \n", recv_data[0], recv_data[1]);
}
if( (send_data[0] != recv_data[0]) || (send_data[1] != recv_data[1]) ) {
printf("Error during external32 pack/unack for contiguous types (MPI_INT32_T)\n");
exit(-1);
}
}
/* Simple contiguous data: MPI_INT16_T */
{
int16_t send_data[2] = {1234, 5678};
int16_t recv_data[2] = {-1, -1};
if( verbose ) {
printf("send data %08x %08x \n", send_data[0], send_data[1]);
printf("data "); dump_hex(&send_data, sizeof(int16_t) * 2); printf("\n");
}
(void)pack_unpack_datatype( send_data, &ompi_mpi_int16_t.dt, 2,
recv_data, check_contiguous, (void*)&ompi_mpi_int16_t.dt );
if( verbose ) {
printf("recv "); dump_hex(&recv_data, sizeof(int16_t) * 2); printf("\n");
printf("recv data %08x %08x \n", recv_data[0], recv_data[1]);
}
if( (send_data[0] != recv_data[0]) || (send_data[1] != recv_data[1]) ) {
printf("Error during external32 pack/unack for contiguous types\n");
exit(-1);
}
}
/* Vector datatype */
printf("\n\nVector datatype\n\n");
{
int count=2, blocklength=1, stride=2;
int send_data[3] = {1234, 0, 5678};
int recv_data[3] = {-1, -1, -1};
ompi_datatype_t *ddt;
ompi_datatype_create_vector ( count, blocklength, stride, &ompi_mpi_int.dt, &ddt );
{
const int* a_i[3] = {&count, &blocklength, &stride};
ompi_datatype_t *type = &ompi_mpi_int.dt;
ompi_datatype_set_args( ddt, 3, a_i, 0, NULL, 1, &type, MPI_COMBINER_VECTOR );
}
ompi_datatype_commit(&ddt);
if( verbose ) {
printf("send data %08x %x08x %08x \n", send_data[0], send_data[1], send_data[2]);
printf("data "); dump_hex(&send_data, sizeof(int32_t) * 3); printf("\n");
}
(void)pack_unpack_datatype( send_data, ddt, 1, recv_data, check_vector, (void*)&ompi_mpi_int32_t.dt );
if( verbose ) {
printf("recv "); dump_hex(&recv_data, sizeof(int32_t) * 3); printf("\n");
printf("recv data %08x %08x %08x \n", recv_data[0], recv_data[1], recv_data[2]);
}
ompi_datatype_destroy(&ddt);
if( (send_data[0] != recv_data[0]) || (send_data[2] != recv_data[2]) ) {
printf("Error during external32 pack/unack for vector types (MPI_INT32_T)\n");
exit(-1);
}
}
ompi_datatype_finalize();
return 0;
}