/* try to get a small message out on to the wire quickly */ static inline int mca_pml_ob1_send_inline (const void *buf, size_t count, ompi_datatype_t * datatype, int dst, int tag, int16_t seqn, ompi_proc_t *dst_proc, mca_bml_base_endpoint_t* endpoint, ompi_communicator_t * comm) { mca_pml_ob1_match_hdr_t match; mca_bml_base_btl_t *bml_btl; opal_convertor_t convertor; size_t size; int rc; bml_btl = mca_bml_base_btl_array_get_next(&endpoint->btl_eager); if( NULL == bml_btl->btl->btl_sendi) return OMPI_ERR_NOT_AVAILABLE; ompi_datatype_type_size (datatype, &size); if ((size * count) > 256) { /* some random number */ return OMPI_ERR_NOT_AVAILABLE; } if (count > 0) { /* initialize just enough of the convertor to avoid a SEGV in opal_convertor_cleanup */ OBJ_CONSTRUCT(&convertor, opal_convertor_t); /* We will create a convertor specialized for the */ /* remote architecture and prepared with the datatype. */ opal_convertor_copy_and_prepare_for_send (dst_proc->super.proc_convertor, (const struct opal_datatype_t *) datatype, count, buf, 0, &convertor); opal_convertor_get_packed_size (&convertor, &size); } else { size = 0; } mca_pml_ob1_match_hdr_prepare (&match, MCA_PML_OB1_HDR_TYPE_MATCH, 0, comm->c_contextid, comm->c_my_rank, tag, seqn); ob1_hdr_hton(&match, MCA_PML_OB1_HDR_TYPE_MATCH, dst_proc); /* try to send immediately */ rc = mca_bml_base_sendi (bml_btl, &convertor, &match, OMPI_PML_OB1_MATCH_HDR_LEN, size, MCA_BTL_NO_ORDER, MCA_BTL_DES_FLAGS_PRIORITY | MCA_BTL_DES_FLAGS_BTL_OWNERSHIP, MCA_PML_OB1_HDR_TYPE_MATCH, NULL); if (count > 0) { opal_convertor_cleanup (&convertor); } if (OPAL_UNLIKELY(OMPI_SUCCESS != rc)) { return rc; } return (int) size; }
/** * Send an FIN to the peer. If we fail to send this ack (no more available * fragments or the send failed) this function automatically add the FIN * to the list of pending FIN, Which guarantee that the FIN will be sent * later. */ int mca_pml_ob1_send_fin( ompi_proc_t* proc, mca_bml_base_btl_t* bml_btl, ompi_ptr_t hdr_des, uint8_t order, uint32_t status ) { mca_btl_base_descriptor_t* fin; mca_pml_ob1_fin_hdr_t* hdr; int rc; mca_bml_base_alloc(bml_btl, &fin, order, sizeof(mca_pml_ob1_fin_hdr_t), MCA_BTL_DES_FLAGS_PRIORITY | MCA_BTL_DES_FLAGS_BTL_OWNERSHIP); if(NULL == fin) { MCA_PML_OB1_ADD_FIN_TO_PENDING(proc, hdr_des, bml_btl, order, status); return OMPI_ERR_OUT_OF_RESOURCE; } fin->des_cbfunc = mca_pml_ob1_fin_completion; fin->des_cbdata = NULL; /* fill in header */ hdr = (mca_pml_ob1_fin_hdr_t*)fin->des_src->seg_addr.pval; hdr->hdr_common.hdr_flags = 0; hdr->hdr_common.hdr_type = MCA_PML_OB1_HDR_TYPE_FIN; hdr->hdr_des = hdr_des; hdr->hdr_fail = status; ob1_hdr_hton(hdr, MCA_PML_OB1_HDR_TYPE_FIN, proc); /* queue request */ rc = mca_bml_base_send( bml_btl, fin, MCA_PML_OB1_HDR_TYPE_FIN ); if( OPAL_LIKELY( rc >= 0 ) ) { if( OPAL_LIKELY( 1 == rc ) ) { MCA_PML_OB1_PROGRESS_PENDING(bml_btl); } return OMPI_SUCCESS; } mca_bml_base_free(bml_btl, fin); MCA_PML_OB1_ADD_FIN_TO_PENDING(proc, hdr_des, bml_btl, order, status); return OMPI_ERR_OUT_OF_RESOURCE; }
/** * Send an FIN to the peer. If we fail to send this ack (no more available * fragments or the send failed) this function automatically add the FIN * to the list of pending FIN, Which guarantee that the FIN will be sent * later. */ int mca_pml_ob1_send_fin( ompi_proc_t* proc, mca_bml_base_btl_t* bml_btl, opal_ptr_t hdr_frag, uint64_t rdma_size, uint8_t order, int status ) { mca_btl_base_descriptor_t* fin; int rc; mca_bml_base_alloc(bml_btl, &fin, order, sizeof(mca_pml_ob1_fin_hdr_t), MCA_BTL_DES_FLAGS_PRIORITY | MCA_BTL_DES_FLAGS_BTL_OWNERSHIP | MCA_BTL_DES_FLAGS_SIGNAL); if(NULL == fin) { MCA_PML_OB1_ADD_FIN_TO_PENDING(proc, hdr_frag, rdma_size, bml_btl, order, status); return OMPI_ERR_OUT_OF_RESOURCE; } fin->des_cbfunc = mca_pml_ob1_fin_completion; fin->des_cbdata = NULL; /* fill in header */ mca_pml_ob1_fin_hdr_prepare ((mca_pml_ob1_fin_hdr_t *) fin->des_segments->seg_addr.pval, 0, hdr_frag.lval, status ? status : (int64_t) rdma_size); ob1_hdr_hton((mca_pml_ob1_hdr_t *) fin->des_segments->seg_addr.pval, MCA_PML_OB1_HDR_TYPE_FIN, proc); /* queue request */ rc = mca_bml_base_send( bml_btl, fin, MCA_PML_OB1_HDR_TYPE_FIN ); if( OPAL_LIKELY( rc >= 0 ) ) { if( OPAL_LIKELY( 1 == rc ) ) { MCA_PML_OB1_PROGRESS_PENDING(bml_btl); } return OMPI_SUCCESS; } mca_bml_base_free(bml_btl, fin); MCA_PML_OB1_ADD_FIN_TO_PENDING(proc, hdr_frag, rdma_size, bml_btl, order, status); return OMPI_ERR_OUT_OF_RESOURCE; }
/* try to get a small message out on to the wire quickly */ static inline int mca_pml_ob1_send_inline (void *buf, size_t count, ompi_datatype_t * datatype, int dst, int tag, int16_t seqn, ompi_proc_t *dst_proc, mca_bml_base_endpoint_t* endpoint, ompi_communicator_t * comm) { mca_btl_base_descriptor_t *des = NULL; mca_pml_ob1_match_hdr_t match; mca_bml_base_btl_t *bml_btl; OPAL_PTRDIFF_TYPE lb, extent; opal_convertor_t convertor; size_t size = 0; int rc; bml_btl = mca_bml_base_btl_array_get_next(&endpoint->btl_eager); ompi_datatype_get_extent (datatype, &lb, &extent); if (OPAL_UNLIKELY((extent * count) > 256 || !bml_btl->btl->btl_sendi)) { return OMPI_ERR_NOT_AVAILABLE; } if (count > 0) { /* initialize just enough of the convertor to avoid a SEGV in opal_convertor_cleanup */ OBJ_CONSTRUCT(&convertor, opal_convertor_t); /* We will create a convertor specialized for the */ /* remote architecture and prepared with the datatype. */ opal_convertor_copy_and_prepare_for_send (dst_proc->proc_convertor, (const struct opal_datatype_t *) datatype, count, buf, 0, &convertor); opal_convertor_get_packed_size (&convertor, &size); } match.hdr_common.hdr_flags = 0; match.hdr_common.hdr_type = MCA_PML_OB1_HDR_TYPE_MATCH; match.hdr_ctx = comm->c_contextid; match.hdr_src = comm->c_my_rank; match.hdr_tag = tag; match.hdr_seq = seqn; ob1_hdr_hton(&match, MCA_PML_OB1_HDR_TYPE_MATCH, dst_proc); /* try to send immediately */ rc = mca_bml_base_sendi (bml_btl, &convertor, &match, OMPI_PML_OB1_MATCH_HDR_LEN, size, MCA_BTL_NO_ORDER, MCA_BTL_DES_FLAGS_PRIORITY | MCA_BTL_DES_FLAGS_BTL_OWNERSHIP, MCA_PML_OB1_HDR_TYPE_MATCH, &des); if (count > 0) { opal_convertor_cleanup (&convertor); } if (OPAL_UNLIKELY(OMPI_SUCCESS != rc)) { if (des) { mca_bml_base_free (bml_btl, des); } return rc; } return (int) size; }