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

Method GetCommunicator

tensorflow/core/nccl/nccl_manager.cc:251–407  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

249}
250
251Status NcclManager::GetCommunicator(NcclManager::Collective* collective,
252 NcclManager::Communicator** communicator) {
253 // Sort by global rank to make ordering of participants deterministic.
254 std::sort(collective->participants.begin(), collective->participants.end(),
255 [](const std::unique_ptr<Participant>& a,
256 const std::unique_ptr<Participant>& b) {
257 if (a->global_rank == b->global_rank) {
258 return a->executor < b->executor;
259 }
260 return a->global_rank < b->global_rank;
261 });
262
263 mutex_lock l(mu_);
264
265 if (collective->communicator_key.empty()) {
266 // For single-node collectives, when the caller does not specify a
267 // `communicator_key`, we identify a communicator uniquely by the set of
268 // devices participating in the collective. For example, if a collective is
269 // for GPUs 0, 1, and 2 then this will scan to find the communicator for
270 // GPUs 0, 1, and 2.
271 //
272 // Note that each executor identifies a context on one device, so this is
273 // the same as getting the communicator connecting the devices in the
274 // collective. A device can be in different communicators as well - for
275 // example, a communicator for GPUs 0 and 1 is separate from one for GPUs 0,
276 // 1, and 2.
277 //
278 // Since it's expected that a small number of distinct communicators will
279 // be needed, communicators_ is not garbage collected currently.
280 //
281 // Launching of kernels must be serialized so that, given collectives A and
282 // B, and an order of them (e.g., A before B), then for each comm_stream
283 // involved, the kernel for A is launched before the kernel for B. This is
284 // guaranteed currently be a global mutex controlling additions of the
285 // kernels to per-stream launch queues. The launch queues are processed by
286 // LoopKernelLaunches.
287 for (auto& comm : communicators_) {
288 if (comm->num_devices == collective->num_global_devices) {
289 int i;
290 for (i = 0; i < collective->num_local_devices; ++i) {
291 if (comm->members[i].nccl_stream->executor !=
292 collective->participants[i]->executor) {
293 break;
294 }
295 }
296 if (i == collective->num_local_devices) {
297 *communicator = comm.get();
298 return Status::OK();
299 }
300 }
301 }
302 } else {
303#if NCCL_MAJOR < 2
304 return errors::Internal(
305 "Cannot use multi-node NCCL collectives with NCCL 1.x");
306#endif
307 if (collective->communicator_key.size() != NCCL_UNIQUE_ID_BYTES) {
308 return errors::Internal("Expected communicator_key of size ",

Callers

nothing calls this directly

Calls 15

sortFunction · 0.85
InternalFunction · 0.85
DefaultFunction · 0.85
nccl_streamMethod · 0.80
StringToNcclUniqueIdFunction · 0.70
beginMethod · 0.45
endMethod · 0.45
emptyMethod · 0.45
getMethod · 0.45
sizeMethod · 0.45
insertMethod · 0.45
resetMethod · 0.45

Tested by

no test coverage detected