Пример #1
0
int
ompi_mtl_psm2_send(struct mca_mtl_base_module_t* mtl,
                 struct ompi_communicator_t* comm,
                 int dest,
                 int tag,
                 struct opal_convertor_t *convertor,
                 mca_pml_base_send_mode_t mode)
{
    psm_error_t err;
    mca_mtl_psm2_request_t mtl_psm2_request;
    psm_mq_tag_t mqtag;
    uint32_t flags = 0;
    int ret;
    size_t length;
    ompi_proc_t* ompi_proc = ompi_comm_peer_lookup( comm, dest );
    mca_mtl_psm2_endpoint_t* psm_endpoint = (mca_mtl_psm2_endpoint_t*) ompi_proc->proc_endpoints[OMPI_PROC_ENDPOINT_TAG_MTL];

    assert(mtl == &ompi_mtl_psm2.super);

    PSM_MAKE_MQTAG(comm->c_contextid, comm->c_my_rank, tag, mqtag);

    ret = ompi_mtl_datatype_pack(convertor,
                                 &mtl_psm2_request.buf,
                                 &length,
                                 &mtl_psm2_request.free_after);


    mtl_psm2_request.length = length;
    mtl_psm2_request.convertor = convertor;
    mtl_psm2_request.type = OMPI_mtl_psm2_ISEND;

    if (OMPI_SUCCESS != ret) return ret;

    if (mode == MCA_PML_BASE_SEND_SYNCHRONOUS)
	flags |= PSM_MQ_FLAG_SENDSYNC;

    err = psm_mq_send2(ompi_mtl_psm2.mq,
		      psm_endpoint->peer_addr,
		      flags,
		      &mqtag,
		      mtl_psm2_request.buf,
		      length);

    if (mtl_psm2_request.free_after) {
	free(mtl_psm2_request.buf);
    }

    return err == PSM_OK ? OMPI_SUCCESS : OMPI_ERROR;
}
Пример #2
0
ssize_t psmx_tagged_inject_no_flag_av_table(struct fid_ep *ep, const void *buf, size_t len,
					    fi_addr_t dest_addr, uint64_t tag)
{
	struct psmx_fid_ep *ep_priv;
	struct psmx_fid_av *av;
	psm_epaddr_t psm_epaddr;
	uint64_t psm_tag;
#if (PSM_VERNO_MAJOR >= 2)
	psm_mq_tag_t psm_tag2;
#endif
	int err;
	size_t idx;

	if (len > PSMX_INJECT_SIZE)
		return -FI_EMSGSIZE;

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

	av = ep_priv->av;
	idx = (size_t)dest_addr;
	if (idx >= av->last)
		return -FI_EINVAL;

	psm_epaddr = av->psm_epaddrs[idx];
	psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
#if (PSM_VERNO_MAJOR >= 2)
	PSMX_SET_TAG(psm_tag2, psm_tag, 0);
#endif

#if (PSM_VERNO_MAJOR >= 2)
	err = psm_mq_send2(ep_priv->domain->psm_mq, psm_epaddr, 0, &psm_tag2, buf, len);
#else
	err = psm_mq_send(ep_priv->domain->psm_mq, psm_epaddr, 0, psm_tag, buf, len);
#endif

	if (err != PSM_OK)
		return psmx_errno(err);

	if (ep_priv->send_cntr)
		psmx_cntr_inc(ep_priv->send_cntr);

	return 0;
}
Пример #3
0
ssize_t _psmx_tagged_send(struct fid_ep *ep, const void *buf, size_t len,
			  void *desc, fi_addr_t dest_addr, uint64_t tag,
			  void *context, uint64_t flags)
