1
- // Copyright 2021-2022 Intel Corporation. All Rights Reserved.
1
+ // Copyright 2021-2023 Intel Corporation. All Rights Reserved.
2
2
//
3
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
4
// you may not use this file except in compliance with the License.
@@ -39,13 +39,16 @@ import (
39
39
"errors"
40
40
"flag"
41
41
"fmt"
42
- "golang.org/x/sys/unix"
43
42
"io/fs"
44
43
"log"
45
44
"math"
46
45
"os"
46
+ "strings"
47
+
48
+ "golang.org/x/sys/unix"
47
49
)
48
50
51
+ // https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
49
52
const (
50
53
dirMode = 0775
51
54
fileMode = 0644
@@ -56,11 +59,11 @@ const (
56
59
devfsPath = "dev"
57
60
mib = 1024.0 * 1024.0
58
61
// null device major, minor on linux.
59
- devNullMajor = 1
60
- devNullMinor = 3
61
- devNullType = unix .S_IFCHR
62
- maxNfdLileLen = 63
63
- fullyConnected = "FULL"
62
+ devNullMajor = 1
63
+ devNullMinor = 3
64
+ devNullType = unix .S_IFCHR
65
+ maxK8sLabelSize = 63
66
+ fullyConnected = "FULL"
64
67
)
65
68
66
69
var verbose bool
@@ -79,6 +82,11 @@ type genOptions struct {
79
82
devs int
80
83
}
81
84
85
+ func min (val1 int , val2 int ) int {
86
+ // TODO replace this with template version of Min(), once Golang standard library gets one
87
+ return int (math .Min (float64 (val1 ), float64 (val2 )))
88
+ }
89
+
82
90
func addSysfsDriTree (root string , opts * genOptions , i int ) error {
83
91
card := cardBase + i
84
92
base := fmt .Sprintf ("%s/class/drm/card%d" , root , card )
@@ -240,7 +248,7 @@ func generateDriFiles(opts genOptions) {
240
248
log .Printf ("Generating fake DRI device(s) sysfs, debugfs and devfs content under '%s' & '%s'" ,
241
249
sysfsPath , devfsPath )
242
250
243
- makeXelinkSideCar (opts .Capabilities ["xelink -topology" ], opts .DevCount , opts .TilesPerDev , opts .Capabilities ["xelink-topology " ])
251
+ makeXelinkSideCar (opts .Capabilities ["connection -topology" ], opts .DevCount , opts .TilesPerDev , opts .Capabilities ["connections " ])
244
252
245
253
opts .dirs , opts .files = 0 , 0
246
254
for i := 0 ; i < opts .DevCount ; i ++ {
@@ -306,76 +314,57 @@ func getOptions(name string) genOptions {
306
314
return opts
307
315
}
308
316
309
- func makeXelinkSideCar (topology string , gpus int , tiles int , connections string ) {
317
+ func makeXelinkSideCar (topology string , gpus , tiles int , connections string ) {
310
318
if topology != fullyConnected {
311
- log .Printf ("XELINK: generate xelink sidecar label file, using (GPUs: %d, Tiles: %d, Connections: %s )" , gpus , tiles , connections )
319
+ log .Printf ("XELINK: generate xelink sidecar label file, using (GPUs: %d, Tiles: %d)" , gpus , tiles )
312
320
} else {
313
321
log .Printf ("XELINK: generate xelink sidecar label file, using (GPUs: %d, Tiles: %d, Topology: %s)" , gpus , tiles , topology )
314
322
}
315
323
316
- smap := ""
317
-
318
324
if topology == fullyConnected {
319
- // create 2d slice with zeros
320
- var cmap = make ([][]int , 0 )
321
-
322
- var total = gpus * tiles
325
+ saveSideCarFile (buildConnectionList (gpus , tiles ))
326
+ } else {
327
+ saveSideCarFile (connections )
328
+ }
329
+ }
323
330
324
- for y := 0 ; y < total ; y ++ {
325
- var xmap = make ([] int , 0 )
331
+ func buildConnectionList ( gpus , tiles int ) string {
332
+ mm := 0
326
333
327
- for x := 0 ; x < total ; x ++ {
328
- if x != y {
329
- xmap = append (xmap , 1 )
330
- } else {
331
- xmap = append (xmap , 0 )
332
- }
333
- }
334
+ var nodes = make ([]string , 0 )
334
335
335
- cmap = append (cmap , [][]int {xmap }... )
336
+ for mm < gpus {
337
+ nn := 0
338
+ for nn < tiles {
339
+ nodes = append (nodes , fmt .Sprintf ("%d.%d" , mm , nn ))
340
+ nn ++
336
341
}
342
+ mm ++
343
+ }
337
344
338
- // filter double connections
339
- for y := 0 ; y < total ; y ++ {
340
- for x := 0 ; x < total ; x ++ {
341
- if cmap [y ][x ] == cmap [x ][y ] {
342
- cmap [x ][y ] = 0
343
- }
344
- }
345
- }
345
+ var links = make (map [string ]struct {}, 0 )
346
346
347
- // make connection string
348
- smap = buildConnectionList (gpus , tiles , cmap )
349
- } else {
350
- smap = connections
351
- }
347
+ var smap = make ([]string , 0 )
352
348
353
- saveSideCarFile (smap )
354
- }
349
+ for _ , from := range nodes {
350
+ for _ , to := range nodes {
351
+ // no self links, TODO ignore in-gpu xelinks
352
+ if to == from {
353
+ continue
354
+ }
355
355
356
- func buildConnectionList (gpus int , tiles int , cmap [][]int ) string {
357
- smap := ""
356
+ link := fmt .Sprintf ("%s-%s" , to , from )
358
357
359
- for gpuy := 0 ; gpuy < gpus ; gpuy ++ {
360
- for tiley := 0 ; tiley < tiles ; tiley ++ {
361
- y := gpuy * tiles + tiley
358
+ reverselink := fmt . Sprintf ( "%s-%s" , from , to )
359
+ if _ , exists := links [ reverselink ]; ! exists {
360
+ links [ link ] = struct {}{}
362
361
363
- for gpux := 0 ; gpux < gpus ; gpux ++ {
364
- for tilex := 0 ; tilex < tiles ; tilex ++ {
365
- x := gpux * tiles + tilex
366
- if cmap [y ][x ] == 1 {
367
- smap = fmt .Sprintf ("%s_%d.%d-%d.%d" , smap , gpuy , tiley , gpux , tilex )
368
- }
369
- }
362
+ smap = append (smap , link )
370
363
}
371
364
}
372
365
}
373
366
374
- if smap != "" {
375
- smap = smap [1 :]
376
- }
377
-
378
- return smap
367
+ return fmt .Sprintf ("%s\n " , strings .Join (smap , "_" ))
379
368
}
380
369
381
370
func saveSideCarFile (connections string ) {
@@ -385,32 +374,36 @@ func saveSideCarFile(connections string) {
385
374
}
386
375
defer f .Close ()
387
376
388
- if len (connections ) > maxNfdLileLen {
389
- line := fmt .Sprintf ("xpumanager.intel.com/xe-links=%s" , connections [: maxNfdLileLen ] )
377
+ if len (connections ) <= maxK8sLabelSize {
378
+ line := fmt .Sprintf ("xpumanager.intel.com/xe-links=%s" , connections )
390
379
fmt .Println (line )
391
380
392
381
if _ , err := f .WriteString (line + "\n " ); err != nil {
393
382
panic (err )
394
383
}
395
384
396
- index := 2
385
+ return
386
+ }
387
+
388
+ // Write first line without Z prefix
389
+ line := fmt .Sprintf ("xpumanager.intel.com/xe-links=%s" , connections [:maxK8sLabelSize ])
390
+ fmt .Println (line )
397
391
398
- for i := maxNfdLileLen ; i < len ( connections ); i += ( maxNfdLileLen - 1 ) {
399
- line := fmt . Sprintf ( "xpumanager.intel.com/xe-links%d=Z%s" , index , connections [ i : int ( math . Min ( float64 ( len ( connections )), float64 ( i + maxNfdLileLen - 1 )))] )
400
- fmt . Println ( line )
392
+ if _ , err := f . WriteString ( line + " \n " ); err != nil {
393
+ panic ( err )
394
+ }
401
395
402
- if _ , err := f .WriteString (line + "\n " ); err != nil {
403
- panic (err )
404
- }
405
- index ++
406
- }
407
- } else {
408
- line := fmt .Sprintf ("xpumanager.intel.com/xe-links=%s" , connections [:int (math .Min (float64 (len (connections )), float64 (maxNfdLileLen )))])
396
+ index := 2
397
+
398
+ // Write next lines with Z prefix
399
+ for i := maxK8sLabelSize ; i < len (connections ); i += (maxK8sLabelSize - 1 ) {
400
+ line := fmt .Sprintf ("xpumanager.intel.com/xe-links%d=Z%s" , index , connections [i :min (len (connections ), i + maxK8sLabelSize - 1 )])
409
401
fmt .Println (line )
410
402
411
403
if _ , err := f .WriteString (line + "\n " ); err != nil {
412
404
panic (err )
413
405
}
406
+ index ++
414
407
}
415
408
}
416
409
0 commit comments