Repository navigation
UCP/RMA: Add SGL support to ucp_get_nbx #12191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 26 commits
f6c122f
6b3e599
83c09db
1310a95
e66f515
1b00c0a
7707911
6bb884f
3cc34f9
a30608b
719fe4e
a33a3ff
36d2668
ba533ec
d8902f5
c797f99
6c6b9d2
e7c25f2
7a3ce46
2af290c
54d5e14
87b2909
bb14368
f55427a
1c61c0c
3c2de12
1187eaa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -381,4 +381,193 @@ ucp_proto_multi_rma_init_func(ucp_request_t *req) | |
| return ucp_ep_rma_handle_fence(req->send.ep, req, mpriv->lane_map); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these helpers are RMA-SGL specific ( |
||
| } | ||
|
|
||
| typedef ucs_status_t (*ucp_proto_rma_sgl_post_func_t)( | ||
|
michal-shalev marked this conversation as resolved.
Resolved
michal-shalev marked this conversation as resolved.
Resolved
|
||
| ucp_request_t *req, const ucp_proto_multi_lane_priv_t *lpriv, | ||
| void *const *buffers, const size_t *lengths, uct_mem_h const *memhs, | ||
| const uint64_t *remote_addrs, uct_rkey_t const *rkeys, size_t count); | ||
|
|
||
| /* Returns UCS_INPROGRESS if the fragment was already submitted */ | ||
| typedef ucs_status_t (*ucp_proto_rma_sgl_adjust_func_t)( | ||
| ucp_request_t *req, const ucp_proto_multi_lane_priv_t *lpriv, | ||
| size_t elem_index, void **buffer_p, size_t *length_p, | ||
| uint64_t *remote_addr_p); | ||
|
|
||
| /* Split the SGL by its total length, like a multi-lane contiguous message */ | ||
| static UCS_F_ALWAYS_INLINE size_t | ||
| ucp_proto_rma_sgl_max_payload(const ucp_request_t *req, | ||
| const ucp_proto_multi_lane_priv_t *lpriv) | ||
| { | ||
| size_t length = req->send.rma.sgl.length; | ||
|
|
||
| return ucp_proto_multi_lane_payload(lpriv, length, length, | ||
| lpriv->max_frag); | ||
| } | ||
|
|
||
| static UCS_F_INLINE_OPTIMIZED ucs_status_t | ||
| ucp_proto_rma_sgl_offload_send_frags( | ||
| ucp_request_t *req, const ucp_proto_multi_lane_priv_t *lpriv, | ||
| size_t max_frag_count, ucp_datatype_iter_t *next_iter, | ||
| ucp_proto_rma_sgl_post_func_t post_func, | ||
| ucp_proto_rma_sgl_adjust_func_t adjust_func) | ||
| { | ||
| ucp_datatype_iter_t *dt_iter = &req->send.state.dt_iter; | ||
| ucp_rsc_index_t md_index = lpriv->super.md_index; | ||
| ucp_mem_h *sgl_memhs = dt_iter->type.sgl.memhs; | ||
| ucp_rkey_h const *sgl_rkeys = req->send.rma.sgl.rkeys; | ||
| void *buffers[UCP_MAX_IOV]; | ||
| size_t lengths[UCP_MAX_IOV]; | ||
| uint64_t remote_addrs[UCP_MAX_IOV]; | ||
| size_t elem_indices[UCP_MAX_IOV]; | ||
| uct_mem_h uct_memhs[UCP_MAX_IOV]; | ||
| uct_rkey_t uct_rkeys[UCP_MAX_IOV]; | ||
| size_t frag_count, frag_index, elem_index; | ||
| ucs_status_t status; | ||
|
|
||
| ucs_assert(max_frag_count <= UCP_MAX_IOV); | ||
| ucs_assert((adjust_func == NULL) || (max_frag_count == 1)); | ||
|
|
||
| if (max_frag_count == 1) { | ||
| /* Silence compiler warning, a single fragment is read by the adjust | ||
| * and post functions */ | ||
| buffers[0] = NULL; | ||
| lengths[0] = 0; | ||
| remote_addrs[0] = 0; | ||
| } | ||
|
|
||
| frag_count = ucp_datatype_iter_next_sgl_frags( | ||
| dt_iter, req->send.rma.sgl.remote_addrs, max_frag_count, | ||
| ucp_proto_rma_sgl_max_payload(req, lpriv), next_iter, buffers, | ||
| lengths, remote_addrs, elem_indices); | ||
| if (frag_count == 0) { | ||
| return UCS_OK; | ||
| } | ||
|
|
||
| if (adjust_func != NULL) { | ||
| status = adjust_func(req, lpriv, elem_indices[0], &buffers[0], | ||
| &lengths[0], &remote_addrs[0]); | ||
| if (ucs_unlikely(status != UCS_OK)) { | ||
| return (status == UCS_INPROGRESS) ? UCS_OK : status; | ||
| } | ||
| } | ||
|
|
||
| for (frag_index = 0; frag_index < frag_count; frag_index++) { | ||
| elem_index = elem_indices[frag_index]; | ||
| uct_memhs[frag_index] = (sgl_memhs != NULL) ? | ||
| ucp_datatype_iter_uct_memh(sgl_memhs[elem_index], | ||
| md_index) : | ||
| UCT_MEM_HANDLE_NULL; | ||
| uct_rkeys[frag_index] = ucp_rkey_get_tl_rkey(sgl_rkeys[elem_index], | ||
| lpriv->super.rkey_index); | ||
| } | ||
|
|
||
| return post_func(req, lpriv, buffers, lengths, uct_memhs, remote_addrs, | ||
| uct_rkeys, frag_count); | ||
| } | ||
|
|
||
| static UCS_F_ALWAYS_INLINE ucs_status_t | ||
| ucp_proto_rma_sgl_offload_send_func( | ||
| ucp_request_t *req, const ucp_proto_multi_lane_priv_t *lpriv, | ||
| ucp_datatype_iter_t *next_iter, | ||
| ucp_proto_rma_sgl_post_func_t post_func, | ||
| ucp_proto_rma_sgl_adjust_func_t adjust_func) | ||
| { | ||
| ucp_datatype_iter_t *dt_iter = &req->send.state.dt_iter; | ||
| ucp_rsc_index_t md_index = lpriv->super.md_index; | ||
| ucp_rsc_index_t rkey_index = lpriv->super.rkey_index; | ||
| size_t max_payload = ucp_proto_rma_sgl_max_payload(req, lpriv); | ||
| size_t min_length = ucs_max(lpriv->min_sgl_frag, 1); | ||
| size_t max_frag_count = ucs_min(lpriv->max_sgl_zcopy_count, | ||
| UCP_MAX_IOV); | ||
| size_t frags_count = (adjust_func == NULL) ? max_frag_count : 1; | ||
| ucp_mem_h *sgl_memhs = dt_iter->type.sgl.memhs; | ||
| ucp_rkey_h const *sgl_rkeys = req->send.rma.sgl.rkeys; | ||
| void *const *buffers = dt_iter->type.sgl.buffers; | ||
| const size_t *lengths = dt_iter->type.sgl.lengths; | ||
| const uint64_t *remote_addrs = req->send.rma.sgl.remote_addrs; | ||
| size_t start_index = dt_iter->offset; | ||
| size_t max_elem_count = ucs_min(lpriv->max_sgl_zcopy_count, | ||
| dt_iter->length - start_index); | ||
| size_t uct_rkeys_size; | ||
| size_t uct_memhs_size; | ||
| uct_rkey_t *uct_rkeys; | ||
| uct_mem_h *uct_memhs; | ||
| ucs_status_t status; | ||
| size_t elem_count, idx, length, total_length; | ||
|
|
||
| ucs_assert(max_payload > 0); | ||
| ucs_assert(max_elem_count > 0); | ||
|
|
||
| /* Silence compiler warning, in case of an early return below */ | ||
| next_iter->offset = start_index; | ||
| next_iter->type.sgl.frag_offset = dt_iter->type.sgl.frag_offset; | ||
|
|
||
| /* The first element must be posted as a whole, otherwise it is fragmented */ | ||
| if (ucs_unlikely((dt_iter->type.sgl.frag_offset != 0) || | ||
| (lengths[start_index] < min_length) || | ||
| (lengths[start_index] > max_payload))) { | ||
| return ucp_proto_rma_sgl_offload_send_frags(req, lpriv, frags_count, | ||
| next_iter, post_func, | ||
| adjust_func); | ||
| } | ||
|
|
||
| /* Stop at the lane payload, so that each lane sends its share of the | ||
| * message */ | ||
| for (elem_count = 0, total_length = 0; elem_count < max_elem_count; | ||
| elem_count++) { | ||
| length = lengths[start_index + elem_count]; | ||
| if ((length < min_length) || ((total_length + length) > max_payload)) { | ||
| break; | ||
| } | ||
|
|
||
| total_length += length; | ||
| } | ||
|
|
||
| /* A long batch is not redirected, to keep posting the user arrays without | ||
| * copying them */ | ||
| if (ucs_unlikely((adjust_func == NULL) && (total_length < max_payload) && | ||
| (elem_count < max_frag_count) && | ||
| ((start_index + elem_count) < dt_iter->length))) { | ||
| return ucp_proto_rma_sgl_offload_send_frags(req, lpriv, frags_count, | ||
| next_iter, post_func, | ||
| adjust_func); | ||
| } | ||
|
|
||
| uct_rkeys_size = elem_count * sizeof(uct_rkey_t); | ||
| uct_memhs_size = elem_count * sizeof(uct_mem_h); | ||
|
|
||
| uct_rkeys = ucs_alloc_on_stack(uct_rkeys_size, "uct_sgl_rkeys"); | ||
| if (uct_rkeys == NULL) { | ||
| return UCS_ERR_NO_MEMORY; | ||
| } | ||
|
|
||
| uct_memhs = ucs_alloc_on_stack(uct_memhs_size, "uct_sgl_memhs"); | ||
| if (uct_memhs == NULL) { | ||
| ucs_free_on_stack(uct_rkeys, uct_rkeys_size); | ||
| return UCS_ERR_NO_MEMORY; | ||
| } | ||
|
|
||
| for (idx = 0; idx < elem_count; idx++) { | ||
| uct_memhs[idx] = (sgl_memhs != NULL) ? | ||
| ucp_datatype_iter_uct_memh(sgl_memhs[start_index + idx], | ||
| md_index) : | ||
| UCT_MEM_HANDLE_NULL; | ||
| uct_rkeys[idx] = ucp_rkey_get_tl_rkey(sgl_rkeys[start_index + idx], | ||
| rkey_index); | ||
| } | ||
|
|
||
| next_iter->offset = start_index + elem_count; | ||
| next_iter->type.sgl.frag_offset = 0; | ||
|
|
||
| status = post_func(req, lpriv, &buffers[start_index], &lengths[start_index], | ||
| uct_memhs, &remote_addrs[start_index], uct_rkeys, | ||
| elem_count); | ||
|
|
||
| /* coverity[incorrect_free] */ | ||
| ucs_free_on_stack(uct_memhs, uct_memhs_size); | ||
| /* coverity[incorrect_free] */ | ||
| ucs_free_on_stack(uct_rkeys, uct_rkeys_size); | ||
|
|
||
| return status; | ||
| } | ||
|
|
||
| #endif | ||
Uh oh!
There was an error while loading. Please reload this page.