@@ -28,7 +28,9 @@ import (
2828
2929const (
3030 // AttributeMediaExtensions holds the string representation for the media extension MIG profile attribute.
31- AttributeMediaExtensions = "me"
31+ AttributeMediaExtensions = "me"
32+ AttributeMediaExtensionsAll = "me.all"
33+ AttributeGraphics = "gfx"
3234)
3335
3436// MigProfile represents a specific MIG profile.
@@ -46,6 +48,7 @@ type MigProfileInfo struct {
4648 G int
4749 GB int
4850 Attributes []string
51+ NegAttributes []string
4952 GIProfileID int
5053 CIProfileID int
5154 CIEngProfileID int
@@ -59,14 +62,21 @@ func (d *devicelib) NewMigProfile(giProfileID, ciProfileID, ciEngProfileID int,
5962 switch giProfileID {
6063 case nvml .GPU_INSTANCE_PROFILE_1_SLICE ,
6164 nvml .GPU_INSTANCE_PROFILE_1_SLICE_REV1 ,
62- nvml .GPU_INSTANCE_PROFILE_1_SLICE_REV2 :
65+ nvml .GPU_INSTANCE_PROFILE_1_SLICE_REV2 ,
66+ nvml .GPU_INSTANCE_PROFILE_1_SLICE_GFX ,
67+ nvml .GPU_INSTANCE_PROFILE_1_SLICE_NO_ME ,
68+ nvml .GPU_INSTANCE_PROFILE_1_SLICE_ALL_ME :
6369 giSlices = 1
6470 case nvml .GPU_INSTANCE_PROFILE_2_SLICE ,
65- nvml .GPU_INSTANCE_PROFILE_2_SLICE_REV1 :
71+ nvml .GPU_INSTANCE_PROFILE_2_SLICE_REV1 ,
72+ nvml .GPU_INSTANCE_PROFILE_2_SLICE_GFX ,
73+ nvml .GPU_INSTANCE_PROFILE_2_SLICE_NO_ME ,
74+ nvml .GPU_INSTANCE_PROFILE_2_SLICE_ALL_ME :
6675 giSlices = 2
6776 case nvml .GPU_INSTANCE_PROFILE_3_SLICE :
6877 giSlices = 3
69- case nvml .GPU_INSTANCE_PROFILE_4_SLICE :
78+ case nvml .GPU_INSTANCE_PROFILE_4_SLICE ,
79+ nvml .GPU_INSTANCE_PROFILE_4_SLICE_GFX :
7080 giSlices = 4
7181 case nvml .GPU_INSTANCE_PROFILE_6_SLICE :
7282 giSlices = 6
@@ -104,13 +114,27 @@ func (d *devicelib) NewMigProfile(giProfileID, ciProfileID, ciEngProfileID int,
104114 case nvml .GPU_INSTANCE_PROFILE_1_SLICE_REV1 ,
105115 nvml .GPU_INSTANCE_PROFILE_2_SLICE_REV1 :
106116 attrs = append (attrs , AttributeMediaExtensions )
117+ case nvml .GPU_INSTANCE_PROFILE_1_SLICE_ALL_ME ,
118+ nvml .GPU_INSTANCE_PROFILE_2_SLICE_ALL_ME :
119+ attrs = append (attrs , AttributeMediaExtensionsAll )
120+ case nvml .GPU_INSTANCE_PROFILE_1_SLICE_GFX ,
121+ nvml .GPU_INSTANCE_PROFILE_2_SLICE_GFX ,
122+ nvml .GPU_INSTANCE_PROFILE_4_SLICE_GFX :
123+ attrs = append (attrs , AttributeGraphics )
124+ }
125+ var negAttrs []string
126+ switch giProfileID {
127+ case nvml .GPU_INSTANCE_PROFILE_1_SLICE_NO_ME ,
128+ nvml .GPU_INSTANCE_PROFILE_2_SLICE_NO_ME :
129+ negAttrs = append (negAttrs , AttributeMediaExtensions )
107130 }
108131
109132 p := & MigProfileInfo {
110133 C : ciSlices ,
111134 G : giSlices ,
112135 GB : int (getMigMemorySizeGB (deviceMemorySizeBytes , migMemorySizeMB )),
113136 Attributes : attrs ,
137+ NegAttributes : negAttrs ,
114138 GIProfileID : giProfileID ,
115139 CIProfileID : ciProfileID ,
116140 CIEngProfileID : ciEngProfileID ,
@@ -121,7 +145,7 @@ func (d *devicelib) NewMigProfile(giProfileID, ciProfileID, ciEngProfileID int,
121145
122146// AssertValidMigProfileFormat checks if the string is in the proper format to represent a MIG profile.
123147func (d * devicelib ) AssertValidMigProfileFormat (profile string ) error {
124- _ , _ , _ , _ , err := parseMigProfile (profile )
148+ _ , _ , _ , _ , _ , err := parseMigProfile (profile )
125149 return err
126150}
127151
@@ -147,6 +171,9 @@ func (p MigProfileInfo) String() string {
147171 if len (p .Attributes ) > 0 {
148172 suffix = "+" + strings .Join (p .Attributes , "," )
149173 }
174+ if len (p .NegAttributes ) > 0 {
175+ suffix = "-" + strings .Join (p .NegAttributes , "," )
176+ }
150177 if p .C == p .G {
151178 return fmt .Sprintf ("%dg.%dgb%s" , p .G , p .GB , suffix )
152179 }
@@ -184,7 +211,7 @@ func (p MigProfileInfo) Equals(other MigProfile) bool {
184211
185212// Matches checks if a MigProfile matches the string passed in.
186213func (p MigProfileInfo ) Matches (profile string ) bool {
187- c , g , gb , attrs , err := parseMigProfile (profile )
214+ c , g , gb , attrs , negAttrs , err := parseMigProfile (profile )
188215 if err != nil {
189216 return false
190217 }
@@ -197,46 +224,69 @@ func (p MigProfileInfo) Matches(profile string) bool {
197224 if gb != p .GB {
198225 return false
199226 }
200- if len (attrs ) != len (p .Attributes ) {
227+ if ! matchAttributes (attrs , p .Attributes ) {
228+ return false
229+ }
230+ if ! matchAttributes (negAttrs , p .NegAttributes ) {
231+ return false
232+ }
233+ return true
234+ }
235+
236+ func matchAttributes (attrs1 , attrs2 []string ) bool {
237+ if len (attrs1 ) != len (attrs2 ) {
201238 return false
202239 }
203- sort .Strings (attrs )
204- sort .Strings (p . Attributes )
205- for i , a := range p . Attributes {
206- if a != attrs [i ] {
240+ sort .Strings (attrs1 )
241+ sort .Strings (attrs2 )
242+ for i , a := range attrs2 {
243+ if a != attrs1 [i ] {
207244 return false
208245 }
209246 }
210247 return true
211248}
212249
213- func parseMigProfile (profile string ) (int , int , int , []string , error ) {
250+ func parseMigProfile (profile string ) (int , int , int , []string , [] string , error ) {
214251 // If we are handed the empty string, we cannot parse it.
215252 if profile == "" {
216- return - 1 , - 1 , - 1 , nil , fmt .Errorf ("profile is the empty string" )
253+ return - 1 , - 1 , - 1 , nil , nil , fmt .Errorf ("profile is the empty string" )
217254 }
218255
219- // Split by + to separate out attributes.
256+ // Split by +/- to separate out attributes.
220257 split := strings .SplitN (profile , "+" , 2 )
258+ negsplit := strings .SplitN (profile , "-" , 2 )
259+ // Make sure we don't get both positive and negative attributes.
260+ if len (split ) == 2 && len (negsplit ) == 2 {
261+ return - 1 , - 1 , - 1 , nil , nil , fmt .Errorf ("cannot parse profile '%v'" , profile )
262+ }
263+
264+ if len (split ) == 1 {
265+ split = negsplit
266+ }
221267
222268 // Check to make sure the c, g, and gb values match.
223269 c , g , gb , err := parseMigProfileFields (split [0 ])
224270 if err != nil {
225- return - 1 , - 1 , - 1 , nil , fmt .Errorf ("cannot parse fields of '%v': %v" , profile , err )
271+ return - 1 , - 1 , - 1 , nil , nil , fmt .Errorf ("cannot parse fields of '%v': %v" , profile , err )
226272 }
227273
228274 // If we have no attributes we are done.
229275 if len (split ) == 1 {
230- return c , g , gb , nil , nil
276+ return c , g , gb , nil , nil , nil
231277 }
232278
233279 // Make sure we have the same set of attributes.
234280 attrs , err := parseMigProfileAttributes (split [1 ])
235281 if err != nil {
236- return - 1 , - 1 , - 1 , nil , fmt .Errorf ("cannot parse attributes of '%v': %v" , profile , err )
282+ return - 1 , - 1 , - 1 , nil , nil , fmt .Errorf ("cannot parse attributes of '%v': %v" , profile , err )
283+ }
284+
285+ if len (negsplit ) == 2 {
286+ return c , g , gb , nil , attrs , nil
237287 }
238288
239- return c , g , gb , attrs , nil
289+ return c , g , gb , attrs , nil , nil
240290}
241291
242292func parseMigProfileField (s string , field string ) (int , error ) {
@@ -310,8 +360,11 @@ func parseMigProfileAttributes(s string) ([]string, error) {
310360 if a [0 ] >= '0' && a [0 ] <= '9' {
311361 return nil , fmt .Errorf ("attribute begins with a number" )
312362 }
363+ if a [0 ] == '.' || a [len (a )- 1 ] == '.' {
364+ return nil , fmt .Errorf ("attribute begins/ends with a dot" )
365+ }
313366 for _ , c := range a {
314- if (c < 'a' || c > 'z' ) && (c < 'A' || c > 'Z' ) && (c < '0' || c > '9' ) {
367+ if (c < 'a' || c > 'z' ) && (c < 'A' || c > 'Z' ) && (c < '0' || c > '9' ) && c != '.' {
315368 return nil , fmt .Errorf ("non alpha-numeric character or digit in attribute" )
316369 }
317370 }
0 commit comments