Skip to content

[tsuji] 読み進めメモ #3

@tyohei

Description

@tyohei

疑問

  • ncclAsyncMode とは
  • Channel とは
  • opCount とは
  • devComm とは → comm との違い
  • ``llmode` とは
  • NCCL_MAX_OPS とは

AllReduce の動作

AllReduce の main

ncclEnqueueCheck enqueue.cc#L409

  • IF ncclAsyncModel
  • ELSE
    • ArgsCheck(info)
    • saveKernel(info)
    • ncclBarrierEnqueue(info->comm)
    • ncclBarrierEnqueueWait(info->comm)
    • ncclEnqueueEvents(info->comm)

saveKernel(info) enqueue.cc#L356

  • computeColl(info, &coll, &proxyArgs) → 何をしている?
  • blockDim.x を指定 → 何をしている?
  • cudaStream 指定
  • for (int bid=0; bid<coll.args.nChannels, bid++)

For 文の中身

まだ良くわからない

  • Block ID ごとにループを回している?
  • ループが回る回数は nChannels だけ → 何を意味している?

computeColl(info, &coll, &proxyArgs)

  1. info から coll へ情報(root, count, send/recv buffers, devComm, opCount)をコピー
  2. info から proxyArgs へ情報(nsteps, sliceSteps, chunkSteps, llMode, opCount)を計算及びコピー
  • その際に llMode or treeMode を判定している → これらの違いは?
  • llMode の意味は?
  • sliceSteps の意味は?
  • chunkSteps の意味は?

ncclBarrierEnqueue(info->comm)

基本的には User stream (nccl の通信を呼び出すストリーミ?、デフォルトストリーミかな)、とパラメータで指定されたストリーム(グループの場合もある)の違いによって、 cudaStreamWaitEvent を呼び出すようになっている

  • ncclCpuBarrierIn → わからない
  • ncclCpuBarrierLast → わからない

このあとに if(isLast) があるので、intra のプロセスを待ち、最後のプロセスが処理をするようになっている

    if (comm->launchMode == ncclComm::GROUP) {
      // I'm the last. Launch all operations.
      NCCLCHECK(ncclLaunchCooperativeKernelMultiDevice(comm->intraParams, comm->intraCudaDevs, comm->intraRanks, *comm-
    }
    NCCLCHECK(ncclCpuBarrierLast(comm));

こんな処理


ncclBarrierEnqueueWait(info->comm)

  • ncclCpuBarrierOut(comm)
  • launchMode == GROUP の場合は ncclBarrierEnqueue でカーネルが呼びされていだが、 PARALLEL の場合はここで呼び出される
  • comm->channels に格納されている各 channel に対して次の二つのを定義
    • collStart = channel->collFifiTail
    • collCount = 0
  • NCCLCHECK(transportStartProxy(comm));

// Start the network proxies as soon as the kernel has been launched. We can't
// perform any CUDA call between the two or having a cudaFree between the CUDA
// launch and the transportStartProxy call could cause a deadlock.
// Also, starting the proxies after the CUDA launch seems to be better for
// performance (latency).


ncclEnqueueEvents(comm)

必要ならストリームを待つのと、 userStreamSet を初期化する

けっこう単純な関数

ncclResult_t ncclEnqueueEvents(ncclComm_t comm) {
  struct cudaLaunchParams *params = comm->myParams;
  // Enqueue event after NCCL kernel
  CUDACHECK(cudaEventRecord(comm->doneEvent, params->stream));
  // Use internal NCCL stream for CGMD/GROUP launch if required or if the user stream is NULL
  if (comm->launchMode == ncclComm::GROUP && (comm->groupCudaStream || comm->userStream == NULL)) {
    // Create dependency between NCCL internal stream and user stream
    CUDACHECK(cudaStreamWaitEvent(comm->userStream, comm->doneEvent, 0));
  }
  comm->userStreamSet = false;
  return ncclSuccess;
}

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions