Merge pull request #1509 from ggouaillardet/topic/external_support2
Add support for packing to/from external32 format.
Этот коммит содержится в:
Коммит
21f59b81a7
@ -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
Обычный файл
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
Обычный файл
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;
|
||||
}
|
Загрузка…
x
Ссылка в новой задаче
Block a user