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