Beispiel #1
0
int ompi_mtl_psm2_iprobe(struct mca_mtl_base_module_t* mtl,
                              struct ompi_communicator_t *comm,
                              int src,
                              int tag,
                              int *flag,
                              struct ompi_status_public_t *status)
{
    psm2_mq_tag_t mqtag, tagsel;
    psm2_mq_status2_t mqstat;
    psm2_error_t err;

    PSM2_MAKE_TAGSEL(src, tag, comm->c_contextid, mqtag, tagsel);

    err = psm2_mq_iprobe2(ompi_mtl_psm2.mq,
            PSM2_MQ_ANY_ADDR, &mqtag, &tagsel, &mqstat);
    if (err == PSM2_OK) {
	*flag = 1;
	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;
            }
        }

        return OMPI_SUCCESS;
    }
    else if (err == PSM2_MQ_INCOMPLETE) {
	*flag = 0;
	return OMPI_SUCCESS;
    }
    else
	return OMPI_ERROR;
}
Beispiel #2
0
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);
	}
}