2.21.5-1
Add support for IB SHARP 1PPN operation with user buffers. Improve support for MNNVL, add NVLS support and multi-clique support. * Detect the NVLS clique through NVML * Exchange XML between peers in the same NVLS clique and fuse XMLs before creating the topology graph. * Rework bootstrap allgather algorithms to allow for large allgather operations intra-node (XML exchange). Net/IB: add support for dynamic GID detection. * Automatically select RoCEv2/IPv4 interface by default. Allow to select IPv6 or even the network/mask. Reduce NVLS memory usage. * Add stepSize as property of a connection to allow for different sizes on different peers; set it to 128K for NVLink SHARP. Improve tuner loading * Look for more paths, be more consistent with the network device plugin. * Also search for tuner support inside the net plugin. Improve tuner API * Add context to support multi-device per process. Add magic number around comm object to detect comm corruption. * Add some basic check around communicators so that we can report a problem when a communicator gets corrupted or a wrong comm pointer is passed to NCCL. Fix net/IB error path. Github PR #1164 Fix collnet rail mapping with split comm. Fix packet reordering issue causing bootstrap mismatch * Use a different tag in ncclTransportP2pSetup for the connectInfo exchange and the following barrier. Fix hang when crossNic is inconsistent between ranks. Fix minCompCap/maxCompCap computation. Github issue #1184
Αυτή η υποβολή περιλαμβάνεται σε:
1 γονέας
6dd51f15bf
υποβολή
ab2b89c4c3
52 files changed
+2124
-944
No files matched your search
+86
-3
@@ -172,8 +172,8 @@ struct xmlHandler {
|
||||
ncclResult_t xmlLoadSub(FILE* file, struct ncclXml* xml, struct ncclXmlNode* head, struct xmlHandler handlers[], int nHandlers) {
|
||||
if (head && head->type == NODE_TYPE_SINGLE) return ncclSuccess;
|
||||
while (1) {
|
||||
if (xml->maxIndex == MAX_NODES) {
|
||||
WARN("Error : XML parser is limited to 1024 nodes");
|
||||
if (xml->maxIndex == xml->maxNodes) {
|
||||
WARN("Error : XML parser is limited to %d nodes", xml->maxNodes);
|
||||
return ncclInternalError;
|
||||
}
|
||||
struct ncclXmlNode* node = xml->nodes+xml->maxIndex;
|
||||
@@ -198,7 +198,13 @@ ncclResult_t xmlLoadSub(FILE* file, struct ncclXml* xml, struct ncclXmlNode* hea
|
||||
int found = 0;
|
||||
for (int h=0; h<nHandlers; h++) {
|
||||
if (strcmp(node->name, handlers[h].name) == 0) {
|
||||
if (head) head->subs[head->nSubs++] = node;
|
||||
if (head) {
|
||||
if (head->nSubs == MAX_SUBS) {
|
||||
WARN("Error : XML parser is limited to %d subnodes", MAX_SUBS);
|
||||
return ncclInternalError;
|
||||
}
|
||||
head->subs[head->nSubs++] = node;
|
||||
}
|
||||
node->parent = head;
|
||||
node->nSubs = 0;
|
||||
xml->maxIndex++;
|
||||
@@ -218,6 +224,23 @@ ncclResult_t xmlLoadSub(FILE* file, struct ncclXml* xml, struct ncclXmlNode* hea
|
||||
/* XML Writer */
|
||||
/**************/
|
||||
|
||||
// exp == 1 -- serialize; exp == 0 -- deserialize
|
||||
ncclResult_t ncclTopoConvertXml(struct ncclXml* xml, uintptr_t base, int exp) {
|
||||
for (int n = 0; n < xml->maxIndex; n++) {
|
||||
struct ncclXmlNode *node = &xml->nodes[n];
|
||||
|
||||
// For "parent", we shift the base by 1 so that we can distinguish actual
|
||||
// NULL pointers from pointers pointing to the first node.
|
||||
if (node->parent)
|
||||
node->parent = (struct ncclXmlNode *) (exp ? ((uintptr_t)node->parent - base + 1) : (base - 1 + (uintptr_t)node->parent));
|
||||
|
||||
for (int s = 0; s < node->nSubs; s++) {
|
||||
node->subs[s] = (struct ncclXmlNode *) (exp ? ((uintptr_t)node->subs[s] - base) : (base + (uintptr_t)node->subs[s]));
|
||||
}
|
||||
}
|
||||
return ncclSuccess;
|
||||
}
|
||||
|
||||
ncclResult_t ncclTopoDumpXmlRec(int indent, FILE* file, struct ncclXmlNode* node) {
|
||||
for (int i=0; i<indent; i++) fprintf(file, " ");
|
||||
fprintf(file, "<%s", node->name);
|
||||
@@ -249,6 +272,60 @@ ncclResult_t ncclTopoDumpXmlToFile(const char* xmlTopoFile, struct ncclXml* xml)
|
||||
return ncclSuccess;
|
||||
}
|
||||
|
||||
ncclResult_t ncclTopoFuseXml(struct ncclXml* dst, struct ncclXml* src) {
|
||||
struct ncclXmlNode* topNode;
|
||||
NCCLCHECK(xmlFindTag(dst, "system", &topNode));
|
||||
|
||||
if (topNode == NULL) {
|
||||
xmlAddTree(dst, NULL, src->nodes);
|
||||
return ncclSuccess;
|
||||
}
|
||||
|
||||
// Fuse the CPUs with the first XML
|
||||
struct ncclXmlNode* srcCpu;
|
||||
NCCLCHECK(xmlFindTag(src, "cpu", &srcCpu));
|
||||
while (srcCpu) {
|
||||
const char* srcNumaId;
|
||||
const char* srcHostHash;
|
||||
NCCLCHECK(xmlGetAttr(srcCpu, "numaid", &srcNumaId));
|
||||
if (srcNumaId == NULL) {
|
||||
WARN("TopoFuseXmls : could not find CPU numa ID.");
|
||||
return ncclInternalError;
|
||||
}
|
||||
xmlGetAttr(srcCpu, "host_hash", &srcHostHash);
|
||||
if (srcHostHash == NULL)
|
||||
srcHostHash = "0";
|
||||
|
||||
// Search through the destination for a duplicate. Note that
|
||||
// this makes the complexity of this whole function O(n^2), but n
|
||||
// is expected to be small.
|
||||
struct ncclXmlNode* dstCpu;
|
||||
NCCLCHECK(xmlFindTag(dst, "cpu", &dstCpu));
|
||||
while (dstCpu) {
|
||||
const char* dstNumaId;
|
||||
const char* dstHostHash;
|
||||
NCCLCHECK(xmlGetAttr(dstCpu, "numaid", &dstNumaId));
|
||||
if (dstNumaId == NULL) {
|
||||
WARN("TopoFuseXmls : could not find CPU numa ID.");
|
||||
return ncclInternalError;
|
||||
}
|
||||
xmlGetAttr(dstCpu, "host_hash", &dstHostHash);
|
||||
if (dstHostHash == NULL)
|
||||
dstHostHash = "0";
|
||||
if (strcmp(srcNumaId, dstNumaId) == 0 && strcmp(srcHostHash, dstHostHash) == 0)
|
||||
break;
|
||||
|
||||
NCCLCHECK(xmlFindNextTag(dst, "cpu", dstCpu, &dstCpu));
|
||||
}
|
||||
// Only add the CPU if no duplicate was found
|
||||
if (dstCpu == NULL)
|
||||
NCCLCHECK(xmlAddTree(dst, topNode, srcCpu));
|
||||
NCCLCHECK(xmlFindNextTag(src, "cpu", srcCpu, &srcCpu));
|
||||
}
|
||||
return ncclSuccess;
|
||||
}
|
||||
|
||||
|
||||
/****************************************/
|
||||
/* Parser rules for our specific format */
|
||||
/****************************************/
|
||||
@@ -556,6 +633,7 @@ ncclResult_t ncclTopoGetXmlFromSys(struct ncclXmlNode* pciNode, struct ncclXml*
|
||||
NCCLCHECK(xmlGetSubKv(topNode, "cpu", &parent, "numaid", numaIdStr));
|
||||
if (parent == NULL) {
|
||||
NCCLCHECK(xmlAddNode(xml, topNode, "cpu", &parent));
|
||||
NCCLCHECK(xmlSetAttrLong(parent, "host_hash", getHostHash()));
|
||||
NCCLCHECK(xmlSetAttr(parent, "numaid", numaIdStr));
|
||||
}
|
||||
} else if (slashCount == 2) {
|
||||
@@ -581,6 +659,7 @@ ncclResult_t ncclTopoGetXmlFromSys(struct ncclXmlNode* pciNode, struct ncclXml*
|
||||
struct ncclXmlNode* topNode;
|
||||
NCCLCHECK(xmlFindTag(xml, "system", &topNode));
|
||||
NCCLCHECK(xmlAddNode(xml, topNode, "cpu", &parent));
|
||||
NCCLCHECK(xmlSetAttrLong(parent, "host_hash", getHostHash()));
|
||||
NCCLCHECK(xmlSetAttr(parent, "numaid", "-1"));
|
||||
NCCLCHECK(ncclTopoGetXmlFromCpu(parent, xml));
|
||||
}
|
||||
@@ -595,6 +674,10 @@ ncclResult_t ncclTopoGetXmlFromSys(struct ncclXmlNode* pciNode, struct ncclXml*
|
||||
NCCLCHECK(xmlGetAttr(parent->subs[s], "busid", &busId));
|
||||
if (busId != NULL && strcmp(newBusId, busId) < 0) { subIndex = s; break; }
|
||||
}
|
||||
if (parent->nSubs == MAX_SUBS) {
|
||||
WARN("Error : XML parser is limited to %d subnodes", MAX_SUBS);
|
||||
return ncclInternalError;
|
||||
}
|
||||
for (int s = parent->nSubs; s > subIndex; s--) parent->subs[s] = parent->subs[s-1];
|
||||
parent->subs[subIndex] = pciNode;
|
||||
parent->nSubs++;
|
||||
|
||||
Reference in new issue
Block a user