| 186 | } |
| 187 | |
| 188 | void Network::AllgatherRecursiveDoubling(char* input, const comm_size_t* block_start, const comm_size_t* block_len, char* output, comm_size_t) { |
| 189 | // use output as receive buffer |
| 190 | std::memcpy(output + block_start[rank_], input, block_len[rank_]); |
| 191 | for (int i = 0; i < bruck_map_.k; ++i) { |
| 192 | // get current local block size |
| 193 | int cur_step = 1 << i; |
| 194 | const int vgroup = rank_ / cur_step; |
| 195 | const int vrank = vgroup * cur_step; |
| 196 | int target = rank_ + cur_step; |
| 197 | int target_vrank = (vgroup + 1) * cur_step; |
| 198 | if (vgroup & 1) { |
| 199 | target = rank_ - cur_step; |
| 200 | target_vrank = (vgroup - 1) * cur_step; |
| 201 | } |
| 202 | // get send information |
| 203 | comm_size_t need_send_len = 0; |
| 204 | // get recv information |
| 205 | comm_size_t need_recv_len = 0; |
| 206 | for (int j = 0; j < cur_step; ++j) { |
| 207 | need_send_len += block_len[(vrank + j)]; |
| 208 | need_recv_len += block_len[(target_vrank + j)]; |
| 209 | } |
| 210 | // send and recv at same time |
| 211 | linkers_->SendRecv(target, output + block_start[vrank], need_send_len, |
| 212 | target, output + block_start[target_vrank], need_recv_len); |
| 213 | } |
| 214 | } |
| 215 | |
| 216 | void Network::AllgatherRing(char* input, const comm_size_t* block_start, const comm_size_t* block_len, char* output, comm_size_t) { |
| 217 | // use output as receive buffer |