Example #1
0
static UCS_F_ALWAYS_INLINE ucs_status_ptr_t
ucp_tag_send_req(ucp_request_t *req, size_t count,
                 const ucp_ep_msg_config_t* msg_config,
                 size_t rndv_rma_thresh, size_t rndv_am_thresh,
                 ucp_send_callback_t cb, const ucp_proto_t *proto)
{
    size_t seg_size     = (msg_config->max_bcopy - proto->only_hdr_size);
    size_t rndv_thresh  = ucp_tag_get_rndv_threshold(req, count,
                                                     msg_config->max_iov,
                                                     rndv_rma_thresh,
                                                     rndv_am_thresh, seg_size);
    size_t zcopy_thresh = ucp_proto_get_zcopy_threshold(req, msg_config, count,
                                                        rndv_thresh);
    ssize_t max_short   = ucp_proto_get_short_max(req, msg_config);
    ucs_status_t status;

    ucs_trace_req("select tag request(%p) progress algorithm datatype=%lx "
                  "buffer=%p length=%zu max_short=%zd rndv_thresh=%zu "
                  "zcopy_thresh=%zu",
                  req, req->send.datatype, req->send.buffer, req->send.length,
                  max_short, rndv_thresh, zcopy_thresh);

    status = ucp_request_send_start(req, max_short, zcopy_thresh, seg_size,
                                    rndv_thresh, proto);
    if (ucs_unlikely(status != UCS_OK)) {
        if (status == UCS_ERR_NO_PROGRESS) {
             ucs_assert(req->send.length >= rndv_thresh);
            /* RMA/AM rendezvous */
            status = ucp_tag_send_start_rndv(req);
        }
        if (status != UCS_OK) {
            return UCS_STATUS_PTR(status);
        }
    }

    ucp_request_send_tag_stat(req);

    /*
     * Start the request.
     * If it is completed immediately, release the request and return the status.
     * Otherwise, return the request.
     */
    status = ucp_request_send(req);
    if (req->flags & UCP_REQUEST_FLAG_COMPLETED) {
        ucs_trace_req("releasing send request %p, returning status %s", req,
                      ucs_status_string(status));
        ucp_request_put(req);
        return UCS_STATUS_PTR(status);
    }

    ucp_request_set_callback(req, send.cb, cb)
    ucs_trace_req("returning send request %p", req);
    return req + 1;
}
Example #2
0
static ucs_status_t ucp_tag_req_start_contig(ucp_request_t *req, size_t count,
                                             ssize_t max_short, size_t zcopy_thresh,
                                             size_t rndv_thresh,
                                             const ucp_proto_t *proto)
{
    ucp_ep_config_t *config = ucp_ep_config(req->send.ep);
    size_t only_hdr_size = proto->only_hdr_size;
    ucs_status_t status;
    size_t max_zcopy;
    ssize_t length;

    length           = ucp_contig_dt_length(req->send.datatype, count);
    req->send.length = length;

    if (length <= max_short) {
        /* short */
        req->send.uct.func = proto->contig_short;
    } else if (length >= rndv_thresh) {
        /* rendezvous */
        status = ucp_tag_send_start_rndv(req);
        if (status != UCS_OK) {
            return status;
        }
    } else if (length < zcopy_thresh) {
        /* bcopy */
        if (req->send.length <= config->max_am_bcopy - only_hdr_size) {
            req->send.uct.func = proto->bcopy_single;
        } else {
            req->send.uct.func = proto->bcopy_multi;
        }
    } else {
        /* eager zcopy */
        status = ucp_request_send_buffer_reg(req, ucp_ep_get_am_lane(req->send.ep));
        if (status != UCS_OK) {
            return status;
        }

        req->send.uct_comp.func = proto->contig_zcopy_completion;

        max_zcopy = config->max_am_zcopy;
        if (req->send.length <= max_zcopy - only_hdr_size) {
            req->send.uct_comp.count = 1;
            req->send.uct.func = proto->contig_zcopy_single;
        } else {
            /* calculate number of zcopy fragments */
            req->send.uct_comp.count = 1 +
                    (length + proto->first_hdr_size - proto->mid_hdr_size - 1) /
                    (max_zcopy - proto->mid_hdr_size);
            req->send.uct.func = proto->contig_zcopy_multi;
        }
    }
    return UCS_OK;
}
Example #3
0
static ucs_status_t
ucp_tag_send_start_req(ucp_ep_h ep, const void *buffer, size_t count,
                       ucp_datatype_t datatype, ucp_tag_t tag,
                       ucp_request_t *req)
{
    size_t rndv_thresh = ep->worker->context->config.rndv_thresh;
    ucp_dt_generic_t *dt_gen;
    void *state;

    req->send.ep           = ep;
    req->send.buffer       = buffer;
    req->send.count        = count;
    req->send.datatype     = datatype;
    req->send.state.offset = 0;
    req->send.tag          = tag;

    switch (datatype & UCP_DATATYPE_CLASS_MASK) {
    case UCP_DATATYPE_CONTIG:
        /* TODO check for zero-copy */
        req->send.length = ucp_contig_dt_length(datatype, count);
        if (req->send.length <= rndv_thresh) {
            req->send.uct.func = ucp_tag_progress_eager_contig;
            return UCS_OK;
        }
        break;

    case UCP_DATATYPE_GENERIC:
        dt_gen = ucp_dt_generic(datatype);
        state = dt_gen->ops.start_pack(dt_gen->context, buffer, count);

        req->send.state.dt.generic.state = state;
        req->send.length = dt_gen->ops.packed_size(state);
        if (req->send.length <= rndv_thresh) {
            req->send.uct.func = ucp_tag_progress_eager_generic;
            return UCS_OK;
        }
        break;

    default:
        return UCS_ERR_INVALID_PARAM;
    }

    return ucp_tag_send_start_rndv(req);
}