-
Notifications
You must be signed in to change notification settings - Fork 101
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
TL/UCP: Allow self copy in allgather using network loopback #1021
base: master
Are you sure you want to change the base?
Conversation
Can one of the admins verify this patch? |
5e852a7
to
7e6c55d
Compare
d13b885
to
b3c2e80
Compare
ok to test |
482006f
to
eecdebf
Compare
1d88c9b
to
820794d
Compare
@Sergei-Lebedev why do we have to keep approving runs when force pushing?? Seems an outlier here |
32b3ccd
to
b1c875b
Compare
2dc74f3
to
a2c5fee
Compare
} | ||
} else { | ||
/* Loopback */ | ||
ucc_rank_t rank = ucc_ep_map_eval(task->subset.map, trank); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
declare variables in the beginning of function
UCPCHECK_GOTO(ucc_tl_ucp_send_nb(sbuf, data_size, smem, trank, team, task),task, err); | ||
UCPCHECK_GOTO(ucc_tl_ucp_recv_nb(PTR_OFFSET(rbuf, data_size * trank), data_size, rmem, trank, team, task),task, err); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe make a loopback copy function, this pattern repeats in every algorithm
} | ||
} | ||
|
||
if (use_cuda) EXEC_TASK_TEST(UCC_KN_PHASE_INIT, "failed during ee task test", task->allgather_kn.etask); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just else for prev if
step = task->tagged.send_posted; | ||
int iter = use_cuda ? tsize - 1 : tsize; //when using loopback tagged.send_posted has 1 more which will cause non-complete ring algorithm | ||
while (task->tagged.send_posted < iter) { | ||
step = use_cuda ? task->tagged.send_posted : task->tagged.send_posted - 1; //when using loopback tagged.send_posted has 1 more which will cause wrong calculation of send/recv |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since loopback affects algorithm flow I would rather consider checking loopback copy result somehow differently, maybe add custom callback for ucp recv completion
a2c5fee
to
5940100
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! It Looks good, I left a bunch of comments mainly on codestyle.
However, please add tests for that feature.
Also please note from the CI:
Commit title is too long: 59
Bad commit title: 'TL/UCP: Allow self copy in allgather using network loopback'
@@ -77,9 +77,15 @@ void ucc_tl_ucp_allgather_knomial_progress(ucc_coll_task_t *coll_task) | |||
size_t peer_seg_count, local_seg_count; | |||
ucc_status_t status; | |||
size_t extra_count; | |||
int use_cuda = UCC_TL_UCP_TEAM_LIB(team)->cfg.allgather_use_cuda; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
codestyle: initialized variables go first. Please, move this line upwards, to be just after
size_t local = GET_LOCAL_COUNT(args, size, rank);
, and please align the datatype, name variable and "=" sign
} | ||
} | ||
|
||
if (use_cuda) EXEC_TASK_TEST(UCC_KN_PHASE_INIT, "failed during ee task test", task->allgather_kn.etask); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
codestyle: please use curly brakcets and new line:
for (condition) {
[body]
}
src/components/tl/ucp/tl_ucp.h
Outdated
@@ -45,6 +45,7 @@ extern ucc_tl_ucp_iface_t ucc_tl_ucp; | |||
typedef struct ucc_tl_ucp_lib_config { | |||
ucc_tl_lib_config_t super; | |||
uint32_t kn_radix; | |||
uint32_t allgather_use_cuda; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we usually use int
for booleans, rather than uint32_t
. Btw it needs to be consistent with int use_cuda = UCC_TL_UCP_TEAM_LIB(team)->cfg.allgather_use_cuda;
from allgather_knomial.c
@@ -140,6 +140,10 @@ ucc_config_field_t ucc_tl_ucp_lib_config_table[] = { | |||
ucc_offsetof(ucc_tl_ucp_lib_config_t, allgather_kn_radix), | |||
UCC_CONFIG_TYPE_UINT}, | |||
|
|||
{"ALLGATHER_USE_CUDA", "1", "If set to 1 uses mc cuda copy, otherwise performs loopback for self copy", | |||
ucc_offsetof(ucc_tl_ucp_lib_config_t, allgather_use_cuda), | |||
UCC_CONFIG_TYPE_UINT}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UCC_CONFIG_TYPE_UINT}, | |
UCC_CONFIG_TYPE_BOOL}, |
if (!use_loopback) { | ||
status = ucc_mc_memcpy(PTR_OFFSET(rbuf, data_size * trank), sbuf, | ||
data_size, rmem, smem); | ||
if (ucc_unlikely(UCC_OK != status)) { | ||
return status; | ||
if (ucc_unlikely(UCC_OK != status)) { | ||
return status; | ||
} | ||
} else { | ||
/* Loopback */ | ||
UCPCHECK_GOTO(ucc_tl_ucp_send_nb(sbuf, data_size, smem, trank, team, task),task, out); | ||
UCPCHECK_GOTO(ucc_tl_ucp_recv_nb(PTR_OFFSET(rbuf, data_size * trank), data_size, rmem, trank, team, task),task, out); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this whole code block is duplicated in neighbor, ring and sparbit. It should be refactored into a helper function and called there.
Ideally, this could also be refactored with the call from knomial, with an additional control about whether to use ucc_mc_memcpy
or the executor.
} | ||
} | ||
|
||
return ucc_progress_queue_enqueue(UCC_TL_CORE_CTX(team)->pq, &task->super); | ||
out: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a goto redirection is not needed here. We could simply check status when it is returned, and return it if it is in error state.
Apply in other places of this PR where this pattern is used
|
||
if (UCC_INPROGRESS == ucc_tl_ucp_test(task)) { | ||
return; | ||
} | ||
sendto = ucc_ep_map_eval(task->subset.map, (trank + 1) % tsize); | ||
recvfrom = ucc_ep_map_eval(task->subset.map, (trank - 1 + tsize) % tsize); | ||
|
||
while (task->tagged.send_posted < tsize - 1) { | ||
step = task->tagged.send_posted; | ||
int iter = use_loopback ? tsize : tsize - 1; //when using loopback tagged.send_posted has 1 more which will cause non-complete ring algorithm |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
declaration of variable goes to the beginning of the function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure to understand the comment. What do you mean by "will cause non-complete ring algorithm"?
Can you use a more explicit name than iter
for that variable?
@@ -43,15 +43,18 @@ void ucc_tl_ucp_allgather_ring_progress(ucc_coll_task_t *coll_task) | |||
ucc_rank_t sendto, recvfrom, sblock, rblock; | |||
int step; | |||
void *buf; | |||
int use_loopback = UCC_TL_UCP_TEAM_LIB(team)->cfg.allgather_use_loopback; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initialized variables go first
What
Add option for self copy loopback in out of place start for allgather algorithms: knomial, ring, neighbor, sparbit
Why ?
When using UCC plugin for NCCL, using cuda_memcpy might cause deadlock
How ?
Add UCC_TL_UCP_ALLGATHER_USE_LOOPBACK flag to control this
Tested on ISRAEL-1 with multiple test cases - showed good results and same performance with and without loopback