33 */
44#include " broadcast.h"
55
6- #include < cmath> // for ceil, log2
76#include < cstdint> // for int32_t, int8_t
87#include < utility> // for move
98#include < vector> // for vector
109
11- #include " ../common/bitfield.h" // for TrailingZeroBits, RBitField32
12- #include " comm.h" // for Comm
10+ #include " comm.h" // for Comm, binomial_tree
1311#include " xgboost/collective/result.h" // for Result
1412#include " xgboost/span.h" // for Span
1513
@@ -19,11 +17,9 @@ namespace {
1917Result BroadcastTree (Comm const & comm, common::Span<std::int8_t > data) {
2018 auto rank = comm.Rank ();
2119 auto world = comm.World ();
22- std::int32_t depth = std::ceil (std::log2 (static_cast <double >(world))) - 1 ;
2320
2421 if (rank != 0 ) {
25- auto k = TrailingZeroBits (static_cast <std::uint32_t >(rank));
26- auto parent = rank - (1 << k);
22+ auto parent = binomial_tree::Parent (rank);
2723 auto rc = Success () << [&] {
2824 return comm.Chan (parent)->RecvAll (data);
2925 } << [&] {
@@ -34,9 +30,9 @@ Result BroadcastTree(Comm const& comm, common::Span<std::int8_t> data) {
3430 }
3531 }
3632
37- for (std::int32_t i = depth; i >= 0 ; --i ) {
38- if (rank % ( 1 << (i + 1 )) == 0 && rank + ( 1 << i) < world) {
39- auto child = rank + ( 1 << i );
33+ for (std::int32_t level = binomial_tree::Depth (world); level >= 0 ; --level ) {
34+ if (binomial_tree::HasChild ( rank, level, world) ) {
35+ auto child = binomial_tree::Child ( rank, level );
4036 auto rc = comm.Chan (child)->SendAll (data);
4137 if (!rc.OK ()) {
4238 return rc;
@@ -48,27 +44,25 @@ Result BroadcastTree(Comm const& comm, common::Span<std::int8_t> data) {
4844}
4945
5046// Compute the path from `src` to rank 0 through the binomial tree (excluding 0).
51- std::vector<std::int32_t > TreePathToRoot (std::int32_t src ) {
47+ std::vector<std::int32_t > TreePathToRoot (std::int32_t node ) {
5248 std::vector<std::int32_t > path;
53- auto cursor = src ;
49+ auto cursor = node ;
5450 while (cursor > 0 ) {
5551 path.push_back (cursor);
56- auto k = TrailingZeroBits (static_cast <std::uint32_t >(cursor));
57- cursor -= (1 << k);
52+ cursor = binomial_tree::Parent (cursor);
5853 }
5954 return path;
6055}
6156
62- // Relay data from `root ` up to rank 0 through the binomial tree.
63- // Only nodes on the path from root to 0 participate; all others skip.
64- Result RelayToRoot (Comm const & comm, common::Span<std::int8_t > data, std::int32_t root ) {
57+ // Relay data from `node ` up to rank 0 through the binomial tree.
58+ // Only nodes on the path from `node` to 0 participate; all others skip.
59+ Result RelayToRoot (Comm const & comm, common::Span<std::int8_t > data, std::int32_t node ) {
6560 auto rank = comm.Rank ();
66- auto path = TreePathToRoot (root );
61+ auto path = TreePathToRoot (node );
6762
6863 for (auto node : path) {
6964 CHECK_GT (node, 0 );
70- auto k = TrailingZeroBits (static_cast <std::uint32_t >(node));
71- auto parent = node - (std::int32_t {1 } << k);
65+ auto parent = binomial_tree::Parent (node);
7266
7367 if (rank == node) {
7468 auto rc = Success () << [&] {
0 commit comments