root/ompi/datatype/ompi_datatype_sndrcv.c

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

DEFINITIONS

This source file includes following definitions.
  1. ompi_datatype_sndrcv

   1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
   2 /*
   3  * Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2013 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2006 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2009      Oak Ridge National Labs.  All rights reserved.
  14  * Copyright (c) 2014-2015 Research Organization for Information Science
  15  *                         and Technology (RIST). All rights reserved.
  16  * $COPYRIGHT$
  17  *
  18  * Additional copyrights may follow
  19  *
  20  * $HEADER$
  21  */
  22 
  23 #include "ompi_config.h"
  24 
  25 #include "opal/datatype/opal_datatype.h"
  26 #include "opal/datatype/opal_datatype_internal.h"
  27 #include "opal/datatype/opal_convertor.h"
  28 #include "ompi/datatype/ompi_datatype.h"
  29 #include "ompi/datatype/ompi_datatype_internal.h"
  30 /*
  31  * opal_datatype_sndrcv
  32  *
  33  * Function: - copy MPI message from buffer into another
  34  *           - send/recv done if cannot optimize
  35  * Accepts:  - send buffer
  36  *           - send count
  37  *           - send datatype
  38  *           - receive buffer
  39  *           - receive count
  40  *           - receive datatype
  41  *           - tag
  42  *           - communicator
  43  * Returns:  - MPI_SUCCESS or error code
  44  */
  45 int32_t ompi_datatype_sndrcv( const void *sbuf, int32_t scount, const ompi_datatype_t* sdtype,
  46                               void *rbuf, int32_t rcount, const ompi_datatype_t* rdtype)
  47 {
  48     opal_convertor_t send_convertor, recv_convertor;
  49     struct iovec iov;
  50     int length, completed;
  51     uint32_t iov_count;
  52     size_t max_data;
  53 
  54     /* First check if we really have something to do */
  55     if (0 == rcount || 0 == rdtype->super.size) {
  56         return ((0 == scount || 0 == sdtype->super.size) ? MPI_SUCCESS : MPI_ERR_TRUNCATE);
  57     }
  58 
  59     /* If same datatypes used, just copy. */
  60     if (sdtype == rdtype) {
  61         int32_t count = ( scount < rcount ? scount : rcount );
  62         opal_datatype_copy_content_same_ddt(&(rdtype->super), count, (char*)rbuf, (char*)sbuf);
  63         return ((scount > rcount) ? MPI_ERR_TRUNCATE : MPI_SUCCESS);
  64     }
  65 
  66     /* If receive packed. */
  67     if (rdtype->id == OMPI_DATATYPE_MPI_PACKED) {
  68         OBJ_CONSTRUCT( &send_convertor, opal_convertor_t );
  69         opal_convertor_copy_and_prepare_for_send( ompi_mpi_local_convertor,
  70                                                   &(sdtype->super), scount, sbuf, 0,
  71                                                   &send_convertor );
  72 
  73         iov_count = 1;
  74         iov.iov_base = (IOVBASE_TYPE*)rbuf;
  75         iov.iov_len = scount * sdtype->super.size;
  76         if( (int32_t)iov.iov_len > rcount ) iov.iov_len = rcount;
  77 
  78         opal_convertor_pack( &send_convertor, &iov, &iov_count, &max_data );
  79         OBJ_DESTRUCT( &send_convertor );
  80         return ((max_data < (size_t)rcount) ? MPI_ERR_TRUNCATE : MPI_SUCCESS);
  81     }
  82 
  83     /* If send packed. */
  84     if (sdtype->id == OMPI_DATATYPE_MPI_PACKED) {
  85         OBJ_CONSTRUCT( &recv_convertor, opal_convertor_t );
  86         opal_convertor_copy_and_prepare_for_recv( ompi_mpi_local_convertor,
  87                                                   &(rdtype->super), rcount, rbuf, 0,
  88                                                   &recv_convertor );
  89 
  90         iov_count = 1;
  91         iov.iov_base = (IOVBASE_TYPE*)sbuf;
  92         iov.iov_len = rcount * rdtype->super.size;
  93         if( (int32_t)iov.iov_len > scount ) iov.iov_len = scount;
  94 
  95         opal_convertor_unpack( &recv_convertor, &iov, &iov_count, &max_data );
  96         OBJ_DESTRUCT( &recv_convertor );
  97         return (((size_t)scount > max_data) ? MPI_ERR_TRUNCATE : MPI_SUCCESS);
  98     }
  99 
 100     iov.iov_len = length = 64 * 1024;
 101     iov.iov_base = (IOVBASE_TYPE*)malloc( length * sizeof(char) );
 102 
 103     OBJ_CONSTRUCT( &send_convertor, opal_convertor_t );
 104     opal_convertor_copy_and_prepare_for_send( ompi_mpi_local_convertor,
 105                                               &(sdtype->super), scount, sbuf, 0,
 106                                               &send_convertor );
 107     OBJ_CONSTRUCT( &recv_convertor, opal_convertor_t );
 108     opal_convertor_copy_and_prepare_for_recv( ompi_mpi_local_convertor,
 109                                               &(rdtype->super), rcount, rbuf, 0,
 110                                               &recv_convertor );
 111 
 112     completed = 0;
 113     while( !completed ) {
 114         iov.iov_len = length;
 115         iov_count = 1;
 116         max_data = length;
 117         completed |= opal_convertor_pack( &send_convertor, &iov, &iov_count, &max_data );
 118         completed |= opal_convertor_unpack( &recv_convertor, &iov, &iov_count, &max_data );
 119     }
 120     free( iov.iov_base );
 121     OBJ_DESTRUCT( &send_convertor );
 122     OBJ_DESTRUCT( &recv_convertor );
 123 
 124     return ( (scount * sdtype->super.size) <= (rcount * rdtype->super.size) ? MPI_SUCCESS : MPI_ERR_TRUNCATE );
 125 }

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