#endif
{
	struct psmx_fid_ep *ep_priv;
	struct psmx_fid_av *av;
	psm_epaddr_t psm_epaddr;
	psm_mq_req_t psm_req;
	uint64_t psm_tag;
#if (PSM_VERNO_MAJOR >= 2)
	psm_mq_tag_t psm_tag2;
#endif
	struct fi_context *fi_context;
	int err;
	size_t idx;
	int no_completion = 0;
	struct psmx_cq_event *event;

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

	if (flags & FI_TRIGGER) {
		struct psmx_trigger *trigger;
		struct fi_triggered_context *ctxt = context;

		trigger = calloc(1, sizeof(*trigger));
		if (!trigger)
			return -FI_ENOMEM;

		trigger->op = PSMX_TRIGGERED_TSEND;
		trigger->cntr = container_of(ctxt->trigger.threshold.cntr,
					     struct psmx_fid_cntr, cntr);
		trigger->threshold = ctxt->trigger.threshold.threshold;
		trigger->tsend.ep = ep;
		trigger->tsend.buf = buf;
		trigger->tsend.len = len;
		trigger->tsend.desc = desc;
		trigger->tsend.dest_addr = dest_addr;
		trigger->tsend.tag = tag;
		trigger->tsend.context = context;
		trigger->tsend.flags = flags & ~FI_TRIGGER;
#if (PSM_VERNO_MAJOR >= 2)
		trigger->tsend.data = data;
#endif

		psmx_cntr_add_trigger(trigger->cntr, trigger);
		return 0;
	}

	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);
	}

	av = ep_priv->av;
	if (av && av->type == FI_AV_TABLE) {
		idx = (size_t)dest_addr;
		if (idx >= av->last)
			return -FI_EINVAL;

		psm_epaddr = av->psm_epaddrs[idx];
	}
	else  {
		psm_epaddr = (psm_epaddr_t) dest_addr;
	}

	psm_tag = tag & (~ep_priv->domain->reserved_tag_bits);
#if (PSM_VERNO_MAJOR >= 2)
	PSMX_SET_TAG(psm_tag2, psm_tag, data);
#endif

	if ((flags & PSMX_NO_COMPLETION) ||
	    (ep_priv->send_selective_completion && !(flags & FI_COMPLETION)))
		no_completion = 1;

	if (flags & FI_INJECT) {
		if (len > PSMX_INJECT_SIZE)
			return -FI_EMSGSIZE;

#if (PSM_VERNO_MAJOR >= 2)
		err = psm_mq_send2(ep_priv->domain->psm_mq, psm_epaddr, 0,
				   &psm_tag2, buf, len);
#else
		err = psm_mq_send(ep_priv->domain->psm_mq, psm_epaddr, 0,
				  psm_tag, buf, len);
#endif

		if (err != PSM_OK)
			return psmx_errno(err);

		if (ep_priv->send_cntr)
			psmx_cntr_inc(ep_priv->send_cntr);

		if (ep_priv->send_cq && !no_completion) {
			event = psmx_cq_create_event(
					ep_priv->send_cq,
					context, (void *)buf, flags, len,
#if (PSM_VERNO_MAJOR >= 2)
					(uint64_t) data, psm_tag,
#else
					0 /* data */, psm_tag,
#endif
					0 /* olen */,
					0 /* err */);

			if (event)
				psmx_cq_enqueue_event(ep_priv->send_cq, event);
			else
				return -FI_ENOMEM;
		}

		return 0;
	}

	if (no_completion && !context) {
		fi_context = &ep_priv->nocomp_send_context;
	}
	else {
		if (!context)
			return -FI_EINVAL;

		fi_context = context;
		PSMX_CTXT_TYPE(fi_context) = PSMX_TSEND_CONTEXT;
		PSMX_CTXT_USER(fi_context) = (void *)buf;
		PSMX_CTXT_EP(fi_context) = ep_priv;
	}

#if (PSM_VERNO_MAJOR >= 2)
	err = psm_mq_isend2(ep_priv->domain->psm_mq, psm_epaddr, 0,
				&psm_tag2, buf, len, (void*)fi_context, &psm_req);
#else
	err = psm_mq_isend(ep_priv->domain->psm_mq, psm_epaddr, 0,
				psm_tag, buf, len, (void*)fi_context, &psm_req);
#endif

	if (err != PSM_OK)
		return psmx_errno(err);

	if (fi_context == context)
		PSMX_CTXT_REQ(fi_context) = psm_req;

	return 0;
}