Пример #1
0
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;
    }
}
Пример #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);
	}
}