Skip to content

Commit 0971871

Browse files
committed
feat(FR-1328): Ensure UI supports MIG usage smoothly (#4880)
Resolves #4066 ([FR-1328](https://lablup.atlassian.net/browse/FR-1328)) # Limit Unique Resource Type Allocation to Maximum of 1 This PR adds a constraint for unique resource types (like TPU) to limit their allocation to a maximum of 1 unit. The implementation: 1. Uses the `useResourceSlots` hook to identify unique resource types 2. Adds validation logic to prevent allocating more than 1 unit of a unique resource type 3. Limits the slider and input controls to a maximum value of 1 for unique resource types 4. Adds appropriate error messages in all supported languages 5. Fixes the CPU utilization display in the Agent Detail Modal by moving the conditional rendering to the correct position ![image.png](https://app.graphite.com/user-attachments/assets/144ef553-599f-47d8-ba46-bd1300bedc99.png) **Checklist:** - [x] Documentation - [ ] Minium required manager version - [x] Specific setting for review (eg., KB link, endpoint or how to setup): 10.122.12.117 - [ ] Minimum requirements to check during review - [ ] Test case(s) to demonstrate the difference of before/after [FR-1328]: https://lablup.atlassian.net/browse/FR-1328?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
1 parent a0d228c commit 0971871

23 files changed

Lines changed: 64 additions & 9 deletions

react/src/components/AgentDetailModal.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ const AgentDetailModal: React.FC<AgentDetailModalProps> = ({
6666
>
6767
<BAIFlex direction="column" align="stretch" gap={'md'}>
6868
<Row gutter={[24, 24]}>
69-
<Col xs={24} sm={12}>
70-
{parsedLiveStat?.devices?.cpu_util ? (
69+
{parsedLiveStat?.devices?.cpu_util ? (
70+
<Col xs={24} sm={12}>
7171
<BAIFlex direction="column" gap="xxs" align="stretch">
7272
<Typography.Title level={5} style={{ marginTop: 0 }}>
7373
{mergedResourceSlots?.cpu?.human_readable_name}
@@ -91,8 +91,8 @@ const AgentDetailModal: React.FC<AgentDetailModalProps> = ({
9191
</BAIFlex>
9292
))}
9393
</BAIFlex>
94-
) : null}
95-
</Col>
94+
</Col>
95+
) : null}
9696
<Col xs={24} sm={12}>
9797
{parsedAvailableSlots?.mem ? (
9898
<BAIFlex direction="column" gap="xxs" align="stretch">

react/src/components/SessionFormItems/ResourceAllocationFormItems.tsx

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
convertToBinaryUnit,
66
} from '../../helper';
77
import { useSuspendedBackendaiClient } from '../../hooks';
8+
import { useResourceSlots } from '../../hooks/backendai';
89
import { useCurrentKeyPairResourcePolicyLazyLoadQuery } from '../../hooks/hooksUsingRelay';
910
import { useCurrentProjectValue } from '../../hooks/useCurrentProject';
1011
import {
@@ -163,6 +164,8 @@ const ResourceAllocationFormItems: React.FC<
163164
currentImage: currentImage,
164165
});
165166

167+
const [resourceSlots] = useResourceSlots();
168+
166169
const { mergedResourceSlots, resourceSlotsInRG } = useResourceSlotsDetails(
167170
currentResourceGroupInForm || undefined,
168171
);
@@ -904,6 +907,12 @@ const ResourceAllocationFormItems: React.FC<
904907
currentAcceleratorType,
905908
'shares',
906909
);
910+
911+
const isUniqueType =
912+
resourceSlots[
913+
currentAcceleratorType as keyof typeof resourceSlots
914+
] === 'unique';
915+
907916
const isSingleCluster =
908917
form.getFieldValue('cluster_size') < 2;
909918
const hasQuantumSize = _.isNumber(
@@ -948,6 +957,7 @@ const ResourceAllocationFormItems: React.FC<
948957
/>
949958
),
950959
}}
960+
dependencies={[['resource', 'acceleratorType']]}
951961
rules={[
952962
{
953963
required:
@@ -960,9 +970,12 @@ const ResourceAllocationFormItems: React.FC<
960970
resourceLimits.accelerators[
961971
currentAcceleratorType
962972
]?.min || 0,
963-
max: resourceLimits.accelerators[
964-
currentAcceleratorType
965-
]?.max,
973+
// Unique type should only allow 0 or 1
974+
max: isUniqueType
975+
? 1
976+
: resourceLimits.accelerators[
977+
currentAcceleratorType
978+
]?.max,
966979
},
967980
{
968981
validator: async (_rule: any, value: number) => {
@@ -1053,6 +1066,22 @@ const ResourceAllocationFormItems: React.FC<
10531066
return Promise.resolve();
10541067
},
10551068
},
1069+
{
1070+
warningOnly: true,
1071+
validator: async (_rule, _value) => {
1072+
if (isUniqueType) {
1073+
return Promise.reject(
1074+
t(
1075+
'session.launcher.CurrentAcceleratorTypeAllowsMaxOne',
1076+
{
1077+
accelerator: currentAcceleratorType,
1078+
},
1079+
),
1080+
);
1081+
}
1082+
return Promise.resolve();
1083+
},
1084+
},
10561085
]}
10571086
>
10581087
<InputNumberWithSlider
@@ -1083,6 +1112,7 @@ const ResourceAllocationFormItems: React.FC<
10831112
]?.max,
10841113
}
10851114
: {}),
1115+
...(isUniqueType ? { 1: 1 } : {}),
10861116
},
10871117
tooltip: {
10881118
formatter: (value = 0) => {
@@ -1100,8 +1130,12 @@ const ResourceAllocationFormItems: React.FC<
11001130
}
11011131
min={0}
11021132
max={
1103-
resourceLimits.accelerators[currentAcceleratorType]
1104-
?.max
1133+
// Unique type should only allow 0 or 1
1134+
isUniqueType
1135+
? 1
1136+
: resourceLimits.accelerators[
1137+
currentAcceleratorType
1138+
]?.max
11051139
}
11061140
step={currentAcceleratorStep}
11071141
onChange={() => {

resources/i18n/de.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,6 +1524,7 @@
15241524
"Container": "Container",
15251525
"Core": "Ader",
15261526
"CreatedAt": "Erstellt am",
1527+
"CurrentAcceleratorTypeAllowsMaxOne": "Vom Typ \"{{ accelerator }}\" kann höchstens 1 zugewiesen werden.",
15271528
"CurrentResourceGroup": "Aktuelle Ressourcengruppe",
15281529
"CustomAllocation": "Benutzerdefinierte Zuordnung",
15291530
"CustomResourceApplied": "Benutzerdefinierte Ressource wird angewendet",

resources/i18n/el.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,6 +1523,7 @@
15231523
"Container": "Δοχείο",
15241524
"Core": "Πυρήνας",
15251525
"CreatedAt": "Δημιουργήθηκε στο",
1526+
"CurrentAcceleratorTypeAllowsMaxOne": "Μπορεί να εκχωρηθεί μόνο 1 συσκευή τύπου \"{{ accelerator }}\".",
15261527
"CurrentResourceGroup": "Τρέχουσα ομάδα πόρων",
15271528
"CustomAllocation": "Προσαρμοσμένη κατανομή",
15281529
"CustomResourceApplied": "Εφαρμόζεται προσαρμοσμένος πόρος",

resources/i18n/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1531,6 +1531,7 @@
15311531
"Container": "Container",
15321532
"Core": "Core",
15331533
"CreatedAt": "CreatedAt",
1534+
"CurrentAcceleratorTypeAllowsMaxOne": "\"{{ accelerator }}\" type can only have a maximum of 1.",
15341535
"CurrentResourceGroup": "Current Resource Group",
15351536
"CustomAllocation": "Custom allocation",
15361537
"CustomResourceApplied": "Custom resource applied",

resources/i18n/es.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,6 +1526,7 @@
15261526
"Container": "Contenedor",
15271527
"Core": "Núcleo",
15281528
"CreatedAt": "Creado en",
1529+
"CurrentAcceleratorTypeAllowsMaxOne": "Solo se puede asignar como máximo 1 \"{{ accelerator }}\".",
15291530
"CurrentResourceGroup": "Grupo de recursos actual",
15301531
"CustomAllocation": "Asignación personalizada",
15311532
"CustomResourceApplied": "Se aplica el recurso personalizado",

resources/i18n/fi.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,6 +1525,7 @@
15251525
"Container": "Kontti",
15261526
"Core": "Ydin",
15271527
"CreatedAt": "LuotuAt",
1528+
"CurrentAcceleratorTypeAllowsMaxOne": "\"{{ accelerator }}\"-tyyppiä voi olla enintään yksi.",
15281529
"CurrentResourceGroup": "Nykyinen resurssiryhmä",
15291530
"CustomAllocation": "Mukautettu jako",
15301531
"CustomResourceApplied": "Mukautettua resurssia sovelletaan",

resources/i18n/fr.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,6 +1526,7 @@
15261526
"Container": "Container",
15271527
"Core": "Cœur",
15281528
"CreatedAt": "Créé à",
1529+
"CurrentAcceleratorTypeAllowsMaxOne": "Pour le type \"{{ accelerator }}\", vous ne pouvez attribuer qu'un seul exemplaire.",
15291530
"CurrentResourceGroup": "Groupe de ressources actuel",
15301531
"CustomAllocation": "Attribution personnalisée",
15311532
"CustomResourceApplied": "Ressource personnalisée appliquée",

resources/i18n/id.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,6 +1524,7 @@
15241524
"Container": "Kontainer",
15251525
"Core": "Core",
15261526
"CreatedAt": "DibuatPada",
1527+
"CurrentAcceleratorTypeAllowsMaxOne": "Tipe \"{{ accelerator }}\" hanya dapat dialokasikan paling banyak 1.",
15271528
"CurrentResourceGroup": "Grup Sumber Daya Saat Ini",
15281529
"CustomAllocation": "Alokasi khusus",
15291530
"CustomResourceApplied": "Sumber daya khusus diterapkan",

resources/i18n/it.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1523,6 +1523,7 @@
15231523
"Container": "Contenitore",
15241524
"Core": "Nucleo",
15251525
"CreatedAt": "CreatoAt",
1526+
"CurrentAcceleratorTypeAllowsMaxOne": "È possibile assegnare al massimo 1 acceleratore di tipo \"{{ accelerator }}\".",
15261527
"CurrentResourceGroup": "Gruppo di risorse attuale",
15271528
"CustomAllocation": "Allocazione personalizzata",
15281529
"CustomResourceApplied": "Viene applicata la risorsa personalizzata",

0 commit comments

Comments
 (0)