in tensorpipe/channel/cuda_gdr/channel_impl.cc [213:280]
void ChannelImpl::advanceSendOperation(
SendOpIter opIter,
SendOperation::State prevOpState) {
TP_DCHECK(context_->inLoop());
SendOperation& op = *opIter;
sendOps_.attemptTransition(
opIter,
/*from=*/SendOperation::UNINITIALIZED,
/*to=*/SendOperation::FINISHED,
/*cond=*/error_ || op.length == 0,
/*actions=*/{&ChannelImpl::callSendCallback});
// Needs to go after previous op to ensure predictable and consistent ordering
// of write calls on the descriptor control connection and read calls on the
// completion control connection.
sendOps_.attemptTransition(
opIter,
/*from=*/SendOperation::UNINITIALIZED,
/*to=*/SendOperation::READING_READY_TO_RECEIVE,
/*cond=*/!error_ && state_ == ESTABLISHED &&
prevOpState >= SendOperation::READING_READY_TO_RECEIVE,
/*actions=*/
{&ChannelImpl::writeDescriptor, &ChannelImpl::readReadyToReceive});
sendOps_.attemptTransition(
opIter,
/*from=*/SendOperation::READING_READY_TO_RECEIVE,
/*to=*/SendOperation::FINISHED,
/*cond=*/error_ && op.doneReadingReadyToReceive,
/*actions=*/{&ChannelImpl::callSendCallback});
// This doesn't strictly need to go after the previous op, but it doesn't make
// sense to busy poll multiple events if only one of them is actually able to
// then make progress.
sendOps_.attemptTransition(
opIter,
/*from=*/SendOperation::READING_READY_TO_RECEIVE,
/*to=*/SendOperation::WAITING_FOR_CUDA_EVENT,
/*cond=*/!error_ && op.doneReadingReadyToReceive &&
prevOpState >= SendOperation::SENDING_OVER_IB,
/*actions=*/{&ChannelImpl::waitForSendCudaEvent});
sendOps_.attemptTransition(
opIter,
/*from=*/SendOperation::WAITING_FOR_CUDA_EVENT,
/*to=*/SendOperation::FINISHED,
/*cond=*/error_ && op.doneWaitingForCudaEvent,
/*actions=*/{&ChannelImpl::callSendCallback});
// Needs to go after previous op to ensure predictable and consistent ordering
// of send calls on InfiniBand queue pair.
sendOps_.attemptTransition(
opIter,
/*from=*/SendOperation::WAITING_FOR_CUDA_EVENT,
/*to=*/SendOperation::SENDING_OVER_IB,
/*cond=*/!error_ && op.doneWaitingForCudaEvent &&
prevOpState >= SendOperation::SENDING_OVER_IB,
/*actions=*/{&ChannelImpl::sendOverIb});
sendOps_.attemptTransition(
opIter,
/*from=*/SendOperation::SENDING_OVER_IB,
/*to=*/SendOperation::FINISHED,
/*cond=*/op.numChunksBeingSent == 0,
/*actions=*/{&ChannelImpl::callSendCallback});
}