Read NVLink and GPU-to-adapter distance from nvidia-smi topo
The release binary is built without cgo, so without NVML, and NVML was the only source of NVLink peers: on every NVLink machine the portable agent reported none, and tensor-parallel groups were chosen by GPU index. Discovery now reads `nvidia-smi topo -m` after either path, for the NVLink peers (kept from NVML where it gave them), each card's NUMA node, and how far each network adapter is from it - PIX, PXB, PHB, NODE or SYS - which travels to the control plane as nic_paths for placement to use. Both the NICn-with-legend layout of newer drivers and the adapter-named columns of older ones are read. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
22bb098247
commit
bf2d171e89
8 files changed
+363
-30
No files matched your search
@@ -933,8 +933,11 @@ type GPU struct {
|
||||
// Zero when the driver is too old to report it, which is not the same as
|
||||
// idle: the metric is simply absent rather than wrong.
|
||||
UtilizationPercent int32 `protobuf:"varint,15,opt,name=utilization_percent,json=utilizationPercent,proto3" json:"utilization_percent,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
// nic_paths is how far each network adapter is from this card, by HCA
|
||||
// name: PIX, PXB, PHB, NODE or SYS, from nvidia-smi topo.
|
||||
NicPaths map[string]string `protobuf:"bytes,16,rep,name=nic_paths,json=nicPaths,proto3" json:"nic_paths,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *GPU) Reset() {
|
||||
@@ -1072,6 +1075,13 @@ func (x *GPU) GetUtilizationPercent() int32 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *GPU) GetNicPaths() map[string]string {
|
||||
if x != nil {
|
||||
return x.NicPaths
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type FabricAttachment struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
// fabric is the operator-assigned name. It is not derived from the GID
|
||||
@@ -2604,7 +2614,7 @@ const file_llmgw_v1_agent_proto_rawDesc = "" +
|
||||
"\vleader_port\x18\x0e \x01(\x05R\n" +
|
||||
"leaderPort\x12\x1d\n" +
|
||||
"\n" +
|
||||
"profile_fp\x18\x0f \x01(\tR\tprofileFp\"\xf9\x03\n" +
|
||||
"profile_fp\x18\x0f \x01(\tR\tprofileFp\"\xf0\x04\n" +
|
||||
"\x03GPU\x12\x14\n" +
|
||||
"\x05index\x18\x01 \x01(\x05R\x05index\x12\x12\n" +
|
||||
"\x04uuid\x18\x02 \x01(\tR\x04uuid\x12\x12\n" +
|
||||
@@ -2623,7 +2633,11 @@ const file_llmgw_v1_agent_proto_rawDesc = "" +
|
||||
"\rtemperature_c\x18\r \x01(\x05R\ftemperatureC\x12\x1d\n" +
|
||||
"\n" +
|
||||
"ecc_errors\x18\x0e \x01(\x05R\teccErrors\x12/\n" +
|
||||
"\x13utilization_percent\x18\x0f \x01(\x05R\x12utilizationPercent\"[\n" +
|
||||
"\x13utilization_percent\x18\x0f \x01(\x05R\x12utilizationPercent\x128\n" +
|
||||
"\tnic_paths\x18\x10 \x03(\v2\x1b.llmgw.v1.GPU.NicPathsEntryR\bnicPaths\x1a;\n" +
|
||||
"\rNicPathsEntry\x12\x10\n" +
|
||||
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
|
||||
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"[\n" +
|
||||
"\x10FabricAttachment\x12\x16\n" +
|
||||
"\x06fabric\x18\x01 \x01(\tR\x06fabric\x12\x12\n" +
|
||||
"\x04hcas\x18\x02 \x03(\tR\x04hcas\x12\x1b\n" +
|
||||
@@ -2783,7 +2797,7 @@ func file_llmgw_v1_agent_proto_rawDescGZIP() []byte {
|
||||
}
|
||||
|
||||
var file_llmgw_v1_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
|
||||
var file_llmgw_v1_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 29)
|
||||
var file_llmgw_v1_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 30)
|
||||
var file_llmgw_v1_agent_proto_goTypes = []any{
|
||||
(ShardStatus_State)(0), // 0: llmgw.v1.ShardStatus.State
|
||||
(*AgentMessage)(nil), // 1: llmgw.v1.AgentMessage
|
||||
@@ -2813,8 +2827,9 @@ var file_llmgw_v1_agent_proto_goTypes = []any{
|
||||
(*LogsReply)(nil), // 25: llmgw.v1.LogsReply
|
||||
nil, // 26: llmgw.v1.Register.LabelsEntry
|
||||
nil, // 27: llmgw.v1.Register.EngineVersionsEntry
|
||||
nil, // 28: llmgw.v1.Heartbeat.EngineVersionsEntry
|
||||
nil, // 29: llmgw.v1.EngineProfile.EnvEntry
|
||||
nil, // 28: llmgw.v1.GPU.NicPathsEntry
|
||||
nil, // 29: llmgw.v1.Heartbeat.EngineVersionsEntry
|
||||
nil, // 30: llmgw.v1.EngineProfile.EnvEntry
|
||||
}
|
||||
var file_llmgw_v1_agent_proto_depIdxs = []int32{
|
||||
3, // 0: llmgw.v1.AgentMessage.register:type_name -> llmgw.v1.Register
|
||||
@@ -2837,24 +2852,25 @@ var file_llmgw_v1_agent_proto_depIdxs = []int32{
|
||||
5, // 17: llmgw.v1.Register.storage:type_name -> llmgw.v1.Storage
|
||||
4, // 18: llmgw.v1.Register.host:type_name -> llmgw.v1.Host
|
||||
0, // 19: llmgw.v1.RunningShard.state:type_name -> llmgw.v1.ShardStatus.State
|
||||
11, // 20: llmgw.v1.NodeLoad.shards:type_name -> llmgw.v1.ShardLoad
|
||||
5, // 21: llmgw.v1.Heartbeat.storage:type_name -> llmgw.v1.Storage
|
||||
9, // 22: llmgw.v1.Heartbeat.weights:type_name -> llmgw.v1.LocalWeights
|
||||
28, // 23: llmgw.v1.Heartbeat.engine_versions:type_name -> llmgw.v1.Heartbeat.EngineVersionsEntry
|
||||
15, // 24: llmgw.v1.Heartbeat.provision:type_name -> llmgw.v1.ProvisionStatus
|
||||
10, // 25: llmgw.v1.Heartbeat.load:type_name -> llmgw.v1.NodeLoad
|
||||
14, // 26: llmgw.v1.Provision.engines:type_name -> llmgw.v1.EngineWant
|
||||
0, // 27: llmgw.v1.ShardStatus.state:type_name -> llmgw.v1.ShardStatus.State
|
||||
17, // 28: llmgw.v1.ShardStatus.fetch:type_name -> llmgw.v1.FetchProgress
|
||||
19, // 29: llmgw.v1.StartShard.profile:type_name -> llmgw.v1.EngineProfile
|
||||
29, // 30: llmgw.v1.EngineProfile.env:type_name -> llmgw.v1.EngineProfile.EnvEntry
|
||||
1, // 31: llmgw.v1.AgentService.Connect:input_type -> llmgw.v1.AgentMessage
|
||||
2, // 32: llmgw.v1.AgentService.Connect:output_type -> llmgw.v1.ControlMessage
|
||||
32, // [32:33] is the sub-list for method output_type
|
||||
31, // [31:32] is the sub-list for method input_type
|
||||
31, // [31:31] is the sub-list for extension type_name
|
||||
31, // [31:31] is the sub-list for extension extendee
|
||||
0, // [0:31] is the sub-list for field type_name
|
||||
28, // 20: llmgw.v1.GPU.nic_paths:type_name -> llmgw.v1.GPU.NicPathsEntry
|
||||
11, // 21: llmgw.v1.NodeLoad.shards:type_name -> llmgw.v1.ShardLoad
|
||||
5, // 22: llmgw.v1.Heartbeat.storage:type_name -> llmgw.v1.Storage
|
||||
9, // 23: llmgw.v1.Heartbeat.weights:type_name -> llmgw.v1.LocalWeights
|
||||
29, // 24: llmgw.v1.Heartbeat.engine_versions:type_name -> llmgw.v1.Heartbeat.EngineVersionsEntry
|
||||
15, // 25: llmgw.v1.Heartbeat.provision:type_name -> llmgw.v1.ProvisionStatus
|
||||
10, // 26: llmgw.v1.Heartbeat.load:type_name -> llmgw.v1.NodeLoad
|
||||
14, // 27: llmgw.v1.Provision.engines:type_name -> llmgw.v1.EngineWant
|
||||
0, // 28: llmgw.v1.ShardStatus.state:type_name -> llmgw.v1.ShardStatus.State
|
||||
17, // 29: llmgw.v1.ShardStatus.fetch:type_name -> llmgw.v1.FetchProgress
|
||||
19, // 30: llmgw.v1.StartShard.profile:type_name -> llmgw.v1.EngineProfile
|
||||
30, // 31: llmgw.v1.EngineProfile.env:type_name -> llmgw.v1.EngineProfile.EnvEntry
|
||||
1, // 32: llmgw.v1.AgentService.Connect:input_type -> llmgw.v1.AgentMessage
|
||||
2, // 33: llmgw.v1.AgentService.Connect:output_type -> llmgw.v1.ControlMessage
|
||||
33, // [33:34] is the sub-list for method output_type
|
||||
32, // [32:33] is the sub-list for method input_type
|
||||
32, // [32:32] is the sub-list for extension type_name
|
||||
32, // [32:32] is the sub-list for extension extendee
|
||||
0, // [0:32] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_llmgw_v1_agent_proto_init() }
|
||||
@@ -2883,7 +2899,7 @@ func file_llmgw_v1_agent_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_llmgw_v1_agent_proto_rawDesc), len(file_llmgw_v1_agent_proto_rawDesc)),
|
||||
NumEnums: 1,
|
||||
NumMessages: 29,
|
||||
NumMessages: 30,
|
||||
NumExtensions: 0,
|
||||
NumServices: 1,
|
||||
},
|
||||
|
||||
@@ -207,6 +207,9 @@ message GPU {
|
||||
// Zero when the driver is too old to report it, which is not the same as
|
||||
// idle: the metric is simply absent rather than wrong.
|
||||
int32 utilization_percent = 15;
|
||||
// nic_paths is how far each network adapter is from this card, by HCA
|
||||
// name: PIX, PXB, PHB, NODE or SYS, from nvidia-smi topo.
|
||||
map<string, string> nic_paths = 16;
|
||||
}
|
||||
|
||||
message FabricAttachment {
|
||||
|
||||
Reference in new issue
Block a user