示例#1
0
ssize_t _psmx_tagged_peek(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 psmx_fid_ep *ep_priv;
	psm_mq_status_t psm_status;
	uint64_t psm_tag, psm_tagsel;
	struct psmx_cq_event *event;
	int err;

	ep_priv = container_of(ep, struct psmx_fid_ep, ep);

	if (tag & ep_priv->domain->reserved_tag_bits) {
		FI_WARN(&psmx_prov, FI_LOG_EP_DATA,
			"using reserved tag bits."
			"tag=%lx. reserved_bits=%lx.\n", tag,
			ep_priv->domain->reserved_tag_bits);
	}

	psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
	psm_tagsel = (~ignore) | ep_priv->domain->reserved_tag_bits;

	if (flags & (FI_CLAIM | FI_DISCARD))
		return -FI_EOPNOTSUPP;

	err = psm_mq_iprobe(ep_priv->domain->psm_mq, psm_tag, psm_tagsel,
			    &psm_status);
	switch (err) {
	case PSM_OK:
		if (ep_priv->recv_cq) {
			event = psmx_cq_create_event(
					ep_priv->recv_cq,
					context,		/* op_context */
					NULL,			/* buf */
					flags|FI_RECV|FI_TAGGED,/* flags */
					psm_status.msg_length,	/* len */
					0,			/* data */
					psm_status.msg_tag,	/* tag */
					psm_status.msg_length,	/* olen */
					0);			/* err */
			if (event)
				psmx_cq_enqueue_event(ep_priv->recv_cq, event);
			else
				return -FI_ENOMEM;

			/* TODO: set message source to FI_ADDR_NOTAVAIL? */
		}
		return 0;

	case PSM_MQ_NO_COMPLETIONS:
		return -FI_ENOMSG;

	default:
		return psmx_errno(err);
	}
}
示例#2
0
int ompi_mtl_psm_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)
{
    uint64_t mqtag, tagsel;
    psm_mq_status_t mqstat;
    psm_error_t err;

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

    err = psm_mq_iprobe(ompi_mtl_psm.mq, mqtag, tagsel, &mqstat);
    if (err == PSM_OK) {
	*flag = 1;
	if(MPI_STATUS_IGNORE != status) { 
            status->MPI_SOURCE = PSM_GET_MQRANK(mqstat.msg_tag);
            status->MPI_TAG = PSM_GET_MQUTAG(mqstat.msg_tag);
            status->_ucount = mqstat.nbytes;

            switch (mqstat.error_code) {
	    case PSM_OK:
		status->MPI_ERROR = OMPI_SUCCESS;
		break;
	    case PSM_MQ_TRUNCATION:
		status->MPI_ERROR = MPI_ERR_TRUNCATE;
		break;
	    default:
		status->MPI_ERROR = MPI_ERR_INTERN;
            }
        }
        
        return OMPI_SUCCESS;
    }
    else if (err == PSM_MQ_INCOMPLETE) {
	*flag = 0;
	return OMPI_SUCCESS;
    }
    else
	return OMPI_ERROR;
}
示例#3
0
ssize_t _psmx_tagged_peek(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 psmx_fid_ep *ep_priv;
#if (PSM_VERNO_MAJOR >= 2)
	psm_mq_status2_t psm_status2;
	psm_mq_tag_t psm_tag2, psm_tagsel2;
	psm_mq_req_t req;
	struct psmx_fid_av *av;
	size_t idx;
	psm_epaddr_t psm_src_addr;
#else
	psm_mq_status_t psm_status;
#endif
	uint64_t psm_tag, psm_tagsel;
	struct psmx_cq_event *event;
	int err;

	ep_priv = container_of(ep, struct psmx_fid_ep, ep);

	if (tag & ep_priv->domain->reserved_tag_bits) {
		FI_WARN(&psmx_prov, FI_LOG_EP_DATA,
			"using reserved tag bits."
			"tag=%lx. reserved_bits=%lx.\n", tag,
			ep_priv->domain->reserved_tag_bits);
	}

	psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
	psm_tagsel = (~ignore) | ep_priv->domain->reserved_tag_bits;

#if (PSM_VERNO_MAJOR >= 2)
	if (src_addr != FI_ADDR_UNSPEC) {
		av = ep_priv->av;
		if (av && av->type == FI_AV_TABLE) {
			idx = (size_t)src_addr;
			if (idx >= av->last)
				return -FI_EINVAL;

			psm_src_addr = av->psm_epaddrs[idx];
		}
		else {
			psm_src_addr = (psm_epaddr_t)src_addr;
		}
	}
	else {
		psm_src_addr = NULL;
	}

	PSMX_SET_TAG(psm_tag2, psm_tag, 0);
	PSMX_SET_TAG(psm_tagsel2, psm_tagsel, 0);

	if (flags & (FI_CLAIM | FI_DISCARD))
		err = psm_mq_improbe2(ep_priv->domain->psm_mq,
				      psm_src_addr,
				      &psm_tag2, &psm_tagsel2,
				      &req, &psm_status2);
	else
		err = psm_mq_iprobe2(ep_priv->domain->psm_mq,
				     psm_src_addr,
				     &psm_tag2, &psm_tagsel2,
				     &psm_status2);
#else
	if (flags & (FI_CLAIM | FI_DISCARD))
		return -FI_EOPNOTSUPP;

	err = psm_mq_iprobe(ep_priv->domain->psm_mq, psm_tag, psm_tagsel,
			    &psm_status);
#endif
	switch (err) {
	case PSM_OK:
		if (ep_priv->recv_cq) {
#if (PSM_VERNO_MAJOR >= 2)
			if ((flags & FI_CLAIM) && context)
				PSMX_CTXT_REQ((struct fi_context *)context) = req;

			tag = psm_status2.msg_tag.tag0 | (((uint64_t)psm_status2.msg_tag.tag1) << 32);
			len = psm_status2.msg_length;
			src_addr = (fi_addr_t)psm_status2.msg_peer;
#else
			tag = psm_status.msg_tag;
			len = psm_status.msg_length;
			src_addr = 0;
#endif
			event = psmx_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;

			event->source = src_addr;
			psmx_cq_enqueue_event(ep_priv->recv_cq, event);
		}
		return 0;

	case PSM_MQ_NO_COMPLETIONS:
		return -FI_ENOMSG;

	default:
		return psmx_errno(err);
	}
}