int ompi_mtl_psm2_improbe(struct mca_mtl_base_module_t *mtl, struct ompi_communicator_t *comm, int src, int tag, int *matched, struct ompi_message_t **message, struct ompi_status_public_t *status) { struct ompi_message_t* msg; psm2_mq_tag_t mqtag, tagsel; psm2_mq_status2_t mqstat; psm2_mq_req_t mqreq; psm2_error_t err; PSM2_MAKE_TAGSEL(src, tag, comm->c_contextid, mqtag, tagsel); err = psm2_mq_improbe2(ompi_mtl_psm2.mq, PSM2_MQ_ANY_ADDR, &mqtag, &tagsel, &mqreq, &mqstat); if (err == PSM2_OK) { if(MPI_STATUS_IGNORE != status) { status->MPI_SOURCE = mqstat.msg_tag.tag1; status->MPI_TAG = mqstat.msg_tag.tag0; status->_ucount = mqstat.nbytes; switch (mqstat.error_code) { case PSM2_OK: status->MPI_ERROR = OMPI_SUCCESS; break; case PSM2_MQ_TRUNCATION: status->MPI_ERROR = MPI_ERR_TRUNCATE; break; default: status->MPI_ERROR = MPI_ERR_INTERN; } } msg = ompi_message_alloc(); if(NULL == msg) { return OMPI_ERR_OUT_OF_RESOURCE; } msg->comm = comm; msg->req_ptr = mqreq; msg->peer = mqstat.msg_tag.tag1; msg->count = mqstat.nbytes; *message = msg; *matched = 1; return OMPI_SUCCESS; } else if(err == PSM2_MQ_INCOMPLETE) { *matched = 0; *message = MPI_MESSAGE_NULL; return OMPI_SUCCESS; } else { return OMPI_ERROR; } }
static ssize_t psmx2_tagged_peek_generic(struct fid_ep *ep, void *buf, size_t len, void *desc, fi_addr_t src_addr, uint64_t tag, uint64_t ignore, void *context, uint64_t flags) { struct psmx2_fid_ep *ep_priv; struct psmx2_fid_av *av; struct psmx2_cq_event *event; psm2_epaddr_t psm2_epaddr; uint8_t vlane; psm2_mq_req_t req; psm2_mq_status2_t psm2_status; psm2_mq_tag_t psm2_tag, psm2_tagsel; uint32_t tag32, tagsel32; size_t idx; int err; ep_priv = container_of(ep, struct psmx2_fid_ep, ep); if (src_addr != FI_ADDR_UNSPEC) { av = ep_priv->av; if (av && PSMX2_SEP_ADDR_TEST(src_addr)) { psm2_epaddr = psmx2_av_translate_sep(av, ep_priv->trx_ctxt, src_addr); vlane = 0; } else if (av && av->type == FI_AV_TABLE) { idx = (size_t)src_addr; if (idx >= av->last) return -FI_EINVAL; psm2_epaddr = av->epaddrs[idx]; vlane = av->vlanes[idx]; } else { psm2_epaddr = PSMX2_ADDR_TO_EP(src_addr); vlane = PSMX2_ADDR_TO_VL(src_addr); } tag32 = PSMX2_TAG32(0, vlane, ep_priv->vlane); tagsel32 = -1; } else { psm2_epaddr = 0; tag32 = PSMX2_TAG32(0, 0, ep_priv->vlane); tagsel32 = ~PSMX2_SRC_BITS; } PSMX2_SET_TAG(psm2_tag, tag, tag32); PSMX2_SET_TAG(psm2_tagsel, ~ignore, tagsel32); if (flags & (FI_CLAIM | FI_DISCARD)) err = psm2_mq_improbe2(ep_priv->trx_ctxt->psm2_mq, psm2_epaddr, &psm2_tag, &psm2_tagsel, &req, &psm2_status); else err = psm2_mq_iprobe2(ep_priv->trx_ctxt->psm2_mq, psm2_epaddr, &psm2_tag, &psm2_tagsel, &psm2_status); switch (err) { case PSM2_OK: if (ep_priv->recv_cq) { if (flags & FI_CLAIM) { if (context) PSMX2_CTXT_REQ((struct fi_context *)context) = req; } else if (flags & FI_DISCARD) { if (!psm2_mq_imrecv(ep_priv->trx_ctxt->psm2_mq, 0, NULL, 0, req, &req)) psm2_mq_wait2(&req, NULL); } tag = PSMX2_GET_TAG64(psm2_status.msg_tag); len = psm2_status.msg_length; event = psmx2_cq_create_event( ep_priv->recv_cq, context, /* op_context */ NULL, /* buf */ flags|FI_RECV|FI_TAGGED,/* flags */ len, /* len */ 0, /* data */ tag, /* tag */ len, /* olen */ 0); /* err */ if (!event) return -FI_ENOMEM; vlane = PSMX2_TAG32_GET_SRC(psm2_status.msg_tag.tag2); event->source_is_valid = 1; event->source = PSMX2_EP_TO_ADDR(psm2_status.msg_peer, vlane); event->source_av = ep_priv->av; psmx2_cq_enqueue_event(ep_priv->recv_cq, event); } return 0; case PSM2_MQ_NO_COMPLETIONS: if (ep_priv->recv_cq) { event = psmx2_cq_create_event( ep_priv->recv_cq, context, /* op_context */ NULL, /* buf */ flags|FI_RECV|FI_TAGGED,/* flags */ len, /* len */ 0, /* data */ tag, /* tag */ len, /* olen */ -FI_ENOMSG); /* err */ if (!event) return -FI_ENOMEM; event->source = 0; psmx2_cq_enqueue_event(ep_priv->recv_cq, event); } return 0; default: return psmx2_errno(err); } }