int mca_btl_self_send( struct mca_btl_base_module_t* btl, struct mca_btl_base_endpoint_t* endpoint, struct mca_btl_base_descriptor_t* des, mca_btl_base_tag_t tag ) { mca_btl_active_message_callback_t* reg; int btl_ownership = (des->des_flags & MCA_BTL_DES_FLAGS_BTL_OWNERSHIP); /** * We have to set the dst before the call to the function and reset them * after. */ des->des_dst = des->des_src; des->des_dst_cnt = des->des_src_cnt; /* upcall */ reg = mca_btl_base_active_message_trigger + tag; reg->cbfunc( btl, tag, des, reg->cbdata ); des->des_dst = NULL; des->des_dst_cnt = 0; /* send completion */ if( des->des_flags & MCA_BTL_DES_SEND_ALWAYS_CALLBACK ) { des->des_cbfunc( btl, endpoint, des, OMPI_SUCCESS ); } if( btl_ownership ) { mca_btl_self_free( btl, des ); } return 1; }
/** * Prepare data for send * * @param btl (IN) BTL module */ static struct mca_btl_base_descriptor_t *mca_btl_self_prepare_src (struct mca_btl_base_module_t* btl, struct mca_btl_base_endpoint_t *endpoint, struct opal_convertor_t *convertor, uint8_t order, size_t reserve, size_t *size, uint32_t flags) { bool inline_send = !opal_convertor_need_buffers(convertor); size_t buffer_len = reserve + (inline_send ? 0 : *size); mca_btl_self_frag_t *frag; frag = (mca_btl_self_frag_t *) mca_btl_self_alloc (btl, endpoint, order, buffer_len, flags); if (OPAL_UNLIKELY(NULL == frag)) { return NULL; } /* non-contigous data */ if (OPAL_UNLIKELY(!inline_send)) { struct iovec iov = {.iov_len = *size, .iov_base = (IOVBASE_TYPE *) ((uintptr_t) frag->data + reserve)}; size_t max_data = *size; uint32_t iov_count = 1; int rc; rc = opal_convertor_pack (convertor, &iov, &iov_count, &max_data); if(rc < 0) { mca_btl_self_free (btl, &frag->base); return NULL; } *size = max_data; frag->segments[0].seg_len = reserve + max_data; } else { void *data_ptr; opal_convertor_get_current_pointer (convertor, &data_ptr); frag->segments[1].seg_addr.pval = data_ptr; frag->segments[1].seg_len = *size; frag->base.des_segment_count = 2; } return &frag->base; }
static int mca_btl_self_send (struct mca_btl_base_module_t *btl, struct mca_btl_base_endpoint_t *endpoint, struct mca_btl_base_descriptor_t *des, mca_btl_base_tag_t tag) { mca_btl_active_message_callback_t* reg; int btl_ownership = (des->des_flags & MCA_BTL_DES_FLAGS_BTL_OWNERSHIP); /* upcall */ reg = mca_btl_base_active_message_trigger + tag; reg->cbfunc( btl, tag, des, reg->cbdata ); /* send completion */ if( des->des_flags & MCA_BTL_DES_SEND_ALWAYS_CALLBACK ) { des->des_cbfunc( btl, endpoint, des, OPAL_SUCCESS ); } if( btl_ownership ) { mca_btl_self_free( btl, des ); } return 1; }
int mca_btl_self_rdma( struct mca_btl_base_module_t* btl, struct mca_btl_base_endpoint_t* endpoint, struct mca_btl_base_descriptor_t* des ) { mca_btl_base_segment_t* src = des->des_src; mca_btl_base_segment_t* dst = des->des_dst; size_t src_cnt = des->des_src_cnt; size_t dst_cnt = des->des_dst_cnt; unsigned char* src_addr = (unsigned char *)(uintptr_t) src->seg_addr.lval; size_t src_len = src->seg_len; unsigned char* dst_addr = (unsigned char *)(uintptr_t) dst->seg_addr.lval; size_t dst_len = dst->seg_len; int btl_ownership = (des->des_flags & MCA_BTL_DES_FLAGS_BTL_OWNERSHIP); while(src_len && dst_len) { if(src_len == dst_len) { memcpy(dst_addr, src_addr, src_len); /* advance src */ if(--src_cnt != 0) { src++; src_addr = (unsigned char*)src->seg_addr.pval; src_len = src->seg_len; } else { src_len = 0; } /* advance dst */ if(--dst_cnt != 0) { dst++; dst_addr = (unsigned char*)dst->seg_addr.pval; dst_len = dst->seg_len; } else { dst_len = 0; } } else { size_t bytes = src_len < dst_len ? src_len : dst_len; memcpy(dst_addr, src_addr, bytes); /* advance src */ src_len -= bytes; if(src_len == 0) { if(--src_cnt != 0) { src++; src_addr = (unsigned char*)src->seg_addr.pval; src_len = src->seg_len; } } else { src_addr += bytes; } /* advance dst */ dst_len -= bytes; if(dst_len == 0) { if(--dst_cnt != 0) { dst++; dst_addr = (unsigned char*)src->seg_addr.pval; dst_len = src->seg_len; } } else { dst_addr += bytes; } } } /* rdma completion */ des->des_cbfunc( btl, endpoint, des, OMPI_SUCCESS ); if( btl_ownership ) { mca_btl_self_free( btl, des ); } return OMPI_SUCCESS; }