MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / RunTree

Method RunTree

tensorflow/core/common_runtime/hierarchical_tree_broadcaster.cc:292–406  ·  view source on GitHub ↗

Executes a hierarchical tree broadcast. Each subdiv is a broadcast between a subset of the devices. If there is only one task, there is one subdiv comprising a broadcast between all devices belonging to the task. If there are n tasks, n>1, then there are n+1 subdivs. In the first (global) subdiv, one device from each task participates in a binary tree broadcast. Each task receives a copy of the t

Source from the content-addressed store, hash-verified

290// corresponds to broadcast between all devices on task i. Thus, each task
291// participates in at most 2 subdivs.
292void HierarchicalTreeBroadcaster::RunTree() {
293 int num_subdivs = static_cast<int>(col_params_->subdiv_rank.size());
294 // TODO(b/78352018): this is easily improved when a node participates in both
295 // first and second subdivision. It would first send to its descendents in
296 // the first subdiv, then wait until all pending ops are finished before
297 // sending to descendents in second subdiv. A better implementation would
298 // collapse the two send blocks.
299 for (int si = 0; si < num_subdivs; si++) {
300 int my_rank = col_params_->subdiv_rank[si];
301 // If rank is -1, this device does not participate in this subdiv.
302 if (-1 == my_rank) continue;
303 int source_rank = col_params_->instance.impl_details.subdiv_source_rank[si];
304 if (VLOG_IS_ON(1)) {
305 string subdiv_buf;
306 for (int r : col_params_->instance.impl_details.subdiv_permutations[si]) {
307 strings::StrAppend(&subdiv_buf, r, ",");
308 }
309 VLOG(1) << "Running Broadcast tree device=" << col_ctx_->device_name
310 << " subdiv=" << si << " perm=" << subdiv_buf
311 << " my_rank=" << my_rank << " source_rank=" << source_rank;
312 }
313
314 mutex mu; // also guards status_ while callbacks are pending
315 int pending_count = 0; // GUARDED_BY(mu)
316 condition_variable all_done;
317
318 if (my_rank >= 0 && my_rank != source_rank) {
319 // Begin by receiving the value.
320 profiler::TraceMe activity(
321 [&] { return strings::StrCat("ReceiveValue:", si); },
322 profiler::TraceMeLevel::kInfo);
323 int recv_from_rank = TreeRecvFrom(*col_params_, si);
324 Notification note;
325 DispatchRecv(si, recv_from_rank, my_rank, col_ctx_->output,
326 [this, &mu, &note](const Status& s) {
327 mutex_lock l(mu);
328 status_.Update(s);
329 note.Notify();
330 });
331 note.WaitForNotification();
332 }
333
334 // Then forward value to all descendent devices.
335 {
336 profiler::TraceMe activity(
337 [&] { return strings::StrCat("ForwardValue:", si); },
338 profiler::TraceMeLevel::kInfo);
339 if (my_rank >= 0 && status_.ok()) {
340 std::vector<int> send_to_ranks;
341 TreeSendTo(*col_params_, si, &send_to_ranks);
342 for (int i = 0; i < send_to_ranks.size(); ++i) {
343 int target_rank = send_to_ranks[i];
344 {
345 mutex_lock l(mu);
346 ++pending_count;
347 }
348 DispatchSend(si, target_rank, my_rank,
349 (is_source_ ? col_ctx_->input : col_ctx_->output),

Callers

nothing calls this directly

Calls 13

baseClass · 0.85
notify_allMethod · 0.80
input_alloc_attrMethod · 0.80
output_alloc_attrMethod · 0.80
StrAppendFunction · 0.50
StrCatFunction · 0.50
sizeMethod · 0.45
UpdateMethod · 0.45
NotifyMethod · 0.45
WaitForNotificationMethod · 0.45
okMethod · 0.45
op_device_contextMethod · 0.45

Tested by

no test coverage detected