net_utils.cpp 3.37 KB
Newer Older
lishen's avatar
lishen committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "net_utils.h"

namespace sccl {
namespace hardware {
namespace net {

/**
 * 解析网络接口字符串列表
 *
 * @param string 输入字符串,格式为"前缀:端口,前缀:端口,..."
 * @param ifList 存储解析结果的网络接口数组
 * @param maxList 最大可解析的接口数量
 * @return 实际解析出的接口数量
 *
 * 功能说明:
 * 将形如"eth0:1234,ib0:5678"的字符串解析为网络接口结构体数组。
 * 每个接口包含前缀和端口号,未指定端口时设为-1。
 * 遇到maxList限制或字符串结束时停止解析。
 */
int parseStringList(const char* string, struct netIf* ifList, int maxList) {
    if(!string)
        return 0;

    const char* ptr = string;

    int ifNum = 0;
    int ifC   = 0;
    char c;
    do {
        c = *ptr;
        if(c == ':') {
            if(ifC > 0) {
                ifList[ifNum].prefix[ifC] = '\0';
                ifList[ifNum].port        = atoi(ptr + 1);
                ifNum++;
                ifC = 0;
            }
            while(c != ',' && c != '\0')
                c = *(++ptr);
        } else if(c == ',' || c == '\0') {
            if(ifC > 0) {
                ifList[ifNum].prefix[ifC] = '\0';
                ifList[ifNum].port        = -1;
                ifNum++;
                ifC = 0;
            }
        } else {
            ifList[ifNum].prefix[ifC] = c;
            ifC++;
        }
        ptr++;
    } while(ifNum < maxList && c);
    return ifNum;
}

static bool matchIf(const char* string, const char* ref, bool matchExact) {
    // Make sure to include '\0' in the exact case
    int matchLen = matchExact ? strlen(string) + 1 : strlen(ref);
    return strncmp(string, ref, matchLen) == 0;
}

static bool matchPort(const int port1, const int port2) {
    if(port1 == -1)
        return true;
    if(port2 == -1)
        return true;
    if(port1 == port2)
        return true;
    return false;
}

/**
 * 检查给定的字符串和端口是否匹配网络接口列表中的任意一项
 *
 * @param string 待匹配的字符串
 * @param port 待匹配的端口号
 * @param ifList 网络接口列表
 * @param listSize 网络接口列表大小
 * @param matchExact 是否要求精确匹配
 * @return 如果匹配成功返回true,否则返回false
 * @note 当listSize为0时,默认返回true
 */
bool matchIfList(const char* string, int port, struct netIf* ifList, int listSize, bool matchExact) {
    // Make an exception for the case where no user list is defined
    if(listSize == 0)
        return true;

    for(int i = 0; i < listSize; i++) {
        if(matchIf(string, ifList[i].prefix, matchExact) && matchPort(port, ifList[i].port)) {
            return true;
        }
    }
    return false;
}

100
scclResult_t printNetProps(const scclNetProperties_t* props, int rank, int localRank) {
101
    printf("rank=%d, localRank=%d, device name=%s, pciPath=%s, guid=%lu, ptrSupport=%u, speed=%d, port=%d, latency=%f, maxComms=%d, maxRecvs=%d\n",
102
103
104
105
106
           rank,
           localRank,
           props->name,
           props->pciPath,
           props->guid,
107
           static_cast<unsigned int>(props->ptrSupport),
108
109
110
111
112
113
114
115
           props->speed,
           props->port,
           props->latency,
           props->maxComms,
           props->maxRecvs);
    return scclSuccess;
}

lishen's avatar
lishen committed
116
117
118
} // namespace net
} // namespace hardware
} // namespace sccl