in tensorpipe/transport/uv/utility.cc [138:215]
std::tuple<Error, std::string> lookupAddrLikeNccl(
optional<sa_family_t> familyFilter) {
int rv;
InterfaceAddresses addresses;
int count;
std::tie(rv, addresses, count) = getInterfaceAddresses();
if (rv < 0) {
return std::make_tuple(TP_CREATE_ERROR(UVError, rv), std::string());
}
// Libuv already only returns the interfaces that are up and running, whose
// address is not null, and whose family is IPv4 or IPv6.
// NCCL prioritizes the interfaces whose name starts with "ib" (for IP over
// InfiniBand?), and deprioritizes those that start with "docker" or "lo".
optional<std::string> withIbPrefix;
optional<std::string> withoutPrefix;
optional<std::string> withDockerPrefix;
optional<std::string> withLoPrefix;
for (auto i = 0; i < count; i++) {
const uv_interface_address_t& interface = addresses[i];
const struct sockaddr* sockaddr =
reinterpret_cast<const struct sockaddr*>(&interface.address);
// NCCL also seems to ignore any IPv6 loopback address.
if (sockaddr->sa_family == AF_INET6 && interface.is_internal) {
continue;
}
if (familyFilter.has_value() &&
sockaddr->sa_family != familyFilter.value()) {
continue;
}
std::string addr;
switch (sockaddr->sa_family) {
case AF_INET:
addr = Sockaddr(sockaddr, sizeof(struct sockaddr_in)).str();
break;
case AF_INET6:
addr = Sockaddr(sockaddr, sizeof(struct sockaddr_in6)).str();
break;
}
std::string name = interface.name;
if (name.find("ib") == 0) {
if (!withIbPrefix.has_value()) {
withIbPrefix = std::move(addr);
}
} else if (name.find("docker") == 0) {
if (!withDockerPrefix.has_value()) {
withDockerPrefix = std::move(addr);
}
} else if (name.find("lo") == 0) {
if (!withLoPrefix.has_value()) {
withLoPrefix = std::move(addr);
}
} else {
if (!withoutPrefix.has_value()) {
withoutPrefix = std::move(addr);
}
}
}
if (withIbPrefix.has_value()) {
return std::make_tuple(Error::kSuccess, std::move(withIbPrefix).value());
} else if (withoutPrefix.has_value()) {
return std::make_tuple(Error::kSuccess, std::move(withoutPrefix).value());
} else if (withDockerPrefix.has_value()) {
return std::make_tuple(
Error::kSuccess, std::move(withDockerPrefix).value());
} else if (withLoPrefix.has_value()) {
return std::make_tuple(Error::kSuccess, std::move(withLoPrefix).value());
}
return std::make_tuple(TP_CREATE_ERROR(NoAddrFoundError), std::string());
}