root/ompi/mca/pml/cm/pml_cm_recvreq.h

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

INCLUDED FROM


   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2005 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-2005 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) 2012      Sandia National Laboratories.  All rights reserved.
  14  * Copyright (c) 2015      Los Alamos National Security, LLC. All rights
  15  *                         reserved.
  16  * Copyright (c) 2017      Intel, Inc. All rights reserved
  17  * $COPYRIGHT$
  18  *
  19  * Additional copyrights may follow
  20  *
  21  * $HEADER$
  22  */
  23 
  24 #ifndef PML_CM_RECVREQ_H
  25 #define PML_CM_RECVREQ_H
  26 
  27 #include "pml_cm_request.h"
  28 #include "ompi/mca/pml/base/pml_base_recvreq.h"
  29 #include "ompi/mca/mtl/mtl.h"
  30 
  31 struct mca_pml_cm_thin_recv_request_t {
  32     mca_pml_cm_request_t req_base;
  33     mca_mtl_request_t req_mtl;            /**< the mtl specific memory. This field should be the last in the struct */
  34 };
  35 typedef struct mca_pml_cm_thin_recv_request_t mca_pml_cm_thin_recv_request_t;
  36 OBJ_CLASS_DECLARATION(mca_pml_cm_thin_recv_request_t);
  37 
  38 struct mca_pml_cm_hvy_recv_request_t {
  39     mca_pml_cm_request_t req_base;
  40     void *req_addr;                       /**< pointer to application buffer */
  41     size_t req_count;                     /**< count of user datatype elements */
  42     int32_t req_peer;                     /**< peer process - rank w/in this communicator */
  43     int32_t req_tag;                      /**< user defined tag */
  44     void *req_buff;                       /**< pointer to send buffer - may not be application buffer */
  45     size_t req_bytes_packed;              /**< packed size of a message given the datatype and count */
  46     bool req_blocking;
  47     mca_mtl_request_t req_mtl;            /**< the mtl specific memory. This field should be the last in the struct */
  48 };
  49 typedef struct mca_pml_cm_hvy_recv_request_t mca_pml_cm_hvy_recv_request_t;
  50 
  51 OBJ_CLASS_DECLARATION(mca_pml_cm_hvy_recv_request_t);
  52 
  53 /**
  54  *  Allocate a recv request from the modules free list.
  55  *
  56  *  @param rc (OUT)  OMPI_SUCCESS or error status on failure.
  57  *  @return          Receive request.
  58  */
  59 #define MCA_PML_CM_THIN_RECV_REQUEST_ALLOC(recvreq)                            \
  60 do {                                                                           \
  61     recvreq = (mca_pml_cm_thin_recv_request_t*)                                \
  62       opal_free_list_get (&mca_pml_base_recv_requests);                        \
  63     recvreq->req_base.req_pml_type = MCA_PML_CM_REQUEST_RECV_THIN;             \
  64     recvreq->req_mtl.ompi_req = (ompi_request_t*) recvreq;                     \
  65     recvreq->req_mtl.completion_callback = mca_pml_cm_recv_request_completion; \
  66  } while (0)
  67 
  68 #define MCA_PML_CM_HVY_RECV_REQUEST_ALLOC(recvreq)                             \
  69 do {                                                                           \
  70     recvreq = (mca_pml_cm_hvy_recv_request_t*)                                 \
  71       opal_free_list_get (&mca_pml_base_recv_requests);                        \
  72     recvreq->req_base.req_pml_type = MCA_PML_CM_REQUEST_RECV_HEAVY;            \
  73     recvreq->req_mtl.ompi_req = (ompi_request_t*) recvreq;                     \
  74     recvreq->req_mtl.completion_callback = mca_pml_cm_recv_request_completion; \
  75  } while (0)
  76 
  77 
  78 /**
  79  * Initialize a receive request with call parameters.
  80  *
  81  * @param request (IN)       Receive request.
  82  * @param addr (IN)          User buffer.
  83  * @param count (IN)         Number of elements of indicated datatype.
  84  * @param datatype (IN)      User defined datatype.
  85  * @param src (IN)           Source rank w/in the communicator.
  86  * @param comm (IN)          Communicator.
  87  * @param persistent (IN)    Is this a ersistent request.
  88  */
  89 #if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
  90 #define MCA_PML_CM_THIN_RECV_REQUEST_INIT( request,                     \
  91                                            ompi_proc,                   \
  92                                            comm,                        \
  93                                            src,                         \
  94                                            datatype,                    \
  95                                            addr,                        \
  96                                            count,                       \
  97                                            flags )                      \
  98 do {                                                                    \
  99     OMPI_REQUEST_INIT(&(request)->req_base.req_ompi, false);            \
 100     (request)->req_base.req_ompi.req_mpi_object.comm = comm;            \
 101     (request)->req_base.req_pml_complete = false;                       \
 102     (request)->req_base.req_free_called = false;                        \
 103     request->req_base.req_comm = comm;                                  \
 104     request->req_base.req_datatype = datatype;                          \
 105     OBJ_RETAIN(comm);                                                   \
 106     OMPI_DATATYPE_RETAIN(datatype);                                     \
 107                                                                         \
 108     if( MPI_ANY_SOURCE == src ) {                                       \
 109         ompi_proc = ompi_proc_local_proc;                               \
 110     } else {                                                            \
 111         ompi_proc = ompi_comm_peer_lookup( comm, src );                 \
 112     }                                                                   \
 113     MCA_PML_CM_SWITCH_CUDA_CONVERTOR_OFF(flags, datatype, count);       \
 114     opal_convertor_copy_and_prepare_for_recv(                           \
 115                                   ompi_proc->super.proc_convertor,      \
 116                                   &(datatype->super),                   \
 117                                   count,                                \
 118                                   addr,                                 \
 119                                   flags,                                \
 120                                   &(request)->req_base.req_convertor ); \
 121 } while(0)
 122 #else
 123 #define MCA_PML_CM_THIN_RECV_REQUEST_INIT( request,                     \
 124                                            ompi_proc,                   \
 125                                            comm,                        \
 126                                            src,                         \
 127                                            datatype,                    \
 128                                            addr,                        \
 129                                            count,                       \
 130                                            flags )                      \
 131 do {                                                                    \
 132     OMPI_REQUEST_INIT(&(request)->req_base.req_ompi, false);            \
 133     (request)->req_base.req_ompi.req_mpi_object.comm = comm;            \
 134     (request)->req_base.req_pml_complete = false;                       \
 135     (request)->req_base.req_free_called = false;                        \
 136     request->req_base.req_comm = comm;                                  \
 137     request->req_base.req_datatype = datatype;                          \
 138     OBJ_RETAIN(comm);                                                   \
 139     OMPI_DATATYPE_RETAIN(datatype);                                     \
 140                                                                         \
 141     MCA_PML_CM_SWITCH_CUDA_CONVERTOR_OFF(flags, datatype, count);       \
 142     opal_convertor_copy_and_prepare_for_recv(                           \
 143         ompi_mpi_local_convertor,                                       \
 144         &(datatype->super),                                             \
 145         count,                                                          \
 146         addr,                                                           \
 147         flags,                                                          \
 148         &(request)->req_base.req_convertor );                           \
 149 } while(0)
 150 #endif
 151 
 152 #if OPAL_ENABLE_HETEROGENEOUS_SUPPORT
 153 #define MCA_PML_CM_HVY_RECV_REQUEST_INIT( request,                      \
 154                                           ompi_proc,                    \
 155                                           comm,                         \
 156                                           tag,                          \
 157                                           src,                          \
 158                                           datatype,                     \
 159                                           addr,                         \
 160                                           count,                        \
 161                                           flags,                        \
 162                                           persistent)                   \
 163 do {                                                                    \
 164     OMPI_REQUEST_INIT(&(request)->req_base.req_ompi, persistent);       \
 165     (request)->req_base.req_ompi.req_mpi_object.comm = comm;            \
 166     (request)->req_base.req_pml_complete = OPAL_INT_TO_BOOL(persistent); \
 167     (request)->req_base.req_free_called = false;                        \
 168     request->req_base.req_comm = comm;                                  \
 169     request->req_base.req_datatype = datatype;                          \
 170     request->req_tag = tag;                                             \
 171     request->req_peer = src;                                            \
 172     request->req_addr = addr;                                           \
 173     request->req_count = count;                                         \
 174     OBJ_RETAIN(comm);                                                   \
 175     OMPI_DATATYPE_RETAIN(datatype);                                     \
 176                                                                         \
 177     if( MPI_ANY_SOURCE == src ) {                                       \
 178         ompi_proc = ompi_proc_local_proc;                               \
 179     } else {                                                            \
 180         ompi_proc = ompi_comm_peer_lookup( comm, src );                 \
 181     }                                                                   \
 182     MCA_PML_CM_SWITCH_CUDA_CONVERTOR_OFF(flags, datatype, count);       \
 183     opal_convertor_copy_and_prepare_for_recv(                           \
 184                                   ompi_proc->super.proc_convertor,      \
 185                                   &(datatype->super),                   \
 186                                   count,                                \
 187                                   addr,                                 \
 188                                   flags,                                \
 189                                   &(request)->req_base.req_convertor ); \
 190  } while(0)
 191 #else
 192 #define MCA_PML_CM_HVY_RECV_REQUEST_INIT( request,                      \
 193                                           ompi_proc,                    \
 194                                           comm,                         \
 195                                           tag,                          \
 196                                           src,                          \
 197                                           datatype,                     \
 198                                           addr,                         \
 199                                           count,                        \
 200                                           flags,                        \
 201                                           persistent)                   \
 202 do {                                                                    \
 203     OMPI_REQUEST_INIT(&(request)->req_base.req_ompi, persistent);       \
 204     (request)->req_base.req_ompi.req_mpi_object.comm = comm;            \
 205     (request)->req_base.req_pml_complete = OPAL_INT_TO_BOOL(persistent); \
 206     (request)->req_base.req_free_called = false;                        \
 207     request->req_base.req_comm = comm;                                  \
 208     request->req_base.req_datatype = datatype;                          \
 209     request->req_tag = tag;                                             \
 210     request->req_peer = src;                                            \
 211     request->req_addr = addr;                                           \
 212     request->req_count = count;                                         \
 213     OBJ_RETAIN(comm);                                                   \
 214     OMPI_DATATYPE_RETAIN(datatype);                                     \
 215                                                                         \
 216     MCA_PML_CM_SWITCH_CUDA_CONVERTOR_OFF(flags, datatype, count);       \
 217     opal_convertor_copy_and_prepare_for_recv(                           \
 218         ompi_mpi_local_convertor,                                       \
 219         &(datatype->super),                                             \
 220         count,                                                          \
 221         addr,                                                           \
 222         flags,                                                          \
 223         &(request)->req_base.req_convertor );                           \
 224  } while(0)
 225 #endif
 226 
 227 /**
 228  * Start an initialized request.
 229  *
 230  * @param request  Receive request.
 231  * @return         OMPI_SUCESS or error status on failure.
 232  */
 233 #define MCA_PML_CM_THIN_RECV_REQUEST_START(request, comm, tag, src, ret) \
 234 do {                                                                    \
 235     /* init/re-init the request */                                      \
 236     request->req_base.req_pml_complete = false;                         \
 237     request->req_base.req_ompi.req_complete = false;                    \
 238     request->req_base.req_ompi.req_state = OMPI_REQUEST_ACTIVE;         \
 239                                                                         \
 240     /* always set the req_status.MPI_TAG to ANY_TAG before starting the \
 241      * request. This field is used if cancelled to find out if the request \
 242      * has been matched or not.                                         \
 243      */                                                                 \
 244     request->req_base.req_ompi.req_status.MPI_TAG = OMPI_ANY_TAG;       \
 245     request->req_base.req_ompi.req_status.MPI_ERROR = OMPI_SUCCESS;     \
 246     request->req_base.req_ompi.req_status._cancelled = 0;               \
 247     ret = OMPI_MTL_CALL(irecv(ompi_mtl,                                 \
 248                               comm,                                     \
 249                               src,                                      \
 250                               tag,                                      \
 251                               &recvreq->req_base.req_convertor,         \
 252                               &recvreq->req_mtl));                      \
 253 } while (0)
 254 
 255 #define MCA_PML_CM_THIN_RECV_REQUEST_MATCHED_START(request, message, ret) \
 256 do {                                                                    \
 257     /* init/re-init the request */                                      \
 258     request->req_base.req_pml_complete = false;                         \
 259     request->req_base.req_ompi.req_complete = false;                    \
 260     request->req_base.req_ompi.req_state = OMPI_REQUEST_ACTIVE;         \
 261                                                                         \
 262     /* always set the req_status.MPI_TAG to ANY_TAG before starting the \
 263      * request. This field is used if cancelled to find out if the request \
 264      * has been matched or not.                                         \
 265      */                                                                 \
 266     request->req_base.req_ompi.req_status.MPI_TAG = OMPI_ANY_TAG;       \
 267     request->req_base.req_ompi.req_status.MPI_ERROR = OMPI_SUCCESS;     \
 268     request->req_base.req_ompi.req_status._cancelled = 0;               \
 269     ret = OMPI_MTL_CALL(imrecv(ompi_mtl,                                \
 270                                &recvreq->req_base.req_convertor,        \
 271                                message,                                 \
 272                                &recvreq->req_mtl));                     \
 273 } while (0)
 274 
 275 
 276 #define MCA_PML_CM_HVY_RECV_REQUEST_START(request, ret)                 \
 277 do {                                                                    \
 278 /*     opal_output(0, "posting hvy request %d\n", request);                */ \
 279     /* init/re-init the request */                                      \
 280     request->req_base.req_pml_complete = false;                         \
 281     request->req_base.req_ompi.req_complete = false;                    \
 282     request->req_base.req_ompi.req_state = OMPI_REQUEST_ACTIVE;         \
 283                                                                         \
 284     /* always set the req_status.MPI_TAG to ANY_TAG before starting the \
 285      * request. This field is used if cancelled to find out if the request \
 286      * has been matched or not.                                         \
 287      */                                                                 \
 288     request->req_base.req_ompi.req_status.MPI_TAG = OMPI_ANY_TAG;       \
 289     request->req_base.req_ompi.req_status.MPI_ERROR = OMPI_SUCCESS;     \
 290     request->req_base.req_ompi.req_status._cancelled = 0;               \
 291     ret = OMPI_MTL_CALL(irecv(ompi_mtl,                                 \
 292                               request->req_base.req_comm,               \
 293                               request->req_peer,                        \
 294                               request->req_tag,                         \
 295                               &recvreq->req_base.req_convertor,         \
 296                               &recvreq->req_mtl));                      \
 297 } while (0)
 298 
 299 
 300 /**
 301  * Mark the request as completed at MPI level for internal purposes.
 302  *
 303  *  @param recvreq (IN)  Receive request.
 304  */
 305 #define MCA_PML_CM_THIN_RECV_REQUEST_MPI_COMPLETE( recvreq )            \
 306 do {                                                                    \
 307     ompi_request_complete(  &(recvreq->req_base.req_ompi), true );      \
 308  } while (0)
 309 
 310 
 311 /**
 312  *  Return a recv request to the modules free list.
 313  *
 314  *  @param recvreq (IN)  Receive request.
 315  */
 316 #define MCA_PML_CM_THIN_RECV_REQUEST_PML_COMPLETE(recvreq)              \
 317 do {                                                                    \
 318     assert( false == recvreq->req_base.req_pml_complete );              \
 319                                                                         \
 320     if( true == recvreq->req_base.req_free_called ) {                   \
 321         MCA_PML_CM_THIN_RECV_REQUEST_RETURN( recvreq );                 \
 322     } else {                                                            \
 323         recvreq->req_base.req_pml_complete = true;                      \
 324         ompi_request_complete( &(recvreq->req_base.req_ompi), true );   \
 325     }                                                                   \
 326  } while(0)
 327 
 328 
 329 
 330 
 331 /**
 332  *  Return a recv request to the modules free list.
 333  *
 334  *  @param recvreq (IN)  Receive request.
 335  */
 336 #define MCA_PML_CM_HVY_RECV_REQUEST_PML_COMPLETE(recvreq)               \
 337 do {                                                                    \
 338     assert( false == recvreq->req_base.req_pml_complete );              \
 339                                                                         \
 340     if( true == recvreq->req_base.req_free_called ) {                   \
 341         MCA_PML_CM_HVY_RECV_REQUEST_RETURN( recvreq );                  \
 342     } else {                                                            \
 343         /* initialize request status */                                 \
 344         if(recvreq->req_base.req_ompi.req_persistent) {                 \
 345             /* rewind convertor */                                      \
 346             size_t offset = 0;                                          \
 347             opal_convertor_set_position(&recvreq->req_base.req_convertor, &offset); \
 348         }                                                               \
 349         recvreq->req_base.req_pml_complete = true;                      \
 350         ompi_request_complete(  &(recvreq->req_base.req_ompi), true );  \
 351     }                                                                   \
 352  } while(0)
 353 
 354 
 355 /**
 356  *  Free the PML receive request
 357  */
 358 #define MCA_PML_CM_HVY_RECV_REQUEST_RETURN(recvreq)                     \
 359 {                                                                       \
 360     OBJ_RELEASE((recvreq)->req_base.req_comm);                          \
 361     OMPI_DATATYPE_RELEASE((recvreq)->req_base.req_datatype);            \
 362     OMPI_REQUEST_FINI(&(recvreq)->req_base.req_ompi);                   \
 363     opal_convertor_cleanup( &((recvreq)->req_base.req_convertor) );     \
 364     opal_free_list_return ( &mca_pml_base_recv_requests,                \
 365                            (opal_free_list_item_t*)(recvreq));          \
 366 }
 367 
 368 /**
 369  *  Free the PML receive request
 370  */
 371 #define MCA_PML_CM_THIN_RECV_REQUEST_RETURN(recvreq)                    \
 372 {                                                                       \
 373     OBJ_RELEASE((recvreq)->req_base.req_comm);                          \
 374     OMPI_DATATYPE_RELEASE((recvreq)->req_base.req_datatype);            \
 375     OMPI_REQUEST_FINI(&(recvreq)->req_base.req_ompi);                   \
 376     opal_convertor_cleanup( &((recvreq)->req_base.req_convertor) );     \
 377     opal_free_list_return ( &mca_pml_base_recv_requests,                \
 378                            (opal_free_list_item_t*)(recvreq));          \
 379 }
 380 
 381 extern void mca_pml_cm_recv_request_completion(struct mca_mtl_request_t *mtl_request);
 382 
 383 #endif
 384 
 385 

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