| 154 | } |
| 155 | |
| 156 | void Network::AllgatherBruck(char* input, const comm_size_t* block_start, const comm_size_t* block_len, char* output, comm_size_t all_size) { |
| 157 | comm_size_t write_pos = 0; |
| 158 | // use output as receive buffer |
| 159 | std::memcpy(output, input, block_len[rank_]); |
| 160 | write_pos += block_len[rank_]; |
| 161 | int accumulated_block = 1; |
| 162 | for (int i = 0; i < bruck_map_.k; ++i) { |
| 163 | // get current local block size |
| 164 | int cur_block_size = std::min(1 << i, num_machines_ - accumulated_block); |
| 165 | // get out rank |
| 166 | int out_rank = bruck_map_.out_ranks[i]; |
| 167 | // get in rank |
| 168 | int in_rank = bruck_map_.in_ranks[i]; |
| 169 | // get send information |
| 170 | comm_size_t need_send_len = 0; |
| 171 | // get recv information |
| 172 | comm_size_t need_recv_len = 0; |
| 173 | for (int j = 0; j < cur_block_size; ++j) { |
| 174 | need_send_len += block_len[(rank_ + j) % num_machines_]; |
| 175 | need_recv_len += block_len[(rank_ + accumulated_block + j) % num_machines_]; |
| 176 | } |
| 177 | // send and recv at same time |
| 178 | linkers_->SendRecv(out_rank, output, need_send_len, in_rank, output + write_pos, need_recv_len); |
| 179 | write_pos += need_recv_len; |
| 180 | accumulated_block += cur_block_size; |
| 181 | } |
| 182 | // rotate in-place |
| 183 | std::reverse<char*>(output, output + all_size); |
| 184 | std::reverse<char*>(output, output + block_start[rank_]); |
| 185 | std::reverse<char*>(output + block_start[rank_], output + all_size); |
| 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 |