226 строки
8.0 KiB
C
226 строки
8.0 KiB
C
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
|
|
/*
|
|
* Copyright (C) Mellanox Technologies Ltd. 2001-2011. ALL RIGHTS RESERVED.
|
|
* Copyright (c) 2015 Los Alamos National Security, LLC. All rights
|
|
* reserved.
|
|
* $COPYRIGHT$
|
|
*
|
|
* Additional copyrights may follow
|
|
*
|
|
* $HEADER$
|
|
*/
|
|
|
|
#ifndef PML_YALLA_REQUEST_H_
|
|
#define PML_YALLA_REQUEST_H_
|
|
|
|
#include "pml_yalla.h"
|
|
#include "pml_yalla_datatype.h"
|
|
|
|
|
|
#define MCA_PML_YALLA_REQUEST_FLAG_SEND 0x1 /* Persistent send */
|
|
#define MCA_PML_YALLA_REQUEST_FLAG_BSEND 0x2 /* Persistent buffered send */
|
|
#define MCA_PML_YALLA_REQUEST_FLAG_FREE_CALLED 0x4
|
|
|
|
struct pml_yalla_base_request {
|
|
ompi_request_t ompi;
|
|
mca_pml_yalla_convertor_t *convertor;
|
|
int flags;
|
|
/* overlaps with base of send/recv
|
|
* In ISO C90, you would have to give contents a length of 1,
|
|
* which means either you waste space or complicate the argument to malloc.
|
|
* Note:
|
|
* - 1 was the portable way to go, though it was rather strange
|
|
* - 0 was better at indicating intent, but not legal as far as
|
|
* the Standard was concerned and supported as an extension by some compilers (including gcc)
|
|
*/
|
|
mxm_req_base_t mxm_base[1];
|
|
};
|
|
|
|
struct pml_yalla_send_request {
|
|
mca_pml_yalla_base_request_t super;
|
|
mxm_send_req_t mxm;
|
|
};
|
|
|
|
struct pml_yalla_bsend_request {
|
|
opal_free_list_item_t super;
|
|
mxm_send_req_t mxm;
|
|
};
|
|
|
|
struct pml_yalla_recv_request {
|
|
mca_pml_yalla_base_request_t super;
|
|
mxm_recv_req_t mxm;
|
|
};
|
|
|
|
|
|
OBJ_CLASS_DECLARATION(mca_pml_yalla_send_request_t);
|
|
OBJ_CLASS_DECLARATION(mca_pml_yalla_bsend_request_t);
|
|
OBJ_CLASS_DECLARATION(mca_pml_yalla_recv_request_t);
|
|
|
|
void mca_pml_yalla_init_reqs(void);
|
|
|
|
#define PML_YALLA_RESET_OMPI_REQ(_ompi_req, _state) \
|
|
{ \
|
|
(_ompi_req)->req_state = _state; \
|
|
(_ompi_req)->req_complete = false; \
|
|
(_ompi_req)->req_status._cancelled = false; \
|
|
}
|
|
|
|
#define PML_YALLA_INIT_OMPI_REQ(_ompi_req, _comm, _state) \
|
|
{ \
|
|
PML_YALLA_RESET_OMPI_REQ(_ompi_req, _state); \
|
|
(_ompi_req)->req_mpi_object.comm = _comm; \
|
|
OBJ_RETAIN(_comm); \
|
|
}
|
|
|
|
#define PML_YALLA_RESET_PML_REQ(_pml_req) \
|
|
{ \
|
|
(_pml_req)->mxm_base[0].state = MXM_REQ_NEW; \
|
|
PML_YALLA_RESET_PML_REQ_DATA(_pml_req); \
|
|
}
|
|
|
|
#define PML_YALLA_INIT_MXM_REQ_BASE(_req_base, _comm) \
|
|
{ \
|
|
(_req_base)->state = MXM_REQ_NEW; \
|
|
(_req_base)->mq = (mxm_mq_h)(_comm)->c_pml_comm; \
|
|
}
|
|
|
|
#define PML_YALLA_PEER_CONN(_comm, _rank) \
|
|
ompi_comm_peer_lookup(_comm, _rank)->proc_endpoints[OMPI_PROC_ENDPOINT_TAG_PML]
|
|
|
|
#define PML_YALLA_INIT_MXM_SEND_REQ(_sreq, _buf, _count, _dtype, _rank, _tag, _mode, _comm, _stream_type, ...) \
|
|
{ \
|
|
PML_YALLA_INIT_MXM_REQ_BASE(&(_sreq)->base, _comm); \
|
|
PML_YALLA_INIT_MXM_REQ_DATA(&(_sreq)->base, _buf, _count, _dtype, _stream_type, ## __VA_ARGS__); \
|
|
(_sreq)->base.conn = PML_YALLA_PEER_CONN(_comm, _rank); \
|
|
(_sreq)->opcode = ((_mode) == MCA_PML_BASE_SEND_SYNCHRONOUS) ? MXM_REQ_OP_SEND_SYNC : MXM_REQ_OP_SEND; \
|
|
(_sreq)->op.send.tag = _tag; \
|
|
(_sreq)->op.send.imm_data = ompi_comm_rank(_comm); \
|
|
}
|
|
|
|
#define PML_YALLA_INIT_MXM_RECV_REQ_ENVELOPE(_rreq, _rank, _tag, _comm) \
|
|
{ \
|
|
(_rreq)->base.conn = ((_rank) == MPI_ANY_SOURCE) ? NULL : PML_YALLA_PEER_CONN(_comm, _rank); \
|
|
if ((_tag) == MPI_ANY_TAG) { \
|
|
(_rreq)->tag = 0; \
|
|
(_rreq)->tag_mask = 0x80000000u; \
|
|
} else { \
|
|
(_rreq)->tag = _tag; \
|
|
(_rreq)->tag_mask = 0xffffffffu; \
|
|
} \
|
|
}
|
|
|
|
#define PML_YALLA_INIT_MXM_RECV_REQ(_rreq, _buf, _count, _dtype, _rank, _tag, _comm, _stream_type, ...) \
|
|
{ \
|
|
PML_YALLA_INIT_MXM_REQ_BASE(&(_rreq)->base, _comm); \
|
|
PML_YALLA_INIT_MXM_REQ_DATA(&(_rreq)->base, _buf, _count, _dtype, _stream_type, ## __VA_ARGS__); \
|
|
PML_YALLA_INIT_MXM_RECV_REQ_ENVELOPE(_rreq, _rank, _tag, _comm); \
|
|
}
|
|
|
|
#define PML_YALLA_INIT_BLOCKING_MXM_SEND_REQ(_sreq) \
|
|
{ \
|
|
(_sreq)->base.completed_cb = NULL; \
|
|
(_sreq)->flags = MXM_REQ_SEND_FLAG_BLOCKING; \
|
|
}
|
|
|
|
#define PML_YALLA_INIT_BLOCKING_MXM_RECV_REQ(_rreq) \
|
|
{ \
|
|
(_rreq)->base.completed_cb = NULL; \
|
|
}
|
|
|
|
#define PML_YALLA_FREE_BLOCKING_MXM_REQ(_req) \
|
|
{ \
|
|
if ((_req)->completed_cb != NULL) { \
|
|
mca_pml_yalla_convertor_free((mca_pml_yalla_convertor_t*)((_req)->context)); \
|
|
} \
|
|
}
|
|
|
|
static inline mca_pml_yalla_recv_request_t* MCA_PML_YALLA_RREQ_INIT(void *_buf, size_t _count, ompi_datatype_t *_datatype,
|
|
int _src, int _tag, struct ompi_communicator_t* _comm, int _state)
|
|
{
|
|
mca_pml_yalla_recv_request_t *rreq = (mca_pml_yalla_recv_request_t *)PML_YALLA_FREELIST_GET(&ompi_pml_yalla.recv_reqs);
|
|
PML_YALLA_INIT_OMPI_REQ(&rreq->super.ompi, _comm, _state);
|
|
PML_YALLA_INIT_MXM_RECV_REQ(&rreq->mxm, _buf, _count, _datatype, _src, _tag, _comm, irecv, rreq);
|
|
return rreq;
|
|
}
|
|
|
|
static inline mca_pml_yalla_send_request_t* MCA_PML_YALLA_SREQ_INIT(void *_buf, size_t _count, ompi_datatype_t *_datatype,
|
|
int _dst, int _tag, mca_pml_base_send_mode_t _mode, struct ompi_communicator_t* _comm, int _state)
|
|
{
|
|
mca_pml_yalla_send_request_t *sreq = (mca_pml_yalla_send_request_t *)PML_YALLA_FREELIST_GET(&ompi_pml_yalla.send_reqs);
|
|
PML_YALLA_INIT_OMPI_REQ(&sreq->super.ompi, _comm, _state);
|
|
PML_YALLA_INIT_MXM_SEND_REQ(&sreq->mxm, _buf, _count, _datatype, _dst, _tag, _mode, _comm, isend, sreq);
|
|
sreq->super.ompi.req_status.MPI_TAG = _tag;
|
|
sreq->super.ompi.req_status.MPI_SOURCE = (_comm)->c_my_rank;
|
|
sreq->super.ompi.req_status._ucount = _count;
|
|
return sreq;
|
|
}
|
|
|
|
#define PML_YALLA_INIT_MXM_PROBE_REQ(_rreq, _rank, _tag, _comm) \
|
|
{ \
|
|
PML_YALLA_INIT_MXM_REQ_BASE(&(_rreq)->base, _comm); \
|
|
PML_YALLA_INIT_MXM_RECV_REQ_ENVELOPE(_rreq, _rank, _tag, _comm); \
|
|
}
|
|
|
|
/*
|
|
* For multi-threaded MPI, avoid blocking inside mxm_wait(), since it prevents
|
|
* from other threads making progress.
|
|
*/
|
|
#define PML_YALLA_WAIT_MXM_REQ(_req_base) \
|
|
{ \
|
|
if (opal_using_threads()) { \
|
|
while (!mxm_req_test(_req_base)) { \
|
|
sched_yield(); \
|
|
opal_progress(); \
|
|
} \
|
|
} else if (!mxm_req_test(_req_base)) { \
|
|
mxm_wait_t wait; \
|
|
wait.progress_cb = (mxm_progress_cb_t)opal_progress; \
|
|
wait.progress_arg = NULL; \
|
|
wait.req = (_req_base); \
|
|
wait.state = MXM_REQ_COMPLETED; \
|
|
mxm_wait(&wait); \
|
|
} \
|
|
}
|
|
|
|
#define PML_YALLA_SET_RECV_STATUS(_rreq, _length, _mpi_status) \
|
|
{ \
|
|
if ((_mpi_status) != MPI_STATUS_IGNORE) { \
|
|
switch ((_rreq)->base.error) { \
|
|
case MXM_OK: \
|
|
(_mpi_status)->MPI_ERROR = OMPI_SUCCESS; \
|
|
break; \
|
|
case MXM_ERR_CANCELED: \
|
|
(_mpi_status)->MPI_ERROR = OMPI_SUCCESS; \
|
|
(_mpi_status)->_cancelled = true; \
|
|
break; \
|
|
case MXM_ERR_MESSAGE_TRUNCATED: \
|
|
(_mpi_status)->MPI_ERROR = MPI_ERR_TRUNCATE; \
|
|
break; \
|
|
default: \
|
|
(_mpi_status)->MPI_ERROR = MPI_ERR_INTERN; \
|
|
break; \
|
|
} \
|
|
\
|
|
(_mpi_status)->MPI_TAG = (_rreq)->completion.sender_tag; \
|
|
(_mpi_status)->MPI_SOURCE = (_rreq)->completion.sender_imm; \
|
|
(_mpi_status)->_ucount = (_length); \
|
|
} \
|
|
}
|
|
|
|
#define PML_YALLA_SET_MESSAGE(_rreq, _comm, _mxm_msg, _message) \
|
|
{ \
|
|
*(_message) = ompi_message_alloc(); \
|
|
(*(_message))->comm = (_comm); \
|
|
(*(_message))->count = (_rreq)->completion.sender_len; \
|
|
(*(_message))->peer = (_rreq)->completion.sender_imm; \
|
|
(*(_message))->req_ptr = (_mxm_msg); \
|
|
}
|
|
|
|
#define PML_YALLA_MESSAGE_RELEASE(_message) \
|
|
{ \
|
|
ompi_message_return(*(_message)); \
|
|
*(_message) = NULL; \
|
|
}
|
|
|
|
#endif /* PML_YALLA_REQUEST_H_ */
|