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

Function BackgroundThreadLoop

tensorflow/contrib/mpi_collectives/mpi_ops.cc:574–796  ·  view source on GitHub ↗

The MPI background thread loop coordinates all the MPI processes and the tensor reductions. The design of the communicator mechanism is limited by a few considerations: 1. Some MPI implementations require all MPI calls to happen from a single thread. Since TensorFlow may use several threads for graph processing, this means we must have our own dedicated thread for dealing with MPI. 2. We want to

Source from the content-addressed store, hash-verified

572// background loop.
573// TODO: Use the global mpi_global state variable instead of a local one
574void BackgroundThreadLoop() {
575#if GOOGLE_CUDA
576 // Set the device, so that this thread uses the same GPU context as the
577 // calling thread.
578 // TODO: Ensure that this is operating correctly. The background thread
579 // needs to be able to control all GPUs that the rank has access to, and
580 // might be more than 1 GPU. Tensors could be resident in any of the
581 // GPUs, so the background thread's accumulate and copy kernels might need
582 // to correctly set the device and it might be necessary for the background
583 // thread to manage multiple streams.
584 cudaSetDevice(mpi_global.device);
585 cudaStreamCreate(&mpi_global.stream);
586#endif
587
588 // Initialize MPI. This must happen on the background thread, since not all
589 // MPI implementations support being called from multiple threads.
590 auto init_result = MPI_Init(NULL, NULL);
591 if (init_result != MPI_SUCCESS) {
592 mpi_global.init_status =
593 errors::Unknown("Could not initialize MPI; MPI_Init() failed.");
594 mpi_global.initialization_done = true;
595 mpi_global.cv.notify_all();
596 return;
597 } else {
598 mpi_global.init_status = Status::OK();
599 }
600
601 // Get MPI rank to determine if we are rank zero.
602 int rank;
603 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
604 bool is_coordinator = rank == 0;
605
606 // Get MPI size to determine how many tensors to wait for before reducing.
607 int size;
608 MPI_Comm_size(MPI_COMM_WORLD, &size);
609
610 // Determine local rank by querying the local communicator.
611 MPI_Comm local_comm;
612 MPI_Comm_split_type(MPI_COMM_WORLD, MPI_COMM_TYPE_SHARED, 0, MPI_INFO_NULL,
613 &local_comm);
614 int local_rank;
615 MPI_Comm_rank(local_comm, &local_rank);
616
617 mpi_global.rank = rank;
618 mpi_global.local_rank = local_rank;
619 mpi_global.size = size;
620 mpi_global.initialization_done = true;
621
622 // Notify calling thread that initialization is complete
623 mpi_global.cv.notify_all();
624
625 // TODO: MOVE MESSAGE TABLE INITIALIZATION TO LIBRARY LOAD!
626 // Initialize the tensor count table. No tensors are available yet.
627 if (is_coordinator) {
628 mpi_global.message_table =
629 std::unique_ptr<MessageTable>(new MessageTable());
630 }
631

Callers

nothing calls this directly

Calls 15

notify_allMethod · 0.80
c_strMethod · 0.80
IncrementTensorCountFunction · 0.70
ConstructMPIResponseFunction · 0.70
PerformCollectiveOpFunction · 0.70
UnknownFunction · 0.50
emptyMethod · 0.45
frontMethod · 0.45
popMethod · 0.45
pushMethod · 0.45
push_backMethod · 0.45
tensor_nameMethod · 0.45

Tested by

no test coverage detected