/************************************************************************* * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved. * * See LICENSE.txt for license information ************************************************************************/ #include "core.h" namespace sccl { namespace hardware { namespace topology { namespace detect { #define MAXWIDTH 20 #define PREFIXLEN 15 #define STRLENGTH (PREFIXLEN + 5 * MAXWIDTH) void dumpLine(int* values, int nranks, const char* prefix) { int prefixlen = strlen(prefix); char line[STRLENGTH + 1]; line[STRLENGTH] = '\0'; memset(line, ' ', STRLENGTH); strncpy(line, prefix, PREFIXLEN); for(int i = 0; i < nranks && i < MAXWIDTH; i++) sprintf(line + prefixlen + 4 * i, " %3d", values[i]); INFO(SCCL_INIT, "%s", line); } scclResult_t scclBuildRings(int nrings, int* rings, int rank, int nranks, int* prev, int* next) { for(int r = 0; r < nrings; r++) { char prefix[40]; /*sprintf(prefix, "[%d] Channel %d Prev : ", rank, r); dumpLine(prev+r*nranks, nranks, prefix); sprintf(prefix, "[%d] Channel %d Next : ", rank, r); dumpLine(next+r*nranks, nranks, prefix);*/ int current = rank; for(int i = 0; i < nranks; i++) { rings[r * nranks + i] = current; current = next[r * nranks + current]; } sprintf(prefix, "Channel %02d/%02d : ", r, nrings); if(rank == 0) dumpLine(rings + r * nranks, nranks, prefix); if(current != rank) { WARN("Error : ring %d does not loop back to start (%d != %d)", r, current, rank); return scclInternalError; } // Check that all ranks are there for(int i = 0; i < nranks; i++) { int found = 0; for(int j = 0; j < nranks; j++) { if(rings[r * nranks + j] == i) { found = 1; break; } } if(found == 0) { WARN("Error : ring %d does not contain rank %d", r, i); return scclInternalError; } } } return scclSuccess; } } // namespace detect } // namespace topology } // namespace hardware } // namespace sccl